/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/

var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __esm = (fn, res) => function __init() {
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);

// src/resources/flags.js
var flags;
var init_flags = __esm({
  "src/resources/flags.js"() {
    flags = {
      "red": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH6QMBFCMRzbWhYAAAAm9JREFUWIXt1Eto03AcwPHfPy21r6WZ2JOKrN2jrV3b6ZAWHxQcXpwOvDkUD4MdnDfdSPAQi+JBUG8TRMGDrOrwAeKiUCHIYBE8zR3s1sdBkYEwpgOXf5v272WW1dKtaZMepH8IhF8eny9/SIAQAoQQGDh0IPz3vBkHih4Mhe+cOzXnpO2rP3+vM1efvY28+jAngc6LunTisOCk7QAAjMNqgfHBqKA3CgBA7d7pYDYP9u1qZya9HvZIR0dYV9hAoYrhiMXMJxhaSPh97EhXpy4BVJW5GSHEHDWZ+Mk2u/AtFCB3vR42ouEuVINLAQDAOCkKLlrM/HuGFmb8PvZ8Z+O7sB1cFmFAiDluMvEPaLuQCvayN3q66w5QA5cCAIDZazDw4zarsNYXJNP7fewZt1tVRD1wWYAJITi9w8THHW3CfMB/hatxFxqBKyJ6jMbr12xWYaUvSB75POyg21U1Qiu4LMCGEJw1m/nnDlr4FPCzl7u7KgK0hisieo1G/qbdJvwIBcl9r4eNbnySesJlATSF4ILFzL9rdwgnXa6wsQlwaSUVJfZYxuKbTEbSHV4nBGZyeS4uy+LrdEa6tTHXDc4UCtwTGYux5KI0DADD/1zXFFYAIIFz3JSMxafptBTb4l5N4O+FAjeNc+LEl6Q0BABDNTxTN0wIgdl8novjnPhwKSVNqHxeNbxSLMILnOPiMhZns1lpQO0L1MIf8woXl2Xx3lJKGgOAsTrBmuBfRQIvMeamZCyK2ax0rEFsW/izokBcxpHbi0vSKACMaghuCffPL6B+HbDNqxn/6hbcglvwfwobF74uw/LqWtlwTxPgP3n3GrlhLVHIAAAAAElFTkSuQmCC",
      "checkers": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAC5klEQVRYhe2WS0hUYRTHf8fX+EpnfPQwKXIT9iKLYsSNRLZSgkoICgKJWiTVJopaRFRCENFrkVEbF0G1yAiyaGMGWZARPcQMsjDKMHN0SjOz0+J+l3vV66Q4uvLAcL//+ebO77zudwdVRVVZv3ZV0F5Px0eKV68Mntle1pidlhrq6ev3H7lxr7C2ofEJU2wxlRuK6rLTUgH86clJHCgtrptqKEDM/Ix0v9uxMCvgR+QQIsEpBcfGyChnHlQVwaOpDCDGy9kF8g3igKNA3XkRPSdyJZpBxHk5e8w1AIk5kPjGktuuw9ZmkdpjcBHVSQ2gZ8a2hQF1ZOIySCmHLUDdZNvgmXE6kAb8sYnALKDTkr7T4HsJJ2ogjIj/BbR9grulqpXjBXtm/AvIdGk/kOPSYeAnxJotPsCiftiDSCciV8cD9sx4wFzjTWS2zgJ6gd9G+4BB4K/R+ZCVDBVNIhXAyztQX6a6z4sRscdJQKpLx464IdkEZ1sr8N6RK17B3nqR74hUjwucg9XXXqDLrDOAr1htyDNBdWNVY44JYMj4/EAQOAwUQ2AT7Lotoog8R2Q/jFHqNKDfpRMB9zEzaCDufXcGfcBHl35ogt0IBUABIsme4BZXAAlAyGifqUa70cvN2t6PB1JwZiAfKMSqGsAD6A1BfblqlSfYtniskto2G1js0l+AHy6dy/DpH8KqDtAMXCtRPWnveYIzgYAr0gScnts3peCccHOBeUCb0ceBEgi3wi1Ud3gxPMEhnPJhgoh1aWH4NHfjHDbAuyXQEFTd6fXbEcH24ASwnlE7s2ysqTbl4ylWjwesM+U+quUAmyMRI4Ft0xF6AU65ARLgcxc8toETMU/wUuAtTvkuYQ1Nk/OVZ0BNgeqFgokSI4EHsV4KthUDPmuIbzLGERgVcKu5ngLWQcsaqEb1bDSAEcHGLh9U3R1N2P/BqqP/iEXZIr6dZsAz4BnwDDiSxb1u76AjFB7mzJ0G8D/kvRAp7yYAQQAAAABJRU5ErkJggg==",
      "blue": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACMElEQVRYhWP4//8/w////xlczIwsYGx6YEYHYwOLvhjf46J8PB8+fvsuUL1qh+WGQ8dPMNAYMOW4WW8X5eNhYGBgEODn4mQo9XHYTmtLGRgYGJikhfgFkAXkRQQFfCLX7tD3n55CU4uZmRgxBB9IOLozKQTOiopau8MhcCZNHMCCTfAnExvDTyY2xkviju6s/365qRZ/ma36bOfOJ99erbm0MXMONSxmwif5k4mN4QsLDyMDAwPDIwlHd2aFwFkRUWt32AVQHgpYfYzLET+Z2BivQEMhNXp9yKvvr9dsXJdGVggQbTG6A46L2cOjQf/5zp1Pv71ec3xDBtGOINlidAcwMDAw3ICGQlL0Wv8X399u3EZEKJBtMTZHnBJz9GH998tbtfjLbO3nO3c++/Z6zSkcoYA3cZHjAFhivCPu6P5bPmBWfPS6He5YsiRVfIzLET+Z2BjPijnA04Lms507H397teb8xsw5NLMY3QEMDAwM9yQgacHMfwbtfIwNmL46sPPFt9drtm/MoL2PGRgYGHSh2W0+UkKjmcV2L3bvfPX99ZrN69LmMDAEY8hT3WJDqO/mEihMqGKx44vdO19/f71mPQ7fUd1i0+c7dz77/mbNrPXpJJfXZFmsDs2PyyioIom22PzFrp3Pv71es3d9OtHBSZHFsNJmCZUaAAQtVrq3NHUnlXxHtMW3e3kYGRjSaWIhDFC1dhq1eNTiUYtHlsUsVx6/YHjx4TOKoAwdLAYATv0+zO4Wc9kAAAAASUVORK5CYII=",
      "green": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACOUlEQVRYhe2VzWsTQRjG39kMQaW0UcxJQWIbQSQbtVprE6RKmz3Y4kkQ8ag3r0Vt7+1uD/4BaY6CKAMqHrpDBSWI8ZJEiIjamBz8aEqVrBaVhd0ZL90S7SZu404v5oWF5Z3D73medz6Acw6ccxgZODro/G/Fh4b7Dw/evDSeC3d3GV9//AxN3dVP3s/mnoPgkq6mEvPh7i4AgFDPju0wMTY8LxoKACDt2dUTamzs270zdEbt1Q9ci1wWCg5IaEPzbZwpVhKlz2l9+okb+4UIwG5NEwOYmKO8bCtBC6XCC5G5Q3mJfqwzsqhVM36ApVaLJgZY3cYRAEA5zhQ7idLjWp9+3IcUWoLdRBRlW/kyBOmLs1E9NdnbtgDXqP8mwMQcZWPW+hiOFQJ0qc7IC7XieQyeHbsJcMZQkm3lWwLSF7Tow9MeU9i042YiTMzRU9kaC1robHghMnckL9Elg5GS6r4Z23bcTICTwqs4U74nUPr8bFQ/5ZKCL46biTAxR7mGvSCvHcnXWjUjDPynAACAN3GmBC2Uil2PiHPsVokSpssGI0/UinjHAAD9hQD9VLfJHXVxfaMJA48UMV0xGHk0/S4DoxvXfQcPrF0mtxvcuZUvYKWI6WeDE3267OrOd/BQIUBrBiO3Zlq78w0cy0v0Q52RB1q57SfSMzhZwHTZsMmzmYrnOP8J7Nw297TNx9kW+OBj6Uq2yVEQBl4ZrSJRQKd8fZ064A64A/6/wPjl+xrUjNXfmnu3APwLyT02r9kBUpoAAAAASUVORK5CYII=",
      "pink": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABSUlEQVRYhe2WsUrEQBCGv4tXRDnuVvEqBV9BFCSHzRVipXB18BEsFRWLQ+x9jCus0sVSbM4H8A1srjwR1G5tNqC4e9kkuykkAwvDpPj+f3bYCVJKpJQc7O1EWV7HaQ13t6O7k+Npv9uZv318iuv7h0HyNH3GcwSnh/tpv9sBEL2VZc6PhqlvKECwsdYTPwtb66uCOLkkTiKv4KWgpauPgdSngLahHqozBi6IEwFcAY9MRk7uP8j5HgJC5U67kAfWiXAiwNTqPAGVr6GIY50AofKsC2e2XSjj2CQiBG6BL5suVHFsEiBUvnAWXDk2iTDOgmvHJgFC5VkXIp+OdXGDclwX+M+g+QQvnGofYKvHxBW48MtVFVx6Y5UFV16RRcBO97EN2CnQBjxwDcsHT0baHzGXUcdb3YAbcAP+p+D2y+uM2fz9V3GzBvA3IcG57wVt5SkAAAAASUVORK5CYII=",
      "yellow": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABPklEQVRYhe3Wv0rDQBzA8W9jKVVKexE7KfgKoiApLiWIk76Bj+CooDiIuPsgTm5xKuJSH8A3cOmWiqCS5VwqxHhJ8+d3GaQHgeOWzze54whaa7TW7O9uez/zOp7GcGfLuz0+Gve7nenbx6e6vHsY3D+Nn7E8nJODvaDf7QCo3soyZ4fDwDYK4Kyv9lR8YXPNVWHkn4eR71mFl5yGaf0KCGwGOCnrbUDFArR0RBqcDADhrzAPNkWIBBSB0wJKbUMZOBlALOI0b0CzApyMaAM3wFcY+Qq4AB7d1sh4GVV547QANZtnngVp2BRhPAs24WQAsQhPao/zjmtm+14X/Oeg2YQzT7UNOBOUhnNhknBhsCpcGiwDV8aKwqJgHnggjc2F3dbI+CMmOeq4qxfwAl7A/xRuvrxOmEzffy1u1AB/A5cP1WBzW154AAAAAElFTkSuQmCC",
      "orange": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABTElEQVRYhWP4//8/w////xlczIwsYGx6YEYHYwOLvhjf46J8PB8+fvsuUL1qh+WGQ8dPMNAYMOW4WW8X5eNhYGBgEODn4mQo9XHYTmtLGRgYGJikhfgFkAXkRQQFflSqVvyoVLWgqcXMTIzYxOsZGBi209IBLDjEOaC4noGBofxHpaoAAwNDJQMDwwGO9ttUiX8mAvIcDAwMAlA2VUOBkMXYHEEVB+AKakIOoDgaSPExNgcIQNmwUCghNhTI8TEuR3AwMDA0MzAw/CAmFCjxMS4HCEDZeNMCtXyMyxE40wK1fYzLAQJQNiwULGjpY2ygkQHqY3pZjJHQaGkx3lRNC4uJKkyoZTHJJRelFpNdY5FrMcVVJCkWU7U+JsZiqlpIjMWW1LaMoMUc7bexNsSoCehRVo9aPGrxqMXD1GKWK49fMLz48BlFUIYOFgMAyz/KBzK6zGkAAAAASUVORK5CYII=",
      "purple": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABPElEQVRYhe3WPUvDQByA8aexQ5TSnmInBafsomBTXDqIk34DP4KjguIg4u4HcXKLo7jU7G4dXTpWBM12LhVivKR5+V8GyUHguOX3JHccQWuN1pqDvR3/Z17H0xrtbvt3J8fjfrcze//8Ulf3j8OH5/ELlodzergf9LsdANVbWeb8aBTYRgGcjbWeii9sra+q0IsuQi/yrcJLTsu0fg0ENgOclHUXULEALR2RBicDQPgrLIJNESIBReC0gFLbUAZOBhCLOMsb0K4AJyNc4BaIQi9SwCXwNJi4xsuoyhunBaj5PPMsSMOmCONZsAknA4hF+FJ7nHfcMN/3uuA/B80mnHmqbcCZoDScC5OEC4NV4dJgGbgyVhQWBfPAQ2lsITyYuMYfMclRx13dwA3cwP8Ubr++TZnOPn4tbtYAfwMBYNJpfZpdcwAAAABJRU5ErkJggg==",
      "white": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABJklEQVRYhe3WsUrDQBjA8X9jB5XSnmImBV9BLEiKSwdxsm/gIzgqKA4i7j6IU7d0LC7tA/gGLh0rgo7nFDjjxV6S724o+SAQvuX3JzlC0Fqjtebs5DjJ7kNcrWH/KHm+HM3ibmf58fWt7l8mg/HrbI7nia7OT9O42wFQve0tbi6GqW8UINrf7Slzcbi3o4BbIPEKb0Qt2/4BSH0GRAX7TUAZAVo6ogjOB4DwU1gF2yJEAsrARQGVXkMVOB+AEXHtGlAHtkU84fgUpOB8AKw4C9KwLcJ6FnzC+QCMiKQdADbnEZgC81DwXQZmC5/wH8wcH/C/oDTshEnCpcG6cGWwClwbKwuLgi7wQBpzga0/YpIT4lvdwA3cwGsKt9/eFyyWn7+WBwHgH/UUmOp6KmdeAAAAAElFTkSuQmCC",
      "black": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABLElEQVRYhe3Wv2rCUBTH8d9NHbSI3oqZWvAVpEKJuDiIk76Bj+DYQksHKe59kE5ucZQu+gB9AxdHi6DjcQpc05vm37l3kBwIhLN8viSXEBARiAiDp0cvuLdxiX6n7X1Oxmu3Vt3/Hk/y/WvZXXyvNzA8znTY891aFQBk/baCl1HfN40CgHPfqEt10WreSSHEqxDCMwrfOEK3nwHwTQY4EfsyAKkEEHdEFBwOAJifQhysi2AJSANHBWR6DVngcACUiOekAXlgXcQcCZ8CFxwOAGLOAjesi9CeBZNwOABKhFeyAKvzAWBFRBtb8FsABguT8B9MHRPwvyA3nAjjhFODeeHMYBY4N5YWZgWTwF1uLBYmIu2PGOfY+FYXcAEX8JXCpZ/tDrv94WL5YAE+A0hLuhQ62ZsRAAAAAElFTkSuQmCC",
      "finish-line": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADyklEQVRYhe2WTUgjZxjHf0mcfJqYafyciqW5aIyWpsUS8SLS9FIloBUWWhCWsj10aU/FQg9FbBcEKavtwS3txUPB9tAFobZ40S10FRoq2hVNwQ8izYImxkRN4pikBzuzys4Gt9U9+cDA/J933vf3vM/7zDNDoVCgUCjw+muv+JX7Z3Hp2l992f/FO133Kxylib3DtPOT739uvXvv/hyXbPqbb7RNVThKAZxlVgsfdbZPXTYUQP/8c2XO044XykUn8DHgv1SwQa97zOl2u2+1tbX9epkB6LWcsVhMt7OzUwJ8CkyNjo4WRkZGvrnIIEq0nHt7ewCIomiWJMn84MEDgLcnJiauLS8v3x0YGPgK+F8FqAlWLJVKUSgUFGluamrC6/W+BbwJDAEz/zUATXBZWRkOh4Pj4+MTotmM3W5ne3sbwDQ8PGxaXFz8bHx8PAU4FxYW1re2tn7q7Oy8eV6w5hlnMhlcLpeqnU4nkiSpOpVKcXBwYACcABsbGy+m0+n3gW3g2/OANXeczWYBEAQBvV6v6vLycpLJJEdHRwCYTCZkWSafzwPg8XjKrVbr9VAodB1YnJycnOnq6vrw3DtWzGKxUFpaqmqDwYBe/2iK1WpFEARVh8Nh1tbWFPnS0tLSBzMzM3Hgzrl2LEkS8XicTCYDnJyx1WolHo8D4Ha7iUajpNNpAKqqqojH4+RyOeDkaBoaGpibmwMQu7u7b/T19d0IBoN/AOPAbU2ww+FQF1XAOt2jRiPLsgpRxk9n4vDwkM3NTVXPzs7idrsJBoM+wAdYNcErKytqAEajkUQiAZycqSRJRCIRAJqbm4lEIuq4IAjYbDa1BjweD62trcRiMQCmp6eTiURipre391bR91gQBCwWi6orKyupr69XdTQaZX9/X9W1tbVnqj+XyyHLMsAy8F0gEPhcGdMEu1wuRFFUIzUajZjNZpLJ5MmkkhJsNpva4aqrq6mpqWF9fR2AwcFBAoFAKhwO/wj0aTE0wYlEQk0fgCiKGAwGVet0ujPVvLu7qzYb4K/GxsZ7fr//Xa21i4KVwhFFkXw+r+6soqKCTCajpI/5+XkikQjZbDYF/AL0AvT09BRjPhms2Kk+DUBdXZ2abgCj0fh3LBb7TQE+jWmCvV4vq6uravrGxsaQJIlQKKQ88jsw7vP5vvT5fE/LfDJYlmXsdruq29vbMZlMUeAHQLMFXgg4HA4DMDQ0REdHx0pLS8sd4PZFAIuC/7Wv+/v737tI2HnAj/+IXbAV/Tpdga/AV+ArcDEr+TPykIeJ1Bln7TMA/wOG1Kb5w4e1ggAAAABJRU5ErkJggg==",
      "bee": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAD+UlEQVRYhe2WXUxbZRjHf+f0uytQoB2sEvEjMTEmaOfYSgyOGVyauO4CcXPOj2wxbGTLZqJbjMZwMbcLLwwGL0RYXFhC4mAbyjaqF0pYIqC4JroYFxIxOvvByRBaKF/tOV6ctYXspLKs7Ip/0qT/5+05v/6f9zlvi6IoKIpC7eaNntT7+/ESap5+yvPxq75BZ75tcio+a3//nL+qZ2BwiFWWeHj7M33OfBuAvcBq4diOmr7VhgKIDxQV2JcWyh2F9oDf9W7A7/KsJlivE4U7ir5946ccRbrkF7g+APrd3mDOWy9qFSejsjA5JeuBJqDveGOBcuxgQXsuu6DXKl49XwrA1vqI2VksmrtbnQB7vx2Yffmzs3k9B1/L+/Reu6CZOKWZWRlFSVvzo+WGdbXVlnqg717nQDNx9YthbFaRkcsbAPDsDGO1CHz3ZQmAqeP8jGl0bPHDE+/YYwG/y37jj8WxcUm+cqTp1uGVgjUTLyxAQX5mKc8m4CzWpX08LjM7p+gAO0Awknx4bkE5FPC7pIDfdXolYM3Ew73qHlfuCCEKQtpv2x1hJi7zY6/aiS2+MImkws9XVF/XIDnMJmF/Z4trP/DLwPBc/9GmiaMrTpyS2ShgtWQeN50IopDxZpOAXpfxf91M8E8ombIVo2OJI20fOSYCflfrihJv3xshGlMY+lpN6tkZxmwS6O8qAcC3bxxpQmboK3W9dk+EqZjMyO3kz9aHeahMT0ezA6Dw7RP/NvgGixpqqswBoMPtDTZrgm1Wkfl5Oe2NRlgSlEQCZFlZsi4s68TcvEJoPJ2ca78uULZBR02V2Q24A36XVRN8oc0JQHVdGL1BYKBbTbbFF8ZZLNJ3dj0AuxolwlIyvV65I4TFLKRnoK5BouJxI9+fUzs1dG0+GptR+o+fnDilCU5JrxcwGzNJiuwi5WWZS6QJmfhsJnmJQ7ds+mUZEgkF4Degs/G9WyfT99YCbtsVIc8mpL/pZl8Ik0Hg6gU12aYX1GSpE+75VyI4CnVcOqN2oq1zGs9GU6yn3XnR7Q2+oRlKqxiblolNZ3y+TURcMv+CoHYjpWhMIZFM7+noIw/qB15/S3pT695Zwanp3FofQVaUdLLndkdYWFT46ZK6fv3GImEpyXBvaQz4xu0NvgTg9mZDZgGnpKAs86XrdczEMzW9nuBUVP4hBbwbaYLrD0j8eTORPqu7L8dxFot0tjhSHxkBOvYcklruFpgVnEjCOktmUzdVGDEYhBDQ5fYGNY/AnIB72tXn+EzXNJVPmn5/4jFDq9sbbM4FMCv4tj7/5HT0QC5h/wt2e4N3/hHLsbL+Oq2B18Br4DVwNumv/x0mPBlbViy7D+D/APJpt+laKOEtAAAAAElFTkSuQmCC",
      "red-fade-light": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACmElEQVRYhe2VS2sTURSAv5NJm7bWvNrYYiv5ByIVpFIXFWpBUNGVLsSdICq6UTddCIorwYUIIv4D3eimdVEQRGgXQheKC0ERWmkCsaaW2qRJ5riYRyaPThNtusodZrhz7p3zndc9g6qiqkwcGRl15rtxy/jhQ6OPLp6eS4R7s6t/NqJTL94cffVubp4Wj8D1ybGZRLgXIBrp6eb2qfGZVkMBAkPxSNQrSPbHokuDg6nlkZGnLQUbAakRltLpgc2FhSuLw32aPjE23RKw36ICxfTyydSxg/rz0tkfq1M3nrQc3DUxgQgIgAilTGZ/8euXa9mrF/LrD+68bhk4NzsLCOzpARRsI6RQ6tSVzJmNuzc1//je938FB31XOzoJBIKAYvQPQH7dDgEgApuFZOHZQzUiMQLxviKT5zoaBfvmmEIeM58jEItDIWfJ1L6tB4iiAqoaZP6t8nlB/xssoS4oljBXViitZl0u4QjEE0hiEMSrwmYuflN+ZZT8Ru6fwJrPoWbJzq8BhmFFen0NYyiJZlJgKqJuGByTrXclhCdGDYNREOcTNcEsWXPTpPjxgxtydVuBtyfU9AfHgN/be4xUpBO19KmrVsu1hmejKKjWYQOwF8j551hsjVJ23dGnKiBiG1GJdz/eusy6tg21o7Ami6K2QFDUXlN3f52x6bgB251j8RzbKp1lI7TCwOrVrazwB1folLK5HvfFvqowJrF+w0+1P7hOkhSsKhYPX+wiGz1ev5yaBatUVSt2nVkz+weiBM5fbhjYEFjc41RboRLqzIZu3Y81C2wI7Emky408f9m0d82D7ZYk3T1r+6bfh3cC2BD4wFJmR7xrGJxUbRnQGf6dqw1ug9vgNthnBD8tpkhl1yqEw7sA/gs0rjmZ1qf2MwAAAABJRU5ErkJggg==",
      "blue-fade-light": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACwElEQVRYhe2Vy08TURTGvzPToYXwmFYQBSLRuHGlQUMwLsQETYyPxL1/gIlsXLhy4daFceFGl65d+NiIC1csxEQWmmhiSAxECUKIUKlCO+3M52LundvSMmkJZdWTTHvvmen5ne+cc6cgCZKYGB0Z0+v9uGT89KmxRzevzfR1d2b/bG65956/PftqeuYDmmzW5KVzU33dnQDg9nS04+7V8almQwHAGsz0uOWO4d60e+j94vLI7K8nTQXbllQ5Vzy//9Nf79ax6R+88nHpTTPAiVpOAUB1rXj+5YmZRR5td5aGkomX908cmNwLsFXLSQAX0ymzIbDm+QPzm97tO59XCw/n1l43BQwA79bzAICOhAUIQAIiAp9B23rRv/7g228+/Z5d2C04ttRtlsAWABT0JW14PsO7DO+XyOFnC1n2ODZcxy5dONjh1AveUTEAeAGR9wnXERQCqqozyk4ACCRMlEjMruU5l/O4a7D+ZUoEAYn1YoBcKQBAiABdjoWMY6M3acNSbQAAUQdkaavIbDFgIWC+IbCoKx8QPqE0ISw7gH+lAIdTCawWfHUfpj8qgoTlScIckPoUc9uaAAKG5IDA141ClCD1q0CVHyAoOqOqsBuxircHigQpin4m7LkhUMkXIFRdbV0A8rE9NnwJfTqamPRFnzUw/NaDzxr1NZbacaqNolBVhQKKKXMUXtRTelvRdADwYMYn/hxHIk3nQFhRVlqx6KMlyhv2BCJWuYYKqwneXiJqzaKn1fQ1GsSotAICgevYdq3YseDyDAhAygfKfKB8RSHOpFM11dUNjkotqswSKqSWFk1y2OEbg111A2PBrNpVx3UsyU4ez6QbBcaCtZkCG/Djk/0Nq2sYrEvbblu5F6MD3XsBrAs8f/7InqirG8zx4aYBtcX+H7fALXAL3ALHWeLLz2UsZ3MVzqF9AP8HvhlcMbOYSC0AAAAASUVORK5CYII=",
      "red-fade-dark": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACWElEQVRYhe2UzWsTURTFz518zCSZSVMxtdWQUBDcSiTS4qaLICrqP6B7Bd24cKP/gyuxiPsuXOnGiBQEXdRFoQRKQdwEYjDNQtIkZmYyyVwXyWgymUw+yHSVAwkz9713f+e8eTwwM5gZ2avpDev5NH60deXyxov7d/biUbl60lRjz99+3Hz3Ze8bPJbw+Pq1XDwqA0BsKRzC09tbOa+hACBcOLMU6y+kzi7Hfq6uln+l09uegn0CDRU7x8fnWgcHD78T8WEy+cET8LgJRrF48ysRf04kSp8ymZeeg6VsduBdLZXO/97ff/RGFPXX6+vvPQNru7vdCYoCALA+iNlqBU8KhbvPiPhJJFKYOxgAIIogvw8AICWTAwYAQG82U/eI+AYRbwYCxvzAug6zqSKwsoKOqgIAuDdkP5Kddtt/kYjjRIwJ5HcbpFAIbBgwKhW0+ury2hp8soxIOIzG0RHIMAbMSERsAAiIoq5pmuTU2zUxqyrQbnebCgLI3/X5p1JBIpNBKZ9HxzD+7YI9qq7rIhExOeyCO7ivGZsmuGeCzQ7yOztDILKtHRjrGVAUpTYWPHy1/K+RQ23U9+9Xo9FQJEnSxl4gdhD3/hjuCd2kaZo0Fmx1d2tsmXDaBUvBYLDFzMTMBIw51S4+RhqwP1sguxwTD8x0iep0uAiAIAim2ZfOSY6JnVhuSam35ocLaCKwmxknU7kpgFOD7ZIUpfqqVluedf3U4AczpJsZ7JPl+q16PToP4ETgS3NKNzE45SHQ0vibawFegBfgBXiE/IfFMsrV+kAxcQrgv2BEIMc8VIzqAAAAAElFTkSuQmCC",
      "blue-fade-dark": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAC0klEQVRYhe2Uu08UURTGvzM77A6wu+waUVEQLUwsjUSDscFoiBr0H8DCCk2ksbDRxMpY2hlDrLWwURvZxsZHMGJMSNRoYoGCumqCCzvAvI/F7B1mhtlxMLtUe5J93DNn5vd959y5YGYwM04cPjgo/m/Gh4YGDgzeOndmqjufrSyurBauPSgdefRs6hWaHNL48NHJ7nwWAApdHe24MjI02WwoAEi7tnQV/In+rcVCz8v58sD0jztNBackWpcsG/b2t6p+kUqfeHfp/ZNmgOWoJDEAIjAYc6vGKbr3nHthft8B6+H06PB4I8BSVJIJOF5UXAG1mF/Wdr75uXApc+OuvvfmxOOmgAHg6R8NTEBedkvEQAzbSc8uLJ6lC1e58/zl2f8Fx7QayEgSUjViX7YdX9UlnwRgxTD6aWSUUVmAXK1Y5sxUW1Jw3VYzA7rtYMVmbFPasGrZYXkAxCwYlm3J1LePqdDNSBCRjgGACFBkgqkDvzQT0AwP0pPPItueQkexEx8+qjCJABDc7QhQWmFYJjLpNl3TNCWxY8B1rFmAxa4BiQiyJAFE+K0u49CeXsx8+QbTsgFmDwqqqQZD1/UMETERretCJFiU+asdZliOA4BhsYP7r2cCFSxmz2IPBM8HISCXyy0B9Vrt3Rs1LgLVCtiXgeeYg4pDoapqTlEUrW6rKaTaWzODxbOFSQH1In5/aZqmRO9q/73ky9W+KVAYFAhGuMsAgHQ6bTAzMbuzqLur3cf5cSLnU0IUuOKtee1VE6BwxB4grvNQE8XcKSyJvVpJkhzbcVJxpiLBnkYm+KfNCO94rxAAgec+R7pLDBZGyNfVtTOK1tXxi1JiYCyYyA8KX3R/ckqmsjRxu7hRYCw4zGHfiq+PbdhdcjAL1y4yK6eq1bHT+UYAY8FMNacn9zfEXXLwsf6mAUXUPTJb4Ba4BW6B/xXyu7kyypVqINm7CeC/dmFnE+0zAOgAAAAASUVORK5CYII="
    };
  }
});

// src/utils/semver.js
var semver;
var init_semver = __esm({
  "src/utils/semver.js"() {
    semver = {
      parse: (versionString) => {
        const [major, minor, patch] = versionString.split(".").map(Number);
        return { major, minor, patch };
      },
      gt: (v1, v2) => {
        const ver1 = semver.parse(v1);
        const ver2 = semver.parse(v2);
        if (ver1.major > ver2.major) return true;
        if (ver1.major < ver2.major) return false;
        if (ver1.minor > ver2.minor) return true;
        if (ver1.minor < ver2.minor) return false;
        return ver1.patch > ver2.patch;
      }
    };
  }
});

// src/resources/constants.js
var PIXEL_BANNER_PLUS;
var init_constants = __esm({
  "src/resources/constants.js"() {
    PIXEL_BANNER_PLUS = {
      API_URL: "https://pixel-banner.online/",
      // API_URL: 'http://localhost:3000/',
      ENDPOINTS: {
        PING: "ping",
        VERIFY: "verify",
        TEXT_TO_IMAGE_MODELS: "text-to-image-models",
        UPLOAD_TEMP_IMAGE: "/upload-temp-image",
        GENERATE: "generatev2",
        GENERATE_BANNER_IDEA: "generate-banner-idea",
        GENERATE_BANNER_IDEA_FROM_SEED: "generate-banner-idea-from-seed",
        REWRITE_BANNER_IDEA: "rewrite-banner-idea",
        HISTORY: "history",
        HISTORY_COUNT: "history/count",
        HISTORY_PAGE: "history/page",
        HISTORY_DELETE: "history/image",
        STORE_CATEGORIES: "store-categories",
        STORE_CATEGORY_IMAGES: "store-category-images",
        STORE_IMAGE_BY_ID: "store-image-by-id",
        STORE_IMAGE_SEARCH: "store-search",
        SIGNUP: "signup",
        BANNER_VOTES_STATS: "api/banner-votes/:id/stats",
        BANNER_VOTES_USER_VOTE: "api/banner-votes/:id/user-vote",
        BANNER_VOTES_UPVOTE: "api/banner-votes/:id/upvote",
        BANNER_VOTES_DOWNVOTE: "api/banner-votes/:id/downvote",
        INFO: "api/pixel-banner-info",
        DAILY_GAME: "games/daily-embed",
        BANNER_ICON_CATEGORIES: "api/icon-categories",
        BANNER_ICONS: "api/banner-icons",
        BANNER_ICONS_SEARCH: "api/banner-icons/search",
        BANNER_ICONS_ID: "api/banner-icons/:id"
      },
      SHOP_URL: "https://ko-fi.com/s/7ce609ff2c",
      DONATE_URL: "https://ko-fi.com/jparkerweb",
      BANNER_ICON_KEY: "pixel-banner-icons"
    };
  }
});

// src/modal/modals/releaseNotesModal.js
var import_obsidian7, ReleaseNotesModal;
var init_releaseNotesModal = __esm({
  "src/modal/modals/releaseNotesModal.js"() {
    import_obsidian7 = require("obsidian");
    ReleaseNotesModal = class extends import_obsidian7.Modal {
      constructor(app, version, releaseNotes2) {
        super(app);
        this.version = version;
        this.releaseNotes = releaseNotes2;
      }
      onOpen() {
        const { contentEl } = this;
        contentEl.empty();
        this.modalEl.addClass("pixel-banner-release-notes-modal");
        this.addStyles();
        contentEl.createEl("h2", { text: `Welcome to \u{1F6A9} Pixel Banner v${this.version}` });
        contentEl.createEl("p", {
          text: "After each update you'll be prompted with the release notes. You can disable this in the plugin settings General tab.",
          cls: "release-notes-instructions"
        });
        const promotionalLinks = contentEl.createEl("div", { cls: "promotional-links" });
        const equilllabsLink = promotionalLinks.createEl("a", {
          href: "https://www.equilllabs.com",
          target: "equilllabs"
        });
        equilllabsLink.createEl("img", {
          attr: {
            height: "36",
            src: "https://raw.githubusercontent.com/jparkerweb/pixel-banner/refs/heads/main/img/equilllabs.png?raw=true",
            alt: "eQuill Labs"
          }
        });
        const discordLink = promotionalLinks.createEl("a", {
          href: "https://discord.gg/sp8AQQhMJ7",
          target: "discord"
        });
        discordLink.createEl("img", {
          attr: {
            height: "36",
            src: "https://raw.githubusercontent.com/jparkerweb/pixel-banner/refs/heads/main/img/discord.png?raw=true",
            alt: "Discord"
          }
        });
        const kofiLink = promotionalLinks.createEl("a", {
          href: "https://ko-fi.com/Z8Z212UMBI",
          target: "kofi"
        });
        kofiLink.createEl("img", {
          attr: {
            height: "36",
            src: "https://raw.githubusercontent.com/jparkerweb/pixel-banner/refs/heads/main/img/support.png?raw=true",
            alt: "Buy Me a Coffee at ko-fi.com"
          }
        });
        const notesContainer = contentEl.createDiv("release-notes-container");
        notesContainer.innerHTML = this.releaseNotes;
        contentEl.createEl("div", { cls: "release-notes-spacer" });
        new import_obsidian7.Setting(contentEl).addButton((btn) => btn.setButtonText("Close").onClick(() => this.close()));
        const modalEl = this.modalEl;
        modalEl.style.position = "absolute";
        modalEl.style.left = `${modalEl.getBoundingClientRect().left}px`;
        modalEl.style.top = `${modalEl.getBoundingClientRect().top}px`;
      }
      addStyles() {
        const styleEl = document.createElement("style");
        styleEl.id = "pixel-banner-release-notes-styles";
        const existingStyle = document.getElementById(styleEl.id);
        if (existingStyle) {
          existingStyle.remove();
        }
        styleEl.textContent = `
            .pixel-banner-release-notes-modal {
                max-width: 600px;
                width: 100%;
                top: 50% !important;
                left: 50% !important;
                transform: translate(-50%, -50%);
            }
            
            .promotional-links {
                display: flex;
                flex-direction: row;
                justify-content: space-around;
                margin: 15px 0;
            }
            
            .promotional-links img {
                border: 0;
                height: 36px;
                transition: transform 0.2s ease;
            }
            
            .promotional-links a:hover img {
                transform: scale(1.1);
            }
            
            .release-notes-instructions {
                font-size: 0.75em;
                font-weight: 300;
                letter-spacing: 2px;
                text-align: center;
                margin: 10px 0;
            }

            .release-notes-container {
                max-height: 400px;
                overflow-y: auto;
                padding: 10px;
                margin: 10px 0;
                border-radius: 5px;
                background-color: var(--background-secondary);
            }

            .release-notes-container img {
                max-width: 100%;
            }

            .release-notes-section {
                margin: 10px 0;
            }

            .release-notes-section h4 {
                margin: 15px 0 5px 0;
                color: var(--text-accent-hover);
            }

            .release-notes-container > ul {
                padding-left: 25px;
            }
            
            .release-notes-container ul:not(:last-of-type) {
                padding-bottom: 20px;
            }

            .release-notes-section ul {
                margin: 0;
                padding-left: 20px;
            }

            .release-notes-container li,
            .release-notes-section li {
                margin: 5px 0;
            }

            .release-notes-spacer {
                margin: 10px 0;
                height: 20px;
            }
        `;
        document.head.appendChild(styleEl);
      }
      onClose() {
        const { contentEl } = this;
        contentEl.empty();
        const styleEl = document.getElementById("pixel-banner-release-notes-styles");
        if (styleEl) {
          styleEl.remove();
        }
      }
    };
  }
});

// src/modal/modals/imageViewModal.js
var import_obsidian8, ImageViewModal;
var init_imageViewModal = __esm({
  "src/modal/modals/imageViewModal.js"() {
    import_obsidian8 = require("obsidian");
    ImageViewModal = class extends import_obsidian8.Modal {
      constructor(app, imageUrl, bannerPath = "") {
        super(app);
        this.imageUrl = imageUrl;
        this.bannerPath = bannerPath;
      }
      onOpen() {
        this.modalEl.addClass("pixel-banner-image-modal");
        this.addStyles();
        const { contentEl } = this;
        contentEl.empty();
        contentEl.addClass("pixel-banner-image-view-modal");
        const actualUrl = this.getActualUrl(this.imageUrl);
        const imageContainer = contentEl.createDiv("image-container");
        const isVideo = this.isVideoUrl(actualUrl);
        let mediaElement;
        if (isVideo) {
          mediaElement = imageContainer.createEl("video", {
            attr: {
              src: actualUrl,
              controls: true,
              autoplay: false,
              preload: "metadata"
            }
          });
        } else {
          mediaElement = imageContainer.createEl("img", {
            attr: {
              src: actualUrl,
              alt: "Banner Image"
            }
          });
        }
        if (this.bannerPath) {
          const pathContainer = contentEl.createEl("div", { cls: "path-container" });
          const pathDisplay = pathContainer.createEl("div", {
            text: this.bannerPath,
            cls: "banner-path"
          });
          const copyButton = pathContainer.createEl("button", {
            text: "Copy Path",
            cls: "mod-cta"
          });
          copyButton.addEventListener("click", () => {
            navigator.clipboard.writeText(this.bannerPath).then(() => {
              const originalText = copyButton.textContent;
              copyButton.textContent = "Copied!";
              setTimeout(() => {
                copyButton.textContent = originalText;
              }, 2e3);
            });
          });
        }
        const closeButton = contentEl.createEl("button", {
          text: "Close",
          cls: "mod-cta close-button"
        });
        closeButton.addEventListener("click", () => this.close());
        this.scope.register([], "Escape", () => this.close());
        const modalEl = this.modalEl;
        modalEl.style.position = "absolute";
        modalEl.style.left = `${modalEl.getBoundingClientRect().left}px`;
        modalEl.style.top = `${modalEl.getBoundingClientRect().top}px`;
      }
      addStyles() {
        const styleEl = document.createElement("style");
        styleEl.id = "pixel-banner-image-view-styles";
        const existingStyle = document.getElementById(styleEl.id);
        if (existingStyle) {
          existingStyle.remove();
        }
        styleEl.textContent = `
            .pixel-banner-image-modal {
                max-width: 80vw;
                max-height: 90vh;
                width: 100%;
                height: auto;
                top: 50% !important;
                left: 50% !important;
                transform: translate(-50%, -50%);
            }

            .pixel-banner-image-view-modal {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                padding: 20px;
            }

            .pixel-banner-image-view-modal img {
                max-width: 100%;
                max-height: 90vh;
                object-fit: contain;
                border-radius: 8px;
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
            }

            .pixel-banner-image-view-modal button {
                padding: 8px 16px;
                border-radius: 4px;
                cursor: pointer;
                transition: background-color 0.2s ease-in-out;
            }

            .pixel-banner-image-view-modal .image-container {
                display: flex;
                justify-content: center;
                align-items: center;
                margin-bottom: 10px;
            }

            .pixel-banner-image-view-modal .image-container img,
            .pixel-banner-image-view-modal .image-container video {
                display: flex;
                justify-content: center;
                align-items: center;
                width: 100%;
                height: 100%;
                max-width: 100%;
                max-height: 90vh;
                object-fit: contain;
            }

            .pixel-banner-image-view-modal .path-container {
                display: flex;
                align-items: center;
                justify-content: space-between;
                margin-top: 10px;
                margin-bottom: 10px;
            }

            .pixel-banner-image-view-modal .banner-path {
                flex-grow: 1;
                margin-right: 10px;
                font-family: var(--font-monospace);
                font-size: 0.9em;
                overflow-x: auto;
                padding: 4px;
                background-color: var(--background-secondary);
                border-radius: 4px;
                word-break: break-word;
            }

            .pixel-banner-image-view-modal .close-button {
                margin-top: 10px;
                width: 150px;
            }
        `;
        document.head.appendChild(styleEl);
      }
      onClose() {
        const { contentEl } = this;
        contentEl.empty();
        const styleEl = document.getElementById("pixel-banner-image-view-styles");
        if (styleEl) {
          styleEl.remove();
        }
      }
      isVideoUrl(url) {
        if (!url) return false;
        const videoExtensions = [".mp4", ".mov", ".webm", ".ogg"];
        const pathWithoutQuery = url.split("?")[0].toLowerCase();
        return videoExtensions.some((ext) => pathWithoutQuery.endsWith(ext));
      }
      getActualUrl(imageUrl) {
        if (typeof imageUrl === "object" && imageUrl !== null) {
          return imageUrl.url || imageUrl.src || "";
        }
        return imageUrl;
      }
    };
  }
});

// src/modal/modals/folderSelectionModal.js
var folderSelectionModal_exports = {};
__export(folderSelectionModal_exports, {
  FolderSelectionModal: () => FolderSelectionModal
});
var import_obsidian9, FolderSelectionModal;
var init_folderSelectionModal = __esm({
  "src/modal/modals/folderSelectionModal.js"() {
    import_obsidian9 = require("obsidian");
    FolderSelectionModal = class extends import_obsidian9.FuzzySuggestModal {
      constructor(app, defaultFolder, onChoose) {
        super(app);
        this.defaultFolder = defaultFolder;
        this.onChoose = onChoose;
        this.modalEl.addClass("pixel-banner-folder-select-modal");
        const titleDiv = document.createElement("p");
        titleDiv.innerHTML = "\u{1F4BE} Choose a <strong>Folder</strong> to save the selected Banner in your vault";
        titleDiv.style.margin = "10px 0";
        titleDiv.style.padding = "20px 20px 0";
        titleDiv.style.color = "var(--text-accent)";
        titleDiv.style.borderTop = "1px dashed var(--modal-border-color)";
        this.modalEl.appendChild(titleDiv);
        const descriptionDiv = document.createElement("p");
        descriptionDiv.innerHTML = "If you set a default value in settings it will be pre-filled above.<br>Select any folder in your vault to continue.";
        descriptionDiv.style.margin = "0 0 20px 0";
        descriptionDiv.style.padding = "0 20px";
        descriptionDiv.style.color = "var(--text-muted)";
        descriptionDiv.style.fontSize = ".9em";
        this.modalEl.appendChild(descriptionDiv);
        this.setPlaceholder("Select or type folder path to save Banner Image");
        this.addStyle();
      }
      addStyle() {
        const style = document.createElement("style");
        style.textContent = `
            .prompt.pixel-banner-folder-select-modal {
                top: unset !important;
                padding: 20px !important;
            }
            .pixel-banner-folder-select-modal .prompt {
                position: fixed !important;
                top: 50% !important;
                left: 50% !important;
                transform: translate(-50%, -50%) !important;
            }
        `;
        document.head.appendChild(style);
        this.style = style;
      }
      onClose() {
        if (this.style) {
          this.style.remove();
        }
      }
      getItems() {
        const folderPaths = this.app.vault.getAllLoadedFiles().filter((file) => file.children).map((folder) => folder.path);
        if (!folderPaths.includes(this.defaultFolder)) {
          folderPaths.unshift(this.defaultFolder);
        }
        return folderPaths;
      }
      getItemText(item) {
        return item;
      }
      onChooseItem(item) {
        this.onChoose(item);
      }
      onOpen() {
        super.onOpen();
        const inputEl = this.inputEl;
        inputEl.addClass("prompt-input");
        inputEl.value = this.defaultFolder;
        inputEl.focus();
        inputEl.select();
        this.updateSuggestions();
      }
    };
  }
});

// src/modal/modals/saveImageModal.js
var saveImageModal_exports = {};
__export(saveImageModal_exports, {
  SaveImageModal: () => SaveImageModal
});
var import_obsidian10, SaveImageModal;
var init_saveImageModal = __esm({
  "src/modal/modals/saveImageModal.js"() {
    import_obsidian10 = require("obsidian");
    SaveImageModal = class extends import_obsidian10.Modal {
      constructor(app, suggestedName, onSubmit) {
        super(app);
        this.suggestedName = suggestedName;
        this.onSubmit = onSubmit;
        this.useAsBanner = true;
      }
      onOpen() {
        const { contentEl } = this;
        contentEl.empty();
        contentEl.createEl("h2", { text: "Save Image", cls: "margin-top-0" });
        contentEl.createEl("p", { text: "Enter a name for the media file." });
        const fileNameSetting = new import_obsidian10.Setting(contentEl).setName("File name").addText((text) => {
          this.textInput = text;
          text.setValue(this.suggestedName).onChange((value) => {
            this.suggestedName = value;
          }).inputEl.style.width = "100%";
          text.inputEl.addEventListener("keydown", (e) => {
            if (e.key === "Enter" && this.suggestedName) {
              this.onSubmit(this.suggestedName, this.useAsBanner);
              this.close();
            }
          });
        });
        new import_obsidian10.Setting(contentEl).setName("Use Saved Image as Banner").setDesc("If disabled, the saved image will be saved to your vault, but not applied to the current note.").addToggle((toggle) => {
          toggle.setValue(this.useAsBanner).onChange((value) => {
            this.useAsBanner = value;
          });
        });
        const buttonContainer = contentEl.createDiv();
        buttonContainer.style.display = "flex";
        buttonContainer.style.justifyContent = "flex-end";
        buttonContainer.style.gap = "8px";
        buttonContainer.style.marginTop = "1em";
        const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
        const saveButton = buttonContainer.createEl("button", {
          text: "Save",
          cls: "mod-cta"
        });
        cancelButton.addEventListener("click", () => this.close());
        saveButton.addEventListener("click", () => {
          if (this.suggestedName) {
            this.onSubmit(this.suggestedName, this.useAsBanner);
            this.close();
          } else {
            new import_obsidian10.Notice("Please enter a file name");
          }
        });
        const modalEl = this.modalEl;
        modalEl.style.position = "absolute";
        modalEl.style.left = `${modalEl.getBoundingClientRect().left}px`;
        modalEl.style.top = `${modalEl.getBoundingClientRect().top}px`;
      }
      onClose() {
        const { contentEl } = this;
        contentEl.empty();
      }
    };
  }
});

// src/modal/modals/pinChoiceModal.js
var import_obsidian11, PinChoiceModal;
var init_pinChoiceModal = __esm({
  "src/modal/modals/pinChoiceModal.js"() {
    import_obsidian11 = require("obsidian");
    PinChoiceModal = class extends import_obsidian11.Modal {
      constructor(app, onChoice) {
        super(app);
        this.onChoice = onChoice;
      }
      onOpen() {
        const { contentEl } = this;
        contentEl.empty();
        contentEl.createEl("h2", { text: "Pin Image", cls: "margin-top-0" });
        contentEl.createEl("p", {
          text: "How would you like to pin this image?",
          cls: "setting-item-description"
        });
        const localOptionContainer = contentEl.createDiv({
          cls: "pin-choice-option"
        });
        localOptionContainer.style.cssText = `
            border: 1px solid var(--background-modifier-border);
            border-radius: 6px;
            padding: 1em;
            margin: 0.5em 0;
            cursor: pointer;
            transition: background-color 0.2s ease;
        `;
        const localTitle = localOptionContainer.createEl("h3", {
          text: "\u{1F4BE} Save Image Locally",
          cls: "margin-top-0"
        });
        localTitle.style.marginBottom = "0.5em";
        localOptionContainer.createEl("p", {
          text: "Download and save the image to your vault. The image will be stored locally and referenced by file path.",
          cls: "setting-item-description"
        });
        localOptionContainer.createEl("p", {
          text: "\u2713 Image remains available even if original source is removed",
          cls: "setting-item-description"
        });
        localOptionContainer.createEl("p", {
          text: "\u2713 Works offline",
          cls: "setting-item-description"
        });
        const urlOptionContainer = contentEl.createDiv({
          cls: "pin-choice-option"
        });
        urlOptionContainer.style.cssText = `
            border: 1px solid var(--background-modifier-border);
            border-radius: 6px;
            padding: 1em;
            margin: 0.5em 0;
            cursor: pointer;
            transition: background-color 0.2s ease;
        `;
        const urlTitle = urlOptionContainer.createEl("h3", {
          text: "\u{1F517} Pin Image URL",
          cls: "margin-top-0"
        });
        urlTitle.style.marginBottom = "0.5em";
        urlOptionContainer.createEl("p", {
          text: "Save only the image URL to frontmatter. The image will be loaded from the original source each time.",
          cls: "setting-item-description"
        });
        urlOptionContainer.createEl("p", {
          text: "\u2713 No storage space used in vault",
          cls: "setting-item-description"
        });
        urlOptionContainer.createEl("p", {
          text: "\u26A0 Requires internet connection to display",
          cls: "setting-item-description"
        });
        const addHoverEffect = (element) => {
          element.addEventListener("mouseenter", () => {
            element.style.backgroundColor = "var(--background-modifier-hover)";
          });
          element.addEventListener("mouseleave", () => {
            element.style.backgroundColor = "";
          });
        };
        addHoverEffect(localOptionContainer);
        addHoverEffect(urlOptionContainer);
        localOptionContainer.addEventListener("click", () => {
          this.onChoice("local");
          this.close();
        });
        urlOptionContainer.addEventListener("click", () => {
          this.onChoice("url");
          this.close();
        });
        const buttonContainer = contentEl.createDiv();
        buttonContainer.style.cssText = `
            display: flex;
            justify-content: flex-end;
            gap: 8px;
            margin-top: 1em;
        `;
        const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
        cancelButton.addEventListener("click", () => {
          this.onChoice(null);
          this.close();
        });
        const modalEl = this.modalEl;
        modalEl.style.position = "absolute";
        modalEl.style.left = `${modalEl.getBoundingClientRect().left}px`;
        modalEl.style.top = `${modalEl.getBoundingClientRect().top}px`;
      }
      onClose() {
        const { contentEl } = this;
        contentEl.empty();
      }
    };
  }
});

// src/utils/frontmatterUtils.js
var frontmatterUtils_exports = {};
__export(frontmatterUtils_exports, {
  getFrontmatterValue: () => getFrontmatterValue,
  getValueWithZeroCheck: () => getValueWithZeroCheck,
  updateNoteFrontmatter: () => updateNoteFrontmatter,
  updateNoteFrontmatterWithUrl: () => updateNoteFrontmatterWithUrl
});
function getFrontmatterValue(frontmatter, fieldNames) {
  if (!frontmatter || !fieldNames) return null;
  const fields = Array.isArray(fieldNames) ? fieldNames : [fieldNames];
  const processedFields = fields.flatMap((field) => {
    if (typeof field === "string" && field.includes(",")) {
      return field.split(",").map((f) => f.trim()).filter((f) => f.length > 0);
    }
    return field;
  });
  for (const field of processedFields) {
    if (frontmatter.hasOwnProperty(field)) {
      const value = frontmatter[field];
      if (value === 0) {
        return 0;
      }
      if (typeof value === "string" && (value.toLowerCase() === "true" || value.toLowerCase() === "false")) {
        return value.toLowerCase() === "true";
      }
      return value;
    }
  }
  return null;
}
function getValueWithZeroCheck(values) {
  if (!Array.isArray(values)) {
    console.warn("getValueWithZeroCheck expects an array of values");
    return null;
  }
  for (const value of values) {
    if (value === 0) return 0;
    if (value !== null && value !== void 0) return value;
  }
  return values[values.length - 1];
}
async function updateNoteFrontmatter(imagePath, plugin, usedField = null) {
  const activeFile = plugin.app.workspace.getActiveFile();
  if (!activeFile) return;
  let imageReference = imagePath;
  if (plugin.settings.useShortPath) {
    const imageFile = plugin.app.vault.getAbstractFileByPath(imagePath);
    if (imageFile) {
      const allFiles = plugin.app.vault.getFiles();
      const matchingFiles = allFiles.filter((f) => f.name === imageFile.name);
      imageReference = matchingFiles.length === 1 ? imageFile.name : imageFile.path;
    }
  }
  const bannerField = usedField || (Array.isArray(plugin.settings.customBannerField) && plugin.settings.customBannerField.length > 0 ? plugin.settings.customBannerField[0] : "banner");
  const format = plugin.settings.imagePropertyFormat;
  let bannerValue;
  if (format === "image") {
    bannerValue = imageReference;
  } else if (format === "[[image]]") {
    bannerValue = `[[${imageReference}]]`;
  } else {
    bannerValue = `![[${imageReference}]]`;
  }
  await plugin.app.fileManager.processFrontMatter(activeFile, (frontmatter) => {
    if (Array.isArray(plugin.settings.customBannerField)) {
      for (const field of plugin.settings.customBannerField) {
        if (field !== bannerField && field in frontmatter) {
          delete frontmatter[field];
        }
      }
    }
    frontmatter[bannerField] = bannerValue;
  });
  if (plugin.settings.useShortPath && imageReference === imagePath) {
    new import_obsidian12.Notice("Banner image pinned (full path used due to duplicate filenames)");
  } else {
    new import_obsidian12.Notice("Banner image pinned");
  }
}
async function updateNoteFrontmatterWithUrl(imageUrl, plugin, usedField = null) {
  const activeFile = plugin.app.workspace.getActiveFile();
  if (!activeFile) return;
  const bannerField = usedField || (Array.isArray(plugin.settings.customBannerField) && plugin.settings.customBannerField.length > 0 ? plugin.settings.customBannerField[0] : "banner");
  await plugin.app.fileManager.processFrontMatter(activeFile, (frontmatter) => {
    if (Array.isArray(plugin.settings.customBannerField)) {
      for (const field of plugin.settings.customBannerField) {
        if (field !== bannerField && field in frontmatter) {
          delete frontmatter[field];
        }
      }
    }
    frontmatter[bannerField] = imageUrl;
  });
  new import_obsidian12.Notice("Banner image URL pinned");
}
var import_obsidian12;
var init_frontmatterUtils = __esm({
  "src/utils/frontmatterUtils.js"() {
    import_obsidian12 = require("obsidian");
  }
});

// src/utils/handlePinIconClick.js
async function handlePinIconClick(imageUrl, plugin, usedField = null, suggestedFilename = null, showChoiceModal = true) {
  let choice = "local";
  if (showChoiceModal) {
    choice = await new Promise((resolve) => {
      const modal = new PinChoiceModal(plugin.app, (result) => {
        resolve(result);
      });
      modal.open();
    });
    if (!choice) {
      return null;
    }
  }
  if (choice === "url") {
    await updateNoteFrontmatterWithUrl(imageUrl, plugin, usedField);
    hidePinIcon();
    return imageUrl;
  } else {
    const imageBlob = await fetchImage(imageUrl);
    const { file, useAsBanner } = await saveImageLocally(imageBlob, plugin, suggestedFilename);
    const finalPath = await waitForFileRename(file, plugin);
    if (!finalPath) {
      console.error("\u274C Failed to resolve valid file path");
      new Notice("Failed to save image - file not found");
      return null;
    }
    if (useAsBanner) {
      await updateNoteFrontmatter(finalPath, plugin, usedField);
      hidePinIcon();
    }
    return finalPath;
  }
}
async function fetchImage(url) {
  const response = await fetch(url);
  if (!response.ok) throw new Error("Image download failed");
  return await response.arrayBuffer();
}
async function saveImageLocally(arrayBuffer, plugin, suggestedFilename = null) {
  const format = detectImageFormat(arrayBuffer);
  const vault = plugin.app.vault;
  const defaultFolderPath = plugin.settings.pinnedImageFolder;
  const folderPath = await new Promise((resolve) => {
    const modal = new FolderSelectionModal(plugin.app, defaultFolderPath, (result) => {
      resolve(result);
    });
    modal.open();
  });
  if (!folderPath) {
    throw new Error("No folder selected");
  }
  if (!await vault.adapter.exists(folderPath)) {
    await vault.createFolder(folderPath);
  }
  const suggestedName = (suggestedFilename == null ? void 0 : suggestedFilename.toLowerCase()) || plugin.settings.pinnedImageFilename;
  const userInput = await new Promise((resolve) => {
    const modal = new SaveImageModal(plugin.app, suggestedName, (name, useAsBanner) => {
      resolve({ name, useAsBanner });
    });
    modal.open();
  });
  if (!userInput) {
    throw new Error("No filename provided");
  }
  let baseName = userInput.name.replace(/[^a-zA-Z0-9-_ ]/g, "").trim();
  if (!baseName) baseName = "banner";
  if (!baseName.toLowerCase().endsWith(`.${format}`)) baseName += `.${format}`;
  let fileName = baseName;
  let counter = 1;
  while (await vault.adapter.exists(`${folderPath}/${fileName}`)) {
    const nameWithoutExt = baseName.slice(0, -4);
    fileName = `${nameWithoutExt}-${counter}.${format}`;
    counter++;
  }
  const filePath = `${folderPath}/${fileName}`;
  const savedFile = await vault.createBinary(filePath, arrayBuffer);
  return {
    initialPath: filePath,
    file: savedFile,
    useAsBanner: userInput.useAsBanner
  };
}
function detectImageFormat(arrayBuffer) {
  const uint8arr = new Uint8Array(arrayBuffer);
  const signatures = {
    jpeg: [255, 216, 255],
    png: [137, 80, 78, 71],
    gif: [71, 73, 70, 56],
    webp: [82, 73, 70, 70]
  };
  for (const [format, signature] of Object.entries(signatures)) {
    if (signature.every((byte, i) => uint8arr[i] === byte)) {
      return format === "jpeg" ? "jpg" : format;
    }
  }
  return "jpg";
}
function hidePinIcon() {
  const pinIcon = document.querySelector(".pin-icon");
  if (pinIcon) pinIcon.style.display = "none";
}
async function waitForFileRename(file, plugin) {
  return new Promise((resolve) => {
    const initialPath = file.path;
    let timeoutId;
    let renamedPath = null;
    const validatePath = async (path) => {
      if (!path) return false;
      return await plugin.app.vault.adapter.exists(path);
    };
    const handleRename = async (theFile) => {
      if (theFile == null ? void 0 : theFile.path) {
        renamedPath = theFile == null ? void 0 : theFile.path;
      }
    };
    const cleanup = () => {
      plugin.app.vault.off("rename", handleRename);
    };
    plugin.app.vault.on("rename", handleRename);
    timeoutId = setTimeout(async () => {
      cleanup();
      if (renamedPath) {
        const exists = await validatePath(renamedPath);
        if (exists) {
          return resolve(renamedPath);
        }
      }
      const initialExists = await validatePath(initialPath);
      if (initialExists) {
        return resolve(initialPath);
      }
      resolve(null);
    }, 100);
  });
}
var init_handlePinIconClick = __esm({
  "src/utils/handlePinIconClick.js"() {
    init_folderSelectionModal();
    init_saveImageModal();
    init_pinChoiceModal();
    init_frontmatterUtils();
  }
});

// src/utils/fractionTextDisplay.js
function decimalToFractionString(num) {
  const fractionMap = {
    0.25: "\xBC",
    0.5: "\xBD",
    0.75: "\xBE"
  };
  const whole = Math.floor(num);
  const decimal = +(num - whole).toFixed(2);
  let fraction = fractionMap[decimal] || "";
  if (whole === 0 && fraction) return fraction;
  if (whole === 0 && !fraction) return num.toString();
  return fraction ? `${whole} ${fraction}` : `${whole}`;
}
var init_fractionTextDisplay = __esm({
  "src/utils/fractionTextDisplay.js"() {
  }
});

// src/utils/downloadHistory.js
var DownloadHistory;
var init_downloadHistory = __esm({
  "src/utils/downloadHistory.js"() {
    DownloadHistory = class {
      constructor() {
        this.maxHistory = 50;
        this.loadHistory();
      }
      loadHistory() {
        const saved = localStorage.getItem("pixel-banner-download-history");
        this.history = saved ? JSON.parse(saved) : [];
      }
      saveHistory() {
        localStorage.setItem("pixel-banner-download-history", JSON.stringify(this.history));
      }
      addImage(imageId) {
        if (!this.history.includes(imageId)) {
          this.history.unshift(imageId);
          if (this.history.length > this.maxHistory) {
            this.history.pop();
          }
        }
        this.saveHistory();
      }
      hasImage(imageId) {
        return this.history.includes(imageId);
      }
    };
  }
});

// src/modal/modals/selectPixelBannerModal.js
var import_obsidian13, SelectPixelBannerModal;
var init_selectPixelBannerModal = __esm({
  "src/modal/modals/selectPixelBannerModal.js"() {
    import_obsidian13 = require("obsidian");
    init_modals();
    init_flags();
    init_semver();
    init_fractionTextDisplay();
    init_constants();
    SelectPixelBannerModal = class extends import_obsidian13.Modal {
      constructor(app, plugin) {
        super(app);
        this.plugin = plugin;
        this.isLoading = false;
        this.isVerifyingAPI = true;
      }
      async onOpen() {
        const { contentEl } = this;
        contentEl.empty();
        await this.initializeBasicUI();
        if (this.plugin.settings.pixelBannerPlusEnabled) {
          this.initializeAPIDependentSections().catch((error) => {
            console.error("Error initializing API-dependent sections:", error);
            this.updateAPIStatusUI(false);
          });
        }
      }
      // Create a loading spinner element
      createLoadingSpinner() {
        const spinner = document.createElement("div");
        spinner.classList.add("pixel-banner-section-spinner");
        spinner.innerHTML = `
            <div class="pixel-banner-spinner" style="
                width: 20px;
                height: 20px;
                border: 2px solid var(--background-modifier-border);
                border-top: 2px solid var(--text-accent);
                border-radius: 50%;
                animation: pixel-banner-spin 1s linear infinite;
            "></div>
        `;
        return spinner;
      }
      // Refresh the modal when Pixel Banner Plus enabled state changes
      async refreshModal() {
        this.contentEl.empty();
        await this.onOpen();
      }
      // Initialize the basic UI (non-API dependent)
      async initializeBasicUI() {
        var _a;
        const { contentEl } = this;
        const titleContainer = contentEl.createEl("h2", {
          cls: "pixel-banner-selector-title",
          attr: {
            style: `
                    display: flex;
                    align-items: center;
                    justify-content: flex-start;
                    margin-top: 5px;
                `
          }
        });
        const flagImg = titleContainer.createEl("img", {
          attr: {
            src: flags[this.plugin.settings.selectImageIconFlag] || flags["red"],
            alt: "Pixel Banner",
            style: `
                    width: 20px;
                    height: 25px;
                    vertical-align: middle;
                    margin: -5px 10px 0 20px;
                `
          }
        });
        titleContainer.appendChild(document.createTextNode("Pixel Banner"));
        const versionText = titleContainer.createEl("span", {
          text: `v${this.plugin.settings.lastVersion}`,
          attr: {
            style: `
                    font-size: 12px;
                    opacity: 0.7;
                    margin-left: 10px;
                    font-weight: normal;
                `
          }
        });
        const settingsButton = titleContainer.createEl("button", {
          cls: "pixel-banner-settings-button",
          attr: {
            style: `
                    margin-left: auto;
                    margin-right: 20px;
                    padding: 4px 10px;
                    // background: transparent;
                    border: none;
                    cursor: pointer;
                    font-size: 14px;
                    text-transform: uppercase;
                `
          }
        });
        settingsButton.innerHTML = "\u2699\uFE0F Plugin Settings";
        settingsButton.title = "Open Pixel Banner Plugin Settings";
        settingsButton.addEventListener("click", () => {
          this.close();
          const openSettings = async () => {
            await this.app.setting.open();
            await new Promise((resolve) => setTimeout(resolve, 300));
            const settingsTabs = document.querySelectorAll(".vertical-tab-header-group .vertical-tab-nav-item");
            for (const tab of settingsTabs) {
              if (tab.textContent.includes("Pixel Banner")) {
                tab.click();
                break;
              }
            }
          };
          openSettings();
        });
        const activeFile = this.app.workspace.getActiveFile();
        const hasBanner = activeFile ? this.plugin.hasBannerFrontmatter(activeFile) || ((_a = this.plugin.app.metadataCache.getFileCache(activeFile)) == null ? void 0 : _a.frontmatter) && this.plugin.settings.customBannerShuffleField.some(
          (field) => {
            var _a2, _b;
            return (_b = (_a2 = this.plugin.app.metadataCache.getFileCache(activeFile)) == null ? void 0 : _a2.frontmatter) == null ? void 0 : _b[field];
          }
        ) : false;
        const mainContainer = contentEl.createDiv({ cls: "pixel-banner-main-container" });
        const bannerSourceSection = mainContainer.createDiv({ cls: "pixel-banner-section" });
        bannerSourceSection.createEl("h3", {
          text: "Choose a Banner",
          cls: "pixel-banner-section-title",
          attr: {
            style: `
                    margin: 0;
                `
          }
        });
        const bannerSourceButtons = bannerSourceSection.createDiv({
          cls: "pixel-banner-source-buttons"
        });
        const vaultButton = bannerSourceButtons.createEl("button", {
          cls: "pixel-banner-source-button"
        });
        const vaultButtonContent = vaultButton.createDiv({ cls: "pixel-banner-button-content" });
        vaultButtonContent.createEl("span", { text: "\u{1F4BE}", cls: "pixel-banner-button-icon" });
        vaultButtonContent.createEl("div", { cls: "pixel-banner-button-text-container" }).createEl("span", {
          text: "Your Vault",
          cls: "pixel-banner-button-text"
        });
        vaultButton.addEventListener("click", () => {
          this.close();
          new ImageSelectionModal(
            this.app,
            this.plugin,
            async (file) => {
              const activeFile2 = this.app.workspace.getActiveFile();
              if (activeFile2) {
                await this.plugin.app.fileManager.processFrontMatter(activeFile2, (frontmatter) => {
                  const bannerField = this.plugin.settings.customBannerField[0];
                  const format = this.plugin.settings.imagePropertyFormat;
                  let bannerValue;
                  if (format === "image") {
                    bannerValue = file.path;
                  } else if (format === "[[image]]") {
                    bannerValue = `[[${file.path}]]`;
                  } else {
                    bannerValue = `![[${file.path}]]`;
                  }
                  frontmatter[bannerField] = bannerValue;
                });
                if (this.plugin.settings.openTargetingModalAfterSelectingBannerOrIcon) {
                  new TargetPositionModal(this.app, this.plugin).open();
                }
              }
            },
            this.plugin.settings.defaultSelectImagePath
          ).open();
        });
        const webAddressButton = bannerSourceButtons.createEl("button", {
          cls: "pixel-banner-source-button"
        });
        const webAddressButtonContent = webAddressButton.createDiv({ cls: "pixel-banner-button-content" });
        webAddressButtonContent.createEl("span", { text: "\u{1F310}", cls: "pixel-banner-button-icon" });
        webAddressButtonContent.createEl("div", { cls: "pixel-banner-button-text-container" }).createEl("span", {
          text: "URL",
          cls: "pixel-banner-button-text"
        });
        webAddressButton.addEventListener("click", () => {
          this.close();
          new WebAddressModal(this.app, this.plugin).open();
        });
        if (this.plugin.settings.pixelBannerPlusEnabled) {
          const aiButton = bannerSourceButtons.createEl("button", {
            cls: "pixel-banner-source-button pixel-banner-api-dependent",
            attr: {
              id: "pixel-banner-plus-ai-button",
              style: `
                        position: relative;
                    `
            }
          });
          const aiButtonContent = aiButton.createDiv({ cls: "pixel-banner-button-content" });
          aiButtonContent.createEl("span", { text: "\u2728", cls: "pixel-banner-button-icon" });
          aiButtonContent.createEl("div", { cls: "pixel-banner-button-text-container" }).createEl("span", {
            text: "AI Banner",
            cls: "pixel-banner-button-text"
          });
          const aiLoadingOverlay = aiButton.createDiv({
            cls: "pixel-banner-button-loading-overlay",
            attr: {
              style: `
                        position: absolute;
                        top: 0;
                        left: 0;
                        right: 0;
                        bottom: 0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        background-color: var(--background-primary);
                        opacity: 0.8;
                        z-index: 10;
                    `
            }
          });
          aiLoadingOverlay.appendChild(this.createLoadingSpinner());
          const storeButton = bannerSourceButtons.createEl("button", {
            cls: "pixel-banner-source-button pixel-banner-api-dependent",
            attr: {
              id: "pixel-banner-plus-store-button",
              style: `
                        position: relative;
                    `
            }
          });
          const storeButtonContent = storeButton.createDiv({ cls: "pixel-banner-button-content" });
          storeButtonContent.createEl("span", { text: "\u{1F3EA}", cls: "pixel-banner-button-icon" });
          storeButtonContent.createEl("div", { cls: "pixel-banner-button-text-container" }).createEl("span", {
            text: "Plus Collection",
            cls: "pixel-banner-button-text"
          });
          const storeLoadingOverlay = storeButton.createDiv({
            cls: "pixel-banner-button-loading-overlay",
            attr: {
              style: `
                        position: absolute;
                        top: 0;
                        left: 0;
                        right: 0;
                        bottom: 0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        background-color: var(--background-primary);
                        opacity: 0.8;
                        z-index: 10;
                    `
            }
          });
          storeLoadingOverlay.appendChild(this.createLoadingSpinner());
          storeButton.addEventListener("click", () => {
            this.close();
            new PixelBannerStoreModal(this.app, this.plugin).open();
          });
        }
        const customizationSection = mainContainer.createDiv({ cls: "pixel-banner-section" });
        customizationSection.createEl("h3", {
          text: "Customize Banner",
          cls: "pixel-banner-section-title",
          attr: {
            style: `
                    margin: 0;
                `
          }
        });
        const customizationOptions = customizationSection.createDiv({ cls: "pixel-banner-customization-options" });
        const bannerIconImageButton = customizationOptions.createEl("button", {
          cls: "pixel-banner-customize-button"
        });
        const bannerIconImageContent = bannerIconImageButton.createDiv({ cls: "pixel-banner-button-content" });
        bannerIconImageContent.createEl("span", { text: "\u2B50", cls: "pixel-banner-button-icon" });
        bannerIconImageContent.createEl("div", { cls: "pixel-banner-button-text-container" }).createEl("span", {
          text: "Icon Image",
          cls: "pixel-banner-button-text"
        });
        if (!hasBanner) {
          bannerIconImageButton.disabled = true;
          bannerIconImageButton.classList.add("pixel-banner-button-disabled");
          bannerIconImageButton.title = "You need to add a banner first";
        }
        bannerIconImageButton.addEventListener("click", () => {
          this.close();
          const onChooseBannerIconImage = async (filePath) => {
            if (!filePath) {
              return;
            }
            let pathString = filePath;
            if (typeof filePath === "object" && filePath.path) {
              pathString = filePath.path;
            } else if (typeof filePath !== "string") {
              return;
            }
            const activeFile2 = this.app.workspace.getActiveFile();
            if (!activeFile2) return;
            const file = this.app.vault.getAbstractFileByPath(pathString);
            if (typeof pathString === "string" && (pathString.startsWith("http://") || pathString.startsWith("https://"))) {
              this.app.fileManager.processFrontMatter(activeFile2, (fm) => {
                const iconImageField = Array.isArray(this.plugin.settings.customBannerIconImageField) ? this.plugin.settings.customBannerIconImageField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageField;
                fm[iconImageField] = pathString;
              });
              new TargetPositionModal(this.app, this.plugin).open();
              return;
            }
            const extensionPart = pathString.split(".").pop();
            const fileExtension = extensionPart ? extensionPart.toLowerCase() : "";
            if (fileExtension && fileExtension.match(/^(jpg|jpeg|png|gif|bmp|svg|webp|avif)$/)) {
              try {
                const imageUrl = await this.plugin.getVaultImageUrl(pathString);
                if (imageUrl) {
                  this.plugin.loadedImages.set(pathString, imageUrl);
                  const preloadImg = new Image();
                  preloadImg.src = imageUrl;
                }
              } catch (error) {
                console.error("Error preloading icon image:", error);
              }
            }
            this.app.fileManager.processFrontMatter(activeFile2, (fm) => {
              const iconImageField = Array.isArray(this.plugin.settings.customBannerIconImageField) ? this.plugin.settings.customBannerIconImageField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageField;
              const format = this.plugin.settings.imagePropertyFormat;
              let iconValue;
              if (format === "image") {
                iconValue = pathString;
              } else if (format === "[[image]]") {
                iconValue = `[[${pathString}]]`;
              } else {
                iconValue = `![[${pathString}]]`;
              }
              fm[iconImageField] = iconValue;
            });
            new TargetPositionModal(this.app, this.plugin).open();
          };
          new IconImageSelectionModal(
            this.app,
            this.plugin,
            onChooseBannerIconImage,
            this.plugin.settings.defaultSelectIconPath
          ).open();
        });
        const bannerIconButton = customizationOptions.createEl("button", {
          cls: "pixel-banner-customize-button"
        });
        const bannerIconContent = bannerIconButton.createDiv({ cls: "pixel-banner-button-content" });
        bannerIconContent.createEl("span", { text: "\u{1F4F0}", cls: "pixel-banner-button-icon" });
        bannerIconContent.createEl("div", { cls: "pixel-banner-button-text-container" }).createEl("span", {
          text: "Icon Emoji & Text",
          cls: "pixel-banner-button-text"
        });
        if (!hasBanner) {
          bannerIconButton.disabled = true;
          bannerIconButton.classList.add("pixel-banner-button-disabled");
          bannerIconButton.title = "You need to add a banner first";
        }
        bannerIconButton.addEventListener("click", () => {
          if (!hasBanner) return;
          this.close();
          new EmojiSelectionModal(
            this.app,
            this.plugin,
            async (emoji) => {
              const activeFile2 = this.app.workspace.getActiveFile();
              if (activeFile2) {
                await this.plugin.app.fileManager.processFrontMatter(activeFile2, (frontmatter) => {
                  const iconField = this.plugin.settings.customBannerIconField[0];
                  if (emoji) {
                    frontmatter[iconField] = emoji;
                  } else {
                    delete frontmatter[iconField];
                  }
                });
              }
            }
          ).open();
        });
        const targetingIconButton = customizationOptions.createEl("button", {
          cls: "pixel-banner-customize-button"
        });
        const targetingIconContent = targetingIconButton.createDiv({ cls: "pixel-banner-button-content" });
        targetingIconContent.createEl("span", { text: "\u{1F3AF}", cls: "pixel-banner-button-icon" });
        targetingIconContent.createEl("div", { cls: "pixel-banner-button-text-container" }).createEl("span", {
          text: "Position, Size, & Style",
          cls: "pixel-banner-button-text"
        });
        if (!hasBanner) {
          targetingIconButton.disabled = true;
          targetingIconButton.classList.add("pixel-banner-button-disabled");
          targetingIconButton.title = "You need to add a banner first";
        }
        targetingIconButton.addEventListener("click", () => {
          this.close();
          new TargetPositionModal(this.app, this.plugin).open();
        });
        setTimeout(() => {
          if (hasBanner && targetingIconButton) {
            targetingIconButton.focus();
          }
        }, 1e3);
        if (!hasBanner) {
          const noBannerMessage = customizationSection.createDiv({ cls: "pixel-banner-no-banner-message" });
          noBannerMessage.createEl("p", {
            text: "Add a banner first to enable customization options.",
            cls: "pixel-banner-message-text"
          });
        }
        const accountSection = mainContainer.createDiv({
          cls: "pixel-banner-section pixel-banner-api-dependent",
          attr: {
            style: `
                    gap: 5px;
                    position: relative;
                    min-height: ${this.plugin.settings.pixelBannerPlusEnabled ? "97px" : "60px"};
                `
          }
        });
        const accountTitleContainer = accountSection.createDiv({
          attr: {
            style: `
                    display: flex;
                    align-items: center;
                    justify-content: space-between;
                    margin-bottom: ${this.plugin.settings.pixelBannerPlusEnabled ? "10px" : "0"};
                `
          }
        });
        const accountTitle = accountTitleContainer.createEl("h3", {
          text: "Pixel Banner Plus",
          cls: "pixel-banner-section-title",
          attr: {
            style: `
                    margin: 0;
                    cursor: help;
                    width: max-content;
                `
          }
        });
        const toggleContainer = accountTitleContainer.createDiv({
          cls: "pixel-banner-plus-toggle-container",
          attr: {
            style: `
                    display: flex;
                    align-items: center;
                    gap: 8px;
                `
          }
        });
        toggleContainer.createEl("span", {
          text: "Enabled",
          attr: {
            style: `
                    font-size: 12px;
                    opacity: 0.8;
                    font-weight: normal;
                `
          }
        });
        const toggleSettingContainer = toggleContainer.createDiv({
          attr: {
            style: `
                    display: inline-flex;
                    align-items: center;
                `
          }
        });
        new import_obsidian13.Setting(toggleSettingContainer).addToggle(
          (toggle) => toggle.setValue(this.plugin.settings.pixelBannerPlusEnabled).onChange(async (value) => {
            this.plugin.pixelBannerPlusEnabled = value;
            this.plugin.settings.pixelBannerPlusEnabled = value;
            await this.plugin.saveSettings();
            this.refreshModal();
          })
        ).then((setting) => {
          if (setting.nameEl) setting.nameEl.style.display = "none";
          if (setting.descEl) setting.descEl.style.display = "none";
          if (setting.settingEl) {
            setting.settingEl.style.border = "none";
            setting.settingEl.style.padding = "0";
            setting.settingEl.style.margin = "0";
          }
        });
        if (this.plugin.settings.pixelBannerPlusEnabled) {
          const accountInfo = accountSection.createDiv({
            cls: "pixel-banner-account-info",
            attr: {
              style: "visibility: hidden;"
            }
          });
          const accountLoadingOverlay = accountSection.createDiv({
            cls: "pixel-banner-section-loading-overlay",
            attr: {
              style: `
                        position: absolute;
                        top: 0;
                        left: 0;
                        right: 0;
                        bottom: 0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        background-color: var(--background-primary);
                        opacity: 0.8;
                        z-index: 10;
                        min-height: 50px;
                    `
            }
          });
          accountLoadingOverlay.appendChild(this.createLoadingSpinner());
        }
        this.addStyle();
      }
      // Initialize the API-dependent UI sections
      async initializeAPIDependentSections() {
        try {
          await this.plugin.verifyPixelBannerPlusCredentials();
          await this.plugin.getPixelBannerInfo();
          this.updateAPIStatusUI(true);
        } catch (error) {
          console.error("Error initializing API-dependent sections:", error);
          this.plugin.pixelBannerPlusServerOnline = false;
          this.updateAPIStatusUI(false);
        }
      }
      // Update UI elements that depend on API status
      updateAPIStatusUI(isOnline) {
        this.isVerifyingAPI = false;
        const { contentEl } = this;
        if (!isOnline) {
          this.plugin.pixelBannerPlusServerOnline = false;
        }
        const apiButtons = contentEl.querySelectorAll(".pixel-banner-api-dependent");
        apiButtons.forEach((element) => {
          const loadingOverlay = element.querySelector(".pixel-banner-button-loading-overlay, .pixel-banner-section-loading-overlay");
          if (loadingOverlay) {
            loadingOverlay.remove();
          }
          if (element.tagName === "BUTTON") {
            if (isOnline && this.plugin.pixelBannerPlusServerOnline) {
              element.style.display = "flex";
              element.classList.remove("pixel-banner-button-disabled");
              element.disabled = false;
              if (element.textContent.includes("AI Banner")) {
                element.addEventListener("click", () => {
                  this.close();
                  new GenerateAIBannerModal(this.app, this.plugin).open();
                });
              } else if (element.textContent.includes("Store")) {
                element.addEventListener("click", () => {
                  this.close();
                  new PixelBannerStoreModal(this.app, this.plugin).open();
                });
              }
            } else {
              element.style.display = "none";
            }
          }
        });
        if (this.plugin.settings.pixelBannerPlusEnabled) {
          const accountSection = contentEl.querySelector(".pixel-banner-section.pixel-banner-api-dependent");
          if (accountSection) {
            const accountInfo = accountSection.querySelector(".pixel-banner-account-info");
            if (accountInfo) {
              accountInfo.style.visibility = "visible";
              accountInfo.empty();
              const statusContainer = accountInfo.createDiv({
                attr: {
                  style: `
                                display: flex;
                                flex-direction: row;
                                gap: 10px;
                                align-items: center;
                                cursor: help;
                            `
                }
              });
              const openPlusSettings = async () => {
                this.close();
                await this.app.setting.open();
                await new Promise((resolve) => setTimeout(resolve, 300));
                const settingsTabs = document.querySelectorAll(".vertical-tab-header-group .vertical-tab-nav-item");
                for (const tab of settingsTabs) {
                  if (tab.textContent.includes("Pixel Banner")) {
                    tab.click();
                    break;
                  }
                }
                const pixelBannerSettingsTabs = document.querySelectorAll(".pixel-banner-settings-tabs > button.pixel-banner-settings-tab");
                for (const tab of pixelBannerSettingsTabs) {
                  if (tab.textContent.includes("Plus")) {
                    tab.click();
                    break;
                  }
                }
              };
              const accountTitle = accountSection.querySelector(".pixel-banner-section-title");
              if (accountTitle) accountTitle.addEventListener("click", openPlusSettings);
              const isConnected = this.plugin.pixelBannerPlusEnabled;
              const pixelBannerPlusServerOnline = this.plugin.pixelBannerPlusServerOnline;
              if (!isConnected) {
                const aiButton = document.getElementById("pixel-banner-plus-ai-button");
                const storeButton = document.getElementById("pixel-banner-plus-store-button");
                if (aiButton) {
                  aiButton.disabled = true;
                  aiButton.classList.add("pixel-banner-button-disabled");
                  aiButton.title = "You need an authorize Pixel Banner Plus account to use this feature";
                }
                if (storeButton) {
                  storeButton.disabled = true;
                  storeButton.classList.add("pixel-banner-button-disabled");
                  storeButton.title = "You need an authorize Pixel Banner Plus account to use this feature";
                }
              }
              const statusText = !isOnline || !pixelBannerPlusServerOnline ? "\u{1F6A8} Servers Offline \u{1F6A8}" : isConnected ? "\u2705 Authorized" : "\u274C Not Authorized";
              const statusBorderColor = !isOnline || !pixelBannerPlusServerOnline ? "#FF6B6B" : isConnected ? "#177d47" : "#FF0000";
              const statusEl = statusContainer.createEl("span", {
                text: statusText,
                cls: "pixel-banner-status-value",
                attr: {
                  style: `border: 1px dashed ${statusBorderColor};`
                }
              });
              statusEl.addEventListener("click", openPlusSettings);
              const isMobileDevice = window.navigator.userAgent.includes("Android") || window.navigator.userAgent.includes("iPhone") || window.navigator.userAgent.includes("iPad") || window.navigator.userAgent.includes("iPod");
              if (isOnline && pixelBannerPlusServerOnline) {
                const tokenCount = this.plugin.pixelBannerPlusBannerTokens !== void 0 ? `\u{1FA99} ${decimalToFractionString(this.plugin.pixelBannerPlusBannerTokens)} Tokens` : "\u2753 Unknown";
                const tokenCountEl = statusContainer.createEl("span", {
                  text: tokenCount,
                  cls: "pixel-banner-status-value",
                  attr: {
                    style: `
                                    border: 1px dashed #bba00f;
                                    display: ${pixelBannerPlusServerOnline && this.plugin.pixelBannerPlusEnabled ? "inline-flex" : "none"};
                                `
                  }
                });
                tokenCountEl.addEventListener("click", openPlusSettings);
                if (!isMobileDevice && isConnected) {
                  const gameButton = statusContainer.createEl("button", {
                    cls: "pixel-banner-game-button",
                    attr: {
                      style: `
                                        margin-left: auto;
                                        margin-right: 10px;
                                        padding: 4px 10px;
                                        background: transparent;
                                        border: none;
                                        box-shadow: none;
                                        cursor: pointer;
                                        font-size: 14px;
                                        display: none;
                                        text-transform: uppercase;
                                    `
                    }
                  });
                  gameButton.innerHTML = "\u{1F579}\uFE0F";
                  gameButton.title = "Play Daily Game (optional)... chance to win Banner Tokens";
                  gameButton.addEventListener("click", () => {
                    this.close();
                    new DailyGameModal(this.app, this.plugin.settings.pixelBannerPlusEmail, this.plugin.settings.pixelBannerPlusApiKey, this.plugin).open();
                  });
                  const showGameButton = isOnline && this.plugin.pixelBannerPlusServerOnline && this.plugin.pixelBannerPlusEnabled && !this.plugin.settings.enableDailyGame;
                  gameButton.style.display = showGameButton ? "inline-block" : "none";
                }
                if (!isMobileDevice && this.plugin.settings.enableDailyGame && isConnected) {
                  const dailyGameContainer = accountInfo.createDiv({
                    cls: "pixel-banner-daily-game-container",
                    attr: {
                      style: `
                                        display: flex;
                                        flex-direction: row;
                                        align-items: center;
                                        gap: 10px;
                                        justify-content: space-between;
                                        width: 100%;
                                        border-top: 1px solid var(--modal-border-color);
                                        padding-top: 20px;
                                        margin-top: 10px;
                                    `
                    }
                  });
                  const dailyGameInfoBlock = dailyGameContainer.createDiv({
                    attr: {
                      style: `
                                        display: flex;
                                        flex-direction: column;
                                        align-items: flex-start;
                                        gap: 5px;
                                        width: 100%;
                                    `
                    }
                  });
                  const infoBlockRow1 = dailyGameInfoBlock.createEl("div");
                  infoBlockRow1.createEl("span", { text: "\u{1F3AE} Daily Game " });
                  infoBlockRow1.createEl("span", {
                    text: this.plugin.pixelBannerPlusDailyGameName,
                    attr: {
                      style: `
                                        font-style: italic;
                                        padding: 0px 8px;
                                        border-radius: 7px;
                                        line-height: 1.38;
                                        color: var(--text-color);
                                        background-color: var(--interactive-normal);
                                        box-shadow: var(--input-shadow);
                                    `
                    }
                  });
                  const infoBlockRow2 = dailyGameInfoBlock.createEl("div");
                  infoBlockRow2.createEl("span", { text: "\u{1F3C6} High Score " });
                  infoBlockRow2.createEl("span", {
                    text: this.plugin.pixelBannerPlusHighScore,
                    attr: { style: `
                                    font-style: italic;
                                    padding: 0px 8px;
                                    border-radius: 7px;
                                    line-height: 1.38;
                                    color: var(--text-color);
                                    background-color: var(--interactive-normal);
                                    box-shadow: var(--input-shadow);
                                ` }
                  });
                  const infoBlockRow3 = dailyGameInfoBlock.createEl("div");
                  infoBlockRow3.createEl("span", { text: "\u{1F4B0} Current Jackpot " });
                  infoBlockRow3.createEl("span", {
                    text: `\u{1FA99} ${decimalToFractionString(this.plugin.pixelBannerPlusJackpot)} Tokens`,
                    attr: { style: `
                                    font-style: italic;
                                    padding: 0px 8px;
                                    border-radius: 7px;
                                    line-height: 1.38;
                                    color: var(--text-color);
                                    background-color: var(--interactive-normal);
                                    box-shadow: var(--input-shadow);
                                ` }
                  });
                  const infoBlockRow4 = dailyGameInfoBlock.createEl("div");
                  infoBlockRow4.createEl("span", { text: "\u23F0 Time Left " });
                  infoBlockRow4.createEl("span", {
                    text: this.plugin.pixelBannerPlusTimeLeft,
                    attr: { style: `
                                    font-style: italic;
                                    padding: 0px 8px;
                                    border-radius: 7px;
                                    line-height: 1.38;
                                    color: var(--text-color);
                                    background-color: var(--interactive-normal);
                                    box-shadow: var(--input-shadow);
                                ` }
                  });
                  const infoBlockRow5 = dailyGameInfoBlock.createEl("div");
                  infoBlockRow5.createEl("span", {
                    text: "3 FREE",
                    attr: {
                      style: `
                                        background: darkgreen;
                                        color: white;
                                        padding: 0px 4px;
                                        border-radius: 5px;
                                        letter-spacing: 1px;
                                    `
                    }
                  });
                  infoBlockRow5.createEl("span", { text: " plays per day!" });
                  const dailyGameButton = dailyGameContainer.createEl("button", {
                    cls: "pixel-banner-account-button pixel-banner-daily-game-button",
                    attr: {
                      style: `
                                        min-width: 110px;
                                    `
                    }
                  });
                  const dailyGameContent = dailyGameButton.createDiv({
                    cls: "pixel-banner-button-content",
                    attr: {
                      style: `
                                        display: flex;
                                        align-items: center;
                                        gap: 10px;
                                    `
                    }
                  });
                  dailyGameContent.createEl("span", { text: "\u{1F579}\uFE0F", cls: "pixel-banner-button-icon pixel-banner-twinkle-animation" });
                  dailyGameContent.createEl("div", { cls: "pixel-banner-button-text-container" }).createEl("span", {
                    text: "Play Daily Game",
                    cls: "pixel-banner-button-text"
                  });
                  dailyGameButton.addEventListener("click", () => {
                    this.close();
                    new DailyGameModal(this.app, this.plugin.settings.pixelBannerPlusEmail, this.plugin.settings.pixelBannerPlusApiKey, this.plugin).open();
                  });
                }
              } else {
                const retryButton = statusContainer.createEl("button", {
                  text: "\u{1F504} Try Again",
                  cls: "pixel-banner-account-button pixel-banner-retry-button",
                  attr: {
                    style: `
                                    background-color: var(--background-accent) !important;
                                    color: var(--text-on-accent) !important;
                                    margin-left: 10px;
                                `
                  }
                });
                retryButton.addEventListener("click", async () => {
                  statusContainer.empty();
                  statusContainer.createEl("span", {
                    text: "Connecting...",
                    cls: "pixel-banner-status-value"
                  });
                  const tempSpinner = this.createLoadingSpinner();
                  statusContainer.appendChild(tempSpinner);
                  try {
                    await this.plugin.verifyPixelBannerPlusCredentials();
                    await this.plugin.getPixelBannerInfo();
                    this.updateAPIStatusUI(true);
                  } catch (error) {
                    console.error("Error reconnecting:", error);
                    this.plugin.pixelBannerPlusServerOnline = false;
                    this.updateAPIStatusUI(false);
                  }
                });
              }
              if (pixelBannerPlusServerOnline && isConnected && this.plugin.pixelBannerPlusBannerTokens === 0) {
                const buyTokensButton = accountInfo.createEl("button", {
                  cls: "pixel-banner-account-button pixel-banner-buy-tokens-button",
                  text: "\u{1F4B5} Buy More Tokens"
                });
                buyTokensButton.addEventListener("click", (event) => {
                  event.preventDefault();
                  window.open(PIXEL_BANNER_PLUS.SHOP_URL, "_blank");
                });
              } else if (pixelBannerPlusServerOnline && !isConnected) {
                const signupButton = accountInfo.createEl("button", {
                  cls: "pixel-banner-account-button pixel-banner-signup-button",
                  text: "\u{1F6A9} Signup for Free!"
                });
                signupButton.addEventListener("click", (event) => {
                  event.preventDefault();
                  const signupUrl = PIXEL_BANNER_PLUS.API_URL + PIXEL_BANNER_PLUS.ENDPOINTS.SIGNUP;
                  window.open(signupUrl, "_blank");
                });
              }
              const cloudVersion = this.plugin.pixelBannerVersion;
              const currentVersion = this.plugin.settings.lastVersion;
              const isCloudVersionGreater = semver.gt(cloudVersion, currentVersion);
              let versionText, cursor;
              if (isCloudVersionGreater) {
                versionText = `\u{1F504} Update Available!`;
                cursor = "pointer";
              } else {
                versionText = ``;
                cursor = "default";
              }
              const versionInfo = accountInfo.createDiv({
                text: versionText,
                attr: {
                  style: `
                                display: flex;
                                flex-direction: row;
                                gap: 10px;
                                align-items: center;
                                cursor: ${cursor};
                                margin-left: auto;
                                animation: pixel-banner-scale-up-down 3s ease-in-out infinite;
                            `
                }
              });
              if (isCloudVersionGreater) {
                const openCommunityPlugins = async () => {
                  this.close();
                  await this.app.setting.open();
                  await new Promise((resolve) => setTimeout(resolve, 300));
                  const settingsTabs = document.querySelectorAll(".vertical-tab-header-group .vertical-tab-nav-item");
                  for (const tab of settingsTabs) {
                    if (tab.textContent.includes("Community plugins")) {
                      tab.click();
                      break;
                    }
                  }
                  await new Promise((resolve) => setTimeout(resolve, 500));
                  const allTheButtons = document.querySelectorAll("button.mod-cta");
                  for (const button of allTheButtons) {
                    if (button.textContent.includes("Check for updates")) {
                      button.click();
                      break;
                    }
                  }
                };
                versionInfo.addEventListener("click", openCommunityPlugins);
              }
            }
          }
        }
      }
      addStyle() {
        const style = document.createElement("style");
        style.textContent = `            
            .pixel-banner-main-container {
                display: flex;
                flex-direction: column;
                gap: 15px;
                padding: 0 16px 16px;
                max-height: 80vh;
                width: 100%;
                box-sizing: border-box;
            }
            
            .pixel-banner-section {
                display: flex;
                flex-direction: column;
                gap: 16px;
                width: 100%;
                padding: 14px;
            }
            
            .pixel-banner-section-title {
                font-size: 16px;
                margin: 0;
                color: var(--text-normal);
                font-weight: 600;
            }
            
            .pixel-banner-source-buttons {
                display: flex;
                flex-wrap: wrap;
                gap: 12px;
                width: 100%;
                justify-content: space-between;
            }
            
            .pixel-banner-source-button {
                display: flex;
                flex-direction: column;
                align-items: center;
                padding: 12px 8px;
                border-radius: 8px;
                border: 1px solid var(--background-modifier-border);
                background: var(--background-primary);
                cursor: pointer;
                transition: all 0.2s ease;
                flex: auto;
                min-width: 80px;
                height: 100%;
                box-sizing: border-box;
                overflow: hidden;
            }
            
            .pixel-banner-source-button:hover {
                background: var(--background-modifier-hover);
                transform: translateY(-2px);
                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
            }
            
            .pixel-banner-button-content {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                gap: 12px;
                width: 100%;
                height: 100%;
            }
            
            .pixel-banner-button-icon {
                font-size: 24px;
                line-height: 1;
                flex-shrink: 0;
            }
            
            .pixel-banner-button-text-container {
                text-align: center;
                width: 100%;
                display: flex;
                align-items: center;
                justify-content: center;
                flex-grow: 1;
                overflow: hidden;
            }
            
            .pixel-banner-button-text {
                font-size: 13px;
                font-weight: 500;
                white-space: normal;
                word-break: break-word;
                line-height: 1.2;
                hyphens: auto;
                overflow-wrap: break-word;
                max-width: 100%;
            }
            
            .pixel-banner-customization-options {
                display: flex;
                flex-wrap: wrap;
                gap: 12px;
                width: 100%;
                justify-content: space-between;
            }
            
            .pixel-banner-customize-button {
                display: flex;
                flex-direction: column;
                align-items: center;
                padding: 12px 8px;
                border-radius: 8px;
                border: 1px solid var(--background-modifier-border);
                background: var(--background-primary);
                cursor: pointer;
                transition: all 0.2s ease;
                flex: auto;
                min-width: 80px;
                height: 100%;
                box-sizing: border-box;
                overflow: hidden;
            }
            
            .pixel-banner-customize-button:hover {
                background: var(--background-modifier-hover);
                transform: translateY(-2px);
                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
            }
            
            .pixel-banner-button-disabled {
                opacity: 0.5;
                cursor: not-allowed;
            }
            
            .pixel-banner-button-disabled:hover {
                background: var(--background-primary);
                transform: none;
                box-shadow: none;
            }
            
            .pixel-banner-no-banner-message {
                background: var(--background-modifier-error-rgb);
                border-radius: 8px;
                width: 100%;
                box-sizing: border-box;
            }
            
            .pixel-banner-message-text {
                margin: 0;
                color: var(--text-accent-hover);
                font-size: 14px;
                text-align: center;
                text-transform: uppercase;
            }
            
            .pixel-banner-settings-button:hover {
                opacity: 0.8;
            }
            
            /* Pixel Banner Plus Account styles */
            .pixel-banner-account-info {
                display: flex;
                flex-direction: column;
                justify-content: center;
                align-items: flex-start;
                flex-wrap: wrap;
                gap: 10px;
                width: 100%;
            }
            
            .pixel-banner-status-value {
                padding: 3px 7px;
                border-radius: 15px;
                font-size: .8em;
                letter-spacing: 1px;
                background-color: var(--background-primary);
                display: inline-flex;
                align-items: center;
            }
            
            .pixel-banner-account-button {
                display: flex;
                flex-direction: column;
                align-items: center;
                padding: 12px 8px;
                border-radius: 8px;
                border: 1px solid var(--background-modifier-border);
                background: var(--background-primary);
                cursor: pointer;
                transition: all 0.2s ease;
                flex: 1;
                min-width: 80px;
                height: 100%;
                box-sizing: border-box;
                overflow: hidden;
            }
            
            .pixel-banner-account-button:hover {
                opacity: 0.9;
                transform: translateY(-2px);
            }
            
            .pixel-banner-buy-tokens-button {
                background-color: darkgreen !important;
                color: papayawhip !important;
                opacity: 0.7;
            }
            
            .pixel-banner-signup-button {
                background-color: var(--interactive-accent) !important;
                color: var(--text-on-accent) !important;
            }
            
            .pixel-banner-retry-button {
                background-color: var(--background-accent) !important;
                color: var(--text-on-accent) !important;
                font-size: 0.8em !important;
                padding: 4px 8px !important;
                animation: pixel-banner-pulse 2s infinite;
            }
            
            @keyframes pixel-banner-pulse {
                0% { transform: scale(1); }
                50% { transform: scale(1.05); }
                100% { transform: scale(1); }
            }
            
            /* Loading spinner styles */
            @keyframes pixel-banner-spin {
                0% { transform: rotate(0deg); }
                100% { transform: rotate(360deg); }
            }
            
            @keyframes pixel-banner-fade-in {
                0% { opacity: 0; }
                100% { opacity: 1; }
            }
            
            @keyframes pixel-banner-scale-up-down {
                0% { transform: scale(1); }
                50% { transform: scale(1.05); }
                100% { transform: scale(1); }
            }
            
            @media (min-width: 400px) {
                .pixel-banner-source-button,
                .pixel-banner-customize-button {
                    padding: 16px 8px;
                }
            }
            
            @media (max-width: 590px) {
                .pixel-banner-daily-game-container {
                    flex-direction: column !important;
                    align-items: flex-start !important;
                }
            }
            
            @media (max-width: 399px) {
                .pixel-banner-source-button,
                .pixel-banner-customize-button {
                    min-height: 90px;
                }
                
                .pixel-banner-button-icon {
                    font-size: 20px;
                }
                
                .pixel-banner-button-text {
                    font-size: 12px;
                }
            }
        `;
        document.head.appendChild(style);
        this.style = style;
      }
      onClose() {
        this.contentEl.empty();
        if (this.style) {
          this.style.remove();
        }
      }
    };
  }
});

// src/modal/modals/generateAIBannerModal.js
var import_obsidian14, GenerateAIBannerModal;
var init_generateAIBannerModal = __esm({
  "src/modal/modals/generateAIBannerModal.js"() {
    import_obsidian14 = require("obsidian");
    init_constants();
    init_handlePinIconClick();
    init_fractionTextDisplay();
    init_downloadHistory();
    init_modals();
    init_selectPixelBannerModal();
    GenerateAIBannerModal = class extends import_obsidian14.Modal {
      constructor(app, plugin) {
        super(app);
        this.plugin = plugin;
        this.prompt = "";
        this.imageContainer = null;
        this.modalEl.addClass("pixel-banner-ai-modal");
        this.downloadHistory = new DownloadHistory();
        this.isLoading = true;
        this.availableModels = {};
        this.selectedModelId = null;
        this.controlValues = {};
        this.controlsContainer = null;
        this.currentPage = 1;
        this.totalPages = 1;
        this.itemsPerPage = 9;
        this.totalItems = 0;
        this.addStyles();
      }
      addStyles() {
        const styleEl = document.createElement("style");
        styleEl.textContent = `
            .ai-banner-pagination {
                display: flex;
                justify-content: center;
                align-items: center;
                gap: 10px;
                margin-top: 10px;
                position: sticky;
                bottom: -20px;
                background-color: var(--modal-background);
                padding: 10px 20px;
                border-radius: 7px;
                z-index: 2;
            }

            .ai-banner-pagination button {
                padding: 4px 8px;
                border-radius: 4px;
            }

            .ai-banner-pagination button:hover:not(.disabled) {
                background-color: var(--interactive-accent-hover);
                cursor: pointer;
            }

            .ai-banner-pagination button.disabled {
                opacity: 0.5;
                cursor: not-allowed;
            }

            .ai-banner-pagination span {
                color: var(--text-muted);
                font-size: 0.9em;
            }

            .pixel-banner-history-container {
                transition: min-height 0.3s ease-out;
            }

            .pixel-banner-history-container.loading {
                opacity: 0.7;
                position: relative;
            }

            .pixel-banner-history-container .pixel-banner-loading {
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
            }
            
            .pixel-banner-loading-overlay {
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                display: flex;
                justify-content: center;
                align-items: center;
                background-color: var(--background-primary);
                z-index: 100;
                animation: pixel-banner-fade-in 0.3s ease-in-out;
            }
            
            .pixel-banner-spinner {
                width: 40px;
                height: 40px;
                border: 4px solid var(--background-modifier-border);
                border-top: 4px solid var(--text-accent);
                border-radius: 50%;
                animation: pixel-banner-spin 1s linear infinite;
            }
            
            /* Dynamic controls styles */
            .pixel-banner-dynamic-controls .setting-item {
                display: flex;
                flex-direction: row;
                justify-content: space-between;
                align-items: center;
                padding: 0.5rem 0;
                border-bottom: 1px solid var(--background-modifier-border);
            }
            
            .pixel-banner-dynamic-controls .setting-item:last-child {
                border-bottom: none;
            }
            
            .pixel-banner-dynamic-controls input[type="range"] {
                width: 100%;
            }
            
            .pixel-banner-dynamic-controls select.dropdown {
                width: 100%;
                padding: 4px 8px;
                border-radius: 4px;
                background-color: var(--background-secondary);
                color: var(--text-normal);
                border: 1px solid var(--background-modifier-border);
            }
            
            .pixel-banner-ai-modal select.dropdown:hover {
                border-color: var(--interactive-accent-hover);
            }
            
            .pixel-banner-ai-modal select.dropdown:focus {
                border-color: var(--interactive-accent);
                outline: none;
            }
        `;
        document.head.appendChild(styleEl);
        this.styleEl = styleEl;
      }
      // Show loading spinner
      showLoadingSpinner(container) {
        this.isLoading = true;
        this.loadingOverlay = container.createDiv({
          cls: "pixel-banner-loading-overlay"
        });
        this.loadingOverlay.createDiv({
          cls: "pixel-banner-spinner"
        });
      }
      // Hide loading spinner
      hideLoadingSpinner() {
        this.isLoading = false;
        if (this.loadingOverlay) {
          this.loadingOverlay.remove();
          this.loadingOverlay = null;
        }
      }
      // Fetch available AI models from the API
      async fetchAvailableModels() {
        try {
          const modelUrl = new URL(PIXEL_BANNER_PLUS.ENDPOINTS.TEXT_TO_IMAGE_MODELS, PIXEL_BANNER_PLUS.API_URL).toString();
          const response = await (0, import_obsidian14.requestUrl)({
            url: modelUrl,
            method: "GET",
            headers: {
              "X-User-Email": this.plugin.settings.pixelBannerPlusEmail,
              "X-API-Key": this.plugin.settings.pixelBannerPlusApiKey,
              "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
              "Accept": "application/json"
            }
          });
          if (response.status === 200) {
            this.availableModels = response.json;
            return true;
          } else {
            throw new Error("Failed to fetch models");
          }
        } catch (error) {
          console.error("Error fetching models:", error);
          return false;
        }
      }
      // Helper method to capitalize first letter of a string
      capitalizeFirstLetter(string) {
        return string.charAt(0).toUpperCase() + string.slice(1);
      }
      // Render model selection UI
      renderModelSelection(container) {
        container.empty();
        const modelInfo = container.createDiv({ cls: "setting-item-info" });
        modelInfo.createDiv({
          cls: "setting-item-name",
          text: "AI Model",
          attr: {
            style: `
                    min-width: 100px;
                `
          }
        });
        const modelControl = container.createDiv({
          cls: "setting-item-control",
          attr: { style: "width: 100%;" }
        });
        const modelSelect = modelControl.createEl("select", {
          cls: "dropdown",
          attr: {
            id: "ai-model-select",
            style: "width: 100%; padding: 4px 8px; border-radius: 4px; background-color: var(--background-secondary); color: var(--text-normal); border: 1px solid var(--background-modifier-border);"
          }
        });
        let hasEnabledModels = false;
        let firstEnabledModelId = null;
        Object.entries(this.availableModels).forEach(([modelId, modelData]) => {
          if (modelData.enabled === false) {
            return;
          }
          hasEnabledModels = true;
          const tokenCost = modelData.tokens || 1;
          const optionText = `${modelData.name} \u22C5 \u{1FA99} ${decimalToFractionString(tokenCost)}`;
          const option = modelSelect.createEl("option", {
            text: optionText,
            attr: {
              value: modelId,
              title: modelData.description || ""
            }
          });
          if (!firstEnabledModelId) {
            firstEnabledModelId = modelId;
            this.selectedModelId = modelId;
            option.selected = true;
          }
        });
        modelSelect.addEventListener("change", (e) => {
          const previousModelId = this.selectedModelId;
          this.selectedModelId = e.target.value;
          if (previousModelId !== this.selectedModelId) {
            this.renderModelControls();
          }
        });
        return hasEnabledModels;
      }
      // Render dynamic controls based on selected model
      renderModelControls() {
        if (!this.selectedModelId || !this.availableModels[this.selectedModelId]) {
          return;
        }
        this.controlsContainer.empty();
        this.controlValues = {};
        const modelData = this.availableModels[this.selectedModelId];
        const controls = modelData.controls;
        const modelDescription = this.controlsContainer.createDiv({ cls: "setting-item-info" });
        modelDescription.createDiv({
          cls: "setting-item-name",
          text: modelData.description,
          attr: {
            style: `
                    border: 1px solid var(--text-accent);
                    border-radius: 5px;
                    padding: 5px 10px;
                    font-size: 0.9em;
                    color: var(--text-muted);
                    font-style: italic;
                    text-align: justify;
                `
          }
        });
        if (!controls || Object.keys(controls).length === 0) {
          return;
        }
        const formElements = [];
        Object.entries(controls).forEach(([controlKey, control]) => {
          const controlContainer = this.controlsContainer.createDiv({
            cls: "setting-item pixel-banner-ai-control-row"
          });
          const controlInfo = controlContainer.createDiv({ cls: "setting-item-info" });
          controlInfo.createDiv({
            cls: "setting-item-name",
            text: this.capitalizeFirstLetter(controlKey)
          });
          this.controlValues[controlKey] = control.defaultValue;
          const controlValueDisplay = controlInfo.createDiv({
            cls: "setting-item-description",
            text: control.defaultValue
          });
          const controlElement = controlContainer.createDiv({ cls: "setting-item-control" });
          if (control.type === "slider") {
            const slider = controlElement.createEl("input", {
              type: "range",
              attr: {
                id: `control-${this.selectedModelId}-${controlKey}`,
                min: control.min,
                max: control.max,
                step: control.step,
                value: control.defaultValue
              }
            });
            slider.addEventListener("input", (e) => {
              const value = parseInt(e.target.value);
              this.controlValues[controlKey] = value;
              controlValueDisplay.textContent = value;
            });
            formElements.push({
              element: slider,
              type: "slider",
              value: control.defaultValue
            });
          } else if (control.type === "select") {
            const select = controlElement.createEl("select", {
              cls: "dropdown",
              attr: {
                id: `control-${this.selectedModelId}-${controlKey}`,
                style: "width: 100%;"
              }
            });
            control.options.forEach((option) => {
              const optElement = select.createEl("option", {
                text: option,
                attr: {
                  value: option,
                  selected: option === control.defaultValue
                }
              });
            });
            select.addEventListener("change", (e) => {
              this.controlValues[controlKey] = e.target.value;
              controlValueDisplay.textContent = e.target.value;
            });
            formElements.push({
              element: select,
              type: "select",
              value: control.defaultValue
            });
          } else if (control.type === "image_file") {
            const fileContainer = controlElement.createDiv({
              attr: { style: "display: flex; flex-direction: column; gap: 10px;" }
            });
            const fileInput = fileContainer.createEl("input", {
              type: "file",
              attr: {
                id: `control-${this.selectedModelId}-${controlKey}`,
                accept: "image/jpeg,image/jpg,image/png,image/webp,image/gif"
              }
            });
            const previewImage = fileContainer.createEl("img", {
              attr: {
                id: `${fileInput.id}-preview`,
                style: "max-width: 200px; max-height: 200px; display: none; border-radius: 4px; border: 1px solid var(--background-modifier-border);"
              }
            });
            const fileInfo = fileContainer.createDiv({
              attr: {
                id: `${fileInput.id}-info`,
                style: "font-size: 12px; color: var(--text-muted);"
              },
              text: "No file selected (max 10MB)"
            });
            fileInput.addEventListener("change", (e) => {
              const file = e.target.files[0];
              if (file) {
                const maxFileSize = 10 * 1024 * 1024;
                const fileSizeMB = (file.size / (1024 * 1024)).toFixed(1);
                if (file.size > maxFileSize) {
                  fileInfo.innerHTML = `<span style="color: var(--text-error);">\u274C File too large: ${fileSizeMB}MB (max 10MB)</span>`;
                  previewImage.style.display = "none";
                  this.controlValues[controlKey] = null;
                  controlValueDisplay.textContent = "File too large";
                  console.error(`File too large: ${fileSizeMB}MB`);
                  return;
                }
                fileInfo.innerHTML = `\u{1F4C1} ${file.name} (${fileSizeMB}MB)`;
                const reader = new FileReader();
                reader.onload = (e2) => {
                  previewImage.src = e2.target.result;
                  previewImage.style.display = "block";
                };
                reader.onerror = (e2) => {
                  console.error("File reader error:", e2);
                };
                reader.readAsDataURL(file);
                this.controlValues[controlKey] = "FILE_SELECTED";
                controlValueDisplay.textContent = "File selected";
              } else {
                fileInfo.textContent = "No file selected (max 10MB)";
                previewImage.style.display = "none";
                this.controlValues[controlKey] = null;
                controlValueDisplay.textContent = "No file";
              }
            });
          } else if (control.type === "image_files") {
            const fileContainer = controlElement.createDiv({
              attr: { style: "display: flex; flex-direction: column; gap: 10px;" }
            });
            if (!this.selectedFiles) this.selectedFiles = {};
            this.selectedFiles[controlKey] = [];
            const fileInput = fileContainer.createEl("input", {
              type: "file",
              attr: {
                id: `control-${this.selectedModelId}-${controlKey}`,
                accept: "image/jpeg,image/jpg,image/png,image/webp,image/gif",
                multiple: true
              }
            });
            const previewContainer = fileContainer.createDiv({
              attr: {
                id: `${fileInput.id}-previews`,
                style: "display: flex; flex-wrap: wrap; gap: 10px; display: none;"
              }
            });
            const fileInfo = fileContainer.createDiv({
              attr: {
                id: `${fileInput.id}-info`,
                style: "font-size: 12px; color: var(--text-muted);"
              },
              text: "No files selected (max 10MB each)"
            });
            const updatePreviewDisplay = () => {
              previewContainer.empty();
              const validFiles = this.selectedFiles[controlKey];
              if (validFiles.length > 0) {
                validFiles.forEach((file, index) => {
                  const previewItem = previewContainer.createDiv({
                    attr: {
                      style: "display: flex; flex-direction: column; align-items: center; position: relative;"
                    }
                  });
                  const removeButton = previewItem.createEl("button", {
                    text: "X",
                    attr: {
                      style: "position: absolute; top: -5px; right: -5px; width: 20px; height: 20px; border-radius: 50%; background: maroon; color: white; border: none; font-weight: bold; cursor: pointer; z-index: 1; line-height: 1; font-size: 14px;",
                      title: "Remove this image"
                    }
                  });
                  const previewImage = previewItem.createEl("img", {
                    attr: {
                      style: "max-width: 100px; max-height: 100px; border-radius: 4px; border: 1px solid var(--background-modifier-border);"
                    }
                  });
                  const fileName = previewItem.createDiv({
                    text: file.name,
                    attr: { style: "font-size: 10px; color: var(--text-muted); text-align: center; max-width: 100px; word-break: break-word;" }
                  });
                  const reader = new FileReader();
                  reader.onload = (e) => {
                    previewImage.src = e.target.result;
                  };
                  reader.onerror = (e) => {
                    console.error("File reader error:", e);
                  };
                  reader.readAsDataURL(file);
                  removeButton.addEventListener("click", (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    this.selectedFiles[controlKey] = this.selectedFiles[controlKey].filter((_, i) => i !== index);
                    updatePreviewDisplay();
                  });
                });
                const totalSize = validFiles.reduce((sum, file) => sum + file.size, 0);
                const totalSizeMB = (totalSize / (1024 * 1024)).toFixed(1);
                let infoText = `\u{1F4C1} ${validFiles.length} file${validFiles.length !== 1 ? "s" : ""} selected (${totalSizeMB}MB total)`;
                fileInfo.textContent = infoText;
                previewContainer.style.display = "flex";
                this.controlValues[controlKey] = "FILES_SELECTED";
                controlValueDisplay.textContent = `${validFiles.length} files selected`;
              } else {
                fileInfo.textContent = "No files selected (max 10MB each)";
                previewContainer.style.display = "none";
                this.controlValues[controlKey] = null;
                controlValueDisplay.textContent = "No files";
              }
            };
            fileInput.addEventListener("change", (e) => {
              const newFiles = Array.from(e.target.files);
              if (newFiles.length > 0) {
                let errors = [];
                newFiles.forEach((file) => {
                  const maxFileSize = 10 * 1024 * 1024;
                  const fileSizeMB = (file.size / (1024 * 1024)).toFixed(1);
                  const isDuplicate = this.selectedFiles[controlKey].some(
                    (existingFile) => existingFile.name === file.name && existingFile.size === file.size
                  );
                  if (file.size > maxFileSize) {
                    errors.push(`${file.name}: ${fileSizeMB}MB (too large)`);
                    return;
                  }
                  if (isDuplicate) {
                    errors.push(`${file.name}: already selected`);
                    return;
                  }
                  this.selectedFiles[controlKey].push(file);
                });
                if (errors.length > 0) {
                  const errorMsg = `\u274C ${errors.length} file${errors.length !== 1 ? "s" : ""} rejected: ${errors.join(", ")}`;
                  fileInfo.innerHTML = errorMsg;
                  setTimeout(() => updatePreviewDisplay(), 3e3);
                } else {
                  updatePreviewDisplay();
                }
              }
              fileInput.value = "";
            });
          }
        });
        setTimeout(() => {
          formElements.forEach((item) => {
            if (item.type === "slider") {
              item.element.value = item.value;
              const event = new Event("input", { bubbles: true });
              item.element.dispatchEvent(event);
            } else if (item.type === "select") {
              item.element.value = item.value;
              const event = new Event("change", { bubbles: true });
              item.element.dispatchEvent(event);
            }
          });
        }, 50);
      }
      // Helper method to collect control values
      async collectControlValues() {
        var _a;
        if (!this.selectedModelId || !this.availableModels[this.selectedModelId]) {
          console.error("No selected model or model data not found");
          return {};
        }
        const controlValues = {};
        const controls = this.availableModels[this.selectedModelId].controls;
        for (const controlKey in controls) {
          const controlId = `control-${this.selectedModelId}-${controlKey}`;
          const controlElement = this.contentEl.querySelector(`#${controlId}`);
          if (controlElement) {
            if (controls[controlKey].type === "slider") {
              controlValues[controlKey] = parseInt(controlElement.value, 10);
            } else if (controls[controlKey].type === "image_file") {
              const file = controlElement.files[0];
              controlValues[controlKey] = file ? "FILE_SELECTED" : null;
            } else if (controls[controlKey].type === "image_files") {
              const selectedFiles = ((_a = this.selectedFiles) == null ? void 0 : _a[controlKey]) || [];
              controlValues[controlKey] = selectedFiles.length > 0 ? "FILES_SELECTED" : null;
            } else {
              controlValues[controlKey] = controlElement.value;
            }
          } else {
            console.warn(`Control element not found for ${controlKey} (ID: ${controlId})`);
          }
        }
        return controlValues;
      }
      // Helper method to upload image files
      async uploadImageFiles(controlValues) {
        var _a, _b, _c;
        const controls = this.availableModels[this.selectedModelId].controls;
        const updatedControlValues = { ...controlValues };
        for (const controlKey in controlValues) {
          if (((_a = controls[controlKey]) == null ? void 0 : _a.type) === "image_file" && controlValues[controlKey] === "FILE_SELECTED") {
            const controlId = `control-${this.selectedModelId}-${controlKey}`;
            const fileInput = this.contentEl.querySelector(`#${controlId}`);
            const file = fileInput == null ? void 0 : fileInput.files[0];
            if (file) {
              try {
                const maxFileSize = 10 * 1024 * 1024;
                if (file.size > maxFileSize) {
                  throw new Error(`Image file too large. Maximum size is ${maxFileSize / (1024 * 1024)}MB, but file is ${(file.size / (1024 * 1024)).toFixed(1)}MB`);
                }
                const formData = new FormData();
                formData.append("image", file);
                const uploadUrl = new URL(PIXEL_BANNER_PLUS.ENDPOINTS.UPLOAD_TEMP_IMAGE, PIXEL_BANNER_PLUS.API_URL).toString();
                const response = await fetch(uploadUrl, {
                  method: "POST",
                  headers: {
                    "X-User-Email": this.plugin.settings.pixelBannerPlusEmail,
                    "X-API-Key": this.plugin.settings.pixelBannerPlusApiKey,
                    "X-Pixel-Banner-Version": this.plugin.settings.lastVersion
                    // Don't set Content-Type - let browser set it with boundary for FormData
                  },
                  body: formData
                });
                if (!response.ok) {
                  const errorText = await response.text();
                  console.error(`Upload failed with status ${response.status}:`, errorText);
                  throw new Error(`Failed to upload ${controlKey} image: HTTP ${response.status}`);
                }
                const responseData = await response.json();
                if (!(responseData == null ? void 0 : responseData.imageId)) {
                  console.error("Upload response missing imageId:", responseData);
                  throw new Error(`Upload response missing imageId for ${controlKey}`);
                }
                updatedControlValues[controlKey] = responseData.imageId;
              } catch (error) {
                console.error(`Error uploading ${controlKey}:`, error);
                throw new Error(`Failed to upload ${controlKey}: ${error.message}`);
              }
            } else {
              updatedControlValues[controlKey] = null;
            }
          } else if (((_b = controls[controlKey]) == null ? void 0 : _b.type) === "image_files" && controlValues[controlKey] === "FILES_SELECTED") {
            const files = ((_c = this.selectedFiles) == null ? void 0 : _c[controlKey]) || [];
            if (files.length > 0) {
              try {
                const uploadedImageIds = [];
                for (const file of files) {
                  const maxFileSize = 10 * 1024 * 1024;
                  if (file.size > maxFileSize) {
                    throw new Error(`Image file too large. Maximum size is ${maxFileSize / (1024 * 1024)}MB, but file is ${(file.size / (1024 * 1024)).toFixed(1)}MB`);
                  }
                  const formData = new FormData();
                  formData.append("image", file);
                  const uploadUrl = new URL(PIXEL_BANNER_PLUS.ENDPOINTS.UPLOAD_TEMP_IMAGE, PIXEL_BANNER_PLUS.API_URL).toString();
                  const response = await fetch(uploadUrl, {
                    method: "POST",
                    headers: {
                      "X-User-Email": this.plugin.settings.pixelBannerPlusEmail,
                      "X-API-Key": this.plugin.settings.pixelBannerPlusApiKey,
                      "X-Pixel-Banner-Version": this.plugin.settings.lastVersion
                      // Don't set Content-Type - let browser set it with boundary for FormData
                    },
                    body: formData
                  });
                  if (!response.ok) {
                    const errorText = await response.text();
                    console.error(`Upload failed with status ${response.status}:`, errorText);
                    throw new Error(`Failed to upload ${controlKey} image: HTTP ${response.status}`);
                  }
                  const responseData = await response.json();
                  if (!(responseData == null ? void 0 : responseData.imageId)) {
                    console.error("Upload response missing imageId:", responseData);
                    throw new Error(`Upload response missing imageId for ${controlKey}`);
                  }
                  uploadedImageIds.push(responseData.imageId);
                }
                updatedControlValues[controlKey] = uploadedImageIds;
              } catch (error) {
                console.error(`Error uploading ${controlKey}:`, error);
                throw new Error(`Failed to upload ${controlKey}: ${error.message}`);
              }
            } else {
              updatedControlValues[controlKey] = null;
            }
          }
        }
        return updatedControlValues;
      }
      async generateImage() {
        if (!this.imageContainer) return;
        if (!this.prompt) {
          new import_obsidian14.Notice("Please enter a prompt");
          return;
        }
        if (!this.selectedModelId && Object.keys(this.availableModels).length > 0) {
          new import_obsidian14.Notice("Please select an AI model");
          return;
        }
        const existingImage = this.imageContainer.querySelector(".pixel-banner-generated-image");
        const existingImageData = existingImage ? {
          base64Image: existingImage.src,
          imageId: existingImage.getAttribute("imageId")
        } : null;
        this.imageContainer.empty();
        const loadingContainer = this.imageContainer.createDiv({ cls: "pixel-banner-loading" });
        loadingContainer.createDiv({ cls: "dot-pulse" });
        try {
          if (existingImageData) {
            await this.refreshHistoryContainer();
          }
          let controlValues = await this.collectControlValues();
          const hasImageFiles = Object.values(controlValues).includes("FILE_SELECTED") || Object.values(controlValues).includes("FILES_SELECTED");
          if (hasImageFiles) {
            loadingContainer.empty();
            const uploadingDiv = loadingContainer.createDiv({ text: "Uploading images..." });
            try {
              controlValues = await this.uploadImageFiles(controlValues);
            } catch (uploadError) {
              console.error("Image upload failed:", uploadError);
              throw uploadError;
            }
            loadingContainer.empty();
            loadingContainer.createDiv({ cls: "dot-pulse" });
          }
          const generateUrl = new URL(PIXEL_BANNER_PLUS.ENDPOINTS.GENERATE, PIXEL_BANNER_PLUS.API_URL).toString();
          const modelData = this.availableModels[this.selectedModelId];
          const modelControlValues = {};
          if (modelData.controls) {
            Object.keys(modelData.controls).forEach((controlKey) => {
              if (controlValues[controlKey] !== void 0) {
                modelControlValues[controlKey] = controlValues[controlKey];
              } else {
                modelControlValues[controlKey] = modelData.controls[controlKey].defaultValue;
              }
            });
          }
          const requestBody = {
            prompt: this.prompt,
            textToImageModel: this.selectedModelId,
            controlValues: modelControlValues
          };
          if (modelData.appendToPrompt) {
            requestBody.prompt += " " + modelData.appendToPrompt;
          }
          const response = await (0, import_obsidian14.requestUrl)({
            url: generateUrl,
            method: "POST",
            headers: {
              "X-User-Email": this.plugin.settings.pixelBannerPlusEmail,
              "X-API-Key": this.plugin.settings.pixelBannerPlusApiKey,
              "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
              "Accept": "application/json",
              "Content-Type": "application/json"
            },
            body: JSON.stringify(requestBody)
          });
          if (response.status === 200 && response.json.image) {
            this.plugin.pixelBannerPlusBannerTokens = response.json.balance;
            const pixelBannerPlusBalanceEl = document.querySelector(".modal.pixel-banner-ai-modal .pixel-banner-plus-token-balance");
            const tokenCountSpan = pixelBannerPlusBalanceEl.querySelector("span") || document.createElement("span");
            tokenCountSpan.style.color = "var(--text-accent)";
            tokenCountSpan.innerText = decimalToFractionString(this.plugin.pixelBannerPlusBannerTokens);
            if (!tokenCountSpan.parentElement) {
              pixelBannerPlusBalanceEl.innerText = "\u{1FA99} Remaining Tokens: ";
              pixelBannerPlusBalanceEl.appendChild(tokenCountSpan);
            }
            tokenCountSpan.classList.remove("token-balance-animation");
            void tokenCountSpan.offsetWidth;
            tokenCountSpan.classList.add("token-balance-animation");
            this.imageContainer.empty();
            const imgWrapper = this.imageContainer.createDiv({ cls: "pixel-banner-generated-image-wrapper" });
            const img = imgWrapper.createEl("img", {
              cls: "pixel-banner-generated-image",
              attr: {
                src: `data:image/jpeg;base64,${response.json.image}`,
                "imageId": response.json.imageId
              }
            });
            const controls = this.imageContainer.createDiv({ cls: "pixel-banner-image-controls" });
            const useAsButton = controls.createEl("button", {
              cls: "mod-cta cursor-pointer",
              text: "\u{1F3F7}\uFE0F Download and Use as Banner"
            });
            const handleUseImage = async () => {
              var _a;
              const imageUrl = `data:image/jpeg;base64,${response.json.image}`;
              let filename = ((_a = this.prompt) == null ? void 0 : _a.toLowerCase().replace(/[^a-zA-Z0-9-_ ]/g, "").trim()) || "banner";
              filename = filename.replace(/\s+/g, "-").substring(0, 47);
              const savedPath = await handlePinIconClick(imageUrl, this.plugin, null, filename, false);
              this.downloadHistory.addImage(response.json.imageId);
              this.close();
              const activeFile = this.plugin.app.workspace.getActiveFile();
              if (!activeFile || !savedPath) return;
              await this.plugin.app.fileManager.processFrontMatter(activeFile, (frontmatter) => {
                const bannerField = this.plugin.settings.customBannerField[0];
                const format = this.plugin.settings.imagePropertyFormat;
                let bannerValue;
                if (format === "image") {
                  bannerValue = savedPath;
                } else if (format === "[[image]]") {
                  bannerValue = `[[${savedPath}]]`;
                } else {
                  bannerValue = `![[${savedPath}]]`;
                }
                frontmatter[bannerField] = bannerValue;
              });
              if (this.plugin.settings.openTargetingModalAfterSelectingBannerOrIcon) {
                new TargetPositionModal(this.app, this.plugin).open();
              }
            };
            img.addEventListener("click", handleUseImage);
            useAsButton.addEventListener("click", handleUseImage);
          } else {
            throw new Error("Failed to generate image");
          }
        } catch (error) {
          console.error("Failed to generate image:", error);
          this.imageContainer.empty();
          const errorDiv = this.imageContainer.createDiv({ cls: "pixel-banner-error" });
          errorDiv.innerHTML = `
                <p>\u{1F62D} Failed to generate image, please try again.</p>
                <p style="font-size: 0.8em; color: var(--text-muted);">Note that NSFW images are not allowed. You were not charged for this request.</p>
            `;
        }
      }
      async checkDownloadHistory(img) {
        const imageId = img.getAttribute("imageid");
        if (this.downloadHistory.hasImage(imageId)) {
          return new Promise((resolve) => {
            const modal = new import_obsidian14.Modal(this.app);
            modal.contentEl.createEl("h2", { text: "Image Already Downloaded" });
            modal.contentEl.createEl("p", { text: "You have already downloaded this image. Do you want to download it again?" });
            const buttonContainer = modal.contentEl.createDiv();
            buttonContainer.style.display = "flex";
            buttonContainer.style.justifyContent = "flex-end";
            buttonContainer.style.gap = "10px";
            const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
            const confirmButton = buttonContainer.createEl("button", { text: "Download Again", cls: "mod-cta" });
            cancelButton.onclick = () => {
              modal.close();
              resolve(false);
            };
            confirmButton.onclick = () => {
              modal.close();
              resolve(true);
            };
            modal.open();
          });
        }
        return true;
      }
      async confirmDelete(prompt) {
        return new Promise((resolve) => {
          let imgDescription = prompt;
          imgDescription = imgDescription.replace(/\s/g, "-").toLowerCase();
          imgDescription = imgDescription.replace(/[^a-zA-Z0-9-_ ]/g, "").trim();
          if (imgDescription.length > 47) {
            imgDescription = imgDescription.substring(0, 47);
            imgDescription = imgDescription + "...";
          }
          const modal = new import_obsidian14.Modal(this.app);
          modal.contentEl.createEl("h2", { text: "Delete Image", cls: "margin-top-0" });
          const deletePrompt = modal.contentEl.createEl("p", { text: `Please confirm you want to delete "IMGDESCRIPTION" from your AI Generated Banner History. This will not delete any images you have previously downloaded to your vault.` });
          deletePrompt.innerHTML = deletePrompt.innerHTML.replace("IMGDESCRIPTION", `<span style="color: var(--text-accent);">${imgDescription}</span>`);
          const buttonContainer = modal.contentEl.createDiv();
          buttonContainer.style.display = "flex";
          buttonContainer.style.justifyContent = "flex-end";
          buttonContainer.style.gap = "10px";
          const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
          const deleteButton = buttonContainer.createEl("button", {
            text: "Delete",
            cls: "mod-warning"
          });
          cancelButton.onclick = () => {
            modal.close();
            resolve(false);
          };
          deleteButton.onclick = () => {
            modal.close();
            resolve(true);
          };
          modal.open();
        });
      }
      async deleteImage(imageId, imgDescription) {
        const confirmed = await this.confirmDelete(imgDescription);
        if (!confirmed) return;
        const deleteUrl = new URL(PIXEL_BANNER_PLUS.ENDPOINTS.HISTORY_DELETE, PIXEL_BANNER_PLUS.API_URL).toString();
        const response = await (0, import_obsidian14.requestUrl)({
          url: `${deleteUrl}/${imageId}`,
          method: "DELETE",
          headers: {
            "X-User-Email": this.plugin.settings.pixelBannerPlusEmail,
            "X-API-Key": this.plugin.settings.pixelBannerPlusApiKey,
            "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
            "Accept": "application/json"
          }
        });
        if (response.status === 200) {
          new import_obsidian14.Notice("Image deleted successfully");
          this.refreshHistoryContainer();
        } else {
          new import_obsidian14.Notice("Failed to delete image");
        }
      }
      async onOpen() {
        const { contentEl } = this;
        contentEl.empty();
        this.showLoadingSpinner(contentEl);
        this.initializeModal().catch((error) => {
          console.error("Error initializing modal:", error);
          this.hideLoadingSpinner();
          contentEl.createEl("p", {
            text: "Failed to load AI banner generator. Please try again later.",
            cls: "pixel-banner-error"
          });
        });
      }
      // Initialize modal content
      async initializeModal() {
        await this.plugin.verifyPixelBannerPlusCredentials();
        const { contentEl } = this;
        let modelsLoaded = false;
        if (this.plugin.pixelBannerPlusEnabled) {
          modelsLoaded = await this.fetchAvailableModels();
        }
        const styleTag = contentEl.createEl("style", {
          text: `
                /* AI Banner Generation Modal */
                .pixel-banner-ai-modal {
                    display: flex;
                    flex-direction: column;
                    align-items: stretch;
                    padding: 20px;
                    width: var(--dialog-max-width);
                    top: unset !important;
                    overflow-x: hidden;
                }

                .pixel-banner-ai-modal .modal-content {
                    display: flex;
                    flex-direction: column;
                    align-items: center;
                }

                .pixel-banner-ai-modal .setting-item {
                    border: none;
                    padding: 0.75rem 0;
                }

                .pixel-banner-ai-modal .full-width-input {
                    width: 100%;
                }

                .pixel-banner-ai-modal input[type="range"] {
                    width: 100%;
                }

                .pixel-banner-ai-modal .pixel-banner-ai-control-row {
                    display: flex;
                    flex-direction: row;
                    gap: 5px;
                    justify-content: space-between;
                    max-width: 500px;
                    width: 100%;
                }

                .pixel-banner-generate-btn-container {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    margin-top: 1rem;
                    gap: 1rem;
                }

                .pixel-banner-token-balance {
                    color: var(--text-muted);
                    font-size: 0.9em;
                }

                .pixel-banner-generate-btn-container button {
                    min-width: 150px;
                }

                .pixel-banner-image-controls {
                    margin-top: 10px;
                    display: flex;
                    justify-content: center;
                    gap: 10px;
                }

                .pixel-banner-generated-image-wrapper {
                    width: 100%;
                    border-radius: 8px;
                    overflow: hidden;
                    background: var(--background-secondary);

                }

                .pixel-banner-generated-image {
                    width: inherit;
                    height: auto;
                    display: block;
                    animation: pixel-banner-fade-in 1300ms ease-in-out;
                    margin: 0 auto;
                }

                /* History container styles */
                .pixel-banner-history-container {
                    display: flex;
                    flex-direction: row;
                    flex-wrap: wrap;
                    justify-content: center;
                    gap: 1rem;
                    margin-top: 2rem;
                    padding: 1rem;
                    border-top: 1px solid var(--background-modifier-border);
                    place-items: start center; /* Ensures the grid is centered while items align naturally */
                }

                /* Image wrapper with masonry alignment */
                .pixel-banner-history-image-wrapper {
                    position: relative;
                    cursor: pointer;
                    border-radius: 8px;
                    border: 5px solid transparent;
                    overflow: hidden;
                    transition: transform 0.2s ease;
                    display: flex;
                    justify-content: center; /* Centers image inside the wrapper */
                    align-items: center;
                    max-width: 300px;
                    max-height: 300px;
                    animation: pixel-banner-fade-in 1300ms ease-in-out;
                }

                /* Hover effect */
                .pixel-banner-history-image-wrapper:hover {
                    transform: scale(1.25);
                    z-index: 2;
                    border-color: var(--modal-border-color) !important;
                }

                /* Ensuring images keep aspect ratio */
                .pixel-banner-history-image {
                    width: 100%;
                    height: auto; /* Maintain height for masonry */
                    object-fit: cover;
                    border-radius: 8px;
                }

                /* Tooltip styles */
                .pixel-banner-history-image-wrapper.has-tooltip {
                    position: relative;
                }

                /* Tooltip on hover */
                .pixel-banner-history-image-wrapper.has-tooltip:hover::after {
                    content: attr(aria-label);
                    position: absolute;
                    bottom: 100%;
                    left: 50%;
                    transform: translateX(-50%);
                    background: var(--background-primary);
                    color: var(--text-normal);
                    padding: 4px 8px;
                    border-radius: 4px;
                    font-size: 12px;
                    white-space: nowrap;
                    z-index: 100;
                    box-shadow: var(--shadow-s);
                    margin-bottom: 4px;
                }

                /* Error message styling */
                .pixel-banner-history-container .pixel-banner-error {
                    color: var(--text-accent);
                    font-size: 12px;
                    text-align: center;
                    padding: 8px;
                }

                .pixel-banner-input-container {
                    display: flex;
                    gap: 8px;
                    width: 100%;
                }

                .pixel-banner-input-container input {
                    flex: 1;
                }

                .pixel-banner-prompt-inspiration-container {
                    display: flex;
                    flex-direction: row;
                    gap: 5px;
                    align-items: center;
                    justify-content: center;
                    width: 100%;
                }
                .pixel-banner-prompt-inspiration-container > button {
                    margin: 0;
                    flex: 1;
                    border: 1px solid var(--modal-border-color);
                    text-transform: uppercase;
                    font-size: 0.8em;
                    letter-spacing: 1px;
                }
                .pixel-banner-inspiration-button,
                .pixel-banner-inspiration-from-seed-button,
                .pixel-banner-rewrite-button {
                    padding: 4px 12px;
                    border-radius: 4px;
                    cursor: pointer;
                    background-color: var(--interactive-accent);
                    color: var(--text-on-accent);
                    border: none;
                    font-size: 16px;
                    margin-left: 10px;
                }
                .pixel-banner-inspiration-button:hover,
                .pixel-banner-inspiration-from-seed-button:hover,
                .pixel-banner-rewrite-button:hover {
                    background-color: var(--interactive-accent-hover);
                }
                .pixel-banner-inspiration-button:disabled,
                .pixel-banner-inspiration-from-seed-button:disabled,
                .pixel-banner-rewrite-button:disabled {
                    opacity: 0.7;
                    cursor: not-allowed;
                    background-color: var(--interactive-accent);
                }

                /* ------------------- */
                /* -- mobile layout -- */
                /* ------------------- */
                @media screen and (max-width: 550px) {
                    .pixel-banner-prompt-description { display: none; }
                    .setting-item.pixel-banner-ai-prompt-container {
                        max-width: var(--dialog-max-width) !important;
                        padding-left: 20px;
                        padding-right: 20px;
                    }
                    .pixel-banner-prompt-inspiration-container { flex-direction: column !important; }
                    .pixel-banner-prompt-inspiration-container button { width: 100% !important; }
                    .pixel-banner-generate-btn-container { flex-direction: column !important; }
                    .pixel-banner-generate-btn-container button { width: 100% !important; }
                }
                /* ------------------- */
            `
        });
        contentEl.createEl("h2", {
          text: "\u2728 Generate a Banner with AI",
          cls: "margin-top-0",
          attr: {
            "style": `
                    margin-bottom: 0px;
                    text-align: center;
                `
          }
        });
        const promptAllowedSection = contentEl.createDiv({
          cls: "prompt-allowed-section",
          attr: {
            "style": `
                    display: ${this.plugin.pixelBannerPlusBannerTokens === 0 ? "none" : "block"};
                `
          }
        });
        const promptContainer = promptAllowedSection.createDiv({
          cls: "setting-item pixel-banner-ai-prompt-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: column;
                    align-items: flex-start;
                    max-width: 500px;
                    width: 100%;
                `
          }
        });
        promptContainer.createDiv({ cls: "setting-item-name", text: "\u{1F58B}\uFE0F Creative Banner Prompt" });
        promptContainer.createDiv({
          cls: "setting-item-description",
          text: 'TIP \u21E2 Type a few words and then press the "\u{1F331} GROW IDEA" button to transform your basic idea into something special! Select a Model and then click "\u2728 Generate Banner".',
          attr: {
            "style": `
                    color: var(--text-muted); 
                    font-size: .8em;
                `
          }
        });
        const promptControl = promptContainer.createDiv({
          cls: "setting-item-control",
          attr: {
            "style": `
                    display: flex;
                    flex-direction: column;
                    align-items: flex-start;
                    margin-top: 10px !important;
                    width: 100% !important;
                `
          }
        });
        const promptInput = promptControl.createEl("textarea", {
          cls: "full-width-input",
          attr: {
            id: "ai-banner-prompt",
            rows: 7
          }
        });
        promptInput.value = this.prompt;
        promptInput.addEventListener("input", (e) => {
          this.prompt = e.target.value;
        });
        const promptInspirationContainer = promptControl.createDiv({ cls: "pixel-banner-prompt-inspiration-container" });
        const inspirationButton = promptInspirationContainer.createEl("button", {
          cls: "pixel-banner-inspiration-button",
          text: "\u{1F4A1} INSPIRATION"
        });
        inspirationButton.addEventListener("click", () => this.getPromptInspiration());
        const inspirationFromSeedButton = promptInspirationContainer.createEl("button", {
          cls: "pixel-banner-inspiration-from-seed-button",
          text: "\u{1F331} GROW IDEA",
          attr: {
            style: `
                    border-bottom: 1px solid var(--interactive-accent-hover);
                `
          }
        });
        inspirationFromSeedButton.addEventListener("click", () => this.getPromptInspirationFromSeed());
        const rewritePromptButton = promptInspirationContainer.createEl("button", {
          cls: "pixel-banner-rewrite-button",
          text: "\u270F\uFE0F REWRITE",
          attr: {
            style: `
                    border-bottom: 1px solid var(--interactive-accent-hover);
                `
          }
        });
        rewritePromptButton.addEventListener("click", () => this.rewritePrompt());
        const inspirationClearButton = promptInspirationContainer.createEl("button", {
          cls: "pixel-banner-inspiration-clear-button",
          text: "\u{1F5D1}\uFE0F CLEAR"
        });
        inspirationClearButton.addEventListener("click", () => this.clearPromptInspiration());
        const modelContainer = promptAllowedSection.createDiv({
          cls: "setting-item pixel-banner-ai-control-row",
          attr: {
            style: `
                    align-items: center;
                    padding-bottom: 0;
                `
          }
        });
        if (!modelsLoaded || Object.keys(this.availableModels).length === 0) {
          modelContainer.empty();
          modelContainer.createEl("p", {
            text: "No AI models available. Please try again later.",
            cls: "pixel-banner-error"
          });
          return;
        }
        const hasModels = this.renderModelSelection(modelContainer);
        if (!hasModels) {
          modelContainer.empty();
          modelContainer.createEl("p", {
            text: "No enabled AI models available.",
            cls: "pixel-banner-error"
          });
          return;
        }
        this.controlsContainer = promptAllowedSection.createDiv({
          cls: "pixel-banner-dynamic-controls",
          attr: {
            style: `
                    display: flex;
                    flex-direction: column;
                    gap: 15px;
                    margin-top: 10px;
                    width: 100%;
                    max-width: 500px;
                `
          }
        });
        this.renderModelControls();
        const promptDisallowedSection = contentEl.createDiv({
          cls: "prompt-disallowed-section",
          attr: {
            "style": `
                    display: ${this.plugin.pixelBannerPlusBannerTokens === 0 || !this.plugin.pixelBannerPlusEnabled ? "block" : "none"};
                    max-width: 500px;
                    margin-top: 20px;
                `
          }
        });
        promptDisallowedSection.createEl("p", {
          text: "You have no remaining banner tokens \u{1F62D}. Please purchase more tokens to generate a banner. Your previous banners (if any) will still be available for download below.",
          attr: {
            "style": `
                    display: ${this.plugin.pixelBannerPlusEnabled ? "block" : "none"};
                    color: var(--text-muted);
                    font-size: 1.1em;
                    text-align: center;
                `
          }
        });
        promptDisallowedSection.createEl("p", {
          attr: {
            "style": `
                    display: ${!this.plugin.pixelBannerPlusEnabled ? "block" : "none"};
                    color: var(--text-muted);
                    font-size: 1.1em;
                    text-align: center;
                `
          }
        }).innerHTML = 'You do not have an active <span style="color: var(--text-accent); font-weight: bold;">Pixel Banner Plus</span> account. Please <span style="color: var(--text-accent); font-weight: bold;">Signup for Free</span> or connect to your account in Settings to generate awesome banners with AI \u{1F916}.';
        const buttonContainer = contentEl.createDiv({
          cls: "setting-item pixel-banner-generate-btn-container pixel-banner-ai-control-row",
          attr: {
            "style": `
                    justify-content: ${!this.plugin.pixelBannerPlusEnabled ? "center !important" : "space-between"};
                `
          }
        });
        const tokenBalance = buttonContainer.createDiv({ cls: "pixel-banner-plus-token-balance" });
        tokenBalance.style.display = `${this.plugin.pixelBannerPlusEnabled ? "inline-block" : "none"}`;
        const tokenCountSpan = document.createElement("span");
        tokenCountSpan.style.color = "var(--text-accent)";
        tokenCountSpan.style.fontWeight = "bold";
        tokenCountSpan.style.letterSpacing = "1px";
        tokenCountSpan.innerText = decimalToFractionString(this.plugin.pixelBannerPlusBannerTokens);
        tokenBalance.setText("\u{1FA99} Remaining Tokens: ");
        tokenBalance.appendChild(tokenCountSpan);
        tokenCountSpan.classList.add("token-balance-animation");
        const generateButton = buttonContainer.createEl("button", {
          cls: "mod-cta cursor-pointer radial-pulse-animation",
          text: "\u2728 Generate Banner",
          attr: {
            "style": `
                    display: ${this.plugin.pixelBannerPlusEnabled && this.plugin.pixelBannerPlusBannerTokens > 0 ? "block" : "none"};
                `
          }
        });
        generateButton.addEventListener("click", async () => {
          if (!this.prompt) {
            new import_obsidian14.Notice("Please enter a prompt");
            return;
          }
          await this.generateImage();
        });
        const buyTokensButton = buttonContainer.createEl("button", {
          cls: "mod-cta cursor-pointer radial-pulse-animation",
          text: "\u{1F4B5} Buy More Tokens",
          attr: {
            "style": `
                    display: ${this.plugin.pixelBannerPlusEnabled && this.plugin.pixelBannerPlusBannerTokens === 0 ? "block" : "none"};
                `
          }
        });
        buyTokensButton.addEventListener("click", (event) => {
          event.preventDefault();
          window.open(PIXEL_BANNER_PLUS.SHOP_URL, "_blank");
        });
        const signupButton = buttonContainer.createEl("button", {
          cls: "mod-cta cursor-pointer radial-pulse-animation",
          text: "\u{1F6A9} Signup for Free!",
          attr: {
            "style": `
                    display: ${!this.plugin.pixelBannerPlusEnabled ? "block" : "none"};
                `
          }
        });
        signupButton.addEventListener("click", (event) => {
          event.preventDefault();
          const signupUrl = PIXEL_BANNER_PLUS.API_URL + PIXEL_BANNER_PLUS.ENDPOINTS.SIGNUP;
          window.open(signupUrl, "_blank");
        });
        const backToMainButton = buttonContainer.createEl("button", {
          text: "\u21E0 Main Menu",
          cls: "cursor-pointer",
          attr: {
            style: `
                    width: max-content;
                    min-width: auto;
                `
          }
        });
        backToMainButton.addEventListener("click", () => {
          this.close();
          new SelectPixelBannerModal(this.app, this.plugin).open();
        });
        this.imageContainer = contentEl.createDiv({
          cls: "pixel-banner-image-container",
          attr: {
            "style": `
                    display: ${this.plugin.pixelBannerPlusEnabled && this.plugin.pixelBannerPlusBannerTokens > 0 ? "block" : "none"};
                `
          }
        });
        contentEl.createEl("h5", {
          text: "\u23F3 Previous AI Generated Banners",
          attr: {
            "style": `
                    margin-bottom: -20px;
                    display: ${this.plugin.pixelBannerPlusEnabled ? "block" : "none"};
                `
          }
        });
        const historyContainerDescription = contentEl.createEl("p", {
          text: `Click an image to download and use as a banner. These downloads are always FREE as you have already paid to generate them. Images older than one month are subject to deletion from our servers.`,
          cls: "pixel-banner-history-description",
          attr: {
            style: `
                    font-size: 12px; 
                    color: var(--text-muted); 
                    padding-top: 10px; 
                    margin-bottom: -10px;
                    display: ${this.plugin.pixelBannerPlusEnabled ? "block" : "none"};
                `
          }
        });
        historyContainerDescription.innerHTML = historyContainerDescription.innerHTML.replace(/FREE/g, '<span style="color: var(--color-green); font-weight: bold;">FREE</span>');
        const historyContainer = contentEl.createDiv({
          cls: "pixel-banner-history-container",
          attr: {
            "style": `
                    display: ${this.plugin.pixelBannerPlusEnabled ? "flex" : "none"};
                `
          }
        });
        const paginationContainer = contentEl.createDiv({
          cls: "ai-banner-pagination",
          attr: {
            "style": `
                    display: ${this.plugin.pixelBannerPlusEnabled ? "flex" : "none"};
                `
          }
        });
        if (this.plugin.pixelBannerPlusEnabled) {
          await this.refreshHistoryContainer();
        }
        this.hideLoadingSpinner();
        if (promptInput) {
          setTimeout(() => {
            promptInput.focus();
          }, 100);
        }
        this.hideLoadingSpinner();
      }
      async getPromptInspiration() {
        var _a;
        const inspirationButton = this.contentEl.querySelector(".pixel-banner-inspiration-button");
        const originalText = inspirationButton.textContent;
        const promptTextarea = this.contentEl.querySelector("#ai-banner-prompt");
        try {
          inspirationButton.textContent = "\u23F3";
          inspirationButton.disabled = true;
          const inspirationUrl = new URL(PIXEL_BANNER_PLUS.ENDPOINTS.GENERATE_BANNER_IDEA, PIXEL_BANNER_PLUS.API_URL).toString();
          const response = await (0, import_obsidian14.requestUrl)({
            url: inspirationUrl,
            method: "GET",
            headers: {
              "X-User-Email": this.plugin.settings.pixelBannerPlusEmail,
              "X-API-Key": this.plugin.settings.pixelBannerPlusApiKey,
              "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
              "Accept": "application/json"
            }
          });
          if (response.status === 200 && response.json.bannerIdea) {
            const promptInput = this.contentEl.querySelector("#ai-banner-prompt");
            if (promptInput) {
              let promptIdea = (_a = response.json.bannerIdea) == null ? void 0 : _a.toLowerCase();
              promptIdea = promptIdea.trim();
              promptInput.value = promptIdea;
              this.prompt = promptIdea;
            }
          }
        } catch (error) {
          console.error("Failed to get prompt inspiration:", error);
          new import_obsidian14.Notice("Failed to get prompt inspiration. Please try again.");
        } finally {
          inspirationButton.textContent = originalText;
          inspirationButton.disabled = false;
        }
      }
      async getPromptInspirationFromSeed() {
        var _a;
        const inspirationFromSeedButton = this.contentEl.querySelector(".pixel-banner-inspiration-from-seed-button");
        const originalText = inspirationFromSeedButton.textContent;
        const promptTextarea = this.contentEl.querySelector("#ai-banner-prompt");
        let seed = promptTextarea.value.trim();
        if (seed.length === 0) {
          new import_obsidian14.Notice("Please enter at lease one word in the Prompt box to grow your banner idea from.");
          return;
        }
        try {
          inspirationFromSeedButton.textContent = "\u23F3";
          inspirationFromSeedButton.disabled = true;
          const inspirationUrl = new URL(PIXEL_BANNER_PLUS.ENDPOINTS.GENERATE_BANNER_IDEA_FROM_SEED, PIXEL_BANNER_PLUS.API_URL).toString();
          const response = await (0, import_obsidian14.requestUrl)({
            url: inspirationUrl + `/${seed}`,
            method: "GET",
            headers: {
              "X-User-Email": this.plugin.settings.pixelBannerPlusEmail,
              "X-API-Key": this.plugin.settings.pixelBannerPlusApiKey,
              "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
              "Accept": "application/json"
            }
          });
          if (response.status === 200 && response.json.bannerIdea) {
            const promptInput = this.contentEl.querySelector("#ai-banner-prompt");
            if (promptInput) {
              let promptIdea = (_a = response.json.bannerIdea) == null ? void 0 : _a.toLowerCase();
              promptIdea = promptIdea.trim();
              promptInput.value = promptIdea;
              this.prompt = promptIdea;
            }
          }
        } catch (error) {
          console.error("Failed to get prompt inspiration:", error);
          new import_obsidian14.Notice("Failed to get prompt inspiration. Please try again.");
        } finally {
          inspirationFromSeedButton.textContent = originalText;
          inspirationFromSeedButton.disabled = false;
        }
      }
      async rewritePrompt() {
        var _a;
        const rewritePromptButton = this.contentEl.querySelector(".pixel-banner-rewrite-button");
        const originalText = rewritePromptButton.textContent;
        const promptTextarea = this.contentEl.querySelector("#ai-banner-prompt");
        let seed = promptTextarea.value.trim();
        if (seed.length === 0) {
          new import_obsidian14.Notice("Please enter at lease one word in the Prompt box to generate a rewritten prompt.");
          return;
        }
        try {
          rewritePromptButton.textContent = "\u23F3";
          rewritePromptButton.disabled = true;
          const inspirationUrl = new URL(PIXEL_BANNER_PLUS.ENDPOINTS.REWRITE_BANNER_IDEA, PIXEL_BANNER_PLUS.API_URL).toString();
          const response = await (0, import_obsidian14.requestUrl)({
            url: inspirationUrl + `/${seed}`,
            method: "GET",
            headers: {
              "X-User-Email": this.plugin.settings.pixelBannerPlusEmail,
              "X-API-Key": this.plugin.settings.pixelBannerPlusApiKey,
              "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
              "Accept": "application/json"
            }
          });
          if (response.status === 200 && response.json.bannerIdea) {
            const promptInput = this.contentEl.querySelector("#ai-banner-prompt");
            if (promptInput) {
              let promptIdea = (_a = response.json.bannerIdea) == null ? void 0 : _a.toLowerCase();
              promptIdea = promptIdea.trim();
              promptInput.value = promptIdea;
              this.prompt = promptIdea;
            }
          }
        } catch (error) {
          console.error("Failed to rewrite prompt:", error);
          new import_obsidian14.Notice("Failed to rewrite prompt. Please try again.");
        } finally {
          rewritePromptButton.textContent = originalText;
          rewritePromptButton.disabled = false;
        }
      }
      async clearPromptInspiration() {
        const promptTextarea = this.contentEl.querySelector("#ai-banner-prompt");
        if (promptTextarea) {
          promptTextarea.value = "";
          promptTextarea.focus();
        }
      }
      async refreshHistoryContainer() {
        const styleTag = this.contentEl.createEl("style", {
          text: `
                /* Delete icon for history images */
                .pixel-banner-history-container .pixel-banner-image-delete {
                    position: absolute;
                    top: 8px;
                    right: 8px;
                    width: 24px;
                    height: 24px;
                    background-color: var(--background-secondary);
                    border-radius: 50%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    opacity: .5;
                    transition: opacity 0.2s ease, background-color 0.2s ease;
                    cursor: pointer;
                    z-index: 2;
                }

                .pixel-banner-history-container pixel-banner-history-image-wrapper:hover .pixel-banner-image-delete {
                    opacity: 1;
                }

                .pixel-banner-history-container .pixel-banner-image-delete:hover {
                    background-color: red;
                    color: white;
                    opacity: 1;
                }

                .pixel-banner-history-container .pixel-banner-image-delete svg {
                    width: 16px;
                    height: 16px;
                }
            `
        });
        this.contentEl.appendChild(styleTag);
        const historyContainer = this.contentEl.querySelector(".pixel-banner-history-container");
        if (!historyContainer) return;
        historyContainer.empty();
        try {
          const countUrl = new URL(PIXEL_BANNER_PLUS.ENDPOINTS.HISTORY_COUNT, PIXEL_BANNER_PLUS.API_URL).toString();
          const countResponse = await (0, import_obsidian14.requestUrl)({
            url: countUrl,
            method: "GET",
            headers: {
              "X-User-Email": this.plugin.settings.pixelBannerPlusEmail,
              "X-API-Key": this.plugin.settings.pixelBannerPlusApiKey,
              "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
              "Accept": "application/json"
            }
          });
          const countData = JSON.parse(new TextDecoder().decode(countResponse.arrayBuffer));
          if (countResponse.status === 200 && countData.count !== void 0) {
            this.totalItems = countData.count;
            this.totalPages = Math.ceil(this.totalItems / this.itemsPerPage);
          }
          const historyUrl = new URL(`${PIXEL_BANNER_PLUS.ENDPOINTS.HISTORY_PAGE}/${this.currentPage}?limit=${this.itemsPerPage}`, PIXEL_BANNER_PLUS.API_URL).toString();
          const response = await (0, import_obsidian14.requestUrl)({
            url: historyUrl,
            method: "GET",
            headers: {
              "X-User-Email": this.plugin.settings.pixelBannerPlusEmail,
              "X-API-Key": this.plugin.settings.pixelBannerPlusApiKey,
              "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
              "Accept": "application/json"
            }
          });
          if (response.status === 200 && response.json.images) {
            response.json.images.forEach((imageData) => {
              const imgWrapper = this.renderImageItem(imageData, historyContainer);
            });
            this.updatePaginationUI();
          }
        } catch (error) {
          console.error("Failed to fetch history:", error);
          const errorDiv = historyContainer.createDiv({ cls: "pixel-banner-error" });
          errorDiv.setText("Failed to load history. Please try again later.");
        }
      }
      renderImageItem(imageData, container) {
        const imgWrapper = container.createDiv({ cls: "pixel-banner-history-image-wrapper" });
        const img = imgWrapper.createEl("img", {
          cls: "pixel-banner-history-image",
          attr: {
            src: imageData.base64Image,
            "imageId": imageData.imageId,
            "filename": imageData.prompt.trim().substr(0, 47).replace(/\s/g, "-").toLowerCase()
          }
        });
        const deleteBtn = imgWrapper.createDiv({ cls: "pixel-banner-image-delete" });
        const trashIcon = `<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>`;
        deleteBtn.innerHTML = trashIcon;
        deleteBtn.addEventListener("click", async (e) => {
          e.stopPropagation();
          e.preventDefault();
          await this.deleteImage(imageData.imageId, imageData.prompt);
        });
        let promptText = imageData.prompt;
        if (promptText.length > 70) {
          promptText = promptText.substring(0, 70) + "...";
        }
        imgWrapper.setAttribute("aria-label", `Download \u21E2 ${promptText}`);
        imgWrapper.addClass("has-tooltip");
        imgWrapper.addEventListener("click", async () => {
          const shouldDownload = await this.checkDownloadHistory(img);
          if (!shouldDownload) return;
          const filename = img.getAttribute("filename");
          const savedPath = await handlePinIconClick(imageData.base64Image, this.plugin, null, filename, false);
          this.downloadHistory.addImage(img.getAttribute("imageid"));
          this.close();
          const activeFile = this.plugin.app.workspace.getActiveFile();
          if (!activeFile || !savedPath) return;
          await this.plugin.app.fileManager.processFrontMatter(activeFile, (frontmatter) => {
            const bannerField = this.plugin.settings.customBannerField[0];
            const format = this.plugin.settings.imagePropertyFormat;
            let bannerValue;
            if (format === "image") {
              bannerValue = savedPath;
            } else if (format === "[[image]]") {
              bannerValue = `[[${savedPath}]]`;
            } else {
              bannerValue = `![[${savedPath}]]`;
            }
            frontmatter[bannerField] = bannerValue;
          });
          if (this.plugin.settings.openTargetingModalAfterSelectingBannerOrIcon) {
            new TargetPositionModal(this.app, this.plugin).open();
          }
        });
        return imgWrapper;
      }
      async updateHistoryContent() {
        const historyContainer = this.contentEl.querySelector(".pixel-banner-history-container");
        if (!historyContainer) return;
        const scrollPos = this.contentEl.scrollTop;
        const containerHeight = historyContainer.offsetHeight;
        historyContainer.style.minHeight = `${containerHeight}px`;
        historyContainer.addClass("loading");
        historyContainer.empty();
        const loadingDiv = historyContainer.createDiv({ cls: "pixel-banner-loading" });
        loadingDiv.createDiv({ cls: "dot-pulse" });
        try {
          const historyUrl = new URL(`${PIXEL_BANNER_PLUS.ENDPOINTS.HISTORY_PAGE}/${this.currentPage}?limit=${this.itemsPerPage}`, PIXEL_BANNER_PLUS.API_URL).toString();
          const response = await (0, import_obsidian14.requestUrl)({
            url: historyUrl,
            method: "GET",
            headers: {
              "X-User-Email": this.plugin.settings.pixelBannerPlusEmail,
              "X-API-Key": this.plugin.settings.pixelBannerPlusApiKey,
              "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
              "Accept": "application/json"
            }
          });
          if (response.status === 200 && response.json.images) {
            historyContainer.empty();
            response.json.images.forEach((imageData) => {
              const imgWrapper = this.renderImageItem(imageData, historyContainer);
            });
          }
          this.updatePaginationUI();
          this.contentEl.scrollTo({
            top: this.contentEl.scrollHeight,
            behavior: "smooth"
          });
        } catch (error) {
          console.error("Failed to fetch history:", error);
          const errorDiv = historyContainer.createDiv({ cls: "pixel-banner-error" });
          errorDiv.setText("Failed to load history. Please try again later.");
        } finally {
          historyContainer.removeClass("loading");
          setTimeout(() => {
            historyContainer.style.minHeight = "";
          }, 300);
        }
      }
      updatePaginationUI() {
        let paginationContainer = this.contentEl.querySelector(".ai-banner-pagination");
        if (!paginationContainer) {
          paginationContainer = this.contentEl.createDiv({ cls: "ai-banner-pagination" });
        }
        paginationContainer.empty();
        const firstButton = paginationContainer.createEl("button", {
          text: "\xAB"
        });
        firstButton.disabled = this.currentPage <= 1;
        if (firstButton.disabled) {
          firstButton.addClass("disabled");
        }
        const prevButton = paginationContainer.createEl("button", {
          text: "\u2039"
        });
        prevButton.disabled = this.currentPage <= 1;
        if (prevButton.disabled) {
          prevButton.addClass("disabled");
        }
        const pageInfo = paginationContainer.createSpan({
          text: `${this.currentPage} of ${this.totalPages}`
        });
        const nextButton = paginationContainer.createEl("button", {
          text: "\u203A"
        });
        nextButton.disabled = this.currentPage >= this.totalPages;
        if (nextButton.disabled) {
          nextButton.addClass("disabled");
        }
        const lastButton = paginationContainer.createEl("button", {
          text: "\xBB"
        });
        lastButton.disabled = this.currentPage >= this.totalPages;
        if (lastButton.disabled) {
          lastButton.addClass("disabled");
        }
        firstButton.addEventListener("click", async (e) => {
          if (this.currentPage > 1) {
            this.currentPage = 1;
            await this.updateHistoryContent();
          }
        });
        prevButton.addEventListener("click", async (e) => {
          if (this.currentPage > 1) {
            this.currentPage--;
            await this.updateHistoryContent();
          }
        });
        nextButton.addEventListener("click", async (e) => {
          if (this.currentPage < this.totalPages) {
            this.currentPage++;
            await this.updateHistoryContent();
          }
        });
        lastButton.addEventListener("click", async (e) => {
          if (this.currentPage < this.totalPages) {
            this.currentPage = this.totalPages;
            await this.updateHistoryContent();
          }
        });
      }
      onClose() {
        const { contentEl } = this;
        contentEl.empty();
        if (this.styleEl) {
          this.styleEl.remove();
        }
        if (this.loadingOverlay) {
          this.loadingOverlay.remove();
        }
      }
    };
  }
});

// src/modal/modals/imageSelectionModal.js
var import_obsidian15, ImageSelectionModal;
var init_imageSelectionModal = __esm({
  "src/modal/modals/imageSelectionModal.js"() {
    import_obsidian15 = require("obsidian");
    init_generateAIBannerModal();
    init_folderSelectionModal();
    init_saveImageModal();
    init_selectPixelBannerModal();
    ImageSelectionModal = class extends import_obsidian15.Modal {
      constructor(app, plugin, onChoose, defaultPath = "") {
        super(app);
        this.plugin = plugin;
        this.onChoose = onChoose;
        this.defaultPath = defaultPath;
        this.searchQuery = defaultPath.toLowerCase();
        this.currentPage = 1;
        this.imagesPerPage = 20;
        this.sortOrder = "name-asc";
        this.imageFiles = this.app.vault.getFiles().filter((file) => file.extension.toLowerCase().match(/^(jpg|jpeg|png|gif|bmp|svg|webp|avif|mp4|mov)$/));
      }
      debounce(func, wait) {
        let timeout;
        return (...args) => {
          clearTimeout(timeout);
          timeout = setTimeout(() => func.apply(this, args), wait);
        };
      }
      async confirmDelete(file) {
        return new Promise((resolve) => {
          const modal = new import_obsidian15.Modal(this.app);
          modal.contentEl.createEl("h2", { text: "Delete Image" });
          modal.contentEl.createEl("p", { text: `Are you sure you want to delete "${file.name}"?` });
          const buttonContainer = modal.contentEl.createDiv();
          buttonContainer.style.display = "flex";
          buttonContainer.style.justifyContent = "flex-end";
          buttonContainer.style.gap = "10px";
          const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
          const deleteButton = buttonContainer.createEl("button", {
            text: "Delete",
            cls: "mod-warning"
          });
          cancelButton.onclick = () => {
            modal.close();
            resolve(false);
          };
          deleteButton.onclick = () => {
            modal.close();
            resolve(true);
          };
          modal.open();
        });
      }
      async deleteImage(file) {
        const confirmed = await this.confirmDelete(file);
        if (!confirmed) return;
        try {
          await this.app.vault.delete(file);
          this.imageFiles = this.imageFiles.filter((f) => f.path !== file.path);
          this.updateImageGrid();
        } catch (error) {
          new import_obsidian15.Notice(`Failed to delete image: ${error.message}`);
        }
      }
      onOpen() {
        this.modalEl.addClass("pixel-banner-image-select-modal");
        const { contentEl } = this;
        contentEl.empty();
        const style = document.createElement("style");
        style.textContent = `
            .pixel-banner-image-modal {
                width: var(--dialog-max-width);
                top: unset !important;
            }

            .pixel-banner-image-select-modal {
                top: unset !important;
                width: var(--dialog-max-width);
                max-width: 1100px;
            }

            .pixel-banner-image-select-modal .pixel-banner-image-delete {
                position: absolute;
                top: 8px;
                right: 8px;
                width: 24px;
                height: 24px;
                background-color: var(--background-secondary);
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                opacity: .5;
                transition: opacity 0.2s ease, background-color 0.2s ease;
                cursor: pointer;
                z-index: 2;
            }

            .pixel-banner-image-select-modal .pixel-banner-image-wrapper:hover .pixel-banner-image-delete {
                opacity: 1;
            }

            .pixel-banner-image-select-modal .pixel-banner-image-delete:hover {
                background-color: red;
                color: white;
                opacity: 1;
            }

            .pixel-banner-image-select-modal .pixel-banner-image-delete svg {
                width: 16px;
                height: 16px;
            }

            .pixel-banner-image-select-description {
                margin-top: -15px;
                font-size: 0.8em;
                word-break: break-all;
                color: var(--text-muted);
                margin-bottom: 15px;
            }

            .pixel-banner-search-container {
                margin-bottom: 1rem;
            }
            
            .pixel-banner-search-container input {
                width: 100%;
                padding: 8px;
                border-radius: 4px;
                border: 1px solid var(--background-modifier-border);
            }

            .pixel-banner-search-container .search-row {
                flex: 1;
                display: flex;
                gap: 8px;
                margin: 0;
            }

            .pixel-banner-search-container .controls-row {
                flex: 0 auto;
                display: flex;
                gap: 8px;
                margin: 0;
            }

            .pixel-banner-image-thumbnail {
                width: 100%;
                height: 150px;
                object-fit: cover;
                border-radius: 2px;
            }

            .pixel-banner-image-path {
                margin-top: 8px;
                font-size: 0.8em;
                word-break: break-all;
                color: var(--text-muted);
            }

            .pixel-banner-image-error {
                height: 150px;
                display: flex;
                align-items: center;
                justify-content: center;
                background-color: var(--background-modifier-error);
                color: var(--text-error);
                border-radius: 2px;
            }

            .pixel-banner-image-grid {
                display: grid;
                grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
                gap: 1rem;
                padding: 0 1rem;
                overflow-y: auto;
                max-height: 60vh;
            }

            .pixel-banner-pagination-button {
                padding: 4px 8px;
                border-radius: 4px;
                background: var(--background-secondary);
                border: 1px solid var(--background-modifier-border);
                cursor: pointer;
                font-size: 14px;
                line-height: 1;
            }
            
            .pixel-banner-pagination-button:hover:not(.disabled) {
                background: var(--background-modifier-hover);
            }
            
            .pixel-banner-pagination-button.disabled {
                opacity: 0.5;
                cursor: not-allowed;
            }
            
            .pixel-banner-pagination-info {
                font-size: 14px;
                color: var(--text-muted);
            }
            
            .pixel-banner-image-container {
                cursor: pointer;
                border-radius: 6px;
                border: 1px solid var(--background-modifier-border);
                transition: transform 0.2s ease, box-shadow 0.2s ease;
                position: relative;
            }
            
            .pixel-banner-image-container:hover {
                transform: translateY(-2px);
                box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            }
            
            .pixel-banner-image-grid {
                display: grid;
                grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
                gap: 15px;
                margin-top: 15px;
                max-height: 60vh;
                overflow-y: auto;
                padding: 5px;
            }
            
            .pixel-banner-no-images {
                width: 100%;
                height: 200px;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 1.2em;
                color: var(--text-muted);
                border: 1px dashed var(--background-modifier-border);
                border-radius: 8px;
                background-color: var(--background-secondary);
                grid-column: 1 / -1;
                text-align: center;
                padding: 20px;
            }
            
            .pixel-banner-image-thumbnail {
                width: 100%;
                height: 150px;
                object-fit: cover;
                display: block;
            }
            
            .pixel-banner-image-info {
                padding: 8px;
                font-size: 12px;
                background: var(--background-secondary);
            }
            
            .pixel-banner-image-path {
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
                margin-bottom: 4px;
            }
            
            .pixel-banner-image-delete {
                position: absolute;
                top: 5px;
                right: 5px;
                background: rgba(0, 0, 0, 0.5);
                border-radius: 50%;
                width: 24px;
                height: 24px;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                opacity: 0;
                transition: opacity 0.2s ease;
            }
            
            .pixel-banner-image-container:hover .pixel-banner-image-delete {
                opacity: 1;
            }
            
            .pixel-banner-image-delete svg {
                width: 16px;
                height: 16px;
                color: white;
            }

            /* ------------------- */
            /* -- mobile layout -- */
            /* ------------------- */
            @media screen and (max-width: 550px) {
                .pixel-banner-pagination { flex-direction: column !important; }
                .pixel-banner-pagination .pixel-banner-controls { flex-direction: column !important; }
            }

            @media screen and (max-width: 775px) {
                .pixel-banner-search-container {
                    flex-direction: column !important;
                    gap: 8px !important;
                }

                .pixel-banner-search-container .search-row {
                    display: flex;
                    width: 100%;
                    gap: 8px;
                }

                .pixel-banner-search-container .controls-row {
                    display: flex;
                    width: 100%;
                    gap: 8px;
                    align-items: center;
                }

                .pixel-banner-search-container input[type="text"] {
                    flex: 1;
                }
            }
        `;
        document.head.appendChild(style);
        this.style = style;
        contentEl.createEl("h2", { text: "\u{1F4BE} Select Banner Image", cls: "margin-top-0" });
        contentEl.createEl("div", {
          text: "Select an image from your vault or upload a new one.",
          cls: "pixel-banner-image-select-description"
        });
        const searchContainer = contentEl.createDiv({ cls: "pixel-banner-search-container" });
        searchContainer.style.display = "flex";
        searchContainer.style.gap = "8px";
        searchContainer.style.alignItems = "center";
        searchContainer.style.marginBottom = "1em";
        const searchRow = searchContainer.createDiv({ cls: "search-row" });
        const searchInput = searchRow.createEl("input", {
          type: "text",
          placeholder: "Search images...",
          value: this.defaultPath
        });
        searchInput.style.flex = "1";
        const clearButton = searchRow.createEl("button", {
          text: "Clear"
        });
        const controlsRow = searchContainer.createDiv({ cls: "controls-row" });
        if (this.plugin.pixelBannerPlusEnabled && this.plugin.pixelBannerPlusServerOnline) {
          const pixelBannerPlusGenAIButton = controlsRow.createEl("button");
          pixelBannerPlusGenAIButton.addClass("radial-pulse-animation");
          const sparkleSpan = pixelBannerPlusGenAIButton.createSpan({ cls: "pixel-banner-twinkle-animation", text: "\u2728 " });
          pixelBannerPlusGenAIButton.createSpan({ cls: "margin-left-5", text: "AI" });
          pixelBannerPlusGenAIButton.addEventListener("click", () => {
            this.close();
            new GenerateAIBannerModal(this.app, this.plugin).open();
          });
        }
        const uploadButton = controlsRow.createEl("button", {
          text: "\u{1F4E4} Upload"
        });
        uploadButton.addEventListener("click", () => {
          fileInput.click();
        });
        const toggleContainer = controlsRow.createDiv({
          cls: "pixel-banner-path-toggle",
          attr: {
            style: "display: flex; align-items: center; gap: 8px;"
          }
        });
        const toggleLabel = toggleContainer.createSpan({
          text: "Use short path",
          attr: {
            style: "font-size: 12px; color: var(--text-muted);"
          }
        });
        const toggle = new import_obsidian15.Setting(toggleContainer).addToggle((cb) => {
          cb.setValue(this.plugin.settings.useShortPath).onChange(async (value) => {
            this.plugin.settings.useShortPath = value;
            await this.plugin.saveSettings();
          });
        });
        toggle.settingEl.style.border = "none";
        toggle.settingEl.style.padding = "0";
        toggle.settingEl.style.margin = "0";
        toggle.infoEl.remove();
        const fileInput = searchContainer.createEl("input", {
          type: "file",
          attr: {
            accept: "image/*,video/mp4,video/quicktime",
            style: "display: none;"
          }
        });
        fileInput.addEventListener("change", async (event) => {
          const file = event.target.files[0];
          if (file) {
            const reader = new FileReader();
            reader.onload = async () => {
              const arrayBuffer = reader.result;
              const defaultFolder = this.plugin.settings.pinnedImageFolder || "";
              const folderPath = await new Promise((resolve) => {
                new FolderSelectionModal(this.app, defaultFolder, (result) => {
                  resolve(result);
                }).open();
              });
              if (!folderPath) {
                new import_obsidian15.Notice("No folder selected");
                return;
              }
              if (!await this.app.vault.adapter.exists(folderPath)) {
                await this.app.vault.createFolder(folderPath);
              }
              const suggestedName = file.name;
              const fileName = await new Promise((resolve) => {
                new SaveImageModal(this.app, suggestedName, (result) => {
                  resolve(result);
                }).open();
              });
              if (!fileName) {
                new import_obsidian15.Notice("No file name provided");
                return;
              }
              try {
                const fullPath = `${folderPath}/${fileName}`.replace(/\/+/g, "/");
                const newFile = await this.app.vault.createBinary(fullPath, arrayBuffer);
                this.onChoose(newFile);
                this.close();
              } catch (error) {
                new import_obsidian15.Notice("Failed to save image: " + error.message);
              }
            };
            reader.readAsArrayBuffer(file);
          }
        });
        clearButton.addEventListener("click", () => {
          searchInput.value = "";
          this.searchQuery = "";
          this.updateImageGrid();
        });
        searchInput.addEventListener("input", this.debounce(() => {
          this.searchQuery = searchInput.value.toLowerCase();
          this.updateImageGrid();
        }, 500));
        this.gridContainer = contentEl.createDiv({ cls: "pixel-banner-image-grid" });
        this.paginationContainer = contentEl.createDiv({
          cls: "pixel-banner-pagination",
          attr: {
            style: `
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    gap: 10px;
                    flex-wrap: wrap;
                    margin-top: 15px;
                `
          }
        });
        this.updateImageGrid();
        const modalEl = this.modalEl;
        modalEl.style.position = "absolute";
        modalEl.style.left = `${modalEl.getBoundingClientRect().left}px`;
        modalEl.style.top = `${modalEl.getBoundingClientRect().top}px`;
      }
      updateImageGrid() {
        this.gridContainer.empty();
        this.paginationContainer.empty();
        let filteredFiles = this.imageFiles.filter((file) => {
          const filePath = file.path.toLowerCase();
          const fileName = file.name.toLowerCase();
          return filePath.includes(this.searchQuery) || fileName.includes(this.searchQuery);
        });
        filteredFiles = this.sortFiles(filteredFiles);
        const totalImages = filteredFiles.length;
        const totalPages = Math.ceil(totalImages / this.imagesPerPage);
        const startIndex = (this.currentPage - 1) * this.imagesPerPage;
        const endIndex = Math.min(startIndex + this.imagesPerPage, totalImages);
        const currentFiles = filteredFiles.slice(startIndex, endIndex);
        if (currentFiles.length === 0) {
          const noImagesMessage = this.gridContainer.createEl("div", {
            cls: "pixel-banner-no-images",
            text: filteredFiles.length === 0 ? "\u{1F50D} No images found matching your search." : "No images on this page."
          });
        }
        currentFiles.forEach((file) => {
          const imageContainer = this.gridContainer.createDiv({ cls: "pixel-banner-image-container" });
          const thumbnailContainer = imageContainer.createDiv();
          const fileExt = file.extension.toLowerCase();
          if (fileExt === "svg") {
            this.app.vault.read(file).then((content) => {
              const parser = new DOMParser();
              const svgDoc = parser.parseFromString(content, "image/svg+xml");
              const svgElement = svgDoc.documentElement;
              svgElement.classList.add("pixel-banner-image-thumbnail");
              svgElement.style.width = "100%";
              svgElement.style.height = "100%";
              thumbnailContainer.empty();
              thumbnailContainer.appendChild(svgElement);
            }).catch(() => {
              thumbnailContainer.createEl("div", {
                cls: "pixel-banner-image-error",
                text: "Error loading SVG"
              });
            });
          } else if (fileExt === "mp4" || fileExt === "mov") {
            const resourcePath = this.app.vault.getResourcePath(file);
            const video = thumbnailContainer.createEl("video", {
              cls: "pixel-banner-video-thumbnail",
              attr: {
                src: resourcePath,
                preload: "metadata",
                muted: true
              }
            });
            video.style.width = "100%";
            video.style.height = "100%";
            video.style.objectFit = "cover";
            video.addEventListener("loadedmetadata", () => {
              video.currentTime = Math.min(1, video.duration / 4);
            });
            const videoOverlay = thumbnailContainer.createDiv({ cls: "pixel-banner-video-overlay" });
            videoOverlay.innerHTML = "\u25B6\uFE0F";
            videoOverlay.style.cssText = `
                    position: absolute;
                    top: 50%;
                    left: 50%;
                    transform: translate(-50%, -50%);
                    font-size: 24px;
                    background: rgba(0, 0, 0, 0.7);
                    border-radius: 50%;
                    padding: 8px;
                    pointer-events: none;
                `;
          } else {
            this.app.vault.readBinary(file).then((arrayBuffer) => {
              const blob = new Blob([arrayBuffer]);
              const url = URL.createObjectURL(blob);
              const img = thumbnailContainer.createEl("img", {
                cls: "pixel-banner-image-thumbnail",
                attr: { src: url }
              });
              const cleanup = () => URL.revokeObjectURL(url);
              img.addEventListener("load", cleanup);
              img.addEventListener("error", cleanup);
            }).catch(() => {
              thumbnailContainer.createEl("div", {
                cls: "pixel-banner-image-error",
                text: "Error loading image"
              });
            });
          }
          const infoContainer = imageContainer.createDiv("pixel-banner-image-info");
          infoContainer.createEl("div", {
            cls: "pixel-banner-image-path",
            text: file.path
          });
          const statsContainer = infoContainer.createDiv("pixel-banner-image-stats");
          statsContainer.style.fontSize = "0.8em";
          statsContainer.style.color = "var(--text-muted)";
          const fileSize = this.formatFileSize(file.stat.size);
          const modifiedDate = this.formatDate(file.stat.mtime);
          statsContainer.createEl("span", {
            text: `${fileSize} \u2022 ${modifiedDate}`
          });
          const deleteBtn = imageContainer.createDiv({ cls: "pixel-banner-image-delete" });
          const trashIcon = `<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>`;
          deleteBtn.innerHTML = trashIcon;
          deleteBtn.addEventListener("click", (e) => {
            e.stopPropagation();
            this.deleteImage(file);
          });
          imageContainer.addEventListener("click", () => {
            this.onChoose(file);
            this.close();
          });
        });
        const paginationContainer = this.paginationContainer;
        paginationContainer.innerHTML = "";
        paginationContainer.style.display = "flex";
        paginationContainer.style.alignItems = "center";
        paginationContainer.style.justifyContent = "center";
        paginationContainer.style.gap = "10px";
        paginationContainer.style.marginTop = "15px";
        const controlsContainer = paginationContainer.createDiv({
          cls: "pixel-banner-controls",
          attr: {
            style: `
                    display: flex;
                    justify-content: center;
                    gap: 20px;
                    align-items: center;
                    margin-left: auto;
                    margin-right: auto;
                `
          }
        });
        const sortContainer = controlsContainer.createDiv({ cls: "pixel-banner-sort-container" });
        sortContainer.style.display = "flex";
        sortContainer.style.alignItems = "center";
        sortContainer.style.gap = "5px";
        const sortLabel = sortContainer.createEl("span", {
          text: "Sort by:",
          attr: {
            style: "font-size: 14px; color: var(--text-muted);"
          }
        });
        const sortSelect = sortContainer.createEl("select", { cls: "dropdown" });
        const sortOptions = [
          { value: "name-asc", label: "Name (A-Z)" },
          { value: "name-desc", label: "Name (Z-A)" },
          { value: "date-desc", label: "Date (Newest)" },
          { value: "date-asc", label: "Date (Oldest)" },
          { value: "size-desc", label: "Size (Largest)" },
          { value: "size-asc", label: "Size (Smallest)" }
        ];
        sortOptions.forEach((option) => {
          const optionEl = sortSelect.createEl("option", {
            value: option.value,
            text: option.label
          });
          if (option.value === this.sortOrder) {
            optionEl.selected = true;
          }
        });
        sortSelect.addEventListener("change", () => {
          this.sortOrder = sortSelect.value;
          this.currentPage = 1;
          this.updateImageGrid();
        });
        const paginationDiv = controlsContainer.createDiv({ cls: "pixel-banner-pagination-buttons" });
        paginationDiv.style.display = "flex";
        paginationDiv.style.gap = "10px";
        paginationDiv.style.alignItems = "center";
        const firstButton = paginationDiv.createEl("button", {
          text: "\xAB",
          cls: "pixel-banner-pagination-button",
          attr: {
            "aria-label": "First page"
          }
        });
        firstButton.disabled = this.currentPage === 1 || totalImages === 0;
        if (firstButton.disabled) {
          firstButton.addClass("disabled");
        }
        firstButton.onclick = () => {
          if (this.currentPage !== 1) {
            this.currentPage = 1;
            this.updateImageGrid();
          }
        };
        const prevButton = paginationDiv.createEl("button", {
          text: "\u2039",
          cls: "pixel-banner-pagination-button",
          attr: {
            "aria-label": "Previous page"
          }
        });
        prevButton.disabled = this.currentPage === 1 || totalImages === 0;
        if (prevButton.disabled) {
          prevButton.addClass("disabled");
        }
        prevButton.onclick = () => {
          if (this.currentPage > 1) {
            this.currentPage--;
            this.updateImageGrid();
          }
        };
        const pageInfo = paginationDiv.createEl("span", {
          text: `${this.currentPage} / ${totalPages}`,
          cls: "pixel-banner-pagination-info",
          attr: {
            style: "white-space: nowrap;"
          }
        });
        const nextButton = paginationDiv.createEl("button", {
          text: "\u203A",
          cls: "pixel-banner-pagination-button",
          attr: {
            "aria-label": "Next page"
          }
        });
        nextButton.disabled = this.currentPage === totalPages || totalImages === 0;
        if (nextButton.disabled) {
          nextButton.addClass("disabled");
        }
        nextButton.onclick = () => {
          if (this.currentPage < totalPages) {
            this.currentPage++;
            this.updateImageGrid();
          }
        };
        const lastButton = paginationDiv.createEl("button", {
          text: "\xBB",
          cls: "pixel-banner-pagination-button",
          attr: {
            "aria-label": "Last page"
          }
        });
        lastButton.disabled = this.currentPage === totalPages || totalImages === 0;
        if (lastButton.disabled) {
          lastButton.addClass("disabled");
        }
        lastButton.onclick = () => {
          if (this.currentPage !== totalPages) {
            this.currentPage = totalPages;
            this.updateImageGrid();
          }
        };
        const backToMainButton = paginationContainer.createEl("button", {
          text: "\u21E0 Main Menu",
          cls: "pixel-banner-image-select-back-to-main",
          attr: {
            style: `
                    margin-right: 20px;
                    cursor: pointer;
                `
          }
        });
        backToMainButton.addEventListener("click", () => {
          this.close();
          new SelectPixelBannerModal(this.app, this.plugin).open();
        });
      }
      sortFiles(files) {
        return files.sort((a, b) => {
          switch (this.sortOrder) {
            case "name-asc":
              return a.name.localeCompare(b.name);
            case "name-desc":
              return b.name.localeCompare(a.name);
            case "date-desc":
              return b.stat.mtime - a.stat.mtime;
            case "date-asc":
              return a.stat.mtime - b.stat.mtime;
            case "size-desc":
              return b.stat.size - a.stat.size;
            case "size-asc":
              return a.stat.size - b.stat.size;
            default:
              return 0;
          }
        });
      }
      formatFileSize(bytes) {
        if (bytes < 1024) return bytes + " B";
        if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB";
        return (bytes / (1024 * 1024)).toFixed(1) + " MB";
      }
      formatDate(timestamp) {
        const date = new Date(timestamp);
        return date.toLocaleDateString();
      }
      onClose() {
        const { contentEl } = this;
        contentEl.empty();
        if (this.style) {
          this.style.remove();
        }
      }
    };
  }
});

// src/modal/modals/iconFolderSelectionModal.js
var import_obsidian16, IconFolderSelectionModal;
var init_iconFolderSelectionModal = __esm({
  "src/modal/modals/iconFolderSelectionModal.js"() {
    import_obsidian16 = require("obsidian");
    IconFolderSelectionModal = class extends import_obsidian16.FuzzySuggestModal {
      constructor(app, defaultFolder, onChoose) {
        super(app);
        this.defaultFolder = defaultFolder;
        this.onChoose = onChoose;
        this.modalEl.addClass("pixel-banner-icon-image-folder-select-modal");
        const titleDiv = document.createElement("p");
        titleDiv.innerHTML = "\u{1F4BE} Choose a <strong>Folder</strong> to save the selected Icon in your vault";
        titleDiv.style.margin = "10px 0";
        titleDiv.style.padding = "20px 20px 0";
        titleDiv.style.color = "var(--text-accent)";
        titleDiv.style.borderTop = "1px dashed var(--modal-border-color)";
        this.modalEl.appendChild(titleDiv);
        const descriptionDiv = document.createElement("p");
        descriptionDiv.innerHTML = "If you set a default value in settings it will be pre-filled above.<br>Select any folder in your vault to continue.";
        descriptionDiv.style.margin = "0 0 20px 0";
        descriptionDiv.style.padding = "0 20px";
        descriptionDiv.style.color = "var(--text-muted)";
        descriptionDiv.style.fontSize = ".9em";
        this.modalEl.appendChild(descriptionDiv);
        this.setPlaceholder("Select or type folder path to save the Icon Image");
        this.addStyle();
      }
      addStyle() {
        const style = document.createElement("style");
        style.textContent = `
            .prompt.pixel-banner-icon-image-folder-select-modal {
                top: unset !important;
                padding: 20px !important;
            }
            .pixel-banner-icon-image-folder-select-modal .prompt {
                position: fixed !important;
                top: 50% !important;
                left: 50% !important;
                transform: translate(-50%, -50%) !important;
            }
        `;
        document.head.appendChild(style);
        this.style = style;
      }
      onClose() {
        if (this.style) {
          this.style.remove();
        }
      }
      getItems() {
        const folderPaths = this.app.vault.getAllLoadedFiles().filter((file) => file.children).map((folder) => folder.path);
        if (!folderPaths.includes(this.defaultFolder)) {
          folderPaths.unshift(this.defaultFolder);
        }
        return folderPaths;
      }
      getItemText(item) {
        return item;
      }
      onChooseItem(item) {
        this.onChoose(item);
      }
      onOpen() {
        super.onOpen();
        const inputEl = this.inputEl;
        inputEl.value = this.defaultFolder;
        inputEl.focus();
        this.updateSuggestions();
      }
    };
  }
});

// src/utils/getCurrentTheme.js
function getCurrentTheme() {
  return document.body.classList.contains("theme-dark") ? "dark" : "light";
}
var getCurrentTheme_default;
var init_getCurrentTheme = __esm({
  "src/utils/getCurrentTheme.js"() {
    getCurrentTheme_default = getCurrentTheme;
  }
});

// src/modal/modals/targetPositionModal.js
var targetPositionModal_exports = {};
__export(targetPositionModal_exports, {
  TargetPositionModal: () => TargetPositionModal
});
var import_obsidian17, TargetPositionModal;
var init_targetPositionModal = __esm({
  "src/modal/modals/targetPositionModal.js"() {
    import_obsidian17 = require("obsidian");
    init_getCurrentTheme();
    init_modals();
    init_selectPixelBannerModal();
    init_flags();
    init_frontmatterUtils();
    TargetPositionModal = class _TargetPositionModal extends import_obsidian17.Modal {
      constructor(app, plugin, onPositionChange) {
        var _a;
        super(app);
        this.plugin = plugin;
        this.onPositionChange = onPositionChange;
        this.isDragging = false;
        const activeFile = this.app.workspace.getActiveFile();
        const frontmatter = (_a = this.app.metadataCache.getFileCache(activeFile)) == null ? void 0 : _a.frontmatter;
        const alignmentField = Array.isArray(this.plugin.settings.customBannerAlignmentField) ? this.plugin.settings.customBannerAlignmentField[0].split(",")[0].trim() : this.plugin.settings.customBannerAlignmentField;
        this.currentAlignment = (frontmatter == null ? void 0 : frontmatter[alignmentField]) || "center";
        const displayField = Array.isArray(this.plugin.settings.customImageDisplayField) ? this.plugin.settings.customImageDisplayField[0].split(",")[0].trim() : this.plugin.settings.customImageDisplayField;
        this.currentDisplay = (frontmatter == null ? void 0 : frontmatter[displayField]) || this.plugin.settings.imageDisplay;
        const xField = Array.isArray(this.plugin.settings.customXPositionField) ? this.plugin.settings.customXPositionField[0].split(",")[0].trim() : this.plugin.settings.customXPositionField;
        this.currentX = getValueWithZeroCheck([
          frontmatter == null ? void 0 : frontmatter[xField],
          this.plugin.settings.xPosition
        ]);
        const yField = Array.isArray(this.plugin.settings.customYPositionField) ? this.plugin.settings.customYPositionField[0].split(",")[0].trim() : this.plugin.settings.customYPositionField;
        this.currentY = getValueWithZeroCheck([
          frontmatter == null ? void 0 : frontmatter[yField],
          this.plugin.settings.yPosition
        ]);
        const heightField = Array.isArray(this.plugin.settings.customBannerHeightField) ? this.plugin.settings.customBannerHeightField[0].split(",")[0].trim() : this.plugin.settings.customBannerHeightField;
        this.currentHeight = (frontmatter == null ? void 0 : frontmatter[heightField]) || this.plugin.settings.bannerHeight;
        const maxWidthField = Array.isArray(this.plugin.settings.customBannerMaxWidthField) ? this.plugin.settings.customBannerMaxWidthField[0].split(",")[0].trim() : this.plugin.settings.customBannerMaxWidthField;
        const maxWidthValue = frontmatter == null ? void 0 : frontmatter[maxWidthField];
        const directMaxWidth = frontmatter == null ? void 0 : frontmatter["banner-max-width"];
        const maxWidthExists = maxWidthValue !== void 0 && maxWidthValue !== null || directMaxWidth !== void 0 && directMaxWidth !== null;
        const isMaxWidthUnset = !maxWidthExists;
        this.currentMaxWidth = isMaxWidthUnset ? 1928 : parseInt(maxWidthValue || directMaxWidth) || 1928;
        const contentStartPositionField = Array.isArray(this.plugin.settings.customContentStartField) ? this.plugin.settings.customContentStartField[0].split(",")[0].trim() : this.plugin.settings.customContentStartField;
        this.currentContentStartPosition = (frontmatter == null ? void 0 : frontmatter[contentStartPositionField]) || this.plugin.settings.contentStartPosition;
        const bannerIconXPositionField = Array.isArray(this.plugin.settings.customBannerIconXPositionField) ? this.plugin.settings.customBannerIconXPositionField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconXPositionField;
        this.currentBannerIconXPosition = (frontmatter == null ? void 0 : frontmatter[bannerIconXPositionField]) || this.plugin.settings.bannerIconXPosition;
        const bannerIconImageAlignmentField = Array.isArray(this.plugin.settings.customBannerIconImageAlignmentField) ? this.plugin.settings.customBannerIconImageAlignmentField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageAlignmentField;
        const bannerIconRotateField = Array.isArray(this.plugin.settings.customBannerIconRotateField) ? this.plugin.settings.customBannerIconRotateField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconRotateField;
        this.currentBannerIconRotate = getValueWithZeroCheck([
          frontmatter == null ? void 0 : frontmatter[bannerIconRotateField],
          0
        ]);
        const frontmatterValue = frontmatter == null ? void 0 : frontmatter[bannerIconImageAlignmentField];
        const defaultValue = this.plugin.settings.bannerIconImageAlignment;
        this.currentBannerIconImageAlignment = frontmatterValue === "right" ? "right" : "left";
        const repeatField = Array.isArray(this.plugin.settings.customImageRepeatField) ? this.plugin.settings.customImageRepeatField[0].split(",")[0].trim() : this.plugin.settings.customImageRepeatField;
        this.currentRepeat = (frontmatter == null ? void 0 : frontmatter[repeatField]) !== void 0 ? frontmatter[repeatField] : this.plugin.settings.imageRepeat;
        const fadeField = Array.isArray(this.plugin.settings.customFadeField) ? this.plugin.settings.customFadeField[0].split(",")[0].trim() : this.plugin.settings.customFadeField;
        this.currentFade = (frontmatter == null ? void 0 : frontmatter[fadeField]) !== void 0 ? frontmatter[fadeField] : this.plugin.settings.fade;
        const borderRadiusField = Array.isArray(this.plugin.settings.customBorderRadiusField) ? this.plugin.settings.customBorderRadiusField[0].split(",")[0].trim() : this.plugin.settings.customBorderRadiusField;
        this.currentBorderRadius = (frontmatter == null ? void 0 : frontmatter[borderRadiusField]) !== void 0 ? frontmatter[borderRadiusField] : this.plugin.settings.borderRadius || 0;
        this.currentZoom = 100;
        if (this.currentDisplay && this.currentDisplay.endsWith("%")) {
          this.currentZoom = parseInt(this.currentDisplay) || 100;
          this.currentDisplay = "cover-zoom";
        }
      }
      // Helper to update frontmatter with new display value
      updateDisplayMode(mode, zoom = null) {
        const displayField = Array.isArray(this.plugin.settings.customImageDisplayField) ? this.plugin.settings.customImageDisplayField[0].split(",")[0].trim() : this.plugin.settings.customImageDisplayField;
        const repeatField = Array.isArray(this.plugin.settings.customImageRepeatField) ? this.plugin.settings.customImageRepeatField[0].split(",")[0].trim() : this.plugin.settings.customImageRepeatField;
        let newValue = mode;
        if (mode === "cover-zoom") {
          newValue = `${zoom}%`;
        }
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (fm) => {
          fm[displayField] = newValue;
          if (mode === "contain" || mode === "auto") {
            fm[repeatField] = this.currentRepeat;
          } else {
            if (repeatField in fm) {
              delete fm[repeatField];
            }
          }
        });
      }
      updateBannerMaxWidth(maxWidth) {
        const maxWidthField = Array.isArray(this.plugin.settings.customBannerMaxWidthField) ? this.plugin.settings.customBannerMaxWidthField[0].split(",")[0].trim() : this.plugin.settings.customBannerMaxWidthField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          if (maxWidth === "unset") {
            if (maxWidthField in frontmatter) {
              delete frontmatter[maxWidthField];
            }
          } else {
            frontmatter[maxWidthField] = maxWidth;
          }
        });
        setTimeout(() => {
          const view = this.app.workspace.getActiveViewOfType(import_obsidian17.MarkdownView);
          if (view) {
            this.plugin.updateBanner(view, true);
          }
        }, 350);
      }
      updateBannerHeight(height) {
        const heightField = Array.isArray(this.plugin.settings.customBannerHeightField) ? this.plugin.settings.customBannerHeightField[0].split(",")[0].trim() : this.plugin.settings.customBannerHeightField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[heightField] = height;
        });
      }
      updateBannerContentStartPosition(position) {
        const contentStartPositionField = Array.isArray(this.plugin.settings.customContentStartField) ? this.plugin.settings.customContentStartField[0].split(",")[0].trim() : this.plugin.settings.customContentStartField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[contentStartPositionField] = position;
        });
      }
      updateBannerIconXPosition(position) {
        const bannerIconXPositionField = Array.isArray(this.plugin.settings.customBannerIconXPositionField) ? this.plugin.settings.customBannerIconXPositionField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconXPositionField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconXPositionField] = position;
        });
      }
      updateBannerIconSize(size) {
        const bannerIconSizeField = Array.isArray(this.plugin.settings.customBannerIconSizeField) ? this.plugin.settings.customBannerIconSizeField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconSizeField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconSizeField] = size;
        });
      }
      updateBannerIconImageSizeMultiplier(sizeMultiplier) {
        const bannerIconImageSizeMultiplierField = Array.isArray(this.plugin.settings.customBannerIconImageSizeMultiplierField) ? this.plugin.settings.customBannerIconImageSizeMultiplierField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageSizeMultiplierField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconImageSizeMultiplierField] = sizeMultiplier;
        });
      }
      updateBannerIconRotate(rotate) {
        const bannerIconRotateField = Array.isArray(this.plugin.settings.customBannerIconRotateField) ? this.plugin.settings.customBannerIconRotateField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconRotateField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconRotateField] = rotate;
        });
      }
      updateBannerIconColor(color) {
        const bannerIconColorField = Array.isArray(this.plugin.settings.customBannerIconColorField) ? this.plugin.settings.customBannerIconColorField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconColorField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconColorField] = color;
        });
      }
      updateBannerIconFontWeight(fontWeight) {
        const bannerIconFontWeightField = Array.isArray(this.plugin.settings.customBannerIconFontWeightField) ? this.plugin.settings.customBannerIconFontWeightField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconFontWeightField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconFontWeightField] = fontWeight;
        });
      }
      updateBannerIconBgColor(color, alpha) {
        const bannerIconBgColorField = Array.isArray(this.plugin.settings.customBannerIconBackgroundColorField) ? this.plugin.settings.customBannerIconBackgroundColorField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconBackgroundColorField;
        let finalColor = color;
        if (alpha < 100) {
          if (color.startsWith("#")) {
            const r = parseInt(color.slice(1, 3), 16);
            const g = parseInt(color.slice(3, 5), 16);
            const b = parseInt(color.slice(5, 7), 16);
            finalColor = `rgba(${r}, ${g}, ${b}, ${alpha / 100})`;
          } else if (color && !color.startsWith("rgb")) {
            const tempEl = document.createElement("div");
            tempEl.style.color = color;
            document.body.appendChild(tempEl);
            const computedColor = window.getComputedStyle(tempEl).color;
            document.body.removeChild(tempEl);
            const rgbMatch = computedColor.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);
            if (rgbMatch) {
              const r = parseInt(rgbMatch[1]);
              const g = parseInt(rgbMatch[2]);
              const b = parseInt(rgbMatch[3]);
              finalColor = `rgba(${r}, ${g}, ${b}, ${alpha / 100})`;
            }
          }
        }
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconBgColorField] = finalColor;
        });
      }
      updateBannerIconPaddingX(paddingX) {
        const bannerIconPaddingXField = Array.isArray(this.plugin.settings.customBannerIconPaddingXField) ? this.plugin.settings.customBannerIconPaddingXField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconPaddingXField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconPaddingXField] = paddingX;
        });
      }
      updateBannerIconPaddingY(paddingY) {
        const bannerIconPaddingYField = Array.isArray(this.plugin.settings.customBannerIconPaddingYField) ? this.plugin.settings.customBannerIconPaddingYField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconPaddingYField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconPaddingYField] = paddingY;
        });
      }
      updateBannerIconBorderRadius(borderRadius) {
        const bannerIconBorderRadiusField = Array.isArray(this.plugin.settings.customBannerIconBorderRadiusField) ? this.plugin.settings.customBannerIconBorderRadiusField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconBorderRadiusField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconBorderRadiusField] = borderRadius;
        });
      }
      updateBannerIconVerticalOffset(verticalOffset) {
        const bannerIconVerticalOffsetField = Array.isArray(this.plugin.settings.customBannerIconVerticalOffsetField) ? this.plugin.settings.customBannerIconVerticalOffsetField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconVerticalOffsetField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconVerticalOffsetField] = verticalOffset;
        });
      }
      updateBannerIconTextVerticalOffset(textVerticalOffset) {
        const bannerIconTextVerticalOffsetField = Array.isArray(this.plugin.settings.customBannerIconTextVerticalOffsetField) ? this.plugin.settings.customBannerIconTextVerticalOffsetField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconTextVerticalOffsetField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconTextVerticalOffsetField] = textVerticalOffset;
        });
      }
      updateBannerIconImageAlignment(alignment) {
        const bannerIconImageAlignmentField = Array.isArray(this.plugin.settings.customBannerIconImageAlignmentField) ? this.plugin.settings.customBannerIconImageAlignmentField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageAlignmentField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[bannerIconImageAlignmentField] = alignment;
        });
        setTimeout(() => {
          const view = this.app.workspace.getActiveViewOfType(import_obsidian17.MarkdownView);
          if (view) {
            this.plugin.updateBanner(view, true);
          }
        }, 350);
      }
      updateTitleColor(color) {
        const titleColorField = Array.isArray(this.plugin.settings.customTitleColorField) ? this.plugin.settings.customTitleColorField[0].split(",")[0].trim() : this.plugin.settings.customTitleColorField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[titleColorField] = color;
        });
      }
      updateRepeatMode(repeat) {
        const repeatField = Array.isArray(this.plugin.settings.customImageRepeatField) ? this.plugin.settings.customImageRepeatField[0].split(",")[0].trim() : this.plugin.settings.customImageRepeatField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (fm) => {
          fm[repeatField] = repeat;
        });
      }
      updateBannerAlignment(alignment) {
        const alignmentField = Array.isArray(this.plugin.settings.customBannerAlignmentField) ? this.plugin.settings.customBannerAlignmentField[0].split(",")[0].trim() : this.plugin.settings.customBannerAlignmentField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (fm) => {
          fm[alignmentField] = alignment;
        });
      }
      updateBannerFade(fade) {
        const fadeField = Array.isArray(this.plugin.settings.customFadeField) ? this.plugin.settings.customFadeField[0].split(",")[0].trim() : this.plugin.settings.customFadeField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[fadeField] = fade;
        });
      }
      updateBannerBorderRadius(borderRadius) {
        const borderRadiusField = Array.isArray(this.plugin.settings.customBorderRadiusField) ? this.plugin.settings.customBorderRadiusField[0].split(",")[0].trim() : this.plugin.settings.customBorderRadiusField;
        this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter) => {
          frontmatter[borderRadiusField] = borderRadius;
        });
        setTimeout(() => {
          const view = this.app.workspace.getActiveViewOfType(import_obsidian17.MarkdownView);
          if (view) {
            this.plugin.updateBanner(view, true);
          }
        }, 350);
      }
      onPositionChange(x, y) {
        const activeFile = this.app.workspace.getActiveFile();
        if (!activeFile) return;
        this.app.fileManager.processFrontMatter(activeFile, (frontmatter) => {
          frontmatter.bannerTargetX = x;
          frontmatter.bannerTargetY = y;
        });
      }
      onOpen() {
        const { contentEl } = this;
        contentEl.empty();
        this.setupUI(contentEl);
      }
      async setupUI(contentEl) {
        var _a;
        const { modalEl, bgEl } = this;
        contentEl.empty();
        contentEl.addClass("target-position-modal");
        modalEl.style.opacity = "0.8";
        modalEl.style.width = "max-content";
        modalEl.style.height = "max-content";
        bgEl.style.opacity = "0";
        const activeFile = this.app.workspace.getActiveFile();
        const frontmatter = activeFile ? ((_a = this.app.metadataCache.getFileCache(activeFile)) == null ? void 0 : _a.frontmatter) || {} : {};
        const dragHandle = contentEl.createDiv({
          cls: "drag-handle",
          attr: {
            style: `
                    cursor: move;
                    position: absolute;
                    left: 50%;
                    transform: translateX(-50%);
                    top: 7px;
                    opacity: .8;
                `
          }
        });
        dragHandle.setText("\u22EE\u22EE\u22EE\u22EE\u22EE\u22EE\u22EE\u22EE\u22EE\u22EE");
        const bannerImageHeader = contentEl.createEl("div", {
          text: "\u{1F5BC}\uFE0F Banner Image Settings",
          cls: "banner-image-header",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    justify-content: space-between;
                    color: var(--text-accent);
                    font-size: 0.9em;
                    font-weight: 600;
                    letter-spacing: 1px;
                    text-transform: uppercase;
                    margin-top: 15px;
                    margin-bottom: 10px;
                `
          }
        });
        const bannerImageHeaderButtons = bannerImageHeader.createEl("div", {
          cls: "banner-image-header-buttons",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    flex-wrap: wrap;
                    gap: 5px;
                `
          }
        });
        const bannerImageHeaderChangeButton = bannerImageHeaderButtons.createEl("button", {
          text: "\u270F\uFE0F Change Banner",
          cls: "banner-image-header-button cursor-pointer",
          attr: {
            style: `
                    text-transform: uppercase;
                    font-size: .8em;
                `
          }
        });
        bannerImageHeaderChangeButton.addEventListener("click", () => {
          this.close();
          new SelectPixelBannerModal(this.app, this.plugin).open();
        });
        const bannerImageHeaderRemoveButton = bannerImageHeaderButtons.createEl("button", {
          text: "\u{1F5D1}\uFE0F Remove Banner",
          cls: "banner-image-header-button cursor-pointer",
          attr: {
            style: `
                    text-transform: uppercase;
                    font-size: .8em;
                `
          }
        });
        bannerImageHeaderRemoveButton.addEventListener("click", () => {
          this.resetPixelBannerNoteSettings(true);
        });
        const mainContainer = contentEl.createDiv({
          cls: "main-container--banner-image",
          attr: {
            style: `
                    position: relative;
                    display: flex;
                    flex-direction: row;
                    gap: 20px;
                    align-items: stretch;
                    justify-content: space-between;
                `
          }
        });
        let isVideoFile = false;
        const bannerField = Array.isArray(this.plugin.settings.customBannerField) ? this.plugin.settings.customBannerField[0].split(",")[0].trim() : this.plugin.settings.customBannerField;
        const bannerValue = frontmatter == null ? void 0 : frontmatter[bannerField];
        if (bannerValue) {
          if (typeof bannerValue === "string") {
            const lowerBanner = bannerValue.toLowerCase();
            isVideoFile = lowerBanner.endsWith(".mp4") || lowerBanner.endsWith(".mov");
          }
          if (!isVideoFile && (bannerValue.includes("[[") || bannerValue.includes("![["))) {
            const linkMatch = bannerValue.match(/\[\[(.*?)\]\]/) || bannerValue.match(/!\[\[(.*?)\]\]/);
            if (linkMatch && linkMatch[1]) {
              const linkPath = linkMatch[1].toLowerCase();
              isVideoFile = linkPath.endsWith(".mp4") || linkPath.endsWith(".mov");
            }
          }
        }
        const controlPanel = mainContainer.createDiv({
          cls: "control-panel",
          id: "display-mode-panel",
          attr: {
            style: `
                    display: ${isVideoFile ? "none" : "flex"};
                    flex-direction: column;
                    gap: 10px;
                    flex: 0 auto;
                `
          }
        });
        const displaySelect = controlPanel.createEl("select", { cls: "display-mode-select" });
        ["cover", "auto", "contain", "cover-zoom"].forEach((mode) => {
          const option = displaySelect.createEl("option", {
            text: mode.replace("-", " "),
            value: mode
          });
          if (mode === this.currentDisplay) {
            option.selected = true;
          }
        });
        const zoomContainer = controlPanel.createDiv({
          cls: "zoom-container",
          attr: {
            style: `
                    display: ${this.currentDisplay === "cover-zoom" ? "flex" : "none"};
                    flex-direction: column;
                    gap: 5px;
                    align-items: center;
                    margin-top: 10px;
                    height: 100%;
                `
          }
        });
        const zoomValue = zoomContainer.createDiv({
          cls: "zoom-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        zoomValue.setText(`${this.currentZoom}%`);
        const zoomSlider = zoomContainer.createEl("input", {
          type: "range",
          cls: "zoom-slider",
          attr: {
            min: "0",
            max: "500",
            step: "10",
            value: this.currentZoom,
            style: `
                    flex: 1;
                    writing-mode: vertical-lr;
                    direction: rtl;
                `
          }
        });
        displaySelect.addEventListener("change", () => {
          const mode = displaySelect.value;
          zoomContainer.style.display = mode === "cover-zoom" ? "flex" : "none";
          this.updateDisplayMode(mode, mode === "cover-zoom" ? this.currentZoom : null);
        });
        zoomSlider.addEventListener("input", () => {
          this.currentZoom = parseInt(zoomSlider.value);
          zoomValue.setText(`${this.currentZoom}%`);
          this.updateDisplayMode("cover-zoom", this.currentZoom);
        });
        const maxWidthContainer = mainContainer.createDiv({
          cls: "max-width-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: column;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                `
          }
        });
        const maxWidthLabel = maxWidthContainer.createEl("div", {
          text: "Max Width",
          cls: "max-width-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const maxWidthField = Array.isArray(this.plugin.settings.customBannerMaxWidthField) ? this.plugin.settings.customBannerMaxWidthField[0].split(",")[0].trim() : this.plugin.settings.customBannerMaxWidthField;
        const maxWidthValue = frontmatter == null ? void 0 : frontmatter[maxWidthField];
        const directMaxWidth = frontmatter == null ? void 0 : frontmatter["banner-max-width"];
        const maxWidthExists = maxWidthValue !== void 0 && maxWidthValue !== null || directMaxWidth !== void 0 && directMaxWidth !== null;
        const isMaxWidthUnset = !maxWidthExists;
        this.currentMaxWidth = isMaxWidthUnset ? 1928 : parseInt(maxWidthValue || directMaxWidth) || 1928;
        const unsetContainer = maxWidthContainer.createDiv({
          cls: "unset-container",
          attr: {
            style: `
                    display: flex;
                    align-items: center;
                    gap: 5px;
                    margin-bottom: 5px;
                `
          }
        });
        const unsetCheckbox = unsetContainer.createEl("input", {
          type: "checkbox",
          cls: "unset-checkbox"
        });
        const shouldBeChecked = isMaxWidthUnset;
        unsetCheckbox.checked = shouldBeChecked;
        unsetContainer.createEl("span", {
          text: "unset"
        });
        const maxWidthValueDisplay = maxWidthContainer.createDiv({
          cls: "max-width-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                    ${isMaxWidthUnset ? "color: var(--text-muted);" : ""}
                `
          }
        });
        maxWidthValueDisplay.setText(isMaxWidthUnset ? "unset" : `${this.currentMaxWidth}px`);
        const maxWidthSlider = maxWidthContainer.createEl("input", {
          type: "range",
          cls: "max-width-slider",
          attr: {
            min: "100",
            max: "2560",
            step: "10",
            value: this.currentMaxWidth,
            disabled: isMaxWidthUnset,
            draggable: false,
            style: `
                    width: 15px;
                    height: 30px;
                    flex: 1;
                    writing-mode: vertical-lr;
                    direction: rtl;
                    ${isMaxWidthUnset ? "opacity: 0.5;" : ""}
                `
          }
        });
        if (!isMaxWidthUnset) {
          maxWidthSlider.disabled = false;
          maxWidthSlider.style.opacity = "1";
        }
        unsetCheckbox.addEventListener("change", () => {
          const isUnset = unsetCheckbox.checked;
          maxWidthSlider.disabled = isUnset;
          maxWidthSlider.style.opacity = isUnset ? "0.5" : "1";
          maxWidthValueDisplay.style.color = isUnset ? "var(--text-muted)" : "";
          maxWidthValueDisplay.setText(isUnset ? "unset" : `${this.currentMaxWidth}px`);
          if (isUnset) {
            this.updateBannerMaxWidth("unset");
          } else {
            this.updateBannerMaxWidth(this.currentMaxWidth);
          }
        });
        maxWidthSlider.addEventListener("input", () => {
          this.currentMaxWidth = parseInt(maxWidthSlider.value);
          maxWidthValueDisplay.setText(`${this.currentMaxWidth}px`);
          this.updateBannerMaxWidth(this.currentMaxWidth);
        });
        const heightContainer = mainContainer.createDiv({
          cls: "height-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: column;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                `
          }
        });
        const heightLabel = heightContainer.createEl("div", {
          text: "Height",
          cls: "height-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const heightValue = heightContainer.createDiv({
          cls: "height-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        heightValue.setText(`${this.currentHeight}px`);
        const heightSlider = heightContainer.createEl("input", {
          type: "range",
          cls: "height-slider",
          attr: {
            min: "0",
            max: "1280",
            step: "10",
            value: this.currentHeight,
            style: `
                    flex: 1;
                    writing-mode: vertical-lr;
                    direction: rtl;
                `
          }
        });
        heightSlider.addEventListener("input", () => {
          this.currentHeight = parseInt(heightSlider.value);
          heightValue.setText(`${this.currentHeight}px`);
          this.updateBannerHeight(this.currentHeight);
        });
        const targetContainer = mainContainer.createDiv({
          cls: "target-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: column;
                    gap: 10px;
                `
          }
        });
        const targetArea = targetContainer.createDiv({
          cls: "target-area",
          attr: {
            style: `
                    width: 200px;
                    height: 200px;
                    border: 2px solid var(--background-modifier-border);
                    position: relative;
                    background-color: var(--background-primary);
                    cursor: crosshair;
                    flex-grow: 1;
                `
          }
        });
        const verticalLine = targetArea.createDiv({ cls: "crosshair-line vertical" });
        const horizontalLine = targetArea.createDiv({ cls: "crosshair-line horizontal" });
        const positionIndicator = targetContainer.createEl("div", {
          cls: "position-indicator",
          attr: {
            style: `
                    text-align: center;
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                    color: var(--text-muted);
                    width: 200px;
                `
          }
        });
        positionIndicator.setText(`X: ${this.currentX}%, Y: ${this.currentY}%`);
        const updatePositionIndicator = () => {
          positionIndicator.setText(`X: ${this.currentX}%, Y: ${this.currentY}%`);
        };
        this.addStyle();
        const updatePosition = (e) => {
          const rect = targetArea.getBoundingClientRect();
          const x = Math.max(0, Math.min(100, (e.clientX - rect.left) / rect.width * 100));
          const y = Math.max(0, Math.min(100, (e.clientY - rect.top) / rect.height * 100));
          verticalLine.style.left = `${x}%`;
          horizontalLine.style.top = `${y}%`;
          this.currentX = Math.round(x);
          this.currentY = Math.round(y);
          const xField = Array.isArray(this.plugin.settings.customXPositionField) ? this.plugin.settings.customXPositionField[0].split(",")[0].trim() : this.plugin.settings.customXPositionField;
          const yField = Array.isArray(this.plugin.settings.customYPositionField) ? this.plugin.settings.customYPositionField[0].split(",")[0].trim() : this.plugin.settings.customYPositionField;
          this.app.fileManager.processFrontMatter(this.app.workspace.getActiveFile(), (frontmatter2) => {
            frontmatter2[xField] = this.currentX;
            frontmatter2[yField] = this.currentY;
          });
          updatePositionIndicator();
        };
        targetArea.addEventListener("click", updatePosition);
        verticalLine.style.left = `${this.currentX}%`;
        horizontalLine.style.top = `${this.currentY}%`;
        const contentStartPositionContainer = mainContainer.createDiv({
          cls: "content-start-position-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: column;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                `
          }
        });
        const contentStartPositionLabel = contentStartPositionContainer.createEl("div", {
          text: "Content Start Position",
          cls: "content-start-position-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                    text-align: center;
                    width: 60px;
                `
          }
        });
        const contentStartPositionValue = contentStartPositionContainer.createDiv({
          cls: "content-start-position-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        contentStartPositionValue.setText(`${this.currentContentStartPosition}px`);
        const contentStartPositionSlider = contentStartPositionContainer.createEl("input", {
          type: "range",
          cls: "content-start-position-slider",
          attr: {
            min: "1",
            max: "800",
            step: "5",
            value: this.currentContentStartPosition,
            style: `
                    flex: 1;
                    writing-mode: vertical-lr;
                    direction: rtl;
                `
          }
        });
        contentStartPositionSlider.addEventListener("input", () => {
          this.currentContentStartPosition = parseInt(contentStartPositionSlider.value);
          contentStartPositionValue.setText(`${this.currentContentStartPosition}px`);
          this.updateBannerContentStartPosition(this.currentContentStartPosition);
        });
        const bannerSettingsRow2 = contentEl.createDiv({
          attr: {
            style: `
                display: flex;
                flex-direction: row;
                flex-wrap: wrap;
                gap: 10px;
                align-items: center;
                flex: 0 auto;
                margin-top: 10px;
                `
          }
        });
        bannerSettingsRow2.createEl("div", {
          text: "Banner Alignment",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const alignmentSelect = bannerSettingsRow2.createEl("select", { cls: "alignment-select" });
        [
          { value: "left", text: "Left" },
          { value: "center", text: "Center" },
          { value: "right", text: "Right" }
        ].forEach((option) => {
          const optionEl = alignmentSelect.createEl("option", {
            text: option.text,
            value: option.value
          });
          if (option.value === this.currentAlignment) {
            optionEl.selected = true;
          }
        });
        alignmentSelect.addEventListener("change", () => {
          this.currentAlignment = alignmentSelect.value;
          this.updateBannerAlignment(this.currentAlignment);
        });
        const bannerFadeContainer = bannerSettingsRow2.createDiv({
          cls: "setting-item",
          attr: {
            style: `
                    flex: 1;
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                `
          }
        });
        const bannerFadeHeader = bannerFadeContainer.createDiv({
          text: "Banner Fade",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const bannerFadeSliderContainer = bannerFadeContainer.createDiv({
          attr: {
            style: `
                    flex: 1;
                    display: flex;
                    gap: 10px;
                    align-items: center;
                `
          }
        });
        const bannerFadeSlider = bannerFadeSliderContainer.createEl("input", {
          type: "range",
          cls: "slider",
          attr: {
            min: "-300",
            max: "100",
            step: "5",
            value: this.currentFade,
            style: `
                    flex: 1;
                `
          }
        });
        const bannerFadeValue = bannerFadeSliderContainer.createDiv({
          text: this.currentFade,
          attr: {
            style: `
                    color: var(--text-muted);
                    font-size: 0.9em;
                    min-width: 45px;
                    text-align: right;
                `
          }
        });
        bannerFadeSlider.addEventListener("input", (e) => {
          const value = parseInt(e.target.value);
          this.updateBannerFade(value);
          bannerFadeValue.setText(value.toString());
        });
        const borderRadiusContainer = bannerSettingsRow2.createDiv({
          cls: "setting-item",
          attr: {
            style: `
                    flex: 1;
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                `
          }
        });
        const borderRadiusHeader = borderRadiusContainer.createDiv({
          text: "Border Radius",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const borderRadiusSliderContainer = borderRadiusContainer.createDiv({
          attr: {
            style: `
                    flex: 1;
                    display: flex;
                    gap: 10px;
                    align-items: center;
                `
          }
        });
        const borderRadiusSlider = borderRadiusSliderContainer.createEl("input", {
          type: "range",
          cls: "slider",
          attr: {
            min: "0",
            max: "50",
            step: "1",
            value: this.currentBorderRadius,
            style: `
                    flex: 1;
                `
          }
        });
        const borderRadiusValue = borderRadiusSliderContainer.createDiv({
          text: this.currentBorderRadius.toString(),
          attr: {
            style: `
                    color: var(--text-muted);
                    font-size: 0.9em;
                    min-width: 45px;
                    text-align: right;
                `
          }
        });
        borderRadiusSlider.addEventListener("input", (e) => {
          const value = parseInt(e.target.value);
          this.updateBannerBorderRadius(value);
          borderRadiusValue.setText(`${value}`);
        });
        const openEmojiPicker = () => {
          this.close();
          new EmojiSelectionModal(
            this.app,
            this.plugin,
            async (emoji) => {
              const activeFile2 = this.app.workspace.getActiveFile();
              if (activeFile2) {
                await this.plugin.app.fileManager.processFrontMatter(activeFile2, (frontmatter2) => {
                  const iconField = this.plugin.settings.customBannerIconField[0];
                  if (emoji) {
                    frontmatter2[iconField] = emoji;
                  } else {
                    delete frontmatter2[iconField];
                  }
                });
              }
            }
          ).open();
        };
        const openIconImagePicker = () => {
          const defaultIconImageFolder = this.plugin.settings.defaultSelectIconPath || "";
          this.close();
          new IconImageSelectionModal(
            this.app,
            this.plugin,
            async (file) => {
              if (!file) return;
              const activeFile2 = this.app.workspace.getActiveFile();
              if (!activeFile2) return;
              if (file.isWebUrl) {
                this.app.fileManager.processFrontMatter(activeFile2, (fm) => {
                  const iconImageField = Array.isArray(this.plugin.settings.customBannerIconImageField) ? this.plugin.settings.customBannerIconImageField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageField;
                  fm[iconImageField] = file.path;
                });
                new _TargetPositionModal(this.app, this.plugin).open();
                return;
              }
              let fileExtension = "";
              let filePath = "";
              if (typeof file === "string") {
                filePath = file;
                const extensionPart = file.split(".").pop();
                fileExtension = extensionPart ? extensionPart.toLowerCase() : "";
              } else if (file && file.extension) {
                filePath = file.path;
                fileExtension = file.extension.toLowerCase();
              }
              if (fileExtension && fileExtension.match(/^(jpg|jpeg|png|gif|bmp|svg|webp|avif)$/)) {
                try {
                  const imageUrl = await this.plugin.getVaultImageUrl(filePath);
                  if (imageUrl) {
                    this.plugin.loadedImages.set(filePath, imageUrl);
                    const preloadImg = new Image();
                    preloadImg.src = imageUrl;
                  }
                } catch (error) {
                  console.error("Error preloading icon image:", error);
                }
              }
              this.app.fileManager.processFrontMatter(activeFile2, (fm) => {
                const iconImageField = Array.isArray(this.plugin.settings.customBannerIconImageField) ? this.plugin.settings.customBannerIconImageField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageField;
                const format = this.plugin.settings.imagePropertyFormat;
                let iconImageValue;
                if (format === "image") {
                  iconImageValue = filePath;
                } else if (format === "[[image]]") {
                  iconImageValue = `[[${filePath}]]`;
                } else {
                  iconImageValue = `![[${filePath}]]`;
                }
                fm[iconImageField] = iconImageValue;
              });
              new _TargetPositionModal(this.app, this.plugin).open();
            },
            defaultIconImageFolder
          ).open();
        };
        const bannerIconField = Array.isArray(this.plugin.settings.customBannerIconField) ? this.plugin.settings.customBannerIconField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconField;
        const bannerIconImageField = Array.isArray(this.plugin.settings.customBannerIconImageField) ? this.plugin.settings.customBannerIconImageField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageField;
        const getStringValue = (value) => {
          if (value === void 0 || value === null) return "";
          if (typeof value === "string") return value;
          if (Array.isArray(value)) {
            let current = value;
            while (Array.isArray(current) && current.length > 0) {
              current = current[0];
            }
            return typeof current === "string" ? current : "";
          }
          return String(value);
        };
        let hasBannerIcon = frontmatter && (frontmatter[bannerIconField] && getStringValue(frontmatter[bannerIconField]).trim() !== "" || frontmatter[bannerIconImageField] && getStringValue(frontmatter[bannerIconImageField]).trim() !== "");
        const hasBannerIconImage = frontmatter && frontmatter[bannerIconImageField] && getStringValue(frontmatter[bannerIconImageField]).trim() !== "";
        if (!hasBannerIcon) {
          await new Promise((resolve) => {
            setTimeout(async () => {
              var _a2;
              const refreshedFrontmatter = (_a2 = this.app.metadataCache.getFileCache(activeFile)) == null ? void 0 : _a2.frontmatter;
              if (refreshedFrontmatter && (refreshedFrontmatter[bannerIconField] && getStringValue(refreshedFrontmatter[bannerIconField]).trim() !== "" || refreshedFrontmatter[bannerIconImageField] && getStringValue(refreshedFrontmatter[bannerIconImageField]).trim() !== "")) {
                hasBannerIcon = true;
              }
              resolve();
            }, 400);
          });
        }
        const addBannerIconContainer = contentEl.createDiv({
          cls: "main-container--banner-icon",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    margin-top: 30px;
                    margin-bottom: 10px;
                    justify-content: space-between;
                    align-items: center;
                `
          }
        });
        const bannerIconHeader = addBannerIconContainer.createEl("div", {
          text: hasBannerIcon ? "\u2B50 Banner Icon Settings" : "",
          cls: "banner-icon-header",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    align-items: center;
                    justify-content: space-between;
                    color: var(--text-accent);
                    font-size: 0.9em;
                    font-weight: 600;
                    letter-spacing: 1px;
                    text-transform: uppercase;
                `
          }
        });
        const bannerIconHeaderButtons = addBannerIconContainer.createDiv({
          cls: "banner-icon-header-buttons",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    justify-content: flex-end;
                `
          }
        });
        const bannerIconHeaderButtonIcon = bannerIconHeaderButtons.createEl("button", {
          text: hasBannerIconImage ? "\u270F\uFE0F Edit Icon Image" : "\u2B50 Add Icon Image",
          cls: "banner-icon-header-button cursor-pointer",
          attr: {
            style: `
                    text-transform: uppercase;
                    font-size: .8em;
                `
          }
        });
        bannerIconHeaderButtonIcon.addEventListener("click", openIconImagePicker);
        const hasBannerIconText = frontmatter && frontmatter[bannerIconField] && getStringValue(frontmatter[bannerIconField]).trim() !== "";
        const bannerIconHeaderButtonText = bannerIconHeaderButtons.createEl("button", {
          text: hasBannerIconText ? "\u{1F4DD} Edit Icon Text & Emoji" : "\u{1F4F0} Add Icon Text & Emoji",
          cls: "banner-icon-header-button cursor-pointer",
          attr: {
            style: `
                    text-transform: uppercase;
                    font-size: .8em;
                `
          }
        });
        bannerIconHeaderButtonText.addEventListener("click", openEmojiPicker);
        const bannerIconControlsContainer = contentEl.createDiv({
          cls: "main-container--banner-icon",
          attr: {
            style: `
                    margin-top: 20px;
                    display: ${hasBannerIcon ? "block" : "none"};
                `
          }
        });
        const bannerIconImageAlignmentContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-image-alignment-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                    margin-bottom: 15px;
                `
          }
        });
        const bannerIconImageAlignmentLabel = bannerIconImageAlignmentContainer.createEl("div", {
          text: "Icon Image Alignment",
          cls: "banner-icon-image-alignment-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                    min-width: 120px;
                `
          }
        });
        const bannerIconImageAlignmentRadioContainer = bannerIconImageAlignmentContainer.createDiv({
          cls: "banner-icon-image-alignment-radio-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 20px;
                    align-items: center;
                `
          }
        });
        const leftRadioContainer = bannerIconImageAlignmentRadioContainer.createDiv({
          cls: "radio-container",
          attr: {
            style: `
                    display: flex;
                    align-items: center;
                    gap: 5px;
                `
          }
        });
        const isRightAlignment = this.currentBannerIconImageAlignment === "right";
        const isLeftAlignment = !isRightAlignment;
        const leftRadio = leftRadioContainer.createEl("input", {
          type: "radio",
          attr: {
            id: "icon-placement-left",
            name: "icon-image-placement",
            value: "left",
            style: `cursor: pointer;`
          }
        });
        leftRadioContainer.createEl("label", {
          text: "Left",
          attr: {
            for: "icon-placement-left",
            style: `
                    cursor: pointer;
                    font-size: 0.9em;
                `
          }
        });
        const rightRadioContainer = bannerIconImageAlignmentRadioContainer.createDiv({
          cls: "radio-container",
          attr: {
            style: `
                    display: flex;
                    align-items: center;
                    gap: 5px;
                `
          }
        });
        const rightRadio = rightRadioContainer.createEl("input", {
          type: "radio",
          attr: {
            id: "icon-placement-right",
            name: "icon-image-placement",
            value: "right",
            style: `cursor: pointer;`
          }
        });
        rightRadioContainer.createEl("label", {
          text: "Right",
          attr: {
            for: "icon-placement-right",
            style: `
                    cursor: pointer;
                    font-size: 0.9em;
                `
          }
        });
        setTimeout(() => {
          leftRadio.checked = isLeftAlignment;
          rightRadio.checked = isRightAlignment;
        }, 50);
        leftRadio.addEventListener("change", () => {
          if (leftRadio.checked) {
            this.currentBannerIconImageAlignment = "left";
            this.updateBannerIconImageAlignment(this.currentBannerIconImageAlignment);
          }
        });
        rightRadio.addEventListener("change", () => {
          if (rightRadio.checked) {
            this.currentBannerIconImageAlignment = "right";
            this.updateBannerIconImageAlignment(this.currentBannerIconImageAlignment);
          }
        });
        const bannerIconXPositionContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-x-position-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                `
          }
        });
        const bannerIconXPositionLabel = bannerIconXPositionContainer.createEl("div", {
          text: "Icon X Position",
          cls: "banner-icon-x-position-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const bannerIconXPositionSlider = bannerIconXPositionContainer.createEl("input", {
          type: "range",
          cls: "banner-icon-x-position-slider",
          attr: {
            min: "1",
            max: "100",
            step: "1",
            value: this.currentBannerIconXPosition,
            style: `
                    flex: 1;
                    writing-mode: horizontal-tb;
                    direction: ltr;
                `
          }
        });
        const bannerIconXPositionValue = bannerIconXPositionContainer.createDiv({
          cls: "banner-icon-x-position-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        bannerIconXPositionValue.setText(`${this.currentBannerIconXPosition}`);
        bannerIconXPositionSlider.addEventListener("input", () => {
          this.currentBannerIconXPosition = parseInt(bannerIconXPositionSlider.value);
          bannerIconXPositionValue.setText(`${this.currentBannerIconXPosition}`);
          this.updateBannerIconXPosition(this.currentBannerIconXPosition);
        });
        const bannerIconVerticalOffsetContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-vertical-offset-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                    margin-top: 10px;
                `
          }
        });
        const bannerIconVerticalOffsetLabel = bannerIconVerticalOffsetContainer.createEl("div", {
          text: "Icon Y Position",
          cls: "banner-icon-vertical-offset-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const iconVerticalOffsetField = Array.isArray(this.plugin.settings.customBannerIconVerticalOffsetField) ? this.plugin.settings.customBannerIconVerticalOffsetField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconVerticalOffsetField;
        this.currentBannerIconVerticalOffset = (frontmatter == null ? void 0 : frontmatter[iconVerticalOffsetField]) || this.plugin.settings.bannerIconVerticalOffset;
        const bannerIconVerticalOffsetSlider = bannerIconVerticalOffsetContainer.createEl("input", {
          type: "range",
          cls: "banner-icon-vertical-offset-slider",
          attr: {
            min: "-100",
            max: "100",
            step: "1",
            value: this.currentBannerIconVerticalOffset,
            style: `
                    flex: 1;
                    writing-mode: horizontal-tb;
                    direction: ltr;
                `
          }
        });
        const bannerIconVerticalOffsetValue = bannerIconVerticalOffsetContainer.createDiv({
          cls: "banner-icon-vertical-offset-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        bannerIconVerticalOffsetValue.setText(`${this.currentBannerIconVerticalOffset}`);
        bannerIconVerticalOffsetSlider.addEventListener("input", () => {
          this.currentBannerIconVerticalOffset = parseInt(bannerIconVerticalOffsetSlider.value);
          bannerIconVerticalOffsetValue.setText(`${this.currentBannerIconVerticalOffset}`);
          this.updateBannerIconVerticalOffset(this.currentBannerIconVerticalOffset);
        });
        const bannerIconSizeContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-size-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                    margin-top: 10px;
                `
          }
        });
        const bannerIconSizeLabel = bannerIconSizeContainer.createEl("div", {
          text: "Icon Size",
          cls: "banner-icon-size-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const iconSizeField = Array.isArray(this.plugin.settings.customBannerIconSizeField) ? this.plugin.settings.customBannerIconSizeField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconSizeField;
        this.currentBannerIconSize = (frontmatter == null ? void 0 : frontmatter[iconSizeField]) || this.plugin.settings.bannerIconSize;
        const bannerIconSizeSlider = bannerIconSizeContainer.createEl("input", {
          type: "range",
          cls: "banner-icon-size-slider",
          attr: {
            min: "10",
            max: "200",
            step: "1",
            value: this.currentBannerIconSize,
            style: `
                    flex: 1;
                    writing-mode: horizontal-tb;
                    direction: ltr;
                `
          }
        });
        const bannerIconSizeValue = bannerIconSizeContainer.createDiv({
          cls: "banner-icon-size-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        bannerIconSizeValue.setText(`${this.currentBannerIconSize}`);
        bannerIconSizeSlider.addEventListener("input", () => {
          this.currentBannerIconSize = parseInt(bannerIconSizeSlider.value);
          bannerIconSizeValue.setText(`${this.currentBannerIconSize}`);
          this.updateBannerIconSize(this.currentBannerIconSize);
        });
        const bannerIconImageSizeMultiplierContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-image-size-multiplier-container",
          attr: {
            style: `
                    display: ${hasBannerIconImage ? "flex" : "none"};
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                    margin-top: 10px;
                `
          }
        });
        const bannerIconImageSizeMultiplierLabel = bannerIconImageSizeMultiplierContainer.createEl("div", {
          text: "Icon Image Size Multiplier",
          cls: "banner-icon-image-size-multiplier-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const iconImageSizeMultiplierField = Array.isArray(this.plugin.settings.customBannerIconImageSizeMultiplierField) ? this.plugin.settings.customBannerIconImageSizeMultiplierField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageSizeMultiplierField;
        this.currentBannerIconImageSizeMultiplier = (frontmatter == null ? void 0 : frontmatter[iconImageSizeMultiplierField]) || this.plugin.settings.bannerIconImageSizeMultiplier;
        const bannerIconImageSizeMultiplierSlider = bannerIconImageSizeMultiplierContainer.createEl("input", {
          type: "range",
          cls: "banner-icon-image-size-multiplier-slider",
          attr: {
            min: ".2",
            max: "3",
            step: "0.1",
            value: this.currentBannerIconImageSizeMultiplier,
            style: `
                    flex: 1;
                    writing-mode: horizontal-tb;
                    direction: ltr;
                `
          }
        });
        const bannerIconImageSizeMultiplierValue = bannerIconImageSizeMultiplierContainer.createDiv({
          cls: "banner-icon-image-size-multiplier-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        bannerIconImageSizeMultiplierValue.setText(`${this.currentBannerIconImageSizeMultiplier}`);
        bannerIconImageSizeMultiplierSlider.addEventListener("input", () => {
          this.currentBannerIconImageSizeMultiplier = parseFloat(bannerIconImageSizeMultiplierSlider.value);
          bannerIconImageSizeMultiplierValue.setText(`${this.currentBannerIconImageSizeMultiplier}`);
          this.updateBannerIconImageSizeMultiplier(this.currentBannerIconImageSizeMultiplier);
        });
        const bannerIconTextVerticalOffsetContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-text-vertical-offset-container",
          attr: {
            style: `
                    display: ${hasBannerIconText ? "flex" : "none"};
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                    margin-top: 10px;
                `
          }
        });
        const bannerIconTextVerticalOffsetLabel = bannerIconTextVerticalOffsetContainer.createEl("div", {
          text: "Icon Text Vertical Offset",
          cls: "banner-icon-text-vertical-offset-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const iconTextVerticalOffsetField = Array.isArray(this.plugin.settings.customBannerIconTextVerticalOffsetField) ? this.plugin.settings.customBannerIconTextVerticalOffsetField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconTextVerticalOffsetField;
        this.currentBannerIconTextVerticalOffset = (frontmatter == null ? void 0 : frontmatter[iconTextVerticalOffsetField]) || this.plugin.settings.bannerIconTextVerticalOffset || 0;
        const bannerIconTextVerticalOffsetSlider = bannerIconTextVerticalOffsetContainer.createEl("input", {
          type: "range",
          cls: "banner-icon-text-vertical-offset-slider",
          attr: {
            min: "-50",
            max: "50",
            step: "1",
            value: this.currentBannerIconTextVerticalOffset,
            style: `
                    flex: 1;
                    writing-mode: horizontal-tb;
                    direction: ltr;
                `
          }
        });
        const bannerIconTextVerticalOffsetValue = bannerIconTextVerticalOffsetContainer.createDiv({
          cls: "banner-icon-text-vertical-offset-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        bannerIconTextVerticalOffsetValue.setText(`${this.currentBannerIconTextVerticalOffset}`);
        bannerIconTextVerticalOffsetSlider.addEventListener("input", () => {
          this.currentBannerIconTextVerticalOffset = parseInt(bannerIconTextVerticalOffsetSlider.value);
          bannerIconTextVerticalOffsetValue.setText(`${this.currentBannerIconTextVerticalOffset}`);
          this.updateBannerIconTextVerticalOffset(this.currentBannerIconTextVerticalOffset);
        });
        const bannerIconRotateContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-rotate-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                    margin-top: 10px;
                `
          }
        });
        const bannerIconRotateLabel = bannerIconRotateContainer.createEl("div", {
          text: "Icon Rotation",
          cls: "banner-icon-rotate-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const iconRotateField = Array.isArray(this.plugin.settings.customBannerIconRotateField) ? this.plugin.settings.customBannerIconRotateField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconRotateField;
        this.currentBannerIconRotate = (frontmatter == null ? void 0 : frontmatter[iconRotateField]) || 0;
        const bannerIconRotateSlider = bannerIconRotateContainer.createEl("input", {
          type: "range",
          cls: "banner-icon-rotate-slider",
          attr: {
            min: "0",
            max: "360",
            step: "5",
            value: this.currentBannerIconRotate,
            style: `
                    flex: 1;
                    writing-mode: horizontal-tb;
                    direction: ltr;
                `
          }
        });
        const bannerIconRotateValue = bannerIconRotateContainer.createDiv({
          cls: "banner-icon-rotate-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        bannerIconRotateValue.setText(`${this.currentBannerIconRotate}`);
        bannerIconRotateSlider.addEventListener("input", () => {
          this.currentBannerIconRotate = parseInt(bannerIconRotateSlider.value);
          bannerIconRotateValue.setText(`${this.currentBannerIconRotate}`);
          this.updateBannerIconRotate(this.currentBannerIconRotate);
        });
        const bannerIconColorContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-color-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    flex: 0 auto;
                    margin-top: 10px;
                `
          }
        });
        const bannerIconColorLabel = bannerIconColorContainer.createEl("div", {
          text: "Icon Text Color",
          cls: "banner-icon-color-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const iconColorField = Array.isArray(this.plugin.settings.customBannerIconColorField) ? this.plugin.settings.customBannerIconColorField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconColorField;
        let currentIconColor = this.plugin.settings.bannerIconColor;
        if ((frontmatter == null ? void 0 : frontmatter[iconColorField]) || this.plugin.settings.bannerIconColor) {
          const colorValue = (frontmatter == null ? void 0 : frontmatter[iconColorField]) || this.plugin.settings.bannerIconColor;
          if (typeof colorValue === "string" && colorValue.startsWith("#")) {
            currentIconColor = colorValue;
          } else if (typeof colorValue === "string" && colorValue.trim() !== "") {
            currentIconColor = colorValue;
          }
        }
        this.currentBannerIconColor = currentIconColor;
        const ensureValidHexColor = (color) => {
          if (!color || !/^#[0-9A-F]{6}$/i.test(color)) {
            return "#000000";
          }
          return color;
        };
        const bannerIconColorPicker = bannerIconColorContainer.createEl("input", {
          type: "color",
          cls: "banner-icon-color-picker",
          attr: {
            value: ensureValidHexColor(this.currentBannerIconColor),
            style: `
                    width: 30px;
                    height: 30px;
                    cursor: pointer;
                    padding: 0;
                    background-color: transparent;
                    margin-left: 5px;
                    border: 1px solid;
                    border-radius: 50%;
                `
          }
        });
        const bannerIconColorInput = bannerIconColorContainer.createEl("input", {
          type: "text",
          cls: "banner-icon-color-input",
          attr: {
            value: this.currentBannerIconColor || "",
            placeholder: "#RRGGBB or color name",
            style: `
                    flex: 1;
                    max-width: 120px;
                `
          }
        });
        bannerIconColorInput.addEventListener("change", () => {
          this.currentBannerIconColor = bannerIconColorInput.value;
          if (this.currentBannerIconColor.startsWith("#")) {
            bannerIconColorPicker.value = this.currentBannerIconColor;
          }
          this.updateBannerIconColor(this.currentBannerIconColor);
        });
        bannerIconColorPicker.addEventListener("input", () => {
          this.currentBannerIconColor = bannerIconColorPicker.value;
          bannerIconColorInput.value = this.currentBannerIconColor;
          this.updateBannerIconColor(this.currentBannerIconColor);
        });
        const bannerIconFontWeightContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-font-weight-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                    margin-top: 10px;
                `
          }
        });
        const bannerIconFontWeightLabel = bannerIconFontWeightContainer.createEl("div", {
          text: "Icon Text Font Weight",
          cls: "banner-icon-font-weight-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const iconFontWeightField = Array.isArray(this.plugin.settings.customBannerIconFontWeightField) ? this.plugin.settings.customBannerIconFontWeightField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconFontWeightField;
        this.currentBannerIconFontWeight = (frontmatter == null ? void 0 : frontmatter[iconFontWeightField]) || this.plugin.settings.bannerIconFontWeight;
        const bannerIconFontWeightSelect = bannerIconFontWeightContainer.createEl("select", {
          cls: "banner-icon-font-weight-select"
        });
        ["lighter", "normal", "bold"].forEach((weight) => {
          const option = bannerIconFontWeightSelect.createEl("option", {
            text: weight.charAt(0).toUpperCase() + weight.slice(1),
            value: weight
          });
          if (weight === this.currentBannerIconFontWeight) {
            option.selected = true;
          }
        });
        bannerIconFontWeightSelect.addEventListener("change", () => {
          this.currentBannerIconFontWeight = bannerIconFontWeightSelect.value;
          this.updateBannerIconFontWeight(this.currentBannerIconFontWeight);
        });
        const bannerIconBgColorContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-bg-color-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: column;
                    gap: 10px;
                    min-width: 60px;
                    flex: 0 auto;
                    margin-top: 10px;
                `
          }
        });
        const bannerIconBgColorLabel = bannerIconBgColorContainer.createEl("div", {
          text: "Icon Background Color",
          cls: "banner-icon-bg-color-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const colorPickerAndAlphaSliderRow = bannerIconBgColorContainer.createDiv({
          cls: "color-picker-and-alpha-slider-row",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    width: 100%;
                `
          }
        });
        const colorPickerRow = colorPickerAndAlphaSliderRow.createDiv({
          cls: "color-picker-row",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    width: 100%;
                `
          }
        });
        const iconBgColorField = Array.isArray(this.plugin.settings.customBannerIconBackgroundColorField) ? this.plugin.settings.customBannerIconBackgroundColorField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconBackgroundColorField;
        let currentColor = this.plugin.settings.bannerIconBackgroundColor;
        let currentAlpha = 100;
        if ((frontmatter == null ? void 0 : frontmatter[iconBgColorField]) || this.plugin.settings.bannerIconBackgroundColor) {
          const colorValue = (frontmatter == null ? void 0 : frontmatter[iconBgColorField]) || this.plugin.settings.bannerIconBackgroundColor;
          const rgbaMatch = colorValue == null ? void 0 : colorValue.match(/rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);
          if (rgbaMatch) {
            const r = parseInt(rgbaMatch[1]);
            const g = parseInt(rgbaMatch[2]);
            const b = parseInt(rgbaMatch[3]);
            currentColor = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
            currentAlpha = Math.round(parseFloat(rgbaMatch[4]) * 100);
          } else if (colorValue == null ? void 0 : colorValue.startsWith("#")) {
            currentColor = colorValue;
          } else if (colorValue) {
            currentColor = colorValue;
          }
        }
        this.currentBannerIconBgColor = currentColor;
        this.currentBannerIconBgAlpha = currentAlpha;
        const bannerIconBgColorInput = colorPickerAndAlphaSliderRow.createEl("input", {
          type: "text",
          cls: "banner-icon-bg-color-input",
          attr: {
            value: this.currentBannerIconBgColor || "",
            placeholder: "#RRGGBB or color name",
            style: `
                    flex: 1;
                    max-width: 120px;
                `
          }
        });
        const bannerIconBgColorPicker = colorPickerAndAlphaSliderRow.createEl("input", {
          type: "color",
          cls: "banner-icon-bg-color-picker",
          attr: {
            value: this.currentBannerIconBgColor && this.currentBannerIconBgColor.startsWith("#") ? this.currentBannerIconBgColor : "",
            style: `
                    width: 30px;
                    height: 30px;
                    cursor: pointer;
                    padding: 0;
                    background-color: transparent;
                    margin-left: 5px;
                    border: 1px solid;
                    border-radius: 50%;
                `
          }
        });
        const alphaSliderRow = colorPickerAndAlphaSliderRow.createDiv({
          cls: "alpha-slider-row",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    width: 100%;
                    margin-top: 5px;
                `
          }
        });
        const alphaLabel = colorPickerAndAlphaSliderRow.createEl("div", {
          text: "Opacity:",
          cls: "alpha-label",
          attr: {
            style: `
                    color: var(--text-muted);
                    font-size: 0.9em;
                    min-width: 60px;
                `
          }
        });
        const alphaSlider = colorPickerAndAlphaSliderRow.createEl("input", {
          type: "range",
          cls: "alpha-slider",
          attr: {
            min: "0",
            max: "100",
            step: "1",
            value: this.currentBannerIconBgAlpha,
            style: `
                    flex: 1;
                `
          }
        });
        const alphaValue = colorPickerAndAlphaSliderRow.createDiv({
          cls: "alpha-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                    min-width: 40px;
                    text-align: right;
                `
          }
        });
        alphaValue.setText(`${this.currentBannerIconBgAlpha}%`);
        const colorPreview = colorPickerAndAlphaSliderRow.createDiv({
          cls: "color-preview",
          attr: {
            style: `
                    width: 100%;
                    height: 20px;
                    border: 1px solid var(--background-modifier-border);
                    border-radius: 4px;
                    background-color: ${this.currentBannerIconBgColor};
                    opacity: ${this.currentBannerIconBgAlpha / 100};
                `
          }
        });
        const updateColorPreview = () => {
          colorPreview.style.backgroundColor = this.currentBannerIconBgColor;
          colorPreview.style.opacity = this.currentBannerIconBgAlpha / 100;
          this.updateBannerIconBgColor(this.currentBannerIconBgColor, this.currentBannerIconBgAlpha);
        };
        bannerIconBgColorInput.addEventListener("change", () => {
          this.currentBannerIconBgColor = bannerIconBgColorInput.value;
          if (this.currentBannerIconBgColor.startsWith("#")) {
            bannerIconBgColorPicker.value = this.currentBannerIconBgColor;
          }
          updateColorPreview();
        });
        bannerIconBgColorPicker.addEventListener("input", () => {
          this.currentBannerIconBgColor = bannerIconBgColorPicker.value;
          bannerIconBgColorInput.value = this.currentBannerIconBgColor;
          updateColorPreview();
        });
        alphaSlider.addEventListener("input", () => {
          this.currentBannerIconBgAlpha = parseInt(alphaSlider.value);
          alphaValue.setText(`${this.currentBannerIconBgAlpha}%`);
          updateColorPreview();
        });
        const bannerIconPaddingXContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-padding-x-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                    margin-top: 10px;
                `
          }
        });
        const bannerIconPaddingXLabel = bannerIconPaddingXContainer.createEl("div", {
          text: "Icon Padding X",
          cls: "banner-icon-padding-x-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const iconPaddingXField = Array.isArray(this.plugin.settings.customBannerIconPaddingXField) ? this.plugin.settings.customBannerIconPaddingXField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconPaddingXField;
        this.currentBannerIconPaddingX = (frontmatter == null ? void 0 : frontmatter[iconPaddingXField]) || this.plugin.settings.bannerIconPaddingX;
        const bannerIconPaddingXSlider = bannerIconPaddingXContainer.createEl("input", {
          type: "range",
          cls: "banner-icon-padding-x-slider",
          attr: {
            min: "0",
            max: "100",
            step: "1",
            value: this.currentBannerIconPaddingX,
            style: `
                    flex: 1;
                    writing-mode: horizontal-tb;
                    direction: ltr;
                `
          }
        });
        const bannerIconPaddingXValue = bannerIconPaddingXContainer.createDiv({
          cls: "banner-icon-padding-x-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        bannerIconPaddingXValue.setText(`${this.currentBannerIconPaddingX}`);
        bannerIconPaddingXSlider.addEventListener("input", () => {
          this.currentBannerIconPaddingX = parseInt(bannerIconPaddingXSlider.value);
          bannerIconPaddingXValue.setText(`${this.currentBannerIconPaddingX}`);
          this.updateBannerIconPaddingX(this.currentBannerIconPaddingX);
        });
        const bannerIconPaddingYContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-padding-y-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                    margin-top: 10px;
                `
          }
        });
        const bannerIconPaddingYLabel = bannerIconPaddingYContainer.createEl("div", {
          text: "Icon Padding Y",
          cls: "banner-icon-padding-y-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const iconPaddingYField = Array.isArray(this.plugin.settings.customBannerIconPaddingYField) ? this.plugin.settings.customBannerIconPaddingYField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconPaddingYField;
        this.currentBannerIconPaddingY = (frontmatter == null ? void 0 : frontmatter[iconPaddingYField]) || this.plugin.settings.bannerIconPaddingY;
        const bannerIconPaddingYSlider = bannerIconPaddingYContainer.createEl("input", {
          type: "range",
          cls: "banner-icon-padding-y-slider",
          attr: {
            min: "0",
            max: "100",
            step: "1",
            value: this.currentBannerIconPaddingY,
            style: `
                    flex: 1;
                    writing-mode: horizontal-tb;
                    direction: ltr;
                `
          }
        });
        const bannerIconPaddingYValue = bannerIconPaddingYContainer.createDiv({
          cls: "banner-icon-padding-y-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        bannerIconPaddingYValue.setText(`${this.currentBannerIconPaddingY}`);
        bannerIconPaddingYSlider.addEventListener("input", () => {
          this.currentBannerIconPaddingY = parseInt(bannerIconPaddingYSlider.value);
          bannerIconPaddingYValue.setText(`${this.currentBannerIconPaddingY}`);
          this.updateBannerIconPaddingY(this.currentBannerIconPaddingY);
        });
        const bannerIconBorderRadiusContainer = bannerIconControlsContainer.createDiv({
          cls: "banner-icon-border-radius-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    min-width: 60px;
                    flex: 0 auto;
                    margin-top: 10px;
                `
          }
        });
        const bannerIconBorderRadiusLabel = bannerIconBorderRadiusContainer.createEl("div", {
          text: "Icon Border Radius",
          cls: "banner-icon-border-radius-label",
          attr: {
            style: `
                    color: var(--text-muted); 
                    font-size: 0.9em;
                `
          }
        });
        const iconBorderRadiusField = Array.isArray(this.plugin.settings.customBannerIconBorderRadiusField) ? this.plugin.settings.customBannerIconBorderRadiusField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconBorderRadiusField;
        this.currentBannerIconBorderRadius = getValueWithZeroCheck([
          frontmatter == null ? void 0 : frontmatter[iconBorderRadiusField],
          this.plugin.settings.bannerIconBorderRadius
        ]);
        const bannerIconBorderRadiusSlider = bannerIconBorderRadiusContainer.createEl("input", {
          type: "range",
          cls: "banner-icon-border-radius-slider",
          attr: {
            min: "0",
            max: "200",
            step: "1",
            value: this.currentBannerIconBorderRadius,
            style: `
                    flex: 1;
                    writing-mode: horizontal-tb;
                    direction: ltr;
                `
          }
        });
        const bannerIconBorderRadiusValue = bannerIconBorderRadiusContainer.createDiv({
          cls: "banner-icon-border-radius-value",
          attr: {
            style: `
                    font-family: var(--font-monospace);
                    font-size: 0.9em;
                `
          }
        });
        bannerIconBorderRadiusValue.setText(`${this.currentBannerIconBorderRadius}`);
        bannerIconBorderRadiusSlider.addEventListener("input", () => {
          this.currentBannerIconBorderRadius = parseInt(bannerIconBorderRadiusSlider.value);
          bannerIconBorderRadiusValue.setText(`${this.currentBannerIconBorderRadius}`);
          this.updateBannerIconBorderRadius(this.currentBannerIconBorderRadius);
        });
        const flagColorSection = contentEl.createDiv({
          cls: "flag-color-section",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 5px;
                    margin-top: 20px;
                    padding: 15px;
                    border-radius: 5px;
                    background-color: var(--background-secondary);
                    max-width: 600px;
                `
          }
        });
        flagColorSection.createEl("span", {
          text: "Flag Color",
          attr: {
            style: `
                    color: var(--text-muted);
                    font-size: 0.9em;
                `
          }
        });
        const flagRadioContainer = flagColorSection.createDiv({
          cls: "pixel-banner-flag-radio-container",
          attr: {
            style: `
                    max-width: 440px;
                    display: flex;
                    flex-direction: row;
                    flex-wrap: wrap;
                    gap: 10px;
                `
          }
        });
        const currentFlagColor = getFrontmatterValue(frontmatter, this.plugin.settings.customFlagColorField) || this.plugin.settings.selectImageIconFlag;
        Object.keys(flags).forEach((color) => {
          const radioContainer = flagRadioContainer.createDiv({
            cls: "pixel-banner-flag-radio",
            attr: {
              style: `
                        display: flex;
                        align-items: center;
                        gap: 5px;
                    `
            }
          });
          const radio = radioContainer.createEl("input", {
            type: "radio",
            attr: {
              id: `flag-${color}`,
              name: "pixel-banner-flag",
              value: color,
              style: `
                        margin-right: 5px;
                        cursor: pointer;
                    `
            }
          });
          radio.checked = currentFlagColor === color;
          const label = radioContainer.createEl("label", {
            attr: {
              for: `flag-${color}`,
              style: `
                        display: flex;
                        align-items: center;
                        cursor: pointer;
                    `
            }
          });
          label.createEl("img", {
            attr: {
              src: flags[color],
              alt: color,
              style: `
                        width: 15px;
                        height: 20px;
                        margin-right: 3px;
                    `
            }
          });
          label.createEl("span", {
            text: color.charAt(0).toUpperCase() + color.slice(1),
            attr: {
              style: `
                        display: none;
                        font-size: 12px;
                    `
            }
          });
          radio.addEventListener("change", async () => {
            if (radio.checked) {
              const activeFile2 = this.app.workspace.getActiveFile();
              if (activeFile2) {
                await this.plugin.app.fileManager.processFrontMatter(activeFile2, (frontmatter2) => {
                  const flagColorField = this.plugin.settings.customFlagColorField[0];
                  frontmatter2[flagColorField] = color;
                });
                const view = this.plugin.app.workspace.getActiveViewOfType(import_obsidian17.MarkdownView);
                if (view) {
                  await this.plugin.updateBanner(view, true);
                }
              }
            }
          });
        });
        const inlineTitleEnabled = this.app.vault.config.showInlineTitle;
        const titleColorSection = contentEl.createDiv({
          cls: "title-color-section",
          attr: {
            style: `
                    display: ${inlineTitleEnabled ? "flex" : "none"};
                    flex-direction: row;
                    gap: 10px;
                    margin-top: 20px;
                    padding: 15px;
                    border-radius: 5px;
                    background-color: var(--background-secondary);
                    max-width: 510px;
                    align-items: center;
                `
          }
        });
        titleColorSection.createEl("span", {
          text: "Inline Title Color",
          attr: {
            style: `
                    color: var(--text-muted);
                    font-size: 0.9em;
                    min-width: 90px;
                `
          }
        });
        const titleColorField = Array.isArray(this.plugin.settings.customTitleColorField) ? this.plugin.settings.customTitleColorField[0].split(",")[0].trim() : this.plugin.settings.customTitleColorField;
        let currentTitleColor = (frontmatter == null ? void 0 : frontmatter[titleColorField]) || this.plugin.settings.titleColor;
        if (currentTitleColor && currentTitleColor.startsWith("var(--")) {
          const tempEl = document.createElement("div");
          tempEl.style.color = currentTitleColor;
          document.body.appendChild(tempEl);
          const computedColor = window.getComputedStyle(tempEl).color;
          document.body.removeChild(tempEl);
          const rgbMatch = computedColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
          if (rgbMatch) {
            const [_, r, g, b] = rgbMatch;
            currentTitleColor = "#" + parseInt(r).toString(16).padStart(2, "0") + parseInt(g).toString(16).padStart(2, "0") + parseInt(b).toString(16).padStart(2, "0");
          }
        }
        this.currentTitleColor = currentTitleColor || (getCurrentTheme_default() === "dark" ? "#ffffff" : "#000000");
        const titleColorInput = titleColorSection.createEl("input", {
          type: "text",
          cls: "title-color-input",
          attr: {
            value: this.currentTitleColor || "",
            placeholder: "#RRGGBB or color name",
            style: `
                    flex: 1;
                    max-width: 90px;
                `
          }
        });
        const titleColorPicker = titleColorSection.createEl("input", {
          type: "color",
          cls: "title-color-picker",
          attr: {
            value: this.currentTitleColor && this.currentTitleColor.startsWith("#") ? this.currentTitleColor : getCurrentTheme_default() === "dark" ? "#ffffff" : "#000000",
            style: `
                    width: 30px;
                    height: 30px;
                    cursor: pointer;
                    padding: 0;
                    background-color: transparent;
                    margin-left: 5px;
                `
          }
        });
        titleColorInput.addEventListener("change", () => {
          this.currentTitleColor = titleColorInput.value;
          if (this.currentTitleColor.startsWith("#")) {
            titleColorPicker.value = this.currentTitleColor;
          }
          this.updateTitleColor(this.currentTitleColor);
        });
        titleColorPicker.addEventListener("input", () => {
          this.currentTitleColor = titleColorPicker.value;
          titleColorInput.value = this.currentTitleColor;
          this.updateTitleColor(this.currentTitleColor);
        });
        const buttonContainer = contentEl.createDiv({
          cls: "button-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    justify-content: center;
                    position: sticky;
                    bottom: -20px;
                    background: var(--modal-background);
                    padding: 20px 0;
                `
          }
        });
        const resetButton = buttonContainer.createEl("button", {
          text: "Reset to Defaults",
          cls: "reset-button",
          attr: {
            style: `
                    flex: 1;
                `
          }
        });
        const closeSettingsButton = buttonContainer.createEl("button", {
          text: "Close Settings",
          cls: "mod-cta close-settings-button",
          attr: {
            style: `
                    flex: 1;
                `
          }
        });
        closeSettingsButton.addEventListener("click", () => {
          this.close();
        });
        this.resetPixelBannerNoteSettings = (deleteBannerAndIcon = false) => {
          displaySelect.value = "cover";
          zoomContainer.style.display = "none";
          repeatContainer.style.display = "none";
          zoomSlider.value = 100;
          heightSlider.value = this.plugin.settings.bannerHeight;
          contentStartPositionSlider.value = this.plugin.settings.contentStartPosition;
          bannerIconXPositionSlider.value = this.plugin.settings.bannerIconXPosition;
          bannerFadeSlider.value = this.plugin.settings.fade;
          bannerFadeValue.setText(this.plugin.settings.fade.toString());
          if (borderRadiusSlider) borderRadiusSlider.value = this.plugin.settings.borderRadius;
          if (borderRadiusValue) borderRadiusValue.setText(this.plugin.settings.borderRadius.toString());
          this.updateBannerBorderRadius(this.plugin.settings.borderRadius);
          const currentTheme = getCurrentTheme_default();
          let defaultColor = currentTheme === "dark" ? "#ffffff" : "#000000";
          if (bannerIconSizeSlider) bannerIconSizeSlider.value = this.plugin.settings.bannerIconSize;
          if (bannerIconImageSizeMultiplierSlider) bannerIconImageSizeMultiplierSlider.value = this.plugin.settings.bannerIconImageSizeMultiplier;
          if (bannerIconRotateSlider) bannerIconRotateSlider.value = 0;
          if (bannerIconTextVerticalOffsetSlider) bannerIconTextVerticalOffsetSlider.value = this.plugin.settings.bannerIconTextVerticalOffset;
          if (bannerIconColorInput) {
            const defaultIconColor = this.plugin.settings.bannerIconColor || defaultColor;
            bannerIconColorInput.value = defaultIconColor;
            if (bannerIconColorPicker) {
              bannerIconColorPicker.value = defaultIconColor.startsWith("#") ? defaultIconColor : defaultColor;
            }
            this.updateBannerIconColor(defaultIconColor);
          }
          if (bannerIconFontWeightSelect) bannerIconFontWeightSelect.value = this.plugin.settings.bannerIconFontWeight;
          if (bannerIconBgColorInput) {
            let defaultAlpha = 100;
            if (this.plugin.settings.bannerIconBackgroundColor) {
              const colorValue = this.plugin.settings.bannerIconBackgroundColor;
              const rgbaMatch = colorValue == null ? void 0 : colorValue.match(/rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);
              if (rgbaMatch) {
                const r = parseInt(rgbaMatch[1]);
                const g = parseInt(rgbaMatch[2]);
                const b = parseInt(rgbaMatch[3]);
                defaultColor = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
                defaultAlpha = Math.round(parseFloat(rgbaMatch[4]) * 100);
              } else if (colorValue == null ? void 0 : colorValue.startsWith("#")) {
                defaultColor = colorValue;
              } else if (colorValue) {
                defaultColor = colorValue;
              }
            }
            bannerIconBgColorInput.value = defaultColor;
            if (bannerIconBgColorPicker) bannerIconBgColorPicker.value = defaultColor.startsWith("#") ? defaultColor : "#ffffff";
            if (alphaSlider) alphaSlider.value = defaultAlpha;
            if (alphaValue) alphaValue.setText(`${defaultAlpha}%`);
            if (colorPreview) {
              colorPreview.style.backgroundColor = defaultColor;
              colorPreview.style.opacity = defaultAlpha / 100;
            }
            this.updateBannerIconBgColor(defaultColor, defaultAlpha);
          }
          if (bannerIconPaddingXSlider) bannerIconPaddingXSlider.value = this.plugin.settings.bannerIconPaddingX;
          if (bannerIconPaddingYSlider) bannerIconPaddingYSlider.value = this.plugin.settings.bannerIconPaddingY;
          if (bannerIconBorderRadiusSlider) bannerIconBorderRadiusSlider.value = this.plugin.settings.bannerIconBorderRadius;
          if (bannerIconVerticalOffsetSlider) bannerIconVerticalOffsetSlider.value = this.plugin.settings.bannerIconVerticalOffset;
          if (bannerIconSizeSlider) bannerIconSizeSlider.value = this.plugin.settings.bannerIconSize;
          if (bannerIconRotateSlider) bannerIconRotateSlider.value = 0;
          zoomValue.setText("100%");
          heightValue.setText(`${this.plugin.settings.bannerHeight}px`);
          contentStartPositionValue.setText(`${this.plugin.settings.contentStartPosition}px`);
          bannerIconXPositionValue.setText(`${this.plugin.settings.bannerIconXPosition}`);
          if (unsetCheckbox) {
            unsetCheckbox.checked = true;
            maxWidthValueDisplay.style.color = "var(--text-muted)";
            maxWidthValueDisplay.setText("unset");
          }
          if (alignmentSelect) {
            alignmentSelect.value = "center";
          }
          if (bannerIconSizeValue) bannerIconSizeValue.setText(`${this.plugin.settings.bannerIconSize}`);
          if (bannerIconImageSizeMultiplierValue) bannerIconImageSizeMultiplierValue.setText(`${this.plugin.settings.bannerIconImageSizeMultiplier}`);
          if (bannerIconTextVerticalOffsetValue) bannerIconTextVerticalOffsetValue.setText(`${this.plugin.settings.bannerIconTextVerticalOffset}`);
          if (bannerIconPaddingXValue) bannerIconPaddingXValue.setText(`${this.plugin.settings.bannerIconPaddingX}`);
          if (bannerIconPaddingYValue) bannerIconPaddingYValue.setText(`${this.plugin.settings.bannerIconPaddingY}`);
          if (bannerIconBorderRadiusValue) bannerIconBorderRadiusValue.setText(`${this.plugin.settings.bannerIconBorderRadius}`);
          if (bannerIconVerticalOffsetValue) bannerIconVerticalOffsetValue.setText(`${this.plugin.settings.bannerIconVerticalOffset}`);
          if (bannerIconRotateValue) bannerIconRotateValue.setText(`${this.plugin.settings.bannerIconRotate}`);
          toggleInput.checked = false;
          this.currentX = this.plugin.settings.xPosition;
          this.currentY = this.plugin.settings.yPosition;
          verticalLine.style.left = `${this.currentX}%`;
          horizontalLine.style.top = `${this.currentY}%`;
          updatePositionIndicator();
          const activeFile2 = this.app.workspace.getActiveFile();
          this.app.fileManager.processFrontMatter(activeFile2, (frontmatter2) => {
            const displayField = Array.isArray(this.plugin.settings.customImageDisplayField) ? this.plugin.settings.customImageDisplayField[0].split(",")[0].trim() : this.plugin.settings.customImageDisplayField;
            const heightField = Array.isArray(this.plugin.settings.customBannerHeightField) ? this.plugin.settings.customBannerHeightField[0].split(",")[0].trim() : this.plugin.settings.customBannerHeightField;
            const maxWidthField2 = Array.isArray(this.plugin.settings.customBannerMaxWidthField) ? this.plugin.settings.customBannerMaxWidthField[0].split(",")[0].trim() : this.plugin.settings.customBannerMaxWidthField;
            const xField = Array.isArray(this.plugin.settings.customXPositionField) ? this.plugin.settings.customXPositionField[0].split(",")[0].trim() : this.plugin.settings.customXPositionField;
            const yField = Array.isArray(this.plugin.settings.customYPositionField) ? this.plugin.settings.customYPositionField[0].split(",")[0].trim() : this.plugin.settings.customYPositionField;
            const contentStartPositionField = Array.isArray(this.plugin.settings.customContentStartField) ? this.plugin.settings.customContentStartField[0].split(",")[0].trim() : this.plugin.settings.customContentStartField;
            const bannerIconXPositionField = Array.isArray(this.plugin.settings.customBannerIconXPositionField) ? this.plugin.settings.customBannerIconXPositionField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconXPositionField;
            const bannerIconImageAlignmentField = Array.isArray(this.plugin.settings.customBannerIconImageAlignmentField) ? this.plugin.settings.customBannerIconImageAlignmentField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageAlignmentField;
            const repeatField = Array.isArray(this.plugin.settings.customImageRepeatField) ? this.plugin.settings.customImageRepeatField[0].split(",")[0].trim() : this.plugin.settings.customImageRepeatField;
            const fadeField = Array.isArray(this.plugin.settings.customFadeField) ? this.plugin.settings.customFadeField[0].split(",")[0].trim() : this.plugin.settings.customFadeField;
            const borderRadiusField = Array.isArray(this.plugin.settings.customBorderRadiusField) ? this.plugin.settings.customBorderRadiusField[0].split(",")[0].trim() : this.plugin.settings.customBorderRadiusField;
            const bannerIconColorField = Array.isArray(this.plugin.settings.customBannerIconColorField) ? this.plugin.settings.customBannerIconColorField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconColorField;
            const bannerIconFontWeightField = Array.isArray(this.plugin.settings.customBannerIconFontWeightField) ? this.plugin.settings.customBannerIconFontWeightField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconFontWeightField;
            const bannerIconBgColorField = Array.isArray(this.plugin.settings.customBannerIconBackgroundColorField) ? this.plugin.settings.customBannerIconBackgroundColorField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconBackgroundColorField;
            const bannerIconPaddingXField = Array.isArray(this.plugin.settings.customBannerIconPaddingXField) ? this.plugin.settings.customBannerIconPaddingXField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconPaddingXField;
            const bannerIconPaddingYField = Array.isArray(this.plugin.settings.customBannerIconPaddingYField) ? this.plugin.settings.customBannerIconPaddingYField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconPaddingYField;
            const bannerIconBorderRadiusField = Array.isArray(this.plugin.settings.customBannerIconBorderRadiusField) ? this.plugin.settings.customBannerIconBorderRadiusField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconBorderRadiusField;
            const bannerIconVerticalOffsetField = Array.isArray(this.plugin.settings.customBannerIconVerticalOffsetField) ? this.plugin.settings.customBannerIconVerticalOffsetField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconVerticalOffsetField;
            const bannerIconSizeField = Array.isArray(this.plugin.settings.customBannerIconSizeField) ? this.plugin.settings.customBannerIconSizeField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconSizeField;
            const bannerIconTextVerticalOffsetField = Array.isArray(this.plugin.settings.customBannerIconTextVerticalOffsetField) ? this.plugin.settings.customBannerIconTextVerticalOffsetField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconTextVerticalOffsetField;
            const bannerIconImageSizeMultiplierField = Array.isArray(this.plugin.settings.customBannerIconImageSizeMultiplierField) ? this.plugin.settings.customBannerIconImageSizeMultiplierField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageSizeMultiplierField;
            const bannerIconRotateField = Array.isArray(this.plugin.settings.customBannerIconRotateField) ? this.plugin.settings.customBannerIconRotateField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconRotateField;
            delete frontmatter2[displayField];
            delete frontmatter2[heightField];
            delete frontmatter2[maxWidthField2];
            delete frontmatter2[xField];
            delete frontmatter2[yField];
            delete frontmatter2[contentStartPositionField];
            delete frontmatter2[repeatField];
            delete frontmatter2[fadeField];
            delete frontmatter2[borderRadiusField];
            delete frontmatter2[bannerIconXPositionField];
            delete frontmatter2[bannerIconImageAlignmentField];
            delete frontmatter2[bannerIconColorField];
            delete frontmatter2[bannerIconFontWeightField];
            delete frontmatter2[bannerIconBgColorField];
            delete frontmatter2[bannerIconPaddingXField];
            delete frontmatter2[bannerIconPaddingYField];
            delete frontmatter2[bannerIconBorderRadiusField];
            delete frontmatter2[bannerIconVerticalOffsetField];
            delete frontmatter2[bannerIconSizeField];
            delete frontmatter2[bannerIconTextVerticalOffsetField];
            delete frontmatter2[bannerIconImageSizeMultiplierField];
            delete frontmatter2[bannerIconRotateField];
            const alignmentField = Array.isArray(this.plugin.settings.customBannerAlignmentField) ? this.plugin.settings.customBannerAlignmentField[0].split(",")[0].trim() : this.plugin.settings.customBannerAlignmentField;
            delete frontmatter2[alignmentField];
            const flagColorField = Array.isArray(this.plugin.settings.customFlagColorField) ? this.plugin.settings.customFlagColorField[0].split(",")[0].trim() : this.plugin.settings.customFlagColorField;
            delete frontmatter2[flagColorField];
            if (deleteBannerAndIcon) {
              const bannerField2 = Array.isArray(this.plugin.settings.customBannerField) ? this.plugin.settings.customBannerField[0].split(",")[0].trim() : this.plugin.settings.customBannerField;
              const bannerIconImageField2 = Array.isArray(this.plugin.settings.customBannerIconImageField) ? this.plugin.settings.customBannerIconImageField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageField;
              const bannerIconField2 = Array.isArray(this.plugin.settings.customBannerIconField) ? this.plugin.settings.customBannerIconField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconField;
              delete frontmatter2[bannerField2];
              delete frontmatter2[bannerIconImageField2];
              delete frontmatter2[bannerIconField2];
            }
          });
          if (flagRadioContainer) {
            const flagRadios = flagRadioContainer.querySelectorAll('input[type="radio"]');
            flagRadios.forEach((radio) => {
              radio.checked = radio.value === this.plugin.settings.selectImageIconFlag;
            });
          }
          if (bannerIconImageAlignmentRadioContainer) {
            const bannerIconImageAlignmentRadios = bannerIconImageAlignmentRadioContainer.querySelectorAll('input[type="radio"]');
            bannerIconImageAlignmentRadios.forEach((radio) => {
              radio.checked = radio.value === this.plugin.settings.bannerIconImageAlignment;
            });
          }
          if (inlineTitleEnabled && titleColorInput) {
            let defaultTitleColor = this.plugin.settings.titleColor;
            if (defaultTitleColor.startsWith("var(--")) {
              console.log("defaultTitleColor", defaultTitleColor);
              const tempEl = document.createElement("div");
              tempEl.style.color = defaultTitleColor;
              document.body.appendChild(tempEl);
              const computedColor = window.getComputedStyle(tempEl).color;
              document.body.removeChild(tempEl);
              const rgbMatch = computedColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
              if (rgbMatch) {
                const [_, r, g, b] = rgbMatch;
                defaultTitleColor = "#" + parseInt(r).toString(16).padStart(2, "0") + parseInt(g).toString(16).padStart(2, "0") + parseInt(b).toString(16).padStart(2, "0");
              }
            }
            titleColorInput.value = defaultTitleColor;
            if (titleColorPicker) {
              titleColorPicker.value = defaultTitleColor.startsWith("#") ? defaultTitleColor : getCurrentTheme_default() === "dark" ? "#ffffff" : "#000000";
            }
          }
          const titleColorField2 = Array.isArray(this.plugin.settings.customTitleColorField) ? this.plugin.settings.customTitleColorField[0].split(",")[0].trim() : this.plugin.settings.customTitleColorField;
          if (activeFile2) {
            this.app.fileManager.processFrontMatter(activeFile2, (fm) => {
              delete fm[titleColorField2];
            });
          }
          this.currentX = this.plugin.settings.xPosition;
          this.currentY = this.plugin.settings.yPosition;
          verticalLine.style.left = `${this.currentX}%`;
          horizontalLine.style.top = `${this.currentY}%`;
          updatePositionIndicator();
          setTimeout(() => {
            const view = this.app.workspace.getActiveViewOfType(import_obsidian17.MarkdownView);
            if (view) {
              this.plugin.updateBanner(view, true);
            }
          }, 750);
          if (deleteBannerAndIcon) {
            this.close();
          }
        };
        resetButton.addEventListener("click", () => {
          this.resetPixelBannerNoteSettings();
        });
        const repeatContainer = controlPanel.createDiv({
          cls: "repeat-container",
          attr: {
            style: `
                    display: ${this.currentDisplay === "contain" || this.currentDisplay === "auto" ? "flex" : "none"};
                    flex-direction: column;
                    gap: 5px;
                    align-items: center;
                    justify-content: flex-start;
                    margin-top: 10px;
                    max-width: 70px;
                    text-align: center;
                `
          }
        });
        const repeatLabel = repeatContainer.createEl("div", {
          text: "repeat banner image?",
          cls: "repeat-label",
          attr: {
            style: `
                    color: var(--text-muted);
                    font-size: 0.9em;
                    margin-bottom: 20px;
                `
          }
        });
        const repeatToggle = repeatContainer.createEl("div", {
          cls: "repeat-toggle",
          attr: {
            style: `
                    margin-top: 10px;
                `
          }
        });
        const toggleInput = repeatToggle.createEl("input", {
          type: "checkbox",
          cls: "repeat-checkbox",
          attr: {
            checked: this.currentDisplay === "contain" || this.currentDisplay === "auto" ? this.currentRepeat : this.plugin.settings.imageRepeat
          }
        });
        displaySelect.addEventListener("change", () => {
          const mode = displaySelect.value;
          zoomContainer.style.display = mode === "cover-zoom" ? "flex" : "none";
          repeatContainer.style.display = mode === "contain" || mode === "auto" ? "flex" : "none";
          if (mode === "contain" || mode === "auto") {
            toggleInput.checked = this.currentRepeat;
          } else {
            toggleInput.checked = this.plugin.settings.imageRepeat;
            this.currentRepeat = this.plugin.settings.imageRepeat;
          }
          this.updateDisplayMode(mode, mode === "cover-zoom" ? this.currentZoom : null);
        });
        toggleInput.addEventListener("change", () => {
          this.currentRepeat = toggleInput.checked;
          this.updateRepeatMode(this.currentRepeat);
        });
        let isDragging = false;
        let offsetX, offsetY;
        let isCrosshairDragging = false;
        modalEl.addEventListener("mousedown", (e) => {
          if (e.target === zoomSlider || e.target === heightSlider || e.target === maxWidthSlider || e.target === contentStartPositionSlider || e.target === bannerFadeSlider || e.target === borderRadiusSlider || e.target === bannerIconXPositionSlider || e.target === bannerIconSizeSlider || e.target === bannerIconImageSizeMultiplierSlider || e.target === bannerIconTextVerticalOffsetSlider || e.target === bannerIconRotateSlider || e.target === bannerIconColorPicker || e.target === bannerIconColorInput || e.target === bannerIconPaddingXSlider || e.target === bannerIconPaddingYSlider || e.target === bannerIconBorderRadiusSlider || e.target === bannerIconVerticalOffsetSlider || e.target === alphaSlider || e.target === bannerIconBgColorPicker || e.target === bannerIconBgColorInput || e.target === titleColorPicker || e.target === titleColorInput || e.target === targetArea || e.target === verticalLine || e.target === horizontalLine) return;
          isDragging = true;
          offsetX = e.clientX - modalEl.getBoundingClientRect().left;
          offsetY = e.clientY - modalEl.getBoundingClientRect().top;
          modalEl.style.cursor = "grabbing";
        });
        document.addEventListener("mousemove", (e) => {
          if (isDragging) {
            modalEl.style.left = `${e.clientX - offsetX}px`;
            modalEl.style.top = `${e.clientY - offsetY}px`;
          }
          if (isCrosshairDragging) {
            updatePosition(e);
          }
        });
        document.addEventListener("mouseup", () => {
          isDragging = false;
          isCrosshairDragging = false;
          modalEl.style.cursor = "default";
          targetArea.style.cursor = "crosshair";
        });
        targetArea.addEventListener("mousedown", (e) => {
          isCrosshairDragging = true;
          targetArea.style.cursor = "move";
          updatePosition(e);
          e.preventDefault();
        });
        verticalLine.addEventListener("mousedown", (e) => {
          isCrosshairDragging = true;
          targetArea.style.cursor = "move";
          e.preventDefault();
        });
        horizontalLine.addEventListener("mousedown", (e) => {
          isCrosshairDragging = true;
          targetArea.style.cursor = "move";
          e.preventDefault();
        });
        modalEl.style.position = "absolute";
        modalEl.style.left = `${modalEl.getBoundingClientRect().left}px`;
        modalEl.style.top = `${modalEl.getBoundingClientRect().top}px`;
      }
      addStyle() {
        const style = document.createElement("style");
        style.textContent = `
            /* --------------------------- */
            /* -- Target Position Modal -- */
            /* --------------------------- */
            .target-position-modal {
                display: flex;
                flex-direction: column;
                justify-content: space-between;
            }

            .target-position-modal .target-container {
                display: flex;
                flex-direction: column;
                gap: 10px;
                min-width: 200px;
            }

            .target-position-modal .target-area {
                box-shadow: 0 2px 5px rgba(0,0,0,0.1);
                border-radius: 4px;
            }

            .target-position-modal .position-indicator {
                padding: 4px;
                border-radius: 4px;
                background-color: var(--background-secondary);
            }

            .target-position-modal .crosshair-line {
                position: absolute;
                background-color: var(--text-accent);
                pointer-events: none;
            }

            .target-position-modal .vertical {
                width: 1px;
                height: 100%;
            }

            .target-position-modal .horizontal {
                width: 100%;
                height: 1px;
            }

            .target-position-modal .control-panel {
                background-color: var(--background-secondary);
                padding: 15px;
                border-radius: 8px;
            }

            .target-position-modal .display-mode-select {
                width: 100%;
                min-width: max-content;
                padding: 6px;
                border-radius: 4px;
                border: 1px solid var(--background-modifier-border);
                background-color: var(--background-primary);
                color: var(--text-normal);
            }

            .target-position-modal .zoom-container {
                position: relative;
            }

            .target-position-modal .zoom-slider {
                width: 15px;
                background-color: var(--background-primary);
                border-radius: 5px;
                cursor: pointer;
                margin: 10px auto;
                appearance: none;
            }

            .target-position-modal .zoom-slider::-webkit-slider-runnable-track {
                width: 100%;
                height: 200px;
                background: var(--background-modifier-border);
                border-radius: 5px;
                border: none;
            }

            .target-position-modal .zoom-slider::-moz-range-track {
                width: 100%;
                height: 200px;
                background: var(--background-modifier-border);
                border-radius: 5px;
                border: none;
            }

            .target-position-modal .zoom-slider::-webkit-slider-thumb {
                -webkit-appearance: none;
                width: 20px;
                height: 20px;
                border-radius: 50%;
                background: var(--text-accent);
                cursor: pointer;
                border: none;
                margin-top: 90px;
                position: relative;
                left: -2px;
            }

            .target-position-modal .zoom-slider::-moz-range-thumb {
                width: 20px;
                height: 20px;
                border-radius: 50%;
                background: var(--text-accent);
                cursor: pointer;
                border: none;
            }

            .target-position-modal .zoom-value {
                color: var(--text-muted);
                text-align: center;
            }

            .target-position-modal .height-slider,
            .target-position-modal .content-start-position-slider {
                width: 15px;
                background-color: var(--background-primary);
                border-radius: 5px;
                cursor: pointer;
                margin: 10px auto;
                appearance: none;
            }

            .target-position-modal .height-slider::-webkit-slider-runnable-track,
            .target-position-modal .content-start-position-slider::-webkit-slider-runnable-track {
                width: 100%;
                height: 200px;
                background: var(--background-modifier-border);
                border-radius: 5px;
                border: none;
            }

            .target-position-modal .height-slider::-moz-range-track,
            .target-position-modal .content-start-position-slider::-moz-range-track {
                width: 100%;
                height: 200px;
                background: var(--background-modifier-border);
                border-radius: 5px;
                border: none;
            }

            .target-position-modal .max-width-slider::-webkit-slider-runnable-track,
            .target-position-modal .height-slider::-webkit-slider-runnable-track,
            .target-position-modal .content-start-position-slider::-webkit-slider-runnable-track {
                width: 100%;
                height: 200px;
                background: var(--background-modifier-border);
                border-radius: 5px;
                border: none;
            }

            .target-position-modal .max-width-slider::-moz-range-track,
            .target-position-modal .height-slider::-moz-range-track,
            .target-position-modal .content-start-position-slider::-moz-range-track {
                width: 100%;
                height: 200px;
                background: var(--background-modifier-border);
                border-radius: 5px;
                border: none;
            }

            .target-position-modal .max-width-slider::-webkit-slider-thumb,
            .target-position-modal .height-slider::-webkit-slider-thumb,
            .target-position-modal .content-start-position-slider::-webkit-slider-thumb {
                -webkit-appearance: none;
                width: 20px;
                height: 20px;
                border-radius: 50%;
                background: var(--text-accent);
                cursor: pointer;
                border: none;
                margin-top: 90px;
                position: relative;
                left: -2px;
            }

            .target-position-modal .max-width-slider:disabled {
                opacity: 0;
                cursor: not-allowed;
            }

            .target-position-modal .max-width-slider::-moz-range-thumb,
            .target-position-modal .height-slider::-moz-range-thumb,
            .target-position-modal .content-start-position-slider::-moz-range-thumb {
                width: 20px;
                height: 20px;
                border-radius: 50%;
                background: var(--text-accent);
                cursor: pointer;
                border: none;
            }

            .target-position-modal .height-value,
            .target-position-modal .content-start-position-value {
                color: var(--text-muted);
                text-align: center;
            }

            .target-position-modal .max-width-container,
            .target-position-modal .height-container,
            .target-position-modal .content-start-position-container {
                display: flex;
                flex-direction: column;
                gap: 5px;
                align-items: center;
                background-color: var(--background-secondary);
                padding: 15px;
                border-radius: 4px;
            }

            .target-position-modal .height-label,
            .target-position-modal .content-start-position-label {
                color: var(--text-muted);
                font-size: 0.9em;
            }

            .target-position-modal .height-value,
            .target-position-modal .content-start-position-value {
                font-family: var(--font-monospace);
                font-size: 0.9em;
                color: var(--text-muted);
            }

            .target-position-modal .reset-button {
                padding: 8px;
                width: 100%;
                font-size: 14px;
                border-radius: 4px;
                cursor: pointer;
                transition: background-color 0.2s ease;
            }

            .target-position-modal .reset-button:hover {
                background-color: var(--interactive-accent-hover);
            }

            .target-position-modal .target-area {
                box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            }
            .target-position-modal .vertical {
                position: absolute;
                background-color: var(--text-accent);
                pointer-events: none;
                width: 1px;
                height: 100%;
                left: ${this.currentX}%;
                pointer-events: auto;
                cursor: move;
            }
            .target-position-modal .horizontal {
                position: absolute;
                background-color: var(--text-accent);
                pointer-events: none;
                width: 100%;
                height: 1px;
                top: ${this.currentY}%;
                pointer-events: auto;
                cursor: move;
            }
            .target-position-modal .position-indicator {
                text-align: center;
                margin-top: 10px;
                font-family: var(--font-monospace);
            }
            .target-position-modal .repeat-container {
                min-height: 120px;
                display: flex;
                justify-content: center;
            }
            
            .target-position-modal .repeat-checkbox {
                transform: scale(1.2);
                cursor: pointer;
            }

            /* ------------------- */
            /* -- mobile layout -- */
            /* ------------------- */
            @media screen and (max-width: 550px) {
                .banner-image-header { flex-direction: column !important; }
                .banner-icon-header { flex-direction: column !important; }
                .main-container--banner-image { flex-direction: column !important; }
                .main-container--banner-icon { flex-direction: column !important; }
                .target-container { order: -1 !important; align-items: center !important; }
                .height-slider,
                .content-start-position-slider {
                    rotate: 90deg !important;
                    flex: 0 auto !important;
                    writing-mode: unset !important;
                    direction: unset !important;
                }
                .color-picker-and-alpha-slider-row { flex-wrap: wrap !important; }
            }
        `;
        document.head.appendChild(style);
      }
      onClose() {
        const style = document.head.querySelector("style:last-child");
        if (style) {
          style.remove();
        }
      }
    };
  }
});

// src/modal/modals/iconImageSelectionModal.js
var import_obsidian18, IconImageSelectionModal;
var init_iconImageSelectionModal = __esm({
  "src/modal/modals/iconImageSelectionModal.js"() {
    import_obsidian18 = require("obsidian");
    init_iconFolderSelectionModal();
    init_saveImageModal();
    init_modals();
    init_constants();
    IconImageSelectionModal = class extends import_obsidian18.Modal {
      constructor(app, plugin, onChoose, defaultPath = "") {
        super(app);
        this.plugin = plugin;
        this.onChoose = onChoose;
        this.defaultPath = defaultPath || "";
        this.searchQuery = defaultPath && typeof defaultPath === "string" ? defaultPath.toLowerCase() : "";
        this.currentPage = 1;
        this.imagesPerPage = 20;
        this.sortOrder = "name-asc";
        this.imageFiles = this.app.vault.getFiles().filter((file) => file && file.extension && file.extension.toLowerCase && file.extension.toLowerCase().match(/^(jpg|jpeg|png|gif|bmp|svg|webp|avif)$/));
        this.iconCategories = [];
        this.selectedIconCategory = null;
        this.selectedIconCategoryIndex = 0;
        this.iconsCurrentPage = 1;
        this.iconsTotalPages = 1;
        this.iconsSearchTerm = "";
        this.isIconsSearchMode = false;
        this.iconsPerPage = 10;
        this._isPaginating = false;
        this.targetingModalOpened = false;
        const originalOnChoose = this.onChoose;
        this.onChoose = (file) => {
          this.targetingModalOpened = true;
          originalOnChoose(file);
        };
      }
      debounce(func, wait) {
        let timeout;
        return (...args) => {
          clearTimeout(timeout);
          timeout = setTimeout(() => func.apply(this, args), wait);
        };
      }
      async confirmDelete(file) {
        return new Promise((resolve) => {
          const modal = new import_obsidian18.Modal(this.app);
          modal.contentEl.createEl("h2", { text: "Delete Image" });
          modal.contentEl.createEl("p", { text: `Are you sure you want to delete "${file.name}"?` });
          const buttonContainer = modal.contentEl.createDiv();
          buttonContainer.style.display = "flex";
          buttonContainer.style.justifyContent = "flex-end";
          buttonContainer.style.gap = "10px";
          const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
          const deleteButton = buttonContainer.createEl("button", {
            text: "Delete",
            cls: "mod-warning"
          });
          cancelButton.onclick = () => {
            modal.close();
            resolve(false);
          };
          deleteButton.onclick = () => {
            modal.close();
            resolve(true);
          };
          modal.open();
        });
      }
      async deleteImage(file) {
        const confirmed = await this.confirmDelete(file);
        if (!confirmed) return;
        try {
          await this.app.vault.delete(file);
          this.imageFiles = this.imageFiles.filter((f) => f.path !== file.path);
          this.updateImageGrid();
        } catch (error) {
          new import_obsidian18.Notice(`Failed to delete image: ${error.message}`);
        }
      }
      onOpen() {
        this.modalEl.addClass("pixel-banner-image-select-modal");
        const { contentEl } = this;
        contentEl.empty();
        const style = document.createElement("style");
        style.textContent = `
            .pixel-banner-image-modal {
                width: var(--dialog-max-width);
                top: unset !important;
            }

            .pixel-banner-image-select-modal {
                top: unset !important;
                width: var(--dialog-max-width);
                max-width: 1100px;
                min-height: 50vh;
                max-height: 95vh;
            }

            .pixel-banner-image-select-modal .pixel-banner-image-delete {
                position: absolute;
                top: 8px;
                right: 8px;
                width: 24px;
                height: 24px;
                background-color: var(--background-secondary);
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                opacity: .5;
                transition: opacity 0.2s ease, background-color 0.2s ease;
                cursor: pointer;
                z-index: 2;
            }

            .pixel-banner-image-select-modal .pixel-banner-image-wrapper:hover .pixel-banner-image-delete {
                opacity: 1;
            }

            .pixel-banner-image-select-modal .pixel-banner-image-delete:hover {
                background-color: red;
                color: white;
                opacity: 1;
            }

            .pixel-banner-image-select-modal .pixel-banner-image-delete svg {
                width: 16px;
                height: 16px;
            }

            .pixel-banner-image-select-description {
                margin-top: -15px;
                font-size: 0.8em;
                word-break: break-all;
                color: var(--text-muted);
                margin-bottom: 15px;
            }

            .pixel-banner-search-container {
                margin-bottom: 1rem;
            }
            
            .pixel-banner-search-container input {
                width: 100%;
                padding: 8px;
                border-radius: 4px;
                border: 1px solid var(--background-modifier-border);
            }

            .pixel-banner-search-container .search-row {
                flex: 1;
                display: flex;
                gap: 8px;
                margin: 0;
            }

            .pixel-banner-search-container .controls-row {
                flex: 0 auto;
                display: flex;
                gap: 8px;
                margin: 0;
            }

            .pixel-banner-image-path {
                margin-top: 8px;
                font-size: 0.8em;
                word-break: break-all;
                color: var(--text-muted);
            }

            .pixel-banner-image-error {
                height: 150px;
                display: flex;
                align-items: center;
                justify-content: center;
                background-color: var(--background-modifier-error);
                color: var(--text-error);
                border-radius: 2px;
            }

            .pixel-banner-image-grid {
                display: grid;
                grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
                gap: 1rem;
                padding: 0 1rem;
                overflow-y: auto;
                max-height: 60vh;
            }

            .pixel-banner-pagination-button {
                padding: 4px 8px;
                border-radius: 4px;
                background: var(--background-secondary);
                border: 1px solid var(--background-modifier-border);
                cursor: pointer;
                font-size: 14px;
                line-height: 1;
            }

            button.pixel-banner-pagination-button:not([disabled]),
            .pixel-banner-pagination-button:hover:not(.disabled) {
                background-color: var(--interactive-accent);
                color: var(--text-on-accent);
            }
            
            .pixel-banner-pagination-button.disabled {
                opacity: 0.5;
                cursor: not-allowed;
            }
            
            .pixel-banner-pagination-info {
                font-size: 14px;
                color: var(--text-muted);
            }
            
            .pixel-banner-image-container {
                cursor: pointer;
                border-radius: 6px;
                border: 1px solid var(--background-modifier-border);
                transition: transform 0.2s ease, box-shadow 0.2s ease;
                position: relative;
            }
            
            .pixel-banner-image-container:hover {
                transform: translateY(-2px);
                box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            }
            
            .pixel-banner-image-grid {
                display: grid;
                grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
                gap: 15px;
                margin-top: 15px;
                max-height: 60vh;
                overflow-y: auto;
                padding: 5px;
            }
            
            .pixel-banner-no-images {
                width: 100%;
                height: 200px;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 1.2em;
                color: var(--text-muted);
                border: 1px dashed var(--background-modifier-border);
                border-radius: 8px;
                background-color: var(--background-secondary);
                grid-column: 1 / -1;
                text-align: center;
                padding: 20px;
            }
            
            .pixel-banner-image-thumbnail {
                width: 100%;
                max-width: fit-content;
                height: auto;
                max-height: 150px;
                object-fit: cover;
                display: block;
            }
            
            .pixel-banner-image-info {
                padding: 8px;
                font-size: 12px;
                background: var(--background-secondary);
            }
            
            .pixel-banner-image-path {
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
                margin-bottom: 4px;
            }
            
            .pixel-banner-image-delete {
                position: absolute;
                top: 5px;
                right: 5px;
                background: rgba(0, 0, 0, 0.5);
                border-radius: 50%;
                width: 24px;
                height: 24px;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                opacity: 0;
                transition: opacity 0.2s ease;
            }
            
            .pixel-banner-image-container:hover .pixel-banner-image-delete {
                opacity: 1;
            }
            
            .pixel-banner-image-delete svg {
                width: 16px;
                height: 16px;
                color: white;
            }

            /* ------------------- */
            /* -- mobile layout -- */
            /* ------------------- */
            @media screen and (max-width: 550px) {
                .pixel-banner-pagination { flex-direction: column !important; }
                .pixel-banner-pagination .pixel-banner-controls { flex-direction: column !important; }
            }

            @media screen and (max-width: 775px) {
                .pixel-banner-search-container {
                    flex-direction: column !important;
                    gap: 8px !important;
                }

                .pixel-banner-search-container .search-row {
                    display: flex;
                    width: 100%;
                    gap: 8px;
                }

                .pixel-banner-search-container .controls-row {
                    display: flex;
                    width: 100%;
                    gap: 8px;
                    align-items: center;
                }

                .pixel-banner-search-container input[type="text"] {
                    flex: 1;
                }
            }
        `;
        document.head.appendChild(style);
        this.style = style;
        contentEl.createEl("h2", { text: "\u2B50 Select Banner Icon Image", cls: "margin-top-0" });
        const titleDescriptionRow = contentEl.createEl("div", {
          text: "Select an image to use as a banner icon.",
          cls: "pixel-banner-image-select-description",
          attr: {
            style: `
                    display: flex;
                    align-items: center;
                    justify-content: space-between;
                `
          }
        });
        const removeIconImageButton = titleDescriptionRow.createEl("button", {
          text: "\u{1F5D1}\uFE0F Remove",
          cls: "remove-icon-image-button cursor-pointer"
        });
        removeIconImageButton.addEventListener("click", async () => {
          const activeFile = this.app.workspace.getActiveFile();
          if (activeFile) {
            await this.app.fileManager.processFrontMatter(activeFile, (frontmatter) => {
              const bannerIconField = Array.isArray(this.plugin.settings.customBannerIconField) ? this.plugin.settings.customBannerIconField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconField;
              const bannerIconImageAlignmentField = Array.isArray(this.plugin.settings.customBannerIconImageAlignmentField) ? this.plugin.settings.customBannerIconImageAlignmentField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageAlignmentField;
              const iconSizeField = Array.isArray(this.plugin.settings.customBannerIconSizeField) ? this.plugin.settings.customBannerIconSizeField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconSizeField;
              const iconImageSizeMultiplierField = Array.isArray(this.plugin.settings.customBannerIconImageSizeMultiplierField) ? this.plugin.settings.customBannerIconImageSizeMultiplierField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageSizeMultiplierField;
              const iconRotateField = Array.isArray(this.plugin.settings.customBannerIconRotateField) ? this.plugin.settings.customBannerIconRotateField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconRotateField;
              const iconYPositionField = Array.isArray(this.plugin.settings.customBannerIconVerticalOffsetField) ? this.plugin.settings.customBannerIconVerticalOffsetField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconVerticalOffsetField;
              const iconXPositionField = Array.isArray(this.plugin.settings.customBannerIconXPositionField) ? this.plugin.settings.customBannerIconXPositionField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconXPositionField;
              const iconColorField = Array.isArray(this.plugin.settings.customBannerIconColorField) ? this.plugin.settings.customBannerIconColorField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconColorField;
              const iconBgColorField = Array.isArray(this.plugin.settings.customBannerIconBackgroundColorField) ? this.plugin.settings.customBannerIconBackgroundColorField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconBackgroundColorField;
              const iconXPaddingField = Array.isArray(this.plugin.settings.customBannerIconPaddingXField) ? this.plugin.settings.customBannerIconPaddingXField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconPaddingXField;
              const iconYPaddingField = Array.isArray(this.plugin.settings.customBannerIconPaddingYField) ? this.plugin.settings.customBannerIconPaddingYField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconPaddingYField;
              const iconBorderRadiusField = Array.isArray(this.plugin.settings.customBannerIconBorderRadiusField) ? this.plugin.settings.customBannerIconBorderRadiusField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconBorderRadiusField;
              const bannerIconImageField = Array.isArray(this.plugin.settings.customBannerIconImageField) ? this.plugin.settings.customBannerIconImageField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageField;
              const hasTextEmoji = frontmatter[bannerIconField] !== void 0 && frontmatter[bannerIconField] !== null && frontmatter[bannerIconField] !== "";
              if (!hasTextEmoji) {
                delete frontmatter[bannerIconField];
                delete frontmatter[bannerIconImageField];
                delete frontmatter[bannerIconImageAlignmentField];
                delete frontmatter[iconSizeField];
                delete frontmatter[iconImageSizeMultiplierField];
                delete frontmatter[iconRotateField];
                delete frontmatter[iconYPositionField];
                delete frontmatter[iconXPositionField];
                delete frontmatter[iconColorField];
                delete frontmatter[iconBgColorField];
                delete frontmatter[iconXPaddingField];
                delete frontmatter[iconYPaddingField];
                delete frontmatter[iconBorderRadiusField];
              } else {
                delete frontmatter[bannerIconImageField];
                delete frontmatter[iconImageSizeMultiplierField];
                delete frontmatter[bannerIconImageAlignmentField];
              }
            });
            this.onChoose(null);
            this.close();
            const activeView = this.app.workspace.getActiveViewOfType(import_obsidian18.MarkdownView);
            if (activeView) {
              const contentEl2 = activeView.contentEl;
              if (contentEl2) {
                const existingOverlays = contentEl2.querySelectorAll(".banner-icon-overlay");
                existingOverlays.forEach((overlay) => {
                  this.plugin.returnIconOverlay(overlay);
                });
              }
              await this.plugin.updateBanner(activeView, true, this.plugin.UPDATE_MODE.FULL_UPDATE);
            }
            if (!this.skipTargetingModal && this.plugin.settings.openTargetingModalAfterSelectingBannerOrIcon) {
              await new Promise((resolve) => {
                var _a;
                const initialFrontmatter = JSON.stringify(
                  ((_a = this.app.metadataCache.getFileCache(activeFile)) == null ? void 0 : _a.frontmatter) || {}
                );
                const eventRef = this.app.metadataCache.on("changed", (file) => {
                  var _a2;
                  if (file.path !== activeFile.path) return;
                  const updatedFrontmatter = JSON.stringify(
                    ((_a2 = this.app.metadataCache.getFileCache(file)) == null ? void 0 : _a2.frontmatter) || {}
                  );
                  if (updatedFrontmatter !== initialFrontmatter) {
                    this.app.metadataCache.off("changed", eventRef);
                    resolve();
                  }
                });
                setTimeout(() => {
                  this.app.metadataCache.off("changed", eventRef);
                  resolve();
                }, 500);
              });
              new TargetPositionModal(this.app, this.plugin).open();
            }
          }
        });
        const tabContainer = contentEl.createDiv({
          cls: "pixel-banner-tabs-container",
          attr: {
            style: `
                    display: flex;
                    margin-bottom: 16px;
                    border-bottom: 1px solid var(--background-modifier-border);
                `
          }
        });
        const localImageTab = tabContainer.createDiv({
          cls: "pixel-banner-tab active",
          text: "\u{1F4BE} Local Image",
          attr: {
            style: `
                    padding: 8px 16px;
                    cursor: pointer;
                    border-bottom: 2px solid transparent;
                    margin-right: 8px;
                    transition: all 0.2s ease;
                `
          }
        });
        const webTab = tabContainer.createDiv({
          cls: "pixel-banner-tab",
          text: "\u{1F310} WEB",
          attr: {
            style: `
                    padding: 8px 16px;
                    cursor: pointer;
                    border-bottom: 2px solid transparent;
                    margin-right: 8px;
                    transition: all 0.2s ease;
                `
          }
        });
        this.collectionsTab = tabContainer.createDiv({
          cls: "pixel-banner-tab",
          text: "\u{1F4D1} Collections",
          attr: {
            style: `
                    padding: 8px 16px;
                    cursor: pointer;
                    border-bottom: 2px solid transparent;
                    transition: all 0.2s ease;
                    display: none; /* Initially hidden */
                `
          }
        });
        const localImageContent = contentEl.createDiv({
          cls: "pixel-banner-tab-content local-image-content",
          attr: {
            style: `
                    display: block;
                `
          }
        });
        const webContent = contentEl.createDiv({
          cls: "pixel-banner-tab-content web-content",
          attr: {
            style: `
                    display: none;
                `
          }
        });
        this.collectionsContent = contentEl.createDiv({
          cls: "pixel-banner-tab-content collections-content",
          attr: {
            style: `
                    display: none;
                `
          }
        });
        const tabStyles = document.createElement("style");
        tabStyles.textContent = `
            .pixel-banner-tab.active {
                border-bottom: 2px solid var(--interactive-accent) !important;
                font-weight: bold;
            }
        `;
        document.head.appendChild(tabStyles);
        this.tabStyles = tabStyles;
        const switchTab = (targetTab) => {
          localImageTab.classList.remove("active");
          webTab.classList.remove("active");
          if (this.collectionsTab) {
            this.collectionsTab.classList.remove("active");
          }
          targetTab.classList.add("active");
          if (targetTab === localImageTab) {
            localImageContent.style.display = "block";
            webContent.style.display = "none";
            this.collectionsContent.style.display = "none";
          } else if (targetTab === webTab) {
            localImageContent.style.display = "none";
            webContent.style.display = "block";
            this.collectionsContent.style.display = "none";
          } else {
            localImageContent.style.display = "none";
            webContent.style.display = "none";
            this.collectionsContent.style.display = "block";
          }
        };
        localImageTab.addEventListener("click", () => switchTab(localImageTab));
        webTab.addEventListener("click", () => switchTab(webTab));
        this.collectionsTab.addEventListener("click", () => switchTab(this.collectionsTab));
        this.checkServerStatus();
        const searchContainer = localImageContent.createDiv({ cls: "pixel-banner-search-container" });
        searchContainer.style.display = "flex";
        searchContainer.style.gap = "8px";
        searchContainer.style.alignItems = "center";
        searchContainer.style.marginBottom = "1em";
        this.initializeCollectionsTab(this.collectionsContent);
        const searchRow = searchContainer.createDiv({ cls: "search-row" });
        const searchInput = searchRow.createEl("input", {
          type: "text",
          placeholder: "Search images...",
          value: this.defaultPath
        });
        searchInput.style.flex = "1";
        const clearButton = searchRow.createEl("button", {
          text: "Clear"
        });
        const controlsRow = searchContainer.createDiv({
          cls: "controls-row",
          attr: {
            style: `
                    display: flex !important;
                    gap: 8px;
                    align-items: center;
                `
          }
        });
        const uploadButton = controlsRow.createEl("button", {
          text: "\u{1F4E4} Upload"
        });
        uploadButton.addEventListener("click", () => {
          fileInput.click();
        });
        const shorPathToggleContainer = controlsRow.createDiv({
          cls: "pixel-banner-path-toggle",
          attr: {
            style: `
                    display: flex !important;
                    align-items: center;
                    gap: 8px;
                    cursor: pointer;
                `
          }
        });
        const shorPathToggleLabel = shorPathToggleContainer.createSpan({
          text: "Use short path",
          attr: {
            style: `
                    font-size: 12px;
                    color: var(--text-muted);
                `
          }
        });
        const shorPathToggle = new import_obsidian18.Setting(shorPathToggleContainer).addToggle((cb) => {
          cb.setValue(this.plugin.settings.useShortPath).onChange(async (value) => {
            this.plugin.settings.useShortPath = value;
            await this.plugin.saveSettings();
          });
        });
        shorPathToggle.settingEl.style.border = "none";
        shorPathToggle.settingEl.style.padding = "0";
        shorPathToggle.settingEl.style.margin = "0";
        shorPathToggle.infoEl.remove();
        const fileInput = searchContainer.createEl("input", {
          type: "file",
          attr: {
            accept: "image/*",
            style: "display: none;"
          }
        });
        fileInput.addEventListener("change", async (event) => {
          const file = event.target.files[0];
          if (file) {
            const reader = new FileReader();
            reader.onload = async () => {
              const arrayBuffer = reader.result;
              const defaultFolder = this.plugin.settings.defaultSelectIconPath || "";
              const folderPath = await new Promise((resolve) => {
                new IconFolderSelectionModal(this.app, defaultFolder, (result) => {
                  resolve(result);
                }).open();
              });
              if (!folderPath) {
                new import_obsidian18.Notice("No folder selected");
                return;
              }
              if (!await this.app.vault.adapter.exists(folderPath)) {
                await this.app.vault.createFolder(folderPath);
              }
              const suggestedName = file.name;
              const fileName = await new Promise((resolve) => {
                new SaveImageModal(this.app, suggestedName, (result) => {
                  resolve(result);
                }).open();
              });
              if (!fileName) {
                new import_obsidian18.Notice("No file name provided");
                return;
              }
              try {
                const fullPath = `${folderPath}/${fileName}`.replace(/\/+/g, "/");
                const newFile = await this.app.vault.createBinary(fullPath, arrayBuffer);
                this.onChoose(newFile);
                this.close();
              } catch (error) {
                new import_obsidian18.Notice(`Failed to save image: ${error.message}`);
              }
            };
            reader.readAsArrayBuffer(file);
          }
        });
        clearButton.addEventListener("click", () => {
          searchInput.value = "";
          this.searchQuery = "";
          this.updateImageGrid();
        });
        searchInput.addEventListener("input", this.debounce(() => {
          this.searchQuery = searchInput && searchInput.value && typeof searchInput.value === "string" ? searchInput.value.toLowerCase() : "";
          this.updateImageGrid();
        }, 500));
        const webUrlInputContainer = webContent.createDiv({
          cls: "web-url-input-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: row;
                    align-items: center;
                    gap: 10px;
                    margin-bottom: 16px;
                `
          }
        });
        const urlInput = webUrlInputContainer.createEl("input", {
          type: "text",
          placeholder: "Enter image URL...",
          cls: "web-url-input",
          attr: {
            style: `
                    flex: 1;
                    padding: 8px;
                    border-radius: 4px;
                    border: 1px solid var(--background-modifier-border);
                `
          }
        });
        const useUrlButton = webUrlInputContainer.createEl("button", {
          text: "Use URL",
          cls: "use-url-button",
          attr: {
            style: `
                    background-color: var(--interactive-accent);
                    color: var(--text-on-accent);
                `
          }
        });
        useUrlButton.addEventListener("click", () => {
          const url = urlInput.value.trim();
          if (validateUrl(url)) {
            this.onChoose({
              path: url,
              name: url.split("/").pop() || "image",
              extension: url.split(".").pop() || "jpg",
              isWebUrl: true
            });
            this.close();
          } else {
            new import_obsidian18.Notice("Please enter a valid image URL");
          }
        });
        const validateUrl = (url) => {
          try {
            new URL(url);
            const imageExtensions = ["jpg", "jpeg", "png", "gif", "svg", "webp", "avif", "bmp"];
            const extension = url && url.split && url.split(".").pop() ? url.split(".").pop().toLowerCase() : "";
            return imageExtensions.includes(extension);
          } catch (e) {
            return false;
          }
        };
        webContent.createEl("div", {
          text: "Enter a direct URL to an image file (jpg, png, gif, etc.).",
          attr: {
            style: `
                    font-size: 12px;
                    color: var(--text-muted);
                    margin-bottom: 16px;
                `
          }
        });
        const previewContainer = webContent.createDiv({
          cls: "web-image-preview-container",
          attr: {
            style: `
                    display: none;
                    flex-direction: column;
                    align-items: center;
                    justify-content: center;
                    margin-top: 16px;
                    padding: 16px;
                    border: 1px dashed var(--background-modifier-border);
                    border-radius: 4px;
                `
          }
        });
        const previewImage = previewContainer.createEl("img", {
          cls: "web-image-preview",
          attr: {
            style: `
                    max-width: 100%;
                    max-height: 200px;
                    object-fit: contain;
                `
          }
        });
        const previewCaption = previewContainer.createEl("div", {
          cls: "web-image-preview-caption",
          attr: {
            style: `
                    margin-top: 8px;
                    font-size: 12px;
                    color: var(--text-muted);
                `
          }
        });
        urlInput.addEventListener("input", this.debounce(() => {
          const url = urlInput.value.trim();
          if (validateUrl(url)) {
            previewImage.src = url;
            previewCaption.textContent = url.split("/").pop();
            previewContainer.style.display = "flex";
            previewImage.onerror = () => {
              previewContainer.style.display = "none";
              new import_obsidian18.Notice("Failed to load image preview");
            };
          } else {
            previewContainer.style.display = "none";
          }
        }, 500));
        this.gridContainer = localImageContent.createDiv({ cls: "pixel-banner-image-grid" });
        this.paginationContainer = localImageContent.createDiv({
          cls: "pixel-banner-pagination",
          attr: {
            style: `
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    gap: 10px;
                    flex-wrap: wrap;
                    margin-top: 15px;
                `
          }
        });
        this.updateImageGrid();
        const modalEl = this.modalEl;
        modalEl.style.position = "absolute";
        modalEl.style.left = `${modalEl.getBoundingClientRect().left}px`;
        modalEl.style.top = `${modalEl.getBoundingClientRect().top}px`;
      }
      async checkServerStatus() {
        try {
          const pingUrl = `${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.PING}`;
          const response = await fetch(pingUrl);
          const data = await response.json();
          if (response.ok && data.response === "pong") {
            this.collectionsTab.style.display = "block";
          } else {
            console.log("Server response did not match expected format", data);
          }
        } catch (error) {
          console.error(`Failed to connect to server: ${error.message}`);
        }
      }
      async fetchIconCategories() {
        try {
          const url = `${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.BANNER_ICON_CATEGORIES}?key=${PIXEL_BANNER_PLUS.BANNER_ICON_KEY}`;
          const headers = {
            "Accept": "application/json"
          };
          const response = await fetch(url, {
            headers
          });
          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }
          const data = await response.json();
          if (!data.success) {
            throw new Error(data.error || "Failed to fetch icon categories");
          }
          this.iconCategories = data.categories || [];
          if (this.iconCategories.length === 0) {
            throw new Error("No icon categories found");
          }
          return this.iconCategories;
        } catch (error) {
          console.error("Error fetching icon categories:", error);
          throw error;
        }
      }
      async fetchIconsByCategory() {
        this.showCollectionsLoading();
        try {
          let url = `${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.BANNER_ICONS}?page=${this.iconsCurrentPage}&limit=${this.iconsPerPage}&key=${PIXEL_BANNER_PLUS.BANNER_ICON_KEY}`;
          if (this.selectedIconCategory && this.selectedIconCategory !== "all") {
            url += `&category_id=${this.selectedIconCategory}`;
          }
          const headers = {
            "Accept": "application/json"
          };
          const response = await fetch(url, {
            headers
          });
          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }
          const data = await response.json();
          if (!data.success) {
            throw new Error(data.error || "Failed to fetch icons");
          }
          this.iconsCurrentPage = data.currentPage || this.iconsCurrentPage;
          this.renderIcons(data.bannerIcons, data.totalPages, data.totalCount);
        } catch (error) {
          console.error("Error fetching icons by category:", error);
          this.showCollectionsError(error.message);
        } finally {
          this.hideCollectionsLoading();
        }
      }
      initializeCollectionsTab(contentEl) {
        const loadingContainer = contentEl.createDiv({
          cls: "pixel-banner-loading-container",
          attr: {
            style: `
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    height: 200px;
                `
          }
        });
        const loadingSpinner = loadingContainer.createDiv({
          cls: "pixel-banner-loading-spinner",
          attr: {
            style: `
                    width: 40px;
                    height: 40px;
                    border: 4px solid var(--background-modifier-border);
                    border-top: 4px solid var(--text-accent);
                    border-radius: 50%;
                    animation: pixel-banner-spin 1s linear infinite;
                `
          }
        });
        const spinnerStyle = document.createElement("style");
        spinnerStyle.textContent = `
            @keyframes pixel-banner-spin {
                0% { transform: rotate(0deg); }
                100% { transform: rotate(360deg); }
            }
        `;
        document.head.appendChild(spinnerStyle);
        this.spinnerStyle = spinnerStyle;
        this.fetchIconCategories().then(() => {
          loadingContainer.remove();
          const categoriesContainer = contentEl.createDiv({
            cls: "pixel-banner-categories-container",
            attr: {
              style: `
                        display: flex;
                        align-items: center;
                        gap: 8px;
                        margin-bottom: 16px;
                    `
            }
          });
          categoriesContainer.createSpan({
            text: "Icon Categories:",
            attr: {
              style: `
                        font-size: 12px;
                        color: var(--text-muted);
                    `
            }
          });
          this.categoriesDropdown = categoriesContainer.createEl("select", {
            cls: "pixel-banner-categories-dropdown",
            attr: {
              style: `
                        border-radius: 4px;
                        border: 1px solid var(--background-modifier-border);
                        flex-grow: 1;
                    `
            }
          });
          const allIconsOption = this.categoriesDropdown.createEl("option", {
            text: "\u2B50 ALL ICONS",
            value: "all"
          });
          allIconsOption.selected = true;
          this.iconCategories.forEach((category, index) => {
            this.categoriesDropdown.createEl("option", {
              text: category.category,
              value: category.id
            });
          });
          this.categoriesDropdown.addEventListener("change", async () => {
            this.selectedIconCategory = this.categoriesDropdown.value;
            this.selectedIconCategoryIndex = this.categoriesDropdown.selectedIndex;
            this.iconsCurrentPage = 1;
            this.iconSearchInput.value = "";
            this.isIconsSearchMode = false;
            await this.fetchIconsByCategory();
          });
          const nextCategoryButton = categoriesContainer.createEl("button", {
            text: "\u25B6\uFE0F Next Category",
            cls: "pixel-banner-next-category-button",
            attr: {
              style: `
                        padding: 8px 10px;
                        border-radius: 4px;
                        background-color: var(--interactive-accent);
                        color: var(--text-on-accent);
                        cursor: pointer;
                        transition: background-color 0.2s ease;
                    `
            }
          });
          nextCategoryButton.addEventListener("click", async () => {
            const optionsCount = this.categoriesDropdown.options.length;
            let nextIndex = this.selectedIconCategoryIndex + 1;
            if (nextIndex >= optionsCount) {
              nextIndex = 0;
            }
            this.categoriesDropdown.selectedIndex = nextIndex;
            this.selectedIconCategory = this.categoriesDropdown.value;
            this.selectedIconCategoryIndex = nextIndex;
            this.iconSearchInput.value = "";
            this.isIconsSearchMode = false;
            this.iconsCurrentPage = 1;
            await this.fetchIconsByCategory();
          });
          const searchContainer = contentEl.createDiv({
            cls: "pixel-banner-search-container",
            attr: {
              style: `
                        display: flex;
                        align-items: center;
                        gap: 8px;
                        margin-bottom: 16px;
                    `
            }
          });
          this.iconSearchInput = searchContainer.createEl("input", {
            type: "text",
            placeholder: "Search icons...",
            cls: "pixel-banner-search-input",
            attr: {
              style: `
                        padding: 8px;
                        border-radius: 4px;
                        border: 1px solid var(--background-modifier-border);
                        flex-grow: 1;
                    `
            }
          });
          const searchButton = searchContainer.createEl("button", {
            text: "Search",
            cls: "pixel-banner-search-button",
            attr: {
              style: `
                        padding: 8px 16px;
                        border-radius: 4px;
                        background-color: var(--interactive-accent);
                        color: var(--text-on-accent);
                    `
            }
          });
          searchButton.addEventListener("click", () => {
            this.searchIcons();
          });
          this.iconSearchInput.addEventListener("keydown", (e) => {
            if (e.key === "Enter") {
              this.searchIcons();
            }
          });
          const clearSearchButton = searchContainer.createEl("button", {
            text: "Clear",
            cls: "pixel-banner-clear-search-button"
          });
          clearSearchButton.addEventListener("click", () => {
            this.iconSearchInput.value = "";
            this.isIconsSearchMode = false;
            if (this.selectedIconCategory) {
              this.fetchIconsByCategory();
            }
          });
          this.collectionsGridContainer = contentEl.createDiv({
            cls: "pixel-banner-collections-grid",
            attr: {
              style: `
                        position: relative;
                        display: grid;
                        grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
                        gap: 12px;
                        margin-top: 12px;
                        max-height: 400px;
                        overflow-y: auto;
                        padding: 8px;
                        min-height: 200px;
                    `
            }
          });
          this.collectionsPaginationContainer = contentEl.createDiv({
            cls: "pixel-banner-collections-pagination",
            attr: {
              style: `
                        display: flex;
                        justify-content: space-between;
                        align-items: center;
                        margin-top: 12px;
                        padding-top: 8px;
                        border-top: 1px solid var(--background-modifier-border);
                    `
            }
          });
          this.selectedIconCategory = "all";
          this.selectedIconCategoryIndex = 0;
          this.fetchIconsByCategory();
        }).catch((err) => {
          loadingContainer.remove();
          contentEl.createEl("div", {
            cls: "pixel-banner-error",
            text: `\u{1F62D} Failed to load icon categories. Please try again later.`,
            attr: {
              style: `
                        color: var(--text-error);
                        padding: 16px;
                        border: 1px solid var(--background-modifier-error);
                        border-radius: 4px;
                        background-color: var(--background-modifier-error-rgb);
                        margin-bottom: 16px;
                    `
            }
          });
        });
      }
      async onChooseIcon(icon) {
        try {
          const url = `${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.BANNER_ICONS_ID.replace(":id", icon.id)}?key=${PIXEL_BANNER_PLUS.BANNER_ICON_KEY}`;
          const response = await fetch(url, {
            headers: {
              "x-user-email": this.plugin.settings.pixelBannerPlusEmail,
              "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
              "Accept": "application/json"
            }
          });
          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }
          const data = await response.json();
          if (!data.success) {
            throw new Error(data.error || "Failed to fetch icon details");
          }
          const iconData = data.bannerIcon;
          let extension = "png";
          if (iconData.base64Image) {
            const mimeTypeMatch = iconData.base64Image.match(/data:image\/([\w\+\-\.]+);base64/);
            if (mimeTypeMatch && mimeTypeMatch[1]) {
              extension = mimeTypeMatch[1];
              if (extension === "jpeg") extension = "jpg";
              if (extension === "svg+xml") extension = "svg";
            }
          } else if (iconData.file_name) {
            const parts = iconData.file_name.split(".");
            if (parts.length > 1) {
              extension = parts && parts.length > 0 && parts[parts.length - 1] ? parts[parts.length - 1].toLowerCase() : "";
            }
          }
          if (iconData.base64Image) {
            const defaultFolder = this.plugin.settings.defaultSelectIconPath || "";
            const folderPath = await new Promise((resolve) => {
              new IconFolderSelectionModal(this.app, defaultFolder, (result) => {
                resolve(result);
              }).open();
            });
            if (!folderPath) {
              new import_obsidian18.Notice("No folder selected");
              return;
            }
            if (!await this.app.vault.adapter.exists(folderPath)) {
              await this.app.vault.createFolder(folderPath);
            }
            const suggestedName = `${iconData.description || "icon"}`;
            const userFileName = await new Promise((resolve) => {
              new SaveImageModal(this.app, suggestedName, (result) => {
                resolve(result);
              }).open();
            });
            if (!userFileName) {
              new import_obsidian18.Notice("No file name provided");
              return;
            }
            let baseName = userFileName;
            if (baseName.includes(".")) {
              baseName = baseName.substring(0, baseName.lastIndexOf("."));
            }
            const finalFileName = `${baseName}.${extension}`;
            const base64Parts = iconData.base64Image.split(",");
            const base64Data = base64Parts[1];
            const binaryString = window.atob(base64Data);
            const bytes = new Uint8Array(binaryString.length);
            for (let i = 0; i < binaryString.length; i++) {
              bytes[i] = binaryString.charCodeAt(i);
            }
            try {
              const fullPath = `${folderPath}/${finalFileName}`.replace(/\/+/g, "/");
              const newFile = await this.app.vault.createBinary(fullPath, bytes.buffer);
              this.onChoose(newFile);
              this.close();
            } catch (error) {
              new import_obsidian18.Notice(`Failed to save image: ${error.message}`);
            }
          }
        } catch (error) {
          console.error("Error selecting icon:", error);
          new import_obsidian18.Notice(`Failed to select icon: ${error.message}`);
        }
      }
      showCollectionsLoading() {
        if (this.collectionsGridContainer) {
          const loadingContainer = this.collectionsGridContainer.createDiv({
            cls: "pixel-banner-loading-container",
            attr: {
              style: `
                        position: absolute;
                        top: 0;
                        right: 0;
                        bottom: 0;
                        left: 0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        background-color: var(--background-secondary);
                        opacity: 0.7;
                    `
            }
          });
          loadingContainer.createDiv({
            cls: "pixel-banner-loading-spinner",
            attr: {
              style: `
                        width: 40px;
                        height: 40px;
                        border: 4px solid var(--background-modifier-border);
                        border-top: 4px solid var(--text-accent);
                        border-radius: 50%;
                        animation: pixel-banner-spin 1s linear infinite;
                    `
            }
          });
        }
      }
      hideCollectionsLoading() {
      }
      showCollectionsError(message) {
        if (this.collectionsGridContainer) {
          this.collectionsGridContainer.empty();
          this.collectionsGridContainer.createEl("div", {
            cls: "pixel-banner-error",
            text: `Error: ${message}`,
            attr: {
              style: `
                        color: var(--text-error);
                        padding: 16px;
                        border: 1px solid var(--background-modifier-error);
                        border-radius: 4px;
                        background-color: var(--background-modifier-error-rgb);
                        margin-bottom: 16px;
                        grid-column: 1 / -1;
                    `
            }
          });
        }
      }
      renderIcons(icons, totalPages, totalCount) {
        this.collectionsGridContainer.empty();
        this.collectionsPaginationContainer.empty();
        this.iconsTotalPages = totalPages || 1;
        if (!icons || icons.length === 0) {
          this.collectionsGridContainer.createEl("div", {
            cls: "pixel-banner-no-icons",
            text: this.isIconsSearchMode ? "No icons found matching your search." : "No icons found in this category.",
            attr: {
              style: `
                        width: 100%;
                        padding: 32px;
                        text-align: center;
                        color: var(--text-muted);
                        background-color: var(--background-secondary);
                        border-radius: 4px;
                        grid-column: 1 / -1;
                    `
            }
          });
          return;
        }
        icons.forEach((icon) => {
          const iconContainer = this.collectionsGridContainer.createDiv({
            cls: "pixel-banner-icon-item",
            attr: {
              style: `
                        border: 1px solid var(--background-modifier-border);
                        border-radius: 4px;
                        overflow: hidden;
                        cursor: pointer;
                        transition: transform 0.2s ease, box-shadow 0.2s ease;
                    `
            }
          });
          iconContainer.addEventListener("mouseenter", () => {
            iconContainer.style.transform = "translateY(-2px)";
            iconContainer.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.1)";
          });
          iconContainer.addEventListener("mouseleave", () => {
            iconContainer.style.transform = "none";
            iconContainer.style.boxShadow = "none";
          });
          const imageContainer = iconContainer.createDiv({
            attr: {
              style: `
                        height: 120px;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        background-color: var(--background-secondary);
                        padding: 8px;
                    `
            }
          });
          const image = imageContainer.createEl("img", {
            attr: {
              src: icon.base64Image,
              alt: icon.description,
              style: `
                        max-width: 100%;
                        max-height: 100%;
                        object-fit: contain;
                    `
            }
          });
          const infoContainer = iconContainer.createDiv({
            attr: {
              style: `
                        padding: 8px;
                        background-color: var(--background-primary);
                    `
            }
          });
          infoContainer.createEl("div", {
            text: icon.description,
            attr: {
              style: `
                        font-size: 12px;
                        font-weight: 500;
                        margin-bottom: 4px;
                        white-space: nowrap;
                        overflow: hidden;
                        text-overflow: ellipsis;
                    `
            }
          });
          infoContainer.createEl("div", {
            text: icon.category,
            attr: {
              style: `
                        font-size: 10px;
                        color: var(--text-muted);
                    `
            }
          });
          iconContainer.addEventListener("click", () => {
            this.onChooseIcon(icon);
          });
        });
        if (totalPages > 1) {
          const paginationInfo = this.collectionsPaginationContainer.createEl("div", {
            text: `Page ${this.iconsCurrentPage} of ${totalPages} (${totalCount} icons)`,
            attr: {
              style: `
                        font-size: 12px;
                        color: var(--text-muted);
                    `
            }
          });
          const paginationControls = this.collectionsPaginationContainer.createDiv({
            attr: {
              style: `
                        display: flex;
                        gap: 4px;
                    `
            }
          });
          const firstPageButton = paginationControls.createEl("button", {
            text: "\xAB",
            cls: "pixel-banner-pagination-button"
          });
          if (this.iconsCurrentPage === 1) {
            firstPageButton.disabled = true;
          }
          firstPageButton.addEventListener("click", () => {
            if (this.iconsCurrentPage !== 1) {
              this.iconsCurrentPage = 1;
              this._isPaginating = true;
              this.isIconsSearchMode ? this.searchIcons() : this.fetchIconsByCategory();
            }
          });
          const prevPageButton = paginationControls.createEl("button", {
            text: "\u2039",
            cls: "pixel-banner-pagination-button"
          });
          if (this.iconsCurrentPage === 1) {
            prevPageButton.disabled = true;
          }
          prevPageButton.addEventListener("click", () => {
            if (this.iconsCurrentPage > 1) {
              this.iconsCurrentPage--;
              this._isPaginating = true;
              this.isIconsSearchMode ? this.searchIcons() : this.fetchIconsByCategory();
            }
          });
          const pageNumber = paginationControls.createEl("span", {
            text: this.iconsCurrentPage.toString(),
            attr: {
              style: `
                        padding: 4px 8px;
                    `
            }
          });
          const nextPageButton = paginationControls.createEl("button", {
            text: "\u203A",
            cls: "pixel-banner-pagination-button"
          });
          if (this.iconsCurrentPage === totalPages) {
            nextPageButton.disabled = true;
          }
          nextPageButton.addEventListener("click", () => {
            if (this.iconsCurrentPage < totalPages) {
              this.iconsCurrentPage++;
              this._isPaginating = true;
              this.isIconsSearchMode ? this.searchIcons() : this.fetchIconsByCategory();
            }
          });
          const lastPageButton = paginationControls.createEl("button", {
            text: "\u203A\u203A",
            cls: "pixel-banner-pagination-button"
          });
          if (this.iconsCurrentPage === totalPages) {
            lastPageButton.disabled = true;
          }
          lastPageButton.addEventListener("click", () => {
            if (this.iconsCurrentPage !== totalPages) {
              this.iconsCurrentPage = totalPages;
              this._isPaginating = true;
              this.isIconsSearchMode ? this.searchIcons() : this.fetchIconsByCategory();
            }
          });
        }
      }
      async searchIcons() {
        const searchTerm = this.iconSearchInput.value.trim();
        if (!searchTerm) return;
        this.isIconsSearchMode = true;
        if (!this._isPaginating) {
          this.iconsCurrentPage = 1;
        }
        this.showCollectionsLoading();
        try {
          const url = `${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.BANNER_ICONS_SEARCH}?key=${PIXEL_BANNER_PLUS.BANNER_ICON_KEY}`;
          const response = await fetch(url, {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              "Accept": "application/json"
            },
            body: JSON.stringify({
              searchTerm,
              page: this.iconsCurrentPage,
              limit: this.iconsPerPage
            })
          });
          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }
          const data = await response.json();
          if (!data.success) {
            throw new Error(data.error || "Failed to search icons");
          }
          this.iconsCurrentPage = data.currentPage || this.iconsCurrentPage;
          this.renderIcons(data.bannerIcons, data.totalPages, data.totalCount);
        } catch (error) {
          console.error("Error searching icons:", error);
          this.showCollectionsError(error.message);
        } finally {
          this.hideCollectionsLoading();
          this._isPaginating = false;
        }
      }
      updateImageGrid() {
        this.gridContainer.empty();
        this.paginationContainer.empty();
        let filteredFiles = this.imageFiles.filter((file) => {
          const filePath = file && file.path ? file.path.toLowerCase() : "";
          const fileName = file && file.name ? file.name.toLowerCase() : "";
          return filePath.includes(this.searchQuery) || fileName.includes(this.searchQuery);
        });
        filteredFiles = this.sortFiles(filteredFiles);
        const totalImages = filteredFiles.length;
        const totalPages = Math.ceil(totalImages / this.imagesPerPage);
        const startIndex = (this.currentPage - 1) * this.imagesPerPage;
        const endIndex = Math.min(startIndex + this.imagesPerPage, totalImages);
        const currentFiles = filteredFiles.slice(startIndex, endIndex);
        if (currentFiles.length === 0) {
          const noImagesMessage = this.gridContainer.createEl("div", {
            cls: "pixel-banner-no-images",
            text: filteredFiles.length === 0 ? "\u{1F50D} No images found matching your search." : "No images on this page.",
            attr: {
              style: `
                        width: 100%;
                        height: 200px;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        font-size: 1.2em;
                        color: var(--text-muted);
                        border: 1px dashed var(--background-modifier-border);
                        border-radius: 8px;
                        background-color: var(--background-secondary);
                        grid-column: 1 / -1;
                        text-align: center;
                        padding: 20px;
                    `
            }
          });
        }
        currentFiles.forEach((file) => {
          const imageContainer = this.gridContainer.createDiv({ cls: "pixel-banner-image-container" });
          const thumbnailContainer = imageContainer.createDiv({
            attr: {
              style: `
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        height: 150px;
                    `
            }
          });
          if (file && file.extension && file.extension.toLowerCase() === "svg") {
            this.app.vault.readBinary(file).then((arrayBuffer) => {
              const blob = new Blob([arrayBuffer], { type: "image/svg+xml" });
              const url = URL.createObjectURL(blob);
              const img = thumbnailContainer.createEl("img", {
                cls: "pixel-banner-image-thumbnail",
                attr: { src: url }
              });
              const cleanup = () => URL.revokeObjectURL(url);
              img.addEventListener("load", cleanup);
              img.addEventListener("error", cleanup);
            }).catch(() => {
              thumbnailContainer.createEl("div", {
                cls: "pixel-banner-image-error",
                text: "Error loading SVG"
              });
            });
          } else {
            this.app.vault.readBinary(file).then((arrayBuffer) => {
              const blob = new Blob([arrayBuffer]);
              const url = URL.createObjectURL(blob);
              const img = thumbnailContainer.createEl("img", {
                cls: "pixel-banner-image-thumbnail",
                attr: { src: url }
              });
              const cleanup = () => URL.revokeObjectURL(url);
              img.addEventListener("load", cleanup);
              img.addEventListener("error", cleanup);
            }).catch(() => {
              thumbnailContainer.createEl("div", {
                cls: "pixel-banner-image-error",
                text: "Error loading image"
              });
            });
          }
          const deleteButton = imageContainer.createDiv({ cls: "pixel-banner-image-delete" });
          deleteButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>';
          deleteButton.addEventListener("click", (e) => {
            e.stopPropagation();
            this.deleteImage(file);
          });
          const infoContainer = imageContainer.createDiv({ cls: "pixel-banner-image-info" });
          const displayPath = this.plugin.settings.useShortPath ? this.getShortPath(file.path) : file.path;
          infoContainer.createDiv({ text: displayPath, cls: "pixel-banner-image-path" });
          imageContainer.addEventListener("click", () => {
            if (!file || !file.path) {
              console.error("\u{1F527} ERROR: file or file.path is undefined during selection");
              return;
            }
            this.onChoose(file.path);
            this.close();
          });
        });
        if (totalPages > 1) {
          const paginationInfo = this.paginationContainer.createDiv({
            cls: "pixel-banner-pagination-info",
            text: `Showing ${startIndex + 1}-${endIndex} of ${totalImages} images | Page ${this.currentPage} of ${totalPages}`
          });
          const paginationControls = this.paginationContainer.createDiv({
            cls: "pixel-banner-controls",
            attr: {
              style: "display: flex; gap: 5px; align-items: center;"
            }
          });
          const firstPageButton = paginationControls.createEl("button", {
            cls: `pixel-banner-pagination-button ${this.currentPage === 1 ? "disabled" : ""}`,
            text: "\xAB\xAB"
          });
          firstPageButton.addEventListener("click", () => {
            if (this.currentPage !== 1) {
              this.currentPage = 1;
              this.updateImageGrid();
            }
          });
          const prevPageButton = paginationControls.createEl("button", {
            cls: `pixel-banner-pagination-button ${this.currentPage === 1 ? "disabled" : ""}`,
            text: "\u2039"
          });
          prevPageButton.addEventListener("click", () => {
            if (this.currentPage > 1) {
              this.currentPage--;
              this.updateImageGrid();
            }
          });
          const nextPageButton = paginationControls.createEl("button", {
            cls: `pixel-banner-pagination-button ${this.currentPage === totalPages ? "disabled" : ""}`,
            text: "\u203A"
          });
          nextPageButton.addEventListener("click", () => {
            if (this.currentPage < totalPages) {
              this.currentPage++;
              this.updateImageGrid();
            }
          });
          const lastPageButton = paginationControls.createEl("button", {
            cls: `pixel-banner-pagination-button ${this.currentPage === totalPages ? "disabled" : ""}`,
            text: "\u203A\u203A"
          });
          lastPageButton.addEventListener("click", () => {
            if (this.currentPage !== totalPages) {
              this.currentPage = totalPages;
              this.updateImageGrid();
            }
          });
        }
      }
      sortFiles(files) {
        return files.sort((a, b) => {
          if (this.sortOrder === "name-asc") {
            return a.name.localeCompare(b.name);
          } else if (this.sortOrder === "name-desc") {
            return b.name.localeCompare(a.name);
          } else if (this.sortOrder === "date-asc") {
            return a.stat.mtime - b.stat.mtime;
          } else if (this.sortOrder === "date-desc") {
            return b.stat.mtime - a.stat.mtime;
          }
          return 0;
        });
      }
      getShortPath(path) {
        const parts = path.split("/");
        const fileName = parts.pop();
        if (parts.length > 1) {
          return `${parts[0]}/.../${fileName}`;
        }
        return path;
      }
      onClose() {
        if (this.style) {
          this.style.remove();
        }
        if (this.tabStyles) {
          this.tabStyles.remove();
        }
        if (this.spinnerStyle) {
          this.spinnerStyle.remove();
        }
        if (this.plugin.settings.openTargetingModalAfterSelectingBannerOrIcon && !this.targetingModalOpened) {
          const activeFile = this.app.workspace.getActiveFile();
          if (activeFile) {
            const { TargetPositionModal: TargetPositionModal2 } = (init_targetPositionModal(), __toCommonJS(targetPositionModal_exports));
            new TargetPositionModal2(this.app, this.plugin).open();
          }
        }
        const { contentEl } = this;
        contentEl.empty();
      }
    };
  }
});

// node_modules/emojilib/dist/emoji-en-US.json
var emoji_en_US_default;
var init_emoji_en_US = __esm({
  "node_modules/emojilib/dist/emoji-en-US.json"() {
    emoji_en_US_default = {
      "\u{1F600}": [
        "grinning_face",
        "face",
        "smile",
        "happy",
        "joy",
        ":D",
        "grin",
        "smiley"
      ],
      "\u{1F603}": [
        "grinning_face_with_big_eyes",
        "face",
        "happy",
        "joy",
        "haha",
        ":D",
        ":)",
        "smile",
        "funny",
        "mouth",
        "open",
        "smiley",
        "smiling"
      ],
      "\u{1F604}": [
        "grinning_face_with_smiling_eyes",
        "face",
        "happy",
        "joy",
        "funny",
        "haha",
        "laugh",
        "like",
        ":D",
        ":)",
        "smile",
        "eye",
        "grin",
        "mouth",
        "open",
        "pleased",
        "smiley"
      ],
      "\u{1F601}": [
        "beaming_face_with_smiling_eyes",
        "face",
        "happy",
        "smile",
        "joy",
        "kawaii",
        "eye",
        "grin",
        "grinning"
      ],
      "\u{1F606}": [
        "grinning_squinting_face",
        "happy",
        "joy",
        "lol",
        "satisfied",
        "haha",
        "face",
        "glad",
        "XD",
        "laugh",
        "big",
        "closed",
        "eyes",
        "grin",
        "laughing",
        "mouth",
        "open",
        "smile",
        "smiling",
        "tightly"
      ],
      "\u{1F605}": [
        "grinning_face_with_sweat",
        "face",
        "hot",
        "happy",
        "laugh",
        "sweat",
        "smile",
        "relief",
        "cold",
        "exercise",
        "mouth",
        "open",
        "smiling"
      ],
      "\u{1F923}": [
        "rolling_on_the_floor_laughing",
        "face",
        "rolling",
        "floor",
        "laughing",
        "lol",
        "haha",
        "rofl",
        "laugh",
        "rotfl"
      ],
      "\u{1F602}": [
        "face_with_tears_of_joy",
        "face",
        "cry",
        "tears",
        "weep",
        "happy",
        "happytears",
        "haha",
        "crying",
        "laugh",
        "laughing",
        "lol",
        "tear"
      ],
      "\u{1F642}": [
        "slightly_smiling_face",
        "face",
        "smile",
        "fine",
        "happy",
        "this"
      ],
      "\u{1F643}": [
        "upside_down_face",
        "face",
        "flipped",
        "silly",
        "smile",
        "sarcasm"
      ],
      "\u{1F609}": [
        "winking_face",
        "face",
        "happy",
        "mischievous",
        "secret",
        ";)",
        "smile",
        "eye",
        "flirt",
        "wink",
        "winky"
      ],
      "\u{1F60A}": [
        "smiling_face_with_smiling_eyes",
        "face",
        "smile",
        "happy",
        "flushed",
        "crush",
        "embarrassed",
        "shy",
        "joy",
        "^^",
        "blush",
        "eye",
        "proud",
        "smiley"
      ],
      "\u{1F607}": [
        "smiling_face_with_halo",
        "face",
        "angel",
        "heaven",
        "halo",
        "innocent",
        "fairy",
        "fantasy",
        "smile",
        "tale"
      ],
      "\u{1F970}": [
        "smiling_face_with_hearts",
        "face",
        "love",
        "like",
        "affection",
        "valentines",
        "infatuation",
        "crush",
        "hearts",
        "adore",
        "eyes",
        "three"
      ],
      "\u{1F60D}": [
        "smiling_face_with_heart_eyes",
        "face",
        "love",
        "like",
        "affection",
        "valentines",
        "infatuation",
        "crush",
        "heart",
        "eye",
        "shaped",
        "smile"
      ],
      "\u{1F929}": [
        "star_struck",
        "face",
        "smile",
        "starry",
        "eyes",
        "grinning",
        "excited",
        "eyed",
        "wow"
      ],
      "\u{1F618}": [
        "face_blowing_a_kiss",
        "face",
        "love",
        "like",
        "affection",
        "valentines",
        "infatuation",
        "kiss",
        "blow",
        "flirt",
        "heart",
        "kissing",
        "throwing"
      ],
      "\u{1F617}": [
        "kissing_face",
        "love",
        "like",
        "face",
        "3",
        "valentines",
        "infatuation",
        "kiss",
        "duck",
        "kissy",
        "whistling"
      ],
      "\u263A\uFE0F": [
        "smiling_face",
        "face",
        "blush",
        "massage",
        "happiness",
        "happy",
        "outlined",
        "pleased",
        "relaxed",
        "smile",
        "smiley",
        "white"
      ],
      "\u{1F61A}": [
        "kissing_face_with_closed_eyes",
        "face",
        "love",
        "like",
        "affection",
        "valentines",
        "infatuation",
        "kiss",
        "eye",
        "kissy"
      ],
      "\u{1F619}": [
        "kissing_face_with_smiling_eyes",
        "face",
        "affection",
        "valentines",
        "infatuation",
        "kiss",
        "eye",
        "kissy",
        "smile",
        "whistle",
        "whistling"
      ],
      "\u{1F60B}": [
        "face_savoring_food",
        "happy",
        "joy",
        "tongue",
        "smile",
        "face",
        "silly",
        "yummy",
        "nom",
        "delicious",
        "savouring",
        "goofy",
        "hungry",
        "lick",
        "licking",
        "lips",
        "smiling",
        "um",
        "yum"
      ],
      "\u{1F61B}": [
        "face_with_tongue",
        "face",
        "prank",
        "childish",
        "playful",
        "mischievous",
        "smile",
        "tongue",
        "cheeky",
        "out",
        "stuck"
      ],
      "\u{1F61C}": [
        "winking_face_with_tongue",
        "face",
        "prank",
        "childish",
        "playful",
        "mischievous",
        "smile",
        "wink",
        "tongue",
        "crazy",
        "eye",
        "joke",
        "out",
        "silly",
        "stuck"
      ],
      "\u{1F92A}": [
        "zany_face",
        "face",
        "goofy",
        "crazy",
        "excited",
        "eye",
        "eyes",
        "grinning",
        "large",
        "one",
        "small",
        "wacky",
        "wild"
      ],
      "\u{1F61D}": [
        "squinting_face_with_tongue",
        "face",
        "prank",
        "playful",
        "mischievous",
        "smile",
        "tongue",
        "closed",
        "eye",
        "eyes",
        "horrible",
        "out",
        "stuck",
        "taste",
        "tightly"
      ],
      "\u{1F911}": [
        "money_mouth_face",
        "face",
        "rich",
        "dollar",
        "money",
        "eyes",
        "sign"
      ],
      "\u{1F917}": [
        "hugging_face",
        "face",
        "smile",
        "hug",
        "hands",
        "hugs",
        "open",
        "smiling"
      ],
      "\u{1F92D}": [
        "face_with_hand_over_mouth",
        "face",
        "whoops",
        "shock",
        "surprise",
        "blushing",
        "covering",
        "eyes",
        "quiet",
        "smiling"
      ],
      "\u{1F92B}": [
        "shushing_face",
        "face",
        "quiet",
        "shhh",
        "closed",
        "covering",
        "finger",
        "hush",
        "lips",
        "shh",
        "shush",
        "silence"
      ],
      "\u{1F914}": [
        "thinking_face",
        "face",
        "hmmm",
        "think",
        "consider",
        "chin",
        "shade",
        "thinker",
        "throwing",
        "thumb"
      ],
      "\u{1F910}": [
        "zipper_mouth_face",
        "face",
        "sealed",
        "zipper",
        "secret",
        "hush",
        "lips",
        "silence",
        "zip"
      ],
      "\u{1F928}": [
        "face_with_raised_eyebrow",
        "face",
        "distrust",
        "scepticism",
        "disapproval",
        "disbelief",
        "surprise",
        "suspicious",
        "colbert",
        "mild",
        "one",
        "rock",
        "skeptic"
      ],
      "\u{1F610}": [
        "neutral_face",
        "indifference",
        "meh",
        ":|",
        "neutral",
        "deadpan",
        "faced",
        "mouth",
        "straight"
      ],
      "\u{1F611}": [
        "expressionless_face",
        "face",
        "indifferent",
        "-_-",
        "meh",
        "deadpan",
        "inexpressive",
        "mouth",
        "straight",
        "unexpressive"
      ],
      "\u{1F636}": [
        "face_without_mouth",
        "face",
        "blank",
        "mouthless",
        "mute",
        "no",
        "quiet",
        "silence",
        "silent"
      ],
      "\u{1F60F}": [
        "smirking_face",
        "face",
        "smile",
        "mean",
        "prank",
        "smug",
        "sarcasm",
        "flirting",
        "sexual",
        "smirk",
        "suggestive"
      ],
      "\u{1F612}": [
        "unamused_face",
        "indifference",
        "bored",
        "straight face",
        "serious",
        "sarcasm",
        "unimpressed",
        "skeptical",
        "dubious",
        "ugh",
        "side_eye",
        "dissatisfied",
        "meh",
        "unhappy"
      ],
      "\u{1F644}": [
        "face_with_rolling_eyes",
        "face",
        "eyeroll",
        "frustrated",
        "eye",
        "roll"
      ],
      "\u{1F62C}": [
        "grimacing_face",
        "face",
        "grimace",
        "teeth",
        "awkward",
        "eek",
        "nervous"
      ],
      "\u{1F925}": [
        "lying_face",
        "face",
        "lie",
        "pinocchio",
        "liar",
        "long",
        "nose"
      ],
      "\u{1F60C}": [
        "relieved_face",
        "face",
        "relaxed",
        "phew",
        "massage",
        "happiness",
        "content",
        "pleased",
        "whew"
      ],
      "\u{1F614}": [
        "pensive_face",
        "face",
        "sad",
        "depressed",
        "upset",
        "dejected",
        "sadface",
        "sorrowful"
      ],
      "\u{1F62A}": [
        "sleepy_face",
        "face",
        "tired",
        "rest",
        "nap",
        "bubble",
        "side",
        "sleep",
        "snot",
        "tear"
      ],
      "\u{1F924}": [
        "drooling_face",
        "face",
        "drool"
      ],
      "\u{1F634}": [
        "sleeping_face",
        "face",
        "tired",
        "sleepy",
        "night",
        "zzz",
        "sleep",
        "snoring"
      ],
      "\u{1F637}": [
        "face_with_medical_mask",
        "face",
        "sick",
        "ill",
        "disease",
        "covid",
        "cold",
        "coronavirus",
        "doctor",
        "medicine",
        "surgical"
      ],
      "\u{1F912}": [
        "face_with_thermometer",
        "sick",
        "temperature",
        "thermometer",
        "cold",
        "fever",
        "covid",
        "ill"
      ],
      "\u{1F915}": [
        "face_with_head_bandage",
        "injured",
        "clumsy",
        "bandage",
        "hurt",
        "bandaged",
        "injury"
      ],
      "\u{1F922}": [
        "nauseated_face",
        "face",
        "vomit",
        "gross",
        "green",
        "sick",
        "throw up",
        "ill",
        "barf",
        "disgust",
        "disgusted",
        "green\xA0face"
      ],
      "\u{1F92E}": [
        "face_vomiting",
        "face",
        "sick",
        "barf",
        "ill",
        "mouth",
        "open",
        "puke",
        "spew",
        "throwing",
        "up",
        "vomit"
      ],
      "\u{1F927}": [
        "sneezing_face",
        "face",
        "gesundheit",
        "sneeze",
        "sick",
        "allergy",
        "achoo"
      ],
      "\u{1F975}": [
        "hot_face",
        "face",
        "feverish",
        "heat",
        "red",
        "sweating",
        "overheated",
        "stroke"
      ],
      "\u{1F976}": [
        "cold_face",
        "face",
        "blue",
        "freezing",
        "frozen",
        "frostbite",
        "icicles",
        "ice"
      ],
      "\u{1F974}": [
        "woozy_face",
        "face",
        "dizzy",
        "intoxicated",
        "tipsy",
        "wavy",
        "drunk",
        "eyes",
        "groggy",
        "mouth",
        "uneven"
      ],
      "\u{1F635}": [
        "dizzy_face",
        "spent",
        "unconscious",
        "xox",
        "dizzy",
        "cross",
        "crossed",
        "dead",
        "eyes",
        "knocked",
        "out",
        "spiral\xA0eyes"
      ],
      "\u{1F92F}": [
        "exploding_head",
        "face",
        "shocked",
        "mind",
        "blown",
        "blowing",
        "explosion",
        "mad"
      ],
      "\u{1F920}": [
        "cowboy_hat_face",
        "face",
        "cowgirl",
        "hat"
      ],
      "\u{1F973}": [
        "partying_face",
        "face",
        "celebration",
        "woohoo",
        "birthday",
        "hat",
        "horn",
        "party"
      ],
      "\u{1F60E}": [
        "smiling_face_with_sunglasses",
        "face",
        "cool",
        "smile",
        "summer",
        "beach",
        "sunglass",
        "best",
        "bright",
        "eye",
        "eyewear",
        "friends",
        "glasses",
        "mutual",
        "snapchat",
        "sun",
        "weather"
      ],
      "\u{1F913}": [
        "nerd_face",
        "face",
        "nerdy",
        "geek",
        "dork",
        "glasses",
        "smiling"
      ],
      "\u{1F9D0}": [
        "face_with_monocle",
        "face",
        "stuffy",
        "wealthy",
        "rich",
        "exploration",
        "inspection"
      ],
      "\u{1F615}": [
        "confused_face",
        "face",
        "indifference",
        "huh",
        "weird",
        "hmmm",
        ":/",
        "meh",
        "nonplussed",
        "puzzled",
        "s"
      ],
      "\u{1F61F}": [
        "worried_face",
        "face",
        "concern",
        "nervous",
        ":(",
        "sad",
        "sadface"
      ],
      "\u{1F641}": [
        "slightly_frowning_face",
        "face",
        "frowning",
        "disappointed",
        "sad",
        "upset",
        "frown",
        "unhappy"
      ],
      "\u2639\uFE0F": [
        "frowning_face",
        "face",
        "sad",
        "upset",
        "frown",
        "megafrown",
        "unhappy",
        "white"
      ],
      "\u{1F62E}": [
        "face_with_open_mouth",
        "face",
        "surprise",
        "impressed",
        "wow",
        "whoa",
        ":O",
        "surprised",
        "sympathy"
      ],
      "\u{1F62F}": [
        "hushed_face",
        "face",
        "woo",
        "shh",
        "silence",
        "speechless",
        "stunned",
        "surprise",
        "surprised"
      ],
      "\u{1F632}": [
        "astonished_face",
        "face",
        "xox",
        "surprised",
        "poisoned",
        "amazed",
        "drunk\xA0face",
        "gasp",
        "gasping",
        "shocked",
        "totally"
      ],
      "\u{1F633}": [
        "flushed_face",
        "face",
        "blush",
        "shy",
        "flattered",
        "blushing",
        "dazed",
        "embarrassed",
        "eyes",
        "open",
        "shame",
        "wide"
      ],
      "\u{1F97A}": [
        "pleading_face",
        "face",
        "begging",
        "mercy",
        "cry",
        "tears",
        "sad",
        "grievance",
        "eyes",
        "glossy",
        "puppy",
        "simp"
      ],
      "\u{1F626}": [
        "frowning_face_with_open_mouth",
        "face",
        "aw",
        "what",
        "frown",
        "yawning"
      ],
      "\u{1F627}": [
        "anguished_face",
        "face",
        "stunned",
        "nervous",
        "pained"
      ],
      "\u{1F628}": [
        "fearful_face",
        "face",
        "scared",
        "terrified",
        "nervous",
        "fear",
        "oops",
        "shocked",
        "surprised"
      ],
      "\u{1F630}": [
        "anxious_face_with_sweat",
        "face",
        "nervous",
        "sweat",
        "blue",
        "cold",
        "concerned\xA0face",
        "mouth",
        "open",
        "rushed"
      ],
      "\u{1F625}": [
        "sad_but_relieved_face",
        "face",
        "phew",
        "sweat",
        "nervous",
        "disappointed",
        "eyebrow",
        "whew"
      ],
      "\u{1F622}": [
        "crying_face",
        "face",
        "tears",
        "sad",
        "depressed",
        "upset",
        ":'(",
        "cry",
        "tear"
      ],
      "\u{1F62D}": [
        "loudly_crying_face",
        "sobbing",
        "face",
        "cry",
        "tears",
        "sad",
        "upset",
        "depressed",
        "bawling",
        "sob",
        "tear"
      ],
      "\u{1F631}": [
        "face_screaming_in_fear",
        "face",
        "munch",
        "scared",
        "omg",
        "alone",
        "fearful",
        "home",
        "horror",
        "scream",
        "shocked"
      ],
      "\u{1F616}": [
        "confounded_face",
        "face",
        "confused",
        "sick",
        "unwell",
        "oops",
        ":S",
        "mouth",
        "quivering",
        "scrunched"
      ],
      "\u{1F623}": [
        "persevering_face",
        "face",
        "sick",
        "no",
        "upset",
        "oops",
        "eyes",
        "helpless",
        "persevere",
        "scrunched",
        "struggling"
      ],
      "\u{1F61E}": [
        "disappointed_face",
        "face",
        "sad",
        "upset",
        "depressed",
        ":(",
        "sadface"
      ],
      "\u{1F613}": [
        "downcast_face_with_sweat",
        "face",
        "hot",
        "sad",
        "tired",
        "exercise",
        "cold",
        "hard",
        "work"
      ],
      "\u{1F629}": [
        "weary_face",
        "face",
        "tired",
        "sleepy",
        "sad",
        "frustrated",
        "upset",
        "distraught",
        "wailing"
      ],
      "\u{1F62B}": [
        "tired_face",
        "sick",
        "whine",
        "upset",
        "frustrated",
        "distraught",
        "exhausted",
        "fed",
        "up"
      ],
      "\u{1F971}": [
        "yawning_face",
        "tired",
        "sleepy",
        "bored",
        "yawn"
      ],
      "\u{1F624}": [
        "face_with_steam_from_nose",
        "face",
        "gas",
        "phew",
        "proud",
        "pride",
        "triumph",
        "airing",
        "frustrated",
        "grievances",
        "look",
        "mad",
        "smug",
        "steaming",
        "won"
      ],
      "\u{1F621}": [
        "pouting_face",
        "angry",
        "mad",
        "hate",
        "despise",
        "enraged",
        "grumpy",
        "pout",
        "rage",
        "red"
      ],
      "\u{1F620}": [
        "angry_face",
        "mad",
        "face",
        "annoyed",
        "frustrated",
        "anger",
        "grumpy"
      ],
      "\u{1F92C}": [
        "face_with_symbols_on_mouth",
        "face",
        "swearing",
        "cursing",
        "cussing",
        "profanity",
        "expletive",
        "covering",
        "foul",
        "grawlix",
        "over",
        "serious"
      ],
      "\u{1F608}": [
        "smiling_face_with_horns",
        "devil",
        "horns",
        "evil",
        "fairy",
        "fantasy",
        "happy",
        "imp",
        "purple",
        "red\xA0devil",
        "smile",
        "tale"
      ],
      "\u{1F47F}": [
        "angry_face_with_horns",
        "devil",
        "angry",
        "horns",
        "demon",
        "evil",
        "fairy",
        "fantasy",
        "goblin",
        "imp",
        "purple",
        "sad",
        "tale"
      ],
      "\u{1F480}": [
        "skull",
        "dead",
        "skeleton",
        "creepy",
        "death",
        "dead",
        "body",
        "danger",
        "face",
        "fairy",
        "grey",
        "halloween",
        "monster",
        "poison",
        "tale"
      ],
      "\u2620\uFE0F": [
        "skull_and_crossbones",
        "poison",
        "danger",
        "deadly",
        "scary",
        "death",
        "pirate",
        "evil",
        "body",
        "face",
        "halloween",
        "monster"
      ],
      "\u{1F4A9}": [
        "pile_of_poo",
        "hankey",
        "shitface",
        "fail",
        "turd",
        "shit",
        "comic",
        "crap",
        "dirt",
        "dog",
        "dung",
        "face",
        "monster",
        "poop",
        "smiling",
        "bad",
        "needs_improvement"
      ],
      "\u{1F921}": [
        "clown_face",
        "face",
        "mock"
      ],
      "\u{1F479}": [
        "ogre",
        "monster",
        "red",
        "mask",
        "halloween",
        "scary",
        "creepy",
        "devil",
        "demon",
        "japanese_ogre",
        "creature",
        "face",
        "fairy",
        "fantasy",
        "oni",
        "tale",
        "shrek"
      ],
      "\u{1F47A}": [
        "goblin",
        "red",
        "evil",
        "mask",
        "monster",
        "scary",
        "creepy",
        "japanese_goblin",
        "creature",
        "face",
        "fairy",
        "fantasy",
        "long",
        "nose",
        "tale",
        "tengu"
      ],
      "\u{1F47B}": [
        "ghost",
        "halloween",
        "spooky",
        "scary",
        "creature",
        "disappear",
        "face",
        "fairy",
        "fantasy",
        "ghoul",
        "monster",
        "tale"
      ],
      "\u{1F47D}": [
        "alien",
        "UFO",
        "paul",
        "weird",
        "outer_space",
        "creature",
        "et",
        "extraterrestrial",
        "face",
        "fairy",
        "fantasy",
        "monster",
        "tale",
        "external"
      ],
      "\u{1F47E}": [
        "alien_monster",
        "game",
        "arcade",
        "play",
        "creature",
        "extraterrestrial",
        "face",
        "fairy",
        "fantasy",
        "invader",
        "retro",
        "space",
        "tale",
        "ufo",
        "video"
      ],
      "\u{1F916}": [
        "robot",
        "computer",
        "machine",
        "bot",
        "face",
        "monster"
      ],
      "\u{1F63A}": [
        "grinning_cat",
        "animal",
        "cats",
        "happy",
        "smile",
        "face",
        "mouth",
        "open",
        "smiley",
        "smiling"
      ],
      "\u{1F638}": [
        "grinning_cat_with_smiling_eyes",
        "animal",
        "cats",
        "smile",
        "eye",
        "face",
        "grin",
        "happy"
      ],
      "\u{1F639}": [
        "cat_with_tears_of_joy",
        "animal",
        "cats",
        "haha",
        "happy",
        "tears",
        "face",
        "laughing",
        "tear"
      ],
      "\u{1F63B}": [
        "smiling_cat_with_heart_eyes",
        "animal",
        "love",
        "like",
        "affection",
        "cats",
        "valentines",
        "heart",
        "eye",
        "face",
        "loving\xA0cat",
        "shaped",
        "smile"
      ],
      "\u{1F63C}": [
        "cat_with_wry_smile",
        "animal",
        "cats",
        "smirk",
        "face",
        "ironic",
        "smirking"
      ],
      "\u{1F63D}": [
        "kissing_cat",
        "animal",
        "cats",
        "kiss",
        "closed",
        "eye",
        "eyes",
        "face"
      ],
      "\u{1F640}": [
        "weary_cat",
        "animal",
        "cats",
        "munch",
        "scared",
        "scream",
        "face",
        "fear",
        "horror",
        "oh",
        "screaming",
        "surprised"
      ],
      "\u{1F63F}": [
        "crying_cat",
        "animal",
        "tears",
        "weep",
        "sad",
        "cats",
        "upset",
        "cry",
        "face",
        "sad\xA0cat",
        "tear"
      ],
      "\u{1F63E}": [
        "pouting_cat",
        "animal",
        "cats",
        "face",
        "grumpy"
      ],
      "\u{1F648}": [
        "see_no_evil_monkey",
        "monkey",
        "animal",
        "nature",
        "haha",
        "blind",
        "covering",
        "eyes",
        "face",
        "forbidden",
        "gesture",
        "ignore",
        "mizaru",
        "not",
        "prohibited"
      ],
      "\u{1F649}": [
        "hear_no_evil_monkey",
        "animal",
        "monkey",
        "nature",
        "covering",
        "deaf",
        "ears",
        "face",
        "forbidden",
        "gesture",
        "kikazaru",
        "not",
        "prohibited"
      ],
      "\u{1F64A}": [
        "speak_no_evil_monkey",
        "monkey",
        "animal",
        "nature",
        "omg",
        "covering",
        "face",
        "forbidden",
        "gesture",
        "hush",
        "iwazaru",
        "mouth",
        "mute",
        "not",
        "no\xA0speaking",
        "prohibited",
        "ignore"
      ],
      "\u{1F48B}": [
        "kiss_mark",
        "face",
        "lips",
        "love",
        "like",
        "affection",
        "valentines",
        "heart",
        "kissing",
        "lipstick",
        "romance"
      ],
      "\u{1F48C}": [
        "love_letter",
        "email",
        "like",
        "affection",
        "envelope",
        "valentines",
        "heart",
        "mail",
        "note",
        "romance"
      ],
      "\u{1F498}": [
        "heart_with_arrow",
        "love",
        "like",
        "heart",
        "affection",
        "valentines",
        "cupid",
        "lovestruck",
        "romance"
      ],
      "\u{1F49D}": [
        "heart_with_ribbon",
        "love",
        "valentines",
        "box",
        "chocolate",
        "chocolates",
        "gift",
        "valentine"
      ],
      "\u{1F496}": [
        "sparkling_heart",
        "love",
        "like",
        "affection",
        "valentines",
        "excited",
        "sparkle",
        "sparkly",
        "stars\xA0heart"
      ],
      "\u{1F497}": [
        "growing_heart",
        "like",
        "love",
        "affection",
        "valentines",
        "pink",
        "excited",
        "heartpulse",
        "multiple",
        "nervous",
        "pulse",
        "triple"
      ],
      "\u{1F493}": [
        "beating_heart",
        "love",
        "like",
        "affection",
        "valentines",
        "pink",
        "heart",
        "alarm",
        "heartbeat",
        "pulsating",
        "wifi"
      ],
      "\u{1F49E}": [
        "revolving_hearts",
        "love",
        "like",
        "affection",
        "valentines",
        "heart",
        "two"
      ],
      "\u{1F495}": [
        "two_hearts",
        "love",
        "like",
        "affection",
        "valentines",
        "heart",
        "pink",
        "small"
      ],
      "\u{1F49F}": [
        "heart_decoration",
        "purple-square",
        "love",
        "like"
      ],
      "\u2763\uFE0F": [
        "heart_exclamation",
        "decoration",
        "love",
        "above",
        "an",
        "as",
        "dot",
        "heavy",
        "mark",
        "ornament",
        "punctuation",
        "red"
      ],
      "\u{1F494}": [
        "broken_heart",
        "sad",
        "sorry",
        "break",
        "heart",
        "heartbreak",
        "breaking",
        "brokenhearted"
      ],
      "\u2764\uFE0F": [
        "red_heart",
        "love",
        "like",
        "valentines",
        "black",
        "heavy"
      ],
      "\u{1F9E1}": [
        "orange_heart",
        "love",
        "like",
        "affection",
        "valentines"
      ],
      "\u{1F49B}": [
        "yellow_heart",
        "love",
        "like",
        "affection",
        "valentines",
        "bf",
        "gold",
        "snapchat"
      ],
      "\u{1F49A}": [
        "green_heart",
        "love",
        "like",
        "affection",
        "valentines",
        "nct"
      ],
      "\u{1F499}": [
        "blue_heart",
        "love",
        "like",
        "affection",
        "valentines",
        "brand",
        "neutral"
      ],
      "\u{1F49C}": [
        "purple_heart",
        "love",
        "like",
        "affection",
        "valentines",
        "bts",
        "emoji"
      ],
      "\u{1F90E}": [
        "brown_heart",
        "coffee"
      ],
      "\u{1F5A4}": [
        "black_heart",
        "evil",
        "dark",
        "wicked"
      ],
      "\u{1F90D}": [
        "white_heart",
        "pure"
      ],
      "\u{1F4AF}": [
        "hundred_points",
        "score",
        "perfect",
        "numbers",
        "century",
        "exam",
        "quiz",
        "test",
        "pass",
        "hundred",
        "100",
        "full",
        "keep",
        "symbol"
      ],
      "\u{1F4A2}": [
        "anger_symbol",
        "angry",
        "mad",
        "comic",
        "pop",
        "sign",
        "vein"
      ],
      "\u{1F4A5}": [
        "collision",
        "bomb",
        "explode",
        "explosion",
        "blown",
        "bang",
        "boom",
        "comic",
        "impact",
        "red",
        "spark",
        "symbol",
        "break"
      ],
      "\u{1F4AB}": [
        "dizzy",
        "star",
        "sparkle",
        "shoot",
        "magic",
        "circle",
        "comic",
        "symbol",
        "animations",
        "transitions"
      ],
      "\u{1F4A6}": [
        "sweat_droplets",
        "water",
        "drip",
        "oops",
        "comic",
        "drops",
        "plewds",
        "splashing",
        "symbol",
        "workout"
      ],
      "\u{1F4A8}": [
        "dashing_away",
        "wind",
        "air",
        "fast",
        "shoo",
        "fart",
        "smoke",
        "puff",
        "blow",
        "comic",
        "dash",
        "gust",
        "running",
        "steam",
        "symbol",
        "vaping"
      ],
      "\u{1F573}\uFE0F": [
        "hole",
        "embarrassing"
      ],
      "\u{1F4A3}": [
        "bomb",
        "boom",
        "explode",
        "explosion",
        "terrorism",
        "comic"
      ],
      "\u{1F4AC}": [
        "speech_balloon",
        "bubble",
        "words",
        "message",
        "talk",
        "chatting",
        "chat",
        "comic",
        "comment",
        "dialog",
        "text",
        "literals"
      ],
      "\u{1F441}\uFE0F\u200D\u{1F5E8}\uFE0F": [
        "eye_in_speech_bubble",
        "info",
        "am",
        "i",
        "witness"
      ],
      "\u{1F5E8}\uFE0F": [
        "left_speech_bubble",
        "words",
        "message",
        "talk",
        "chatting",
        "dialog"
      ],
      "\u{1F5EF}\uFE0F": [
        "right_anger_bubble",
        "caption",
        "speech",
        "thinking",
        "mad",
        "angry",
        "balloon",
        "zag",
        "zig"
      ],
      "\u{1F4AD}": [
        "thought_balloon",
        "bubble",
        "cloud",
        "speech",
        "thinking",
        "dream",
        "comic"
      ],
      "\u{1F4A4}": [
        "zzz",
        "sleepy",
        "tired",
        "dream",
        "bedtime",
        "boring",
        "comic",
        "sign",
        "sleep",
        "sleeping",
        "symbol"
      ],
      "\u{1F44B}": [
        "waving_hand",
        "wave",
        "hands",
        "gesture",
        "goodbye",
        "solong",
        "farewell",
        "hello",
        "hi",
        "palm",
        "body",
        "sign"
      ],
      "\u{1F91A}": [
        "raised_back_of_hand",
        "fingers",
        "raised",
        "backhand",
        "body"
      ],
      "\u{1F590}\uFE0F": [
        "hand_with_fingers_splayed",
        "hand",
        "fingers",
        "palm",
        "body",
        "finger",
        "five",
        "raised"
      ],
      "\u270B": [
        "raised_hand",
        "fingers",
        "stop",
        "highfive",
        "palm",
        "ban",
        "body",
        "five",
        "high"
      ],
      "\u{1F596}": [
        "vulcan_salute",
        "hand",
        "fingers",
        "spock",
        "star trek",
        "between",
        "body",
        "finger",
        "middle",
        "part",
        "prosper",
        "raised",
        "ring",
        "split"
      ],
      "\u{1F44C}": [
        "ok_hand",
        "fingers",
        "limbs",
        "perfect",
        "ok",
        "okay",
        "body",
        "sign"
      ],
      "\u{1F90F}": [
        "pinching_hand",
        "tiny",
        "small",
        "size",
        "amount",
        "body",
        "little"
      ],
      "\u270C\uFE0F": [
        "victory_hand",
        "fingers",
        "ohyeah",
        "hand",
        "peace",
        "victory",
        "two",
        "air",
        "body",
        "quotes",
        "sign",
        "v"
      ],
      "\u{1F91E}": [
        "crossed_fingers",
        "good",
        "lucky",
        "body",
        "cross",
        "finger",
        "hand",
        "hopeful",
        "index",
        "luck",
        "middle"
      ],
      "\u{1F91F}": [
        "love_you_gesture",
        "hand",
        "fingers",
        "gesture",
        "body",
        "i",
        "ily",
        "sign"
      ],
      "\u{1F918}": [
        "sign_of_the_horns",
        "hand",
        "fingers",
        "evil_eye",
        "sign_of_horns",
        "rock_on",
        "body",
        "devil",
        "finger",
        "heavy",
        "metal"
      ],
      "\u{1F919}": [
        "call_me_hand",
        "hands",
        "gesture",
        "shaka",
        "body",
        "phone",
        "sign"
      ],
      "\u{1F448}": [
        "backhand_index_pointing_left",
        "direction",
        "fingers",
        "hand",
        "left",
        "body",
        "finger",
        "point",
        "white"
      ],
      "\u{1F449}": [
        "backhand_index_pointing_right",
        "fingers",
        "hand",
        "direction",
        "right",
        "body",
        "finger",
        "point",
        "white"
      ],
      "\u{1F446}": [
        "backhand_index_pointing_up",
        "fingers",
        "hand",
        "direction",
        "up",
        "body",
        "finger",
        "middle",
        "point",
        "white"
      ],
      "\u{1F595}": [
        "middle_finger",
        "hand",
        "fingers",
        "rude",
        "middle",
        "flipping",
        "bird",
        "body",
        "dito",
        "extended",
        "fu",
        "medio",
        "middle\xA0finger",
        "reversed"
      ],
      "\u{1F447}": [
        "backhand_index_pointing_down",
        "fingers",
        "hand",
        "direction",
        "down",
        "body",
        "finger",
        "point",
        "white"
      ],
      "\u261D\uFE0F": [
        "index_pointing_up",
        "hand",
        "fingers",
        "direction",
        "up",
        "body",
        "finger",
        "point",
        "secret",
        "white"
      ],
      "\u{1F44D}": [
        "thumbs_up",
        "thumbsup",
        "yes",
        "awesome",
        "good",
        "agree",
        "accept",
        "cool",
        "hand",
        "like",
        "+1",
        "approve",
        "body",
        "ok",
        "sign",
        "thumb"
      ],
      "\u{1F44E}": [
        "thumbs_down",
        "thumbsdown",
        "no",
        "dislike",
        "hand",
        "-1",
        "bad",
        "body",
        "bury",
        "disapprove",
        "sign",
        "thumb"
      ],
      "\u270A": [
        "raised_fist",
        "fingers",
        "hand",
        "grasp",
        "body",
        "clenched",
        "power",
        "pump",
        "punch"
      ],
      "\u{1F44A}": [
        "oncoming_fist",
        "angry",
        "violence",
        "fist",
        "hit",
        "attack",
        "hand",
        "body",
        "bro",
        "brofist",
        "bump",
        "clenched",
        "closed",
        "facepunch",
        "fisted",
        "punch",
        "sign"
      ],
      "\u{1F91B}": [
        "left_facing_fist",
        "hand",
        "fistbump",
        "body",
        "bump",
        "leftwards"
      ],
      "\u{1F91C}": [
        "right_facing_fist",
        "hand",
        "fistbump",
        "body",
        "bump",
        "rightwards",
        "right\xA0fist"
      ],
      "\u{1F44F}": [
        "clapping_hands",
        "hands",
        "praise",
        "applause",
        "congrats",
        "yay",
        "body",
        "clap",
        "golf",
        "hand",
        "round",
        "sign"
      ],
      "\u{1F64C}": [
        "raising_hands",
        "gesture",
        "hooray",
        "yea",
        "celebration",
        "hands",
        "air",
        "arms",
        "banzai",
        "body",
        "both",
        "festivus",
        "hallelujah",
        "hand",
        "miracle",
        "person",
        "praise",
        "raised",
        "two"
      ],
      "\u{1F450}": [
        "open_hands",
        "fingers",
        "butterfly",
        "hands",
        "open",
        "body",
        "hand",
        "hug",
        "jazz",
        "sign"
      ],
      "\u{1F932}": [
        "palms_up_together",
        "hands",
        "gesture",
        "cupped",
        "prayer",
        "body",
        "dua",
        "facing"
      ],
      "\u{1F91D}": [
        "handshake",
        "agreement",
        "shake",
        "deal",
        "hand",
        "hands",
        "meeting",
        "shaking"
      ],
      "\u{1F64F}": [
        "folded_hands",
        "please",
        "hope",
        "wish",
        "namaste",
        "highfive",
        "pray",
        "thank you",
        "thanks",
        "appreciate",
        "ask",
        "body",
        "bow",
        "five",
        "gesture",
        "hand",
        "high",
        "person",
        "prayer",
        "pressed",
        "together"
      ],
      "\u270D\uFE0F": [
        "writing_hand",
        "lower_left_ballpoint_pen",
        "stationery",
        "write",
        "compose",
        "body"
      ],
      "\u{1F485}": [
        "nail_polish",
        "nail_care",
        "beauty",
        "manicure",
        "finger",
        "fashion",
        "nail",
        "slay",
        "body",
        "cosmetics",
        "fingers",
        "nonchalant"
      ],
      "\u{1F933}": [
        "selfie",
        "camera",
        "phone",
        "arm",
        "hand"
      ],
      "\u{1F4AA}": [
        "flexed_biceps",
        "arm",
        "flex",
        "hand",
        "summer",
        "strong",
        "biceps",
        "bicep",
        "body",
        "comic",
        "feats",
        "flexing",
        "muscle",
        "muscles",
        "strength",
        "workout"
      ],
      "\u{1F9BE}": [
        "mechanical_arm",
        "accessibility",
        "body",
        "prosthetic"
      ],
      "\u{1F9BF}": [
        "mechanical_leg",
        "accessibility",
        "body",
        "prosthetic"
      ],
      "\u{1F9B5}": [
        "leg",
        "kick",
        "limb",
        "body"
      ],
      "\u{1F9B6}": [
        "foot",
        "kick",
        "stomp",
        "body"
      ],
      "\u{1F442}": [
        "ear",
        "face",
        "hear",
        "sound",
        "listen",
        "body",
        "ears",
        "hearing",
        "listening",
        "nose"
      ],
      "\u{1F9BB}": [
        "ear_with_hearing_aid",
        "accessibility",
        "body",
        "hard"
      ],
      "\u{1F443}": [
        "nose",
        "smell",
        "sniff",
        "body",
        "smelling",
        "sniffing",
        "stinky"
      ],
      "\u{1F9E0}": [
        "brain",
        "smart",
        "intelligent",
        "body",
        "organ"
      ],
      "\u{1F9B7}": [
        "tooth",
        "teeth",
        "dentist",
        "body"
      ],
      "\u{1F9B4}": [
        "bone",
        "skeleton",
        "body"
      ],
      "\u{1F440}": [
        "eyes",
        "look",
        "watch",
        "stalk",
        "peek",
        "see",
        "body",
        "eye",
        "eyeballs",
        "face",
        "shifty",
        "wide"
      ],
      "\u{1F441}\uFE0F": [
        "eye",
        "face",
        "look",
        "see",
        "watch",
        "stare",
        "body",
        "single"
      ],
      "\u{1F445}": [
        "tongue",
        "mouth",
        "playful",
        "body",
        "out",
        "taste"
      ],
      "\u{1F444}": [
        "mouth",
        "kiss",
        "body",
        "kissing",
        "lips"
      ],
      "\u{1F476}": [
        "baby",
        "child",
        "boy",
        "girl",
        "toddler",
        "newborn",
        "young"
      ],
      "\u{1F9D2}": [
        "child",
        "gender-neutral",
        "young",
        "boy",
        "gender",
        "girl",
        "inclusive",
        "neutral",
        "person",
        "unspecified"
      ],
      "\u{1F466}": [
        "boy",
        "man",
        "male",
        "guy",
        "teenager",
        "child",
        "young"
      ],
      "\u{1F467}": [
        "girl",
        "female",
        "woman",
        "teenager",
        "child",
        "maiden",
        "virgin",
        "virgo",
        "young",
        "zodiac"
      ],
      "\u{1F9D1}": [
        "person",
        "gender-neutral",
        "adult",
        "female",
        "gender",
        "inclusive",
        "male",
        "man",
        "men",
        "neutral",
        "unspecified",
        "woman",
        "women"
      ],
      "\u{1F471}": [
        "person_blond_hair",
        "hairstyle",
        "blonde",
        "haired",
        "man"
      ],
      "\u{1F468}": [
        "man",
        "mustache",
        "father",
        "dad",
        "guy",
        "classy",
        "sir",
        "moustache",
        "adult",
        "male",
        "men"
      ],
      "\u{1F9D4}": [
        "man_beard",
        "person",
        "bewhiskered",
        "bearded"
      ],
      "\u{1F468}\u200D\u{1F9B0}": [
        "man_red_hair",
        "hairstyle",
        "adult",
        "ginger",
        "haired",
        "male",
        "men",
        "redhead"
      ],
      "\u{1F468}\u200D\u{1F9B1}": [
        "man_curly_hair",
        "hairstyle",
        "adult",
        "haired",
        "male",
        "men"
      ],
      "\u{1F468}\u200D\u{1F9B3}": [
        "man_white_hair",
        "old",
        "elder",
        "adult",
        "haired",
        "male",
        "men"
      ],
      "\u{1F468}\u200D\u{1F9B2}": [
        "man_bald",
        "hairless",
        "adult",
        "hair",
        "male",
        "men",
        "no"
      ],
      "\u{1F469}": [
        "woman",
        "female",
        "girls",
        "lady",
        "adult",
        "women",
        "yellow"
      ],
      "\u{1F469}\u200D\u{1F9B0}": [
        "woman_red_hair",
        "hairstyle",
        "adult",
        "female",
        "ginger",
        "haired",
        "redhead",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F9B0}": [
        "person_red_hair",
        "hairstyle",
        "adult",
        "gender",
        "haired",
        "unspecified"
      ],
      "\u{1F469}\u200D\u{1F9B1}": [
        "woman_curly_hair",
        "hairstyle",
        "adult",
        "female",
        "haired",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F9B1}": [
        "person_curly_hair",
        "hairstyle",
        "adult",
        "gender",
        "haired",
        "unspecified"
      ],
      "\u{1F469}\u200D\u{1F9B3}": [
        "woman_white_hair",
        "old",
        "elder",
        "adult",
        "female",
        "haired",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F9B3}": [
        "person_white_hair",
        "elder",
        "old",
        "adult",
        "gender",
        "haired",
        "unspecified"
      ],
      "\u{1F469}\u200D\u{1F9B2}": [
        "woman_bald",
        "hairless",
        "adult",
        "female",
        "hair",
        "no",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F9B2}": [
        "person_bald",
        "hairless",
        "adult",
        "gender",
        "hair",
        "no",
        "unspecified"
      ],
      "\u{1F471}\u200D\u2640\uFE0F": [
        "woman_blond_hair",
        "woman",
        "female",
        "girl",
        "blonde",
        "person",
        "haired",
        "women"
      ],
      "\u{1F471}\u200D\u2642\uFE0F": [
        "man_blond_hair",
        "man",
        "male",
        "boy",
        "blonde",
        "guy",
        "person",
        "haired",
        "men"
      ],
      "\u{1F9D3}": [
        "older_person",
        "human",
        "elder",
        "senior",
        "gender-neutral",
        "adult",
        "female",
        "gender",
        "male",
        "man",
        "men",
        "neutral",
        "old",
        "unspecified",
        "woman",
        "women"
      ],
      "\u{1F474}": [
        "old_man",
        "human",
        "male",
        "men",
        "old",
        "elder",
        "senior",
        "adult",
        "elderly",
        "grandpa",
        "older"
      ],
      "\u{1F475}": [
        "old_woman",
        "human",
        "female",
        "women",
        "lady",
        "old",
        "elder",
        "senior",
        "adult",
        "elderly",
        "grandma",
        "nanna",
        "older"
      ],
      "\u{1F64D}": [
        "person_frowning",
        "worried",
        "frown",
        "gesture",
        "sad",
        "woman"
      ],
      "\u{1F64D}\u200D\u2642\uFE0F": [
        "man_frowning",
        "male",
        "boy",
        "man",
        "sad",
        "depressed",
        "discouraged",
        "unhappy",
        "frown",
        "gesture",
        "men"
      ],
      "\u{1F64D}\u200D\u2640\uFE0F": [
        "woman_frowning",
        "female",
        "girl",
        "woman",
        "sad",
        "depressed",
        "discouraged",
        "unhappy",
        "frown",
        "gesture",
        "women"
      ],
      "\u{1F64E}": [
        "person_pouting",
        "upset",
        "blank",
        "face",
        "fed",
        "gesture",
        "look",
        "up"
      ],
      "\u{1F64E}\u200D\u2642\uFE0F": [
        "man_pouting",
        "male",
        "boy",
        "man",
        "gesture",
        "men"
      ],
      "\u{1F64E}\u200D\u2640\uFE0F": [
        "woman_pouting",
        "female",
        "girl",
        "woman",
        "gesture",
        "women"
      ],
      "\u{1F645}": [
        "person_gesturing_no",
        "decline",
        "arms",
        "deal",
        "denied",
        "face",
        "forbidden",
        "gesture",
        "good",
        "halt",
        "hand",
        "not",
        "ok",
        "prohibited",
        "stop",
        "x"
      ],
      "\u{1F645}\u200D\u2642\uFE0F": [
        "man_gesturing_no",
        "male",
        "boy",
        "man",
        "nope",
        "denied",
        "forbidden",
        "gesture",
        "good",
        "halt",
        "hand",
        "men",
        "ng",
        "not",
        "ok",
        "prohibited",
        "stop"
      ],
      "\u{1F645}\u200D\u2640\uFE0F": [
        "woman_gesturing_no",
        "female",
        "girl",
        "woman",
        "nope",
        "denied",
        "forbidden",
        "gesture",
        "good",
        "halt",
        "hand",
        "ng",
        "not",
        "ok",
        "prohibited",
        "stop",
        "women"
      ],
      "\u{1F646}": [
        "person_gesturing_ok",
        "agree",
        "ballerina",
        "face",
        "gesture",
        "hand",
        "hands",
        "head"
      ],
      "\u{1F646}\u200D\u2642\uFE0F": [
        "man_gesturing_ok",
        "men",
        "boy",
        "male",
        "blue",
        "human",
        "man",
        "gesture",
        "hand"
      ],
      "\u{1F646}\u200D\u2640\uFE0F": [
        "woman_gesturing_ok",
        "women",
        "girl",
        "female",
        "pink",
        "human",
        "woman",
        "gesture",
        "hand"
      ],
      "\u{1F481}": [
        "person_tipping_hand",
        "information",
        "attendant",
        "bellhop",
        "concierge",
        "desk",
        "female",
        "flick",
        "girl",
        "hair",
        "help",
        "sassy",
        "woman",
        "women"
      ],
      "\u{1F481}\u200D\u2642\uFE0F": [
        "man_tipping_hand",
        "male",
        "boy",
        "man",
        "human",
        "information",
        "desk",
        "help",
        "men",
        "sassy"
      ],
      "\u{1F481}\u200D\u2640\uFE0F": [
        "woman_tipping_hand",
        "female",
        "girl",
        "woman",
        "human",
        "information",
        "desk",
        "help",
        "sassy",
        "women"
      ],
      "\u{1F64B}": [
        "person_raising_hand",
        "question",
        "answering",
        "gesture",
        "happy",
        "one",
        "raised",
        "up"
      ],
      "\u{1F64B}\u200D\u2642\uFE0F": [
        "man_raising_hand",
        "male",
        "boy",
        "man",
        "gesture",
        "happy",
        "men",
        "one",
        "raised"
      ],
      "\u{1F64B}\u200D\u2640\uFE0F": [
        "woman_raising_hand",
        "female",
        "girl",
        "woman",
        "gesture",
        "happy",
        "one",
        "raised",
        "women"
      ],
      "\u{1F9CF}": [
        "deaf_person",
        "accessibility",
        "ear",
        "hear"
      ],
      "\u{1F9CF}\u200D\u2642\uFE0F": [
        "deaf_man",
        "accessibility",
        "male",
        "men"
      ],
      "\u{1F9CF}\u200D\u2640\uFE0F": [
        "deaf_woman",
        "accessibility",
        "female",
        "women"
      ],
      "\u{1F647}": [
        "person_bowing",
        "respectiful",
        "apology",
        "bow",
        "boy",
        "cute",
        "deeply",
        "dogeza",
        "gesture",
        "man",
        "massage",
        "respect",
        "sorry",
        "thanks"
      ],
      "\u{1F647}\u200D\u2642\uFE0F": [
        "man_bowing",
        "man",
        "male",
        "boy",
        "apology",
        "bow",
        "deeply",
        "favor",
        "gesture",
        "men",
        "respect",
        "sorry",
        "thanks"
      ],
      "\u{1F647}\u200D\u2640\uFE0F": [
        "woman_bowing",
        "woman",
        "female",
        "girl",
        "apology",
        "bow",
        "deeply",
        "favor",
        "gesture",
        "respect",
        "sorry",
        "thanks",
        "women"
      ],
      "\u{1F926}": [
        "person_facepalming",
        "disappointed",
        "disbelief",
        "exasperation",
        "face",
        "facepalm",
        "head",
        "hitting",
        "palm",
        "picard",
        "smh"
      ],
      "\u{1F926}\u200D\u2642\uFE0F": [
        "man_facepalming",
        "man",
        "male",
        "boy",
        "disbelief",
        "exasperation",
        "face",
        "facepalm",
        "men",
        "palm"
      ],
      "\u{1F926}\u200D\u2640\uFE0F": [
        "woman_facepalming",
        "woman",
        "female",
        "girl",
        "disbelief",
        "exasperation",
        "face",
        "facepalm",
        "palm",
        "women"
      ],
      "\u{1F937}": [
        "person_shrugging",
        "regardless",
        "doubt",
        "ignorance",
        "indifference",
        "shrug",
        "shruggie",
        "\xAF\\"
      ],
      "\u{1F937}\u200D\u2642\uFE0F": [
        "man_shrugging",
        "man",
        "male",
        "boy",
        "confused",
        "indifferent",
        "doubt",
        "ignorance",
        "indifference",
        "men",
        "shrug"
      ],
      "\u{1F937}\u200D\u2640\uFE0F": [
        "woman_shrugging",
        "woman",
        "female",
        "girl",
        "confused",
        "indifferent",
        "doubt",
        "ignorance",
        "indifference",
        "shrug",
        "women"
      ],
      "\u{1F9D1}\u200D\u2695\uFE0F": [
        "health_worker",
        "hospital",
        "dentist",
        "doctor",
        "healthcare",
        "md",
        "nurse",
        "physician",
        "professional",
        "therapist"
      ],
      "\u{1F468}\u200D\u2695\uFE0F": [
        "man_health_worker",
        "doctor",
        "nurse",
        "therapist",
        "healthcare",
        "man",
        "human",
        "dentist",
        "male",
        "md",
        "men",
        "physician",
        "professional"
      ],
      "\u{1F469}\u200D\u2695\uFE0F": [
        "woman_health_worker",
        "doctor",
        "nurse",
        "therapist",
        "healthcare",
        "woman",
        "human",
        "dentist",
        "female",
        "md",
        "physician",
        "professional",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F393}": [
        "student",
        "learn",
        "education",
        "graduate",
        "pupil",
        "school"
      ],
      "\u{1F468}\u200D\u{1F393}": [
        "man_student",
        "graduate",
        "man",
        "human",
        "education",
        "graduation",
        "male",
        "men",
        "pupil",
        "school"
      ],
      "\u{1F469}\u200D\u{1F393}": [
        "woman_student",
        "graduate",
        "woman",
        "human",
        "education",
        "female",
        "graduation",
        "pupil",
        "school",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F3EB}": [
        "teacher",
        "professor",
        "education",
        "educator",
        "instructor"
      ],
      "\u{1F468}\u200D\u{1F3EB}": [
        "man_teacher",
        "instructor",
        "professor",
        "man",
        "human",
        "education",
        "educator",
        "male",
        "men",
        "school"
      ],
      "\u{1F469}\u200D\u{1F3EB}": [
        "woman_teacher",
        "instructor",
        "professor",
        "woman",
        "human",
        "education",
        "educator",
        "female",
        "school",
        "women"
      ],
      "\u{1F9D1}\u200D\u2696\uFE0F": [
        "judge",
        "law",
        "court",
        "justice",
        "scales"
      ],
      "\u{1F468}\u200D\u2696\uFE0F": [
        "man_judge",
        "justice",
        "court",
        "man",
        "human",
        "law",
        "male",
        "men",
        "scales"
      ],
      "\u{1F469}\u200D\u2696\uFE0F": [
        "woman_judge",
        "justice",
        "court",
        "woman",
        "human",
        "female",
        "law",
        "scales",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F33E}": [
        "farmer",
        "crops",
        "farm",
        "farming",
        "gardener",
        "rancher",
        "worker"
      ],
      "\u{1F468}\u200D\u{1F33E}": [
        "man_farmer",
        "rancher",
        "gardener",
        "man",
        "human",
        "farm",
        "farming",
        "male",
        "men",
        "worker"
      ],
      "\u{1F469}\u200D\u{1F33E}": [
        "woman_farmer",
        "rancher",
        "gardener",
        "woman",
        "human",
        "farm",
        "farming",
        "female",
        "women",
        "worker"
      ],
      "\u{1F9D1}\u200D\u{1F373}": [
        "cook",
        "food",
        "kitchen",
        "culinary",
        "chef",
        "cooking",
        "service"
      ],
      "\u{1F468}\u200D\u{1F373}": [
        "man_cook",
        "chef",
        "man",
        "human",
        "cooking",
        "food",
        "male",
        "men",
        "service"
      ],
      "\u{1F469}\u200D\u{1F373}": [
        "woman_cook",
        "chef",
        "woman",
        "human",
        "cooking",
        "female",
        "food",
        "service",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F527}": [
        "mechanic",
        "worker",
        "technician",
        "electrician",
        "person",
        "plumber",
        "repair",
        "tradesperson"
      ],
      "\u{1F468}\u200D\u{1F527}": [
        "man_mechanic",
        "plumber",
        "man",
        "human",
        "wrench",
        "electrician",
        "male",
        "men",
        "person",
        "repair",
        "tradesperson"
      ],
      "\u{1F469}\u200D\u{1F527}": [
        "woman_mechanic",
        "plumber",
        "woman",
        "human",
        "wrench",
        "electrician",
        "female",
        "person",
        "repair",
        "tradesperson",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F3ED}": [
        "factory_worker",
        "labor",
        "assembly",
        "industrial",
        "welder"
      ],
      "\u{1F468}\u200D\u{1F3ED}": [
        "man_factory_worker",
        "assembly",
        "industrial",
        "man",
        "human",
        "male",
        "men",
        "welder"
      ],
      "\u{1F469}\u200D\u{1F3ED}": [
        "woman_factory_worker",
        "assembly",
        "industrial",
        "woman",
        "human",
        "female",
        "welder",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F4BC}": [
        "office_worker",
        "business",
        "accountant",
        "adviser",
        "analyst",
        "architect",
        "banker",
        "clerk",
        "manager"
      ],
      "\u{1F468}\u200D\u{1F4BC}": [
        "man_office_worker",
        "business",
        "manager",
        "man",
        "human",
        "accountant",
        "adviser",
        "analyst",
        "architect",
        "banker",
        "businessman",
        "ceo",
        "clerk",
        "male",
        "men"
      ],
      "\u{1F469}\u200D\u{1F4BC}": [
        "woman_office_worker",
        "business",
        "manager",
        "woman",
        "human",
        "accountant",
        "adviser",
        "analyst",
        "architect",
        "banker",
        "businesswoman",
        "ceo",
        "clerk",
        "female",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F52C}": [
        "scientist",
        "chemistry",
        "biologist",
        "chemist",
        "engineer",
        "lab",
        "mathematician",
        "physicist",
        "technician"
      ],
      "\u{1F468}\u200D\u{1F52C}": [
        "man_scientist",
        "biologist",
        "chemist",
        "engineer",
        "physicist",
        "man",
        "human",
        "lab",
        "male",
        "mathematician",
        "men",
        "research",
        "technician"
      ],
      "\u{1F469}\u200D\u{1F52C}": [
        "woman_scientist",
        "biologist",
        "chemist",
        "engineer",
        "physicist",
        "woman",
        "human",
        "female",
        "lab",
        "mathematician",
        "research",
        "technician",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F4BB}": [
        "technologist",
        "computer",
        "coder",
        "engineer",
        "laptop",
        "software",
        "technology",
        "developer"
      ],
      "\u{1F468}\u200D\u{1F4BB}": [
        "man_technologist",
        "coder",
        "developer",
        "engineer",
        "programmer",
        "software",
        "man",
        "human",
        "laptop",
        "computer",
        "blogger",
        "male",
        "men",
        "technology"
      ],
      "\u{1F469}\u200D\u{1F4BB}": [
        "woman_technologist",
        "coder",
        "developer",
        "engineer",
        "programmer",
        "software",
        "woman",
        "human",
        "laptop",
        "computer",
        "blogger",
        "female",
        "technology",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F3A4}": [
        "singer",
        "song",
        "artist",
        "performer",
        "actor",
        "entertainer",
        "music",
        "musician",
        "rock",
        "rocker",
        "rockstar",
        "star"
      ],
      "\u{1F468}\u200D\u{1F3A4}": [
        "man_singer",
        "rockstar",
        "entertainer",
        "man",
        "human",
        "actor",
        "aladdin",
        "bowie",
        "male",
        "men",
        "music",
        "musician",
        "rock",
        "rocker",
        "sane",
        "star"
      ],
      "\u{1F469}\u200D\u{1F3A4}": [
        "woman_singer",
        "rockstar",
        "entertainer",
        "woman",
        "human",
        "actor",
        "female",
        "music",
        "musician",
        "rock",
        "rocker",
        "star",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F3A8}": [
        "artist",
        "painting",
        "draw",
        "creativity",
        "art",
        "paint",
        "painter",
        "palette"
      ],
      "\u{1F468}\u200D\u{1F3A8}": [
        "man_artist",
        "painter",
        "man",
        "human",
        "art",
        "male",
        "men",
        "paint",
        "palette"
      ],
      "\u{1F469}\u200D\u{1F3A8}": [
        "woman_artist",
        "painter",
        "woman",
        "human",
        "art",
        "female",
        "paint",
        "palette",
        "women"
      ],
      "\u{1F9D1}\u200D\u2708\uFE0F": [
        "pilot",
        "fly",
        "plane",
        "airplane",
        "aviation",
        "aviator"
      ],
      "\u{1F468}\u200D\u2708\uFE0F": [
        "man_pilot",
        "aviator",
        "plane",
        "man",
        "human",
        "airplane",
        "aviation",
        "male",
        "men"
      ],
      "\u{1F469}\u200D\u2708\uFE0F": [
        "woman_pilot",
        "aviator",
        "plane",
        "woman",
        "human",
        "airplane",
        "aviation",
        "female",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F680}": [
        "astronaut",
        "outerspace",
        "moon",
        "planets",
        "rocket",
        "space",
        "stars"
      ],
      "\u{1F468}\u200D\u{1F680}": [
        "man_astronaut",
        "space",
        "rocket",
        "man",
        "human",
        "cosmonaut",
        "male",
        "men",
        "moon",
        "planets",
        "stars"
      ],
      "\u{1F469}\u200D\u{1F680}": [
        "woman_astronaut",
        "space",
        "rocket",
        "woman",
        "human",
        "cosmonaut",
        "female",
        "moon",
        "planets",
        "stars",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F692}": [
        "firefighter",
        "fire",
        "firetruck"
      ],
      "\u{1F468}\u200D\u{1F692}": [
        "man_firefighter",
        "fireman",
        "man",
        "human",
        "fire",
        "firetruck",
        "male",
        "men"
      ],
      "\u{1F469}\u200D\u{1F692}": [
        "woman_firefighter",
        "fireman",
        "woman",
        "human",
        "female",
        "fire",
        "firetruck",
        "women"
      ],
      "\u{1F46E}": [
        "police_officer",
        "cop",
        "law",
        "policeman",
        "policewoman"
      ],
      "\u{1F46E}\u200D\u2642\uFE0F": [
        "man_police_officer",
        "man",
        "police",
        "law",
        "legal",
        "enforcement",
        "arrest",
        "911",
        "cop",
        "male",
        "men",
        "policeman"
      ],
      "\u{1F46E}\u200D\u2640\uFE0F": [
        "woman_police_officer",
        "woman",
        "police",
        "law",
        "legal",
        "enforcement",
        "arrest",
        "911",
        "female",
        "cop",
        "policewoman",
        "women"
      ],
      "\u{1F575}\uFE0F": [
        "detective",
        "human",
        "spy",
        "eye",
        "or",
        "private",
        "sleuth"
      ],
      "\u{1F575}\uFE0F\u200D\u2642\uFE0F": [
        "man_detective",
        "crime",
        "male",
        "men",
        "sleuth",
        "spy"
      ],
      "\u{1F575}\uFE0F\u200D\u2640\uFE0F": [
        "woman_detective",
        "human",
        "spy",
        "detective",
        "female",
        "woman",
        "sleuth",
        "women"
      ],
      "\u{1F482}": [
        "guard",
        "protect",
        "british",
        "guardsman"
      ],
      "\u{1F482}\u200D\u2642\uFE0F": [
        "man_guard",
        "uk",
        "gb",
        "british",
        "male",
        "guy",
        "royal",
        "guardsman",
        "men"
      ],
      "\u{1F482}\u200D\u2640\uFE0F": [
        "woman_guard",
        "uk",
        "gb",
        "british",
        "female",
        "royal",
        "woman",
        "guardsman",
        "guardswoman",
        "women"
      ],
      "\u{1F477}": [
        "construction_worker",
        "labor",
        "build",
        "builder",
        "face",
        "hard",
        "hat",
        "helmet",
        "safety",
        "add_ci",
        "update_ci"
      ],
      "\u{1F477}\u200D\u2642\uFE0F": [
        "man_construction_worker",
        "male",
        "human",
        "wip",
        "guy",
        "build",
        "construction",
        "worker",
        "labor",
        "helmet",
        "men"
      ],
      "\u{1F477}\u200D\u2640\uFE0F": [
        "woman_construction_worker",
        "female",
        "human",
        "wip",
        "build",
        "construction",
        "worker",
        "labor",
        "woman",
        "helmet",
        "women"
      ],
      "\u{1F934}": [
        "prince",
        "boy",
        "man",
        "male",
        "crown",
        "royal",
        "king",
        "fairy",
        "fantasy",
        "men",
        "tale"
      ],
      "\u{1F478}": [
        "princess",
        "girl",
        "woman",
        "female",
        "blond",
        "crown",
        "royal",
        "queen",
        "blonde",
        "fairy",
        "fantasy",
        "tale",
        "tiara",
        "women"
      ],
      "\u{1F473}": [
        "person_wearing_turban",
        "headdress",
        "arab",
        "man",
        "muslim",
        "sikh"
      ],
      "\u{1F473}\u200D\u2642\uFE0F": [
        "man_wearing_turban",
        "male",
        "indian",
        "hinduism",
        "arabs",
        "men"
      ],
      "\u{1F473}\u200D\u2640\uFE0F": [
        "woman_wearing_turban",
        "female",
        "indian",
        "hinduism",
        "arabs",
        "woman",
        "women"
      ],
      "\u{1F472}": [
        "man_with_skullcap",
        "male",
        "boy",
        "chinese",
        "asian",
        "cap",
        "gua",
        "hat",
        "mao",
        "person",
        "pi"
      ],
      "\u{1F9D5}": [
        "woman_with_headscarf",
        "female",
        "hijab",
        "mantilla",
        "tichel"
      ],
      "\u{1F935}": [
        "man_in_tuxedo",
        "couple",
        "marriage",
        "wedding",
        "groom",
        "male",
        "men",
        "person",
        "suit"
      ],
      "\u{1F470}": [
        "bride_with_veil",
        "couple",
        "marriage",
        "wedding",
        "woman",
        "bride",
        "person"
      ],
      "\u{1F930}": [
        "pregnant_woman",
        "baby",
        "female",
        "pregnancy",
        "pregnant\xA0lady",
        "women"
      ],
      "\u{1F931}": [
        "breast_feeding",
        "nursing",
        "baby",
        "breastfeeding",
        "child",
        "female",
        "infant",
        "milk",
        "mother",
        "woman",
        "women"
      ],
      "\u{1F47C}": [
        "baby_angel",
        "heaven",
        "wings",
        "halo",
        "cherub",
        "cupid",
        "face",
        "fairy",
        "fantasy",
        "putto",
        "tale"
      ],
      "\u{1F385}": [
        "santa_claus",
        "festival",
        "man",
        "male",
        "xmas",
        "father christmas",
        "activity",
        "celebration",
        "men",
        "nicholas",
        "saint",
        "sinterklaas"
      ],
      "\u{1F936}": [
        "mrs_claus",
        "woman",
        "female",
        "xmas",
        "mother christmas",
        "activity",
        "celebration",
        "mrs.",
        "santa",
        "women"
      ],
      "\u{1F9B8}": [
        "superhero",
        "marvel",
        "fantasy",
        "good",
        "hero",
        "heroine",
        "superpower",
        "superpowers"
      ],
      "\u{1F9B8}\u200D\u2642\uFE0F": [
        "man_superhero",
        "man",
        "male",
        "good",
        "hero",
        "superpowers",
        "fantasy",
        "men",
        "superpower"
      ],
      "\u{1F9B8}\u200D\u2640\uFE0F": [
        "woman_superhero",
        "woman",
        "female",
        "good",
        "heroine",
        "superpowers",
        "fantasy",
        "hero",
        "superpower",
        "women"
      ],
      "\u{1F9B9}": [
        "supervillain",
        "marvel",
        "bad",
        "criminal",
        "evil",
        "fantasy",
        "superpower",
        "superpowers",
        "villain"
      ],
      "\u{1F9B9}\u200D\u2642\uFE0F": [
        "man_supervillain",
        "man",
        "male",
        "evil",
        "bad",
        "criminal",
        "hero",
        "superpowers",
        "fantasy",
        "men",
        "superpower",
        "villain"
      ],
      "\u{1F9B9}\u200D\u2640\uFE0F": [
        "woman_supervillain",
        "woman",
        "female",
        "evil",
        "bad",
        "criminal",
        "heroine",
        "superpowers",
        "fantasy",
        "superpower",
        "villain",
        "women"
      ],
      "\u{1F9D9}": [
        "mage",
        "magic",
        "fantasy",
        "sorcerer",
        "sorceress",
        "witch",
        "wizard"
      ],
      "\u{1F9D9}\u200D\u2642\uFE0F": [
        "man_mage",
        "man",
        "male",
        "mage",
        "sorcerer",
        "fantasy",
        "men",
        "wizard"
      ],
      "\u{1F9D9}\u200D\u2640\uFE0F": [
        "woman_mage",
        "woman",
        "female",
        "mage",
        "witch",
        "fantasy",
        "sorceress",
        "wizard",
        "women"
      ],
      "\u{1F9DA}": [
        "fairy",
        "wings",
        "magical",
        "fantasy",
        "oberon",
        "puck",
        "titania"
      ],
      "\u{1F9DA}\u200D\u2642\uFE0F": [
        "man_fairy",
        "man",
        "male",
        "fantasy",
        "men",
        "oberon",
        "puck"
      ],
      "\u{1F9DA}\u200D\u2640\uFE0F": [
        "woman_fairy",
        "woman",
        "female",
        "fantasy",
        "titania",
        "wings",
        "women"
      ],
      "\u{1F9DB}": [
        "vampire",
        "blood",
        "twilight",
        "dracula",
        "fantasy",
        "undead"
      ],
      "\u{1F9DB}\u200D\u2642\uFE0F": [
        "man_vampire",
        "man",
        "male",
        "dracula",
        "fantasy",
        "men",
        "undead"
      ],
      "\u{1F9DB}\u200D\u2640\uFE0F": [
        "woman_vampire",
        "woman",
        "female",
        "fantasy",
        "undead",
        "unded",
        "women"
      ],
      "\u{1F9DC}": [
        "merperson",
        "sea",
        "fantasy",
        "merboy",
        "mergirl",
        "mermaid",
        "merman",
        "merwoman"
      ],
      "\u{1F9DC}\u200D\u2642\uFE0F": [
        "merman",
        "man",
        "male",
        "triton",
        "fantasy",
        "men",
        "mermaid"
      ],
      "\u{1F9DC}\u200D\u2640\uFE0F": [
        "mermaid",
        "woman",
        "female",
        "merwoman",
        "ariel",
        "fantasy",
        "women"
      ],
      "\u{1F9DD}": [
        "elf",
        "magical",
        "ears",
        "fantasy",
        "legolas",
        "pointed"
      ],
      "\u{1F9DD}\u200D\u2642\uFE0F": [
        "man_elf",
        "man",
        "male",
        "ears",
        "fantasy",
        "magical",
        "men",
        "pointed"
      ],
      "\u{1F9DD}\u200D\u2640\uFE0F": [
        "woman_elf",
        "woman",
        "female",
        "ears",
        "fantasy",
        "magical",
        "pointed",
        "women"
      ],
      "\u{1F9DE}": [
        "genie",
        "magical",
        "wishes",
        "djinn",
        "djinni",
        "fantasy",
        "jinni"
      ],
      "\u{1F9DE}\u200D\u2642\uFE0F": [
        "man_genie",
        "man",
        "male",
        "djinn",
        "fantasy",
        "men"
      ],
      "\u{1F9DE}\u200D\u2640\uFE0F": [
        "woman_genie",
        "woman",
        "female",
        "djinn",
        "fantasy",
        "women"
      ],
      "\u{1F9DF}": [
        "zombie",
        "dead",
        "fantasy",
        "undead",
        "walking"
      ],
      "\u{1F9DF}\u200D\u2642\uFE0F": [
        "man_zombie",
        "man",
        "male",
        "dracula",
        "undead",
        "walking dead",
        "fantasy",
        "men"
      ],
      "\u{1F9DF}\u200D\u2640\uFE0F": [
        "woman_zombie",
        "woman",
        "female",
        "undead",
        "walking dead",
        "fantasy",
        "women"
      ],
      "\u{1F486}": [
        "person_getting_massage",
        "relax",
        "face",
        "head",
        "massaging",
        "salon",
        "spa"
      ],
      "\u{1F486}\u200D\u2642\uFE0F": [
        "man_getting_massage",
        "male",
        "boy",
        "man",
        "head",
        "face",
        "men",
        "salon",
        "spa"
      ],
      "\u{1F486}\u200D\u2640\uFE0F": [
        "woman_getting_massage",
        "female",
        "girl",
        "woman",
        "head",
        "face",
        "salon",
        "spa",
        "women"
      ],
      "\u{1F487}": [
        "person_getting_haircut",
        "hairstyle",
        "barber",
        "beauty",
        "cutting",
        "hair",
        "hairdresser",
        "parlor"
      ],
      "\u{1F487}\u200D\u2642\uFE0F": [
        "man_getting_haircut",
        "male",
        "boy",
        "man",
        "barber",
        "beauty",
        "men",
        "parlor"
      ],
      "\u{1F487}\u200D\u2640\uFE0F": [
        "woman_getting_haircut",
        "female",
        "girl",
        "woman",
        "barber",
        "beauty",
        "parlor",
        "women"
      ],
      "\u{1F6B6}": [
        "person_walking",
        "move",
        "hike",
        "pedestrian",
        "walk",
        "walker"
      ],
      "\u{1F6B6}\u200D\u2642\uFE0F": [
        "man_walking",
        "human",
        "feet",
        "steps",
        "hike",
        "male",
        "men",
        "pedestrian",
        "walk"
      ],
      "\u{1F6B6}\u200D\u2640\uFE0F": [
        "woman_walking",
        "human",
        "feet",
        "steps",
        "woman",
        "female",
        "hike",
        "pedestrian",
        "walk",
        "women"
      ],
      "\u{1F9CD}": [
        "person_standing",
        "still",
        "stand"
      ],
      "\u{1F9CD}\u200D\u2642\uFE0F": [
        "man_standing",
        "still",
        "male",
        "men",
        "stand"
      ],
      "\u{1F9CD}\u200D\u2640\uFE0F": [
        "woman_standing",
        "still",
        "female",
        "stand",
        "women"
      ],
      "\u{1F9CE}": [
        "person_kneeling",
        "pray",
        "respectful",
        "kneel"
      ],
      "\u{1F9CE}\u200D\u2642\uFE0F": [
        "man_kneeling",
        "pray",
        "respectful",
        "kneel",
        "male",
        "men"
      ],
      "\u{1F9CE}\u200D\u2640\uFE0F": [
        "woman_kneeling",
        "respectful",
        "pray",
        "female",
        "kneel",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F9AF}": [
        "person_with_probing_cane",
        "blind",
        "accessibility",
        "white"
      ],
      "\u{1F468}\u200D\u{1F9AF}": [
        "man_with_probing_cane",
        "blind",
        "accessibility",
        "male",
        "men",
        "white"
      ],
      "\u{1F469}\u200D\u{1F9AF}": [
        "woman_with_probing_cane",
        "blind",
        "accessibility",
        "female",
        "white",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F9BC}": [
        "person_in_motorized_wheelchair",
        "disability",
        "accessibility"
      ],
      "\u{1F468}\u200D\u{1F9BC}": [
        "man_in_motorized_wheelchair",
        "disability",
        "accessibility",
        "male",
        "men"
      ],
      "\u{1F469}\u200D\u{1F9BC}": [
        "woman_in_motorized_wheelchair",
        "disability",
        "accessibility",
        "female",
        "women"
      ],
      "\u{1F9D1}\u200D\u{1F9BD}": [
        "person_in_manual_wheelchair",
        "disability",
        "accessibility"
      ],
      "\u{1F468}\u200D\u{1F9BD}": [
        "man_in_manual_wheelchair",
        "disability",
        "accessibility",
        "male",
        "men"
      ],
      "\u{1F469}\u200D\u{1F9BD}": [
        "woman_in_manual_wheelchair",
        "disability",
        "accessibility",
        "female",
        "women"
      ],
      "\u{1F3C3}": [
        "person_running",
        "move",
        "exercise",
        "jogging",
        "marathon",
        "run",
        "runner",
        "workout"
      ],
      "\u{1F3C3}\u200D\u2642\uFE0F": [
        "man_running",
        "man",
        "walking",
        "exercise",
        "race",
        "running",
        "male",
        "marathon",
        "men",
        "racing",
        "runner",
        "workout"
      ],
      "\u{1F3C3}\u200D\u2640\uFE0F": [
        "woman_running",
        "woman",
        "walking",
        "exercise",
        "race",
        "running",
        "female",
        "boy",
        "marathon",
        "racing",
        "runner",
        "women",
        "workout"
      ],
      "\u{1F483}": [
        "woman_dancing",
        "female",
        "girl",
        "woman",
        "fun",
        "dance",
        "dancer",
        "dress",
        "red",
        "salsa",
        "women"
      ],
      "\u{1F57A}": [
        "man_dancing",
        "male",
        "boy",
        "fun",
        "dancer",
        "dance",
        "disco",
        "men"
      ],
      "\u{1F574}\uFE0F": [
        "man_in_suit_levitating",
        "suit",
        "business",
        "levitate",
        "hover",
        "jump",
        "boy",
        "hovering",
        "jabsco",
        "male",
        "men",
        "person",
        "rude",
        "walt"
      ],
      "\u{1F46F}": [
        "people_with_bunny_ears",
        "perform",
        "costume",
        "dancer",
        "dancing",
        "ear",
        "partying",
        "wearing",
        "women"
      ],
      "\u{1F46F}\u200D\u2642\uFE0F": [
        "men_with_bunny_ears",
        "male",
        "bunny",
        "men",
        "boys",
        "dancer",
        "dancing",
        "ear",
        "man",
        "partying",
        "wearing"
      ],
      "\u{1F46F}\u200D\u2640\uFE0F": [
        "women_with_bunny_ears",
        "female",
        "bunny",
        "women",
        "girls",
        "dancer",
        "dancing",
        "ear",
        "partying",
        "people",
        "wearing"
      ],
      "\u{1F9D6}": [
        "person_in_steamy_room",
        "relax",
        "spa",
        "hamam",
        "sauna",
        "steam",
        "steambath"
      ],
      "\u{1F9D6}\u200D\u2642\uFE0F": [
        "man_in_steamy_room",
        "male",
        "man",
        "spa",
        "steamroom",
        "sauna",
        "hamam",
        "men",
        "steam",
        "steambath"
      ],
      "\u{1F9D6}\u200D\u2640\uFE0F": [
        "woman_in_steamy_room",
        "female",
        "woman",
        "spa",
        "steamroom",
        "sauna",
        "hamam",
        "steam",
        "steambath",
        "women"
      ],
      "\u{1F9D7}": [
        "person_climbing",
        "sport",
        "bouldering",
        "climber",
        "rock"
      ],
      "\u{1F9D7}\u200D\u2642\uFE0F": [
        "man_climbing",
        "sports",
        "hobby",
        "man",
        "male",
        "rock",
        "bouldering",
        "climber",
        "men"
      ],
      "\u{1F9D7}\u200D\u2640\uFE0F": [
        "woman_climbing",
        "sports",
        "hobby",
        "woman",
        "female",
        "rock",
        "bouldering",
        "climber",
        "women"
      ],
      "\u{1F93A}": [
        "person_fencing",
        "sports",
        "fencing",
        "sword",
        "fencer"
      ],
      "\u{1F3C7}": [
        "horse_racing",
        "animal",
        "betting",
        "competition",
        "gambling",
        "luck",
        "jockey",
        "race",
        "racehorse"
      ],
      "\u26F7\uFE0F": [
        "skier",
        "sports",
        "winter",
        "snow",
        "ski"
      ],
      "\u{1F3C2}": [
        "snowboarder",
        "sports",
        "winter",
        "ski",
        "snow",
        "snowboard",
        "snowboarding"
      ],
      "\u{1F3CC}\uFE0F": [
        "person_golfing",
        "sports",
        "business",
        "ball",
        "club",
        "golf",
        "golfer"
      ],
      "\u{1F3CC}\uFE0F\u200D\u2642\uFE0F": [
        "man_golfing",
        "sport",
        "ball",
        "golf",
        "golfer",
        "male",
        "men"
      ],
      "\u{1F3CC}\uFE0F\u200D\u2640\uFE0F": [
        "woman_golfing",
        "sports",
        "business",
        "woman",
        "female",
        "ball",
        "golf",
        "golfer",
        "women"
      ],
      "\u{1F3C4}": [
        "person_surfing",
        "sport",
        "sea",
        "surf",
        "surfer"
      ],
      "\u{1F3C4}\u200D\u2642\uFE0F": [
        "man_surfing",
        "sports",
        "ocean",
        "sea",
        "summer",
        "beach",
        "male",
        "men",
        "surfer"
      ],
      "\u{1F3C4}\u200D\u2640\uFE0F": [
        "woman_surfing",
        "sports",
        "ocean",
        "sea",
        "summer",
        "beach",
        "woman",
        "female",
        "surfer",
        "women"
      ],
      "\u{1F6A3}": [
        "person_rowing_boat",
        "sport",
        "move",
        "paddles",
        "rowboat",
        "vehicle"
      ],
      "\u{1F6A3}\u200D\u2642\uFE0F": [
        "man_rowing_boat",
        "sports",
        "hobby",
        "water",
        "ship",
        "male",
        "men",
        "rowboat",
        "vehicle"
      ],
      "\u{1F6A3}\u200D\u2640\uFE0F": [
        "woman_rowing_boat",
        "sports",
        "hobby",
        "water",
        "ship",
        "woman",
        "female",
        "rowboat",
        "vehicle",
        "women"
      ],
      "\u{1F3CA}": [
        "person_swimming",
        "sport",
        "pool",
        "swim",
        "swimmer"
      ],
      "\u{1F3CA}\u200D\u2642\uFE0F": [
        "man_swimming",
        "sports",
        "exercise",
        "human",
        "athlete",
        "water",
        "summer",
        "male",
        "men",
        "swim",
        "swimmer"
      ],
      "\u{1F3CA}\u200D\u2640\uFE0F": [
        "woman_swimming",
        "sports",
        "exercise",
        "human",
        "athlete",
        "water",
        "summer",
        "woman",
        "female",
        "swim",
        "swimmer",
        "women"
      ],
      "\u26F9\uFE0F": [
        "person_bouncing_ball",
        "sports",
        "human",
        "basketball",
        "player"
      ],
      "\u26F9\uFE0F\u200D\u2642\uFE0F": [
        "man_bouncing_ball",
        "sport",
        "basketball",
        "male",
        "men",
        "player"
      ],
      "\u26F9\uFE0F\u200D\u2640\uFE0F": [
        "woman_bouncing_ball",
        "sports",
        "human",
        "woman",
        "female",
        "basketball",
        "player",
        "women"
      ],
      "\u{1F3CB}\uFE0F": [
        "person_lifting_weights",
        "sports",
        "training",
        "exercise",
        "bodybuilder",
        "gym",
        "lifter",
        "weight",
        "weightlifter",
        "workout"
      ],
      "\u{1F3CB}\uFE0F\u200D\u2642\uFE0F": [
        "man_lifting_weights",
        "sport",
        "gym",
        "lifter",
        "male",
        "men",
        "weight",
        "weightlifter",
        "workout"
      ],
      "\u{1F3CB}\uFE0F\u200D\u2640\uFE0F": [
        "woman_lifting_weights",
        "sports",
        "training",
        "exercise",
        "woman",
        "female",
        "gym",
        "lifter",
        "weight",
        "weightlifter",
        "women",
        "workout"
      ],
      "\u{1F6B4}": [
        "person_biking",
        "bicycle",
        "bike",
        "cyclist",
        "sport",
        "move",
        "bicyclist"
      ],
      "\u{1F6B4}\u200D\u2642\uFE0F": [
        "man_biking",
        "bicycle",
        "bike",
        "cyclist",
        "sports",
        "exercise",
        "hipster",
        "bicyclist",
        "male",
        "men"
      ],
      "\u{1F6B4}\u200D\u2640\uFE0F": [
        "woman_biking",
        "bicycle",
        "bike",
        "cyclist",
        "sports",
        "exercise",
        "hipster",
        "woman",
        "female",
        "bicyclist",
        "women"
      ],
      "\u{1F6B5}": [
        "person_mountain_biking",
        "bicycle",
        "bike",
        "cyclist",
        "sport",
        "move",
        "bicyclist",
        "biker"
      ],
      "\u{1F6B5}\u200D\u2642\uFE0F": [
        "man_mountain_biking",
        "bicycle",
        "bike",
        "cyclist",
        "transportation",
        "sports",
        "human",
        "race",
        "bicyclist",
        "biker",
        "male",
        "men"
      ],
      "\u{1F6B5}\u200D\u2640\uFE0F": [
        "woman_mountain_biking",
        "bicycle",
        "bike",
        "cyclist",
        "transportation",
        "sports",
        "human",
        "race",
        "woman",
        "female",
        "bicyclist",
        "biker",
        "women"
      ],
      "\u{1F938}": [
        "person_cartwheeling",
        "sport",
        "gymnastic",
        "cartwheel",
        "doing",
        "gymnast",
        "gymnastics"
      ],
      "\u{1F938}\u200D\u2642\uFE0F": [
        "man_cartwheeling",
        "gymnastics",
        "cartwheel",
        "doing",
        "male",
        "men"
      ],
      "\u{1F938}\u200D\u2640\uFE0F": [
        "woman_cartwheeling",
        "gymnastics",
        "cartwheel",
        "doing",
        "female",
        "women"
      ],
      "\u{1F93C}": [
        "people_wrestling",
        "sport",
        "wrestle",
        "wrestler",
        "wrestlers"
      ],
      "\u{1F93C}\u200D\u2642\uFE0F": [
        "men_wrestling",
        "sports",
        "wrestlers",
        "male",
        "man",
        "wrestle",
        "wrestler"
      ],
      "\u{1F93C}\u200D\u2640\uFE0F": [
        "women_wrestling",
        "sports",
        "wrestlers",
        "female",
        "woman",
        "wrestle",
        "wrestler"
      ],
      "\u{1F93D}": [
        "person_playing_water_polo",
        "sport"
      ],
      "\u{1F93D}\u200D\u2642\uFE0F": [
        "man_playing_water_polo",
        "sports",
        "pool",
        "male",
        "men"
      ],
      "\u{1F93D}\u200D\u2640\uFE0F": [
        "woman_playing_water_polo",
        "sports",
        "pool",
        "female",
        "women"
      ],
      "\u{1F93E}": [
        "person_playing_handball",
        "sport",
        "ball"
      ],
      "\u{1F93E}\u200D\u2642\uFE0F": [
        "man_playing_handball",
        "sports",
        "ball",
        "male",
        "men"
      ],
      "\u{1F93E}\u200D\u2640\uFE0F": [
        "woman_playing_handball",
        "sports",
        "ball",
        "female",
        "women"
      ],
      "\u{1F939}": [
        "person_juggling",
        "performance",
        "balance",
        "juggle",
        "juggler",
        "multitask",
        "skill"
      ],
      "\u{1F939}\u200D\u2642\uFE0F": [
        "man_juggling",
        "juggle",
        "balance",
        "skill",
        "multitask",
        "juggler",
        "male",
        "men"
      ],
      "\u{1F939}\u200D\u2640\uFE0F": [
        "woman_juggling",
        "juggle",
        "balance",
        "skill",
        "multitask",
        "female",
        "juggler",
        "women"
      ],
      "\u{1F9D8}": [
        "person_in_lotus_position",
        "meditate",
        "meditation",
        "serenity",
        "yoga"
      ],
      "\u{1F9D8}\u200D\u2642\uFE0F": [
        "man_in_lotus_position",
        "man",
        "male",
        "meditation",
        "yoga",
        "serenity",
        "zen",
        "mindfulness",
        "men"
      ],
      "\u{1F9D8}\u200D\u2640\uFE0F": [
        "woman_in_lotus_position",
        "woman",
        "female",
        "meditation",
        "yoga",
        "serenity",
        "zen",
        "mindfulness",
        "women"
      ],
      "\u{1F6C0}": [
        "person_taking_bath",
        "clean",
        "shower",
        "bathroom",
        "bathing",
        "bathtub",
        "hot"
      ],
      "\u{1F6CC}": [
        "person_in_bed",
        "bed",
        "rest",
        "accommodation",
        "hotel",
        "sleep",
        "sleeping"
      ],
      "\u{1F9D1}\u200D\u{1F91D}\u200D\u{1F9D1}": [
        "people_holding_hands",
        "friendship",
        "couple",
        "date",
        "gender",
        "hand",
        "hold",
        "inclusive",
        "neutral",
        "nonconforming"
      ],
      "\u{1F46D}": [
        "women_holding_hands",
        "pair",
        "friendship",
        "couple",
        "love",
        "like",
        "female",
        "people",
        "human",
        "date",
        "hand",
        "hold",
        "lesbian",
        "lgbt",
        "pride",
        "two",
        "woman"
      ],
      "\u{1F46B}": [
        "woman_and_man_holding_hands",
        "pair",
        "people",
        "human",
        "love",
        "date",
        "dating",
        "like",
        "affection",
        "valentines",
        "marriage",
        "couple",
        "female",
        "hand",
        "heterosexual",
        "hold",
        "male",
        "men",
        "straight",
        "women"
      ],
      "\u{1F46C}": [
        "men_holding_hands",
        "pair",
        "couple",
        "love",
        "like",
        "bromance",
        "friendship",
        "people",
        "human",
        "date",
        "gay",
        "hand",
        "hold",
        "lgbt",
        "male",
        "man",
        "pride",
        "two"
      ],
      "\u{1F48F}": [
        "kiss",
        "pair",
        "valentines",
        "love",
        "like",
        "dating",
        "marriage",
        "couple",
        "couplekiss",
        "female",
        "gender",
        "heart",
        "kissing",
        "male",
        "man",
        "men",
        "neutral",
        "romance",
        "woman",
        "women"
      ],
      "\u{1F469}\u200D\u2764\uFE0F\u200D\u{1F48B}\u200D\u{1F468}": [
        "kiss_woman_man",
        "love",
        "couple",
        "couplekiss",
        "female",
        "heart",
        "kissing",
        "male",
        "men",
        "romance",
        "women"
      ],
      "\u{1F468}\u200D\u2764\uFE0F\u200D\u{1F48B}\u200D\u{1F468}": [
        "kiss_man_man",
        "pair",
        "valentines",
        "love",
        "like",
        "dating",
        "marriage",
        "couple",
        "couplekiss",
        "gay",
        "heart",
        "kissing",
        "lgbt",
        "male",
        "men",
        "pride",
        "romance",
        "two"
      ],
      "\u{1F469}\u200D\u2764\uFE0F\u200D\u{1F48B}\u200D\u{1F469}": [
        "kiss_woman_woman",
        "pair",
        "valentines",
        "love",
        "like",
        "dating",
        "marriage",
        "couple",
        "couplekiss",
        "female",
        "heart",
        "kissing",
        "lesbian",
        "lgbt",
        "pride",
        "romance",
        "two",
        "women"
      ],
      "\u{1F491}": [
        "couple_with_heart",
        "pair",
        "love",
        "like",
        "affection",
        "human",
        "dating",
        "valentines",
        "marriage",
        "female",
        "gender",
        "loving",
        "male",
        "man",
        "men",
        "neutral",
        "romance",
        "woman",
        "women"
      ],
      "\u{1F469}\u200D\u2764\uFE0F\u200D\u{1F468}": [
        "couple_with_heart_woman_man",
        "love",
        "female",
        "male",
        "men",
        "romance",
        "women"
      ],
      "\u{1F468}\u200D\u2764\uFE0F\u200D\u{1F468}": [
        "couple_with_heart_man_man",
        "pair",
        "love",
        "like",
        "affection",
        "human",
        "dating",
        "valentines",
        "marriage",
        "gay",
        "lgbt",
        "male",
        "men",
        "pride",
        "romance",
        "two"
      ],
      "\u{1F469}\u200D\u2764\uFE0F\u200D\u{1F469}": [
        "couple_with_heart_woman_woman",
        "pair",
        "love",
        "like",
        "affection",
        "human",
        "dating",
        "valentines",
        "marriage",
        "female",
        "lesbian",
        "lgbt",
        "pride",
        "romance",
        "two",
        "women"
      ],
      "\u{1F46A}": [
        "family",
        "home",
        "parents",
        "child",
        "mom",
        "dad",
        "father",
        "mother",
        "people",
        "human",
        "boy",
        "female",
        "male",
        "man",
        "men",
        "woman",
        "women"
      ],
      "\u{1F468}\u200D\u{1F469}\u200D\u{1F466}": [
        "family_man_woman_boy",
        "love",
        "father",
        "mother",
        "son"
      ],
      "\u{1F468}\u200D\u{1F469}\u200D\u{1F467}": [
        "family_man_woman_girl",
        "home",
        "parents",
        "people",
        "human",
        "child",
        "daughter",
        "father",
        "female",
        "male",
        "men",
        "mother",
        "women"
      ],
      "\u{1F468}\u200D\u{1F469}\u200D\u{1F467}\u200D\u{1F466}": [
        "family_man_woman_girl_boy",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "daughter",
        "father",
        "female",
        "male",
        "men",
        "mother",
        "son",
        "women"
      ],
      "\u{1F468}\u200D\u{1F469}\u200D\u{1F466}\u200D\u{1F466}": [
        "family_man_woman_boy_boy",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "father",
        "female",
        "male",
        "men",
        "mother",
        "sons",
        "two",
        "women"
      ],
      "\u{1F468}\u200D\u{1F469}\u200D\u{1F467}\u200D\u{1F467}": [
        "family_man_woman_girl_girl",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "daughters",
        "father",
        "female",
        "male",
        "men",
        "mother",
        "two",
        "women"
      ],
      "\u{1F468}\u200D\u{1F468}\u200D\u{1F466}": [
        "family_man_man_boy",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "father",
        "fathers",
        "gay",
        "lgbt",
        "male",
        "men",
        "pride",
        "son",
        "two"
      ],
      "\u{1F468}\u200D\u{1F468}\u200D\u{1F467}": [
        "family_man_man_girl",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "daughter",
        "father",
        "fathers",
        "gay",
        "lgbt",
        "male",
        "men",
        "pride",
        "two"
      ],
      "\u{1F468}\u200D\u{1F468}\u200D\u{1F467}\u200D\u{1F466}": [
        "family_man_man_girl_boy",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "daughter",
        "father",
        "fathers",
        "gay",
        "lgbt",
        "male",
        "men",
        "pride",
        "son",
        "two"
      ],
      "\u{1F468}\u200D\u{1F468}\u200D\u{1F466}\u200D\u{1F466}": [
        "family_man_man_boy_boy",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "father",
        "fathers",
        "gay",
        "lgbt",
        "male",
        "men",
        "pride",
        "sons",
        "two"
      ],
      "\u{1F468}\u200D\u{1F468}\u200D\u{1F467}\u200D\u{1F467}": [
        "family_man_man_girl_girl",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "daughters",
        "father",
        "fathers",
        "gay",
        "lgbt",
        "male",
        "men",
        "pride",
        "two"
      ],
      "\u{1F469}\u200D\u{1F469}\u200D\u{1F466}": [
        "family_woman_woman_boy",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "female",
        "lesbian",
        "lgbt",
        "mother",
        "mothers",
        "pride",
        "son",
        "two",
        "women"
      ],
      "\u{1F469}\u200D\u{1F469}\u200D\u{1F467}": [
        "family_woman_woman_girl",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "daughter",
        "female",
        "lesbian",
        "lgbt",
        "mother",
        "mothers",
        "pride",
        "two",
        "women"
      ],
      "\u{1F469}\u200D\u{1F469}\u200D\u{1F467}\u200D\u{1F466}": [
        "family_woman_woman_girl_boy",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "daughter",
        "female",
        "lesbian",
        "lgbt",
        "mother",
        "mothers",
        "pride",
        "son",
        "two",
        "women"
      ],
      "\u{1F469}\u200D\u{1F469}\u200D\u{1F466}\u200D\u{1F466}": [
        "family_woman_woman_boy_boy",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "female",
        "lesbian",
        "lgbt",
        "mother",
        "mothers",
        "pride",
        "sons",
        "two",
        "women"
      ],
      "\u{1F469}\u200D\u{1F469}\u200D\u{1F467}\u200D\u{1F467}": [
        "family_woman_woman_girl_girl",
        "home",
        "parents",
        "people",
        "human",
        "children",
        "child",
        "daughters",
        "female",
        "lesbian",
        "lgbt",
        "mother",
        "mothers",
        "pride",
        "two",
        "women"
      ],
      "\u{1F468}\u200D\u{1F466}": [
        "family_man_boy",
        "home",
        "parent",
        "people",
        "human",
        "child",
        "father",
        "male",
        "men",
        "son"
      ],
      "\u{1F468}\u200D\u{1F466}\u200D\u{1F466}": [
        "family_man_boy_boy",
        "home",
        "parent",
        "people",
        "human",
        "children",
        "child",
        "father",
        "male",
        "men",
        "sons",
        "two"
      ],
      "\u{1F468}\u200D\u{1F467}": [
        "family_man_girl",
        "home",
        "parent",
        "people",
        "human",
        "child",
        "daughter",
        "father",
        "female",
        "male"
      ],
      "\u{1F468}\u200D\u{1F467}\u200D\u{1F466}": [
        "family_man_girl_boy",
        "home",
        "parent",
        "people",
        "human",
        "children",
        "child",
        "daughter",
        "father",
        "male",
        "men",
        "son"
      ],
      "\u{1F468}\u200D\u{1F467}\u200D\u{1F467}": [
        "family_man_girl_girl",
        "home",
        "parent",
        "people",
        "human",
        "children",
        "child",
        "daughters",
        "father",
        "female",
        "male",
        "two"
      ],
      "\u{1F469}\u200D\u{1F466}": [
        "family_woman_boy",
        "home",
        "parent",
        "people",
        "human",
        "child",
        "female",
        "mother",
        "son",
        "women"
      ],
      "\u{1F469}\u200D\u{1F466}\u200D\u{1F466}": [
        "family_woman_boy_boy",
        "home",
        "parent",
        "people",
        "human",
        "children",
        "child",
        "female",
        "mother",
        "sons",
        "two",
        "women"
      ],
      "\u{1F469}\u200D\u{1F467}": [
        "family_woman_girl",
        "home",
        "parent",
        "people",
        "human",
        "child",
        "daughter",
        "female",
        "mother",
        "women"
      ],
      "\u{1F469}\u200D\u{1F467}\u200D\u{1F466}": [
        "family_woman_girl_boy",
        "home",
        "parent",
        "people",
        "human",
        "children",
        "child",
        "daughter",
        "female",
        "male",
        "mother",
        "son"
      ],
      "\u{1F469}\u200D\u{1F467}\u200D\u{1F467}": [
        "family_woman_girl_girl",
        "home",
        "parent",
        "people",
        "human",
        "children",
        "child",
        "daughters",
        "female",
        "mother",
        "two",
        "women"
      ],
      "\u{1F5E3}\uFE0F": [
        "speaking_head",
        "user",
        "person",
        "human",
        "sing",
        "say",
        "talk",
        "face",
        "mansplaining",
        "shout",
        "shouting",
        "silhouette",
        "speak"
      ],
      "\u{1F464}": [
        "bust_in_silhouette",
        "user",
        "person",
        "human",
        "shadow"
      ],
      "\u{1F465}": [
        "busts_in_silhouette",
        "user",
        "person",
        "human",
        "group",
        "team",
        "bust",
        "people",
        "shadows",
        "silhouettes",
        "two",
        "users",
        "contributors"
      ],
      "\u{1F463}": [
        "footprints",
        "feet",
        "tracking",
        "walking",
        "beach",
        "body",
        "clothing",
        "footprint",
        "footsteps",
        "print",
        "tracks"
      ],
      "\u{1F435}": [
        "monkey_face",
        "animal",
        "nature",
        "circus",
        "head"
      ],
      "\u{1F412}": [
        "monkey",
        "animal",
        "nature",
        "banana",
        "circus",
        "cheeky"
      ],
      "\u{1F98D}": [
        "gorilla",
        "animal",
        "nature",
        "circus"
      ],
      "\u{1F9A7}": [
        "orangutan",
        "animal",
        "ape"
      ],
      "\u{1F436}": [
        "dog_face",
        "animal",
        "friend",
        "nature",
        "woof",
        "puppy",
        "pet",
        "faithful"
      ],
      "\u{1F415}": [
        "dog",
        "animal",
        "nature",
        "friend",
        "doge",
        "pet",
        "faithful",
        "dog2",
        "doggo"
      ],
      "\u{1F9AE}": [
        "guide_dog",
        "animal",
        "blind",
        "accessibility",
        "eye",
        "seeing"
      ],
      "\u{1F415}\u200D\u{1F9BA}": [
        "service_dog",
        "blind",
        "animal",
        "accessibility",
        "assistance"
      ],
      "\u{1F429}": [
        "poodle",
        "dog",
        "animal",
        "101",
        "nature",
        "pet",
        "miniature",
        "standard",
        "toy"
      ],
      "\u{1F43A}": [
        "wolf",
        "animal",
        "nature",
        "wild",
        "face"
      ],
      "\u{1F98A}": [
        "fox",
        "animal",
        "nature",
        "face"
      ],
      "\u{1F99D}": [
        "raccoon",
        "animal",
        "nature",
        "curious",
        "face",
        "sly"
      ],
      "\u{1F431}": [
        "cat_face",
        "animal",
        "meow",
        "nature",
        "pet",
        "kitten",
        "kitty"
      ],
      "\u{1F408}": [
        "cat",
        "animal",
        "meow",
        "pet",
        "cats",
        "cat2",
        "domestic",
        "feline",
        "housecat"
      ],
      "\u{1F981}": [
        "lion",
        "animal",
        "nature",
        "face",
        "leo",
        "zodiac"
      ],
      "\u{1F42F}": [
        "tiger_face",
        "animal",
        "cat",
        "danger",
        "wild",
        "nature",
        "roar",
        "cute"
      ],
      "\u{1F405}": [
        "tiger",
        "animal",
        "nature",
        "roar",
        "bengal",
        "tiger2"
      ],
      "\u{1F406}": [
        "leopard",
        "animal",
        "nature",
        "african",
        "jaguar"
      ],
      "\u{1F434}": [
        "horse_face",
        "animal",
        "brown",
        "nature",
        "head"
      ],
      "\u{1F40E}": [
        "horse",
        "animal",
        "gamble",
        "luck",
        "equestrian",
        "galloping",
        "racehorse",
        "racing",
        "speed"
      ],
      "\u{1F984}": [
        "unicorn",
        "animal",
        "nature",
        "mystical",
        "face"
      ],
      "\u{1F993}": [
        "zebra",
        "animal",
        "nature",
        "stripes",
        "safari",
        "face",
        "stripe"
      ],
      "\u{1F98C}": [
        "deer",
        "animal",
        "nature",
        "horns",
        "venison",
        "buck",
        "reindeer",
        "stag"
      ],
      "\u{1F42E}": [
        "cow_face",
        "beef",
        "ox",
        "animal",
        "nature",
        "moo",
        "milk",
        "happy"
      ],
      "\u{1F402}": [
        "ox",
        "animal",
        "cow",
        "beef",
        "bull",
        "bullock",
        "oxen",
        "steer",
        "taurus",
        "zodiac"
      ],
      "\u{1F403}": [
        "water_buffalo",
        "animal",
        "nature",
        "ox",
        "cow",
        "domestic"
      ],
      "\u{1F404}": [
        "cow",
        "beef",
        "ox",
        "animal",
        "nature",
        "moo",
        "milk",
        "cow2",
        "dairy"
      ],
      "\u{1F437}": [
        "pig_face",
        "animal",
        "oink",
        "nature",
        "head"
      ],
      "\u{1F416}": [
        "pig",
        "animal",
        "nature",
        "hog",
        "pig2",
        "sow"
      ],
      "\u{1F417}": [
        "boar",
        "animal",
        "nature",
        "pig",
        "warthog",
        "wild"
      ],
      "\u{1F43D}": [
        "pig_nose",
        "animal",
        "oink",
        "face",
        "snout"
      ],
      "\u{1F40F}": [
        "ram",
        "animal",
        "sheep",
        "nature",
        "aries",
        "male",
        "zodiac"
      ],
      "\u{1F411}": [
        "ewe",
        "animal",
        "nature",
        "wool",
        "shipit",
        "female",
        "lamb",
        "sheep"
      ],
      "\u{1F410}": [
        "goat",
        "animal",
        "nature",
        "capricorn",
        "zodiac"
      ],
      "\u{1F42A}": [
        "camel",
        "animal",
        "hot",
        "desert",
        "hump",
        "arabian",
        "bump",
        "dromedary",
        "one"
      ],
      "\u{1F42B}": [
        "two_hump_camel",
        "animal",
        "nature",
        "hot",
        "desert",
        "hump",
        "asian",
        "bactrian",
        "bump"
      ],
      "\u{1F999}": [
        "llama",
        "animal",
        "nature",
        "alpaca",
        "guanaco",
        "vicu\xF1a",
        "wool"
      ],
      "\u{1F992}": [
        "giraffe",
        "animal",
        "nature",
        "spots",
        "safari",
        "face"
      ],
      "\u{1F418}": [
        "elephant",
        "animal",
        "nature",
        "nose",
        "th",
        "circus"
      ],
      "\u{1F98F}": [
        "rhinoceros",
        "animal",
        "nature",
        "horn",
        "rhino"
      ],
      "\u{1F99B}": [
        "hippopotamus",
        "animal",
        "nature",
        "hippo"
      ],
      "\u{1F42D}": [
        "mouse_face",
        "animal",
        "nature",
        "cheese_wedge",
        "rodent"
      ],
      "\u{1F401}": [
        "mouse",
        "animal",
        "nature",
        "rodent",
        "dormouse",
        "mice",
        "mouse2"
      ],
      "\u{1F400}": [
        "rat",
        "animal",
        "mouse",
        "rodent"
      ],
      "\u{1F439}": [
        "hamster",
        "animal",
        "nature",
        "face",
        "pet"
      ],
      "\u{1F430}": [
        "rabbit_face",
        "animal",
        "nature",
        "pet",
        "spring",
        "magic",
        "bunny",
        "easter"
      ],
      "\u{1F407}": [
        "rabbit",
        "animal",
        "nature",
        "pet",
        "magic",
        "spring",
        "bunny",
        "rabbit2"
      ],
      "\u{1F43F}\uFE0F": [
        "chipmunk",
        "animal",
        "nature",
        "rodent",
        "squirrel"
      ],
      "\u{1F994}": [
        "hedgehog",
        "animal",
        "nature",
        "spiny",
        "face"
      ],
      "\u{1F987}": [
        "bat",
        "animal",
        "nature",
        "blind",
        "vampire",
        "batman"
      ],
      "\u{1F43B}": [
        "bear",
        "animal",
        "nature",
        "wild",
        "face",
        "teddy"
      ],
      "\u{1F428}": [
        "koala",
        "animal",
        "nature",
        "bear",
        "face",
        "marsupial"
      ],
      "\u{1F43C}": [
        "panda",
        "animal",
        "nature",
        "face"
      ],
      "\u{1F9A5}": [
        "sloth",
        "animal",
        "lazy",
        "slow"
      ],
      "\u{1F9A6}": [
        "otter",
        "animal",
        "fishing",
        "playful"
      ],
      "\u{1F9A8}": [
        "skunk",
        "animal",
        "smelly",
        "stink"
      ],
      "\u{1F998}": [
        "kangaroo",
        "animal",
        "nature",
        "australia",
        "joey",
        "hop",
        "marsupial",
        "jump",
        "roo"
      ],
      "\u{1F9A1}": [
        "badger",
        "animal",
        "nature",
        "honey",
        "pester"
      ],
      "\u{1F43E}": [
        "paw_prints",
        "animal",
        "tracking",
        "footprints",
        "dog",
        "cat",
        "pet",
        "feet",
        "kitten",
        "print",
        "puppy"
      ],
      "\u{1F983}": [
        "turkey",
        "animal",
        "bird",
        "thanksgiving",
        "wild"
      ],
      "\u{1F414}": [
        "chicken",
        "animal",
        "cluck",
        "nature",
        "bird",
        "hen"
      ],
      "\u{1F413}": [
        "rooster",
        "animal",
        "nature",
        "chicken",
        "bird",
        "cock",
        "cockerel"
      ],
      "\u{1F423}": [
        "hatching_chick",
        "animal",
        "chicken",
        "egg",
        "born",
        "baby",
        "bird"
      ],
      "\u{1F424}": [
        "baby_chick",
        "animal",
        "chicken",
        "bird",
        "yellow"
      ],
      "\u{1F425}": [
        "front_facing_baby_chick",
        "animal",
        "chicken",
        "baby",
        "bird",
        "hatched",
        "standing"
      ],
      "\u{1F426}": [
        "bird",
        "animal",
        "nature",
        "fly",
        "tweet",
        "spring"
      ],
      "\u{1F427}": [
        "penguin",
        "animal",
        "nature",
        "bird"
      ],
      "\u{1F54A}\uFE0F": [
        "dove",
        "animal",
        "bird",
        "fly",
        "peace"
      ],
      "\u{1F985}": [
        "eagle",
        "animal",
        "nature",
        "bird",
        "bald"
      ],
      "\u{1F986}": [
        "duck",
        "animal",
        "nature",
        "bird",
        "mallard"
      ],
      "\u{1F9A2}": [
        "swan",
        "animal",
        "nature",
        "bird",
        "cygnet",
        "duckling",
        "ugly"
      ],
      "\u{1F989}": [
        "owl",
        "animal",
        "nature",
        "bird",
        "hoot",
        "wise"
      ],
      "\u{1F9A9}": [
        "flamingo",
        "animal",
        "flamboyant",
        "tropical"
      ],
      "\u{1F99A}": [
        "peacock",
        "animal",
        "nature",
        "peahen",
        "bird",
        "ostentatious",
        "proud"
      ],
      "\u{1F99C}": [
        "parrot",
        "animal",
        "nature",
        "bird",
        "pirate",
        "talk"
      ],
      "\u{1F438}": [
        "frog",
        "animal",
        "nature",
        "croak",
        "toad",
        "face"
      ],
      "\u{1F40A}": [
        "crocodile",
        "animal",
        "nature",
        "reptile",
        "lizard",
        "alligator",
        "croc"
      ],
      "\u{1F422}": [
        "turtle",
        "animal",
        "slow",
        "nature",
        "tortoise",
        "terrapin"
      ],
      "\u{1F98E}": [
        "lizard",
        "animal",
        "nature",
        "reptile",
        "gecko"
      ],
      "\u{1F40D}": [
        "snake",
        "animal",
        "evil",
        "nature",
        "hiss",
        "python",
        "bearer",
        "ophiuchus",
        "serpent",
        "zodiac"
      ],
      "\u{1F432}": [
        "dragon_face",
        "animal",
        "myth",
        "nature",
        "chinese",
        "green",
        "fairy",
        "head",
        "tale"
      ],
      "\u{1F409}": [
        "dragon",
        "animal",
        "myth",
        "nature",
        "chinese",
        "green",
        "fairy",
        "tale"
      ],
      "\u{1F995}": [
        "sauropod",
        "animal",
        "nature",
        "dinosaur",
        "brachiosaurus",
        "brontosaurus",
        "diplodocus",
        "extinct"
      ],
      "\u{1F996}": [
        "t_rex",
        "animal",
        "nature",
        "dinosaur",
        "tyrannosaurus",
        "extinct",
        "trex"
      ],
      "\u{1F433}": [
        "spouting_whale",
        "animal",
        "nature",
        "sea",
        "ocean",
        "cute",
        "face"
      ],
      "\u{1F40B}": [
        "whale",
        "animal",
        "nature",
        "sea",
        "ocean",
        "whale2"
      ],
      "\u{1F42C}": [
        "dolphin",
        "animal",
        "nature",
        "fish",
        "sea",
        "ocean",
        "flipper",
        "fins",
        "beach"
      ],
      "\u{1F41F}": [
        "fish",
        "animal",
        "food",
        "nature",
        "freshwater",
        "pisces",
        "zodiac"
      ],
      "\u{1F420}": [
        "tropical_fish",
        "animal",
        "swim",
        "ocean",
        "beach",
        "nemo",
        "blue",
        "yellow"
      ],
      "\u{1F421}": [
        "blowfish",
        "animal",
        "nature",
        "food",
        "sea",
        "ocean",
        "fish",
        "fugu",
        "pufferfish"
      ],
      "\u{1F988}": [
        "shark",
        "animal",
        "nature",
        "fish",
        "sea",
        "ocean",
        "jaws",
        "fins",
        "beach",
        "great",
        "white"
      ],
      "\u{1F419}": [
        "octopus",
        "animal",
        "creature",
        "ocean",
        "sea",
        "nature",
        "beach"
      ],
      "\u{1F41A}": [
        "spiral_shell",
        "nature",
        "sea",
        "beach",
        "seashell"
      ],
      "\u{1F40C}": [
        "snail",
        "slow",
        "animal",
        "shell",
        "garden",
        "slug"
      ],
      "\u{1F98B}": [
        "butterfly",
        "animal",
        "insect",
        "nature",
        "caterpillar",
        "pretty"
      ],
      "\u{1F41B}": [
        "bug",
        "animal",
        "insect",
        "nature",
        "worm",
        "caterpillar"
      ],
      "\u{1F41C}": [
        "ant",
        "animal",
        "insect",
        "nature",
        "bug"
      ],
      "\u{1F41D}": [
        "honeybee",
        "animal",
        "insect",
        "nature",
        "bug",
        "spring",
        "honey",
        "bee",
        "bumblebee"
      ],
      "\u{1F41E}": [
        "lady_beetle",
        "animal",
        "insect",
        "nature",
        "ladybug",
        "bug",
        "ladybird"
      ],
      "\u{1F997}": [
        "cricket",
        "animal",
        "chirp",
        "grasshopper",
        "insect",
        "orthoptera"
      ],
      "\u{1F577}\uFE0F": [
        "spider",
        "animal",
        "arachnid",
        "insect"
      ],
      "\u{1F578}\uFE0F": [
        "spider_web",
        "animal",
        "insect",
        "arachnid",
        "silk",
        "cobweb",
        "spiderweb"
      ],
      "\u{1F982}": [
        "scorpion",
        "animal",
        "arachnid",
        "scorpio",
        "scorpius",
        "zodiac"
      ],
      "\u{1F99F}": [
        "mosquito",
        "animal",
        "nature",
        "insect",
        "malaria",
        "disease",
        "fever",
        "pest",
        "virus"
      ],
      "\u{1F9A0}": [
        "microbe",
        "amoeba",
        "bacteria",
        "germs",
        "virus",
        "covid",
        "cell",
        "coronavirus",
        "germ",
        "microorganism"
      ],
      "\u{1F490}": [
        "bouquet",
        "flowers",
        "nature",
        "spring",
        "flower",
        "plant",
        "romance"
      ],
      "\u{1F338}": [
        "cherry_blossom",
        "nature",
        "plant",
        "spring",
        "flower",
        "pink",
        "sakura"
      ],
      "\u{1F4AE}": [
        "white_flower",
        "japanese",
        "spring",
        "blossom",
        "cherry",
        "doily",
        "done",
        "paper",
        "stamp",
        "well"
      ],
      "\u{1F3F5}\uFE0F": [
        "rosette",
        "flower",
        "decoration",
        "military",
        "plant"
      ],
      "\u{1F339}": [
        "rose",
        "flowers",
        "valentines",
        "love",
        "spring",
        "flower",
        "plant",
        "red"
      ],
      "\u{1F940}": [
        "wilted_flower",
        "plant",
        "nature",
        "flower",
        "rose",
        "dead",
        "drooping"
      ],
      "\u{1F33A}": [
        "hibiscus",
        "plant",
        "vegetable",
        "flowers",
        "beach",
        "flower"
      ],
      "\u{1F33B}": [
        "sunflower",
        "nature",
        "plant",
        "fall",
        "flower",
        "sun",
        "yellow"
      ],
      "\u{1F33C}": [
        "blossom",
        "nature",
        "flowers",
        "yellow",
        "blossoming\xA0flower",
        "daisy",
        "flower",
        "plant"
      ],
      "\u{1F337}": [
        "tulip",
        "flowers",
        "plant",
        "nature",
        "summer",
        "spring",
        "flower"
      ],
      "\u{1F331}": [
        "seedling",
        "plant",
        "nature",
        "grass",
        "lawn",
        "spring",
        "sprout",
        "sprouting",
        "young",
        "seed"
      ],
      "\u{1F332}": [
        "evergreen_tree",
        "plant",
        "nature",
        "fir",
        "pine",
        "wood"
      ],
      "\u{1F333}": [
        "deciduous_tree",
        "plant",
        "nature",
        "rounded",
        "shedding",
        "wood"
      ],
      "\u{1F334}": [
        "palm_tree",
        "plant",
        "vegetable",
        "nature",
        "summer",
        "beach",
        "mojito",
        "tropical",
        "coconut"
      ],
      "\u{1F335}": [
        "cactus",
        "vegetable",
        "plant",
        "nature",
        "desert"
      ],
      "\u{1F33E}": [
        "sheaf_of_rice",
        "nature",
        "plant",
        "crop",
        "ear",
        "farming",
        "grain",
        "wheat"
      ],
      "\u{1F33F}": [
        "herb",
        "vegetable",
        "plant",
        "medicine",
        "weed",
        "grass",
        "lawn",
        "crop",
        "leaf"
      ],
      "\u2618\uFE0F": [
        "shamrock",
        "vegetable",
        "plant",
        "nature",
        "irish",
        "clover",
        "trefoil"
      ],
      "\u{1F340}": [
        "four_leaf_clover",
        "vegetable",
        "plant",
        "nature",
        "lucky",
        "irish",
        "ireland",
        "luck"
      ],
      "\u{1F341}": [
        "maple_leaf",
        "nature",
        "plant",
        "vegetable",
        "ca",
        "fall",
        "canada",
        "canadian",
        "falling"
      ],
      "\u{1F342}": [
        "fallen_leaf",
        "nature",
        "plant",
        "vegetable",
        "leaves",
        "autumn",
        "brown",
        "fall",
        "falling"
      ],
      "\u{1F343}": [
        "leaf_fluttering_in_wind",
        "nature",
        "plant",
        "tree",
        "vegetable",
        "grass",
        "lawn",
        "spring",
        "blow",
        "flutter",
        "green",
        "leaves"
      ],
      "\u{1F347}": [
        "grapes",
        "fruit",
        "food",
        "wine",
        "grape",
        "plant"
      ],
      "\u{1F348}": [
        "melon",
        "fruit",
        "nature",
        "food",
        "cantaloupe",
        "honeydew",
        "muskmelon",
        "plant"
      ],
      "\u{1F349}": [
        "watermelon",
        "fruit",
        "food",
        "picnic",
        "summer",
        "plant"
      ],
      "\u{1F34A}": [
        "tangerine",
        "food",
        "fruit",
        "nature",
        "orange",
        "mandarin",
        "plant"
      ],
      "\u{1F34B}": [
        "lemon",
        "fruit",
        "nature",
        "citrus",
        "lemonade",
        "plant"
      ],
      "\u{1F34C}": [
        "banana",
        "fruit",
        "food",
        "monkey",
        "plant",
        "plantain"
      ],
      "\u{1F34D}": [
        "pineapple",
        "fruit",
        "nature",
        "food",
        "plant"
      ],
      "\u{1F96D}": [
        "mango",
        "fruit",
        "food",
        "tropical"
      ],
      "\u{1F34E}": [
        "red_apple",
        "fruit",
        "mac",
        "school",
        "delicious",
        "plant"
      ],
      "\u{1F34F}": [
        "green_apple",
        "fruit",
        "nature",
        "delicious",
        "golden",
        "granny",
        "plant",
        "smith"
      ],
      "\u{1F350}": [
        "pear",
        "fruit",
        "nature",
        "food",
        "plant"
      ],
      "\u{1F351}": [
        "peach",
        "fruit",
        "nature",
        "food",
        "bottom",
        "butt",
        "plant"
      ],
      "\u{1F352}": [
        "cherries",
        "food",
        "fruit",
        "berries",
        "cherry",
        "plant",
        "red",
        "wild"
      ],
      "\u{1F353}": [
        "strawberry",
        "fruit",
        "food",
        "nature",
        "berry",
        "plant"
      ],
      "\u{1F95D}": [
        "kiwi_fruit",
        "fruit",
        "food",
        "chinese",
        "gooseberry",
        "kiwifruit"
      ],
      "\u{1F345}": [
        "tomato",
        "fruit",
        "vegetable",
        "nature",
        "food",
        "plant"
      ],
      "\u{1F965}": [
        "coconut",
        "fruit",
        "nature",
        "food",
        "palm",
        "cocoanut",
        "colada",
        "pi\xF1a"
      ],
      "\u{1F951}": [
        "avocado",
        "fruit",
        "food"
      ],
      "\u{1F346}": [
        "eggplant",
        "vegetable",
        "nature",
        "food",
        "aubergine",
        "phallic",
        "plant",
        "purple"
      ],
      "\u{1F954}": [
        "potato",
        "food",
        "tuber",
        "vegatable",
        "starch",
        "baked",
        "idaho",
        "vegetable"
      ],
      "\u{1F955}": [
        "carrot",
        "vegetable",
        "food",
        "orange"
      ],
      "\u{1F33D}": [
        "ear_of_corn",
        "food",
        "vegetable",
        "plant",
        "cob",
        "maize",
        "maze"
      ],
      "\u{1F336}\uFE0F": [
        "hot_pepper",
        "food",
        "spicy",
        "chilli",
        "chili",
        "plant"
      ],
      "\u{1F952}": [
        "cucumber",
        "fruit",
        "food",
        "pickle",
        "gherkin",
        "vegetable"
      ],
      "\u{1F96C}": [
        "leafy_green",
        "food",
        "vegetable",
        "plant",
        "bok choy",
        "cabbage",
        "kale",
        "lettuce",
        "chinese",
        "cos",
        "greens",
        "romaine"
      ],
      "\u{1F966}": [
        "broccoli",
        "fruit",
        "food",
        "vegetable",
        "cabbage",
        "wild"
      ],
      "\u{1F9C4}": [
        "garlic",
        "food",
        "spice",
        "cook",
        "flavoring",
        "plant",
        "vegetable"
      ],
      "\u{1F9C5}": [
        "onion",
        "cook",
        "food",
        "spice",
        "flavoring",
        "plant",
        "vegetable"
      ],
      "\u{1F344}": [
        "mushroom",
        "plant",
        "vegetable",
        "fungus",
        "shroom",
        "toadstool"
      ],
      "\u{1F95C}": [
        "peanuts",
        "food",
        "nut",
        "nuts",
        "peanut",
        "vegetable"
      ],
      "\u{1F330}": [
        "chestnut",
        "food",
        "squirrel",
        "acorn",
        "nut",
        "plant"
      ],
      "\u{1F35E}": [
        "bread",
        "food",
        "wheat",
        "breakfast",
        "toast",
        "loaf"
      ],
      "\u{1F950}": [
        "croissant",
        "food",
        "bread",
        "french",
        "breakfast",
        "crescent",
        "roll"
      ],
      "\u{1F956}": [
        "baguette_bread",
        "food",
        "bread",
        "french",
        "france",
        "bakery"
      ],
      "\u{1F968}": [
        "pretzel",
        "food",
        "bread",
        "twisted",
        "germany",
        "bakery",
        "soft",
        "twist"
      ],
      "\u{1F96F}": [
        "bagel",
        "food",
        "bread",
        "bakery",
        "schmear",
        "jewish_bakery",
        "breakfast",
        "cheese",
        "cream"
      ],
      "\u{1F95E}": [
        "pancakes",
        "food",
        "breakfast",
        "flapjacks",
        "hotcakes",
        "brunch",
        "cr\xEApe",
        "cr\xEApes",
        "hotcake",
        "pancake"
      ],
      "\u{1F9C7}": [
        "waffle",
        "food",
        "breakfast",
        "brunch",
        "indecisive",
        "iron"
      ],
      "\u{1F9C0}": [
        "cheese_wedge",
        "food",
        "chadder",
        "swiss"
      ],
      "\u{1F356}": [
        "meat_on_bone",
        "good",
        "food",
        "drumstick",
        "barbecue",
        "bbq",
        "manga"
      ],
      "\u{1F357}": [
        "poultry_leg",
        "food",
        "meat",
        "drumstick",
        "bird",
        "chicken",
        "turkey",
        "bone"
      ],
      "\u{1F969}": [
        "cut_of_meat",
        "food",
        "cow",
        "meat",
        "cut",
        "chop",
        "lambchop",
        "porkchop",
        "steak"
      ],
      "\u{1F953}": [
        "bacon",
        "food",
        "breakfast",
        "pork",
        "pig",
        "meat",
        "brunch",
        "rashers"
      ],
      "\u{1F354}": [
        "hamburger",
        "meat",
        "fast food",
        "beef",
        "cheeseburger",
        "mcdonalds",
        "burger king"
      ],
      "\u{1F35F}": [
        "french_fries",
        "chips",
        "snack",
        "fast food",
        "potato",
        "mcdonald's"
      ],
      "\u{1F355}": [
        "pizza",
        "food",
        "party",
        "italy",
        "cheese",
        "pepperoni",
        "slice"
      ],
      "\u{1F32D}": [
        "hot_dog",
        "food",
        "frankfurter",
        "america",
        "hotdog",
        "redhot",
        "sausage",
        "wiener"
      ],
      "\u{1F96A}": [
        "sandwich",
        "food",
        "lunch",
        "bread",
        "toast",
        "bakery",
        "cheese",
        "deli",
        "meat",
        "vegetables"
      ],
      "\u{1F32E}": [
        "taco",
        "food",
        "mexican"
      ],
      "\u{1F32F}": [
        "burrito",
        "food",
        "mexican",
        "wrap"
      ],
      "\u{1F959}": [
        "stuffed_flatbread",
        "food",
        "flatbread",
        "stuffed",
        "gyro",
        "mediterranean",
        "doner",
        "falafel",
        "kebab",
        "pita",
        "sandwich",
        "shawarma"
      ],
      "\u{1F9C6}": [
        "falafel",
        "food",
        "mediterranean",
        "chickpea",
        "falfel",
        "meatball"
      ],
      "\u{1F95A}": [
        "egg",
        "food",
        "chicken",
        "breakfast",
        "easter_egg"
      ],
      "\u{1F373}": [
        "cooking",
        "food",
        "breakfast",
        "kitchen",
        "egg",
        "skillet",
        "fried",
        "frying",
        "pan"
      ],
      "\u{1F958}": [
        "shallow_pan_of_food",
        "food",
        "cooking",
        "casserole",
        "paella",
        "skillet",
        "curry"
      ],
      "\u{1F372}": [
        "pot_of_food",
        "food",
        "meat",
        "soup",
        "hot pot",
        "bowl",
        "stew"
      ],
      "\u{1F963}": [
        "bowl_with_spoon",
        "food",
        "breakfast",
        "cereal",
        "oatmeal",
        "porridge",
        "congee",
        "tableware"
      ],
      "\u{1F957}": [
        "green_salad",
        "food",
        "healthy",
        "lettuce",
        "vegetable"
      ],
      "\u{1F37F}": [
        "popcorn",
        "food",
        "movie theater",
        "films",
        "snack",
        "drama",
        "corn",
        "popping"
      ],
      "\u{1F9C8}": [
        "butter",
        "food",
        "cook",
        "dairy"
      ],
      "\u{1F9C2}": [
        "salt",
        "condiment",
        "shaker"
      ],
      "\u{1F96B}": [
        "canned_food",
        "food",
        "soup",
        "tomatoes",
        "can",
        "preserve",
        "tin",
        "tinned"
      ],
      "\u{1F371}": [
        "bento_box",
        "food",
        "japanese",
        "box",
        "lunch",
        "assets"
      ],
      "\u{1F358}": [
        "rice_cracker",
        "food",
        "japanese",
        "snack",
        "senbei"
      ],
      "\u{1F359}": [
        "rice_ball",
        "food",
        "japanese",
        "onigiri",
        "omusubi"
      ],
      "\u{1F35A}": [
        "cooked_rice",
        "food",
        "asian",
        "boiled",
        "bowl",
        "steamed"
      ],
      "\u{1F35B}": [
        "curry_rice",
        "food",
        "spicy",
        "hot",
        "indian"
      ],
      "\u{1F35C}": [
        "steaming_bowl",
        "food",
        "japanese",
        "noodle",
        "chopsticks",
        "ramen",
        "noodles",
        "soup"
      ],
      "\u{1F35D}": [
        "spaghetti",
        "food",
        "italian",
        "pasta",
        "noodle"
      ],
      "\u{1F360}": [
        "roasted_sweet_potato",
        "food",
        "nature",
        "plant",
        "goguma",
        "yam"
      ],
      "\u{1F362}": [
        "oden",
        "skewer",
        "food",
        "japanese",
        "kebab",
        "seafood",
        "stick"
      ],
      "\u{1F363}": [
        "sushi",
        "food",
        "fish",
        "japanese",
        "rice",
        "sashimi",
        "seafood"
      ],
      "\u{1F364}": [
        "fried_shrimp",
        "food",
        "animal",
        "appetizer",
        "summer",
        "prawn",
        "tempura"
      ],
      "\u{1F365}": [
        "fish_cake_with_swirl",
        "food",
        "japan",
        "sea",
        "beach",
        "narutomaki",
        "pink",
        "swirl",
        "kamaboko",
        "surimi",
        "ramen",
        "design",
        "fishcake",
        "pastry"
      ],
      "\u{1F96E}": [
        "moon_cake",
        "food",
        "autumn",
        "dessert",
        "festival",
        "mooncake",
        "yu\xE8b\u01D0ng"
      ],
      "\u{1F361}": [
        "dango",
        "food",
        "dessert",
        "sweet",
        "japanese",
        "barbecue",
        "meat",
        "balls",
        "green",
        "pink",
        "skewer",
        "stick",
        "white"
      ],
      "\u{1F95F}": [
        "dumpling",
        "food",
        "empanada",
        "pierogi",
        "potsticker",
        "gyoza",
        "gy\u014Dza",
        "jiaozi"
      ],
      "\u{1F960}": [
        "fortune_cookie",
        "food",
        "prophecy",
        "dessert"
      ],
      "\u{1F961}": [
        "takeout_box",
        "food",
        "leftovers",
        "chinese",
        "container",
        "out",
        "oyster",
        "pail",
        "take"
      ],
      "\u{1F980}": [
        "crab",
        "animal",
        "crustacean",
        "cancer",
        "zodiac"
      ],
      "\u{1F99E}": [
        "lobster",
        "animal",
        "nature",
        "bisque",
        "claws",
        "seafood"
      ],
      "\u{1F990}": [
        "shrimp",
        "animal",
        "ocean",
        "nature",
        "seafood",
        "food",
        "prawn",
        "shellfish",
        "small"
      ],
      "\u{1F991}": [
        "squid",
        "animal",
        "nature",
        "ocean",
        "sea",
        "food",
        "molusc"
      ],
      "\u{1F9AA}": [
        "oyster",
        "food",
        "diving",
        "pearl"
      ],
      "\u{1F366}": [
        "soft_ice_cream",
        "food",
        "hot",
        "dessert",
        "summer",
        "icecream",
        "mr.",
        "serve",
        "sweet",
        "whippy"
      ],
      "\u{1F367}": [
        "shaved_ice",
        "hot",
        "dessert",
        "summer",
        "cone",
        "snow",
        "sweet"
      ],
      "\u{1F368}": [
        "ice_cream",
        "food",
        "hot",
        "dessert",
        "bowl",
        "sweet"
      ],
      "\u{1F369}": [
        "doughnut",
        "food",
        "dessert",
        "snack",
        "sweet",
        "donut",
        "breakfast"
      ],
      "\u{1F36A}": [
        "cookie",
        "food",
        "snack",
        "oreo",
        "chocolate",
        "sweet",
        "dessert",
        "biscuit",
        "chip"
      ],
      "\u{1F382}": [
        "birthday_cake",
        "food",
        "dessert",
        "cake",
        "candles",
        "celebration",
        "party",
        "pastry",
        "sweet"
      ],
      "\u{1F370}": [
        "shortcake",
        "food",
        "dessert",
        "cake",
        "pastry",
        "piece",
        "slice",
        "strawberry",
        "sweet"
      ],
      "\u{1F9C1}": [
        "cupcake",
        "food",
        "dessert",
        "bakery",
        "sweet",
        "cake",
        "fairy",
        "pastry"
      ],
      "\u{1F967}": [
        "pie",
        "food",
        "dessert",
        "pastry",
        "filling",
        "sweet"
      ],
      "\u{1F36B}": [
        "chocolate_bar",
        "food",
        "snack",
        "dessert",
        "sweet",
        "candy"
      ],
      "\u{1F36C}": [
        "candy",
        "snack",
        "dessert",
        "sweet",
        "lolly"
      ],
      "\u{1F36D}": [
        "lollipop",
        "food",
        "snack",
        "candy",
        "sweet",
        "dessert",
        "lollypop",
        "sucker"
      ],
      "\u{1F36E}": [
        "custard",
        "dessert",
        "food",
        "pudding",
        "flan",
        "caramel",
        "creme",
        "sweet"
      ],
      "\u{1F36F}": [
        "honey_pot",
        "bees",
        "sweet",
        "kitchen",
        "honeypot"
      ],
      "\u{1F37C}": [
        "baby_bottle",
        "food",
        "container",
        "milk",
        "drink",
        "feeding"
      ],
      "\u{1F95B}": [
        "glass_of_milk",
        "beverage",
        "drink",
        "cow"
      ],
      "\u2615": [
        "hot_beverage",
        "beverage",
        "caffeine",
        "latte",
        "espresso",
        "coffee",
        "mug",
        "cafe",
        "chocolate",
        "drink",
        "steaming",
        "tea"
      ],
      "\u{1F375}": [
        "teacup_without_handle",
        "drink",
        "bowl",
        "breakfast",
        "green",
        "british",
        "beverage",
        "cup",
        "matcha",
        "tea"
      ],
      "\u{1F376}": [
        "sake",
        "wine",
        "drink",
        "drunk",
        "beverage",
        "japanese",
        "alcohol",
        "booze",
        "bar",
        "bottle",
        "cup",
        "rice"
      ],
      "\u{1F37E}": [
        "bottle_with_popping_cork",
        "drink",
        "wine",
        "bottle",
        "celebration",
        "bar",
        "bubbly",
        "champagne",
        "party",
        "sparkling"
      ],
      "\u{1F377}": [
        "wine_glass",
        "drink",
        "beverage",
        "drunk",
        "alcohol",
        "booze",
        "bar",
        "red"
      ],
      "\u{1F378}": [
        "cocktail_glass",
        "drink",
        "drunk",
        "alcohol",
        "beverage",
        "booze",
        "mojito",
        "bar",
        "martini"
      ],
      "\u{1F379}": [
        "tropical_drink",
        "beverage",
        "cocktail",
        "summer",
        "beach",
        "alcohol",
        "booze",
        "mojito",
        "bar",
        "fruit",
        "punch",
        "tiki",
        "vacation"
      ],
      "\u{1F37A}": [
        "beer_mug",
        "relax",
        "beverage",
        "drink",
        "drunk",
        "party",
        "pub",
        "summer",
        "alcohol",
        "booze",
        "bar",
        "stein"
      ],
      "\u{1F37B}": [
        "clinking_beer_mugs",
        "relax",
        "beverage",
        "drink",
        "drunk",
        "party",
        "pub",
        "summer",
        "alcohol",
        "booze",
        "bar",
        "beers",
        "cheers",
        "clink",
        "drinks",
        "mug"
      ],
      "\u{1F942}": [
        "clinking_glasses",
        "beverage",
        "drink",
        "party",
        "alcohol",
        "celebrate",
        "cheers",
        "wine",
        "champagne",
        "toast",
        "celebration",
        "clink",
        "glass"
      ],
      "\u{1F943}": [
        "tumbler_glass",
        "drink",
        "beverage",
        "drunk",
        "alcohol",
        "liquor",
        "booze",
        "bourbon",
        "scotch",
        "whisky",
        "glass",
        "shot",
        "rum",
        "whiskey"
      ],
      "\u{1F964}": [
        "cup_with_straw",
        "drink",
        "soda",
        "go",
        "juice",
        "malt",
        "milkshake",
        "pop",
        "smoothie",
        "soft",
        "tableware",
        "water"
      ],
      "\u{1F9C3}": [
        "beverage_box",
        "drink",
        "juice",
        "straw",
        "sweet"
      ],
      "\u{1F9C9}": [
        "mate",
        "drink",
        "tea",
        "beverage",
        "bombilla",
        "chimarr\xE3o",
        "cimarr\xF3n",
        "mat\xE9",
        "yerba"
      ],
      "\u{1F9CA}": [
        "ice",
        "water",
        "cold",
        "cube",
        "iceberg"
      ],
      "\u{1F962}": [
        "chopsticks",
        "food",
        "hashi",
        "jeotgarak",
        "kuaizi"
      ],
      "\u{1F37D}\uFE0F": [
        "fork_and_knife_with_plate",
        "food",
        "eat",
        "meal",
        "lunch",
        "dinner",
        "restaurant",
        "cooking",
        "cutlery",
        "dining",
        "tableware"
      ],
      "\u{1F374}": [
        "fork_and_knife",
        "cutlery",
        "kitchen",
        "cooking",
        "silverware",
        "tableware"
      ],
      "\u{1F944}": [
        "spoon",
        "cutlery",
        "kitchen",
        "tableware"
      ],
      "\u{1F52A}": [
        "kitchen_knife",
        "knife",
        "blade",
        "cutlery",
        "kitchen",
        "weapon",
        "butchers",
        "chop",
        "cooking",
        "cut",
        "hocho",
        "tool"
      ],
      "\u{1F3FA}": [
        "amphora",
        "vase",
        "jar",
        "aquarius",
        "cooking",
        "drink",
        "jug",
        "tool",
        "zodiac"
      ],
      "\u{1F30D}": [
        "globe_showing_europe_africa",
        "globe",
        "world",
        "earth",
        "international",
        "planet"
      ],
      "\u{1F30E}": [
        "globe_showing_americas",
        "globe",
        "world",
        "USA",
        "earth",
        "international",
        "planet"
      ],
      "\u{1F30F}": [
        "globe_showing_asia_australia",
        "globe",
        "world",
        "east",
        "earth",
        "international",
        "planet"
      ],
      "\u{1F310}": [
        "globe_with_meridians",
        "earth",
        "international",
        "world",
        "internet",
        "interweb",
        "i18n",
        "global",
        "web",
        "wide",
        "www",
        "internationalization",
        "localization"
      ],
      "\u{1F5FA}\uFE0F": [
        "world_map",
        "location",
        "direction",
        "travel"
      ],
      "\u{1F5FE}": [
        "map_of_japan",
        "nation",
        "country",
        "japanese",
        "asia",
        "silhouette"
      ],
      "\u{1F9ED}": [
        "compass",
        "magnetic",
        "navigation",
        "orienteering"
      ],
      "\u{1F3D4}\uFE0F": [
        "snow_capped_mountain",
        "photo",
        "nature",
        "environment",
        "winter",
        "cold"
      ],
      "\u26F0\uFE0F": [
        "mountain",
        "photo",
        "nature",
        "environment"
      ],
      "\u{1F30B}": [
        "volcano",
        "photo",
        "nature",
        "disaster",
        "eruption",
        "mountain",
        "weather"
      ],
      "\u{1F5FB}": [
        "mount_fuji",
        "photo",
        "mountain",
        "nature",
        "japanese",
        "capped",
        "san",
        "snow"
      ],
      "\u{1F3D5}\uFE0F": [
        "camping",
        "photo",
        "outdoors",
        "tent",
        "campsite"
      ],
      "\u{1F3D6}\uFE0F": [
        "beach_with_umbrella",
        "weather",
        "summer",
        "sunny",
        "sand",
        "mojito"
      ],
      "\u{1F3DC}\uFE0F": [
        "desert",
        "photo",
        "warm",
        "saharah"
      ],
      "\u{1F3DD}\uFE0F": [
        "desert_island",
        "photo",
        "tropical",
        "mojito"
      ],
      "\u{1F3DE}\uFE0F": [
        "national_park",
        "photo",
        "environment",
        "nature"
      ],
      "\u{1F3DF}\uFE0F": [
        "stadium",
        "photo",
        "place",
        "sports",
        "concert",
        "venue",
        "grandstand",
        "sport"
      ],
      "\u{1F3DB}\uFE0F": [
        "classical_building",
        "art",
        "culture",
        "history"
      ],
      "\u{1F3D7}\uFE0F": [
        "building_construction",
        "wip",
        "working",
        "progress",
        "crane",
        "architectural"
      ],
      "\u{1F9F1}": [
        "brick",
        "bricks",
        "clay",
        "construction",
        "mortar",
        "wall",
        "infrastructure"
      ],
      "\u{1F3D8}\uFE0F": [
        "houses",
        "buildings",
        "photo",
        "building",
        "group",
        "house"
      ],
      "\u{1F3DA}\uFE0F": [
        "derelict_house",
        "abandon",
        "evict",
        "broken",
        "building",
        "abandoned",
        "haunted",
        "old"
      ],
      "\u{1F3E0}": [
        "house",
        "building",
        "home"
      ],
      "\u{1F3E1}": [
        "house_with_garden",
        "home",
        "plant",
        "nature",
        "building",
        "tree"
      ],
      "\u{1F3E2}": [
        "office_building",
        "building",
        "bureau",
        "work",
        "city",
        "high",
        "rise"
      ],
      "\u{1F3E3}": [
        "japanese_post_office",
        "building",
        "envelope",
        "communication",
        "japan",
        "mark",
        "postal"
      ],
      "\u{1F3E4}": [
        "post_office",
        "building",
        "email",
        "european"
      ],
      "\u{1F3E5}": [
        "hospital",
        "building",
        "health",
        "surgery",
        "doctor",
        "cross",
        "emergency",
        "medical",
        "medicine",
        "red",
        "room"
      ],
      "\u{1F3E6}": [
        "bank",
        "building",
        "money",
        "sales",
        "cash",
        "business",
        "enterprise",
        "bakkureru",
        "bk",
        "branch"
      ],
      "\u{1F3E8}": [
        "hotel",
        "building",
        "accomodation",
        "checkin",
        "accommodation",
        "h"
      ],
      "\u{1F3E9}": [
        "love_hotel",
        "like",
        "affection",
        "dating",
        "building",
        "heart",
        "hospital"
      ],
      "\u{1F3EA}": [
        "convenience_store",
        "building",
        "shopping",
        "groceries",
        "corner",
        "e",
        "eleven\xAE",
        "hour",
        "kwik",
        "mart",
        "shop"
      ],
      "\u{1F3EB}": [
        "school",
        "building",
        "student",
        "education",
        "learn",
        "teach",
        "clock",
        "elementary",
        "high",
        "middle",
        "tower"
      ],
      "\u{1F3EC}": [
        "department_store",
        "building",
        "shopping",
        "mall",
        "center",
        "shops"
      ],
      "\u{1F3ED}": [
        "factory",
        "building",
        "industry",
        "pollution",
        "smoke",
        "industrial",
        "smog"
      ],
      "\u{1F3EF}": [
        "japanese_castle",
        "photo",
        "building",
        "fortress"
      ],
      "\u{1F3F0}": [
        "castle",
        "building",
        "royalty",
        "history",
        "european",
        "turrets"
      ],
      "\u{1F492}": [
        "wedding",
        "love",
        "like",
        "affection",
        "couple",
        "marriage",
        "bride",
        "groom",
        "activity",
        "chapel",
        "church",
        "heart",
        "romance"
      ],
      "\u{1F5FC}": [
        "tokyo_tower",
        "photo",
        "japanese",
        "eiffel",
        "red"
      ],
      "\u{1F5FD}": [
        "statue_of_liberty",
        "american",
        "newyork",
        "new",
        "york"
      ],
      "\u26EA": [
        "church",
        "building",
        "religion",
        "christ",
        "christian",
        "cross"
      ],
      "\u{1F54C}": [
        "mosque",
        "islam",
        "worship",
        "minaret",
        "domed",
        "muslim",
        "religion",
        "roof"
      ],
      "\u{1F6D5}": [
        "hindu_temple",
        "religion"
      ],
      "\u{1F54D}": [
        "synagogue",
        "judaism",
        "worship",
        "temple",
        "jewish",
        "jew",
        "religion",
        "synagog"
      ],
      "\u26E9\uFE0F": [
        "shinto_shrine",
        "temple",
        "japan",
        "kyoto",
        "kami",
        "michi",
        "no",
        "religion"
      ],
      "\u{1F54B}": [
        "kaaba",
        "mecca",
        "mosque",
        "islam",
        "muslim",
        "religion"
      ],
      "\u26F2": [
        "fountain",
        "photo",
        "summer",
        "water",
        "fresh",
        "feature",
        "park"
      ],
      "\u26FA": [
        "tent",
        "photo",
        "camping",
        "outdoors"
      ],
      "\u{1F301}": [
        "foggy",
        "photo",
        "mountain",
        "bridge",
        "city",
        "fog",
        "fog\xA0bridge",
        "karl",
        "under",
        "weather"
      ],
      "\u{1F303}": [
        "night_with_stars",
        "evening",
        "city",
        "downtown",
        "star",
        "starry",
        "weather"
      ],
      "\u{1F3D9}\uFE0F": [
        "cityscape",
        "photo",
        "night life",
        "urban",
        "building",
        "city",
        "skyline"
      ],
      "\u{1F304}": [
        "sunrise_over_mountains",
        "view",
        "vacation",
        "photo",
        "morning",
        "mountain",
        "sun",
        "weather"
      ],
      "\u{1F305}": [
        "sunrise",
        "morning",
        "view",
        "vacation",
        "photo",
        "sun",
        "sunset",
        "weather"
      ],
      "\u{1F306}": [
        "cityscape_at_dusk",
        "photo",
        "evening",
        "sky",
        "buildings",
        "building",
        "city",
        "landscape",
        "orange",
        "sun",
        "sunset",
        "weather"
      ],
      "\u{1F307}": [
        "sunset",
        "photo",
        "good morning",
        "dawn",
        "building",
        "buildings",
        "city",
        "dusk",
        "over",
        "sun",
        "sunrise",
        "weather"
      ],
      "\u{1F309}": [
        "bridge_at_night",
        "photo",
        "sanfrancisco",
        "gate",
        "golden",
        "weather"
      ],
      "\u2668\uFE0F": [
        "hot_springs",
        "bath",
        "warm",
        "relax",
        "hotsprings",
        "onsen",
        "steam",
        "steaming"
      ],
      "\u{1F3A0}": [
        "carousel_horse",
        "photo",
        "carnival",
        "activity",
        "entertainment",
        "fairground",
        "go",
        "merry",
        "round"
      ],
      "\u{1F3A1}": [
        "ferris_wheel",
        "photo",
        "carnival",
        "londoneye",
        "activity",
        "amusement",
        "big",
        "entertainment",
        "fairground",
        "observation",
        "park"
      ],
      "\u{1F3A2}": [
        "roller_coaster",
        "carnival",
        "playground",
        "photo",
        "fun",
        "activity",
        "amusement",
        "entertainment",
        "park",
        "rollercoaster",
        "theme"
      ],
      "\u{1F488}": [
        "barber_pole",
        "hair",
        "salon",
        "style",
        "barber's",
        "haircut",
        "hairdresser",
        "shop",
        "stripes"
      ],
      "\u{1F3AA}": [
        "circus_tent",
        "festival",
        "carnival",
        "party",
        "activity",
        "big",
        "entertainment",
        "top"
      ],
      "\u{1F682}": [
        "locomotive",
        "transportation",
        "vehicle",
        "train",
        "engine",
        "railway",
        "steam"
      ],
      "\u{1F683}": [
        "railway_car",
        "transportation",
        "vehicle",
        "carriage",
        "electric",
        "railcar",
        "railroad",
        "train",
        "tram",
        "trolleybus",
        "wagon"
      ],
      "\u{1F684}": [
        "high_speed_train",
        "transportation",
        "vehicle",
        "bullettrain",
        "railway",
        "shinkansen",
        "side"
      ],
      "\u{1F685}": [
        "bullet_train",
        "transportation",
        "vehicle",
        "speed",
        "fast",
        "public",
        "travel",
        "bullettrain",
        "front",
        "high",
        "nose",
        "railway",
        "shinkansen"
      ],
      "\u{1F686}": [
        "train",
        "transportation",
        "vehicle",
        "diesel",
        "electric",
        "passenger",
        "railway",
        "regular",
        "train2"
      ],
      "\u{1F687}": [
        "metro",
        "transportation",
        "blue-square",
        "mrt",
        "underground",
        "tube",
        "subway",
        "train",
        "vehicle"
      ],
      "\u{1F688}": [
        "light_rail",
        "transportation",
        "vehicle",
        "railway"
      ],
      "\u{1F689}": [
        "station",
        "transportation",
        "vehicle",
        "public",
        "platform",
        "railway",
        "train"
      ],
      "\u{1F68A}": [
        "tram",
        "transportation",
        "vehicle",
        "trolleybus"
      ],
      "\u{1F69D}": [
        "monorail",
        "transportation",
        "vehicle"
      ],
      "\u{1F69E}": [
        "mountain_railway",
        "transportation",
        "vehicle",
        "car",
        "funicular",
        "train"
      ],
      "\u{1F68B}": [
        "tram_car",
        "transportation",
        "vehicle",
        "carriage",
        "public",
        "travel",
        "train",
        "trolleybus"
      ],
      "\u{1F68C}": [
        "bus",
        "car",
        "vehicle",
        "transportation",
        "school"
      ],
      "\u{1F68D}": [
        "oncoming_bus",
        "vehicle",
        "transportation",
        "front"
      ],
      "\u{1F68E}": [
        "trolleybus",
        "bart",
        "transportation",
        "vehicle",
        "bus",
        "electric\xA0bus",
        "tram",
        "trolley"
      ],
      "\u{1F690}": [
        "minibus",
        "vehicle",
        "car",
        "transportation",
        "bus",
        "minivan",
        "mover",
        "people"
      ],
      "\u{1F691}": [
        "ambulance",
        "health",
        "911",
        "hospital",
        "vehicle"
      ],
      "\u{1F692}": [
        "fire_engine",
        "transportation",
        "cars",
        "vehicle",
        "department",
        "truck"
      ],
      "\u{1F693}": [
        "police_car",
        "vehicle",
        "cars",
        "transportation",
        "law",
        "legal",
        "enforcement",
        "cop",
        "patrol",
        "side"
      ],
      "\u{1F694}": [
        "oncoming_police_car",
        "vehicle",
        "law",
        "legal",
        "enforcement",
        "911",
        "front\xA0of",
        "\u{1F693}\xA0cop"
      ],
      "\u{1F695}": [
        "taxi",
        "uber",
        "vehicle",
        "cars",
        "transportation",
        "new",
        "side",
        "taxicab",
        "york"
      ],
      "\u{1F696}": [
        "oncoming_taxi",
        "vehicle",
        "cars",
        "uber",
        "front",
        "taxicab"
      ],
      "\u{1F697}": [
        "automobile",
        "red",
        "transportation",
        "vehicle",
        "car",
        "side"
      ],
      "\u{1F698}": [
        "oncoming_automobile",
        "car",
        "vehicle",
        "transportation",
        "front"
      ],
      "\u{1F699}": [
        "sport_utility_vehicle",
        "transportation",
        "vehicle",
        "blue",
        "campervan",
        "car",
        "motorhome",
        "recreational",
        "rv"
      ],
      "\u{1F69A}": [
        "delivery_truck",
        "cars",
        "transportation",
        "vehicle",
        "resources"
      ],
      "\u{1F69B}": [
        "articulated_lorry",
        "vehicle",
        "cars",
        "transportation",
        "express",
        "green",
        "semi",
        "truck"
      ],
      "\u{1F69C}": [
        "tractor",
        "vehicle",
        "car",
        "farming",
        "agriculture",
        "farm"
      ],
      "\u{1F3CE}\uFE0F": [
        "racing_car",
        "sports",
        "race",
        "fast",
        "formula",
        "f1",
        "one"
      ],
      "\u{1F3CD}\uFE0F": [
        "motorcycle",
        "race",
        "sports",
        "fast",
        "motorbike",
        "racing"
      ],
      "\u{1F6F5}": [
        "motor_scooter",
        "vehicle",
        "vespa",
        "sasha",
        "bike",
        "cycle"
      ],
      "\u{1F9BD}": [
        "manual_wheelchair",
        "accessibility"
      ],
      "\u{1F9BC}": [
        "motorized_wheelchair",
        "accessibility"
      ],
      "\u{1F6FA}": [
        "auto_rickshaw",
        "move",
        "transportation",
        "tuk"
      ],
      "\u{1F6B2}": [
        "bicycle",
        "bike",
        "sports",
        "exercise",
        "hipster",
        "push",
        "vehicle"
      ],
      "\u{1F6F4}": [
        "kick_scooter",
        "vehicle",
        "kick",
        "razor"
      ],
      "\u{1F6F9}": [
        "skateboard",
        "board",
        "skate"
      ],
      "\u{1F68F}": [
        "bus_stop",
        "transportation",
        "wait",
        "busstop"
      ],
      "\u{1F6E3}\uFE0F": [
        "motorway",
        "road",
        "cupertino",
        "interstate",
        "highway"
      ],
      "\u{1F6E4}\uFE0F": [
        "railway_track",
        "train",
        "transportation"
      ],
      "\u{1F6E2}\uFE0F": [
        "oil_drum",
        "barrell"
      ],
      "\u26FD": [
        "fuel_pump",
        "gas station",
        "petroleum",
        "diesel",
        "fuelpump",
        "petrol"
      ],
      "\u{1F6A8}": [
        "police_car_light",
        "police",
        "ambulance",
        "911",
        "emergency",
        "alert",
        "error",
        "pinged",
        "law",
        "legal",
        "beacon",
        "cars",
        "car\u2019s",
        "emergency\xA0light",
        "flashing",
        "revolving",
        "rotating",
        "siren",
        "vehicle",
        "warning"
      ],
      "\u{1F6A5}": [
        "horizontal_traffic_light",
        "transportation",
        "signal"
      ],
      "\u{1F6A6}": [
        "vertical_traffic_light",
        "transportation",
        "driving",
        "semaphore",
        "signal"
      ],
      "\u{1F6D1}": [
        "stop_sign",
        "stop",
        "octagonal"
      ],
      "\u{1F6A7}": [
        "construction",
        "wip",
        "progress",
        "caution",
        "warning",
        "barrier",
        "black",
        "roadwork",
        "sign",
        "striped",
        "yellow",
        "work_in_progress"
      ],
      "\u2693": [
        "anchor",
        "ship",
        "ferry",
        "sea",
        "boat",
        "admiralty",
        "fisherman",
        "pattern",
        "tool"
      ],
      "\u26F5": [
        "sailboat",
        "ship",
        "summer",
        "transportation",
        "water",
        "sailing",
        "boat",
        "dinghy",
        "resort",
        "sea",
        "vehicle",
        "yacht"
      ],
      "\u{1F6F6}": [
        "canoe",
        "boat",
        "paddle",
        "water",
        "ship"
      ],
      "\u{1F6A4}": [
        "speedboat",
        "ship",
        "transportation",
        "vehicle",
        "summer",
        "boat",
        "motorboat",
        "powerboat"
      ],
      "\u{1F6F3}\uFE0F": [
        "passenger_ship",
        "yacht",
        "cruise",
        "ferry",
        "vehicle"
      ],
      "\u26F4\uFE0F": [
        "ferry",
        "boat",
        "ship",
        "yacht",
        "passenger"
      ],
      "\u{1F6E5}\uFE0F": [
        "motor_boat",
        "ship",
        "motorboat",
        "vehicle"
      ],
      "\u{1F6A2}": [
        "ship",
        "transportation",
        "titanic",
        "deploy",
        "boat",
        "cruise",
        "passenger",
        "vehicle"
      ],
      "\u2708\uFE0F": [
        "airplane",
        "vehicle",
        "transportation",
        "flight",
        "fly",
        "aeroplane",
        "plane"
      ],
      "\u{1F6E9}\uFE0F": [
        "small_airplane",
        "flight",
        "transportation",
        "fly",
        "vehicle",
        "aeroplane",
        "plane"
      ],
      "\u{1F6EB}": [
        "airplane_departure",
        "airport",
        "flight",
        "landing",
        "aeroplane",
        "departures",
        "off",
        "plane",
        "taking",
        "vehicle"
      ],
      "\u{1F6EC}": [
        "airplane_arrival",
        "airport",
        "flight",
        "boarding",
        "aeroplane",
        "arrivals",
        "arriving",
        "landing",
        "plane",
        "vehicle"
      ],
      "\u{1FA82}": [
        "parachute",
        "fly",
        "glide",
        "hang",
        "parasail",
        "skydive"
      ],
      "\u{1F4BA}": [
        "seat",
        "sit",
        "airplane",
        "transport",
        "bus",
        "flight",
        "fly",
        "aeroplane",
        "chair",
        "train"
      ],
      "\u{1F681}": [
        "helicopter",
        "transportation",
        "vehicle",
        "fly"
      ],
      "\u{1F69F}": [
        "suspension_railway",
        "vehicle",
        "transportation"
      ],
      "\u{1F6A0}": [
        "mountain_cableway",
        "transportation",
        "vehicle",
        "ski",
        "cable",
        "gondola"
      ],
      "\u{1F6A1}": [
        "aerial_tramway",
        "transportation",
        "vehicle",
        "ski",
        "cable",
        "car",
        "gondola",
        "ropeway"
      ],
      "\u{1F6F0}\uFE0F": [
        "satellite",
        "communication",
        "gps",
        "orbit",
        "spaceflight",
        "NASA",
        "ISS",
        "artificial",
        "space",
        "vehicle"
      ],
      "\u{1F680}": [
        "rocket",
        "launch",
        "ship",
        "staffmode",
        "NASA",
        "outer space",
        "outer_space",
        "fly",
        "shuttle",
        "vehicle",
        "deploy"
      ],
      "\u{1F6F8}": [
        "flying_saucer",
        "transportation",
        "vehicle",
        "ufo",
        "alien",
        "extraterrestrial",
        "fantasy",
        "space"
      ],
      "\u{1F6CE}\uFE0F": [
        "bellhop_bell",
        "service",
        "hotel"
      ],
      "\u{1F9F3}": [
        "luggage",
        "packing",
        "travel",
        "suitcase"
      ],
      "\u231B": [
        "hourglass_done",
        "time",
        "clock",
        "oldschool",
        "limit",
        "exam",
        "quiz",
        "test",
        "sand",
        "timer"
      ],
      "\u23F3": [
        "hourglass_not_done",
        "oldschool",
        "time",
        "countdown",
        "flowing",
        "sand",
        "timer"
      ],
      "\u231A": [
        "watch",
        "time",
        "accessories",
        "apple",
        "clock",
        "timepiece",
        "wrist",
        "wristwatch"
      ],
      "\u23F0": [
        "alarm_clock",
        "time",
        "wake",
        "morning"
      ],
      "\u23F1\uFE0F": [
        "stopwatch",
        "time",
        "deadline",
        "clock"
      ],
      "\u23F2\uFE0F": [
        "timer_clock",
        "alarm"
      ],
      "\u{1F570}\uFE0F": [
        "mantelpiece_clock",
        "time"
      ],
      "\u{1F55B}": [
        "twelve_o_clock",
        "12",
        "00:00",
        "0000",
        "12:00",
        "1200",
        "time",
        "noon",
        "midnight",
        "midday",
        "late",
        "early",
        "schedule",
        "clock12",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F567}": [
        "twelve_thirty",
        "00:30",
        "0030",
        "12:30",
        "1230",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock1230",
        "face"
      ],
      "\u{1F550}": [
        "one_o_clock",
        "1",
        "1:00",
        "100",
        "13:00",
        "1300",
        "time",
        "late",
        "early",
        "schedule",
        "clock1",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F55C}": [
        "one_thirty",
        "1:30",
        "130",
        "13:30",
        "1330",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock130",
        "face"
      ],
      "\u{1F551}": [
        "two_o_clock",
        "2",
        "2:00",
        "200",
        "14:00",
        "1400",
        "time",
        "late",
        "early",
        "schedule",
        "clock2",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F55D}": [
        "two_thirty",
        "2:30",
        "230",
        "14:30",
        "1430",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock230",
        "face"
      ],
      "\u{1F552}": [
        "three_o_clock",
        "3",
        "3:00",
        "300",
        "15:00",
        "1500",
        "time",
        "late",
        "early",
        "schedule",
        "clock3",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F55E}": [
        "three_thirty",
        "3:30",
        "330",
        "15:30",
        "1530",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock330",
        "face"
      ],
      "\u{1F553}": [
        "four_o_clock",
        "4",
        "4:00",
        "400",
        "16:00",
        "1600",
        "time",
        "late",
        "early",
        "schedule",
        "clock4",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F55F}": [
        "four_thirty",
        "4:30",
        "430",
        "16:30",
        "1630",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock430",
        "face"
      ],
      "\u{1F554}": [
        "five_o_clock",
        "5",
        "5:00",
        "500",
        "17:00",
        "1700",
        "time",
        "late",
        "early",
        "schedule",
        "clock5",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F560}": [
        "five_thirty",
        "5:30",
        "530",
        "17:30",
        "1730",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock530",
        "face"
      ],
      "\u{1F555}": [
        "six_o_clock",
        "6",
        "6:00",
        "600",
        "18:00",
        "1800",
        "time",
        "late",
        "early",
        "schedule",
        "dawn",
        "dusk",
        "clock6",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F561}": [
        "six_thirty",
        "6:30",
        "630",
        "18:30",
        "1830",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock630",
        "face"
      ],
      "\u{1F556}": [
        "seven_o_clock",
        "7",
        "7:00",
        "700",
        "19:00",
        "1900",
        "time",
        "late",
        "early",
        "schedule",
        "clock7",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F562}": [
        "seven_thirty",
        "7:30",
        "730",
        "19:30",
        "1930",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock730",
        "face"
      ],
      "\u{1F557}": [
        "eight_o_clock",
        "8",
        "8:00",
        "800",
        "20:00",
        "2000",
        "time",
        "late",
        "early",
        "schedule",
        "clock8",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F563}": [
        "eight_thirty",
        "8:30",
        "830",
        "20:30",
        "2030",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock830",
        "face"
      ],
      "\u{1F558}": [
        "nine_o_clock",
        "9",
        "9:00",
        "900",
        "21:00",
        "2100",
        "time",
        "late",
        "early",
        "schedule",
        "clock9",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F564}": [
        "nine_thirty",
        "9:30",
        "930",
        "21:30",
        "2130",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock930",
        "face"
      ],
      "\u{1F559}": [
        "ten_o_clock",
        "10",
        "10:00",
        "1000",
        "22:00",
        "2200",
        "time",
        "late",
        "early",
        "schedule",
        "clock10",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F565}": [
        "ten_thirty",
        "10:30",
        "1030",
        "22:30",
        "2230",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock1030",
        "face"
      ],
      "\u{1F55A}": [
        "eleven_o_clock",
        "11",
        "11:00",
        "1100",
        "23:00",
        "2300",
        "time",
        "late",
        "early",
        "schedule",
        "clock11",
        "face",
        "oclock",
        "o\u2019clock"
      ],
      "\u{1F566}": [
        "eleven_thirty",
        "11:30",
        "1130",
        "23:30",
        "2330",
        "time",
        "late",
        "early",
        "schedule",
        "clock",
        "clock1130",
        "face"
      ],
      "\u{1F311}": [
        "new_moon",
        "nature",
        "twilight",
        "planet",
        "space",
        "night",
        "evening",
        "sleep",
        "dark",
        "eclipse",
        "shadow\xA0moon",
        "solar",
        "symbol",
        "weather"
      ],
      "\u{1F312}": [
        "waxing_crescent_moon",
        "nature",
        "twilight",
        "planet",
        "space",
        "night",
        "evening",
        "sleep",
        "symbol",
        "weather"
      ],
      "\u{1F313}": [
        "first_quarter_moon",
        "nature",
        "twilight",
        "planet",
        "space",
        "night",
        "evening",
        "sleep",
        "symbol",
        "weather"
      ],
      "\u{1F314}": [
        "waxing_gibbous_moon",
        "nature",
        "night",
        "sky",
        "gray",
        "twilight",
        "planet",
        "space",
        "evening",
        "sleep",
        "symbol",
        "weather"
      ],
      "\u{1F315}": [
        "full_moon",
        "nature",
        "yellow",
        "twilight",
        "planet",
        "space",
        "night",
        "evening",
        "sleep",
        "symbol",
        "weather"
      ],
      "\u{1F316}": [
        "waning_gibbous_moon",
        "nature",
        "twilight",
        "planet",
        "space",
        "night",
        "evening",
        "sleep",
        "waxing_gibbous_moon",
        "symbol",
        "weather"
      ],
      "\u{1F317}": [
        "last_quarter_moon",
        "nature",
        "twilight",
        "planet",
        "space",
        "night",
        "evening",
        "sleep",
        "symbol",
        "weather"
      ],
      "\u{1F318}": [
        "waning_crescent_moon",
        "nature",
        "twilight",
        "planet",
        "space",
        "night",
        "evening",
        "sleep",
        "symbol",
        "weather"
      ],
      "\u{1F319}": [
        "crescent_moon",
        "night",
        "sleep",
        "sky",
        "evening",
        "magic",
        "space",
        "weather"
      ],
      "\u{1F31A}": [
        "new_moon_face",
        "nature",
        "twilight",
        "planet",
        "space",
        "night",
        "evening",
        "sleep",
        "creepy",
        "dark",
        "molester",
        "weather"
      ],
      "\u{1F31B}": [
        "first_quarter_moon_face",
        "nature",
        "twilight",
        "planet",
        "space",
        "night",
        "evening",
        "sleep",
        "weather"
      ],
      "\u{1F31C}": [
        "last_quarter_moon_face",
        "nature",
        "twilight",
        "planet",
        "space",
        "night",
        "evening",
        "sleep",
        "weather"
      ],
      "\u{1F321}\uFE0F": [
        "thermometer",
        "weather",
        "temperature",
        "hot",
        "cold"
      ],
      "\u2600\uFE0F": [
        "sun",
        "weather",
        "nature",
        "brightness",
        "summer",
        "beach",
        "spring",
        "black",
        "bright",
        "rays",
        "space",
        "sunny",
        "sunshine"
      ],
      "\u{1F31D}": [
        "full_moon_face",
        "nature",
        "twilight",
        "planet",
        "space",
        "night",
        "evening",
        "sleep",
        "bright",
        "moonface",
        "smiley",
        "smiling",
        "weather"
      ],
      "\u{1F31E}": [
        "sun_with_face",
        "nature",
        "morning",
        "sky",
        "bright",
        "smiley",
        "smiling",
        "space",
        "summer",
        "sunface",
        "weather"
      ],
      "\u{1FA90}": [
        "ringed_planet",
        "outerspace",
        "planets",
        "saturn",
        "saturnine",
        "space"
      ],
      "\u2B50": [
        "star",
        "night",
        "yellow",
        "gold",
        "medium",
        "white"
      ],
      "\u{1F31F}": [
        "glowing_star",
        "night",
        "sparkle",
        "awesome",
        "good",
        "magic",
        "glittery",
        "glow",
        "shining",
        "star2"
      ],
      "\u{1F320}": [
        "shooting_star",
        "night",
        "photo",
        "activity",
        "falling",
        "meteoroid",
        "space",
        "stars",
        "upon",
        "when",
        "wish",
        "you"
      ],
      "\u{1F30C}": [
        "milky_way",
        "photo",
        "space",
        "stars",
        "galaxy",
        "night",
        "sky",
        "universe",
        "weather"
      ],
      "\u2601\uFE0F": [
        "cloud",
        "weather",
        "sky",
        "cloudy",
        "overcast"
      ],
      "\u26C5": [
        "sun_behind_cloud",
        "weather",
        "nature",
        "cloudy",
        "morning",
        "fall",
        "spring",
        "partly",
        "sunny"
      ],
      "\u26C8\uFE0F": [
        "cloud_with_lightning_and_rain",
        "weather",
        "lightning",
        "thunder"
      ],
      "\u{1F324}\uFE0F": [
        "sun_behind_small_cloud",
        "weather",
        "white"
      ],
      "\u{1F325}\uFE0F": [
        "sun_behind_large_cloud",
        "weather",
        "white"
      ],
      "\u{1F326}\uFE0F": [
        "sun_behind_rain_cloud",
        "weather",
        "white"
      ],
      "\u{1F327}\uFE0F": [
        "cloud_with_rain",
        "weather"
      ],
      "\u{1F328}\uFE0F": [
        "cloud_with_snow",
        "weather",
        "cold"
      ],
      "\u{1F329}\uFE0F": [
        "cloud_with_lightning",
        "weather",
        "thunder"
      ],
      "\u{1F32A}\uFE0F": [
        "tornado",
        "weather",
        "cyclone",
        "twister",
        "cloud",
        "whirlwind"
      ],
      "\u{1F32B}\uFE0F": [
        "fog",
        "weather",
        "cloud"
      ],
      "\u{1F32C}\uFE0F": [
        "wind_face",
        "gust",
        "air",
        "blow",
        "blowing",
        "cloud",
        "mother",
        "nature",
        "weather"
      ],
      "\u{1F300}": [
        "cyclone",
        "weather",
        "swirl",
        "blue",
        "cloud",
        "vortex",
        "spiral",
        "whirlpool",
        "spin",
        "tornado",
        "hurricane",
        "typhoon",
        "dizzy",
        "twister"
      ],
      "\u{1F308}": [
        "rainbow",
        "nature",
        "happy",
        "unicorn_face",
        "photo",
        "sky",
        "spring",
        "gay",
        "lgbt",
        "pride",
        "primary",
        "rain",
        "weather"
      ],
      "\u{1F302}": [
        "closed_umbrella",
        "weather",
        "rain",
        "drizzle",
        "clothing",
        "collapsed\xA0umbrella",
        "pink"
      ],
      "\u2602\uFE0F": [
        "umbrella",
        "weather",
        "spring",
        "clothing",
        "open",
        "rain"
      ],
      "\u2614": [
        "umbrella_with_rain_drops",
        "rainy",
        "weather",
        "spring",
        "clothing",
        "drop",
        "raining"
      ],
      "\u26F1\uFE0F": [
        "umbrella_on_ground",
        "weather",
        "summer",
        "beach",
        "parasol",
        "rain",
        "sun"
      ],
      "\u26A1": [
        "high_voltage",
        "thunder",
        "weather",
        "lightning bolt",
        "fast",
        "zap",
        "danger",
        "electric",
        "electricity",
        "sign",
        "thunderbolt",
        "speed"
      ],
      "\u2744\uFE0F": [
        "snowflake",
        "winter",
        "season",
        "cold",
        "weather",
        "christmas",
        "xmas",
        "snow",
        "snowing"
      ],
      "\u2603\uFE0F": [
        "snowman",
        "winter",
        "season",
        "cold",
        "weather",
        "christmas",
        "xmas",
        "frozen",
        "snow",
        "snowflakes",
        "snowing"
      ],
      "\u26C4": [
        "snowman_without_snow",
        "winter",
        "season",
        "cold",
        "weather",
        "christmas",
        "xmas",
        "frozen",
        "without_snow",
        "frosty",
        "olaf"
      ],
      "\u2604\uFE0F": [
        "comet",
        "space"
      ],
      "\u{1F525}": [
        "fire",
        "hot",
        "cook",
        "flame",
        "burn",
        "lit",
        "snapstreak",
        "tool",
        "remove"
      ],
      "\u{1F4A7}": [
        "droplet",
        "water",
        "drip",
        "faucet",
        "spring",
        "cold",
        "comic",
        "drop",
        "sweat",
        "weather"
      ],
      "\u{1F30A}": [
        "water_wave",
        "sea",
        "water",
        "wave",
        "nature",
        "tsunami",
        "disaster",
        "beach",
        "ocean",
        "waves",
        "weather"
      ],
      "\u{1F383}": [
        "jack_o_lantern",
        "halloween",
        "light",
        "pumpkin",
        "creepy",
        "fall",
        "activity",
        "celebration",
        "entertainment",
        "gourd"
      ],
      "\u{1F384}": [
        "christmas_tree",
        "festival",
        "vacation",
        "december",
        "xmas",
        "celebration",
        "activity",
        "entertainment",
        "xmas\xA0tree"
      ],
      "\u{1F386}": [
        "fireworks",
        "photo",
        "festival",
        "carnival",
        "congratulations",
        "activity",
        "celebration",
        "entertainment",
        "explosion"
      ],
      "\u{1F387}": [
        "sparkler",
        "stars",
        "night",
        "shine",
        "activity",
        "celebration",
        "entertainment",
        "firework",
        "fireworks",
        "hanabi",
        "senko",
        "sparkle"
      ],
      "\u{1F9E8}": [
        "firecracker",
        "dynamite",
        "boom",
        "explode",
        "explosion",
        "explosive",
        "fireworks"
      ],
      "\u2728": [
        "sparkles",
        "stars",
        "shine",
        "shiny",
        "cool",
        "awesome",
        "good",
        "magic",
        "entertainment",
        "glitter",
        "sparkle",
        "star"
      ],
      "\u{1F388}": [
        "balloon",
        "party",
        "celebration",
        "birthday",
        "circus",
        "activity",
        "entertainment",
        "red"
      ],
      "\u{1F389}": [
        "party_popper",
        "party",
        "congratulations",
        "birthday",
        "magic",
        "circus",
        "celebration",
        "tada",
        "activity",
        "entertainment",
        "hat",
        "hooray"
      ],
      "\u{1F38A}": [
        "confetti_ball",
        "festival",
        "party",
        "birthday",
        "circus",
        "activity",
        "celebration",
        "entertainment"
      ],
      "\u{1F38B}": [
        "tanabata_tree",
        "plant",
        "nature",
        "branch",
        "summer",
        "bamboo",
        "wish",
        "star_festival",
        "tanzaku",
        "activity",
        "banner",
        "celebration",
        "entertainment",
        "japanese"
      ],
      "\u{1F38D}": [
        "pine_decoration",
        "japanese",
        "plant",
        "nature",
        "vegetable",
        "panda",
        "new_years",
        "bamboo",
        "activity",
        "celebration",
        "kadomatsu",
        "year"
      ],
      "\u{1F38E}": [
        "japanese_dolls",
        "japanese",
        "toy",
        "kimono",
        "activity",
        "celebration",
        "doll",
        "entertainment",
        "festival",
        "hinamatsuri",
        "imperial"
      ],
      "\u{1F38F}": [
        "carp_streamer",
        "fish",
        "japanese",
        "koinobori",
        "carp",
        "banner",
        "activity",
        "celebration",
        "entertainment",
        "flag",
        "flags",
        "socks",
        "wind"
      ],
      "\u{1F390}": [
        "wind_chime",
        "nature",
        "ding",
        "spring",
        "bell",
        "activity",
        "celebration",
        "entertainment",
        "furin",
        "jellyfish"
      ],
      "\u{1F391}": [
        "moon_viewing_ceremony",
        "photo",
        "japan",
        "asia",
        "tsukimi",
        "activity",
        "autumn",
        "celebration",
        "dumplings",
        "entertainment",
        "festival",
        "grass",
        "harvest",
        "mid",
        "rice",
        "scene"
      ],
      "\u{1F9E7}": [
        "red_envelope",
        "gift",
        "ang",
        "good",
        "h\xF3ngb\u0101o",
        "lai",
        "luck",
        "money",
        "packet",
        "pao",
        "see"
      ],
      "\u{1F380}": [
        "ribbon",
        "decoration",
        "pink",
        "girl",
        "bowtie",
        "bow",
        "celebration"
      ],
      "\u{1F381}": [
        "wrapped_gift",
        "present",
        "birthday",
        "christmas",
        "xmas",
        "box",
        "celebration",
        "entertainment"
      ],
      "\u{1F397}\uFE0F": [
        "reminder_ribbon",
        "sports",
        "cause",
        "support",
        "awareness",
        "celebration"
      ],
      "\u{1F39F}\uFE0F": [
        "admission_tickets",
        "sports",
        "concert",
        "entrance",
        "entertainment",
        "ticket"
      ],
      "\u{1F3AB}": [
        "ticket",
        "event",
        "concert",
        "pass",
        "activity",
        "admission",
        "entertainment",
        "stub",
        "tour",
        "world"
      ],
      "\u{1F396}\uFE0F": [
        "military_medal",
        "award",
        "winning",
        "army",
        "celebration",
        "decoration",
        "medallion"
      ],
      "\u{1F3C6}": [
        "trophy",
        "win",
        "award",
        "contest",
        "place",
        "ftw",
        "ceremony",
        "championship",
        "prize",
        "winner",
        "winners"
      ],
      "\u{1F3C5}": [
        "sports_medal",
        "award",
        "winning",
        "gold",
        "winner"
      ],
      "\u{1F947}": [
        "1st_place_medal",
        "award",
        "winning",
        "first",
        "gold"
      ],
      "\u{1F948}": [
        "2nd_place_medal",
        "award",
        "second",
        "silver"
      ],
      "\u{1F949}": [
        "3rd_place_medal",
        "award",
        "third",
        "bronze"
      ],
      "\u26BD": [
        "soccer_ball",
        "sports",
        "football"
      ],
      "\u26BE": [
        "baseball",
        "sports",
        "balls",
        "ball",
        "softball"
      ],
      "\u{1F94E}": [
        "softball",
        "sports",
        "balls",
        "ball",
        "game",
        "glove",
        "sport",
        "underarm"
      ],
      "\u{1F3C0}": [
        "basketball",
        "sports",
        "balls",
        "NBA",
        "ball",
        "hoop",
        "orange"
      ],
      "\u{1F3D0}": [
        "volleyball",
        "sports",
        "balls",
        "ball",
        "game"
      ],
      "\u{1F3C8}": [
        "american_football",
        "sports",
        "balls",
        "NFL",
        "ball",
        "gridiron",
        "superbowl"
      ],
      "\u{1F3C9}": [
        "rugby_football",
        "sports",
        "team",
        "ball",
        "league",
        "union"
      ],
      "\u{1F3BE}": [
        "tennis",
        "sports",
        "balls",
        "green",
        "ball",
        "racket",
        "racquet"
      ],
      "\u{1F94F}": [
        "flying_disc",
        "sports",
        "frisbee",
        "ultimate",
        "game",
        "golf",
        "sport"
      ],
      "\u{1F3B3}": [
        "bowling",
        "sports",
        "fun",
        "play",
        "ball",
        "game",
        "pin",
        "pins",
        "skittles",
        "ten"
      ],
      "\u{1F3CF}": [
        "cricket_game",
        "sports",
        "ball",
        "bat",
        "field"
      ],
      "\u{1F3D1}": [
        "field_hockey",
        "sports",
        "ball",
        "game",
        "stick"
      ],
      "\u{1F3D2}": [
        "ice_hockey",
        "sports",
        "game",
        "puck",
        "stick"
      ],
      "\u{1F94D}": [
        "lacrosse",
        "sports",
        "ball",
        "stick",
        "game",
        "goal",
        "sport"
      ],
      "\u{1F3D3}": [
        "ping_pong",
        "sports",
        "pingpong",
        "ball",
        "bat",
        "game",
        "paddle",
        "table",
        "tennis"
      ],
      "\u{1F3F8}": [
        "badminton",
        "sports",
        "birdie",
        "game",
        "racquet",
        "shuttlecock"
      ],
      "\u{1F94A}": [
        "boxing_glove",
        "sports",
        "fighting"
      ],
      "\u{1F94B}": [
        "martial_arts_uniform",
        "judo",
        "karate",
        "taekwondo"
      ],
      "\u{1F945}": [
        "goal_net",
        "sports",
        "catch"
      ],
      "\u26F3": [
        "flag_in_hole",
        "sports",
        "business",
        "flag",
        "hole",
        "summer",
        "golf"
      ],
      "\u26F8\uFE0F": [
        "ice_skate",
        "sports",
        "skating"
      ],
      "\u{1F3A3}": [
        "fishing_pole",
        "food",
        "hobby",
        "summer",
        "entertainment",
        "fish",
        "rod"
      ],
      "\u{1F93F}": [
        "diving_mask",
        "sport",
        "ocean",
        "scuba",
        "snorkeling"
      ],
      "\u{1F3BD}": [
        "running_shirt",
        "play",
        "pageant",
        "athletics",
        "marathon",
        "sash",
        "singlet"
      ],
      "\u{1F3BF}": [
        "skis",
        "sports",
        "winter",
        "cold",
        "snow",
        "boot",
        "ski",
        "skiing"
      ],
      "\u{1F6F7}": [
        "sled",
        "sleigh",
        "luge",
        "toboggan",
        "sledge"
      ],
      "\u{1F94C}": [
        "curling_stone",
        "sports",
        "game",
        "rock"
      ],
      "\u{1F3AF}": [
        "direct_hit",
        "game",
        "play",
        "bar",
        "target",
        "bullseye",
        "activity",
        "archery",
        "bull",
        "dart",
        "darts",
        "entertainment",
        "eye"
      ],
      "\u{1FA80}": [
        "yo_yo",
        "toy",
        "fluctuate",
        "yoyo"
      ],
      "\u{1FA81}": [
        "kite",
        "wind",
        "fly",
        "soar",
        "toy"
      ],
      "\u{1F3B1}": [
        "pool_8_ball",
        "pool",
        "hobby",
        "game",
        "luck",
        "magic",
        "8ball",
        "billiard",
        "billiards",
        "cue",
        "eight",
        "snooker"
      ],
      "\u{1F52E}": [
        "crystal_ball",
        "disco",
        "party",
        "magic",
        "circus",
        "fortune_teller",
        "clairvoyant",
        "fairy",
        "fantasy",
        "psychic",
        "purple",
        "tale",
        "tool"
      ],
      "\u{1F9FF}": [
        "nazar_amulet",
        "bead",
        "charm",
        "boncu\u011Fu",
        "evil",
        "eye",
        "talisman"
      ],
      "\u{1F3AE}": [
        "video_game",
        "play",
        "console",
        "PS4",
        "controller",
        "entertainment",
        "gamepad",
        "playstation",
        "u",
        "wii",
        "xbox"
      ],
      "\u{1F579}\uFE0F": [
        "joystick",
        "game",
        "play",
        "entertainment",
        "video"
      ],
      "\u{1F3B0}": [
        "slot_machine",
        "bet",
        "gamble",
        "vegas",
        "fruit machine",
        "luck",
        "casino",
        "activity",
        "gambling",
        "game",
        "poker"
      ],
      "\u{1F3B2}": [
        "game_die",
        "dice",
        "random",
        "tabletop",
        "play",
        "luck",
        "entertainment",
        "gambling"
      ],
      "\u{1F9E9}": [
        "puzzle_piece",
        "interlocking",
        "puzzle",
        "piece",
        "clue",
        "jigsaw"
      ],
      "\u{1F9F8}": [
        "teddy_bear",
        "plush",
        "stuffed",
        "plaything",
        "toy"
      ],
      "\u2660\uFE0F": [
        "spade_suit",
        "poker",
        "cards",
        "suits",
        "magic",
        "black",
        "card",
        "game",
        "spades"
      ],
      "\u2665\uFE0F": [
        "heart_suit",
        "poker",
        "cards",
        "magic",
        "suits",
        "black",
        "card",
        "game",
        "hearts"
      ],
      "\u2666\uFE0F": [
        "diamond_suit",
        "poker",
        "cards",
        "magic",
        "suits",
        "black",
        "card",
        "diamonds",
        "game"
      ],
      "\u2663\uFE0F": [
        "club_suit",
        "poker",
        "cards",
        "magic",
        "suits",
        "black",
        "card",
        "clubs",
        "game"
      ],
      "\u265F\uFE0F": [
        "chess_pawn",
        "expendable",
        "black",
        "dupe",
        "game",
        "piece"
      ],
      "\u{1F0CF}": [
        "joker",
        "poker",
        "cards",
        "game",
        "play",
        "magic",
        "black",
        "card",
        "entertainment",
        "playing",
        "wildcard"
      ],
      "\u{1F004}": [
        "mahjong_red_dragon",
        "game",
        "play",
        "chinese",
        "kanji",
        "tile"
      ],
      "\u{1F3B4}": [
        "flower_playing_cards",
        "game",
        "sunset",
        "red",
        "activity",
        "card",
        "deck",
        "entertainment",
        "hanafuda",
        "hwatu",
        "japanese",
        "of\xA0cards"
      ],
      "\u{1F3AD}": [
        "performing_arts",
        "acting",
        "theater",
        "drama",
        "activity",
        "art",
        "comedy",
        "entertainment",
        "greek",
        "logo",
        "mask",
        "masks",
        "theatre",
        "theatre\xA0masks",
        "tragedy"
      ],
      "\u{1F5BC}\uFE0F": [
        "framed_picture",
        "photography",
        "art",
        "frame",
        "museum",
        "painting"
      ],
      "\u{1F3A8}": [
        "artist_palette",
        "design",
        "paint",
        "draw",
        "colors",
        "activity",
        "art",
        "entertainment",
        "museum",
        "painting",
        "improve"
      ],
      "\u{1F9F5}": [
        "thread",
        "needle",
        "sewing",
        "spool",
        "string",
        "crafts"
      ],
      "\u{1F9F6}": [
        "yarn",
        "ball",
        "crochet",
        "knit",
        "crafts"
      ],
      "\u{1F453}": [
        "glasses",
        "fashion",
        "accessories",
        "eyesight",
        "nerdy",
        "dork",
        "geek",
        "clothing",
        "eye",
        "eyeglasses",
        "eyewear"
      ],
      "\u{1F576}\uFE0F": [
        "sunglasses",
        "face",
        "cool",
        "accessories",
        "dark",
        "eye",
        "eyewear",
        "glasses"
      ],
      "\u{1F97D}": [
        "goggles",
        "eyes",
        "protection",
        "safety",
        "clothing",
        "eye",
        "swimming",
        "welding"
      ],
      "\u{1F97C}": [
        "lab_coat",
        "doctor",
        "experiment",
        "scientist",
        "chemist",
        "clothing"
      ],
      "\u{1F9BA}": [
        "safety_vest",
        "protection",
        "emergency"
      ],
      "\u{1F454}": [
        "necktie",
        "shirt",
        "suitup",
        "formal",
        "fashion",
        "cloth",
        "business",
        "clothing",
        "tie"
      ],
      "\u{1F455}": [
        "t_shirt",
        "fashion",
        "cloth",
        "casual",
        "shirt",
        "tee",
        "clothing",
        "polo",
        "tshirt"
      ],
      "\u{1F456}": [
        "jeans",
        "fashion",
        "shopping",
        "clothing",
        "denim",
        "pants",
        "trousers"
      ],
      "\u{1F9E3}": [
        "scarf",
        "neck",
        "winter",
        "clothes",
        "clothing"
      ],
      "\u{1F9E4}": [
        "gloves",
        "hands",
        "winter",
        "clothes",
        "clothing",
        "hand"
      ],
      "\u{1F9E5}": [
        "coat",
        "jacket",
        "clothing"
      ],
      "\u{1F9E6}": [
        "socks",
        "stockings",
        "clothes",
        "clothing",
        "pair",
        "stocking"
      ],
      "\u{1F457}": [
        "dress",
        "clothes",
        "fashion",
        "shopping",
        "clothing",
        "gown",
        "skirt"
      ],
      "\u{1F458}": [
        "kimono",
        "dress",
        "fashion",
        "women",
        "female",
        "japanese",
        "clothing",
        "dressing",
        "gown"
      ],
      "\u{1F97B}": [
        "sari",
        "dress",
        "clothing",
        "saree",
        "shari"
      ],
      "\u{1FA71}": [
        "one_piece_swimsuit",
        "fashion",
        "bathing",
        "clothing",
        "suit",
        "swim"
      ],
      "\u{1FA72}": [
        "briefs",
        "clothing",
        "bathing",
        "brief",
        "suit",
        "swim",
        "swimsuit",
        "underwear"
      ],
      "\u{1FA73}": [
        "shorts",
        "clothing",
        "bathing",
        "pants",
        "suit",
        "swim",
        "swimsuit",
        "underwear"
      ],
      "\u{1F459}": [
        "bikini",
        "swimming",
        "female",
        "woman",
        "girl",
        "fashion",
        "beach",
        "summer",
        "bathers",
        "clothing",
        "swim",
        "swimsuit"
      ],
      "\u{1F45A}": [
        "woman_s_clothes",
        "fashion",
        "shopping_bags",
        "female",
        "blouse",
        "clothing",
        "pink",
        "shirt",
        "womans",
        "woman\u2019s"
      ],
      "\u{1F45B}": [
        "purse",
        "fashion",
        "accessories",
        "money",
        "sales",
        "shopping",
        "clothing",
        "coin",
        "wallet"
      ],
      "\u{1F45C}": [
        "handbag",
        "fashion",
        "accessory",
        "accessories",
        "shopping",
        "bag",
        "clothing",
        "purse",
        "women\u2019s"
      ],
      "\u{1F45D}": [
        "clutch_bag",
        "bag",
        "accessories",
        "shopping",
        "clothing",
        "pouch",
        "small"
      ],
      "\u{1F6CD}\uFE0F": [
        "shopping_bags",
        "mall",
        "buy",
        "purchase",
        "bag",
        "hotel"
      ],
      "\u{1F392}": [
        "backpack",
        "student",
        "education",
        "bag",
        "activity",
        "rucksack",
        "satchel",
        "school"
      ],
      "\u{1F45E}": [
        "man_s_shoe",
        "fashion",
        "male",
        "brown",
        "clothing",
        "dress",
        "mans",
        "man\u2019s"
      ],
      "\u{1F45F}": [
        "running_shoe",
        "shoes",
        "sports",
        "sneakers",
        "athletic",
        "clothing",
        "runner",
        "sneaker",
        "sport",
        "tennis",
        "trainer"
      ],
      "\u{1F97E}": [
        "hiking_boot",
        "backpacking",
        "camping",
        "hiking",
        "clothing"
      ],
      "\u{1F97F}": [
        "flat_shoe",
        "ballet",
        "slip-on",
        "slipper",
        "clothing",
        "woman\u2019s"
      ],
      "\u{1F460}": [
        "high_heeled_shoe",
        "fashion",
        "shoes",
        "female",
        "pumps",
        "stiletto",
        "clothing",
        "heel",
        "heels",
        "woman"
      ],
      "\u{1F461}": [
        "woman_s_sandal",
        "shoes",
        "fashion",
        "flip flops",
        "clothing",
        "heeled",
        "sandals",
        "shoe",
        "womans",
        "woman\u2019s"
      ],
      "\u{1FA70}": [
        "ballet_shoes",
        "dance",
        "clothing",
        "pointe",
        "shoe"
      ],
      "\u{1F462}": [
        "woman_s_boot",
        "shoes",
        "fashion",
        "boots",
        "clothing",
        "cowgirl",
        "heeled",
        "high",
        "knee",
        "shoe",
        "womans",
        "woman\u2019s"
      ],
      "\u{1F451}": [
        "crown",
        "king",
        "kod",
        "leader",
        "royalty",
        "lord",
        "clothing",
        "queen",
        "royal"
      ],
      "\u{1F452}": [
        "woman_s_hat",
        "fashion",
        "accessories",
        "female",
        "lady",
        "spring",
        "bow",
        "clothing",
        "ladies",
        "womans",
        "woman\u2019s"
      ],
      "\u{1F3A9}": [
        "top_hat",
        "magic",
        "gentleman",
        "classy",
        "circus",
        "activity",
        "clothing",
        "entertainment",
        "formal",
        "groom",
        "tophat",
        "wear"
      ],
      "\u{1F393}": [
        "graduation_cap",
        "school",
        "college",
        "degree",
        "university",
        "graduation",
        "cap",
        "hat",
        "legal",
        "learn",
        "education",
        "academic",
        "activity",
        "board",
        "celebration",
        "clothing",
        "graduate",
        "mortar",
        "square"
      ],
      "\u{1F9E2}": [
        "billed_cap",
        "cap",
        "baseball",
        "clothing",
        "hat"
      ],
      "\u26D1\uFE0F": [
        "rescue_worker_s_helmet",
        "construction",
        "build",
        "aid",
        "cross",
        "face",
        "hat",
        "white",
        "worker\u2019s"
      ],
      "\u{1F4FF}": [
        "prayer_beads",
        "dhikr",
        "religious",
        "clothing",
        "necklace",
        "religion",
        "rosary"
      ],
      "\u{1F484}": [
        "lipstick",
        "female",
        "girl",
        "fashion",
        "woman",
        "cosmetics",
        "gloss",
        "lip",
        "makeup",
        "style"
      ],
      "\u{1F48D}": [
        "ring",
        "wedding",
        "propose",
        "marriage",
        "valentines",
        "diamond",
        "fashion",
        "jewelry",
        "gem",
        "engagement",
        "engaged",
        "romance"
      ],
      "\u{1F48E}": [
        "gem_stone",
        "blue",
        "ruby",
        "diamond",
        "jewelry",
        "gemstone",
        "jewel",
        "romance"
      ],
      "\u{1F507}": [
        "muted_speaker",
        "sound",
        "volume",
        "silence",
        "quiet",
        "cancellation",
        "mute",
        "off",
        "silent",
        "stroke"
      ],
      "\u{1F508}": [
        "speaker_low_volume",
        "sound",
        "volume",
        "silence",
        "broadcast",
        "soft"
      ],
      "\u{1F509}": [
        "speaker_medium_volume",
        "volume",
        "speaker",
        "broadcast",
        "low",
        "one",
        "reduce",
        "sound",
        "wave"
      ],
      "\u{1F50A}": [
        "speaker_high_volume",
        "volume",
        "noise",
        "noisy",
        "speaker",
        "broadcast",
        "entertainment",
        "increase",
        "loud",
        "sound",
        "three",
        "waves"
      ],
      "\u{1F4E2}": [
        "loudspeaker",
        "volume",
        "sound",
        "address",
        "announcement",
        "bullhorn",
        "communication",
        "loud",
        "megaphone",
        "pa",
        "public",
        "system"
      ],
      "\u{1F4E3}": [
        "megaphone",
        "sound",
        "speaker",
        "volume",
        "bullhorn",
        "cheering",
        "communication",
        "mega"
      ],
      "\u{1F4EF}": [
        "postal_horn",
        "instrument",
        "music",
        "bugle",
        "communication",
        "entertainment",
        "french",
        "post"
      ],
      "\u{1F514}": [
        "bell",
        "sound",
        "notification",
        "christmas",
        "xmas",
        "chime",
        "liberty",
        "ringer",
        "wedding"
      ],
      "\u{1F515}": [
        "bell_with_slash",
        "sound",
        "volume",
        "mute",
        "quiet",
        "silent",
        "cancellation",
        "disabled",
        "forbidden",
        "muted",
        "no",
        "not",
        "notifications",
        "off",
        "prohibited",
        "ringer",
        "stroke"
      ],
      "\u{1F3BC}": [
        "musical_score",
        "treble",
        "clef",
        "compose",
        "activity",
        "entertainment",
        "music",
        "sheet"
      ],
      "\u{1F3B5}": [
        "musical_note",
        "score",
        "tone",
        "sound",
        "activity",
        "beamed",
        "eighth",
        "entertainment",
        "music",
        "notes",
        "pair",
        "quavers"
      ],
      "\u{1F3B6}": [
        "musical_notes",
        "music",
        "score",
        "activity",
        "entertainment",
        "multiple",
        "note",
        "singing"
      ],
      "\u{1F399}\uFE0F": [
        "studio_microphone",
        "sing",
        "recording",
        "artist",
        "talkshow",
        "mic",
        "music",
        "podcast"
      ],
      "\u{1F39A}\uFE0F": [
        "level_slider",
        "scale",
        "music"
      ],
      "\u{1F39B}\uFE0F": [
        "control_knobs",
        "dial",
        "music"
      ],
      "\u{1F3A4}": [
        "microphone",
        "sound",
        "music",
        "PA",
        "sing",
        "talkshow",
        "activity",
        "entertainment",
        "karaoke",
        "mic",
        "singing"
      ],
      "\u{1F3A7}": [
        "headphone",
        "music",
        "score",
        "gadgets",
        "activity",
        "earbud",
        "earphone",
        "earphones",
        "entertainment",
        "headphones",
        "ipod"
      ],
      "\u{1F4FB}": [
        "radio",
        "communication",
        "music",
        "podcast",
        "program",
        "digital",
        "entertainment",
        "video",
        "wireless"
      ],
      "\u{1F3B7}": [
        "saxophone",
        "music",
        "instrument",
        "jazz",
        "blues",
        "activity",
        "entertainment",
        "sax"
      ],
      "\u{1F3B8}": [
        "guitar",
        "music",
        "instrument",
        "acoustic\xA0guitar",
        "activity",
        "bass",
        "electric",
        "entertainment",
        "rock"
      ],
      "\u{1F3B9}": [
        "musical_keyboard",
        "piano",
        "instrument",
        "compose",
        "activity",
        "entertainment",
        "music"
      ],
      "\u{1F3BA}": [
        "trumpet",
        "music",
        "brass",
        "activity",
        "entertainment",
        "horn",
        "instrument",
        "jazz"
      ],
      "\u{1F3BB}": [
        "violin",
        "music",
        "instrument",
        "orchestra",
        "symphony",
        "activity",
        "entertainment",
        "quartet",
        "smallest",
        "string",
        "world\u2019s"
      ],
      "\u{1FA95}": [
        "banjo",
        "music",
        "instructment",
        "activity",
        "entertainment",
        "instrument",
        "stringed"
      ],
      "\u{1F941}": [
        "drum",
        "music",
        "instrument",
        "drumsticks",
        "snare"
      ],
      "\u{1F4F1}": [
        "mobile_phone",
        "technology",
        "apple",
        "gadgets",
        "dial",
        "cell",
        "communication",
        "iphone",
        "smartphone",
        "telephone",
        "responsive_design"
      ],
      "\u{1F4F2}": [
        "mobile_phone_with_arrow",
        "iphone",
        "incoming",
        "call",
        "calling",
        "cell",
        "communication",
        "left",
        "pointing",
        "receive",
        "rightwards",
        "telephone"
      ],
      "\u260E\uFE0F": [
        "telephone",
        "technology",
        "communication",
        "dial",
        "black",
        "phone",
        "rotary"
      ],
      "\u{1F4DE}": [
        "telephone_receiver",
        "technology",
        "communication",
        "dial",
        "call",
        "handset",
        "phone"
      ],
      "\u{1F4DF}": [
        "pager",
        "bbcall",
        "oldschool",
        "90s",
        "beeper",
        "bleeper",
        "communication"
      ],
      "\u{1F4E0}": [
        "fax_machine",
        "communication",
        "technology",
        "facsimile"
      ],
      "\u{1F50B}": [
        "battery",
        "power",
        "energy",
        "sustain",
        "aa",
        "phone"
      ],
      "\u{1F50C}": [
        "electric_plug",
        "charger",
        "power",
        "ac",
        "adaptor",
        "cable",
        "electricity"
      ],
      "\u{1F4BB}": [
        "laptop",
        "technology",
        "screen",
        "display",
        "monitor",
        "computer",
        "desktop",
        "notebook",
        "pc",
        "personal"
      ],
      "\u{1F5A5}\uFE0F": [
        "desktop_computer",
        "technology",
        "computing",
        "screen",
        "imac"
      ],
      "\u{1F5A8}\uFE0F": [
        "printer",
        "paper",
        "ink",
        "computer"
      ],
      "\u2328\uFE0F": [
        "keyboard",
        "technology",
        "computer",
        "type",
        "input",
        "text"
      ],
      "\u{1F5B1}\uFE0F": [
        "computer_mouse",
        "click",
        "button",
        "three"
      ],
      "\u{1F5B2}\uFE0F": [
        "trackball",
        "technology",
        "trackpad",
        "computer"
      ],
      "\u{1F4BD}": [
        "computer_disk",
        "technology",
        "record",
        "data",
        "disk",
        "90s",
        "entertainment",
        "minidisc",
        "minidisk",
        "optical"
      ],
      "\u{1F4BE}": [
        "floppy_disk",
        "oldschool",
        "technology",
        "save",
        "90s",
        "80s",
        "computer"
      ],
      "\u{1F4BF}": [
        "optical_disk",
        "technology",
        "dvd",
        "disk",
        "disc",
        "90s",
        "cd",
        "compact",
        "computer",
        "rom"
      ],
      "\u{1F4C0}": [
        "dvd",
        "cd",
        "disk",
        "disc",
        "computer",
        "entertainment",
        "optical",
        "rom",
        "video"
      ],
      "\u{1F9EE}": [
        "abacus",
        "calculation",
        "count",
        "counting",
        "frame",
        "math"
      ],
      "\u{1F3A5}": [
        "movie_camera",
        "film",
        "record",
        "activity",
        "cinema",
        "entertainment",
        "hollywood",
        "video"
      ],
      "\u{1F39E}\uFE0F": [
        "film_frames",
        "movie",
        "cinema",
        "entertainment",
        "strip"
      ],
      "\u{1F4FD}\uFE0F": [
        "film_projector",
        "video",
        "tape",
        "record",
        "movie",
        "cinema",
        "entertainment"
      ],
      "\u{1F3AC}": [
        "clapper_board",
        "movie",
        "film",
        "record",
        "activity",
        "clapboard",
        "director",
        "entertainment",
        "slate"
      ],
      "\u{1F4FA}": [
        "television",
        "technology",
        "program",
        "oldschool",
        "show",
        "entertainment",
        "tv",
        "video"
      ],
      "\u{1F4F7}": [
        "camera",
        "gadgets",
        "photography",
        "digital",
        "entertainment",
        "photo",
        "video"
      ],
      "\u{1F4F8}": [
        "camera_with_flash",
        "photography",
        "gadgets",
        "photo",
        "video",
        "snapshots"
      ],
      "\u{1F4F9}": [
        "video_camera",
        "film",
        "record",
        "camcorder",
        "entertainment"
      ],
      "\u{1F4FC}": [
        "videocassette",
        "record",
        "video",
        "oldschool",
        "90s",
        "80s",
        "entertainment",
        "tape",
        "vcr",
        "vhs"
      ],
      "\u{1F50D}": [
        "magnifying_glass_tilted_left",
        "search",
        "zoom",
        "find",
        "detective",
        "icon",
        "mag",
        "magnifier",
        "pointing",
        "tool"
      ],
      "\u{1F50E}": [
        "magnifying_glass_tilted_right",
        "search",
        "zoom",
        "find",
        "detective",
        "icon",
        "mag",
        "magnifier",
        "pointing",
        "tool",
        "seo"
      ],
      "\u{1F56F}\uFE0F": [
        "candle",
        "fire",
        "wax",
        "light"
      ],
      "\u{1F4A1}": [
        "light_bulb",
        "light",
        "electricity",
        "idea",
        "comic",
        "electric"
      ],
      "\u{1F526}": [
        "flashlight",
        "dark",
        "camping",
        "sight",
        "night",
        "electric",
        "light",
        "tool",
        "torch"
      ],
      "\u{1F3EE}": [
        "red_paper_lantern",
        "light",
        "paper",
        "halloween",
        "spooky",
        "asian",
        "bar",
        "izakaya",
        "japanese"
      ],
      "\u{1FA94}": [
        "diya_lamp",
        "lighting",
        "oil"
      ],
      "\u{1F4D4}": [
        "notebook_with_decorative_cover",
        "classroom",
        "notes",
        "record",
        "paper",
        "study",
        "book",
        "decorated"
      ],
      "\u{1F4D5}": [
        "closed_book",
        "read",
        "library",
        "knowledge",
        "textbook",
        "learn",
        "red"
      ],
      "\u{1F4D6}": [
        "open_book",
        "book",
        "read",
        "library",
        "knowledge",
        "literature",
        "learn",
        "study",
        "novel"
      ],
      "\u{1F4D7}": [
        "green_book",
        "read",
        "library",
        "knowledge",
        "study",
        "textbook"
      ],
      "\u{1F4D8}": [
        "blue_book",
        "read",
        "library",
        "knowledge",
        "learn",
        "study",
        "textbook"
      ],
      "\u{1F4D9}": [
        "orange_book",
        "read",
        "library",
        "knowledge",
        "textbook",
        "study"
      ],
      "\u{1F4DA}": [
        "books",
        "literature",
        "library",
        "study",
        "book",
        "pile",
        "stack"
      ],
      "\u{1F4D3}": [
        "notebook",
        "stationery",
        "record",
        "notes",
        "paper",
        "study",
        "black",
        "book",
        "composition",
        "white"
      ],
      "\u{1F4D2}": [
        "ledger",
        "notes",
        "paper",
        "binder",
        "book",
        "bound",
        "notebook",
        "spiral",
        "yellow"
      ],
      "\u{1F4C3}": [
        "page_with_curl",
        "documents",
        "office",
        "paper",
        "curled",
        "curly\xA0page",
        "document",
        "license"
      ],
      "\u{1F4DC}": [
        "scroll",
        "documents",
        "ancient",
        "history",
        "paper",
        "degree",
        "document",
        "parchment"
      ],
      "\u{1F4C4}": [
        "page_facing_up",
        "documents",
        "office",
        "paper",
        "information",
        "document",
        "printed"
      ],
      "\u{1F4F0}": [
        "newspaper",
        "press",
        "headline",
        "communication",
        "news",
        "paper"
      ],
      "\u{1F5DE}\uFE0F": [
        "rolled_up_newspaper",
        "press",
        "headline",
        "delivery",
        "news",
        "paper",
        "roll"
      ],
      "\u{1F4D1}": [
        "bookmark_tabs",
        "favorite",
        "save",
        "order",
        "tidy",
        "mark",
        "marker"
      ],
      "\u{1F516}": [
        "bookmark",
        "favorite",
        "label",
        "save",
        "mark",
        "price",
        "tag"
      ],
      "\u{1F3F7}\uFE0F": [
        "label",
        "sale",
        "tag"
      ],
      "\u{1F4B0}": [
        "money_bag",
        "dollar",
        "payment",
        "coins",
        "sale",
        "cream",
        "moneybag",
        "moneybags",
        "rich"
      ],
      "\u{1F4B4}": [
        "yen_banknote",
        "money",
        "sales",
        "japanese",
        "dollar",
        "currency",
        "bank",
        "banknotes",
        "bill",
        "note",
        "sign"
      ],
      "\u{1F4B5}": [
        "dollar_banknote",
        "money",
        "sales",
        "bill",
        "currency",
        "american",
        "bank",
        "banknotes",
        "note",
        "sign"
      ],
      "\u{1F4B6}": [
        "euro_banknote",
        "money",
        "sales",
        "dollar",
        "currency",
        "bank",
        "banknotes",
        "bill",
        "note",
        "sign"
      ],
      "\u{1F4B7}": [
        "pound_banknote",
        "british",
        "sterling",
        "money",
        "sales",
        "bills",
        "uk",
        "england",
        "currency",
        "bank",
        "banknotes",
        "bill",
        "note",
        "quid",
        "sign",
        "twenty"
      ],
      "\u{1F4B8}": [
        "money_with_wings",
        "dollar",
        "bills",
        "payment",
        "sale",
        "bank",
        "banknote",
        "bill",
        "fly",
        "flying",
        "losing",
        "note"
      ],
      "\u{1F4B3}": [
        "credit_card",
        "money",
        "sales",
        "dollar",
        "bill",
        "payment",
        "shopping",
        "amex",
        "bank",
        "club",
        "diners",
        "mastercard",
        "subscription",
        "visa"
      ],
      "\u{1F9FE}": [
        "receipt",
        "accounting",
        "expenses",
        "bookkeeping",
        "evidence",
        "proof"
      ],
      "\u{1F4B9}": [
        "chart_increasing_with_yen",
        "green-square",
        "graph",
        "presentation",
        "stats",
        "bank",
        "currency",
        "exchange",
        "growth",
        "market",
        "money",
        "rate",
        "rise",
        "sign",
        "trend",
        "upward",
        "upwards"
      ],
      "\u{1F4B1}": [
        "currency_exchange",
        "money",
        "sales",
        "dollar",
        "travel",
        "bank"
      ],
      "\u{1F4B2}": [
        "heavy_dollar_sign",
        "money",
        "sales",
        "payment",
        "currency",
        "buck"
      ],
      "\u2709\uFE0F": [
        "envelope",
        "letter",
        "postal",
        "inbox",
        "communication",
        "email",
        "\u2709\xA0letter"
      ],
      "\u{1F4E7}": [
        "e_mail",
        "communication",
        "inbox",
        "email",
        "letter",
        "symbol"
      ],
      "\u{1F4E8}": [
        "incoming_envelope",
        "email",
        "inbox",
        "communication",
        "fast",
        "letter",
        "lines",
        "mail",
        "receive"
      ],
      "\u{1F4E9}": [
        "envelope_with_arrow",
        "email",
        "communication",
        "above",
        "down",
        "downwards",
        "insert",
        "letter",
        "mail",
        "outgoing",
        "sent"
      ],
      "\u{1F4E4}": [
        "outbox_tray",
        "inbox",
        "email",
        "box",
        "communication",
        "letter",
        "mail",
        "sent"
      ],
      "\u{1F4E5}": [
        "inbox_tray",
        "email",
        "documents",
        "box",
        "communication",
        "letter",
        "mail",
        "receive"
      ],
      "\u{1F4E6}": [
        "package",
        "mail",
        "gift",
        "cardboard",
        "box",
        "moving",
        "communication",
        "parcel",
        "shipping",
        "container"
      ],
      "\u{1F4EB}": [
        "closed_mailbox_with_raised_flag",
        "email",
        "inbox",
        "communication",
        "mail",
        "postbox"
      ],
      "\u{1F4EA}": [
        "closed_mailbox_with_lowered_flag",
        "email",
        "communication",
        "inbox",
        "mail",
        "postbox"
      ],
      "\u{1F4EC}": [
        "open_mailbox_with_raised_flag",
        "email",
        "inbox",
        "communication",
        "mail",
        "postbox"
      ],
      "\u{1F4ED}": [
        "open_mailbox_with_lowered_flag",
        "email",
        "inbox",
        "communication",
        "mail",
        "no",
        "postbox"
      ],
      "\u{1F4EE}": [
        "postbox",
        "email",
        "letter",
        "envelope",
        "communication",
        "mail",
        "mailbox"
      ],
      "\u{1F5F3}\uFE0F": [
        "ballot_box_with_ballot",
        "election",
        "vote",
        "voting"
      ],
      "\u270F\uFE0F": [
        "pencil",
        "stationery",
        "write",
        "paper",
        "writing",
        "school",
        "study",
        "lead",
        "pencil2",
        "typos"
      ],
      "\u2712\uFE0F": [
        "black_nib",
        "pen",
        "stationery",
        "writing",
        "write",
        "fountain",
        "\u2712\xA0fountain"
      ],
      "\u{1F58B}\uFE0F": [
        "fountain_pen",
        "stationery",
        "writing",
        "write",
        "communication",
        "left",
        "lower"
      ],
      "\u{1F58A}\uFE0F": [
        "pen",
        "stationery",
        "writing",
        "write",
        "ballpoint",
        "communication",
        "left",
        "lower"
      ],
      "\u{1F58C}\uFE0F": [
        "paintbrush",
        "drawing",
        "creativity",
        "art",
        "brush",
        "communication",
        "left",
        "lower",
        "painting"
      ],
      "\u{1F58D}\uFE0F": [
        "crayon",
        "drawing",
        "creativity",
        "communication",
        "left",
        "lower"
      ],
      "\u{1F4DD}": [
        "memo",
        "write",
        "documents",
        "stationery",
        "pencil",
        "paper",
        "writing",
        "legal",
        "exam",
        "quiz",
        "test",
        "study",
        "compose",
        "communication",
        "document",
        "memorandum",
        "note",
        "documentation"
      ],
      "\u{1F4BC}": [
        "briefcase",
        "business",
        "documents",
        "work",
        "law",
        "legal",
        "job",
        "career",
        "suitcase"
      ],
      "\u{1F4C1}": [
        "file_folder",
        "documents",
        "business",
        "office",
        "closed",
        "directory",
        "manilla"
      ],
      "\u{1F4C2}": [
        "open_file_folder",
        "documents",
        "load"
      ],
      "\u{1F5C2}\uFE0F": [
        "card_index_dividers",
        "organizing",
        "business",
        "stationery"
      ],
      "\u{1F4C5}": [
        "calendar",
        "schedule",
        "date",
        "day",
        "emoji",
        "july",
        "world"
      ],
      "\u{1F4C6}": [
        "tear_off_calendar",
        "schedule",
        "date",
        "planning",
        "day",
        "desk"
      ],
      "\u{1F5D2}\uFE0F": [
        "spiral_notepad",
        "memo",
        "stationery",
        "note",
        "pad"
      ],
      "\u{1F5D3}\uFE0F": [
        "spiral_calendar",
        "date",
        "schedule",
        "planning",
        "pad"
      ],
      "\u{1F4C7}": [
        "card_index",
        "business",
        "stationery",
        "rolodex",
        "system"
      ],
      "\u{1F4C8}": [
        "chart_increasing",
        "graph",
        "presentation",
        "stats",
        "recovery",
        "business",
        "economics",
        "money",
        "sales",
        "good",
        "success",
        "growth",
        "metrics",
        "pointing",
        "positive\xA0chart",
        "trend",
        "up",
        "upward",
        "upwards",
        "analytics"
      ],
      "\u{1F4C9}": [
        "chart_decreasing",
        "graph",
        "presentation",
        "stats",
        "recession",
        "business",
        "economics",
        "money",
        "sales",
        "bad",
        "failure",
        "down",
        "downwards",
        "down\xA0pointing",
        "metrics",
        "negative\xA0chart",
        "trend"
      ],
      "\u{1F4CA}": [
        "bar_chart",
        "graph",
        "presentation",
        "stats",
        "metrics"
      ],
      "\u{1F4CB}": [
        "clipboard",
        "stationery",
        "documents"
      ],
      "\u{1F4CC}": [
        "pushpin",
        "stationery",
        "mark",
        "here",
        "location",
        "pin",
        "tack",
        "thumb"
      ],
      "\u{1F4CD}": [
        "round_pushpin",
        "stationery",
        "location",
        "map",
        "here",
        "dropped",
        "pin",
        "red"
      ],
      "\u{1F4CE}": [
        "paperclip",
        "documents",
        "stationery",
        "clippy"
      ],
      "\u{1F587}\uFE0F": [
        "linked_paperclips",
        "documents",
        "stationery",
        "communication",
        "link",
        "paperclip"
      ],
      "\u{1F4CF}": [
        "straight_ruler",
        "stationery",
        "calculate",
        "length",
        "math",
        "school",
        "drawing",
        "architect",
        "sketch",
        "edge"
      ],
      "\u{1F4D0}": [
        "triangular_ruler",
        "stationery",
        "math",
        "architect",
        "sketch",
        "set",
        "triangle"
      ],
      "\u2702\uFE0F": [
        "scissors",
        "stationery",
        "cut",
        "black",
        "cutting",
        "tool"
      ],
      "\u{1F5C3}\uFE0F": [
        "card_file_box",
        "business",
        "stationery",
        "database"
      ],
      "\u{1F5C4}\uFE0F": [
        "file_cabinet",
        "filing",
        "organizing"
      ],
      "\u{1F5D1}\uFE0F": [
        "wastebasket",
        "bin",
        "trash",
        "rubbish",
        "garbage",
        "toss",
        "basket",
        "can",
        "litter",
        "wastepaper"
      ],
      "\u{1F512}": [
        "locked",
        "security",
        "password",
        "padlock",
        "closed",
        "lock",
        "private",
        "privacy"
      ],
      "\u{1F513}": [
        "unlocked",
        "privacy",
        "security",
        "lock",
        "open",
        "padlock",
        "unlock"
      ],
      "\u{1F50F}": [
        "locked_with_pen",
        "security",
        "secret",
        "fountain",
        "ink",
        "lock",
        "lock\xA0with",
        "nib",
        "privacy"
      ],
      "\u{1F510}": [
        "locked_with_key",
        "security",
        "privacy",
        "closed",
        "lock",
        "secure",
        "secret"
      ],
      "\u{1F511}": [
        "key",
        "lock",
        "door",
        "password",
        "gold"
      ],
      "\u{1F5DD}\uFE0F": [
        "old_key",
        "lock",
        "door",
        "password",
        "clue"
      ],
      "\u{1F528}": [
        "hammer",
        "tools",
        "build",
        "create",
        "claw",
        "handyman",
        "tool"
      ],
      "\u{1FA93}": [
        "axe",
        "tool",
        "chop",
        "cut",
        "hatchet",
        "split",
        "wood"
      ],
      "\u26CF\uFE0F": [
        "pick",
        "tools",
        "dig",
        "mining",
        "pickaxe",
        "tool"
      ],
      "\u2692\uFE0F": [
        "hammer_and_pick",
        "tools",
        "build",
        "create",
        "tool"
      ],
      "\u{1F6E0}\uFE0F": [
        "hammer_and_wrench",
        "tools",
        "build",
        "create",
        "spanner",
        "tool"
      ],
      "\u{1F5E1}\uFE0F": [
        "dagger",
        "weapon",
        "knife"
      ],
      "\u2694\uFE0F": [
        "crossed_swords",
        "weapon"
      ],
      "\u{1F52B}": [
        "pistol",
        "violence",
        "weapon",
        "revolver",
        "gun",
        "handgun",
        "shoot",
        "squirt",
        "tool",
        "water"
      ],
      "\u{1F3F9}": [
        "bow_and_arrow",
        "sports",
        "archer",
        "archery",
        "sagittarius",
        "tool",
        "zodiac"
      ],
      "\u{1F6E1}\uFE0F": [
        "shield",
        "protection",
        "security",
        "weapon"
      ],
      "\u{1F527}": [
        "wrench",
        "tools",
        "diy",
        "ikea",
        "fix",
        "maintainer",
        "spanner",
        "tool"
      ],
      "\u{1F529}": [
        "nut_and_bolt",
        "handy",
        "tools",
        "fix",
        "screw",
        "tool"
      ],
      "\u2699\uFE0F": [
        "gear",
        "cog",
        "cogwheel",
        "tool"
      ],
      "\u{1F5DC}\uFE0F": [
        "clamp",
        "tool",
        "compress",
        "compression",
        "table",
        "vice",
        "winzip"
      ],
      "\u2696\uFE0F": [
        "balance_scale",
        "law",
        "fairness",
        "weight",
        "justice",
        "libra",
        "scales",
        "tool",
        "zodiac"
      ],
      "\u{1F9AF}": [
        "probing_cane",
        "accessibility",
        "blind",
        "white"
      ],
      "\u{1F517}": [
        "link",
        "rings",
        "url",
        "chain",
        "hyperlink",
        "linked",
        "symbol"
      ],
      "\u26D3\uFE0F": [
        "chains",
        "lock",
        "arrest",
        "chain"
      ],
      "\u{1F9F0}": [
        "toolbox",
        "tools",
        "diy",
        "fix",
        "maintainer",
        "mechanic",
        "chest",
        "tool"
      ],
      "\u{1F9F2}": [
        "magnet",
        "attraction",
        "magnetic",
        "horseshoe"
      ],
      "\u2697\uFE0F": [
        "alembic",
        "distilling",
        "science",
        "experiment",
        "chemistry",
        "tool"
      ],
      "\u{1F9EA}": [
        "test_tube",
        "chemistry",
        "experiment",
        "lab",
        "science",
        "chemist",
        "test"
      ],
      "\u{1F9EB}": [
        "petri_dish",
        "bacteria",
        "biology",
        "culture",
        "lab",
        "biologist"
      ],
      "\u{1F9EC}": [
        "dna",
        "biologist",
        "genetics",
        "life",
        "double",
        "evolution",
        "gene",
        "helix"
      ],
      "\u{1F52C}": [
        "microscope",
        "laboratory",
        "experiment",
        "zoomin",
        "science",
        "study",
        "investigate",
        "magnify",
        "tool"
      ],
      "\u{1F52D}": [
        "telescope",
        "stars",
        "space",
        "zoom",
        "science",
        "astronomy",
        "stargazing",
        "tool"
      ],
      "\u{1F4E1}": [
        "satellite_antenna",
        "communication",
        "future",
        "radio",
        "space",
        "dish",
        "signal"
      ],
      "\u{1F489}": [
        "syringe",
        "health",
        "hospital",
        "drugs",
        "blood",
        "medicine",
        "needle",
        "doctor",
        "nurse",
        "shot",
        "sick",
        "tool",
        "vaccination",
        "vaccine"
      ],
      "\u{1FA78}": [
        "drop_of_blood",
        "period",
        "hurt",
        "harm",
        "wound",
        "bleed",
        "doctor",
        "donation",
        "injury",
        "medicine",
        "menstruation"
      ],
      "\u{1F48A}": [
        "pill",
        "health",
        "medicine",
        "doctor",
        "pharmacy",
        "drug",
        "capsule",
        "drugs",
        "sick",
        "tablet"
      ],
      "\u{1FA79}": [
        "adhesive_bandage",
        "heal",
        "aid",
        "band",
        "doctor",
        "medicine",
        "plaster"
      ],
      "\u{1FA7A}": [
        "stethoscope",
        "health",
        "doctor",
        "heart",
        "medicine",
        "healthcheck"
      ],
      "\u{1F6AA}": [
        "door",
        "house",
        "entry",
        "exit",
        "doorway",
        "front"
      ],
      "\u{1F6CF}\uFE0F": [
        "bed",
        "sleep",
        "rest",
        "bedroom",
        "hotel"
      ],
      "\u{1F6CB}\uFE0F": [
        "couch_and_lamp",
        "read",
        "chill",
        "hotel",
        "lounge",
        "settee",
        "sofa"
      ],
      "\u{1FA91}": [
        "chair",
        "sit",
        "furniture",
        "seat"
      ],
      "\u{1F6BD}": [
        "toilet",
        "restroom",
        "wc",
        "washroom",
        "bathroom",
        "potty",
        "loo"
      ],
      "\u{1F6BF}": [
        "shower",
        "clean",
        "water",
        "bathroom",
        "bath",
        "head"
      ],
      "\u{1F6C1}": [
        "bathtub",
        "clean",
        "shower",
        "bathroom",
        "bath",
        "bubble"
      ],
      "\u{1FA92}": [
        "razor",
        "cut",
        "sharp",
        "shave"
      ],
      "\u{1F9F4}": [
        "lotion_bottle",
        "moisturizer",
        "sunscreen",
        "shampoo"
      ],
      "\u{1F9F7}": [
        "safety_pin",
        "diaper",
        "punk",
        "rock"
      ],
      "\u{1F9F9}": [
        "broom",
        "cleaning",
        "sweeping",
        "witch",
        "brush",
        "sweep"
      ],
      "\u{1F9FA}": [
        "basket",
        "laundry",
        "farming",
        "picnic"
      ],
      "\u{1F9FB}": [
        "roll_of_paper",
        "roll",
        "toilet",
        "towels"
      ],
      "\u{1F9FC}": [
        "soap",
        "bar",
        "bathing",
        "cleaning",
        "lather",
        "soapdish"
      ],
      "\u{1F9FD}": [
        "sponge",
        "absorbing",
        "cleaning",
        "porous"
      ],
      "\u{1F9EF}": [
        "fire_extinguisher",
        "quench",
        "extinguish"
      ],
      "\u{1F6D2}": [
        "shopping_cart",
        "trolley"
      ],
      "\u{1F6AC}": [
        "cigarette",
        "kills",
        "tobacco",
        "joint",
        "smoke",
        "activity",
        "smoking",
        "symbol"
      ],
      "\u26B0\uFE0F": [
        "coffin",
        "vampire",
        "dead",
        "die",
        "death",
        "rip",
        "graveyard",
        "cemetery",
        "casket",
        "funeral",
        "box",
        "remove"
      ],
      "\u26B1\uFE0F": [
        "funeral_urn",
        "dead",
        "die",
        "death",
        "rip",
        "ashes",
        "vase"
      ],
      "\u{1F5FF}": [
        "moai",
        "rock",
        "easter island",
        "carving",
        "face",
        "human",
        "moyai",
        "statue",
        "stone"
      ],
      "\u{1F3E7}": [
        "atm_sign",
        "money",
        "sales",
        "cash",
        "blue-square",
        "payment",
        "bank",
        "automated",
        "machine",
        "teller"
      ],
      "\u{1F6AE}": [
        "litter_in_bin_sign",
        "blue-square",
        "sign",
        "human",
        "info",
        "its",
        "litterbox",
        "person",
        "place",
        "put",
        "symbol",
        "trash"
      ],
      "\u{1F6B0}": [
        "potable_water",
        "blue-square",
        "liquid",
        "restroom",
        "cleaning",
        "faucet",
        "drink",
        "drinking",
        "symbol",
        "tap",
        "thirst",
        "thirsty"
      ],
      "\u267F": [
        "wheelchair_symbol",
        "blue-square",
        "disabled",
        "accessibility",
        "access",
        "accessible",
        "bathroom"
      ],
      "\u{1F6B9}": [
        "men_s_room",
        "toilet",
        "restroom",
        "wc",
        "blue-square",
        "gender",
        "male",
        "lavatory",
        "man",
        "mens",
        "men\u2019s",
        "symbol"
      ],
      "\u{1F6BA}": [
        "women_s_room",
        "purple-square",
        "woman",
        "female",
        "toilet",
        "loo",
        "restroom",
        "gender",
        "lavatory",
        "symbol",
        "wc",
        "womens",
        "womens\xA0toilet",
        "women\u2019s"
      ],
      "\u{1F6BB}": [
        "restroom",
        "blue-square",
        "toilet",
        "refresh",
        "wc",
        "gender",
        "bathroom",
        "lavatory",
        "sign"
      ],
      "\u{1F6BC}": [
        "baby_symbol",
        "orange-square",
        "child",
        "change",
        "changing",
        "nursery",
        "station"
      ],
      "\u{1F6BE}": [
        "water_closet",
        "toilet",
        "restroom",
        "blue-square",
        "lavatory",
        "wc"
      ],
      "\u{1F6C2}": [
        "passport_control",
        "custom",
        "blue-square",
        "border",
        "permissions",
        "authorization",
        "roles"
      ],
      "\u{1F6C3}": [
        "customs",
        "passport",
        "border",
        "blue-square"
      ],
      "\u{1F6C4}": [
        "baggage_claim",
        "blue-square",
        "airport",
        "transport"
      ],
      "\u{1F6C5}": [
        "left_luggage",
        "blue-square",
        "travel",
        "baggage",
        "bag\xA0with",
        "key",
        "locked",
        "locker",
        "suitcase"
      ],
      "\u26A0\uFE0F": [
        "warning",
        "exclamation",
        "wip",
        "alert",
        "error",
        "problem",
        "issue",
        "sign",
        "symbol"
      ],
      "\u{1F6B8}": [
        "children_crossing",
        "school",
        "warning",
        "danger",
        "sign",
        "driving",
        "yellow-diamond",
        "child",
        "kids",
        "pedestrian",
        "traffic",
        "experience",
        "usability"
      ],
      "\u26D4": [
        "no_entry",
        "limit",
        "security",
        "privacy",
        "bad",
        "denied",
        "stop",
        "circle",
        "forbidden",
        "not",
        "prohibited",
        "traffic"
      ],
      "\u{1F6AB}": [
        "prohibited",
        "forbid",
        "stop",
        "limit",
        "denied",
        "disallow",
        "circle",
        "backslash",
        "banned",
        "block",
        "crossed",
        "entry",
        "forbidden",
        "no",
        "not",
        "red",
        "restricted",
        "sign"
      ],
      "\u{1F6B3}": [
        "no_bicycles",
        "no_bikes",
        "bicycle",
        "bike",
        "cyclist",
        "prohibited",
        "circle",
        "forbidden",
        "not",
        "sign",
        "vehicle"
      ],
      "\u{1F6AD}": [
        "no_smoking",
        "cigarette",
        "blue-square",
        "smell",
        "smoke",
        "forbidden",
        "not",
        "prohibited",
        "sign",
        "symbol"
      ],
      "\u{1F6AF}": [
        "no_littering",
        "trash",
        "bin",
        "garbage",
        "circle",
        "do",
        "forbidden",
        "litter",
        "not",
        "prohibited",
        "symbol"
      ],
      "\u{1F6B1}": [
        "non_potable_water",
        "drink",
        "faucet",
        "tap",
        "circle",
        "drinking",
        "forbidden",
        "no",
        "not",
        "prohibited",
        "symbol"
      ],
      "\u{1F6B7}": [
        "no_pedestrians",
        "rules",
        "crossing",
        "walking",
        "circle",
        "forbidden",
        "not",
        "pedestrian",
        "people",
        "prohibited"
      ],
      "\u{1F4F5}": [
        "no_mobile_phones",
        "iphone",
        "mute",
        "circle",
        "cell",
        "communication",
        "forbidden",
        "not",
        "phone",
        "prohibited",
        "smartphones",
        "telephone"
      ],
      "\u{1F51E}": [
        "no_one_under_eighteen",
        "18",
        "drink",
        "pub",
        "night",
        "minor",
        "circle",
        "age",
        "forbidden",
        "not",
        "nsfw",
        "prohibited",
        "restriction",
        "symbol",
        "underage"
      ],
      "\u2622\uFE0F": [
        "radioactive",
        "nuclear",
        "danger",
        "international",
        "radiation",
        "sign",
        "symbol"
      ],
      "\u2623\uFE0F": [
        "biohazard",
        "danger",
        "sign"
      ],
      "\u2B06\uFE0F": [
        "up_arrow",
        "blue-square",
        "continue",
        "top",
        "direction",
        "black",
        "cardinal",
        "north",
        "pointing",
        "upwards",
        "upgrade"
      ],
      "\u2197\uFE0F": [
        "up_right_arrow",
        "blue-square",
        "point",
        "direction",
        "diagonal",
        "northeast",
        "east",
        "intercardinal",
        "north",
        "upper"
      ],
      "\u27A1\uFE0F": [
        "right_arrow",
        "blue-square",
        "next",
        "black",
        "cardinal",
        "direction",
        "east",
        "pointing",
        "rightwards",
        "right\xA0arrow"
      ],
      "\u2198\uFE0F": [
        "down_right_arrow",
        "blue-square",
        "direction",
        "diagonal",
        "southeast",
        "east",
        "intercardinal",
        "lower",
        "right\xA0arrow",
        "south"
      ],
      "\u2B07\uFE0F": [
        "down_arrow",
        "blue-square",
        "direction",
        "bottom",
        "black",
        "cardinal",
        "downwards",
        "down\xA0arrow",
        "pointing",
        "south",
        "downgrade"
      ],
      "\u2199\uFE0F": [
        "down_left_arrow",
        "blue-square",
        "direction",
        "diagonal",
        "southwest",
        "intercardinal",
        "left\xA0arrow",
        "lower",
        "south",
        "west"
      ],
      "\u2B05\uFE0F": [
        "left_arrow",
        "blue-square",
        "previous",
        "back",
        "black",
        "cardinal",
        "direction",
        "leftwards",
        "left\xA0arrow",
        "pointing",
        "west"
      ],
      "\u2196\uFE0F": [
        "up_left_arrow",
        "blue-square",
        "point",
        "direction",
        "diagonal",
        "northwest",
        "intercardinal",
        "left\xA0arrow",
        "north",
        "upper",
        "west"
      ],
      "\u2195\uFE0F": [
        "up_down_arrow",
        "blue-square",
        "direction",
        "way",
        "vertical",
        "arrows",
        "intercardinal",
        "northwest"
      ],
      "\u2194\uFE0F": [
        "left_right_arrow",
        "shape",
        "direction",
        "horizontal",
        "sideways",
        "arrows",
        "horizontal\xA0arrows"
      ],
      "\u21A9\uFE0F": [
        "right_arrow_curving_left",
        "back",
        "return",
        "blue-square",
        "undo",
        "enter",
        "curved",
        "email",
        "hook",
        "leftwards",
        "reply"
      ],
      "\u21AA\uFE0F": [
        "left_arrow_curving_right",
        "blue-square",
        "return",
        "rotate",
        "direction",
        "email",
        "forward",
        "hook",
        "rightwards",
        "right\xA0curved"
      ],
      "\u2934\uFE0F": [
        "right_arrow_curving_up",
        "blue-square",
        "direction",
        "top",
        "heading",
        "pointing",
        "rightwards",
        "then",
        "upwards"
      ],
      "\u2935\uFE0F": [
        "right_arrow_curving_down",
        "blue-square",
        "direction",
        "bottom",
        "curved",
        "downwards",
        "heading",
        "pointing",
        "rightwards",
        "then"
      ],
      "\u{1F503}": [
        "clockwise_vertical_arrows",
        "sync",
        "cycle",
        "round",
        "repeat",
        "arrow",
        "circle",
        "downwards",
        "open",
        "reload",
        "upwards"
      ],
      "\u{1F504}": [
        "counterclockwise_arrows_button",
        "blue-square",
        "sync",
        "cycle",
        "anticlockwise",
        "arrow",
        "circle",
        "downwards",
        "open",
        "refresh",
        "rotate",
        "switch",
        "upwards",
        "withershins"
      ],
      "\u{1F519}": [
        "back_arrow",
        "arrow",
        "words",
        "return",
        "above",
        "leftwards"
      ],
      "\u{1F51A}": [
        "end_arrow",
        "words",
        "arrow",
        "above",
        "leftwards"
      ],
      "\u{1F51B}": [
        "on_arrow",
        "arrow",
        "words",
        "above",
        "exclamation",
        "left",
        "mark",
        "on!",
        "right"
      ],
      "\u{1F51C}": [
        "soon_arrow",
        "arrow",
        "words",
        "above",
        "rightwards"
      ],
      "\u{1F51D}": [
        "top_arrow",
        "words",
        "blue-square",
        "above",
        "up",
        "upwards"
      ],
      "\u{1F6D0}": [
        "place_of_worship",
        "religion",
        "church",
        "temple",
        "prayer",
        "building",
        "religious"
      ],
      "\u269B\uFE0F": [
        "atom_symbol",
        "science",
        "physics",
        "chemistry",
        "atheist"
      ],
      "\u{1F549}\uFE0F": [
        "om",
        "hinduism",
        "buddhism",
        "sikhism",
        "jainism",
        "aumkara",
        "hindu",
        "omkara",
        "pranava",
        "religion",
        "symbol"
      ],
      "\u2721\uFE0F": [
        "star_of_david",
        "judaism",
        "jew",
        "jewish",
        "magen",
        "religion"
      ],
      "\u2638\uFE0F": [
        "wheel_of_dharma",
        "hinduism",
        "buddhism",
        "sikhism",
        "jainism",
        "buddhist",
        "helm",
        "religion"
      ],
      "\u262F\uFE0F": [
        "yin_yang",
        "balance",
        "religion",
        "tao",
        "taoist"
      ],
      "\u271D\uFE0F": [
        "latin_cross",
        "christianity",
        "christian",
        "religion"
      ],
      "\u2626\uFE0F": [
        "orthodox_cross",
        "suppedaneum",
        "religion",
        "christian"
      ],
      "\u262A\uFE0F": [
        "star_and_crescent",
        "islam",
        "muslim",
        "religion"
      ],
      "\u262E\uFE0F": [
        "peace_symbol",
        "hippie",
        "sign"
      ],
      "\u{1F54E}": [
        "menorah",
        "hanukkah",
        "candles",
        "jewish",
        "branches",
        "candelabrum",
        "candlestick",
        "chanukiah",
        "nine",
        "religion"
      ],
      "\u{1F52F}": [
        "dotted_six_pointed_star",
        "purple-square",
        "religion",
        "jewish",
        "hexagram",
        "dot",
        "fortune",
        "middle"
      ],
      "\u2648": [
        "aries",
        "sign",
        "purple-square",
        "zodiac",
        "astrology",
        "ram"
      ],
      "\u2649": [
        "taurus",
        "purple-square",
        "sign",
        "zodiac",
        "astrology",
        "bull",
        "ox"
      ],
      "\u264A": [
        "gemini",
        "sign",
        "zodiac",
        "purple-square",
        "astrology",
        "twins"
      ],
      "\u264B": [
        "cancer",
        "sign",
        "zodiac",
        "purple-square",
        "astrology",
        "crab"
      ],
      "\u264C": [
        "leo",
        "sign",
        "purple-square",
        "zodiac",
        "astrology",
        "lion"
      ],
      "\u264D": [
        "virgo",
        "sign",
        "zodiac",
        "purple-square",
        "astrology",
        "maiden",
        "virgin"
      ],
      "\u264E": [
        "libra",
        "sign",
        "purple-square",
        "zodiac",
        "astrology",
        "balance",
        "justice",
        "scales"
      ],
      "\u264F": [
        "scorpio",
        "sign",
        "zodiac",
        "purple-square",
        "astrology",
        "scorpion",
        "scorpius"
      ],
      "\u2650": [
        "sagittarius",
        "sign",
        "zodiac",
        "purple-square",
        "astrology",
        "archer"
      ],
      "\u2651": [
        "capricorn",
        "sign",
        "zodiac",
        "purple-square",
        "astrology",
        "goat"
      ],
      "\u2652": [
        "aquarius",
        "sign",
        "purple-square",
        "zodiac",
        "astrology",
        "bearer",
        "water"
      ],
      "\u2653": [
        "pisces",
        "purple-square",
        "sign",
        "zodiac",
        "astrology",
        "fish"
      ],
      "\u26CE": [
        "ophiuchus",
        "sign",
        "purple-square",
        "constellation",
        "astrology",
        "bearer",
        "serpent",
        "snake",
        "zodiac"
      ],
      "\u{1F500}": [
        "shuffle_tracks_button",
        "blue-square",
        "shuffle",
        "music",
        "random",
        "arrow",
        "arrows",
        "crossed",
        "rightwards",
        "symbol",
        "twisted",
        "merge"
      ],
      "\u{1F501}": [
        "repeat_button",
        "loop",
        "record",
        "arrow",
        "arrows",
        "circle",
        "clockwise",
        "leftwards",
        "open",
        "retweet",
        "rightwards",
        "symbol"
      ],
      "\u{1F502}": [
        "repeat_single_button",
        "blue-square",
        "loop",
        "arrow",
        "arrows",
        "circle",
        "circled",
        "clockwise",
        "leftwards",
        "number",
        "once",
        "one",
        "open",
        "overlay",
        "rightwards",
        "symbol",
        "track"
      ],
      "\u25B6\uFE0F": [
        "play_button",
        "blue-square",
        "right",
        "direction",
        "play",
        "arrow",
        "black",
        "forward",
        "pointing",
        "right\xA0triangle",
        "triangle"
      ],
      "\u23E9": [
        "fast_forward_button",
        "blue-square",
        "play",
        "speed",
        "continue",
        "arrow",
        "black",
        "double",
        "pointing",
        "right",
        "symbol",
        "triangle"
      ],
      "\u23ED\uFE0F": [
        "next_track_button",
        "forward",
        "next",
        "blue-square",
        "arrow",
        "bar",
        "black",
        "double",
        "pointing",
        "right",
        "scene",
        "skip",
        "symbol",
        "triangle",
        "vertical"
      ],
      "\u23EF\uFE0F": [
        "play_or_pause_button",
        "blue-square",
        "play",
        "pause",
        "arrow",
        "bar",
        "black",
        "double",
        "play/pause",
        "pointing",
        "right",
        "symbol",
        "triangle",
        "vertical"
      ],
      "\u25C0\uFE0F": [
        "reverse_button",
        "blue-square",
        "left",
        "direction",
        "arrow",
        "backward",
        "black",
        "pointing",
        "triangle"
      ],
      "\u23EA": [
        "fast_reverse_button",
        "play",
        "blue-square",
        "arrow",
        "black",
        "double",
        "left",
        "pointing",
        "rewind",
        "symbol",
        "triangle",
        "revert"
      ],
      "\u23EE\uFE0F": [
        "last_track_button",
        "backward",
        "arrow",
        "bar",
        "black",
        "double",
        "left",
        "pointing",
        "previous",
        "scene",
        "skip",
        "symbol",
        "triangle",
        "vertical"
      ],
      "\u{1F53C}": [
        "upwards_button",
        "blue-square",
        "triangle",
        "direction",
        "point",
        "forward",
        "top",
        "arrow",
        "pointing",
        "red",
        "small",
        "up"
      ],
      "\u23EB": [
        "fast_up_button",
        "blue-square",
        "direction",
        "top",
        "arrow",
        "black",
        "double",
        "pointing",
        "triangle"
      ],
      "\u{1F53D}": [
        "downwards_button",
        "blue-square",
        "direction",
        "bottom",
        "arrow",
        "down",
        "pointing",
        "red",
        "small",
        "triangle"
      ],
      "\u23EC": [
        "fast_down_button",
        "blue-square",
        "direction",
        "bottom",
        "arrow",
        "black",
        "double",
        "pointing",
        "triangle"
      ],
      "\u23F8\uFE0F": [
        "pause_button",
        "pause",
        "blue-square",
        "bar",
        "double",
        "symbol",
        "vertical"
      ],
      "\u23F9\uFE0F": [
        "stop_button",
        "blue-square",
        "black",
        "for",
        "square",
        "symbol"
      ],
      "\u23FA\uFE0F": [
        "record_button",
        "blue-square",
        "black",
        "circle",
        "for",
        "symbol"
      ],
      "\u23CF\uFE0F": [
        "eject_button",
        "blue-square",
        "symbol"
      ],
      "\u{1F3A6}": [
        "cinema",
        "blue-square",
        "record",
        "film",
        "movie",
        "curtain",
        "stage",
        "theater",
        "activity",
        "camera",
        "entertainment",
        "movies",
        "screen",
        "symbol"
      ],
      "\u{1F505}": [
        "dim_button",
        "sun",
        "afternoon",
        "warm",
        "summer",
        "brightness",
        "decrease",
        "low",
        "symbol"
      ],
      "\u{1F506}": [
        "bright_button",
        "sun",
        "light",
        "brightness",
        "high",
        "increase",
        "symbol"
      ],
      "\u{1F4F6}": [
        "antenna_bars",
        "blue-square",
        "reception",
        "phone",
        "internet",
        "connection",
        "wifi",
        "bluetooth",
        "bars",
        "bar",
        "cell",
        "cellular",
        "communication",
        "mobile",
        "signal",
        "stairs",
        "strength",
        "telephone"
      ],
      "\u{1F4F3}": [
        "vibration_mode",
        "orange-square",
        "phone",
        "cell",
        "communication",
        "heart",
        "mobile",
        "silent",
        "telephone"
      ],
      "\u{1F4F4}": [
        "mobile_phone_off",
        "mute",
        "orange-square",
        "silence",
        "quiet",
        "cell",
        "communication",
        "telephone"
      ],
      "\u2640\uFE0F": [
        "female_sign",
        "woman",
        "women",
        "lady",
        "girl",
        "symbol",
        "venus"
      ],
      "\u2642\uFE0F": [
        "male_sign",
        "man",
        "boy",
        "men",
        "mars",
        "symbol"
      ],
      "\u2695\uFE0F": [
        "medical_symbol",
        "health",
        "hospital",
        "aesculapius",
        "asclepius",
        "asklepios",
        "care",
        "doctor",
        "medicine",
        "rod",
        "snake",
        "staff"
      ],
      "\u267E\uFE0F": [
        "infinity",
        "forever",
        "paper",
        "permanent",
        "sign",
        "unbounded",
        "universal"
      ],
      "\u267B\uFE0F": [
        "recycling_symbol",
        "arrow",
        "environment",
        "garbage",
        "trash",
        "black",
        "green",
        "logo",
        "recycle",
        "universal",
        "reuse"
      ],
      "\u269C\uFE0F": [
        "fleur_de_lis",
        "decorative",
        "scout",
        "new",
        "orleans",
        "saints",
        "scouts"
      ],
      "\u{1F531}": [
        "trident_emblem",
        "weapon",
        "spear",
        "anchor",
        "pitchfork",
        "ship",
        "tool"
      ],
      "\u{1F4DB}": [
        "name_badge",
        "fire",
        "forbid",
        "tag",
        "tofu"
      ],
      "\u{1F530}": [
        "japanese_symbol_for_beginner",
        "badge",
        "shield",
        "chevron",
        "green",
        "leaf",
        "mark",
        "shoshinsha",
        "tool",
        "yellow"
      ],
      "\u2B55": [
        "hollow_red_circle",
        "circle",
        "round",
        "correct",
        "heavy",
        "large",
        "mark",
        "o"
      ],
      "\u2705": [
        "check_mark_button",
        "green-square",
        "ok",
        "agree",
        "vote",
        "election",
        "answer",
        "tick",
        "green",
        "heavy",
        "symbol",
        "white",
        "pass_tests"
      ],
      "\u2611\uFE0F": [
        "check_box_with_check",
        "ok",
        "agree",
        "confirm",
        "black-square",
        "vote",
        "election",
        "yes",
        "tick",
        "ballot",
        "checkbox",
        "mark"
      ],
      "\u2714\uFE0F": [
        "check_mark",
        "ok",
        "nike",
        "answer",
        "yes",
        "tick",
        "heavy"
      ],
      "\u2716\uFE0F": [
        "multiplication_sign",
        "math",
        "calculation",
        "cancel",
        "heavy",
        "multiply",
        "symbol",
        "x"
      ],
      "\u274C": [
        "cross_mark",
        "no",
        "delete",
        "remove",
        "cancel",
        "red",
        "multiplication",
        "multiply",
        "x"
      ],
      "\u274E": [
        "cross_mark_button",
        "x",
        "green-square",
        "no",
        "deny",
        "negative",
        "square",
        "squared"
      ],
      "\u2795": [
        "plus_sign",
        "math",
        "calculation",
        "addition",
        "more",
        "increase",
        "heavy",
        "symbol",
        "add"
      ],
      "\u2796": [
        "minus_sign",
        "math",
        "calculation",
        "subtract",
        "less",
        "heavy",
        "symbol",
        "remove"
      ],
      "\u2797": [
        "division_sign",
        "divide",
        "math",
        "calculation",
        "heavy",
        "symbol"
      ],
      "\u27B0": [
        "curly_loop",
        "scribble",
        "draw",
        "shape",
        "squiggle",
        "curl",
        "curling"
      ],
      "\u27BF": [
        "double_curly_loop",
        "tape",
        "cassette",
        "curl",
        "curling",
        "voicemail"
      ],
      "\u303D\uFE0F": [
        "part_alternation_mark",
        "graph",
        "presentation",
        "stats",
        "business",
        "economics",
        "bad",
        "m",
        "mcdonald\u2019s"
      ],
      "\u2733\uFE0F": [
        "eight_spoked_asterisk",
        "star",
        "sparkle",
        "green-square"
      ],
      "\u2734\uFE0F": [
        "eight_pointed_star",
        "orange-square",
        "shape",
        "polygon",
        "black",
        "orange"
      ],
      "\u2747\uFE0F": [
        "sparkle",
        "stars",
        "green-square",
        "awesome",
        "good",
        "fireworks"
      ],
      "\u203C\uFE0F": [
        "double_exclamation_mark",
        "exclamation",
        "surprise",
        "bangbang",
        "punctuation",
        "red"
      ],
      "\u2049\uFE0F": [
        "exclamation_question_mark",
        "wat",
        "punctuation",
        "surprise",
        "interrobang",
        "red"
      ],
      "\u2753": [
        "question_mark",
        "doubt",
        "confused",
        "black",
        "ornament",
        "punctuation",
        "red"
      ],
      "\u2754": [
        "white_question_mark",
        "doubts",
        "gray",
        "huh",
        "confused",
        "grey",
        "ornament",
        "outlined",
        "punctuation"
      ],
      "\u2755": [
        "white_exclamation_mark",
        "surprise",
        "punctuation",
        "gray",
        "wow",
        "warning",
        "grey",
        "ornament",
        "outlined"
      ],
      "\u2757": [
        "exclamation_mark",
        "heavy_exclamation_mark",
        "danger",
        "surprise",
        "punctuation",
        "wow",
        "warning",
        "bang",
        "red",
        "symbol"
      ],
      "\u3030\uFE0F": [
        "wavy_dash",
        "draw",
        "line",
        "moustache",
        "mustache",
        "squiggle",
        "scribble",
        "punctuation",
        "wave"
      ],
      "\xA9\uFE0F": [
        "copyright",
        "ip",
        "license",
        "circle",
        "law",
        "legal",
        "c",
        "sign"
      ],
      "\xAE\uFE0F": [
        "registered",
        "alphabet",
        "circle",
        "r",
        "sign"
      ],
      "\u2122\uFE0F": [
        "trade_mark",
        "trademark",
        "brand",
        "law",
        "legal",
        "sign",
        "tm"
      ],
      "#\uFE0F\u20E3": [
        "keycap_",
        "symbol",
        "blue-square",
        "twitter",
        "hash",
        "hashtag",
        "key",
        "number",
        "octothorpe",
        "pound",
        "sign"
      ],
      "*\uFE0F\u20E3": [
        "keycap_",
        "star",
        "keycap",
        "asterisk"
      ],
      "0\uFE0F\u20E3": [
        "keycap_0",
        "0",
        "numbers",
        "blue-square",
        "null",
        "zero",
        "digit"
      ],
      "1\uFE0F\u20E3": [
        "keycap_1",
        "blue-square",
        "numbers",
        "1",
        "one",
        "digit"
      ],
      "2\uFE0F\u20E3": [
        "keycap_2",
        "numbers",
        "2",
        "prime",
        "blue-square",
        "two",
        "digit"
      ],
      "3\uFE0F\u20E3": [
        "keycap_3",
        "3",
        "numbers",
        "prime",
        "blue-square",
        "three",
        "digit"
      ],
      "4\uFE0F\u20E3": [
        "keycap_4",
        "4",
        "numbers",
        "blue-square",
        "four",
        "digit"
      ],
      "5\uFE0F\u20E3": [
        "keycap_5",
        "5",
        "numbers",
        "blue-square",
        "prime",
        "five",
        "digit"
      ],
      "6\uFE0F\u20E3": [
        "keycap_6",
        "6",
        "numbers",
        "blue-square",
        "six",
        "digit"
      ],
      "7\uFE0F\u20E3": [
        "keycap_7",
        "7",
        "numbers",
        "blue-square",
        "prime",
        "seven",
        "digit"
      ],
      "8\uFE0F\u20E3": [
        "keycap_8",
        "8",
        "blue-square",
        "numbers",
        "eight",
        "digit"
      ],
      "9\uFE0F\u20E3": [
        "keycap_9",
        "blue-square",
        "numbers",
        "9",
        "nine",
        "digit"
      ],
      "\u{1F51F}": [
        "keycap_10",
        "numbers",
        "10",
        "blue-square",
        "ten",
        "number"
      ],
      "\u{1F520}": [
        "input_latin_uppercase",
        "alphabet",
        "words",
        "letters",
        "uppercase",
        "blue-square",
        "abcd",
        "capital",
        "for",
        "symbol"
      ],
      "\u{1F521}": [
        "input_latin_lowercase",
        "blue-square",
        "letters",
        "lowercase",
        "alphabet",
        "abcd",
        "for",
        "small",
        "symbol"
      ],
      "\u{1F522}": [
        "input_numbers",
        "numbers",
        "blue-square",
        "1234",
        "1",
        "2",
        "3",
        "4",
        "for",
        "numeric",
        "symbol"
      ],
      "\u{1F523}": [
        "input_symbols",
        "blue-square",
        "music",
        "note",
        "ampersand",
        "percent",
        "glyphs",
        "characters",
        "for",
        "symbol",
        "symbol\xA0input"
      ],
      "\u{1F524}": [
        "input_latin_letters",
        "blue-square",
        "alphabet",
        "abc",
        "for",
        "symbol"
      ],
      "\u{1F170}\uFE0F": [
        "a_button",
        "red-square",
        "alphabet",
        "letter",
        "blood",
        "capital",
        "latin",
        "negative",
        "squared",
        "type"
      ],
      "\u{1F18E}": [
        "ab_button",
        "red-square",
        "alphabet",
        "blood",
        "negative",
        "squared",
        "type"
      ],
      "\u{1F171}\uFE0F": [
        "b_button",
        "red-square",
        "alphabet",
        "letter",
        "blood",
        "capital",
        "latin",
        "negative",
        "squared",
        "type"
      ],
      "\u{1F191}": [
        "cl_button",
        "alphabet",
        "words",
        "red-square",
        "clear",
        "sign",
        "squared"
      ],
      "\u{1F192}": [
        "cool_button",
        "words",
        "blue-square",
        "sign",
        "square",
        "squared"
      ],
      "\u{1F193}": [
        "free_button",
        "blue-square",
        "words",
        "sign",
        "squared"
      ],
      "\u2139\uFE0F": [
        "information",
        "blue-square",
        "alphabet",
        "letter",
        "i",
        "info",
        "lowercase",
        "source",
        "tourist"
      ],
      "\u{1F194}": [
        "id_button",
        "purple-square",
        "words",
        "identification",
        "identity",
        "sign",
        "squared"
      ],
      "\u24C2\uFE0F": [
        "circled_m",
        "alphabet",
        "blue-circle",
        "letter",
        "capital",
        "circle",
        "latin",
        "metro"
      ],
      "\u{1F195}": [
        "new_button",
        "blue-square",
        "words",
        "start",
        "fresh",
        "sign",
        "squared"
      ],
      "\u{1F196}": [
        "ng_button",
        "blue-square",
        "words",
        "shape",
        "icon",
        "blooper",
        "good",
        "no",
        "sign",
        "squared"
      ],
      "\u{1F17E}\uFE0F": [
        "o_button",
        "alphabet",
        "red-square",
        "letter",
        "blood",
        "capital",
        "latin",
        "negative",
        "o2",
        "squared",
        "type"
      ],
      "\u{1F197}": [
        "ok_button",
        "good",
        "agree",
        "yes",
        "blue-square",
        "okay",
        "sign",
        "square",
        "squared"
      ],
      "\u{1F17F}\uFE0F": [
        "p_button",
        "cars",
        "blue-square",
        "alphabet",
        "letter",
        "capital",
        "latin",
        "negative",
        "parking",
        "sign",
        "squared"
      ],
      "\u{1F198}": [
        "sos_button",
        "help",
        "red-square",
        "words",
        "emergency",
        "911",
        "distress",
        "sign",
        "signal",
        "squared"
      ],
      "\u{1F199}": [
        "up_button",
        "blue-square",
        "above",
        "high",
        "exclamation",
        "level",
        "mark",
        "sign",
        "squared",
        "up!"
      ],
      "\u{1F19A}": [
        "vs_button",
        "words",
        "orange-square",
        "squared",
        "versus"
      ],
      "\u{1F201}": [
        "japanese_here_button",
        "blue-square",
        "here",
        "katakana",
        "japanese",
        "destination",
        "koko",
        "meaning",
        "sign",
        "squared",
        "word",
        "\u201Chere\u201D"
      ],
      "\u{1F202}\uFE0F": [
        "japanese_service_charge_button",
        "japanese",
        "blue-square",
        "katakana",
        "charge\u201D",
        "meaning",
        "or",
        "sa",
        "sign",
        "squared",
        "\u201Cservice",
        "\u201Cservice\u201D"
      ],
      "\u{1F237}\uFE0F": [
        "japanese_monthly_amount_button",
        "chinese",
        "month",
        "moon",
        "japanese",
        "orange-square",
        "kanji",
        "amount\u201D",
        "cjk",
        "ideograph",
        "meaning",
        "radical",
        "sign",
        "squared",
        "u6708",
        "unified",
        "\u201Cmonthly"
      ],
      "\u{1F236}": [
        "japanese_not_free_of_charge_button",
        "orange-square",
        "chinese",
        "have",
        "kanji",
        "charge\u201D",
        "cjk",
        "exist",
        "ideograph",
        "meaning",
        "own",
        "sign",
        "squared",
        "u6709",
        "unified",
        "\u201Cnot"
      ],
      "\u{1F22F}": [
        "japanese_reserved_button",
        "chinese",
        "point",
        "green-square",
        "kanji",
        "cjk",
        "finger",
        "ideograph",
        "meaning",
        "sign",
        "squared",
        "u6307",
        "unified",
        "\u201Creserved\u201D"
      ],
      "\u{1F250}": [
        "japanese_bargain_button",
        "chinese",
        "kanji",
        "obtain",
        "get",
        "circle",
        "acquire",
        "advantage",
        "circled",
        "ideograph",
        "meaning",
        "sign",
        "\u201Cbargain\u201D"
      ],
      "\u{1F239}": [
        "japanese_discount_button",
        "cut",
        "divide",
        "chinese",
        "kanji",
        "pink-square",
        "bargain",
        "cjk",
        "ideograph",
        "meaning",
        "sale",
        "sign",
        "squared",
        "u5272",
        "unified",
        "\u201Cdiscount\u201D"
      ],
      "\u{1F21A}": [
        "japanese_free_of_charge_button",
        "nothing",
        "chinese",
        "kanji",
        "japanese",
        "orange-square",
        "charge\u201D",
        "cjk",
        "ideograph",
        "lacking",
        "meaning",
        "negation",
        "sign",
        "squared",
        "u7121",
        "unified",
        "\u201Cfree"
      ],
      "\u{1F232}": [
        "japanese_prohibited_button",
        "kanji",
        "japanese",
        "chinese",
        "forbidden",
        "limit",
        "restricted",
        "red-square",
        "cjk",
        "forbid",
        "ideograph",
        "meaning",
        "prohibit",
        "sign",
        "squared",
        "u7981",
        "unified",
        "\u201Cprohibited\u201D"
      ],
      "\u{1F251}": [
        "japanese_acceptable_button",
        "ok",
        "good",
        "chinese",
        "kanji",
        "agree",
        "yes",
        "orange-circle",
        "accept",
        "circled",
        "ideograph",
        "meaning",
        "sign",
        "\u201Cacceptable\u201D"
      ],
      "\u{1F238}": [
        "japanese_application_button",
        "chinese",
        "japanese",
        "kanji",
        "orange-square",
        "apply",
        "cjk",
        "form",
        "ideograph",
        "meaning",
        "monkey",
        "request",
        "sign",
        "squared",
        "u7533",
        "unified",
        "\u201Capplication\u201D"
      ],
      "\u{1F234}": [
        "japanese_passing_grade_button",
        "japanese",
        "chinese",
        "join",
        "kanji",
        "red-square",
        "agreement",
        "cjk",
        "grade\u201D",
        "ideograph",
        "meaning",
        "sign",
        "squared",
        "together",
        "u5408",
        "unified",
        "\u201Cpassing"
      ],
      "\u{1F233}": [
        "japanese_vacancy_button",
        "kanji",
        "japanese",
        "chinese",
        "empty",
        "sky",
        "blue-square",
        "7a7a",
        "available",
        "cjk",
        "ideograph",
        "meaning",
        "sign",
        "squared",
        "u7a7a",
        "unified",
        "\u201Cvacancy\u201D"
      ],
      "\u3297\uFE0F": [
        "japanese_congratulations_button",
        "chinese",
        "kanji",
        "japanese",
        "red-circle",
        "circled",
        "congratulate",
        "congratulation",
        "ideograph",
        "meaning",
        "sign",
        "\u201Ccongratulations\u201D"
      ],
      "\u3299\uFE0F": [
        "japanese_secret_button",
        "privacy",
        "chinese",
        "sshh",
        "kanji",
        "red-circle",
        "circled",
        "ideograph",
        "meaning",
        "sign",
        "\u201Csecret\u201D"
      ],
      "\u{1F23A}": [
        "japanese_open_for_business_button",
        "japanese",
        "opening hours",
        "orange-square",
        "55b6",
        "business\u201D",
        "chinese",
        "cjk",
        "ideograph",
        "meaning",
        "operating",
        "sign",
        "squared",
        "u55b6",
        "unified",
        "work",
        "\u201Copen"
      ],
      "\u{1F235}": [
        "japanese_no_vacancy_button",
        "full",
        "chinese",
        "japanese",
        "red-square",
        "kanji",
        "6e80",
        "cjk",
        "fullness",
        "ideograph",
        "meaning",
        "sign",
        "squared",
        "u6e80",
        "unified",
        "vacancy\u201D",
        "\u201Cfull;",
        "\u201Cno"
      ],
      "\u{1F534}": [
        "red_circle",
        "shape",
        "error",
        "danger",
        "geometric",
        "large"
      ],
      "\u{1F7E0}": [
        "orange_circle",
        "round",
        "geometric",
        "large"
      ],
      "\u{1F7E1}": [
        "yellow_circle",
        "round",
        "geometric",
        "large"
      ],
      "\u{1F7E2}": [
        "green_circle",
        "round",
        "geometric",
        "large"
      ],
      "\u{1F535}": [
        "blue_circle",
        "shape",
        "icon",
        "button",
        "geometric",
        "large"
      ],
      "\u{1F7E3}": [
        "purple_circle",
        "round",
        "geometric",
        "large"
      ],
      "\u{1F7E4}": [
        "brown_circle",
        "round",
        "geometric",
        "large"
      ],
      "\u26AB": [
        "black_circle",
        "shape",
        "button",
        "round",
        "geometric",
        "medium"
      ],
      "\u26AA": [
        "white_circle",
        "shape",
        "round",
        "geometric",
        "medium"
      ],
      "\u{1F7E5}": [
        "red_square",
        "card",
        "geometric",
        "large"
      ],
      "\u{1F7E7}": [
        "orange_square",
        "geometric",
        "large"
      ],
      "\u{1F7E8}": [
        "yellow_square",
        "card",
        "geometric",
        "large"
      ],
      "\u{1F7E9}": [
        "green_square",
        "geometric",
        "large"
      ],
      "\u{1F7E6}": [
        "blue_square",
        "geometric",
        "large"
      ],
      "\u{1F7EA}": [
        "purple_square",
        "geometric",
        "large"
      ],
      "\u{1F7EB}": [
        "brown_square",
        "geometric",
        "large"
      ],
      "\u2B1B": [
        "black_large_square",
        "shape",
        "icon",
        "button",
        "geometric"
      ],
      "\u2B1C": [
        "white_large_square",
        "shape",
        "icon",
        "stone",
        "button",
        "geometric"
      ],
      "\u25FC\uFE0F": [
        "black_medium_square",
        "shape",
        "button",
        "icon",
        "geometric"
      ],
      "\u25FB\uFE0F": [
        "white_medium_square",
        "shape",
        "stone",
        "icon",
        "geometric"
      ],
      "\u25FE": [
        "black_medium_small_square",
        "icon",
        "shape",
        "button",
        "geometric"
      ],
      "\u25FD": [
        "white_medium_small_square",
        "shape",
        "stone",
        "icon",
        "button",
        "geometric"
      ],
      "\u25AA\uFE0F": [
        "black_small_square",
        "shape",
        "icon",
        "geometric"
      ],
      "\u25AB\uFE0F": [
        "white_small_square",
        "shape",
        "icon",
        "geometric"
      ],
      "\u{1F536}": [
        "large_orange_diamond",
        "shape",
        "jewel",
        "gem",
        "geometric"
      ],
      "\u{1F537}": [
        "large_blue_diamond",
        "shape",
        "jewel",
        "gem",
        "geometric"
      ],
      "\u{1F538}": [
        "small_orange_diamond",
        "shape",
        "jewel",
        "gem",
        "geometric"
      ],
      "\u{1F539}": [
        "small_blue_diamond",
        "shape",
        "jewel",
        "gem",
        "geometric"
      ],
      "\u{1F53A}": [
        "red_triangle_pointed_up",
        "shape",
        "direction",
        "up",
        "top",
        "geometric",
        "pointing",
        "small"
      ],
      "\u{1F53B}": [
        "red_triangle_pointed_down",
        "shape",
        "direction",
        "bottom",
        "geometric",
        "pointing",
        "small"
      ],
      "\u{1F4A0}": [
        "diamond_with_a_dot",
        "jewel",
        "blue",
        "gem",
        "crystal",
        "fancy",
        "comic",
        "cuteness",
        "flower",
        "geometric",
        "inside",
        "kawaii",
        "shape"
      ],
      "\u{1F518}": [
        "radio_button",
        "input",
        "old",
        "music",
        "circle",
        "geometric"
      ],
      "\u{1F533}": [
        "white_square_button",
        "shape",
        "input",
        "geometric",
        "outlined"
      ],
      "\u{1F532}": [
        "black_square_button",
        "shape",
        "input",
        "frame",
        "geometric"
      ],
      "\u{1F3C1}": [
        "chequered_flag",
        "contest",
        "finishline",
        "race",
        "gokart",
        "checkered",
        "finish",
        "girl",
        "grid",
        "milestone",
        "racing"
      ],
      "\u{1F6A9}": [
        "triangular_flag",
        "mark",
        "milestone",
        "place",
        "pole",
        "post",
        "red",
        "flag"
      ],
      "\u{1F38C}": [
        "crossed_flags",
        "japanese",
        "nation",
        "country",
        "border",
        "activity",
        "celebration",
        "cross",
        "flag",
        "two"
      ],
      "\u{1F3F4}": [
        "black_flag",
        "pirate",
        "waving"
      ],
      "\u{1F3F3}\uFE0F": [
        "white_flag",
        "losing",
        "loser",
        "lost",
        "surrender",
        "give up",
        "fail",
        "waving"
      ],
      "\u{1F3F3}\uFE0F\u200D\u{1F308}": [
        "rainbow_flag",
        "flag",
        "rainbow",
        "pride",
        "gay",
        "lgbt",
        "queer",
        "homosexual",
        "lesbian",
        "bisexual"
      ],
      "\u{1F3F4}\u200D\u2620\uFE0F": [
        "pirate_flag",
        "skull",
        "crossbones",
        "flag",
        "banner",
        "jolly",
        "plunder",
        "roger",
        "treasure"
      ],
      "\u{1F1E6}\u{1F1E8}": [
        "flag_ascension_island"
      ],
      "\u{1F1E6}\u{1F1E9}": [
        "flag_andorra",
        "ad",
        "flag",
        "nation",
        "country",
        "banner",
        "andorra",
        "andorran"
      ],
      "\u{1F1E6}\u{1F1EA}": [
        "flag_united_arab_emirates",
        "united",
        "arab",
        "emirates",
        "flag",
        "nation",
        "country",
        "banner",
        "united_arab_emirates",
        "emirati",
        "uae"
      ],
      "\u{1F1E6}\u{1F1EB}": [
        "flag_afghanistan",
        "af",
        "flag",
        "nation",
        "country",
        "banner",
        "afghanistan",
        "afghan"
      ],
      "\u{1F1E6}\u{1F1EC}": [
        "flag_antigua_barbuda",
        "antigua",
        "barbuda",
        "flag",
        "nation",
        "country",
        "banner",
        "antigua_barbuda"
      ],
      "\u{1F1E6}\u{1F1EE}": [
        "flag_anguilla",
        "ai",
        "flag",
        "nation",
        "country",
        "banner",
        "anguilla",
        "anguillan"
      ],
      "\u{1F1E6}\u{1F1F1}": [
        "flag_albania",
        "al",
        "flag",
        "nation",
        "country",
        "banner",
        "albania",
        "albanian"
      ],
      "\u{1F1E6}\u{1F1F2}": [
        "flag_armenia",
        "am",
        "flag",
        "nation",
        "country",
        "banner",
        "armenia",
        "armenian"
      ],
      "\u{1F1E6}\u{1F1F4}": [
        "flag_angola",
        "ao",
        "flag",
        "nation",
        "country",
        "banner",
        "angola",
        "angolan"
      ],
      "\u{1F1E6}\u{1F1F6}": [
        "flag_antarctica",
        "aq",
        "flag",
        "nation",
        "country",
        "banner",
        "antarctica",
        "antarctic"
      ],
      "\u{1F1E6}\u{1F1F7}": [
        "flag_argentina",
        "ar",
        "flag",
        "nation",
        "country",
        "banner",
        "argentina",
        "argentinian"
      ],
      "\u{1F1E6}\u{1F1F8}": [
        "flag_american_samoa",
        "american",
        "ws",
        "flag",
        "nation",
        "country",
        "banner",
        "american_samoa",
        "samoan"
      ],
      "\u{1F1E6}\u{1F1F9}": [
        "flag_austria",
        "at",
        "flag",
        "nation",
        "country",
        "banner",
        "austria",
        "austrian"
      ],
      "\u{1F1E6}\u{1F1FA}": [
        "flag_australia",
        "au",
        "flag",
        "nation",
        "country",
        "banner",
        "australia",
        "aussie",
        "australian",
        "heard",
        "mcdonald"
      ],
      "\u{1F1E6}\u{1F1FC}": [
        "flag_aruba",
        "aw",
        "flag",
        "nation",
        "country",
        "banner",
        "aruba",
        "aruban"
      ],
      "\u{1F1E6}\u{1F1FD}": [
        "flag_aland_islands",
        "\xC5land",
        "islands",
        "flag",
        "nation",
        "country",
        "banner",
        "aland_islands"
      ],
      "\u{1F1E6}\u{1F1FF}": [
        "flag_azerbaijan",
        "az",
        "flag",
        "nation",
        "country",
        "banner",
        "azerbaijan",
        "azerbaijani"
      ],
      "\u{1F1E7}\u{1F1E6}": [
        "flag_bosnia_herzegovina",
        "bosnia",
        "herzegovina",
        "flag",
        "nation",
        "country",
        "banner",
        "bosnia_herzegovina"
      ],
      "\u{1F1E7}\u{1F1E7}": [
        "flag_barbados",
        "bb",
        "flag",
        "nation",
        "country",
        "banner",
        "barbados",
        "bajan",
        "barbadian"
      ],
      "\u{1F1E7}\u{1F1E9}": [
        "flag_bangladesh",
        "bd",
        "flag",
        "nation",
        "country",
        "banner",
        "bangladesh",
        "bangladeshi"
      ],
      "\u{1F1E7}\u{1F1EA}": [
        "flag_belgium",
        "be",
        "flag",
        "nation",
        "country",
        "banner",
        "belgium",
        "belgian"
      ],
      "\u{1F1E7}\u{1F1EB}": [
        "flag_burkina_faso",
        "burkina",
        "faso",
        "flag",
        "nation",
        "country",
        "banner",
        "burkina_faso",
        "burkinabe"
      ],
      "\u{1F1E7}\u{1F1EC}": [
        "flag_bulgaria",
        "bg",
        "flag",
        "nation",
        "country",
        "banner",
        "bulgaria",
        "bulgarian"
      ],
      "\u{1F1E7}\u{1F1ED}": [
        "flag_bahrain",
        "bh",
        "flag",
        "nation",
        "country",
        "banner",
        "bahrain",
        "bahrainian",
        "bahrani"
      ],
      "\u{1F1E7}\u{1F1EE}": [
        "flag_burundi",
        "bi",
        "flag",
        "nation",
        "country",
        "banner",
        "burundi",
        "burundian"
      ],
      "\u{1F1E7}\u{1F1EF}": [
        "flag_benin",
        "bj",
        "flag",
        "nation",
        "country",
        "banner",
        "benin",
        "beninese"
      ],
      "\u{1F1E7}\u{1F1F1}": [
        "flag_st_barthelemy",
        "saint",
        "barth\xE9lemy",
        "flag",
        "nation",
        "country",
        "banner",
        "st_barthelemy",
        "st."
      ],
      "\u{1F1E7}\u{1F1F2}": [
        "flag_bermuda",
        "bm",
        "flag",
        "nation",
        "country",
        "banner",
        "bermuda",
        "bermudan\xA0flag"
      ],
      "\u{1F1E7}\u{1F1F3}": [
        "flag_brunei",
        "bn",
        "darussalam",
        "flag",
        "nation",
        "country",
        "banner",
        "brunei",
        "bruneian"
      ],
      "\u{1F1E7}\u{1F1F4}": [
        "flag_bolivia",
        "bo",
        "flag",
        "nation",
        "country",
        "banner",
        "bolivia",
        "bolivian"
      ],
      "\u{1F1E7}\u{1F1F6}": [
        "flag_caribbean_netherlands",
        "bonaire",
        "flag",
        "nation",
        "country",
        "banner",
        "caribbean_netherlands",
        "eustatius",
        "saba",
        "sint"
      ],
      "\u{1F1E7}\u{1F1F7}": [
        "flag_brazil",
        "br",
        "flag",
        "nation",
        "country",
        "banner",
        "brazil",
        "brasil",
        "brazilian",
        "for"
      ],
      "\u{1F1E7}\u{1F1F8}": [
        "flag_bahamas",
        "bs",
        "flag",
        "nation",
        "country",
        "banner",
        "bahamas",
        "bahamian"
      ],
      "\u{1F1E7}\u{1F1F9}": [
        "flag_bhutan",
        "bt",
        "flag",
        "nation",
        "country",
        "banner",
        "bhutan",
        "bhutanese"
      ],
      "\u{1F1E7}\u{1F1FB}": [
        "flag_bouvet_island",
        "norway"
      ],
      "\u{1F1E7}\u{1F1FC}": [
        "flag_botswana",
        "bw",
        "flag",
        "nation",
        "country",
        "banner",
        "botswana",
        "batswana"
      ],
      "\u{1F1E7}\u{1F1FE}": [
        "flag_belarus",
        "by",
        "flag",
        "nation",
        "country",
        "banner",
        "belarus",
        "belarusian"
      ],
      "\u{1F1E7}\u{1F1FF}": [
        "flag_belize",
        "bz",
        "flag",
        "nation",
        "country",
        "banner",
        "belize",
        "belizean"
      ],
      "\u{1F1E8}\u{1F1E6}": [
        "flag_canada",
        "ca",
        "flag",
        "nation",
        "country",
        "banner",
        "canada",
        "canadian"
      ],
      "\u{1F1E8}\u{1F1E8}": [
        "flag_cocos_islands",
        "cocos",
        "keeling",
        "islands",
        "flag",
        "nation",
        "country",
        "banner",
        "cocos_islands",
        "island"
      ],
      "\u{1F1E8}\u{1F1E9}": [
        "flag_congo_kinshasa",
        "congo",
        "democratic",
        "republic",
        "flag",
        "nation",
        "country",
        "banner",
        "congo_kinshasa",
        "drc"
      ],
      "\u{1F1E8}\u{1F1EB}": [
        "flag_central_african_republic",
        "central",
        "african",
        "republic",
        "flag",
        "nation",
        "country",
        "banner",
        "central_african_republic"
      ],
      "\u{1F1E8}\u{1F1EC}": [
        "flag_congo_brazzaville",
        "congo",
        "flag",
        "nation",
        "country",
        "banner",
        "congo_brazzaville",
        "republic"
      ],
      "\u{1F1E8}\u{1F1ED}": [
        "flag_switzerland",
        "ch",
        "flag",
        "nation",
        "country",
        "banner",
        "switzerland",
        "cross",
        "red",
        "swiss"
      ],
      "\u{1F1E8}\u{1F1EE}": [
        "flag_cote_d_ivoire",
        "ivory",
        "coast",
        "flag",
        "nation",
        "country",
        "banner",
        "cote_d_ivoire",
        "c\xF4te",
        "divoire",
        "d\u2019ivoire"
      ],
      "\u{1F1E8}\u{1F1F0}": [
        "flag_cook_islands",
        "cook",
        "islands",
        "flag",
        "nation",
        "country",
        "banner",
        "cook_islands",
        "island",
        "islander"
      ],
      "\u{1F1E8}\u{1F1F1}": [
        "flag_chile",
        "flag",
        "nation",
        "country",
        "banner",
        "chile",
        "chilean"
      ],
      "\u{1F1E8}\u{1F1F2}": [
        "flag_cameroon",
        "cm",
        "flag",
        "nation",
        "country",
        "banner",
        "cameroon",
        "cameroonian"
      ],
      "\u{1F1E8}\u{1F1F3}": [
        "flag_china",
        "china",
        "chinese",
        "prc",
        "flag",
        "country",
        "nation",
        "banner",
        "cn",
        "indicator",
        "letters",
        "regional",
        "symbol"
      ],
      "\u{1F1E8}\u{1F1F4}": [
        "flag_colombia",
        "co",
        "flag",
        "nation",
        "country",
        "banner",
        "colombia",
        "colombian"
      ],
      "\u{1F1E8}\u{1F1F5}": [
        "flag_clipperton_island"
      ],
      "\u{1F1E8}\u{1F1F7}": [
        "flag_costa_rica",
        "costa",
        "rica",
        "flag",
        "nation",
        "country",
        "banner",
        "costa_rica",
        "rican"
      ],
      "\u{1F1E8}\u{1F1FA}": [
        "flag_cuba",
        "cu",
        "flag",
        "nation",
        "country",
        "banner",
        "cuba",
        "cuban"
      ],
      "\u{1F1E8}\u{1F1FB}": [
        "flag_cape_verde",
        "cabo",
        "verde",
        "flag",
        "nation",
        "country",
        "banner",
        "cape_verde",
        "verdian"
      ],
      "\u{1F1E8}\u{1F1FC}": [
        "flag_curacao",
        "cura\xE7ao",
        "flag",
        "nation",
        "country",
        "banner",
        "curacao",
        "antilles",
        "cura\xE7aoan"
      ],
      "\u{1F1E8}\u{1F1FD}": [
        "flag_christmas_island",
        "christmas",
        "island",
        "flag",
        "nation",
        "country",
        "banner",
        "christmas_island"
      ],
      "\u{1F1E8}\u{1F1FE}": [
        "flag_cyprus",
        "cy",
        "flag",
        "nation",
        "country",
        "banner",
        "cyprus",
        "cypriot"
      ],
      "\u{1F1E8}\u{1F1FF}": [
        "flag_czechia",
        "cz",
        "flag",
        "nation",
        "country",
        "banner",
        "czechia",
        "czech",
        "republic"
      ],
      "\u{1F1E9}\u{1F1EA}": [
        "flag_germany",
        "german",
        "nation",
        "flag",
        "country",
        "banner",
        "germany",
        "de",
        "deutsch",
        "indicator",
        "letters",
        "regional",
        "symbol"
      ],
      "\u{1F1E9}\u{1F1EC}": [
        "flag_diego_garcia"
      ],
      "\u{1F1E9}\u{1F1EF}": [
        "flag_djibouti",
        "dj",
        "flag",
        "nation",
        "country",
        "banner",
        "djibouti",
        "djiboutian"
      ],
      "\u{1F1E9}\u{1F1F0}": [
        "flag_denmark",
        "dk",
        "flag",
        "nation",
        "country",
        "banner",
        "denmark",
        "danish"
      ],
      "\u{1F1E9}\u{1F1F2}": [
        "flag_dominica",
        "dm",
        "flag",
        "nation",
        "country",
        "banner",
        "dominica"
      ],
      "\u{1F1E9}\u{1F1F4}": [
        "flag_dominican_republic",
        "dominican",
        "republic",
        "flag",
        "nation",
        "country",
        "banner",
        "dominican_republic",
        "dom",
        "rep"
      ],
      "\u{1F1E9}\u{1F1FF}": [
        "flag_algeria",
        "dz",
        "flag",
        "nation",
        "country",
        "banner",
        "algeria",
        "algerian"
      ],
      "\u{1F1EA}\u{1F1E6}": [
        "flag_ceuta_melilla"
      ],
      "\u{1F1EA}\u{1F1E8}": [
        "flag_ecuador",
        "ec",
        "flag",
        "nation",
        "country",
        "banner",
        "ecuador",
        "ecuadorian"
      ],
      "\u{1F1EA}\u{1F1EA}": [
        "flag_estonia",
        "ee",
        "flag",
        "nation",
        "country",
        "banner",
        "estonia",
        "estonian"
      ],
      "\u{1F1EA}\u{1F1EC}": [
        "flag_egypt",
        "eg",
        "flag",
        "nation",
        "country",
        "banner",
        "egypt",
        "egyptian"
      ],
      "\u{1F1EA}\u{1F1ED}": [
        "flag_western_sahara",
        "western",
        "sahara",
        "flag",
        "nation",
        "country",
        "banner",
        "western_sahara",
        "saharan",
        "west"
      ],
      "\u{1F1EA}\u{1F1F7}": [
        "flag_eritrea",
        "er",
        "flag",
        "nation",
        "country",
        "banner",
        "eritrea",
        "eritrean"
      ],
      "\u{1F1EA}\u{1F1F8}": [
        "flag_spain",
        "spain",
        "flag",
        "nation",
        "country",
        "banner",
        "ceuta",
        "es",
        "indicator",
        "letters",
        "melilla",
        "regional",
        "spanish",
        "symbol"
      ],
      "\u{1F1EA}\u{1F1F9}": [
        "flag_ethiopia",
        "et",
        "flag",
        "nation",
        "country",
        "banner",
        "ethiopia",
        "ethiopian"
      ],
      "\u{1F1EA}\u{1F1FA}": [
        "flag_european_union",
        "european",
        "union",
        "flag",
        "banner",
        "eu"
      ],
      "\u{1F1EB}\u{1F1EE}": [
        "flag_finland",
        "fi",
        "flag",
        "nation",
        "country",
        "banner",
        "finland",
        "finnish"
      ],
      "\u{1F1EB}\u{1F1EF}": [
        "flag_fiji",
        "fj",
        "flag",
        "nation",
        "country",
        "banner",
        "fiji",
        "fijian"
      ],
      "\u{1F1EB}\u{1F1F0}": [
        "flag_falkland_islands",
        "falkland",
        "islands",
        "malvinas",
        "flag",
        "nation",
        "country",
        "banner",
        "falkland_islands",
        "falklander",
        "falklands",
        "island",
        "islas"
      ],
      "\u{1F1EB}\u{1F1F2}": [
        "flag_micronesia",
        "micronesia",
        "federated",
        "states",
        "flag",
        "nation",
        "country",
        "banner",
        "micronesian"
      ],
      "\u{1F1EB}\u{1F1F4}": [
        "flag_faroe_islands",
        "faroe",
        "islands",
        "flag",
        "nation",
        "country",
        "banner",
        "faroe_islands",
        "island",
        "islander"
      ],
      "\u{1F1EB}\u{1F1F7}": [
        "flag_france",
        "banner",
        "flag",
        "nation",
        "france",
        "french",
        "country",
        "clipperton",
        "fr",
        "indicator",
        "island",
        "letters",
        "martin",
        "regional",
        "saint",
        "st.",
        "symbol"
      ],
      "\u{1F1EC}\u{1F1E6}": [
        "flag_gabon",
        "ga",
        "flag",
        "nation",
        "country",
        "banner",
        "gabon",
        "gabonese"
      ],
      "\u{1F1EC}\u{1F1E7}": [
        "flag_united_kingdom",
        "united",
        "kingdom",
        "great",
        "britain",
        "northern",
        "ireland",
        "flag",
        "nation",
        "country",
        "banner",
        "british",
        "UK",
        "english",
        "england",
        "union jack",
        "united_kingdom",
        "cornwall",
        "gb",
        "scotland",
        "wales"
      ],
      "\u{1F1EC}\u{1F1E9}": [
        "flag_grenada",
        "gd",
        "flag",
        "nation",
        "country",
        "banner",
        "grenada",
        "grenadian"
      ],
      "\u{1F1EC}\u{1F1EA}": [
        "flag_georgia",
        "ge",
        "flag",
        "nation",
        "country",
        "banner",
        "georgia",
        "georgian"
      ],
      "\u{1F1EC}\u{1F1EB}": [
        "flag_french_guiana",
        "french",
        "guiana",
        "flag",
        "nation",
        "country",
        "banner",
        "french_guiana",
        "guinean"
      ],
      "\u{1F1EC}\u{1F1EC}": [
        "flag_guernsey",
        "gg",
        "flag",
        "nation",
        "country",
        "banner",
        "guernsey"
      ],
      "\u{1F1EC}\u{1F1ED}": [
        "flag_ghana",
        "gh",
        "flag",
        "nation",
        "country",
        "banner",
        "ghana",
        "ghanaian"
      ],
      "\u{1F1EC}\u{1F1EE}": [
        "flag_gibraltar",
        "gi",
        "flag",
        "nation",
        "country",
        "banner",
        "gibraltar",
        "gibraltarian"
      ],
      "\u{1F1EC}\u{1F1F1}": [
        "flag_greenland",
        "gl",
        "flag",
        "nation",
        "country",
        "banner",
        "greenland",
        "greenlandic"
      ],
      "\u{1F1EC}\u{1F1F2}": [
        "flag_gambia",
        "gm",
        "flag",
        "nation",
        "country",
        "banner",
        "gambia",
        "gambian\xA0flag"
      ],
      "\u{1F1EC}\u{1F1F3}": [
        "flag_guinea",
        "gn",
        "flag",
        "nation",
        "country",
        "banner",
        "guinea",
        "guinean"
      ],
      "\u{1F1EC}\u{1F1F5}": [
        "flag_guadeloupe",
        "gp",
        "flag",
        "nation",
        "country",
        "banner",
        "guadeloupe",
        "guadeloupean"
      ],
      "\u{1F1EC}\u{1F1F6}": [
        "flag_equatorial_guinea",
        "equatorial",
        "gn",
        "flag",
        "nation",
        "country",
        "banner",
        "equatorial_guinea",
        "equatoguinean",
        "guinean"
      ],
      "\u{1F1EC}\u{1F1F7}": [
        "flag_greece",
        "gr",
        "flag",
        "nation",
        "country",
        "banner",
        "greece",
        "greek"
      ],
      "\u{1F1EC}\u{1F1F8}": [
        "flag_south_georgia_south_sandwich_islands",
        "south",
        "georgia",
        "sandwich",
        "islands",
        "flag",
        "nation",
        "country",
        "banner",
        "south_georgia_south_sandwich_islands",
        "island"
      ],
      "\u{1F1EC}\u{1F1F9}": [
        "flag_guatemala",
        "gt",
        "flag",
        "nation",
        "country",
        "banner",
        "guatemala",
        "guatemalan"
      ],
      "\u{1F1EC}\u{1F1FA}": [
        "flag_guam",
        "gu",
        "flag",
        "nation",
        "country",
        "banner",
        "guam",
        "chamorro",
        "guamanian"
      ],
      "\u{1F1EC}\u{1F1FC}": [
        "flag_guinea_bissau",
        "gw",
        "bissau",
        "flag",
        "nation",
        "country",
        "banner",
        "guinea_bissau"
      ],
      "\u{1F1EC}\u{1F1FE}": [
        "flag_guyana",
        "gy",
        "flag",
        "nation",
        "country",
        "banner",
        "guyana",
        "guyanese"
      ],
      "\u{1F1ED}\u{1F1F0}": [
        "flag_hong_kong_sar_china",
        "hong",
        "kong",
        "flag",
        "nation",
        "country",
        "banner",
        "hong_kong_sar_china"
      ],
      "\u{1F1ED}\u{1F1F2}": [
        "flag_heard_mcdonald_islands"
      ],
      "\u{1F1ED}\u{1F1F3}": [
        "flag_honduras",
        "hn",
        "flag",
        "nation",
        "country",
        "banner",
        "honduras",
        "honduran"
      ],
      "\u{1F1ED}\u{1F1F7}": [
        "flag_croatia",
        "hr",
        "flag",
        "nation",
        "country",
        "banner",
        "croatia",
        "croatian"
      ],
      "\u{1F1ED}\u{1F1F9}": [
        "flag_haiti",
        "ht",
        "flag",
        "nation",
        "country",
        "banner",
        "haiti",
        "haitian"
      ],
      "\u{1F1ED}\u{1F1FA}": [
        "flag_hungary",
        "hu",
        "flag",
        "nation",
        "country",
        "banner",
        "hungary",
        "hungarian"
      ],
      "\u{1F1EE}\u{1F1E8}": [
        "flag_canary_islands",
        "canary",
        "islands",
        "flag",
        "nation",
        "country",
        "banner",
        "canary_islands",
        "island"
      ],
      "\u{1F1EE}\u{1F1E9}": [
        "flag_indonesia",
        "flag",
        "nation",
        "country",
        "banner",
        "indonesia",
        "indonesian"
      ],
      "\u{1F1EE}\u{1F1EA}": [
        "flag_ireland",
        "ie",
        "flag",
        "nation",
        "country",
        "banner",
        "ireland",
        "irish\xA0flag"
      ],
      "\u{1F1EE}\u{1F1F1}": [
        "flag_israel",
        "il",
        "flag",
        "nation",
        "country",
        "banner",
        "israel",
        "israeli"
      ],
      "\u{1F1EE}\u{1F1F2}": [
        "flag_isle_of_man",
        "isle",
        "man",
        "flag",
        "nation",
        "country",
        "banner",
        "isle_of_man",
        "manx"
      ],
      "\u{1F1EE}\u{1F1F3}": [
        "flag_india",
        "in",
        "flag",
        "nation",
        "country",
        "banner",
        "india",
        "indian"
      ],
      "\u{1F1EE}\u{1F1F4}": [
        "flag_british_indian_ocean_territory",
        "british",
        "indian",
        "ocean",
        "territory",
        "flag",
        "nation",
        "country",
        "banner",
        "british_indian_ocean_territory",
        "chagos",
        "diego",
        "garcia",
        "island"
      ],
      "\u{1F1EE}\u{1F1F6}": [
        "flag_iraq",
        "iq",
        "flag",
        "nation",
        "country",
        "banner",
        "iraq",
        "iraqi"
      ],
      "\u{1F1EE}\u{1F1F7}": [
        "flag_iran",
        "iran",
        "islamic",
        "republic",
        "flag",
        "nation",
        "country",
        "banner",
        "iranian\xA0flag"
      ],
      "\u{1F1EE}\u{1F1F8}": [
        "flag_iceland",
        "is",
        "flag",
        "nation",
        "country",
        "banner",
        "iceland",
        "icelandic"
      ],
      "\u{1F1EE}\u{1F1F9}": [
        "flag_italy",
        "italy",
        "flag",
        "nation",
        "country",
        "banner",
        "indicator",
        "italian",
        "letters",
        "regional",
        "symbol"
      ],
      "\u{1F1EF}\u{1F1EA}": [
        "flag_jersey",
        "je",
        "flag",
        "nation",
        "country",
        "banner",
        "jersey"
      ],
      "\u{1F1EF}\u{1F1F2}": [
        "flag_jamaica",
        "jm",
        "flag",
        "nation",
        "country",
        "banner",
        "jamaica",
        "jamaican\xA0flag"
      ],
      "\u{1F1EF}\u{1F1F4}": [
        "flag_jordan",
        "jo",
        "flag",
        "nation",
        "country",
        "banner",
        "jordan",
        "jordanian"
      ],
      "\u{1F1EF}\u{1F1F5}": [
        "flag_japan",
        "japanese",
        "nation",
        "flag",
        "country",
        "banner",
        "japan",
        "jp",
        "ja",
        "indicator",
        "letters",
        "regional",
        "symbol"
      ],
      "\u{1F1F0}\u{1F1EA}": [
        "flag_kenya",
        "ke",
        "flag",
        "nation",
        "country",
        "banner",
        "kenya",
        "kenyan"
      ],
      "\u{1F1F0}\u{1F1EC}": [
        "flag_kyrgyzstan",
        "kg",
        "flag",
        "nation",
        "country",
        "banner",
        "kyrgyzstan",
        "kyrgyzstani"
      ],
      "\u{1F1F0}\u{1F1ED}": [
        "flag_cambodia",
        "kh",
        "flag",
        "nation",
        "country",
        "banner",
        "cambodia",
        "cambodian"
      ],
      "\u{1F1F0}\u{1F1EE}": [
        "flag_kiribati",
        "ki",
        "flag",
        "nation",
        "country",
        "banner",
        "kiribati",
        "i"
      ],
      "\u{1F1F0}\u{1F1F2}": [
        "flag_comoros",
        "km",
        "flag",
        "nation",
        "country",
        "banner",
        "comoros",
        "comoran"
      ],
      "\u{1F1F0}\u{1F1F3}": [
        "flag_st_kitts_nevis",
        "saint",
        "kitts",
        "nevis",
        "flag",
        "nation",
        "country",
        "banner",
        "st_kitts_nevis",
        "st."
      ],
      "\u{1F1F0}\u{1F1F5}": [
        "flag_north_korea",
        "north",
        "korea",
        "nation",
        "flag",
        "country",
        "banner",
        "north_korea",
        "korean"
      ],
      "\u{1F1F0}\u{1F1F7}": [
        "flag_south_korea",
        "south",
        "korea",
        "nation",
        "flag",
        "country",
        "banner",
        "south_korea",
        "indicator",
        "korean",
        "kr",
        "letters",
        "regional",
        "symbol"
      ],
      "\u{1F1F0}\u{1F1FC}": [
        "flag_kuwait",
        "kw",
        "flag",
        "nation",
        "country",
        "banner",
        "kuwait",
        "kuwaiti"
      ],
      "\u{1F1F0}\u{1F1FE}": [
        "flag_cayman_islands",
        "cayman",
        "islands",
        "flag",
        "nation",
        "country",
        "banner",
        "cayman_islands",
        "caymanian",
        "island"
      ],
      "\u{1F1F0}\u{1F1FF}": [
        "flag_kazakhstan",
        "kz",
        "flag",
        "nation",
        "country",
        "banner",
        "kazakhstan",
        "kazakh",
        "kazakhstani"
      ],
      "\u{1F1F1}\u{1F1E6}": [
        "flag_laos",
        "lao",
        "democratic",
        "republic",
        "flag",
        "nation",
        "country",
        "banner",
        "laos",
        "laotian"
      ],
      "\u{1F1F1}\u{1F1E7}": [
        "flag_lebanon",
        "lb",
        "flag",
        "nation",
        "country",
        "banner",
        "lebanon",
        "lebanese"
      ],
      "\u{1F1F1}\u{1F1E8}": [
        "flag_st_lucia",
        "saint",
        "lucia",
        "flag",
        "nation",
        "country",
        "banner",
        "st_lucia",
        "st."
      ],
      "\u{1F1F1}\u{1F1EE}": [
        "flag_liechtenstein",
        "li",
        "flag",
        "nation",
        "country",
        "banner",
        "liechtenstein",
        "liechtensteiner"
      ],
      "\u{1F1F1}\u{1F1F0}": [
        "flag_sri_lanka",
        "sri",
        "lanka",
        "flag",
        "nation",
        "country",
        "banner",
        "sri_lanka",
        "lankan"
      ],
      "\u{1F1F1}\u{1F1F7}": [
        "flag_liberia",
        "lr",
        "flag",
        "nation",
        "country",
        "banner",
        "liberia",
        "liberian"
      ],
      "\u{1F1F1}\u{1F1F8}": [
        "flag_lesotho",
        "ls",
        "flag",
        "nation",
        "country",
        "banner",
        "lesotho",
        "basotho"
      ],
      "\u{1F1F1}\u{1F1F9}": [
        "flag_lithuania",
        "lt",
        "flag",
        "nation",
        "country",
        "banner",
        "lithuania",
        "lithuanian"
      ],
      "\u{1F1F1}\u{1F1FA}": [
        "flag_luxembourg",
        "lu",
        "flag",
        "nation",
        "country",
        "banner",
        "luxembourg",
        "luxembourger"
      ],
      "\u{1F1F1}\u{1F1FB}": [
        "flag_latvia",
        "lv",
        "flag",
        "nation",
        "country",
        "banner",
        "latvia",
        "latvian"
      ],
      "\u{1F1F1}\u{1F1FE}": [
        "flag_libya",
        "ly",
        "flag",
        "nation",
        "country",
        "banner",
        "libya",
        "libyan"
      ],
      "\u{1F1F2}\u{1F1E6}": [
        "flag_morocco",
        "ma",
        "flag",
        "nation",
        "country",
        "banner",
        "morocco",
        "moroccan"
      ],
      "\u{1F1F2}\u{1F1E8}": [
        "flag_monaco",
        "mc",
        "flag",
        "nation",
        "country",
        "banner",
        "monaco",
        "mon\xE9gasque"
      ],
      "\u{1F1F2}\u{1F1E9}": [
        "flag_moldova",
        "moldova",
        "republic",
        "flag",
        "nation",
        "country",
        "banner",
        "moldovan"
      ],
      "\u{1F1F2}\u{1F1EA}": [
        "flag_montenegro",
        "me",
        "flag",
        "nation",
        "country",
        "banner",
        "montenegro",
        "montenegrin"
      ],
      "\u{1F1F2}\u{1F1EB}": [
        "flag_st_martin",
        "st."
      ],
      "\u{1F1F2}\u{1F1EC}": [
        "flag_madagascar",
        "mg",
        "flag",
        "nation",
        "country",
        "banner",
        "madagascar",
        "madagascan"
      ],
      "\u{1F1F2}\u{1F1ED}": [
        "flag_marshall_islands",
        "marshall",
        "islands",
        "flag",
        "nation",
        "country",
        "banner",
        "marshall_islands",
        "island",
        "marshallese"
      ],
      "\u{1F1F2}\u{1F1F0}": [
        "flag_north_macedonia",
        "macedonia",
        "flag",
        "nation",
        "country",
        "banner",
        "north_macedonia",
        "macedonian"
      ],
      "\u{1F1F2}\u{1F1F1}": [
        "flag_mali",
        "ml",
        "flag",
        "nation",
        "country",
        "banner",
        "mali",
        "malian"
      ],
      "\u{1F1F2}\u{1F1F2}": [
        "flag_myanmar",
        "mm",
        "flag",
        "nation",
        "country",
        "banner",
        "myanmar",
        "burma",
        "burmese",
        "for",
        "myanmarese\xA0flag"
      ],
      "\u{1F1F2}\u{1F1F3}": [
        "flag_mongolia",
        "mn",
        "flag",
        "nation",
        "country",
        "banner",
        "mongolia",
        "mongolian"
      ],
      "\u{1F1F2}\u{1F1F4}": [
        "flag_macao_sar_china",
        "macao",
        "flag",
        "nation",
        "country",
        "banner",
        "macao_sar_china",
        "macanese\xA0flag",
        "macau"
      ],
      "\u{1F1F2}\u{1F1F5}": [
        "flag_northern_mariana_islands",
        "northern",
        "mariana",
        "islands",
        "flag",
        "nation",
        "country",
        "banner",
        "northern_mariana_islands",
        "island",
        "micronesian",
        "north"
      ],
      "\u{1F1F2}\u{1F1F6}": [
        "flag_martinique",
        "mq",
        "flag",
        "nation",
        "country",
        "banner",
        "martinique",
        "martiniquais\xA0flag",
        "of\xA0martinique",
        "snake"
      ],
      "\u{1F1F2}\u{1F1F7}": [
        "flag_mauritania",
        "mr",
        "flag",
        "nation",
        "country",
        "banner",
        "mauritania",
        "mauritanian"
      ],
      "\u{1F1F2}\u{1F1F8}": [
        "flag_montserrat",
        "ms",
        "flag",
        "nation",
        "country",
        "banner",
        "montserrat",
        "montserratian"
      ],
      "\u{1F1F2}\u{1F1F9}": [
        "flag_malta",
        "mt",
        "flag",
        "nation",
        "country",
        "banner",
        "malta",
        "maltese"
      ],
      "\u{1F1F2}\u{1F1FA}": [
        "flag_mauritius",
        "mu",
        "flag",
        "nation",
        "country",
        "banner",
        "mauritius",
        "mauritian"
      ],
      "\u{1F1F2}\u{1F1FB}": [
        "flag_maldives",
        "mv",
        "flag",
        "nation",
        "country",
        "banner",
        "maldives",
        "maldivian"
      ],
      "\u{1F1F2}\u{1F1FC}": [
        "flag_malawi",
        "mw",
        "flag",
        "nation",
        "country",
        "banner",
        "malawi",
        "malawian\xA0flag"
      ],
      "\u{1F1F2}\u{1F1FD}": [
        "flag_mexico",
        "mx",
        "flag",
        "nation",
        "country",
        "banner",
        "mexico",
        "mexican"
      ],
      "\u{1F1F2}\u{1F1FE}": [
        "flag_malaysia",
        "my",
        "flag",
        "nation",
        "country",
        "banner",
        "malaysia",
        "malaysian"
      ],
      "\u{1F1F2}\u{1F1FF}": [
        "flag_mozambique",
        "mz",
        "flag",
        "nation",
        "country",
        "banner",
        "mozambique",
        "mozambican"
      ],
      "\u{1F1F3}\u{1F1E6}": [
        "flag_namibia",
        "na",
        "flag",
        "nation",
        "country",
        "banner",
        "namibia",
        "namibian"
      ],
      "\u{1F1F3}\u{1F1E8}": [
        "flag_new_caledonia",
        "new",
        "caledonia",
        "flag",
        "nation",
        "country",
        "banner",
        "new_caledonia",
        "caledonian"
      ],
      "\u{1F1F3}\u{1F1EA}": [
        "flag_niger",
        "ne",
        "flag",
        "nation",
        "country",
        "banner",
        "niger",
        "nigerien\xA0flag"
      ],
      "\u{1F1F3}\u{1F1EB}": [
        "flag_norfolk_island",
        "norfolk",
        "island",
        "flag",
        "nation",
        "country",
        "banner",
        "norfolk_island"
      ],
      "\u{1F1F3}\u{1F1EC}": [
        "flag_nigeria",
        "flag",
        "nation",
        "country",
        "banner",
        "nigeria",
        "nigerian"
      ],
      "\u{1F1F3}\u{1F1EE}": [
        "flag_nicaragua",
        "ni",
        "flag",
        "nation",
        "country",
        "banner",
        "nicaragua",
        "nicaraguan"
      ],
      "\u{1F1F3}\u{1F1F1}": [
        "flag_netherlands",
        "nl",
        "flag",
        "nation",
        "country",
        "banner",
        "netherlands",
        "dutch"
      ],
      "\u{1F1F3}\u{1F1F4}": [
        "flag_norway",
        "no",
        "flag",
        "nation",
        "country",
        "banner",
        "norway",
        "bouvet",
        "jan",
        "mayen",
        "norwegian",
        "svalbard"
      ],
      "\u{1F1F3}\u{1F1F5}": [
        "flag_nepal",
        "np",
        "flag",
        "nation",
        "country",
        "banner",
        "nepal",
        "nepalese"
      ],
      "\u{1F1F3}\u{1F1F7}": [
        "flag_nauru",
        "nr",
        "flag",
        "nation",
        "country",
        "banner",
        "nauru",
        "nauruan"
      ],
      "\u{1F1F3}\u{1F1FA}": [
        "flag_niue",
        "nu",
        "flag",
        "nation",
        "country",
        "banner",
        "niue",
        "niuean"
      ],
      "\u{1F1F3}\u{1F1FF}": [
        "flag_new_zealand",
        "new",
        "zealand",
        "flag",
        "nation",
        "country",
        "banner",
        "new_zealand",
        "kiwi"
      ],
      "\u{1F1F4}\u{1F1F2}": [
        "flag_oman",
        "om_symbol",
        "flag",
        "nation",
        "country",
        "banner",
        "oman",
        "omani"
      ],
      "\u{1F1F5}\u{1F1E6}": [
        "flag_panama",
        "pa",
        "flag",
        "nation",
        "country",
        "banner",
        "panama",
        "panamanian"
      ],
      "\u{1F1F5}\u{1F1EA}": [
        "flag_peru",
        "pe",
        "flag",
        "nation",
        "country",
        "banner",
        "peru",
        "peruvian"
      ],
      "\u{1F1F5}\u{1F1EB}": [
        "flag_french_polynesia",
        "french",
        "polynesia",
        "flag",
        "nation",
        "country",
        "banner",
        "french_polynesia",
        "polynesian"
      ],
      "\u{1F1F5}\u{1F1EC}": [
        "flag_papua_new_guinea",
        "papua",
        "new",
        "guinea",
        "flag",
        "nation",
        "country",
        "banner",
        "papua_new_guinea",
        "guinean",
        "png"
      ],
      "\u{1F1F5}\u{1F1ED}": [
        "flag_philippines",
        "ph",
        "flag",
        "nation",
        "country",
        "banner",
        "philippines"
      ],
      "\u{1F1F5}\u{1F1F0}": [
        "flag_pakistan",
        "pk",
        "flag",
        "nation",
        "country",
        "banner",
        "pakistan",
        "pakistani"
      ],
      "\u{1F1F5}\u{1F1F1}": [
        "flag_poland",
        "pl",
        "flag",
        "nation",
        "country",
        "banner",
        "poland",
        "polish"
      ],
      "\u{1F1F5}\u{1F1F2}": [
        "flag_st_pierre_miquelon",
        "saint",
        "pierre",
        "miquelon",
        "flag",
        "nation",
        "country",
        "banner",
        "st_pierre_miquelon",
        "st."
      ],
      "\u{1F1F5}\u{1F1F3}": [
        "flag_pitcairn_islands",
        "pitcairn",
        "flag",
        "nation",
        "country",
        "banner",
        "pitcairn_islands",
        "island"
      ],
      "\u{1F1F5}\u{1F1F7}": [
        "flag_puerto_rico",
        "puerto",
        "rico",
        "flag",
        "nation",
        "country",
        "banner",
        "puerto_rico",
        "rican"
      ],
      "\u{1F1F5}\u{1F1F8}": [
        "flag_palestinian_territories",
        "palestine",
        "palestinian",
        "territories",
        "flag",
        "nation",
        "country",
        "banner",
        "palestinian_territories"
      ],
      "\u{1F1F5}\u{1F1F9}": [
        "flag_portugal",
        "pt",
        "flag",
        "nation",
        "country",
        "banner",
        "portugal",
        "portugese"
      ],
      "\u{1F1F5}\u{1F1FC}": [
        "flag_palau",
        "pw",
        "flag",
        "nation",
        "country",
        "banner",
        "palau",
        "palauan"
      ],
      "\u{1F1F5}\u{1F1FE}": [
        "flag_paraguay",
        "py",
        "flag",
        "nation",
        "country",
        "banner",
        "paraguay",
        "paraguayan"
      ],
      "\u{1F1F6}\u{1F1E6}": [
        "flag_qatar",
        "qa",
        "flag",
        "nation",
        "country",
        "banner",
        "qatar",
        "qatari"
      ],
      "\u{1F1F7}\u{1F1EA}": [
        "flag_reunion",
        "r\xE9union",
        "flag",
        "nation",
        "country",
        "banner",
        "reunion",
        "r\xE9unionnais"
      ],
      "\u{1F1F7}\u{1F1F4}": [
        "flag_romania",
        "ro",
        "flag",
        "nation",
        "country",
        "banner",
        "romania",
        "romanian"
      ],
      "\u{1F1E8}\u{1F1F6}": [
        "flag_sark",
        "cq",
        "flag",
        "banner"
      ],
      "\u{1F1F7}\u{1F1F8}": [
        "flag_serbia",
        "rs",
        "flag",
        "nation",
        "country",
        "banner",
        "serbia",
        "serbian\xA0flag"
      ],
      "\u{1F1F7}\u{1F1FA}": [
        "flag_russia",
        "russian",
        "federation",
        "flag",
        "nation",
        "country",
        "banner",
        "russia",
        "indicator",
        "letters",
        "regional",
        "ru",
        "symbol"
      ],
      "\u{1F1F7}\u{1F1FC}": [
        "flag_rwanda",
        "rw",
        "flag",
        "nation",
        "country",
        "banner",
        "rwanda",
        "rwandan"
      ],
      "\u{1F1F8}\u{1F1E6}": [
        "flag_saudi_arabia",
        "flag",
        "nation",
        "country",
        "banner",
        "saudi_arabia",
        "arabian\xA0flag"
      ],
      "\u{1F1F8}\u{1F1E7}": [
        "flag_solomon_islands",
        "solomon",
        "islands",
        "flag",
        "nation",
        "country",
        "banner",
        "solomon_islands",
        "island",
        "islander\xA0flag"
      ],
      "\u{1F1F8}\u{1F1E8}": [
        "flag_seychelles",
        "sc",
        "flag",
        "nation",
        "country",
        "banner",
        "seychelles",
        "seychellois\xA0flag"
      ],
      "\u{1F1F8}\u{1F1E9}": [
        "flag_sudan",
        "sd",
        "flag",
        "nation",
        "country",
        "banner",
        "sudan",
        "sudanese"
      ],
      "\u{1F1F8}\u{1F1EA}": [
        "flag_sweden",
        "se",
        "flag",
        "nation",
        "country",
        "banner",
        "sweden",
        "swedish"
      ],
      "\u{1F1F8}\u{1F1EC}": [
        "flag_singapore",
        "sg",
        "flag",
        "nation",
        "country",
        "banner",
        "singapore",
        "singaporean"
      ],
      "\u{1F1F8}\u{1F1ED}": [
        "flag_st_helena",
        "saint",
        "helena",
        "ascension",
        "tristan",
        "cunha",
        "flag",
        "nation",
        "country",
        "banner",
        "st_helena",
        "st."
      ],
      "\u{1F1F8}\u{1F1EE}": [
        "flag_slovenia",
        "si",
        "flag",
        "nation",
        "country",
        "banner",
        "slovenia",
        "slovenian"
      ],
      "\u{1F1F8}\u{1F1EF}": [
        "flag_svalbard_jan_mayen"
      ],
      "\u{1F1F8}\u{1F1F0}": [
        "flag_slovakia",
        "sk",
        "flag",
        "nation",
        "country",
        "banner",
        "slovakia",
        "slovakian",
        "slovak\xA0flag"
      ],
      "\u{1F1F8}\u{1F1F1}": [
        "flag_sierra_leone",
        "sierra",
        "leone",
        "flag",
        "nation",
        "country",
        "banner",
        "sierra_leone",
        "leonean"
      ],
      "\u{1F1F8}\u{1F1F2}": [
        "flag_san_marino",
        "san",
        "marino",
        "flag",
        "nation",
        "country",
        "banner",
        "san_marino",
        "sammarinese"
      ],
      "\u{1F1F8}\u{1F1F3}": [
        "flag_senegal",
        "sn",
        "flag",
        "nation",
        "country",
        "banner",
        "senegal",
        "sengalese"
      ],
      "\u{1F1F8}\u{1F1F4}": [
        "flag_somalia",
        "so",
        "flag",
        "nation",
        "country",
        "banner",
        "somalia",
        "somalian\xA0flag"
      ],
      "\u{1F1F8}\u{1F1F7}": [
        "flag_suriname",
        "sr",
        "flag",
        "nation",
        "country",
        "banner",
        "suriname",
        "surinamer"
      ],
      "\u{1F1F8}\u{1F1F8}": [
        "flag_south_sudan",
        "south",
        "sd",
        "flag",
        "nation",
        "country",
        "banner",
        "south_sudan",
        "sudanese\xA0flag"
      ],
      "\u{1F1F8}\u{1F1F9}": [
        "flag_sao_tome_principe",
        "sao",
        "tome",
        "principe",
        "flag",
        "nation",
        "country",
        "banner",
        "sao_tome_principe",
        "pr\xEDncipe",
        "s\xE3o",
        "tom\xE9"
      ],
      "\u{1F1F8}\u{1F1FB}": [
        "flag_el_salvador",
        "el",
        "salvador",
        "flag",
        "nation",
        "country",
        "banner",
        "el_salvador",
        "salvadoran"
      ],
      "\u{1F1F8}\u{1F1FD}": [
        "flag_sint_maarten",
        "sint",
        "maarten",
        "dutch",
        "flag",
        "nation",
        "country",
        "banner",
        "sint_maarten"
      ],
      "\u{1F1F8}\u{1F1FE}": [
        "flag_syria",
        "syrian",
        "arab",
        "republic",
        "flag",
        "nation",
        "country",
        "banner",
        "syria"
      ],
      "\u{1F1F8}\u{1F1FF}": [
        "flag_eswatini",
        "sz",
        "flag",
        "nation",
        "country",
        "banner",
        "eswatini",
        "swaziland"
      ],
      "\u{1F1F9}\u{1F1E6}": [
        "flag_tristan_da_cunha"
      ],
      "\u{1F1F9}\u{1F1E8}": [
        "flag_turks_caicos_islands",
        "turks",
        "caicos",
        "islands",
        "flag",
        "nation",
        "country",
        "banner",
        "turks_caicos_islands",
        "island"
      ],
      "\u{1F1F9}\u{1F1E9}": [
        "flag_chad",
        "td",
        "flag",
        "nation",
        "country",
        "banner",
        "chad",
        "chadian"
      ],
      "\u{1F1F9}\u{1F1EB}": [
        "flag_french_southern_territories",
        "french",
        "southern",
        "territories",
        "flag",
        "nation",
        "country",
        "banner",
        "french_southern_territories",
        "antarctic",
        "lands"
      ],
      "\u{1F1F9}\u{1F1EC}": [
        "flag_togo",
        "tg",
        "flag",
        "nation",
        "country",
        "banner",
        "togo",
        "togolese"
      ],
      "\u{1F1F9}\u{1F1ED}": [
        "flag_thailand",
        "th",
        "flag",
        "nation",
        "country",
        "banner",
        "thailand",
        "thai"
      ],
      "\u{1F1F9}\u{1F1EF}": [
        "flag_tajikistan",
        "tj",
        "flag",
        "nation",
        "country",
        "banner",
        "tajikistan",
        "tajik"
      ],
      "\u{1F1F9}\u{1F1F0}": [
        "flag_tokelau",
        "tk",
        "flag",
        "nation",
        "country",
        "banner",
        "tokelau",
        "tokelauan"
      ],
      "\u{1F1F9}\u{1F1F1}": [
        "flag_timor_leste",
        "timor",
        "leste",
        "flag",
        "nation",
        "country",
        "banner",
        "timor_leste",
        "east",
        "leste\xA0flag",
        "timorese"
      ],
      "\u{1F1F9}\u{1F1F2}": [
        "flag_turkmenistan",
        "flag",
        "nation",
        "country",
        "banner",
        "turkmenistan",
        "turkmen"
      ],
      "\u{1F1F9}\u{1F1F3}": [
        "flag_tunisia",
        "tn",
        "flag",
        "nation",
        "country",
        "banner",
        "tunisia",
        "tunisian"
      ],
      "\u{1F1F9}\u{1F1F4}": [
        "flag_tonga",
        "to",
        "flag",
        "nation",
        "country",
        "banner",
        "tonga",
        "tongan\xA0flag"
      ],
      "\u{1F1F9}\u{1F1F7}": [
        "flag_turkey",
        "turkey",
        "flag",
        "nation",
        "country",
        "banner",
        "tr",
        "turkish\xA0flag",
        "t\xFCrkiye"
      ],
      "\u{1F1F9}\u{1F1F9}": [
        "flag_trinidad_tobago",
        "trinidad",
        "tobago",
        "flag",
        "nation",
        "country",
        "banner",
        "trinidad_tobago"
      ],
      "\u{1F1F9}\u{1F1FB}": [
        "flag_tuvalu",
        "flag",
        "nation",
        "country",
        "banner",
        "tuvalu",
        "tuvaluan"
      ],
      "\u{1F1F9}\u{1F1FC}": [
        "flag_taiwan",
        "tw",
        "flag",
        "nation",
        "country",
        "banner",
        "taiwan",
        "china",
        "taiwanese"
      ],
      "\u{1F1F9}\u{1F1FF}": [
        "flag_tanzania",
        "tanzania",
        "united",
        "republic",
        "flag",
        "nation",
        "country",
        "banner",
        "tanzanian"
      ],
      "\u{1F1FA}\u{1F1E6}": [
        "flag_ukraine",
        "ua",
        "flag",
        "nation",
        "country",
        "banner",
        "ukraine",
        "ukrainian"
      ],
      "\u{1F1FA}\u{1F1EC}": [
        "flag_uganda",
        "ug",
        "flag",
        "nation",
        "country",
        "banner",
        "uganda",
        "ugandan\xA0flag"
      ],
      "\u{1F1FA}\u{1F1F2}": [
        "flag_u_s_outlying_islands",
        "u.s.",
        "us"
      ],
      "\u{1F1FA}\u{1F1F3}": [
        "flag_united_nations",
        "un",
        "flag",
        "banner"
      ],
      "\u{1F1FA}\u{1F1F8}": [
        "flag_united_states",
        "united",
        "states",
        "america",
        "flag",
        "nation",
        "country",
        "banner",
        "united_states",
        "american",
        "indicator",
        "islands",
        "letters",
        "outlying",
        "regional",
        "symbol",
        "us",
        "usa"
      ],
      "\u{1F1FA}\u{1F1FE}": [
        "flag_uruguay",
        "uy",
        "flag",
        "nation",
        "country",
        "banner",
        "uruguay",
        "uruguayan"
      ],
      "\u{1F1FA}\u{1F1FF}": [
        "flag_uzbekistan",
        "uz",
        "flag",
        "nation",
        "country",
        "banner",
        "uzbekistan",
        "uzbek",
        "uzbekistani"
      ],
      "\u{1F1FB}\u{1F1E6}": [
        "flag_vatican_city",
        "vatican",
        "city",
        "flag",
        "nation",
        "country",
        "banner",
        "vatican_city",
        "vanticanien"
      ],
      "\u{1F1FB}\u{1F1E8}": [
        "flag_st_vincent_grenadines",
        "saint",
        "vincent",
        "grenadines",
        "flag",
        "nation",
        "country",
        "banner",
        "st_vincent_grenadines",
        "st."
      ],
      "\u{1F1FB}\u{1F1EA}": [
        "flag_venezuela",
        "ve",
        "bolivarian",
        "republic",
        "flag",
        "nation",
        "country",
        "banner",
        "venezuela",
        "venezuelan"
      ],
      "\u{1F1FB}\u{1F1EC}": [
        "flag_british_virgin_islands",
        "british",
        "virgin",
        "islands",
        "bvi",
        "flag",
        "nation",
        "country",
        "banner",
        "british_virgin_islands",
        "island",
        "islander"
      ],
      "\u{1F1FB}\u{1F1EE}": [
        "flag_u_s_virgin_islands",
        "virgin",
        "islands",
        "us",
        "flag",
        "nation",
        "country",
        "banner",
        "u_s_virgin_islands",
        "america",
        "island",
        "islander",
        "states",
        "u.s.",
        "united",
        "usa"
      ],
      "\u{1F1FB}\u{1F1F3}": [
        "flag_vietnam",
        "viet",
        "nam",
        "flag",
        "nation",
        "country",
        "banner",
        "vietnam",
        "vietnamese"
      ],
      "\u{1F1FB}\u{1F1FA}": [
        "flag_vanuatu",
        "vu",
        "flag",
        "nation",
        "country",
        "banner",
        "vanuatu",
        "ni",
        "vanuatu\xA0flag"
      ],
      "\u{1F1FC}\u{1F1EB}": [
        "flag_wallis_futuna",
        "wallis",
        "futuna",
        "flag",
        "nation",
        "country",
        "banner",
        "wallis_futuna"
      ],
      "\u{1F1FC}\u{1F1F8}": [
        "flag_samoa",
        "ws",
        "flag",
        "nation",
        "country",
        "banner",
        "samoa",
        "samoan\xA0flag"
      ],
      "\u{1F1FD}\u{1F1F0}": [
        "flag_kosovo",
        "xk",
        "flag",
        "nation",
        "country",
        "banner",
        "kosovo",
        "kosovar"
      ],
      "\u{1F1FE}\u{1F1EA}": [
        "flag_yemen",
        "ye",
        "flag",
        "nation",
        "country",
        "banner",
        "yemen",
        "yemeni\xA0flag"
      ],
      "\u{1F1FE}\u{1F1F9}": [
        "flag_mayotte",
        "yt",
        "flag",
        "nation",
        "country",
        "banner",
        "mayotte"
      ],
      "\u{1F1FF}\u{1F1E6}": [
        "flag_south_africa",
        "south",
        "africa",
        "flag",
        "nation",
        "country",
        "banner",
        "south_africa",
        "african\xA0flag"
      ],
      "\u{1F1FF}\u{1F1F2}": [
        "flag_zambia",
        "zm",
        "flag",
        "nation",
        "country",
        "banner",
        "zambia",
        "zambian"
      ],
      "\u{1F1FF}\u{1F1FC}": [
        "flag_zimbabwe",
        "zw",
        "flag",
        "nation",
        "country",
        "banner",
        "zimbabwe",
        "zim",
        "zimbabwean\xA0flag"
      ],
      "\u{1F3F4}\u{E0067}\u{E0062}\u{E0065}\u{E006E}\u{E0067}\u{E007F}": [
        "flag_england",
        "flag",
        "english",
        "cross",
        "george's",
        "st"
      ],
      "\u{1F3F4}\u{E0067}\u{E0062}\u{E0073}\u{E0063}\u{E0074}\u{E007F}": [
        "flag_scotland",
        "flag",
        "scottish",
        "andrew's",
        "cross",
        "saltire",
        "st"
      ],
      "\u{1F3F4}\u{E0067}\u{E0062}\u{E0077}\u{E006C}\u{E0073}\u{E007F}": [
        "flag_wales",
        "flag",
        "welsh",
        "baner",
        "cymru",
        "ddraig",
        "dragon",
        "goch",
        "red",
        "y"
      ],
      "\u{1F972}": [
        "smiling face with tear",
        "sad",
        "cry",
        "pretend",
        "grateful",
        "happy",
        "proud",
        "relieved",
        "smile",
        "touched"
      ],
      "\u{1F978}": [
        "disguised face",
        "pretent",
        "brows",
        "glasses",
        "moustache",
        "disguise",
        "incognito",
        "nose"
      ],
      "\u{1F90C}": [
        "pinched fingers",
        "size",
        "tiny",
        "small",
        "che",
        "finger",
        "gesture",
        "hand",
        "interrogation",
        "ma",
        "purse",
        "sarcastic",
        "vuoi"
      ],
      "\u{1FAC0}": [
        "anatomical heart",
        "health",
        "heartbeat",
        "cardiology",
        "organ",
        "pulse"
      ],
      "\u{1FAC1}": [
        "lungs",
        "breathe",
        "breath",
        "exhalation",
        "inhalation",
        "organ",
        "respiration"
      ],
      "\u{1F977}": [
        "ninja",
        "ninjutsu",
        "skills",
        "japanese",
        "fighter",
        "hidden",
        "stealth"
      ],
      "\u{1F935}\u200D\u2642\uFE0F": [
        "man in tuxedo",
        "formal",
        "fashion",
        "groom",
        "male",
        "men",
        "person",
        "suit",
        "wedding"
      ],
      "\u{1F935}\u200D\u2640\uFE0F": [
        "woman in tuxedo",
        "formal",
        "fashion",
        "female",
        "wedding",
        "women"
      ],
      "\u{1F470}\u200D\u2642\uFE0F": [
        "man with veil",
        "wedding",
        "marriage",
        "bride",
        "male",
        "men"
      ],
      "\u{1F470}\u200D\u2640\uFE0F": [
        "woman with veil",
        "wedding",
        "marriage",
        "bride",
        "female",
        "women"
      ],
      "\u{1F469}\u200D\u{1F37C}": [
        "woman feeding baby",
        "birth",
        "food",
        "bottle",
        "child",
        "female",
        "infant",
        "milk",
        "nursing",
        "women"
      ],
      "\u{1F468}\u200D\u{1F37C}": [
        "man feeding baby",
        "birth",
        "food",
        "bottle",
        "child",
        "infant",
        "male",
        "men",
        "milk",
        "nursing"
      ],
      "\u{1F9D1}\u200D\u{1F37C}": [
        "person feeding baby",
        "birth",
        "food",
        "bottle",
        "child",
        "infant",
        "milk",
        "nursing"
      ],
      "\u{1F9D1}\u200D\u{1F384}": [
        "mx claus",
        "christmas",
        "activity",
        "celebration",
        "mx.",
        "santa"
      ],
      "\u{1FAC2}": [
        "people hugging",
        "care",
        "goodbye",
        "hello",
        "hug",
        "thanks"
      ],
      "\u{1F408}\u200D\u2B1B": [
        "black cat",
        "superstition",
        "luck",
        "halloween",
        "pet",
        "unlucky"
      ],
      "\u{1F9AC}": [
        "bison",
        "ox",
        "buffalo",
        "herd",
        "wisent"
      ],
      "\u{1F9A3}": [
        "mammoth",
        "elephant",
        "tusks",
        "extinct",
        "extinction",
        "large",
        "tusk",
        "woolly"
      ],
      "\u{1F9AB}": [
        "beaver",
        "animal",
        "rodent",
        "dam"
      ],
      "\u{1F43B}\u200D\u2744\uFE0F": [
        "polar bear",
        "animal",
        "arctic",
        "face",
        "white"
      ],
      "\u{1F9A4}": [
        "dodo",
        "animal",
        "bird",
        "extinct",
        "extinction",
        "large",
        "mauritius",
        "obsolete"
      ],
      "\u{1FAB6}": [
        "feather",
        "bird",
        "fly",
        "flight",
        "light",
        "plumage"
      ],
      "\u{1F9AD}": [
        "seal",
        "animal",
        "creature",
        "sea",
        "lion"
      ],
      "\u{1FAB2}": [
        "beetle",
        "insect",
        "bug"
      ],
      "\u{1FAB3}": [
        "cockroach",
        "insect",
        "pests",
        "pest",
        "roach"
      ],
      "\u{1FAB0}": [
        "fly",
        "insect",
        "disease",
        "maggot",
        "pest",
        "rotting"
      ],
      "\u{1FAB1}": [
        "worm",
        "animal",
        "annelid",
        "earthworm",
        "parasite"
      ],
      "\u{1FAB4}": [
        "potted plant",
        "greenery",
        "house",
        "boring",
        "grow",
        "houseplant",
        "nurturing",
        "useless"
      ],
      "\u{1FAD0}": [
        "blueberries",
        "fruit",
        "berry",
        "bilberry",
        "blue",
        "blueberry"
      ],
      "\u{1FAD2}": [
        "olive",
        "fruit",
        "food",
        "olives"
      ],
      "\u{1FAD1}": [
        "bell pepper",
        "fruit",
        "plant",
        "capsicum",
        "vegetable"
      ],
      "\u{1FAD3}": [
        "flatbread",
        "flour",
        "food",
        "bakery",
        "arepa",
        "bread",
        "flat",
        "lavash",
        "naan",
        "pita"
      ],
      "\u{1FAD4}": [
        "tamale",
        "food",
        "masa",
        "mexican",
        "tamal",
        "wrapped"
      ],
      "\u{1FAD5}": [
        "fondue",
        "cheese",
        "pot",
        "food",
        "chocolate",
        "melted",
        "swiss"
      ],
      "\u{1FAD6}": [
        "teapot",
        "drink",
        "hot",
        "kettle",
        "pot",
        "tea"
      ],
      "\u{1F9CB}": [
        "bubble tea",
        "taiwan",
        "boba",
        "milk tea",
        "straw",
        "momi",
        "pearl",
        "tapioca"
      ],
      "\u{1FAA8}": [
        "rock",
        "stone",
        "boulder",
        "construction",
        "heavy",
        "solid"
      ],
      "\u{1FAB5}": [
        "wood",
        "nature",
        "timber",
        "trunk",
        "construction",
        "log",
        "lumber"
      ],
      "\u{1F6D6}": [
        "hut",
        "house",
        "structure",
        "roundhouse",
        "yurt"
      ],
      "\u{1F6FB}": [
        "pickup truck",
        "car",
        "transportation",
        "vehicle"
      ],
      "\u{1F6FC}": [
        "roller skate",
        "footwear",
        "sports",
        "derby",
        "inline"
      ],
      "\u{1FA84}": [
        "magic wand",
        "supernature",
        "power",
        "witch",
        "wizard"
      ],
      "\u{1FA85}": [
        "pinata",
        "mexico",
        "candy",
        "celebration",
        "party",
        "pi\xF1ata"
      ],
      "\u{1FA86}": [
        "nesting dolls",
        "matryoshka",
        "toy",
        "doll",
        "russia",
        "russian"
      ],
      "\u{1FAA1}": [
        "sewing needle",
        "stitches",
        "embroidery",
        "sutures",
        "tailoring"
      ],
      "\u{1FAA2}": [
        "knot",
        "rope",
        "scout",
        "tangled",
        "tie",
        "twine",
        "twist"
      ],
      "\u{1FA74}": [
        "thong sandal",
        "footwear",
        "summer",
        "beach",
        "flip",
        "flops",
        "jandals",
        "sandals",
        "thongs",
        "z\u014Dri"
      ],
      "\u{1FA96}": [
        "military helmet",
        "army",
        "protection",
        "soldier",
        "warrior"
      ],
      "\u{1FA97}": [
        "accordion",
        "music",
        "accordian",
        "box",
        "concertina",
        "squeeze"
      ],
      "\u{1FA98}": [
        "long drum",
        "music",
        "beat",
        "conga",
        "djembe",
        "rhythm"
      ],
      "\u{1FA99}": [
        "coin",
        "money",
        "currency",
        "gold",
        "metal",
        "silver",
        "treasure"
      ],
      "\u{1FA83}": [
        "boomerang",
        "weapon",
        "australia",
        "rebound",
        "repercussion"
      ],
      "\u{1FA9A}": [
        "carpentry saw",
        "cut",
        "chop",
        "carpenter",
        "hand",
        "lumber",
        "tool"
      ],
      "\u{1FA9B}": [
        "screwdriver",
        "tools",
        "screw",
        "tool"
      ],
      "\u{1FA9D}": [
        "hook",
        "tools",
        "catch",
        "crook",
        "curve",
        "ensnare",
        "fishing",
        "point",
        "selling",
        "tool"
      ],
      "\u{1FA9C}": [
        "ladder",
        "tools",
        "climb",
        "rung",
        "step",
        "tool"
      ],
      "\u{1F6D7}": [
        "elevator",
        "lift",
        "accessibility",
        "hoist"
      ],
      "\u{1FA9E}": [
        "mirror",
        "reflection",
        "reflector",
        "speculum"
      ],
      "\u{1FA9F}": [
        "window",
        "scenery",
        "air",
        "frame",
        "fresh",
        "glass",
        "opening",
        "transparent",
        "view"
      ],
      "\u{1FAA0}": [
        "plunger",
        "toilet",
        "cup",
        "force",
        "plumber",
        "suction"
      ],
      "\u{1FAA4}": [
        "mouse trap",
        "cheese",
        "bait",
        "mousetrap",
        "rodent",
        "snare"
      ],
      "\u{1FAA3}": [
        "bucket",
        "water",
        "container",
        "cask",
        "pail",
        "vat"
      ],
      "\u{1FAA5}": [
        "toothbrush",
        "hygiene",
        "dental",
        "bathroom",
        "brush",
        "clean",
        "teeth"
      ],
      "\u{1FAA6}": [
        "headstone",
        "death",
        "rip",
        "grave",
        "cemetery",
        "graveyard",
        "halloween",
        "tombstone"
      ],
      "\u{1FAA7}": [
        "placard",
        "announcement",
        "demonstration",
        "lawn",
        "picket",
        "post",
        "protest",
        "sign"
      ],
      "\u26A7\uFE0F": [
        "transgender symbol",
        "transgender",
        "lgbtq",
        "female",
        "lgbt",
        "male",
        "pride",
        "sign",
        "stroke"
      ],
      "\u{1F3F3}\uFE0F\u200D\u26A7\uFE0F": [
        "transgender flag",
        "transgender",
        "flag",
        "pride",
        "lgbtq",
        "blue",
        "lgbt",
        "light",
        "pink",
        "trans",
        "white"
      ],
      "\u{1F636}\u200D\u{1F32B}\uFE0F": [
        "face in clouds",
        "shower",
        "steam",
        "dream",
        "absentminded",
        "brain",
        "fog",
        "forgetful",
        "haze",
        "head",
        "impractical",
        "unrealistic"
      ],
      "\u{1F62E}\u200D\u{1F4A8}": [
        "face exhaling",
        "relieve",
        "relief",
        "tired",
        "sigh",
        "exhale",
        "gasp",
        "groan",
        "whisper",
        "whistle"
      ],
      "\u{1F635}\u200D\u{1F4AB}": [
        "face with spiral eyes",
        "sick",
        "ill",
        "confused",
        "nauseous",
        "nausea",
        "dizzy",
        "hypnotized",
        "trouble",
        "whoa"
      ],
      "\u2764\uFE0F\u200D\u{1F525}": [
        "heart on fire",
        "passionate",
        "enthusiastic",
        "burn",
        "love",
        "lust",
        "sacred"
      ],
      "\u2764\uFE0F\u200D\u{1FA79}": [
        "mending heart",
        "broken heart",
        "bandage",
        "wounded",
        "bandaged",
        "healing",
        "healthier",
        "improving",
        "recovering",
        "recuperating",
        "unbroken",
        "well"
      ],
      "\u{1F9D4}\u200D\u2642\uFE0F": [
        "man beard",
        "facial hair",
        "bearded",
        "bewhiskered",
        "male",
        "men"
      ],
      "\u{1F9D4}\u200D\u2640\uFE0F": [
        "woman beard",
        "facial hair",
        "bearded",
        "bewhiskered",
        "female",
        "women"
      ],
      "\u{1FAE0}": [
        "melting face",
        "hot",
        "heat",
        "disappear",
        "dissolve",
        "dread",
        "liquid",
        "melt",
        "sarcasm"
      ],
      "\u{1FAE2}": [
        "face with open eyes and hand over mouth",
        "silence",
        "secret",
        "shock",
        "surprise",
        "amazement",
        "awe",
        "disbelief",
        "embarrass",
        "gasp",
        "scared"
      ],
      "\u{1FAE3}": [
        "face with peeking eye",
        "scared",
        "frightening",
        "embarrassing",
        "shy",
        "captivated",
        "peep",
        "stare"
      ],
      "\u{1FAE1}": [
        "saluting face",
        "respect",
        "salute",
        "ok",
        "sunny",
        "troops",
        "yes"
      ],
      "\u{1FAE5}": [
        "dotted line face",
        "invisible",
        "lonely",
        "isolation",
        "depression",
        "depressed",
        "disappear",
        "hide",
        "introvert"
      ],
      "\u{1FAE4}": [
        "face with diagonal mouth",
        "skeptic",
        "confuse",
        "frustrated",
        "indifferent",
        "confused",
        "disappointed",
        "meh",
        "skeptical",
        "unsure"
      ],
      "\u{1F979}": [
        "face holding back tears",
        "touched",
        "gratitude",
        "cry",
        "angry",
        "proud",
        "resist",
        "sad"
      ],
      "\u{1FAF1}": [
        "rightwards hand",
        "palm",
        "offer",
        "right",
        "rightward"
      ],
      "\u{1FAF2}": [
        "leftwards hand",
        "palm",
        "offer",
        "left",
        "leftward"
      ],
      "\u{1FAF3}": [
        "palm down hand",
        "palm",
        "drop",
        "dismiss",
        "shoo"
      ],
      "\u{1FAF4}": [
        "palm up hand",
        "lift",
        "offer",
        "demand",
        "beckon",
        "catch",
        "come"
      ],
      "\u{1FAF0}": [
        "hand with index finger and thumb crossed",
        "heart",
        "love",
        "money",
        "expensive",
        "snap"
      ],
      "\u{1FAF5}": [
        "index pointing at the viewer",
        "you",
        "recruit",
        "point"
      ],
      "\u{1FAF6}": [
        "heart hands",
        "love",
        "appreciation",
        "support"
      ],
      "\u{1FAE6}": [
        "biting lip",
        "flirt",
        "sexy",
        "pain",
        "worry",
        "anxious",
        "fear",
        "flirting",
        "nervous",
        "uncomfortable",
        "worried"
      ],
      "\u{1FAC5}": [
        "person with crown",
        "royalty",
        "power",
        "monarch",
        "noble",
        "regal"
      ],
      "\u{1FAC3}": [
        "pregnant man",
        "baby",
        "belly",
        "bloated",
        "full"
      ],
      "\u{1FAC4}": [
        "pregnant person",
        "baby",
        "belly",
        "bloated",
        "full"
      ],
      "\u{1F9CC}": [
        "troll",
        "mystical",
        "monster",
        "fairy",
        "fantasy",
        "tale",
        "shrek"
      ],
      "\u{1FAB8}": [
        "coral",
        "ocean",
        "sea",
        "reef"
      ],
      "\u{1FAB7}": [
        "lotus",
        "flower",
        "calm",
        "meditation",
        "buddhism",
        "hinduism",
        "india",
        "purity",
        "vietnam"
      ],
      "\u{1FAB9}": [
        "empty nest",
        "bird",
        "nesting"
      ],
      "\u{1FABA}": [
        "nest with eggs",
        "bird",
        "nesting"
      ],
      "\u{1FAD8}": [
        "beans",
        "food",
        "kidney",
        "legume"
      ],
      "\u{1FAD7}": [
        "pouring liquid",
        "cup",
        "water",
        "drink",
        "empty",
        "glass",
        "spill"
      ],
      "\u{1FAD9}": [
        "jar",
        "container",
        "sauce",
        "condiment",
        "empty",
        "store"
      ],
      "\u{1F6DD}": [
        "playground slide",
        "fun",
        "park",
        "amusement",
        "play"
      ],
      "\u{1F6DE}": [
        "wheel",
        "car",
        "transport",
        "circle",
        "tire",
        "turn"
      ],
      "\u{1F6DF}": [
        "ring buoy",
        "life saver",
        "life preserver",
        "float",
        "rescue",
        "safety"
      ],
      "\u{1FAAC}": [
        "hamsa",
        "religion",
        "protection",
        "amulet",
        "fatima",
        "hand",
        "mary",
        "miriam"
      ],
      "\u{1FAA9}": [
        "mirror ball",
        "disco",
        "dance",
        "party",
        "glitter"
      ],
      "\u{1FAAB}": [
        "low battery",
        "drained",
        "dead",
        "electronic",
        "energy",
        "no",
        "red"
      ],
      "\u{1FA7C}": [
        "crutch",
        "accessibility",
        "assist",
        "aid",
        "cane",
        "disability",
        "hurt",
        "mobility",
        "stick"
      ],
      "\u{1FA7B}": [
        "x-ray",
        "skeleton",
        "medicine",
        "bones",
        "doctor",
        "medical",
        "ray",
        "x"
      ],
      "\u{1FAE7}": [
        "bubbles",
        "soap",
        "fun",
        "carbonation",
        "sparkling",
        "burp",
        "clean",
        "underwater"
      ],
      "\u{1FAAA}": [
        "identification card",
        "document",
        "credentials",
        "id",
        "license",
        "security"
      ],
      "\u{1F7F0}": [
        "heavy equals sign",
        "math",
        "equality"
      ],
      "\u{1FAE8}": [
        "shaking face",
        "dizzy",
        "shock",
        "blurry",
        "earthquake"
      ],
      "\u{1FA77}": [
        "pink heart",
        "valentines"
      ],
      "\u{1FA75}": [
        "light blue heart",
        "ice",
        "baby blue"
      ],
      "\u{1FA76}": [
        "grey heart",
        "silver",
        "monochrome"
      ],
      "\u{1FAF7}": [
        "leftwards pushing hand",
        "highfive",
        "pressing",
        "stop"
      ],
      "\u{1FAF8}": [
        "rightwards pushing hand",
        "highfive",
        "pressing",
        "stop"
      ],
      "\u{1FACE}": [
        "moose",
        "canada",
        "sweden",
        "sven",
        "cool"
      ],
      "\u{1FACF}": [
        "donkey",
        "eeyore",
        "mule"
      ],
      "\u{1FABD}": [
        "wing",
        "angel",
        "birds",
        "flying",
        "fly"
      ],
      "\u{1F426}\u200D\u2B1B": [
        "black bird",
        "crow"
      ],
      "\u{1FABF}": [
        "goose",
        "silly",
        "jemima",
        "goosebumps",
        "honk"
      ],
      "\u{1FABC}": [
        "jellyfish",
        "sting",
        "tentacles"
      ],
      "\u{1FABB}": [
        "hyacinth",
        "flower",
        "lavender"
      ],
      "\u{1FADA}": [
        "ginger root",
        "spice",
        "yellow",
        "cooking",
        "gingerbread"
      ],
      "\u{1FADB}": [
        "pea pod",
        "cozy",
        "green"
      ],
      "\u{1FAAD}": [
        "folding hand fan",
        "flamenco",
        "hot",
        "sensu"
      ],
      "\u{1FAAE}": [
        "hair pick",
        "afro",
        "comb"
      ],
      "\u{1FA87}": [
        "maracas",
        "music",
        "instrument",
        "percussion",
        "shaker"
      ],
      "\u{1FA88}": [
        "flute",
        "bamboo",
        "music",
        "instrument",
        "pied piper",
        "recorder"
      ],
      "\u{1FAAF}": [
        "khanda",
        "Sikhism",
        "religion"
      ],
      "\u{1F6DC}": [
        "wireless",
        "wifi",
        "internet",
        "contactless",
        "signal"
      ],
      "\u{1F642}\u200D\u2194\uFE0F": [
        "head shaking horizontally",
        "disapprove",
        "indiffernt",
        "left"
      ],
      "\u{1F642}\u200D\u2195\uFE0F": [
        "head shaking vertically",
        "down",
        "nod"
      ],
      "\u{1F6B6}\u200D\u27A1\uFE0F": [
        "person walking facing right",
        "peerson",
        "exercise"
      ],
      "\u{1F6B6}\u200D\u2640\uFE0F\u200D\u27A1\uFE0F": [
        "woman walking facing right",
        "person",
        "exercise"
      ],
      "\u{1F6B6}\u200D\u2642\uFE0F\u200D\u27A1\uFE0F": [
        "man walking facing right",
        "person",
        "exercise"
      ],
      "\u{1F9CE}\u200D\u27A1\uFE0F": [
        "person kneeling facing right",
        "pray"
      ],
      "\u{1F9CE}\u200D\u2640\uFE0F\u200D\u27A1\uFE0F": [
        "woman kneeling facing right",
        "pray",
        "worship"
      ],
      "\u{1F9CE}\u200D\u2642\uFE0F\u200D\u27A1\uFE0F": [
        "man kneeling facing right",
        "pray",
        "worship"
      ],
      "\u{1F9D1}\u200D\u{1F9AF}\u200D\u27A1\uFE0F": [
        "person with white cane facing right",
        "walk",
        "walk",
        "visually impaired",
        "blind"
      ],
      "\u{1F468}\u200D\u{1F9AF}\u200D\u27A1\uFE0F": [
        "man with white cane facing right",
        "visually impaired",
        "blind",
        "walk",
        "stick"
      ],
      "\u{1F469}\u200D\u{1F9AF}\u200D\u27A1\uFE0F": [
        "woman with white cane facing right",
        "stick",
        "visually impaired",
        "blind"
      ],
      "\u{1F9D1}\u200D\u{1F9BC}\u200D\u27A1\uFE0F": [
        "person in motorized wheelchair facing right",
        "accessibility",
        "disability"
      ],
      "\u{1F468}\u200D\u{1F9BC}\u200D\u27A1\uFE0F": [
        "man in motorized wheelchair facing right",
        "disability",
        "accessibility",
        "mobility"
      ],
      "\u{1F469}\u200D\u{1F9BC}\u200D\u27A1\uFE0F": [
        "woman in motorized wheelchair facing right",
        "mobility",
        "accessibility",
        "disability"
      ],
      "\u{1F9D1}\u200D\u{1F9BD}\u200D\u27A1\uFE0F": [
        "person in manual wheelchair facing right",
        "mobility",
        "accessibility",
        "disability"
      ],
      "\u{1F468}\u200D\u{1F9BD}\u200D\u27A1\uFE0F": [
        "man in manual wheelchair facing right",
        "mobility",
        "accessibility",
        "disability"
      ],
      "\u{1F469}\u200D\u{1F9BD}\u200D\u27A1\uFE0F": [
        "woman in manual wheelchair facing right",
        "disability",
        "mobility",
        "accessibility"
      ],
      "\u{1F3C3}\u200D\u27A1\uFE0F": [
        "person running facing right",
        "exercise",
        "jog"
      ],
      "\u{1F3C3}\u200D\u2640\uFE0F\u200D\u27A1\uFE0F": [
        "woman running facing right",
        "exercise",
        "jog"
      ],
      "\u{1F3C3}\u200D\u2642\uFE0F\u200D\u27A1\uFE0F": [
        "man running facing right",
        "jog",
        "exercise"
      ],
      "\u{1F9D1}\u200D\u{1F9D1}\u200D\u{1F9D2}": [
        "family adult, adult, child",
        "kid",
        "parents"
      ],
      "\u{1F9D1}\u200D\u{1F9D1}\u200D\u{1F9D2}\u200D\u{1F9D2}": [
        "family adult, adult, child, child",
        "children",
        "parents"
      ],
      "\u{1F9D1}\u200D\u{1F9D2}": [
        "family adult, child",
        "parent",
        "kid"
      ],
      "\u{1F9D1}\u200D\u{1F9D2}\u200D\u{1F9D2}": [
        "family adult, child, child",
        "parent",
        "children"
      ],
      "\u{1F426}\u200D\u{1F525}": [
        "phoenix",
        "immortal",
        "bird",
        "mythtical",
        "reborn"
      ],
      "\u{1F34B}\u200D\u{1F7E9}": [
        "lime",
        "fruit",
        "acidic",
        "citric"
      ],
      "\u{1F344}\u200D\u{1F7EB}": [
        "brown mushroom",
        "toadstool",
        "fungus"
      ],
      "\u26D3\uFE0F\u200D\u{1F4A5}": [
        "broken chain",
        "constraint",
        "break"
      ],
      "\u{1FAE9}": [
        "face with bags under eyes",
        "tired",
        "sleepy",
        "exhausted"
      ],
      "\u{1FAC6}": [
        "fingerprint"
      ],
      "\u{1FABE}": [
        "leafless tree"
      ],
      "\u{1FADC}": [
        "root vegetable",
        "radish"
      ],
      "\u{1FA89}": [
        "harp",
        "music",
        "instrument"
      ],
      "\u{1FA8F}": [
        "shovel",
        "tool",
        "dig"
      ],
      "\u{1FADF}": [
        "splatter"
      ]
    };
  }
});

// src/resources/emojis.js
var emojiData;
var init_emojis = __esm({
  "src/resources/emojis.js"() {
    init_emoji_en_US();
    emojiData = Object.entries(emoji_en_US_default).map(([emoji, keywords]) => ({
      emoji,
      keywords: keywords.join(" ")
    }));
  }
});

// src/modal/modals/emojiSelectionModal.js
var import_obsidian19, EmojiSelectionModal;
var init_emojiSelectionModal = __esm({
  "src/modal/modals/emojiSelectionModal.js"() {
    import_obsidian19 = require("obsidian");
    init_emojis();
    init_modals();
    EmojiSelectionModal = class extends import_obsidian19.Modal {
      constructor(app, plugin, onChoose, skipTargetingModal = false) {
        super(app);
        this.plugin = plugin;
        this.onChoose = onChoose;
        this.searchQuery = "";
        this.skipTargetingModal = skipTargetingModal;
        this.closedByButton = false;
      }
      onOpen() {
        var _a;
        const { contentEl } = this;
        contentEl.empty();
        contentEl.addClass("pixel-banner-emoji-select-modal");
        this.closedByButton = false;
        const activeFile = this.app.workspace.getActiveFile();
        const frontmatter = (_a = this.app.metadataCache.getFileCache(activeFile)) == null ? void 0 : _a.frontmatter;
        const bannerIconField = Array.isArray(this.plugin.settings.customBannerIconField) ? this.plugin.settings.customBannerIconField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconField;
        this.currentBannerIconField = (frontmatter == null ? void 0 : frontmatter[bannerIconField]) || "";
        contentEl.createEl("h3", {
          text: "\u{1F4F0} Set Banner Icon Emoji & Text",
          cls: "banner-icon-title margin-top-0"
        });
        contentEl.createEl("p", {
          text: `Use the form below to optionally set an emoji and/or text as this note's Banner Icon. Leave the value blank and click the "Update Banner Icon" button to clear any existing banner icon if it exists.`,
          attr: {
            style: `
                    padding-top: 20px;
                    border-top: 1px solid var(--background-modifier-border);
                    font-size: 0.8em;
                    color: var(--text-muted);
                `
          }
        });
        const bannerIconContainer = contentEl.createDiv({
          cls: "banner-icon-input-container",
          attr: {
            style: `
                    display: flex;
                    gap: 8px;
                    align-items: center;
                    margin-top: 1em;
                    padding: 8px;
                `
          }
        });
        this.bannerIconInput = bannerIconContainer.createEl("input", {
          type: "text",
          placeholder: "Enter an emoji and/or text...",
          cls: "banner-icon-input",
          attr: {
            style: `
                    font-size: 1.2em;
                    padding: 15px 10px;
                `
          },
          value: this.currentBannerIconField || ""
        });
        const setBannerButton = bannerIconContainer.createEl("button", {
          text: "\u{1F4BE} Insert / Update",
          cls: "set-banner-button",
          attr: {
            style: `
                    background-color: var(--interactive-accent);
                    --text-color: var(--text-on-accent);
                `
          }
        });
        const removeBannerIconButton = bannerIconContainer.createEl("button", {
          text: "\u{1F5D1}\uFE0F Remove",
          cls: "remove-banner-icon-button cursor-pointer"
        });
        const handleSetBannerButtonClick = async () => {
          this.closedByButton = true;
          const trimmedValue = this.bannerIconInput.value.trim();
          await this.onChoose(trimmedValue === "" ? null : trimmedValue);
          if (trimmedValue === "") {
            const activeFile3 = this.app.workspace.getActiveFile();
            if (activeFile3) {
              await this.app.fileManager.processFrontMatter(activeFile3, (frontmatter2) => {
                const bannerIconField2 = Array.isArray(this.plugin.settings.customBannerIconField) ? this.plugin.settings.customBannerIconField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconField;
                const bannerIconImageAlignmentField = Array.isArray(this.plugin.settings.customBannerIconImageAlignmentField) ? this.plugin.settings.customBannerIconImageAlignmentField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageAlignmentField;
                const iconSizeField = Array.isArray(this.plugin.settings.customBannerIconSizeField) ? this.plugin.settings.customBannerIconSizeField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconSizeField;
                const iconTextVerticalOffsetField = Array.isArray(this.plugin.settings.customBannerIconTextVerticalOffsetField) ? this.plugin.settings.customBannerIconTextVerticalOffsetField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconTextVerticalOffsetField;
                const iconRotateField = Array.isArray(this.plugin.settings.customBannerIconRotateField) ? this.plugin.settings.customBannerIconRotateField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconRotateField;
                const iconYPositionField = Array.isArray(this.plugin.settings.customBannerIconVerticalOffsetField) ? this.plugin.settings.customBannerIconVerticalOffsetField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconVerticalOffsetField;
                const iconXPositionField = Array.isArray(this.plugin.settings.customBannerIconXPositionField) ? this.plugin.settings.customBannerIconXPositionField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconXPositionField;
                const iconColorField = Array.isArray(this.plugin.settings.customBannerIconColorField) ? this.plugin.settings.customBannerIconColorField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconColorField;
                const iconBgColorField = Array.isArray(this.plugin.settings.customBannerIconBackgroundColorField) ? this.plugin.settings.customBannerIconBackgroundColorField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconBackgroundColorField;
                const iconXPaddingField = Array.isArray(this.plugin.settings.customBannerIconPaddingXField) ? this.plugin.settings.customBannerIconPaddingXField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconPaddingXField;
                const iconYPaddingField = Array.isArray(this.plugin.settings.customBannerIconPaddingYField) ? this.plugin.settings.customBannerIconPaddingYField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconPaddingYField;
                const iconBorderRadiusField = Array.isArray(this.plugin.settings.customBannerIconBorderRadiusField) ? this.plugin.settings.customBannerIconBorderRadiusField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconBorderRadiusField;
                const bannerIconImageField = Array.isArray(this.plugin.settings.customBannerIconImageField) ? this.plugin.settings.customBannerIconImageField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageField;
                const iconImageSizeMultiplierField = Array.isArray(this.plugin.settings.customBannerIconImageSizeMultiplierField) ? this.plugin.settings.customBannerIconImageSizeMultiplierField[0].split(",")[0].trim() : this.plugin.settings.customBannerIconImageSizeMultiplierField;
                const hasBannerIconImage = frontmatter2[bannerIconImageField] !== void 0 && frontmatter2[bannerIconImageField] !== null && frontmatter2[bannerIconImageField] !== "";
                if (!hasBannerIconImage) {
                  delete frontmatter2[bannerIconField2];
                  delete frontmatter2[bannerIconImageAlignmentField];
                  delete frontmatter2[iconSizeField];
                  delete frontmatter2[iconTextVerticalOffsetField];
                  delete frontmatter2[iconRotateField];
                  delete frontmatter2[iconYPositionField];
                  delete frontmatter2[iconXPositionField];
                  delete frontmatter2[iconColorField];
                  delete frontmatter2[iconBgColorField];
                  delete frontmatter2[iconXPaddingField];
                  delete frontmatter2[iconYPaddingField];
                  delete frontmatter2[iconBorderRadiusField];
                  delete frontmatter2[iconImageSizeMultiplierField];
                } else {
                  delete frontmatter2[bannerIconField2];
                  delete frontmatter2[iconTextVerticalOffsetField];
                  delete frontmatter2[iconColorField];
                  delete frontmatter2[bannerIconImageAlignmentField];
                }
              });
            }
          }
          this.close();
          const activeFile2 = this.app.workspace.getActiveFile();
          if (activeFile2) {
            const activeView = this.app.workspace.getActiveViewOfType(import_obsidian19.MarkdownView);
            if (activeView) {
              const contentEl2 = activeView.contentEl;
              if (contentEl2) {
                const existingOverlays = contentEl2.querySelectorAll(".banner-icon-overlay");
                existingOverlays.forEach((overlay) => {
                  this.plugin.returnIconOverlay(overlay);
                });
              }
              await this.plugin.updateBanner(activeView, true, this.plugin.UPDATE_MODE.FULL_UPDATE);
            }
          }
          if (!this.skipTargetingModal && this.plugin.settings.openTargetingModalAfterSelectingBannerOrIcon) {
            const activeFile3 = this.app.workspace.getActiveFile();
            if (activeFile3) {
              await new Promise((resolve) => {
                var _a2;
                const initialFrontmatter = JSON.stringify(
                  ((_a2 = this.app.metadataCache.getFileCache(activeFile3)) == null ? void 0 : _a2.frontmatter) || {}
                );
                const eventRef = this.app.metadataCache.on("changed", (file) => {
                  var _a3;
                  if (file.path !== activeFile3.path) return;
                  const updatedFrontmatter = JSON.stringify(
                    ((_a3 = this.app.metadataCache.getFileCache(file)) == null ? void 0 : _a3.frontmatter) || {}
                  );
                  if (updatedFrontmatter !== initialFrontmatter) {
                    this.app.metadataCache.off("changed", eventRef);
                    resolve();
                  }
                });
                setTimeout(() => {
                  this.app.metadataCache.off("changed", eventRef);
                  resolve();
                }, 500);
              });
              new TargetPositionModal(this.app, this.plugin).open();
            }
          }
        };
        setBannerButton.addEventListener("click", handleSetBannerButtonClick);
        removeBannerIconButton.addEventListener("click", async () => {
          this.bannerIconInput.value = "";
          await handleSetBannerButtonClick();
        });
        contentEl.createEl("h5", { text: "Emoji Selector" });
        const searchContainer = contentEl.createDiv({ cls: "emoji-search-container" });
        const searchInput = searchContainer.createEl("input", {
          type: "text",
          placeholder: "Search emojis...",
          cls: "emoji-search-input"
        });
        this.gridContainer = contentEl.createDiv({ cls: "emoji-grid-container" });
        searchInput.addEventListener("input", () => {
          this.searchQuery = searchInput.value.toLowerCase();
          this.updateEmojiGrid();
        });
        this.updateEmojiGrid();
        const modalEl = this.modalEl;
        modalEl.style.position = "absolute";
        modalEl.style.left = `${modalEl.getBoundingClientRect().left}px`;
        modalEl.style.top = `${modalEl.getBoundingClientRect().top}px`;
      }
      updateEmojiGrid() {
        this.gridContainer.empty();
        const filteredEmojis = emojiData.filter(({ emoji, keywords }) => {
          if (!this.searchQuery) return true;
          return keywords.toLowerCase().includes(this.searchQuery);
        });
        filteredEmojis.forEach(({ emoji }) => {
          const emojiButton = this.gridContainer.createEl("button", {
            text: emoji,
            cls: "emoji-button",
            attr: {
              "aria-label": this.getEmojiDescription(emoji)
            }
          });
          emojiButton.addEventListener("click", () => {
            this.bannerIconInput.value += emoji;
          });
        });
        const style = document.createElement("style");
        style.textContent = `
            .pixel-banner-emoji-select-modal {
                max-width: 600px;
                max-height: 80vh;
            }
            .emoji-search-container {
                margin-bottom: 1em;
            }
            .emoji-search-input {
                width: 100%;
                padding: 8px;
                margin-bottom: 1em;
            }
            .emoji-grid-container {
                overflow-y: auto;
                max-height: 400px !important;
            }
            .emoji-button {
                font-size: 1.5em;
                padding: 8px;
                background: var(--background-secondary);
                border: 1px solid var(--background-modifier-border);
                border-radius: 4px;
                cursor: pointer;
                transition: background-color 0.2s ease;
                margin: 4px;
            }
            .emoji-button:hover {
                background: var(--background-modifier-hover);
            }
            .banner-icon-input {
                flex: 1;
                padding: 8px;
            }
            .set-banner-button {
                padding: 8px 16px;
                background: var(--interactive-accent);
                color: var(--text-on-accent);
                border: none;
                border-radius: 4px;
                cursor: pointer;
            }
            .set-banner-button:hover {
                background: var(--interactive-accent-hover);
            }

            /* ------------------- */
            /* -- mobile layout -- */
            /* ------------------- */
            @media screen and (max-width: 640px) {
                .banner-icon-input-container { flex-direction: column !important; }
                .banner-icon-input-container * { width: 100% !important; }
            }
        `;
        document.head.appendChild(style);
      }
      getEmojiDescription(emoji) {
        const emojiItem = emojiData.find((item) => item.emoji === emoji);
        return emojiItem ? emojiItem.keywords : "";
      }
      onClose() {
        const { contentEl } = this;
        contentEl.empty();
        const activeFile = this.app.workspace.getActiveFile();
        const hasBanner = activeFile ? this.plugin.hasBannerFrontmatter(activeFile) : false;
        if (!this.closedByButton && this.plugin.settings.openTargetingModalAfterSelectingBannerOrIcon && hasBanner) {
          const openTargetingModal = async () => {
            if (activeFile) {
              await new Promise((resolve) => {
                var _a;
                const initialFrontmatter = JSON.stringify(
                  ((_a = this.app.metadataCache.getFileCache(activeFile)) == null ? void 0 : _a.frontmatter) || {}
                );
                const eventRef = this.app.metadataCache.on("changed", (file) => {
                  var _a2;
                  if (file.path !== activeFile.path) return;
                  const updatedFrontmatter = JSON.stringify(
                    ((_a2 = this.app.metadataCache.getFileCache(file)) == null ? void 0 : _a2.frontmatter) || {}
                  );
                  if (updatedFrontmatter !== initialFrontmatter) {
                    this.app.metadataCache.off("changed", eventRef);
                    resolve();
                  }
                });
                setTimeout(() => {
                  this.app.metadataCache.off("changed", eventRef);
                  resolve();
                }, 300);
              });
              new TargetPositionModal(this.app, this.plugin).open();
            }
          };
          setTimeout(openTargetingModal, 100);
        }
      }
    };
  }
});

// src/modal/modals/pixelBannerStoreModal.js
var import_obsidian20, PixelBannerStoreModal, ConfirmPurchaseModal;
var init_pixelBannerStoreModal = __esm({
  "src/modal/modals/pixelBannerStoreModal.js"() {
    import_obsidian20 = require("obsidian");
    init_constants();
    init_handlePinIconClick();
    init_fractionTextDisplay();
    init_modals();
    init_flags();
    init_selectPixelBannerModal();
    PixelBannerStoreModal = class extends import_obsidian20.Modal {
      constructor(app, plugin) {
        super(app);
        this.plugin = plugin;
        this.categories = [];
        this.selectedCategory = null;
        this.selectedCategoryIndex = 0;
        this.imageContainer = null;
        this.loadingEl = null;
        this.modalEl.addClass("pixel-banner-store-modal");
        this.isLoading = true;
        this.currentPage = 1;
        this.totalPages = 1;
        this.searchTerm = "";
        this.isSearchMode = false;
        this.itemsPerPage = 18;
        this.voteStats = {};
        this.userVotes = {};
        this.storeVotingEnabled = this.plugin.settings.storeVotingEnabled !== false;
      }
      // ----------------
      // -- Open Modal --
      // ----------------
      async onOpen() {
        const { contentEl } = this;
        contentEl.empty();
        this.showLoadingSpinner(contentEl);
        this.initializeModal().catch((error) => {
          console.error("Error initializing modal:", error);
          this.hideLoadingSpinner();
          contentEl.createEl("p", {
            text: "Failed to load store. Please try again later.",
            cls: "pixel-banner-store-error"
          });
        });
      }
      // Show loading spinner
      showLoadingSpinner(container) {
        this.isLoading = true;
        this.loadingOverlay = container.createDiv({
          cls: "pixel-banner-store-loading-overlay",
          attr: {
            style: `
                    position: absolute;
                    top: 0;
                    left: 0;
                    right: 0;
                    bottom: 0;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    background-color: var(--background-primary);
                    z-index: 100;
                `
          }
        });
        this.loadingOverlay.createDiv({
          cls: "pixel-banner-store-spinner",
          attr: {
            style: `
                    width: 40px;
                    height: 40px;
                    border: 4px solid var(--background-modifier-border);
                    border-top: 4px solid var(--text-accent);
                    border-radius: 50%;
                    animation: pixel-banner-spin 1s linear infinite;
                `
          }
        });
      }
      // Hide loading spinner
      hideLoadingSpinner() {
        this.isLoading = false;
        if (this.loadingOverlay) {
          this.loadingOverlay.remove();
          this.loadingOverlay = null;
        }
      }
      // Download and save banner (handles both images and videos)
      async downloadAndSaveBanner(data, filename) {
        try {
          if (data.fileType === "video") {
            await this.saveVideoFileWithPrompts(data.base64Image, filename);
          } else {
            await handlePinIconClick(data.base64Image, this.plugin, null, filename.replace(/\.[^/.]+$/, ""), false);
          }
        } catch (error) {
          console.error("Error saving banner:", error);
          new import_obsidian20.Notice("Failed to save banner. Please try again.");
        }
      }
      // Save video file with user prompts (similar to handlePinIconClick flow)
      async saveVideoFileWithPrompts(base64Video, suggestedFilename) {
        try {
          const base64Data = base64Video.split(",")[1];
          const byteCharacters = atob(base64Data);
          const byteNumbers = new Array(byteCharacters.length);
          for (let i = 0; i < byteCharacters.length; i++) {
            byteNumbers[i] = byteCharacters.charCodeAt(i);
          }
          const arrayBuffer = new Uint8Array(byteNumbers).buffer;
          const { file, useAsBanner } = await this.saveVideoLocally(arrayBuffer, suggestedFilename);
          const finalPath = await this.waitForFileRename(file);
          if (!finalPath) {
            console.error("\u274C Failed to resolve valid file path");
            new import_obsidian20.Notice("Failed to save video - file not found");
            return null;
          }
          if (useAsBanner) {
            const { updateNoteFrontmatter: updateNoteFrontmatter2 } = await Promise.resolve().then(() => (init_frontmatterUtils(), frontmatterUtils_exports));
            await updateNoteFrontmatter2(finalPath, this.plugin, null);
          }
          return finalPath;
        } catch (error) {
          console.error("Error saving video file:", error);
          throw error;
        }
      }
      // Save video locally with folder/filename prompts (adapted from handlePinIconClick)
      async saveVideoLocally(arrayBuffer, suggestedFilename) {
        const { FolderSelectionModal: FolderSelectionModal2 } = await Promise.resolve().then(() => (init_folderSelectionModal(), folderSelectionModal_exports));
        const { SaveImageModal: SaveImageModal2 } = await Promise.resolve().then(() => (init_saveImageModal(), saveImageModal_exports));
        const vault = this.plugin.app.vault;
        const defaultFolderPath = this.plugin.settings.pinnedImageFolder;
        const folderPath = await new Promise((resolve) => {
          const modal = new FolderSelectionModal2(this.plugin.app, defaultFolderPath, (result) => {
            resolve(result);
          });
          modal.open();
        });
        if (!folderPath) {
          throw new Error("No folder selected");
        }
        if (!await vault.adapter.exists(folderPath)) {
          await vault.createFolder(folderPath);
        }
        const filenameParts = suggestedFilename.match(/^(.+)\.(\w+)$/);
        const baseName = filenameParts ? filenameParts[1] : suggestedFilename;
        const extension = filenameParts ? filenameParts[2] : "mp4";
        const userInput = await new Promise((resolve) => {
          const modal = new SaveImageModal2(this.plugin.app, baseName, (name, useAsBanner) => {
            resolve({ name, useAsBanner });
          });
          modal.open();
        });
        if (!userInput) {
          throw new Error("No filename provided");
        }
        let finalBaseName = userInput.name.replace(/[^a-zA-Z0-9-_ ]/g, "").trim();
        if (!finalBaseName) finalBaseName = "banner";
        if (!finalBaseName.toLowerCase().endsWith(`.${extension}`)) {
          finalBaseName += `.${extension}`;
        }
        let fileName = finalBaseName;
        let counter = 1;
        while (await vault.adapter.exists(`${folderPath}/${fileName}`)) {
          const nameWithoutExt = finalBaseName.slice(0, -(extension.length + 1));
          fileName = `${nameWithoutExt}-${counter}.${extension}`;
          counter++;
        }
        const filePath = `${folderPath}/${fileName}`;
        const savedFile = await vault.createBinary(filePath, arrayBuffer);
        return {
          initialPath: filePath,
          file: savedFile,
          useAsBanner: userInput.useAsBanner
        };
      }
      // Wait for potential file rename (adapted from handlePinIconClick)
      async waitForFileRename(file) {
        const maxWaitTime = 5e3;
        const checkInterval = 100;
        let elapsedTime = 0;
        while (elapsedTime < maxWaitTime) {
          try {
            const currentFile = this.plugin.app.vault.getAbstractFileByPath(file.path);
            if (currentFile) {
              return currentFile.path;
            }
          } catch (error) {
          }
          await new Promise((resolve) => setTimeout(resolve, checkInterval));
          elapsedTime += checkInterval;
        }
        return file.path;
      }
      // Initialize modal content
      async initializeModal() {
        await this.plugin.verifyPixelBannerPlusCredentials();
        const { contentEl } = this;
        contentEl.createEl("h3", { text: "\u{1F3EA} Pixel Banner Plus Collection", cls: "margin-top-0" });
        contentEl.createEl("p", {
          text: `Browse the Pixel Banner Plus Collection to find the perfect banner for your needs. Banner Token prices are displayed on each card below (FREE or 1 Banner Token). Previous purchases will be listed as FREE.`,
          attr: {
            "style": "font-size: 12px; color: var(--text-muted);"
          }
        });
        const selectContainer = contentEl.createDiv({ cls: "pixel-banner-store-select-container" });
        if (this.plugin.pixelBannerPlusEnabled) {
          this.searchContainer = selectContainer.createDiv({
            cls: "pixel-banner-store-search-container",
            attr: {
              style: `
                        display: none;
                        align-items: center;
                        gap: 5px;
                        margin: 0 0 0 auto;
                    `
            }
          });
          this.searchInput = this.searchContainer.createEl("input", {
            type: "text",
            placeholder: "Search banners...",
            cls: "pixel-banner-store-search-input"
          });
          this.searchInput.addEventListener("keydown", (e) => {
            if (e.key === "Enter") {
              this.searchBanners();
            }
          });
          this.searchButton = this.searchContainer.createEl("button", {
            text: "Search",
            cls: "pixel-banner-store-search-button"
          });
          this.searchButton.addEventListener("click", () => {
            this.searchBanners();
          });
          this.stopSearchButton = this.searchContainer.createEl("button", {
            text: "Back to Categories",
            cls: "pixel-banner-store-stop-search-button"
          });
          this.stopSearchButton.addEventListener("click", () => {
            this.toggleSearchMode(false);
          });
        }
        this.categorySelect = selectContainer.createEl("select", {
          cls: "pixel-banner-store-select",
          attr: {
            style: `
                    display: ${this.plugin.pixelBannerPlusEnabled ? "block" : "none"};
                `
          }
        });
        const defaultOption = this.categorySelect.createEl("option", {
          text: "Select a category...",
          value: ""
        });
        defaultOption.disabled = true;
        defaultOption.selected = true;
        try {
          const response = await fetch(
            `${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.STORE_CATEGORIES}`,
            {
              headers: {
                "x-user-email": this.plugin.settings.pixelBannerPlusEmail,
                "x-api-key": this.plugin.settings.pixelBannerPlusApiKey,
                "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
                "Accept": "application/json"
              }
            }
          );
          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }
          const data = await response.json();
          this.categories = Array.isArray(data) ? data : data.categories || [];
          if (this.categories.length === 0) {
            throw new Error("No categories found");
          }
          this.categories.forEach((category) => {
            this.categorySelect.createEl("option", {
              value: category.id,
              text: category.category
            });
          });
          this.categorySelect.addEventListener("change", async (e) => {
            this.selectedCategory = e.target.value;
            this.selectedCategoryIndex = e.target.selectedIndex;
            await this.loadCategoryImages();
          });
        } catch (error) {
          console.error("Failed to fetch categories:", error);
          selectContainer.createEl("p", {
            text: "Failed to load categories. Please try again later.",
            cls: "pixel-banner-store-error",
            attr: {
              style: `
                        display: ${this.plugin.pixelBannerPlusEnabled ? "block" : "none"};
                    `
            }
          });
        }
        this.categoryControlsContainer = selectContainer.createDiv({
          cls: "pixel-banner-store-category-controls",
          attr: {
            style: `
                    display: flex;
                    align-items: center;
                    gap: 10px;
                `
          }
        });
        this.nextCategoryButton = this.categoryControlsContainer.createEl("button", {
          text: "\u25B6\uFE0F Next Category",
          cls: "pixel-banner-store-next-category radial-pulse-animation",
          attr: {
            style: `
                    display: ${this.plugin.pixelBannerPlusEnabled ? "inline-flex" : "none"};
                `
          }
        });
        this.nextCategoryButton.addEventListener("click", async () => {
          if (this.selectedCategoryIndex >= this.categories.length) {
            this.selectedCategoryIndex = 1;
          } else {
            this.selectedCategoryIndex++;
          }
          this.categorySelect.selectedIndex = this.selectedCategoryIndex;
          this.selectedCategory = this.categorySelect.value;
          await this.loadCategoryImages();
        });
        if (this.plugin.pixelBannerPlusEnabled) {
          this.searchAllButton = this.categoryControlsContainer.createEl("button", {
            text: "\u{1F50D} Search All",
            cls: "pixel-banner-store-search-all-button"
          });
          this.searchAllButton.addEventListener("click", () => {
            this.toggleSearchMode(true);
          });
        }
        const backToMainButton = selectContainer.createEl("button", {
          text: "\u21E0 Main Menu",
          cls: "pixel-banner-store-back-to-main"
        });
        backToMainButton.addEventListener("click", () => {
          this.close();
          new SelectPixelBannerModal(this.app, this.plugin).open();
        });
        if (this.plugin.pixelBannerPlusEnabled) {
          this.imageContainer = contentEl.createDiv({ cls: "pixel-banner-store-image-grid -empty" });
          if (!this.storeVotingEnabled) {
            this.imageContainer.addClass("store-voting-off");
          }
          setTimeout(async () => {
            if (this.categorySelect.selectedIndex === 0) {
              this.categorySelect.selectedIndex = 1;
              this.selectedCategoryIndex = 1;
              this.selectedCategory = this.categorySelect.value;
              await this.loadCategoryImages();
            }
          }, 50);
        } else {
          this.imageContainer = contentEl.createDiv({ cls: "pixel-banner-store-image-grid -not-connected" });
        }
        const bottomControlsContainer = contentEl.createDiv({
          cls: "pixel-banner-store-bottom-controls",
          attr: {
            "style": `
                    display: flex;
                    flex-direction: row;
                    align-items: center;
                    justify-content: space-between;
                    margin-top: 15px;
                    border-top: 1px solid var(--background-modifier-border);
                    padding-top: 10px;
                `
          }
        });
        const pixelBannerPlusAccountStatus = bottomControlsContainer.createDiv({
          cls: "pixel-banner-store-account-status",
          attr: {
            "style": `
                    display: flex;
                    flex-direction: row;
                    gap: 10px;
                    align-items: center;
                    justify-content: flex-start;
                    font-size: .9em;
                `
          }
        });
        this.paginationContainer = bottomControlsContainer.createDiv({
          cls: "pixel-banner-store-pagination-container",
          attr: {
            "style": `
                    display: flex;
                    align-items: center;
                    gap: 8px;
                `
          }
        });
        const storeVotingContainer = bottomControlsContainer.createDiv({
          cls: "pixel-banner-store-voting-container",
          attr: {
            "style": `
                    display: flex;
                    align-items: center;
                    gap: 8px;
                    margin-left: 16px;
                `
          }
        });
        const storeVotingToggle = storeVotingContainer.createEl("input", {
          type: "checkbox",
          cls: "pixel-banner-store-voting-toggle",
          attr: {
            id: "store-voting-toggle",
            style: `
                    cursor: pointer;
                `
          }
        });
        storeVotingToggle.checked = this.storeVotingEnabled === true;
        storeVotingContainer.createEl("label", {
          text: "Collection Voting",
          cls: "pixel-banner-store-voting-label",
          attr: {
            for: "store-voting-toggle",
            style: `
                    font-size: 0.8em;
                    cursor: pointer;
                    color: var(--text-muted);
                    letter-spacing: 0.05em;
                `
          }
        });
        storeVotingToggle.addEventListener("change", (e) => {
          this.storeVotingEnabled = e.target.checked;
          this.plugin.settings.storeVotingEnabled = this.storeVotingEnabled;
          this.plugin.saveSettings();
          if (this.storeVotingEnabled) {
            this.imageContainer.removeClass("store-voting-off");
          } else {
            this.imageContainer.addClass("store-voting-off");
          }
        });
        const isConnected = this.plugin.pixelBannerPlusEnabled;
        const statusText = isConnected ? "\u2705 Connected" : "\u274C Not Connected";
        const statusBorderColor = isConnected ? "#20bf6b" : "#FF0000";
        const connectionStatusEl = pixelBannerPlusAccountStatus.createEl("span", {
          text: statusText,
          cls: "pixel-banner-status-value",
          attr: {
            style: `border: 1px dotted ${statusBorderColor};`
          }
        });
        const tokenCount = this.plugin.pixelBannerPlusBannerTokens !== void 0 ? `\u{1FA99} ${decimalToFractionString(this.plugin.pixelBannerPlusBannerTokens)} Tokens` : "\u2753 Unknown";
        const tokenCountEl = pixelBannerPlusAccountStatus.createEl("span", {
          text: tokenCount,
          cls: "pixel-banner-status-value",
          attr: {
            style: `
                    border: 1px dotted #F3B93B;
                    display: ${this.plugin.pixelBannerPlusEnabled ? "inline-flex" : "none"};
                `
          }
        });
        const openPlusSettings = async () => {
          this.close();
          await this.app.setting.open();
          await new Promise((resolve) => setTimeout(resolve, 300));
          const settingsTabs = document.querySelectorAll(".vertical-tab-header-group .vertical-tab-nav-item");
          for (const tab of settingsTabs) {
            if (tab.textContent.includes("Pixel Banner")) {
              tab.click();
              break;
            }
          }
          const pixelBannerSettingsTabs = document.querySelectorAll(".pixel-banner-settings-tabs > button.pixel-banner-settings-tab");
          for (const tab of pixelBannerSettingsTabs) {
            if (tab.textContent.includes("Plus")) {
              tab.click();
              break;
            }
          }
        };
        connectionStatusEl.addEventListener("click", openPlusSettings);
        tokenCountEl.addEventListener("click", openPlusSettings);
        if (isConnected && this.plugin.pixelBannerPlusBannerTokens === 0) {
          const buyTokensButton = pixelBannerPlusAccountStatus.createEl("button", {
            cls: "pixel-banner-account-button pixel-banner-buy-tokens-button",
            text: "\u{1F4B5} Buy More Tokens"
          });
          buyTokensButton.addEventListener("click", (event) => {
            event.preventDefault();
            window.open(PIXEL_BANNER_PLUS.SHOP_URL, "_blank");
          });
        } else if (!isConnected) {
          const signupButton = pixelBannerPlusAccountStatus.createEl("button", {
            cls: "pixel-banner-account-button pixel-banner-signup-button",
            text: "\u{1F6A9} Signup for Free!"
          });
          signupButton.addEventListener("click", (event) => {
            event.preventDefault();
            const signupUrl = PIXEL_BANNER_PLUS.API_URL + PIXEL_BANNER_PLUS.ENDPOINTS.SIGNUP;
            window.open(signupUrl, "_blank");
          });
        }
        this.addStyle();
        this.hideLoadingSpinner();
      }
      // --------------------------
      // -- Load Category Images --
      // --------------------------
      async loadCategoryImages(page = 1) {
        if (!this.selectedCategory) return;
        this.isSearchMode = false;
        this.currentPage = page;
        if (page === 1) {
          this.userVotes = {};
          this.voteStats = {};
        }
        this.imageContainer.empty();
        if (this.storeVotingEnabled) {
          this.imageContainer.removeClass("store-voting-off");
        } else {
          this.imageContainer.addClass("store-voting-off");
        }
        this.loadingEl = this.imageContainer.createDiv({ cls: "pixel-banner-store-loading" });
        this.loadingEl.innerHTML = `<div class="pixel-banner-store-spinner"></div>`;
        try {
          const response = await fetch(
            `${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.STORE_CATEGORY_IMAGES}?categoryId=${this.selectedCategory}&page=${this.currentPage}&limit=${this.itemsPerPage}`,
            {
              headers: {
                "x-user-email": this.plugin.settings.pixelBannerPlusEmail,
                "x-api-key": this.plugin.settings.pixelBannerPlusApiKey,
                "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
                "Accept": "application/json"
              }
            }
          );
          if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
          const data = await response.json();
          let images, totalPages = 1, totalItems = 0;
          if (Array.isArray(data)) {
            images = data;
            totalPages = Math.ceil(images.length / this.itemsPerPage);
            totalItems = images.length;
            const startIndex = (this.currentPage - 1) * this.itemsPerPage;
            const endIndex = startIndex + this.itemsPerPage;
            images = images.slice(startIndex, endIndex);
          } else {
            images = data.images || data.banners || [];
            totalPages = data.totalPages || 1;
            totalItems = data.totalItems || data.totalCount || images.length;
          }
          this.totalPages = totalPages;
          this.displayImages(images, false, totalItems);
          if (totalPages > 1) {
            this.addPaginationControls();
          } else {
            this.paginationContainer.style.display = "none";
          }
        } catch (error) {
          console.error("Failed to fetch images:", error);
          this.imageContainer.empty();
          this.imageContainer.createEl("p", {
            text: "Failed to load images. Please try again.",
            cls: "pixel-banner-store-error"
          });
        }
      }
      // -----------------
      // -- Search Banners --
      // -----------------
      async searchBanners(page = 1) {
        this.searchTerm = this.searchInput.value.trim();
        if (!this.searchTerm) {
          new import_obsidian20.Notice("Please enter a search term");
          return;
        }
        this.isSearchMode = true;
        this.currentPage = page;
        this.imageContainer.empty();
        if (this.storeVotingEnabled) {
          this.imageContainer.removeClass("store-voting-off");
        } else {
          this.imageContainer.addClass("store-voting-off");
        }
        this.loadingEl = this.imageContainer.createDiv({ cls: "pixel-banner-store-loading" });
        this.loadingEl.innerHTML = `<div class="pixel-banner-store-spinner"></div>`;
        try {
          const response = await fetch(
            `${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.STORE_IMAGE_SEARCH}`,
            {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
                "x-user-email": this.plugin.settings.pixelBannerPlusEmail,
                "x-api-key": this.plugin.settings.pixelBannerPlusApiKey,
                "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
                "Accept": "application/json"
              },
              body: JSON.stringify({
                searchTerm: this.searchTerm,
                page: this.currentPage,
                limit: this.itemsPerPage,
                sort: "date_added",
                order: "desc"
              })
            }
          );
          if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
          const data = await response.json();
          this.totalPages = data.totalPages || data.total_pages || 1;
          let imagesArray = [];
          if (data.images && Array.isArray(data.images)) {
            imagesArray = data.images;
          } else if (data.banners && Array.isArray(data.banners)) {
            imagesArray = data.banners;
          } else if (data.results && Array.isArray(data.results)) {
            imagesArray = data.results;
          } else if (Array.isArray(data)) {
            imagesArray = data;
          } else if (data.image) {
            imagesArray = [data.image];
          } else if (data.banner) {
            imagesArray = [data.banner];
          } else if (typeof data === "object" && data !== null) {
            imagesArray = [data];
          }
          if (!Array.isArray(imagesArray)) {
            console.error("Failed to extract images array from response:", data);
            throw new Error("Invalid response format: could not extract images array");
          }
          if (imagesArray.length === 0) {
            this.imageContainer.empty();
            this.imageContainer.createEl("p", {
              text: `No results found for "${this.searchTerm}"`,
              cls: "pixel-banner-store-no-results",
              attr: {
                style: `
                            text-align: center;
                            margin-top: 100px;
                            font-size: 16px;
                        `
              }
            });
            return;
          }
          this.userVotes = {};
          this.voteStats = {};
          this.displayImages(imagesArray, true);
        } catch (error) {
          console.error("Failed to search images:", error);
          this.imageContainer.empty();
          this.imageContainer.createEl("p", {
            text: `Failed to search images: ${error.message}. Please try again.`,
            cls: "pixel-banner-store-error"
          });
        }
      }
      // --------------------
      // -- Display Images --
      // --------------------
      displayImages(images, isSearchResult = false, totalItems = 0) {
        if (this.loadingEl) {
          this.loadingEl.remove();
          this.loadingEl = null;
        }
        if (!Array.isArray(images)) {
          console.error("displayImages received non-array:", images);
          this.imageContainer.createEl("p", {
            text: "Error displaying images: Invalid data format",
            cls: "pixel-banner-store-error"
          });
          return;
        }
        if (images.length > 0) {
          this.imageContainer.removeClass("-empty");
          this.imageContainer.removeClass("-not-connected");
        }
        const container = this.imageContainer;
        container.empty();
        const imageIds = images.map((image) => image.id || image.imageId || image.bannerId).filter((id) => id && id !== "unknown");
        if (this.plugin.pixelBannerPlusEnabled && imageIds.length > 0) {
          images.forEach((image) => {
            const id = image.id || image.imageId || image.bannerId;
            if (!id || id === "unknown") return;
            this.voteStats[id] = {
              upvotes: image.upvotes || 0,
              downvotes: image.downvotes || 0,
              total: image.vote_score || 0
            };
            if (image.user_vote === 1 || image.user_vote === "up") {
              this.userVotes[id] = "up";
            } else if (image.user_vote === -1 || image.user_vote === "down") {
              this.userVotes[id] = "down";
            } else {
              this.userVotes[id] = null;
            }
            this.updateVoteDisplay(id);
          });
        }
        images.forEach((image) => {
          try {
            if (!image || typeof image !== "object") {
              console.warn("Skipping invalid image entry:", image);
              return;
            }
            const imageId = image.id || image.imageId || image.bannerId || "unknown";
            const imageCost = typeof image.cost !== "undefined" ? image.cost : image.premium ? 1 : 0;
            const card = container.createEl("div", {
              cls: "pixel-banner-store-image-card",
              attr: {
                "data-image-id": imageId,
                "data-image-cost": imageCost,
                "data-image-new": true,
                "data-image-hot": image.hot ? "true" : "false",
                "style": "position: relative;"
                // Ensure proper positioning for absolute children
              }
            });
            const imageSource = image.base64Image || image.base64 || image.url || image.src || "";
            const isVideo = image.fileType === "video";
            if (isVideo) {
              const imgEl = card.createEl("img", {
                attr: {
                  src: imageSource,
                  alt: image.prompt || image.description || "Banner video thumbnail"
                }
              });
              const videoBadge = card.createEl("div", {
                text: "VIDEO",
                cls: "pixel-banner-store-video-badge",
                attr: {
                  style: `
                                position: absolute;
                                top: 8px;
                                right: 8px;
                                background: rgba(255, 255, 255, 0.9);
                                color: #333;
                                padding: 2px 6px;
                                border-radius: 3px;
                                font-size: 10px;
                                font-weight: bold;
                                z-index: 2;
                                pointer-events: none;
                            `
                }
              });
            } else {
              const imgEl = card.createEl("img", {
                attr: {
                  src: imageSource,
                  alt: image.prompt || image.description || "Banner image"
                }
              });
            }
            const details = card.createDiv({ cls: "pixel-banner-store-image-details" });
            const promptWrapper = details.createDiv({ cls: "pixel-banner-store-prompt-wrapper" });
            const promptText = image.prompt || image.description || image.title || "No description";
            const truncatedPrompt = promptText.length > 85 ? promptText.slice(0, 85) + "..." : promptText;
            promptWrapper.createEl("p", { text: truncatedPrompt, cls: "pixel-banner-store-prompt" });
            if (image.filesize) {
              promptWrapper.createEl("div", {
                text: image.filesize,
                cls: "pixel-banner-store-filesize",
                attr: {
                  style: `
                                color: var(--text-muted);
                                font-size: 10px;
                                margin: 2px 0 0 0;
                                text-align: left;
                            `
                }
              });
            }
            const metaDetails = details.createEl("div", { cls: "pixel-banner-store-meta-details" });
            const costText = imageCost === 0 ? "FREE" : `\u{1FA99} ${decimalToFractionString(imageCost)}`;
            const costEl = metaDetails.createEl("div", {
              text: costText,
              cls: "pixel-banner-store-cost",
              attr: {
                style: "color: var(--text-normal);"
              }
            });
            if (imageCost === 0) {
              costEl.addClass("free");
            }
            if (image.new) {
              metaDetails.createEl("div", {
                text: "NEW",
                attr: {
                  style: `
                                color: var(--interactive-accent);
                                font-weight: bold;
                                font-size: 11px;
                                margin: 0;
                                text-align: right;
                                white-space: nowrap;
                                margin-left: 5px;
                            `
                }
              });
            }
            if (image.hot) {
              metaDetails.createEl("div", {
                text: "\u{1F525}HOT",
                attr: {
                  style: `
                                color: var(--error-color);
                                font-weight: bold;
                                font-size: 11px;
                                margin: 0;
                                text-align: right;
                                white-space: nowrap;
                                margin-left: 5px;
                            `
                }
              });
            }
            if (this.plugin.pixelBannerPlusEnabled && imageId !== "unknown") {
              const voteControls = card.createDiv({
                cls: "pixel-banner-store-vote-controls",
                attr: {
                  "data-banner-id": imageId
                }
              });
              const upvoteButton = voteControls.createEl("button", {
                cls: "pixel-banner-store-vote-button upvote",
                attr: {
                  "aria-label": "Upvote Banner",
                  "data-banner-id": imageId
                }
              });
              upvoteButton.innerHTML = "\u{1F44D}";
              const voteCount = voteControls.createEl("span", {
                cls: "pixel-banner-store-vote-count",
                text: "0",
                attr: {
                  "data-banner-id": imageId
                }
              });
              const downvoteButton = voteControls.createEl("button", {
                cls: "pixel-banner-store-vote-button downvote",
                attr: {
                  "aria-label": "Downvote Banner",
                  "data-banner-id": imageId
                }
              });
              downvoteButton.innerHTML = "\u{1F44E}";
              upvoteButton.addEventListener("click", (e) => {
                e.stopPropagation();
                this.upvoteBanner(imageId);
              });
              downvoteButton.addEventListener("click", (e) => {
                e.stopPropagation();
                this.downvoteBanner(imageId);
              });
              this.updateVoteDisplay(imageId);
            }
            card.addEventListener("click", async () => {
              var _a;
              const cost = Number(card.getAttribute("data-image-cost"));
              if (cost > 0) {
                new ConfirmPurchaseModal(this.app, cost, image.prompt, image.base64Image, async () => {
                  var _a2;
                  try {
                    const response = await fetch(`${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.STORE_IMAGE_BY_ID}?bannerId=${image.id}`, {
                      headers: {
                        "x-user-email": this.plugin.settings.pixelBannerPlusEmail,
                        "x-api-key": this.plugin.settings.pixelBannerPlusApiKey,
                        "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
                        "Accept": "application/json"
                      }
                    });
                    if (!response.ok) {
                      throw new Error("Failed to fetch banner");
                    }
                    await this.plugin.verifyPixelBannerPlusCredentials();
                    card.setAttribute("data-image-cost", "0");
                    card.querySelector(".pixel-banner-store-cost").classList.add("free");
                    card.querySelector(".pixel-banner-store-cost").textContent = "FREE";
                    const data = await response.json();
                    let filename = ((_a2 = image.prompt) == null ? void 0 : _a2.toLowerCase().replace(/[^a-zA-Z0-9-_ ]/g, "").trim()) || "banner";
                    filename = filename.replace(/\s+/g, "-").substring(0, 47);
                    if (data.fileType === "video") {
                      filename += `.${data.fileExtension || "mp4"}`;
                    } else {
                      filename += `.${data.fileExtension || "jpg"}`;
                    }
                    await this.downloadAndSaveBanner(data, filename);
                    this.close();
                    if (this.plugin.settings.openTargetingModalAfterSelectingBannerOrIcon) {
                      new TargetPositionModal(this.app, this.plugin).open();
                    }
                  } catch (error) {
                    console.error("Error purchasing banner:", error);
                    new import_obsidian20.Notice("Failed to purchase banner. Please try again.");
                  }
                }, this.plugin, isVideo, image.fileType, image.file_extension).open();
              } else {
                try {
                  const response = await fetch(`${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.STORE_IMAGE_BY_ID}?bannerId=${image.id}`, {
                    headers: {
                      "x-user-email": this.plugin.settings.pixelBannerPlusEmail,
                      "x-api-key": this.plugin.settings.pixelBannerPlusApiKey,
                      "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
                      "Accept": "application/json"
                    }
                  });
                  if (!response.ok) {
                    throw new Error("Failed to fetch banner");
                  }
                  const data = await response.json();
                  let filename = ((_a = image.prompt) == null ? void 0 : _a.toLowerCase().replace(/[^a-zA-Z0-9-_ ]/g, "").trim()) || "banner";
                  filename = filename.replace(/\s+/g, "-").substring(0, 47);
                  if (data.fileType === "video") {
                    filename += `.${data.fileExtension || "mp4"}`;
                  } else {
                    filename += `.${data.fileExtension || "jpg"}`;
                  }
                  await this.downloadAndSaveBanner(data, filename);
                  this.close();
                  if (this.plugin.settings.openTargetingModalAfterSelectingBannerOrIcon) {
                    new TargetPositionModal(this.app, this.plugin).open();
                  }
                } catch (error) {
                  console.error("Error fetching store banner:", error);
                }
              }
            });
          } catch (error) {
            console.error("Error rendering image card:", error, image);
          }
        });
        if (this.isSearchMode && this.totalPages > 1) {
          this.addPaginationControls();
        } else {
          this.paginationContainer.style.display = "none";
        }
      }
      // Update vote display for a specific banner
      updateVoteDisplay(bannerId) {
        if (!bannerId) return;
        const voteControls = document.querySelector(`.pixel-banner-store-vote-controls[data-banner-id="${bannerId}"]`);
        if (!voteControls) {
          return;
        }
        const voteCount = voteControls.querySelector(".pixel-banner-store-vote-count");
        const upvoteButton = voteControls.querySelector(".upvote");
        const downvoteButton = voteControls.querySelector(".downvote");
        if (!upvoteButton || !downvoteButton) {
          return;
        }
        if (voteCount && this.voteStats[bannerId]) {
          voteCount.textContent = this.voteStats[bannerId].total.toString();
          voteCount.removeClass("positive", "negative", "neutral");
          if (this.voteStats[bannerId].total > 0) {
            voteCount.addClass("positive");
          } else if (this.voteStats[bannerId].total < 0) {
            voteCount.addClass("negative");
          } else {
            voteCount.addClass("neutral");
          }
        }
        if (upvoteButton && downvoteButton) {
          upvoteButton.removeClass("active");
          upvoteButton.removeClass("active-upvote");
          downvoteButton.removeClass("active");
          downvoteButton.removeClass("active-downvote");
          const userVote = this.userVotes[bannerId];
          if (userVote === "up" || userVote === 1) {
            upvoteButton.addClass("active");
            upvoteButton.addClass("active-upvote");
          } else if (userVote === "down" || userVote === -1) {
            downvoteButton.addClass("active");
            downvoteButton.addClass("active-downvote");
          }
        }
      }
      // Upvote a banner
      async upvoteBanner(bannerId) {
        if (!bannerId || !this.plugin.pixelBannerPlusEnabled) return;
        try {
          const endpoint = PIXEL_BANNER_PLUS.ENDPOINTS.BANNER_VOTES_UPVOTE.replace(":id", bannerId);
          const response = await fetch(`${PIXEL_BANNER_PLUS.API_URL}${endpoint}`, {
            method: "POST",
            headers: {
              "x-user-email": this.plugin.settings.pixelBannerPlusEmail,
              "x-api-key": this.plugin.settings.pixelBannerPlusApiKey,
              "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
              "Content-Type": "application/json",
              "Accept": "application/json"
            }
          });
          if (response.ok) {
            const data = await response.json();
            this.voteStats[bannerId] = {
              upvotes: data.votes.upvotes || 0,
              downvotes: data.votes.downvotes || 0,
              total: data.votes.total || 0
            };
            this.userVotes[bannerId] = this.userVotes[bannerId] === "up" ? null : "up";
            this.updateVoteDisplay(bannerId);
          }
        } catch (error) {
          console.error("Error upvoting banner:", error);
          new import_obsidian20.Notice("Failed to upvote banner. Please try again.");
        }
      }
      // Downvote a banner
      async downvoteBanner(bannerId) {
        if (!bannerId || !this.plugin.pixelBannerPlusEnabled) return;
        try {
          const endpoint = PIXEL_BANNER_PLUS.ENDPOINTS.BANNER_VOTES_DOWNVOTE.replace(":id", bannerId);
          const response = await fetch(`${PIXEL_BANNER_PLUS.API_URL}${endpoint}`, {
            method: "POST",
            headers: {
              "x-user-email": this.plugin.settings.pixelBannerPlusEmail,
              "x-api-key": this.plugin.settings.pixelBannerPlusApiKey,
              "X-Pixel-Banner-Version": this.plugin.settings.lastVersion,
              "Content-Type": "application/json",
              "Accept": "application/json"
            }
          });
          if (response.ok) {
            const data = await response.json();
            this.voteStats[bannerId] = {
              upvotes: data.votes.upvotes || 0,
              downvotes: data.votes.downvotes || 0,
              total: data.votes.total || 0
            };
            this.userVotes[bannerId] = this.userVotes[bannerId] === "down" ? null : "down";
            this.updateVoteDisplay(bannerId);
          }
        } catch (error) {
          console.error("Error downvoting banner:", error);
          new import_obsidian20.Notice("Failed to downvote banner. Please try again.");
        }
      }
      // Toggle between search mode and category browsing mode
      toggleSearchMode(enableSearch) {
        if (enableSearch) {
          this.categorySelect.style.display = "none";
          this.nextCategoryButton.style.display = "none";
          this.searchAllButton.style.display = "none";
          this.searchContainer.style.display = "flex";
          this.searchInput.value = "";
          this.searchInput.focus();
          this.isSearchMode = true;
        } else {
          this.searchContainer.style.display = "none";
          this.categorySelect.style.display = "block";
          this.nextCategoryButton.style.display = "inline-flex";
          this.searchAllButton.style.display = "inline-flex";
          this.isSearchMode = false;
          this.paginationContainer.style.display = "none";
          if (this.selectedCategory) {
            this.loadCategoryImages();
          }
        }
      }
      // --------------------------
      // -- Add Pagination Controls --
      // --------------------------
      addPaginationControls() {
        this.paginationContainer.empty();
        this.paginationContainer.style.display = "flex";
        const prevButton = this.paginationContainer.createEl("button", {
          text: "\u2190 Previous",
          cls: "pixel-banner-store-pagination-button",
          attr: {
            disabled: this.currentPage === 1 ? "disabled" : null
          }
        });
        prevButton.addEventListener("click", () => {
          if (this.currentPage > 1) {
            if (this.isSearchMode) {
              this.searchBanners(this.currentPage - 1);
            } else {
              this.loadCategoryImages(this.currentPage - 1);
            }
          }
        });
        this.paginationContainer.createEl("span", {
          text: `Page ${this.currentPage} of ${this.totalPages}`,
          cls: "pixel-banner-store-pagination-info"
        });
        const nextButton = this.paginationContainer.createEl("button", {
          text: "Next \u2192",
          cls: "pixel-banner-store-pagination-button",
          attr: {
            disabled: this.currentPage === this.totalPages ? "disabled" : null
          }
        });
        nextButton.addEventListener("click", () => {
          if (this.currentPage < this.totalPages) {
            if (this.isSearchMode) {
              this.searchBanners(this.currentPage + 1);
            } else {
              this.loadCategoryImages(this.currentPage + 1);
            }
          }
        });
      }
      addStyle() {
        const style = document.createElement("style");
        style.textContent = `
            .pixel-banner-store-modal {
                top: unset !important;
                width: var(--dialog-max-width);
                max-width: 1100px;
                animation: pixel-banner-fade-in 1300ms ease-in-out;
            }

            .pixel-banner-store-select-container {
                display: flex;
                flex-direction: row;
                gap: 10px;
                align-items: center;
                justify-content: flex-end;
            }
            
            .pixel-banner-store-category-controls {
                display: flex;
                align-items: center;
                gap: 10px;
            }
            
            .pixel-banner-store-select {
                width: max-content;
                font-size: 14px;
            }
            
            /* Search Styles */
            .pixel-banner-store-search-container {
                display: flex;
                align-items: center;
                gap: 5px;
                margin: 0 0 0 auto;
            }
            
            .pixel-banner-store-search-input {
                width: 200px;
                font-size: 14px;
                padding: 5px 10px;
                border: 1px solid var(--background-modifier-border);
                border-radius: 4px;
            }
            
            .pixel-banner-store-search-button,
            .pixel-banner-store-stop-search-button,
            .pixel-banner-store-search-all-button {
                font-size: 14px;
                padding: 6px 12px;
                border-radius: 4px;
                cursor: pointer;
                border: none;
                white-space: nowrap;
            }
            
            .pixel-banner-store-search-button,
            .pixel-banner-store-stop-search-button {
                background-color: var(--interactive-accent) !important;
                color: var(--text-on-accent) !important;
            }
            
            .pixel-banner-store-search-button:hover,
            .pixel-banner-store-stop-search-button:hover,
            .pixel-banner-store-search-all-button:hover {
                background-color: var(--interactive-accent-hover) !important;
            }
            
            /* Pagination Styles */
            .pixel-banner-store-bottom-controls {
                display: flex;
                flex-direction: row;
                align-items: center;
                justify-content: space-between;
                margin-top: 15px;
                border-top: 1px solid var(--background-modifier-border);
                padding-top: 10px;
            }
            
            .pixel-banner-store-pagination-container {
                display: flex;
                align-items: center;
                gap: 8px;
            }
            
            .pixel-banner-store-pagination-button {
                font-size: 12px;
                padding: 4px 10px;
                border-radius: 4px;
                cursor: pointer;
                background-color: var(--interactive-accent) !important;
                color: var(--text-on-accent) !important;
                border: none;
            }
            
            .pixel-banner-store-pagination-button:not([disabled]):hover {
                background-color: var(--interactive-accent-hover) !important;
            }
            
            .pixel-banner-store-pagination-button[disabled] {
                opacity: 0.5;
                cursor: not-allowed;
                color: var(--text-color);
                background-color: var(--interactive-normal);
            }
            
            .pixel-banner-store-pagination-info {
                font-size: 12px;
                color: var(--text-normal);
                white-space: nowrap;
            }

            .pixel-banner-store-next-category {
                font-size: 14px;
                padding: 8px 12px;
                border-radius: 4px;
                cursor: pointer;
                background-color: var(--interactive-accent) !important;
                color: var(--text-on-accent) !important;
                border: none;
            }
            .pixel-banner-store-next-category:hover {
                background-color: var(--interactive-accent-hover) !important;
            }
            
            .pixel-banner-store-back-to-main {
                font-size: 14px;
                padding: 8px 12px;
                border-radius: 4px;
                cursor: pointer;
                border: none;
            }
            .pixel-banner-store-back-to-main:hover {
                background-color: var(--interactive-accent) !important;
            }
            
            .pixel-banner-store-error {
                color: var(--text-accent);
                margin-top: 8px;
            }

            .pixel-banner-store-image-grid {
                gap: 18px;
                padding: 18px;
                margin-top: 20px;
                display: flex;
                flex-direction: row;
                flex-wrap: wrap;
                align-items: normal;
                justify-content: center;
                height: 800px;
                max-height: 60vh;
                overflow-y: auto;
                overflow-x: hidden;
                border: 1px solid var(--table-border-color);
                position: relative; /* For the sticky pagination */
            }
            .pixel-banner-store-image-grid.-empty::after {
                display: none;
                // content: "\u{1FA84} Select a Category above, or click the Next Category button to cycle through them. A wonderful selection of banners awaits! The '\u2747\uFE0F Featured' category is updated often, and will be automatically displayed shortly if a selection is not made.";
                // position: relative;
                // top: 40%;
                // max-width: 380px;
                // font-size: 1.3em;
                // color: var(--text-muted);
                // max-height: 80px;
                // text-align: center;
                // opacity: 0.7;
            }
            .pixel-banner-store-image-grid.-not-connected::after {
                content: "\u26A1 Please connect your Pixel Banner Plus account in Settings to access the store. If you don't have an account, you can sign up for FREE using the button below! No payment information is required, and you will get access to a wide range of FREE banners.";
                position: relative;
                top: 40%;
                max-width: 458px;
                font-size: 1.3em;
                color: var(--text-muted);
                max-height: 80px;
                text-align: center;
                opacity: 0.7;
            }

            .pixel-banner-store-image-card {
                border: 5px solid transparent;
                border-radius: 8px;
                overflow: hidden;
                display: flex;
                flex-direction: column;
                align-items: center;
                padding: 12px 12px 7px 12px;
                width: 324px;
                transition: transform 0.2s ease;
                cursor: pointer;
                height: max-content;
                animation: pixel-banner-fade-in 1300ms ease-in-out;
                background: var(--background-secondary);
            }
            .pixel-banner-store-image-card:hover {
                transform: scale(1.1);
                border-color: var(--modal-border-color);
                z-index: 2;
            }

            .pixel-banner-store-image-card img {
                max-width: 300px;
                max-height: 300px;
                object-fit: cover;
            }

            .pixel-banner-store-image-details {
                display: flex;
                flex-direction: row;
                justify-content: space-between;
                padding: 8px 0;
                width: 100%;
            }

            .pixel-banner-store-prompt {
                font-size: 12px;
                margin: 0 0 4px;
                text-transform: lowercase;
                opacity: 0.8;
            }

            .pixel-banner-store-cost {
                font-size: 12px;
                color: var(--text-accent);
                margin: 0;
                text-align: right;
                white-space: nowrap;
                margin-left: 5px;
            }
            .pixel-banner-store-cost.free {
                color: var(--text-success) !important;
                font-weight: bold !important;
            }
            
            /* Vote Controls Styles */
            .pixel-banner-store-vote-controls {
                display: flex;
                align-items: center;
                justify-content: center;
                width: 100%;
                padding: 5px 0 0;
                gap: 7px;
            }
            
            .pixel-banner-store-vote-button {
                background: transparent;
                border: none;
                cursor: pointer;
                padding: 0;
                font-size: 14px;
                opacity: 0.4;
                transition: all 0.2s ease;
                width: 28px;
                height: 27px;
                line-height: 1.38;
                border-radius: 50%;
                border: 1px dashed transparent;
            }
            
            .pixel-banner-store-vote-button:hover {
                transform: scale(1.2);
                opacity: 1 !important;
            }
            
            .pixel-banner-store-vote-button.active {
                opacity: 0.7;
                transform: scale(1.1);
            }
            
            .pixel-banner-store-vote-button.active-upvote {
                border-color: var(--text-success);
            }
            
            .pixel-banner-store-vote-button.active-downvote {
                border-color: var(--text-error);
            }
            
            .pixel-banner-store-vote-button.disabled {
                opacity: 0.3;
                cursor: not-allowed;
                transform: none;
            }
            
            .pixel-banner-store-vote-button.disabled:hover {
                transform: none;
                opacity: 0.3;
            }
            
            .pixel-banner-store-vote-count {
                font-size: 14px;
                font-weight: bold;
                min-width: 30px;
                text-align: center;
            }
            
            .pixel-banner-store-vote-count.positive {
                color: var(--text-success);
            }
            
            .pixel-banner-store-vote-count.negative {
                color: var(--text-error);
            }
            
            .pixel-banner-store-vote-count.neutral {
                color: var(--text-muted);
            }

            .pixel-banner-store-loading {
                display: flex;
                justify-content: center;
                padding: 32px;
            }

            .pixel-banner-store-spinner {
                width: 40px;
                height: 40px;
                border: 4px solid var(--background-modifier-border);
                border-top: 4px solid var(--text-accent);
                border-radius: 50%;
                animation: pixel-banner-spin 1s linear infinite;
            }

            .pixel-banner-store-loading-overlay {
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                display: flex;
                justify-content: center;
                align-items: center;
                background-color: var(--background-primary);
                z-index: 100;
                animation: pixel-banner-fade-in 0.3s ease-in-out;
            }

            .pixel-banner-store-status-value {
                padding: 3px 7px;
                border-radius: 0px;
                font-size: .8em;
                letter-spacing: 1px;
                background-color: var(--background-primary);
                display: inline-flex;
                align-items: center;
                cursor: help;
            }
            
            .pixel-banner-account-button {
                padding: 3px 7px;
                border-radius: 5px;
                cursor: pointer;
                text-transform: uppercase;
                letter-spacing: 1px;
                font-size: .7em;
                transition: all 0.2s ease;
                border: 1px solid var(--background-modifier-border);
            }
            
            .pixel-banner-account-button:hover {
                opacity: 0.9;
                transform: translateY(-2px);
            }
            
            .pixel-banner-buy-tokens-button {
                background-color: darkgreen !important;
                color: papayawhip !important;
                opacity: 0.7;
            }
            
            .pixel-banner-signup-button {
                background-color: var(--interactive-accent) !important;
                color: var(--text-on-accent) !important;
            }

            .pixel-banner-store-image-grid.store-voting-off .pixel-banner-store-vote-controls {
                display: none;
            }


            /* ------------------- */
            /* -- mobile layout -- */
            /* ------------------- */
            @media screen and (max-width: 800px) {
                .pixel-banner-store-select-container { flex-direction: column !important; width: 100% !important; }
                .pixel-banner-store-select-container * { width: 100% !important; }
                .pixel-banner-store-search-container { flex-direction: column !important; width: 100% !important; }
                .pixel-banner-store-search-container * { width: 100% !important; }
            }
        `;
        document.head.appendChild(style);
        this.style = style;
      }
      onClose() {
        this.contentEl.empty();
        if (this.style) {
          this.style.remove();
        }
        if (this.loadingOverlay) {
          this.loadingOverlay.remove();
        }
      }
    };
    ConfirmPurchaseModal = class extends import_obsidian20.Modal {
      constructor(app, cost, prompt, previewImage, onConfirm, plugin, isVideo = false, fileType = "image", fileExtension = "jpg") {
        super(app);
        this.cost = cost;
        this.prompt = prompt;
        this.previewImage = previewImage;
        this.onConfirm = onConfirm;
        this.plugin = plugin;
        this.isVideo = isVideo;
        this.fileType = fileType;
        this.fileExtension = fileExtension;
      }
      onOpen() {
        var _a;
        const { contentEl } = this;
        contentEl.empty();
        this.addStyle();
        const titleContainer = contentEl.createEl("h3", {
          cls: "margin-top-0 pixel-banner-selector-title"
        });
        const flagImg = titleContainer.createEl("img", {
          attr: {
            src: flags[this.plugin.settings.selectImageIconFlag] || flags["red"],
            alt: "Pixel Banner",
            style: `
                    width: 20px;
                    height: 25px;
                    vertical-align: middle;
                    margin: -5px 10px 0 20px;
                `
          }
        });
        titleContainer.appendChild(document.createTextNode("Confirm Pixel Banner Purchase"));
        const mediaContainer = contentEl.createDiv({ cls: "pixel-banner-store-confirm-media" });
        if (this.isVideo) {
          const videoPreview = mediaContainer.createDiv({ cls: "pixel-banner-store-video-preview" });
          videoPreview.createEl("img", {
            attr: {
              src: this.previewImage,
              alt: "Video Banner Thumbnail"
            }
          });
          const playOverlay = videoPreview.createDiv({
            cls: "pixel-banner-store-play-overlay",
            attr: {
              style: `
                        position: absolute;
                        top: 50%;
                        left: 50%;
                        transform: translate(-50%, -50%);
                        background: rgba(0, 0, 0, 0.7);
                        border-radius: 50%;
                        width: 60px;
                        height: 60px;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        color: white;
                        font-size: 24px;
                        pointer-events: none;
                    `
            }
          });
          playOverlay.innerHTML = "\u25B6";
          const typeIndicator = mediaContainer.createDiv({
            text: `VIDEO (${this.fileExtension.toUpperCase()})`,
            cls: "pixel-banner-store-type-indicator",
            attr: {
              style: `
                        text-align: center;
                        margin-top: 8px;
                        font-size: 0.8em;
                        color: var(--text-muted);
                        font-weight: bold;
                    `
            }
          });
        } else {
          mediaContainer.createEl("img", {
            attr: {
              src: this.previewImage,
              alt: "Banner Preview"
            }
          });
        }
        contentEl.createEl("p", {
          text: `"${(_a = this.prompt) == null ? void 0 : _a.toLowerCase().replace(/[^a-zA-Z0-9-_ ]/g, "").trim()}"`,
          cls: "pixel-banner-store-confirm-prompt",
          attr: {
            "style": `
                    margin-top: -30px;
                    margin-bottom: 30px;
                    margin-left: auto;
                    margin-right: auto;
                    max-width: 320px;
                    text-align: center;
                    font-size: .9em;
                    font-style: italic;
                `
          }
        });
        const buttonContainer = contentEl.createDiv({
          cls: "setting-item-control",
          attr: {
            style: `
                    display: flex; 
                    justify-content: flex-end; 
                    gap: 8px;
                    margin-top: 10px;
                    align-items: flex-start;
                `
          }
        });
        const explanationText = buttonContainer.createEl("p", {
          text: `\u{1FA99} ${decimalToFractionString(this.cost)} Banner Token${this.cost > 1 ? "s" : ""} (this is not a monitary transaction). Once purchased, the banner will be added to your vault, and will be free to download while listed in the store.`,
          cls: "setting-item-description",
          attr: {
            style: `
                    text-align: left;
                    margin: 0 20px 0 0;
                    opacity: .8;
                    font-size: .8em;
                `
          }
        });
        const confirmButton = buttonContainer.createEl("button", {
          text: `\u{1FA99} ${decimalToFractionString(this.cost)} Token${this.cost > 1 ? "s" : ""}`,
          cls: "mod-cta radial-pulse-animation"
        });
        confirmButton.addEventListener("click", () => {
          this.close();
          this.onConfirm();
        });
        const cancelButton = buttonContainer.createEl("button", {
          text: "Cancel"
        });
        cancelButton.addEventListener("click", () => this.close());
      }
      // Add styles for the preview media
      addStyle() {
        const style = document.createElement("style");
        style.textContent = `
            .pixel-banner-store-confirm-media {
                display: flex;
                flex-direction: column;
                align-items: center;
                margin: 40px 10px;
            }
            
            .pixel-banner-store-confirm-media img {
                max-width: 100%;
                height: auto;
                border-radius: 4px;
            }
            
            .pixel-banner-store-video-preview {
                position: relative;
                display: inline-block;
            }
            
            .pixel-banner-store-video-preview img {
                display: block;
            }
            
            .pixel-banner-store-image-card {
                position: relative;
            }
        `;
        document.head.appendChild(style);
        this.style = style;
      }
      onClose() {
        const { contentEl } = this;
        contentEl.empty();
        if (this.style) {
          this.style.remove();
        }
      }
    };
  }
});

// src/modal/modals/webAddressModal.js
var import_obsidian21, WebAddressModal;
var init_webAddressModal = __esm({
  "src/modal/modals/webAddressModal.js"() {
    import_obsidian21 = require("obsidian");
    init_modals();
    WebAddressModal = class extends import_obsidian21.Modal {
      constructor(app, plugin) {
        super(app);
        this.plugin = plugin;
      }
      async onOpen() {
        const { contentEl } = this;
        contentEl.empty();
        const style = document.createElement("style");
        style.textContent = `
            /* ------------------- */
            /* -- mobile layout -- */
            /* ------------------- */
            @media screen and (max-width: 375px) {
                .pixel-banner-web-address-button-container { flex-direction: column !important; }
                .pixel-banner-web-address-button-container button { width: 100% !important; }
            }
        `;
        document.head.appendChild(style);
        this.style = style;
        const mainContainer = contentEl.createDiv({ cls: "pixel-banner-web-address-modal" });
        const titleContainer = mainContainer.createEl("h2", {
          cls: "pixel-banner-web-address-title",
          text: "\u{1F310} Enter Banner URL",
          attr: {
            style: `
                    margin-top: 10px;
                    margin-bottom: 20px;
                    text-align: center;
                `
          }
        });
        const inputContainer = mainContainer.createDiv({
          cls: "pixel-banner-web-address-input-container",
          attr: {
            style: `
                    display: flex;
                    flex-direction: column;
                    gap: 10px;
                    margin-bottom: 20px;
                `
          }
        });
        inputContainer.createEl("label", {
          text: "Image URL (http/https)",
          attr: {
            for: "pixel-banner-url-input",
            style: `
                    font-size: 14px;
                    font-weight: 500;
                `
          }
        });
        const urlInput = inputContainer.createEl("input", {
          cls: "pixel-banner-url-input",
          attr: {
            id: "pixel-banner-url-input",
            type: "url",
            placeholder: "https://example.com/image.jpg",
            style: `
                    width: 100%;
                    padding: 8px 12px;
                    border-radius: 4px;
                    border: 1px solid var(--background-modifier-border);
                    background-color: var(--background-primary);
                    font-size: 14px;
                `
          }
        });
        const errorContainer = inputContainer.createDiv({
          cls: "pixel-banner-url-error",
          attr: {
            style: `
                    color: var(--text-error);
                    font-size: 12px;
                    margin-top: 5px;
                    display: none;
                `
          }
        });
        const buttonContainer = mainContainer.createDiv({
          cls: "pixel-banner-web-address-button-container",
          attr: {
            style: `
                    display: flex;
                    justify-content: space-between;
                    gap: 10px;
                    margin-top: 20px;
                `
          }
        });
        const setBannerButton = buttonContainer.createEl("button", {
          cls: "pixel-banner-set-button",
          text: "Set Banner",
          attr: {
            style: `
                    padding: 8px 16px;
                    border-radius: 4px;
                    background-color: var(--interactive-accent);
                    color: var(--text-on-accent);
                    font-weight: 500;
                    cursor: pointer;
                    border: none;
                    flex: 1;
                `
          }
        });
        const backToMenuButton = buttonContainer.createEl("button", {
          cls: "pixel-banner-back-button",
          text: "\u21E0 Main Menu",
          attr: {
            style: `
                    padding: 8px 16px;
                    border-radius: 4px;
                    background-color: var(--background-modifier-border);
                    color: var(--text-normal);
                    font-weight: 500;
                    cursor: pointer;
                    border: none;
                `
          }
        });
        const validateImageUrl = async (url) => {
          try {
            if (!url || !url.startsWith("http")) {
              throw new Error("Please enter a valid http/https URL");
            }
            return new Promise((resolve, reject) => {
              const img = new Image();
              img.onload = () => resolve(true);
              img.onerror = () => reject(new Error("URL does not point to a valid image"));
              img.src = url;
              setTimeout(() => reject(new Error("Image loading timed out")), 5e3);
            });
          } catch (error) {
            throw error;
          }
        };
        const showError = (message) => {
          errorContainer.setText(message);
          errorContainer.style.display = "block";
          urlInput.addClass("pixel-banner-url-input-error");
        };
        const clearError = () => {
          errorContainer.setText("");
          errorContainer.style.display = "none";
          urlInput.removeClass("pixel-banner-url-input-error");
        };
        urlInput.addEventListener("input", () => {
          clearError();
        });
        setBannerButton.addEventListener("click", async () => {
          const url = urlInput.value.trim();
          clearError();
          try {
            setBannerButton.disabled = true;
            setBannerButton.setText("Validating...");
            await validateImageUrl(url);
            const activeFile = this.app.workspace.getActiveFile();
            if (!activeFile) {
              throw new Error("No active file to add banner to");
            }
            await this.plugin.app.fileManager.processFrontMatter(activeFile, (frontmatter) => {
              const bannerField = this.plugin.settings.customBannerField[0];
              frontmatter[bannerField] = url;
            });
            if (this.plugin.settings.openTargetingModalAfterSelectingBannerOrIcon) {
              this.close();
              new TargetPositionModal(this.app, this.plugin).open();
            } else {
              this.close();
            }
          } catch (error) {
            showError(error.message);
            setBannerButton.disabled = false;
            setBannerButton.setText("Set Banner");
          }
        });
        backToMenuButton.addEventListener("click", () => {
          this.close();
          new SelectPixelBannerModal(this.app, this.plugin).open();
        });
        this.addStyle();
        urlInput.focus();
      }
      addStyle() {
        const style = document.createElement("style");
        style.textContent = `
            .pixel-banner-web-address-modal {
                padding: 16px;
                max-width: 500px;
                width: 100%;
            }
            
            .pixel-banner-url-input-error {
                border-color: var(--text-error) !important;
            }
            
            @keyframes pixel-banner-fade-in {
                from { opacity: 0; }
                to { opacity: 1; }
            }
        `;
        document.head.appendChild(style);
        this.style = style;
      }
      onClose() {
        this.contentEl.empty();
        if (this.style) {
          this.style.remove();
        }
      }
    };
  }
});

// src/modal/modals/dailyGame.js
var import_obsidian22, DailyGameModal;
var init_dailyGame = __esm({
  "src/modal/modals/dailyGame.js"() {
    import_obsidian22 = require("obsidian");
    init_constants();
    init_selectPixelBannerModal();
    DailyGameModal = class extends import_obsidian22.Modal {
      constructor(app, userEmail, apiKey, plugin) {
        super(app);
        this.userEmail = userEmail;
        this.apiKey = apiKey;
        this.iframe = null;
        this.plugin = plugin;
      }
      onOpen() {
        const style = document.createElement("style");
        style.innerHTML = `
        .pixel-banner-game-modal {
        width: 800px;
        max-width: 90vw;
        }

        .pixel-banner-game-modal .game-container {
        margin: 1rem 0;
        border: 1px solid var(--background-modifier-border);
        border-radius: 4px;
        overflow: hidden;
        height: 600px;
        }

        .pixel-banner-game-modal iframe {
        border: none;
        }
    `;
        const { contentEl } = this;
        contentEl.addClass("pixel-banner-game-modal");
        const gameContainer = contentEl.createDiv({ cls: "game-container" });
        this.iframe = gameContainer.createEl("iframe", {
          attr: {
            src: `${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.DAILY_GAME}`,
            width: "100%",
            height: "600px",
            frameborder: "0",
            allowfullscreen: "true",
            allow: "clipboard-write; encrypted-media",
            sandbox: "allow-scripts allow-same-origin allow-popups allow-forms"
          }
        });
        const buttonContainer = contentEl.createDiv({
          cls: "button-container",
          attr: {
            style: `
                display: flex;
                align-items: center;
                justify-content: space-between;
            `
          }
        });
        const buyTokensButton = buttonContainer.createEl("button", {
          cls: "pixel-banner-account-button pixel-banner-buy-tokens-button",
          text: "\u{1F4B5} Buy More Tokens"
        });
        buyTokensButton.addEventListener("click", (event) => {
          event.preventDefault();
          window.open(PIXEL_BANNER_PLUS.SHOP_URL, "_blank");
        });
        const backToMainButton = buttonContainer.createEl("button", {
          text: "\u21E0 Main Menu",
          cls: "cursor-pointer",
          attr: {
            style: `
              margin-left: auto;
              width: max-content;
              min-width: auto;
          `
          }
        });
        backToMainButton.addEventListener("click", () => {
          this.close();
          new SelectPixelBannerModal(this.app, this.plugin).open();
        });
        this.iframe.onload = () => {
          this.sendAuthToIframe();
        };
      }
      sendAuthToIframe() {
        if (!this.iframe.contentWindow) {
          console.error("Iframe content window not available");
          return;
        }
        this.iframe.contentWindow.postMessage({
          type: "auth",
          data: {
            userEmail: this.userEmail,
            apiKey: this.apiKey
          }
        }, PIXEL_BANNER_PLUS.API_URL);
      }
      onClose() {
        const { contentEl } = this;
        contentEl.empty();
      }
    };
  }
});

// src/modal/modals.js
var modals_exports = {};
__export(modals_exports, {
  DailyGameModal: () => DailyGameModal,
  EmojiSelectionModal: () => EmojiSelectionModal,
  FolderSelectionModal: () => FolderSelectionModal,
  GenerateAIBannerModal: () => GenerateAIBannerModal,
  IconFolderSelectionModal: () => IconFolderSelectionModal,
  IconImageSelectionModal: () => IconImageSelectionModal,
  ImageSelectionModal: () => ImageSelectionModal,
  ImageViewModal: () => ImageViewModal,
  PinChoiceModal: () => PinChoiceModal,
  PixelBannerStoreModal: () => PixelBannerStoreModal,
  ReleaseNotesModal: () => ReleaseNotesModal,
  SaveImageModal: () => SaveImageModal,
  SelectPixelBannerModal: () => SelectPixelBannerModal,
  TargetPositionModal: () => TargetPositionModal,
  WebAddressModal: () => WebAddressModal
});
var init_modals = __esm({
  "src/modal/modals.js"() {
    init_releaseNotesModal();
    init_imageViewModal();
    init_imageSelectionModal();
    init_iconImageSelectionModal();
    init_folderSelectionModal();
    init_iconFolderSelectionModal();
    init_generateAIBannerModal();
    init_saveImageModal();
    init_pinChoiceModal();
    init_emojiSelectionModal();
    init_targetPositionModal();
    init_selectPixelBannerModal();
    init_pixelBannerStoreModal();
    init_webAddressModal();
    init_dailyGame();
  }
});

// src/main.js
var main_exports = {};
__export(main_exports, {
  default: () => main_default
});
module.exports = __toCommonJS(main_exports);

// src/core/pixelBannerPlugin.js
var import_obsidian31 = require("obsidian");

// virtual-module:virtual:release-notes
var releaseNotes = '<a href="https://www.youtube.com/watch?v=tfNqEAQuhXs">\n  <img src="https://pixel-banner.online/img/pixel-banner-v3.6.jpg" alt="Pixel Banner" style="max-width: 400px;">\n</a>\n\n<h2>\u{1F389} What&#39;s New</h2>\n<h3>v3.6.0</h3>\n<h4>\u2728 Added</h4>\n<ul>\n<li>Support for \u{1F3AC} Video Banners!<ul>\n<li>Upload and choose Video files as banners from your vault</li>\n<li>Downloadable \u{1F3AC} Video Banners from the <code>Pixel Banner Plus Collection</code></li>\n</ul>\n</li>\n<li>Added paging controls to the <code>Pixel Banner Plus Collection</code></li>\n<li>New global <code>Banner Max Width</code> setting to control the default max width for all banners</li>\n</ul>\n<h4>\u{1F4E6} Updated</h4>\n<ul>\n<li>Moved <code>Default Saved Banners Folder</code> setting to the <code>General</code> tab</li>\n<li>Renamed <code>Pixel Banner Plus Store</code> to <code>Pixel Banner Plus Collection</code> as many items are free</li>\n</ul>\n<h3>v3.6.1</h3>\n<h4>\u{1F41B} Fixed</h4>\n<ul>\n<li>Resolved issue with Icon Image selection modal not setting the selected icon image</li>\n</ul>\n<h3>v3.6.2</h3>\n<h4>\u{1F4E6} Updated</h4>\n<ul>\n<li>Improved debounce logic to prevent multiple banner reloads when opening a note</li>\n</ul>\n<h3>v3.6.3</h3>\n<h4>\u2728 Added</h4>\n<ul>\n<li>Added <code>filesize</code> display to the store modal</li>\n</ul>\n<h3>v3.6.4</h3>\n<h4>\u2728 Added</h4>\n<ul>\n<li>Banner images now support local <code>file</code> protocol for images outside of your vault (e.g. <code>file:///C:\\path\\banner.jpg</code>)</li>\n</ul>\n<h4>\u{1F4E6} Updated</h4>\n<ul>\n<li>Allow commas in banner filenames</li>\n</ul>\n<h4>\u{1F41B} Fixed</h4>\n<ul>\n<li>Ensure pinned banner is the currently displayed image when saving API banners</li>\n<li>Ensure banner icons are only rendered when a main banner image is present</li>\n<li>Banner Icon Image not always rendered until the note was clicked/focused</li>\n</ul>\n<h3>v3.6.5</h3>\n<h4>\u{1F41B} Fixed</h4>\n<ul>\n<li>Fix refresh button to use original comma-separated keywords from frontmatter instead of the cached single keyword</li>\n<li>Resolved issue with the default x/y frontmatter fields not being hidden when the &quot;Hide Pixel Banner Fields&quot; option is enabled</li>\n<li>Updated API call for <code>Pexels</code> to conform to spec changes on their side</li>\n</ul>\n<h3>v3.6.6</h3>\n<h4>\u{1F41B} Fixed</h4>\n<ul>\n<li>New folder group entries now inherit the user&#39;s default Content Start Position setting instead of being hardcoded to 150px</li>\n</ul>\n<h3>v3.6.8</h3>\n<h4>\u2728 Added</h4>\n<ul>\n<li><strong>Pin Choice Modal</strong>: When pinning API images, users can now choose between saving locally or pinning the URL directly to frontmatter<ul>\n<li>New choice modal presents &quot;Save Image Locally&quot; vs &quot;Pin Image URL&quot; options</li>\n<li>URL pinning saves no storage space in vault but requires internet connection</li>\n<li>Local saving remains available for offline access and permanence</li>\n<li>Choice only appears for user-initiated pin actions (pin icon, command palette)</li>\n<li>AI generation and Pixel Banner Plus continue to save locally automatically</li>\n</ul>\n</li>\n<li><strong>Auto-Focus Enhancement</strong>: Folder selection modal now automatically focuses and selects the text input for improved workflow</li>\n</ul>\n<h3>v3.6.7</h3>\n<h4>\u{1F41B} Fixed</h4>\n<ul>\n<li>Fixed ImageViewModal to properly display banner images and videos when clicking the &quot;Show View Image Icon&quot;<ul>\n<li>Added support for MP4 and MOV video files in the ImageViewModal with proper video player controls</li>\n<li>Correctly display actual image URLs instead of keywords for 3rd party API banners in the ImageViewModal</li>\n<li>Local images, videos, and file:/// paths maintain original display behavior</li>\n</ul>\n</li>\n</ul>\n<h3>v3.6.8</h3>\n<h4>\u2728 Added</h4>\n<ul>\n<li><strong>Pin Choice Modal</strong>: When pinning API images, users can now choose between saving locally or pinning the URL directly to frontmatter<ul>\n<li>New choice modal presents &quot;Save Image Locally&quot; vs &quot;Pin Image URL&quot; options</li>\n<li>URL pinning saves no storage space in vault but requires internet connection</li>\n<li>Local saving remains available for offline access and permanence</li>\n<li>Choice only appears for user-initiated pin actions (pin icon, command palette)</li>\n<li>AI generation and Pixel Banner Plus continue to save locally automatically</li>\n</ul>\n</li>\n<li><strong>Auto-Focus Enhancement</strong>: Folder selection modal now automatically focuses and selects the text input for improved workflow</li>\n<li><code>Enter</code> button support for submitting the save image form in the <code>Save Image Modal</code></li>\n<li>New <code>Pin Image URL</code> option to save API images directly as URL references in frontmatter without downloading to vault</li>\n</ul>\n<h4>\u{1F4E6} Updated</h4>\n<ul>\n<li>Replaced manual frontmatter string manipulation with Obsidian&#39;s native processFrontMatter API for more reliable metadata updates</li>\n</ul>\n<h3>v3.6.9</h3>\n<h4>\u2728 Added</h4>\n<ul>\n<li>New <code>Icon Image Size Multiplier</code> setting to the <code>General</code> settings tab to control the global size of banner icon images</li>\n<li>Check for version updates when opening <code>General</code> settings and show update button if available</li>\n</ul>\n<h4>\u{1F4E6} Updated</h4>\n<ul>\n<li>Moved <code>AI Model</code> selection from radio buttons to a dropdown for better organization</li>\n<li>Changed default banner fade value from <code>-70</code> to <code>-40</code></li>\n</ul>\n<h3>v3.6.10</h3>\n<h4>\u{1F41B} Fixed</h4>\n<ul>\n<li>Icon images and emojis not being displayed properly</li>\n</ul>\n<h3>v3.6.11</h3>\n<h4>\u2728 Added</h4>\n<ul>\n<li>New toggle to turn on/off <code>Pixel Banner Plus</code> in the main Pixel Banner select modal</li>\n<li><strong>Plain image format support</strong>: Added <code>image</code> option to Image Property Format setting (without brackets), improving compatibility with Make.md and other plugins</li>\n</ul>\n<h4>\u{1F4E6} Updated</h4>\n<ul>\n<li>Added unquoted wiki-link support for Image Icons paths (e.g. <code>[[path/icon.png]]</code>)</li>\n<li>Misc code cleanup</li>\n</ul>\n<h3>v3.6.12</h3>\n<h4>\u{1F41B} Fixed</h4>\n<ul>\n<li>Resolved incorrect <code>Pixel Banner Plus Server</code> URL</li>\n</ul>\n<h3>v3.6.13</h3>\n<h4>\u2728 Added</h4>\n<ul>\n<li>Support for Multiple Image Reference for new AI Image Generation models<ul>\n<li><code>Nano Banana</code></li>\n<li><code>Seedream 4</code></li>\n</ul>\n</li>\n</ul>\n<h3>v3.6.14</h3>\n<h4>\u{1F41B} Fixed</h4>\n<ul>\n<li>Resolved issue with <code>.webp</code> images not being displayed</li>\n</ul>\n<h3>v3.6.15</h3>\n<h4>\u{1F41B} Fixed</h4>\n<ul>\n<li>Resolved issue with plain paths not working for video files (<code>.mp4</code>, <code>.mov</code>)</li>\n</ul>\n<h3>v3.6.16</h3>\n<h4>\u{1F41B} Fixed</h4>\n<ul>\n<li>Fixed an occasional error that could prevent banners from displaying correctly</li>\n</ul>\n<a href="https://www.youtube.com/watch?v=pJFsMfrWak4">\n  <img src="https://pixel-banner.online/img/pixel-banner-transparent-bg.png" alt="Pixel Banner" style="max-width: 400px;">\n</a>\n';

// src/settings/settings.js
var import_obsidian6 = require("obsidian");

// src/settings/tabs/settingsTabAPISettings.js
var import_obsidian = require("obsidian");
async function testPexelsApi(apiKey) {
  try {
    const response = await fetch(`https://api.pexels.com/v1/search?query=${random20characters()}&per_page=3`, {
      headers: {
        "Authorization": apiKey
      }
    });
    if (!response.ok) {
      throw new Error("\u274C Invalid Pexels API key");
    }
    const data = await response.json();
    return data.photos;
  } catch (error) {
    return false;
  }
}
async function testPixabayApi(apiKey) {
  try {
    const response = await fetch(`https://pixabay.com/api/?key=${apiKey}&q=test&per_page=3`);
    const data = await response.json();
    if (data.error) {
      throw new Error(data.error);
    }
    return true;
  } catch (error) {
    return false;
  }
}
async function testFlickrApi(apiKey) {
  try {
    const response = await fetch(`https://www.flickr.com/services/rest/?method=flickr.test.echo&api_key=${apiKey}&format=json&nojsoncallback=1`);
    const data = await response.json();
    return data.stat === "ok";
  } catch (error) {
    return false;
  }
}
async function testUnsplashApi(apiKey) {
  try {
    const response = await fetch("https://api.unsplash.com/photos/random", {
      headers: {
        "Authorization": `Client-ID ${apiKey}`
      }
    });
    return response.ok;
  } catch (error) {
    return false;
  }
}
function random20characters() {
  const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  let result = "";
  for (let i = 0; i < 20; i++) {
    result += characters.charAt(Math.floor(Math.random() * characters.length));
  }
  return result;
}
function createAPISettings(containerEl, plugin) {
  const calloutEl = containerEl.createEl("div", { cls: "tab-callout" });
  calloutEl.createEl("div", { text: "\u{1F310} Optionally select which 3rd party API provider to use for displaying random images." });
  new import_obsidian.Setting(containerEl).setName("API Provider").setDesc("Select the API provider for fetching images").addDropdown((dropdown) => dropdown.addOption("all", "All (Random)").addOption("pexels", "Pexels").addOption("pixabay", "Pixabay").addOption("flickr", "Flickr").addOption("unsplash", "Unsplash").setValue(plugin.settings.apiProvider).onChange(async (value) => {
    plugin.settings.apiProvider = value;
    await plugin.saveSettings();
    plugin.settingTab.display();
  }));
  new import_obsidian.Setting(containerEl).setName("Pexels API Key");
  containerEl.createEl("span", { text: "Enter your Pexels API key. Get your API key from ", cls: "setting-item-description" }).createEl("a", { href: "https://www.pexels.com/api/", text: "Pexels API" });
  const pexelsApiKeySetting = new import_obsidian.Setting(containerEl).setClass("full-width-control").addText((text) => {
    text.setPlaceholder("Pexels API key").setValue(plugin.settings.pexelsApiKey).onChange(async (value) => {
      plugin.settings.pexelsApiKey = value;
      await plugin.saveSettings();
    });
    text.inputEl.style.width = "calc(100% - 100px)";
  }).addButton((button) => button.setButtonText("Test API").onClick(async () => {
    const apiKey = plugin.settings.pexelsApiKey;
    if (!apiKey) {
      new import_obsidian.Notice("Please enter an API key first");
      return;
    }
    button.setButtonText("Testing...");
    button.setDisabled(true);
    const isValid = await testPexelsApi(apiKey);
    button.setButtonText("Test API");
    button.setDisabled(false);
    new import_obsidian.Notice(isValid ? "\u2705 Pexels API key is valid!" : "\u274C Invalid Pexels API key");
  }));
  pexelsApiKeySetting.settingEl.style.width = "100%";
  new import_obsidian.Setting(containerEl).setName("Pixabay API Key");
  containerEl.createEl("span", { text: "Enter your Pixabay API key. Get your API key from ", cls: "setting-item-description" }).createEl("a", { href: "https://pixabay.com/api/docs/", text: "Pixabay API" });
  const pixabayApiKeySetting = new import_obsidian.Setting(containerEl).setClass("full-width-control").addText((text) => {
    text.setPlaceholder("Pixabay API key").setValue(plugin.settings.pixabayApiKey).onChange(async (value) => {
      plugin.settings.pixabayApiKey = value;
      await plugin.saveSettings();
    });
    text.inputEl.style.width = "calc(100% - 100px)";
  }).addButton((button) => button.setButtonText("Test API").onClick(async () => {
    const apiKey = plugin.settings.pixabayApiKey;
    if (!apiKey) {
      new import_obsidian.Notice("Please enter an API key first");
      return;
    }
    button.setButtonText("Testing...");
    button.setDisabled(true);
    const isValid = await testPixabayApi(apiKey);
    button.setButtonText("Test API");
    button.setDisabled(false);
    new import_obsidian.Notice(isValid ? "\u2705 Pixabay API key is valid!" : "\u274C Invalid Pixabay API key");
  }));
  pixabayApiKeySetting.settingEl.style.width = "100%";
  new import_obsidian.Setting(containerEl).setName("Flickr API Key");
  containerEl.createEl("span", { text: "Enter your Flickr API key. Get your API key from ", cls: "setting-item-description" }).createEl("a", { href: "https://www.flickr.com/services/api/", text: "Flickr API" });
  const flickrApiKeySetting = new import_obsidian.Setting(containerEl).setClass("full-width-control").addText((text) => {
    text.setPlaceholder("Flickr API key").setValue(plugin.settings.flickrApiKey).onChange(async (value) => {
      plugin.settings.flickrApiKey = value;
      await plugin.saveSettings();
    });
    text.inputEl.style.width = "calc(100% - 100px)";
  }).addButton((button) => button.setButtonText("Test API").onClick(async () => {
    const apiKey = plugin.settings.flickrApiKey;
    if (!apiKey) {
      new import_obsidian.Notice("Please enter an API key first");
      return;
    }
    button.setButtonText("Testing...");
    button.setDisabled(true);
    const isValid = await testFlickrApi(apiKey);
    button.setButtonText("Test API");
    button.setDisabled(false);
    new import_obsidian.Notice(isValid ? "\u2705 Flickr API key is valid!" : "\u274C Invalid Flickr API key");
  }));
  new import_obsidian.Setting(containerEl).setName("Unsplash API Key");
  containerEl.createEl("span", { text: "Enter your Unsplash API key (Access Key). Get your API key from ", cls: "setting-item-description" }).createEl("a", { href: "https://unsplash.com/oauth/applications", text: "Unsplash API" });
  const unsplashApiKeySetting = new import_obsidian.Setting(containerEl).setClass("full-width-control").addText((text) => {
    text.setPlaceholder("Unsplash API key").setValue(plugin.settings.unsplashApiKey).onChange(async (value) => {
      plugin.settings.unsplashApiKey = value;
      await plugin.saveSettings();
    });
    text.inputEl.style.width = "calc(100% - 100px)";
  }).addButton((button) => button.setButtonText("Test API").onClick(async () => {
    const apiKey = plugin.settings.unsplashApiKey;
    if (!apiKey) {
      new import_obsidian.Notice("Please enter an API key first");
      return;
    }
    button.setButtonText("Testing...");
    button.setDisabled(true);
    const isValid = await testUnsplashApi(apiKey);
    button.setButtonText("Test API");
    button.setDisabled(false);
    new import_obsidian.Notice(isValid ? "\u2705 Unsplash API key is valid!" : "\u274C Invalid Unsplash API key");
  }));
  const exampleContainer = containerEl.createEl("div", {
    attr: {
      style: `
                margin: 20px 0;
                padding: 20px;
                border: 1px solid var(--modal-border-color);
                border-radius: 7px;
            `
    }
  });
  exampleContainer.createEl("div", {
    text: "Usage Example",
    attr: {
      style: `
                font-weight: bold;
                font-size: 1.1rem;
                color: var(--color-accent);
            `
    }
  });
  exampleContainer.createEl("div", {
    text: "Add keyword(s) to the banner frontmatter to display random API images matching the keywords.",
    attr: {
      style: `
                margin: 10px 0;
            `
    }
  });
  exampleContainer.createEl("img", {
    attr: {
      src: "https://raw.githubusercontent.com/jparkerweb/pixel-banner/refs/heads/main/img/3rd-party-apis-example.jpg",
      style: `
                width: auto;
                max-width: 100%;
            `
    }
  });
  new import_obsidian.Setting(containerEl).setName("Images").setDesc("Configure settings for images fetched from API. These settings apply when using keywords to fetch random images.").setHeading();
  new import_obsidian.Setting(containerEl).setName("Show Pin Icon").setDesc("Show a pin icon on random banner images that allows saving them to your vault. Once pinned, your frontmatter will be updated to use the local image instead of the API image.").addToggle((toggle) => toggle.setValue(plugin.settings.showPinIcon).onChange(async (value) => {
    plugin.settings.showPinIcon = value;
    refreshIconSetting.settingEl.style.display = value ? "flex" : "none";
    await plugin.saveSettings();
  }));
  new import_obsidian.Setting(containerEl).setName("Pinned Image Filename").setDesc("Set the default filename for pinned images.").addText((text) => text.setPlaceholder("pixel-banner-image").setValue(plugin.settings.pinnedImageFilename).onChange(async (value) => {
    plugin.settings.pinnedImageFilename = value;
    await plugin.saveSettings();
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    plugin.settings.pinnedImageFilename = DEFAULT_SETTINGS.pinnedImageFilename;
    await plugin.saveSettings();
    const textInput = button.extraSettingsEl.parentElement.querySelector("input");
    textInput.value = DEFAULT_SETTINGS.pinnedImageFilename;
  }));
  const refreshIconSetting = new import_obsidian.Setting(containerEl).setName("Show Refresh Icon").setDesc("Show a refresh icon on random banner images that allows fetching a new random image.").addToggle((toggle) => toggle.setValue(plugin.settings.showRefreshIcon).onChange(async (value) => {
    plugin.settings.showRefreshIcon = value;
    await plugin.saveSettings();
  }));
  refreshIconSetting.settingEl.style.display = plugin.settings.showPinIcon ? "flex" : "none";
  new import_obsidian.Setting(containerEl).setName("Size").setDesc("Select the size of the image - (API only)").addDropdown((dropdown) => dropdown.addOption("small", "Small").addOption("medium", "Medium").addOption("large", "Large").setValue(plugin.settings.imageSize).onChange(async (value) => {
    plugin.settings.imageSize = value;
    await plugin.saveSettings();
  }));
  new import_obsidian.Setting(containerEl).setName("Orientation").setDesc("Select the orientation of the image - (API only)").addDropdown((dropdown) => dropdown.addOption("landscape", "Landscape").addOption("portrait", "Portrait").addOption("square", "Square").setValue(plugin.settings.imageOrientation).onChange(async (value) => {
    plugin.settings.imageOrientation = value;
    await plugin.saveSettings();
  }));
  new import_obsidian.Setting(containerEl).setName("Number of images").setDesc("Enter the number of random images to fetch (3-50) - (API only)").addText((text) => text.setPlaceholder("10").setValue(String(plugin.settings.numberOfImages || 10)).onChange(async (value) => {
    let numValue = Number(value);
    if (!isNaN(numValue)) {
      numValue = Math.max(3, Math.min(numValue, 50));
      plugin.settings.numberOfImages = numValue;
      await plugin.saveSettings();
    }
  })).then((setting) => {
    const inputEl = setting.controlEl.querySelector("input");
    inputEl.type = "number";
    inputEl.min = "3";
    inputEl.max = "50";
    inputEl.style.width = "50px";
  });
  const defaultKeywordsSetting = new import_obsidian.Setting(containerEl).setName("Default keywords").setDesc("Enter a comma-separated list of default keywords to be used when no keyword is provided in the frontmatter, or when the provided keyword does not return any results. - (API only)").addTextArea((text) => {
    text.setPlaceholder("Enter keywords, separated by commas").setValue(plugin.settings.defaultKeywords).onChange(async (value) => {
      plugin.settings.defaultKeywords = value;
      await plugin.saveSettings();
    });
    text.inputEl.style.width = "100%";
    text.inputEl.style.marginTop = "15px";
    text.inputEl.style.height = "90px";
  }).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    plugin.settings.defaultKeywords = DEFAULT_SETTINGS.defaultKeywords;
    await plugin.saveSettings();
    plugin.settingTab.display();
  }));
  defaultKeywordsSetting.settingEl.dataset.id = "defaultKeywords";
  defaultKeywordsSetting.settingEl.style.display = "flex";
  defaultKeywordsSetting.settingEl.style.flexDirection = "column";
}

// src/settings/tabs/settingsTabFolderImages.js
var import_obsidian2 = require("obsidian");
function createFolderSettings(containerEl, plugin) {
  const calloutEl = containerEl.createEl("div", { cls: "tab-callout" });
  calloutEl.createEl("div", { text: "\u{1F5C3}\uFE0F Configure banner settings for specific folders. These settings will override the default settings for all notes in the specified folder." });
  const folderImagesContainer = containerEl.createEl("div", { cls: "folder-images-container" });
  plugin.settings.folderImages.forEach((folderImage, index) => {
    new FolderImageSetting(
      folderImagesContainer,
      plugin,
      folderImage,
      index,
      () => updateFolderSettings(containerEl, plugin)
    );
  });
  const addFolderImageSetting = new import_obsidian2.Setting(containerEl).setClass("add-folder-image-setting").addButton((button) => button.setButtonText("Add Folder Image").onClick(async () => {
    const newFolderImage = {
      folder: "",
      image: "",
      imageDisplay: plugin.settings.imageDisplay,
      imageRepeat: plugin.settings.imageRepeat,
      yPosition: plugin.settings.yPosition,
      xPosition: plugin.settings.xPosition,
      contentStartPosition: plugin.settings.contentStartPosition,
      bannerHeight: plugin.settings.bannerHeight,
      fade: plugin.settings.fade,
      borderRadius: plugin.settings.borderRadius,
      titleColor: "var(--inline-title-color)",
      directChildrenOnly: false,
      enableImageShuffle: false,
      shuffleFolder: ""
    };
    plugin.settings.folderImages.push(newFolderImage);
    await plugin.saveSettings();
    updateFolderSettings(containerEl, plugin);
  }));
}
function updateFolderSettings(containerEl, plugin) {
  containerEl.empty();
  createFolderSettings(containerEl, plugin);
}
var FolderImageSetting = class extends import_obsidian2.Setting {
  constructor(containerEl, plugin, folderImage, index, onDelete) {
    super(containerEl);
    this.plugin = plugin;
    this.folderImage = folderImage;
    this.index = index;
    this.onDelete = onDelete;
    this.setClass("folder-image-setting");
    this.settingEl.empty();
    const folderImageDeleteContainer = this.settingEl.createDiv("folder-image-delete-container");
    this.addDeleteButton(folderImageDeleteContainer);
    const infoEl = this.settingEl.createDiv("setting-item-info");
    infoEl.createDiv("setting-item-name");
    infoEl.createDiv("setting-item-description");
    this.addFolderInput();
    this.addImageInput();
    this.addImageDisplaySettings();
    this.addYPostionAndContentStart();
    this.addFadeAndBannerHeight();
    const controlEl = this.settingEl.createDiv("setting-item-control full-width-control");
    this.addContentStartInput(controlEl);
    this.addBorderRadiusInput(controlEl);
    const controlEl2 = this.settingEl.createDiv("setting-item-control full-width-control");
    this.addColorSettings(controlEl2);
    this.addBannerIconSettings();
    this.addDirectChildrenOnlyToggle();
  }
  addDeleteButton(containerEl) {
    const deleteButton = containerEl.createEl("button", { cls: "pixel-banner-setting--delete-button" });
    deleteButton.style.marginLeft = "20px";
    deleteButton.style.width = "30px";
    deleteButton.style.height = "30px";
    deleteButton.style.padding = "0";
    deleteButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-trash-2"><path d="M3 6h18"></path><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg>`;
    deleteButton.addEventListener("click", async () => {
      this.plugin.settings.folderImages.splice(this.index, 1);
      await this.plugin.saveSettings();
      this.settingEl.remove();
      if (this.onDelete) {
        this.onDelete();
      }
    });
  }
  addFolderInput() {
    const folderInputContainer = this.settingEl.createDiv("folder-input-container");
    const folderInput = new import_obsidian2.Setting(folderInputContainer).setName("Folder Path").addText((text) => {
      text.setValue(this.folderImage.folder || "").onChange(async (value) => {
        this.folderImage.folder = value;
        await this.plugin.saveSettings();
      });
      this.folderInputEl = text.inputEl;
      this.folderInputEl.style.width = "300px";
    });
    folderInput.addButton((button) => button.setButtonText("Browse").onClick(() => {
      new FolderSuggestModal(this.plugin.app, (chosenPath) => {
        this.folderImage.folder = chosenPath;
        this.folderInputEl.value = chosenPath;
        this.plugin.saveSettings();
      }).open();
    }));
    const shuffleContainer = this.settingEl.createDiv("shuffle-container");
    const shuffleToggle = new import_obsidian2.Setting(shuffleContainer).setName("Enable Image Shuffle").setDesc("Randomly select an image from a specified folder each time the note loads").addToggle((toggle) => {
      toggle.setValue(this.folderImage.enableImageShuffle || false).onChange(async (value) => {
        this.folderImage.enableImageShuffle = value;
        if (value) {
          shuffleFolderInput.settingEl.style.display = "flex";
          this.imageInputContainer.style.display = "none";
        } else {
          shuffleFolderInput.settingEl.style.display = "none";
          this.imageInputContainer.style.display = "block";
        }
        await this.plugin.saveSettings();
      });
    });
    const shuffleFolderInput = new import_obsidian2.Setting(shuffleContainer).setName("Image Shuffle Folder").setDesc("Folder containing images to randomly select from").addText((text) => {
      text.setValue(this.folderImage.shuffleFolder || "").onChange(async (value) => {
        this.folderImage.shuffleFolder = value;
        await this.plugin.saveSettings();
      });
      text.inputEl.style.width = "300px";
    });
    shuffleFolderInput.addButton((button) => button.setButtonText("Browse").onClick(() => {
      new FolderSuggestModal(this.plugin.app, (chosenPath) => {
        this.folderImage.shuffleFolder = chosenPath;
        shuffleFolderInput.controlEl.querySelector("input").value = chosenPath;
        this.plugin.saveSettings();
      }).open();
    }));
    if (!this.folderImage.enableImageShuffle) {
      shuffleFolderInput.settingEl.style.display = "none";
    }
  }
  addImageInput() {
    this.imageInputContainer = this.settingEl.createDiv("folder-input-container");
    if (this.folderImage.enableImageShuffle) {
      this.imageInputContainer.style.display = "none";
    }
    const imageInput = new import_obsidian2.Setting(this.imageInputContainer).setName("Image URL or Keyword").addText((text) => {
      text.setValue(this.folderImage.image || "").onChange(async (value) => {
        this.folderImage.image = value;
        await this.plugin.saveSettings();
      });
      this.imageInputEl = text.inputEl;
      this.imageInputEl.style.width = "306px";
    });
  }
  addImageDisplaySettings(containerEl) {
    const displayContainer = this.settingEl.createDiv("display-and-repeat-container");
    const displaySetting = new import_obsidian2.Setting(displayContainer).setName("Image Display").addDropdown((dropdown) => {
      dropdown.addOption("auto", "Auto").addOption("cover", "Cover").addOption("contain", "Contain").setValue(this.folderImage.imageDisplay || "cover").onChange(async (value) => {
        this.folderImage.imageDisplay = value;
        await this.plugin.saveSettings();
      });
      dropdown.selectEl.style.marginRight = "20px";
    });
    const repeatSetting = new import_obsidian2.Setting(displayContainer).setName("repeat").addToggle((toggle) => {
      toggle.setValue(this.folderImage.imageRepeat || false).onChange(async (value) => {
        this.folderImage.imageRepeat = value;
        await this.plugin.saveSettings();
      });
    });
    const toggleEl = repeatSetting.controlEl.querySelector(".checkbox-container");
    if (toggleEl) toggleEl.style.justifyContent = "flex-start";
  }
  addYPostionAndContentStart() {
    const controlEl = this.settingEl.createDiv("setting-item-control full-width-control");
    this.addYPositionInput(controlEl);
    this.addXPositionInput(controlEl);
  }
  addFadeAndBannerHeight() {
    const controlEl = this.settingEl.createDiv("setting-item-control full-width-control");
    this.addFadeInput(controlEl);
    this.addBannerHeightInput(controlEl);
  }
  addYPositionInput(containerEl) {
    const label = containerEl.createEl("label", { text: "Y-Position", cls: "setting-item-name__label" });
    const sliderContainer = containerEl.createEl("div", { cls: "slider-container" });
    const slider = sliderContainer.createEl("input", {
      type: "range",
      cls: "slider",
      attr: {
        min: "0",
        max: "100",
        step: "1"
      }
    });
    slider.value = this.folderImage.yPosition || "50";
    slider.style.width = "100px";
    slider.style.marginLeft = "10px";
    const valueDisplay = sliderContainer.createEl("div", { cls: "slider-value" });
    valueDisplay.style.marginLeft = "10px";
    const updateValueDisplay = (value) => {
      valueDisplay.textContent = value;
    };
    updateValueDisplay(slider.value);
    slider.addEventListener("input", (event) => {
      updateValueDisplay(event.target.value);
    });
    slider.addEventListener("change", async () => {
      this.folderImage.yPosition = parseInt(slider.value);
      await this.plugin.saveSettings();
    });
    label.appendChild(sliderContainer);
    containerEl.appendChild(label);
  }
  addXPositionInput(containerEl) {
    const label = containerEl.createEl("label", { text: "X-Position", cls: "setting-item-name__label" });
    label.style.marginLeft = "20px";
    const sliderContainer = containerEl.createEl("div", { cls: "slider-container" });
    const slider = sliderContainer.createEl("input", {
      type: "range",
      cls: "slider",
      attr: {
        min: "0",
        max: "100",
        step: "1"
      }
    });
    slider.value = this.folderImage.xPosition || "50";
    slider.style.width = "100px";
    slider.style.marginLeft = "10px";
    const valueDisplay = sliderContainer.createEl("div", { cls: "slider-value" });
    valueDisplay.style.marginLeft = "10px";
    const updateValueDisplay = (value) => {
      valueDisplay.textContent = value;
    };
    updateValueDisplay(slider.value);
    slider.addEventListener("input", (event) => {
      updateValueDisplay(event.target.value);
    });
    slider.addEventListener("change", async () => {
      this.folderImage.xPosition = parseInt(slider.value);
      await this.plugin.saveSettings();
    });
    label.appendChild(sliderContainer);
    containerEl.appendChild(label);
  }
  addBannerHeightInput(containerEl) {
    const label = containerEl.createEl("label", { text: "Banner Height", cls: "setting-item-name__label" });
    label.style.marginLeft = "20px";
    const heightInput = containerEl.createEl("input", {
      type: "number",
      attr: {
        min: "0",
        max: "1280"
      }
    });
    heightInput.style.width = "50px";
    heightInput.style.marginLeft = "10px";
    heightInput.value = this.folderImage.bannerHeight || "";
    heightInput.placeholder = String(this.plugin.settings.bannerHeight || 350);
    heightInput.addEventListener("change", async () => {
      let value = heightInput.value ? parseInt(heightInput.value) : null;
      if (value !== null) {
        value = Math.max(0, Math.min(1280, value));
        this.folderImage.bannerHeight = value;
        heightInput.value = value;
      } else {
        delete this.folderImage.bannerHeight;
        heightInput.value = "";
      }
      await this.plugin.saveSettings();
    });
    label.appendChild(heightInput);
    containerEl.appendChild(label);
  }
  addFadeInput(containerEl) {
    const label = containerEl.createEl("label", { text: "Fade", cls: "setting-item-name__label" });
    const sliderContainer = containerEl.createEl("div", { cls: "slider-container" });
    const slider = sliderContainer.createEl("input", {
      type: "range",
      cls: "slider",
      attr: {
        min: "-1500",
        max: "100",
        step: "5"
      }
    });
    slider.value = this.folderImage.fade !== void 0 ? this.folderImage.fade : "-75";
    slider.style.width = "100px";
    slider.style.marginLeft = "10px";
    const valueDisplay = sliderContainer.createEl("div", { cls: "slider-value" });
    valueDisplay.style.marginLeft = "10px";
    const updateValueDisplay = (value) => {
      valueDisplay.textContent = value;
    };
    updateValueDisplay(slider.value);
    slider.addEventListener("input", (event) => {
      updateValueDisplay(event.target.value);
    });
    slider.addEventListener("change", async () => {
      this.folderImage.fade = parseInt(slider.value);
      await this.plugin.saveSettings();
    });
    label.appendChild(sliderContainer);
    containerEl.appendChild(label);
  }
  addColorSettings(containerEl) {
    const colorContainer = containerEl.createDiv("color-settings-container");
    new import_obsidian2.Setting(colorContainer).setName("Inline Title Color").addColorPicker((color) => color.setValue((() => {
      const currentColor = this.folderImage.titleColor || this.plugin.settings.titleColor;
      if (currentColor.startsWith("var(--")) {
        const temp = document.createElement("div");
        temp.style.color = currentColor;
        document.body.appendChild(temp);
        const computedColor = getComputedStyle(temp).color;
        document.body.removeChild(temp);
        const rgbMatch = computedColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
        if (rgbMatch) {
          const [_, r, g, b] = rgbMatch;
          const hexColor = "#" + parseInt(r).toString(16).padStart(2, "0") + parseInt(g).toString(16).padStart(2, "0") + parseInt(b).toString(16).padStart(2, "0");
          return hexColor;
        }
        return "#000000";
      }
      return currentColor;
    })()).onChange(async (value) => {
      this.folderImage.titleColor = value;
      await this.plugin.saveSettings();
    })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
      this.folderImage.titleColor = this.plugin.settings.titleColor;
      await this.plugin.saveSettings();
      const colorPickerEl = button.extraSettingsEl.parentElement.querySelector('input[type="color"]');
      if (colorPickerEl) {
        const currentColor = this.plugin.settings.titleColor;
        if (currentColor.startsWith("var(--")) {
          const temp = document.createElement("div");
          temp.style.color = currentColor;
          document.body.appendChild(temp);
          const computedColor = getComputedStyle(temp).color;
          document.body.removeChild(temp);
          const rgbMatch = computedColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
          if (rgbMatch) {
            const [_, r, g, b] = rgbMatch;
            const hexColor = "#" + parseInt(r).toString(16).padStart(2, "0") + parseInt(g).toString(16).padStart(2, "0") + parseInt(b).toString(16).padStart(2, "0");
            colorPickerEl.value = hexColor;
          }
        } else {
          colorPickerEl.value = currentColor;
        }
      }
    }));
  }
  addDirectChildrenOnlyToggle() {
    new import_obsidian2.Setting(this.settingEl).setName("Direct Children Only").setDesc("Apply banner only to direct children of the folder").addToggle((toggle) => {
      toggle.setValue(this.folderImage.directChildrenOnly || false).onChange(async (value) => {
        this.folderImage.directChildrenOnly = value;
        await this.plugin.saveSettings();
      });
    });
  }
  addContentStartInput(containerEl) {
    var _a;
    const label = containerEl.createEl("label", { text: "Content Start", cls: "setting-item-name__label" });
    label.style.marginRight = "20px";
    const contentStartInput = containerEl.createEl("input", {
      type: "number",
      attr: {
        min: "0"
      }
    });
    contentStartInput.style.width = "50px";
    contentStartInput.style.marginLeft = "10px";
    contentStartInput.value = (_a = this.folderImage.contentStartPosition) != null ? _a : "355";
    contentStartInput.addEventListener("change", async () => {
      this.folderImage.contentStartPosition = parseInt(contentStartInput.value);
      await this.plugin.saveSettings();
    });
    label.appendChild(contentStartInput);
    containerEl.appendChild(label);
  }
  addBorderRadiusInput(containerEl) {
    var _a;
    const label = containerEl.createEl("label", { text: "Border Radius", cls: "setting-item-name__label" });
    const radiusInput = containerEl.createEl("input", {
      type: "number",
      attr: {
        min: "0",
        max: "50"
      }
    });
    radiusInput.style.width = "50px";
    radiusInput.style.marginLeft = "10px";
    radiusInput.value = (_a = this.folderImage.borderRadius) != null ? _a : "";
    radiusInput.placeholder = String(this.plugin.settings.borderRadius || 17);
    radiusInput.addEventListener("change", async () => {
      let value = radiusInput.value ? parseInt(radiusInput.value) : null;
      if (value !== null) {
        value = Math.max(0, Math.min(50, value));
        this.folderImage.borderRadius = value;
        radiusInput.value = String(value);
      } else {
        delete this.folderImage.borderRadius;
        radiusInput.value = "";
      }
      await this.plugin.saveSettings();
    });
    label.appendChild(radiusInput);
    containerEl.appendChild(label);
  }
  addBannerIconSettings() {
    const controlEl1 = this.settingEl.createDiv("setting-item-control full-width-control");
    new import_obsidian2.Setting(controlEl1).setName("Icon Size").addSlider((slider) => slider.setLimits(10, 200, 1).setValue(this.folderImage.bannerIconSize || this.plugin.settings.bannerIconSize).setDynamicTooltip().onChange(async (value) => {
      this.folderImage.bannerIconSize = value;
      await this.plugin.saveSettings();
    }));
    new import_obsidian2.Setting(controlEl1).setName("Icon X Position").addSlider((slider) => slider.setLimits(0, 100, 1).setValue(this.folderImage.bannerIconXPosition || this.plugin.settings.bannerIconXPosition).setDynamicTooltip().onChange(async (value) => {
      this.folderImage.bannerIconXPosition = value;
      await this.plugin.saveSettings();
    }));
    const controlEl2 = this.settingEl.createDiv("setting-item-control full-width-control");
    new import_obsidian2.Setting(controlEl2).setName("Icon Opacity").addSlider((slider) => slider.setLimits(0, 100, 1).setValue(this.folderImage.bannerIconOpacity || this.plugin.settings.bannerIconOpacity).setDynamicTooltip().onChange(async (value) => {
      this.folderImage.bannerIconOpacity = value;
      await this.plugin.saveSettings();
    }));
    new import_obsidian2.Setting(controlEl2).setName("Icon Color").addText((text) => {
      text.setPlaceholder("(e.g., #ffffff or white)").setValue(this.folderImage.bannerIconColor || this.plugin.settings.bannerIconColor).onChange(async (value) => {
        this.folderImage.bannerIconColor = value;
        await this.plugin.saveSettings();
      });
      text.inputEl.style.width = "160px";
    });
    const controlEl3 = this.settingEl.createDiv("setting-item-control full-width-control");
    new import_obsidian2.Setting(controlEl3).setName("Icon Font Weight").addDropdown((dropdown) => {
      dropdown.addOption("lighter", "Lighter").addOption("normal", "Normal").addOption("bold", "Bold").setValue(this.folderImage.bannerIconFontWeight || this.plugin.settings.bannerIconFontWeight).onChange(async (value) => {
        this.folderImage.bannerIconFontWeight = value;
        await this.plugin.saveSettings();
      });
    });
    new import_obsidian2.Setting(controlEl3).setName("Icon BG Color").addText((text) => {
      text.setPlaceholder("(e.g., #ffffff or transparent)").setValue(this.folderImage.bannerIconBackgroundColor || this.plugin.settings.bannerIconBackgroundColor).onChange(async (value) => {
        this.folderImage.bannerIconBackgroundColor = value;
        await this.plugin.saveSettings();
      });
      text.inputEl.style.width = "160px";
    });
    const controlEl4 = this.settingEl.createDiv("setting-item-control full-width-control");
    new import_obsidian2.Setting(controlEl4).setName("Icon Padding X").addSlider((slider) => slider.setLimits(0, 100, 1).setValue(this.folderImage.bannerIconPaddingX || this.plugin.settings.bannerIconPaddingX).setDynamicTooltip().onChange(async (value) => {
      this.folderImage.bannerIconPaddingX = value;
      await this.plugin.saveSettings();
    }));
    new import_obsidian2.Setting(controlEl4).setName("Icon Padding Y").addSlider((slider) => slider.setLimits(0, 100, 1).setValue(this.folderImage.bannerIconPaddingY || this.plugin.settings.bannerIconPaddingY).setDynamicTooltip().onChange(async (value) => {
      this.folderImage.bannerIconPaddingY = value;
      await this.plugin.saveSettings();
    }));
    const controlEl5 = this.settingEl.createDiv("setting-item-control full-width-control");
    new import_obsidian2.Setting(controlEl5).setName("Icon Border Radius").addSlider((slider) => slider.setLimits(0, 50, 1).setValue(this.folderImage.bannerIconBorderRadius || this.plugin.settings.bannerIconBorderRadius).setDynamicTooltip().onChange(async (value) => {
      this.folderImage.bannerIconBorderRadius = value;
      await this.plugin.saveSettings();
    }));
    new import_obsidian2.Setting(controlEl5).setName("Icon Vertical Offset").addSlider((slider) => slider.setLimits(-100, 100, 1).setValue(this.folderImage.bannerIconVerticalOffset || this.plugin.settings.bannerIconVerticalOffset).setDynamicTooltip().onChange(async (value) => {
      this.folderImage.bannerIconVerticalOffset = value;
      await this.plugin.saveSettings();
    }));
  }
};

// src/settings/tabs/settingsTabCustomFieldNames.js
var import_obsidian3 = require("obsidian");
function arrayToString(arr) {
  return Array.isArray(arr) ? arr.join(", ") : arr;
}
function stringToArray(str) {
  return str.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
}
function validateFieldNames(settings, allFields, currentField, newNames) {
  const validNamePattern = /^[a-zA-Z0-9_-]+$/;
  const invalidNames = newNames.filter((name) => !validNamePattern.test(name));
  if (invalidNames.length > 0) {
    return {
      isValid: false,
      message: `Invalid characters in field names (only letters, numbers, dashes, and underscores allowed): ${invalidNames.join(", ")}`
    };
  }
  const otherFields = allFields.filter((f) => f !== currentField);
  const otherFieldNames = otherFields.flatMap((f) => settings[f]);
  const duplicates = newNames.filter((name) => otherFieldNames.includes(name));
  if (duplicates.length > 0) {
    return {
      isValid: false,
      message: `Duplicate field names found: ${duplicates.join(", ")}`
    };
  }
  return { isValid: true };
}
function createCustomFieldsSettings(containerEl, plugin) {
  const calloutEl = containerEl.createEl("div", { cls: "tab-callout" });
  calloutEl.createEl("div", { text: '\u{1F5FA}\uFE0F Customize the frontmatter field names used for Pixel Banner. You can define multiple names for each field, separated by commas. Field names can only contain letters, numbers, dashes, and underscores. Example: "banner, pixel-banner, header_image" could all be used as the banner field name.' });
  const customFields = [
    {
      setting: "customBannerField",
      name: "Banner Field Names",
      desc: "Set custom field names for the banner in frontmatter",
      values: '[[image.png]], "images/image.jpg"',
      placeholder: "banner, pixel-banner, header-image"
    },
    {
      setting: "customYPositionField",
      name: "Y-Position Field Names",
      desc: "Set custom field names for the Y-position in frontmatter",
      values: "5, 70, 100",
      placeholder: "banner-y, y-position, banner-offset"
    },
    {
      setting: "customXPositionField",
      name: "X-Position Field Names",
      desc: "Set custom field names for the X-position in frontmatter",
      values: "0, 30, 90",
      placeholder: "banner-x, x-position, banner-offset-x"
    },
    {
      setting: "customContentStartField",
      name: "Content Start Position Field Names",
      desc: "Set custom field names for the content start position in frontmatter",
      values: "75, 150, 450",
      placeholder: "content-start, start-position, content-offset"
    },
    {
      setting: "customImageDisplayField",
      name: "Image Display Field Names",
      desc: "Set custom field names for the image display in frontmatter",
      values: "cover, contain, auto, 200%, 70%",
      placeholder: "banner-display, image-display, display-mode"
    },
    {
      setting: "customImageRepeatField",
      name: "Image Repeat Field Names",
      desc: "Set custom field names for the image repeat in frontmatter",
      values: "true, false",
      placeholder: "banner-repeat, image-repeat, repeat"
    },
    {
      setting: "customBannerMaxWidthField",
      name: "Banner Max Width Field Names",
      desc: "Set custom field names for the banner maximum width in frontmatter",
      values: "800px, 100%, 1200px",
      placeholder: "banner-max-width, max-width, banner-width"
    },
    {
      setting: "customBannerAlignmentField",
      name: "Banner Alignment Field Names",
      desc: "Set custom field names for the banner alignment in frontmatter",
      values: "left, center, right",
      placeholder: "banner-alignment"
    },
    {
      setting: "customBannerHeightField",
      name: "Banner Height Field Names",
      desc: "Set custom field names for the banner height in frontmatter",
      values: "150, 350, 500",
      placeholder: "banner-height, height, banner-size"
    },
    {
      setting: "customFadeField",
      name: "Fade Field Names",
      desc: "Set custom field names for the fade in frontmatter",
      values: "-300, -50, 0, 100",
      placeholder: "banner-fade, fade, fade-amount"
    },
    {
      setting: "customBorderRadiusField",
      name: "Border Radius Field Names",
      desc: "Set custom field names for the border radius in frontmatter",
      values: "0, 17, 25",
      placeholder: "banner-radius, radius, border-radius"
    },
    {
      setting: "customTitleColorField",
      name: "Title Color Field Names",
      desc: "Set custom field names for the title color in frontmatter",
      values: "#ffffff, white, var(--text-normal)",
      placeholder: "banner-title-color, title-color, inline-title-color"
    },
    {
      setting: "customBannerShuffleField",
      name: "Banner Shuffle Field Names",
      desc: "Set custom field names for the banner shuffle in frontmatter",
      values: "true, false",
      placeholder: "banner-shuffle, shuffle, random-banner"
    },
    {
      setting: "customFlagColorField",
      name: "Pixel Banner Flag Color Field Names",
      desc: "Set custom field names for the pixel banner flag color in frontmatter",
      values: "red, blue, green, orange, purple, yellow",
      placeholder: "pixel-banner-flag-color, banner-flag-color, flag-color"
    },
    {
      setting: "customBannerIconField",
      name: "Banner Icon Field Names",
      desc: "Set custom field names for the banner icon in frontmatter",
      values: "\u{1F31F}, \u{1F3A8}, \u{1F4DD}",
      placeholder: "banner-icon, icon, header-icon"
    },
    {
      setting: "customBannerIconImageField",
      name: "Banner Icon Image Field Names",
      desc: "Set custom field names for the banner icon image in frontmatter",
      values: '[[image.png]], "images/icon.jpg"',
      placeholder: "banner-icon-image, icon-image"
    },
    {
      setting: "customBannerIconSizeField",
      name: "Banner Icon Size Field Names",
      desc: "Set custom field names for the banner icon size in frontmatter",
      values: "50, 70, 100",
      placeholder: "banner-icon-size, icon-size"
    },
    {
      setting: "customBannerIconImageSizeMultiplierField",
      name: "Banner Icon Image Size Multiplier Field Names",
      desc: "Set custom field names for the banner icon image size multiplier in frontmatter",
      values: ".5, 1.5, 2",
      placeholder: "banner-icon-image-size-multiplier, icon-image-size-multiplier"
    },
    {
      setting: "customBannerIconTextVerticalOffsetField",
      name: "Banner Icon Text Vertical Offset Field Names",
      desc: "Set custom field names for the banner icon text vertical offset in frontmatter",
      values: "-10, 0, 10",
      placeholder: "banner-icon-text-vertical-offset, icon-text-vertical-offset"
    },
    {
      setting: "customBannerIconRotateField",
      name: "Banner Icon Rotate Field Names",
      desc: "Set custom field names for the banner icon rotate in frontmatter",
      values: "50, 70, 100",
      placeholder: "banner-icon-rotate, icon-rotate"
    },
    {
      setting: "customBannerIconXPositionField",
      name: "Banner Icon X Position Field Names",
      desc: "Set custom field names for the banner icon X position in frontmatter",
      values: "25, 50, 75",
      placeholder: "banner-icon-x, icon-x"
    },
    {
      setting: "customBannerIconOpacityField",
      name: "Banner Icon Opacity Field Names",
      desc: "Set custom field names for the banner icon opacity in frontmatter",
      values: "50, 75, 100",
      placeholder: "banner-icon-opacity, icon-opacity"
    },
    {
      setting: "customBannerIconColorField",
      name: "Banner Icon Color Field Names",
      desc: "Set custom field names for the banner icon color in frontmatter",
      values: "#ffffff, white, var(--text-normal)",
      placeholder: "banner-icon-color, icon-color"
    },
    {
      setting: "customBannerIconFontWeightField",
      name: "Banner Icon Font Weight Field Names",
      desc: "Set custom field names for the banner icon font weight in frontmatter",
      values: "lighter, normal, bold",
      placeholder: "banner-icon-font-weight, icon-font-weight"
    },
    {
      setting: "customBannerIconBackgroundColorField",
      name: "Banner Icon Background Color Field Names",
      desc: "Set custom field names for the banner icon background color in frontmatter",
      values: "#000000, black, transparent",
      placeholder: "banner-icon-bg-color, icon-bg-color"
    },
    {
      setting: "customBannerIconPaddingXField",
      name: "Banner Icon Padding X Field Names",
      desc: "Set custom field names for the banner icon padding X in frontmatter",
      values: "0, 10, 20",
      placeholder: "banner-icon-padding-x, icon-padding-x"
    },
    {
      setting: "customBannerIconPaddingYField",
      name: "Banner Icon Padding Y Field Names",
      desc: "Set custom field names for the banner icon padding Y in frontmatter",
      values: "0, 10, 20",
      placeholder: "banner-icon-padding-y, icon-padding-y"
    },
    {
      setting: "customBannerIconBorderRadiusField",
      name: "Banner Icon Border Radius Field Names",
      desc: "Set custom field names for the banner icon border radius in frontmatter",
      values: "0, 17, 25",
      placeholder: "banner-icon-border-radius, icon-border-radius"
    },
    {
      setting: "customBannerIconVerticalOffsetField",
      name: "Banner Icon Vertical Offset Field Names",
      desc: "Set custom field names for the banner icon vertical offset in frontmatter",
      values: "-50, 0, 50",
      placeholder: "banner-icon-y, icon-y"
    },
    {
      setting: "customBannerIconImageAlignmentField",
      name: "Banner Icon Image Alignment Field Names",
      desc: "Set custom field names for the banner icon image alignment in frontmatter",
      values: "left, right",
      placeholder: "banner-icon-image-alignment, icon-image-alignment"
    }
  ];
  customFields.forEach((field) => {
    new import_obsidian3.Setting(containerEl).setName(field.name).setDesc(createFragment((el) => {
      el.createEl("div", { text: field.desc });
      el.createEl("div", { cls: "setting-item-example" }).innerHTML = `Example frontmatter values: <code>${field.values}</code>`;
    })).addText((text) => {
      text.setPlaceholder(field.placeholder).setValue(arrayToString(plugin.settings[field.setting])).onChange(async (value) => {
        const newNames = stringToArray(value);
        const allFields = customFields.map((f) => f.setting);
        const validation = validateFieldNames(plugin.settings, allFields, field.setting, newNames);
        if (!validation.isValid) {
          text.inputEl.addClass("is-invalid");
          text.inputEl.title = validation.message;
          return;
        }
        text.inputEl.removeClass("is-invalid");
        text.inputEl.title = "";
        plugin.settings[field.setting] = newNames;
        await plugin.saveSettings();
      });
      text.inputEl.style.width = "300px";
    }).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
      plugin.settings[field.setting] = DEFAULT_SETTINGS[field.setting];
      await plugin.saveSettings();
      const settingEl = button.extraSettingsEl.parentElement;
      const textInput = settingEl.querySelector('input[type="text"]');
      textInput.value = arrayToString(DEFAULT_SETTINGS[field.setting]);
      const event = new Event("input", { bubbles: true, cancelable: true });
      textInput.dispatchEvent(event);
    }));
  });
}

// src/settings/tabs/settingsTabGeneral.js
var import_obsidian4 = require("obsidian");
init_flags();
init_semver();
function addUpdateButtonIfNeeded(containerEl, plugin, insertAfterCallout = false) {
  if (!plugin.pixelBannerVersion) {
    console.log("[Pixel Banner] No cloud version available, skipping update button");
    return;
  }
  const cloudVersion = plugin.pixelBannerVersion;
  const currentVersion = plugin.settings.lastVersion;
  const isCloudVersionGreater = semver.gt(cloudVersion, currentVersion);
  if (isCloudVersionGreater) {
    if (containerEl.querySelector(".pixel-banner-update-button")) {
      return;
    }
    const updateContainer = document.createElement("div");
    updateContainer.style.cssText = `
            display: flex;
            justify-content: flex-end;
            margin-top: 15px;
        `;
    const updateButton = document.createElement("button");
    updateButton.textContent = "\u{1F504} Update Available!";
    updateButton.className = "pixel-banner-scale-up-down-animation pixel-banner-update-button";
    updateButton.style.cssText = `
            padding: 6px 12px;
            background-color: var(--interactive-accent);
            color: var(--text-on-accent);
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-weight: 500;
        `;
    updateContainer.appendChild(updateButton);
    const calloutEl = containerEl.querySelector(".tab-callout");
    if (calloutEl && calloutEl.nextSibling) {
      calloutEl.parentNode.insertBefore(updateContainer, calloutEl.nextSibling);
    } else {
      containerEl.appendChild(updateContainer);
    }
    updateButton.addEventListener("click", async () => {
      await plugin.app.setting.open();
      await new Promise((resolve) => setTimeout(resolve, 300));
      const settingsTabs = document.querySelectorAll(".vertical-tab-header-group .vertical-tab-nav-item");
      for (const tab of settingsTabs) {
        if (tab.textContent.includes("Community plugins")) {
          tab.click();
          break;
        }
      }
      await new Promise((resolve) => setTimeout(resolve, 500));
      const allTheButtons = document.querySelectorAll("button.mod-cta");
      for (const button of allTheButtons) {
        if (button.textContent.includes("Check for updates")) {
          button.click();
          break;
        }
      }
    });
  }
}
function createGeneralSettings(containerEl, plugin) {
  const calloutEl = containerEl.createEl("div", { cls: "tab-callout margin-bottom-0" });
  calloutEl.createEl("div", { text: `v${plugin.settings.lastVersion} \u22C5 Configure default settings for all notes.` });
  if (!plugin.pixelBannerVersion) {
    plugin.getPixelBannerInfo().then(() => {
      addUpdateButtonIfNeeded(containerEl, plugin);
    }).catch((error) => {
      console.log("[Pixel Banner] Failed to fetch version info:", error.message);
    });
  } else if (!plugin.pixelBannerVersion) {
    console.log("[Pixel Banner] Version not available, skipping version check");
  } else {
    addUpdateButtonIfNeeded(containerEl, plugin);
  }
  const SelectImageSettingsGroup = containerEl.createDiv({ cls: "setting-group" });
  const showSelectImageIconSetting = new import_obsidian4.Setting(SelectImageSettingsGroup).setName("Show Pixel Banner Flag").setDesc("Show the banner selector icon in the top-left corner of notes").addToggle((toggle) => toggle.setValue(plugin.settings.showSelectImageIcon).onChange(async (value) => {
    try {
      plugin.settings.showSelectImageIcon = value;
      await plugin.saveSettings();
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.showSelectImageIcon = DEFAULT_SETTINGS.showSelectImageIcon;
      await plugin.saveSettings();
      const toggleComponent = showSelectImageIconSetting.components[0];
      if (toggleComponent) {
        toggleComponent.setValue(DEFAULT_SETTINGS.showSelectImageIcon);
      }
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const selectImageIconOpacitySetting = new import_obsidian4.Setting(SelectImageSettingsGroup).setName("Pixel Banner Flag Opacity").setDesc("Set the opacity of the banner selector icon in the top-left corner (0-100)").addSlider((slider) => slider.setLimits(0, 100, 1).setValue(plugin.settings.selectImageIconOpacity).setDynamicTooltip().onChange(async (value) => {
    try {
      plugin.settings.selectImageIconOpacity = value;
      await plugin.saveSettings();
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.selectImageIconOpacity = DEFAULT_SETTINGS.selectImageIconOpacity;
      await plugin.saveSettings();
      const sliderEl = button.extraSettingsEl.parentElement.querySelector(".slider");
      sliderEl.value = DEFAULT_SETTINGS.selectImageIconOpacity;
      sliderEl.dispatchEvent(new Event("input"));
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const selectImageIconFlagSetting = new import_obsidian4.Setting(SelectImageSettingsGroup).setName("Select Pixel Banner Flag Color").setDesc("Choose which flag color to use for the banner selector");
  const flagRadioContainer = selectImageIconFlagSetting.controlEl.createDiv({
    cls: "pixel-banner-flag-radio-container",
    attr: {
      style: `
                max-width: 600px;
            `
    }
  });
  flagRadioContainer.style.display = "flex";
  flagRadioContainer.style.flexWrap = "wrap";
  flagRadioContainer.style.gap = "10px";
  Object.keys(flags).forEach((color) => {
    const radioContainer = flagRadioContainer.createDiv({
      cls: "pixel-banner-flag-radio"
    });
    const radio = radioContainer.createEl("input", {
      type: "radio",
      attr: {
        id: `flag-${color}`,
        name: "pixel-banner-flag",
        value: color
      }
    });
    radio.checked = plugin.settings.selectImageIconFlag === color;
    radio.addEventListener("change", async () => {
      if (radio.checked) {
        try {
          plugin.settings.selectImageIconFlag = color;
          await plugin.saveSettings();
          plugin.updateAllBanners();
        } catch (error) {
          console.error("Failed to save settings:", error);
        }
      }
    });
    const label = radioContainer.createEl("label", {
      attr: {
        for: `flag-${color}`
      }
    });
    const img = label.createEl("img", {
      attr: {
        src: flags[color],
        alt: `${color} flag`
      }
    });
    img.style.width = "20px";
    img.style.height = "25px";
    img.style.verticalAlign = "middle";
    img.style.marginLeft = "5px";
  });
  selectImageIconFlagSetting.addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.selectImageIconFlag = DEFAULT_SETTINGS.selectImageIconFlag;
      await plugin.saveSettings();
      const radios = selectImageIconFlagSetting.controlEl.querySelectorAll('input[type="radio"]');
      radios.forEach((radio) => {
        radio.checked = radio.value === DEFAULT_SETTINGS.selectImageIconFlag;
      });
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const defaultSavedBannersFolderSetting = new import_obsidian4.Setting(SelectImageSettingsGroup).setName("Default Saved Banners Folder").setDesc("Default folder where Banners will be saved").addText((text) => {
    text.setPlaceholder("pixel-banner-images").setValue(plugin.settings.pinnedImageFolder).onChange(async (value) => {
      try {
        plugin.settings.pinnedImageFolder = value;
        await plugin.saveSettings();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    });
    text.inputEl.addEventListener("blur", async (event) => {
      let value = text.inputEl.value.trim();
      if (!value) {
        value = "pixel-banner-images";
      }
      text.setValue(value);
      plugin.settings.pinnedImageFolder = value;
      try {
        await plugin.saveSettings();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    });
    return text;
  }).addButton((button) => button.setButtonText("Browse").onClick(() => {
    new FolderSuggestModal(plugin.app, (chosenPath) => {
      plugin.settings.pinnedImageFolder = chosenPath;
      const textInput = defaultSavedBannersFolderSetting.components[0];
      if (textInput) {
        textInput.setValue(chosenPath);
      }
      plugin.saveSettings();
    }).open();
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.pinnedImageFolder = DEFAULT_SETTINGS.pinnedImageFolder;
      await plugin.saveSettings();
      const textComponent = defaultSavedBannersFolderSetting.components[0];
      if (textComponent) {
        textComponent.setValue(DEFAULT_SETTINGS.pinnedImageFolder);
      }
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const defaultSelectImagePathSetting = new import_obsidian4.Setting(SelectImageSettingsGroup).setName("Default Select Image Path").setDesc("Set a default folder path to filter images when opening the Select Image modal").addText((text) => {
    text.setPlaceholder("Example: Images/Banners").setValue(plugin.settings.defaultSelectImagePath).onChange(async (value) => {
      try {
        plugin.settings.defaultSelectImagePath = value;
        await plugin.saveSettings();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    });
    text.inputEl.style.width = "200px";
    return text;
  }).addButton((button) => button.setButtonText("Browse").onClick(() => {
    new FolderSuggestModal(plugin.app, (chosenPath) => {
      plugin.settings.defaultSelectImagePath = chosenPath;
      const textInput = defaultSelectImagePathSetting.components[0];
      if (textInput) {
        textInput.setValue(chosenPath);
      }
      plugin.saveSettings();
    }).open();
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.defaultSelectImagePath = DEFAULT_SETTINGS.defaultSelectImagePath;
      await plugin.saveSettings();
      const textComponent = defaultSelectImagePathSetting.components[0];
      if (textComponent) {
        textComponent.setValue(DEFAULT_SETTINGS.defaultSelectImagePath);
      }
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const defaultSelectIconPathSetting = new import_obsidian4.Setting(SelectImageSettingsGroup).setName("Default Select Icon Path").setDesc("Set a default folder path to filter images when selecting a banner icon image").addText((text) => {
    text.setPlaceholder("Example: Images/Icons").setValue(plugin.settings.defaultSelectIconPath).onChange(async (value) => {
      try {
        plugin.settings.defaultSelectIconPath = value;
        await plugin.saveSettings();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    });
    text.inputEl.style.width = "200px";
    return text;
  }).addButton((button) => button.setButtonText("Browse").onClick(() => {
    new FolderSuggestModal(plugin.app, (chosenPath) => {
      plugin.settings.defaultSelectIconPath = chosenPath;
      const textInput = defaultSelectIconPathSetting.components[0];
      if (textInput) {
        textInput.setValue(chosenPath);
      }
      plugin.saveSettings();
    }).open();
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.defaultSelectIconPath = DEFAULT_SETTINGS.defaultSelectIconPath;
      await plugin.saveSettings();
      const textComponent = defaultSelectIconPathSetting.components[0];
      if (textComponent) {
        textComponent.setValue(DEFAULT_SETTINGS.defaultSelectIconPath);
      }
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const openTargetingModalSetting = new import_obsidian4.Setting(SelectImageSettingsGroup).setName("Open Targeting Modal after selecting a Banner or Icon").setDesc("Automatically open the Targeting Modal after selecting a banner image or icon").addToggle((toggle) => toggle.setValue(plugin.settings.openTargetingModalAfterSelectingBannerOrIcon).onChange(async (value) => {
    try {
      plugin.settings.openTargetingModalAfterSelectingBannerOrIcon = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.openTargetingModalAfterSelectingBannerOrIcon = DEFAULT_SETTINGS.openTargetingModalAfterSelectingBannerOrIcon;
      await plugin.saveSettings();
      const toggleComponent = openTargetingModalSetting.components[0];
      if (toggleComponent) {
        toggleComponent.setValue(DEFAULT_SETTINGS.openTargetingModalAfterSelectingBannerOrIcon);
      }
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Banner Max Width").setDesc("Set the maximum width for banner images (100-2560 pixels)").addSlider((slider) => slider.setLimits(100, 2560, 10).setValue(plugin.settings.bannerMaxWidth).setDynamicTooltip().onChange(async (value) => {
    try {
      plugin.settings.bannerMaxWidth = value;
      await plugin.saveSettings();
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerMaxWidth = DEFAULT_SETTINGS.bannerMaxWidth;
      await plugin.saveSettings();
      const sliderInput = button.extraSettingsEl.parentElement.querySelector('input[type="range"]');
      sliderInput.value = DEFAULT_SETTINGS.bannerMaxWidth;
      const event = new Event("input", { bubbles: true, cancelable: true });
      sliderInput.dispatchEvent(event);
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Image Horizontal Position").setDesc("Set the horizontal position of the image (0-100)").addSlider(
    (slider) => slider.setLimits(0, 100, 1).setValue(plugin.settings.xPosition).setDynamicTooltip().onChange(async (value) => {
      try {
        plugin.settings.xPosition = value;
        await plugin.saveSettings();
        plugin.updateAllBanners();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    })
  ).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.xPosition = DEFAULT_SETTINGS.xPosition;
      await plugin.saveSettings();
      plugin.updateAllBanners();
      const sliderEl = button.extraSettingsEl.parentElement.querySelector(".slider");
      sliderEl.value = DEFAULT_SETTINGS.xPosition;
      sliderEl.dispatchEvent(new Event("input"));
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Image Vertical Position").setDesc("Set the vertical position of the image (0-100)").addSlider(
    (slider) => slider.setLimits(0, 100, 1).setValue(plugin.settings.yPosition).setDynamicTooltip().onChange(async (value) => {
      try {
        plugin.settings.yPosition = value;
        await plugin.saveSettings();
        plugin.updateAllBanners();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    })
  ).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.yPosition = DEFAULT_SETTINGS.yPosition;
      await plugin.saveSettings();
      plugin.updateAllBanners();
      const sliderEl = button.extraSettingsEl.parentElement.querySelector(".slider");
      sliderEl.value = DEFAULT_SETTINGS.yPosition;
      sliderEl.dispatchEvent(new Event("input"));
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Content Start Position").setDesc("Set the default vertical position where the content starts (in pixels)").addText((text) => text.setPlaceholder("150").setValue(String(plugin.settings.contentStartPosition)).onChange(async (value) => {
    try {
      const numValue = Number(value);
      if (!isNaN(numValue) && numValue >= 0) {
        plugin.settings.contentStartPosition = numValue;
        await plugin.saveSettings();
        plugin.updateAllBanners();
      }
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).then((setting) => {
    const inputEl = setting.controlEl.querySelector("input");
    inputEl.type = "number";
    inputEl.min = "0";
    inputEl.style.width = "60px";
  }).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.contentStartPosition = DEFAULT_SETTINGS.contentStartPosition;
      await plugin.saveSettings();
      plugin.updateAllBanners();
      const inputEl = button.extraSettingsEl.parentElement.querySelector("input");
      inputEl.value = DEFAULT_SETTINGS.contentStartPosition;
      inputEl.dispatchEvent(new Event("input"));
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Image Display").setDesc("Set how the banner image should be displayed").addDropdown((dropdown) => {
    dropdown.addOption("auto", "Auto").addOption("cover", "Cover").addOption("contain", "Contain").setValue(plugin.settings.imageDisplay || "cover").onChange(async (value) => {
      try {
        plugin.settings.imageDisplay = value;
        await plugin.saveSettings();
        plugin.updateAllBanners();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    });
    return dropdown;
  }).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.imageDisplay = DEFAULT_SETTINGS.imageDisplay;
      await plugin.saveSettings();
      const dropdownEl = button.extraSettingsEl.parentElement.querySelector("select");
      dropdownEl.value = DEFAULT_SETTINGS.imageDisplay;
      dropdownEl.dispatchEvent(new Event("change"));
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Image Repeat").setDesc('Enable image repetition when "Contain" is selected').addToggle((toggle) => {
    toggle.setValue(plugin.settings.imageRepeat).onChange(async (value) => {
      try {
        plugin.settings.imageRepeat = value;
        await plugin.saveSettings();
        plugin.updateAllBanners();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    });
    return toggle;
  }).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.imageRepeat = DEFAULT_SETTINGS.imageRepeat;
      await plugin.saveSettings();
      plugin.updateAllBanners();
      const checkboxContainer = button.extraSettingsEl.parentElement.querySelector(".checkbox-container");
      const toggleEl = checkboxContainer.querySelector("input");
      if (toggleEl) {
        toggleEl.checked = DEFAULT_SETTINGS.imageRepeat;
        checkboxContainer.classList.toggle("is-enabled", DEFAULT_SETTINGS.imageRepeat);
        const event = new Event("change", { bubbles: true });
        toggleEl.dispatchEvent(event);
      }
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Banner Height").setDesc("Set the default height of the banner image (0-1280 pixels)").addText((text) => {
    text.setPlaceholder("350").setValue(String(plugin.settings.bannerHeight)).onChange(async (value) => {
      try {
        if (value === "" || !isNaN(Number(value))) {
          await plugin.saveSettings();
        }
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    });
    text.inputEl.addEventListener("blur", async (event) => {
      try {
        let numValue = Number(event.target.value);
        if (isNaN(numValue) || event.target.value === "") {
          numValue = 350;
        } else {
          numValue = Math.max(0, Math.min(1280, numValue));
        }
        plugin.settings.bannerHeight = numValue;
        text.setValue(String(numValue));
        await plugin.saveSettings();
        plugin.updateAllBanners();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    });
    text.inputEl.type = "number";
    text.inputEl.min = "0";
    text.inputEl.max = "1280";
    text.inputEl.style.width = "50px";
  }).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerHeight = DEFAULT_SETTINGS.bannerHeight;
      await plugin.saveSettings();
      plugin.updateAllBanners();
      const inputEl = button.extraSettingsEl.parentElement.querySelector("input");
      inputEl.value = DEFAULT_SETTINGS.bannerHeight;
      inputEl.dispatchEvent(new Event("input"));
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Banner Fade").setDesc("Set the default fade effect for the banner image (-300 to 100)").addSlider(
    (slider) => slider.setLimits(-300, 100, 5).setValue(plugin.settings.fade).setDynamicTooltip().onChange(async (value) => {
      try {
        plugin.settings.fade = value;
        await plugin.saveSettings();
        plugin.updateAllBanners();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    })
  ).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.fade = DEFAULT_SETTINGS.fade;
      await plugin.saveSettings();
      plugin.updateAllBanners();
      const sliderEl = button.extraSettingsEl.parentElement.querySelector(".slider");
      sliderEl.value = DEFAULT_SETTINGS.fade;
      sliderEl.dispatchEvent(new Event("input"));
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Banner Fade In Animation Duration").setDesc("Set the default fade in animation duration for the banner image (0-1000 milliseconds)").addSlider(
    (slider) => slider.setLimits(0, 1e3, 1).setValue(plugin.settings.bannerFadeInAnimationDuration).setDynamicTooltip().onChange(async (value) => {
      try {
        plugin.settings.bannerFadeInAnimationDuration = value;
        await plugin.saveSettings();
        plugin.updateAllBanners();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    })
  ).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerFadeInAnimationDuration = DEFAULT_SETTINGS.bannerFadeInAnimationDuration;
      await plugin.saveSettings();
      plugin.updateAllBanners();
      const sliderEl = button.extraSettingsEl.parentElement.querySelector(".slider");
      sliderEl.value = DEFAULT_SETTINGS.bannerFadeInAnimationDuration;
      sliderEl.dispatchEvent(new Event("input"));
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Border Radius").setDesc("Set the default border radius of the banner image (0-50 pixels)").addSlider((slider) => slider.setLimits(0, 50, 1).setValue(plugin.settings.borderRadius).setDynamicTooltip().onChange(async (value) => {
    try {
      plugin.settings.borderRadius = value;
      await plugin.saveSettings();
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.borderRadius = DEFAULT_SETTINGS.borderRadius;
      await plugin.saveSettings();
      plugin.updateAllBanners();
      const sliderEl = button.extraSettingsEl.parentElement.querySelector(".slider");
      sliderEl.value = DEFAULT_SETTINGS.borderRadius;
      sliderEl.dispatchEvent(new Event("input"));
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Banner Gap").setDesc("Set the gap between the banner and the window edges (0-50 pixels)").addSlider(
    (slider) => slider.setLimits(0, 50, 1).setValue(plugin.settings.bannerGap).setDynamicTooltip().onChange(async (value) => {
      try {
        plugin.settings.bannerGap = value;
        await plugin.saveSettings();
        plugin.updateAllBanners();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    })
  ).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerGap = DEFAULT_SETTINGS.bannerGap;
      await plugin.saveSettings();
      plugin.updateAllBanners();
      const sliderEl = button.extraSettingsEl.parentElement.querySelector(".slider");
      sliderEl.value = DEFAULT_SETTINGS.bannerGap;
      sliderEl.dispatchEvent(new Event("input"));
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Inline Title Color").setDesc("Set the default inline title color for all banners").addColorPicker((color) => color.setValue((() => {
    const currentColor = plugin.settings.titleColor;
    if (currentColor && currentColor.startsWith("var(--")) {
      const temp = document.createElement("div");
      temp.style.color = currentColor;
      document.body.appendChild(temp);
      const computedColor = getComputedStyle(temp).color;
      document.body.removeChild(temp);
      const rgbMatch = computedColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
      if (rgbMatch) {
        const [_, r, g, b] = rgbMatch;
        const hexColor = "#" + parseInt(r).toString(16).padStart(2, "0") + parseInt(g).toString(16).padStart(2, "0") + parseInt(b).toString(16).padStart(2, "0");
        return hexColor;
      }
      return "#000000";
    }
    return currentColor || "#000000";
  })()).onChange(async (value) => {
    try {
      plugin.settings.titleColor = value;
      await plugin.saveSettings();
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.titleColor = DEFAULT_SETTINGS.titleColor;
      await plugin.saveSettings();
      const colorPickerEl = button.extraSettingsEl.parentElement.querySelector('input[type="color"]');
      if (colorPickerEl) {
        const temp = document.createElement("div");
        temp.style.color = DEFAULT_SETTINGS.titleColor;
        document.body.appendChild(temp);
        const computedColor = getComputedStyle(temp).color;
        document.body.removeChild(temp);
        const rgbMatch = computedColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
        if (rgbMatch) {
          const [_, r, g, b] = rgbMatch;
          const hexColor = "#" + parseInt(r).toString(16).padStart(2, "0") + parseInt(g).toString(16).padStart(2, "0") + parseInt(b).toString(16).padStart(2, "0");
          colorPickerEl.value = hexColor;
        }
      }
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const hideEmbeddedNoteTitlesSetting = new import_obsidian4.Setting(containerEl).setName("Hide Embedded Note Titles").setDesc(`Hide titles of embedded notes if Obsidian's "Show inline title" setting is enabled`).addToggle((toggle) => toggle.setValue(plugin.settings.hideEmbeddedNoteTitles).onChange(async (value) => {
    try {
      plugin.settings.hideEmbeddedNoteTitles = value;
      await plugin.saveSettings();
      plugin.updateEmbeddedTitlesVisibility();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.hideEmbeddedNoteTitles = DEFAULT_SETTINGS.hideEmbeddedNoteTitles;
      await plugin.saveSettings();
      const toggleComponent = hideEmbeddedNoteTitlesSetting.components[0];
      if (toggleComponent) {
        toggleComponent.setValue(DEFAULT_SETTINGS.hideEmbeddedNoteTitles);
      }
      plugin.updateEmbeddedTitlesVisibility();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const hideEmbeddedNoteBannersSetting = new import_obsidian4.Setting(containerEl).setName("Hide Embedded Note Banners").setDesc("Hide banners of embedded notes").addToggle((toggle) => toggle.setValue(plugin.settings.hideEmbeddedNoteBanners).onChange(async (value) => {
    try {
      plugin.settings.hideEmbeddedNoteBanners = value;
      await plugin.saveSettings();
      plugin.updateEmbeddedBannersVisibility();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.hideEmbeddedNoteBanners = DEFAULT_SETTINGS.hideEmbeddedNoteBanners;
      await plugin.saveSettings();
      const toggleComponent = hideEmbeddedNoteBannersSetting.components[0];
      if (toggleComponent) {
        toggleComponent.setValue(DEFAULT_SETTINGS.hideEmbeddedNoteBanners);
      }
      plugin.updateEmbeddedBannersVisibility();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Show Banner in Popover Previews").setDesc("Show banners in popover note previews").addToggle((toggle) => toggle.setValue(plugin.settings.showBannerInPopoverPreviews).onChange(async (value) => {
    try {
      plugin.settings.showBannerInPopoverPreviews = value;
      await plugin.saveSettings();
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.showBannerInPopoverPreviews = DEFAULT_SETTINGS.showBannerInPopoverPreviews;
      await plugin.saveSettings();
      plugin.updateAllBanners();
      const checkboxContainer = button.extraSettingsEl.parentElement.querySelector(".checkbox-container");
      const toggleEl = checkboxContainer.querySelector("input");
      if (toggleEl) {
        toggleEl.checked = DEFAULT_SETTINGS.showBannerInPopoverPreviews;
        checkboxContainer.classList.toggle("is-enabled", DEFAULT_SETTINGS.showBannerInPopoverPreviews);
      }
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const showViewImageIconSetting = new import_obsidian4.Setting(containerEl).setName("Show View Image Icon").setDesc("Show an icon to view the banner image in full screen").addToggle((toggle) => toggle.setValue(plugin.settings.showViewImageIcon).onChange(async (value) => {
    try {
      plugin.settings.showViewImageIcon = value;
      await plugin.saveSettings();
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.showViewImageIcon = DEFAULT_SETTINGS.showViewImageIcon;
      await plugin.saveSettings();
      const toggleComponent = showViewImageIconSetting.components[0];
      if (toggleComponent) {
        toggleComponent.setValue(DEFAULT_SETTINGS.showViewImageIcon);
      }
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Image Property Format").setDesc("Set the format for the banner property value.").addDropdown((dropdown) => dropdown.addOption("image", "image").addOption("[[image]]", "[[image]]").addOption("![[image]]", "![[image]]").setValue(plugin.settings.imagePropertyFormat).onChange(async (value) => {
    try {
      plugin.settings.imagePropertyFormat = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.imagePropertyFormat = DEFAULT_SETTINGS.imagePropertyFormat;
      await plugin.saveSettings();
      const dropdown = button.extraSettingsEl.parentElement.querySelector("select");
      dropdown.value = DEFAULT_SETTINGS.imagePropertyFormat;
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const hideSettingsGroup = containerEl.createDiv({ cls: "setting-group" });
  const hidePixelBannerFieldsSetting = new import_obsidian4.Setting(hideSettingsGroup).setName("Hide Pixel Banner Fields").setDesc("Hide banner-related frontmatter fields in Reading mode").addToggle((toggle) => toggle.setValue(plugin.settings.hidePixelBannerFields).onChange(async (value) => {
    try {
      plugin.settings.hidePixelBannerFields = value;
      if (!value) {
        plugin.settings.hidePropertiesSectionIfOnlyBanner = false;
        const dependentToggle = hidePropertiesSection.components[0];
        if (dependentToggle) {
          dependentToggle.setValue(false);
          dependentToggle.setDisabled(true);
        }
        hidePropertiesSection.settingEl.addClass("is-disabled");
        plugin.app.workspace.iterateAllLeaves((leaf) => {
          if (leaf.view instanceof import_obsidian4.MarkdownView && leaf.view.contentEl) {
            const propertiesContainer = leaf.view.contentEl.querySelector(".metadata-container");
            if (propertiesContainer) {
              propertiesContainer.classList.remove("pixel-banner-hidden-section");
              const hiddenFields = propertiesContainer.querySelectorAll(".pixel-banner-hidden-field");
              hiddenFields.forEach((field) => {
                field.classList.remove("pixel-banner-hidden-field");
              });
            }
          }
        });
      } else {
        const dependentToggle = hidePropertiesSection.components[0];
        if (dependentToggle) {
          dependentToggle.setDisabled(false);
        }
        hidePropertiesSection.settingEl.removeClass("is-disabled");
      }
      await plugin.saveSettings();
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.hidePixelBannerFields = DEFAULT_SETTINGS.hidePixelBannerFields;
      plugin.settings.hidePropertiesSectionIfOnlyBanner = DEFAULT_SETTINGS.hidePropertiesSectionIfOnlyBanner;
      await plugin.saveSettings();
      const mainToggle = hidePixelBannerFieldsSetting.components[0];
      if (mainToggle) {
        mainToggle.setValue(DEFAULT_SETTINGS.hidePixelBannerFields);
      }
      const dependentToggle = hidePropertiesSection.components[0];
      if (dependentToggle) {
        dependentToggle.setValue(DEFAULT_SETTINGS.hidePropertiesSectionIfOnlyBanner);
        dependentToggle.setDisabled(!DEFAULT_SETTINGS.hidePixelBannerFields);
      }
      hidePropertiesSection.settingEl.toggleClass("is-disabled", !DEFAULT_SETTINGS.hidePixelBannerFields);
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const hidePropertiesSection = new import_obsidian4.Setting(hideSettingsGroup).setName("Hide Properties Section").setDesc("Hide the entire Properties section in Reading mode if it only contains Pixel Banner fields").addToggle((toggle) => toggle.setValue(plugin.settings.hidePropertiesSectionIfOnlyBanner).setDisabled(!plugin.settings.hidePixelBannerFields).onChange(async (value) => {
    try {
      plugin.settings.hidePropertiesSectionIfOnlyBanner = value;
      await plugin.saveSettings();
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.hidePropertiesSectionIfOnlyBanner = DEFAULT_SETTINGS.hidePropertiesSectionIfOnlyBanner;
      await plugin.saveSettings();
      const toggle = hidePropertiesSection.components[0];
      if (toggle) {
        toggle.setValue(DEFAULT_SETTINGS.hidePropertiesSectionIfOnlyBanner);
      }
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  hidePropertiesSection.settingEl.addClass("setting-dependent");
  if (!plugin.settings.hidePixelBannerFields) {
    hidePropertiesSection.settingEl.addClass("is-disabled");
  }
  new import_obsidian4.Setting(containerEl).setName("Default Banner Icon Size").setDesc("Set the default size for the banner icon").addSlider((slider) => slider.setLimits(10, 200, 1).setValue(plugin.settings.bannerIconSize).setDynamicTooltip().onChange(async (value) => {
    try {
      plugin.settings.bannerIconSize = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerIconSize = DEFAULT_SETTINGS.bannerIconSize;
      await plugin.saveSettings();
      const sliderInput = button.extraSettingsEl.parentElement.querySelector('input[type="range"]');
      sliderInput.value = DEFAULT_SETTINGS.bannerIconSize;
      const event = new Event("input", { bubbles: true, cancelable: true });
      sliderInput.dispatchEvent(event);
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Default Banner Icon Image Size Multiplier").setDesc("Set the default size multiplier for banner icon images (0.1-5)").addSlider((slider) => slider.setLimits(0.1, 5, 0.1).setValue(plugin.settings.bannerIconImageSizeMultiplier).setDynamicTooltip().onChange(async (value) => {
    try {
      plugin.settings.bannerIconImageSizeMultiplier = value;
      await plugin.saveSettings();
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerIconImageSizeMultiplier = DEFAULT_SETTINGS.bannerIconImageSizeMultiplier;
      await plugin.saveSettings();
      const sliderInput = button.extraSettingsEl.parentElement.querySelector('input[type="range"]');
      sliderInput.value = DEFAULT_SETTINGS.bannerIconImageSizeMultiplier;
      const event = new Event("input", { bubbles: true, cancelable: true });
      sliderInput.dispatchEvent(event);
      plugin.updateAllBanners();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Default Banner Icon X Position").setDesc("Set the default X position for the banner icon (0-100)").addSlider((slider) => slider.setLimits(0, 100, 1).setValue(plugin.settings.bannerIconXPosition).setDynamicTooltip().onChange(async (value) => {
    try {
      plugin.settings.bannerIconXPosition = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerIconXPosition = DEFAULT_SETTINGS.bannerIconXPosition;
      await plugin.saveSettings();
      const sliderInput = button.extraSettingsEl.parentElement.querySelector('input[type="range"]');
      sliderInput.value = DEFAULT_SETTINGS.bannerIconXPosition;
      const event = new Event("input", { bubbles: true, cancelable: true });
      sliderInput.dispatchEvent(event);
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Default Banner Icon Opacity").setDesc("Set the default opacity for the banner icon (0-100)").addSlider((slider) => slider.setLimits(0, 100, 1).setValue(plugin.settings.bannerIconOpacity).setDynamicTooltip().onChange(async (value) => {
    try {
      plugin.settings.bannerIconOpacity = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerIconOpacity = DEFAULT_SETTINGS.bannerIconOpacity;
      await plugin.saveSettings();
      const sliderInput = button.extraSettingsEl.parentElement.querySelector('input[type="range"]');
      sliderInput.value = DEFAULT_SETTINGS.bannerIconOpacity;
      const event = new Event("input", { bubbles: true, cancelable: true });
      sliderInput.dispatchEvent(event);
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Default Banner Icon Text Color").setDesc("Set the default text color for the banner icon").addText((text) => text.setPlaceholder("Enter color (e.g., #ffffff or white)").setValue(plugin.settings.bannerIconColor).onChange(async (value) => {
    try {
      plugin.settings.bannerIconColor = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerIconColor = DEFAULT_SETTINGS.bannerIconColor;
      await plugin.saveSettings();
      const textInput = button.extraSettingsEl.parentElement.querySelector('input[type="text"]');
      textInput.value = DEFAULT_SETTINGS.bannerIconColor;
      const event = new Event("input", { bubbles: true, cancelable: true });
      textInput.dispatchEvent(event);
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Default Banner Icon Font Weight").setDesc("Set the default font weight for the banner icon").addDropdown((dropdown) => {
    dropdown.addOption("lighter", "Lighter").addOption("normal", "Normal").addOption("bold", "Bold").setValue(plugin.settings.bannerIconFontWeight || "normal").onChange(async (value) => {
      try {
        plugin.settings.bannerIconFontWeight = value;
        await plugin.saveSettings();
      } catch (error) {
        console.error("Failed to save settings:", error);
      }
    });
    return dropdown;
  }).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerIconFontWeight = DEFAULT_SETTINGS.bannerIconFontWeight;
      await plugin.saveSettings();
      const dropdownEl = button.extraSettingsEl.parentElement.querySelector("select");
      dropdownEl.value = DEFAULT_SETTINGS.bannerIconFontWeight;
      dropdownEl.dispatchEvent(new Event("change"));
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Default Banner Icon Background Color").setDesc("Set the default background color for the banner icon").addText((text) => text.setPlaceholder("Enter color (e.g., #ffffff or transparent)").setValue(plugin.settings.bannerIconBackgroundColor).onChange(async (value) => {
    try {
      plugin.settings.bannerIconBackgroundColor = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerIconBackgroundColor = DEFAULT_SETTINGS.bannerIconBackgroundColor;
      await plugin.saveSettings();
      const textInput = button.extraSettingsEl.parentElement.querySelector('input[type="text"]');
      textInput.value = DEFAULT_SETTINGS.bannerIconBackgroundColor;
      const event = new Event("input", { bubbles: true, cancelable: true });
      textInput.dispatchEvent(event);
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Default Banner Icon Padding X").setDesc("Set the default padding X for the banner icon").addSlider((slider) => slider.setLimits(0, 100, 1).setValue(plugin.settings.bannerIconPaddingX).setDynamicTooltip().onChange(async (value) => {
    try {
      plugin.settings.bannerIconPaddingX = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerIconPaddingX = DEFAULT_SETTINGS.bannerIconPaddingX;
      await plugin.saveSettings();
      const sliderInput = button.extraSettingsEl.parentElement.querySelector('input[type="range"]');
      sliderInput.value = DEFAULT_SETTINGS.bannerIconPaddingX;
      const event = new Event("input", { bubbles: true, cancelable: true });
      sliderInput.dispatchEvent(event);
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Default Banner Icon Padding Y").setDesc("Set the default padding Y for the banner icon").addSlider((slider) => slider.setLimits(0, 100, 1).setValue(plugin.settings.bannerIconPaddingY).setDynamicTooltip().onChange(async (value) => {
    try {
      plugin.settings.bannerIconPaddingY = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerIconPaddingY = DEFAULT_SETTINGS.bannerIconPaddingY;
      await plugin.saveSettings();
      const sliderInput = button.extraSettingsEl.parentElement.querySelector('input[type="range"]');
      sliderInput.value = DEFAULT_SETTINGS.bannerIconPaddingY;
      const event = new Event("input", { bubbles: true, cancelable: true });
      sliderInput.dispatchEvent(event);
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Default Banner Icon Border Radius").setDesc("Set the default border radius for the banner icon").addSlider((slider) => slider.setLimits(0, 100, 1).setValue(plugin.settings.bannerIconBorderRadius).setDynamicTooltip().onChange(async (value) => {
    try {
      plugin.settings.bannerIconBorderRadius = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerIconBorderRadius = DEFAULT_SETTINGS.bannerIconBorderRadius;
      await plugin.saveSettings();
      const sliderInput = button.extraSettingsEl.parentElement.querySelector('input[type="range"]');
      sliderInput.value = DEFAULT_SETTINGS.bannerIconBorderRadius;
      const event = new Event("input", { bubbles: true, cancelable: true });
      sliderInput.dispatchEvent(event);
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  new import_obsidian4.Setting(containerEl).setName("Default Banner Icon Vertical Offset").setDesc("Set the default vertical offset for the banner icon").addSlider((slider) => slider.setLimits(-100, 100, 1).setValue(plugin.settings.bannerIconVerticalOffset).setDynamicTooltip().onChange(async (value) => {
    try {
      plugin.settings.bannerIconVerticalOffset = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.bannerIconVerticalOffset = DEFAULT_SETTINGS.bannerIconVerticalOffset;
      await plugin.saveSettings();
      const sliderInput = button.extraSettingsEl.parentElement.querySelector('input[type="range"]');
      sliderInput.value = DEFAULT_SETTINGS.bannerIconVerticalOffset;
      const event = new Event("input", { bubbles: true, cancelable: true });
      sliderInput.dispatchEvent(event);
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const showReleaseNotesSetting = new import_obsidian4.Setting(containerEl).setName("Show Release Notes").setDesc("Show release notes after plugin updates").addToggle((toggle) => toggle.setValue(plugin.settings.showReleaseNotes).onChange(async (value) => {
    try {
      plugin.settings.showReleaseNotes = value;
      await plugin.saveSettings();
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    try {
      plugin.settings.showReleaseNotes = DEFAULT_SETTINGS.showReleaseNotes;
      await plugin.saveSettings();
      const toggleComponent = showReleaseNotesSetting.components[0];
      if (toggleComponent) {
        toggleComponent.setValue(DEFAULT_SETTINGS.showReleaseNotes);
      }
    } catch (error) {
      console.error("Failed to save settings:", error);
    }
  }));
  const promotionalLinks = containerEl.createDiv({
    cls: "pixel-banner-promotional-links",
    attr: {
      style: `
                display: flex;
                gap: 10px;
                justify-content: center;
                margin-top: 30px;
                padding-top: 20px;
                border-top: 1px solid var(--background-modifier-border);
            `
    }
  });
  const discordLink = promotionalLinks.createEl("a", {
    href: "https://discord.gg/sp8AQQhMJ7",
    target: "discord"
  });
  discordLink.createEl("img", {
    attr: {
      height: "36",
      src: "https://raw.githubusercontent.com/jparkerweb/pixel-banner/refs/heads/main/img/discord.png?raw=true",
      alt: "Discord"
    }
  });
  const kofiLink = promotionalLinks.createEl("a", {
    href: "https://ko-fi.com/Z8Z212UMBI",
    target: "kofi"
  });
  kofiLink.createEl("img", {
    attr: {
      height: "36",
      src: "https://raw.githubusercontent.com/jparkerweb/pixel-banner/refs/heads/main/img/support.png?raw=true",
      alt: "Buy Me a Coffee at ko-fi.com"
    }
  });
}

// src/settings/tabs/settingsTabPixelBannerPlus.js
var import_obsidian5 = require("obsidian");
init_constants();
function createPixelBannerPlusSettings(containerEl, plugin) {
  plugin.pixelBannerPlusEnabled = plugin.settings.pixelBannerPlusEnabled !== false;
  const calloutElPixelBannerPlus = containerEl.createEl("div", { cls: "tab-callout margin-bottom-0" });
  calloutElPixelBannerPlus.createEl("h4", {
    text: "\u2728 Pixel Banner Plus \u2728",
    attr: {
      style: "margin-top: 5px;"
    }
  });
  calloutElPixelBannerPlus.createEl("div", { text: "Pixel Banner Plus enhances your notes with AI-generated, high-quality banners. Using a token-based system, you can instantly create stunning, customized visuals\u2014no design skills needed. Sign up for free to access the banner store, which includes a selection of zero-token banners at no cost. No subscription required\u2014simply purchase tokens whenever you need AI-generated designs. Transform your Obsidian workspace with professional banners, starting for free and only adding tokens as needed." });
  const pixelBannerPlusSettingsGroup = containerEl.createDiv({ cls: "setting-group" });
  const plusDependentSettings = containerEl.createDiv({ cls: "pixel-banner-plus-dependent-settings" });
  function updatePlusDependentSettingsVisibility(isEnabled) {
    if (isEnabled) {
      plusDependentSettings.style.display = "block";
    } else {
      plusDependentSettings.style.display = "none";
    }
  }
  new import_obsidian5.Setting(pixelBannerPlusSettingsGroup).setName("Pixel Banner Plus Enabled").setDesc("Enable or disable Pixel Banner Plus features").addToggle((toggle) => toggle.setValue(plugin.settings.pixelBannerPlusEnabled !== false).onChange(async (value) => {
    plugin.pixelBannerPlusEnabled = value;
    plugin.settings.pixelBannerPlusEnabled = value;
    await plugin.saveSettings();
    updatePlusDependentSettingsVisibility(value);
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    plugin.settings.pixelBannerPlusEnabled = DEFAULT_SETTINGS.pixelBannerPlusEnabled;
    plugin.pixelBannerPlusEnabled = plugin.settings.pixelBannerPlusEnabled;
    await plugin.saveSettings();
    const toggleComponent = button.extraSettingsEl.parentElement.querySelector(".checkbox-container input");
    if (toggleComponent) {
      toggleComponent.checked = plugin.settings.pixelBannerPlusEnabled;
      toggleComponent.parentElement.classList.toggle("is-enabled", plugin.settings.pixelBannerPlusEnabled);
      toggleComponent.dispatchEvent(new Event("change"));
    }
    updatePlusDependentSettingsVisibility(plugin.settings.pixelBannerPlusEnabled);
  })).then((setting) => {
    const nameEl = setting.nameEl;
    if (nameEl) {
      nameEl.innerHTML = '<span class="pixel-banner-twinkle-animation">\u2728</span> Pixel Banner Plus Enabled';
    }
  });
  updatePlusDependentSettingsVisibility(plugin.settings.pixelBannerPlusEnabled !== false);
  const accountSettingsGroup = plusDependentSettings.createDiv({ cls: "setting-group margin-top-0" });
  new import_obsidian5.Setting(accountSettingsGroup).setName("Pixel Banner Plus Email Address").setDesc("Your email address for Pixel Banner Plus authentication").addText(
    (text) => text.setPlaceholder("Enter your email address").setValue(plugin.settings.pixelBannerPlusEmail).onChange(async (value) => {
      plugin.settings.pixelBannerPlusEmail = value;
      await plugin.saveSettings();
      if (!value) {
        plugin.pixelBannerPlusEnabled = false;
        plugin.settings.pixelBannerPlusEnabled = false;
      }
    }).inputEl.style = "width: 100%; max-width: 275px; padding: 5px 10px;"
  );
  new import_obsidian5.Setting(accountSettingsGroup).setName("Pixel Banner Plus API Key").setDesc("Your API key for Pixel Banner Plus authentication").addText(
    (text) => text.setPlaceholder("Enter your API key").setValue(plugin.settings.pixelBannerPlusApiKey).onChange(async (value) => {
      plugin.settings.pixelBannerPlusApiKey = value;
      await plugin.saveSettings();
      if (!value) {
        plugin.pixelBannerPlusEnabled = false;
        plugin.settings.pixelBannerPlusEnabled = false;
      }
    }).inputEl.style = "width: 100%; max-width: 275px; padding: 5px 10px;"
  );
  new import_obsidian5.Setting(accountSettingsGroup).setName("Establish Connection").setDesc("Establish a connection to your Pixel Banner Plus account").addButton((button) => {
    const buttonEl = button.buttonEl;
    buttonEl.style.textTransform = "uppercase";
    buttonEl.style.letterSpacing = "1px";
    buttonEl.style.fontWeight = "bold";
    buttonEl.style.borderRadius = "5px";
    buttonEl.style.padding = "5px 10px";
    buttonEl.style.fontSize = ".9em";
    buttonEl.style.cursor = "pointer";
    button.buttonEl.innerHTML = "\u26A1 Refresh / Connect Account";
    button.setCta();
    button.onClick(async () => {
      const email = plugin.settings.pixelBannerPlusEmail;
      const apiKey = plugin.settings.pixelBannerPlusApiKey;
      if (!email || !apiKey) {
        new import_obsidian5.Notice("Please enter both email and API key");
        return;
      }
      button.buttonEl.innerHTML = "Verifying Account...";
      button.setDisabled(true);
      try {
        const data = await plugin.verifyPixelBannerPlusCredentials();
        if (data) {
          if (data.verified) {
            new import_obsidian5.Notice(`\u2705 Pixel Banner Plus connection successful
\u{1FA99} Banner Tokens Remaining: ${data.bannerTokens}`);
            plugin.pixelBannerPlusServerOnline = data.serverOnline;
            plugin.pixelBannerPlusEnabled = true;
            plugin.pixelBannerPlusBannerTokens = data.bannerTokens;
            updateAccountStatusSection(accountStatusGroup, plugin);
            updateSignupSection(pixelBannerPlusSettingsGroup, plugin);
          } else {
            if (data.serverOnline) {
              new import_obsidian5.Notice("\u274C Invalid credentials");
            } else {
              new import_obsidian5.Notice("\u274C Cannot connect to Pixel Banner Plus servers. Please try again later.");
            }
            plugin.pixelBannerPlusServerOnline = data.serverOnline;
            plugin.pixelBannerPlusEnabled = false;
            plugin.pixelBannerPlusBannerTokens = 0;
            updateAccountStatusSection(accountStatusGroup, plugin);
            updateSignupSection(pixelBannerPlusSettingsGroup, plugin);
          }
        } else {
          new import_obsidian5.Notice("\u274C Cannot connect to Pixel Banner Plus servers. Please try again later.");
          plugin.pixelBannerPlusServerOnline = false;
          plugin.pixelBannerPlusEnabled = false;
          plugin.pixelBannerPlusBannerTokens = 0;
          updateAccountStatusSection(accountStatusGroup, plugin);
          updateSignupSection(pixelBannerPlusSettingsGroup, plugin);
        }
      } catch (error) {
        new import_obsidian5.Notice("\u274C Connection failed.");
        plugin.pixelBannerPlusEnabled = false;
        updateAccountStatusSection(accountStatusGroup, plugin);
        updateSignupSection(pixelBannerPlusSettingsGroup, plugin);
      }
      button.buttonEl.innerHTML = "\u26A1 Refresh / Authorize Account";
      button.setDisabled(false);
    });
  });
  new import_obsidian5.Setting(accountSettingsGroup).setName("Show Daily Game").setDesc("Enable the daily game feature in the banner selection modal for a chance to win the daily jackpot's Tokens").addToggle((toggle) => toggle.setValue(plugin.settings.enableDailyGame).onChange(async (value) => {
    plugin.settings.enableDailyGame = value;
    await plugin.saveSettings();
  })).addExtraButton((button) => button.setIcon("reset").setTooltip("Reset to default").onClick(async () => {
    plugin.settings.enableDailyGame = DEFAULT_SETTINGS.enableDailyGame;
    await plugin.saveSettings();
    const toggleComponent = button.extraSettingsEl.parentElement.querySelector(".checkbox-container input");
    if (toggleComponent) {
      toggleComponent.checked = DEFAULT_SETTINGS.enableDailyGame;
      toggleComponent.parentElement.classList.toggle("is-enabled", DEFAULT_SETTINGS.enableDailyGame);
      toggleComponent.dispatchEvent(new Event("change"));
    }
  })).then((setting) => {
    const nameEl = setting.nameEl;
    if (nameEl) {
      nameEl.innerHTML = '<span class="pixel-banner-twinkle-animation">\u{1F579}\uFE0F</span> Show Daily Game';
    }
  });
  updateSignupSection(plusDependentSettings, plugin);
  const accountStatusGroup = plusDependentSettings.createDiv({ cls: "setting-group" });
  accountStatusGroup.createEl("h3", { text: "Account Status" });
  updateAccountStatusSection(accountStatusGroup, plugin);
}
function updateSignupSection(containerEl, plugin) {
  containerEl.querySelectorAll(".setting-item").forEach((el) => {
    var _a;
    if (((_a = el.querySelector(".setting-item-name")) == null ? void 0 : _a.textContent) === "Signup") {
      el.remove();
    }
  });
  if (!plugin.pixelBannerPlusEnabled && plugin.pixelBannerPlusServerOnline) {
    new import_obsidian5.Setting(containerEl).setName("Signup").setDesc("Create a FREE Pixel Banner Plus account to get started. You will receive \u{1FA99} 5 FREE banner tokens at signup (no payment info required). This form can also be use to recover your account if you forget your API Key.").addButton((button) => {
      const buttonEl = button.buttonEl;
      buttonEl.style.textTransform = "uppercase";
      buttonEl.style.letterSpacing = "1px";
      buttonEl.style.fontWeight = "bold";
      buttonEl.style.borderRadius = "5px";
      buttonEl.style.padding = "5px 10px";
      buttonEl.style.fontSize = ".9em";
      buttonEl.style.cursor = "pointer";
      buttonEl.classList.add("scale-up-down-animation");
      button.buttonEl.innerHTML = "\u{1F6A9} Signup for Free!";
      button.setCta();
      button.onClick(() => {
        const signupUrl = PIXEL_BANNER_PLUS.API_URL + PIXEL_BANNER_PLUS.ENDPOINTS.SIGNUP;
        window.open(signupUrl, "_blank");
      });
    });
  }
}
function updateAccountStatusSection(containerEl, plugin) {
  containerEl.empty();
  containerEl.createEl("h3", {
    text: "Account Status",
    attr: {
      style: `
                margin-top: 0;
                margin-bottom: 0;
            `
    }
  });
  new import_obsidian5.Setting(containerEl).setName("Connection Status").setDesc("Current status of your Pixel Banner Plus account").addText((text) => {
    const statusText = plugin.pixelBannerPlusServerOnline ? plugin.pixelBannerPlusEnabled ? "\u2705 Authorized" : "\u274C Not Authorized" : "\u{1F6A8} Servers Offline \u{1F6A8}";
    const isLightMode = document.body.classList.contains("theme-light");
    const statusColor = isLightMode ? "black" : "white";
    const statusBGColor = isLightMode ? "white" : "black";
    const statusBorderColor = plugin.pixelBannerPlusEnabled ? "#20bf6b" : "#FF0000";
    const span = text.inputEl.parentElement.createSpan({
      text: statusText,
      attr: {
        style: `
                        color: ${statusColor};
                        background-color: ${statusBGColor};
                        border: 1px dotted ${statusBorderColor};
                        padding: 5px 10px;
                        border-radius: 0px;
                        text-transform: uppercase;
                        font-size: .9em;
                        letter-spacing: 1.5px;
                    `
      }
    });
    text.inputEl.style.display = "none";
  });
  new import_obsidian5.Setting(containerEl).setName("Available Tokens").setDesc("Number of banner tokens available in your account").addText((text) => {
    const tokenCount = plugin.pixelBannerPlusBannerTokens !== void 0 ? `\u{1FA99} ${plugin.pixelBannerPlusBannerTokens.toString()}` : "\u2753 Unknown";
    const isLightMode = document.body.classList.contains("theme-light");
    const tokenColor = isLightMode ? "black" : "white";
    const tokenBGColor = isLightMode ? "white" : "black";
    const span = text.inputEl.parentElement.createSpan({
      text: tokenCount,
      attr: {
        style: `
                        font-weight: bold; 
                        color: ${tokenColor}; 
                        background-color: ${tokenBGColor}; 
                        border: 1px dotted #F3B93B; 
                        padding: 5px 10px; 
                        border-radius: 0px; 
                        text-transform: uppercase; 
                        font-size: .9em; 
                        letter-spacing: 1.5px;
                    `
      }
    });
    text.inputEl.style.display = "none";
  });
  if (plugin.pixelBannerPlusServerOnline && plugin.pixelBannerPlusEnabled) {
    new import_obsidian5.Setting(containerEl).setName("Buy Tokens").setDesc(createFragment((el) => {
      el.createEl("div", { text: "Purchase tokens to download Banners from the Store or Generate them with AI \u2728" });
      el.createEl("div").innerHTML = 'This greatly helps support the development of this plugin and keep the AI Servers running \u{1F917}. In addition to buying tokens directly, any donation on our <a href="https://ko-fi.com/jparkerweb" target="_blank" style="text-transform: uppercase;background: white;border: 1px solid green;color: black;font-size: 0.9em;font-weight: bold;padding: 0 3px;cursor: pointer;text-decoration: none;border-radius: 5px;">Ko-fi page</a> will also add tokens to your account \u{1F496}';
    })).addButton((button) => {
      const buttonEl = button.buttonEl;
      buttonEl.style.textTransform = "uppercase";
      buttonEl.style.letterSpacing = "1px";
      buttonEl.style.borderRadius = "5px";
      buttonEl.style.border = "1px solid papayawhip";
      buttonEl.style.padding = "5px 10px";
      buttonEl.style.fontSize = ".9em";
      buttonEl.style.lineHeight = "1";
      buttonEl.style.backgroundColor = "darkgreen";
      buttonEl.style.color = "papayawhip";
      buttonEl.style.cursor = "pointer";
      buttonEl.classList.add("scale-up-down-animation");
      button.buttonEl.innerHTML = "\u{1F4B5} Buy More Tokens";
      button.onClick(() => {
        window.open(PIXEL_BANNER_PLUS.SHOP_URL, "_blank");
      });
    });
  }
}

// src/settings/settings.js
var DEFAULT_SETTINGS = {
  pixelBannerPlusEmail: "",
  pixelBannerPlusApiKey: "",
  pixelBannerPlusEnabled: true,
  apiProvider: "all",
  pexelsApiKey: "",
  pixabayApiKey: "",
  flickrApiKey: "",
  unsplashApiKey: "",
  imageSize: "medium",
  imageOrientation: "landscape",
  numberOfImages: 10,
  defaultKeywords: "nature, abstract, landscape, technology, art, cityscape, wildlife, ocean, mountains, forest, space, architecture, food, travel, science, music, sports, fashion, business, education, health, culture, history, weather, transportation, industry, people, animals, plants, patterns",
  xPosition: 50,
  yPosition: 60,
  customBannerField: ["banner"],
  customXPositionField: ["banner-x", "x"],
  customYPositionField: ["banner-y", "y"],
  customContentStartField: ["content-start"],
  customImageDisplayField: ["banner-display"],
  customImageRepeatField: ["banner-repeat"],
  customBannerMaxWidthField: ["banner-max-width"],
  customBannerAlignmentField: ["banner-align"],
  customBannerHeightField: ["banner-height"],
  customFadeField: ["banner-fade"],
  customBorderRadiusField: ["banner-radius"],
  customTitleColorField: ["banner-inline-title-color"],
  customBannerShuffleField: ["banner-shuffle"],
  customBannerIconField: ["icon"],
  customBannerIconImageField: ["icon-image"],
  customBannerIconSizeField: ["icon-size"],
  customBannerIconImageSizeMultiplierField: ["icon-image-size-multiplier"],
  customBannerIconTextVerticalOffsetField: ["icon-text-vertical-offset"],
  customBannerIconRotateField: ["icon-rotate"],
  customBannerIconXPositionField: ["icon-x"],
  customBannerIconOpacityField: ["icon-opacity"],
  customBannerIconColorField: ["icon-color"],
  customBannerIconFontWeightField: ["icon-font-weight"],
  customBannerIconBackgroundColorField: ["icon-bg-color"],
  customBannerIconPaddingXField: ["icon-padding-x"],
  customBannerIconPaddingYField: ["icon-padding-y"],
  customBannerIconBorderRadiusField: ["icon-border-radius"],
  customBannerIconVerticalOffsetField: ["icon-y"],
  customBannerIconImageAlignmentField: ["banner-icon-image-alignment"],
  customFlagColorField: ["pixel-banner-flag-color"],
  folderImages: [],
  contentStartPosition: 355,
  imageDisplay: "cover",
  imageRepeat: false,
  bannerHeight: 350,
  bannerMaxWidth: 2560,
  fade: -40,
  bannerFadeInAnimationDuration: 300,
  borderRadius: 17,
  showPinIcon: false,
  pinnedImageFolder: "pixel-banner-images",
  pinnedImageFilename: "pixel-banner-image",
  imagePropertyFormat: "image",
  showReleaseNotes: true,
  lastVersion: null,
  showRefreshIcon: false,
  showViewImageIcon: false,
  hidePixelBannerFields: true,
  hidePropertiesSectionIfOnlyBanner: true,
  titleColor: "var(--inline-title-color)",
  enableImageShuffle: false,
  hideEmbeddedNoteTitles: false,
  hideEmbeddedNoteBanners: false,
  showBannerInPopoverPreviews: true,
  showSelectImageIcon: true,
  selectImageIconOpacity: 40,
  selectImageIconFlag: "red",
  defaultSelectImagePath: "",
  defaultSelectIconPath: "",
  useShortPath: true,
  bannerGap: 12,
  bannerIconSize: 70,
  bannerIconImageSizeMultiplier: 1,
  bannerIconTextVerticalOffset: 0,
  bannerIconXPosition: 75,
  bannerIconOpacity: 100,
  bannerIconColor: "",
  bannerIconFontWeight: "normal",
  bannerIconBackgroundColor: "",
  bannerIconPaddingX: "10",
  bannerIconPaddingY: "10",
  bannerIconBorderRadius: "17",
  bannerIconVerticalOffset: "0",
  bannerIconImageAlignment: "left",
  openTargetingModalAfterSelectingBannerOrIcon: true,
  enableDailyGame: false
};
var FolderSuggestModal = class extends import_obsidian6.FuzzySuggestModal {
  constructor(app, onChoose) {
    super(app);
    this.onChoose = onChoose;
  }
  getItems() {
    return this.app.vault.getAllLoadedFiles().filter((file) => file.children).map((folder) => folder.path);
  }
  getItemText(item) {
    return item;
  }
  onChooseItem(item) {
    this.onChoose(item);
  }
};
var PixelBannerSettingTab = class extends import_obsidian6.PluginSettingTab {
  constructor(app, plugin) {
    super(app, plugin);
    this.plugin = plugin;
  }
  display() {
    const { containerEl } = this;
    containerEl.empty();
    containerEl.addClass("pixel-banner-settings");
    const mainContent = containerEl.createEl("div", { cls: "pixel-banner-main-content" });
    const { tabsEl, tabContentContainer } = this.createTabs(mainContent, [
      "\u2699\uFE0F General",
      "\u2728 Plus",
      "\u{1F5FA}\uFE0F Custom Fields",
      "\u{1F5C3}\uFE0F Folder Groups",
      "\u{1F310} 3rd Party APIs"
    ]);
    const generalTab = tabContentContainer.createEl("div", { cls: "tab-content", attr: { "data-tab": "\u2699\uFE0F General" } });
    createGeneralSettings(generalTab, this.plugin);
    const pixelBannerPlusTab = tabContentContainer.createEl("div", { cls: "tab-content", attr: { "data-tab": "\u2728 Plus" } });
    createPixelBannerPlusSettings(pixelBannerPlusTab, this.plugin);
    const customFieldsTab = tabContentContainer.createEl("div", { cls: "tab-content", attr: { "data-tab": "\u{1F5FA}\uFE0F Custom Fields" } });
    createCustomFieldsSettings(customFieldsTab, this.plugin);
    const apiTab = tabContentContainer.createEl("div", { cls: "tab-content", attr: { "data-tab": "\u{1F310} 3rd Party APIs" } });
    createAPISettings(apiTab, this.plugin);
    const foldersTab = tabContentContainer.createEl("div", { cls: "tab-content", attr: { "data-tab": "\u{1F5C3}\uFE0F Folder Groups" } });
    createFolderSettings(foldersTab, this.plugin);
    tabsEl.firstChild.click();
  }
  createTabs(containerEl, tabNames) {
    const tabsEl = containerEl.createEl("div", { cls: "pixel-banner-settings-tabs" });
    const tabContentContainer = containerEl.createEl("div", { cls: "pixel-banner-settings-tab-content-container" });
    tabNames.forEach((tabName) => {
      const tabEl = tabsEl.createEl("button", { cls: "pixel-banner-settings-tab", text: tabName });
      tabEl.addEventListener("click", () => {
        tabsEl.querySelectorAll(".pixel-banner-settings-tab").forEach((tab) => tab.removeClass("active"));
        tabContentContainer.querySelectorAll(".tab-content").forEach((content) => content.style.display = "none");
        tabEl.addClass("active");
        tabContentContainer.querySelector(`.tab-content[data-tab="${tabName}"]`).style.display = "flex";
      });
    });
    return { tabsEl, tabContentContainer };
  }
};
function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

// src/core/pixelBannerPlugin.js
init_modals();
init_handlePinIconClick();

// src/core/settings.js
var import_obsidian23 = require("obsidian");
async function loadSettings(plugin) {
  plugin.settings = Object.assign({}, DEFAULT_SETTINGS, await plugin.loadData());
  if (!Array.isArray(plugin.settings.folderImages)) {
    plugin.settings.folderImages = [];
  }
  if (!Array.isArray(plugin.settings.customBannerField)) {
    plugin.settings.customBannerField = DEFAULT_SETTINGS.customBannerField;
  }
  if (typeof plugin.settings.xPosition !== "number") {
    plugin.settings.xPosition = parseInt(plugin.settings.xPosition) || DEFAULT_SETTINGS.xPosition;
  }
  if (typeof plugin.settings.yPosition !== "number") {
    plugin.settings.yPosition = parseInt(plugin.settings.yPosition) || DEFAULT_SETTINGS.yPosition;
  }
  if (plugin.settings.folderImages) {
    plugin.settings.folderImages.forEach((folderImage) => {
      folderImage.imageDisplay = folderImage.imageDisplay || "cover";
      folderImage.imageRepeat = folderImage.imageRepeat || false;
      folderImage.directChildrenOnly = folderImage.directChildrenOnly || false;
    });
  }
}
async function saveSettings(plugin) {
  await plugin.saveData(plugin.settings);
  plugin.loadedImages.clear();
  plugin.lastKeywords.clear();
  plugin.imageCache.clear();
  plugin.app.workspace.iterateAllLeaves((leaf) => {
    if (leaf.view instanceof import_obsidian23.MarkdownView) {
      plugin.updateBanner(leaf.view, true);
      if (plugin.settings.hidePixelBannerFields) {
        plugin.updateFieldVisibility(leaf.view);
      }
    }
  });
}

// src/core/bannerIconHelpers.js
var import_obsidian24 = require("obsidian");
init_modals();
function normalizeColor(color) {
  if (!color || color === "transparent" || color === "none") return "transparent";
  return color.toLowerCase().replace(/\s+/g, "");
}
function getIconOverlay(plugin) {
  if (plugin.iconOverlayPool.length > 0) {
    return plugin.iconOverlayPool.pop();
  }
  const overlay = document.createElement("div");
  overlay.className = "banner-icon-overlay";
  return overlay;
}
function returnIconOverlay(plugin, overlay) {
  if (!overlay) return;
  if (plugin.iconOverlayPool.length < plugin.MAX_POOL_SIZE) {
    overlay.style.cssText = "";
    overlay.className = "banner-icon-overlay";
    overlay.textContent = "";
    overlay.remove();
    plugin.iconOverlayPool.push(overlay);
  }
}
function shouldUpdateIconOverlay(plugin, existingOverlay, newIconState, viewType) {
  if (!existingOverlay || !newIconState) return true;
  if (!existingOverlay._isPersistentBannerIcon || existingOverlay.dataset.viewType !== viewType || existingOverlay.textContent !== newIconState.icon) {
    return true;
  }
  const computedStyle = window.getComputedStyle(existingOverlay);
  const styleChecks = {
    fontSize: `${newIconState.size}px`,
    left: `${newIconState.xPosition}%`,
    opacity: `${newIconState.opacity}%`,
    color: newIconState.color,
    fontWeight: newIconState.fontWeight,
    backgroundColor: newIconState.backgroundColor,
    borderRadius: `${newIconState.borderRadius}px`,
    marginTop: `${newIconState.verticalOffset}px`
  };
  const currentPadding = computedStyle.padding.split(" ");
  const expectedPadding = `${newIconState.paddingY}px ${newIconState.paddingX}px`;
  if (currentPadding.join(" ") !== expectedPadding) {
    return true;
  }
  return Object.entries(styleChecks).some(([prop, value]) => {
    const current = computedStyle[prop];
    return current !== value && // Handle special cases for colors
    !(prop.includes("color") && normalizeColor(current) === normalizeColor(value));
  });
}
async function handleSetBannerIcon(plugin) {
  const activeFile = plugin.app.workspace.getActiveFile();
  if (!activeFile) {
    new import_obsidian24.Notice("No active file");
    return;
  }
  new EmojiSelectionModal(
    plugin.app,
    plugin,
    async (selectedEmoji) => {
      if (!selectedEmoji) {
        await plugin.app.fileManager.processFrontMatter(activeFile, (frontmatter) => {
          const bannerIconField2 = Array.isArray(plugin.settings.customBannerIconField) && plugin.settings.customBannerIconField.length > 0 ? plugin.settings.customBannerIconField[0] : "banner-icon";
          delete frontmatter[bannerIconField2];
        });
        await new Promise((resolve) => setTimeout(resolve, 300));
        const view = plugin.app.workspace.getActiveViewOfType(import_obsidian24.MarkdownView);
        if (view) {
          await plugin.updateBanner(view, true);
        }
        new import_obsidian24.Notice("Banner icon removed");
        return;
      }
      const bannerIconField = Array.isArray(plugin.settings.customBannerIconField) && plugin.settings.customBannerIconField.length > 0 ? plugin.settings.customBannerIconField[0] : "banner-icon";
      await plugin.app.fileManager.processFrontMatter(activeFile, (frontmatter) => {
        plugin.settings.customBannerIconField.forEach((field) => {
          if (field in frontmatter) {
            delete frontmatter[field];
          }
        });
        frontmatter[bannerIconField] = selectedEmoji;
      });
      const metadataUpdated = new Promise((resolve) => {
        let eventRef = null;
        let resolved = false;
        const cleanup = () => {
          if (eventRef) {
            plugin.app.metadataCache.off("changed", eventRef);
            eventRef = null;
          }
        };
        const timeoutId = setTimeout(() => {
          if (!resolved) {
            resolved = true;
            cleanup();
            resolve();
          }
        }, 2e3);
        eventRef = plugin.app.metadataCache.on("changed", (file) => {
          if (file.path === activeFile.path && !resolved) {
            resolved = true;
            clearTimeout(timeoutId);
            cleanup();
            setTimeout(resolve, 50);
          }
        });
      });
      await metadataUpdated;
      const maxRetries = 3;
      const retryDelay = 150;
      let success = false;
      for (let i = 0; i < maxRetries && !success; i++) {
        const view = plugin.app.workspace.getActiveViewOfType(import_obsidian24.MarkdownView);
        if (view) {
          try {
            const cache = plugin.app.metadataCache.getFileCache(activeFile);
            if (!cache || !cache.frontmatter || cache.frontmatter[bannerIconField] !== selectedEmoji) {
              await new Promise((resolve) => setTimeout(resolve, 100));
              continue;
            }
            await plugin.updateBanner(view, true);
            success = true;
          } catch (error) {
            if (i < maxRetries - 1) {
              await new Promise((resolve) => setTimeout(resolve, retryDelay));
            }
          }
        }
      }
      if (!success) {
        await new Promise((resolve) => setTimeout(resolve, 500));
        const view = plugin.app.workspace.getActiveViewOfType(import_obsidian24.MarkdownView);
        if (view) {
          await plugin.updateBanner(view, true);
        }
      }
      new import_obsidian24.Notice("Banner icon updated");
      if (plugin.settings.openTargetingModalAfterSelectingBannerOrIcon) {
        await new Promise((resolve) => setTimeout(resolve, 200));
        const { TargetPositionModal: TargetPositionModal2 } = (init_modals(), __toCommonJS(modals_exports));
        new TargetPositionModal2(plugin.app, plugin).open();
      }
    },
    true
    // Skip the targeting modal in EmojiSelectionModal since we handle it in the callback
  ).open();
}
function cleanupIconOverlay(plugin, view) {
  if (!view || !view.contentEl) return;
  const bannerIconOverlays = view.contentEl.querySelectorAll(".banner-icon-overlay");
  bannerIconOverlays.forEach((overlay) => {
    if (overlay) {
      returnIconOverlay(plugin, overlay);
    }
  });
}
async function handleSetBannerIconImage(plugin) {
  const activeFile = plugin.app.workspace.getActiveFile();
  if (!activeFile) {
    new import_obsidian24.Notice("No active file");
    return;
  }
  new IconImageSelectionModal(
    plugin.app,
    plugin,
    async (selectedImage) => {
      if (!selectedImage) {
        return;
      }
      const imagePath = selectedImage.path ? selectedImage.path : selectedImage;
      const bannerIconImageField = Array.isArray(plugin.settings.customBannerIconImageField) && plugin.settings.customBannerIconImageField.length > 0 ? plugin.settings.customBannerIconImageField[0].split(",")[0].trim() : "icon-image";
      await plugin.app.fileManager.processFrontMatter(activeFile, (frontmatter) => {
        if (Array.isArray(plugin.settings.customBannerIconImageField)) {
          plugin.settings.customBannerIconImageField.forEach((field) => {
            const fieldNames = field.split(",").map((f) => f.trim());
            fieldNames.forEach((fieldName) => {
              if (fieldName in frontmatter) {
                delete frontmatter[fieldName];
              }
            });
          });
        }
        const format = plugin.settings.imagePropertyFormat;
        let iconValue;
        if (format === "image") {
          iconValue = imagePath;
        } else if (format === "[[image]]") {
          iconValue = `[[${imagePath}]]`;
        } else {
          iconValue = `![[${imagePath}]]`;
        }
        frontmatter[bannerIconImageField] = iconValue;
      });
      const metadataUpdated = new Promise((resolve) => {
        let eventRef = null;
        let resolved = false;
        const cleanup = () => {
          if (eventRef) {
            plugin.app.metadataCache.off("changed", eventRef);
            eventRef = null;
          }
        };
        const timeoutId = setTimeout(() => {
          if (!resolved) {
            resolved = true;
            cleanup();
            resolve();
          }
        }, 2e3);
        eventRef = plugin.app.metadataCache.on("changed", (file) => {
          if (file.path === activeFile.path && !resolved) {
            resolved = true;
            clearTimeout(timeoutId);
            cleanup();
            setTimeout(resolve, 50);
          }
        });
      });
      await metadataUpdated;
      const maxRetries = 3;
      const retryDelay = 150;
      let success = false;
      for (let i = 0; i < maxRetries && !success; i++) {
        const view = plugin.app.workspace.getActiveViewOfType(import_obsidian24.MarkdownView);
        if (view) {
          try {
            const cache = plugin.app.metadataCache.getFileCache(activeFile);
            if (!cache || !cache.frontmatter || cache.frontmatter[bannerIconImageField] !== imagePath) {
              await new Promise((resolve) => setTimeout(resolve, 100));
              continue;
            }
            await plugin.updateBanner(view, true);
            success = true;
            new import_obsidian24.Notice(`Banner icon image updated: ${imagePath.split("/").pop()}`);
          } catch (error) {
            if (i < maxRetries - 1) {
              await new Promise((resolve) => setTimeout(resolve, retryDelay));
            }
          }
        }
      }
      if (!success) {
        new import_obsidian24.Notice("Banner icon image set, but banner update failed. Try reopening the note.");
      }
    }
  ).open();
}

// src/core/cacheHelpers.js
var import_obsidian25 = require("obsidian");
function generateCacheKey(filePath, leafId, isShuffled = false) {
  const encodedPath = encodeURIComponent(filePath);
  return `${encodedPath}-${leafId}${isShuffled ? "-shuffle" : ""}`;
}
function getCacheEntriesForFile(filePath) {
  const encodedPath = encodeURIComponent(filePath);
  return Array.from(this.bannerStateCache.entries()).filter(([key]) => key.startsWith(`${encodedPath}-`));
}
function cleanupCache(force = false) {
  var _a, _b;
  const now = Date.now();
  for (const [key, entry] of this.bannerStateCache) {
    const maxAge = entry.isShuffled ? this.SHUFFLE_CACHE_AGE : this.MAX_CACHE_AGE;
    const isOrphaned = entry.leafId && !this.app.workspace.getLeafById(entry.leafId);
    if (force || now - entry.timestamp > maxAge || isOrphaned) {
      if (entry.leafId) {
        const leaf = this.app.workspace.getLeafById(entry.leafId);
        if ((leaf == null ? void 0 : leaf.view) instanceof import_obsidian25.MarkdownView) {
          const contentEl = leaf.view.contentEl;
          ["cm-sizer", "markdown-preview-sizer"].forEach((selector) => {
            const container = contentEl.querySelector(`.${selector}`);
            if (container) {
              const iconOverlays = container.querySelectorAll('.banner-icon-overlay[data-persistent="true"]');
              iconOverlays.forEach((overlay) => overlay.remove());
            }
          });
        }
      }
      if (((_a = entry.state) == null ? void 0 : _a.imageUrl) && typeof entry.state.imageUrl === "string" && entry.state.imageUrl.startsWith("blob:")) {
        URL.revokeObjectURL(entry.state.imageUrl);
      }
      this.bannerStateCache.delete(key);
    }
  }
  if (!force && this.bannerStateCache.size > this.MAX_CACHE_ENTRIES) {
    const entries = Array.from(this.bannerStateCache.entries()).sort(([, a], [, b]) => a.timestamp - b.timestamp);
    while (entries.length > this.MAX_CACHE_ENTRIES) {
      const [key, entry] = entries.shift();
      if (entry.leafId) {
        const leaf = this.app.workspace.getLeafById(entry.leafId);
        if ((leaf == null ? void 0 : leaf.view) instanceof import_obsidian25.MarkdownView) {
          const contentEl = leaf.view.contentEl;
          ["cm-sizer", "markdown-preview-sizer"].forEach((selector) => {
            const container = contentEl.querySelector(`.${selector}`);
            if (container) {
              const iconOverlays = container.querySelectorAll('.banner-icon-overlay[data-persistent="true"]');
              iconOverlays.forEach((overlay) => overlay.remove());
            }
          });
        }
      }
      if (((_b = entry.state) == null ? void 0 : _b.imageUrl) && typeof entry.state.imageUrl === "string" && entry.state.imageUrl.startsWith("blob:")) {
        URL.revokeObjectURL(entry.state.imageUrl);
      }
      this.bannerStateCache.delete(key);
    }
  }
}
function invalidateLeafCache(leafId) {
  var _a;
  for (const [key, entry] of this.bannerStateCache) {
    if (key && typeof key === "string" && key.includes(`-${leafId}`)) {
      const leaf = this.app.workspace.getLeafById(leafId);
      if ((leaf == null ? void 0 : leaf.view) instanceof import_obsidian25.MarkdownView) {
        const contentEl = leaf.view.contentEl;
        ["cm-sizer", "markdown-preview-sizer"].forEach((selector) => {
          const container = contentEl.querySelector(`.${selector}`);
          if (container) {
            const iconOverlays = container.querySelectorAll('.banner-icon-overlay[data-persistent="true"]');
            iconOverlays.forEach((overlay) => overlay.remove());
          }
        });
      }
      if (((_a = entry.state) == null ? void 0 : _a.imageUrl) && typeof entry.state.imageUrl === "string" && entry.state.imageUrl.startsWith("blob:")) {
        URL.revokeObjectURL(entry.state.imageUrl);
      }
      this.bannerStateCache.delete(key);
    }
  }
}

// src/services/apiService.js
var import_obsidian26 = require("obsidian");
var rateLimiter = {
  lastRequestTime: 0,
  // Use shorter interval in test environment to speed up tests
  minInterval: typeof globalThis.vitest !== "undefined" ? 10 : 1e3
  // 10ms in tests, 1s in production
};
async function makeRequest(url, options = {}) {
  const now = Date.now();
  if (now - rateLimiter.lastRequestTime < rateLimiter.minInterval) {
    await new Promise((resolve) => setTimeout(resolve, rateLimiter.minInterval));
  }
  rateLimiter.lastRequestTime = Date.now();
  try {
    const response = await (0, import_obsidian26.requestUrl)({
      url,
      headers: options.headers || {},
      ...options
    });
    return response;
  } catch (error) {
    console.error("Request failed:", error);
    throw new Error(`Request failed: ${error.message}`);
  }
}
async function fetchPexelsImage(plugin, keyword, disableInternalFallback = false) {
  const apiKey = plugin.settings.pexelsApiKey;
  if (!apiKey) return null;
  const useInternalFallback = !disableInternalFallback;
  const defaultKeywords = useInternalFallback && plugin.settings.defaultKeywords ? plugin.settings.defaultKeywords.split(",").map((k) => k.trim()) : [];
  const fallbackKeyword = defaultKeywords.length > 0 ? defaultKeywords[Math.floor(Math.random() * defaultKeywords.length)] : null;
  const keywords = useInternalFallback && fallbackKeyword ? [keyword, fallbackKeyword] : [keyword];
  for (const currentKeyword of keywords) {
    try {
      const response = await makeRequest(
        `https://api.pexels.com/v1/search?query=${encodeURIComponent(currentKeyword)}&per_page=${plugin.settings.numberOfImages}`,
        {
          headers: {
            "Authorization": apiKey
          }
        }
      );
      if (response.status !== 200) {
        console.error("Failed to fetch images:", response.status, response.text);
        continue;
      }
      const data = response.json;
      if (data.photos && data.photos.length > 0) {
        const randomIndex = Math.floor(Math.random() * data.photos.length);
        const imageUrl = data.photos[randomIndex].src[plugin.settings.imageSize];
        return imageUrl;
      }
    } catch (error) {
      console.error(`Error fetching image from Pexels for keyword "${currentKeyword}":`, error);
    }
  }
  return null;
}
async function fetchPixabayImage(plugin, keyword) {
  var _a;
  const apiKey = plugin.settings.pixabayApiKey;
  if (!apiKey) return null;
  const apiUrl = "https://pixabay.com/api/";
  const params = new URLSearchParams({
    key: apiKey,
    q: encodeURIComponent(keyword),
    image_type: "photo",
    per_page: plugin.settings.numberOfImages,
    safesearch: true
  });
  try {
    const response = await makeRequest(`${apiUrl}?${params}`);
    if (response.status !== 200) {
      return null;
    }
    let data;
    if (response.json) {
      data = response.json;
    } else if (response.arrayBuffer) {
      data = JSON.parse(new TextDecoder().decode(response.arrayBuffer));
    } else {
      return null;
    }
    if (((_a = data.hits) == null ? void 0 : _a.length) > 0) {
      const imageUrls = data.hits.map((hit) => hit.largeImageURL);
      return imageUrls[Math.floor(Math.random() * imageUrls.length)];
    }
    return null;
  } catch (error) {
    console.error(`Error fetching image from Pixabay for keyword "${keyword}":`, error);
    return null;
  }
}
async function fetchFlickrImage(plugin, keyword) {
  var _a, _b;
  const apiKey = plugin.settings.flickrApiKey;
  if (!apiKey) return null;
  try {
    const searchUrl = `https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=${apiKey}&text=${encodeURIComponent(keyword)}&per_page=${plugin.settings.numberOfImages}&format=json&nojsoncallback=1&sort=relevance&content_type=1&media=photos&safe_search=1`;
    const response = await makeRequest(searchUrl);
    if (response.status !== 200) {
      return null;
    }
    let data;
    if (response.text && response.text.includes("jsonFlickrApi(")) {
      const jsonpMatch = response.text.match(/jsonFlickrApi\((.*)\)/);
      if (jsonpMatch && jsonpMatch[1]) {
        try {
          data = JSON.parse(jsonpMatch[1]);
        } catch (e) {
          console.error("Error parsing JSONP response:", e);
          return null;
        }
      } else {
        console.error("Invalid JSONP format");
        return null;
      }
    } else {
      try {
        if (response.json) {
          data = response.json;
        } else if (response.arrayBuffer) {
          data = JSON.parse(new TextDecoder().decode(response.arrayBuffer));
        } else {
          return null;
        }
      } catch (e) {
        console.error("Error parsing JSON response:", e);
        return null;
      }
    }
    if (data.stat && data.stat !== "ok" || !((_b = (_a = data.photos) == null ? void 0 : _a.photo) == null ? void 0 : _b.length)) {
      return null;
    }
    const photos = data.photos.photo;
    const photo = photos[Math.floor(Math.random() * photos.length)];
    let size = "z";
    if (plugin.settings && plugin.settings.imageSize) {
      switch (plugin.settings.imageSize) {
        case "small":
          size = "n";
          break;
        case "medium":
          size = "z";
          break;
        case "large":
          size = "b";
          break;
        default:
          size = "z";
          break;
      }
    }
    return `https://live.staticflickr.com/${photo.server}/${photo.id}_${photo.secret}_${size}.jpg`;
  } catch (error) {
    console.error(`Error fetching image from Flickr for keyword "${keyword}":`, error);
    return null;
  }
}
async function fetchUnsplashImage(plugin, keyword) {
  var _a;
  const apiKey = plugin.settings.unsplashApiKey;
  if (!apiKey) return null;
  try {
    const apiUrl = "https://api.unsplash.com/search/photos";
    const params = new URLSearchParams({
      query: keyword,
      per_page: plugin.settings.numberOfImages,
      orientation: plugin.settings.imageOrientation
    });
    const response = await makeRequest(`${apiUrl}?${params}`, {
      headers: {
        "Authorization": `Client-ID ${apiKey}`,
        "Accept-Version": "v1"
      }
    });
    if (response.status !== 200) {
      return null;
    }
    let data;
    if (response.json) {
      data = response.json;
    } else if (response.arrayBuffer) {
      data = JSON.parse(new TextDecoder().decode(response.arrayBuffer));
    } else {
      return null;
    }
    if (!((_a = data.results) == null ? void 0 : _a.length)) {
      return null;
    }
    const photo = data.results[Math.floor(Math.random() * data.results.length)];
    return photo.urls[plugin.settings.imageSize === "small" ? "small" : plugin.settings.imageSize === "medium" ? "regular" : "full"];
  } catch (error) {
    console.error(`Error fetching image from Unsplash for keyword "${keyword}":`, error);
    return null;
  }
}

// src/services/apiPIxelBannerPlus.js
init_constants();
async function verifyPixelBannerPlusCredentials(plugin) {
  if (!plugin.settings.pixelBannerPlusEmail || !plugin.settings.pixelBannerPlusApiKey) {
    return { serverOnline: true, verified: false, bannerTokens: 0 };
  }
  try {
    const response = await makeRequest(
      `${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.VERIFY}`,
      {
        method: "GET",
        headers: {
          "X-User-Email": plugin.settings.pixelBannerPlusEmail,
          "X-API-Key": plugin.settings.pixelBannerPlusApiKey,
          "X-Pixel-Banner-Version": plugin.settings.lastVersion,
          "Accept": "application/json"
        }
      }
    );
    if (response.status === 200) {
      const data = response.json;
      return {
        serverOnline: true,
        verified: data.success,
        bannerTokens: data.banner_tokens,
        jackpot: data.jackpot,
        dailyGameName: data.daily_game,
        highScore: data.high_score,
        topUser: data.top_user,
        timeLeft: data.time_left
      };
    }
    return { serverOnline: true, verified: false, bannerTokens: 0, jackpot: 0, dailyGameName: "", highScore: 0, topUser: "", timeLeft: "0" };
  } catch (error) {
    console.error("Failed to verify Pixel Banner Plus credentials:", error);
    const errorMessage = error.message.toLowerCase();
    const errorName = error.name.toLowerCase();
    const isConnectionError = errorName === "typeerror" || errorName === "error" || errorMessage.includes("network error") || errorMessage.includes("failed to fetch") || errorMessage.includes("network") || errorMessage.startsWith("err_") || !navigator.onLine;
    const isUnauthorized = errorMessage.includes("401") || errorMessage.includes("unauthorized");
    console.log(`pixel banner plus error.message: ${error.message}`);
    console.log(`pixel banner plus isConnectionError: ${isConnectionError}`);
    console.log(`pixel banner plus isUnauthorized: ${isUnauthorized}`);
    return {
      serverOnline: !isConnectionError || isUnauthorized,
      verified: false,
      bannerTokens: 0,
      jackpot: 0,
      dailyGameName: "",
      highScore: 0,
      topUser: "",
      timeLeft: "0"
    };
  }
}
async function getPixelBannerInfo() {
  try {
    const response = await makeRequest(
      `${PIXEL_BANNER_PLUS.API_URL}${PIXEL_BANNER_PLUS.ENDPOINTS.INFO}`,
      {
        method: "GET"
      }
    );
    if (response.status === 200) {
      const data = response.json;
      return {
        version: data.version
      };
    }
  } catch (error) {
    console.error("Failed to get Pixel Banner Plus info:", error);
  }
  return { version: "0.0.0" };
}

// src/core/bannerManager.js
var import_obsidian27 = require("obsidian");
init_modals();
init_frontmatterUtils();
init_handlePinIconClick();
init_flags();

// src/utils/debounce.js
function debounceFunction(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}
function debounceAndSwallow(func, wait) {
  let lastCallTime = 0;
  return function executedFunction(...args) {
    const now = Date.now();
    if (now - lastCallTime >= wait) {
      lastCallTime = now;
      return func(...args);
    }
  };
}

// src/core/bannerManager.js
var markdownPostProcessorDebounceMap = /* @__PURE__ */ new Map();
var MARKDOWN_PROCESSOR_DEBOUNCE_DELAY = 200;
var updateBannerDebounceMap = /* @__PURE__ */ new Map();
var UPDATE_BANNER_DEBOUNCE_DELAY = 250;
var SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg", "avif"];
var SUPPORTED_MOVIE_EXTENSIONS = ["mp4", "mov"];
var SUPPORTED_EXTENSIONS = [...SUPPORTED_IMAGE_EXTENSIONS, ...SUPPORTED_MOVIE_EXTENSIONS];
var debouncedAddPixelBanner = debounceAndSwallow(addPixelBanner, 350);
async function addPixelBanner(plugin, el, ctx) {
  var _a, _b, _c;
  const { frontmatter, file, isContentChange, yPosition, xPosition, contentStartPosition, bannerImage, isReadingView, updateMode } = ctx;
  const viewContent = el;
  const isEmbedded = viewContent.classList.contains("internal-embed") && viewContent.classList.contains("markdown-embed");
  const isHoverPopover = viewContent.closest(".hover-popover") !== null;
  const hideEmbeddedNoteBanners = getFrontmatterValue(frontmatter, plugin.settings.customHideEmbeddedNoteBannersField) || ((_a = plugin.getFolderSpecificImage(file.path)) == null ? void 0 : _a.hideEmbeddedNoteBanners) || plugin.settings.hideEmbeddedNoteBanners || false;
  if (!isEmbedded && !isHoverPopover && viewContent.classList.contains("view-content")) {
    const sourceEl = viewContent.querySelector(":scope > .markdown-source-view .cm-sizer");
    if (sourceEl) {
      sourceEl.style.paddingTop = "var(--pixel-banner-content-start, 355px)";
      sourceEl.style.paddingBottom = "0px !important";
    }
    const previewEl = viewContent.querySelector(":scope > .markdown-reading-view .markdown-preview-sizer");
    if (previewEl) {
      previewEl.style.paddingTop = "var(--pixel-banner-content-start, 355px)";
      previewEl.style.paddingBottom = "0px !important";
    }
    viewContent.classList.add("pixel-banner");
    plugin.setupResizeObserver(viewContent);
    plugin.applyBannerWidth(viewContent);
  } else if (isEmbedded) {
    viewContent.classList.add("pixel-banner");
    plugin.applyContentStartPosition(viewContent, contentStartPosition);
    const embedContentDiv = viewContent.querySelector(":scope > .markdown-embed-content");
    if (embedContentDiv && !hideEmbeddedNoteBanners) {
      const previewViewEl = embedContentDiv.querySelector(":scope > .markdown-preview-view");
      if (previewViewEl) {
        const folderSpecific = plugin.getFolderSpecificImage(file.path);
        const maxWidth = getFrontmatterValue(frontmatter, plugin.settings.customBannerMaxWidthField) || (folderSpecific == null ? void 0 : folderSpecific.bannerMaxWidth) || plugin.settings.bannerMaxWidth || "unset";
        const maxWidthValue = maxWidth === "unset" ? "unset" : `${maxWidth}px`;
        const bannerYPosition = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customYPositionField),
          folderSpecific == null ? void 0 : folderSpecific.bannerYPosition,
          plugin.settings.bannerYPosition,
          0
        ]);
        const bannerXPosition = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customXPositionField),
          folderSpecific == null ? void 0 : folderSpecific.bannerXPosition,
          plugin.settings.bannerXPosition,
          0
        ]);
        const bannerTitleColor = getFrontmatterValue(frontmatter, plugin.settings.customTitleColorField) || (folderSpecific == null ? void 0 : folderSpecific.titleColor) || plugin.settings.titleColor || "var(--inline-title-color)";
        previewViewEl.style.setProperty("--pixel-banner-y-position", `${bannerYPosition}%`);
        previewViewEl.style.setProperty("--pixel-banner-x-position", `${bannerXPosition}%`);
        previewViewEl.style.setProperty("--pixel-banner-max-width", maxWidthValue);
        previewViewEl.style.setProperty("--pixel-banner-title-color", bannerTitleColor);
        const bannerIconSize = getFrontmatterValue(frontmatter, plugin.settings.customBannerIconSizeField) || (folderSpecific == null ? void 0 : folderSpecific.bannerIconSize) || plugin.settings.bannerIconSize || 70;
        const bannerIconXPosition = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconXPositionField),
          folderSpecific == null ? void 0 : folderSpecific.bannerIconXPosition,
          plugin.settings.bannerIconXPosition,
          25
        ]);
        const bannerIconOpacity = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconOpacityField),
          folderSpecific == null ? void 0 : folderSpecific.bannerIconOpacity,
          plugin.settings.bannerIconOpacity,
          100
        ]);
        const bannerIconColor = getFrontmatterValue(frontmatter, plugin.settings.customBannerIconColorField) || (folderSpecific == null ? void 0 : folderSpecific.bannerIconColor) || plugin.settings.bannerIconColor || "var(--text-normal)";
        const bannerIconFontWeight = getFrontmatterValue(frontmatter, plugin.settings.customBannerIconFontWeightField) || (folderSpecific == null ? void 0 : folderSpecific.bannerIconFontWeight) || plugin.settings.bannerIconFontWeight || "normal";
        const bannerIconBackgroundColor = getFrontmatterValue(frontmatter, plugin.settings.customBannerIconBackgroundColorField) || (folderSpecific == null ? void 0 : folderSpecific.bannerIconBackgroundColor) || plugin.settings.bannerIconBackgroundColor || "transparent";
        const bannerIconPaddingX = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconPaddingXField),
          folderSpecific == null ? void 0 : folderSpecific.bannerIconPaddingX,
          plugin.settings.bannerIconPaddingX,
          10
        ]);
        const bannerIconPaddingY = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconPaddingYField),
          folderSpecific == null ? void 0 : folderSpecific.bannerIconPaddingY,
          plugin.settings.bannerIconPaddingY,
          10
        ]);
        const bannerIconBorderRadius = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconBorderRadiusField),
          folderSpecific == null ? void 0 : folderSpecific.bannerIconBorderRadius,
          plugin.settings.bannerIconBorderRadius,
          17
        ]);
        const bannerIconVerticalOffset = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconVerticalOffsetField),
          folderSpecific == null ? void 0 : folderSpecific.bannerIconVerticalOffset,
          plugin.settings.bannerIconVerticalOffset,
          0
        ]);
        const bannerIconRotate = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconRotateField),
          0
        ]);
        const bannerIconImageSizeMultiplier = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconImageSizeMultiplierField),
          plugin.settings.bannerIconImageSizeMultiplier,
          1
        ]);
        const bannerIconTextVerticalOffset = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconTextVerticalOffsetField),
          plugin.settings.bannerIconTextVerticalOffset,
          0
        ]);
        previewViewEl.style.setProperty("--pixel-banner-icon-size", `${bannerIconSize}px`);
        previewViewEl.style.setProperty("--pixel-banner-icon-x", `${bannerIconXPosition}%`);
        previewViewEl.style.setProperty("--pixel-banner-icon-opacity", `${bannerIconOpacity}%`);
        previewViewEl.style.setProperty("--pixel-banner-icon-color", bannerIconColor);
        previewViewEl.style.setProperty("--pixel-banner-icon-font-weight", bannerIconFontWeight);
        previewViewEl.style.setProperty("--pixel-banner-icon-background-color", bannerIconBackgroundColor);
        previewViewEl.style.setProperty("--pixel-banner-icon-padding-x", `${bannerIconPaddingX}px`);
        previewViewEl.style.setProperty("--pixel-banner-icon-padding-y", `${bannerIconPaddingY}px`);
        previewViewEl.style.setProperty("--pixel-banner-icon-border-radius", `${bannerIconBorderRadius}px`);
        previewViewEl.style.setProperty("--pixel-banner-icon-vertical-offset", `${bannerIconVerticalOffset}px`);
        previewViewEl.style.setProperty("--pixel-banner-icon-rotate", `${bannerIconRotate}deg`);
        previewViewEl.style.setProperty("--pixel-banner-icon-image-size-multiplier", `${bannerIconImageSizeMultiplier}em`);
        previewViewEl.style.setProperty("--pixel-banner-icon-text-vertical-offset", `${bannerIconTextVerticalOffset}px`);
        const bannerHeight = getFrontmatterValue(frontmatter, plugin.settings.customBannerHeightField) || (folderSpecific == null ? void 0 : folderSpecific.bannerHeight) || plugin.settings.bannerHeight || 150;
        const embedMinHeight = `${parseInt(bannerHeight) + parseInt(bannerIconSize) / 2}px`;
        previewViewEl.style.setProperty("--pixel-banner-embed-min-height", embedMinHeight);
        previewViewEl.style.setProperty("--pixel-banner-height", `${bannerHeight}px`);
        const bannerFade = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerFadeField),
          folderSpecific == null ? void 0 : folderSpecific.bannerFade,
          plugin.settings.fade,
          -75
        ]);
        previewViewEl.style.setProperty("--pixel-banner-fade", `${bannerFade}%`);
        const bannerRadius = getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBorderRadiusField),
          folderSpecific == null ? void 0 : folderSpecific.borderRadius,
          plugin.settings.borderRadius,
          17
        ]);
        previewViewEl.style.setProperty("--pixel-banner-radius", `${bannerRadius}px`);
        const bannerAlignment = getFrontmatterValue(frontmatter, plugin.settings.customBannerAlignmentField) || "center";
        let alignmentValue = "0 auto";
        if (bannerAlignment === "left") {
          alignmentValue = "0 auto 0 0";
        } else if (bannerAlignment === "right") {
          alignmentValue = "0 0 0 auto";
        }
        previewViewEl.style.setProperty("--pixel-banner-alignment", alignmentValue);
        previewViewEl.style.setProperty("--pixel-banner-icon-start", `${bannerHeight - bannerIconSize / 2}px`);
        const contentStart = !hideEmbeddedNoteBanners ? `${parseInt(bannerHeight) + parseInt(bannerIconSize) / 2 + parseInt(bannerIconVerticalOffset) + parseInt(bannerIconPaddingY)}px` : "0px";
        previewViewEl.style.setProperty("--pixel-banner-content-start", contentStart);
      }
    }
  } else if (isHoverPopover && plugin.settings.showBannerInPopoverPreviews) {
    const previewEl = viewContent.querySelector(".markdown-preview-view");
    if (previewEl) {
      previewEl.classList.add("pixel-banner");
      plugin.setupResizeObserver(previewEl);
      plugin.applyBannerWidth(previewEl);
    }
  }
  let container;
  if (isEmbedded) {
    container = viewContent.querySelector(".markdown-preview-sizer");
    if (!container) {
      container = viewContent.querySelector(".markdown-embed-content");
    }
    if (!container) {
      container = viewContent;
    }
  } else if (isHoverPopover && plugin.settings.showBannerInPopoverPreviews) {
    container = viewContent.querySelector(".markdown-preview-sizer") || viewContent.querySelector(".markdown-preview-view");
    if (!container) {
      if (viewContent.classList.contains("markdown-preview-view")) {
        container = viewContent;
      } else if (viewContent.parentElement && viewContent.parentElement.classList.contains("markdown-preview-view")) {
        container = viewContent.parentElement;
      }
    }
  } else {
    container = isReadingView ? viewContent.querySelector(".markdown-preview-sizer:not(.internal-embed .markdown-preview-sizer)") || viewContent.querySelector(".markdown-preview-view") : viewContent.querySelector(".cm-sizer") || viewContent.querySelector(".markdown-source-view");
    if (!container && viewContent.classList.contains("markdown-preview-view")) {
      container = viewContent;
    }
  }
  if (!container) {
    return;
  }
  let bannerDiv = container.querySelector(":scope > .pixel-banner-image");
  if (!bannerDiv) {
    bannerDiv = createDiv({ cls: "pixel-banner-image" });
    container.insertBefore(bannerDiv, container.firstChild);
    bannerDiv._isPersistentBanner = true;
  }
  const oldViewIcons = container.querySelectorAll(".view-image-icon");
  const oldPinIcons = container.querySelectorAll(".pin-icon");
  const oldRefreshIcons = container.querySelectorAll(".refresh-icon");
  const oldSelectIcons = container.querySelectorAll(".select-image-icon");
  [...oldViewIcons, ...oldPinIcons, ...oldRefreshIcons, ...oldSelectIcons].forEach((el2) => el2.remove());
  if (isEmbedded || isHoverPopover) {
    plugin.updateEmbeddedBannersVisibility();
  } else {
    let leftOffset = plugin.settings.bannerGap + 15;
    if (plugin.settings.showSelectImageIcon) {
      const opacity = plugin.settings.selectImageIconOpacity / 100;
      const selectImageIcon = createDiv({
        cls: "select-image-icon",
        attr: {
          style: `
                        position: absolute;
                        top: 10px;
                        left: ${leftOffset}px;
                        font-size: 1.8em;
                        cursor: pointer;
                        opacity: ${opacity};
                    `
        }
      });
      const flagColor = getFrontmatterValue(frontmatter, plugin.settings.customFlagColorField) || plugin.settings.selectImageIconFlag;
      selectImageIcon.innerHTML = `<img src="${flags[flagColor] || flags["red"]}" alt="Select Banner" style="width: 25px; height: 30px;">`;
      selectImageIcon._isPersistentSelectImage = true;
      selectImageIcon.onclick = () => plugin.handleBannerIconClick();
      container.appendChild(selectImageIcon);
      leftOffset += 35;
    }
    if (bannerImage && plugin.settings.showViewImageIcon && !isEmbedded) {
      const viewImageIcon = createDiv({
        cls: "view-image-icon",
        attr: {
          style: `
                        display: none;
                        position: absolute;
                        top: 10px;
                        left: ${leftOffset}px;
                        font-size: 1.5em;
                        cursor: pointer;
                    `
        }
      });
      viewImageIcon.innerHTML = "\u{1F5BC}\uFE0F";
      viewImageIcon._isPersistentViewImage = true;
      viewImageIcon.innerHTML = "\u{1F5BC}\uFE0F";
      viewImageIcon._updateVisibility = (newUrl, originalPath) => {
        viewImageIcon.style.display = newUrl ? "block" : "none";
        if (newUrl) {
          viewImageIcon.onclick = () => {
            new ImageViewModal(plugin.app, newUrl, originalPath).open();
          };
        }
      };
      container.appendChild(viewImageIcon);
      leftOffset += 35;
    }
    const activeFile = plugin.app.workspace.getActiveFile();
    const hasBanner = activeFile && plugin.hasBannerFrontmatter(activeFile);
  }
  if (!container._hasOverriddenSetChildrenInPlace) {
    const originalSetChildrenInPlace = container.setChildrenInPlace;
    container.setChildrenInPlace = function(children) {
      const bannerElement = this.querySelector(":scope > .pixel-banner-image");
      const viewImageElement = this.querySelector(":scope > .view-image-icon");
      const pinElement = this.querySelector(":scope > .pin-icon");
      const refreshElement = this.querySelector(":scope > .refresh-icon");
      const selectImageElement = this.querySelector(":scope > .select-image-icon");
      const bannerIconOverlay = this.querySelector(":scope > .banner-icon-overlay");
      children = Array.from(children).filter(
        (child) => {
          var _a2, _b2, _c2, _d, _e, _f;
          return !((_a2 = child.classList) == null ? void 0 : _a2.contains("pixel-banner-image")) && !((_b2 = child.classList) == null ? void 0 : _b2.contains("view-image-icon")) && !((_c2 = child.classList) == null ? void 0 : _c2.contains("pin-icon")) && !((_d = child.classList) == null ? void 0 : _d.contains("refresh-icon")) && !((_e = child.classList) == null ? void 0 : _e.contains("select-image-icon")) && !((_f = child.classList) == null ? void 0 : _f.contains("banner-icon-overlay"));
        }
      );
      if (bannerElement == null ? void 0 : bannerElement._isPersistentBanner) {
        children.unshift(bannerElement);
      }
      if (bannerIconOverlay == null ? void 0 : bannerIconOverlay._isPersistentBannerIcon) {
        children.push(bannerIconOverlay);
      }
      if (selectImageElement == null ? void 0 : selectImageElement._isPersistentSelectImage) {
        children.push(selectImageElement);
      }
      if (viewImageElement == null ? void 0 : viewImageElement._isPersistentViewImage) {
        children.push(viewImageElement);
      }
      if (pinElement == null ? void 0 : pinElement._isPersistentPin) {
        children.push(pinElement);
      }
      if (refreshElement == null ? void 0 : refreshElement._isPersistentRefresh) {
        children.push(refreshElement);
      }
      return originalSetChildrenInPlace.call(this, children);
    };
    container._hasOverriddenSetChildrenInPlace = true;
  }
  if (bannerImage) {
    let imageUrl = plugin.loadedImages.get(file.path);
    const lastInput = plugin.lastKeywords.get(file.path);
    const inputType = plugin.getInputType(bannerImage, file.path);
    const folderSpecific = plugin.getFolderSpecificImage(file.path);
    const hasShufflePath = getFrontmatterValue(frontmatter, plugin.settings.customBannerShuffleField);
    const isShuffled = hasShufflePath || (folderSpecific == null ? void 0 : folderSpecific.enableImageShuffle);
    const effectiveUpdateMode = updateMode || plugin.UPDATE_MODE.FULL_UPDATE;
    let shouldFetchNewImage = false;
    if (effectiveUpdateMode === plugin.UPDATE_MODE.ENSURE_VISIBILITY) {
      shouldFetchNewImage = !imageUrl;
    } else {
      shouldFetchNewImage = effectiveUpdateMode === plugin.UPDATE_MODE.FULL_UPDATE || !imageUrl || isShuffled || isContentChange && bannerImage !== lastInput;
    }
    if (shouldFetchNewImage) {
      imageUrl = await plugin.getImageUrl(inputType, bannerImage, file.path);
      if (imageUrl) {
        plugin.loadedImages.set(file.path, imageUrl);
        plugin.lastKeywords.set(file.path, bannerImage);
      }
    }
    if (imageUrl) {
      const imageDisplay = getFrontmatterValue(frontmatter, plugin.settings.customImageDisplayField) || (folderSpecific == null ? void 0 : folderSpecific.imageDisplay) || plugin.settings.imageDisplay;
      const imageRepeat = getFrontmatterValue(frontmatter, plugin.settings.customImageRepeatField) || (folderSpecific == null ? void 0 : folderSpecific.imageRepeat) || plugin.settings.imageRepeat;
      let isVideoFile = false;
      let fileUrl = "";
      if (typeof imageUrl === "object" && imageUrl !== null) {
        isVideoFile = imageUrl.isVideo === true;
        fileUrl = imageUrl.url;
      } else {
        fileUrl = imageUrl;
        if (typeof fileUrl === "string" && fileUrl.includes("/media-attachment/") && (fileUrl.toLowerCase().endsWith(".mp4") || fileUrl.toLowerCase().endsWith(".mov"))) {
          isVideoFile = true;
        }
      }
      const isSvg = fileUrl.includes("image/svg+xml") || file.path && file.path.toLowerCase().endsWith(".svg");
      if (fileUrl.startsWith("blob:")) {
        try {
          const response = await fetch(fileUrl);
          if (!response.ok) {
            throw new Error("Blob URL validation failed");
          }
        } catch (error) {
          console.log("Blob URL invalid, refreshing file:", error);
          plugin.loadedImages.delete(file.path);
          URL.revokeObjectURL(fileUrl);
          const inputType2 = plugin.getInputType(bannerImage, file.path);
          const freshResult = await plugin.getImageUrl(inputType2, bannerImage, file.path);
          if (freshResult) {
            if (typeof freshResult === "object" && freshResult !== null) {
              isVideoFile = freshResult.isVideo === true;
              fileUrl = freshResult.url;
            } else {
              fileUrl = freshResult;
            }
            plugin.loadedImages.set(file.path, fileUrl);
          }
        }
      }
      if (isVideoFile) {
        bannerDiv.style.backgroundImage = "";
        const existingVideo = bannerDiv.querySelector("video");
        if (existingVideo) {
          existingVideo.remove();
        }
        const videoEl = document.createElement("video");
        videoEl.className = "pixel-banner-video";
        videoEl.src = fileUrl;
        videoEl.autoplay = true;
        videoEl.loop = true;
        videoEl.muted = true;
        videoEl.playsInline = true;
        videoEl.style.width = "100%";
        videoEl.style.height = "100%";
        videoEl.style.objectFit = imageDisplay || "cover";
        videoEl.style.position = "absolute";
        videoEl.style.top = "0";
        videoEl.style.left = "0";
        bannerDiv.appendChild(videoEl);
      } else {
        const existingVideo = bannerDiv.querySelector("video");
        if (existingVideo) {
          existingVideo.remove();
        }
        bannerDiv.style.backgroundImage = `url('${fileUrl}')`;
        if (isSvg) {
          bannerDiv.style.backgroundSize = imageDisplay === "contain" ? "contain" : "100% 100%";
        } else {
          bannerDiv.style.backgroundSize = imageDisplay || "cover";
        }
        bannerDiv.style.backgroundRepeat = imageRepeat ? "repeat" : "no-repeat";
      }
      bannerDiv.style.display = "block";
      if (isEmbedded) {
        bannerDiv.style.setProperty("--pixel-banner-image", `url('${imageUrl}')`);
      }
      const viewImageIcon = container.querySelector(":scope > .view-image-icon");
      if (viewImageIcon && viewImageIcon._updateVisibility) {
        const bannerValue = getFrontmatterValue(frontmatter, plugin.settings.customBannerField);
        let displayUrl = bannerValue || file.path;
        if (inputType === "keyword") {
          if (imageUrl && typeof imageUrl === "object" && imageUrl.url) {
            displayUrl = imageUrl.url;
          } else if (imageUrl && typeof imageUrl === "string") {
            displayUrl = imageUrl;
          }
        }
        viewImageIcon._updateVisibility(imageUrl, displayUrl);
      }
      plugin.applyBannerSettings(bannerDiv, ctx, isEmbedded);
      const hideEmbeddedNoteBanners2 = getFrontmatterValue(frontmatter, plugin.settings.customHideEmbeddedNoteBannersField) || (folderSpecific == null ? void 0 : folderSpecific.hideEmbeddedNoteBanners) || plugin.settings.hideEmbeddedNoteBanners || false;
      let effectiveContentStart = 0;
      if (!hideEmbeddedNoteBanners2 || !isEmbedded) {
        const frontmatterContentStart = getFrontmatterValue(frontmatter, plugin.settings.customContentStartField);
        const parsedFrontmatterStart = frontmatterContentStart ? Number(frontmatterContentStart) : null;
        effectiveContentStart = (_c = (_b = parsedFrontmatterStart != null ? parsedFrontmatterStart : contentStartPosition) != null ? _b : folderSpecific == null ? void 0 : folderSpecific.contentStartPosition) != null ? _c : plugin.settings.contentStartPosition;
      }
      plugin.applyContentStartPosition(viewContent, effectiveContentStart);
      plugin.applyBannerWidth(viewContent);
      const canPin = (inputType === "keyword" || inputType === "url") && plugin.settings.showPinIcon && !isEmbedded && !isHoverPopover;
      if (canPin) {
        let leftOffset = plugin.settings.bannerGap + 5;
        const iconEls = container.querySelectorAll(".select-image-icon, .view-image-icon");
        if (iconEls == null ? void 0 : iconEls.length) {
          leftOffset = 10 + 35 * iconEls.length + plugin.settings.bannerGap;
        }
        const pinIcon = createDiv({ cls: "pin-icon" });
        pinIcon.style.position = "absolute";
        pinIcon.style.top = "10px";
        pinIcon.style.left = `${leftOffset}px`;
        pinIcon.style.fontSize = "1.5em";
        pinIcon.style.cursor = "pointer";
        pinIcon.innerHTML = "\u{1F4CC}";
        pinIcon._isPersistentPin = true;
        pinIcon.onclick = async () => {
          try {
            const currentImage = plugin.loadedImages.get(file.path);
            if (!currentImage) {
              new import_obsidian27.Notice("Could not find the current image URL to pin.");
              console.error("Error pinning image: currentImage is null or undefined for file.path:", file.path);
              return;
            }
            const imageUrlToPin = typeof currentImage === "object" && currentImage.url ? currentImage.url : currentImage;
            await handlePinIconClick(imageUrlToPin, plugin);
          } catch (error) {
            console.error("Error pinning image:", error);
            new import_obsidian27.Notice("Failed to pin the image.");
          }
        };
        container.appendChild(pinIcon);
        leftOffset += 35;
        if (inputType === "keyword" && plugin.settings.showRefreshIcon) {
          const refreshIcon = createDiv({
            cls: "refresh-icon",
            attr: {
              style: `
                                position: absolute;
                                top: 10px;
                                left: ${leftOffset}px;
                                font-size: 1.5em;
                                cursor: pointer;
                            `
            }
          });
          refreshIcon.innerHTML = "\u{1F504}";
          refreshIcon._isPersistentRefresh = true;
          refreshIcon.onclick = async () => {
            try {
              plugin.loadedImages.delete(file.path);
              plugin.lastKeywords.delete(file.path);
              const originalBannerValue = getFrontmatterValue(frontmatter, plugin.settings.customBannerField);
              const result = await plugin.getImageUrl(inputType, originalBannerValue || bannerImage, file.path);
              if (result) {
                let isVideoFile2 = false;
                let fileUrl2 = "";
                if (typeof result === "object" && result !== null) {
                  isVideoFile2 = result.isVideo === true;
                  fileUrl2 = result.url;
                } else {
                  fileUrl2 = result;
                }
                plugin.loadedImages.set(file.path, fileUrl2);
                plugin.lastKeywords.set(file.path, bannerImage);
                if (isVideoFile2) {
                  bannerDiv.style.backgroundImage = "";
                  const existingVideo = bannerDiv.querySelector("video");
                  if (existingVideo) {
                    existingVideo.remove();
                  }
                  const videoEl = document.createElement("video");
                  videoEl.className = "pixel-banner-video";
                  videoEl.src = fileUrl2;
                  videoEl.autoplay = true;
                  videoEl.loop = true;
                  videoEl.muted = true;
                  videoEl.playsInline = true;
                  videoEl.style.width = "100%";
                  videoEl.style.height = "100%";
                  videoEl.style.objectFit = "cover";
                  videoEl.style.position = "absolute";
                  videoEl.style.top = "0";
                  videoEl.style.left = "0";
                  bannerDiv.appendChild(videoEl);
                } else {
                  bannerDiv.style.backgroundImage = `url('${fileUrl2}')`;
                  const existingVideo = bannerDiv.querySelector("video");
                  if (existingVideo) {
                    existingVideo.remove();
                  }
                }
                const viewImageIcon2 = container.querySelector(":scope > .view-image-icon");
                if (viewImageIcon2 && viewImageIcon2._updateVisibility) {
                  const bannerValue = getFrontmatterValue(frontmatter, plugin.settings.customBannerField);
                  let displayUrl = bannerValue || file.path;
                  const refreshInputType = plugin.getInputType(bannerValue, file.path);
                  if (refreshInputType === "keyword") {
                    if (fileUrl2 && typeof fileUrl2 === "object" && fileUrl2.url) {
                      displayUrl = fileUrl2.url;
                    } else if (fileUrl2 && typeof fileUrl2 === "string") {
                      displayUrl = fileUrl2;
                    }
                  }
                  viewImageIcon2._updateVisibility(fileUrl2, displayUrl);
                }
                new import_obsidian27.Notice("\u{1F504} Refreshed banner");
              }
            } catch (error) {
              console.error("Error refreshing banner:", error);
              new import_obsidian27.Notice("Failed to refresh the banner.");
            }
          };
          container.appendChild(refreshIcon);
        }
      }
    } else {
      bannerDiv.style.display = "none";
      plugin.loadedImages.delete(file.path);
      plugin.lastKeywords.delete(file.path);
      if (!isEmbedded) {
        viewContent.classList.remove("pixel-banner");
      }
    }
  }
}
var debouncedUpdateBanner = debounceFunction(updateBanner, 50);
async function updateBanner(plugin, view, isContentChange, updateMode = plugin.UPDATE_MODE.FULL_UPDATE) {
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
  if (!view || !view.file) {
    return;
  }
  const filePath = view.file.path;
  const currentTime = Date.now();
  const lastUpdateTime = updateBannerDebounceMap.get(filePath);
  if (lastUpdateTime && currentTime - lastUpdateTime < UPDATE_BANNER_DEBOUNCE_DELAY) {
    return;
  }
  updateBannerDebounceMap.set(filePath, currentTime);
  if (!isContentChange) {
    await new Promise((resolve) => setTimeout(resolve, 50));
  }
  const frontmatter = (_a = plugin.app.metadataCache.getFileCache(view.file)) == null ? void 0 : _a.frontmatter;
  const contentEl = view.contentEl;
  const isEmbedded = contentEl.classList.contains("internal-embed") && contentEl.classList.contains("markdown-embed");
  const isHoverPopover = contentEl.closest(".hover-popover") !== null;
  const viewContent = contentEl;
  const nonPersistentOverlays = viewContent.querySelectorAll('.banner-icon-overlay:not([data-persistent="true"])');
  nonPersistentOverlays.forEach((overlay) => overlay.remove());
  ["markdown-preview-sizer", "cm-sizer"].forEach((container) => {
    const containerEl = viewContent.querySelector(`.${container}`);
    if (containerEl) {
      const bannerImage2 = containerEl.querySelector(":scope > .pixel-banner-image");
      if (bannerImage2) {
        const allOverlays = containerEl.querySelectorAll(':scope > .banner-icon-overlay[data-persistent="true"]');
        allOverlays.forEach((overlay) => {
          if (overlay.previousElementSibling !== bannerImage2) {
            overlay.remove();
          }
        });
      }
    }
  });
  const existingBanner = contentEl.querySelector(".pixel-banner-image");
  const folderSpecific = plugin.getFolderSpecificImage(view.file.path);
  let bannerImage = null;
  const shufflePath = getFrontmatterValue(frontmatter, plugin.settings.customBannerShuffleField) || (folderSpecific == null ? void 0 : folderSpecific.enableImageShuffle);
  if (shufflePath && updateMode !== plugin.UPDATE_MODE.ENSURE_VISIBILITY) {
    const randomImagePath = await plugin.getRandomImageFromFolder(shufflePath);
    if (randomImagePath) {
      bannerImage = randomImagePath;
    }
  } else if (shufflePath && updateMode === plugin.UPDATE_MODE.ENSURE_VISIBILITY) {
    const cacheKey = plugin.generateCacheKey(view.file.path, plugin.app.workspace.activeLeaf.id, true);
    const cachedState = plugin.bannerStateCache.get(cacheKey);
    if ((_b = cachedState == null ? void 0 : cachedState.state) == null ? void 0 : _b.imageUrl) {
      bannerImage = cachedState.state.imageUrl;
    } else {
      const randomImagePath = await plugin.getRandomImageFromFolder(shufflePath);
      if (randomImagePath) {
        bannerImage = randomImagePath;
      }
    }
  }
  if (!bannerImage) {
    bannerImage = getFrontmatterValue(frontmatter, plugin.settings.customBannerField) || (folderSpecific == null ? void 0 : folderSpecific.image);
  }
  if (!isEmbedded && !bannerImage) {
    contentEl.classList.remove("pixel-banner");
    const previewSizer = contentEl.querySelector(".markdown-preview-sizer");
    if (previewSizer) {
      previewSizer.style.removeProperty("padding-top");
    }
    const sourceSizer = contentEl.querySelector(".cm-sizer");
    if (sourceSizer) {
      sourceSizer.style.removeProperty("padding-top");
    }
    if (existingBanner) {
      existingBanner.style.backgroundImage = "";
      existingBanner.style.display = "none";
    }
  } else if (isEmbedded && !bannerImage) {
    const embedRoot = viewContent.closest(".internal-embed.markdown-embed");
    if (embedRoot) {
      embedRoot.style.setProperty("--pixel-banner-embed-min-height", "1%");
      embedRoot.style.setProperty("--pixel-banner-content-start", "0");
    }
  }
  if (isContentChange) {
    plugin.loadedImages.delete(view.file.path);
    plugin.lastKeywords.delete(view.file.path);
  }
  let yPosition = (_c = folderSpecific == null ? void 0 : folderSpecific.yPosition) != null ? _c : plugin.settings.yPosition;
  let xPosition = (_d = folderSpecific == null ? void 0 : folderSpecific.xPosition) != null ? _d : plugin.settings.xPosition;
  let contentStartPosition = (_e = folderSpecific == null ? void 0 : folderSpecific.contentStartPosition) != null ? _e : plugin.settings.contentStartPosition;
  if (bannerImage) {
    if (Array.isArray(bannerImage)) {
      bannerImage = bannerImage.flat()[0];
    }
    if (typeof bannerImage === "string" && !bannerImage.startsWith("[[") && !bannerImage.startsWith("![[") && !bannerImage.startsWith("http")) {
      if (bannerImage.includes(",")) {
        const parts = bannerImage.split(",").map((p) => p.trim());
        const isFile = (str) => SUPPORTED_EXTENSIONS.some((ext) => str.toLowerCase().endsWith(`.${ext}`));
        const isKeyword = (str) => !str.includes(".");
        if (parts.length > 1 && (parts.every(isFile) || parts.every(isKeyword))) {
          const bannerValues = parts.filter((v) => v.length > 0);
          if (bannerValues.length > 0) {
            bannerImage = bannerValues[Math.floor(Math.random() * bannerValues.length)];
          } else {
            bannerImage = null;
          }
        }
      }
    }
    if (bannerImage && typeof bannerImage === "string" && !bannerImage.startsWith("[[") && !bannerImage.startsWith("![[") && !bannerImage.startsWith("http")) {
      const file = plugin.app.vault.getAbstractFileByPath(bannerImage);
      if (file && "extension" in file) {
        if (file.extension.match(/^(jpg|jpeg|png|gif|bmp|svg)$/i)) {
          bannerImage = `![[${bannerImage}]]`;
        }
      }
    }
  }
  let imageDisplay = getFrontmatterValue(frontmatter, plugin.settings.customImageDisplayField) || (folderSpecific == null ? void 0 : folderSpecific.imageDisplay) || plugin.settings.imageDisplay;
  let imageRepeat = (_g = (_f = getFrontmatterValue(frontmatter, plugin.settings.customImageRepeatField)) != null ? _f : folderSpecific == null ? void 0 : folderSpecific.imageRepeat) != null ? _g : plugin.settings.imageRepeat;
  let bannerHeight = (_i = (_h = getFrontmatterValue(frontmatter, plugin.settings.customBannerHeightField)) != null ? _h : folderSpecific == null ? void 0 : folderSpecific.bannerHeight) != null ? _i : plugin.settings.bannerHeight;
  let fade = (_k = (_j = getFrontmatterValue(frontmatter, plugin.settings.customFadeField)) != null ? _j : folderSpecific == null ? void 0 : folderSpecific.fade) != null ? _k : plugin.settings.fade;
  let borderRadius = (_m = (_l = getFrontmatterValue(frontmatter, plugin.settings.customBorderRadiusField)) != null ? _l : folderSpecific == null ? void 0 : folderSpecific.borderRadius) != null ? _m : plugin.settings.borderRadius;
  let maxWidth = getFrontmatterValue(frontmatter, plugin.settings.customBannerMaxWidthField) || (folderSpecific == null ? void 0 : folderSpecific.bannerMaxWidth) || "unset";
  if (bannerImage) {
    await addPixelBanner(plugin, contentEl, {
      frontmatter,
      file: view.file,
      isContentChange,
      yPosition,
      xPosition,
      contentStartPosition,
      bannerImage,
      imageDisplay,
      imageRepeat,
      bannerHeight,
      fade,
      borderRadius,
      maxWidth,
      isReadingView: view.getMode && view.getMode() === "preview",
      updateMode
    });
    plugin.lastYPositions.set(view.file.path, yPosition);
  } else if (existingBanner) {
    existingBanner.style.display = "none";
  }
  if (!isEmbedded) {
    const embeddedNotes = contentEl.querySelectorAll(".internal-embed.markdown-embed");
    for (const embed of embeddedNotes) {
      const embedSrc = embed.getAttribute("src");
      if (!embedSrc) continue;
      const embedFile = plugin.app.metadataCache.getFirstLinkpathDest(embedSrc, view.file.path);
      if (embedFile) {
        const embedView = {
          file: embedFile,
          contentEl: embed,
          getMode: () => "preview"
        };
        await updateBanner(plugin, embedView, false);
      }
    }
  }
  if (!bannerImage) {
    const viewContent2 = view.contentEl;
    const isReadingView = view.getMode && view.getMode() === "preview";
    let container = isReadingView ? viewContent2.querySelector(".markdown-preview-sizer:not(.internal-embed .markdown-preview-sizer)") || viewContent2.querySelector(".markdown-preview-view") : viewContent2.querySelector(".cm-sizer") || viewContent2.querySelector(".markdown-source-view");
    if (!container && viewContent2.classList.contains("markdown-preview-view")) {
      container = viewContent2;
    }
    if (container) {
      const oldViewIcons = container.querySelectorAll(".view-image-icon");
      const oldPinIcons = container.querySelectorAll(".pin-icon");
      const oldRefreshIcons = container.querySelectorAll(".refresh-icon");
      const oldSelectIcons = container.querySelectorAll(".select-image-icon");
      [...oldViewIcons, ...oldPinIcons, ...oldRefreshIcons, ...oldSelectIcons].forEach((el) => el.remove());
    }
    if (!isEmbedded && container && plugin.settings.showSelectImageIcon) {
      const opacity = plugin.settings.selectImageIconOpacity / 100;
      const existingSelectIcon = container.querySelector(".select-image-icon");
      if (!existingSelectIcon) {
        const selectImageIcon = createDiv({
          cls: "select-image-icon",
          attr: {
            style: `
                            position: absolute;
                            top: 10px;
                            left: ${plugin.settings.bannerGap + 5}px;
                            font-size: 1.8em;
                            cursor: pointer;
                            opacity: ${opacity};
                        `
          }
        });
        const flagColor = getFrontmatterValue(frontmatter, plugin.settings.customFlagColorField) || plugin.settings.selectImageIconFlag;
        selectImageIcon.innerHTML = `<img src="${flags[flagColor] || flags["red"]}" alt="Select Banner" style="width: 25px; height: 30px;">`;
        selectImageIcon._isPersistentSelectImage = true;
        selectImageIcon.onclick = () => plugin.handleBannerIconClick();
        container.insertBefore(selectImageIcon, container.firstChild);
      }
    }
    if (container) {
      const existingViewImageIcon = container.querySelector(".view-image-icon");
      if (existingViewImageIcon) {
        existingViewImageIcon.remove();
      }
    }
  }
  if (plugin.settings.hidePixelBannerFields && view.getMode() === "preview") {
    plugin.updateFieldVisibility(view);
  }
  const bannerIcon = getFrontmatterValue(frontmatter, plugin.settings.customBannerIconField);
  let bannerIconImage = getFrontmatterValue(frontmatter, plugin.settings.customBannerIconImageField);
  if (Array.isArray(bannerIconImage)) {
    bannerIconImage = bannerIconImage.flat()[0];
    if (bannerIconImage && !bannerIconImage.startsWith("[[") && !bannerIconImage.startsWith("![[")) {
      bannerIconImage = `[[${bannerIconImage}]]`;
    }
  }
  if (isEmbedded) {
    const embedContainer = contentEl.querySelector(".markdown-preview-sizer") || contentEl.querySelector(".markdown-embed-content") || contentEl;
    const thisEmbedOverlays = embedContainer.querySelectorAll(':scope > .banner-icon-overlay:not([data-persistent="true"])');
    thisEmbedOverlays.forEach((overlay) => overlay.remove());
  } else {
    ["markdown-preview-view", "markdown-source-view"].forEach((viewType) => {
      const viewContainer = contentEl.querySelector(`.${viewType}`);
      if (viewContainer) {
        const mainOverlays = viewContainer.querySelectorAll(':scope > .banner-icon-overlay:not([data-persistent="true"])');
        mainOverlays.forEach((overlay) => overlay.remove());
      }
    });
  }
  if ((!bannerIcon || typeof bannerIcon === "string" && !bannerIcon.trim()) && (!bannerIconImage || typeof bannerIconImage === "string" && !bannerIconImage.trim())) {
    if (isEmbedded) {
      const embedContainer = contentEl.querySelector(".markdown-preview-sizer") || contentEl.querySelector(".markdown-embed-content") || contentEl;
      const persistentOverlays = embedContainer.querySelectorAll(':scope > .banner-icon-overlay[data-persistent="true"]');
      persistentOverlays.forEach((overlay) => {
        plugin.returnIconOverlay(overlay);
        overlay.remove();
      });
    } else {
      const previewContainer = contentEl.querySelector("div.markdown-preview-sizer");
      const sourceContainer = contentEl.querySelector("div.cm-sizer");
      if (previewContainer) {
        const previewOverlays = previewContainer.querySelectorAll(':scope > .banner-icon-overlay[data-persistent="true"]');
        previewOverlays.forEach((overlay) => {
          plugin.returnIconOverlay(overlay);
          overlay.remove();
        });
      }
      if (sourceContainer) {
        const sourceOverlays = sourceContainer.querySelectorAll(':scope > .banner-icon-overlay[data-persistent="true"]');
        sourceOverlays.forEach((overlay) => {
          plugin.returnIconOverlay(overlay);
          overlay.remove();
        });
      }
    }
  }
  if (bannerIcon && typeof bannerIcon === "string" && bannerIcon.trim() || bannerIconImage && typeof bannerIconImage === "string" && bannerIconImage.trim()) {
    const cleanIcon = bannerIcon ? bannerIcon.trim() : "";
    const cacheKey = plugin.generateCacheKey(view.file.path, plugin.app.workspace.activeLeaf.id);
    const cachedState = plugin.bannerStateCache.get(cacheKey);
    const cachedIconState = (_n = cachedState == null ? void 0 : cachedState.state) == null ? void 0 : _n.iconState;
    const createOrUpdateIconOverlay = async (banner, viewType) => {
      var _a2, _b2;
      if (!banner) {
        return;
      }
      const currentIconState = {
        icon: cleanIcon,
        size: getFrontmatterValue(frontmatter, plugin.settings.customBannerIconSizeField) || plugin.settings.bannerIconSize,
        xPosition: getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconXPositionField),
          plugin.settings.bannerIconXPosition
        ]),
        opacity: getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconOpacityField),
          plugin.settings.bannerIconOpacity
        ]),
        color: getFrontmatterValue(frontmatter, plugin.settings.customBannerIconColorField) || plugin.settings.bannerIconColor,
        fontWeight: getFrontmatterValue(frontmatter, plugin.settings.customBannerIconFontWeightField) || plugin.settings.bannerIconFontWeight,
        backgroundColor: getFrontmatterValue(frontmatter, plugin.settings.customBannerIconBackgroundColorField) || plugin.settings.bannerIconBackgroundColor,
        paddingX: getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconPaddingXField),
          plugin.settings.bannerIconPaddingX
        ]),
        paddingY: getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconPaddingYField),
          plugin.settings.bannerIconPaddingY
        ]),
        borderRadius: getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconBorderRadiusField),
          plugin.settings.bannerIconBorderRadius
        ]),
        verticalOffset: getValueWithZeroCheck([
          getFrontmatterValue(frontmatter, plugin.settings.customBannerIconVerticalOffsetField),
          plugin.settings.bannerIconVerticalOffset
        ]),
        imageAlignment: getFrontmatterValue(frontmatter, plugin.settings.customBannerIconImageAlignmentField) || plugin.settings.bannerIconImageAlignment,
        viewType
      };
      const existingOverlay = ((_b2 = (_a2 = banner.nextElementSibling) == null ? void 0 : _a2.classList) == null ? void 0 : _b2.contains("banner-icon-overlay")) ? banner.nextElementSibling : null;
      if (existingOverlay) {
        if (!plugin.shouldUpdateIconOverlay(existingOverlay, currentIconState, viewType)) {
          return existingOverlay;
        }
        plugin.returnIconOverlay(existingOverlay);
      }
      const bannerIconOverlay = plugin.getIconOverlay();
      bannerIconOverlay.dataset.viewType = viewType;
      bannerIconOverlay.dataset.persistent = "true";
      bannerIconOverlay.textContent = "";
      bannerIconOverlay._isPersistentBannerIcon = true;
      bannerIconOverlay.innerHTML = "";
      const imageAlignment = currentIconState.imageAlignment === "right" ? "right" : "left";
      let imgElement = null;
      if (bannerIconImage) {
        const inputType = plugin.getIconImageInputType(bannerIconImage, view.file.path);
        let imagePath = null;
        let resolvedVaultPath = null;
        if (inputType === "invalid") {
          console.warn("Invalid banner icon image value detected:", bannerIconImage);
        } else {
          switch (inputType) {
            case "obsidianLink":
              const file = plugin.getPathFromObsidianLink(bannerIconImage);
              if (file) {
                imagePath = plugin.loadedImages.get(file.path);
                if (!imagePath) {
                  imagePath = await plugin.getVaultImageUrl(file.path);
                  if (imagePath) plugin.loadedImages.set(file.path, imagePath);
                }
              }
              break;
            case "markdownImage":
              const mdPath = plugin.getPathFromMarkdownImage(bannerIconImage);
              if (typeof mdPath === "string") {
                try {
                  new URL(mdPath);
                  imagePath = mdPath;
                } catch (_) {
                  imagePath = plugin.loadedImages.get(mdPath);
                  if (!imagePath) {
                    imagePath = await plugin.getVaultImageUrl(mdPath);
                    if (imagePath) plugin.loadedImages.set(mdPath, imagePath);
                  }
                }
              } else if (mdPath) {
                imagePath = plugin.loadedImages.get(mdPath.path);
                if (!imagePath) {
                  imagePath = await plugin.getVaultImageUrl(mdPath.path);
                  if (imagePath) plugin.loadedImages.set(mdPath.path, imagePath);
                }
              }
              break;
            case "vaultPath":
              const cleanedInput = bannerIconImage.trim().replace(/^["'](.*)["']$/, "$1");
              let resolvedFile = plugin.app.vault.getAbstractFileByPath(cleanedInput);
              if (!resolvedFile) {
                resolvedFile = plugin.app.metadataCache.getFirstLinkpathDest(cleanedInput, view.file.path);
              }
              if (resolvedFile && "path" in resolvedFile) {
                resolvedVaultPath = resolvedFile.path;
                imagePath = plugin.loadedImages.get(resolvedVaultPath);
                if (!imagePath) {
                  imagePath = await plugin.getVaultImageUrl(resolvedVaultPath);
                  if (imagePath) plugin.loadedImages.set(resolvedVaultPath, imagePath);
                }
              } else {
                console.warn("[Icon Image] Could not resolve vault path:", cleanedInput);
              }
              break;
            case "url":
              imagePath = bannerIconImage;
              break;
            case "fileUrl":
              console.warn("file:/// URLs are not supported for banner icon images");
              break;
            case "keyword":
              console.warn("Keywords are not supported for banner icon images");
              break;
          }
          if (imagePath) {
            imgElement = document.createElement("img");
            const imageUrl = typeof imagePath === "object" && imagePath.url ? imagePath.url : imagePath;
            imgElement.src = imageUrl;
            imgElement.className = "banner-icon-image";
          }
        }
      }
      let textElement = null;
      if (cleanIcon) {
        textElement = document.createElement("div");
        textElement.className = "banner-icon-text";
        textElement.textContent = cleanIcon;
      }
      if (imageAlignment === "right") {
        if (textElement) bannerIconOverlay.appendChild(textElement);
        if (imgElement) bannerIconOverlay.appendChild(imgElement);
      } else {
        if (imgElement) bannerIconOverlay.appendChild(imgElement);
        if (textElement) bannerIconOverlay.appendChild(textElement);
      }
      bannerIconOverlay.style.display = "block";
      bannerIconOverlay.style.fontSize = `${currentIconState.size}px`;
      bannerIconOverlay.style.left = `${currentIconState.xPosition}%`;
      bannerIconOverlay.style.opacity = `${currentIconState.opacity}%`;
      bannerIconOverlay.style.color = currentIconState.color;
      bannerIconOverlay.style.fontWeight = currentIconState.fontWeight;
      bannerIconOverlay.style.backgroundColor = currentIconState.backgroundColor;
      bannerIconOverlay.style.padding = `${currentIconState.paddingY}px ${currentIconState.paddingX}px`;
      bannerIconOverlay.style.borderRadius = `${currentIconState.borderRadius}px`;
      bannerIconOverlay.style.marginTop = `${currentIconState.verticalOffset}px`;
      banner.insertAdjacentElement("afterend", bannerIconOverlay);
      return bannerIconOverlay;
    };
    if (isEmbedded) {
      const embedContainer = contentEl.querySelector(".markdown-preview-sizer") || contentEl.querySelector(".markdown-embed-content") || contentEl;
      const previewBanner = embedContainer.querySelector(":scope > .pixel-banner-image");
      await createOrUpdateIconOverlay(previewBanner, "preview");
    } else {
      const previewContainer = contentEl.querySelector("div.markdown-preview-sizer");
      const sourceContainer = contentEl.querySelector("div.cm-sizer");
      if (previewContainer) {
        const previewBanner = previewContainer.querySelector(":scope > .pixel-banner-image");
        await createOrUpdateIconOverlay(previewBanner, "preview");
      }
      if (sourceContainer) {
        const sourceBanner = sourceContainer.querySelector(":scope > .pixel-banner-image");
        await createOrUpdateIconOverlay(sourceBanner, "source");
      }
    }
  }
}
var debouncedApplyBannerSettings = debounceAndSwallow(applyBannerSettings, 350);
function applyBannerSettings(plugin, bannerDiv, ctx, isEmbedded) {
  const { frontmatter, imageDisplay, imageRepeat, bannerHeight, fade, borderRadius, maxWidth } = ctx;
  const folderSpecific = plugin.getFolderSpecificImage(ctx.file.path);
  let pixelBannerYPosition = getValueWithZeroCheck([
    getFrontmatterValue(frontmatter, plugin.settings.customYPositionField),
    folderSpecific == null ? void 0 : folderSpecific.yPosition,
    plugin.settings.yPosition
  ]);
  let pixelBannerXPosition = getValueWithZeroCheck([
    getFrontmatterValue(frontmatter, plugin.settings.customXPositionField),
    folderSpecific == null ? void 0 : folderSpecific.xPosition,
    plugin.settings.xPosition
  ]);
  const pixelBannerMaxWidth = getFrontmatterValue(frontmatter, plugin.settings.customBannerMaxWidthField) || (folderSpecific == null ? void 0 : folderSpecific.bannerMaxWidth) || plugin.settings.bannerMaxWidth || "unset";
  const titleColor = getFrontmatterValue(frontmatter, plugin.settings.customTitleColorField) || (folderSpecific == null ? void 0 : folderSpecific.titleColor) || plugin.settings.titleColor;
  const bannerIconSize = getFrontmatterValue(frontmatter, plugin.settings.customBannerIconSizeField) || (folderSpecific == null ? void 0 : folderSpecific.bannerIconSize) || plugin.settings.bannerIconSize || 70;
  const bannerIconXPosition = getValueWithZeroCheck([
    getFrontmatterValue(frontmatter, plugin.settings.customBannerIconXPositionField),
    folderSpecific == null ? void 0 : folderSpecific.bannerIconXPosition,
    plugin.settings.bannerIconXPosition,
    25
  ]);
  const bannerIconOpacity = getValueWithZeroCheck([
    getFrontmatterValue(frontmatter, plugin.settings.customBannerIconOpacityField),
    folderSpecific == null ? void 0 : folderSpecific.bannerIconOpacity,
    plugin.settings.bannerIconOpacity,
    100
  ]);
  const bannerIconColor = getFrontmatterValue(frontmatter, plugin.settings.customBannerIconColorField) || (folderSpecific == null ? void 0 : folderSpecific.bannerIconColor) || plugin.settings.bannerIconColor || "var(--text-normal)";
  const bannerIconFontWeight = getFrontmatterValue(frontmatter, plugin.settings.customBannerIconFontWeightField) || (folderSpecific == null ? void 0 : folderSpecific.bannerIconFontWeight) || plugin.settings.bannerIconFontWeight || "normal";
  const bannerIconBackgroundColor = getFrontmatterValue(frontmatter, plugin.settings.customBannerIconBackgroundColorField) || (folderSpecific == null ? void 0 : folderSpecific.bannerIconBackgroundColor) || plugin.settings.bannerIconBackgroundColor || "transparent";
  const bannerIconPaddingX = getValueWithZeroCheck([
    getFrontmatterValue(frontmatter, plugin.settings.customBannerIconPaddingXField),
    folderSpecific == null ? void 0 : folderSpecific.bannerIconPaddingX,
    plugin.settings.bannerIconPaddingX,
    10
  ]);
  const bannerIconPaddingY = getValueWithZeroCheck([
    getFrontmatterValue(frontmatter, plugin.settings.customBannerIconPaddingYField),
    folderSpecific == null ? void 0 : folderSpecific.bannerIconPaddingY,
    plugin.settings.bannerIconPaddingY,
    10
  ]);
  const bannerIconBorderRadius = getValueWithZeroCheck([
    getFrontmatterValue(frontmatter, plugin.settings.customBannerIconBorderRadiusField),
    folderSpecific == null ? void 0 : folderSpecific.bannerIconBorderRadius,
    plugin.settings.bannerIconBorderRadius,
    17
  ]);
  const bannerIconVerticalOffset = getValueWithZeroCheck([
    Number(getFrontmatterValue(frontmatter, plugin.settings.customBannerIconVerticalOffsetField)),
    folderSpecific == null ? void 0 : folderSpecific.bannerIconVerticalOffset,
    plugin.settings.bannerIconVerticalOffset,
    0
  ]);
  const bannerIconRotate = getValueWithZeroCheck([
    getFrontmatterValue(frontmatter, plugin.settings.customBannerIconRotateField),
    0
  ]);
  const bannerIconImageSizeMultiplier = getValueWithZeroCheck([
    getFrontmatterValue(frontmatter, plugin.settings.customBannerIconImageSizeMultiplierField),
    plugin.settings.bannerIconImageSizeMultiplier,
    1
  ]);
  const bannerIconTextVerticalOffset = getValueWithZeroCheck([
    getFrontmatterValue(frontmatter, plugin.settings.customBannerIconTextVerticalOffsetField),
    plugin.settings.bannerIconTextVerticalOffset,
    0
  ]);
  const hideEmbeddedNoteBanners = getFrontmatterValue(frontmatter, plugin.settings.customHideEmbeddedNoteBannersField) || (folderSpecific == null ? void 0 : folderSpecific.hideEmbeddedNoteBanners) || plugin.settings.hideEmbeddedNoteBanners || false;
  const bannerAlignment = getFrontmatterValue(frontmatter, plugin.settings.customBannerAlignmentField) || "center";
  let alignmentValue = "0 auto";
  if (bannerAlignment === "left") {
    alignmentValue = "0 auto 0 0";
  } else if (bannerAlignment === "right") {
    alignmentValue = "0 0 0 auto";
  }
  const cssVars = {
    "--pixel-banner-height": hideEmbeddedNoteBanners && isEmbedded ? "0px" : `${bannerHeight}px`,
    "--pixel-banner-fade": `${fade}%`,
    "--pixel-banner-fade-in-animation-duration": `${plugin.settings.bannerFadeInAnimationDuration}ms`,
    "--pixel-banner-radius": `${borderRadius}px`,
    "--pixel-banner-max-width": pixelBannerMaxWidth === "unset" ? "unset" : `${pixelBannerMaxWidth}px`,
    "--pixel-banner-y-position": `${pixelBannerYPosition}%`,
    "--pixel-banner-x-position": `${pixelBannerXPosition}%`,
    "--pixel-banner-title-color": titleColor,
    "--pixel-banner-icon-size": `${bannerIconSize}px`,
    "--pixel-banner-icon-start": `${bannerHeight - bannerIconSize / 2}px`,
    "--pixel-banner-icon-x": `${bannerIconXPosition}%`,
    "--pixel-banner-icon-opacity": `${bannerIconOpacity}%`,
    "--pixel-banner-icon-color": bannerIconColor,
    "--pixel-banner-icon-font-weight": bannerIconFontWeight,
    "--pixel-banner-icon-background-color": bannerIconBackgroundColor,
    "--pixel-banner-icon-padding-x": `${bannerIconPaddingX}px`,
    "--pixel-banner-icon-padding-y": `${bannerIconPaddingY}px`,
    "--pixel-banner-icon-border-radius": `${bannerIconBorderRadius}px`,
    "--pixel-banner-icon-vertical-offset": `${bannerIconVerticalOffset}px`,
    "--pixel-banner-icon-rotate": `${bannerIconRotate}deg`,
    "--pixel-banner-icon-image-size-multiplier": `${bannerIconImageSizeMultiplier}em`,
    "--pixel-banner-icon-text-vertical-offset": `${bannerIconTextVerticalOffset}px`,
    "--pixel-banner-embed-min-height": !hideEmbeddedNoteBanners ? `${parseInt(bannerHeight) + parseInt(bannerIconSize) / 2 + parseInt(bannerIconVerticalOffset) + parseInt(bannerIconPaddingY)}px` : "0px",
    "--pixel-banner-alignment": alignmentValue
  };
  bannerDiv.style.backgroundSize = imageDisplay || "cover";
  bannerDiv.style.backgroundRepeat = imageRepeat ? "repeat" : "no-repeat";
  Object.entries(cssVars).forEach(([property, value]) => {
    bannerDiv.style.setProperty(property, value);
  });
  const container = bannerDiv.closest(".markdown-preview-view, .markdown-source-view");
  if (container) {
    Object.entries(cssVars).forEach(([property, value]) => {
      container.style.setProperty(property, value);
    });
  }
  if (isEmbedded) {
    const embedContainer = bannerDiv.closest(".internal-embed");
    if (embedContainer) {
      embedContainer.style.setProperty("--pixel-banner-content-start", cssVars["--pixel-banner-embed-min-height"]);
      const embedContentDiv = embedContainer.querySelector(":scope > .markdown-embed-content");
      if (embedContentDiv) {
        Object.entries(cssVars).forEach(([property, value]) => {
          embedContentDiv.style.setProperty(property, value);
        });
        const previewViewEl = embedContentDiv.querySelector(":scope > .markdown-preview-view");
        if (previewViewEl) {
          Object.entries(cssVars).forEach(([property, value]) => {
            previewViewEl.style.setProperty(property, value);
          });
        }
      }
    }
  }
}
var debouncedApplyContentStartPosition = debounceAndSwallow(applyContentStartPosition, 350);
function applyContentStartPosition(plugin, el, contentStartPosition) {
  if (!el) {
    return;
  }
  el.style.setProperty("--pixel-banner-content-start", `${contentStartPosition}px`);
}
var debouncedApplyBannerWidth = debounceAndSwallow(applyBannerWidth, 350);
function applyBannerWidth(plugin, el) {
  if (!el) return;
  setTimeout(() => {
    if (!el.classList.contains("view-content")) {
      return;
    }
    const theWidth = el.clientWidth;
    const bannerGap = plugin.settings.bannerGap;
    el.style.setProperty("--pixel-banner-width", `${theWidth - bannerGap * 2}px`);
    el.style.setProperty("--pixel-banner-banner-gap", `${bannerGap}px`);
  }, 50);
}
var debouncedUpdateAllBanners = debounceAndSwallow(updateAllBanners, 350);
function updateAllBanners(plugin) {
  plugin.app.workspace.iterateAllLeaves((leaf) => {
    if (leaf.view.getViewType() === "markdown") {
      updateBanner(plugin, leaf.view, true);
    }
  });
}
var debouncedUpdateBannerPosition = debounceAndSwallow(updateBannerPosition, 350);
async function updateBannerPosition(plugin, file, position) {
  if (!file) return;
  const metadata = plugin.app.metadataCache.getFileCache(file);
  if (!(metadata == null ? void 0 : metadata.frontmatter)) return;
  await plugin.app.fileManager.processFrontMatter(file, (frontmatter) => {
    frontmatter.banner_x = position.x;
    frontmatter.banner_y = position.y;
  });
}
function registerMarkdownPostProcessor(plugin) {
  plugin.registerMarkdownPostProcessor((el, ctx) => {
    var _a;
    const isPreview = ctx.containerEl.classList.contains("markdown-preview-view");
    const isHoverPopover = ctx.containerEl.closest(".hover-popover");
    const debounceFile = ctx.sourcePath ? plugin.app.vault.getAbstractFileByPath(ctx.sourcePath) : null;
    if (debounceFile) {
      const currentTime = Date.now();
      const lastProcessTime = markdownPostProcessorDebounceMap.get(debounceFile.path);
      if (lastProcessTime && currentTime - lastProcessTime < MARKDOWN_PROCESSOR_DEBOUNCE_DELAY) {
        return;
      }
      markdownPostProcessorDebounceMap.set(debounceFile.path, currentTime);
    }
    if (!isPreview && !isHoverPopover) return;
    const file = ctx.sourcePath ? plugin.app.vault.getAbstractFileByPath(ctx.sourcePath) : null;
    if (!file) return;
    const frontmatter = (_a = plugin.app.metadataCache.getFileCache(file)) == null ? void 0 : _a.frontmatter;
    let bannerImage = null;
    for (const field of plugin.settings.customBannerField) {
      if (frontmatter == null ? void 0 : frontmatter[field]) {
        bannerImage = frontmatter[field];
        break;
      }
    }
    if (!bannerImage) {
      const folderSpecific2 = plugin.getFolderSpecificImage(file.path);
      if (folderSpecific2 == null ? void 0 : folderSpecific2.image) {
        bannerImage = folderSpecific2.image;
      }
    }
    if (!bannerImage) return;
    const folderSpecific = plugin.getFolderSpecificImage(file.path);
    const yPosition = getFrontmatterValue(frontmatter, plugin.settings.customYPositionField) || (folderSpecific == null ? void 0 : folderSpecific.yPosition) || plugin.settings.yPosition;
    const xPosition = getFrontmatterValue(frontmatter, plugin.settings.customXPositionField) || (folderSpecific == null ? void 0 : folderSpecific.xPosition) || plugin.settings.xPosition;
    const contentStartPosition = getFrontmatterValue(frontmatter, plugin.settings.customContentStartField) || (folderSpecific == null ? void 0 : folderSpecific.contentStartPosition) || plugin.settings.contentStartPosition;
    addPixelBanner(plugin, ctx.containerEl, {
      frontmatter,
      file,
      isContentChange: false,
      yPosition,
      xPosition,
      contentStartPosition,
      bannerImage,
      isReadingView: true,
      updateMode: plugin.UPDATE_MODE.FULL_UPDATE
    });
  });
}

// src/core/bannerUtils.js
var import_obsidian28 = require("obsidian");
function getInputType(input, sourcePath = "") {
  if (Array.isArray(input)) {
    input = input.flat()[0];
  }
  if (typeof input !== "string") {
    return "invalid";
  }
  let cleanedInput = input.trim().replace(/^["'](.*)["']$/, "$1");
  cleanedInput = cleanedInput.replace(/^!\[\[(.*)\]\]$/, "$1").replace(/^\[\[(.*)\]\]$/, "$1");
  if (cleanedInput.includes("file:///")) {
    return "fileUrl";
  }
  if (input.match(/^!?\[{2}.*\]{2}$/) || input.match(/^"?!?\[{2}.*\]{2}"?$/)) {
    return "obsidianLink";
  }
  if (input.match(/^!\[\]\(.*\)$/) || input.match(/^"?!\[\]\(.*\)"?$/)) {
    return "markdownImage";
  }
  try {
    new URL(cleanedInput);
    return "url";
  } catch (_) {
    const file = this.app.vault.getAbstractFileByPath(cleanedInput);
    if (file && "extension" in file) {
      if (file.extension.match(/^(jpg|jpeg|png|gif|bmp|svg|webp|avif|mp4|mov)$/i)) {
        return "vaultPath";
      }
    }
    const resolvedFile = this.app.metadataCache.getFirstLinkpathDest(cleanedInput, sourcePath);
    if (resolvedFile && "extension" in resolvedFile) {
      if (resolvedFile.extension.match(/^(jpg|jpeg|png|gif|bmp|svg|webp|avif|mp4|mov)$/i)) {
        return "vaultPath";
      }
    }
    return "keyword";
  }
}
function getPathFromObsidianLink(link) {
  let cleanLink = link.replace(/^["'](.*)["']$/, "$1");
  cleanLink = cleanLink.startsWith("!") ? cleanLink.slice(1) : cleanLink;
  let innerLink = cleanLink.startsWith("[[") ? cleanLink.slice(2) : cleanLink;
  innerLink = innerLink.endsWith("]]") ? innerLink.slice(0, -2) : innerLink;
  const path = innerLink.split("|")[0];
  return this.app.metadataCache.getFirstLinkpathDest(path, "");
}
function getPathFromMarkdownImage(link) {
  let cleanLink = link.replace(/^["'](.*)["']$/, "$1");
  const match = cleanLink.match(/^!\[\]\((.*)\)$/);
  if (match && match[1]) {
    const path = match[1];
    try {
      new URL(path);
      return path;
    } catch (_) {
      return this.app.metadataCache.getFirstLinkpathDest(path, "");
    }
  }
  return null;
}
async function getVaultImageUrl(path) {
  const file = this.app.vault.getAbstractFileByPath(path);
  if (file && "extension" in file) {
    try {
      const fileExt = file.extension.toLowerCase();
      const videoExtensions = ["mp4", "mov"];
      if (videoExtensions.includes(fileExt)) {
        const resourcePath = this.app.vault.getResourcePath(file);
        return {
          url: resourcePath,
          isVideo: true,
          fileType: fileExt,
          // Store original path to help with caching
          originalPath: path
        };
      }
      const arrayBuffer = await this.app.vault.readBinary(file);
      const mimeType = fileExt === "svg" ? "image/svg+xml" : `image/${fileExt}`;
      const blob = new Blob([arrayBuffer], { type: mimeType });
      const url = URL.createObjectURL(blob);
      return {
        url,
        isVideo: false,
        fileType: fileExt
      };
    } catch (error) {
      console.error("Error reading vault file:", error);
      return null;
    }
  }
  return null;
}
function preloadImage(url) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve(url);
    img.onerror = reject;
    img.src = url;
  });
}
function getIconImageInputType(input, sourcePath = "") {
  if (Array.isArray(input)) {
    input = input.flat()[0];
  }
  if (typeof input !== "string") {
    return "invalid";
  }
  let cleanedInput = input.trim().replace(/^["'](.*)["']$/, "$1");
  cleanedInput = cleanedInput.replace(/^!\[\[(.*)\]\]$/, "$1").replace(/^\[\[(.*)\]\]$/, "$1");
  if (cleanedInput.includes("file:///")) {
    return "fileUrl";
  }
  if (input.match(/^!?\[{2}.*\]{2}$/) || input.match(/^"?!?\[{2}.*\]{2}"?$/)) {
    return "obsidianLink";
  }
  if (input.match(/^!\[\]\(.*\)$/) || input.match(/^"?!\[\]\(.*\)"?$/)) {
    return "markdownImage";
  }
  try {
    new URL(cleanedInput);
    return "url";
  } catch (_) {
    const file = this.app.vault.getAbstractFileByPath(cleanedInput);
    if (file && "extension" in file) {
      if (file.extension.match(/^(jpg|jpeg|png|gif|bmp|svg|webp|avif|mp4|mov)$/i)) {
        return "vaultPath";
      }
    }
    const resolvedFile = this.app.metadataCache.getFirstLinkpathDest(cleanedInput, sourcePath);
    if (resolvedFile && "extension" in resolvedFile) {
      if (resolvedFile.extension.match(/^(jpg|jpeg|png|gif|bmp|svg|webp|avif|mp4|mov)$/i)) {
        return "vaultPath";
      }
    }
    return "keyword";
  }
}
function getFolderPath(filePath) {
  if (!filePath) return "/";
  if (!filePath.includes("/")) {
    return "/";
  }
  const lastSlashIndex = filePath.lastIndexOf("/");
  return lastSlashIndex !== -1 ? filePath.substring(0, lastSlashIndex) : "";
}
function getFolderSpecificImage(filePath) {
  if (!filePath) return null;
  const folderPath = this.getFolderPath(filePath);
  const sortedFolderImages = [...this.settings.folderImages].sort(
    (a, b) => {
      var _a, _b;
      return (((_a = b.folder) == null ? void 0 : _a.length) || 0) - (((_b = a.folder) == null ? void 0 : _b.length) || 0);
    }
  );
  for (const folderImage of sortedFolderImages) {
    if (!folderImage.folder) continue;
    if (folderImage.folder === "/") {
      if (folderImage.directChildrenOnly) {
        if (!filePath.includes("/")) {
          return this.createFolderImageSettings(folderImage);
        }
      } else {
        return this.createFolderImageSettings(folderImage);
      }
      continue;
    }
    const normalizedFolderPath = folderImage.folder.startsWith("/") ? folderImage.folder : "/" + folderImage.folder;
    const normalizedFileFolderPath = "/" + folderPath;
    if (folderImage.directChildrenOnly) {
      if (normalizedFileFolderPath === normalizedFolderPath) {
        return this.createFolderImageSettings(folderImage);
      }
    } else {
      if (normalizedFileFolderPath.startsWith(normalizedFolderPath)) {
        return this.createFolderImageSettings(folderImage);
      }
    }
  }
  return null;
}
function getFolderSpecificSetting(filePath, settingName) {
  var _a;
  const folderPath = this.getFolderPath(filePath);
  for (const folderImage of this.settings.folderImages) {
    if (folderPath.startsWith(folderImage.folder)) {
      return (_a = folderImage[settingName]) != null ? _a : void 0;
    }
  }
  return void 0;
}
function getRandomImageFromFolder(folderPath) {
  try {
    const folder = this.app.vault.getAbstractFileByPath(folderPath);
    if (!folder || !folder.children) return null;
    const imageFiles = folder.children.filter(
      (file) => file.extension && ["png", "jpg", "jpeg", "gif", "webp", "svg", "avif"].includes(file.extension.toLowerCase())
    );
    if (imageFiles.length === 0) return null;
    const randomImage = imageFiles[Math.floor(Math.random() * imageFiles.length)];
    return randomImage.path;
  } catch (error) {
    console.error("Error getting random image:", error);
    return null;
  }
}
function getActiveApiProvider() {
  if (this.settings.apiProvider !== "all") {
    return this.settings.apiProvider;
  }
  if (this.settings.apiProviders && Array.isArray(this.settings.apiProviders)) {
    for (const provider of this.settings.apiProviders) {
      const hasKey = provider === "pexels" && this.settings.pexelsApiKey || provider === "pixabay" && this.settings.pixabayApiKey || provider === "flickr" && this.settings.flickrApiKey || provider === "unsplash" && this.settings.unsplashApiKey;
      if (hasKey) {
        return provider;
      }
    }
  }
  const availableProviders = [];
  if (this.settings.pexelsApiKey) availableProviders.push("pexels");
  if (this.settings.pixabayApiKey) availableProviders.push("pixabay");
  if (this.settings.flickrApiKey) availableProviders.push("flickr");
  if (this.settings.unsplashApiKey) availableProviders.push("unsplash");
  if (availableProviders.length === 0) {
    return null;
  }
  return availableProviders[Math.floor(Math.random() * availableProviders.length)];
}
function hasBannerFrontmatter(file) {
  const metadata = this.app.metadataCache.getFileCache(file);
  if (!(metadata == null ? void 0 : metadata.frontmatter)) return false;
  return this.settings.customBannerField.some(
    (fieldName) => metadata.frontmatter[fieldName] !== void 0
  );
}
function createFolderImageSettings(folderImage) {
  const settings = { ...folderImage };
  if (folderImage.enableImageShuffle && folderImage.shuffleFolder) {
    const randomImagePath = this.getRandomImageFromFolder(folderImage.shuffleFolder);
    if (randomImagePath) {
      settings.image = randomImagePath;
    }
  }
  return settings;
}

// src/core/eventHandler.js
var import_obsidian29 = require("obsidian");
init_modals();
init_frontmatterUtils();
var bannerUpdateDebounceMap = /* @__PURE__ */ new Map();
var BANNER_UPDATE_DEBOUNCE_DELAY = 300;
async function handleActiveLeafChange(leaf) {
  var _a;
  if (!leaf || !(leaf.view instanceof import_obsidian29.MarkdownView) || !leaf.view.file) {
    return;
  }
  const filePath = leaf.view.file.path;
  const debounceCheckTime = Date.now();
  const lastUpdateTime = bannerUpdateDebounceMap.get(filePath);
  if (lastUpdateTime && debounceCheckTime - lastUpdateTime < BANNER_UPDATE_DEBOUNCE_DELAY) {
    return;
  }
  bannerUpdateDebounceMap.set(filePath, debounceCheckTime);
  this.cleanupCache();
  const previousLeaf = this.app.workspace.activeLeaf;
  if (previousLeaf && previousLeaf.view instanceof import_obsidian29.MarkdownView && previousLeaf !== leaf) {
    this.cleanupPreviousLeaf(previousLeaf);
    this.cleanupIconOverlay(previousLeaf.view);
  }
  const currentPath = leaf.view.file.path;
  const leafId = leaf.id;
  const frontmatter = (_a = this.app.metadataCache.getFileCache(leaf.view.file)) == null ? void 0 : _a.frontmatter;
  const currentTime = Date.now();
  const hasBannerIcon = this.settings.customBannerIconField.some((field) => frontmatter == null ? void 0 : frontmatter[field]);
  if (!hasBannerIcon) {
    this.cleanupIconOverlay(leaf.view);
  }
  try {
    const hasShufflePath = !!getFrontmatterValue(frontmatter, this.settings.customBannerShuffleField);
    const folderSpecific = this.getFolderSpecificImage(currentPath);
    const isShuffled = hasShufflePath || (folderSpecific == null ? void 0 : folderSpecific.enableImageShuffle) || false;
    const cacheKey = this.generateCacheKey(currentPath, leafId, isShuffled);
    const cachedState = this.bannerStateCache.get(cacheKey);
    const loadedImage = this.loadedImages.get(currentPath);
    let shouldUpdateBanner = false;
    if (cachedState) {
      if (isShuffled && currentTime - cachedState.timestamp > this.SHUFFLE_CACHE_AGE) {
        shouldUpdateBanner = true;
        this.loadedImages.delete(currentPath);
        this.lastKeywords.delete(currentPath);
        this.imageCache.delete(currentPath);
        this.bannerStateCache.delete(cacheKey);
      } else {
        cachedState.timestamp = currentTime;
        const relevantFields = [
          ...this.settings.customBannerField,
          ...this.settings.customYPositionField,
          ...this.settings.customXPositionField,
          ...this.settings.customContentStartField,
          ...this.settings.customImageDisplayField,
          ...this.settings.customImageRepeatField,
          ...this.settings.customBannerHeightField,
          ...this.settings.customFadeField,
          ...this.settings.customBorderRadiusField,
          ...this.settings.customTitleColorField,
          ...this.settings.customBannerShuffleField,
          ...this.settings.customBannerIconField,
          ...this.settings.customBannerIconSizeField,
          ...this.settings.customBannerIconXPositionField,
          ...this.settings.customBannerIconOpacityField,
          ...this.settings.customBannerIconColorField,
          ...this.settings.customBannerIconFontWeightField,
          ...this.settings.customBannerIconBackgroundColorField,
          ...this.settings.customBannerIconPaddingXField,
          ...this.settings.customBannerIconPaddingYField,
          ...this.settings.customBannerIconBorderRadiusField,
          ...this.settings.customBannerIconVerticalOffsetField
        ];
        const hasRelevantChanges = relevantFields.some(
          (field) => {
            var _a2;
            return (frontmatter == null ? void 0 : frontmatter[field]) !== ((_a2 = cachedState.frontmatter) == null ? void 0 : _a2[field]);
          }
        );
        if (hasRelevantChanges) {
          shouldUpdateBanner = true;
        }
      }
    } else {
      shouldUpdateBanner = true;
    }
    if (!loadedImage) {
      shouldUpdateBanner = true;
    }
    if (shouldUpdateBanner) {
      await this.updateBanner(leaf.view, false, this.UPDATE_MODE.FULL_UPDATE);
      const bannerIcon = getFrontmatterValue(frontmatter, this.settings.customBannerIconField);
      const iconState = bannerIcon ? {
        icon: bannerIcon,
        size: getFrontmatterValue(frontmatter, this.settings.customBannerIconSizeField) || this.settings.bannerIconSize,
        xPosition: getFrontmatterValue(frontmatter, this.settings.customBannerIconXPositionField) || this.settings.bannerIconXPosition,
        opacity: getFrontmatterValue(frontmatter, this.settings.customBannerIconOpacityField) || this.settings.bannerIconOpacity,
        color: getFrontmatterValue(frontmatter, this.settings.customBannerIconColorField) || this.settings.bannerIconColor,
        fontWeight: getFrontmatterValue(frontmatter, this.settings.customBannerIconFontWeightField) || this.settings.bannerIconFontWeight,
        backgroundColor: getFrontmatterValue(frontmatter, this.settings.customBannerIconBackgroundColorField) || this.settings.bannerIconBackgroundColor,
        paddingX: getFrontmatterValue(frontmatter, this.settings.customBannerIconPaddingXField) || this.settings.bannerIconPaddingX,
        paddingY: getFrontmatterValue(frontmatter, this.settings.customBannerIconPaddingYField) || this.settings.bannerIconPaddingY,
        borderRadius: getFrontmatterValue(frontmatter, this.settings.customBannerIconBorderRadiusField) || this.settings.bannerIconBorderRadius,
        verticalOffset: getFrontmatterValue(frontmatter, this.settings.customBannerIconVerticalOffsetField) || this.settings.bannerIconVerticalOffset
      } : null;
      this.bannerStateCache.set(cacheKey, {
        timestamp: currentTime,
        frontmatter: frontmatter ? { ...frontmatter } : null,
        leafId,
        isShuffled,
        state: {
          imageUrl: this.loadedImages.get(currentPath),
          iconState
        }
      });
    } else {
      await this.updateBanner(leaf.view, false, this.UPDATE_MODE.ENSURE_VISIBILITY);
    }
  } catch (error) {
    console.error("Error in handleActiveLeafChange:", error);
    this.invalidateLeafCache(leafId);
    try {
      await this.updateBanner(leaf.view, false);
    } catch (recoveryError) {
      console.error("Failed to recover from error:", recoveryError);
    }
  }
}
function handleLayoutChange() {
  var _a;
  const currentLeafIds = new Set(
    this.app.workspace.getLeavesOfType("markdown").map((leaf) => leaf.id)
  );
  for (const [key, entry] of this.bannerStateCache) {
    if (entry.leafId && !currentLeafIds.has(entry.leafId)) {
      if (((_a = entry.state) == null ? void 0 : _a.imageUrl) && typeof entry.state.imageUrl === "string" && entry.state.imageUrl.startsWith("blob:")) {
        URL.revokeObjectURL(entry.state.imageUrl);
      }
      this.bannerStateCache.delete(key);
    }
  }
  setTimeout(() => {
    const activeLeaf = this.app.workspace.activeLeaf;
    if (activeLeaf && activeLeaf.view instanceof import_obsidian29.MarkdownView) {
      const contentEl = activeLeaf.view.contentEl;
      if (contentEl) {
        const hasBanner = contentEl.querySelector(".pixel-banner-image");
        if (hasBanner) {
          const cacheKey = activeLeaf.id;
          const cachedState = this.bannerStateCache.get(cacheKey);
          if (!cachedState) {
            this.updateBanner(activeLeaf.view, false);
          }
        }
      }
    }
  }, 100);
}
async function handleModeChange(leaf) {
  if (leaf && leaf.view instanceof import_obsidian29.MarkdownView && leaf.view.file) {
    await this.updateBanner(leaf.view, true);
    if (this.settings.hidePixelBannerFields) {
      this.updateFieldVisibility(leaf.view);
    }
  }
}
async function handleSelectImage() {
  const activeFile = this.app.workspace.getActiveFile();
  if (!activeFile) {
    new import_obsidian29.Notice("No active file");
    return;
  }
  new ImageSelectionModal(
    this.app,
    this,
    async (selectedFile) => {
      let imageReference = selectedFile.path;
      if (this.settings.useShortPath) {
        const allFiles = this.app.vault.getFiles();
        const matchingFiles = allFiles.filter((f) => f.name === selectedFile.name);
        imageReference = matchingFiles.length === 1 ? selectedFile.name : selectedFile.path;
      }
      let fileContent = await this.app.vault.read(activeFile);
      const frontmatterRegex = /^---\n([\s\S]*?)\n---/;
      const hasFrontmatter = frontmatterRegex.test(fileContent);
      const bannerField = Array.isArray(this.settings.customBannerField) && this.settings.customBannerField.length > 0 ? this.settings.customBannerField[0] : "banner";
      fileContent = fileContent.replace(/^\s+/, "");
      let updatedContent;
      if (hasFrontmatter) {
        updatedContent = fileContent.replace(frontmatterRegex, (match, frontmatter) => {
          let cleanedFrontmatter = frontmatter.trim();
          this.settings.customBannerField.forEach((field) => {
            const fieldRegex = new RegExp(`${field}:\\s*.+\\n?`, "g");
            cleanedFrontmatter = cleanedFrontmatter.replace(fieldRegex, "");
          });
          const format = this.settings.imagePropertyFormat;
          const bannerValue = format === "[[image]]" ? `[[${imageReference}]]` : `![[${imageReference}]]`;
          const newFrontmatter = `${bannerField}: "${bannerValue}"${cleanedFrontmatter ? "\n" + cleanedFrontmatter : ""}`;
          return `---
${newFrontmatter}
---`;
        });
      } else {
        const cleanContent = fileContent.replace(/^\s+/, "");
        const format = this.settings.imagePropertyFormat;
        const bannerValue = format === "[[image]]" ? `[[${imageReference}]]` : `![[${imageReference}]]`;
        updatedContent = `---
${bannerField}: "${bannerValue}"
---

${cleanContent}`;
      }
      updatedContent = updatedContent.replace(/^\s+/, "");
      if (updatedContent !== fileContent) {
        await this.app.vault.modify(activeFile, updatedContent);
        if (this.settings.useShortPath && imageReference === selectedFile.path) {
          new import_obsidian29.Notice("Banner image updated (full path used due to duplicate filenames)");
        } else {
          new import_obsidian29.Notice("Banner image updated");
        }
      }
    },
    this.settings.defaultSelectImagePath
  ).open();
}
function handleBannerIconClick() {
  new SelectPixelBannerModal(this.app, this).open();
}

// src/core/domManager.js
var import_obsidian30 = require("obsidian");
function setupMutationObserver() {
  if (this.observer && typeof this.observer.disconnect === "function") {
    this.observer.disconnect();
  }
  this.observer = new MutationObserver((mutations) => {
    for (let mutation of mutations) {
      if (mutation.type === "childList") {
        const removedNodes = Array.from(mutation.removedNodes);
        const addedNodes = Array.from(mutation.addedNodes);
        const bannerRemoved = removedNodes.some(
          (node) => node.classList && node.classList.contains("pixel-banner-image")
        );
        const structuralChange = addedNodes.some(
          (node) => node.nodeType === Node.ELEMENT_NODE && (node.classList.contains("markdown-preview-section") || node.classList.contains("cm-sizer"))
          // Changed from cm-content to cm-sizer
        );
        if (bannerRemoved || structuralChange) {
          const activeLeaf = this.app.workspace.activeLeaf;
          if (activeLeaf && activeLeaf.view instanceof import_obsidian30.MarkdownView) {
            const contentEl = activeLeaf.view.contentEl;
            const hasBanner = contentEl.querySelector('.pixel-banner-image[style*="display: block"]');
            if (!hasBanner) {
              contentEl.classList.remove("pixel-banner");
            }
            if (bannerRemoved || structuralChange) {
              this.debouncedEnsureBanner();
            }
          }
        }
      }
    }
  });
  if (this.observer && typeof this.observer.observe === "function") {
    this.observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  }
}
function setupResizeObserver(viewContent) {
  if (!viewContent.classList.contains("view-content")) {
    return;
  }
  if (!viewContent._resizeObserver) {
    const debouncedResize = debounce(() => {
      this.applyBannerWidth(viewContent);
    }, 100);
    viewContent._resizeObserver = new ResizeObserver(debouncedResize);
    if (viewContent._resizeObserver && typeof viewContent._resizeObserver.observe === "function") {
      viewContent._resizeObserver.observe(viewContent);
    }
  }
}
function updateFieldVisibility(view) {
  if (!view || view.getMode() !== "preview") return;
  const fieldsToHide = [
    ...this.settings.customBannerField,
    ...this.settings.customYPositionField,
    ...this.settings.customXPositionField,
    ...this.settings.customContentStartField,
    ...this.settings.customImageDisplayField,
    ...this.settings.customImageRepeatField,
    ...this.settings.customBannerMaxWidthField,
    ...this.settings.customBannerHeightField,
    ...this.settings.customBannerAlignmentField,
    ...this.settings.customFadeField,
    ...this.settings.customBorderRadiusField,
    ...this.settings.customTitleColorField,
    ...this.settings.customBannerShuffleField,
    ...this.settings.customBannerIconField,
    ...this.settings.customBannerIconImageField,
    ...this.settings.customBannerIconImageAlignmentField,
    ...this.settings.customBannerIconSizeField,
    ...this.settings.customBannerIconImageSizeMultiplierField,
    ...this.settings.customBannerIconTextVerticalOffsetField,
    ...this.settings.customBannerIconRotateField,
    ...this.settings.customBannerIconXPositionField,
    ...this.settings.customBannerIconOpacityField,
    ...this.settings.customBannerIconColorField,
    ...this.settings.customBannerIconFontWeightField,
    ...this.settings.customBannerIconBackgroundColorField,
    ...this.settings.customBannerIconPaddingXField,
    ...this.settings.customBannerIconPaddingYField,
    ...this.settings.customBannerIconBorderRadiusField,
    ...this.settings.customBannerIconVerticalOffsetField,
    ...this.settings.customFlagColorField
  ];
  const propertiesContainer = view.contentEl.querySelector(".metadata-container");
  if (!propertiesContainer) {
    return;
  }
  const propertyElements = propertiesContainer.querySelectorAll(".metadata-property");
  let visiblePropertiesCount = 0;
  let bannerPropertiesCount = 0;
  propertyElements.forEach((propertyEl) => {
    const key = propertyEl.getAttribute("data-property-key");
    if (fieldsToHide.includes(key)) {
      propertyEl.classList.add("pixel-banner-hidden-field");
      bannerPropertiesCount++;
    } else {
      visiblePropertiesCount++;
    }
  });
  if (this.settings.hidePropertiesSectionIfOnlyBanner && this.settings.hidePixelBannerFields && visiblePropertiesCount === 0 && bannerPropertiesCount > 0) {
    propertiesContainer.classList.add("pixel-banner-hidden-section");
  } else {
    propertiesContainer.classList.remove("pixel-banner-hidden-section");
  }
}
function updateEmbeddedTitlesVisibility() {
  const styleId = "pixel-banner-embedded-titles";
  let styleEl = document.getElementById(styleId);
  if (this.settings.hideEmbeddedNoteTitles) {
    if (!styleEl) {
      styleEl = document.createElement("style");
      styleEl.id = styleId;
      document.head.appendChild(styleEl);
    }
    styleEl.textContent = ".embed-title.markdown-embed-title { display: none !important; }";
  } else if (styleEl) {
    styleEl.remove();
  }
}
function updateEmbeddedBannersVisibility() {
  const styleId = "pixel-banner-embedded-banners";
  let styleEl = document.getElementById(styleId);
  if (this.settings.hideEmbeddedNoteBanners) {
    if (!styleEl) {
      styleEl = document.createElement("style");
      styleEl.id = styleId;
      document.head.appendChild(styleEl);
    }
    styleEl.textContent = `
            .internal-embed .pixel-banner-image,
            .internal-embed .banner-icon-overlay {
                display: none !important;
            }
            .internal-embed > .markdown-embed-content .cm-sizer:first-of-type,
            .internal-embed > .markdown-embed-content .markdown-preview-sizer:first-of-type {
                padding-top: unset !important;
            }
            /* hide pusher to prevent content from being pushed down */
            .internal-embed > .markdown-embed-content .cm-sizer:first-of-type > .pixel-banner-image + .markdown-preview-pusher,
            .internal-embed > .markdown-embed-content .markdown-preview-sizer:first-of-type > .pixel-banner-image + .markdown-preview-pusher {
                display: none !important;
            }
        `;
  } else if (styleEl) {
    styleEl.remove();
  }
}
function cleanupPreviousLeaf(previousLeaf) {
  const previousContentEl = previousLeaf.view.contentEl;
  if (!previousContentEl) {
    return;
  }
  previousContentEl.classList.remove("pixel-banner");
  ["cm-sizer", "markdown-preview-sizer"].forEach((selector) => {
    const container = previousContentEl.querySelector(`div.${selector}`);
    if (container) {
      const previousBanner = container.querySelector(".pixel-banner-image");
      if (previousBanner) {
        if (previousLeaf.view.file) {
          const existingUrl = this.loadedImages.get(previousLeaf.view.file.path);
          if (existingUrl && typeof existingUrl === "string" && existingUrl.startsWith("blob:")) {
            URL.revokeObjectURL(existingUrl);
          }
          this.loadedImages.delete(previousLeaf.view.file.path);
        }
        previousBanner.style.backgroundImage = "";
        previousBanner.style.display = "none";
      }
      const iconOverlays = container.querySelectorAll(".banner-icon-overlay");
      iconOverlays.forEach((overlay) => {
        if (!overlay.dataset.persistent) {
          this.returnIconOverlay(overlay);
        }
      });
    }
  });
}

// src/core/pixelBannerPlugin.js
init_frontmatterUtils();
var PixelBannerPlugin = class extends import_obsidian31.Plugin {
  constructor() {
    super(...arguments);
    // Update modes for banner refresh
    __publicField(this, "UPDATE_MODE", {
      FULL_UPDATE: "FULL_UPDATE",
      // Complete update including new images
      ENSURE_VISIBILITY: "ENSURE_VISIBILITY",
      // Only ensure banner is visible with current image
      SHUFFLE_UPDATE: "SHUFFLE_UPDATE"
      // Update for shuffle banners only
    });
    __publicField(this, "debounceTimer", null);
    __publicField(this, "loadedImages", /* @__PURE__ */ new Map());
    __publicField(this, "lastKeywords", /* @__PURE__ */ new Map());
    __publicField(this, "imageCache", /* @__PURE__ */ new Map());
    __publicField(this, "rateLimiter", {
      lastRequestTime: 0,
      minInterval: 1e3
      // 1 second between requests
    });
    __publicField(this, "lastYPositions", /* @__PURE__ */ new Map());
    __publicField(this, "lastFrontmatter", /* @__PURE__ */ new Map());
    // Enhanced cache management properties
    __publicField(this, "bannerStateCache", /* @__PURE__ */ new Map());
    __publicField(this, "MAX_CACHE_AGE", 30 * 60 * 1e3);
    // 30 minutes in milliseconds
    __publicField(this, "MAX_CACHE_ENTRIES", 30);
    // Maximum number of entries to keep in cache
    __publicField(this, "SHUFFLE_CACHE_AGE", 5 * 1e3);
    // 5 seconds in milliseconds for shuffled banners
    // Add element pool for icon overlays
    __publicField(this, "iconOverlayPool", []);
    __publicField(this, "MAX_POOL_SIZE", 10);
    // -----------------------------
    // -- debounced ensure banner --
    // -----------------------------
    __publicField(this, "debouncedEnsureBanner", debounce(() => {
      const activeLeaf = this.app.workspace.activeLeaf;
      if (activeLeaf && activeLeaf.view instanceof import_obsidian31.MarkdownView) {
        const contentEl = activeLeaf.view.contentEl;
        const hasBanner = contentEl.querySelector(".pixel-banner-image");
        if (hasBanner) {
          this.updateBanner(activeLeaf.view, false);
        }
      }
    }, 100));
  }
  // ----------------------------------------------------
  // -- bind imported functions to the plugin instance --
  // ----------------------------------------------------
  async loadSettings() {
    await loadSettings(this);
  }
  async saveSettings() {
    await saveSettings(this);
  }
  getIconOverlay() {
    return getIconOverlay(this);
  }
  returnIconOverlay(overlay) {
    returnIconOverlay(this, overlay);
  }
  shouldUpdateIconOverlay(existingOverlay, newIconState, viewType) {
    return shouldUpdateIconOverlay(this, existingOverlay, newIconState, viewType);
  }
  generateCacheKey(filePath, leafId, isShuffled = false) {
    return generateCacheKey.call(this, filePath, leafId, isShuffled);
  }
  getCacheEntriesForFile(filePath) {
    return getCacheEntriesForFile.call(this, filePath);
  }
  cleanupCache(force = false) {
    return cleanupCache.call(this, force);
  }
  invalidateLeafCache(leafId) {
    return invalidateLeafCache.call(this, leafId);
  }
  handleSetBannerIcon() {
    return handleSetBannerIcon(this);
  }
  addPixelBanner(el, ctx) {
    return debouncedAddPixelBanner(this, el, ctx);
  }
  updateBanner(view, isContentChange, updateMode) {
    return debouncedUpdateBanner(this, view, isContentChange, updateMode);
  }
  applyBannerSettings(bannerDiv, ctx, isEmbedded) {
    return debouncedApplyBannerSettings(this, bannerDiv, ctx, isEmbedded);
  }
  applyContentStartPosition(el, contentStartPosition) {
    return debouncedApplyContentStartPosition(this, el, contentStartPosition);
  }
  applyBannerWidth(el) {
    return debouncedApplyBannerWidth(this, el);
  }
  updateAllBanners() {
    return debouncedUpdateAllBanners(this);
  }
  updateBannerPosition(file, position) {
    return debouncedUpdateBannerPosition(this, file, position);
  }
  cleanupIconOverlay(view) {
    return cleanupIconOverlay(this, view);
  }
  // --------------------------------------------
  // -- add bindings for the utility functions --
  // --------------------------------------------
  getInputType(input, sourcePath = "") {
    return getInputType.call(this, input, sourcePath);
  }
  getIconImageInputType(input, sourcePath = "") {
    return getIconImageInputType.call(this, input, sourcePath);
  }
  getPathFromObsidianLink(link) {
    return getPathFromObsidianLink.call(this, link);
  }
  getPathFromMarkdownImage(link) {
    return getPathFromMarkdownImage.call(this, link);
  }
  getVaultImageUrl(path) {
    return getVaultImageUrl.call(this, path);
  }
  preloadImage(url) {
    return preloadImage.call(this, url);
  }
  getFolderPath(filePath) {
    return getFolderPath.call(this, filePath);
  }
  getFolderSpecificImage(filePath) {
    return getFolderSpecificImage.call(this, filePath);
  }
  getFolderSpecificSetting(filePath, settingName) {
    return getFolderSpecificSetting.call(this, filePath, settingName);
  }
  getRandomImageFromFolder(folderPath) {
    return getRandomImageFromFolder.call(this, folderPath);
  }
  getActiveApiProvider() {
    return getActiveApiProvider.call(this);
  }
  hasBannerFrontmatter(file) {
    return hasBannerFrontmatter.call(this, file);
  }
  createFolderImageSettings(folderImage) {
    return createFolderImageSettings.call(this, folderImage);
  }
  // -------------------------------------
  // -- add bindings for event handlers --
  // -------------------------------------
  handleActiveLeafChange(leaf) {
    return handleActiveLeafChange.call(this, leaf);
  }
  handleLayoutChange() {
    return handleLayoutChange.call(this);
  }
  handleModeChange(leaf) {
    return handleModeChange.call(this, leaf);
  }
  handleSelectImage() {
    return handleSelectImage.call(this);
  }
  handleBannerIconClick() {
    return handleBannerIconClick.call(this);
  }
  // -------------------------------------
  // -- add bindings for DOM management --
  // -------------------------------------
  setupMutationObserver() {
    return setupMutationObserver.call(this);
  }
  setupResizeObserver(viewContent) {
    return setupResizeObserver.call(this, viewContent);
  }
  updateFieldVisibility(view) {
    return updateFieldVisibility.call(this, view);
  }
  updateEmbeddedTitlesVisibility() {
    return updateEmbeddedTitlesVisibility.call(this);
  }
  updateEmbeddedBannersVisibility() {
    return updateEmbeddedBannersVisibility.call(this);
  }
  cleanupPreviousLeaf(previousLeaf) {
    return cleanupPreviousLeaf.call(this, previousLeaf);
  }
  // --------------------------------------
  // -- onload method / main entry point --
  // --------------------------------------
  async onload() {
    await this.loadSettings();
    this.pixelBannerPlusEnabled = false;
    this.pixelBannerPlusBannerTokens = 0;
    this.verifyPixelBannerPlusCredentials();
    this.updateEmbeddedTitlesVisibility();
    await this.checkVersion();
    this.addSettingTab(new PixelBannerSettingTab(this.app, this));
    this.addCommand({
      id: "generate-banner-with-ai",
      name: "\u2728 Generate Banner with AI",
      checkCallback: (checking) => {
        if (checking) {
          return this.pixelBannerPlusEnabled;
        }
        new GenerateAIBannerModal(this.app, this).open();
      }
    });
    this.addCommand({
      id: "play-daily-game",
      name: "\u{1F579}\uFE0F Play Daily Game",
      callback: () => {
        new DailyGameModal(this.app, this.settings.pixelBannerPlusEmail, this.settings.pixelBannerPlusApiKey, this).open();
      }
    });
    this.registerEvent(
      this.app.workspace.on("active-leaf-change", this.handleActiveLeafChange.bind(this))
    );
    this.registerEvent(
      this.app.workspace.on("layout-change", this.handleLayoutChange.bind(this))
    );
    this.registerEvent(
      this.app.workspace.on("resize", this.debouncedEnsureBanner.bind(this))
    );
    this.registerEvent(
      this.app.metadataCache.on("changed", async (file) => {
        var _a;
        const frontmatter = (_a = this.app.metadataCache.getFileCache(file)) == null ? void 0 : _a.frontmatter;
        if (!frontmatter) {
          return;
        }
        const previousFrontmatter = this.lastFrontmatter.get(file.path);
        if (JSON.stringify(frontmatter) === JSON.stringify(previousFrontmatter)) {
          return;
        }
        const relevantFields = [
          ...this.settings.customBannerField,
          ...this.settings.customYPositionField,
          ...this.settings.customXPositionField,
          ...this.settings.customContentStartField,
          ...this.settings.customImageDisplayField,
          ...this.settings.customImageRepeatField,
          ...this.settings.customBannerMaxWidthField,
          ...this.settings.customBannerHeightField,
          ...this.settings.customFadeField,
          ...this.settings.customBorderRadiusField,
          ...this.settings.customTitleColorField,
          ...this.settings.customBannerShuffleField,
          ...this.settings.customBannerIconField,
          ...this.settings.customBannerIconSizeField,
          ...this.settings.customBannerIconImageSizeMultiplierField,
          ...this.settings.customBannerIconTextVerticalOffsetField,
          ...this.settings.customBannerIconRotateField,
          ...this.settings.customBannerIconImageAlignmentField,
          ...this.settings.customBannerIconXPositionField,
          ...this.settings.customBannerIconOpacityField,
          ...this.settings.customBannerIconColorField,
          ...this.settings.customBannerIconFontWeightField,
          ...this.settings.customBannerIconBackgroundColorField,
          ...this.settings.customBannerIconPaddingXField,
          ...this.settings.customBannerIconPaddingYField,
          ...this.settings.customBannerIconBorderRadiusField,
          ...this.settings.customBannerIconVerticalOffsetField
        ];
        const changedFields = relevantFields.filter(
          (field) => frontmatter[field] !== (previousFrontmatter == null ? void 0 : previousFrontmatter[field])
        );
        const hasRelevantFieldChange = changedFields.length > 0;
        if (!hasRelevantFieldChange) {
          return;
        }
        this.lastFrontmatter.set(file.path, frontmatter);
        const leaves = this.app.workspace.getLeavesOfType("markdown");
        for (const leaf of leaves) {
          if (leaf.view instanceof import_obsidian31.MarkdownView && leaf.view.file === file) {
            this.loadedImages.delete(file.path);
            this.lastKeywords.delete(file.path);
            await this.updateBanner(leaf.view, true);
          }
        }
      })
    );
    this.registerMarkdownPostProcessor((el, ctx) => {
      var _a;
      const isPreview = ctx.containerEl.classList.contains("markdown-preview-view");
      const isHoverPopover = ctx.containerEl.closest(".hover-popover") !== null;
      if (!isPreview && !isHoverPopover) return;
      const file = ctx.sourcePath ? this.app.vault.getAbstractFileByPath(ctx.sourcePath) : null;
      if (!file) return;
      if (isHoverPopover && !this.settings.showBannerInPopoverPreviews) return;
      const frontmatter = (_a = this.app.metadataCache.getFileCache(file)) == null ? void 0 : _a.frontmatter;
      let bannerImage = null;
      for (const field of this.settings.customBannerField) {
        if (frontmatter == null ? void 0 : frontmatter[field]) {
          bannerImage = frontmatter[field];
          break;
        }
      }
      if (!bannerImage) {
        const folderSpecific2 = this.getFolderSpecificImage(file.path);
        if (folderSpecific2 == null ? void 0 : folderSpecific2.image) {
          bannerImage = folderSpecific2.image;
        }
      }
      if (!bannerImage) return;
      const folderSpecific = this.getFolderSpecificImage(file.path);
      const yPosition = getFrontmatterValue(frontmatter, this.settings.customYPositionField) || (folderSpecific == null ? void 0 : folderSpecific.yPosition) || this.settings.yPosition;
      const xPosition = getFrontmatterValue(frontmatter, this.settings.customXPositionField) || (folderSpecific == null ? void 0 : folderSpecific.xPosition) || this.settings.xPosition;
      const contentStartPosition = getFrontmatterValue(frontmatter, this.settings.customContentStartField) || (folderSpecific == null ? void 0 : folderSpecific.contentStartPosition) || this.settings.contentStartPosition;
      if (isHoverPopover) {
        this.addPixelBanner(ctx.containerEl, {
          frontmatter,
          file,
          isContentChange: false,
          yPosition,
          xPosition,
          contentStartPosition,
          bannerImage,
          isReadingView: true
        });
      } else {
        this.updateBanner({
          file,
          contentEl: ctx.containerEl,
          getMode: () => "preview"
        }, false, this.UPDATE_MODE.ENSURE_VISIBILITY);
      }
    });
    this.setupMutationObserver();
    this.addCommand({
      id: "pin-banner-image",
      name: "\u{1F4CC} Pin current banner image",
      checkCallback: (checking) => {
        var _a;
        const activeView = this.app.workspace.getActiveViewOfType(import_obsidian31.MarkdownView);
        if (!activeView || !activeView.file) return false;
        const imageUrl = this.loadedImages.get(activeView.file.path);
        const frontmatter = (_a = this.app.metadataCache.getFileCache(activeView.file)) == null ? void 0 : _a.frontmatter;
        let bannerImage, usedField;
        for (const field of this.settings.customBannerField) {
          if (frontmatter == null ? void 0 : frontmatter[field]) {
            bannerImage = frontmatter[field];
            usedField = field;
            break;
          }
        }
        const inputType = this.getInputType(bannerImage);
        const canPin = imageUrl && (inputType === "keyword" || inputType === "url") && this.settings.showPinIcon;
        if (checking) return canPin;
        if (canPin) {
          setTimeout(() => handlePinIconClick(imageUrl, this, usedField), 0);
        }
        return true;
      }
    });
    this.addCommand({
      id: "refresh-banner-image",
      name: "\u{1F504} Refresh current banner image",
      checkCallback: (checking) => {
        var _a;
        const activeView = this.app.workspace.getActiveViewOfType(import_obsidian31.MarkdownView);
        if (!activeView || !activeView.file) return false;
        const frontmatter = (_a = this.app.metadataCache.getFileCache(activeView.file)) == null ? void 0 : _a.frontmatter;
        let bannerImage;
        for (const field of this.settings.customBannerField) {
          if (frontmatter == null ? void 0 : frontmatter[field]) {
            bannerImage = frontmatter[field];
            break;
          }
        }
        const inputType = this.getInputType(bannerImage);
        const canRefresh = inputType === "keyword" && this.settings.showPinIcon && this.settings.showRefreshIcon;
        if (checking) return canRefresh;
        if (canRefresh) {
          this.loadedImages.delete(activeView.file.path);
          this.lastKeywords.delete(activeView.file.path);
          this.updateBanner(activeView, true).then(() => {
            new import_obsidian31.Notice("\u{1F504} Refreshed banner image");
          }).catch((error) => {
            console.error("Error refreshing image:", error);
            new import_obsidian31.Notice("\u{1F62D} Failed to refresh image");
          });
        }
        return true;
      }
    });
    this.addCommand({
      id: "open-pixel-banner-select",
      name: "\u{1F6A9} Pixel Banner Menu",
      callback: () => {
        this.handleBannerIconClick();
      }
    });
    this.addCommand({
      id: "set-banner-image",
      name: "\u{1F4BE} Select Banner from Vault",
      callback: () => this.handleSelectImage()
    });
    this.addCommand({
      id: "open-banner-store",
      name: "\u{1F3EA} Open Pixel Banner Plus Collection",
      callback: () => this.openBannerStore()
    });
    this.addCommand({
      id: "set-banner-icon-image",
      name: "\u2B50 Select Banner Icon Image",
      checkCallback: (checking) => {
        var _a;
        const activeView = this.app.workspace.getActiveViewOfType(import_obsidian31.MarkdownView);
        if (!activeView || !activeView.file) return false;
        const frontmatter = (_a = this.app.metadataCache.getFileCache(activeView.file)) == null ? void 0 : _a.frontmatter;
        let hasBanner = false;
        for (const field of this.settings.customBannerField) {
          if (frontmatter == null ? void 0 : frontmatter[field]) {
            hasBanner = true;
            break;
          }
        }
        if (checking) return hasBanner;
        if (hasBanner) {
          handleSetBannerIconImage(this);
        }
        return true;
      }
    });
    this.addCommand({
      id: "set-banner-icon",
      name: "\u{1F4F0} Set Banner Icon Text / Emoji",
      checkCallback: (checking) => {
        var _a;
        const activeView = this.app.workspace.getActiveViewOfType(import_obsidian31.MarkdownView);
        if (!activeView || !activeView.file) return false;
        const frontmatter = (_a = this.app.metadataCache.getFileCache(activeView.file)) == null ? void 0 : _a.frontmatter;
        let hasBanner = false;
        for (const field of this.settings.customBannerField) {
          if (frontmatter == null ? void 0 : frontmatter[field]) {
            hasBanner = true;
            break;
          }
        }
        if (checking) return hasBanner;
        if (hasBanner) {
          handleSetBannerIcon(this);
        }
        return true;
      }
    });
    this.addCommand({
      id: "set-banner-position",
      name: "\u{1F3AF} Adjust Position, Size, & Style",
      checkCallback: (checking) => {
        const activeFile = this.app.workspace.getActiveFile();
        const hasBanner = activeFile && this.hasBannerFrontmatter(activeFile);
        if (checking) {
          return hasBanner;
        }
        if (hasBanner) {
          new TargetPositionModal(
            this.app,
            this,
            (position) => this.updateBannerPosition(activeFile, position)
          ).open();
          return true;
        }
        return false;
      }
    });
    if (this.settings.bannerGap === void 0) {
      this.settings.bannerGap = DEFAULT_SETTINGS.bannerGap;
    }
    this.registerEvent(
      this.app.metadataCache.on("resolved", () => {
        var _a;
        const leaf = this.app.workspace.activeLeaf;
        if (leaf && leaf.view instanceof import_obsidian31.MarkdownView) {
          const contentEl = leaf.view.contentEl;
          const hasBanner = contentEl.querySelector(".pixel-banner-image");
          if (hasBanner) {
            const file = leaf.view.file;
            const frontmatter = (_a = this.app.metadataCache.getFileCache(file)) == null ? void 0 : _a.frontmatter;
            const previousFrontmatter = this.lastFrontmatter.get(file.path);
            if (JSON.stringify(frontmatter) !== JSON.stringify(previousFrontmatter)) {
              this.updateBanner(leaf.view, false);
            }
          }
        }
      })
    );
    this.addRibbonIcon("flag", "\u{1F6A9} Pixel Banner Menu", () => {
      this.handleBannerIconClick();
    });
    registerMarkdownPostProcessor(this);
  }
  // -------------------
  // -- get image url --
  // -------------------
  async getImageUrl(type, input, sourcePath = "") {
    if (type === "url" || type === "path") {
      return input;
    }
    if (type === "fileUrl") {
      if (import_obsidian31.Platform.isMobile) {
        new import_obsidian31.Notice("Local file paths are only supported on desktop.");
        return null;
      }
      try {
        const fs = require("fs");
        const path = require("path");
        let filePath = decodeURIComponent(input.substring(process.platform === "win32" ? 8 : 7));
        filePath = filePath.replace('"', "").replace("![[", "").replace("[[", "").replace("]]", "").replace("//", "");
        if (process.platform === "win32" && /^[a-zA-Z]:/.test(filePath)) {
        } else if (process.platform === "win32" && filePath.startsWith("/")) {
          filePath = filePath.substring(1);
        }
        if (!fs.existsSync(filePath)) {
          console.error(`Pixel Banner: File not found at path: ${filePath}`);
          new import_obsidian31.Notice(`Pixel Banner: File not found at path: ${filePath}`);
          return null;
        }
        const data = fs.readFileSync(filePath);
        const base64 = Buffer.from(data).toString("base64");
        const mimeType = "image/" + path.extname(filePath).substring(1);
        return `data:${mimeType};base64,${base64}`;
      } catch (err) {
        console.error("Pixel Banner: Error reading local file:", err);
        new import_obsidian31.Notice("Pixel Banner: Error reading local file. Check console for details.");
        return null;
      }
    }
    if (type === "obsidianLink") {
      const file = this.getPathFromObsidianLink(input);
      if (file) {
        return this.getVaultImageUrl(file.path);
      }
      return null;
    }
    if (type === "markdownImage") {
      const path = this.getPathFromMarkdownImage(input);
      if (typeof path === "string") {
        try {
          new URL(path);
          return path;
        } catch (_) {
          return this.getVaultImageUrl(path);
        }
      }
      if (path) {
        return this.getVaultImageUrl(path.path);
      }
      return null;
    }
    if (type === "vaultPath") {
      let file = this.app.vault.getAbstractFileByPath(input);
      if (file && "extension" in file) {
        return this.getVaultImageUrl(input);
      }
      const resolvedFile = this.app.metadataCache.getFirstLinkpathDest(input, sourcePath);
      if (resolvedFile && "extension" in resolvedFile) {
        return this.getVaultImageUrl(resolvedFile.path);
      }
      return null;
    }
    if (type === "keyword") {
      const keywords = input.includes(",") ? input.split(",").map((k) => k.trim()).filter((k) => k.length > 0).filter(Boolean) : [input];
      if (keywords.length > 0) {
        const selectedKeyword = keywords[Math.floor(Math.random() * keywords.length)];
        const availableProviders = [];
        if (this.settings.apiProviders && Array.isArray(this.settings.apiProviders)) {
          for (const provider of this.settings.apiProviders) {
            const hasKey = provider === "pexels" && this.settings.pexelsApiKey || provider === "pixabay" && this.settings.pixabayApiKey || provider === "flickr" && this.settings.flickrApiKey || provider === "unsplash" && this.settings.unsplashApiKey;
            if (hasKey) {
              availableProviders.push(provider);
            }
          }
        } else {
          if (this.settings.pexelsApiKey) availableProviders.push("pexels");
          if (this.settings.pixabayApiKey) availableProviders.push("pixabay");
          if (this.settings.flickrApiKey) availableProviders.push("flickr");
          if (this.settings.unsplashApiKey) availableProviders.push("unsplash");
        }
        if (availableProviders.length === 0) {
          return null;
        }
        for (const provider of availableProviders) {
          try {
            let result = null;
            switch (provider) {
              case "pexels":
                result = await fetchPexelsImage(this, selectedKeyword, true);
                break;
              case "pixabay":
                result = await fetchPixabayImage(this, selectedKeyword);
                break;
              case "flickr":
                result = await fetchFlickrImage(this, selectedKeyword);
                break;
              case "unsplash":
                result = await fetchUnsplashImage(this, selectedKeyword);
                break;
            }
            if (result) {
              return result;
            }
          } catch (error) {
            console.error(`Error with ${provider} for keyword "${selectedKeyword}":`, error);
          }
        }
        const defaultKeywords = this.settings.defaultKeywords ? this.settings.defaultKeywords.split(",").map((k) => k.trim()).filter((k) => k.length > 0) : [];
        for (const fallbackKeyword of defaultKeywords) {
          for (const provider of availableProviders) {
            try {
              let result = null;
              switch (provider) {
                case "pexels":
                  result = await fetchPexelsImage(this, fallbackKeyword, true);
                  break;
                case "pixabay":
                  result = await fetchPixabayImage(this, fallbackKeyword);
                  break;
                case "flickr":
                  result = await fetchFlickrImage(this, fallbackKeyword);
                  break;
                case "unsplash":
                  result = await fetchUnsplashImage(this, fallbackKeyword);
                  break;
              }
              if (result) {
                return result;
              }
            } catch (error) {
              console.error(`Error with ${provider} for fallback keyword "${fallbackKeyword}":`, error);
            }
          }
        }
        return null;
      }
    }
    return null;
  }
  // --------------------
  // -- post processor --
  // --------------------
  async postProcessor(el, ctx) {
    const frontmatter = ctx.frontmatter;
    let bannerImageValue = null;
    if (frontmatter) {
      for (const field of this.settings.customBannerField) {
        if (frontmatter[field]) {
          bannerImageValue = frontmatter[field];
          break;
        }
      }
    }
    if (bannerImageValue) {
      await this.addPixelBanner(el, {
        frontmatter,
        file: ctx.sourcePath,
        isContentChange: false,
        yPosition: getFrontmatterValue(frontmatter, this.settings.customYPositionField) || this.settings.yPosition,
        contentStartPosition: getFrontmatterValue(frontmatter, this.settings.customContentStartField) || this.settings.contentStartPosition,
        customBannerField: this.settings.customBannerField,
        customYPositionField: this.settings.customYPositionField,
        customXPositionField: this.settings.customXPositionField,
        customContentStartField: this.settings.customContentStartField,
        customImageDisplayField: this.settings.customImageDisplayField,
        customImageRepeatField: this.settings.customImageRepeatField,
        customBannerMaxWidthField: this.settings.customBannerMaxWidthField,
        bannerImage: bannerImageValue
      });
      if (this.settings.hidePixelBannerFields) {
        const frontmatterEl = el.querySelector(".frontmatter");
        if (frontmatterEl) {
          const fieldsToHide = [
            ...this.settings.customBannerField,
            ...this.settings.customYPositionField,
            ...this.settings.customXPositionField,
            ...this.settings.customContentStartField,
            ...this.settings.customImageDisplayField,
            ...this.settings.customImageRepeatField,
            ...this.settings.customBannerMaxWidthField,
            ...this.settings.customBannerHeightField,
            ...this.settings.customBannerAlignmentField,
            ...this.settings.customFadeField,
            ...this.settings.customBorderRadiusField,
            ...this.settings.customTitleColorField,
            ...this.settings.customBannerShuffleField,
            ...this.settings.customBannerIconField,
            ...this.settings.customBannerIconSizeField,
            ...this.settings.customBannerIconImageSizeMultiplierField,
            ...this.settings.customBannerIconTextVerticalOffsetField,
            ...this.settings.customBannerIconRotateField,
            ...this.settings.customBannerIconImageAlignmentField,
            ...this.settings.customBannerIconXPositionField,
            ...this.settings.customBannerIconOpacityField,
            ...this.settings.customBannerIconColorField,
            ...this.settings.customBannerIconFontWeightField,
            ...this.settings.customBannerIconBackgroundColorField,
            ...this.settings.customBannerIconPaddingXField,
            ...this.settings.customBannerIconPaddingYField,
            ...this.settings.customBannerIconBorderRadiusField,
            ...this.settings.customBannerIconVerticalOffsetField
          ];
          const rows = frontmatterEl.querySelectorAll(".frontmatter-container .frontmatter-section-label");
          rows.forEach((row) => {
            const label = row.textContent.replace(":", "").trim();
            if (fieldsToHide.includes(label)) {
              row.closest(".frontmatter-section").classList.add("pixel-banner-hidden-field");
            }
          });
        }
      }
    }
  }
  // --------------
  // -- onunload --
  // --------------
  onunload() {
    if (this.observer && typeof this.observer.disconnect === "function") {
      this.observer.disconnect();
    }
    this.app.workspace.iterateAllLeaves((leaf) => {
      if (leaf.view instanceof import_obsidian31.MarkdownView) {
        const viewContent = leaf.view.contentEl;
        if (viewContent._resizeObserver && typeof viewContent._resizeObserver.disconnect === "function") {
          viewContent._resizeObserver.disconnect();
          delete viewContent._resizeObserver;
        }
      }
    });
    this.iconOverlayPool = [];
    const styleElTitle = document.getElementById("pixel-banner-embedded-titles");
    if (styleElTitle) styleElTitle.remove();
    const styleElBanner = document.getElementById("pixel-banner-embedded-banners");
    if (styleElBanner) styleElBanner.remove();
  }
  // -------------------------
  // -- clean orphaned pins --
  // -------------------------
  async cleanOrphanedPins() {
    var _a;
    const vault = this.app.vault;
    const folderPath = this.settings.pinnedImageFolder;
    let cleaned = 0;
    try {
      if (!await vault.adapter.exists(folderPath)) {
        return { cleaned };
      }
      const pinnedFolder = vault.getAbstractFileByPath(folderPath);
      if (!pinnedFolder || !pinnedFolder.children) {
        return { cleaned };
      }
      const imageExtensions = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg", "avif"];
      const pinnedImages = pinnedFolder.children.filter((file) => imageExtensions.includes(file.extension.toLowerCase())).map((file) => file.path);
      if (!pinnedImages.length) {
        return { cleaned };
      }
      const markdownFiles = this.app.vault.getMarkdownFiles();
      const bannerFields = this.settings.customBannerField;
      const referencedImages = /* @__PURE__ */ new Set();
      for (const file of markdownFiles) {
        const frontmatter = (_a = this.app.metadataCache.getFileCache(file)) == null ? void 0 : _a.frontmatter;
        if (frontmatter) {
          for (const field of bannerFields) {
            const bannerValue = frontmatter[field];
            if (bannerValue && typeof bannerValue === "string") {
              let cleanPath;
              if (bannerValue.startsWith("[[") && bannerValue.endsWith("]]")) {
                cleanPath = bannerValue.slice(2, -2).replace(/["']/g, "");
              } else {
                cleanPath = bannerValue.replace(/["']/g, "");
              }
              if (!cleanPath.startsWith(folderPath)) {
                const resolvedFile = this.app.metadataCache.getFirstLinkpathDest(cleanPath, file.path);
                if (resolvedFile) {
                  cleanPath = resolvedFile.path;
                }
              }
              referencedImages.add(cleanPath);
            }
          }
        }
      }
      for (const imagePath of pinnedImages) {
        if (!referencedImages.has(imagePath)) {
          await vault.trash(vault.getAbstractFileByPath(imagePath), true);
          cleaned++;
        }
      }
      return { cleaned };
    } catch (error) {
      console.error("Error in cleanOrphanedPins:", error);
      throw error;
    }
  }
  // -----------------------------------------
  // -- show release notes for new versions --
  // -----------------------------------------
  async checkVersion() {
    const currentVersion = this.manifest.version;
    const lastVersion = this.settings.lastVersion;
    if (this.settings.showReleaseNotes && (!lastVersion || lastVersion !== currentVersion)) {
      const releaseNotes2 = await this.getReleaseNotes(currentVersion);
      new ReleaseNotesModal(this.app, currentVersion, releaseNotes2).open();
      this.settings.lastVersion = currentVersion;
      await this.saveSettings();
    }
    if (lastVersion && lastVersion !== currentVersion) {
      console.log("[Pixel Banner] Plugin updated from", lastVersion, "to", currentVersion, "- invalidating cached cloud version");
      this.pixelBannerVersion = void 0;
    }
  }
  // -----------------------------------------------
  // -- get release notes for the current version --
  // -----------------------------------------------
  async getReleaseNotes(version) {
    return releaseNotes;
  }
  // ------------------------------------------
  // -- verify pixel banner plus credentials --
  // ------------------------------------------
  async verifyPixelBannerPlusCredentials() {
    if (this.settings.pixelBannerPlusEnabled) {
      const result = await verifyPixelBannerPlusCredentials(this);
      this.pixelBannerPlusServerOnline = result.serverOnline;
      this.pixelBannerPlusEnabled = result.verified;
      this.pixelBannerPlusBannerTokens = result.bannerTokens;
      this.pixelBannerPlusJackpot = result.jackpot;
      this.pixelBannerPlusDailyGameName = result.dailyGameName;
      this.pixelBannerPlusHighScore = result.highScore || "0";
      this.pixelBannerPlusTopUser = result.topUser;
      this.pixelBannerPlusTimeLeft = result.timeLeft;
      return result;
    }
    return {
      serverOnline: false,
      verified: false,
      bannerTokens: 0,
      jackpot: 0,
      dailyGameName: "",
      highScore: "0",
      topUser: "",
      timeLeft: 0
    };
  }
  // -------------------------------- //
  // -- get pixel banner plus info -- //
  // -------------------------------- //
  async getPixelBannerInfo() {
    const result = await getPixelBannerInfo(this);
    this.pixelBannerVersion = result.version;
    return result;
  }
  // --------------------------
  // -- open the banner store --
  // --------------------------
  openBannerStore() {
    new PixelBannerStoreModal(this.app, this).open();
  }
};

// src/main.js
var main_default = PixelBannerPlugin;

/* nosourcemap */