<!DOCTYPE html>

<html lang="pt-BR">
<head>
<script>window.__SW_VERSION__='v20260622-pro-019';window.__AUTH_REQUIRED__=true;window.__EVPL_AUTOLOAD__=false;window.__EVPL_FETCH_TIMEOUT__=30000;</script>
<script src="preauth-guard.js?v=v20260622-pro-019"></script>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<title>Estoque &amp; Vendas – Laser Eletro</title>
<link href="assets/logo.svg?v=v20260622-pro-019" rel="icon"/>
<style id="laser-prepaint">html,body{background:#f4f6fb;color:#152033;}</style>
<link href="styles.css?v=v20260622-pro-019" rel="stylesheet"/>
<link href="styles-enhanced.css?v=v20260622-pro-019" rel="stylesheet"/>
<link href="styles-hotfix-layout.css?v=v20260622-pro-019" rel="stylesheet"/>
<link href="evpl-refined.css?v=v20260622-pro-019" rel="stylesheet"/>
<link href="evpl-pro-manager.css?v=v20260622-pro-019" rel="stylesheet"/>
<link href="evpl-pro-polish.css?v=v20260622-pro-019" rel="stylesheet"/>
<link href="evpl-quality-pass.css?v=v20260622-pro-019" rel="stylesheet"/>
<link href="evpl-pro-finalpass.css?v=v20260622-pro-019" rel="stylesheet"/>
<link href="evpl-pro06-polish.css?v=v20260622-pro-019" rel="stylesheet"/>
<link href="evpl-premium-stable-pro19.css?v=v20260622-pro-019" rel="stylesheet"/>
<meta content="#172033" name="theme-color"/>
<meta name="description" content="PWA rápido e responsivo para consulta de estoque e vendas da Laser Eletro.">
<meta name="application-name" content="LaserScan EVPL">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="apple-mobile-web-app-title" content="LaserScan">
<meta name="format-detection" content="telephone=no">
<link rel="manifest" href="manifest.webmanifest?v=v20260622-pro-019">
<link rel="apple-touch-icon" href="assets/logo-laser.png">
<link rel="preconnect" href="https://docs.google.com">
<link rel="preconnect" href="https://spreadsheets.google.com">
<link rel="preconnect" href="https://*.googleusercontent.com">

<!-- BEGIN: Zebra Rows v3 (screen + print robust) -->
<style>
#tableBase1 tbody tr:nth-child(odd) td,
#tableBase2 tbody tr:nth-child(odd) td,
#tablePivot tbody tr:nth-child(odd) td,
#tablePivotValor tbody tr:nth-child(odd) td,
#tablePivotEV tbody tr:nth-child(odd) td { background-color: #f7f8fb; }
#tableBase1 tbody tr:nth-child(even) td,
#tableBase2 tbody tr:nth-child(even) td,
#tablePivot tbody tr:nth-child(even) td,
#tablePivotValor tbody tr:nth-child(even) td,
#tablePivotEV tbody tr:nth-child(even) td { background-color: #ffffff; }
#tableBase1 tbody tr:hover td,
#tableBase2 tbody tr:hover td,
#tablePivot tbody tr:hover td,
#tablePivotValor tbody tr:hover td,
#tablePivotEV tbody tr:hover td { filter: brightness(0.985); }
@media print {
  *, table, tr, td, th { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
  #tableBase1 tbody tr:nth-child(odd) td,
  #tableBase2 tbody tr:nth-child(odd) td,
  #tablePivot tbody tr:nth-child(odd) td,
  #tablePivotValor tbody tr:nth-child(odd) td,
  #tablePivotEV tbody tr:nth-child(odd) td {
    background-color: #eaeef7 !important;
    box-shadow: inset 1000px 0 0 #eaeef7 !important;
  }
  #tableBase1 tbody tr:nth-child(even) td,
  #tableBase2 tbody tr:nth-child(even) td,
  #tablePivot tbody tr:nth-child(even) td,
  #tablePivotValor tbody tr:nth-child(even) td,
  #tablePivotEV tbody tr:nth-child(even) td {
    background-color: #ffffff !important;
    box-shadow: inset 1000px 0 0 #ffffff !important;
  }
}
</style>
<!-- END: Zebra Rows v3 -->
<!-- BEGIN: Perf CSS v1 -->
<style>
  .tab-pane, .aba, .conteudo-aba, section[data-filtros], section[data-lista]{
    content-visibility: auto;
    contain-intrinsic-size: 1000px 600px;
  }
</style>
<!-- END: Perf CSS v1 -->
<meta name="app-version" content="Versão: 19.06.2026 PRO.19"/>

<link rel="stylesheet" href="theme.css?v=v20260622-pro-019">
<link rel="stylesheet" href="evpl-loading-pro.css?v=v20260622-pro-019">
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="evpl-filter-engine-pro19.css?v=v20260622-pro-019">
<link rel="stylesheet" href="evpl-pro19-ux.css?v=v20260622-pro-019">
<link rel="stylesheet" href="evpl-apply-fix-pro19.css?v=v20260622-pro-019">
<link rel="stylesheet" href="evpl-pro19-final.css?v=v20260622-pro-019">
<link rel="stylesheet" href="evpl-pro19-hotfix.css?v=v20260622-pro-019">
</head>
<body class="evpl-pro">
<header class="app-header">
<div class="left">
<img alt="Logo" class="logo" src="assets/logo.svg?v=v20260622-pro-019" loading="lazy" decoding="async">
<div class="title">
<h1>Estoque &amp; Vendas</h1>
<small class="muted" id="lastUpdate">Base Atualizada –</small>
</div>
</div>
<div class="right top-meta">
<small>Versão: 19.06.2026 PRO.19 • Premium Estável • abas independentes • <span id="status">Aguardando Aplicar</span> • Desenvolvedor: WgR</small>
<div class="btns">
<button class="apply-btn" id="btnApply">🔎 Aplicar</button>
<button class="btn ghost" id="btnClear">🧹 Limpar</button>
<button class="btn ghost" id="btnLoad">⚡ Carregar</button>
<button class="btn" id="btnPrint">🖨️ Imprimir</button>
<button class="btn" id="btnExport">⬇️ Exportar XLS</button><button class="btn" id="btnExportCSV">⬇️ Exportar CSV</button>
<button class="btn ghost" id="btnViewMode" type="button" aria-pressed="false" title="Alternar visualização">🧩 Blocos</button>
<button class="btn ghost" id="btnUpdate" style="display:none">🔄 Atualizar versão</button>
</div>
</div>
</header>
<nav class="tabs">
<button class="tab active" data-tab="produtos">Estoque e Venda</button>
<button class="tab" data-tab="lojas">Estoque e Venda por Loja</button>
<button class="tab" data-tab="pivot">Por Loja Estoque</button>
<button class="tab" data-tab="pivotValor">Por Loja Venda</button>
<button class="tab" data-tab="pivotEV">Por Loja Estoque e Venda</button>
</nav>
<div class="print-area print-header" id="printHeader" style="display:none">
<div class="ph-row">
<div><b>Data:</b> <span id="ph-date">--/--/----</span></div>
<div><b>Hora:</b> <span id="ph-time">--:--:--</span></div>
</div>
<div class="ph-row">
<div><b>Filtros ativos:</b> <span id="ph-filters">Nenhum</span></div>
</div>
</div>
<section class="filters" id="filters">
<!-- PRODUTOS (Base 1) -->
<div class="filter-group active" id="filtros-produtos">
<div class="field wide"><label>Buscar</label><input id="search1" placeholder="Código ou descrição…" type="search"/></div>
<div class="field evpl-bf-field"><label>Produtos BF</label><select id="bf1"><option value="">Todos</option><option value="com_bf">Com (BF)</option><option value="sem_bf">Sem (BF)</option></select></div>
<div class="field"><label>Seção</label><select id="secao1"><option value="">Todas</option></select></div>
<div class="field"><label>Categoria</label><select id="categoria1"><option value="">Todas</option></select></div>
<div class="field"><label>Marca</label><select id="marca1"><option value="">Todas</option></select></div>
<div class="field"><label>Quantidade</label>
  <select id="quant1">
    <option value="">Todas</option>
    <option value="estoque_pos">Com estoque (&gt; 0)</option>
    <option value="venda_pos">Com venda (&gt; 0)</option>
    <option value="estoque_zero">Sem estoque (= 0)</option>
    <option value="venda_zero">Sem venda (= 0)</option>
  </select>
</div>
<div class="filter-chips" id="chips-produtos"></div>
</div>
<!-- LOJAS por Marca (Base 2) -->
<div class="filter-group" id="filtros-lojas">
<div class="field wide"><label>Buscar</label><input id="search2" placeholder="Código ou descrição…" type="search"/></div>
<div class="field evpl-bf-field"><label>Produtos BF</label><select id="bf2"><option value="">Todos</option><option value="com_bf">Com (BF)</option><option value="sem_bf">Sem (BF)</option></select></div>
<div class="field"><label>Filial Num.</label><select id="filialNum2"><option value="">Todas</option></select></div>
<div class="field"><label>Filial Nome</label><select id="filialNome2"><option value="">Todas</option></select></div>
<div class="field"><label>Estado UF</label><select id="estado2"><option value="">Todos</option></select></div>
<div class="field"><label>Seção</label><select id="secao2"><option value="">Todas</option></select></div>
<div class="field"><label>Marca</label><select id="marca2"><option value="">Todas</option></select></div>
<div class="field"><label>Quantidade</label>
  <select id="quant2">
    <option value="">Todas</option>
    <option value="loja_com_estoque">Lojas com estoque (&gt; 0)</option>
    <option value="loja_zerada">Lojas zeradas (= 0)</option>
  </select>
</div>
<div class="field"><label>Categoria</label><select id="categoria2"><option value="">Todas</option></select></div>
<div class="filter-chips" id="chips-lojas"></div>
</div>
<!-- Por Estado Estoque -->
<div class="filter-group" id="filtros-pivot">
<div class="field wide"><label>Buscar</label><input id="search3" placeholder="Código ou descrição…" type="search"/></div>
<div class="field evpl-bf-field"><label>Produtos BF</label><select id="bf3"><option value="">Todos</option><option value="com_bf">Com (BF)</option><option value="sem_bf">Sem (BF)</option></select></div>
<div class="field"><label>Estado</label><select id="estado3"><option value="">Todos</option></select></div>
<div class="field"><label>Marca</label><select id="marca3"><option value="">Todas</option></select></div>
<div class="field"><label>Categoria</label><select id="categoria3"><option value="">Todas</option></select></div>
<div class="field"><label>Seção</label><select id="secao3"><option value="">Todas</option></select></div>
<div class="field"><label>Filial Num.</label><select id="filialNum3"><option value="">Todas</option></select></div>
<div class="field"><label>Filial Nome</label><select id="filialNome3"><option value="">Todas</option></select></div>
<div class="filter-chips" id="chips-pivot"></div>
</div>
<!-- Por Estado Venda -->
<div class="filter-group" id="filtros-pivotValor">
<div class="field wide"><label>Buscar</label><input id="search4" placeholder="Código ou descrição…" type="search"/></div>
<div class="field evpl-bf-field"><label>Produtos BF</label><select id="bf4"><option value="">Todos</option><option value="com_bf">Com (BF)</option><option value="sem_bf">Sem (BF)</option></select></div>
<div class="field"><label>Estado</label><select id="estado4"><option value="">Todos</option></select></div>
<div class="field"><label>Marca</label><select id="marca4"><option value="">Todas</option></select></div>
<div class="field"><label>Categoria</label><select id="categoria4"><option value="">Todas</option></select></div>
<div class="field"><label>Seção</label><select id="secao4"><option value="">Todas</option></select></div>
<div class="field"><label>Filial Num.</label><select id="filialNum4"><option value="">Todas</option></select></div>
<div class="field"><label>Filial Nome</label><select id="filialNome4"><option value="">Todas</option></select></div>
<div class="filter-chips" id="chips-pivotValor"></div>
</div>
<!-- Por Estado Estoque e Venda -->
<div class="filter-group" id="filtros-pivotEV">
<div class="field wide"><label>Buscar</label><input id="search5" placeholder="Código ou descrição…" type="search"/></div>
<div class="field evpl-bf-field"><label>Produtos BF</label><select id="bf5"><option value="">Todos</option><option value="com_bf">Com (BF)</option><option value="sem_bf">Sem (BF)</option></select></div>
<div class="field"><label>Estado</label><select id="estado5"><option value="">Todos</option></select></div>
<div class="field"><label>Marca</label><select id="marca5"><option value="">Todas</option></select></div>
<div class="field"><label>Categoria</label><select id="categoria5"><option value="">Todas</option></select></div>
<div class="field"><label>Seção</label><select id="secao5"><option value="">Todas</option></select></div>
<div class="field"><label>Filial Num.</label><select id="filialNum5"><option value="">Todas</option></select></div>
<div class="field"><label>Filial Nome</label><select id="filialNome5"><option value="">Todas</option></select></div>
<div class="filter-chips" id="chips-pivotEV"></div>
</div>
<div class="field tiny">
<label>Página</label>
<div class="pager">
<button class="btn ghost" id="prevPage">◀</button>
<span id="pageLabel">1/1</span>
<button class="btn ghost" id="nextPage">▶</button>
</div>
</div>
<div class="field tiny">
<label>Itens/pg</label>
<select id="pageSize">
<option value="50">50</option>
<option value="100">100</option>
<option selected="" value="200">200</option>
<option value="500">500</option>
</select>
</div>
</section>
<main>
<div class="empty" id="emptyMsg">Clique em <b>Carregar</b> para baixar as bases. Depois selecione os filtros e clique em <b>Aplicar</b>.</div>
<section class="panel active" id="tab-produtos">
<div class="kpi-bar" id="kpi-produtos"></div>
<div class="table-wrap tall"><table id="tableBase1"><thead></thead><tbody></tbody><tfoot></tfoot></table></div>
<div class="cards-wrap tall" id="cardsWrapBase1" style="display:none;"><div class="cards-grid" id="cardsBase1"></div></div>
</section>
<section class="panel" id="tab-lojas">
<div class="kpi-bar" id="kpi-lojas"></div>
<div class="table-wrap tall"><table id="tableBase2"><thead></thead><tbody></tbody><tfoot></tfoot></table></div>
<div class="cards-wrap tall" id="cardsWrapBase2" style="display:none;"><div class="cards-grid" id="cardsBase2"></div></div>
</section>
<section class="panel" id="tab-pivot">
<div class="table-wrap tall"><table id="tablePivot"><thead></thead><tbody></tbody><tfoot></tfoot></table></div>
</section>
<section class="panel" id="tab-pivotValor">
<div class="table-wrap tall"><table id="tablePivotValor"><thead></thead><tbody></tbody><tfoot></tfoot></table></div>
</section>
<section class="panel" id="tab-pivotEV">
<div class="table-wrap tall"><table id="tablePivotEV"><thead></thead><tbody></tbody><tfoot></tfoot></table></div>
</section>
</main>
<div class="pager footer" id="pagerBottom" style="display:flex;gap:8px;align-items:center;justify-content:flex-end;padding:8px 12px;">
<button class="btn ghost" id="prevPageB">◀</button>
<span id="pageLabelB">1/1</span>
<button class="btn ghost" id="nextPageB">▶</button>
</div>
<div class="print-area" id="printArea"></div>
<button id="scrollTop" class="scroll-top hidden" type="button" aria-label="Voltar ao topo">▲ Topo</button>
<div class="loader hidden" id="loader" aria-live="polite" aria-busy="true">
  <div class="loader-panel" role="group" aria-label="Carregamento">
    <div class="loader-brand">
  <div class="laser-logo-wrap" aria-hidden="true">
    <img class="laser-logo base" src="assets/logo-laser.png" alt="">
    <img class="laser-logo reveal" src="assets/logo-laser.png" alt="">
    <div class="laser-scan" aria-hidden="true"></div>
  </div>
  <div class="loader-brand-text">
    <div class="loader-title">Laser Eletro</div>
    <div class="loader-subtitle">Estoque &amp; Vendas</div>
  </div>
</div>

    <div class="loader-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="10">
      <div class="loader-bar-fill" style="width:10%"></div>
    </div>

    <div class="loader-row">
      <div class="spinner" aria-hidden="true"></div>
      <div class="loader-text">Preparando ambiente…</div>
    </div>

    <div class="loader-note">Carregando com visual otimizado, filtros protegidos e cache inteligente.</div>
  </div>
</div>

<footer class="app-footer"></footer>
<script>window.__SW_VERSION__='v20260622-pro-019';window.__EVPL_AUTOLOAD__=false;window.__EVPL_FETCH_TIMEOUT__=30000;</script>
<script src="app.js?v=v20260622-pro-019" defer></script>
<script src="app-enhancements.js?v=v20260622-pro-019" defer></script>
<script src="app-hotfix-clear-layout.js?v=v20260622-pro-019" defer></script>
<div class="toast hidden" id="toast"></div>
<!-- BEGIN: Filters Stabilizer v1 -->
<script>
(function(){
  function db(fn, ms){ let t; return function(){ clearTimeout(t); const a=arguments, ctx=this; t=setTimeout(function(){ fn.apply(ctx,a); }, ms||200); }; }
  const applyOnce = db(function(){
    try{
      if (typeof PAGE!=="undefined") PAGE = 1;
      if (typeof apply === 'function') apply();
    }catch(e){ try{ console.error(e); showToast && showToast('Erro ao aplicar filtros', 2200, 'error'); }catch(_){ } }
  }, 120);
  function ensureSmartBind(tab){
    try{
      const root = document.getElementById('filtros-'+tab);
      if(!root || root._smartBound) return;
      if (typeof bindSmartFilters === 'function'){ bindSmartFilters(tab); root._smartBound = true; }
    } catch(_) {}
  }
  function attachCaptureHandlers(tab){
    const root = document.getElementById('filtros-'+tab);
    if(!root || root._capBound) return;
    const onChangeCap = function(ev){
      const t = ev.target; if(!t) return;
      const tag = (t.tagName||'').toUpperCase();
      const type = (t.type||'').toLowerCase();
      if (tag==='SELECT' || type==='checkbox' || type==='radio'){
        ev.stopImmediatePropagation(); ev.preventDefault(); applyOnce();
      }
    };
    const onKeyUpCap = function(ev){
      const t = ev.target; if(!t) return;
      if (t.tagName==='INPUT' && /^(text|search|number)$/i.test(t.type||'')){
        ev.stopImmediatePropagation(); ev.preventDefault(); applyOnce();
      }
    };
    root.addEventListener('change', onChangeCap, {capture:true});
    root.addEventListener('keyup', onKeyUpCap, {capture:true});
    root._capBound = true;
  }
  (function softenHideSkeleton(){
    try{
      if (window.hideSkeleton && !window.hideSkeleton._soft){
        const orig = window.hideSkeleton; let raf = 0;
        window.hideSkeleton = function(){ cancelAnimationFrame(raf); raf = requestAnimationFrame(function(){ try{ orig(); }catch(_){ } }); };
        window.hideSkeleton._soft = true;
      }
    }catch(_){}
  })();
  document.addEventListener('DOMContentLoaded', function(){
    ['produtos','lojas','pivot'].forEach(ensureSmartBind);
    ['produtos','lojas'].forEach(attachCaptureHandlers);
  });
})();
</script>
<!-- END: Filters Stabilizer v1 -->
<!-- BEGIN: Clean Master v2 -->
<script>
(function(){
  function fire(el, type){ try{ el.dispatchEvent(new Event(type,{bubbles:true})); }catch(_){ } }
  function detachListeners(node){
    if(!node || !node.parentNode) return node;
    const clone = node.cloneNode(true);
    node.parentNode.replaceChild(clone, node);
    return clone;
  }
  function wipeInputs(root){
    if(!root) return;
    root.querySelectorAll('input,select,textarea').forEach(el=>{
      const tag = (el.tagName||'').toUpperCase();
      const type = (el.type||'').toLowerCase();
      if(tag==='SELECT'){ el.selectedIndex = 0; }
      else if(type==='checkbox' || type==='radio'){ el.checked = false; }
      else { el.value = ''; }
    });
    try{ if(window.jQuery) window.jQuery(root).find('.select2-hidden-accessible').val(null).trigger('change'); }catch(_){}
    try{ root.querySelectorAll('.ts-control').forEach(e=>{ e.tomselect?.clear?.(); e.tomselect?.refreshOptions?.(); }); }catch(_){}
    try{ root.querySelectorAll('input[tagify], .tagify__input').forEach(e=>{ e.__tagify?.removeAllTags?.(); }); }catch(_){}
    try{ root.querySelectorAll('input.flatpickr-input').forEach(e=>{ e._flatpickr?.clear?.(); }); }catch(_){}
    root.querySelectorAll('.applied-filters,.filter-badges,.chips').forEach(ct=>{ ct.innerHTML=''; });
  }
  function wipeTables(ids){
    ids.forEach(id=>{
      const tbl = document.getElementById(id);
      if(!tbl) return;
      const th = tbl.querySelector('thead'); if(th) th.innerHTML='';
      const tb = tbl.querySelector('tbody'); if(tb) tb.innerHTML='';
      const tf = tbl.querySelector('tfoot'); if(tf) tf.innerHTML='';
    });
  }
  function purgeStorage(){
    const pats = [/filtro/i,/filter/i,/busca/i,/search/i,/query/i,/secao/i,/categoria/i,/marca/i,/estado/i,/page/i,/pagina/i,/sort/i,/ordem/i];
    function del(store){
      try{ Object.keys(store).forEach(k=>{ if(pats.some(p=>p.test(k))) store.removeItem(k); }); }catch(_){}
    }
    try{ del(localStorage); }catch(_){}
    try{ del(sessionStorage); }catch(_){}
  }
  function resetURL(){ try{ history.replaceState(null,'',location.pathname); }catch(_){ } }
  function rebindFilters(tab){
    try{
      const root = document.getElementById('filtros-'+tab);
      if (typeof bindSmartFilters==='function' && root){ bindSmartFilters(tab); root._smartBound = true; }
    }catch(_){}
  }
  function focusFirst(tab){
    const root = document.getElementById('filtros-'+tab);
    const first = root && (root.querySelector('input[type="search"],input[type="text"],select'));
    try{ first && first.focus(); }catch(_){}
  }
  function withApplyShadow(fn){
    const had = typeof window.apply==='function'; const orig = window.apply;
    window.__CLEANING__ = true;
    if(had){ window.apply = function(){ if(window.__CLEANING__) return; return orig.apply(this, arguments); }; }
    try{ fn(); } finally { window.__CLEANING__ = false; if(had) window.apply = orig; }
  }
  function resetStateFor(tab){
    try{
      if (typeof PAGE!=='undefined') PAGE = 1;
      if (typeof PAGES!=='undefined') PAGES = 1;
      const adv = document.getElementById('advSearch'); if (adv){ adv.value=''; }
      if (typeof FILTERED!=='undefined'){
        if (tab==='produtos') FILTERED.produtos = [];
        if (tab==='lojas') FILTERED.lojas = [];
        if (tab==='pivot'){ FILTERED.pivotRows = []; FILTERED.pivotCols = []; FILTERED.pivotMap = null; }
      }
      if (typeof MULTI!=='undefined'){
        if (tab==='produtos'){ MULTI.produtos.secao = []; MULTI.produtos.categoria = []; MULTI.produtos.marca = []; }
        else if (tab==='lojas'){ MULTI.lojas.estado = []; MULTI.lojas.secao = []; MULTI.lojas.categoria = []; MULTI.lojas.marca = []; }
      }
      if (typeof SORT!=='undefined'){ SORT.produtos = []; SORT.lojas = []; SORT.pivot = []; }
      const lbl=document.querySelector('#pageLabel'); if (lbl) lbl.textContent='1/1';
      const lblB=document.querySelector('#pageLabelB'); if (lblB) lblB.textContent='1/1';
      const empty=document.getElementById('emptyMsg'); if (empty) empty.style.display='';
      const btnApply=document.getElementById('btnApply'); if (btnApply){ btnApply.disabled=false; btnApply.removeAttribute('aria-disabled'); }
    }catch(_){}
  }
  window.limparAba = function(){
    const tab = (typeof ACTIVE_TAB!=='undefined' && ACTIVE_TAB) ? ACTIVE_TAB : 'produtos';
    withApplyShadow(function(){
      const oldRoot = document.getElementById('filtros-'+tab);
      const root = detachListeners(oldRoot);
      wipeInputs(root);
      if (tab==='produtos') wipeTables(['tableBase1']);
      else if (tab==='lojas') wipeTables(['tableBase2','tablePivotEV']);
      else if (tab==='pivot') wipeTables(['tablePivot','tablePivotValor']);
      resetStateFor(tab);
      resetURL();
    });
    rebindFilters((typeof ACTIVE_TAB!=='undefined' && ACTIVE_TAB) ? ACTIVE_TAB : 'produtos');
    focusFirst((typeof ACTIVE_TAB!=='undefined' && ACTIVE_TAB) ? ACTIVE_TAB : 'produtos');
    try{ setStatus && setStatus('Aba limpa. Selecione filtros e clique em Aplicar.'); }catch(_){}
    document.dispatchEvent(new CustomEvent('app:limpo', { detail: { scope:'tab', tab: (typeof ACTIVE_TAB!=='undefined'&&ACTIVE_TAB)||'produtos', at:Date.now() } }));
  };
  window.limparApp = function(){
    withApplyShadow(function(){
      ['produtos','lojas','pivot'].forEach(function(tab){
        const oldRoot = document.getElementById('filtros-'+tab);
        const root = detachListeners(oldRoot);
        wipeInputs(root);
      });
      wipeTables(['tableBase1','tableBase2','tablePivot','tablePivotValor','tablePivotEV']);
      ['produtos','lojas','pivot'].forEach(resetStateFor);
      purgeStorage(); resetURL();
    });
    ['produtos','lojas','pivot'].forEach(rebindFilters);
    focusFirst((typeof ACTIVE_TAB!=='undefined' && ACTIVE_TAB) ? ACTIVE_TAB : 'produtos');
    try{ setStatus && setStatus('Aplicação limpa por completo.'); }catch(_){}
    document.dispatchEvent(new CustomEvent('app:limpo', { detail: { scope:'app', at:Date.now() } }));
  };
  document.addEventListener('DOMContentLoaded', function(){
    const btn = document.getElementById('btnClear') || document.getElementById('btnLimpar') || document.querySelector('.btn-limpar,[data-action="limpar"],button[name="limpar"]');
    if(btn && !btn._cleanBound){
      btn.addEventListener('click', function(ev){ if (ev.shiftKey) { ev.preventDefault(); return window.limparApp(); } ev.preventDefault(); window.limparAba(); });
      btn._cleanBound = true;
    }
  });
})();
</script>
<!-- END: Clean Master v2 -->
<!-- BEGIN: Cascade Filters v5 -->
<script>
(function(){
  const uniq = (arr)=> Array.from(new Set(arr.filter(v=>v!=null && v!=='')));
  const norm = (s)=>{ const x=String(s==null?'':s); try{ return x.normalize('NFD').replace(/\p{Diacritic}/gu,'').trim().toLowerCase(); }catch(_){ return x.trim().toLowerCase(); } };
  const textOf = el => (el ? (el.innerText || el.textContent || '').trim() : '');
  function findSelectByLabel(root, keywords){
    keywords = Array.isArray(keywords) ? keywords : [keywords];
    const sels = Array.from(root.querySelectorAll('select'));
    let best = null, bestScore = -1;
    sels.forEach(sel=>{
      let txt = '';
      if (sel.id) { const lbl = root.querySelector('label[for="'+sel.id+'"]'); if (lbl) txt += ' ' + (lbl.innerText||lbl.textContent||''); }
      let p = sel.previousElementSibling; if (p) txt += ' ' + (p.innerText||p.textContent||'');
      txt += ' ' + (sel.getAttribute('aria-label')||'') + ' ' + (sel.getAttribute('placeholder')||'') + ' ' + (sel.name||'') + ' ' + (sel.id||'');
      const low = txt.toLowerCase(); let sc=0; keywords.forEach(k=>{ if (low.includes(k.toLowerCase())) sc += 5; });
      if (sc > bestScore){ bestScore = sc; best = sel; }
    });
    return best;
  }
  function getTabRoots(){
    const roots = []; ['produtos','lojas','pivot'].forEach(t=>{ const el = document.getElementById('filtros-'+t); if (el) roots.push(el); });
    if (!roots.length){
      const candidates = Array.from(document.querySelectorAll('section,div,form,fieldset')).slice(0, 50);
      candidates.forEach(c=>{
        const txt = (c.innerText||c.textContent||'').toLowerCase();
        if ((txt.includes('seção') || txt.includes('secao')) && txt.includes('categoria') && txt.includes('marca')) roots.push(c);
      });
    }
    return Array.from(new Set(roots));
  }
  function buildLookups(){
    if (!window.DATA || !window.IDX1 || !window.IDX2) return null;
    const L = { bySecao:new Map(), bySecaoCat:new Map(), catAll:new Set(), marcaAll:new Set() };
    (DATA.base1?.rows||[]).forEach(r=>{
      const s = norm(r[IDX1.secao]);
      const c = norm(r[IDX1.cat] ?? r[IDX1.categoria]);
      const m = norm(r[IDX1.marca]);
      if (!L.bySecao.has(s)) L.bySecao.set(s, {cats:new Set(), marcas:new Set()});
      if (c) L.bySecao.get(s).cats.add(c);
      if (m) L.bySecao.get(s).marcas.add(m);
      const key = s+'|'+c; if (!L.bySecaoCat.has(key)) L.bySecaoCat.set(key, new Set()); if (m) L.bySecaoCat.get(key).add(m);
      if (c) L.catAll.add(c); if(m) L.marcaAll.add(m);
    });
    const M = { bySecao:new Map(), bySecaoCat:new Map(), catAll:new Set(), marcaAll:new Set() };
    (DATA.base2?.rows||[]).forEach(r=>{
      const s = norm(r[IDX2.secao]); const c = norm(r[IDX2.categoria]); const m = norm(r[IDX2.marca]);
      if (!M.bySecao.has(s)) M.bySecao.set(s, {cats:new Set(), marcas:new Set()});
      if (c) M.bySecao.get(s).cats.add(c);
      if (m) M.bySecao.get(s).marcas.add(m);
      const key = s+'|'+c; if (!M.bySecaoCat.has(key)) M.bySecaoCat.set(key, new Set()); if (m) M.bySecaoCat.get(key).add(m);
      if (c) M.catAll.add(c); if(m) M.marcaAll.add(m);
    });
    return {L,M};
  }
  function optionsText(select){ return Array.from(select.querySelectorAll('option')).map(o=>o.value ? (o.textContent||'').trim() : null).filter(Boolean).map(norm); }
  function repopulateWithValues(select, normalizedValues, placeholder){
    if(!select) return; const prev = norm(select.value||''); const vals = uniq(normalizedValues);
    const out = ['<option value="">'+(placeholder||'Todas')+'</option>'].concat(vals.map(v=>'<option value="'+v+'">'+v+'</option>')).join('');
    select.innerHTML = out; if (vals.includes(prev)) select.value = prev; else select.value = '';
    try{ select.dispatchEvent(new Event('change',{bubbles:true})); }catch(_){}
    if (window.jQuery && window.jQuery.fn && window.jQuery.fn.select2){ try{ window.jQuery(select).trigger('change.select2'); }catch(_){ } }
    if (select.tomselect){ try{ select.tomselect.clearOptions(); vals.forEach(v=>select.tomselect.addOption({value:v,text:v})); select.tomselect.refreshOptions(false); if(select.value) select.tomselect.setValue(select.value,true); }catch(_){ } }
  }
  function cascadeInRoot(root, look){
    const secSel = findSelectByLabel(root, ['seção','secao']);
    const catSel = findSelectByLabel(root, ['categoria','cat']);
    const marSel = findSelectByLabel(root, ['marca','brand']);
    if(!secSel || !catSel || !marSel) return;
    const sN = norm(secSel.value);
    if (!sN){
      const cats0 = optionsText(catSel); const mar0  = optionsText(marSel);
      const allCats = uniq(Array.from(look.L.catAll).concat(Array.from(look.M.catAll)));
      const allMar  = uniq(Array.from(look.L.marcaAll).concat(Array.from(look.M.marcaAll)));
      if (cats0.length===0 || cats0.length<allCats.length) repopulateWithValues(catSel, allCats, 'Todas');
      if (mar0.length===0  || mar0.length<allMar.length)   repopulateWithValues(marSel, allMar,  'Todas');
      return;
    }
    const E1 = look.L.bySecao.get(sN) || {cats:new Set(), marcas:new Set()};
    const E2 = look.M.bySecao.get(sN) || {cats:new Set(), marcas:new Set()};
    const cats = uniq(Array.from(E1.cats).concat(Array.from(E2.cats)));
    repopulateWithValues(catSel, cats, 'Todas');
    const cN = norm(catSel.value);
    if (cN){
      const key = sN+'|'+cN;
      const m1 = look.L.bySecaoCat.get(key) || new Set();
      const m2 = look.M.bySecaoCat.get(key) || new Set();
      const marcas = uniq(Array.from(m1).concat(Array.from(m2)));
      repopulateWithValues(marSel, marcas, 'Todas');
    } else {
      const marcas = uniq(Array.from(E1.marcas).concat(Array.from(E2.marcas)));
      repopulateWithValues(marSel, marcas, 'Todas');
    }
  }
  function bindAll(){
    const look = buildLookups(); if(!look) return setTimeout(bindAll, 200);
    const roots = getTabRoots(); if(!roots.length) return setTimeout(bindAll, 200);
    const bindRoot = (root)=>{
      const handler = ()=> cascadeInRoot(root, look);
      handler();
      const secSel = findSelectByLabel(root, ['seção','secao']);
      const catSel = findSelectByLabel(root, ['categoria','cat']);
      if (secSel && !secSel._cascV5){ secSel.addEventListener('change', handler, {capture:true}); secSel._cascV5 = true; }
      if (catSel && !catSel._cascV5){ catSel.addEventListener('change', handler, {capture:true}); catSel._cascV5 = true; }
      if (!root._cascObsV5){
        const obs = new MutationObserver(()=>{ clearTimeout(root._cascTO); root._cascTO = setTimeout(handler, 60); });
        obs.observe(root, {childList:true, subtree:true}); root._cascObsV5 = obs;
      }
    };
    roots.forEach(bindRoot);
    if (typeof window.apply === 'function' && !window.__cascHookV5){
      const orig = window.apply;
      window.apply = function(){ try{ return orig.apply(this, arguments); } finally { try{ roots.forEach(r=> cascadeInRoot(r, look)); }catch(_){ } } };
      window.__cascHookV5 = true;
    }
  }
  document.addEventListener('DOMContentLoaded', bindAll);
})();
</script>
<!-- END: Cascade Filters v5 -->
<!-- BEGIN: Zebra Print Enforcer v3 -->
<script>
(function(){
  const TABLE_IDS = ["tableBase1","tableBase2","tablePivot","tablePivotValor","tablePivotEV"];
  const ODD = "#eaeef7"; const EVEN = "#ffffff";
  function setCellBg(td, color){
    try{ td.style.setProperty('background-color', color, 'important'); td.style.setProperty('background-image', 'none', 'important'); td.style.setProperty('box-shadow', 'none', 'important'); }catch(_){}
  }
  function clearCellBg(td){
    try{ td.style.removeProperty('background-color'); td.style.removeProperty('background-image'); td.style.removeProperty('box-shadow'); }catch(_){}
  }
  function applyPrintZebra(){
    TABLE_IDS.forEach(id=>{
      const tbl = document.getElementById(id); if(!tbl) return;
      const rows = tbl.querySelectorAll('tbody tr');
      for(let i=0;i<rows.length;i++){
        const tds = rows[i].querySelectorAll('td');
        const color = (i%2===0? ODD : EVEN);
        tds.forEach(td=> setCellBg(td, color));
      }
    });
    try{
      const s = document.createElement('style'); s.setAttribute('data-print-zebra','');
      s.textContent = `@media print { *, table, tr, td, th { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; } }`;
      document.head.appendChild(s);
    }catch(_){}
  }
  function clearPrintZebra(){
    TABLE_IDS.forEach(id=>{
      const tbl = document.getElementById(id); if(!tbl) return;
      const tds = tbl.querySelectorAll('tbody td'); tds.forEach(clearCellBg);
    });
    document.querySelectorAll('style[data-print-zebra]').forEach(el=> el.remove());
  }
  if (window.matchMedia){
    const mq = window.matchMedia('print');
    if (mq && mq.addListener){
      mq.addListener(function(m){ if (m.matches){ applyPrintZebra(); } else { clearPrintZebra(); } });
    }
  }
  window.addEventListener('beforeprint', applyPrintZebra);
  window.addEventListener('afterprint', clearPrintZebra);
})();
</script>
<!-- END: Zebra Print Enforcer v3 -->
<!-- BEGIN: Product Store Peek v6 (B1 Código=C; B2 Loja=C, Código=G, Estoque=R) -->
<style>
  .psp-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.35); display: none; align-items: center; justify-content: center; z-index: 9999; }
  .psp-overlay.open { display: flex; }
  .psp-modal { background: #fff; max-width: 760px; width: 92vw; max-height: 80vh; border-radius: 14px; box-shadow: 0 20px 60px rgba(0,0,0,.2); overflow: hidden; }
  .psp-header { display:flex; align-items:center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid #e7eaf3; background:#f9fbff; }
  .psp-title { font-weight: 600; font-size: 16px; margin: 0; }
  .psp-close { background: transparent; border: 0; font-size: 18px; cursor: pointer; line-height: 1; padding: 4px 8px; }
  .psp-body { padding: 8px 16px 16px; overflow: auto; }
  .psp-meta { color:#5b6378; font-size:12px; margin-bottom:8px; }
  .psp-table { width: 100%; border-collapse: collapse; }
  .psp-table th, .psp-table td { padding: 8px 10px; border-bottom: 1px solid #eef1f6; text-align: left; }
  .psp-table tbody tr:nth-child(odd) td { background: #f7f8fb; }
  .psp-table tbody tr:hover td { filter: brightness(0.985); }
  .psp-empty { padding: 16px; color:#6b7280; }
  @media (max-width:560px){ .psp-title { font-size: 14px; } .psp-table th, .psp-table td { padding: 6px 8px; } }
  @media print { .psp-overlay { display:none !important; } }
</style>
<script>
(function(){
  function cleanCode(x){
    var s = String(x==null?'':x).trim();
    s = s.replace(/[\.\s\-_/]/g, '');
    if (/^\d+$/.test(s)) s = s.replace(/^0+/, '');
    return s.toUpperCase();
  }
  function parseNum(x){
    if (typeof x==='number') return isFinite(x)?x:0;
    var s = String(x==null?'':x).trim();
    if (!s) return 0;
    s = s.replace(/[\s]/g,'');
    var hasComma = s.indexOf(',')>-1;
    var hasDot = s.indexOf('.')>-1;
    if (hasComma && hasDot){
      s = s.replace(/\./g,'').replace(',','.');
    } else if (hasComma){
      s = s.replace(',','.');
    }
    var n = parseFloat(s);
    return isFinite(n)?n:0;
  }

  // >>> MAPEAMENTOS <<<
  var B1_CODE_IDX = 2; // Base 1: Código na COLUNA C (0-based)
  var B2_IDX = { loja: 2, codigo: 6, estoque: 17 }; // Base 2: Loja=C, Código=G, Estoque=R

  function getBase2Rows(){
    try{
      if (window.DATA && window.DATA.base2 && Array.isArray(window.DATA.base2.rows) && window.DATA.base2.rows.length) return window.DATA.base2.rows;
      if (window.BASE2 && Array.isArray(window.BASE2.rows) && window.BASE2.rows.length) return window.BASE2.rows;
      if (Array.isArray(window.rowsBase2) && window.rowsBase2.length) return window.rowsBase2;
    }catch(_){}
    var tbl = document.getElementById('tableBase2');
    if (!tbl) return [];
    var rows = [];
    var trs = tbl.querySelectorAll('tbody tr');
    for (var i=0;i<trs.length;i++){
      var tds = trs[i].children || [];
      var row = [];
      for (var j=0;j<tds.length;j++) row.push(tds[j].innerText || tds[j].textContent || '');
      rows.push(row);
    }
    return rows;
  }

  function gatherStoresFor(codeRaw){
    var rows2 = getBase2Rows();
    var map = new Map();
    var c1 = cleanCode(codeRaw);
    for (var i=0;i<rows2.length;i++){
      var r = rows2[i];
      var c2 = cleanCode(r[B2_IDX.codigo]);
      if (!c1 || !c2 || c2!==c1) continue;
      var loja = String(r[B2_IDX.loja]||'');
      var q = parseNum(r[B2_IDX.estoque]);
      if (!map.has(loja)) map.set(loja, 0);
      map.set(loja, map.get(loja)+q);
    }
    var out = Array.from(map.entries()).map(function(p){ return {loja:p[0]||'(Sem loja)', qtd:p[1]||0}; });
    out.sort(function(a,b){ return b.qtd - a.qtd; });
    return out;
  }

  function ensureModal(){
    var overlay = document.getElementById('psp-overlay');
    if (overlay) return overlay;
    overlay = document.createElement('div');
    overlay.id = 'psp-overlay';
    overlay.className = 'psp-overlay';
    overlay.innerHTML = '<div class="psp-modal" role="dialog" aria-modal="true" aria-labelledby="psp-title">'+
      '<div class="psp-header"><h3 id="psp-title" class="psp-title">Lojas com este produto</h3>'+
      '<button class="psp-close" title="Fechar" aria-label="Fechar">&times;</button></div>'+
      '<div class="psp-body"><div class="psp-meta"></div><div class="psp-content"></div></div>'+
      '</div>';
    document.body.appendChild(overlay);
    overlay.addEventListener('click', function(ev){ if (ev.target===overlay) closeModal(); });
    overlay.querySelector('.psp-close').addEventListener('click', closeModal);
    window.addEventListener('keydown', function(ev){ if (ev.key==='Escape') closeModal(); });
    return overlay;
  }
  function openModal(html, title, meta){
    var ov = ensureModal();
    ov.querySelector('.psp-title').textContent = title || 'Lojas com este produto';
    ov.querySelector('.psp-meta').textContent = meta || '';
    ov.querySelector('.psp-content').innerHTML = html || '';
    ov.classList.add('open');
  }
  function closeModal(){ var ov = document.getElementById('psp-overlay'); if (ov) ov.classList.remove('open'); }

  function buildTableHtml(list, code){
    if (!list.length){
      return '<div class="psp-empty">Nenhuma loja encontrada na Base 2 para o código (coluna G).<br>'+
             'Código utilizado (Base 1 - Coluna C): <b>'+ (code||'(vazio)') +'</b><br>'+
             'A comparação ignora espaços, pontos, traços, barras e zeros à esquerda (se numérico).</div>';
    }
    var total = list.reduce(function(s,it){ return s + (it.qtd||0); }, 0);
    return '<table class="psp-table"><thead><tr><th>Loja (Base 2 - Coluna C)</th><th style="text-align:right">Quantidade (Coluna R)</th></tr></thead><tbody>'+
           list.map(function(it){ return '<tr><td>'+ (it.loja||'') +'</td><td style="text-align:right">'+ it.qtd +'</td></tr>'; }).join('')+
           '</tbody><tfoot><tr><th>Total</th><th style="text-align:right">'+ total +'</th></tr></tfoot></table>';
  }

  function getBase1Table(){ return document.getElementById('tableBase1'); }

  function resolveDescIdx(table){
    var ths = table && table.querySelectorAll('thead th');
    if (!ths || !ths.length) return -1;
    var keys = ['descrição','descricao','produto','nome','desc'];
    var best=-1,score=-1;
    for (var i=0;i<ths.length;i++){
      var t = (ths[i].textContent||''); try{ t = t.normalize('NFD').replace(/\p{Diacritic}/gu,''); }catch(_){}
      t = t.trim().toLowerCase();
      var sc = 0; for (var j=0;j<keys.length;j++){ if (t.indexOf(keys[j])>-1) sc++; }
      if (sc>score){ score=sc; best=i; }
    }
    return best;
  }

  function resolveCodeFromRow(row){
    if (!row || !row.cells || row.cells.length<=B1_CODE_IDX) return '';
    return String(row.cells[B1_CODE_IDX].innerText||'').trim();
  }

  function onRowClick(ev){
    var table = getBase1Table(); if (!table) return;
    var cell = ev.target.closest('td'); if (!cell || !table.contains(cell)) return;
    var row = cell.parentElement;
    var descIdx = resolveDescIdx(table);
    var isDesc = (descIdx>=0 && cell.cellIndex===descIdx);
    var force = ev.altKey===true;
    if (!isDesc && !force) return;

    var code = resolveCodeFromRow(row);
    var desc = String((descIdx>=0 && row.cells[descIdx]) ? row.cells[descIdx].innerText||'' : '').trim();
    var list = [];
    try { list = gatherStoresFor(code); } catch(e){ try{ console.error('PSP v6 gather error', e); }catch(_){ } }
    var title = desc || 'Lojas com este produto';
    var meta = code ? ('Código (Base 1 - Coluna C): '+code) : '';
    openModal(buildTableHtml(list, code), title, meta);
  }

  function install(){
    if (document._pspV6) return;
    document.addEventListener('click', onRowClick, true);
    if (typeof window.apply==='function' && !window.__pspHookV6){
      var orig = window.apply;
      window.apply = function(){
        try{ return orig.apply(this, arguments); }
        finally{ try{ /* delegação no document já garante */ }catch(_){ } }
      };
      window.__pspHookV6 = true;
    }
    document._pspV6 = true;
  }

  document.addEventListener('DOMContentLoaded', install);
})();
</script>
<!-- END: Product Store Peek v6 -->
<!-- BEGIN: Purchase History v1 (Base - Espelho de Compra) -->
<style>
  .psp-modal{
    max-height: 90vh;
    display: flex;
    flex-direction: column;
  }
  .psp-body{
    flex: 1 1 auto;
    overflow-y: auto;
  }
</style>
<script>
(function(){
  const CFG = {
    sheetId: '1-ONBPnAswGhNV3hb8sAsbz0q1NDk2dGqa_9NdQ3WHcI',
    gid: '1272885860',
    ttlMs: 5*60*1000
  };
  let CACHE = null;
  let LAST_FETCH = 0;

  function normalizeCode(x){
    try{
      var s = String(x == null ? '' : x).trim();
      s = s.replace(/[\.\s\-_/]/g, '');
      if (/^\d+$/.test(s)) s = s.replace(/^0+/, '');
      return s.toUpperCase();
    }catch(_){
      return '';
    }
  }

  function parseDateBr(s){
    if (!s) return 0;
    if (s instanceof Date) return s.getTime();
    s = String(s).trim();
    var m = s.match(/(\d{1,2})\/(\d{1,2})\/(\d{2,4})/);
    if (!m) return 0;
    var d = parseInt(m[1],10)||1;
    var mo = (parseInt(m[2],10)||1) - 1;
    var y = parseInt(m[3],10)||0;
    if (y < 100) y = 2000 + y;
    return new Date(y, mo, d).getTime();
  }

  function parseValorBr(v){
    if (typeof v === 'number') return isFinite(v) ? v : 0;
    var s = String(v == null ? '' : v).trim();
    if (!s) return 0;
    s = s.replace(/[^0-9,.-]/g, '');
    var hasComma = s.indexOf(',') > -1;
    var hasDot = s.indexOf('.') > -1;
    if (hasComma && hasDot){
      s = s.replace(/\./g,'').replace(',', '.');
    } else if (hasComma){
      s = s.replace(',', '.');
    }
    var n = parseFloat(s);
    return isNaN(n) ? 0 : n;
  }

  function formatCurrency(n){
    try{
      return n.toLocaleString('pt-BR', { style:'currency', currency:'BRL' });
    }catch(_){
      return 'R$ ' + (n||0).toFixed(2).replace('.',',');
    }
  }

  function formatPercent(n){
    if (!isFinite(n)) n = 0;
    return n.toFixed(1).replace('.', ',') + '%';
  }

  function parseCSVLocal(text){
    try{
      if (typeof window.parseCSV === 'function'){
        return window.parseCSV(text);
      }
    }catch(_){}
    var rows = [];
    var row = [];
    var cur = '';
    var q = false;
    for (var i=0;i<text.length;i++){
      var ch = text[i];
      var next = text[i+1];
      if (ch === '"'){
        if (q && next === '"'){ cur += '"'; i++; }
        else { q = !q; }
      } else if (ch === ',' && !q){
        row.push(cur); cur = '';
      } else if ((ch === '\n' || ch === '\r') && !q){
        if (cur !== '' || row.length){ row.push(cur); rows.push(row); row = []; cur=''; }
        if (ch === '\r' && next === '\n') i++;
      } else {
        cur += ch;
      }
    }
    if (cur !== '' || row.length){ row.push(cur); rows.push(row); }
    return rows;
  }

  async function ensureData(){
    var now = Date.now();
    if (CACHE && (now - LAST_FETCH) < CFG.ttlMs) return CACHE;
    var url = 'https://docs.google.com/spreadsheets/d/'+CFG.sheetId+'/export?format=csv&gid='+CFG.gid;
    const resp = await fetch(url, { cache: 'no-store' });
    if (!resp.ok) throw new Error('Falha ao baixar histórico de compras');
    const text = await resp.text();
    const rows = parseCSVLocal(text) || [];
    const header = rows[0] || [];
    const dataRows = rows.slice(1).filter(function(r){ return r && r.length; });
    const idx = {
      codigo: 0,
      data:   1,
      valor:  2,
      icms:   3,
      ipi:    4,
      dep:    5
    };
    CACHE = { header: header, rows: dataRows, idx: idx };
    LAST_FETCH = now;
    return CACHE;
  }

  function buildStats(list, idx){
    if (!list || !list.length) return null;
    var valores = list.map(function(r){ return parseValorBr(r[idx.valor]); }).filter(function(v){ return isFinite(v) && v > 0; });
    if (!valores.length) return null;
    var n = valores.length;
    var soma = valores.reduce(function(a,b){ return a+b; }, 0);
    var media = soma / n;
    var min = Math.min.apply(null, valores);
    var max = Math.max.apply(null, valores);
    var primeiro = parseValorBr(list[list.length-1][idx.valor]);
    var ultimo   = parseValorBr(list[0][idx.valor]);
    var diffAbs = ultimo - primeiro;
    var diffPct = primeiro ? (diffAbs / primeiro) * 100 : 0;
    var tendencia = 'estável';
    if (diffAbs > 0.01) tendencia = 'em alta';
    else if (diffAbs < -0.01) tendencia = 'em queda';
    return {
      n: n,
      media: media,
      min: min,
      max: max,
      primeiro: primeiro,
      ultimo: ultimo,
      diffAbs: diffAbs,
      diffPct: diffPct,
      tendencia: tendencia
    };
  }

  function ensureModal(){
    var ov = document.getElementById('ph-overlay');
    if (ov) return ov;
    ov = document.createElement('div');
    ov.id = 'ph-overlay';
    ov.className = 'psp-overlay';
    ov.innerHTML =
      '<div class="psp-modal" role="dialog" aria-modal="true" aria-labelledby="ph-title">'+
        '<div class="psp-header">'+
          '<h3 id="ph-title" class="psp-title"></h3>'+
          '<button class="psp-close" title="Fechar" aria-label="Fechar">&times;</button>'+
        '</div>'+
        '<div class="psp-body">'+
          '<div class="psp-meta"></div>'+
          '<div class="psp-content"></div>'+
        '</div>'+
      '</div>';
    document.body.appendChild(ov);
    ov.addEventListener('click', function(ev){ if (ev.target === ov) ov.classList.remove('open'); });
    ov.querySelector('.psp-close').addEventListener('click', function(){ ov.classList.remove('open'); });
    window.addEventListener('keydown', function(ev){ if (ev.key === 'Escape') ov.classList.remove('open'); });
    return ov;
  }

  function openHistoryModal(code, desc, list, stats){
    var ov = ensureModal();
    var title = desc || 'Histórico de preço de compra';
    ov.querySelector('.psp-title').textContent = title;
    var metaParts = [];
    if (code) metaParts.push('Código: '+code);
    if (stats){
      metaParts.push('Registros: '+stats.n);
      metaParts.push('Média: '+formatCurrency(stats.media));
      metaParts.push('Mín.: '+formatCurrency(stats.min));
      metaParts.push('Máx.: '+formatCurrency(stats.max));
      metaParts.push('Tendência: '+stats.tendencia);
      metaParts.push('Variação: '+(stats.diffAbs>=0?'+':'')+formatCurrency(stats.diffAbs)+' ('+formatPercent(stats.diffPct)+')');
    }
    ov.querySelector('.psp-meta').textContent = metaParts.join(' • ');

    var idx = CACHE && CACHE.idx || {};
    if (!list || !list.length){
      ov.querySelector('.psp-content').innerHTML =
        '<div class="psp-empty">Nenhuma compra encontrada na base de espelho para este código.</div>';
    } else {
      var rowsHtml = list.map(function(r){
        var dt  = r[idx.data]  || '';
        var vlr = r[idx.valor] || '';
        var icm = r[idx.icms]  || '';
        var ipi = r[idx.ipi]   || '';
        var dep = typeof idx.dep === 'number' ? (r[idx.dep]||'') : '';
        return '<tr>'+
          '<td>'+dt+'</td>'+
          '<td>'+vlr+'</td>'+
          '<td>'+icm+'</td>'+
          '<td>'+ipi+'</td>'+
          '<td>'+dep+'</td>'+
        '</tr>';
      }).join('');
      var html =
        '<table class="psp-table">'+
          '<thead><tr><th>Entrada</th><th>Valor</th><th>ICMS</th><th>IPI</th><th>Dep.</th></tr></thead>'+
          '<tbody>'+rowsHtml+'</tbody>'+
        '</table>';
      ov.querySelector('.psp-content').innerHTML = html;
    }

    ov.classList.add('open');
  }

  async function showHistoryFor(code, desc){
    try{
      var data = await ensureData();
      var idx = data.idx;
      var norm = normalizeCode(code);
      var list = data.rows.filter(function(r){
        return normalizeCode(r[idx.codigo]) === norm;
      });
      list.sort(function(a,b){
        return parseDateBr(b[idx.data]) - parseDateBr(a[idx.data]);
      });
      var stats = buildStats(list, idx);
      openHistoryModal(code, desc, list, stats);
    }catch(e){
      try{ console.error('Histórico de compra - erro', e); }catch(_){}
      alert('Não foi possível carregar o histórico de preço de compra agora.');
    }
  }

  function findHeaderIndex(table, regex){
    try{
      var th = table.querySelector('thead tr');
      if (!th) return -1;
      var cells = Array.from(th.cells || []);
      for (var i=0;i<cells.length;i++){
        var txt = (cells[i].textContent || '').trim();
        if (regex.test(txt)) return i;
      }
    }catch(_){}
    return -1;
  }

  function onClick(ev){
    var cell = ev.target && ev.target.closest && ev.target.closest('#tableBase1 tbody td');
    if (!cell) return;
    var table = document.getElementById('tableBase1');
    if (!table) return;

    var colIdx = cell.cellIndex;
    if (colIdx == null || colIdx < 0) return;

    var headerRow = table.querySelector('thead tr');
    if (!headerRow || !headerRow.cells || !headerRow.cells.length) return;
    var headerCell = headerRow.cells[colIdx];
    var headerText = (headerCell && headerCell.textContent || '').trim().toLowerCase();
    if (!headerText) return;

    if (!(/pc1|pc2|pc3|compra|custo/.test(headerText))) return;

    var row = cell.parentElement;
    if (!row) return;

    var codeCol = findHeaderIndex(table, /c[oó]digo|sku|ean|ref/i);
    var descCol = findHeaderIndex(table, /descri|produto|nome/i);
    var code = '';
    var desc = '';
    try{
      if (codeCol >= 0 && row.cells[codeCol]) code = (row.cells[codeCol].innerText || '').trim();
      if (descCol >= 0 && row.cells[descCol]) desc = (row.cells[descCol].innerText || '').trim();
    }catch(_){}
    if (!code) return;

    showHistoryFor(code, desc);
  }

  document.addEventListener('click', onClick, true);
})();
</script>
<!-- END: Purchase History v1 (Base - Espelho de Compra) -->

<!-- BEGIN: Auto Search Fix v7 -->
<script>
(function(){
  function debounce(fn, ms){ let t; return function(){ const ctx=this, args=arguments; clearTimeout(t); t=setTimeout(function(){ fn.apply(ctx,args); }, ms||180); }; }
  function getRoots(){
    const ids = ['filtros-produtos','filtros-lojas','filtros-pivot'];
    const arr = ids.map(id=>document.getElementById(id)).filter(Boolean);
    if (arr.length) return arr;
    return Array.from(document.querySelectorAll('[id^=filtros-]'));
  }
  function isInsideFilters(el){
    if (!el) return false;
    const roots = getRoots();
    return roots.some(r => r && r.contains(el));
  }
  function tryApply(reason){
    if (window.__CLEANING__) return;
    try {
      if (typeof apply === 'function'){ apply(); }
      else {
        const btn = document.getElementById('btnApply') || document.querySelector('button[name="aplicar"], .btn-apply, [data-action="apply"]');
        if (btn){ btn.click(); }
      }
      try{ setStatus && setStatus('Atualizado ' + (reason?('('+reason+')'):'') ); }catch(_){}
    } catch(e){ try{ console.error('AutoSearchFix apply error', e); }catch(_){ } }
  }
  const onUserChange = debounce(function(ev){
    if (!isInsideFilters(ev.target)) return;
    const t = ev.target; const tag = (t.tagName||'').toUpperCase(); const tp = (t.type||'').toLowerCase();
    const relevant = tag==='SELECT' || tag==='INPUT' || tag==='TEXTAREA';
    if (!relevant) return;
    if (tag==='INPUT' && /^(text|search|number)$/i.test(tp) && String(t.value||'').trim()==='') return;
    if (window.__POST_CLEAR_ARMED__){ window.__POST_CLEAR_ARMED__ = false; tryApply('auto (pós-limpar)'); }
    else { tryApply('auto'); }
  }, 220);
  function installGlobalListeners(){
    if (document.__autoSearchFixBound__) return;
    document.addEventListener('change', onUserChange, true);
    document.addEventListener('keyup', function(e){
      const t = e.target || {}; if (t.tagName==='INPUT' && /^(text|search|number)$/i.test((t.type||''))){ onUserChange(e); }
    }, true);
    document.addEventListener('select2:select', onUserChange, true);
    document.addEventListener('select2:clear', onUserChange, true);
    document.addEventListener('tomselect-change', onUserChange, true);
    document.__autoSearchFixBound__ = true;
  }
  function hookCleaners(){
    if (window.__autoSearchCleanHooked__) return;
    function arm(){ window.__POST_CLEAR_ARMED__ = true; }
    ['limparAba','limparApp'].forEach(fnName=>{
      if (typeof window[fnName] === 'function'){
        const orig = window[fnName];
        window[fnName] = function(){
          try{ return orig.apply(this, arguments); } finally { arm(); installGlobalListeners(); }
        };
      }
    });
    document.addEventListener('click', function(ev){
      const btn = ev.target.closest('#btnClear, #btnLimpar, .btn-limpar, [data-action="limpar"], button[name="limpar"]');
      if (btn){ window.__POST_CLEAR_ARMED__ = true; }
    }, true);
    window.__autoSearchCleanHooked__ = true;
  }
  function hookApply(){
    if (window.__autoSearchApplyHooked__) return;
    if (typeof window.apply === 'function'){
      const orig = window.apply;
      window.apply = function(){
        try{ return orig.apply(this, arguments); }
        finally { installGlobalListeners(); }
      };
      window.__autoSearchApplyHooked__ = true;
    }
  }
  document.addEventListener('DOMContentLoaded', function(){
    installGlobalListeners();
    hookCleaners();
    hookApply();
  });
})();
</script>
<!-- END: Auto Search Fix v7 -->
<!-- BEGIN: Perf+Export Slim v1 -->
<script>
(function(){
  "use strict";
  var DEBUG = false; function log(){ if (DEBUG && window.console) console.log.apply(console, arguments); }

  function isVisible(el){
    if(!el) return false;
    var st = getComputedStyle(el);
    if (st.display === 'none' || st.visibility === 'hidden') return false;
    for (var p = el.parentElement; p; p = p.parentElement){
      var s = getComputedStyle(p);
      if (s.display === 'none' || s.visibility === 'hidden') return false;
    }
    return true;
  }
  function norm(s){
    try{ return String(s==null?'':s).normalize('NFD').replace(/\p{Diacritic}/gu,'').trim().toLowerCase(); }
    catch(_){ return String(s==null?'':s).trim().toLowerCase(); }
  }
  function debounce(fn, ms){ var t; return function(){ var a=arguments, ctx=this; clearTimeout(t); t=setTimeout(function(){ fn.apply(ctx,a); }, ms||250); }; }

  function getActiveTable(){
    var ids=['tableBasePivot','tableBase1','tableBase2'];
    for (var i=0;i<ids.length;i++){
      var el = document.getElementById(ids[i]);
      if (el && el.querySelector('thead') && el.querySelector('tbody') && isVisible(el)) return el;
    }
    var all = document.querySelectorAll('table');
    for (var j=0;j<all.length;j++){
      var t = all[j];
      if (t.querySelector('thead') && t.querySelector('tbody') && isVisible(t)) return t;
    }
    return null;
  }
  function getHeaderInfo(tbl){
    var ths = Array.from(tbl.querySelectorAll('thead th'));
    var labels = [], idxs = [];
    ths.forEach(function(th, i){
      if (isVisible(th)){ labels.push((th.innerText||th.textContent||'').trim()); idxs.push(i); }
    });
    if (!idxs.length){
      for (var k=0;k<ths.length;k++){ labels.push((ths[k].innerText||ths[k].textContent||'').trim()); idxs.push(k); }
    }
    return {labels:labels, idxs:idxs};
  }
  function rowsFromDOM(tbl, idxs){
    var out = [];
    var trs = tbl.querySelectorAll('tbody tr');
    trs.forEach(function(tr){
      if (!isVisible(tr)) return;
      var tds = tr.children || [];
      var row = [];
      idxs.forEach(function(i){
        var td = tds[i];
        var v = td ? (td.innerText||td.textContent||'') : '';
        row.push(String(v).trim());
      });
      out.push(row);
    });
    return out;
  }

  function getDataset(tblId){
    var baseKey=null;
    if (/base1/i.test(tblId)) baseKey='base1';
    else if (/base2/i.test(tblId)) baseKey='base2';
    else if (/pivot/i.test(tblId)) baseKey='pivot';
    var tryPaths=[
      (window.VIEW&&baseKey&&window.VIEW[baseKey]&&window.VIEW[baseKey].rows),
      (window.STATE&&baseKey&&window.STATE[baseKey]&&window.STATE[baseKey].rows),
      (window.DATA&&baseKey&&window.DATA[baseKey]&&window.DATA[baseKey].filteredRows),
      (window.DATA&&baseKey&&window.DATA[baseKey]&&window.DATA[baseKey].rowsFiltered),
      (window.DATA&&baseKey&&window.DATA[baseKey]&&window.DATA[baseKey].rowsView),
      (window.DATA&&baseKey&&window.DATA[baseKey]&&window.DATA[baseKey].rows)
    ];
    for (var i=0;i<tryPaths.length;i++){
      var arr = tryPaths[i];
      if (Array.isArray(arr) && arr.length) return {rows:arr, baseKey:baseKey};
    }
    return {rows:null, baseKey:baseKey};
  }
  function getDatasetHeaders(baseKey){
    var b = window.DATA && window.DATA[baseKey];
    return (b && (b.headers||b.cols)) || [];
  }
  function mapDataset(dataset, visibleLabels, datasetHeaders){
    if(!dataset || !dataset.length) return null;
    var isObj = (typeof dataset[0]==='object' && !Array.isArray(dataset[0]));
    var headers = (Array.isArray(datasetHeaders)&&datasetHeaders.length) ? datasetHeaders.slice() : (isObj? Object.keys(dataset[0]) : []);
    function findIdx(hay, lab){
      var t = norm(lab), best=-1, sc=-1;
      for (var i=0;i<hay.length;i++){
        var h = norm(hay[i]);
        var k = (h===t)?3 : (h.indexOf(t)>-1?2 : -1);
        if (k>sc){ sc=k; best=i; }
      }
      return best;
    }
    var mapIdx = visibleLabels.map(function(l){ return findIdx(headers, l); });
    var out = [];
    for (var r=0;r<dataset.length;r++){
      var src = dataset[r];
      var row = [];
      for (var c=0;c<visibleLabels.length;c++){
        var mi = mapIdx[c], v='';
        if (mi>=0){
          if (isObj){ v = src[headers[mi]]; }
          else if (Array.isArray(src)){ v = src[mi]; }
        }
        row.push(v==null? '' : String(v));
      }
      out.push(row);
    }
    return out;
  }

  function ensureSheetJS(){
    return new Promise(function(resolve){
      if (window.XLSX && window.XLSX.utils && window.XLSX.writeFile) return resolve();
      var s = document.createElement('script');
      s.src = "https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js";
      s.async = true;
      s.onload = resolve;
      s.onerror = resolve;
      document.head.appendChild(s);
    });
  }

  function buildAOA(complete){
    var tbl = getActiveTable();
    if (!tbl){ alert('Tabela não encontrada para exportação.'); return null; }
    var info = getHeaderInfo(tbl);
    var labels = info.labels, idxs = info.idxs;
    if (complete){
      var ds = getDataset(tbl.id||'');
      if (ds.rows){
        var hdrs = getDatasetHeaders(ds.baseKey);
        var mapped = mapDataset(ds.rows, labels, hdrs);
        if (mapped) return [labels].concat(mapped);
      }
    }
    var rows = rowsFromDOM(tbl, idxs);
    return [labels].concat(rows);
  }

  function saveAOA(aoa, filename){
    filename = filename || 'relatorio.xlsx';
    if (window.XLSX && XLSX.utils && XLSX.writeFile){
      var ws = XLSX.utils.aoa_to_sheet(aoa);
      var wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, ws, 'Relatório');
      XLSX.writeFile(wb, filename);
      return;
    }
    var csv = aoa.map(function(r){
      return r.map(function(v){ return '"' + String(v==null?'':v).replace(/"/g,'""') + '"'; }).join(';');
    }).join('\r\n');
    var blob = new Blob(['\ufeff' + csv], {type: 'text/csv;charset=utf-8;'});
    var a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = (filename.replace(/\.[^.]+$/, '') || 'relatorio') + '.csv';
    document.body.appendChild(a); a.click(); a.remove();
  }

  function handleExportClick(ev){
    var aoa = buildAOA(ev && ev.altKey);
    if (!aoa) return;
    var title = document.querySelector('.tab.active, .aba.ativa, .nav-link.active, .tab-link.active');
    var fname = title ? (title.textContent||'').trim().replace(/[\s]+/g,'_').toLowerCase() : 'relatorio';
    ensureSheetJS().then(function(){ saveAOA(aoa, fname + '.xlsx'); });
  }

  function bindExportButtons(){
    ['#btnExportXls', '#btnExport'].forEach(function(sel){
      document.querySelectorAll(sel).forEach(function(btn){
        if (!btn._perfExportBound){
          btn.addEventListener('click', function(ev){
            ev.preventDefault(); ev.stopPropagation();
            setTimeout(function(){ handleExportClick(ev); }, 0);
          }, true);
          btn.title = (btn.title||'') + ' (Dica: ALT+Clique exporta o conjunto completo quando possível)';
          btn._perfExportBound = true;
        }
      });
    });
  }

  function bindDebouncedSearch(){
    var inputs = document.querySelectorAll('input[data-debounce-apply], input[type="search"][data-debounce-apply]');
    inputs.forEach(function(inp){
      if (inp._debApplyBound) return;
      var handler = (function(){
        var t; return function(){
          clearTimeout(t);
          t = setTimeout(function(){ try{ if (typeof window.apply === 'function') window.apply(); }catch(_){} }, 250);
        };
      })();
      inp.addEventListener('input', handler, {passive:true});
      inp._debApplyBound = true;
    });
  }

  document.addEventListener('DOMContentLoaded', function(){
    // Injeta o CSS de performance no head se ainda não estiver
    if (!document.querySelector('style[data-perf-css-v1]')){
      var s = document.createElement('style'); s.setAttribute('data-perf-css-v1','');
      s.textContent = '.tab-pane, .aba, .conteudo-aba, section[data-filtros], section[data-lista]{content-visibility:auto;contain-intrinsic-size:1000px 600px;}';
      document.head.appendChild(s);
    }
    bindExportButtons();
    bindDebouncedSearch();
  });
})();
</script>
<!-- END: Perf+Export Slim v1 -->
<style>
/* === Highlights for Valor & Coluna U === */
th.col-valor, td.col-valor { font-weight: 600; }
th.col-u, td.col-u { font-style: normal; }
td.neg { color: #b20000; }
/* td.num could right-align numbers globally if wanted */
td.num { text-align: right; }
/* keep zebra intact, already present */
</style><style id="chatgpt-print-base">
/* ChatGPT: Print base */
@media print {
  @page { margin: 12mm; } /* respeita orientação do diálogo */
  html, body {
    font-size: var(--print-font-size, 14pt) !important;
    line-height: 1.35 !important;
  }
  table, td, th { font-size: inherit !important; line-height: inherit !important; }
  .no-print { display: none !important; }
  a[href]::after { content: "" !important; }
  /* Evita quebras esquisitas */
  body { break-inside: avoid; page-break-inside: avoid; }
}
</style>

<style>
/* === Zebra for PRINT ONLY (auto-injected) === */
@media print {
  :root {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    color-adjust: exact;
  }
  table tbody tr:nth-child(odd) td {
    background: #ffffff !important;
  }
  table tbody tr:nth-child(even) td {
    background: #d9d9d9 !important;
  }
  table, th, td {
    border-color: #666 !important;
  }
}

</style>



<script id="ev-limpar-hardreset-v3">
(function () {
  function isMainClearButton(el){
    if(!el) return false;
    if(el.id === "btnClear" || el.id === "btnLimpar") return true;
    if(el.matches && (el.matches('[data-action="limpar"]') || el.matches('[data-pro-action="clear"]'))) return true;
    return false;
  }
  function runClearAll(){
    try{
      if (typeof window.EVPL_SAFE_CLEAR === "function") { window.EVPL_SAFE_CLEAR("all"); return; }
      if (typeof window.EV_ClearAll === "function") { window.EV_ClearAll(); return; }
    }catch(_){}
    setTimeout(runClearAll, 60);
  }
  document.addEventListener("click", function(ev){
    const btn = ev.target.closest("button, a, input[type=button], input[type=submit]");
    if (!isMainClearButton(btn)) return;
    setTimeout(runClearAll, 0);
  }, true);
})();
</script>
<script src="net-guard.js?v=v20260622-pro-019" defer></script>
<script src="auth.js?v=v20260622-pro-019" defer></script>
<script src="parcelments.js?v=v20260622-pro-019" defer></script>
<script src="loop-guard.js?v=v20260622-pro-019" defer></script>
<script src="boot.js?v=v20260622-pro-019" defer></script>

<script src="web-vitals.js?v=v20260622-pro-019" defer></script>
<script src="error-monitor.js?v=v20260622-pro-019" defer></script>
<script src="offline-queue.js?v=v20260622-pro-019" defer></script>
<script src="export-csv.js?v=v20260622-pro-019" defer></script>
<script src="debounce.js?v=v20260622-pro-019" defer></script>
<script src="print.js?v=v20260622-pro-019" defer></script>
<script src="badge-api.js?v=v20260622-pro-019" defer></script>
<script src="wake-lock.js?v=v20260622-pro-019" defer></script>
<script src="connection-info.js?v=v20260622-pro-019" defer></script>
<script src="display-mode.js?v=v20260622-pro-019" defer></script>
<script src="evpl-refined.js?v=v20260622-pro-019" defer></script>
<script src="evpl-pro-manager.js?v=v20260622-pro-019" defer></script>
<script src="evpl-pro-polish.js?v=v20260622-pro-019" defer></script>
<script src="evpl-quality-pass.js?v=v20260622-pro-019" defer></script>
<script src="evpl-pro-finalpass.js?v=v20260622-pro-019" defer></script>
<script src="evpl-pro06-polish.js?v=v20260622-pro-019" defer></script>
<script src="evpl-loading-pro.js?v=v20260622-pro-019" defer></script>
<script src="evpl-filter-engine-fix-pro19.js?v=v20260622-pro-019" defer></script>
<script src="evpl-bf-filter-pro19.js?v=v20260622-pro-019" defer></script>
<script src="evpl-premium-stable-pro19.js?v=v20260622-pro-019" defer></script>
<script src="evpl-filter-engine-pro19.js?v=v20260622-pro-019" defer></script>
<script src="evpl-pro19-ux.js?v=v20260622-pro-019" defer></script>
<script>document.addEventListener("DOMContentLoaded",function(){document.body.classList.add("evpl-pro19-filters");});</script>
<script src="evpl-apply-fix-pro19.js?v=v20260622-pro-019" defer></script>
<script>document.addEventListener("DOMContentLoaded",function(){document.body.classList.add("evpl-pro19-apply");});</script>
<script src="evpl-pro19-final.js?v=v20260622-pro-019" defer></script>
<script>document.addEventListener("DOMContentLoaded",function(){document.body.classList.add("evpl-pro19-final");});</script>
<script src="evpl-pro19-filters.js?v=v20260622-pro-019" defer></script>
<!-- Cloudflare Pages Analytics --><script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "58d7fdb774e642598017dc99b1351e7c"}'></script><!-- Cloudflare Pages Analytics --></body>
</html>
