Mucklet Audio Notifier

Audio notifications, per-character sounds and auto-refreshing character metadata

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

Tendrás que instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Tendrás que instalar una extensión como Tampermonkey antes de poder instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         Mucklet Audio Notifier
// @name:de      Mucklet Audio Benachrichtigungen
// @namespace    https://forum.wolfery.com/u/felinex/
// @version      2.1.0
// @description  Audio notifications, per-character sounds and auto-refreshing character metadata
// @description:de Audio-Benachrichtigungen, Sounds pro Charakter und automatische Aktualisierung von Charakter-Metadaten
// @icon         https://mucklet.com/mucklet-logo.svg
// @license      All Rights Reserved
// @author       Felinex Gloomfort
// @match        https://wolfery.com/*
// @match        https://test.wolfery.com/*
// @match        https://mucklet.com/*
// @match        https://*.mucklet.com/*
// @grant        none
// ==/UserScript==
(function() {"use strict";console.log("[AudioNotifier] Script loaded (v2.1.0).");const e="https://actions.google.com/sounds/v1/alarms/beep_short.ogg",t="AudioNotifierSettings",n=1048576;let a=0,r=0,o=!1,i=!1;const l={muteWhenWindowFocused:!1,muteForActiveChar:!1,playOnFocusedChar:!0,soundDefault:null,soundMention:null,soundPrivate:null,soundFocusChar:null,charSounds:{}};let c=function(){try{const e=localStorage.getItem(t);if(!e)return{...l,charSounds:{}};const n=JSON.parse(e);return{...l,...n,charSounds:y(n.charSounds)}}catch(e){return console.error("[AudioNotifier] Failed to load settings",e),{...l,charSounds:{}}}}(),s=!1,d=!1,u=0,m=null;function h(e){return String(e||"").trim().replace(/\s+/g," ").toLowerCase()}function p(e){return"name:"+h(e)}function f(e){return"id:"+String(e)}function y(e){const t={},n=e&&"object"==typeof e?e:{};return Object.keys(n).forEach(e=>{const a=function(e,t){return t&&"object"==typeof t&&!Array.isArray(t)?{name:String(t.name||e.replace(/^name:/,"")).trim(),charId:null!=t.charId?String(t.charId):null!=t.id?String(t.id):null,avatar:t.avatar||null,sound:t.sound||null,alwaysPlay:!!t.alwaysPlay}:{name:String(e.replace(/^name:/,"")).trim(),charId:null,avatar:null,sound:"string"==typeof t?t:null,alwaysPlay:!1}}(e,n[e]),r=a.charId?f(a.charId):p(a.name||e);t[r]=a}),t}function g(){try{localStorage.setItem(t,JSON.stringify(c))}catch(e){console.error("[AudioNotifier] Failed to save settings",e)}}function v(e){try{return window.app&&"function"==typeof window.app.getModule?window.app.getModule(e):null}catch(e){return null}}function C(e){(function(e){return!!m||!!function(e){const t=v("playerTabs");if(!t||"function"!=typeof t.addTab)return!1;if(t.getTabs&&t.getTabs().get&&t.getTabs().get("audioNotifier"))return!1;let n=null,a=null;function r(t){let n=null;return{render:a=>(n=document.createElement("button"),n.type="button",n.className="iconbtn medium default-400 audio-notifier-player-tab-button",n.title=e.tabTitle,n.setAttribute("aria-label",e.tabTitle),n.innerHTML='<i class="fa fa-volume-up" aria-hidden="true"></i>',n.addEventListener("click",e=>{t(),e.stopPropagation()}),a.appendChild(n),n),unrender(){n&&n.parentNode&&n.parentNode.removeChild(n),n=null}}}function o(){return{render:t=>(n=t,a=b(e),t.appendChild(a),W(),a),unrender(){a&&a.parentNode&&a.parentNode.removeChild(a),a=null,n=null}}}try{return t.addTab({id:"audioNotifier",sortOrder:1e4,tabFactory:e=>r(e),factory:(t,n,a)=>({component:o(),title:e.title})}),m={mode:"hook",dispose:()=>{"function"==typeof t.removeTab&&t.removeTab("audioNotifier")}},console.log("[AudioNotifier] Registered via playerTabs.addTab()"),!0}catch(e){return console.debug("[AudioNotifier] playerTabs.addTab() failed:",e),!1}}(e)})(e)||(u++,u<40&&setTimeout(()=>C(e),500))}function b(e,t){const a=document.createElement("div");a.className="pad-bottom-l audio-notifier-panel",a.style.padding="16px";const r=document.createElement("div");r.style.display="flex",r.style.alignItems="center",r.style.justifyContent="space-between",r.style.gap="8px",r.style.marginTop="12px",r.style.marginBottom="12px";const o=document.createElement("h3");if(o.className="margin-bottom-m",o.style.margin="0",o.textContent=e.title,r.appendChild(o),"function"==typeof t){const n=document.createElement("button");n.type="button",n.className="btn small",n.textContent=e.closeBtn,n.addEventListener("click",()=>t()),r.appendChild(n)}a.appendChild(r),a.appendChild(w(e.muteWhenFocused,c.muteWhenWindowFocused,e=>{c.muteWhenWindowFocused=e,g()})),a.appendChild(w(e.muteForActiveChar,c.muteForActiveChar,e=>{c.muteForActiveChar=e,g()})),a.appendChild(w(e.playOnFocusCmd,c.playOnFocusedChar,e=>{c.playOnFocusedChar=e,g()}));const i=document.createElement("h3");i.className="margin-bottom-s",i.style.marginTop="15px",i.textContent=e.hdrDefault,a.appendChild(i),a.appendChild(S(e.soundDefault,"soundDefault",e));const l=document.createElement("h3");return l.className="margin-bottom-s",l.style.marginTop="15px",l.textContent=e.hdrCategories,a.appendChild(l),a.appendChild(S(e.soundMention,"soundMention",e,!0)),a.appendChild(S(e.soundPrivate,"soundPrivate",e,!0)),a.appendChild(S(e.soundFocusChar,"soundFocusChar",e,!0)),a.appendChild(function(e){const t=document.createElement("div");t.style.marginTop="15px";const a=document.createElement("h3");a.className="margin-bottom-s",a.textContent=e.hdrCharSounds,t.appendChild(a);const r=document.createElement("div");r.className="margin-bottom-s",r.style.fontSize="12px",r.style.opacity="0.8",r.textContent=e.searchHint,t.appendChild(r);const o=document.createElement("div");o.style.display="grid",o.style.gridTemplateColumns="1fr auto",o.style.gap="5px",o.style.marginBottom="6px";const i=document.createElement("input");i.type="text",i.placeholder=e.charSearchPlaceholder,l=i,l.style.flex="1",l.style.padding="4px",l.style.background="#1d2233",l.style.color="#fff",l.style.border="1px solid #303753",l.style.borderRadius="4px",l.style.minWidth="0";var l;const s=document.createElement("button");s.className="btn small",s.textContent=e.searchBtn,o.appendChild(i),o.appendChild(s),t.appendChild(o);const d=document.createElement("div");d.style.marginBottom="10px",t.appendChild(d);const u=document.createElement("div");t.appendChild(u);const m=document.createElement("input");m.type="file",m.accept="audio/*",m.style.display="none",t.appendChild(m);let h=null;const y=async()=>{const t=i.value.trim();if(!t)return;d.innerHTML=`<div style="font-size:12px;opacity:.8;padding:4px 0;">${e.searching}</div>`;v(await x(t))};function v(t){d.innerHTML="",t.length?t.slice(0,8).forEach(t=>{const n=document.createElement("div");n.style.display="grid",n.style.gridTemplateColumns="28px 1fr auto",n.style.gap="6px",n.style.alignItems="center",n.style.padding="4px 0",n.style.borderBottom="1px solid rgba(255,255,255,0.05)";const a=document.createElement("div");if(a.style.width="28px",a.style.height="28px",a.style.borderRadius="4px",a.style.overflow="hidden",a.style.background="rgba(255,255,255,0.08)",t.avatar){const e=document.createElement("img");e.src=t.avatar,e.alt=t.name,e.style.width="100%",e.style.height="100%",e.style.objectFit="cover",a.appendChild(e)}const r=document.createElement("div");r.style.minWidth="0";const o=document.createElement("div");o.style.fontSize="12px",o.style.fontWeight="600",o.style.whiteSpace="nowrap",o.style.overflow="hidden",o.style.textOverflow="ellipsis",o.textContent=t.name;const i=document.createElement("div");i.style.fontSize="11px",i.style.opacity="0.75",i.style.whiteSpace="nowrap",i.style.overflow="hidden",i.style.textOverflow="ellipsis",i.textContent=t.charId?`ID ${t.charId}`:e.byName,r.appendChild(o),r.appendChild(i);const l=document.createElement("button");l.className="btn small",l.textContent=e.chooseBtn,l.onclick=()=>{h=t,m.click()},n.appendChild(a),n.appendChild(r),n.appendChild(l),d.appendChild(n)}):d.innerHTML=`<div style="font-size:12px;opacity:.8;padding:4px 0;">${e.noResults}</div>`}function C(){u.innerHTML="";const t=Object.keys(c.charSounds);t.length&&(t.sort((e,t)=>{const n=c.charSounds[e]?.name||"",a=c.charSounds[t]?.name||"";return n.localeCompare(a)}),t.forEach(t=>{const a=c.charSounds[t];if(!a)return;const r=document.createElement("div");r.className="audio-notifier-char-row",r.style.display="grid",r.style.gridTemplateColumns="28px 1fr auto",r.style.gap="6px",r.style.alignItems="center",r.style.background="rgba(0,0,0,0.18)",r.style.padding="5px",r.style.borderRadius="4px",r.style.marginBottom="5px",r.dataset.entryKey=t,r.dataset.charId=a.charId?String(a.charId):"",r.dataset.charName=a.name||"";const o=document.createElement("div");if(o.style.width="28px",o.style.height="28px",o.style.borderRadius="4px",o.style.overflow="hidden",o.style.background="rgba(255,255,255,0.08)",a.avatar){const e=document.createElement("img");e.className="audio-notifier-char-row-avatar",e.src=a.avatar,e.alt=a.name||t,e.style.width="100%",e.style.height="100%",e.style.objectFit="cover",o.appendChild(e)}const i=document.createElement("div");i.style.minWidth="0";const l=document.createElement("div");l.className="audio-notifier-char-row-title",l.style.fontSize="12px",l.style.fontWeight="600",l.style.whiteSpace="nowrap",l.style.overflow="hidden",l.style.textOverflow="ellipsis",l.textContent=a.name||t;const s=document.createElement("div");s.style.fontSize="11px",s.style.opacity="0.75",s.style.whiteSpace="nowrap",s.style.overflow="hidden",s.style.textOverflow="ellipsis",s.textContent=a.charId?`ID ${a.charId}`:e.byName;const d=document.createElement("label");d.className="checkbox",d.style.display="flex",d.style.alignItems="center",d.style.gap="4px",d.style.fontSize="11px",d.style.marginTop="2px";const m=document.createElement("input");m.type="checkbox",m.checked=!!a.alwaysPlay,m.addEventListener("change",e=>{a.alwaysPlay=e.target.checked,g()});const h=document.createElement("span");h.textContent=e.alwaysPlay,d.appendChild(m),d.appendChild(h),i.appendChild(l),i.appendChild(s),i.appendChild(d);const p=document.createElement("div");p.style.display="flex",p.style.gap="4px",p.style.alignItems="center";const f=document.createElement("input");f.type="file",f.accept="audio/*",f.style.display="none",f.addEventListener("change",t=>{const r=t.target.files&&t.target.files[0];if(!r)return;if(r.size>n)return alert(e.sizeWarning);const o=new FileReader;o.onloadend=()=>{a.sound=o.result,g(),C(),f.value=""},o.readAsDataURL(r)});const y=document.createElement("button");y.className="btn small",y.textContent=e.replaceBtn,y.onclick=()=>f.click();const v=document.createElement("button");v.className="btn small primary",v.textContent=e.testBtn,v.onclick=()=>z(a.sound||L("soundDefault"),!0);const b=document.createElement("button");b.className="btn small error",b.textContent=e.resetBtn,b.onclick=()=>{delete c.charSounds[t],g(),C()},p.appendChild(f),p.appendChild(y),p.appendChild(v),p.appendChild(b),r.appendChild(o),r.appendChild(i),r.appendChild(p),u.appendChild(r)}))}return s.addEventListener("click",y),i.addEventListener("keydown",e=>{"Enter"===e.key&&(e.preventDefault(),y())}),m.addEventListener("change",t=>{const a=t.target.files&&t.target.files[0];if(!a||!h)return;if(a.size>n)return alert(e.sizeWarning);const r=new FileReader;r.onloadend=()=>{const e=h,t=e.charId?f(e.charId):p(e.name);c.charSounds[t]={name:e.name,charId:e.charId||null,avatar:e.avatar||null,sound:r.result,alwaysPlay:!1},g(),h=null,m.value="",d.innerHTML="",i.value="",C()},r.readAsDataURL(a)}),C(),t}(e)),a}function w(e,t,n){const a=document.createElement("div");a.className="margin-bottom-m";const r=document.createElement("label");r.className="checkbox",r.style.display="flex",r.style.alignItems="center",r.style.cursor="pointer";const o=document.createElement("input");o.type="checkbox",o.checked=t,o.addEventListener("change",e=>n(e.target.checked));const i=document.createElement("span");return i.textContent=e,i.style.marginLeft="8px",r.appendChild(o),r.appendChild(i),a.appendChild(r),a}function S(e,t,a,r=!1){const o=document.createElement("div");o.className="margin-bottom-m",o.style.display="flex",o.style.alignItems="center",o.style.justifyContent="space-between",o.style.gap="5px";const i=document.createElement("span");i.style.flex="1",i.style.fontSize="14px";const l=()=>{const n=null!==c[t];i.innerHTML=`${e} [${n?"Custom":r?"Fallback":"System Default"}]`};l();const s=document.createElement("div");s.style.display="flex",s.style.gap="5px";const d=document.createElement("input");d.type="file",d.accept="audio/*",d.style.display="none";const u=document.createElement("button");u.className="btn small",u.textContent=a.uploadBtn,u.onclick=()=>d.click();const m=document.createElement("button");m.className="btn small primary",m.textContent=a.testBtn,m.onclick=()=>z(L(t),!0);const h=document.createElement("button");return h.className="btn small error",h.textContent=a.resetBtn,h.onclick=()=>{c[t]=null,g(),l()},d.addEventListener("change",e=>{const r=e.target.files&&e.target.files[0];if(!r)return;if(r.size>n)return alert(a.sizeWarning);const o=new FileReader;o.onloadend=()=>{c[t]=o.result,g(),l(),z(c[t],!0),d.value=""},o.readAsDataURL(r)}),s.appendChild(d),s.appendChild(u),s.appendChild(h),s.appendChild(m),o.appendChild(i),o.appendChild(s),o}async function x(e){const t=String(e||"").trim();if(!t)return[];const n=function(){const e=v("player")||window.player||window.muckletClient?.player||null,t=v("charsAwake")||window.charsAwake||window.muckletClient?.charsAwake||null;return e&&t?{player:e,charsAwake:t}:null}();if(!n)return console.debug("[AudioNotifier] SearchChar modules not available"),[];const{player:a,charsAwake:r}=n;let o=null;if(t.split(/\s+/).length>1&&a?.getPlayer)try{o=await a.getPlayer().call("getChar",{charName:t})}catch(e){(function(e){return!(!e||"core.charNotFound"!==e.code&&"core.charNotFound"!==e.errorCode&&"core.charNotFound"!==e.message)})(e)||console.debug("[AudioNotifier] getChar failed",e)}const i="function"==typeof a?.getActiveChar?a.getActiveChar():null,l="function"==typeof r?.getWatches?r.getWatches():null,c=l&&l.props?Object.keys(l.props).map(e=>l.props[e]?.char).filter(Boolean):[];return A([o?[o]:null,"function"==typeof a?.getChars?a.getChars():null,i?.inRoom?.chars||null,"function"==typeof r?.getCollection?r.getCollection():null,c]).filter(e=>e&&function(e,t){const n=k(I(e)),a=k(t).split(/\s+/).filter(Boolean);return!(!n||!a.length)&&a.every(e=>n.includes(e))}(e,t)).map(e=>N(e)).filter(Boolean).sort(function(e){const t=k(e);return(e,n)=>{const a=k(e.name||""),r=k(n.name||""),o=a===t?1:0,i=r===t?1:0;if(o!==i)return i-o;const l=a.startsWith(t)?1:0,c=r.startsWith(t)?1:0;if(l!==c)return c-l;const s=a.indexOf(t),d=r.indexOf(t),u=-1===s?9999:s,m=-1===d?9999:d;return u!==m?u-m:a.localeCompare(r)}}(t)).slice(0,10)}function A(e){const t=[],n=new Set;for(const a of e)for(const e of E(a)){if(!e)continue;const a=null!=e.id?String(e.id):null,r=I(e),o=a?`id:${a}`:`name:${k(r)}`;o&&!n.has(o)&&(n.add(o),t.push(e))}return t}function E(e){return e?Array.isArray(e)?e.filter(Boolean):"function"==typeof e.toArray?e.toArray().filter(Boolean):e.props&&"object"==typeof e.props?Object.values(e.props).filter(Boolean):e.models&&Array.isArray(e.models)?e.models.filter(Boolean):e.items&&Array.isArray(e.items)?e.items.filter(Boolean):[]:[]}function N(e){if(!e)return null;const t=`${e.name||""} ${e.surname||""}`.trim()||e.fullName||e.label||null;return t?{name:t,charId:null!=e.id?String(e.id):null,avatar:F(e)||null}:null}function I(e){return e&&(`${e.name||""} ${e.surname||""}`.trim()||e.fullName||e.label)||""}function k(e){return String(e||"").normalize("NFD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/\s+/g," ").trim()}function F(e){const t=[e&&e.avatar&&e.avatar.href,e&&e.avatar&&e.avatar.url,e&&e.avatar&&e.avatar.src,e&&e.icon&&e.icon.href,e&&e.icon&&e.icon.url,e&&e.icon&&e.icon.src,e&&e.avatarUrl,e&&e.iconUrl,e&&e.avatar,e&&e.icon,e&&e.image&&e.image.href,e&&e.image&&e.image.url,e&&e.imageUrl,e&&e.portrait&&e.portrait.href,e&&e.img&&e.img.href,e&&e.img&&e.img.url,e&&e.imgUrl].filter(e=>"string"==typeof e&&e.trim());for(const e of t){const t=T(e);if(t)return t}return null}function T(e){const t=String(e||"").trim();return t?/^https?:\/\/file\.wolfery\.com\/core\/char\/avatar\//i.test(t)?B(t):/^https?:\/\/file\.wolfery\.com\/core\/char\/img\//i.test(t)?B(t.replace(/\/core\/char\/img\//i,"/core/char/avatar/")):/^\/core\/char\/avatar\//i.test(t)?B("https://file.wolfery.com"+t):/^\/core\/char\/img\//i.test(t)?B("https://file.wolfery.com"+t.replace(/\/core\/char\/img\//i,"/core/char/avatar/")):/^[a-z0-9]+$/i.test(t)?`https://file.wolfery.com/core/char/avatar/${t}?thumb=l`:/\/char\/avatar\//i.test(t)?B(t):/\/char\/img\//i.test(t)?B(t.replace(/\/char\/img\//i,"/char/avatar/")):null:null}function B(e){const t=String(e||"").replace(/[?&]thumb=[^&]+/gi,"");return t+(t.includes("?")?"&thumb=l":"?thumb=l")}function L(t){return c[t]?c[t]:c.soundDefault?c.soundDefault:e}async function O(e){if(!e)return null;const t={name:String(e.name||"").trim(),charId:null!=e.charId?String(e.charId):null,avatar:e.avatar||null,sound:e.sound||null,alwaysPlay:!!e.alwaysPlay},n=await async function(e){const t=v("player"),n=v("charsAwake"),a=t&&"function"==typeof t.getActiveChar?t.getActiveChar():null,r=A(["function"==typeof t?.getChars?t.getChars():null,a?.inRoom?.chars||null,"function"==typeof n?.getCollection?n.getCollection():null]);if(e.charId){const t=r.find(t=>String(t?.id)===String(e.charId));if(t)return N(t)}if(e.name){const t=(await x(e.name)).find(t=>h(t.name)===h(e.name));if(t)return t}return null}(t);return n?{...t,name:n.name||t.name,charId:n.charId||t.charId,avatar:n.avatar||t.avatar}:t}function P(e){const t=e.target;if(!(t instanceof HTMLImageElement))return;if(!t.classList.contains("audio-notifier-char-row-avatar"))return;const n=t.closest(".audio-notifier-char-row");if(!(n instanceof HTMLElement))return;const a=n.dataset.entryKey||"";let r=a?c.charSounds[a]:null;r||(r=D(n)),r&&O(r).then(e=>{if(!e)return;const o=a||(r.charId?f(r.charId):p(r.name)),i=e.charId?f(e.charId):p(e.name||o);o!==i&&delete c.charSounds[o],c.charSounds[i]=e,g(),M(n,i,e),e.avatar&&t.src!==e.avatar&&(t.src=e.avatar)}).catch(e=>{console.debug("[AudioNotifier] Failed to refresh avatar after image error",e)})}function D(e){const t=e.dataset.charId||"",n=e.dataset.charName||"";if(t){const e=c.charSounds[f(t)];if(e)return e}if(n){const e=c.charSounds[p(n)];if(e)return e}return null}function W(){document.querySelectorAll(".audio-notifier-char-row").forEach(e=>{if(!(e instanceof HTMLElement))return;const t=e.dataset.entryKey||"",n=c.charSounds[t]||D(e);if(!n)return;M(e,n.charId?f(n.charId):p(n.name||t),n)})}function M(e,t,n){e.dataset.entryKey=t,e.dataset.charId=n.charId?String(n.charId):"",e.dataset.charName=n.name||"";const a=e.querySelector(".audio-notifier-char-row-title");a&&(a.textContent=n.name||t);const r=e.querySelector(".audio-notifier-char-row-avatar");r instanceof HTMLImageElement&&n.avatar&&(r.src=n.avatar,r.alt=n.name||t)}function z(t,n=!1){const r=Date.now();if(n||!(r-a<1e3)){n||(a=r);try{const n=new Audio(t||e);n.volume=.5,n.play().catch(e=>{console.error("[AudioNotifier] Playback failed. Browser blocking autoplay?",e)})}catch(e){console.error("[AudioNotifier] Invalid audio source",e)}}}document.addEventListener("click",function e(){new Audio("data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA").play().catch(()=>{}),document.removeEventListener("click",e)},{once:!0}),window.addEventListener("beforeunload",function(){if(m&&"function"==typeof m.dispose)try{m.dispose()}catch(e){console.debug("[AudioNotifier] Failed to dispose custom UI",e)}m=null}),setTimeout(function e(){if(r++,void 0===window.app)return void(r<60&&setTimeout(e,500));const t=v("charLog");t?(o||(!function(){const e=navigator.language.startsWith("de");C({title:e?"Audio Notifier (Benutzerskript)":"Audio Notifier (Userscript)",tabTitle:e?"Audio Notifier öffnen":"Open Audio Notifier",muteWhenFocused:e?"Ton deaktivieren, wenn das Fenster fokussiert ist":"Disable sound when the window is focused",muteForActiveChar:e?"Ton für aktiven Charakter deaktivieren (Ignoriert bei Fokusverlust)":"Disable sound for active character (Ignored if window loses focus)",playOnFocusCmd:e?"Ton abspielen, wenn fokussierter Charakter schreibt (/focus)":"Play sound when a focused character writes (/focus)",hdrDefault:e?"1. Standard-Sound":"1. Default Sound",soundDefault:e?"Allgemeiner Ton":"Global Default Sound",hdrCategories:e?"2. Spezifische Kategorien (Optional)":"2. Specific Categories (Optional)",soundMention:e?"Erwähnungen":"Mentions",soundPrivate:e?"Private Nachrichten":"Private Messages",soundFocusChar:e?"Fokussierte Charaktere":"Focused characters",hdrCharSounds:e?"3. Sound pro Charakter":"3. Per-character sounds",charSearchPlaceholder:e?"Name suchen...":"Search name...",searchBtn:e?"Suchen":"Search",chooseBtn:"Sound",uploadBtn:e?"Wählen":"Browse",replaceBtn:e?"Neu":"Replace",testBtn:"▶️",resetBtn:"✖",closeBtn:e?"Schließen":"Close",sizeWarning:e?"Datei zu groß (max 1MB).":"File too large (max 1MB).",noResults:e?"Keine Treffer":"No results",searching:e?"Suche...":"Searching...",searchHint:e?"Suche per Name, speichere ID + Avatar.":"Search by name, store ID + avatar.",alwaysPlay:e?"Immer":"Always",byId:"ID",byName:"Name",noSound:e?"Kein Sound":"No sound"})}(),o=!0),i||(!function(e){e.addEventModifier({id:"userscriptSoundNotifier",sortOrder:50,callback:(e,t,n)=>{if(n.muted)return;if(e.char&&e.char.id===t.id)return;const a=document.hasFocus();if(c.muteWhenWindowFocused&&a)return;if(c.muteForActiveChar&&a){const e=v("player"),n=e&&"function"==typeof e.getActiveChar?e.getActiveChar():null;if(n&&n.id===t.id)return}let r=function(e){if(!e)return null;const t=null!=e.id?String(e.id):null;if(t){const e=f(t);if(c.charSounds[e])return e}const n=h(`${e.name||""} ${e.surname||""}`.trim()),a=h(e.name||"");return Object.keys(c.charSounds).find(e=>{const r=c.charSounds[e];if(!r)return!1;if(r.charId&&t&&String(r.charId)===t)return!0;const o=h(r.name||e.replace(/^name:/,""));return o&&(o===n||o===a)})||null}(e.char);r&&e.char&&(r=function(e,t){const n=c.charSounds[e];if(!n||!t)return e;const a=`${t.name||""} ${t.surname||""}`.trim()||n.name,r=null!=t.id?String(t.id):n.charId,o=F(t)||n.avatar;if(n.name=a,n.charId=r,n.avatar=o,r){const t=f(r);if(t!==e)return c.charSounds[t]={...n},delete c.charSounds[e],g(),t}return g(),e}(r,e.char));const o=r?c.charSounds[r]:null;let i=!1,l=null;if(o&&o.alwaysPlay&&o.sound&&function(e){return["say","pose","ooc","whisper","message","address"].includes(e.type)}(e)&&(i=!0,l=o.sound),!i&&n.mentioned&&(i=!0,l=L("soundMention")),!i&&function(e,t,n){return!!["whisper","message","address"].includes(e.type)&&(!!n.targeted||(!(!e.target||e.target.id!==t.id)||!!Array.isArray(e.targets)&&e.targets.some(e=>e&&e.id===t.id)))}(e,t,n)&&(i=!0,l=L("soundPrivate")),!i&&c.playOnFocusedChar&&e.char){const n=v("charFocus");n&&"function"==typeof n.hasFocus&&n.hasFocus(t.id,e.char.id)&&(i=!0,l=L("soundFocusChar"))}i&&o&&o.sound&&(l=o.sound),i&&z(l)}})}(t),i=!0),s||(s=!0,function(){const e=Object.entries(c.charSounds||{});if(!e.length)return;Promise.all(e.map(async([e,t])=>{const n=await O(t);return n?[e,n]:null})).then(e=>{let t=!1;for(const n of e){if(!n)continue;const[e,a]=n,r=a.charId?f(a.charId):p(a.name||e),o=JSON.stringify(c.charSounds[e]||null),i=JSON.stringify(a);e!==r&&(delete c.charSounds[e],t=!0),o==i&&c.charSounds[r]||(c.charSounds[r]=a,t=!0)}t&&g(),W()}).catch(e=>{console.debug("[AudioNotifier] Failed to refresh stored character metadata",e)})}()),d||(d=!0,document.addEventListener("error",P,!0),setTimeout(W,1200))):r<60&&setTimeout(e,500)},1e3);})();