KG_Chat_Application

Enhance the chat abilities

目前為 2025-03-18 提交的版本,檢視 最新版本

// ==UserScript==
// @name         KG_Chat_Application
// @namespace    klavogonki
// @version      1.7.6
// @description  Enhance the chat abilities
// @author       Patcher
// @match        *://klavogonki.ru/*
// @exclude      https://klavogonki.ru/g/?gmid=*
// @exclude      https://klavogonki.ru/chatlogs/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=klavogonki.ru
// @grant        none
// ==/UserScript==

(()=>{"use strict";var e={21:(e,t,n)=>{n.d(t,{A:()=>s});var r=n(601),o=n.n(r),a=n(314),i=n.n(a)()(o());i.push([e.id,".help-panel {\n  opacity: 0;\n  transition: opacity 0.3s ease;\n  position: fixed;\n  left: 50%;\n  top: 50%;\n  transform: translate(-50%, -50%);\n  height: fit-content;\n  max-height: 70vh !important;\n  width: fit-content;\n  overflow-y: auto;\n  scrollbar-width: none;\n  /* Existing styles */\n  background: #1e1e1e;\n  border: 1px solid #333 !important;\n  padding: 1em;\n  border-radius: 0.4em !important;\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;\n  color: #deb887 !important;\n  font-family:'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;\n  z-index: 1100;\n}\n\n/* Header styling */\n.help-header {\n  margin-top: 0;\n  font-size: 1.5em;\n  text-align: center;\n  color: #ffa500 !important;\n}\n\n/* Subheader styling – now further differentiated */\n.help-subheader {\n  margin: 0.8em 0 0.3em 1em;\n  /* Added left margin of 1em */\n  font-size: 1.1em;\n  /* Smaller than header */\n  color: #ffcc00 !important;\n  font-weight: normal;\n  text-align: left;\n}\n\n/* Header for a specific section */\n.help-section-header {\n  margin-top: 0 !important;\n  margin-bottom: 1.5em !important;\n  font-size: 1.5em !important;\n  text-align: center;\n  color: #ffa500 !important;\n}\n\n/* Subheader for a specific section (different type) */\n.help-section-subheader {\n  margin: 0.8em 0 1.2em 1em;\n  /* left margin added */\n  font-size: 0.9em;\n  color: #ffcc00 !important;\n  font-weight: normal;\n  text-align: left;\n}\n\n/* List styling */\n.help-list {\n  list-style-type: none;\n  padding-left: 0;\n}\n\n/* List item styling */\n.help-list-item {\n  display: flex;\n  align-items: center;\n  flex-direction: row;\n  padding: 0.3em;\n  border-bottom: 1px dashed #444 !important;\n}\n\n.help-list-item:last-child {\n  border-bottom: none;\n}\n\n/* Hotkey text styling – updated to force command description wrap */\n.help-hotkey {\n  width: fit-content;\n  display: flex;\n  color: #7ed4ff !important;\n  font-family: monospace;\n  background-color: rgba(126, 212, 255, 0.1) !important;\n  border: 1px solid rgba(126, 212, 255, 0.4) !important;\n  border-left: 3px solid rgba(126, 212, 255, 0.4) !important;\n  border-radius: 0 0.2em 0.2em 0 !important;\n  padding: 2px 4px;\n  margin-right: 1em;\n}",""]);const s=i},56:(e,t,n)=>{e.exports=function(e){var t=n.nc;t&&e.setAttribute("nonce",t)}},72:e=>{var t=[];function n(e){for(var n=-1,r=0;r<t.length;r++)if(t[r].identifier===e){n=r;break}return n}function r(e,r){for(var a={},i=[],s=0;s<e.length;s++){var c=e[s],l=r.base?c[0]+r.base:c[0],d=a[l]||0,u="".concat(l," ").concat(d);a[l]=d+1;var m=n(u),p={css:c[1],media:c[2],sourceMap:c[3],supports:c[4],layer:c[5]};if(-1!==m)t[m].references++,t[m].updater(p);else{var h=o(p,r);r.byIndex=s,t.splice(s,0,{identifier:u,updater:h,references:1})}i.push(u)}return i}function o(e,t){var n=t.domAPI(t);n.update(e);return function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap&&t.supports===e.supports&&t.layer===e.layer)return;n.update(e=t)}else n.remove()}}e.exports=function(e,o){var a=r(e=e||[],o=o||{});return function(e){e=e||[];for(var i=0;i<a.length;i++){var s=n(a[i]);t[s].references--}for(var c=r(e,o),l=0;l<a.length;l++){var d=n(a[l]);0===t[d].references&&(t[d].updater(),t.splice(d,1))}a=c}}},113:e=>{e.exports=function(e,t){if(t.styleSheet)t.styleSheet.cssText=e;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}}},314:e=>{e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n="",r=void 0!==t[5];return t[4]&&(n+="@supports (".concat(t[4],") {")),t[2]&&(n+="@media ".concat(t[2]," {")),r&&(n+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),n+=e(t),r&&(n+="}"),t[2]&&(n+="}"),t[4]&&(n+="}"),n})).join("")},t.i=function(e,n,r,o,a){"string"==typeof e&&(e=[[null,e,void 0]]);var i={};if(r)for(var s=0;s<this.length;s++){var c=this[s][0];null!=c&&(i[c]=!0)}for(var l=0;l<e.length;l++){var d=[].concat(e[l]);r&&i[d[0]]||(void 0!==a&&(void 0===d[5]||(d[1]="@layer".concat(d[5].length>0?" ".concat(d[5]):""," {").concat(d[1],"}")),d[5]=a),n&&(d[2]?(d[1]="@media ".concat(d[2]," {").concat(d[1],"}"),d[2]=n):d[2]=n),o&&(d[4]?(d[1]="@supports (".concat(d[4],") {").concat(d[1],"}"),d[4]=o):d[4]="".concat(o)),t.push(d))}},t}},498:(e,t,n)=>{n.d(t,{A:()=>s});var r=n(601),o=n.n(r),a=n(314),i=n.n(a)()(o());i.push([e.id,':root {\n  --emoji-font: "Noto Color Emoji";\n}\n\n.emoji-panel {\n  opacity: 0;\n  transition: opacity 0.3s ease;\n  position: absolute !important;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  background: #1e1e1e !important;\n  border: 1px solid #333 !important;\n  border-radius: 0.4em !important;\n  width: 380px;\n  height: 580px;\n  display: flex;\n  flex-direction: column;\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15) !important;\n  z-index: 1000;\n}\n\n.emoji-search-container {\n  padding: 1em !important;\n  border: none !important;\n}\n\n.emoji-search {\n  width: 100%;\n  padding: 8px;\n  border-radius: 4px;\n  background: #2a2a2a !important;\n  border: none !important;\n  border-radius: 0.2em !important;\n  color: #deb887 !important;\n  caret-color: #deb887 !important;\n  font-size: 0.9em !important;\n}\n\n.emoji-search:focus {\n  outline: none;\n  border-color: #666;\n}\n\n.emoji-categories {\n  position: sticky !important;\n  top: 0 !important;\n  display: grid !important;\n  grid-template-columns: repeat(auto-fill, minmax(32px, 1fr)) !important;\n  padding: 8px !important;\n  border-bottom: 1px solid #333 !important;\n  gap: 8px !important;\n  justify-content: center !important;\n  align-items: center !important;\n  overflow-x: auto !important;\n  scrollbar-width: thin !important;\n}\n\n.emoji-category-btn {\n  font-family: var(--emoji-font) !important;\n  position: relative !important;\n  background: none !important;\n  border: none !important;\n  padding: 4px !important;\n  cursor: pointer !important;\n  font-size: 1.5em !important;\n  transition: background-color 0.2s;\n  width: 100% !important;\n  height: 100% !important;\n  display: flex !important;\n  align-items: center !important;\n  justify-content: center !important;\n  aspect-ratio: 1 !important;\n  border-bottom: 3px solid transparent !important;\n}\n\n/* Active category button gets a 3px {color} border */\n.emoji-category-btn.active {\n  opacity: 1;\n  border-bottom: 3px solid goldenrod !important;\n}\n\n.emoji-category-btn:hover {\n  background-color: #333;\n}\n\n.emoji-container {\n  flex: 1;\n  overflow-y: auto;\n  overflow-x: hidden !important;\n  display: grid !important;\n  gap: 8px !important;\n  width: 100% !important;\n  max-width: 100% !important;\n  scrollbar-width: none !important;\n}\n\n.emoji-category-section {\n  margin-bottom: 10px;\n}\n\n.emoji-category-header {\n  padding: 8px !important;\n  color: #deb887 !important;\n  font-size: 0.9em !important;\n  position: sticky !important;\n  top: 0px !important;\n  background: #1e1e1e !important;\n  z-index: 1 !important;\n  border-bottom: 1px solid #333 !important;\n  width: 100% !important;\n  box-sizing: border-box !important;\n  margin: 0 !important;\n}\n\n.emoji-list {\n  display: grid;\n  grid-template-columns: repeat(auto-fill, minmax(32px, 1fr)) !important;\n  padding: 8px !important;\n  gap: 8px;\n  align-content: start;\n}\n\n.emoji-btn {\n  font-family: var(--emoji-font), sans-serif !important;\n  background: none;\n  border: none;\n  padding: 4px !important;\n  cursor: pointer;\n  font-size: 1.5em !important;\n  transition: background-color 0.2s;\n  width: 100% !important;\n  height: 100% !important;\n  display: flex !important;\n  align-items: center !important;\n  justify-content: center !important;\n  aspect-ratio: 1 !important;\n}\n\n.emoji-btn:hover {\n  background-color: #333;\n}\n\n.emoji-footer {\n  border-top: 1px solid #333 !important;\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  align-items: center;\n  padding: 5px;\n}\n\n/* Info panel fixed at bottom with a 50px height */\n.emoji-info-panel {\n  height: 40px !important;\n  padding: 8px !important;\n  display: flex !important;\n  align-items: center !important;\n  gap: 8px !important;\n  color: #deb887 !important;\n  font-size: 0.9em !important;\n  background: #1e1e1e !important;\n}\n\n.emoji-language-select {\n  border-radius: 0.4em !important;\n  /* Rounded corners */\n  padding: 5px 10px;\n  /* Space inside the select */\n  font-size: 14px;\n  /* Font size for readability */\n  background-color: #2a2a2a !important;\n  /* Dark background to match search input */\n  border: 1px solid #444 !important;\n  /* Subtle dark border */\n  color: #deb887 !important;\n  /* Text color to match headers and info panel */\n  cursor: pointer;\n  /* Pointer cursor to indicate it\'s clickable */\n  transition: border-color 0.3s ease;\n  /* Smooth transition for border color */\n}\n\n/* Focus state */\n.emoji-language-select:focus {\n  outline: none;\n  /* Remove default outline */\n  border-color: goldenrod !important;\n  /* Match active category button */\n}\n\n/* Hover state */\n.emoji-language-select:hover {\n  border-color: #666 !important;\n  /* Lighten border on hover */\n}\n\n/* Optional: Style for options (limited control) */\n.emoji-language-select option {\n  font-size: 14px;\n  /* Match font size */\n  background-color: #2a2a2a !important;\n  /* Dark background for options */\n  color: #deb887 !important;\n  /* Text color for options */\n}\n\n.emoji-info-icon {\n  font-family: var(--emoji-font) !important;\n  font-size: 1.5em !important;\n}\n\n.emoji-info-keywords {\n  color: #888 !important;\n  font-style: italic !important;\n}\n\n/* Scrollbar styling */\n.emoji-container::-webkit-scrollbar,\n.emoji-categories::-webkit-scrollbar {\n  width: 6px;\n  height: 6px;\n}\n\n.emoji-container::-webkit-scrollbar-track,\n.emoji-categories::-webkit-scrollbar-track {\n  background: #1e1e1e;\n}\n\n.emoji-container::-webkit-scrollbar-thumb,\n.emoji-categories::-webkit-scrollbar-thumb {\n  background: #444;\n  border-radius: 3px;\n}\n\n.emoji-container::-webkit-scrollbar-thumb:hover,\n.emoji-categories::-webkit-scrollbar-thumb:hover {\n  background: #555;\n}',""]);const s=i},540:e=>{e.exports=function(e){var t=document.createElement("style");return e.setAttributes(t,e.attributes),e.insert(t,e.options),t}},601:e=>{e.exports=function(e){return e[1]}},659:e=>{var t={};e.exports=function(e,n){var r=function(e){if(void 0===t[e]){var n=document.querySelector(e);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}t[e]=n}return t[e]}(e);if(!r)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");r.appendChild(n)}},825:e=>{e.exports=function(e){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var t=e.insertStyleElement(e);return{update:function(n){!function(e,t,n){var r="";n.supports&&(r+="@supports (".concat(n.supports,") {")),n.media&&(r+="@media ".concat(n.media," {"));var o=void 0!==n.layer;o&&(r+="@layer".concat(n.layer.length>0?" ".concat(n.layer):""," {")),r+=n.css,o&&(r+="}"),n.media&&(r+="}"),n.supports&&(r+="}");var a=n.sourceMap;a&&"undefined"!=typeof btoa&&(r+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),t.styleTagTransform(r,e,t.options)}(t,e,n)},remove:function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(t)}}}},919:(e,t,n)=>{n.d(t,{A:()=>s});var r=n(601),o=n.n(r),a=n(314),i=n.n(a)()(o());i.push([e.id,"@import url(https://fonts.googleapis.com/css2?family=Noto+Color+Emoji&display=swap);"]),i.push([e.id,"@import url(https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap);"]),i.push([e.id,"@import url(https://fonts.googleapis.com/css2?family=Iansui&family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap);"]),i.push([e.id,'/* Variables */\n:root {\n  --border-radius: 0.2em;\n  --min-chat-width: 320px;\n  --min-chat-height: 200px;\n  --user-list-width: fit-content;\n  --emoji-font: "Noto Color Emoji";\n  /* really slight modern box shadow */\n  --box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);\n}\n\n/* Main chat container */\n#app-chat-container {\n  border-radius: 0.4em 0.4em 0 0 !important;\n  position: fixed;\n  bottom: 0;\n  left: 0;\n  height: 300px;\n  background: #1e1e1e !important;\n  border: 1px solid #333 !important;\n  display: flex;\n  font-family: sans-serif;\n  color: #deb887 !important;\n  z-index: 999;\n  min-width: var(--min-chat-width) !important;\n  min-height: var(--min-chat-height) !important;\n  box-sizing: border-box;\n  max-width: 100vw;\n  overflow: hidden;\n  transition: opacity 0.3s ease, transform 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);\n}\n\n#app-chat-container a {\n  color: #82B32A !important;\n  transition: color 0.15s !important;\n}\n\n#app-chat-container a:hover {\n  color: #95cc30 !important;\n}\n\n/* Chat container states */\n#app-chat-container.maximized {\n  position: fixed;\n  z-index: 1010;\n}\n\n#app-chat-container:not(.visible-chat):not(.hidden-chat):not(.maximized):not(.floating-chat) {\n  display: none;\n  opacity: 0;\n}\n\n#app-chat-container.visible-chat {\n  transform: translateY(0) !important;\n}\n\n#app-chat-container.hidden-chat {\n  opacity: 1;\n  transform: translateY(calc(100% - 25px)) !important;\n}\n\n#app-chat-container.floating-chat {\n  border-radius: 0.4em !important;\n}\n\n/* Responsive styles */\n@media (max-width: 780px) {\n  #app-chat-container .chat-wrapper {\n    width: 100% !important;\n    border-right: none !important;\n  }\n}\n\n@media screen and (max-width: 768px),\n(hover: none),\n(pointer: coarse) {\n  body {\n    background-color: #1e1e1e !important;\n  }\n\n  #app-chat-container {\n    height: 100% !important;\n    width: 100vw !important;\n    min-height: 100% !important;\n    min-width: 100vw !important;\n    border: none !important;\n    border-radius: 0 !important;\n    overflow: hidden !important;\n  }\n\n  #app-chat-container .toggle-button {\n    border: none !important;\n    top: unset !important;\n    right: 0 !important;\n    bottom: 0 !important;\n    border-radius: 0.2em !important;\n    margin: 1em !important;\n    box-shadow: var(--box-shadow) !important;\n  }\n\n  /* Hide everything except #app-chat-container */\n  body>*:not(#app-chat-container):not(.dimming-element):not(.scaled-thumbnail):not(.delete-btn):not(.toggle-button) {\n    display: none !important;\n  }\n\n  /* Hide specific elements inside #app-chat-container */\n  #app-chat-container .resize-handle,\n  #app-chat-container .font-size-control,\n  #app-chat-container .header-button,\n  #app-chat-container #send-button {\n    display: none !important;\n  }\n}\n\n@media screen and (max-width: 367px) {\n  #app-chat-container .video-container {\n    transform-origin: left !important;\n    transform: scale(0.9) !important;\n  }\n}\n\n@media screen and (max-width: 350px) {\n  #app-chat-container .video-container {\n    transform-origin: left !important;\n    transform: scale(0.8) !important;\n  }\n}\n\n/* Font size control */\n#app-chat-container .font-size-control {\n  position: absolute !important;\n  top: 0 !important;\n  left: 0 !important;\n  display: flex !important;\n  align-items: center !important;\n  justify-content: center !important;\n  height: 25px !important;\n  padding: 0 10px !important;\n  gap: 5px !important;\n  z-index: 6 !important;\n}\n\n#app-chat-container .font-size-label {\n  color: #deb887 !important;\n  cursor: default !important;\n  user-select: none !important;\n}\n\n#app-chat-container .font-size-label.small {\n  font-size: 0.8em !important;\n}\n\n#app-chat-container .font-size-label.large {\n  font-size: 1.2em !important;\n}\n\n#app-chat-container .font-size-slider {\n  width: 80px !important;\n  height: 4px !important;\n  -webkit-appearance: none !important;\n  appearance: none !important;\n  background: #333 !important;\n  outline: none !important;\n  border-radius: 2px !important;\n  transition: opacity 0.2s !important;\n}\n\n#app-chat-container .font-size-slider::-webkit-slider-thumb {\n  -webkit-appearance: none !important;\n  appearance: none !important;\n  width: 10px !important;\n  height: 10px !important;\n  border-radius: 50% !important;\n  background: #deb887 !important;\n  cursor: pointer !important;\n}\n\n#app-chat-container .font-size-slider::-moz-range-thumb {\n  width: 10px !important;\n  height: 10px !important;\n  border-radius: 50% !important;\n  background: #deb887 !important;\n  cursor: pointer !important;\n  border: none !important;\n}\n\n/* Resize handles */\n#app-chat-container .resize-handle {\n  position: absolute !important;\n  background: transparent !important;\n  z-index: 1000 !important;\n}\n\n#app-chat-container .resize-handle.top {\n  top: -3px !important;\n  left: 0 !important;\n  right: 0 !important;\n  height: 6px !important;\n  cursor: ns-resize !important;\n}\n\n#app-chat-container .resize-handle.left {\n  left: -3px !important;\n  top: 0 !important;\n  bottom: 0 !important;\n  width: 6px !important;\n  cursor: ew-resize !important;\n}\n\n#app-chat-container .resize-handle.right {\n  right: -3px !important;\n  top: 0 !important;\n  bottom: 0 !important;\n  width: 6px !important;\n  cursor: ew-resize !important;\n}\n\n/* Chat wrapper: two-column layout */\n#app-chat-container .chat-wrapper {\n  display: flex !important;\n  flex-direction: row !important;\n  flex: 1 !important;\n  min-width: var(--min-chat-width) !important;\n  overflow: hidden !important;\n}\n\n/* Left column: messages & input */\n#app-chat-container .chat-content {\n  margin-top: 25px !important;\n  background: #1e1e1e !important;\n  display: flex !important;\n  flex-direction: column !important;\n  flex: 1 !important;\n  overflow: hidden !important;\n}\n\n/* Scrollable container settings */\n#app-chat-container .messages-panel {\n  flex: 1 !important;\n  overflow-y: auto !important;\n  overflow-x: hidden !important;\n  padding: 1em !important;\n  display: flex !important;\n  flex-direction: column !important;\n  gap: 0.2em !important;\n  scrollbar-width: thin !important;\n  scrollbar-color: #333 #1e1e1e !important;\n}\n\n#app-chat-container .messages-panel.keyboard-active {\n  transition: margin-bottom 0.3s ease !important;\n}\n\n/* Custom scrollbar styling for WebKit browsers */\n#app-chat-container .messages-panel::-webkit-scrollbar,\n#app-chat-container .user-list-container::-webkit-scrollbar {\n  width: 8px !important;\n}\n\n#app-chat-container .messages-panel::-webkit-scrollbar-thumb,\n#app-chat-container .user-list-container::-webkit-scrollbar-thumb {\n  background-color: #333 !important;\n}\n\n#app-chat-container .messages-panel::-webkit-scrollbar-thumb:hover,\n#app-chat-container .user-list-container::-webkit-scrollbar-thumb:hover {\n  background-color: #444 !important;\n}\n\n#app-chat-container .messages-panel::-webkit-scrollbar-track,\n#app-chat-container .user-list-container::-webkit-scrollbar-track {\n  background-color: #1e1e1e !important;\n}\n\n/* Input container at bottom */\n#app-chat-container .input-container {\n  display: flex !important;\n  align-items: center !important;\n  padding: 1em !important;\n  gap: 0.5em !important;\n  border-top: 1px solid #333 !important;\n  background-color: #1e1e1e !important;\n}\n\n#app-chat-container #message-input {\n  outline: none !important;\n  flex: 1 !important;\n  background: #2a2a2a !important;\n  color: #deb887 !important;\n  padding: 0.5em !important;\n  border-radius: var(--border-radius) !important;\n  min-width: 0 !important;\n  border: none !important;\n  position: relative;\n  font-family: inherit !important;\n  /* Remove any fixed font-size to properly inherit from container */\n  line-height: normal !important;\n  transition: font-size 0.2s ease !important;\n}\n\n#app-chat-container .length-field-popup {\n  position: absolute !important;\n  display: flex !important;\n  font-size: 12px !important;\n  font-weight: bold !important;\n  font-family: "Montserrat", Iansui, sans-serif !important;\n  bottom: 60px !important;\n  transition: left 100ms ease-out !important;\n  height: 20px !important;\n  align-items: center !important;\n  justify-content: center !important;\n  padding: 2px 4px;\n  opacity: 0;\n  border: none !important;\n}\n\n.bounce-in {\n  animation: bounceIn 500ms forwards;\n}\n\n@keyframes bounceIn {\n  0% {\n    transform: translateY(0);\n    opacity: 0;\n  }\n\n  50% {\n    transform: translateY(-10px);\n    opacity: 1;\n  }\n\n  100% {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n\n.bounce-out {\n  animation: bounceOut 500ms forwards;\n}\n\n@keyframes bounceOut {\n  0% {\n    transform: translateY(0);\n    opacity: 1;\n  }\n\n  50% {\n    transform: translateY(-10px);\n    opacity: 1;\n  }\n\n  100% {\n    transform: translateY(0);\n    opacity: 0;\n  }\n}\n\n#app-chat-container #message-input.private-mode {\n  background-color: #ff6b6b38 !important;\n  color: #ff6b6b !important;\n  caret-color: #ff6b6b !important;\n}\n\n#app-chat-container #message-input.private-mode::placeholder {\n  color: #ff6b6b99;\n}\n\n#app-chat-container #messages-panel.private-mode::after {\n  content: "🔒";\n  position: absolute;\n  right: 5px;\n  top: 5px;\n  font-size: 10px;\n  opacity: 0.5;\n}\n\n/* Right column: user list container */\n#app-chat-container .user-list-container {\n  margin-top: 25px;\n  width: var(--user-list-width) !important;\n  min-width: 180px !important;\n  max-width: var(--user-list-width) !important;\n  overflow-y: auto !important;\n  overflow-x: hidden !important;\n  padding: 1em !important;\n  background: #1e1e1e !important;\n  border-left: 1px solid #333 !important;\n  scrollbar-width: thin !important;\n  scrollbar-color: #333 #1e1e1e !important;\n}\n\n.reveal-userlist-btn {\n  position: absolute !important;\n  top: 50% !important;\n  right: -1px !important;\n  transform: translateY(-50%) !important;\n  z-index: 1000 !important;\n  display: flex !important;\n  align-items: center !important;\n  justify-content: center !important;\n  padding: 0.4em !important;\n  background: #222 !important;\n  font-size: 18px !important;\n  font-family: var(--emoji-font), sans-serif !important;\n  font-weight: bold !important;\n  border: 1px solid #333 !important;\n  border-radius: 0.4em 0 0 0.4em !important;\n  cursor: pointer !important;\n  transition: background 0.2s ease, opacity 0.2s ease !important;\n}\n\n/* Hover effect */\n.reveal-userlist-btn:hover {\n  background: #333 !important;\n}\n\n/* When user list is hidden */\n.hidden-userlist {\n  display: flex !important;\n}\n\n/* When user list is shown */\n.shown-userlist {\n  display: none !important;\n}\n\n/* Message styles */\n#app-chat-container .message {\n  padding: 0.2em 0.4em !important;\n  display: flex;\n  flex-direction: row;\n  border-radius: var(--border-radius) !important;\n  width: 100%;\n  max-width: 100% !important;\n  word-break: break-word !important;\n}\n\n#app-chat-container .message-text .emoji-adjuster {\n  font-family: var(--emoji-font), sans-serif !important;\n  font-size: 1.5em !important;\n  margin: 0 0.1em !important;\n  display: inline-flex !important;\n}\n\n#app-chat-container .message-text .mention {\n  display: inline-flex !important;\n  font-family: Montserrat !important;\n  font-weight: 500 !important;\n}\n\n#app-chat-container .message.system {\n  background-color: #ffa50020 !important;\n  border: 1px solid #ffa60030 !important;\n  border-left: 3px solid #ffa500 !important;\n  width: fit-content !important;\n  align-items: center !important;\n}\n\n#app-chat-container .message.system .time {\n  margin-right: unset !important;\n  color: #ffa50060 !important;\n}\n\n#app-chat-container .message.system .username {\n  display: none !important;\n}\n\n#app-chat-container .message.system .message-text {\n  color: #ffa500 !important;\n}\n\n#app-chat-container .message.sent {\n  background: #00ff0020 !important;\n  border: 1px solid #00ff0030 !important;\n  border-left: 3px solid #00ff00 !important;\n}\n\n#app-chat-container .message.sent .time {\n  color: #00ff0060 !important;\n}\n\n#app-chat-container .message.sent .username,\n#app-chat-container .message.sent .message-text {\n  color: #00ff00 !important;\n}\n\n#app-chat-container .message.received {\n  background-color: #ff4d4d20 !important;\n  border: 1px solid #ff4d4d30 !important;\n  border-left: 3px solid #ff4d4d !important;\n}\n\n#app-chat-container .message.received .time {\n  color: #ff4d4d60 !important;\n}\n\n#app-chat-container .message.received .username,\n#app-chat-container .message.received .message-text {\n  color: #ff4d4d !important;\n}\n\n/* Private message styling */\n.message.private-message {\n  width: fit-content !important;\n  background-color: #ffdcdc20;\n  border-left: 3px solid #ff6b6b50;\n}\n\n.message.private-message .message-text {\n  color: #ff6b6b !important;\n}\n\n.message.private-message:not(.sent) {\n  animation: privateMessagePulse 2s ease-in-out 1;\n}\n\n/* Sent private message styling */\n.message.private-message.sent {\n  background: #293e2938 !important;\n  border: 1px solid #293e2959 !important;\n}\n\n/* Received private message styling */\n.message.private-message.received {\n  background-color: #1e1e1e26 !important;\n  border: 1px solid #33333359 !important;\n}\n\n/* Add a subtle animation for received private messages */\n@keyframes privateMessagePulse {\n  0% {\n    background-color: #ffdcdc26;\n  }\n\n  50% {\n    background-color: #ffdcdc4d;\n  }\n\n  100% {\n    background-color: #ffdcdc26;\n  }\n}\n\n#app-chat-container .message-info {\n  margin-right: 1em !important;\n  white-space: nowrap !important;\n}\n\n/* Ensure time and username elements maintain their relative sizes */\n#app-chat-container .message-info .time {\n  font-size: 0.9em !important;\n  margin-right: 1em !important;\n  color: #666 !important;\n}\n\n#app-chat-container .username {\n  font-size: 1em !important;\n}\n\n/* Add to existing style.css content */\n#app-chat-container .username,\n#app-chat-container .time {\n  cursor: pointer !important;\n  transition: opacity 0.2s ease !important;\n}\n\n#app-chat-container .username:hover,\n#app-chat-container .time:hover {\n  opacity: 0.7 !important;\n}\n\n#app-chat-container .message-info .time {\n  margin-right: 1em !important;\n  font-size: 0.9em !important;\n  color: #666 !important;\n}\n\n/* User list item styles */\n#app-chat-container .user-item {\n  display: flex !important;\n  align-items: center !important;\n  padding: 0.2em !important;\n  margin-bottom: 0.2em !important;\n  border-radius: var(--border-radius) !important;\n  max-width: 100% !important;\n  text-overflow: ellipsis !important;\n}\n\n#app-chat-container .user-avatar {\n  display: flex !important;\n  justify-content: center !important;\n  align-items: center !important;\n  width: 24px !important;\n  height: 24px !important;\n  font-size: 18px !important;\n  border-radius: 0.1em !important;\n  margin-right: 1em !important;\n  text-align: center !important;\n  line-height: 24px !important;\n  flex-shrink: 0 !important;\n}\n\n#app-chat-container .user-avatar.image-avatar {\n  cursor: pointer !important;\n  transform-origin: left !important;\n  transition: transform 0.15s ease-out !important;\n}\n\n#app-chat-container .user-avatar.image-avatar:hover {\n  transform: scale(2) !important;\n}\n\n#app-chat-container .user-avatar.svg-avatar {\n  font-family: var(--emoji-font), sans-serif !important;\n}\n\n#app-chat-container .user-info {\n  flex: 1 !important;\n  min-width: 0 !important;\n  overflow: hidden !important;\n  text-overflow: ellipsis !important;\n  white-space: nowrap !important;\n}\n\n#app-chat-container .user-meta {\n  cursor: default;\n  font-size: 0.8em !important;\n  color: #b0b0b0 !important;\n  overflow: hidden !important;\n  text-overflow: ellipsis !important;\n  white-space: nowrap !important;\n}\n\n#app-chat-container .game-link {\n  color: #deb887 !important;\n  text-decoration: none !important;\n  transition: color 0.15s !important;\n}\n\n#app-chat-container .role-moderator {\n  color: #ff7e7e !important;\n}\n\n#app-chat-container .role-participant {\n  color: #7ed4ff !important;\n}\n\n#app-chat-container .role-visitor {\n  color: #b0b0b0 !important;\n}\n\n#app-chat-container .role {\n  font-family: var(--emoji-font), sans-serif !important;\n}\n\n#app-chat-container .role.participant {\n  filter: brightness(0.6) !important;\n}\n\n#app-chat-container .role.visitor {\n  filter: brightness(0.8) !important;\n}\n\n#app-chat-container .traffic-icon {\n  /* Set font-family to var(--emoji-font) or fallback to system emoji */\n  font-family: var(--emoji-font), sans-serif !important;\n}\n\n/* Header toggle button */\n#app-chat-container .header-button {\n  cursor: pointer !important;\n  position: absolute !important;\n  top: 0 !important;\n  width: 25px !important;\n  height: 25px !important;\n  z-index: 5 !important;\n}\n\n#app-chat-container .filled-button {\n  border: none !important;\n  outline: none !important;\n  background-color: transparent !important;\n  transition: all 0.15s ease-out;\n}\n\n#app-chat-container .filled-button:hover {\n  filter: brightness(1.2) !important;\n}\n\n#app-chat-container .emoji-trigger,\n#app-chat-container .private-mode-exit,\n#app-chat-container .send-button {\n  font-family: var(--emoji-font), sans-serif !important;\n  height: 28px !important;\n  width: 28px !important;\n  font-size: 1.5em !important;\n  display: flex !important;\n  align-items: center !important;\n  justify-content: center !important;\n  line-height: 1 !important;\n  cursor: pointer !important;\n  background: transparent !important;\n  border: none !important;\n  outline: none !important;\n  margin: 0 !important;\n  padding: 0 !important;\n}\n\n.chat-toggle-button {\n  right: 0 !important;\n}\n\n.chat-maximize-button {\n  right: 25px !important;\n}\n\n.chat-help-button {\n  color: #82B32A !important;\n  right: 50px !important;\n}\n\n/* Drag area for floating the chat */\n#app-chat-container .chat-drag-area {\n  border-radius: 0.4em 0.4em 0 0 !important;\n  position: absolute !important;\n  top: 0 !important;\n  left: 0 !important;\n  right: 0 !important;\n  height: 25px !important;\n  cursor: move !important;\n  background-color: #161616cc !important;\n}\n\n/* Dimming background style */\n.dimming-element {\n  position: fixed;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background-color: #00000080;\n  z-index: 1010 !important;\n  opacity: 0;\n  transition: opacity 0.3s ease;\n}\n\n/* convertImageLinksToImage */\n.clickable-thumbnail {\n  opacity: 1;\n  transition: opacity 0.15s ease-in-out;\n  border: none;\n  max-width: 150px !important;\n  max-height: 150px !important;\n  cursor: pointer;\n  background-color: transparent;\n  padding: 2px;\n  margin: 6px;\n  overflow-y: auto;\n}\n\n.clickable-thumbnail img {\n  border-radius: var(--border-radius) !important;\n  object-fit: contain;\n  height: 100%;\n  width: 100%;\n}\n\n.clickable-thumbnail:hover {\n  opacity: 0.8;\n}\n\n.scaled-thumbnail {\n  top: 50%;\n  left: 50%;\n  transform-origin: center center;\n  transform: translate(-50%, -50%) scale(1);\n  position: fixed;\n  opacity: 0;\n  z-index: 1015 !important;\n  transform-origin: center center;\n  max-height: 90vh;\n  max-width: 90vw;\n  cursor: pointer;\n  border-radius: 0.6em !important;\n  box-shadow: var(--box-shadow) !important;\n}\n\n/* convertVideoLinksToPlayer */\n.video-wrapper {\n  display: flex;\n  flex-direction: column;\n}\n\n.video-wrapper .processed-video {\n  margin-bottom: 0.6em !important;\n}\n\n.video-container {\n  border-radius: 0.4em !important;\n  display: flex;\n  border: none;\n  height: 200px !important;\n  width: 356px !important;\n}\n\n/* toggleHiddenMessages */\n.toggle-button-hidden {\n  background-color: hsl(0, 20%, 10%);\n  color: hsl(0, 50%, 50%);\n  border: 1px solid hsl(0, 50%, 50%);\n}\n\n.toggle-button-show {\n  background-color: hsl(90, 20%, 10%);\n  color: hsl(90, 50%, 50%);\n  border: 1px solid hsl(90, 50%, 50%);\n}\n\n.toggle-button-hide {\n  background-color: hsl(50, 20%, 10%);\n  color: hsl(50, 50%, 50%);\n  border: 1px solid hsl(50, 50%, 50%);\n}\n\n/* Chat messages manual remover */\n/* Delete button base styles */\n.delete-btn {\n  z-index: 1020 !important;\n  padding: 8px 16px;\n  background-color: hsl(0, 50%, 20%);\n  color: hsl(0, 60%, 70%);\n  border: 1px solid hsl(0, 50%, 35%);\n  transition: all 0.3s;\n  cursor: pointer;\n  filter: brightness(1);\n  border-radius: 0.2em !important;\n}\n\n.delete-btn:hover {\n  filter: brightness(1.5);\n}\n\n/* Common styles for all selected messages */\n.selected-message {\n  background-clip: padding-box !important;\n}\n\n/* message-mode */\n.selected-message.message-mode {\n  background-color: hsla(0, 50%, 50%, 0.2) !important;\n  box-shadow: inset 0px 0px 0px 1px hsl(0, 50%, 50%, 0.4) !important;\n}\n\n/* username-mode */\n.selected-message.username-mode {\n  background-color: hsla(145, 50%, 30%, 0.2) !important;\n  box-shadow: inset 0px 0px 0px 1px hsl(145, 50%, 50%, 0.4) !important;\n}\n\n/* time-mode */\n.selected-message.time-mode {\n  background-color: hsla(200, 50%, 30%, 0.2) !important;\n  box-shadow: inset 0px 0px 0px 1px hsl(200, 50%, 50%, 0.4) !important;\n}\n\n.shown-message {\n  background-color: hsla(30, 60%, 30%, 0.2) !important;\n  box-shadow: inset 0px 0px 0px 1px hsl(30, 60%, 50%, 0.4) !important;\n  background-clip: padding-box !important;\n}\n\n.hidden-message {\n  display: none !important;\n}\n\n/* Toggle button base styles */\n.toggle-button {\n  font: bold 0.9em \'Montserrat\', sans-serif;\n  position: absolute;\n  top: 0;\n  right: 2em;\n  padding: 8px 16px;\n  transition: filter 0.3s;\n  border-radius: 0 0 0.2em 0.2em !important;\n  border-top: none;\n  min-width: 4em;\n}\n\n.toggle-button.toggle-hidden {\n  background: linear-gradient(to top, hsl(0, 50%, 20%), hsl(0, 50%, 25%));\n  color: hsl(0, 60%, 70%);\n  border-left: 1px solid hsl(0, 50%, 35%);\n  border-right: 1px solid hsl(0, 50%, 35%);\n  border-bottom: 1px solid hsl(0, 50%, 35%);\n}\n\n.toggle-button.toggle-shown {\n  background: linear-gradient(to top, hsl(30, 50%, 20%), hsl(30, 50%, 25%));\n  color: hsl(30, 60%, 70%);\n  border-left: 1px solid hsl(30, 50%, 35%);\n  border-right: 1px solid hsl(30, 50%, 35%);\n  border-bottom: 1px solid hsl(30, 50%, 35%);\n}\n\n.toggle-button:hover {\n  filter: brightness(1.5);\n}',""]);const s=i}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var a=t[r]={id:r,exports:{}};return e[r](a,a.exports,n),a.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.nc=void 0;var r=n(72),o=n.n(r),a=n(825),i=n.n(a),s=n(659),c=n.n(s),l=n(56),d=n.n(l),u=n(540),m=n.n(u),p=n(113),h=n.n(p),g=n(919),f={};f.styleTagTransform=h(),f.setAttributes=d(),f.insert=c().bind(null,"head"),f.domAPI=i(),f.insertStyleElement=m();o()(g.A,f);g.A&&g.A.locals&&g.A.locals;var y=n(498),b={};b.styleTagTransform=h(),b.setAttributes=d(),b.insert=c().bind(null,"head"),b.domAPI=i(),b.insertStyleElement=m();o()(y.A,b);y.A&&y.A.locals&&y.A.locals;var v=n(21),w={};w.styleTagTransform=h(),w.setAttributes=d(),w.insert=c().bind(null,"head"),w.domAPI=i(),w.insertStyleElement=m();o()(v.A,w);v.A&&v.A.locals&&v.A.locals;const x="https://klavogonki.ru",k=`${x}/xmpp-httpbind/`,E=5e3,C={get username(){const e=localStorage.getItem("klavoauth");return e?JSON.parse(e).username:""},get password(){const e=localStorage.getItem("klavoauth");return e?JSON.parse(e).password:""}},S=["😀","😁","😂","🤣","😃","😄","😅","😆","😉","😊","😋","😎","😏","😐","😑","😒","😓","😔","😕","😖","😗","😘","😙","😚","😜","😝","😛","🤑","🤗","🤔","🤐","🤨","😣","😥","😮","🤯","😳","😱","😨","😰","😢","🤪","😵","😲","🤤","😷","🤒","🤕","🤢","🤧","😇","🥳","🥺","😬","😴","😌","🤥","🥴","🥵","🥶","🤧","🤭","🤫","😠","😡","😳","😞","😟","😕","🐱","😺","😸","😹","😻","😼","😽","🙀","😿","😾","🐶","🐭","🐹","🐰","🦊","🐻","🐼","🐨","🐯","🦁","🐮","🐷","🐸","🐵","🙈","🙉","🙊","🐔","🦄"];let L={bigImageEvents:{}};const j=["klavogonki.ru","youtube.com","youtu.be","imgur.com","pikabu.ru","userapi.com","ibb.co","yaplakal.com","freepik.com"];class I{constructor({username:e,password:t,bindUrl:n,delay:r=1e3}){this.username=e,this.password=t,this.bindUrl=n,this.delay=r,this.sid=null,this.rid=Math.floor(Date.now()/1e3)}nextRid(){return++this.rid}async sendRequest(e){const t=await fetch(this.bindUrl,{method:"POST",headers:{"Content-Type":"text/xml; charset=UTF-8","User-Agent":"Mozilla/5.0"},body:e});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);return await t.text()}async sendRequestWithRetry(e,t=5){let n,r=this.delay;for(let o=1;o<=t;o++)try{return await this.sendRequest(e)}catch(e){if(n=e,!e.message.includes("429"))throw e;{const e=r*Math.pow(2,o);console.log(`⏱️ Rate limited (attempt ${o}/${t}). Waiting ${e}ms...`),await this.sleep(e)}}throw new Error(`Max retries reached. Last error: ${n.message}`)}sleep(e){return new Promise((t=>setTimeout(t,e)))}base64Encode(e){const t=(new TextEncoder).encode(e);return btoa(String.fromCharCode(...t))}async connect(){console.log("🌐 Step 1: Connecting to XMPP server...");const e=`<body xmlns='http://jabber.org/protocol/httpbind'\n               rid='${this.nextRid()}'\n               to='jabber.klavogonki.ru'\n               xml:lang='en'\n               wait='60'\n               hold='1'\n               ver='1.6'\n               xmpp:version='1.0'\n               xmlns:xmpp='urn:xmpp:xbosh'/>`,t=await this.sendRequestWithRetry(e);this.sid=t.match(/sid=['"]([^'"]+)['"]/)[1],console.log(`🔑 Step 2: Session ID received: ${this.sid}`),await this.sleep(this.delay/8),console.log("🔐 Step 3: Authenticating...");const n=this.base64Encode("\0"+this.username+"\0"+this.password),r=`<body rid='${this.nextRid()}' sid='${this.sid}'\n               xmlns='http://jabber.org/protocol/httpbind'>\n          <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>${n}</auth>\n        </body>`;if(!(await this.sendRequestWithRetry(r)).includes("<success"))throw new Error("❌ Authentication failed");console.log("✅ Step 4: Authentication successful!"),await this.sleep(this.delay/8),console.log("🔄 Step 5: Restarting stream...");const o=`<body rid='${this.nextRid()}' sid='${this.sid}'\n               xmlns='http://jabber.org/protocol/httpbind'\n               to='jabber.klavogonki.ru'\n               xmpp:restart='true'\n               xmlns:xmpp='urn:xmpp:xbosh'/>`;await this.sendRequestWithRetry(o),await this.sleep(this.delay/8),console.log("📦 Step 6: Binding resource...");const a=`<body rid='${this.nextRid()}' sid='${this.sid}'\n               xmlns='http://jabber.org/protocol/httpbind'>\n          <iq type='set' id='bind_1' xmlns='jabber:client'>\n            <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>\n              <resource>web</resource>\n            </bind>\n          </iq>\n        </body>`;await this.sendRequestWithRetry(a),await this.sleep(this.delay/8),console.log("🔌 Step 7: Establishing session...");const i=`<body rid='${this.nextRid()}' sid='${this.sid}'\n               xmlns='http://jabber.org/protocol/httpbind'>\n          <iq type='set' id='session_1' xmlns='jabber:client'>\n            <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>\n          </iq>\n        </body>`;return await this.sendRequestWithRetry(i),await this.sleep(this.delay/8),{sid:this.sid,rid:this.rid}}}const M=["jpg","jpeg","png","gif","webp"],$="📷",T="🖥️",z="💀️️",A=.2,P=10,N=.1;let H=0,B=!1,R=[],q=null;const D=e=>{const t=(e=>{try{return e.match(/\.([^?#.]+)(?:[?#]|$)/i)?.[1]?.toLowerCase()||""}catch(e){return console.error("Error extracting extension:",e.message),""}})(e);return{allowed:M.includes(t),extension:t}},O=(e,t)=>{const n=document.createElement("img");n.src=e,n.classList.add("scaled-thumbnail"),document.body.appendChild(n),H=t;let r=1,o=!1,a=0,i=0,s=0,c=0;let l=document.querySelector(".dimming-element");if(l||(l=document.createElement("div"),l.classList.add("dimming-element"),document.body.appendChild(l)),Xe()){let e=0,t=0,o=0,a=0;const i=e=>{e.preventDefault()},l=i=>{i.preventDefault();const l=i.touches.length;if(2===l){const o=i.touches[0],a=i.touches[1],l=Math.hypot(o.clientX-a.clientX,o.clientY-a.clientY);if(2===e){r*=l/t,r=Math.max(A,Math.min(r,P)),n.style.transform=`translate(-50%, -50%) translate(${s}px, ${c}px) scale(${r})`}t=l}else if(1===l){const t=i.touches[0],l=t.clientX,d=t.clientY;if(1===e){s+=l-o,c+=d-a,n.style.transform=`translate(-50%, -50%) translate(${s}px, ${c}px) scale(${r})`}o=l,a=d}e=l},d=t=>{0===t.touches.length&&(e=0)};n.addEventListener("touchstart",i,{passive:!1}),n.addEventListener("touchmove",l,{passive:!1}),n.addEventListener("touchend",d)}const d=e=>{Ce(e,"hide","0"),!document.querySelector(".popup-panel")&&l&&Ce(l,"hide","0"),Ee()};return L.bigImageEvents.click=e=>{n.contains(e.target)||(n.remove(),Ee())},L.bigImageEvents.keydown=e=>{"Escape"===e.code||"Space"===e.code?(e.preventDefault(),d(n)):"ArrowLeft"===e.code?U(-1):"ArrowRight"===e.code&&U(1)},L.bigImageEvents.wheel=e=>{const t=e.deltaY<0?1:-1;r+=t*N*r,r=Math.max(A,Math.min(r,P)),n.style.transform=`translate(-50%, -50%) translate(${s}px, ${c}px) scale(${r})`},L.bigImageEvents.mousemove=e=>{if(o){if(e.ctrlKey){const t=e.clientY-i,n=t<0?1:-1,o=Math.abs(t)*N*.05;r+=n*o*r,r=Math.max(A,Math.min(r,P))}else{const t=(e.clientX-a)/r*5,n=(e.clientY-i)/r*5;s+=t,c+=n}n.style.transform=`translate(-50%, -50%) translate(${s}px, ${c}px) scale(${r})`,a=e.clientX,i=e.clientY}},L.bigImageEvents.mousedown=e=>{const{button:t,clientX:r,clientY:s,target:c,ctrlKey:l}=e;(0!==t&&2!==t||c===n)&&(0===t?U(-1):2===t?(e.preventDefault(),l?(navigator.clipboard.writeText(c.src).catch(console.error),d(n)):U(1)):1===t&&(o=!0,a=r,i=s,e.preventDefault()))},L.bigImageEvents.mouseup=e=>{1===e.button&&(o=!1)},L.bigImageEvents.contextmenu=e=>e.preventDefault(),Object.entries(L.bigImageEvents).forEach((([e,t])=>{document.addEventListener(e,t)})),Ce(l,"show","1"),l.addEventListener("click",(()=>{d(n)})),n},U=e=>{const t=H+e;t>=0&&t<R.length&&!B&&(B=!0,q&&(q.src=R[t].imgSrc),setTimeout((()=>B=!1),50),H=t)};function _(){const e=document.getElementById("messages-panel");if(!e)return;const t=e.querySelectorAll("a:not(.skipped):not(.processed-image)");function n(t,n){const r=document.createElement("div");r.classList.add("clickable-thumbnail"),r.dataset.sourceLink=t.href;const o=document.createElement("img");o.src=t.href,o.onload=()=>{r.appendChild(o),t.parentNode.insertBefore(r,t.nextSibling),$e()},o.onerror=()=>{console.error("Failed to load image:",t.href),t.classList.add("skipped")},n?t.querySelector(".clickable-thumbnail")||t.addEventListener("click",(e=>{t.querySelector(".clickable-thumbnail")||(r.appendChild(o),t.parentNode.insertBefore(r,t.nextSibling))})):(r.appendChild(o),t.parentNode.insertBefore(r,t.nextSibling)),r.addEventListener("click",(n=>{n.stopPropagation(),R=[],e.querySelectorAll(".clickable-thumbnail").forEach(((e,t)=>{const n=e.querySelector("img");n&&e.dataset.sourceLink&&R.push({link:e.dataset.sourceLink,imgSrc:n.src,index:t})}));const r=R.findIndex((e=>e.link===t.href||e.imgSrc===o.src));q=O(o.src,r>=0?r:0),Ce(q,"show","1");const a=document.querySelector(".dimming-element");a&&Ce(a,"show","1")}))}t.length&&t.forEach((e=>{if(!e.href||!e.href.startsWith("http"))return;const{allowed:t,extension:r}=D(e.href);if(!t)return;e.classList.add("media");const{isTrusted:o,domain:a}=Se(e.href);e.title=Le(e.href)?je(e.href):e.href,o?function(e,t,r){e.textContent=`${$} Image (${t.toUpperCase()}) ${T} Hostname (${r})`,e.classList.add("processed-image"),n(e,!1)}(e,r,a):function(e,t,r){e.classList.add("skipped"),e.textContent=`${$} Image (${t.toUpperCase()}) ${T} Hostname (${r}) ${z} Untrusted`,e.addEventListener("click",(t=>{e.classList.contains("processed-image")||(t.preventDefault(),e.classList.remove("skipped"),e.classList.add("processed-image"),n(e,!0))}))}(e,r,a)}))}const F="🎥",J="🖥️",K="💀️️",W=["mp4","webm","ogg","mov","avi"];function Y(e){const t=document.getElementById("messages-panel");if(!t)return;const n=t.querySelectorAll("a:not(.skipped):not(.processed-video)");function r(e,t,n,r){const{youtubeMatch:o,videoType:a,videoId:i}=r,s=(e=>{const t=e.match(/\.([^?#.]+)(?:[?#]|$)/i)?.[1]?.toLowerCase()||"";return{allowed:W.includes(t),extension:t}})(t);if(!o&&!s.allowed)return;e.classList.add("processed-video");const c=document.createElement("div");c.classList.add("video-wrapper");const l=document.createElement(o?"iframe":"video");l.classList.add("video-container"),e.textContent=`${F} ${a} ${J} Hostname (${n})`,o?(l.src=`https://www.youtube.com/embed/${i}`,l.allowFullscreen=!0):(l.src=t,l.controls=!0),e.title=Le(t)?je(t):t,e.style.display="inline-flex",e.parentNode.insertBefore(c,e),c.append(e,l),$e()}n.length&&n.forEach((e=>{const t=e.href;if(!t)return;const n=function(e){const t=e.match(/(?:shorts\/|live\/|watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/i);if(t){return{youtubeMatch:!0,videoId:t[1],videoType:e.includes("shorts/")?"Shorts":e.includes("live/")?"Live":e.includes("watch?v=")?"Watch":e.includes("youtu.be/")?"Share":"YouTube"}}const n=e.split(".").pop().toLowerCase();if(W.includes(n))return{youtubeMatch:!1,videoType:`Video (${n.toUpperCase()})`};return!1}(t);if(!n)return;e.classList.add("media");const{isTrusted:o,domain:a}=Se(t);if(!o)return e.classList.add("skipped"),e.textContent=`${F} ${n.videoType} ${J} Hostname (${a}) ${K} Untrusted`,void e.addEventListener("click",(o=>{e.classList.contains("processed-video")||(o.preventDefault(),e.classList.remove("skipped"),r(e,t,a,n))}));r(e,t,a,n)}))}const X="http://www.w3.org/2000/svg",V="#82B32A",Q="#B34A2A",G=`\n  <svg xmlns="${X}" \n      width="24" \n      height="24" \n      viewBox="0 0 250 250">\n    <path fill="#096AD9" d="M22.32 98.04l-19.04 -87.15c-0.75,-3.46 0.48,-6.84 3.29,-9 2.81,-2.17 6.39,-2.49 9.55,-0.87l225.95 116.02c3.07,1.57 4.87,4.52 4.87,7.96 0,3.44 -1.8,6.39 -4.87,7.96l-225.95 116.02c-3.16,1.62 -6.74,1.3 -9.55,-0.87 -2.81,-2.16 -4.04,-5.54 -3.29,-9l19.04 -87.15c0.79,-3.62 3.53,-6.26 7.18,-6.91l102.6 -18.19c0.91,-0.16 1.56,-0.94 1.56,-1.86 0,-0.92 -0.65,-1.7 -1.56,-1.86l-102.6 -18.19c-3.65,-0.65 -6.39,-3.29 -7.18,-6.91z"/>\n  </svg>\n`,Z=`\n  <svg xmlns="${X}" \n       width="15" \n       height="15" \n       viewBox="0 0 250 250" \n       style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd">\n      <path fill="${V}" d="M46.62 0l156.76 0c25.64,0 46.62,20.98 46.62,46.62l0 156.75c0,25.65 -20.98,46.63 -46.62,46.63l-156.76 0c-25.64,0 -46.62,-20.98 -46.62,-46.63l0 -156.75c0,-25.64 20.98,-46.62 46.62,-46.62zm45.71 70.24l32.67 32.67 32.67 -32.67c2.73,-2.73 7.18,-2.73 9.91,0l12.18 12.18c2.73,2.73 2.73,7.18 0,9.91l-32.67 32.67 32.67 32.66c2.73,2.74 2.73,7.19 0,9.92l-12.18 12.18c-2.73,2.73 -7.18,2.73 -9.91,0l-32.67 -32.67 -32.67 32.67c-2.73,2.73 -7.18,2.73 -9.91,0l-12.18 -12.18c-2.73,-2.73 -2.73,-7.18 0,-9.92l32.67 -32.66 -32.67 -32.67c-2.73,-2.73 -2.73,-7.18 0,-9.91l12.18 -12.18c2.73,-2.73 7.18,-2.73 9.91,0z"/>\n  </svg>\n`,ee=`\n  <svg xmlns="${X}" \n       width="15" \n       height="15" \n       viewBox="0 0 250 250" \n       style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd">\n      <path fill="${Q}" d="M46.62 0l156.76 0c25.64,0 46.62,20.98 46.62,46.62l0 156.75c0,25.65 -20.98,46.63 -46.62,46.63l-156.76 0c-25.64,0 -46.62,-20.98 -46.62,-46.63l0 -156.75c0,-25.64 20.98,-46.62 46.62,-46.62zm15.5 135.79l57.92 -57.93c2.73,-2.73 7.19,-2.72 9.92,0.01l57.92 57.92c2.73,2.73 2.73,7.18 0,9.91l-12.18 12.18c-2.73,2.73 -7.18,2.73 -9.92,0l-35.82 -35.83c-2.73,-2.73 -7.19,-2.73 -9.92,0l-35.82 35.83c-2.74,2.73 -7.19,2.73 -9.92,0l-12.18 -12.18c-2.73,-2.73 -2.73,-7.18 0,-9.91z"/>\n  </svg>\n`,te=`\n  <svg xmlns="${X}" \n       width="15" \n       height="15" \n       viewBox="0 0 250 250"\n       style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd">\n    <path fill="${V}" d="M46.62 0l156.76 0c25.64,0 46.62,20.98 46.62,46.62l0 156.75c0,25.65 -20.98,46.63 -46.62,46.63l-156.76 0c-25.64,0 -46.62,-20.98 -46.62,-46.63l0 -156.75c0,-25.64 20.98,-46.62 46.62,-46.62zm109.99 181.69l-75.07 0c-7.3,0 -13.23,-5.92 -13.23,-13.22l0 -75.08c0,-2.35 1.92,-4.28 4.28,-4.28l17.9 0c2.35,0 4.27,1.93 4.27,4.28l0 32.81c0,1.77 1.01,3.28 2.64,3.96 1.63,0.67 3.42,0.33 4.66,-0.93l59.68 -59.68c1.67,-1.65 4.38,-1.65 6.05,0l12.66 12.66c1.66,1.67 1.66,4.38 0,6.05l-59.68 59.68c-1.26,1.24 -1.6,3.03 -0.93,4.66 0.68,1.63 2.19,2.64 3.96,2.64l32.81 0c2.35,0 4.28,1.92 4.28,4.28l0 17.9c0,2.36 -1.93,4.28 -4.28,4.28z"/>\n  </svg>\n`,ne=`\n  <svg xmlns="${X}" \n       width="15" \n       height="15" \n       viewBox="0 0 250 250"\n       style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd">\n    <path fill="${Q}" d="M46.62 0l156.76 0c25.64,0 46.62,20.98 46.62,46.62l0 156.75c0,25.65 -20.98,46.63 -46.62,46.63l-156.76 0c-25.64,0 -46.62,-20.98 -46.62,-46.63l0 -156.75c0,-25.64 20.98,-46.62 46.62,-46.62zm46.77 68.31l75.07 0c7.3,0 13.23,5.92 13.23,13.22l0 75.08c0,2.35 -1.92,4.28 -4.28,4.28l-17.9 0c-2.35,0 -4.27,-1.93 -4.27,-4.28l0 -32.81c0,-1.77 -1.01,-3.28 -2.64,-3.96 -1.63,-0.67 -3.42,-0.33 -4.66,0.93l-59.68 59.68c-1.67,1.65 -4.38,1.65 -6.05,0l-12.66 -12.66c-1.66,-1.67 -1.66,-4.38 0,-6.05l59.68 -59.68c1.26,-1.24 1.6,-3.03 0.93,-4.66 -0.68,-1.63 -2.19,-2.64 -3.96,-2.64l-32.81 0c-2.35,0 -4.28,-1.92 -4.28,-4.27l0 -17.9c0,-2.36 1.93,-4.28 4.28,-4.28z"/>\n  </svg>\n`,re=`\n  <svg xmlns="${X}" \n       width="15" \n       height="15" \n       viewBox="0 0 250 250"\n       style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd">\n    <path fill="${V}" d="M46.59 0l156.82 0c25.65,0 46.59,20.94 46.59,46.59l0 156.82c0,25.65 -20.94,46.59 -46.59,46.59l-156.82 0c-25.65,0 -46.59,-20.94 -46.59,-46.59l0 -156.82c0,-25.65 20.94,-46.59 46.59,-46.59zm130.96 87.85c0,6.57 -1.03,12.72 -3.08,18.06 -2.05,5.34 -4.93,9.85 -8.42,13.75 -3.69,3.9 -8,7.39 -13.13,10.47 -4.11,2.46 -8.83,4.93 -13.96,6.98 -1.64,0.82 -2.87,2.46 -2.87,4.51l0 15.19c0,2.67 -2.06,4.72 -4.73,4.72l-25.04 0c-2.66,0 -4.92,-2.05 -4.92,-4.72l0 -25.65c0,-2.26 1.44,-3.9 3.49,-4.52 2.87,-1.02 5.95,-2.05 9.23,-3.28 4.52,-1.85 8.62,-3.9 12.11,-6.57 3.9,-2.67 6.78,-5.75 9.24,-9.24 2.46,-3.49 3.49,-7.59 3.49,-12.31 0,-6.78 -2.05,-11.7 -6.36,-14.78 -4.31,-2.88 -10.06,-4.52 -17.65,-4.52 -5.75,0 -11.7,1.24 -18.07,3.7 -5.33,2.05 -9.85,4.31 -13.13,6.36 -1.03,0.62 -2.26,0.62 -3.29,0 -1.02,-0.62 -1.64,-1.64 -1.64,-2.87l0 -23.2c0,-2.05 1.23,-3.9 3.08,-4.51 4.1,-1.44 9.44,-3.08 15.8,-4.52 8.42,-2.05 17.24,-3.07 26.89,-3.07 8.42,0 16.01,1.02 22.58,3.07 6.36,2.06 12.11,4.72 16.62,8.42 4.52,3.49 7.8,7.8 10.27,12.72 2.26,4.73 3.49,10.06 3.49,15.81l0 0zm-46.19 114.12l-25.04 0c-2.67,0 -4.92,-2.05 -4.92,-4.72l0 -17.24c0,-2.67 2.25,-4.72 4.92,-4.72l25.04 0c2.67,0 4.72,2.05 4.72,4.72l0 17.24c0,2.67 -2.05,4.72 -4.72,4.72z"/>\n  </svg>\n`;function oe(e){e.classList.add("shake-effect"),setTimeout((()=>{e.classList.remove("shake-effect")}),500)}const ae={smileys:["😀","😃","😄","😆","😁","😅","😂","🤣","🥲","☺️","😊","😇","🙂","🙃","😉","😌","😍","🥰","😙","😚","😗","😘","😋","🥸","😵‍💫","😛","😝","😜","🤪","😎","🤓","🧐","🤨","🤩","🥳","😏","😒","😞","😔","😟","😕","🙁","☹️","😣","😖","😫","😩","🥺","😢","😭","😤","😠","😡","🤬","🤯","😳","🥵","🥶","😱","😨","😰","😥","😓","🤗","🤔","🤭","🤫","🤥","😶","😐","😑","😬","🙄","😯","😦","😧","😮","😲","🥱","😴","🤤","😪","😵","🤐","🥴","🤢","🤮","🤧","😷","🤒","🤕","🤑","🤠","😈","👿","👹","👺","🤡","💩","👻","💀","☠️","👽","👾","🤖","🎃","😺","😸","😹","😻","😼","😽","🙀","😿","😾","👋","🤚","🖐️","✋","🖖","👌","🤌","🤏","✌️","🤞","🤟","🤘","🤙","👈","👉","👆","🖕","👇","☝️","👍","👎","✊","👊","🤛","🤜","👏","🙌","👐","🤲","🤝","🙏","✍️","💅","🤳","💪","🦾","🦿","🦵","🦶","👂","🦻","👃","🧠","🫀","🫁","🦷","🦴","👀","👁️","👅","👄","👶","🧒","👦","👧","🧑","👱","👨","🧔","👩","🧓","👴","👵","🙍","🙎","🙅","🙆","💁","🙋","🧏","🙇","🤦","🤷","👮","🕵️","💂","🥷","👷","🤴","👸","👳","👲","🧕","🤵","👰","🤰","🤱","👼","🎅","🤶","🦸","🦹","🧙","🧚","🧛","🧜"],nature:["🐵","🐒","🦍","🦧","🐶","🐕","🦮","🐕‍🦺","🐩","🐺","🦊","🦝","🐱","🐈","🐈‍⬛","🦁","🐯","🐅","🐆","🐴","🐎","🦄","🦓","🦌","🦬","🐮","🐂","🐃","🐄","🐷","🐖","🐗","🐽","🐏","🐑","🐐","🐪","🐫","🦙","🦒","🐘","🦏","🦛","🐭","🐁","🐀","🐹","🐰","🐇","🦫","🦘","🦡","🐿️","🦔","🦦","🦥","🐼","🦨","🦘","🦡","🦃","🐔","🐓","🐣","🐤","🐥","🐦","🐧","🕊️","🦅","🦆","🦢","🦉","🦤","🪶","🦩","🦚","🦜","🐸","🐊","🐢","🦎","🐍","🐲","🐉","🦕","🦖","🐳","🐋","🐬","🦭","🐟","🐠","🐡","🦈","🐙","🐚","🪸","🐌","🦋","🐛","🐜","🐝","🪲","🐞","🦗","🪳","🕷️","🕸️","🦂","🦟","🪰","🪱","🌸","💮","🏵️","🌹","🥀","🌺","🌻","🌼","🌷","🌱","🪴","🌲","🌳","🌴","🌵","🌾","🌿","☘️","🍀","🍁","🍂","🍃"],food:["🍎","🍐","🍊","🍋","🍌","🍉","🍇","🍓","🫐","🍈","🍒","🍑","🥭","🍍","🥥","🥝","🍅","🍆","🥑","🥦","🥬","🥒","🌶️","🫑","🥕","🧄","🧅","🥔","🍠","🥐","🥯","🍞","🥖","🥨","🧀","🥚","🍳","🥓","🥩","🍗","🍖","🦴","🌭","🍔","🍟","🍕","🫓","🥪","🥙","🧆","🌮","🌯","🫔","🥗","🥘","🫕","🥫","🍝","🍜","🍲","🍛","🍣","🍱","🥟","🦪","🍤","🍙","🍚","🍘","🍥","🥠","🥮","🍢","🍡","🍧","🍨","🍦","🥧","🧁","🍰","🎂","🍮","🍭","🍬","🍫","🍿","🍩","🍪","🫖","☕","🍵","🧃","🥤","🧋","🍶","🍺","🍻","🥂","🍷","🥃","🍸","🍹","🧉","🍾"],activities:["⚽","🏀","🏈","⚾","🥎","🎾","🏐","🏉","🥏","🎱","🪀","🏓","🏸","🏒","🏑","🥍","🏏","⛳","🪁","🎣","🤿","🎽","🛹","🛼","🛷","⛸️","🥌","⛷️","🏂","🪂","🏋️","🤼","🤸","⛹️","🤾","🏌️","🏇","🧘","🏄","🏊","🤽","🚣","🧗","🚴","🚵","🎪","🎭","🎨","🎬","🎤","🎧","🎼","🎹","🥁","🎷","🎺","🎸","🎻","🎲","🎯","🎳","🎮","🎰","🧩","🎪","🎫","🎟️"],travel:["🚗","🚕","🚙","🚌","🚎","🏎️","🚓","🚑","🚒","🚐","🛻","🚚","🚛","🚜","🛵","🏍️","🛺","🚲","🛴","✈️","🛩️","🛫","🛬","🚁","🚀","🛸","🛶","⛵","🚤","🛥️","🛳️","⛴️","🚢","🏰","🏯","🏟️","🏖️","🏝️","🏜️","🌋","⛰️","🏔️","🗻","🏕️","🏭","🏢","🏬","🏣","🏤","🏥","🏦","🏨","🏪","🏫","🏩","💒","⛪","🕌","🕍","🛕","⛩️","🏛️"],objects:["📱","💻","⌨️","🖥️","🖨️","🖱️","🖲️","🕹️","🗜️","💽","💾","💿","📀","📼","📷","📸","📹","🎥","📞","☎️","📟","📠","📺","📻","🎙️","🎚️","🎛️","📡","🔋","🔌","💡","🔦","🕯️","🧯","🛢️","💸","💵","💴","💶","💷","🪙","💰","💳","💎","⚖️","🪜","🧰","🔧","🔨","⚒️","🛠️","⛏️","✏️","🖊️","🖋️","✒️","🖌️","🖍️","📝","📚","📖","🔖","📑","🗒️","📄","📰","🗞️","📁","📂","🗂️","🕐","🕑","🕒","🕓","🕔","🕕","🕖","🕗","🕘","🕙","🕚","🕛","🕰️","⏰","⏱️","⏲️","⌚"],symbols:["❤️","🧡","💛","💚","💙","💜","🤎","🖤","🤍","💔","❣️","💕","💞","💓","💗","💖","💘","💝","💟","☮️","✝️","☪️","🕉️","☸️","✡️","🔯","🕎","☯️","☦️","🛐","⛎","⚠️","🚸","⛔","🚫","☢️","☣️","➕","➖","➗","✖️","♾️","💲","💱","⬆️","↗️","➡️","↘️","⬇️","↙️","⬅️","↖️","↕️","↔️","↩️","↪️","⤴️","⤵️","🔃","🔄","🔆","📶","🎦","🔅","♻️","✅","❌","❎","➰","➿","〽️","✳️","✴️","❇️","©️","®️","™️"],flags:["🏁","🚩","🎌","🏴","🏳️","🏳️‍🌈","🏳️‍⚧️","🏴‍☠️","🇺🇸","🇬🇧","🇯🇵","🇰🇷","🇩🇪","🇨🇳","🇧🇷","🇮🇳","🇫🇷","🇪🇸","🇮🇹","🇷🇺","🇨🇦","🇦🇺","🇳🇿","🇲🇽","🇦🇷","🇵🇰","🇪🇬","🇸🇪","🇳🇴","🇳🇱","🇨🇭","🇹🇷","🇮🇩","🇸🇬","🇮🇱","🇵🇹","🇵🇱","🇹🇭"]},ie={"😀":{en:["grinning","face","smile","happy","joy"],ru:["улыбающийся","лицо","улыбка","счастливый","радость"]},"😃":{en:["smiley","face","happy","joy","laugh"],ru:["улыбчивый","лицо","счастливый","радость","смех"]},"😄":{en:["laughing","face","happy","joy","grin"],ru:["смеющийся","лицо","счастливый","радость","ухмылка"]},"😆":{en:["grinning face","laugh"],ru:["улыбка","смех"]},"😁":{en:["beaming","face","grin","smile","happy"],ru:["сияющий","лицо","улыбка","счастье","радость"]},"😅":{en:["sweat","nervous","face","laugh","relief"],ru:["пот","нервный","лицо","смех","облегчение"]},"😂":{en:["tears","joy","face","laugh","happy"],ru:["слёзы","радость","лицо","смех","счастье"]},"🤣":{en:["rolling","floor","laugh","funny","amused"],ru:["катающийся","пол","смех","смешной","развлечённый"]},"🥲":{en:["smiling","tear","bittersweet","nostalgic","happy"],ru:["улыбающийся","слеза","горько-сладкий","ностальгический","счастливый"]},"☺️":{en:["smile","blush","content","peaceful"],ru:["улыбка","румянец","довольный","спокойный"]},"😊":{en:["smiling","happy","blushing","content"],ru:["улыбающийся","счастливый","румянец","довольный"]},"😇":{en:["angel","halo","innocent","saint","pure"],ru:["ангел","ореол","невинный","святой","чистый"]},"🙂":{en:["slight","smile","face","mild"],ru:["слегка","улыбка","лицо","умеренный"]},"🙃":{en:["upside-down","silly","quirky","funny"],ru:["перевернутый","глупый","странный","смешной"]},"😉":{en:["wink","flirt","playful","smile"],ru:["подмигивание","флирт","игривый","улыбка"]},"😌":{en:["relieved","calm","content","satisfied"],ru:["облегчённый","спокойный","довольный","удовлетворённый"]},"😍":{en:["heart","love","smiling","eyes","adore"],ru:["сердце","любовь","улыбающийся","глаза","обожать"]},"🥰":{en:["love","hearts","affection","adoration","cuddle"],ru:["любовь","сердца","нежность","обожание","обниматься"]},"😙":{en:["kiss","love","affection","flirt"],ru:["поцелуй","любовь","нежность","флирт"]},"😗":{en:["kiss","face","smile","affection"],ru:["поцелуй","лицо","улыбка","нежность"]},"😚":{en:["kiss","closed eyes","affection","love"],ru:["поцелуй","закрытые глаза","нежность","любовь"]},"😘":{en:["kiss","love","affection","flirt"],ru:["поцелуй","любовь","нежность","флирт"]},"😋":{en:["yum","delicious","tasty","savor","lick"],ru:["ням","вкусно","аппетитно","наслаждаться","лизать"]},"🥸":{en:["disguise","glasses","funny","sneaky","face"],ru:["маскировка","очки","смешной","хитрый","лицо"]},"😵‍💫":{en:["dizzy","spiral eyes","confused","hypnotized","disoriented"],ru:["головокружение","спиральные глаза","запутанный","загипнотизированный","дезориентированный"]},"😛":{en:["tongue","playful","cheeky","silly"],ru:["язык","игривый","нахальный","глупый"]},"😝":{en:["tongue","silly","wacky","fun"],ru:["язык","глупый","безумный","весёлый"]},"😜":{en:["tongue","wink","playful","fun"],ru:["язык","подмигивание","игривый","весёлый"]},"🤪":{en:["crazy","wacky","zany","quirky"],ru:["сумасшедший","безумный","чудаковатый","странный"]},"😎":{en:["cool","sunglasses","confident","chill"],ru:["крутой","очки","уверенный","расслабленный"]},"🤓":{en:["nerd","geek","glasses","studious"],ru:["ботан","задрот","очки","учёный"]},"🧐":{en:["monocle","investigative","curious","thoughtful"],ru:["одноглазый","расследовательский","любопытный","задумчивый"]},"🤨":{en:["skeptical","doubtful","uncertain","raised eyebrow"],ru:["скептический","сомневающийся","неуверенный","поднятая бровь"]},"🤩":{en:["starstruck","amazed","excited","admire"],ru:["восхищённый","поражённый","взволнованный","обожать"]},"🥳":{en:["party","celebrate","birthday","festive"],ru:["вечеринка","праздновать","день рождения","праздничный"]},"😏":{en:["smirk","sly","mischievous","confident"],ru:["ухмылка","хитрый","озорной","уверенный"]},"😒":{en:["unamused","displeased","bored","sigh"],ru:["неудовлетворённый","недовольный","скучный","вздох"]},"😞":{en:["disappointed","sad","down","somber"],ru:["разочарованный","грустный","унылый","мрачный"]},"😔":{en:["pensive","sad","reflective","mournful"],ru:["задумчивый","грустный","рефлексивный","скорбный"]},"😟":{en:["worried","concerned","anxious","upset"],ru:["обеспокоенный","тревожный","беспокойный","расстроенный"]},"😕":{en:["confused","perplexed","uncertain","baffled"],ru:["смущённый","озадаченный","неуверенный","в замешательстве"]},"🙁":{en:["frowning","sad","disappointed","downcast"],ru:["хмурый","грустный","разочарованный","угнетённый"]},"☹️":{en:["frowning","sad","unhappy","mournful"],ru:["хмурый","грустный","несчастный","скорбный"]},"😣":{en:["strained","persevering","tired","discomfort"],ru:["напряжённый","терпеливый","уставший","дискомфорт"]},"😖":{en:["confounded","annoyed","distressed","exasperated"],ru:["озадаченный","раздражённый","огорчённый","изнурённый"]},"😫":{en:["tired","exhausted","weary","worn out"],ru:["усталый","измученный","изнурённый","измотанный"]},"😩":{en:["weary","tired","exhausted","overwhelmed"],ru:["изнурённый","уставший","измученный","перегруженный"]},"🥺":{en:["pleading","begging","cute","vulnerable"],ru:["умоляющий","просьба","милый","уязвимый"]},"😢":{en:["cry","sad","tear","sorrow"],ru:["плакать","грустный","слеза","печаль"]},"😭":{en:["crying","tearful","sad","heartbroken"],ru:["плачущий","со слезами","грустный","с разбитым сердцем"]},"😤":{en:["triumphant","exasperated","proud","angry"],ru:["триумфальный","раздражённый","гордый","сердитый"]},"😠":{en:["angry","mad","annoyed","irate"],ru:["сердитый","злой","раздражённый","яростный"]},"😡":{en:["pouting","mad","furious","irate"],ru:["надувшийся","злой","яростный","взбешённый"]},"🤬":{en:["cursing","swearing","angry","foul language"],ru:["ругательства","мат","сердитый","неприличный"]},"🤯":{en:["mind blown","shocked","amazed","stunned"],ru:["взрыв мозга","шокированный","поражённый","ошеломлённый"]},"😳":{en:["flushed","embarrassed","shocked","awkward"],ru:["покрасневший","смущённый","шокированный","неловкий"]},"🥵":{en:["hot","overheated","sweaty","exhausted"],ru:["горячий","перегретый","потный","изнурённый"]},"🥶":{en:["cold","freezing","chilly","frozen"],ru:["холодный","замерзающий","прохладный","замороженный"]},"😱":{en:["screaming","horror","shock","fear"],ru:["кричащий","ужас","шок","страх"]},"😨":{en:["fearful","scared","anxious","nervous"],ru:["боязливый","испуганный","тревожный","нервный"]},"😰":{en:["anxious","nervous","sweating","scared"],ru:["тревожный","нервный","потеющий","испуганный"]},"😥":{en:["disappointed","sad","pensive","teary"],ru:["разочарованный","грустный","задумчивый","со слезами"]},"😓":{en:["cold sweat","nervous","anxious","tired"],ru:["холодный пот","нервный","тревожный","усталый"]},"🤗":{en:["hug","embrace","caring","love"],ru:["объятие","принимать","заботливый","любовь"]},"🤔":{en:["thinking","pondering","curious","confused"],ru:["думающий","размышляющий","любопытный","смущённый"]},"🤭":{en:["guilty","shy","embarrassed","oops"],ru:["виноватый","застенчивый","смущённый","упс"]},"🤫":{en:["quiet","secret","hush","shh"],ru:["тихий","секрет","тишина","ш-ш"]},"🤥":{en:["lying","fib","deceitful","dishonest"],ru:["врущий","ложь","обманчивый","нечестный"]},"😶":{en:["speechless","mute","quiet","blank"],ru:["безмолвный","немой","тихий","пустой"]},"😐":{en:["neutral","expressionless","indifferent","flat"],ru:["нейтральный","без выражения","безразличный","плоский"]},"😑":{en:["deadpan","expressionless","blank","unemotional"],ru:["без эмоций","без выражения","пустой","неэмоциональный"]},"😬":{en:["grimace","awkward","nervous","tense"],ru:["гримаса","неловко","нервный","напряжённый"]},"🙄":{en:["eye roll","sarcastic","disdain","bored"],ru:["закатывание глаз","саркастичный","пренебрежительный","скучный"]},"😯":{en:["hushed","surprised","shocked","amazed"],ru:["тихий","удивлённый","шокированный","поражённый"]},"😦":{en:["frowning","dismayed","shocked","surprised"],ru:["хмурый","огорчённый","шокированный","удивлённый"]},"😧":{en:["astonished","stunned","surprised","speechless"],ru:["изумлённый","ошеломлённый","удивлённый","безмолвный"]},"😮":{en:["open mouth","surprised","shocked","amazed"],ru:["открытый рот","удивлённый","шокированный","поражённый"]},"😲":{en:["astonished","stunned","shocked","in awe"],ru:["изумлённый","ошеломлённый","шокированный","в благоговении"]},"🥱":{en:["yawning","sleepy","tired","bored"],ru:["зевота","сонный","усталый","скучный"]},"😴":{en:["sleeping","tired","napping","dozing"],ru:["спящий","усталый","дремлющий","засыпающий"]},"🤤":{en:["drooling","desire","craving","hungry"],ru:["слюнявый","желание","тяга","голодный"]},"😪":{en:["sleepy","drowsy","tired","nodding"],ru:["сонный","вялый","усталый","кивающий"]},"😵":{en:["dizzy","knocked out","stunned","confused"],ru:["головокружительный","вырубленный","ошеломлённый","сбитый с толку"]},"🤐":{en:["zipper-mouth","secretive","quiet","mute"],ru:["закрытый рот","секретный","тихий","немой"]},"🥴":{en:["woozy","tipsy","dizzy","unsteady"],ru:["ошеломлённый","подошедший","головокружительный","неустойчивый"]},"🤢":{en:["nauseated","sick","disgusted","vomit"],ru:["тошнотворный","больной","отвратительный","рвота"]},"🤮":{en:["vomiting","nauseous","sick","disgust"],ru:["рвота","тошнотворный","больной","отвратительный"]},"🤧":{en:["sneezing","ill","sick","allergy"],ru:["чихание","болен","больной","аллергия"]},"😷":{en:["mask","sick","ill","health"],ru:["маска","больной","нездоровый","здоровье"]},"🤒":{en:["fever","sick","ill","unwell"],ru:["лихорадка","больной","нездоровый","неважно"]},"🤕":{en:["injured","hurt","bandaged","pain"],ru:["раненый","повреждённый","забинтованный","боль"]},"🤑":{en:["money","rich","greedy","cash"],ru:["деньги","богатый","жадный","наличные"]},"🤠":{en:["cowboy","hat","western","fun"],ru:["ковбой","шляпа","вестерн","веселье"]},"😈":{en:["devil","mischievous","naughty","sinister"],ru:["дьявол","озорной","непослушный","зловещий"]},"👿":{en:["angry","devil","evil","fiendish"],ru:["сердитый","дьявол","злой","зловещий"]},"👹":{en:["ogre","demon","monster","scary"],ru:["огр","демон","монстр","страшный"]},"👺":{en:["goblin","troll","spooky","creepy"],ru:["гоблин","тролль","жуткий","страшный"]},"🤡":{en:["clown","silly","funny","circus"],ru:["клоун","глупый","смешной","цирк"]},"💩":{en:["poop","crap","feces","funny"],ru:["какашка","дерьмо","фекалии","смешной"]},"👻":{en:["ghost","spirit","haunted","scary"],ru:["призрак","дух","обитающий","страшный"]},"💀":{en:["skull","death","creepy","spooky"],ru:["череп","смерть","жуткий","страшный"]},"☠️":{en:["skull","danger","death","poison"],ru:["череп","опасность","смерть","яд"]},"👽":{en:["alien","extraterrestrial","space","ufo"],ru:["инопланетянин","внеземной","космос","НЛО"]},"👾":{en:["alien","monster","video game","retro"],ru:["инопланетянин","монстр","видеоигра","ретро"]},"🤖":{en:["robot","machine","tech","android"],ru:["робот","машина","технология","андроид"]},"🎃":{en:["pumpkin","halloween","spooky","festive"],ru:["тыква","Хэллоуин","жуткий","праздничный"]},"😺":{en:["smiling","cat","happy","playful"],ru:["улыбающийся","кот","счастливый","игривый"]},"😸":{en:["grinning","cat","joyful","cheerful"],ru:["широко улыбающийся","кот","радостный","весёлый"]},"😹":{en:["tearful","joy","cat","laughing"],ru:["со слезами","радость","кот","смеющийся"]},"😻":{en:["heart","cat","love","adorable"],ru:["сердце","кот","любовь","милый"]},"😼":{en:["smirking","cat","mischievous","sly"],ru:["ухмыляющийся","кот","озорной","хитрый"]},"😽":{en:["kissing","cat","affection","cute"],ru:["целующий","кот","нежность","милый"]},"🙀":{en:["surprised","cat","scared","shocked"],ru:["испуганный","кот","испуганный","шокированный"]},"😿":{en:["crying","cat","sad","tearful"],ru:["плачущий","кот","грустный","со слезами"]},"😾":{en:["angry","cat","annoyed","displeased"],ru:["сердитый","кот","раздражённый","недовольный"]},"👋":{en:["wave","hello","goodbye","greeting"],ru:["махание","привет","прощание","приветствие"]},"🤚":{en:["raised hand","stop","palm"],ru:["поднятая рука","стой","ладонь"]},"🖐️":{en:["hand","high five","greeting"],ru:["рука","дай пять","приветствие"]},"✋":{en:["stop","palm","high five"],ru:["стой","ладонь","дай пять"]},"🖖":{en:["vulcan salute","live long","sci-fi"],ru:["салют Вулканцев","живи долго","научная фантастика"]},"👌":{en:["okay","perfect","good"],ru:["ок","идеально","хорошо"]},"🤌":{en:["pinched","precise","delicious"],ru:["сжатый","точный","вкусный"]},"🤏":{en:["small","tiny","minuscule"],ru:["маленький","крошечный","микроскопический"]},"✌️":{en:["peace","victory","v sign"],ru:["мир","победа","знак победы"]},"🤞":{en:["fingers crossed","hope","luck"],ru:["скрещенные пальцы","надежда","удача"]},"🤟":{en:["I love you","rock on","sign language"],ru:["я тебя люблю","рок он","язык жестов"]},"🤘":{en:["rock","metal","horns"],ru:["рок","металл","рога"]},"🤙":{en:["call me","hang loose","shaka"],ru:["позвони мне","расслабься","шак"]},"👈":{en:["point left","direction","arrow"],ru:["указание влево","направление","стрелка"]},"👉":{en:["point right","direction","arrow"],ru:["указание вправо","направление","стрелка"]},"👆":{en:["point up","direction","up"],ru:["указание вверх","направление","вверх"]},"🖕":{en:["middle finger","offensive","rude"],ru:["средний палец","оскорбительный","грубый"]},"👇":{en:["point down","direction","down"],ru:["указание вниз","направление","вниз"]},"☝️":{en:["point up","number one","important"],ru:["указание вверх","номер один","важный"]},"👍":{en:["thumbs up","good","approve"],ru:["палец вверх","хорошо","одобрить"]},"👎":{en:["thumbs down","bad","disapprove"],ru:["палец вниз","плохо","не одобрять"]},"✊":{en:["fist","power","solidarity"],ru:["кулак","сила","солидарность"]},"👊":{en:["punch","fist bump","hit"],ru:["удар","кулачок","ударить"]},"🤛":{en:["left fist","punch","strike"],ru:["левая рука","удар","нанести удар"]},"🤜":{en:["right fist","punch","strike"],ru:["правая рука","удар","нанести удар"]},"👏":{en:["clap","applause","bravo"],ru:["хлопки","аплодисменты","браво"]},"🙌":{en:["celebrate","praise","hooray"],ru:["торжествовать","хвалить","ура"]},"👐":{en:["open hands","embrace","welcome"],ru:["раскрытые руки","объятие","добро пожаловать"]},"🤲":{en:["palms","offering","receive"],ru:["ладони","предложение","получать"]},"🤝":{en:["handshake","agreement","cooperation"],ru:["рукопожатие","соглашение","сотрудничество"]},"🙏":{en:["pray","thanks","please"],ru:["молиться","спасибо","пожалуйста"]},"✍️":{en:["writing","pen","signature"],ru:["письмо","ручка","подпись"]},"💅":{en:["nail polish","beauty","manicure"],ru:["лак для ногтей","красота","маникюр"]},"🤳":{en:["selfie","photo","camera"],ru:["селфи","фото","камера"]},"💪":{en:["flex","strong","muscle"],ru:["сгибать","сильный","мышцы"]},"🦾":{en:["mechanical arm","robotic","cyborg"],ru:["механическая рука","роботизированный","киборг"]},"🦿":{en:["mechanical leg","prosthetic","robotic"],ru:["механическая нога","протез","роботизированный"]},"🦵":{en:["leg","limb","lower body"],ru:["нога","конечность","нижняя часть тела"]},"🦶":{en:["foot","toes","step"],ru:["нога","пальцы ноги","шаг"]},"👂":{en:["ear","listening","sound"],ru:["ухо","слушание","звук"]},"🦻":{en:["hearing aid","listening","assistive"],ru:["слуховой аппарат","слушание","помощь"]},"👃":{en:["nose","smell","scent"],ru:["нос","запах","аромат"]},"🧠":{en:["brain","intelligence","mind"],ru:["мозг","интеллект","ум"]},"🫀":{en:["heart (organ)","anatomy","biology"],ru:["сердце (орган)","анатомия","биология"]},"🫁":{en:["lungs","breath","organ"],ru:["легкие","дыхание","орган"]},"🦷":{en:["tooth","dental","smile"],ru:["зуб","стоматология","улыбка"]},"🦴":{en:["bone","skeleton","hard"],ru:["кость","скелет","твердый"]},"👀":{en:["eyes","look","see"],ru:["глаза","смотреть","видеть"]},"👁️":{en:["eye","vision","watch"],ru:["глаз","зрение","наблюдать"]},"👅":{en:["tongue","taste","lick"],ru:["язык","вкус","лизать"]},"👄":{en:["lips","kiss","mouth"],ru:["губы","поцелуй","рот"]},"👶":{en:["baby","infant","cute"],ru:["младенец","ребенок","милый"]},"🧒":{en:["child","kid","youth"],ru:["ребенок","малыш","юный"]},"👦":{en:["boy","child","kid"],ru:["мальчик","ребенок","малыш"]},"👧":{en:["girl","child","kid"],ru:["девочка","ребенок","малышка"]},"🧑":{en:["person","human","individual"],ru:["человек","личность","индивид"]},"👱":{en:["blonde","person","light hair"],ru:["блондин","человек","светлые волосы"]},"👨":{en:["man","male","guy"],ru:["мужчина","мужской","парень"]},"🧔":{en:["bearded","man","facial hair"],ru:["бородатый","мужчина","борода"]},"👩":{en:["woman","female","lady"],ru:["женщина","женский","дама"]},"🧓":{en:["elderly","senior","aged"],ru:["пожилой","старший","в преклонном возрасте"]},"👴":{en:["old man","elderly","senior"],ru:["старик","пожилой","старший"]},"👵":{en:["old woman","elderly","senior"],ru:["старуха","пожилая","старшая"]},"🙍":{en:["frowning","sad","displeased"],ru:["хмурый","грустный","недовольный"]},"🙎":{en:["pouting","angry","displeased"],ru:["надувшийся","сердитый","недовольный"]},"🙅":{en:["no","prohibited","refusal"],ru:["нет","запрещено","отказ"]},"🙆":{en:["ok","acceptable","okay"],ru:["ок","приемлемо","хорошо"]},"💁":{en:["information","help","assistance"],ru:["информация","помощь","поддержка"]},"🙋":{en:["raising hand","question","volunteer"],ru:["поднимающая руку","вопрос","доброволец"]},"🧏":{en:["deaf","listening","silent"],ru:["глухой","слушающий","безмолвный"]},"🙇":{en:["bowing","apologetic","respect"],ru:["наклон","извиняющийся","уважение"]},"🤦":{en:["facepalm","disbelief","oops"],ru:["лицо ладонь","недоверие","упс"]},"🤷":{en:["shrug","uncertain","indifferent"],ru:["пожимание плечами","неуверенный","безразличный"]},"👮":{en:["police","officer","law"],ru:["полицейский","офицер","закон"]},"🕵️":{en:["detective","spy","investigate"],ru:["детектив","шпион","расследование"]},"💂":{en:["guard","soldier","military"],ru:["страж","солдат","военный"]},"🥷":{en:["ninja","stealth","assassin"],ru:["ниндзя","скрытность","ассассин"]},"👷":{en:["construction","worker","helmet"],ru:["строитель","рабочий","шлем"]},"🤴":{en:["prince","royalty","king"],ru:["принц","королевская семья","король"]},"👸":{en:["princess","royalty","queen"],ru:["принцесса","королевская семья","королева"]},"👳":{en:["turban","cultural","tradition"],ru:["тюрбан","культура","традиция"]},"👲":{en:["man with cap","cultural","traditional"],ru:["мужчина в кепке","культура","традиционный"]},"🧕":{en:["woman with headscarf","cultural","modest"],ru:["женщина в платке","культурная","скромная"]},"🤵":{en:["tuxedo","groom","formal"],ru:["смокинг","жених","официальный"]},"👰":{en:["bride","wedding","formal"],ru:["невеста","свадьба","официальный"]},"🤰":{en:["pregnant","expecting","mother"],ru:["беременная","ожидающая","мать"]},"🤱":{en:["nursing","mother","baby"],ru:["кормящая","мать","ребенок"]},"👼":{en:["angel","cherub","divine"],ru:["ангел","херувим","божественный"]},"🎅":{en:["santa","christmas","jolly"],ru:["Санта","Рождество","радостный"]},"🤶":{en:["mrs claus","christmas","holiday"],ru:["миссис Клаус","Рождество","праздник"]},"🦸":{en:["superhero","power","hero"],ru:["супергерой","сила","герой"]},"🦹":{en:["villain","bad","criminal"],ru:["злодей","плохой","преступник"]},"🧙":{en:["wizard","magic","sorcery"],ru:["волшебник","магия","колдовство"]},"🧚":{en:["fairy","magic","mystical"],ru:["фея","магия","мистический"]},"🧛":{en:["vampire","dracula","undead"],ru:["вампир","Дракула","нежить"]},"🧜":{en:["mermaid","mythical","ocean"],ru:["русалка","мифическая","океан"]},"🐵":{en:["monkey","ape","funny","mammal"],ru:["обезьяна","примат","смешной","млекопитающее"]},"🐒":{en:["monkey","primate","curious"],ru:["обезьяна","примат","любопытный"]},"🦍":{en:["gorilla","ape","strong","wild"],ru:["горилла","обезьяна","сильный","дикий"]},"🦧":{en:["orangutan","ape","wild","mammal"],ru:["орангутан","обезьяна","дикий","млекопитающее"]},"🐶":{en:["dog","puppy","pet","mammal"],ru:["собака","щенок","домашний питомец","млекопитающее"]},"🐕":{en:["dog","canine","pet"],ru:["собака","псовой","домашний питомец"]},"🦮":{en:["guide dog","service","assistance"],ru:["собака-поводырь","служебная","помощь"]},"🐕‍🦺":{en:["service dog","working","assistance"],ru:["служебная собака","рабочая","помощь"]},"🐩":{en:["poodle","dog","pet","fancy"],ru:["пудель","собака","домашний питомец","элегантный"]},"🐺":{en:["wolf","wild","howl"],ru:["волк","дикий","воет"]},"🦊":{en:["fox","cunning","wild"],ru:["лиса","хитрая","дикая"]},"🦝":{en:["raccoon","mischievous","wild"],ru:["енот","озорной","дикий"]},"🐱":{en:["cat","pet","feline"],ru:["кот","домашний питомец","кошачий"]},"🐈":{en:["cat","feline","pet"],ru:["кот","кошачий","домашний питомец"]},"🐈‍⬛":{en:["black cat","mysterious","feline"],ru:["чёрный кот","загадочный","кошачий"]},"🦁":{en:["lion","king","wild","courage"],ru:["лев","король","дикий","отвага"]},"🐯":{en:["tiger","wild","stripes","fierce"],ru:["тигр","дикий","полосатый","свирепый"]},"🐅":{en:["tiger","stripes","wild"],ru:["тигр","полосатый","дикий"]},"🐆":{en:["leopard","spots","wild","fast"],ru:["леопард","пятна","дикий","быстрый"]},"🐴":{en:["horse","ride","equine"],ru:["лошадь","езда","конный"]},"🐎":{en:["horse","racing","equine"],ru:["лошадь","гонки","конный"]},"🦄":{en:["unicorn","magical","fantasy"],ru:["единорог","волшебный","фэнтези"]},"🦓":{en:["zebra","stripes","wild"],ru:["зебра","полосатая","дикая"]},"🦌":{en:["deer","antlers","forest"],ru:["олень","рога","лес"]},"🦬":{en:["bison","buffalo","wild"],ru:["бизон","буйвол","дикий"]},"🐮":{en:["cow","farm","bovine"],ru:["корова","ферма","коровий"]},"🐂":{en:["ox","bull","bovine"],ru:["вол","бык","коровий"]},"🐃":{en:["water buffalo","bovine","farm"],ru:["водный буйвол","коровий","ферма"]},"🐄":{en:["cow","bovine","farm"],ru:["корова","коровий","ферма"]},"🐷":{en:["pig","farm","oink"],ru:["свинья","ферма","хрюк"]},"🐖":{en:["pig","swine","farm"],ru:["свинья","свинное животное","ферма"]},"🐗":{en:["boar","wild","pig"],ru:["кабан","дикий","свинья"]},"🐽":{en:["pig nose","snout"],ru:["свинной нос","хоботок"]},"🐏":{en:["ram","sheep","male"],ru:["баран","овца","самец"]},"🐑":{en:["sheep","wool","farm"],ru:["овца","шерсть","ферма"]},"🐐":{en:["goat","farm","bleat"],ru:["коза","ферма","блеет"]},"🐪":{en:["camel","desert","hump"],ru:["верблюд","пустыня","горб"]},"🐫":{en:["camel","two-hump","desert"],ru:["двугорбый верблюд","двугорбый","пустыня"]},"🦙":{en:["llama","alpaca","cute"],ru:["лама","альпака","милый"]},"🦒":{en:["giraffe","tall","spots"],ru:["жираф","высокий","пятна"]},"🐘":{en:["elephant","trunk","large"],ru:["слон","хобот","большой"]},"🦏":{en:["rhinoceros","horn","tough"],ru:["носорог","рог","жесткий"]},"🦛":{en:["hippopotamus","water","large"],ru:["бегемот","вода","большой"]},"🦃":{en:["turkey","bird","thanksgiving"],ru:["индейка","птица","День благодарения"]},"🐔":{en:["chicken","rooster","hen"],ru:["курица","петух","курица (самка)"]},"🐓":{en:["rooster","chicken","bird"],ru:["петух","курица","птица"]},"🐣":{en:["hatching chick","baby","bird"],ru:["вылупляющийся цыплёнок","малыш","птица"]},"🐤":{en:["chick","small","bird"],ru:["цыплёнок","маленький","птица"]},"🐥":{en:["baby chicken","cute","bird"],ru:["цыплёнок","милый","птица"]},"🐦":{en:["bird","tweet","wing"],ru:["птица","чирик","крыло"]},"🐧":{en:["penguin","cold","bird"],ru:["пингвин","холодный","птица"]},"🕊️":{en:["dove","peace","bird"],ru:["голубь","мир","птица"]},"🦅":{en:["eagle","wild","bird"],ru:["орёл","дикий","птица"]},"🦆":{en:["duck","water","bird"],ru:["утка","вода","птица"]},"🦢":{en:["swan","graceful","bird"],ru:["лебедь","грациозный","птица"]},"🦉":{en:["owl","wise","night","bird"],ru:["сова","мудрая","ночная","птица"]},"🦤":{en:["dodo","extinct","bird"],ru:["додо","вымершая","птица"]},"🪶":{en:["feather","light","bird"],ru:["перо","лёгкое","птица"]},"🦩":{en:["flamingo","pink","bird"],ru:["фламинго","розовый","птица"]},"🦚":{en:["peacock","colorful","bird"],ru:["павлин","яркий","птица"]},"🦜":{en:["parrot","talkative","colorful"],ru:["попугай","болтливый","яркий"]},"🐸":{en:["frog","amphibian","green"],ru:["лягушка","амфибия","зелёная"]},"🐊":{en:["crocodile","reptile","danger"],ru:["крокодил","рептилия","опасность"]},"🐢":{en:["turtle","slow","reptile"],ru:["черепаха","медленная","рептилия"]},"🦎":{en:["lizard","reptile","scaly"],ru:["ящерица","рептилия","чешуйчатая"]},"🐍":{en:["snake","reptile","slither"],ru:["змея","рептилия","ползать"]},"🐲":{en:["dragon face","mythical","dragon"],ru:["лицо дракона","мифический","дракон"]},"🐉":{en:["dragon","mythical","fire"],ru:["дракон","мифический","огонь"]},"🦕":{en:["dinosaur","sauropod","prehistoric"],ru:["динозавр","зауропод","доисторический"]},"🦖":{en:["dinosaur","T-Rex","prehistoric"],ru:["динозавр","Ти-Рекс","доисторический"]},"🐳":{en:["whale","ocean","large"],ru:["кит","океан","большой"]},"🐋":{en:["whale","ocean","big"],ru:["кит","океан","огромный"]},"🐬":{en:["dolphin","ocean","friendly"],ru:["дельфин","океан","дружелюбный"]},"🦭":{en:["seal","marine","cute"],ru:["тюлень","морской","милый"]},"🐟":{en:["fish","ocean","swim"],ru:["рыба","океан","плавать"]},"🐠":{en:["tropical fish","ocean","colorful"],ru:["тропическая рыба","океан","яркая"]},"🐡":{en:["blowfish","puffer","ocean"],ru:["рыба-иглобрюх","фугу","океан"]},"🦈":{en:["shark","ocean","dangerous"],ru:["акула","океан","опасная"]},"🐙":{en:["octopus","marine","tentacles"],ru:["осьминог","морской","щупальца"]},"🐚":{en:["shell","beach","ocean"],ru:["ракушка","пляж","океан"]},"🪸":{en:["coral","reef","ocean"],ru:["коралл","риф","океан"]},"🐌":{en:["snail","slow","mollusk"],ru:["улитка","медленная","моллюск"]},"🦋":{en:["butterfly","insect","colorful"],ru:["бабочка","насекомое","яркая"]},"🐛":{en:["caterpillar","insect","larva"],ru:["гусеница","насекомое","личинка"]},"🐜":{en:["ant","small","insect"],ru:["муравей","маленький","насекомое"]},"🐝":{en:["bee","insect","honey"],ru:["пчела","насекомое","мёд"]},"🪲":{en:["beetle","insect","bug"],ru:["жук","насекомое","баг"]},"🐞":{en:["ladybug","insect","lucky"],ru:["божья коровка","насекомое","счастливая"]},"🦗":{en:["cricket","insect","chirp"],ru:["сверчок","насекомое","щебет"]},"🪳":{en:["cockroach","insect","pest"],ru:["таракан","насекомое","вредитель"]},"🕷️":{en:["spider","arachnid","insect"],ru:["паук","паукообразное","насекомое"]},"🕸️":{en:["web","spider","trap"],ru:["паутина","паук","ловушка"]},"🦂":{en:["scorpion","insect","venom"],ru:["скорпион","насекомое","яд"]},"🦟":{en:["mosquito","insect","bite"],ru:["комар","насекомое","укус"]},"🪰":{en:["fly","insect","buzz"],ru:["муха","насекомое","жужжание"]},"🪱":{en:["worm","earth","invertebrate"],ru:["червь","земля","беспозвоночное"]},"🌸":{en:["cherry blossom","flower","spring"],ru:["сакура","цветок","весна"]},"💮":{en:["white flower","flower","symbol"],ru:["белый цветок","цветок","символ"]},"🏵️":{en:["rosette","flower","decorative"],ru:["розетка","цветок","декоративный"]},"🌹":{en:["rose","flower","love","romance"],ru:["роза","цветок","любовь","романтика"]},"🥀":{en:["wilted flower","sad","decay"],ru:["увядший цветок","грусть","разложение"]},"🌺":{en:["hibiscus","flower","tropical"],ru:["гибискус","цветок","тропический"]},"🌻":{en:["sunflower","flower","summer"],ru:["подсолнух","цветок","лето"]},"🌼":{en:["blossom","flower","spring"],ru:["цветение","цветок","весна"]},"🌷":{en:["tulip","flower","spring"],ru:["тюльпан","цветок","весна"]},"🌱":{en:["seedling","plant","growth"],ru:["сеянец","растение","рост"]},"🪴":{en:["potted plant","indoor","green"],ru:["растение в горшке","в помещении","зелёное"]},"🌲":{en:["evergreen","tree","forest"],ru:["вечнозелёное","дерево","лес"]},"🌳":{en:["tree","nature","shade"],ru:["дерево","природа","тень"]},"🌴":{en:["palm tree","tropical","beach"],ru:["пальма","тропический","пляж"]},"🌵":{en:["cactus","desert","succulent"],ru:["кактус","пустыня","суккулент"]},"🌾":{en:["sheaf","grain","farm"],ru:["сноп","зерно","ферма"]},"🌿":{en:["herb","plant","leaf"],ru:["трава","растение","лист"]},"☘️":{en:["shamrock","luck","clover"],ru:["клевер","удача","трилистник"]},"🍀":{en:["four-leaf clover","luck","green"],ru:["клевер с четырьмя листьями","удача","зелёный"]},"🍁":{en:["maple leaf","autumn","fall"],ru:["кленовый лист","осень","осенний"]},"🍂":{en:["fallen leaf","autumn","nature"],ru:["опавший лист","осень","природа"]},"🍃":{en:["leaf","wind","nature"],ru:["лист","ветер","природа"]},"🍎":{en:["apple","red","fruit","healthy"],ru:["яблоко","красное","фрукт","полезное"]},"🍐":{en:["pear","fruit","green","juicy"],ru:["груша","фрукт","зелёная","сочная"]},"🍊":{en:["orange","fruit","citrus","vitamin C"],ru:["апельсин","фрукт","цитрус","витамин C"]},"🍋":{en:["lemon","citrus","sour","yellow"],ru:["лимон","цитрус","кислый","жёлтый"]},"🍌":{en:["banana","fruit","yellow","tropical"],ru:["банан","фрукт","жёлтый","тропический"]},"🍉":{en:["watermelon","fruit","summer","refreshing"],ru:["арбуз","фрукт","лето","освежающий"]},"🍇":{en:["grapes","fruit","purple","vine"],ru:["виноград","фрукт","фиолетовый","виноградная лоза"]},"🍓":{en:["strawberry","fruit","red","sweet"],ru:["клубника","фрукт","красная","сладкая"]},"🫐":{en:["blueberry","fruit","blue","healthy"],ru:["черника","фрукт","синяя","полезная"]},"🍈":{en:["melon","fruit","sweet","green"],ru:["дыня","фрукт","сладкая","зелёная"]},"🍒":{en:["cherry","fruit","red","sweet"],ru:["вишня","фрукт","красная","сладкая"]},"🍑":{en:["peach","fruit","fuzzy","sweet"],ru:["персик","фрукт","шероховатый","сладкий"]},"🥭":{en:["mango","fruit","tropical","yellow"],ru:["манго","фрукт","тропический","жёлтый"]},"🍍":{en:["pineapple","fruit","tropical","spiky"],ru:["ананас","фрукт","тропический","колючий"]},"🥥":{en:["coconut","tropical","fruit","white"],ru:["кокос","тропический","фрукт","белый"]},"🥝":{en:["kiwi","fruit","green","tart"],ru:["киви","фрукт","зелёный","кисловатый"]},"🍅":{en:["tomato","vegetable","red","juicy"],ru:["помидор","овощ","красный","сочный"]},"🍆":{en:["eggplant","vegetable","purple","aubergine"],ru:["баклажан","овощ","фиолетовый","баклажан"]},"🥑":{en:["avocado","vegetable","green","healthy"],ru:["авокадо","овощ","зелёный","полезный"]},"🥦":{en:["broccoli","vegetable","green","healthy"],ru:["брокколи","овощ","зелёный","полезный"]},"🥬":{en:["leafy greens","vegetable","lettuce","healthy"],ru:["листья салата","овощ","салат","полезный"]},"🥒":{en:["cucumber","vegetable","green","fresh"],ru:["огурец","овощ","зелёный","свежий"]},"🌶️":{en:["chili pepper","spicy","red","hot"],ru:["чили","острый","красный","горячий"]},"🫑":{en:["bell pepper","vegetable","colorful","sweet"],ru:["болгарский перец","овощ","разноцветный","сладкий"]},"🥕":{en:["carrot","vegetable","orange","crunchy"],ru:["морковь","овощ","оранжевая","хрустящая"]},"🧄":{en:["garlic","vegetable","aromatic","flavorful"],ru:["чеснок","овощ","ароматный","вкусный"]},"🧅":{en:["onion","vegetable","strong","flavor"],ru:["лук","овощ","сильный","вкус"]},"🥔":{en:["potato","vegetable","starchy","brown"],ru:["картофель","овощ","крахмалистый","коричневый"]},"🍠":{en:["sweet potato","vegetable","orange","starchy"],ru:["батат","овощ","оранжевый","крахмалистый"]},"🥐":{en:["croissant","bread","pastry","flaky"],ru:["круассан","хлеб","выпечка","слоёный"]},"🥯":{en:["bagel","bread","round","chewy"],ru:["бейгл","хлеб","круглый","жевательный"]},"🍞":{en:["bread","baked","loaf","toast"],ru:["хлеб","выпеченный","буханка","тост"]},"🥖":{en:["baguette","bread","French","long"],ru:["багет","хлеб","французский","длинный"]},"🥨":{en:["pretzel","snack","salted","twisted"],ru:["претцель","закуска","солёный","скрученный"]},"🧀":{en:["cheese","dairy","yellow","savory"],ru:["сыр","молочный продукт","жёлтый","пикантный"]},"🥚":{en:["egg","protein","breakfast"],ru:["яйцо","белок","завтрак"]},"🍳":{en:["fried egg","breakfast","cooked"],ru:["жареное яйцо","завтрак","приготовленное"]},"🥓":{en:["bacon","meat","crispy","breakfast"],ru:["бекон","мясо","хрустящий","завтрак"]},"🥩":{en:["steak","meat","protein","beef"],ru:["стейк","мясо","белок","говядина"]},"🍗":{en:["chicken leg","meat","drumstick","grilled"],ru:["куриная ножка","мясо","барабанная палочка","гриль"]},"🍖":{en:["meat on bone","barbecue","protein"],ru:["мясо на кости","барбекю","белок"]},"🦴":{en:["bone","meat","dog","skeleton"],ru:["кость","мясо","собака","скелет"]},"🌭":{en:["hot dog","fast food","sausage"],ru:["хот-дог","фастфуд","колбаска"]},"🍔":{en:["burger","fast food","beef","cheese"],ru:["бургер","фастфуд","говядина","сыр"]},"🍟":{en:["french fries","fast food","crispy","potato"],ru:["картофель фри","фастфуд","хрустящий","картофель"]},"🍕":{en:["pizza","cheese","fast food","Italian"],ru:["пицца","сыр","фастфуд","итальянская"]},"🫓":{en:["flatbread","bread","soft"],ru:["лепёшка","хлеб","мягкая"]},"🥪":{en:["sandwich","bread","meal"],ru:["бутерброд","хлеб","приём пищи"]},"🥙":{en:["pita","bread","stuffed","Greek"],ru:["пита","хлеб","фаршированная","греческая"]},"🧆":{en:["falafel","vegetarian","fried"],ru:["фалафель","вегетарианский","жареный"]},"🌮":{en:["taco","Mexican","spicy"],ru:["тако","мексиканская","острая"]},"🌯":{en:["burrito","Mexican","stuffed"],ru:["буррито","мексиканская","фаршированная"]},"🫔":{en:["tamale","Mexican","corn"],ru:["тамале","мексиканская","кукурузная"]},"🥗":{en:["salad","healthy","vegetable"],ru:["салат","здоровый","овощной"]},"🥘":{en:["paella","stew","seafood"],ru:["паэлья","тушёное блюдо","морепродукты"]},"🫕":{en:["fondue","melted","cheese"],ru:["фондю","расплавленный","сыр"]},"🥫":{en:["canned food","storage","preserved"],ru:["консервы","хранение","сохранённое"]},"🍝":{en:["spaghetti","pasta","Italian"],ru:["спагетти","паста","итальянская"]},"🍜":{en:["ramen","noodles","Asian"],ru:["рамен","лапша","азиатская"]},"🍲":{en:["hotpot","stew","broth"],ru:["хотпот","тушёное блюдо","бульон"]},"🍛":{en:["curry","spicy","rice"],ru:["карри","острая","рис"]},"🍣":{en:["sushi","Japanese","fish"],ru:["суши","японская","рыба"]},"🍱":{en:["bento box","Japanese","meal"],ru:["бенто","японская","еда"]},"🥟":{en:["dumpling","Asian","stuffed"],ru:["пельмени","азиатские","фаршированные"]},"🦪":{en:["oyster","seafood","shellfish"],ru:["устрица","морепродукт","раковина"]},"🍤":{en:["shrimp tempura","fried","seafood"],ru:["креветка темпура","жареная","морепродукт"]},"🍙":{en:["rice ball","Japanese","onigiri"],ru:["рисовый шар","японская","онигири"]},"🍚":{en:["cooked rice","staple","Asian"],ru:["варёный рис","основа","азиатская"]},"🍘":{en:["rice cracker","snack","Japanese"],ru:["рисовый крекер","закуска","японская"]},"🍥":{en:["fish cake","Japanese","swirl"],ru:["рыбный пирожок","японская","спираль"]},"🥠":{en:["fortune cookie","Chinese","paper"],ru:["печенье с предсказанием","китайское","бумажное"]},"🥮":{en:["mooncake","Chinese","festival"],ru:["лунное печенье","китайское","фестиваль"]},"🍢":{en:["skewered snack","street food"],ru:["шампур","уличная еда"]},"🍡":{en:["dango","Japanese","mochi"],ru:["данго","японское","мочи"]},"🍧":{en:["shaved ice","dessert","cold"],ru:["измельчённый лёд","десерт","холодный"]},"🍨":{en:["ice cream","cold","sweet"],ru:["мороженое","холодное","сладкое"]},"🍦":{en:["soft serve","dessert","cold"],ru:["мягкое мороженое","десерт","холодное"]},"🥧":{en:["pie","dessert","baked"],ru:["пирог","десерт","выпеченный"]},"🧁":{en:["cupcake","sweet","frosting"],ru:["капкейк","сладкий","с глазурью"]},"🍰":{en:["cake","dessert","slice"],ru:["торт","десерт","кусок"]},"🎂":{en:["birthday cake","celebration","sweet"],ru:["торт ко дню рождения","празднование","сладкий"]},"🍮":{en:["flan","custard","dessert"],ru:["флан","кастард","десерт"]},"🍭":{en:["lollipop","candy","sweet"],ru:["леденец","конфета","сладкий"]},"🍬":{en:["candy","sweet","sugar"],ru:["конфета","сладость","сахар"]},"🍫":{en:["chocolate","sweet","cocoa"],ru:["шоколад","сладкий","какао"]},"🍿":{en:["popcorn","snack","buttery"],ru:["попкорн","закуска","масляный"]},"🍩":{en:["doughnut","sweet","fried"],ru:["пончик","сладкий","жареный"]},"🍪":{en:["cookie","sweet","baked"],ru:["печенье","сладкое","выпеченное"]},"🫖":{en:["teapot","tea","hot"],ru:["чайник","чай","горячий"]},"☕":{en:["coffee","hot drink","caffeine"],ru:["кофе","горячий напиток","кофеин"]},"🍵":{en:["green tea","hot","Japanese"],ru:["зелёный чай","горячий","японский"]},"🧃":{en:["juice","drink","fruit"],ru:["сок","напиток","фруктовый"]},"🥤":{en:["soft drink","straw","fast food"],ru:["безалкогольный напиток","с трубочкой","фастфуд"]},"🧋":{en:["bubble tea","milk tea","boba"],ru:["бабл-ти","молочный чай","боба"]},"🍶":{en:["sake","Japanese","rice wine"],ru:["саке","японский","рисовое вино"]},"🍺":{en:["beer","drink","alcohol"],ru:["пиво","напиток","алкоголь"]},"🍻":{en:["cheers","beer","drinking"],ru:["ура","пиво","выпивка"]},"🥂":{en:["champagne","celebration","toast"],ru:["шампанское","празднование","тост"]},"🍷":{en:["wine","drink","red"],ru:["вино","напиток","красное"]},"🥃":{en:["whiskey","liquor","alcohol"],ru:["виски","ликёр","алкоголь"]},"🍸":{en:["cocktail","martini","drink"],ru:["коктейль","мартини","напиток"]},"🍹":{en:["tropical drink","cocktail","summer"],ru:["тропический напиток","коктейль","лето"]},"🧉":{en:["mate","South American","tea"],ru:["мате","южноамериканский","чай"]},"🍾":{en:["champagne bottle","celebration","party"],ru:["бутылка шампанского","празднование","вечеринка"]},"⚽":{en:["soccer","football","sports","ball"],ru:["футбол","футбол","спорт","мяч"]},"🏀":{en:["basketball","sports","hoop","dunk"],ru:["баскетбол","спорт","кольцо","данк"]},"🏈":{en:["American football","sports","rugby"],ru:["американский футбол","спорт","регби"]},"⚾":{en:["baseball","sports","bat"],ru:["бейсбол","спорт","бита"]},"🥎":{en:["softball","sports","ball"],ru:["софтбол","спорт","мяч"]},"🎾":{en:["tennis","sports","racket"],ru:["теннис","спорт","ракетка"]},"🏐":{en:["volleyball","sports","beach"],ru:["волейбол","спорт","пляж"]},"🏉":{en:["rugby","sports","oval ball"],ru:["регби","спорт","овальный мяч"]},"🥏":{en:["frisbee","throw","flying disc"],ru:["фрисби","бросок","летающий диск"]},"🎱":{en:["billiards","8 ball","pool"],ru:["бильярд","восьмёрка","пул"]},"🪀":{en:["yo-yo","toy","string"],ru:["йо-йо","игрушка","верёвка"]},"🏓":{en:["ping pong","table tennis","sports"],ru:["пинг-понг","настольный теннис","спорт"]},"🏸":{en:["badminton","racket","sports"],ru:["бадминтон","ракетка","спорт"]},"🏒":{en:["hockey","ice hockey","sports"],ru:["хоккей","хоккей на льду","спорт"]},"🏑":{en:["field hockey","sports","stick"],ru:["хоккей на траве","спорт","клюшка"]},"🥍":{en:["lacrosse","sports","net"],ru:["лакросс","спорт","сеть"]},"🏏":{en:["cricket","bat","sports"],ru:["крикет","бита","спорт"]},"⛳":{en:["golf","sports","hole in one"],ru:["гольф","спорт","луночка"]},"🪁":{en:["kite","flying","wind"],ru:["змей","летать","ветер"]},"🎣":{en:["fishing","hook","water"],ru:["рыбалка","крючок","вода"]},"🤿":{en:["diving","underwater","snorkel"],ru:["дайвинг","под водой","снорклинг"]},"🎽":{en:["running","jersey","athlete"],ru:["бег","майка","спортсмен"]},"🛹":{en:["skateboard","sports","extreme"],ru:["скейтборд","спорт","экстрим"]},"🛼":{en:["roller skate","sports","wheels"],ru:["роликовые коньки","спорт","колёса"]},"🛷":{en:["sled","winter","snow"],ru:["санки","зима","снег"]},"⛸️":{en:["ice skate","winter","sports"],ru:["коньки","зима","спорт"]},"🥌":{en:["curling","winter","stone"],ru:["керлинг","зима","камень"]},"⛷️":{en:["skiing","winter","snow"],ru:["лыжи","зима","снег"]},"🏂":{en:["snowboarding","sports","snow"],ru:["сноуборд","спорт","снег"]},"🪂":{en:["parachute","skydiving","air"],ru:["парашют","скайдайвинг","воздух"]},"🏋️":{en:["weightlifting","gym","strong"],ru:["тяжёлая атлетика","спортзал","сильный"]},"🤼":{en:["wrestling","fight","grapple"],ru:["борьба","драка","схватка"]},"🤸":{en:["gymnastics","acrobatics","flip"],ru:["гимнастика","акробатика","сальто"]},"⛹️":{en:["basketball","dribbling","sports"],ru:["баскетбол","дриблинг","спорт"]},"🤾":{en:["handball","sports","throw"],ru:["гандбол","спорт","бросок"]},"🏌️":{en:["golf","swing","sports"],ru:["гольф","мах","спорт"]},"🏇":{en:["horse racing","sports","jockey"],ru:["конные скачки","спорт","жокей"]},"🧘":{en:["meditation","yoga","zen"],ru:["медитация","йога","дзен"]},"🏄":{en:["surfing","wave","water"],ru:["серфинг","волна","вода"]},"🏊":{en:["swimming","water","pool"],ru:["плавание","вода","бассейн"]},"🤽":{en:["water polo","sports","swimming"],ru:["водное поло","спорт","плавание"]},"🚣":{en:["rowing","boat","water"],ru:["гребля","лодка","вода"]},"🧗":{en:["rock climbing","sports","mountain"],ru:["скалолазание","спорт","гора"]},"🚴":{en:["cycling","bike","sports"],ru:["велоспорт","велосипед","спорт"]},"🚵":{en:["mountain biking","sports","outdoor"],ru:["маунтинбайк","спорт","на свежем воздухе"]},"🎪":{en:["circus","tent","performance"],ru:["цирк","палатка","выступление"]},"🎭":{en:["theater","drama","acting"],ru:["театр","драма","актерство"]},"🎨":{en:["painting","art","colors"],ru:["живопись","искусство","цвета"]},"🎬":{en:["film","clapperboard","movie"],ru:["фильм","хлопушка","кино"]},"🎤":{en:["microphone","singing","music"],ru:["микрофон","пение","музыка"]},"🎧":{en:["headphones","music","listening"],ru:["наушники","музыка","прослушивание"]},"🎼":{en:["music","sheet","notes"],ru:["музыка","ноты","сценарий"]},"🎹":{en:["piano","keyboard","music"],ru:["пианино","клавиатура","музыка"]},"🥁":{en:["drums","music","percussion"],ru:["барабаны","музыка","ударные"]},"🎷":{en:["saxophone","jazz","music"],ru:["саксофон","джаз","музыка"]},"🎺":{en:["trumpet","brass","music"],ru:["труба","латунь","музыка"]},"🎸":{en:["guitar","music","rock"],ru:["гитара","музыка","рок"]},"🎻":{en:["violin","music","strings"],ru:["скрипка","музыка","струны"]},"🎲":{en:["dice","game","board game"],ru:["кубики","игра","настольная игра"]},"🎯":{en:["dart","target","game"],ru:["дротик","цель","игра"]},"🎳":{en:["bowling","sports","pins"],ru:["боулинг","спорт","кегли"]},"🎮":{en:["video game","console","gaming"],ru:["видеоигра","консоль","игры"]},"🎰":{en:["slot machine","casino","gambling"],ru:["игровой автомат","казино","азартные игры"]},"🧩":{en:["puzzle","pieces","brain teaser"],ru:["головоломка","кусочки","разминка для мозга"]},"🎫":{en:["ticket","event","entry"],ru:["билет","событие","вход"]},"🎟️":{en:["admission","ticket","event"],ru:["входной билет","билет","событие"]},"🚗":{en:["car","automobile","vehicle","transport"],ru:["автомобиль","машина","транспортное средство","транспорт"]},"🚕":{en:["taxi","cab","transport","vehicle"],ru:["такси","маршрутка","транспорт","транспортное средство"]},"🚙":{en:["suv","vehicle","transport"],ru:["внедорожник","транспортное средство","транспорт"]},"🚌":{en:["bus","public transport","commute"],ru:["автобус","общественный транспорт","коммьют"]},"🚎":{en:["trolleybus","public transport","electric"],ru:["троллейбус","общественный транспорт","электрический"]},"🏎️":{en:["race car","sports car","fast","speed"],ru:["гоночный автомобиль","спортивный автомобиль","быстрый","скорость"]},"🚓":{en:["police car","law enforcement","vehicle"],ru:["полицейская машина","правоохранительные органы","транспортное средство"]},"🚑":{en:["ambulance","emergency","hospital"],ru:["скорая помощь","чрезвычайная ситуация","больница"]},"🚒":{en:["fire truck","firefighter","emergency"],ru:["пожарная машина","пожарный","чрезвычайная ситуация"]},"🚐":{en:["van","minibus","transport"],ru:["фургон","маршрутка","транспорт"]},"🛻":{en:["pickup truck","off-road","vehicle"],ru:["пикап","для бездорожья","транспортное средство"]},"🚚":{en:["delivery truck","freight","cargo"],ru:["грузовик","доставка","груз"]},"🚛":{en:["truck","semi-trailer","transport"],ru:["грузовик","самосвал","транспорт"]},"🚜":{en:["tractor","farming","agriculture"],ru:["трактор","сельское хозяйство","агрономия"]},"🛵":{en:["scooter","motorbike","moped"],ru:["скутер","мотоцикл","мопед"]},"🏍️":{en:["motorcycle","bike","racing"],ru:["мотоцикл","байк","гоночный"]},"🛺":{en:["rickshaw","auto rickshaw","transport"],ru:["рикша","авто-рикша","транспорт"]},"🚲":{en:["bicycle","bike","pedal","cycling"],ru:["велосипед","байк","педаль","велоспорт"]},"🛴":{en:["kick scooter","scooter","ride"],ru:["самокат","скутер","поездка"]},"✈️":{en:["airplane","flight","travel","sky"],ru:["самолёт","рейс","путешествие","небо"]},"🛩️":{en:["small airplane","aviation","sky"],ru:["малый самолёт","авиация","небо"]},"🛫":{en:["departure","takeoff","airport"],ru:["вылет","взлёт","аэропорт"]},"🛬":{en:["landing","arrival","airport"],ru:["посадка","прибытие","аэропорт"]},"🚁":{en:["helicopter","aviation","air"],ru:["вертолёт","авиация","воздух"]},"🚀":{en:["rocket","space","launch","NASA"],ru:["ракета","космос","запуск","НАСА"]},"🛸":{en:["UFO","alien","spaceship","extraterrestrial"],ru:["НЛО","инопланетянин","космический корабль","внеземной"]},"🛶":{en:["canoe","boat","paddle","water"],ru:["каноэ","лодка","весло","вода"]},"⛵":{en:["sailboat","yacht","sea"],ru:["парусник","яхта","море"]},"🚤":{en:["motorboat","speedboat","ocean"],ru:["моторная лодка","скоростной катер","океан"]},"🛥️":{en:["yacht","luxury","boat"],ru:["яхта","роскошь","лодка"]},"🛳️":{en:["cruise ship","ocean","voyage"],ru:["круизный лайнер","океан","путешествие"]},"⛴️":{en:["ferry","boat","transport"],ru:["паром","лодка","транспорт"]},"🚢":{en:["ship","ocean","voyage"],ru:["корабль","океан","путешествие"]},"🏰":{en:["castle","fortress","history"],ru:["замок","крепость","история"]},"🏯":{en:["Japanese castle","Asia","samurai"],ru:["японский замок","Азия","самурай"]},"🏟️":{en:["stadium","sports","arena"],ru:["стадион","спорт","арена"]},"🏖️":{en:["beach","sun","vacation"],ru:["пляж","солнце","отпуск"]},"🏝️":{en:["island","tropical","vacation"],ru:["остров","тропический","отпуск"]},"🏜️":{en:["desert","sand","dry"],ru:["пустыня","песок","сухой"]},"🌋":{en:["volcano","eruption","lava"],ru:["вулкан","извержение","лава"]},"⛰️":{en:["mountain","hiking","nature"],ru:["гора","поход","природа"]},"🏔️":{en:["snowy mountain","climbing","cold"],ru:["снежная гора","скалолазание","холод"]},"🗻":{en:["Mount Fuji","Japan","scenic"],ru:["гора Фудзи","Япония","живописный"]},"🏕️":{en:["camping","tent","outdoors"],ru:["кемпинг","палатка","на природе"]},"🏭":{en:["factory","industry","building"],ru:["фабрика","индустрия","здание"]},"🏢":{en:["office building","corporate","city"],ru:["офисное здание","корпоративный","город"]},"🏬":{en:["shopping mall","retail","stores"],ru:["торговый центр","розничная торговля","магазины"]},"🏣":{en:["post office","mail","building"],ru:["почтовое отделение","почта","здание"]},"🏤":{en:["post office","mail","postal service"],ru:["почтовое отделение","почта","почтовая служба"]},"🏥":{en:["hospital","healthcare","emergency"],ru:["больница","здравоохранение","чрезвычайная ситуация"]},"🏦":{en:["bank","money","finance"],ru:["банк","деньги","финансы"]},"🏨":{en:["hotel","accommodation","stay"],ru:["отель","размещение","проживание"]},"🏪":{en:["convenience store","shopping","24/7"],ru:["магазин","шоппинг","круглосуточно"]},"🏫":{en:["school","education","learning"],ru:["школа","образование","обучение"]},"🏩":{en:["love hotel","romantic","Japan"],ru:["любовный отель","романтический","Япония"]},"💒":{en:["wedding","church","marriage"],ru:["свадьба","церковь","брак"]},"⛪":{en:["church","Christianity","religion"],ru:["церковь","христианство","религия"]},"🕌":{en:["mosque","Islam","prayer"],ru:["мечеть","ислам","молитва"]},"🕍":{en:["synagogue","Judaism","religion"],ru:["синагога","иудаизм","религия"]},"🛕":{en:["hindu temple","spiritual","India"],ru:["индуистский храм","духовный","Индия"]},"⛩️":{en:["shrine","torii","Japan"],ru:["святилище","тории","Япония"]},"🏛️":{en:["government building","politics","history"],ru:["правительственное здание","политика","история"]},"📱":{en:["smartphone","mobile","phone"],ru:["смартфон","мобильный","телефон"]},"💻":{en:["laptop","computer","technology"],ru:["ноутбук","компьютер","технология"]},"⌨️":{en:["keyboard","typing","computer"],ru:["клавиатура","набор текста","компьютер"]},"🖥️":{en:["desktop","monitor","screen"],ru:["настольный компьютер","монитор","экран"]},"🖨️":{en:["printer","print","office"],ru:["принтер","печать","офис"]},"🖱️":{en:["mouse","computer","click"],ru:["мышь","компьютер","клик"]},"🖲️":{en:["trackball","navigation","input"],ru:["трекбол","навигация","ввод"]},"🕹️":{en:["joystick","gaming","console"],ru:["джойстик","игры","консоль"]},"🗜️":{en:["clamp","tool","hardware"],ru:["зажим","инструмент","аппаратное обеспечение"]},"💽":{en:["mini disc","storage","media"],ru:["мини-диск","хранение","медиа"]},"💾":{en:["floppy disk","save","data"],ru:["флоппи-диск","сохранить","данные"]},"💿":{en:["CD","compact disc","music"],ru:["CD","компакт-диск","музыка"]},"📀":{en:["DVD","video","disc"],ru:["DVD","видео","диск"]},"📼":{en:["VHS","video cassette","retro"],ru:["VHS","видеокассета","ретро"]},"📷":{en:["camera","photo","photography"],ru:["камера","фото","фотография"]},"📸":{en:["camera flash","photography","snapshot"],ru:["вспышка камеры","фотография","снимок"]},"📹":{en:["video camera","recording","film"],ru:["видеокамера","запись","фильм"]},"🎥":{en:["movie camera","film","cinema"],ru:["кино-камера","фильм","кино"]},"📞":{en:["telephone","call","communication"],ru:["телефон","звонок","коммуникация"]},"☎️":{en:["phone","landline","call"],ru:["телефон","стационарный","звонок"]},"📟":{en:["pager","message","communication"],ru:["пейджер","сообщение","коммуникация"]},"📠":{en:["fax machine","office","document"],ru:["факс","офис","документ"]},"📺":{en:["TV","television","screen"],ru:["телевизор","теле","экран"]},"📻":{en:["radio","broadcast","audio"],ru:["радио","трансляция","аудио"]},"🎙️":{en:["microphone","recording","podcast"],ru:["микрофон","запись","подкаст"]},"🎚️":{en:["control knob","audio","volume"],ru:["ручка управления","аудио","громкость"]},"🎛️":{en:["sliders","equalizer","settings"],ru:["ползунки","эквалайзер","настройки"]},"📡":{en:["satellite dish","broadcast","signal"],ru:["спутниковая антенна","трансляция","сигнал"]},"🔋":{en:["battery","power","energy"],ru:["батарея","мощность","энергия"]},"🔌":{en:["plug","electricity","charging"],ru:["штекер","электричество","зарядка"]},"💡":{en:["light bulb","idea","illumination"],ru:["лампочка","идея","освещение"]},"🔦":{en:["flashlight","torch","light"],ru:["фонарик","фонарь","свет"]},"🕯️":{en:["candle","light","fire"],ru:["свеча","свет","огонь"]},"🧯":{en:["fire extinguisher","safety","fire"],ru:["огнетушитель","безопасность","огонь"]},"🛢️":{en:["barrel","oil","fuel"],ru:["бочка","масло","топливо"]},"💸":{en:["money with wings","cash","spending"],ru:["деньги с крыльями","наличные","расходы"]},"💵":{en:["dollar bills","money","USD"],ru:["долларовые банкноты","деньги","USD"]},"💴":{en:["yen","money","Japan"],ru:["иена","деньги","Япония"]},"💶":{en:["euro","money","currency"],ru:["евро","деньги","валюта"]},"💷":{en:["pound","money","UK"],ru:["фунт","деньги","Великобритания"]},"🪙":{en:["coin","currency","money"],ru:["монета","валюта","деньги"]},"💰":{en:["money bag","wealth","rich"],ru:["мешок с деньгами","богатство","богатый"]},"💳":{en:["credit card","banking","payment"],ru:["кредитная карта","банковское дело","оплата"]},"💎":{en:["gem","diamond","valuable"],ru:["драгоценный камень","бриллиант","ценный"]},"⚖️":{en:["balance scale","justice","law"],ru:["весы","справедливость","закон"]},"🪜":{en:["ladder","climb","height"],ru:["лестница","лазить","высота"]},"🧰":{en:["toolbox","tools","repair"],ru:["ящик с инструментами","инструменты","ремонт"]},"🔧":{en:["wrench","repair","tools"],ru:["гаечный ключ","ремонт","инструменты"]},"🔨":{en:["hammer","build","fix"],ru:["молоток","строить","чинить"]},"⚒️":{en:["hammer and pick","construction","work"],ru:["молот и кирка","строительство","работа"]},"🛠️":{en:["tools","fix","maintenance"],ru:["инструменты","чинить","обслуживание"]},"⛏️":{en:["pickaxe","mining","digging"],ru:["кирка","горное дело","копать"]},"✏️":{en:["pencil","writing","notes"],ru:["карандаш","написание","заметки"]},"🖊️":{en:["pen","writing","signature"],ru:["ручка","написание","подпись"]},"🖋️":{en:["fountain pen","calligraphy","writing"],ru:["перьевая ручка","каллиграфия","написание"]},"✒️":{en:["nib","ink","writing"],ru:["остриё","чернила","написание"]},"🖌️":{en:["paintbrush","art","painting"],ru:["кисть","искусство","живопись"]},"🖍️":{en:["crayon","drawing","color"],ru:["мелки","рисование","цвет"]},"📝":{en:["memo","notes","document"],ru:["заметка","записи","документ"]},"📚":{en:["books","reading","library"],ru:["книги","чтение","библиотека"]},"📖":{en:["open book","reading","story"],ru:["открытая книга","чтение","история"]},"🔖":{en:["bookmark","reading","save"],ru:["закладка","чтение","сохранить"]},"📑":{en:["bookmark tabs","pages","notes"],ru:["закладки","страницы","заметки"]},"🗒️":{en:["spiral notepad","notes","journal"],ru:["спиральный блокнот","записи","журнал"]},"📄":{en:["document","paper","page"],ru:["документ","бумага","страница"]},"📰":{en:["newspaper","news","journalism"],ru:["газета","новости","журналистика"]},"🗞️":{en:["rolled newspaper","press","print"],ru:["свернутая газета","пресса","печатное издание"]},"📁":{en:["file folder","documents","storage"],ru:["папка","документы","хранение"]},"📂":{en:["open folder","organization","files"],ru:["открытая папка","организация","файлы"]},"🗂️":{en:["card index","catalog","records"],ru:["карточный индекс","каталог","записи"]},"🕐":{en:["1 o'clock","clock face","time"],ru:["час","циферблат","время"]},"🕑":{en:["2 o'clock","clock face","time"],ru:["два часа","циферблат","время"]},"🕒":{en:["3 o'clock","clock face","time"],ru:["три часа","циферблат","время"]},"🕓":{en:["4 o'clock","clock face","time"],ru:["четыре часа","циферблат","время"]},"🕔":{en:["5 o'clock","clock face","time"],ru:["пять часов","циферблат","время"]},"🕕":{en:["6 o'clock","clock face","time"],ru:["шесть часов","циферблат","время"]},"🕖":{en:["7 o'clock","clock face","time"],ru:["семь часов","циферблат","время"]},"🕗":{en:["8 o'clock","clock face","time"],ru:["восемь часов","циферблат","время"]},"🕘":{en:["9 o'clock","clock face","time"],ru:["девять часов","циферблат","время"]},"🕙":{en:["10 o'clock","clock face","time"],ru:["десять часов","циферблат","время"]},"🕚":{en:["11 o'clock","clock face","time"],ru:["одиннадцать часов","циферблат","время"]},"🕛":{en:["12 o'clock","clock face","time"],ru:["двенадцать часов","циферблат","время"]},"🕰️":{en:["mantel clock","clock","time"],ru:["настенные часы","часы","время"]},"⏰":{en:["alarm clock","wake up","time"],ru:["будильник","пробуждение","время"]},"⏱️":{en:["stopwatch","timer","time"],ru:["секундомер","таймер","время"]},"⏲️":{en:["kitchen timer","timer","time"],ru:["кухонный таймер","таймер","время"]},"⌚":{en:["watch","smartwatch","time"],ru:["часы","умные часы","время"]},"❤️":{en:["heart","love","affection"],ru:["сердце","любовь","нежность"]},"🧡":{en:["orange heart","warmth","care"],ru:["оранжевое сердце","теплота","забота"]},"💛":{en:["yellow heart","friendship","happiness"],ru:["жёлтое сердце","дружба","счастье"]},"💚":{en:["green heart","envy","nature","eco"],ru:["зелёное сердце","зависть","природа","эко"]},"💙":{en:["blue heart","loyalty","trust"],ru:["синее сердце","верность","доверие"]},"💜":{en:["purple heart","compassion","admiration"],ru:["фиолетовое сердце","сострадание","восхищение"]},"🤎":{en:["brown heart","earth","stability"],ru:["коричневое сердце","земля","устойчивость"]},"🖤":{en:["black heart","mourning","dark"],ru:["чёрное сердце","скорбь","тёмный"]},"🤍":{en:["white heart","pure","peace"],ru:["белое сердце","чистый","мир"]},"💔":{en:["broken heart","sad","heartbreak"],ru:["разбитое сердце","грусть","сердечная боль"]},"❣️":{en:["heart exclamation","love","emotion"],ru:["сердечный восклицательный знак","любовь","эмоция"]},"💕":{en:["two hearts","romance","affection"],ru:["два сердца","романтика","нежность"]},"💞":{en:["revolving hearts","love","relationship"],ru:["вращающиеся сердца","любовь","отношения"]},"💓":{en:["beating heart","emotion","passion"],ru:["бьющееся сердце","эмоция","страсть"]},"💗":{en:["growing heart","love","expanding"],ru:["растущее сердце","любовь","расширяющееся"]},"💖":{en:["sparkling heart","admiration","shine"],ru:["блестящее сердце","восхищение","сияние"]},"💘":{en:["heart with arrow","love","romance"],ru:["сердце со стрелой","любовь","романтика"]},"💝":{en:["heart with ribbon","gift","affection"],ru:["сердце с лентой","подарок","нежность"]},"💟":{en:["heart decoration","symbol","love"],ru:["украшение сердца","символ","любовь"]},"☮️":{en:["peace","pacifism","symbol"],ru:["мир","пацифизм","символ"]},"✝️":{en:["cross","christianity","religion"],ru:["крест","христианство","религия"]},"☪️":{en:["star and crescent","islam","faith"],ru:["звезда и полумесяц","ислам","вера"]},"🕉️":{en:["om","hinduism","spiritual"],ru:["ом","индуизм","духовный"]},"☸️":{en:["dharma wheel","buddhism","karma"],ru:["колесо дхармы","буддизм","карма"]},"✡️":{en:["star of david","judaism","faith"],ru:["звезда Давида","иудаизм","вера"]},"🔯":{en:["hexagram","mystic","spiritual"],ru:["шестиконечная звезда","мистический","духовный"]},"🕎":{en:["menorah","hanukkah","jewish"],ru:["менора","Ханука","еврейский"]},"☯️":{en:["yin yang","balance","harmony"],ru:["инь-ян","баланс","гармония"]},"☦️":{en:["orthodox cross","christianity","faith"],ru:["православный крест","христианство","вера"]},"🛐":{en:["place of worship","religion","faith"],ru:["место поклонения","религия","вера"]},"⛎":{en:["ophiuchus","zodiac","astrology"],ru:["змееносец","зодиак","астрология"]},"⚠️":{en:["warning","caution","alert"],ru:["предупреждение","осторожность","тревога"]},"🚸":{en:["children crossing","school","pedestrian"],ru:["дети на переходе","школа","пешеход"]},"⛔":{en:["no entry","prohibited","restricted"],ru:["вход запрещён","запрещено","ограничено"]},"🚫":{en:["prohibited","no","forbidden"],ru:["запрещено","нет","запрещено"]},"☢️":{en:["radioactive","hazard","danger"],ru:["радиоактивный","опасность","угроза"]},"☣️":{en:["biohazard","toxic","warning"],ru:["биологическая опасность","ядовитый","предупреждение"]},"➕":{en:["plus","addition","math"],ru:["плюс","сложение","математика"]},"➖":{en:["minus","subtraction","math"],ru:["минус","вычитание","математика"]},"➗":{en:["division","divide","math"],ru:["деление","делить","математика"]},"✖️":{en:["multiplication","times","math"],ru:["умножение","раз","математика"]},"♾️":{en:["infinity","limitless","math"],ru:["бесконечность","безграничный","математика"]},"💲":{en:["dollar","money","currency"],ru:["доллар","деньги","валюта"]},"💱":{en:["currency exchange","finance","money"],ru:["обмен валюты","финансы","деньги"]},"⬆️":{en:["up arrow","increase","direction"],ru:["стрелка вверх","увеличение","направление"]},"↗️":{en:["up-right arrow","growth","move"],ru:["стрелка вверх-вправо","рост","движение"]},"➡️":{en:["right arrow","next","forward"],ru:["стрелка вправо","далее","вперёд"]},"↘️":{en:["down-right arrow","decrease","move"],ru:["стрелка вниз-вправо","уменьшение","движение"]},"⬇️":{en:["down arrow","lower","decline"],ru:["стрелка вниз","понижение","снижение"]},"↙️":{en:["down-left arrow","falling","move"],ru:["стрелка вниз-влево","падение","движение"]},"⬅️":{en:["left arrow","back","previous"],ru:["стрелка влево","назад","предыдущий"]},"↖️":{en:["up-left arrow","direction","move"],ru:["стрелка вверх-влево","направление","движение"]},"↕️":{en:["vertical arrows","up down","change"],ru:["вертикальные стрелки","вверх вниз","изменение"]},"↔️":{en:["horizontal arrows","left right","switch"],ru:["горизонтальные стрелки","влево вправо","переключение"]},"↩️":{en:["back arrow","undo","return"],ru:["стрелка назад","отмена","возврат"]},"↪️":{en:["right curved arrow","redirect","turn"],ru:["изогнутая стрелка вправо","перенаправление","поворот"]},"⤴️":{en:["up-right arrow","diagonal","move"],ru:["диагональная стрелка вверх-вправо","диагональ","движение"]},"⤵️":{en:["down-right arrow","diagonal","move"],ru:["диагональная стрелка вниз-вправо","диагональ","движение"]},"🔃":{en:["repeat","cycle","refresh"],ru:["повтор","цикл","обновление"]},"🔄":{en:["counterclockwise arrows","reload","sync"],ru:["стрелки против часовой стрелки","перезагрузка","синхронизация"]},"🔆":{en:["bright","high brightness","sun"],ru:["яркий","высокая яркость","солнце"]},"📶":{en:["signal","network","connection"],ru:["сигнал","сеть","соединение"]},"🎦":{en:["cinema","movies","entertainment"],ru:["кино","фильмы","развлечения"]},"🔅":{en:["dim","low brightness","light"],ru:["тусклый","низкая яркость","свет"]},"♻️":{en:["recycle","eco","sustainability"],ru:["переработка","эко","устойчивость"]},"✅":{en:["check mark","yes","approved"],ru:["галочка","да","одобрено"]},"❌":{en:["cross mark","no","wrong"],ru:["крестик","нет","неправильно"]},"❎":{en:["negative cross","decline","cancel"],ru:["отрицательный крест","отказ","отмена"]},"➰":{en:["curly loop","infinity","twist"],ru:["извилистая петля","бесконечность","скрутка"]},"➿":{en:["double curly loop","loop","repeat"],ru:["двойная извилистая петля","петля","повтор"]},"〽️":{en:["part alternation","music","symbol"],ru:["знак чередования","музыка","символ"]},"✳️":{en:["eight-spoked asterisk","star","highlight"],ru:["восьмиконечная астериска","звезда","акцент"]},"✴️":{en:["eight-pointed star","shine","special"],ru:["восьмиконечная звезда","сияние","особый"]},"❇️":{en:["sparkle","highlight","shine"],ru:["сверкание","акцент","сияние"]},"©️":{en:["copyright","legal","rights"],ru:["авторское право","юридический","права"]},"®️":{en:["registered","trademark","brand"],ru:["зарегистрировано","торговая марка","бренд"]},"™️":{en:["trademark","brand","symbol"],ru:["торговая марка","бренд","символ"]},"🏁":{en:["checkered flag","finish line","racing"],ru:["шашечный флаг","финишная черта","гонки"]},"🚩":{en:["triangular flag","mark","warning"],ru:["треугольный флаг","метка","предупреждение"]},"🎌":{en:["crossed flags","celebration","Japan"],ru:["перекрещённые флаги","празднование","Япония"]},"🏴":{en:["black flag","protest","symbol"],ru:["чёрный флаг","протест","символ"]},"🏳️":{en:["white flag","surrender","peace"],ru:["белый флаг","капитуляция","мир"]},"🏳️‍🌈":{en:["rainbow flag","LGBTQ+","pride"],ru:["радужный флаг","ЛГБТК+","гордость"]},"🏳️‍⚧️":{en:["transgender flag","trans","pride"],ru:["трансгендерный флаг","транс","гордость"]},"🏴‍☠️":{en:["pirate flag","skull","danger"],ru:["пиратский флаг","череп","опасность"]},"🇺🇸":{en:["United States","USA","America"],ru:["Соединённые Штаты","США","Америка"]},"🇬🇧":{en:["United Kingdom","UK","Britain"],ru:["Соединённое Королевство","Великобритания","Британия"]},"🇯🇵":{en:["Japan","Japanese","Asia"],ru:["Япония","японский","Азия"]},"🇰🇷":{en:["South Korea","Korea","Asian"],ru:["Южная Корея","Корея","азиатский"]},"🇩🇪":{en:["Germany","Deutschland","Europe"],ru:["Германия","Германия","Европа"]},"🇨🇳":{en:["China","Chinese","Asia"],ru:["Китай","китайский","Азия"]},"🇧🇷":{en:["Brazil","Brasil","South America"],ru:["Бразилия","Бразилия","Южная Америка"]},"🇮🇳":{en:["India","Indian","Asia"],ru:["Индия","индийский","Азия"]},"🇫🇷":{en:["France","French","Europe"],ru:["Франция","французский","Европа"]},"🇪🇸":{en:["Spain","Spanish","Europe"],ru:["Испания","испанский","Европа"]},"🇮🇹":{en:["Italy","Italian","Europe"],ru:["Италия","итальянский","Европа"]},"🇷🇺":{en:["Russia","Russian","Europe"],ru:["Россия","русский","Европа"]},"🇨🇦":{en:["Canada","Canadian","North America"],ru:["Канада","канадский","Северная Америка"]},"🇦🇺":{en:["Australia","Aussie","Oceania"],ru:["Австралия","австралиец","Океания"]},"🇳🇿":{en:["New Zealand","Kiwi","Oceania"],ru:["Новая Зеландия","киви","Океания"]},"🇲🇽":{en:["Mexico","Mexican","Latin America"],ru:["Мексика","мексиканский","Латинская Америка"]},"🇦🇷":{en:["Argentina","Argentinian","South America"],ru:["Аргентина","аргентинский","Южная Америка"]},"🇵🇰":{en:["Pakistan","Pakistani","Asia"],ru:["Пакистан","пакистанский","Азия"]},"🇪🇬":{en:["Egypt","Egyptian","Africa"],ru:["Египет","египетский","Африка"]},"🇸🇪":{en:["Sweden","Swedish","Europe"],ru:["Швеция","шведский","Европа"]},"🇳🇴":{en:["Norway","Norwegian","Europe"],ru:["Норвегия","норвежский","Европа"]},"🇳🇱":{en:["Netherlands","Dutch","Europe"],ru:["Нидерланды","голландский","Европа"]},"🇨🇭":{en:["Switzerland","Swiss","Europe"],ru:["Швейцария","швейцарский","Европа"]},"🇹🇷":{en:["Turkey","Turkish","Eurasia"],ru:["Турция","турецкий","Евразия"]},"🇮🇩":{en:["Indonesia","Indonesian","Asia"],ru:["Индонезия","индонезийский","Азия"]},"🇸🇬":{en:["Singapore","Singaporean","Asia"],ru:["Сингапур","сингапурский","Азия"]},"🇮🇱":{en:["Israel","Israeli","Middle East"],ru:["Израиль","израильский","Ближний Восток"]},"🇵🇹":{en:["Portugal","Portuguese","Europe"],ru:["Португалия","португальский","Европа"]},"🇵🇱":{en:["Poland","Polish","Europe"],ru:["Польша","польский","Европа"]},"🇹🇭":{en:["Thailand","Thai","Asia"],ru:["Таиланд","тайский","Азия"]}},se={hslToHex(e,t,n){t/=100,n/=100;const r=(1-Math.abs(2*n-1))*t,o=r*(1-Math.abs(e/60%2-1)),a=n-r/2;let i,s,c;return e<60?(i=r,s=o,c=0):e<120?(i=o,s=r,c=0):e<180?(i=0,s=r,c=o):e<240?(i=0,s=o,c=r):e<300?(i=o,s=0,c=r):(i=r,s=0,c=o),i=Math.round(255*(i+a)),s=Math.round(255*(s+a)),c=Math.round(255*(c+a)),"#"+((1<<24)+(i<<16)+(s<<8)+c).toString(16).slice(1)},hexToHSL(e){3===(e=e.replace(/^#/,"")).length&&(e=e.split("").map((e=>e+e)).join(""));const t=parseInt(e.substring(0,2),16)/255,n=parseInt(e.substring(2,4),16)/255,r=parseInt(e.substring(4,6),16)/255,o=Math.max(t,n,r),a=Math.min(t,n,r);let i=0,s=0;const c=(o+a)/2;if(o!==a){const e=o-a;s=c>.5?e/(2-o-a):e/(o+a),i=o===t?60*((n-r)/e+(n<r?6:0)):o===n?60*((r-t)/e+2):60*((t-n)/e+4)}return{h:Math.round(i),s:100*s,l:100*c}},hexToHue(e){return this.hexToHSL(e).h},getLuminance(e){e=e.replace("#","");const t=parseInt(e.slice(0,2),16)/255,n=parseInt(e.slice(2,4),16)/255,r=parseInt(e.slice(4,6),16)/255,o=e=>e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4);return.2126*o(t)+.7152*o(n)+.0722*o(r)},contrastRatio(e,t){const n=this.getLuminance(e),r=this.getLuminance(t);return(Math.max(n,r)+.05)/(Math.min(n,r)+.05)}};function ce(e){const t=e.storageKey||"usernameColors";let n;try{const e=sessionStorage.getItem(t);n=e?JSON.parse(e):{}}catch(e){n={}}const r=e.hueRanges||[{min:0,max:360}],o=r.reduce(((e,t)=>e+(t.max-t.min)),0),a=Boolean(e.saturation),i=Boolean(e.lightness),s=e.minSaturation||40,c=e.maxSaturation||90,l=e.minLightness||55,d=e.maxLightness||80,u=c-s,m=new Set(Object.values(n)),p=new Set;function h(){let e=Math.floor(Math.random()*o);for(let t of r){const n=t.max-t.min;if(e<n)return t.min+e;e-=n}return r[0].min}return Object.values(n).forEach((e=>{try{p.add(se.hexToHue(e))}catch(e){}})),{getColor(t){if(!t){const t=a?parseInt(e.saturation,10):50;let n=i?parseInt(e.lightness,10):50;return se.hslToHex(0,t,n)}const r=t.trim().toLowerCase();if(n[r])return n[r];let c=null,g=0;for(;!c&&g<10;){let t;if(p.size>=o)t=h();else do{t=h()}while(p.has(t)&&p.size<o);const n=a?parseInt(e.saturation,10):Math.floor(Math.random()*u)+s;let r;if(i)r=parseInt(e.lightness,10),t>=210&&t<280&&r<65&&(r=65);else{let e=l;t>=210&&t<280&&(e=Math.max(l,65));const n=d-e;r=Math.floor(Math.random()*n)+e}const f=se.hslToHex(t,n,r);if(!m.has(f)){c=f,p.add(t);break}g++}if(!c){const t=h(),n=a?parseInt(e.saturation,10):Math.floor(Math.random()*u)+s;let r;if(i)r=parseInt(e.lightness,10),t>=210&&t<280&&r<65&&(r=65);else{let e=l;t>=210&&t<280&&(e=Math.max(l,65));const n=d-e;r=Math.floor(Math.random()*n)+e}c=se.hslToHex(t,n,r)}return n[r]=c,m.add(c),this.saveColors(),c},saveTimeout:null,saveColors(){this.saveTimeout&&clearTimeout(this.saveTimeout),this.saveTimeout=setTimeout((()=>{try{sessionStorage.setItem(t,JSON.stringify(n))}catch(e){}}),500)}}}const le=ce({storageKey:"usernameColors",minSaturation:40,maxSaturation:90,minLightness:55,maxLightness:80}),de=ce({storageKey:"mentionColors",saturation:"80",lightness:"60"});let ue=null;function me(){let e;do{e=S[Math.floor(Math.random()*S.length)]}while(e===ue);return ue=e,e}function pe(){const e=document.querySelector("#app-chat-container .chat-wrapper");if(!e)return;const t=document.querySelector("#app-chat-container"),n=e.offsetWidth<=780,r=e.offsetWidth<=380,o=e.offsetWidth<=340,a=t.classList.contains("maximized"),i=document.querySelector("#app-chat-container .user-list-container"),s=document.querySelector("#app-chat-container .message.system");let c=!1;if(i)if(n&&!a){i.style.position="absolute",i.style.height="100%",i.style.top="0",i.style.right="0",i.style.transition="transform 0.3s ease",i.style.zIndex="1001",i.style.transform="translateX(100%)",s&&s.style.setProperty("align-items","start","important");let l=document.querySelector("#app-chat-container .reveal-userlist-btn");if(!l){function d(e){i.contains(e.target)||e.target===l||(i.style.transform="translateX(100%)",l.classList.remove("shown-userlist"),l.classList.add("hidden-userlist"),c=!1,document.removeEventListener("click",d,!0))}l=document.createElement("button"),l.className="reveal-userlist-btn hidden-userlist",l.textContent="📋",t.appendChild(l),l.addEventListener("click",(e=>{e.stopPropagation(),c||(i.style.transform="translateX(0)",l.classList.remove("hidden-userlist"),l.classList.add("shown-userlist"),c=!0,setTimeout((()=>{document.addEventListener("click",d,!0)}),10))}))}}else{i.style.position="",i.style.height="",i.style.top="",i.style.right="",i.style.transform="",i.style.zIndex="",s&&s.style.removeProperty("align-items");const u=document.querySelector("#app-chat-container .reveal-userlist-btn");u&&u.remove()}document.querySelectorAll("#app-chat-container .message").forEach((e=>{e.style.flexDirection=n&&!a?"column":"row",e.style.marginBottom=n&&!a?"0.4em":"0"})),document.querySelectorAll("#app-chat-container .video-container").forEach((e=>{o?(e.style.transformOrigin="left",e.style.transform="scale(0.8)"):r?(e.style.transformOrigin="left",e.style.transform="scale(0.9)"):(e.style.transformOrigin="",e.style.transform="")}))}function he(){const e=document.getElementById("app-chat-container"),t=document.querySelector(".chat-toggle-button");if(!e||!t)return;const n=ge(),r=window.innerWidth,o=window.innerHeight,a=getComputedStyle(document.documentElement),i=parseInt(a.getPropertyValue("--min-chat-width"))||250,s=parseInt(a.getPropertyValue("--min-chat-height"))||200;e.style.width=Math.min(r,Math.max(i,n.width))+"px",e.style.height=Math.min(o,Math.max(s,n.height))+"px",e.style.left=ve(n.left,0,r-e.offsetWidth)+"px",n.floating?(e.style.top=ve(n.top,0,o-e.offsetHeight)+"px",e.style.bottom="",e.classList.add("floating-chat"),e.style.display=n.isVisible?"flex":"none",e.style.opacity=n.isVisible?"1":"0",t.innerHTML=n.isVisible?Z:ee):(e.style.bottom="0",e.style.top="",e.classList.remove("floating-chat"),e.classList.remove("visible-chat","hidden-chat"),e.classList.add(n.isVisible?"visible-chat":"hidden-chat"),t.innerHTML=n.isVisible?Z:ee),pe()}function ge(){const e=localStorage.getItem("chatState"),t={height:300,width:Math.min(window.innerWidth,600),left:0,floating:!1,top:window.innerHeight-300,isVisible:!0,fontSizeMultiplier:1};return e?{...t,...JSON.parse(e)}:t}function fe(e){const t=document.getElementById("app-chat-container"),n=document.getElementById("message-input");if(!t)return;t.style.fontSize=`${e}em`,n&&(n.style.fontSize="1em");be({...ge(),fontSizeMultiplier:e})}function ye(){fe(ge().fontSizeMultiplier)}function be(e){localStorage.setItem("chatState",JSON.stringify(e))}function ve(e,t,n){return Math.min(Math.max(e,t),n)}function we(e){return"string"!=typeof e?e:e.replace(/^\d+#/,"")}function xe(e){if(!e)return null;const t=e.split("/");if(t.length<2)return null;return t[1].split("#")[0]}function ke(e){return e?e.includes("#")?e.split("#")[1]:e.replace(/^\d+#/,""):"Unknown"}function Ee(){Object.entries(L.bigImageEvents).forEach((([e,t])=>{document.removeEventListener(e,t)}))}function Ce(e,t,n){e&&(e.offsetHeight,e.style.transition="opacity 0.3s ease",e.style.opacity="show"===t?n:"0","hide"===t&&e.addEventListener("transitionend",(()=>{"0"===e.style.opacity&&e.parentNode&&e.parentNode.removeChild(e)}),{once:!0}))}const Se=e=>{try{const{hostname:t}=new URL(e),n=t.toLowerCase().split(".").slice(-2).join(".");return{isTrusted:j.includes(n),domain:n}}catch(t){return console.error("Error in isTrustedDomain:",t.message),{isTrusted:!1,domain:e}}};function Le(e){return/^https?:\/\//.test(e)&&/%[0-9A-Fa-f]{2}/.test(e)}function je(e){const[t]=e.split("#");return decodeURIComponent(t).replace(/ /g,"_")}function Ie(){const e=document.getElementById("messages-panel");if(!e)return;const t=localStorage.getItem("klavoauth");let n="";try{if(t){const e=JSON.parse(t);e&&e.username&&(n=ke(e.username))}}catch(e){console.error("Error parsing auth data:",e)}if(!n)return;const r=[n],o=new WeakSet;e.querySelectorAll(".message-text:not(.processed-mention-word)").forEach((e=>{const t=document.createTreeWalker(e,NodeFilter.SHOW_TEXT,{acceptNode:e=>{if(o.has(e))return NodeFilter.FILTER_SKIP;return e.parentElement.closest(".mention, .time, .username")?NodeFilter.FILTER_SKIP:NodeFilter.FILTER_ACCEPT}}),n=[];let a;for(;a=t.nextNode();)n.push(a);n.length>0&&(n.forEach((e=>{o.has(e)||(!function(e,t){const n=/(@?[\wа-яА-ЯёЁ'-]+)|[\s]+|[^@\s\wа-яА-ЯёЁ'-]+/gu,r=e.textContent.match(n)||[],o=document.createDocumentFragment();r.forEach((e=>{if(t.some((t=>0===t.localeCompare(e,void 0,{sensitivity:"accent"})))){const t=document.createElement("span");t.className="mention",e.split("").forEach((e=>{const n=document.createElement("span");n.style.color=de.getColor(e),n.textContent=e,t.appendChild(n)})),o.appendChild(t)}else o.appendChild(document.createTextNode(e))})),e.parentNode.replaceChild(o,e)}(e,r),o.add(e))})),e.classList.add("processed-mention-word"))}))}const Me=600;function $e(){const e=document.getElementById("messages-panel");if(!e)return;e.scrollHeight-e.scrollTop-e.clientHeight<=Me&&(e.scrollTop=e.scrollHeight)}function Te(e,t={}){const n=document.querySelector(".chat-drag-area");if(!n)return;const r=n.querySelector(".chat-dynamic-alert");r&&r.parentNode===n&&n.removeChild(r);const o={type:"info",duration:3e3,...t},a={info:"#2196F3",warning:"#FF9800",error:"#F44336",success:"#4CAF50"},i=document.createElement("div");i.className="chat-dynamic-alert",i.innerHTML=e,i.style.cssText=`\n    position: absolute;\n    white-space: nowrap;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    color: ${a[o.type]||a.info};\n    padding: 5px 10px;\n    border-radius: 3px;\n    z-index: 1000;\n    font-family: "Montserrat", sans-serif;\n    font-size: 10px;\n    font-weight: 500;\n    opacity: 0;\n  `,n.appendChild(i),requestAnimationFrame((()=>{i.style.transition="all 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55)",i.style.opacity="1",i.style.transform="translate(-50%, -50%)",setTimeout((()=>{i.style.transition="transform 0.05s ease-in-out",[{x:5,delay:0},{x:-7,delay:50},{x:9,delay:100},{x:-6,delay:150},{x:4,delay:200},{x:-3,delay:250},{x:0,delay:300}].forEach((e=>{setTimeout((()=>{i.style.transform=`translate(calc(-50% + ${e.x}px), -50%)`}),e.delay)}))}),300),setTimeout((()=>{i.style.transition="opacity 0.3s ease-in-out",i.style.opacity="0",setTimeout((()=>{i&&i.parentNode===n&&n.removeChild(i)}),300)}),o.duration)}))}function ze(){const e=document.getElementById("app-chat-container"),t=document.getElementById("message-input");return!(!t||!e||"none"===e.style.display)&&(t.focus(),!0)}async function Ae(e){const t=`https://klavogonki.ru/api/profile/search-users?query=${encodeURIComponent(e)}`;try{const n=await async function(e){const t=await fetch(e);if(!t.ok)throw new Error(`Failed to fetch ${e}`);return t.json()}(t);if(!n.all?.length)throw new Error(`User ${e} not found.`);const r=n.all.find((t=>t.login===e));if(!r)throw new Error(`Exact match for user ${e} not found.`);return r.id}catch(t){return Te(`Could not find user "${e}"`,{type:"error",duration:5e3}),null}}const Pe={isPrivateMode:!1,targetUsername:null,targetId:null,fullJid:null,async setPrivateTarget(e){if(!e)return this.exitPrivateMode(),!1;try{const t=await Ae(e);return!!t&&(this.isPrivateMode=!0,this.targetUsername=e,this.targetId=t,this.fullJid=`${t}#${e}@jabber.klavogonki.ru/web`,!0)}catch(e){return console.error("Error setting private target:",e),!1}},exitPrivateMode(){this.isPrivateMode=!1,this.targetUsername=null,this.targetId=null,this.fullJid=null}};async function Ne(e){if(!e)return;const t=e.value,n=/^\/pm\s+([\wа-яА-ЯёЁ\-\.\_\+]+)\s/,r=t.match(n);if(r){const o=r[1];await Pe.setPrivateTarget(o)?(!function(e){const t=document.getElementById("message-input");Pe.isPrivateMode&&Pe.targetUsername!==e&&He();if(t.classList.contains("private-mode")&&Pe.targetUsername===e)Pe.targetUsername===e&&(t.placeholder=`️PM to ➡ ${e}`,Te(`Private chat with ${e} activated`,{type:"warning",duration:3e3}));else{t.classList.add("private-mode"),t.placeholder=`PM to ➡ ${e}`;let n=document.querySelector(".private-mode-exit");if(!n){n=document.createElement("span"),n.className="private-mode-exit",n.addEventListener("click",(()=>{He(),t.focus()}));t.parentElement.insertBefore(n,t.nextSibling)}n.innerHTML="🔒",n.title="Exit private mode",n.addEventListener("mouseenter",(()=>{n.innerHTML="🔓"})),n.addEventListener("mouseleave",(()=>{n.innerHTML="🔒"})),Te(`Private chat with ${e} activated`,{type:"warning",duration:3e3}),Pe.isPrivateMode=!0,Pe.targetUsername=e}}(o),e.value=t.replace(n,"")):(Te(`Could not find user "${o}"`,{type:"error",duration:3e3}),He())}else/^\/exit\s*$/.test(t)&&(He(),e.value="")}function He(){const e=document.getElementById("message-input");if(e.classList.contains("private-mode")){e.classList.remove("private-mode"),e.placeholder="";const t=document.querySelector(".private-mode-exit");t&&t.remove(),Pe.exitPrivateMode(),Te("Exited private chat mode",{type:"success",duration:3e3})}}let Be=null,Re=null,qe=null;const De=document.createElement("canvas").getContext("2d");let Oe,Ue=!1,_e=0;function Fe(e){let t=e>_e?`${e} ➡`:e<_e?`⬅ ${e}`:`${e}`;qe.textContent=t,function(e){if(!qe)return void console.error("lengthPopup is not defined");let t,n=100,r=50;0===e?(t=200,n=20,r=50):t=e<=90?120:e<=100?120-(e-90)/10*60:e<=190?60:e<=200?60-(e-190)/10*20:e<=250?40:e<=300?40-(e-250)/50*40:0;const o=`hsl(${t}, ${n}%, ${r}%)`,a=`hsl(${t}, ${n}%, ${Math.max(r-(e>250?35:30),8)}%)`,i=`hsla(${t}, ${n}%, ${r}%, 0.1)`;qe.style.setProperty("color",o,"important"),qe.style.setProperty("background-color",a,"important"),qe.style.setProperty("border",`1px solid ${i}`,"important"),qe.style.setProperty("border-radius","0.4em","important")}(e),_e=e}function Je(e){Ue!==e&&(qe.classList.toggle("bounce-in",e),qe.classList.toggle("bounce-out",!e),Ue=e,e||setTimeout((()=>qe.classList.remove("bounce-out")),500))}function Ke(){clearTimeout(Oe),Fe(Be.value.length),function(e){if(!Be)return void console.error("chatField is not set.");const t=getComputedStyle(Be);De.font=`${t.fontWeight} ${t.fontSize} ${t.fontFamily}`;const n=De.measureText(e).width,r=Be.offsetLeft+n+5,o=Be.offsetLeft+Be.offsetWidth-qe.offsetWidth;qe.style.left=`${Math.min(r,o)}px`}(Be.value),Je(!0),Oe=setTimeout((()=>Je(!1)),1e3)}function We(e){"Enter"===e.key&&(Fe(0),Object.assign(qe.style,{left:"0px",color:"hsl(200, 20%, 50%)"}),Je(!0),Oe=setTimeout((()=>Je(!1)),1e3))}function Ye(e){return e.replace(/\n/g,"").replace(/\s+/g," ").replace(/>\s+</g,"><").trim()}function Xe(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)||"ontouchstart"in window}class Ve{constructor(e="user-list"){this.container=document.getElementById(e),this.activeUsers=new Map,this.isFirstLoad=!0,this.avatarCache=this.loadAvatarCache(),this.cacheDate=(new Date).toDateString(),this.roleIcons={visitor:"🐥",participant:"🗿",moderator:"⚔️️"},this.rolePriority={moderator:1,participant:2,visitor:3},this.setupEventListeners()}loadAvatarCache(){try{const e=localStorage.getItem("userAvatarCache");if(e){const t=JSON.parse(e);return t.date===(new Date).toDateString()?(console.log("🗃️ Loaded avatar cache from localStorage"),t.avatars||{}):(console.log("🗃️ Avatar cache expired (new day), creating fresh cache"),{})}}catch(e){console.error("Error loading avatar cache:",e)}return{}}saveAvatarCache(){try{localStorage.setItem("userAvatarCache",JSON.stringify({date:this.cacheDate,avatars:this.avatarCache}))}catch(e){console.error("Error saving avatar cache:",e)}}setupEventListeners(){this.container.addEventListener("click",(e=>{if(e.target.classList.contains("username-clickable")){const t=e.target.getAttribute("data-user-id");if(t)if(e.ctrlKey){const t=e.target.textContent.trim(),n=document.getElementById("message-input");n.value=`/pm ${t} `,Ne(n),n.focus()}else{const e=t.split("/")[1].split("#")[0];window.location.href=`https://klavogonki.ru/u/#/${e}/`}}if(e.target.closest(".game-indicator")){const t=e.target.closest(".game-indicator").getAttribute("data-game-id");t&&(e.stopPropagation(),window.location.href=`https://klavogonki.ru/g/?gmid=${t}`)}}))}async updatePresence(e){const t=(new DOMParser).parseFromString(e,"text/xml").getElementsByTagName("presence");if(e.includes('<presence id="initialChatLoad"'))return console.log("🔄 Initial room join detected, requesting full roster"),void this.requestFullRoster();let n=!1;const r=[],o=[];for(let e=0;e<t.length;e++){const a=t[e],i=a.getAttribute("from"),s=a.getAttribute("type");if(!i||!i.includes("[email protected]/"))continue;const c=i.split("/").pop();if(!c)continue;if("клавобот"===c.toLowerCase()||i.toLowerCase().includes("#клавобот"))continue;if("unavailable"===s){if(this.activeUsers.has(i)){const e=this.activeUsers.get(i);xe(i),ke(e.login);this.isFirstLoad,this.activeUsers.delete(i),n=!0}continue}const l=this.activeUsers.get(i)||{},d=xe(i),u=this.avatarCache[d];let m={jid:i,login:c,color:"#777",usernameColor:le.getColor(ke(c)),role:"participant",gameId:null,avatar:null};const p=a.getElementsByTagName("x");let h=!1;for(let e=0;e<p.length;e++){const t=p[e].getAttribute("xmlns");if("klavogonki:userdata"===t){const t=p[e].getElementsByTagName("user")[0];if(t){const e=t.getElementsByTagName("login")[0];e&&e.textContent&&(m.login=e.textContent,m.usernameColor=le.getColor(ke(m.login)));const n=t.getElementsByTagName("avatar")[0];n&&n.textContent&&(m.avatar=n.textContent,h=!0);const r=t.getElementsByTagName("moderator")[0];r&&"1"===r.textContent&&(m.role="moderator")}const n=p[e].getElementsByTagName("game_id")[0];n&&n.textContent&&(m.gameId=n.textContent)}if("http://jabber.org/protocol/muc#user"===t){const t=p[e].getElementsByTagName("item")[0];if(t){const e=t.getAttribute("role");e&&"moderator"!==m.role&&(m.role=e)}}}!h&&l&&l.avatar&&(m.avatar=l.avatar),!m.avatar&&u&&u.hasAvatar&&(m.avatar=u.avatarUrl);ke(m.login);this.activeUsers.has(i)?JSON.stringify(l)!==JSON.stringify(m)&&(this.activeUsers.set(i,m),n=!0,o.push(i)):(this.isFirstLoad,this.activeUsers.set(i,m),n=!0,r.push(i))}n&&this.updateUI(r,o)}updateUI(e=[],t=[]){const n=new Map;this.container.querySelectorAll(".user-item").forEach((e=>{n.set(e.getAttribute("data-jid"),e)}));const r=Array.from(this.activeUsers.values()).sort(((e,t)=>{const n=this.rolePriority[e.role]-this.rolePriority[t.role];return 0!==n?n:ke(e.login).localeCompare(ke(t.login))})),o=document.createDocumentFragment();r.forEach((e=>{let t=n.get(e.jid);const r=xe(e.jid),a=ke(e.login);if(t){if(!t.querySelector(".avatar-container")){const n=document.createElement("span");n.className="avatar-container",this.setUserAvatar(n,e,r,a),t.insertBefore(n,t.firstChild)}n.delete(e.jid);const o=t.querySelector(".role"),i=this.roleIcons[e.role]||"👤";o&&o.textContent!==i&&(o.textContent=i,o.classList.contains(e.role)||(o.className=`role ${e.role}`));const s=t.querySelector(".username");s&&s.style.color!==e.usernameColor&&(s.style.color=e.usernameColor)}else{t=document.createElement("div"),t.classList.add("user-item"),t.setAttribute("data-jid",e.jid);const n=this.roleIcons[e.role]||"👤",o=document.createElement("span");o.className="avatar-container",this.setUserAvatar(o,e,r,a);const i=document.createElement("div");i.className="user-info",i.innerHTML=`\n          <div class="username" style="color: ${e.usernameColor}">\n            <span class="username-clickable" data-user-id="${e.jid}">${a}</span>\n            <span class="role ${e.role}">${n}</span>\n          </div>\n        `,t.appendChild(o),t.appendChild(i)}this.updateGameIndicator(t,e),o.appendChild(t)})),this.container.innerHTML="",this.container.appendChild(o),n.forEach((e=>{e&&e.parentNode&&e.remove()})),this.isFirstLoad||e.forEach((e=>{const t=this.container.querySelector(`.user-item[data-jid="${e}"]`);t&&t.parentNode&&oe(t)})),this.isFirstLoad&&(this.isFirstLoad=!1)}setUserAvatar(e,t,n,r){const o=this.avatarCache[n];if(t.avatar){const t=`${x}/storage/avatars/${n}_big.png`,a=document.createElement("img");a.className="user-avatar image-avatar",a.src=t,a.alt=`${r}'s avatar`,a.addEventListener("error",(()=>{const t=o?.emoji||me();e.innerHTML="";const r=document.createElement("span");r.className="user-avatar svg-avatar",r.textContent=t,e.appendChild(r),this.avatarCache[n]={hasAvatar:!1,emoji:t},this.saveAvatarCache()})),a.addEventListener("load",(()=>{!o||o.hasAvatar,this.avatarCache[n]={hasAvatar:!0,avatarUrl:t},this.saveAvatarCache()})),e.appendChild(a)}else if(o)if(o.hasAvatar){const t=document.createElement("img");t.className="user-avatar image-avatar",t.src=o.avatarUrl,t.alt=`${r}'s avatar`,t.addEventListener("error",(()=>{const t=me();e.innerHTML="";const r=document.createElement("span");r.className="user-avatar svg-avatar",r.textContent=t,e.appendChild(r),this.avatarCache[n]={hasAvatar:!1,emoji:t},this.saveAvatarCache()})),e.appendChild(t)}else{const t=document.createElement("span");t.className="user-avatar svg-avatar",t.textContent=o.emoji,e.appendChild(t),this.avatarCache[n]&&this.avatarCache[n].hasEmoji||(this.avatarCache[n].hasEmoji=!0,this.saveAvatarCache())}else{const t=`${x}/storage/avatars/${n}_big.png`,o=document.createElement("img");o.className="user-avatar image-avatar",o.src=t,o.alt=`${r}'s avatar`,o.addEventListener("error",(()=>{const t=me();e.innerHTML="";const o=document.createElement("span");o.className="user-avatar svg-avatar",o.textContent=t,e.appendChild(o),console.log(`😊 Using emoji avatar for User: ${r} ID: (${n}): ${t}`),this.avatarCache[n]={hasAvatar:!1,emoji:t,hasEmoji:!0},this.saveAvatarCache()})),o.addEventListener("load",(()=>{console.log(`🖼️ Using image avatar for User: ${r} ID: (${n})`),this.avatarCache[n]={hasAvatar:!0,avatarUrl:t},this.saveAvatarCache()})),e.appendChild(o)}}updateGameIndicator(e,t){let n=e.querySelector(".game-indicator");if(t.gameId){if(!n||n.getAttribute("data-game-id")!==t.gameId){const r=`<span class="game-indicator" title="${t.gameId}" data-game-id="${t.gameId}">\n                                    <span class="traffic-icon">🚦</span>\n                                  </span>`;if(n)n.outerHTML=r;else{e.querySelector(".username").insertAdjacentHTML("beforeend",r)}}}else n&&n.parentNode&&n.remove()}async requestFullRoster(){console.log("📑 Would request full roster here (using existing data for now)"),this.updateUI()}}class Qe{constructor(){this.selected=new Set,this.isDragging=!1,this.toggleBtn=null,this.longPressTimer=null,this.longPressDuration=500,this.touchStartX=0,this.touchStartY=0,this.isMobile=Xe(),this.init()}init(){this.attachEvents(),this.updateDeletedMessages(),this.renderToggle()}attachEvents(){document.addEventListener("mousedown",(e=>{const t=e.target.closest(".messages-panel .message");t&&2===e.button&&t&&this.handleSelection(e.target,t,e.ctrlKey)})),document.addEventListener("mouseup",(()=>this.isDragging=!1)),document.addEventListener("mousemove",(e=>{if(!this.isDragging)return;const t=e.target.closest(".messages-panel .message");t&&this.toggleSelect(t,!0,"message-mode")})),document.addEventListener("contextmenu",(e=>{const t=e.target.closest(".messages-panel .message");t&&(e.preventDefault(),this.showDeleteButton(e,t))})),this.isMobile&&(document.addEventListener("touchstart",(e=>{const t=e.target.closest(".messages-panel .message");t&&(this.touchStartX=e.touches[0].clientX,this.touchStartY=e.touches[0].clientY,this.longPressTimer=setTimeout((()=>{this.handleSelection(e.target,t,!1),this.showDeleteButton({clientX:this.touchStartX,clientY:this.touchStartY,preventDefault:()=>{}},t),navigator.vibrate&&navigator.vibrate(50)}),this.longPressDuration))})),document.addEventListener("touchmove",(e=>{this.isDragging&&e.preventDefault();const t=e.touches[0].clientX,n=e.touches[0].clientY,r=Math.abs(t-this.touchStartX),o=Math.abs(n-this.touchStartY);(r>10||o>10)&&this.longPressTimer&&(clearTimeout(this.longPressTimer),this.longPressTimer=null)}),{passive:!1}),document.addEventListener("touchend",(()=>{this.longPressTimer&&(clearTimeout(this.longPressTimer),this.longPressTimer=null)})))}handleSelection(e,t,n){const r=e.closest(".time"),o=e.closest(".username");r?this.handleTimeSelection(t,n):o?this.handleUsernameSelection(o):(this.isDragging=!0,this.toggleSelect(t,!0,"message-mode"))}handleTimeSelection(e,t){const n=Array.from(document.querySelectorAll(".messages-panel .message")),r=n.indexOf(e);if(-1!==r)if(t)n.slice(r).forEach((e=>{this.toggleSelect(e,!0,"time-mode"),e.classList.add("time-mode")}));else{const t=e.querySelector(".username");if(!t)return;const o=t.textContent.trim();n.slice(r).forEach((e=>{const t=e.querySelector(".username");t&&t.textContent.trim()===o&&(this.toggleSelect(e,!0,"time-mode"),e.classList.add("time-mode"))}))}}handleUsernameSelection(e){const t=e.textContent.trim();document.querySelectorAll(".messages-panel .message").forEach((e=>{const n=e.querySelector(".username");n&&n.textContent.trim()===t&&(this.toggleSelect(e,!0,"username-mode"),e.classList.add("username-mode"))}))}toggleSelect(e,t,n="message-mode"){if(!e)return;e.classList.toggle("selected-message",t),t?"message-mode"===n&&e.classList.add("message-mode"):e.classList.remove("username-mode","time-mode","message-mode");const r=Ge(e);t?this.selected.add(r):this.selected.delete(r)}showDeleteButton(e,t){const n=document.querySelector(".delete-btn");n&&n.remove();const r=document.createElement("button");r.className="delete-btn",this.isMobile&&r.classList.add("mobile-delete-btn"),r.textContent="Delete",r.addEventListener("touchstart",(e=>{e.stopPropagation()})),document.body.append(r);const{offsetWidth:o,offsetHeight:a}=r;if(r.remove(),Object.assign(r.style,{position:"fixed",top:e.clientY-a/2+"px",left:e.clientX-o/2+"px"}),r.onclick=()=>this.deleteSelectedMessages(r),this.isMobile){const e=t=>{r.contains(t.target)||(this.clearSelection(),r.remove(),document.removeEventListener("touchstart",e))};document.addEventListener("touchstart",e),r.outsideTapHandler=e}let i;r.addEventListener("mouseenter",(()=>{i&&clearTimeout(i)})),r.addEventListener("mouseleave",(()=>{i=setTimeout((()=>{r.remove(),this.clearSelection()}),1e3)})),document.body.append(r)}deleteSelectedMessages(e){document.querySelectorAll(".selected-message").forEach((e=>{e&&(e.classList.remove("selected-message","username-mode","time-mode","message-mode"),0===e.classList.length&&e.removeAttribute("class"))})),this.storeDeleted([...this.selected]),e.remove(),this.isMobile&&e.outsideTapHandler&&document.removeEventListener("touchstart",e.outsideTapHandler),this.selected.clear(),this.updateDeletedMessages(),this.renderToggle()}clearSelection(){document.querySelectorAll(".selected-message").forEach((e=>{e&&(e.classList.remove("selected-message","username-mode","time-mode","message-mode"),0===e.classList.length&&e.removeAttribute("class"))})),this.selected.clear()}storeDeleted(e){const t=new Set(JSON.parse(localStorage.getItem("deletedChatMessagesContent")||"[]"));e.forEach((e=>t.add(e))),localStorage.setItem("deletedChatMessagesContent",JSON.stringify([...t]))}updateDeletedMessages(){const e=new Set(JSON.parse(localStorage.getItem("deletedChatMessagesContent")||"[]")),t=document.querySelectorAll(".messages-panel .message");0!==t.length&&(t.forEach((t=>{if(!t)return;const n=Ge(t);t.classList.remove("shown-message"),t.classList.toggle("hidden-message",e.has(n))})),localStorage.setItem("deletedChatMessagesContent",JSON.stringify([...e])))}renderToggle(){if(!(JSON.parse(localStorage.getItem("deletedChatMessagesContent")||"[]").length>0))return void(this.toggleBtn&&(this.toggleBtn.remove(),this.toggleBtn=null));const e=document.querySelector(".messages-panel");if(e&&!this.toggleBtn){if(this.toggleBtn=document.createElement("button"),this.toggleBtn.className="toggle-button toggle-hidden",this.toggleBtn.textContent="Show",this.toggleBtn.onclick=e=>{if(e.ctrlKey)return void this.restoreAllMessages();const t="Show"===this.toggleBtn.textContent,n=JSON.parse(localStorage.getItem("deletedChatMessagesContent")||"[]");document.querySelectorAll(".messages-panel .message").forEach((e=>{if(!e)return;const r=Ge(e);n.includes(r)&&(e.classList.toggle("hidden-message",!t),e.classList.toggle("shown-message",t))})),t?(this.toggleBtn.textContent="Hide",this.toggleBtn.classList.remove("toggle-hidden"),this.toggleBtn.classList.add("toggle-shown")):(this.toggleBtn.textContent="Show",this.toggleBtn.classList.remove("toggle-shown"),this.toggleBtn.classList.add("toggle-hidden"))},this.isMobile){let e,t=!1;this.toggleBtn.addEventListener("touchstart",(n=>{this.touchStartX=n.touches[0].clientX,this.touchStartY=n.touches[0].clientY,t=!1,e=setTimeout((()=>{t=!0,this.restoreAllMessages(),navigator.vibrate&&navigator.vibrate(50)}),this.longPressDuration)})),this.toggleBtn.addEventListener("touchmove",(t=>{const n=t.touches[0].clientX,r=t.touches[0].clientY,o=Math.abs(n-this.touchStartX),a=Math.abs(r-this.touchStartY);(o>10||a>10)&&clearTimeout(e)})),this.toggleBtn.addEventListener("touchend",(()=>{clearTimeout(e),t&&this.toggleBtn.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation()}),{once:!0})}))}e.append(this.toggleBtn)}}restoreAllMessages(){document.querySelectorAll(".messages-panel .message").forEach((e=>{e&&e.classList.remove("hidden-message","shown-message")})),localStorage.setItem("deletedChatMessagesContent",JSON.stringify([])),this.selected.clear(),this.updateDeletedMessages(),this.renderToggle()}}function Ge(e){if(!e)return"";if(e.dataset.messageId)return e.dataset.messageId;let t=Array.from(e.childNodes).map((e=>e?e.nodeType===Node.TEXT_NODE||e.classList?.contains("username")?e.textContent.trim():"A"===e.tagName?e.href:"IMG"===e.tagName?e.title.trim():"IFRAME"===e.tagName?e.src.trim():"":"")).join("");return t||(t="msg-"+Math.random().toString(36).substring(2,7)),e.dataset.messageId=t,t}class Ze{constructor(e="messages-panel",t=""){this.panel=document.getElementById(e),this.messages=[],this.messageIdCounter=0,this.currentUsername=t,this.sentMessageTexts=new Set,this.processedMessageIds=new Set,this.chatHistory=new Map,this.initialLoadComplete=!1,this.chatRemover=new Qe}processMessages(e){if(!e||"string"!=typeof e)return;const t=(new DOMParser).parseFromString(e,"text/xml").getElementsByTagName("message");let n=!1;Array.from(t).forEach((e=>{const t=e.getElementsByTagName("body")[0];if(!t||!t.textContent)return;const r=t.textContent.trim();if("This room is not anonymous"===r)return;const o=e.getAttribute("from"),a=we(o&&o.split("#")[1]?.split("@")[0]||"unknown"),i=`<${a}>${r}`;if(this.processedMessageIds.has(i))return;let s=(new Date).toISOString();const c=e.getElementsByTagName("delay");c.length&&c[0].getAttribute("stamp")&&(s=c[0].getAttribute("stamp"));const l=e.getAttribute("to"),d="chat"===e.getAttribute("type");let u=null;d&&l&&(u=l.split("#")[1]?.split("@")[0]||l,u=we(u));const m={id:i,from:a,text:r,timestamp:s,isPrivate:d,recipient:u,pending:!1};this.messages.push(m),this.chatHistory.set(i,m),this.processedMessageIds.add(i),n=!0})),n&&this.updatePanel()}addSentMessage(e,t={}){this.sentMessageTexts.add(e);const n=`<${this.currentUsername}>${e}`,r={id:n,from:this.currentUsername,text:e,timestamp:(new Date).toISOString(),isPrivate:t.isPrivate||!1,recipient:t.recipient||null,pending:t.pending||!1};if(!this.processedMessageIds.has(n)){if(this.messages.push(r),this.chatHistory.set(n,r),this.processedMessageIds.add(n),this.updatePanel(),this.sentMessageTexts.size>20){const e=Array.from(this.sentMessageTexts);for(let t=0;t<e.length-20;t++)this.sentMessageTexts.delete(e[t])}return n}}updatePendingStatus(e,t){const n=this.chatHistory.get(e);n&&(n.pending=t,this.updatePanel())}updatePanel(){if(!this.panel)return;this.messages.sort(((e,t)=>new Date(e.timestamp)-new Date(t.timestamp)));const e=new Set(Array.from(this.panel.querySelectorAll(".message")).map((e=>e.getAttribute("data-message-id"))));let t=!1;this.messages.forEach((n=>{if(!e.has(n.id)){const e=new Date(n.timestamp).toLocaleTimeString("en-GB",{hour12:!1}),r=we(n.from),o=le.getColor(r),a=document.createElement("div");a.className="message",n.isPrivate&&(a.classList.add("private-message"),a.classList.add(n.from===this.currentUsername?"sent":"received"),n.recipient&&a.setAttribute("data-recipient",n.recipient)),n.text.startsWith("/me ")&&(a.classList.add("system"),n.text=`${n.from} ${n.text.substring(n.text.indexOf(" ")+1)}`),n.isSystem&&a.classList.add("system"),a.setAttribute("data-message-id",n.id);const i=document.createElement("div");i.className="message-info";let s=n.from;n.isPrivate&&(s=n.from===this.currentUsername&&n.recipient?`→ ${n.recipient}`:`${n.from} →`),i.innerHTML=`\n          <span class="time">${e}</span>\n          <span class="username" style="color: ${o}">${s}</span>\n        `;const c=document.createElement("div");if(c.className="message-text",c.innerHTML=(e=>{let t=0,n=[];return e=(e=e.replace(/(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gi,(e=>(n.push(e),`___URL${t++}___`)))).replace(/:(\w+):/g,((e,t)=>`<img src="https://klavogonki.ru/img/smilies/${t}.gif" alt="${t}" />`)).replace(/(\p{Emoji_Presentation}|\p{Emoji}\uFE0F)/gu,'<span class="emoji-adjuster">$&</span>'),n.forEach(((t,n)=>{if(Le(t)){const r=je(t);e=e.replace(`___URL${n}___`,`<a class="decoded" href="${t}" target="_blank">${r}</a>`)}else e=e.replace(`___URL${n}___`,`<a href="${t}" target="_blank">${t}</a>`)})),e})(n.text),n.pending){const e=document.createElement("span");e.className="pending-emoji",e.textContent=" ⏱️",c.appendChild(e)}a.appendChild(i),a.appendChild(c),this.panel.appendChild(a),this.currentUsername&&n.text.includes(this.currentUsername)&&(t=!0)}})),this.addDelegatedClickListeners(),Ie(this.currentUsername),requestAnimationFrame((()=>{$e()})),this.initialLoadComplete&&t&&function(){const e=new Audio("https://github.com/VimiummuimiV/KG_Chat_Application/raw/refs/heads/main/src/sounds/notification-pluck-on.mp3");e.volume=1,e.play()}(),this.initialLoadComplete||(this.initialLoadComplete=!0),this.chatRemover&&(this.chatRemover.updateDeletedMessages(),this.chatRemover.renderToggle())}addDelegatedClickListeners(){this.panel._delegatedClickAttached||(this.panel.addEventListener("click",(e=>{const t=e.target.closest(".username");if(t&&this.panel.contains(t)){let n=t.textContent.trim();n.includes("→")&&(n=n.startsWith("→")?n.replace("→","").trim():n.split("→")[0].trim());const r=document.getElementById("message-input");if(e.ctrlKey)r.value=`/pm ${n} `,Ne(r);else{const e=`${n}, `;r.value.includes(e)||(r.value+=e)}r.focus()}const n=e.target.closest(".time");if(n&&this.panel.contains(n)){const e=function(e){const t=180- -(new Date).getTimezoneOffset(),[n,r,o]=e.split(":").map(Number);let a=60*n+r+t;a=(a%1440+1440)%1440;const i=a%60;return`${Math.floor(a/60).toString().padStart(2,"0")}:${i.toString().padStart(2,"0")}:${o.toString().padStart(2,"0")}`}(n.textContent.trim()),t=`https://klavogonki.ru/chatlogs/${new Intl.DateTimeFormat("en-CA").format(new Date)}.html#${e}`;window.open(t,"_blank")}})),this.panel._delegatedClickAttached=!0)}getChatHistory(){return Array.from(this.chatHistory.values())}refreshMessages(e=!1){const t="connection-status",n=e?"Chat connection established. ✓":"Chat connection lost. Reconnecting...";let r=this.chatHistory.get(t);r?(r.text=n,r.timestamp=(new Date).toISOString()):(r={id:t,from:"System",text:n,timestamp:(new Date).toISOString(),isPrivate:!1,recipient:null,isSystem:!0,pending:!1},this.messages.push(r),this.chatHistory.set(t,r),this.processedMessageIds.add(t)),this.updateConnectionStatusInUI(r)}updateConnectionStatusInUI(e){const t=this.panel.querySelector(`[data-message-id="${e.id}"]`);t&&t.remove(),this.updatePanel()}}function et(){const e=document.getElementById("app-chat-container"),t=document.querySelector(".chat-toggle-button");if(!e)return;if(e.classList.contains("maximized"))return void Te("Chat is currently maximized",{type:"warning",duration:1e3});const n=JSON.parse(localStorage.getItem("chatState"))||{};if(n.floating||!1){const r="0"===e.style.opacity;e.style.opacity=r?"1":"0",setTimeout((()=>{e.style.display=r?"flex":"none",t.innerHTML=r?Z:ee,be({...n,isVisible:r}),r&&ze()}),300)}else{const r=!e.classList.contains("visible-chat");e.classList.remove("visible-chat","hidden-chat"),e.classList.add(r?"visible-chat":"hidden-chat"),t.innerHTML=r?Z:ee,be({...n,isVisible:r}),r&&ze()}}class tt{constructor(e={}){this.container=null,this.options={container:e.container||document.body,helpButton:e.helpButton,onDestroy:e.onDestroy},tt.instance=this}init(){return this.createPanel(),this.bindEvents(),this}createPanel(){this.container=document.createElement("div"),this.container.className="help-panel",this.content=document.createElement("div"),this.content.className="help-content",this.updatePanelContent(),this.container.appendChild(this.content),document.body.appendChild(this.container),Ce(this.container,"show","1")}updatePanelContent(){const e={en:{heading:"Chat Commands & Hotkeys",sections:[{title:"Chat Commands",items:[{key:"/help",desc:"Show this help panel"},{key:"/me message",desc:"Send an action message"},{key:"/pm username",desc:"Activate private chat mode with the specified user"},{key:"/exit",desc:"Exit private chat mode"}]},{title:"Chat Hotkeys",items:[{key:"Ctrl + Space",desc:"Hide/Show the chat"},{key:"Shift + Ctrl + Space",desc:"Expand/Collapse the chat"},{key:"Ctrl + Click",desc:"Activate private chat mode with the clicked user"}]},{heading:"Emoji Panel Actions & Hotkeys",subSections:[{title:"Emoji Panel Actions",items:[{key:"Click an emoji",desc:"Insert the emoji"},{key:"Click outside panel",desc:"Closes the panel (emoji or help)"}]},{title:"Emoji Panel Hotkeys",items:[{key:"Ctrl + ;",desc:"Open the Emoji Panel"},{key:"Enter",desc:"Insert the emoji"},{key:"Ctrl + Enter",desc:"Insert the emoji keeping the panel open"},{key:"Ctrl + Click",desc:"Insert the emoji keeping the panel open"},{key:"Shift + Click",desc:"Remove emoji from recent list (in recent category)"},{key:"q",desc:"Hide the Emoji Panel (single press when search is not focused)"},{key:"qq",desc:"Hide the Emoji Panel (double press 'q' when search is focused)"},{key:"Esc",desc:"Close the panel (emoji or help)"}]}]},{heading:"Image Manipulations",subSections:[{title:"Open/Close",items:[{key:"(LMB) Click",desc:"Open the image"},{key:"Ctrl + (RMB)",desc:"Close the image and copy the link"},{key:"Space or ESC",desc:"Close the image"}]},{title:"Movement and Scaling",items:[{key:"Hold (MMB)",desc:"Drag the expanded image"},{key:"Scroll (MMB)",desc:"Zoom in/out the image"},{key:"Ctrl + (MMB)",desc:"Scale the image. Move the cursor up or down."}]},{title:"Navigation",items:[{key:"Arrow keys (< >)",desc:"Switch between images"},{key:"(LMB), (RMB)",desc:"Switch between images"}]}]}]},ru:{heading:"Команды чата и горячие клавиши",sections:[{title:"Команды чата",items:[{key:"/help",desc:"Показать панель помощи"},{key:"/me сообщение",desc:"Отправить сообщение действия"},{key:"/pm username",desc:"Активировать приватный чат для указанного пользователя"},{key:"/exit",desc:"Выйти из приватного чата"}]},{title:"Горячие клавиши чата",items:[{key:"Ctrl + Space",desc:"Скрыть/Показать чат"},{key:"Shift + Ctrl + Space",desc:"Развернуть/Свернуть чат"},{key:"Ctrl + Click",desc:"Активировать приватный чат для выбранного пользователя"}]},{heading:"Действия и горячие клавиши панели эмодзи",subSections:[{title:"Действия панели эмодзи",items:[{key:"Click an emoji",desc:"Вставить эмодзи"},{key:"Click outside panel",desc:"Закрыть панель (эмодзи или помощь)"}]},{title:"Горячие клавиши панели эмодзи",items:[{key:"Ctrl + ;",desc:"Открыть панель эмодзи"},{key:"Enter",desc:"Вставить эмодзи"},{key:"Ctrl + Enter",desc:"Вставить эмодзи, оставив панель открытой"},{key:"Ctrl + Click",desc:"Вставить эмодзи, оставив панель открытой"},{key:"Shift + Click",desc:'Удалить эмодзи из списка "Недавно использованные"'},{key:"q",desc:"Скрыть панель эмодзи (одиночный нажим, когда поиск не в фокусе)"},{key:"qq",desc:"Скрыть панель эмодзи (дважды нажмите 'q', когда поиск в фокусе)"},{key:"Esc",desc:"Закрыть (эмодзи или помощь)"}]}]},{heading:"Манипуляции с изображением",subSections:[{title:"Открытие/Закрытие",items:[{key:"(ЛКМ) Клик",desc:"Открыть изображение"},{key:"Ctrl + (ПКМ)",desc:"Закрыть изображение и скопировать ссылку"},{key:"Space или ESC",desc:"Закрыть изображение"}]},{title:"Перемещение и масштабирование",items:[{key:"Зажатая (СКМ)",desc:"Перемещайте развернутое изображение"},{key:"Прокрутка (СКМ)",desc:"Увеличивайте/уменьшайте изображение"},{key:"Ctrl + (СКМ)",desc:"Масштабируйте изображение. Курсор вверх или вниз."}]},{title:"Навигация",items:[{key:"Стрелки (< >)",desc:"Переключение между изображениями"},{key:"(ЛКМ), (ПКМ)",desc:"Переключение между изображениями"}]}]}]}}[localStorage.getItem("emojiPanelLanguage")||"en"];let t=`<h5 class="help-section-header">${e.heading}</h5>`;e.sections.forEach((e=>{e.title?t+=`<h6 class="help-section-subheader">${e.title}</h6>`:e.heading&&(t+=`<h5 class="help-section-header">${e.heading}</h5>`),e.items&&(t+='<ul class="help-list">',e.items.forEach((e=>{t+=`<li class="help-list-item"><strong class="help-hotkey">${e.key}</strong> ${e.desc}</li>`})),t+="</ul>"),e.subSections&&e.subSections.forEach((e=>{t+=`<h6 class="help-section-subheader">${e.title}</h6>`,t+='<ul class="help-list">',e.items.forEach((e=>{t+=`<li class="help-list-item"><strong class="help-hotkey">${e.key}</strong> ${e.desc}</li>`})),t+="</ul>"}))})),this.content.innerHTML=t}bindEvents(){this._clickOutsideHandler=e=>{this.options.helpButton&&(e.target===this.options.helpButton||this.options.helpButton.contains(e.target))||this.container&&!this.container.contains(e.target)&&(this.remove(),Te("Help panel has been closed.",{type:"warning",duration:2e3}))},document.addEventListener("click",this._clickOutsideHandler,!0),this._escHandler=e=>{"Escape"===e.key&&(this.remove(),Te("Help panel has been closed.",{type:"warning",duration:2e3}))},document.addEventListener("keydown",this._escHandler,!0),this._stopPropagationHandler=e=>{e.stopPropagation()},this.container.addEventListener("click",this._stopPropagationHandler)}remove(){this._clickOutsideHandler&&(document.removeEventListener("click",this._clickOutsideHandler,!0),this._clickOutsideHandler=null),this._escHandler&&(document.removeEventListener("keydown",this._escHandler,!0),this._escHandler=null),this.container&&(this.container.removeEventListener("click",this._stopPropagationHandler),this._stopPropagationHandler=null),this.container&&(Ce(this.container,"hide","0"),this.container=null),"function"==typeof this.options.onDestroy&&this.options.onDestroy(),tt.instance=null}show(){this.container?this.updatePanelContent():this.init(),document.body.contains(this.container)||(document.body.appendChild(this.container),Ce(this.container,"show","1"),Te("Help panel is now visible."))}toggle(){this.container&&document.body.contains(this.container)?this.remove():this.show()}static setupHelpCommandEvents(){const e=document.getElementById("message-input");return e&&e.addEventListener("keydown",(t=>{if("/help"===e.value.trim()&&"Space"===t.code){if(t.preventDefault(),tt.instance)tt.instance.remove();else{const e=new tt({onDestroy:()=>{}});e.init(),e.show(),Te("Help panel is now visible.")}e.value=""}})),tt.instance}}tt.instance=null;(()=>{let e=!1;return function(){e||(document.addEventListener("keydown",(e=>{e.ctrlKey&&"Semicolon"===e.code&&(e.preventDefault(),document.querySelector(".emoji-panel")||new nt({onEmojiSelect:e=>{const t=document.getElementById("message-input");t&&(t.value+=e,t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus())}}).show())})),e=!0)}})()();class nt{static instance=null;constructor(e={}){if(nt.instance)return nt.instance;nt.instance=this,this.options={onEmojiSelect:e.onEmojiSelect||(()=>{}),container:e.container||document.getElementById("messages-panel")||document.body,position:e.position||"bottom",onDestroy:e.onDestroy,emojiButton:e.emojiButton},this.container=null,this.searchInput=null,this.emojiContainer=null,this.categoryNav=null,this.infoPanel=null,this.infoIcon=null,this.infoKeywords=null,this.languageSelect=null,this.categories={recent:{icon:"🕒"},smileys:{icon:"😊"},nature:{icon:"🦊"},food:{icon:"🍔"},activities:{icon:"⚽"},travel:{icon:"✈️"},objects:{icon:"💡"},symbols:{icon:"💕"},flags:{icon:"🎌"}},this.categoryLabels={en:{recent:"Recently Used",smileys:"Smileys & People",nature:"Animals & Nature",food:"Food & Drink",activities:"Activities",travel:"Travel & Places",objects:"Objects",symbols:"Symbols",flags:"Flags"},ru:{recent:"Недавно использованные",smileys:"Смайлы и люди",nature:"Животные и природа",food:"Еда и напитки",activities:"Активности",travel:"Путешествия и места",objects:"Объекты",symbols:"Символы",flags:"Флаги"}},this.uiLabels={en:{searchResults:"Search Results"},ru:{searchResults:"Результаты поиска"}},this.emojiData=ae,this.emojiKeywords=ie,this.recentEmojis=this.loadRecentEmojis(),this.batchSize=50,this.loadedIndices={},this.categorySections={},this.currentLanguage=localStorage.getItem("emojiPanelLanguage")||"en"}init(){return this.createPanel(),this.bindEvents(),this.loadAllEmojis(),this}createPanel(){if(document.querySelector(".emoji-panel"))return;this.container=document.createElement("div"),this.container.className="emoji-panel";const e=document.createElement("div");e.className="emoji-search-container",this.searchInput=document.createElement("input"),this.searchInput.type="search",this.searchInput.className="emoji-search",e.appendChild(this.searchInput),this.categoryNav=document.createElement("div"),this.categoryNav.className="emoji-categories",Object.entries(this.categories).forEach((([e,t])=>{const n=document.createElement("button");n.className="emoji-category-btn",n.dataset.category=e,n.innerHTML=t.icon,n.title=this.getLocalizedCategoryName(e),this.categoryNav.appendChild(n)})),this.emojiContainer=document.createElement("div"),this.emojiContainer.className="emoji-container",this.infoPanel=document.createElement("div"),this.infoPanel.className="emoji-info-panel",this.infoIcon=document.createElement("span"),this.infoIcon.className="emoji-info-icon",this.infoKeywords=document.createElement("span"),this.infoKeywords.className="emoji-info-keywords",this.infoPanel.appendChild(this.infoIcon),this.infoPanel.appendChild(this.infoKeywords),this.languageSelect=document.createElement("select"),this.languageSelect.className="emoji-language-select",this.languageSelect.innerHTML='\n      <option value="en">EN</option>\n      <option value="ru">RU</option>\n    ',this.languageSelect.value=this.currentLanguage;const t=document.createElement("div");t.className="emoji-footer",t.appendChild(this.infoPanel),t.appendChild(this.languageSelect),this.container.appendChild(e),this.container.appendChild(this.categoryNav),this.container.appendChild(this.emojiContainer),this.container.appendChild(t),this.options.container.appendChild(this.container),Ce(this.container,"show","1"),Xe()||this.searchInput.focus()}loadAllEmojis(){this.emojiContainer&&(this.emojiContainer.innerHTML="",this.loadedIndices={},this.categorySections={},Object.keys(this.categories).forEach((e=>{const t=document.createElement("div");t.className="emoji-category-section",t.id=`emoji-section-${e}`;const n=document.createElement("div");n.className="emoji-category-header",n.textContent=this.getLocalizedCategoryName(e),t.appendChild(n);const r=document.createElement("div");r.className="emoji-list",t.appendChild(r),this.emojiContainer.appendChild(t),this.loadedIndices[e]=0,this.categorySections[e]={section:t,emojiList:r,header:n},this.loadMoreEmojisForCategory(e)})))}loadMoreEmojisForCategory(e){const t="recent"===e?this.recentEmojis:this.emojiData[e]||[],n=this.loadedIndices[e],r=t.slice(n,n+this.batchSize);if(!r.length)return;const o=this.categorySections[e].emojiList;r.forEach((t=>{const n=document.createElement("button");n.className="emoji-btn",n.textContent=t,n.addEventListener("mouseenter",(()=>this.updateInfoPanel(t))),n.addEventListener("mouseleave",(()=>this.clearInfoPanel())),n.addEventListener("click",(n=>{n.stopPropagation(),n.shiftKey&&"recent"===e?(n.preventDefault(),this.removeFromRecent(t)):(this.addToRecent(t),this.options.onEmojiSelect(t),n.ctrlKey?this.searchInput.focus():this.destroy())})),o.appendChild(n)})),this.loadedIndices[e]+=r.length}searchEmojis(e){if(!this.emojiContainer)return;this.emojiContainer.innerHTML="";const t=document.createElement("div");t.className="emoji-category-section";const n=document.createElement("div");n.className="emoji-category-header",n.textContent=this.uiLabels[this.currentLanguage].searchResults,t.appendChild(n);const r=document.createElement("div");r.className="emoji-list",t.appendChild(r);const o=[];Object.keys(this.emojiData).forEach((t=>{(this.emojiData[t]||[]).forEach((t=>{const n=this.emojiKeywords[t]||{},r=Object.values(n).flat();(t.includes(e)||r.some((t=>t.toLowerCase().includes(e))))&&o.push(t)}))})),o.forEach((e=>{const t=document.createElement("button");t.className="emoji-btn",t.textContent=e,t.addEventListener("mouseenter",(()=>this.updateInfoPanel(e))),t.addEventListener("mouseleave",(()=>this.clearInfoPanel())),t.addEventListener("click",(t=>{t.stopPropagation(),this.addToRecent(e),this.options.onEmojiSelect(e),t.ctrlKey?this.searchInput.focus():this.destroy()})),r.appendChild(t)})),this.emojiContainer.appendChild(t)}bindEvents(){this._documentClickHandler=e=>{this.container.contains(e.target)||this.destroy()},document.addEventListener("click",this._documentClickHandler),this._emojiKeydownHandler=e=>{"Escape"===e.key&&this.destroy()},document.addEventListener("keydown",this._emojiKeydownHandler),this._qKeydownHandler=e=>{if("KeyQ"===e.code)if(document.activeElement===this.searchInput){const t=Date.now();this._lastQPressTime&&t-this._lastQPressTime<500?(e.preventDefault(),this.destroy(),this._lastQPressTime=0):this._lastQPressTime=t}else e.preventDefault(),this.destroy()},document.addEventListener("keydown",this._qKeydownHandler),this.searchInput.addEventListener("input",(e=>{const t=e.target.value.trim().toLowerCase();t?(this.searchEmojis(t),this.emojiContainer.classList.add("search-active")):(this.loadAllEmojis(),this.emojiContainer.classList.remove("search-active"))})),this.searchInput.addEventListener("keydown",(e=>{if("Enter"===e.key){if(e.preventDefault(),!this.searchInput||!this.emojiContainer)return;if(this.emojiContainer.classList.contains("search-active")){const t=this.emojiContainer?.querySelector(".emoji-btn");if(t){const n=new MouseEvent("click",{bubbles:!0,cancelable:!0,ctrlKey:e.ctrlKey});t.dispatchEvent(n),this.emojiContainer&&(this.emojiContainer.classList.remove("search-active"),this.loadAllEmojis()),this.searchInput&&(this.searchInput.value=""),e.ctrlKey?this.searchInput&&this.searchInput.focus():this.destroy()}}}})),this.categoryNav.addEventListener("click",(e=>{const t=e.target.closest(".emoji-category-btn");if(t){const n=t.dataset.category,r=document.getElementById(`emoji-section-${n}`);r&&this.emojiContainer&&(this.emojiContainer.style.scrollBehavior="smooth",this.emojiContainer.scrollTop=r.offsetTop-this.emojiContainer.offsetTop,e.preventDefault(),e.stopPropagation())}})),this.emojiContainer.addEventListener("scroll",(()=>this.handleScroll())),this.languageSelect.addEventListener("change",(e=>{this.currentLanguage=e.target.value,localStorage.setItem("emojiPanelLanguage",this.currentLanguage);const t=this.infoIcon.textContent;t&&this.updateInfoPanel(t),this.updateCategoryLabels(),this.searchInput.value.trim()&&this.searchEmojis(this.searchInput.value.trim().toLowerCase())})),this.container.addEventListener("click",(e=>{e.stopPropagation()}))}handleScroll(){Object.keys(this.categorySections).forEach((e=>{const{section:t}=this.categorySections[e],n=t.getBoundingClientRect(),r=this.emojiContainer.getBoundingClientRect();n.bottom<r.bottom+100&&this.loadMoreEmojisForCategory(e)}));let e=null,t=1/0;Object.keys(this.categorySections).forEach((n=>{const r=this.categorySections[n].header.getBoundingClientRect(),o=this.emojiContainer.getBoundingClientRect(),a=Math.abs(r.top-o.top);r.top<=o.top+10&&a<t&&(t=a,e=n)})),e&&this.highlightCategory(e)}updateCategoryLabels(){Object.keys(this.categories).forEach((e=>{const t=this.getLocalizedCategoryName(e),n=this.categoryNav.querySelector(`[data-category="${e}"]`);n&&(n.title=t),this.categorySections[e]&&this.categorySections[e].header&&(this.categorySections[e].header.textContent=t)}))}updateInfoPanel(e){if(!this.infoIcon||!this.infoKeywords)return;this.infoIcon.textContent=e;const t=(this.emojiKeywords[e]||{})[this.currentLanguage]||[];this.infoKeywords.textContent=t.join(", ")}clearInfoPanel(){this.infoIcon&&this.infoKeywords&&(this.infoIcon.textContent="",this.infoKeywords.textContent="")}addToRecent(e){if(this.recentEmojis=[e,...this.recentEmojis.filter((t=>t!==e))].slice(0,25),this.saveRecentEmojis(),this.categorySections.recent){this.categorySections.recent.emojiList.innerHTML="",this.loadedIndices.recent=0,this.loadMoreEmojisForCategory("recent")}}removeFromRecent(e){if(this.recentEmojis=this.recentEmojis.filter((t=>t!==e)),this.saveRecentEmojis(),this.categorySections.recent){this.categorySections.recent.emojiList.innerHTML="",this.loadedIndices.recent=0,this.loadMoreEmojisForCategory("recent")}}loadRecentEmojis(){try{return JSON.parse(localStorage.getItem("recentEmojis"))||[]}catch{return[]}}saveRecentEmojis(){try{localStorage.setItem("recentEmojis",JSON.stringify(this.recentEmojis))}catch(e){console.error("Failed to save recent emojis:",e)}}highlightCategory(e){this.categoryNav.querySelectorAll(".emoji-category-btn").forEach((t=>{t.classList.toggle("active",t.dataset.category===e)}))}show(){this.createPanel(),this.bindEvents(),this.loadAllEmojis()}destroy(){document.removeEventListener("keydown",this._emojiKeydownHandler),document.removeEventListener("keydown",this._qKeydownHandler),document.removeEventListener("click",this._documentClickHandler),this.container&&Ce(this.container,"hide","0"),this.container=null,this.searchInput=null,this.emojiContainer=null,this.categoryNav=null,this.infoPanel=null,this.infoIcon=null,this.infoKeywords=null,this.languageSelect=null,nt.instance=null,this.options.emojiButton&&(this.options.emojiButton.title="Open emoji picker"),"function"==typeof this.options.onDestroy&&this.options.onDestroy()}toggle(){document.querySelector(".emoji-panel")?this.destroy():this.show()}getLocalizedCategoryName(e){return this.categoryLabels[this.currentLanguage][e]||e}}function rt(){const e=document.createElement("div");e.id="app-chat-container",["top","left","right"].forEach((t=>{const n=document.createElement("div");n.className=`resize-handle ${t}`,e.appendChild(n)}));const t=document.createElement("div");t.className="chat-wrapper";const n=document.createElement("div");n.className="chat-content";const r=document.createElement("div");r.id="messages-panel",r.className="messages-panel";const o=document.createElement("div");o.className="input-container",requestAnimationFrame((()=>{!function(){if(Xe()){o.style.position="absolute",o.style.top="0",o.style.left="0",o.style.right="0",o.style.borderBottom="1px solid #333",o.style.zIndex="100",r.style.marginTop=`${o.offsetHeight}px`;const e=document.createElement("style");e.classList.add("global-mobile-styles"),e.textContent="\n        .emoji-panel {\n          transform: translate(-50%, 0) !important;\n          height: 60vh !important;\n          bottom: 10px !important;\n          top: unset !important;\n          left: 50% !important;\n          right: unset !important;\n        }\n\n        #app-chat-container .length-field-popup {\n          bottom: unset !important;\n        }\n      ",document.head.appendChild(e);let t=o.offsetHeight;new ResizeObserver((()=>{const e=o.offsetHeight;e!==t&&(r.style.marginTop=`${e}px`,t=e)})).observe(o)}}()}));const a=document.createElement("button");var i,s;a.className="emoji-trigger filled-button",a.innerHTML="🙂",a.classList.add("emoji-button"),a.title="Open emoji picker",a.addEventListener("mouseover",(()=>{a.innerHTML="🙃"})),a.addEventListener("mouseout",(()=>{a.innerHTML="🙂"})),function(e,t){const n=Object.keys(ie),r=setInterval((()=>{const t=n[Math.floor(Math.random()*n.length)];e.innerHTML=t,oe(e),setTimeout((()=>{e.innerHTML="🙂"}),1500)}),t);e.randomEmojiIntervalId=r}(a,((i=6e5)>(s=18e5)&&([i,s]=[s,i]),Math.floor(Math.random()*(s-i+1))+i));let c=null;a.addEventListener("click",(e=>{e.stopPropagation(),c&&document.querySelector(".emoji-panel")?c.destroy():(c=new nt({container:r,position:"bottom",emojiButton:a,onEmojiSelect:e=>{const t=document.getElementById("message-input");if(t){const n=t.selectionStart,r=t.value.substring(0,n),o=t.value.substring(t.selectionEnd);t.value=r+e+o;const a=n+e.length;t.setSelectionRange(a,a),t.focus()}},onDestroy:()=>{a.title="Open emoji picker",c=null}}),c.init(),a.title="Close emoji picker")}));const l=document.createElement("input");l.type="text",l.id="message-input",l.maxLength=300,l.autocomplete="off";const d=document.createElement("button");d.id="send-button",d.className="filled-button send-button",d.innerHTML=G,o.appendChild(a),o.appendChild(l),o.appendChild(d),n.appendChild(r),n.appendChild(o);const u=document.createElement("div");u.className="user-list-container";const m=document.createElement("div");m.id="user-list",u.appendChild(m),t.appendChild(n),t.appendChild(u),e.appendChild(t);const p=document.createElement("button");p.className="filled-button header-button chat-maximize-button",p.innerHTML=ne,p.addEventListener("click",at),e.appendChild(p);const h=document.createElement("button");h.className="filled-button header-button chat-help-button",h.innerHTML=re,h.title="Show chat help";let g=null;h.addEventListener("click",(e=>{if(console.log("Help button clicked."),e.stopPropagation(),g&&document.querySelector(".help-panel"))return g.remove(),h.title="Show chat help",g=null,void Te("Help panel has been closed.",{type:"warning",duration:2e3});console.log("Help panel does not exist. Creating help panel..."),g=new tt({helpButton:h,onDestroy:()=>{h.title="Show chat help",g=null}}),g.init(),g.show(),Te('Help panel has been opened. Press "?" or "ESC" key, or click outside to close.',{type:"success",duration:2e3}),h.title="Hide chat help"})),e.appendChild(h);const f=document.createElement("button");f.className="filled-button header-button chat-toggle-button",f.innerHTML=Z,f.addEventListener("click",et),e.appendChild(f);const y=document.createElement("div");y.className="chat-drag-area",y.addEventListener("dblclick",et),e.appendChild(y),document.body.appendChild(e),he(),function(){if(!document.getElementById("app-chat-container"))return;const e=ge(),t=document.createElement("div");t.className="font-size-control";const n=document.createElement("input");n.type="range",n.min="0.8",n.max="1.5",n.step="0.1",n.value=e.fontSizeMultiplier,n.className="font-size-slider",n.addEventListener("mousedown",(e=>{e.stopPropagation()})),n.addEventListener("input",(e=>{fe(parseFloat(e.target.value))})),t.appendChild(n);const r=document.querySelector(".chat-drag-area");r&&r.appendChild(t)}(),ye(),requestAnimationFrame((()=>{const e=document.getElementById("messages-panel"),t=document.getElementById("message-input");if(e&&t){Xe()?setTimeout((()=>{e.scrollTop=e.scrollHeight}),2e3):e.scrollTop=e.scrollHeight,t.value="",Re=e,qe=document.createElement("div"),qe.className="length-field-popup",Re.appendChild(qe),Be=t,Be?qe&&(Be.addEventListener("input",Ke),Be.addEventListener("keydown",We)):console.error("chatField is null")}}))}let ot=null;function at(){const e=document.getElementById("app-chat-container"),t=document.querySelector(".chat-maximize-button");if(e)if(e.classList.contains("maximized")){const n=document.getElementById("messages-panel"),r=n.scrollHeight-n.scrollTop-n.clientHeight<=300;if(e.maximizeResizeHandler&&(window.removeEventListener("resize",e.maximizeResizeHandler),delete e.maximizeResizeHandler),ot){if(e.style.width=`${ot.width}px`,e.style.height=`${ot.height}px`,e.style.left=`${ot.left}px`,e.style.maxWidth="",e.style.minWidth="",e.style.position="fixed",e.style.right="",e.style.margin="",e.style.transform="",e.style.top="auto",ot.floating){const t=window.innerHeight,n=ot.top;n+ot.height<=t?e.style.top=`${n}px`:(e.style.bottom="0",e.style.top="auto")}else e.style.bottom="0",e.style.top="";be({...ge(),width:ot.width,height:ot.height,left:ot.left,top:ot.top,floating:ot.floating,isVisible:ot.isVisible})}e.classList.remove("maximized"),t.classList.remove("maximized"),t.innerHTML=ne,requestAnimationFrame((()=>{pe(),r&&(n.scrollTop=n.scrollHeight),ze(),ye()}))}else{const n=!e.classList.contains("visible-chat")&&!e.classList.contains("hidden-chat");ot=ge();const r=()=>`${Math.floor(.9*window.innerHeight)}px`;e.style.cssText=`\n      width: 100vw !important;\n      height: ${r()} !important;\n      max-width: 100vw !important;\n      min-width: 100vw !important;\n      position: fixed !important;\n      bottom: 0 !important;\n      left: 0 !important;\n      right: 0 !important;\n      top: auto !important;\n      margin: 0 !important;\n      transform: none !important;\n    `,n&&e.classList.remove("visible-chat","hidden-chat"),e.classList.add("maximized"),t.classList.add("maximized"),t.innerHTML=te;const o=()=>{e.style.height=r(),e.style.bottom="0",e.style.top="auto"};window.addEventListener("resize",o),e.maximizeResizeHandler=o,pe(),ze(),ye()}}let it,st,ct,lt,dt=!1;let ut,mt,pt,ht,gt,ft,yt=!1,bt=null,vt=0;function wt(e,t,n,r){const o=e=>e&&t.updatePresence(e),a=e=>e&&n.processMessages(e);let i=null;function s(){if(i)return i;if(!sessionStorage.getItem("usernameColors"))return console.log("usernameColors key does not exist in sessionStorage, skipping userInfo calculation"),null;try{const e=JSON.parse(sessionStorage.getItem("usernameColors")),t=ke(r),n=t.toLowerCase(),o=e[n]||"#ff00c6",a=(e=>{console.log("Optimizing color for contrast:",e);let{h:t,s:n,l:r}=se.hexToHSL(e),o=e;for(;se.contrastRatio(o,"#FFFFFF")<4.5&&r>0;)o=se.hslToHex(t,n,--r);return o})(o),s=`/storage/avatars/${r.split("#")[0]}.png`,c=Math.floor(Date.now()/1e3);return i={cleanedUsername:t,usernameKey:n,storedColor:o,optimizedColor:a,baseAvatarPath:s,timestamp:c},i}catch(e){return console.error("Error parsing usernameColors from sessionStorage:",e),null}}const c={userManager:t,messageManager:n,presenceInterval:null,isReconnecting:!1,isConnected:!1,messageQueue:[],_createMessageStanza(t,n,o,a){const i=s(),c=`\n      <x xmlns='klavogonki:userdata'>\n        <user>\n          <login>${i.cleanedUsername}</login>\n          <avatar>${i.baseAvatarPath}?updated=${i.timestamp}</avatar>\n          <background>${i.optimizedColor}</background>\n        </user>\n      </x>\n      `,l=o&&a?a:"[email protected]",d=o?"chat":"groupchat";return Ye(`\n      <body rid='${e.nextRid()}' sid='${e.sid}' xmlns='http://jabber.org/protocol/httpbind'>\n        <message \n          from='${r}@jabber.klavogonki.ru/web' \n          to='${l}' \n          type='${d}' \n          id='${n}' \n          xmlns='jabber:client'>\n          <body>${t}</body>\n          ${c}\n        </message>\n      </body>\n      `)},async processQueue(){if(this.isConnected&&!this.isReconnecting)for(;this.messageQueue.length>0;){const t=this.messageQueue[0],r=this._createMessageStanza(t.text,t.id,t.isPrivate,t.fullJid);try{await e.sendRequestWithRetry(r),this.messageQueue.shift(),n.updatePendingStatus(t.id,!1),a(null)}catch(e){console.error(`Failed to send queued message (${t.id}): ${e.message}`);break}}},async connect(){try{this.presenceInterval&&(clearInterval(this.presenceInterval),this.presenceInterval=null);let t=5;for(;t>0&&!this.isConnected;)try{const t=await e.connect();console.log("💬 Step 8: Joining chat room...");const i=s(),c=i?i.cleanedUsername:ke(r),l=i?i.baseAvatarPath:`/storage/avatars/${r.split("#")[0]}.png`,d=i?i.timestamp:Math.floor(Date.now()/1e3),u=i?i.optimizedColor:"#000000",m=Ye(`\n            <body rid='${e.nextRid()}' xmlns='http://jabber.org/protocol/httpbind' sid='${t.sid}'>\n              <presence from='${r}@jabber.klavogonki.ru/web' to='[email protected]/${r}' xmlns='jabber:client'>\n                <x xmlns='http://jabber.org/protocol/muc'/>\n                <x xmlns='klavogonki:userdata'>\n                  <user>\n                    <login>${c}</login>\n                    <avatar>${l}?updated=${d}</avatar>\n                    <background>${u}</background>\n                  </user>\n                </x>\n              </presence>\n            </body>\n            `),p=await e.sendRequestWithRetry(m);console.log("📥 Join response:",p),o(p),a(p);const h=Ye(`\n              <body \n                rid='${e.nextRid()}' \n                sid='${t.sid}' \n                xmlns='http://jabber.org/protocol/httpbind'>\n                <iq \n                  type='get' \n                  id='info_${Math.random().toString(36).substring(2,10)}' \n                  xmlns='jabber:client' \n                  to='[email protected]'>\n                  <query xmlns='http://jabber.org/protocol/disco#info'/>\n                </iq>\n              </body>\n            `);await e.sendRequestWithRetry(h),console.log("🚀 Step 10: Connected! Starting presence updates..."),this.isConnected=!0,this.isReconnecting&&(Te("Chat connected successfully!",{type:"success"}),n.refreshMessages(!0),this.isReconnecting=!1),this.startPresencePolling(e),this.processQueue();break}catch(e){console.error(`💥 Connection error: ${e.message}`),t--,0===t?(console.log("⏳ Scheduling reconnection attempt in 5 seconds..."),this.isReconnecting=!0,setTimeout((()=>this.connect()),E)):(console.log(`🔄 Retrying connection... (${t} attempts left)`),await new Promise((e=>setTimeout(e,5e3))))}}catch(e){console.error(`💥 Final connection error: ${e.message}`),this.isConnected=!1,this.isReconnecting||(console.log("⏳ Scheduling reconnection attempt in 5 seconds..."),this.isReconnecting=!0,setTimeout((()=>this.connect()),E))}},startPresencePolling(e){this.presenceInterval=setInterval((async()=>{if(this.isConnected)try{const t=await e.sendRequestWithRetry(`<body rid='${e.nextRid()}' sid='${e.sid}' xmlns='http://jabber.org/protocol/httpbind'/>`);o(t),a(t),this.isReconnecting=!1}catch(e){console.error("Presence polling error:",e.message),e.message.includes("404")&&!this.isReconnecting&&(console.log("🛑 Connection lost (404). Reconnecting in 5 seconds..."),Te("Chat connection lost. Reconnecting...",{type:"warning"}),n.refreshMessages(!1),this.isReconnecting=!0,this.isConnected=!1,clearInterval(this.presenceInterval),this.presenceInterval=null,setTimeout((()=>this.connect()),E))}else console.log("⚠️ Skipping presence poll - not connected")}),5e3)},sendMessage(e){const t=`msg_${Date.now()}`;let r=!1,o=null,a=null;const i=!this.isConnected||this.isReconnecting;Pe.isPrivateMode&&Pe.fullJid?(r=!0,o=Pe.fullJid,a=Pe.targetUsername,n.addSentMessage(e,{isPrivate:!0,recipient:a,pending:i})):n.addSentMessage(e,{pending:i}),this.messageQueue.push({text:e,id:t,isPrivate:r,fullJid:o,recipient:a,pending:i}),this.isConnected&&!this.isReconnecting&&this.processQueue()}};return window.addEventListener("offline",(()=>{console.log("Network offline. Stopping presence polling."),c.presenceInterval&&(clearInterval(c.presenceInterval),c.presenceInterval=null),c.isConnected=!1})),window.addEventListener("online",(async()=>{var e;console.log("Network online. Scheduling reconnection in 5 seconds..."),await(e=5e3,new Promise((t=>setTimeout(t,e)))),c.isConnected||c.isReconnecting||c.connect()})),c}function xt(){if(function(){try{return window!==window.top}catch(e){return!0}}())return console.error("Application cannot run in an iframe"),!1;const e=new URLSearchParams(window.location.search);if("/g/"===window.location.pathname&&e.has("gmid"))return!1;if(window.location.href.includes("/gamelist/"))return function(){if(window.location.href.startsWith("https://klavogonki.ru/gamelist/"))try{const e=Array.from(document.scripts).find((e=>e.text.includes("PageData")));if(!e)throw new Error("PageData script not found");const t=e.text.match(/\.constant\('PageData', ([\s\S]*?})\)/)[1],n=JSON.parse(t.replace(/(\w+):/g,'"$1":').replace(/'/g,'"')),r=`${n.chatParams.user.id}#${n.chatParams.user.login}`,o=n.chatParams.pass;localStorage.getItem("klavoauth")||(localStorage.setItem("klavoauth",JSON.stringify({username:r,password:o})),setTimeout((()=>{window.location.href="https://klavogonki.ru"}),500))}catch(e){console.error("Auth error:",e),localStorage.removeItem("klavoauth"),alert(`Auth failed: ${e.message}\nPlease refresh the page.`)}}(),!1;return!!(localStorage.getItem("klavoauth")&&C.username&&C.password)||(localStorage.removeItem("klavoauth"),window.location.href="https://klavogonki.ru/gamelist/",!1)}!async function(){try{if(function(){if(!document.querySelector('meta[name="viewport"]')){const e=document.createElement("meta");e.name="viewport",e.content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no",document.head.appendChild(e),console.log("Viewport meta tag added dynamically")}}(),!xt())return;rt(),function(){const e=document.getElementById("app-chat-container"),t=document.getElementById("chat-close-btn"),n=document.getElementById("chat-header");if(!e)return;const r=JSON.parse(localStorage.getItem("chatState"))||{},o=r.floating||!1,a=!1!==r.isVisible;o?(e.style.display=a?"flex":"none",e.style.opacity=a?"1":"0"):(e.classList.remove("visible-chat","hidden-chat"),e.classList.add(a?"visible-chat":"hidden-chat")),document.addEventListener("keydown",(e=>{e.ctrlKey&&e.shiftKey&&"Space"===e.code?(e.preventDefault(),at()):e.ctrlKey&&"Space"===e.code&&(e.preventDefault(),et())})),t&&t.addEventListener("click",et),n&&n.addEventListener("dblclick",et)}(),document.addEventListener("mousedown",(e=>{if(!e.target.closest(".chat-drag-area"))return;const t=document.getElementById("app-chat-container");let n=ge();if(dt=!0,it=e.clientX,st=e.clientY,ct=t.offsetLeft,lt=parseInt(t.style.top)||t.getBoundingClientRect().top,!n.floating){const e=window.innerHeight-t.offsetHeight;t.style.top=e+"px",t.style.bottom="",n.top=e,n.floating=!0,t.classList.add("floating-chat"),be(n)}document.body.style.userSelect="none"})),document.addEventListener("mousemove",(e=>{if(!dt)return;const t=document.getElementById("app-chat-container"),n=window.innerWidth,r=window.innerHeight,o=e.clientX-it,a=e.clientY-st,i=ve(ct+o,0,n-t.offsetWidth),s=ve(lt+a,0,r-t.offsetHeight);t.style.left=i+"px",t.style.top=s+"px";let c=ge();c.left=i,c.top=s,c.floating=!0,be(c)})),document.addEventListener("mouseup",(()=>{if(!dt)return;dt=!1;const e=document.getElementById("app-chat-container"),t=window.innerWidth,n=window.innerHeight,r=e.getBoundingClientRect(),o=r.left<0||r.top<0||r.right>t||r.bottom>n,a=n-r.bottom<50;let i=ge();o||a?(e.style.top="",e.style.bottom="0",i.floating=!1,e.classList.remove("floating-chat")):(i.floating=!0,i.top=r.top,e.classList.add("floating-chat")),be(i),document.body.style.userSelect=""})),document.addEventListener("mousedown",(e=>{const t=e.target.closest(".resize-handle");if(!t)return;yt=!0,bt=t.classList[1];const n=document.getElementById("app-chat-container");ut=e.clientX,mt=e.clientY,pt=n.offsetWidth,ht=n.offsetHeight,gt=n.offsetLeft,ft=parseInt(n.style.top)||n.getBoundingClientRect().top,vt=e.clientY-ft,document.body.style.userSelect="none"})),document.addEventListener("mousemove",(e=>{if(!yt)return;const t=document.getElementById("app-chat-container"),n=window.innerWidth,r=window.innerHeight,o=getComputedStyle(document.documentElement),a=parseInt(o.getPropertyValue("--min-chat-width"))||250,i=parseInt(o.getPropertyValue("--min-chat-height"))||200;let s=ge();if("left"===bt){const r=Math.max(a,pt-(e.clientX-ut)),o=ve(gt+(e.clientX-ut),0,n-r);t.style.width=r+"px",t.style.left=o+"px",s.width=r,s.left=o}else if("right"===bt){const r=n-t.getBoundingClientRect().left,o=Math.min(r,Math.max(a,pt+(e.clientX-ut)));t.style.width=o+"px",s.width=o}const c=e.clientY-vt;if("top"===bt)if(!1===s.floating){let e=ve(c,0,r-i),n=r-e;t.style.top=e+"px",t.style.height=n+"px",s.top=e,s.height=n}else{let e=ve(c,0,ft+ht-i),n=ht-(e-ft);n=Math.min(n,r),t.style.top=e+"px",t.style.height=n+"px",s.top=e,s.height=n}if("left"===bt||"right"===bt)if(!1===s.floating){let e=ve(c,0,r-i),n=r-e;t.style.top=e+"px",t.style.height=n+"px",s.top=e,s.height=n}else{let e=ve(c,0,ft+ht-i),n=ht-(e-ft);n=Math.min(n,r-e),t.style.top=e+"px",t.style.height=n+"px",s.top=e,s.height=n}t.offsetHeight>r&&(t.style.height=r+"px",!1===s.floating&&(t.style.top="0px",s.top=0),s.height=r),be(s),pe()})),document.addEventListener("mouseup",(()=>{yt=!1,document.body.style.userSelect=""})),window.addEventListener("resize",(()=>{he(),pe()})),function(){const e=document.getElementById("messages-panel");if(!e)return;new MutationObserver((()=>{pe(),Y(),_(),$e()})).observe(e,{childList:!0,subtree:!0})}();const e=new Ve("user-list"),t=new Ze("messages-panel",we(C.username)),n=wt(new I({username:C.username,password:C.password,bindUrl:k,delay:200}),e,t,C.username),r=document.getElementById("message-input"),o=()=>{const e=r.value.trim();e&&(n.sendMessage(e),r.value="",r.focus())};document.getElementById("send-button").addEventListener("click",o),r.addEventListener("keypress",(e=>"Enter"===e.key&&o())),function(){const e=document.getElementById("message-input");e&&(e.addEventListener("keydown",(e=>{"Escape"===e.key&&Pe.isPrivateMode&&(He(),e.preventDefault())})),e.addEventListener("input",(()=>{Ne(e)})))}(),tt.setupHelpCommandEvents(),await n.connect(),window.xmppClient=n,r.addEventListener("input",(function(e){Ne(e.target)}))}catch(e){console.error("App init error:",e),localStorage.removeItem("klavoauth"),window.location.href="https://klavogonki.ru/gamelist/"}}()})();