(()=>{
  if(window.__PULSE_PAGE_BRIDGE_INIT__){
    try{window.postMessage({src:"PULSE_PAGE",type:"PULSE_READY",app:"PULSE"},location.origin)}catch{}
    return;
  }
  window.__PULSE_PAGE_BRIDGE_INIT__=true;
  const INFLIGHT=new Map;
  function toBase64(bytes){let s="";for(let i=0;i<bytes.length;i+=32768)s+=String.fromCharCode(...bytes.subarray(i,i+32768));return btoa(s)}
  function isApi(path){return typeof path==="string"&&path.startsWith("/api/")}
  function hasHeader(headers,name){if(!headers)return false;const target=name.toLowerCase();for(const key of Object.keys(headers))if(key.toLowerCase()===target)return true;return false}
  function dropHeader(headers,name){if(!headers)return;const target=name.toLowerCase();for(const key of Object.keys(headers))if(key.toLowerCase()===target)delete headers[key]}
  const NO_REQID=[/^\/api\/chatList\/chatListByUserID\b/i,/^\/api\/chatList\/userDetail\b/i,/^\/api\/chatList\/lastMessage\b/i,/^\/api\/chatList\/chatHistory\b/i,/^\/api\/chatList\/chatUidByProfileAndUserIds\b/i];
  const shouldAddReqId=path=>isApi(path)&&!NO_REQID.some(rx=>rx.test(path));
  const fromBase64=b64=>{const raw=atob(b64),out=new Uint8Array(raw.length);for(let i=0;i<raw.length;i++)out[i]=raw.charCodeAt(i);return out};
  try{window.postMessage({src:"PULSE_PAGE",type:"PULSE_READY",app:"PULSE"},location.origin)}catch{}
  window.addEventListener("message",async ev=>{
    const msg=ev.data;
    if(!msg||msg.src!=="PULSE_SW"||msg.app!=="PULSE")return;
    if(msg.type==="PULSE_PING"){
      try{window.postMessage({src:"PULSE_PAGE",type:"PULSE_READY",app:"PULSE"},location.origin)}catch{}
      return;
    }
    if(msg.type==="PULSE_FETCH_CANCEL"&&msg.id){
      const job=INFLIGHT.get(msg.id);
      if(job){
        try{job.ctrl.abort("cancelled")}catch{}
        clearTimeout(job.killer);
        INFLIGHT.delete(msg.id);
      }
      return;
    }
    if(msg.type!=="PULSE_FETCH_REQ")return;
    const {id,path,method="GET",headers={},bodyBase64=null,timeoutMs,referer=null}=msg;
    try{
      const reqHeaders={...headers};
      if(isApi(path)&&!hasHeader(reqHeaders,"Accept"))reqHeaders.Accept="application/json, text/plain, */*";
      if(shouldAddReqId(path)&&!hasHeader(reqHeaders,"X-Request-Id"))reqHeaders["X-Request-Id"]="-"+"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,c=>{const r=Math.random()*16|0;return (c==="x"?r:(r&3)|8).toString(16)});
      if(String(method).toUpperCase()==="GET")dropHeader(reqHeaders,"Content-Type");
      dropHeader(reqHeaders,"Referer");
      const ctrl=new AbortController();
      const killer=setTimeout(()=>{try{ctrl.abort("timeout")}catch{}},Math.max(500,Number(timeoutMs)||5000));
      INFLIGHT.set(id,{ctrl,killer});
      const init={method,headers:reqHeaders,credentials:"include",signal:ctrl.signal};
      if(bodyBase64) init.body=new TextDecoder().decode(fromBase64(bodyBase64));
      if(referer) init.referrer=referer;
      const res=await fetch("https://alpha.date"+path,init);
      const body=new Uint8Array(await res.arrayBuffer());
      clearTimeout(killer);
      INFLIGHT.delete(id);
      window.postMessage({src:"PULSE_PAGE",type:"PULSE_FETCH_RES",app:"PULSE",id,ok:true,status:res.status,headers:Object.fromEntries(res.headers.entries()),bodyBase64:toBase64(body)},location.origin);
    }catch(err){
      const job=INFLIGHT.get(id);
      if(job){
        clearTimeout(job.killer);
        INFLIGHT.delete(id);
      }
      window.postMessage({src:"PULSE_PAGE",type:"PULSE_FETCH_RES",app:"PULSE",id,ok:false,error:String(err)},location.origin);
    }
  });
})();


;(function(){
  if (window.__PULSE_USERDETAIL_HOOK__) return;
  window.__PULSE_USERDETAIL_HOOK__ = true;

  const MAX_USER_DETAILS_STORE = 250;

  function getCurrentChatUidFromLocation() {
    try {
      const segments = String(location.pathname || '').split('/').filter(Boolean);
      const last = segments[segments.length - 1] || '';
      return /^[a-z0-9-]+$/i.test(last) ? last : '';
    } catch {
      return '';
    }
  }

  function pruneUserDetailsStore(store, preferredChatUid = '') {
    try {
      const keys = Object.keys(store || {});
      if (keys.length <= MAX_USER_DETAILS_STORE) return store;
      const keep = new Set(keys.slice(-MAX_USER_DETAILS_STORE));
      const preferred = String(preferredChatUid || '').trim();
      if (preferred && store && store[preferred]) keep.add(preferred);
      const next = {};
      for (const key of keys) {
        if (keep.has(key) && store[key]) next[key] = store[key];
      }
      return next;
    } catch {
      return store;
    }
  }

  window.addEventListener('message', (event) => {
    try {
      if (event.source !== window) return;
      if (!event.data || event.data.type !== 'REQUEST_USER_DETAILS_DATA') return;

      const rawStore =
        window.__alphaFinderUserDetails && typeof window.__alphaFinderUserDetails === 'object'
          ? window.__alphaFinderUserDetails
          : {};
      const store = pruneUserDetailsStore(rawStore, getCurrentChatUidFromLocation());
      if (store !== rawStore) window.__alphaFinderUserDetails = store;

      window.postMessage(
        { type: 'USER_DETAILS_DATA', userDetails: store },
        location.origin
      );
    } catch {}
  });

  function mergeUserDetailsFromPayload(payload){
    try{
      const arr = Array.isArray(payload?.response) ? payload.response : [];
      if (!arr.length) return;
      const store = window.__alphaFinderUserDetails && typeof window.__alphaFinderUserDetails === 'object' ? window.__alphaFinderUserDetails : {};
      for (const item of arr) {
        const chatUid = item?.chat_uid || item?.chatUid || item?.chat_id || item?.uid;
        if (!chatUid) continue;
        store[chatUid] = item;
      }
      const prunedStore = pruneUserDetailsStore(store, getCurrentChatUidFromLocation());
      window.__alphaFinderUserDetails = prunedStore;
      try { window.postMessage({ type:'USER_DETAILS_DATA', userDetails: prunedStore }, location.origin); } catch {}
    } catch {}
  }

  function tryParseAndStore(text){
    try{
      const payload = JSON.parse(text);
      mergeUserDetailsFromPayload(payload);
    }catch{}
  }

  const origFetch = window.fetch;
  if (typeof origFetch === 'function') {
    window.fetch = async function(...args){
      const res = await origFetch.apply(this, args);
      try {
        const url = String((args[0] && args[0].url) || args[0] || '');
        if (/\/api\/chatList\/userDetail\b/i.test(url)) {
          res.clone().text().then(tryParseAndStore).catch(()=>{});
        }
      } catch {}
      return res;
    };
  }

  const origOpen = XMLHttpRequest.prototype.open;
  const origSend = XMLHttpRequest.prototype.send;
  XMLHttpRequest.prototype.open = function(method, url, ...rest){
    try { this.__pulseUserDetailUrl = String(url || ''); } catch {}
    return origOpen.call(this, method, url, ...rest);
  };
  XMLHttpRequest.prototype.send = function(body){
    try {
      if (/\/api\/chatList\/userDetail\b/i.test(String(this.__pulseUserDetailUrl || ''))) {
        this.addEventListener('load', function(){
          tryParseAndStore(this.responseText);
        }, { once:true });
      }
    } catch {}
    return origSend.call(this, body);
  };
})();


;(function(){
  if (window.__PULSE_FINDER_CONTEXT__) return;
  window.__PULSE_FINDER_CONTEXT__ = true;
  const ORIGIN = location.origin;
  const post = (msg) => { try { window.postMessage(Object.assign({src:'PULSE_PAGE',app:'PULSE'}, msg), ORIGIN); } catch {} };
  const getRawToken = () => {
    try {
      const t = localStorage.getItem('token');
      return t ? String(t) : null;
    } catch { return null; }
  };
  const getBearer = (raw) => {
    const t = String(raw || '').trim();
    if (!t) return null;
    return t.startsWith('Bearer ') ? t : ('Bearer ' + t);
  };
  let lastKnownToken = null;
  let lastProfilesHash = '';
  let profileFetchTimer = null;
  let socket = null;
  let isConnecting = false;
  let reconnectTimer = null;
  let reconnectAttempts = 0;
  let currentToken = null;
  let currentProfiles = [];
  let currentChannels = [];
  const handlers = new Map();
  let finderControl = { ahRunning: false, ahSetRunning: false, likesEnabled: false };

  function persistState(status, extra){ post({ type:'PULSE_FINDER_SOCKET_STATUS', status, extra: extra || null }); }
  function isFinderAllowed(){ return !!(finderControl && finderControl.ahRunning && finderControl.ahSetRunning && finderControl.likesEnabled); }
  function applyFinderControl(next){
    finderControl = Object.assign({}, finderControl, next || {});
    if (!isFinderAllowed()) disconnect();
  }

  async function fetchProfiles(rawToken){
    const bearer = getBearer(rawToken);
    if (!bearer) return [];
    try {
      const res = await fetch('https://alpha.date/api/operator/profiles', {
        method: 'GET',
        headers: { 'Authorization': bearer, 'Accept': 'application/json, text/plain, */*' },
        credentials: 'include'
      });
      if (!res.ok) throw new Error('profiles HTTP ' + res.status);
      const data = await res.json().catch(() => null);
      const profiles = Array.isArray(data) ? data : [];
      const hash = JSON.stringify(profiles.map(p => [p && p.id, p && p.external_id, p && p.name, p && p.online]));
      if (hash !== lastProfilesHash) {
        lastProfilesHash = hash;
        currentProfiles = profiles;
        post({ type:'PULSE_FINDER_PROFILES', profiles });
        resubscribeProfiles();
      }
      return profiles;
    } catch (e) {
      post({ type:'PULSE_FINDER_ERROR', scope:'profiles', message: String(e && e.message || e) });
      return [];
    }
  }

  function clearReconnect(){ if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; } }
  function disconnect(){ clearReconnect(); if (socket) { try { socket.close(); } catch {} } socket = null; isConnecting = false; }
  function scheduleReconnect(){
    if (!isFinderAllowed()) return;
    if (reconnectTimer || !currentToken) return;
    reconnectAttempts += 1;
    const delay = 3000 * Math.min(reconnectAttempts, 5);
    persistState('reconnecting', { delay, attempt: reconnectAttempts });
    reconnectTimer = setTimeout(() => { reconnectTimer = null; connect(); }, delay);
  }
  function subscribe(channel, handler){
    if (!handlers.has(channel)) handlers.set(channel, new Set());
    handlers.get(channel).add(handler);
    return () => {
      const s = handlers.get(channel);
      if (!s) return;
      s.delete(handler);
      if (!s.size) handlers.delete(channel);
    };
  }
  function handleMessage(rawData){
    try {
      let data = rawData;
      if (typeof data === 'string') {
        const match = data.match(/^(\d+)(.*)$/);
        if (match) {
          const prefix = match[1];
          const jsonPart = match[2];
          if (prefix === '2' || prefix === '3') return;
          if (jsonPart && (jsonPart.startsWith('[') || jsonPart.startsWith('{'))) data = JSON.parse(jsonPart); else return;
        } else if (data.startsWith('[') || data.startsWith('{')) {
          data = JSON.parse(data);
        } else return;
      }
      if (Array.isArray(data) && data.length >= 2) {
        const channel = data[0];
        const payload = data[1];
        if (typeof channel === 'string' && handlers.has(channel)) {
          handlers.get(channel).forEach((handler) => { try { handler(payload, channel); } catch (e) {} });
        }
      }
    } catch (e) {
      post({ type:'PULSE_FINDER_ERROR', scope:'socket_parse', message: String(e && e.message || e) });
    }
  }
  let activeProfileUnsubs = [];
  function resubscribeProfiles(){
    for (const off of activeProfileUnsubs) {
      try { off(); } catch {}
    }
    activeProfileUnsubs = [];
    currentChannels = Array.isArray(currentProfiles) ? currentProfiles.map(p => 'counters_profile_' + p.external_id).filter(Boolean) : [];
    post({ type:'PULSE_FINDER_SOCKET_CHANNELS', channels: currentChannels });
    for (const ch of currentChannels) {
      const off = subscribe(ch, (payload, channel) => {
        post({ type:'PULSE_FINDER_SOCKET_EVENT', channel, payload });
      });
      activeProfileUnsubs.push(off);
    }
  }
  function connect(){
    if (!isFinderAllowed()) return;
    if (!currentToken) return;
    if (isConnecting || (socket && socket.readyState === WebSocket.OPEN)) return;
    isConnecting = true;
    const wsUrl = `wss://alpha.date/api/v3/socket/ws/?token=${currentToken}&EIO=3&transport=websocket`;
    persistState('connect_start', { wsUrl });
    try {
      socket = new WebSocket(wsUrl);
      socket.onopen = () => {
        isConnecting = false;
        reconnectAttempts = 0;
        persistState('connected');
      };
      socket.onmessage = (event) => handleMessage(event.data);
      socket.onerror = (event) => {
        persistState('error', { message: 'socket_error' });
        post({ type:'PULSE_FINDER_ERROR', scope:'socket', message:'socket_error' });
      };
      socket.onclose = (event) => {
        socket = null;
        isConnecting = false;
        persistState('disconnected', { code: event && event.code, reason: event && event.reason || '' });
        scheduleReconnect();
      };
    } catch (e) {
      socket = null;
      isConnecting = false;
      persistState('error', { message: String(e && e.message || e) });
      scheduleReconnect();
    }
  }
  async function refreshContext(){
    if (!isFinderAllowed()) {
      disconnect();
      return;
    }
    const raw = getRawToken();
    if (raw && raw !== lastKnownToken) {
      lastKnownToken = raw;
      currentToken = raw.startsWith('Bearer ') ? raw.slice(7) : raw;
      post({ type:'TOKEN_UPDATED', token: currentToken });
      disconnect();
      await fetchProfiles(raw);
      connect();
      return;
    }
    if (raw) await fetchProfiles(raw);
  }

  // initial + watcher logic, like Finder
  refreshContext();
  const originalSetItem = localStorage.setItem.bind(localStorage);
  localStorage.setItem = function(key, value){
    originalSetItem(key, value);
    if (key === 'token' && value !== lastKnownToken) {
      lastKnownToken = value;
      currentToken = String(value || '').startsWith('Bearer ') ? String(value || '').slice(7) : value;
      post({ type:'TOKEN_UPDATED', token: currentToken });
      disconnect();
      fetchProfiles(value).finally(connect);
    }
  };
  setInterval(refreshContext, 5000);
  window.addEventListener('storage', (event) => {
    if (event.key === 'token' && event.newValue !== lastKnownToken) {
      lastKnownToken = event.newValue;
      currentToken = String(event.newValue || '').startsWith('Bearer ') ? String(event.newValue || '').slice(7) : event.newValue;
      post({ type:'TOKEN_UPDATED', token: currentToken });
      disconnect();
      fetchProfiles(event.newValue).finally(connect);
    }
  });
  window.addEventListener('message', (event) => {
    const msg = event.data;
    if (!msg || msg.src !== 'PULSE_SW' || msg.app !== 'PULSE') return;
    if (msg.type === 'PULSE_FINDER_CONTROL_STATE') {
      applyFinderControl({
        ahRunning: !!msg.ahRunning,
        ahSetRunning: !!msg.ahSetRunning,
        likesEnabled: !!msg.likesEnabled
      });
      if (isFinderAllowed()) refreshContext();
      return;
    }
    if (msg.type === 'PULSE_FINDER_REFRESH_CONTEXT') refreshContext();
  });
})();
