📦 Depot

Popmundo envanter paneli — çok dilli arayüz, otomatik tarama, arama, fiyat takibi ve CSV

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

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

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

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

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

You will need to install a user script manager extension to install this script.

(Tôi đã có Trình quản lý tập lệnh người dùng, hãy cài đặt nó!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         📦 Depot
// @name:en      📦 Depot
// @name:pt-BR   📦 Depot
// @namespace    popmundo.inventory
// @version      2.1
// @description  Popmundo envanter paneli — çok dilli arayüz, otomatik tarama, arama, fiyat takibi ve CSV
// @description:en  Popmundo inventory panel — multilingual UI, auto-scan, search, price tracking & CSV export
// @description:pt-BR Painel de inventário Popmundo — multilíngue, varredura automática, busca, preços e CSV
// @author       luke-james-gibson
// @license      MIT
// @id           dpv9q3
// @supportURL   https://greasyfork.org/tr/scripts/568770-popmundo-envanter
// @match        https://*.popmundo.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_deleteValue
// @grant        unsafeWindow
// ==/UserScript==

(function () {
    'use strict';

    // ─── POPCONTROL DISABLE CHECK ────────────────────────────────────────────────
    try { const _ppc = JSON.parse(localStorage.getItem('ppc_enabled')||'{}'); if (_ppc['depot'] === false) return; } catch {}

    // Language
    const LANG = (() => { try { const c = document.cookie.match(/ppm_lang=([^;]+)/); return c ? c[1] : 'TR'; } catch { return 'TR'; } })();
    const _D = (tr, en, pt) => ({ TR: tr, EN: en, 'PT-BR': pt }[LANG] || tr);
    const S = {
        // Scan modal
        scanTitle:       _D('🔄 Otomatik Tarama',              '🔄 Auto Scan',                          '🔄 Varredura Automática'),
        scanPersonal:    _D('👤 Kişisel Eşyalar',              '👤 Personal Items',                     '👤 Itens Pessoais'),
        scanVehicles:    _D('🚗 Kişisel Araçlar',              '🚗 Personal Vehicles',                  '🚗 Veículos Pessoais'),
        scanHousing:     _D('🏠 Evler',                        '🏠 Housing',                            '🏠 Moradias'),
        scanArtist:      _D('🎵 Sanatçı / Turne Aracı',       '🎵 Artist / Tour Vehicle',              '🎵 Artista / Veículo de Turnê'),
        scanWarn:        _D('⚠️ Tarama sırasında sekmeler otomatik değişir.', '⚠️ Tabs will change automatically during scan.', '⚠️ As abas mudarão automaticamente durante a varredura.'),
        scanCancel:      _D('İptal',                           'Cancel',                                'Cancelar'),
        scanStart:       _D('▶ Taramayı Başlat',               '▶ Start Scan',                          '▶ Iniciar Varredura'),
        scanSelectOne:   _D('En az bir kategori seçin.',       'Select at least one category.',         'Selecione pelo menos uma categoria.'),
        // Scan report
        scanDone:        _D('✅ Tarama Tamamlandı',             '✅ Scan Complete',                      '✅ Varredura Concluída'),
        scanLocCount:    _D('Taranan Lokasyon:',               'Scanned Locations:',                    'Locais Varridos:'),
        scanItemCount:   _D('Toplam Eşya:',                    'Total Items:',                          'Total de Itens:'),
        scanClose:       _D('Kapat',                           'Close',                                 'Fechar'),
        // Scan prompts / logs
        scanAskId:       _D('Karakter ID girin:',              'Enter Character ID:',                   'Digite o ID do Personagem:'),
        scanBadId:       _D('Geçerli ID girilmedi.',           'No valid ID entered.',                  'Nenhum ID válido inserido.'),
        scanVehList:     _D('🔍 Araç listesi:',                '🔍 Vehicle list:',                      '🔍 Lista de veículos:'),
        scanVehUnit:     _D('araç.',                           'vehicles.',                             'veículos.'),
        scanHouseList:   _D('🔍 Ev listesi:',                  '🔍 Housing list:',                      '🔍 Lista de moradias:'),
        scanHouseUnit:   _D('ev.',                             'properties.',                           'imóveis.'),
        scanLogOk:       _D('çeşit.',                          'types.',                                'tipos.'),
        scanLogEmpty:    _D('eşya yok.',                       'no items.',                             'sem itens.'),
        scanStop:        _D('🛑 DURDUR',                       '🛑 STOP',                               '🛑 PARAR'),
        // Panel
        panelTitle:      '📦 Depot ' + GM_info.script.version,
        dragHint:        _D('⠿ Sürükle',                      '⠿ Drag',                                '⠿ Arrastar'),
        btnSettings:     _D('Panel Ayarları',                 'Panel Settings',                        'Configurações do Painel'),
        btnBackup:       _D('📤 Scripti Yedekle',              '📤 Backup Script',                      '📤 Fazer Backup'),
        btnRestore:      _D('📥 Yedeği Yükle',                 '📥 Load Backup',                        '📥 Carregar Backup'),
        catLabel:        _D('Kategori CSV (Kategori,Eşya):',   'Category CSV (Category,Item):',         'CSV de Categorias (Categoria,Item):'),
        catPlaceholder:  _D('Kategori,Eşya Adı',               'Category,Item Name',                    'Categoria,Nome do Item'),
        btnCatSave:      _D('💾 Kategorileri Güncelle',        '💾 Update Categories',                  '💾 Atualizar Categorias'),
        btnClearAll:     _D('⚠️ Tüm Veriyi Sıfırla',          '⚠️ Reset All Data',                     '⚠️ Redefinir Todos os Dados'),
        btnSavePage:     _D('📍 Sayfayı Kaydet',               '📍 Save Page',                          '📍 Salvar Página'),
        btnDelRecord:    _D('🗑️ Kaydı Sil',                   '🗑️ Delete Record',                     '🗑️ Excluir Registro'),
        btnInventory:    _D('Envanter İşlemleri',             'Inventory Actions',                     'Ações de Inventário'),
        btnAutoScan:     _D('🔄 OTOMATİK TARA',                '🔄 AUTO SCAN',                          '🔄 VARREDURA AUTOMÁTICA'),
        btnListManage:   _D('📋 ENVANTERLERİ LİSTELE / YÖNET','📋 LIST / MANAGE INVENTORIES',          '📋 LISTAR / GERENCIAR INVENTÁRIOS'),
        btnDetailed:     _D('📄 Detaylı CSV',                  '📄 Detailed CSV',                       '📄 CSV Detalhado'),
        btnStockCSV:     _D('📊 Stok & Fiyatlı CSV',           '📊 Stock & Priced CSV',                 '📊 CSV de Estoque & Preços'),
        btnImportCSV:    _D('📥 CSV Yükle',                    '📥 Import CSV',                         '📥 Importar CSV'),
        searchPH:        _D('Envanterde ara (Örn: Haiku)...',  'Search inventory (e.g. Haiku)...',      'Buscar no inventário (ex: Haiku)...'),
        // Alerts
        alertNoItems:    _D('Bu sayfada eşya bulunamadı.',     'No items found on this page.',          'Nenhum item encontrado nesta página.'),
        alertDeleted:    _D('Silindi.',                        'Deleted.',                              'Excluído.'),
        alertNotFound:   _D('Kayıt bulunamadı.',               'Record not found.',                     'Registro não encontrado.'),
        alertEnterData:  _D('Veri girin.',                     'Enter data.',                           'Insira os dados.'),
        alertCatFmt:     _D("Format hatalı! 'Kategori,Eşya'", "Invalid format! 'Category,Item'",       "Formato inválido! 'Categoria,Item'"),
        alertClearConf:  _D('Tüm DB sıfırlanacak!',           'All data will be reset!',               'Todos os dados serão redefinidos!'),
        alertRestored:   _D('Geri yüklendi.',                  'Restored.',                             'Restaurado.'),
        alertInvalidFile:_D('Geçersiz dosya.',                 'Invalid file.',                         'Arquivo inválido.'),
        // List
        listEmpty:       _D('Veritabanı boş.',                 'Database empty.',                       'Banco de dados vazio.'),
        btnDelAll:       _D('Tümünü Sil',                      'Delete All',                            'Excluir Tudo'),
        btnDel:          _D('SİL',                             'DEL',                                   'EXC'),
        confirmDel:      _D('Bu kayıt silinsin mi?',           'Delete this record?',                   'Excluir este registro?'),
        // Search
        noResults:       _D('Sonuç bulunamadı.',               'No results found.',                     'Nenhum resultado encontrado.'),
        totalLabel:      _D('Toplam',                          'Total',                                 'Total'),
        lastScanLabel:   _D('Son tarama:',                     'Last scan:',                            'Última varredura:'),
        btnCopy:         _D('📋 Bu sonuçları kopyala',         '📋 Copy these results',                 '📋 Copiar estes resultados'),
        btnCopied:       _D('✅ Kopyalandı',                   '✅ Copied',                             '✅ Copiado'),
        noPriceLabel:    _D('Teklif ediniz',                   'Make an offer',                         'Consultar preço'),
        // clsLbl
        clsPersonal:     _D('Eşyalar',                         'Items',                                 'Itens'),
        clsVehicle:      _D('Kişisel Araç',                    'Personal Vehicle',                      'Veículo Pessoal'),
        clsHousing:      _D('Ev',                              'Housing',                               'Moradia'),
        clsArtist:       _D('Sanatçı Aracı',                   'Artist Vehicle',                        'Veículo do Artista'),
        minTooltip:      _D('Paneli aç',                       'Open panel',                            'Abrir painel'),
        btnMinimize:     _D('Küçült',                          'Minimize',                              'Minimizar'),
        btnClose:        _D('Kapat',                           'Close',                                 'Fechar'),
        // Loc name fallbacks
        locVehicleFb:    _D('Kişisel Araç',                    'Personal Vehicle',                      'Veículo Pessoal'),
        locLocaleFb:     _D('Mekan',                           'Locale',                                'Local'),
        locCharFb:       _D('Karakter',                        'Character',                             'Personagem'),
        locInvSuffix:    _D('Envanteri',                       'Inventory',                             'Inventário'),
        locArtistFb:     _D('Grup Aracı',                      'Artist Vehicle',                        'Veículo do Artista'),
        locUnknown:      _D('Bilinmeyen',                      'Unknown',                               'Desconhecido'),
        variantDefault:  _D('Standart',                        'Standard',                              'Padrão'),
    };
    const _clDepot = (() => { try { const v = localStorage.getItem('ppc_lc_depot'); return v ? JSON.parse(v) : null; } catch { return null; } })();
    const s = k => (_clDepot && _clDepot[k]) ? _clDepot[k] : (S[k] || k);

    // GM Storage helpers
    const gmGet  = (k,def) => { try { const v=GM_getValue(k,null); return v?JSON.parse(v):def; } catch { return def; } };
    const gmSet  = (k,v)   => GM_setValue(k, JSON.stringify(v));
    const gmDel  = (k)     => GM_deleteValue(k);

    // localStorage helpers (scan state only)
    const lsGet  = (k,def) => { try { const v=localStorage.getItem(k); return v?JSON.parse(v):def; } catch { return def; } };
    const lsSet  = (k,v)   => localStorage.setItem(k, JSON.stringify(v));
    const lsDel  = (k)     => localStorage.removeItem(k);

    // Storage keys
    const K = { db:'pop_inv_data', cat:'pop_cat_data', price:'pop_price_data', veh:'pop_vehicle_names', char:'pop_char_id', owner:'pop_owner_name', theme:'pop_theme', min:'pop_min', pw:'pop_panel_w', pos:'pop_panel_pos', posMin:'pop_panel_pos_min', scan:'pop_scan_state' };

    // DB cache
    let _db=null, _prices=null;
    const getDB      = ()  => _db     || (_db=gmGet(K.db,{}));
    const saveDB     = (v) => { _db=v;     gmSet(K.db,v); };
    const getPrices  = ()  => _prices || (_prices=gmGet(K.price,{}));
    const savePrices = (v) => { _prices=v; gmSet(K.price,v); };

    // Utilities
    const today     = ()    => { const d=new Date(); return `${String(d.getDate()).padStart(2,'0')}.${String(d.getMonth()+1).padStart(2,'0')}.${d.getFullYear()}`; };
    const getCats   = ()    => gmGet(K.cat,{Manuscripts:['Fıkra','Haiku'],Drugs:['Ağrı Kesici','Afrodizyak İksiri']});
    const saveCats  = (v)   => gmSet(K.cat,v);
    const getCat    = (n)   => { for (const [c,items] of Object.entries(getCats())) if (items.includes(n)) return c; return 'Diğer'; };
    const theme     = ()    => GM_getValue(K.theme,'')||'dark';
    const priceKey  = (n,v) => `${n}|||${v}`;
    const esc       = (v)   => String(v).replace(/&/g,'&').replace(/"/g,'"');
    const normV     = (v)   => v.replace(/\.\s*$/,'').trim();
    const dlCSV     = (content,name) => { const a=document.createElement('a'); a.href=URL.createObjectURL(new Blob([content],{type:'text/csv;charset=utf-8;'})); a.download=name; a.click(); };
    const randDelay = ()    => 2000 + Math.floor(Math.random()*1500);
    const getTitle  = ()    => document.title.replace(/^.*?Popmundo\s*[-–]\s*/i,'').trim();

    // Scan state
    const getScan  = ()    => lsGet(K.scan, {active:false,queue:[],index:0,logs:[]});
    const saveScan = (st)  => lsSet(K.scan, st);

    // Scan: sayfa ayrıştırma
    const getLocInfo = (u) => {
        if (u.includes('/Character/Vehicle/')) {
            const veh=gmGet(K.veh,{}), rel=u.replace(/^https?:\/\/[^/]+/,'');
            return { name:veh[u]||veh[rel]||getTitle()||s('locVehicleFb'), type:'Araç' };
        }
        if (u.includes('/Locale/ItemsEquipment/')) {
            const h2=document.querySelector('.localebox h2')?.innerText.trim();
            const city=document.querySelector('.localebox .right a')?.innerText.trim();
            return { name:h2?(city?`${h2} (${city})`:h2):(getTitle()||s('locLocaleFb')), type:'Mekan' };
        }
        if (u.includes('/Character/Items/')) {
            const n=document.querySelector('.charPresBox h2')?.innerText.trim()||getTitle();
            return { name:`${n||s('locCharFb')} ${s('locInvSuffix')}`, type:'Kişisel' };
        }
        if (u.includes('/Artist/VehicleItems/')) return { name:getTitle()||s('locArtistFb'), type:'Grup Aracı' };
        return { name:s('locUnknown'), type:'Genel' };
    };

    const getOwner = () => {
        const el=document.querySelector('.charPresBox h2');
        if (el) { const n=el.innerText.trim(); GM_setValue(K.owner,n); return n; }
        return GM_getValue(K.owner,'')||s('locCharFb');
    };

    const extractVariant = (anchor) => {
        const td=anchor.closest('td')||anchor.parentElement, clone=td.cloneNode(true);
        clone.querySelector('[id*="lnkItem"]')?.remove();
        clone.querySelectorAll('.tvip-item-id, .tvis-ia-wrap').forEach(el => el.remove());
        const cEm=Array.from(clone.querySelectorAll('em')).find(e=>/^x\d+/i.test(e.textContent.trim()));
        if (cEm) cEm.remove();
        return clone.textContent.replace(/\s+/g,' ').trim()||s('variantDefault');
    };

    const updatePage = () => {
        const u=window.location.href, info=getLocInfo(u), owner=getOwner(), db=getDB(), map={};
        document.querySelectorAll('tr.hoverable').forEach(row => {
            const a=row.querySelector('a[id*="lnkItem"]'); if (!a) return;
            const name=a.innerText.trim(), em=row.querySelector('em');
            const count=em&&/^x\d+/i.test(em.textContent.trim())?(parseInt(em.textContent.replace(/[^\d]/g,''))||1):1;
            const variant=extractVariant(a);
            if (!map[name]) map[name]={variants:{}};
            map[name].variants[variant]=(map[name].variants[variant]||0)+count;
        });
        const cnt=Object.keys(map).length;
        if (cnt>0) {
            if (!db[owner]) db[owner]={};
            db[owner][u]={locType:info.name,locClass:info.type,url:u,lastUpdate:today(),
                items:Object.entries(map).map(([n,d])=>({name:n,variants:d.variants}))};
            _db=db; saveDB(db);
        }
        return cnt;
    };

    // Scan: modal & rapor
    const ovStyle   = 'position:fixed;inset:0;background:rgba(0,0,0,.8);z-index:9999999;display:flex;align-items:center;justify-content:center;';
    const modalWrap = (inner) => '<div style="background:#1a1a1a;border-radius:10px;padding:24px;max-width:420px;width:92%;color:#e0e0e0;font-family:Arial,sans-serif;">'+inner+'</div>';

    const showScanModal = (onConfirm) => {
        const ov=document.createElement('div'); ov.style.cssText=ovStyle;
        ov.innerHTML=modalWrap(
            '<div style="font-size:15px;font-weight:bold;color:#3498db;margin-bottom:12px;">'+s('scanTitle')+'</div>'
            +'<div style="display:flex;flex-direction:column;gap:10px;margin-bottom:14px;">'
            +'<label style="display:flex;align-items:center;gap:8px;font-size:12px;cursor:pointer;"><input type="checkbox" id="sc-p" checked> '+s('scanPersonal')+'</label>'
            +'<label style="display:flex;align-items:center;gap:8px;font-size:12px;cursor:pointer;"><input type="checkbox" id="sc-v" checked> '+s('scanVehicles')+'</label>'
            +'<label style="display:flex;align-items:center;gap:8px;font-size:12px;cursor:pointer;"><input type="checkbox" id="sc-h" checked> '+s('scanHousing')+'</label>'
            +'<label style="display:flex;align-items:center;gap:8px;font-size:12px;cursor:pointer;"><input type="checkbox" id="sc-a" checked> '+s('scanArtist')+'</label>'
            +'</div>'
            +'<div style="font-size:10px;color:#aaa;background:#222;border-radius:4px;padding:8px;margin-bottom:14px;">'+s('scanWarn')+'</div>'
            +'<div style="display:flex;gap:8px;">'
            +'<button id="sc-cancel" style="flex:1;padding:10px;background:none;color:#dc3545;border:1px solid #dc3545;border-radius:5px;cursor:pointer;font-weight:bold;">'+s('scanCancel')+'</button>'
            +'<button id="sc-start" style="flex:2;padding:10px;background:#0056b3;color:white;border:none;border-radius:5px;cursor:pointer;font-weight:bold;">'+s('scanStart')+'</button>'
            +'</div>'
        );
        document.body.appendChild(ov);
        document.getElementById('sc-cancel').onclick=()=>ov.remove();
        document.getElementById('sc-start').onclick=()=>{
            const opts={personal:document.getElementById('sc-p').checked,vehicles:document.getElementById('sc-v').checked,housing:document.getElementById('sc-h').checked,artist:document.getElementById('sc-a').checked};
            if (!Object.values(opts).some(Boolean)){alert(s('scanSelectOne'));return;}
            ov.remove(); onConfirm(opts);
        };
    };

    const showScanReport = (state) => {
        const db=getDB(); let totI=0,totL=0;
        Object.values(db).forEach(od=>{totL+=Object.keys(od).length;Object.values(od).forEach(e=>e.items.forEach(it=>Object.values(it.variants).forEach(c=>{totI+=Number(c)||0;})));});
        const ov=document.createElement('div'); ov.style.cssText=ovStyle.replace('9999999','9999998');
        ov.innerHTML=modalWrap(
            '<div style="font-size:16px;font-weight:bold;color:#2ecc71;margin-bottom:12px;">'+s('scanDone')+'</div>'
            +'<div style="background:#222;border-radius:5px;padding:10px;margin-bottom:10px;font-size:13px;">'
            +'<div>'+s('scanLocCount')+' <b style="color:#2ecc71">'+totL+'</b></div>'
            +'<div>'+s('scanItemCount')+' <b style="color:#2ecc71">'+totI+'</b></div></div>'
            +'<div style="background:#222;border-radius:5px;padding:8px;max-height:180px;overflow-y:auto;font-size:11px;font-family:monospace;line-height:1.6;">'
            +state.logs.map(l=>'<div style="color:'+(l.startsWith('✅')?'#2ecc71':l.startsWith('⚠️')?'#f39c12':'#e74c3c')+'">'+l+'</div>').join('')
            +'</div><button id="sc-done" style="width:100%;margin-top:14px;padding:10px;background:#2ecc71;color:#111;border:none;border-radius:5px;cursor:pointer;font-weight:bold;">'+s('scanClose')+'</button>'
        );
        document.body.appendChild(ov);
        document.getElementById('sc-done').onclick=()=>{ov.remove();location.href=`${location.origin}/World/Popmundo.aspx/Character/${state.charId}`;};
    };

    // Scan: keşif & adım
    const discover = () => {
        const url=window.location.href, base=`${location.origin}/World/Popmundo.aspx`;
        let id=(url.match(/\/Character\/(?:Details|Items|Vehicles|Housing)\/(\d+)/)||[])[1]
            ||document.querySelector('a[href*="/Character/Details/"]')?.href.match(/\/(\d+)$/)?.[1]
            ||document.querySelector('a[href*="/Character/Items/"]')?.href.match(/\/(\d+)$/)?.[1]
            ||GM_getValue(K.char,'');
        if (!id){const inp=prompt(s('scanAskId'));if(inp&&/^\d+$/.test(inp.trim()))id=inp.trim();else{alert(s('scanBadId'));return;}}
        GM_setValue(K.char,id);
        showScanModal(opts=>{
            const q=[];
            if(opts.personal)q.push(`${base}/Character/Items/${id}`);
            if(opts.vehicles)q.push(`${base}/Character/Vehicles/${id}`);
            if(opts.housing) q.push(`${base}/Character/Housing/${id}`);
            if(opts.artist)  q.push(`${base}/Artist/VehicleItems/`);
            saveScan({active:true,queue:q,index:0,logs:[],charId:id});
            location.href=q[0];
        });
    };

    const runStep = () => {
        if (!window.location.href.includes('/World/Popmundo.aspx/')) return;
        let st=getScan(); if (!st.active) return;
        setTimeout(()=>{
            const u=window.location.href; let found=[];
            if (u.includes('Character/Vehicles/')) {
                const anchors=document.querySelectorAll('#tablevehicles a[href*="/Character/Vehicle/"]');
                const veh=gmGet(K.veh,{});
                anchors.forEach(a=>{if(a.href&&a.innerText.trim())veh[a.href]=a.innerText.trim();});
                gmSet(K.veh,veh); found=Array.from(anchors).map(a=>a.href);
                st.logs.push(`${s('scanVehList')} ${found.length} ${s('scanVehUnit')}`);
            } else if (u.includes('Character/Housing/')) {
                found=Array.from(document.querySelectorAll('#tablelocales a[href*="/Locale/"]'))
                    .filter(a=>/\/Locale\/\d+$/.test(a.getAttribute('href')))
                    .map(a=>{const id=a.getAttribute('href').match(/\/Locale\/(\d+)$/)?.[1];return id?`${location.origin}/World/Popmundo.aspx/Locale/ItemsEquipment/${id}`:null;})
                    .filter(Boolean);
                st.logs.push(`${s('scanHouseList')} ${found.length} ${s('scanHouseUnit')}`);
            } else {
                const cnt=updatePage(), info=getLocInfo(u);
                st.logs.push(cnt>0?`✅ ${info.name} (${info.type}): ${cnt} ${s('scanLogOk')}`:`⚠️ ${info.name}: ${s('scanLogEmpty')}`);
            }
            if (found.length) st.queue.splice(st.index+1,0,...found);
            st.index++;
            if (st.index<st.queue.length){saveScan(st);location.href=st.queue[st.index];}
            else{const fs={...st};lsDel(K.scan);GM_setValue('pop_last_scan',today());showScanReport(fs);}
        },randDelay());
    };

    // Panel: temalar
    const CD = { bg:'#111',text:'#e0e0e0',border:'#444',hBg:'#1a1a1a',hBorder:'#444',subBg:'#1a1a1a',inBg:'#222',inText:'#eee',inBorder:'#555',detBg:'#1a1a1a',detBorder:'#444',owBg:'#2a2a2a',owText:'#f0ad4e',loc:'#5bc0de',lbl:'#aaa',muted:'#777',togBg:'#222',togText:'#ccc',togBorder:'#555',taBg:'#222',resBorder:'#2a2a2a',gtBg:'#1e3a1e',gtBorder:'#2ecc71',gtText:'#2ecc71',vtBg:'#1a2535',vtBorder:'#3498db',vtText:'#aad4f5',rowText:'#e0e0e0',countText:'#2ecc71',owText2:'#f0ad4e',link:'#5bc0de',sep:'#555',sec:'#95a5a6',dragHint:'#666',priceBg:'#1a1a1a',priceBorder:'#444',priceText:'#ccc' };
    const CL = { bg:'#f5f5f5',text:'#222',border:'#bbb',hBg:'#e0e0e0',hBorder:'#ccc',subBg:'#e8e8e8',inBg:'#fff',inText:'#222',inBorder:'#aaa',detBg:'#ececec',detBorder:'#ccc',owBg:'#ddd',owText:'#555',loc:'#1a6896',lbl:'#555',muted:'#888',togBg:'#ddd',togText:'#333',togBorder:'#bbb',taBg:'#fff',resBorder:'#ddd',gtBg:'#d4edda',gtBorder:'#28a745',gtText:'#155724',vtBg:'#cce5ff',vtBorder:'#004085',vtText:'#004085',rowText:'#333',countText:'#155724',owText2:'#7d4f00',link:'#1a6896',sep:'#aaa',sec:'#555',dragHint:'#999',priceBg:'#fff',priceBorder:'#aaa',priceText:'#222' };
    const C = () => theme()==='light' ? CL : CD;

    // Panel: CSV export / import
    const exportDetailed = () => {
        const db=getDB(), ds=today();
        let csv='\uFEFFCategory;Item Name;Variant;Qty;Owner;Class;Inventory Name;Date;URL\n';
        Object.keys(db).forEach(owner=>Object.keys(db[owner]).forEach(url=>{
            const e=db[owner][url], rel=url.replace(/^https?:\/\/[^/]+/,'');
            e.items.forEach(item=>Object.entries(item.variants).forEach(([v,c])=>
                csv+=`"${getCat(item.name)}";"${item.name}";"${v}";${c};"${owner}";"${e.locClass||'Genel'}";"${e.locType}";"${e.lastUpdate||ds}";"${rel}"\n`
            ));
        }));
        dlCSV(csv,`Detaylı_Envanter_CSV_${ds}.csv`);
    };

    const exportSummary = () => {
        const db=getDB(), ds=today(), prices=getPrices(), sum={};
        Object.values(db).forEach(od=>Object.values(od).forEach(e=>e.items.forEach(item=>
            Object.entries(item.variants).forEach(([v,c])=>{
                const k=priceKey(item.name,v);
                if (!sum[k]) sum[k]={name:item.name,variant:v,count:0,cat:getCat(item.name)};
                sum[k].count+=c;
            })
        )));
        let csv='\uFEFFCategory;Item Name;Variant;Total Qty;Unit Price;Total Value\n',gt=0,gv=0;
        Object.values(sum).forEach(x=>{
            const rawP=prices[priceKey(x.name,x.variant)]||'0',up=parsePrice(rawP),tv=x.count*up;
            gt+=x.count; gv+=tv; csv+=`"${x.cat}";"${x.name}";"${x.variant}";${x.count};${rawP};${tv}\n`;
        });
        csv+=`;;;"${gt}";;${gv}\n`;
        dlCSV(csv,`Toplu_Stok_Fiyatli_CSV_${ds}.csv`);
    };

    const importCSV = (txt) => {
        try {
            const lines=txt.split(/\r?\n/),delim=txt.includes(';')?';':',',newDB={};
            const h=lines[0].split(delim).map(x=>x.replace(/^"|"$/g,'').trim());
            const [iN,iV,iO,iT,iU]=['Item Name','Variant','Owner','Inventory Name','URL'].map(x=>h.indexOf(x));
            const iC=h.indexOf(h.find(x=>x.includes('Qty')));
            for (let i=1;i<lines.length;i++) {
                if (!lines[i].trim()) continue;
                const c=lines[i].split(delim).map(x=>x.replace(/^"|"$/g,'').trim());
                const owner=c[iO]||s('locUnknown'),url=c[iU]||'';
                if (!newDB[owner]) newDB[owner]={};
                if (!newDB[owner][url]) newDB[owner][url]={locType:c[iT],url,items:[]};
                let ex=newDB[owner][url].items.find(it=>it.name===c[iN]);
                if (!ex){ex={name:c[iN],variants:{}};newDB[owner][url].items.push(ex);}
                ex.variants[c[iV]]=(ex.variants[c[iV]]||0)+(parseInt(c[iC])||0);
            }
            saveDB(newDB); location.reload();
        } catch(e){alert(_D('Hata: ','Error: ','Erro: ')+e.message);}
    };

    // Panel: ayar yedek
    const exportSettings = () => {
        const out={}, gmKeys=[K.db,K.cat,K.price,K.veh,K.char,K.owner,K.theme];
        gmKeys.forEach(k=>{const v=GM_getValue(k,null);if(v)out['gm_'+k]=v;});
        const a=document.createElement('a'); a.href=URL.createObjectURL(new Blob([JSON.stringify(out,null,2)],{type:'application/json'})); a.download=`popmundo_yedek_${today()}.json`; a.click();
    };

    const importSettings = (txt) => {
        try {
            const d=JSON.parse(txt); if (typeof d!=='object') throw new Error();
            Object.entries(d).forEach(([k,v])=>{ if (k.startsWith('gm_')) GM_setValue(k.slice(3),v); });
            alert(s('alertRestored')); location.reload();
        } catch { alert(s('alertInvalidFile')); }
    };

    // Panel: fiyat
    const parsePrice = (str) => {
        if (!str) return 0;
        const v=String(str).trim().toLowerCase().replace(',','.');
        const n=parseFloat(v); if (isNaN(n)) return 0;
        if (v.endsWith('m')) return n*1000000;
        if (v.endsWith('k')) return n*1000;
        return n;
    };

    const doSavePrice = (inp) => {
        const name=inp.dataset.name,variant=inp.dataset.variant; if (!name||!variant) return;
        const raw=inp.value.trim(),p=getPrices(),k=priceKey(name,variant);
        if (raw) p[k]=raw; else delete p[k]; savePrices(p);
        const numVal=parsePrice(raw),count=parseInt(inp.dataset.count)||0;
        const valEl=inp.closest('.pi-vt-row')&&inp.closest('.pi-vt-row').querySelector('.pi-val-span');
        if (valEl) valEl.textContent=numVal>0?'= '+(numVal*count).toLocaleString('tr-TR'):'';
        inp.style.borderColor='#2ecc71'; setTimeout(()=>{inp.style.borderColor='';},1000);
    };

    // Panel: liste & arama
    let invListOpen=false;
    const clsLbl=(c)=>({Kişisel:s('clsPersonal'),Araç:s('clsVehicle'),Mekan:s('clsHousing'),'Grup Aracı':s('clsArtist')}[c]||c||s('clsPersonal'));

    const bindResults = (ld) => {
        ld.addEventListener('click',(e)=>{
            const btn=e.target.closest('[data-del-owner]');
            const btnAll=e.target.closest('[data-del-all-owner]');
            if (btnAll&&confirm(_D(btnAll.dataset.delAllOwner+' tüm verisi silinsin mi?','Delete all data for '+btnAll.dataset.delAllOwner+'?','Excluir todos os dados de '+btnAll.dataset.delAllOwner+'?'))) {
                const db=getDB(); delete db[btnAll.dataset.delAllOwner]; saveDB(db); _db=null; showList(); return;
            }
            if (btn&&confirm(s('confirmDel'))){
                const owner=btn.dataset.delOwner,url=btn.dataset.delUrl,db=getDB();
                delete db[owner][url];
                if (!Object.keys(db[owner]).length) delete db[owner];
                saveDB(db); _db=null; showList();
            }
        });
        ld.addEventListener('keydown',(e)=>{
            if (e.key==='Enter'&&e.target.classList.contains('pi-price-inp')){e.preventDefault();doSavePrice(e.target);}
        });
    };

    const showList = () => {
        const ld=document.getElementById('pi-results'); if (!ld) return;
        const db=getDB(),c=C(),owners=Object.keys(db).sort();
        if (!owners.length){ld.innerHTML='<p style="color:#e74c3c;text-align:center;font-size:11px;">'+s('listEmpty')+'</p>';return;}
        let html='';
        owners.forEach(owner=>{
            const totalCnt=Object.values(db[owner]).reduce((a,e)=>a+e.items.reduce((b,it)=>b+Object.values(it.variants).reduce((x,y)=>x+y,0),0),0);
            html+='<div style="margin-bottom:6px;border:1px solid '+c.border+';background:'+c.subBg+';border-radius:4px;">'
                +'<div style="background:'+c.owBg+';padding:4px 8px;color:'+c.owText+';font-size:11px;font-weight:bold;display:flex;justify-content:space-between;align-items:center;">'
                +'<span>👤 '+esc(owner)+' <span style="font-weight:normal;opacity:.7;">['+totalCnt+']</span></span>'
                +'<button data-del-all-owner="'+esc(owner)+'" style="background:none;color:#e74c3c;border:1px solid #e74c3c;padding:1px 6px;font-size:9px;cursor:pointer;border-radius:2px;">'+s('btnDelAll')+'</button></div>';
            Object.keys(db[owner]).sort().forEach(url=>{
                const e=db[owner][url],cnt=e.items.reduce((a,it)=>a+Object.values(it.variants).reduce((x,y)=>x+y,0),0);
                html+='<div style="padding:4px 8px;border-bottom:1px solid '+c.resBorder+';display:flex;justify-content:space-between;align-items:center;">'
                    +'<a href="'+esc(url)+'" target="_blank" style="font-size:10px;color:'+c.loc+';text-decoration:none;">📍 '+esc(e.locType)+' <span style="color:'+c.muted+'">['+cnt+']</span></a>'
                    +'<button data-del-owner="'+esc(owner)+'" data-del-url="'+esc(url)+'" style="background:#a94442;color:white;border:none;padding:1px 5px;font-size:9px;cursor:pointer;border-radius:2px;">'+s('btnDel')+'</button></div>';
            });
            html+='</div>';
        });
        ld.innerHTML=html; bindResults(ld);
    };

    const renderSearch = (query) => {
        const ld=document.getElementById('pi-results'); if (!ld) return;
        if (!query){invListOpen?showList():(ld.innerHTML='');return;}
        const db=getDB(),c=C(),prices=getPrices(),rows=[],vt={};
        let grand=0;
        Object.keys(db).forEach(owner=>Object.keys(db[owner]).forEach(url=>{
            const e=db[owner][url],displayOwner=e.locClass==='Araç'?e.locType:owner;
            e.items.forEach(item=>{
                if (!item.name.toLowerCase().includes(query.toLowerCase())) return;
                Object.entries(item.variants).forEach(([v,cnt])=>{
                    const nv=normV(v), k=priceKey(item.name,nv);
                    if (!vt[k]) vt[k]={name:item.name,variant:nv,count:0};
                    vt[k].count+=cnt; grand+=cnt;
                    rows.push({name:item.name,variant:nv,count:cnt,displayOwner,locClass:e.locClass,locType:e.locType,url});
                });
            });
        }));
        if (!rows.length){ld.innerHTML='<p style="font-size:10px;color:'+c.muted+';padding:4px;">'+s('noResults')+'</p>';return;}

        const lastScan=GM_getValue('pop_last_scan','')||'—';
        let html='<div style="background:'+c.gtBg+';border:1px solid '+c.gtBorder+';border-radius:4px;padding:6px 10px;margin-bottom:6px;font-size:12px;color:'+c.gtText+';display:flex;justify-content:space-between;align-items:center;">'
            +'<b>'+s('totalLabel')+' "'+esc(query)+'": '+grand+'</b>'
            +'<span style="font-size:10px;font-weight:normal;opacity:.7;">'+s('lastScanLabel')+' '+lastScan+'</span></div>';

        html+='<div style="background:'+c.vtBg+';border:1px solid '+c.vtBorder+';border-radius:4px;padding:6px 10px;margin-bottom:8px;font-size:11px;">';
        const vtList=Object.values(vt);
        vtList.forEach(x=>{
            const pk=priceKey(x.name,x.variant),raw=prices[pk]||'';
            const numVal=parsePrice(raw),valTxt=numVal>0?'= '+(numVal*x.count).toLocaleString('tr-TR'):'';
            html+='<div class="pi-vt-row" style="display:flex;align-items:center;gap:6px;padding:3px 0;border-bottom:1px solid '+c.vtBorder+'44;color:'+c.vtText+';">'
                +'<span style="flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"><b>'+esc(x.name)+'</b> <span style="opacity:.7;font-size:10px;">'+esc(x.variant)+'</span> <span style="color:'+c.gtText+';font-weight:bold;">x'+x.count+'</span></span>'
                +'<input type="text" placeholder="30k / 2m" value="'+esc(raw)+'" data-count="'+x.count+'" data-name="'+esc(x.name)+'" data-variant="'+esc(x.variant)+'" class="pi-price-inp"'
                +' style="width:80px;font-size:10px;padding:2px 4px;background:'+c.priceBg+';color:'+c.priceText+';border:1px solid '+c.priceBorder+';border-radius:3px;flex-shrink:0;">'
                +'<span class="pi-val-span" style="font-size:10px;color:'+c.countText+';min-width:70px;flex-shrink:0;">'+valTxt+'</span></div>';
        });
        html+='<button id="pi-copy-btn" style="width:100%;margin-top:6px;padding:5px;background:#444;color:#ccc;border:1px solid #666;border-radius:3px;cursor:pointer;font-size:10px;">'+s('btnCopy')+'</button>';
        html+='</div><div style="font-size:10px;">';
        rows.forEach(r=>{
            const charIdM = r.url.match(/\/Character\/(?:Items|ItemsEquipment)\/(\d+)/);
            const charUrl = charIdM ? r.url.replace(/\/Character\/(?:Items|ItemsEquipment)\/\d+/, '/Character/Details/'+charIdM[1]) : null;
            const ownerHtml = charUrl
                ? '<a href="'+esc(charUrl)+'" target="_blank" style="color:'+c.owText2+';text-decoration:none;font-weight:600;">'+esc(r.displayOwner)+'</a>'
                : '<span style="color:'+c.owText2+';font-weight:600;">'+esc(r.displayOwner)+'</span>';
            html+='<div style="padding:5px 4px;border-bottom:1px solid '+c.resBorder+';display:flex;flex-direction:column;gap:2px;">'
                +'<div style="display:flex;align-items:baseline;gap:4px;flex-wrap:wrap;">'
                +'<span style="color:'+c.rowText+';font-size:10px;font-weight:600;word-break:break-word;">'+esc(r.name)+'</span>'
                +'<span style="color:'+c.muted+';font-size:9px;">'+esc(r.variant)+'</span>'
                +'<span style="color:'+c.countText+';font-weight:bold;font-size:10px;margin-left:auto;">x'+r.count+'</span>'
                +'</div>'
                +'<div style="display:flex;align-items:center;gap:4px;flex-wrap:wrap;font-size:9px;">'
                +ownerHtml
                +'<span style="color:'+c.sep+';">→</span>'
                +'<a href="'+esc(r.url)+'" target="_blank" style="color:'+c.link+';text-decoration:none;">'+esc(r.locType)+'</a>'
                +'</div>'
                +'</div>';
        });
        ld.innerHTML=html+'</div>';
        bindResults(ld);
        document.getElementById('pi-copy-btn')?.addEventListener('click',()=>{
            const txt=vtList.map(x=>{const raw=prices[priceKey(x.name,x.variant)]||'';return x.name+' '+x.variant+': x'+x.count+(raw?' - '+raw:' - '+s('noPriceLabel'));}).join('\n');
            navigator.clipboard.writeText(txt).then(()=>{const b=document.getElementById('pi-copy-btn');if(b){b.textContent=s('btnCopied');setTimeout(()=>{b.textContent=s('btnCopy');},1500);}});
        });
    };

    // Panel: UI
    function _createDepotFAB() {
        if (document.getElementById('pi-fab')) return;
        if (GM_getValue('dp_pc_connected', false)) return; // PC bağlıysa FAB gösterme
        // Position right of MissionAid float if present
        const maFloat = document.getElementById('qrFloat');
        const rightOffset = maFloat ? (window.innerWidth - maFloat.getBoundingClientRect().left + 8) : 14;
        const fab = document.createElement('button');
        fab.id = 'pi-fab'; fab.type = 'button';
        fab.style.cssText = 'position:fixed;bottom:18px;right:'+rightOffset+'px;z-index:999990;width:40px;height:40px;border-radius:50%;background:#6f42c1;color:#fff;font-size:20px;border:2px solid #fff;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,.35);display:flex;align-items:center;justify-content:center;font-family:inherit;line-height:1';
        fab.title = _D('Envanter','Inventory','Inventário');
        fab.innerHTML = '<span style="pointer-events:none">📦</span>';
        fab.onclick = () => { fab.remove(); createUI(); };
        document.body.appendChild(fab);
    }

    const createUI = () => {
        if (document.getElementById('pi-panel')) return;
        const c=C(),w=Math.min(gmGet(K.pw,340),window.innerWidth-8);
        const panel=document.createElement('div'); panel.id='pi-panel';

        const defaultRight = () => ({ right: 10, top: Math.round(window.innerHeight / 2) - 20 });



        const pos = gmGet(K.pos, null);
        const posStyle = pos
            ? 'left:'+pos.left+'px;top:'+pos.top+'px;'
            : 'right:10px;top:'+Math.round(window.innerHeight/2-200)+'px;';

        const th=theme(), ts='background:'+c.togBg+';color:'+c.togText+';border:1px solid '+c.togBorder;
        const thD=th==='dark'?'background:#333;color:#fff;border:2px solid #f0ad4e':ts;
        const thL=th==='light'?'background:#fff;color:#222;border:2px solid #f0ad4e':ts;

        const mkLangBtn=(lang,label)=>{
            const active=LANG===lang;
            return '<button data-lang="'+lang+'" style="flex:1;padding:6px 4px;font-size:11px;border-radius:4px;cursor:pointer;font-weight:'+(active?'bold':'normal')+';background:'+(active?'#f0ad4e':c.togBg)+';color:'+(active?'#111':c.togText)+';border:2px solid '+(active?'#f0ad4e':c.togBorder)+';transition:all .15s;">'+label+'</button>';
        };

        panel.style.cssText='position:fixed;'+posStyle+'width:'+w+'px;min-width:220px;max-width:calc(100vw - 8px);z-index:999999;background:'+c.bg+';color:'+c.text+';border:2px solid '+c.border+';border-radius:10px;padding:0;font-family:Arial,sans-serif;box-shadow:0 12px 40px rgba(0,0,0,.5);max-height:88vh;overflow-y:auto;overflow-x:hidden;word-break:break-word;';

        panel.innerHTML=
            // HEADER — title + drag hint + minimize
            '<div id="pi-drag" style="background:'+c.hBg+';border-radius:8px 8px 0 0;padding:10px 14px;border-bottom:2px solid '+c.hBorder+';display:flex;justify-content:space-between;align-items:center;cursor:grab;user-select:none;">'
            +'<span style="font-size:14px;font-weight:bold;color:#f0ad4e;">'+s('panelTitle')+'</span>'
            +'<div style="display:flex;gap:6px;align-items:center;">'
            +('ontouchstart' in window ? '' : '<span style="font-size:10px;color:'+c.dragHint+';border:1px dashed '+c.dragHint+';padding:2px 5px;border-radius:3px;">'+s('dragHint')+'</span>')
            +'<button id="pi-min" style="'+ts+';border-radius:6px;padding:3px 8px;cursor:pointer;font-size:11px;display:flex;align-items:center;gap:4px;white-space:nowrap;flex-shrink:0;">'
            +(GM_getValue('dp_pc_connected',false)?'✕ '+s('btnClose'):'📦 '+s('btnMinimize'))
            +'</button>'
            +'</div></div>'
            +'<div style="padding:8px 12px 0;">'
            // ACCORDION ROW — two buttons side by side
            +'<div style="display:flex;gap:6px;margin-bottom:6px;">'
            +'<button id="pi-tog-cfg" style="flex:1;padding:8px 6px;'+ts+';border-radius:5px;cursor:pointer;font-weight:bold;font-size:11px;text-align:center;">⚙️ '+s('btnSettings')+' ▾</button>'
            +'<button id="pi-tog-det" style="flex:1;padding:8px 6px;'+ts+';border-radius:5px;cursor:pointer;font-weight:bold;font-size:11px;text-align:center;">📋 '+s('btnInventory')+' ▾</button>'
            +'</div>'
            // SETTINGS PANEL
            +'<div id="pi-cfg" style="display:none;background:'+c.detBg+';padding:10px;border-radius:5px;border:1px solid '+c.detBorder+';margin-bottom:8px;">'
            // Lang buttons — first row inside settings
            +'<div id="pi-lang-btns" style="display:flex;gap:5px;margin-bottom:10px;">'
            +mkLangBtn('TR','🇹🇷 Türkçe')+mkLangBtn('EN','🇬🇧 English')+mkLangBtn('PT-BR','🇧🇷 Português')
            +'</div>'
            +'<div style="display:flex;gap:6px;margin-bottom:10px;">'
            +'<button id="pi-th-dark"  style="flex:1;padding:7px;border-radius:4px;cursor:pointer;font-size:11px;font-weight:bold;'+thD+'">🌙 Dark</button>'
            +'<button id="pi-th-light" style="flex:1;padding:7px;border-radius:4px;cursor:pointer;font-size:11px;font-weight:bold;'+thL+'">☀️ Light</button></div>'
            +'<div style="display:flex;gap:5px;margin-bottom:6px;">'
            +'<button id="pi-exp-set" style="flex:1;padding:8px;background:#17a2b8;color:white;border:none;border-radius:3px;cursor:pointer;font-size:11px;">'+s('btnBackup')+'</button>'
            +'<button id="pi-imp-set" style="flex:1;padding:8px;background:#6c757d;color:white;border:none;border-radius:3px;cursor:pointer;font-size:11px;">'+s('btnRestore')+'</button></div>'
            +'<label style="color:'+c.lbl+';font-size:10px;">'+s('catLabel')+'</label>'
            +'<textarea id="pi-cat-txt" placeholder="'+s('catPlaceholder')+'" style="width:100%;height:50px;font-size:10px;background:'+c.taBg+';color:'+c.text+';border:1px solid '+c.inBorder+';border-radius:3px;resize:vertical;margin-top:4px;box-sizing:border-box;"></textarea>'
            +'<button id="pi-cat-save" style="width:100%;margin-top:5px;background:#444;color:white;border:none;padding:6px;font-size:10px;border-radius:3px;cursor:pointer;">'+s('btnCatSave')+'</button>'
            +'<button id="pi-clear" style="width:100%;margin-top:8px;padding:7px;background:none;color:#dc3545;border:1px solid #dc3545;border-radius:4px;cursor:pointer;font-size:10px;">'+s('btnClearAll')+'</button>'
            +'</div>'
            // INVENTORY PANEL
            +'<div id="pi-det" style="display:none;background:'+c.detBg+';padding:10px;border-radius:5px;border:1px solid '+c.detBorder+';margin-bottom:8px;">'
            +'<button id="pi-scan" style="width:100%;padding:10px;background:#0056b3;color:white;border:none;border-radius:5px;cursor:pointer;font-weight:bold;margin-bottom:8px;">'+s('btnAutoScan')+'</button>'
            +'<button id="pi-list" style="width:100%;background:#17a2b8;color:white;border:none;padding:8px;font-weight:bold;border-radius:5px;cursor:pointer;margin-bottom:8px;">'+s('btnListManage')+'</button>'
            +'<div style="display:flex;gap:5px;">'
            +'<button id="pi-exp-det" style="flex:1;padding:8px;background:#6c757d;color:white;border:none;border-radius:3px;cursor:pointer;font-size:11px;">'+s('btnDetailed')+'</button>'
            +'<button id="pi-exp-sum" style="flex:1;padding:8px;background:#6c757d;color:white;border:none;border-radius:3px;cursor:pointer;font-size:11px;">'+s('btnStockCSV')+'</button>'
            +'<button id="pi-imp-csv" style="flex:1;padding:8px;background:#6c757d;color:white;border:none;border-radius:3px;cursor:pointer;font-size:11px;">'+s('btnImportCSV')+'</button>'
            +'</div></div>'
            // SAVE / DELETE ROW
            +'<div style="display:flex;gap:6px;margin-bottom:8px;">'
            +'<button id="pi-save" style="flex:3;background:#218838;color:white;border:none;padding:10px;font-weight:bold;border-radius:5px;cursor:pointer;">'+s('btnSavePage')+'</button>'
            +'<button id="pi-del"  style="flex:1;background:none;color:#f39c12;border:1px solid #f39c12;border-radius:4px;cursor:pointer;font-size:10px;">'+s('btnDelRecord')+'</button>'
            +'</div>'
            // SEARCH
            +'<input type="text" id="pi-search" placeholder="'+s('searchPH')+'" style="width:100%;padding:10px;background:'+c.inBg+';color:'+c.inText+';border:2px solid #3498db;border-radius:5px;box-sizing:border-box;outline:none;">'
            +'<div id="pi-results" style="margin-top:10px;"></div>'
            +'</div>';

        document.body.appendChild(panel);

        // Dil butonları — document delegation, pi-cfg içinde display:none sorununu aşar
        document.addEventListener('click',(e)=>{
            const btn=e.target.closest('#pi-lang-btns [data-lang]'); if(!btn)return;
            document.cookie='ppm_lang='+btn.dataset.lang+';path=/;domain=.popmundo.com;max-age=31536000';
            location.reload();
        });

        // Accordion: birine tıklayınca diğeri kapanır
        const togMutual=(bA,dA,bB,dB)=>{
            const btnA=document.getElementById(bA),divA=document.getElementById(dA);
            const btnB=document.getElementById(bB),divB=document.getElementById(dB);
            if(!btnA||!btnB) return;
            const setArrow=(btn,open)=>{btn.textContent=btn.textContent.replace(open?'▴':'▾',open?'▾':'▴');};
            btnA.addEventListener('click',()=>{
                const openA=divA.style.display!=='none';
                divA.style.display=openA?'none':'block'; setArrow(btnA,openA);
                if(!openA){divB.style.display='none'; if(btnB.textContent.includes('▴'))setArrow(btnB,true);}
            });
            btnB.addEventListener('click',()=>{
                const openB=divB.style.display!=='none';
                divB.style.display=openB?'none':'block'; setArrow(btnB,openB);
                if(!openB){divA.style.display='none'; if(btnA.textContent.includes('▴'))setArrow(btnA,true);}
            });
        };
        togMutual('pi-tog-cfg','pi-cfg','pi-tog-det','pi-det');

        // Sol kenardan resize
        const rh=document.createElement('div');
        rh.style.cssText='position:absolute;top:0;left:0;width:8px;height:100%;cursor:ew-resize;z-index:2;';
        panel.appendChild(rh);
        let resizing=false,startX=0,startW=0;
        rh.addEventListener('mousedown',(e)=>{resizing=true;startX=e.clientX;startW=panel.offsetWidth;e.preventDefault();});
        document.addEventListener('mousemove',(e)=>{if(!resizing)return;const nw=Math.max(220,Math.min(window.innerWidth-8,startW-(e.clientX-startX)));panel.style.width=nw+'px';});
        document.addEventListener('mouseup',()=>{if(!resizing)return;resizing=false;gmSet(K.pw,panel.offsetWidth);});

        // Sürükleme
        let drag=false,ox=0,oy=0;
        document.getElementById('pi-drag').addEventListener('mousedown',(e)=>{
            if(e.target.closest('button'))return;
            drag=true; panel.style.cursor='grabbing';
            const rect=panel.getBoundingClientRect();
            ox=rect.left-e.clientX; oy=rect.top-e.clientY;
        });
        document.addEventListener('mousemove',(e)=>{
            if(!drag)return;
            panel.style.left=Math.max(0,e.clientX+ox)+'px';
            panel.style.top=Math.max(0,e.clientY+oy)+'px';
            panel.style.right='auto'; panel.style.bottom='auto';
        });
        document.addEventListener('mouseup',()=>{
            if(!drag)return; drag=false; panel.style.cursor='';
            gmSet(K.pos,{left:panel.offsetLeft,top:panel.offsetTop});
        });

        const fileInput=(accept,cb)=>{const i=document.createElement('input');i.type='file';i.accept=accept;i.onchange=e=>{const r=new FileReader();r.onload=ev=>cb(ev.target.result);r.readAsText(e.target.files[0]);};i.click();};
        const on=(id,fn)=>document.getElementById(id)&&document.getElementById(id).addEventListener('click',fn);

        on('pi-min',()=>{
            panel.remove();
            if (!GM_getValue('dp_pc_connected', false)) _createDepotFAB();
            // If connected: PopControl button brings it back — no FAB needed
        });
        on('pi-save',()=>{const cnt=updatePage();if(cnt>0){alert(_D(cnt+' çeşit eşya kaydedildi.',cnt+' item type(s) saved.',cnt+' tipo(s) de item salvos.'));location.reload();}else alert(s('alertNoItems'));});
        on('pi-del',()=>{const u=location.href,db=getDB();let f=false;Object.keys(db).forEach(o=>{if(db[o]&&db[o][u]){delete db[o][u];f=true;}});if(f){saveDB(db);alert(s('alertDeleted'));location.reload();}else alert(s('alertNotFound'));});
        on('pi-scan',()=>discover());
        on('pi-list',()=>{invListOpen?((document.getElementById('pi-results').innerHTML=''),invListOpen=false):(showList(),invListOpen=true);});
        on('pi-exp-det',exportDetailed);
        on('pi-exp-sum',exportSummary);
        on('pi-imp-csv',()=>fileInput('.csv',importCSV));
        on('pi-exp-set',exportSettings);
        on('pi-imp-set',()=>fileInput('.json',importSettings));
        on('pi-th-dark',()=>{GM_setValue(K.theme,'dark');panel.remove();createUI();});
        on('pi-th-light',()=>{GM_setValue(K.theme,'light');panel.remove();createUI();});
        document.getElementById('pi-search').addEventListener('input',(e)=>renderSearch(e.target.value.trim()));
        on('pi-cat-save',()=>{
            const raw=document.getElementById('pi-cat-txt').value; if(!raw.trim())return alert(s('alertEnterData'));
            const nc={};raw.split('\n').forEach(line=>{const p=line.includes('\t')?line.split('\t'):line.split(',');if(p.length>=2){const cat=p[0].trim(),it=p[1].trim();if(!nc[cat])nc[cat]=[];nc[cat].push(it);}});
            if(Object.keys(nc).length){saveCats(nc);alert(_D(Object.keys(nc).length+' kategori güncellendi!',Object.keys(nc).length+' category/categories updated!',Object.keys(nc).length+' categoria(s) atualizada(s)!'));}else alert(s('alertCatFmt'));
        });
        on('pi-clear',()=>{if(confirm(s('alertClearConf'))){gmDel(K.db);location.reload();}});
    };

    // Scan: oturum başlat
    const sc=getScan();
    if (sc.active && window.location.href.includes('/World/Popmundo.aspx/')) {
        const btn=document.createElement('button');
        const curName=sc.queue[sc.index]?sc.queue[sc.index].split('/').pop():'';
        btn.textContent=`${s('scanStop')} (${sc.index}/${sc.queue.length}) — ${curName}`;
        btn.style.cssText='position:fixed;top:10px;left:50%;transform:translateX(-50%);z-index:999998;padding:10px 20px;background:#dc3545;color:white;border:none;border-radius:6px;cursor:pointer;font-weight:bold;font-size:13px;';
        btn.onclick=()=>{lsDel(K.scan);location.reload();};
        document.body.appendChild(btn);
        if (document.readyState==='complete') runStep();
        else window.addEventListener('load',runStep);
    }

    // EN strings for PopControl export
    window.__ppcStrDepot = {"scanTitle": "🔄 Auto Scan", "scanPersonal": "👤 Personal Items", "scanVehicles": "🚗 Personal Vehicles", "scanHousing": "🏠 Housing", "scanArtist": "🎵 Artist / Tour Vehicle", "scanWarn": "⚠️ Tabs will change automatically during scan.", "scanCancel": "Cancel", "scanStart": "▶ Start Scan", "scanSelectOne": "Select at least one category.", "scanDone": "✅ Scan Complete", "scanLocCount": "Scanned Locations:", "scanItemCount": "Total Items:", "scanClose": "Close", "scanAskId": "Enter Character ID:", "scanBadId": "No valid ID entered.", "scanVehList": "🔍 Vehicle list:", "scanVehUnit": "vehicles.", "scanHouseList": "🔍 Housing list:", "scanHouseUnit": "properties.", "scanLogOk": "types.", "scanLogEmpty": "no items.", "scanStop": "🛑 STOP", "panelTitle": "📦 Depot", "dragHint": "⠿ Drag", "btnSettings": "Panel Settings", "btnBackup": "📤 Backup Script", "btnRestore": "📥 Load Backup", "catLabel": "Category CSV (Category,Item):", "catPlaceholder": "Category,Item Name", "btnCatSave": "💾 Update Categories", "btnClearAll": "⚠️ Reset All Data", "btnSavePage": "📍 Save Page", "btnDelRecord": "🗑️ Delete Record", "btnInventory": "Inventory Actions", "btnAutoScan": "🔄 AUTO SCAN", "btnListManage": "📋 LIST / MANAGE INVENTORIES", "btnDetailed": "📄 Detailed CSV", "btnStockCSV": "📊 Stock & Priced CSV", "btnImportCSV": "📥 Import CSV", "searchPH": "Search inventory (e.g. Haiku)...", "alertNoItems": "No items found on this page.", "alertDeleted": "Deleted.", "alertNotFound": "Record not found.", "alertEnterData": "Enter data.", "alertClearConf": "All data will be reset!", "alertRestored": "Restored.", "alertInvalidFile": "Invalid file.", "listEmpty": "Database empty.", "btnDelAll": "Delete All", "btnDel": "DEL", "confirmDel": "Delete this record?", "noResults": "No results found.", "totalLabel": "Total", "lastScanLabel": "Last scan:", "btnCopy": "📋 Copy these results", "btnCopied": "✅ Copied", "noPriceLabel": "Make an offer", "clsPersonal": "Items", "clsVehicle": "Personal Vehicle", "clsHousing": "Housing", "clsArtist": "Artist Vehicle", "minTooltip": "Open panel", "btnMinimize": "Minimize", "btnClose": "Close", "locVehicleFb": "Personal Vehicle", "locLocaleFb": "Locale", "locCharFb": "Character", "locInvSuffix": "Inventory", "locArtistFb": "Artist Vehicle", "locUnknown": "Unknown", "variantDefault": "Standard"};
    window.__ppcStrDepot.panelTitle = '📦 Depot ' + GM_info.script.version;

    // PopControl hazır olana kadar bekler
    function _waitPC(cb,n){n=n||0;if(unsafeWindow.PopControl){cb();return;}if(n<20)setTimeout(function(){_waitPC(cb,n+1);},300);}

    // Auto-connect to PopControl if available
    _waitPC(function() {
        unsafeWindow.PopControl.register({
            id:'depot', icon:'📦', label:_D('Envanter','Inventory','Inventário'),
            strings: window.__ppcStrDepot || {},
            buttons:[{icon:'📦', label:_D('Depot','Depot','Depot'), onClick:function(){
                var p=document.getElementById('pi-panel');
                if (p) { p.style.display = p.style.display===''?'none':''; }
                else { createUI(); }
            }}],
            onUndo:function(){
                GM_setValue('dp_pc_connected', false);
                document.getElementById('pi-panel')?.remove();
                _createDepotFAB();
            },
        });
        document.getElementById('pi-fab')?.remove();
        GM_setValue('dp_pc_connected', true);
    });

    _createDepotFAB();

})();