PageSourceSearch

https://jrleiloes.com.br/jrleiloes/js/index.js?v=1791487459

js jrleiloes.com.br collected 2026-10-08 19:24:26 UTC 65,719 bytes, 1,350 lines download raw bytes

1// Global variables
2let page = 1;
3let filters = {
4    tipo: '',
5    categoria: '',
6    estado: '',
7    cidade: '',
8    busca: '',
9    valor_min: 0,
10    valor_max: 0
11};
12let isSearchClicked = false;
13let isLoading = false;
14let btnLoading = $('#btn-loading');
15let urlLogos = $('#url_logo_base').val();
16let hasFilters = false;
17let currentPage = 1;
18let totalPages = 0;
19
20$(document).on('click', '#fechar-modal', () => {
21    $('#modal-lotes').addClass('hidden').removeClass('flex');
22    $('html').css({overflowY: 'initial',})
23});
24
25$(document).on('click', '.question', function () {
26    let _this = $(this);
27    _this.children('.icon-plus, .icon-minus').toggleClass('hidden');
28    _this.next('.answer').toggleClass('hidden');
29});
30
31$(document).on('click', '#modal-lotes', function (e) {
32    if (e.target.id === 'modal-lotes') {
33        $('#modal-lotes').addClass('hidden').removeClass('flex');
34        $('html').css({overflowY: 'initial',})
35    }
36});
37
38
39function changePage(newPage, updateUrl = true) {
40    if (newPage > 0 && newPage <= totalPages) {
41        sessionStorage.removeItem('loteClicado');
42        sessionStorage.removeItem('leilaoClicado');
43
44        $('#lotes-list').empty();
45        $('#leiloes-list').empty();
46
47        currentPage = newPage;
48
49        if (updateUrl) {
50            const url = new URL(window.location);
51            url.searchParams.set('page', currentPage);
52            history.pushState({page: currentPage}, '', url);
53        }
54
55        if (isSearchClicked && hasFilters) {
56            sessionStorage.setItem('currentPage', currentPage);
57            $('#lotes-list').empty();
58            getLotes();
59        } else {
60            $('#leiloes-list').empty();
61            const abaAtiva = $('.tab-btn.active').data('tipo') || 'proximos';
62            getLeiloes(abaAtiva);
63        }
64
65        updatePagination(currentPage, totalPages);
66    }
67}
68
69window.addEventListener('popstate', function (event) {
70    if (event.state && event.state.page) {
71        const page = event.state.page;
72        changePage(page, false);
73    }
74});
75
76function updatePagination(currentPage, totalPages) {
77    const paginationContainer = $('#page-numbers');
78    const currentPageText = $('#current-page-text');
79
80    paginationContainer.empty();
81    if (currentPageText.length) {
82        currentPageText.text(currentPage);
83    }
84
85    for (let i = 1; i <= totalPages; i++) {
86        paginationContainer.append(`
87            <button onclick="changePage(${i})" 
88                    class="py-1 px-3 border-[1px] rounded ${i === currentPage ? 'bg-jrBlue-100 text-white' : 'bg-gray-200'} hover:bg-jrBlue-50 hover:text-white transition"
89                    ${i === currentPage ? 'disabled' : ''}>
90                ${i}
91            </button>
92        `);
93    }
94
95    $('#first-page, #prev-page').prop('disabled', currentPage === 1);
96    $('#next-page, #last-page').prop('disabled', currentPage === totalPages);
97}
98
99function getLeiloes(tipo = 'proximos') {
100    if (isLoading) {
101        return;
102    }
103    isLoading = true;
104    btnLoading.removeClass('hidden');
105    $('#leiloes-list').empty();
106
107    let url = '/core/api/get-leiloes';
108    if (tipo === 'encerrados') {
109        url = '/core/api/get-leiloes-encerrados';
110    }
111
112    $.ajax({
113        url: url,
114        type: 'GET',
115        data: {pg: currentPage, itens_pagina: 40},
116        success: (response) => {
117            renderizarLeiloes(response);
118        },
119        error: (xhr) => {
120            try {
121                const res = JSON.parse(xhr.responseText);
122                if (res.items && res.items.length > 0) {
123                    renderizarLeiloes(res);
124                    return;
125                }
126            } catch (e) {
127                // ignora erro de parse
128            }
129
130            $('#leiloes-list').append('<span class="text-red-600">Erro ao carregar leilões.</span>');
131            btnLoading.addClass('hidden');
132        },
133        complete: () => {
134            isLoading = false;
135        }
136    });
137}
138
139function renderizarLeiloes(response) {
140    leiloesCache = response.items;
141
142    response.items.forEach(leilao => mountLeiloes(leilao));
143
144    const leilaoIdClicado = sessionStorage.getItem('leilaoClicado');
145    if (leilaoIdClicado) {
146        const leilaoElement = $(`li[data-leilao-id="${leilaoIdClicado}"]`);
147        if (leilaoElement.length) {
148            leilaoElement[0].scrollIntoView({behavior: 'smooth', block: 'center'});
149            leilaoElement.addClass('destaque');
150            setTimeout(() => {
151                leilaoElement.removeClass('destaque');
152                sessionStorage.removeItem('leilaoClicado');
153            }, 3000);
154        }
155    } else if (isSearchClicked || currentPage > 1) {
156        document.getElementById('scroll-here').scrollIntoView({behavior: 'smooth'});
157    }
158
159    totalPages = response.totalPages || 1;
160    updatePagination(currentPage, totalPages);
161    btnLoading.addClass('hidden');
162}
163
164function fetchLotesData(page, filters) {
165    return $.ajax({
166        url: '/core/api/get-lotes',
167        type: 'POST',
168        data: {
169            pg: page,
170            tipo: filters.tipo || '',
171            categoria: filters.categoria || '',
172            estado: filters.estado || '',
173            cidade: filters.cidade || '',
174            valor_min: filters.valor_min !== null ? filters.valor_min : '',
175            valor_max: filters.valor_max !== null ? filters.valor_max : '',
176            palavra_chave: filters.palavra_chave || '',
177        }
178    });
179}
180
181function getInformacaoLoteByLeilao(leilaoId) {
182    return new Promise((resolve, reject) => {
183        const leilao = leiloesCache.find(item => item.id === leilaoId);
184
185        if (leilao && Array.isArray(leilao.uf)) {
186            resolve(leilao.uf.map(estado => ({
187                nm_estado: estado
188            })));
189        } else {
190            reject(new Error('Leilão não encontrado ou sem estados'));
191        }
192    });
193}
194
195const loteStatesCache = {};
196
197async function updateLoteStates(leilaoId) {
198    if (loteStatesCache[leilaoId]) {
199        applyLoteStates(leilaoId, loteStatesCache[leilaoId]);
200        return;
201    }
202
203    try {
204        const estados = await getInformacaoLoteByLeilao(leilaoId);
205        loteStatesCache[leilaoId] = estados;
206        applyLoteStates(leilaoId, estados);
207    } catch (error) {
208        console.error('Erro ao obter informações dos lotes:', error);
209    }
210}
211
212function applyLoteStates(leilaoId, estados) {
213    let estadoHtml = '';
214    const maxEstados = 8;
215
216    // Remove estados duplicados
217    const estadosUnicos = [...new Set(estados.map(lote => lote.nm_estado))];
218
219    // Exibir os primeiros estados
220    estadosUnicos.slice(0, maxEstados - 1).forEach(estado => {
221        estadoHtml += `<span class="estado-lote">${estado}</span>`;
222    });
223
224    if (estadosUnicos.length > maxEstados) {
225        const remainingCount = estadosUnicos.length - (maxEstados - 1);
226        const remainingEstadosHtml = estadosUnicos.slice(maxEstados - 1).map(estado => `<span>${estado}</span>`).join('');
227
228        // Adiciona o item com o contador e o tooltip
229        estadoHtml += `
230            <span class="estado-lote restante-estados">+${remainingCount}
231                <div class="tooltip hidden">
232                    ${remainingEstadosHtml}
233                </div>
234            </span>`;
235    } else if (estadosUnicos.length === maxEstados) {
236        estadoHtml += `<span class="estado-lote">${estadosUnicos[maxEstados - 1]}</span>`;
237    }
238
239    // Seleciona o elemento específico do leilão com base no ID
240    const leilaoElement = $(`li[data-leilao-id="${leilaoId}"]`);
241    if (leilaoElement.length) {
242        // Limpa os estados anteriores e aplica os novos estados
243        leilaoElement.find('.estado-lote').remove();
244        leilaoElement.find('.estado-lote-span').html(estadoHtml);
245
246        // Ativa o tooltip ao passar o mouse sobre o item de contagem
247        leilaoElement.find('.restante-estados').hover(function () {
248            $(this).find('.tooltip').removeClass('hidden').addClass('grid');
249        }, function () {
250            $(this).find('.tooltip').removeClass('grid').addClass('hidden');
251        });
252    } else {
253        console.error(`Elemento do leilão com ID ${leilaoId} não encontrado no DOM`);
254    }
255}
256
257const ROTULO_PADRAO = 'Leilão';
258
259function buscaRotulo(datas, data, hora) {
260    return data ? datas.find((item) => item.dt_formatado === `${data} ${hora}`) : null;
261}
262
263function formataRotulo(rotulo, totalDatas = 2) {
264    if (!rotulo) return '';
265    const rotuloNome = rotulo.status_rotulo_nm || ROTULO_PADRAO;
266    if (totalDatas === 1) {
267        return rotuloNome;
268    }
269    return `${rotulo.nu_ordemrotulo}º ${rotuloNome}`;
270}
271
272function formatHora(hora) {
273    const [hr, min] = hora.split(':');
274    return min === '00' ? `${hr}h` : `${hr}h ${min}m`;
275}
276
277function formataHoraVigente(hora) {
278    if (!hora || hora === '-') {
279        return '';
280    }
281    return hora.includes(':') ? formatHora(hora) : `${hora}h`;
282}
283
284function getRotuloName(status) {
285    if (status === null || typeof status === 'undefined' || status === '') {
286        return '';
287    }
288    if (isNaN(Number(status))) {
289        return status.toString();
290    }
291    switch (Number(status)) {
292        case 1:  return "Abertura";
293        case 2:  return "Ciclo";
294        case 3:  return "Encerramento";
295        case 4:  return "Leilão";
296        case 5:  return "Praça";
297        default: return "Leilão";
298    }
299}
300
301function mountLeiloes(leilao) {
302    let hideDate = false;
303    if (leilao.datas && Array.isArray(leilao.datas)) {
304        const isVendaDireta = Number(leilao.statusleilao_id) === 13 || Number(leilao.statusleilao_id) === 18;
305        if (!isVendaDireta) {
306            const activeDate = leilao.leilao_id_primeiroleilao === null ? leilao.dt_formatada : leilao.dt_segundoleilao_data;
307            const activeTime = leilao.leilao_id_primeiroleilao === null ? leilao.hr_formatada : leilao.dt_segundoleilao_hora;
308            const matchingRotulo = leilao.datas.find(item => item.dt_formatado === `${activeDate} ${activeTime}`);
309            const labelText = matchingRotulo ? getRotuloName(matchingRotulo.status_rotulo_nm || matchingRotulo.statusrotuloleilao_multiplas) : getRotuloName(leilao.statusrotuloleilao_primeiro);
310            if (labelText && labelText.toLowerCase() === 'ciclo') {
311                hideDate = true;
312            }
313
314            leilao.datas = leilao.datas.filter(data => {
315                const rotulo = data.status_rotulo_nm || data.statusrotuloleilao_multiplas;
316                const labelText = getRotuloName(rotulo);
317                return !labelText || labelText.toLowerCase() !== 'ciclo';
318            });
319        }
320    }
321
322    let listaLeiloes = $('#leiloes-list');
323    let statusClass = 'bg-jrBlue-100';
324    let desc = 0;
325    let classDesc = '';
326    let logoLeilao = '';
327    let linkLeilao = '';
328    let targetLink = '';
329    let statusLeilao = leilao.nm_status;
330    let tituloSplit = leilao.nm ? leilao.nm.split('|')[0] : '';
331    let tituloCompleto = leilao.nm ? leilao.nm.replace(/<[^>]*>?/gm, '') : '';
332    let dt_vigente = '-';
333    let hr_vigente = '-';
334    let estadosLotes = '<span class="estado-lote">Estados...</span>';
335    let categoriasLeilao = '';
336
337    const svgsCategoria = {
338        imoveis: '<svg width="16" height="16" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.3813 7.875L15.75 6.24487V2.25C15.75 1.63125 15.2437 1.125 14.625 1.125H13.5C12.8813 1.125 12.375 1.63125 12.375 2.25V2.87212L10.125 0.624375C9.81787 0.334125 9.53662 0 9 0C8.46338 0 8.18213 0.334125 7.875 0.624375L0.61875 7.875C0.26775 8.24063 0 8.50725 0 9C0 9.63338 0.486 10.125 1.125 10.125H2.25V16.875C2.25 17.4937 2.75625 18 3.375 18H5.625C6.24632 18 6.75 17.4963 6.75 16.875V12.375C6.75 11.7563 7.25625 11.25 7.875 11.25H10.125C10.7437 11.25 11.25 11.7563 11.25 12.375V16.875C11.25 17.4963 11.1912 18 11.8125 18H14.625C15.2437 18 15.75 17.4937 15.75 16.875V10.125H16.875C17.514 10.125 18 9.63338 18 9C18 8.50725 17.7323 8.24063 17.3813 7.875Z" fill="#ccc"/></svg>',
339        equipamentos: '<svg width="15" height="14" viewBox="0 0 15 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15 7.6087C15 8.12095 14.8375 8.61604 14.5423 9.00326C14.2471 9.39047 13.8391 9.64389 13.3929 9.71706V12.7826C13.3929 13.1055 13.28 13.4151 13.079 13.6434C12.8781 13.8717 12.6056 14 12.3214 14H2.67857C2.39441 14 2.12189 13.8717 1.92096 13.6434C1.72003 13.4151 1.60714 13.1055 1.60714 12.7826V9.71706C1.25142 9.65873 0.917947 9.48545 0.646439 9.21787C0.374931 8.95029 0.176828 8.59968 0.0757205 8.2078C-0.0253866 7.81592 -0.025237 7.39928 0.0761516 7.00749C0.17754 6.6157 0.375895 6.26528 0.647596 5.99795C0.919296 5.73063 1.25289 5.55766 1.60866 5.49965C1.96442 5.44164 2.32737 5.50103 2.65427 5.67076C2.98116 5.84048 3.25824 6.11338 3.45251 6.45696C3.64677 6.80054 3.75004 7.20032 3.75 7.6087V10.3478C3.75 10.5093 3.80644 10.6641 3.90691 10.7782C4.00737 10.8924 4.14363 10.9565 4.28571 10.9565C4.42779 10.9565 4.56406 10.8924 4.66452 10.7782C4.76499 10.6641 4.82143 10.5093 4.82143 10.3478V8.52174H10.1786V10.3478C10.1786 10.5093 10.235 10.6641 10.3355 10.7782C10.4359 10.8924 10.5722 10.9565 10.7143 10.9565C10.8564 10.9565 10.9926 10.8924 11.0931 10.7782C11.1936 10.6641 11.25 10.5093 11.25 10.3478V7.6087C11.25 7.04367 11.4475 6.50178 11.7992 6.10225C12.1508 5.70272 12.6277 5.47826 13.125 5.47826C13.6223 5.47826 14.0992 5.70272 14.4508 6.10225C14.8025 6.50178 15 7.04367 15 7.6087ZM1.875 4.26087C2.60972 4.26205 3.31761 4.57467 3.8602 5.13755C4.40278 5.70044 4.741 6.47309 4.8087 7.30435H10.1913C10.259 6.47309 10.5972 5.70044 11.1398 5.13755C11.6824 4.57467 12.3903 4.26205 13.125 4.26087C13.196 4.26087 13.2642 4.2288 13.3144 4.17173C13.3646 4.11465 13.3929 4.03724 13.3929 3.95652V3.04348C13.3929 2.2363 13.1107 1.46218 12.6083 0.891414C12.106 0.320651 11.4247 0 10.7143 0H4.28571C3.57531 0 2.89401 0.320651 2.39168 0.891414C1.88935 1.46218 1.60714 2.2363 1.60714 3.04348V3.95652C1.60714 4.03724 1.63536 4.11465 1.6856 4.17173C1.73583 4.2288 1.80396 4.26087 1.875 4.26087Z" fill="#ccc"/></svg>',
340        veiculos: '<svg width="20" height="14" viewBox="0 0 20 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19.3333 5.47826H18.4333L16.1183 0.722826C16.0136 0.507673 15.8427 0.324876 15.6265 0.196582C15.4102 0.0682878 15.1579 2.81841e-06 14.9 0H5.1C4.84212 2.81841e-06 4.58977 0.0682878 4.37353 0.196582C4.15729 0.324876 3.98643 0.507673 3.88167 0.722826L1.56667 5.47826H0.666667C0.489856 5.47826 0.320286 5.54239 0.195262 5.65654C0.0702379 5.7707 0 5.92552 0 6.08696C0 6.24839 0.0702379 6.40322 0.195262 6.51737C0.320286 6.63152 0.489856 6.69565 0.666667 6.69565H1.33333V12.7826C1.33333 13.1055 1.47381 13.4151 1.72386 13.6434C1.97391 13.8717 2.31304 14 2.66667 14H4.66667C5.02029 14 5.35943 13.8717 5.60948 13.6434C5.85952 13.4151 6 13.1055 6 12.7826V12.1739H14V12.7826C14 13.1055 14.1405 13.4151 14.3905 13.6434C14.6406 13.8717 14.9797 14 15.3333 14H17.3333C17.687 14 18.0261 13.8717 18.2761 13.6434C18.5262 13.4151 18.6667 13.1055 18.6667 12.7826V6.69565H19.3333C19.5101 6.69565 19.6797 6.63152 19.8047 6.51737C19.9298 6.40322 20 6.24839 20 6.08696C20 5.92552 19.9298 5.7707 19.8047 5.65654C19.6797 5.54239 19.5101 5.47826 19.3333 5.47826ZM6 9.13043H4C3.82319 9.13043 3.65362 9.0663 3.5286 8.95215C3.40357 8.838 3.33333 8.68318 3.33333 8.52174C3.33333 8.3603 3.40357 8.20548 3.5286 8.09133C3.65362 7.97717 3.82319 7.91304 4 7.91304H6C6.17681 7.91304 6.34638 7.97717 6.4714 8.09133C6.59643 8.20548 6.66667 8.3603 6.66667 8.52174C6.66667 8.68318 6.59643 8.838 6.4714 8.95215C6.34638 9.0663 
3406.17681 9.13043 6 9.13043ZM16 9.13043H14C13.8232 9.13043 13.6536 9.0663 13.5286 8.95215C13.4036 8.838 13.3333 8.68318 13.3333 8.52174C13.3333 8.3603 13.4036 8.20548 13.5286 8.09133C13.6536 7.97717 13.8232 7.91304 14 7.91304H16C16.1768 7.91304 16.3464 7.97717 16.4714 8.09133C16.5964 8.20548 16.6667 8.3603 16.6667 8.52174C16.6667 8.68318 16.5964 8.838 16.4714 8.95215C16.3464 9.0663 16.1768 9.13043 16 9.13043ZM3.02583 5.47826L5.1 1.21739H14.9L16.9742 5.47826H3.02583Z" fill="#ccc"/></svg>',
341        semoventes: '<svg width="19" height="14" viewBox="0 0 19 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.2012 4.6196C15.2627 4.40203 16.5737 4.40141 17.2 5.3917C17.3362 5.50954 18.4112 7.20355 17.9266 7.09026C17.7812 7.08891 17.6357 7.08666 17.4901 7.08441C17.018 7.07712 16.5453 7.06982 16.0741 7.09312C15.9657 7.09873 15.8586 7.13796 15.7524 7.17681C15.7187 7.18918 15.685 7.2015 15.6514 7.2127C15.1329 7.37754 14.6182 7.25271 14.1069 7.12868C13.9294 7.08564 13.7523 7.0427 13.5756 7.01199L12.3299 11.3294C12.3821 11.4923 12.4103 11.6659 12.4103 11.8462C12.4103 12.7808 11.6526 13.5385 10.7179 13.5385H7.33333C6.3987 13.5385 5.64103 12.7808 5.64103 11.8462C5.64103 11.6575 5.67189 11.4761 5.72884 11.3066C5.53339 10.6339 5.34085 9.9608 5.14816 9.28718C5.08555 9.06827 5.02291 8.84931 4.96016 8.63029C4.90189 8.42883 4.84263 8.22764 4.78337 8.02645C4.69257 7.7182 4.60178 7.40997 4.5146 7.10083C4.48778 7.0057 4.44262 7.01361 4.36687 7.03588C3.71248 7.22582 2.99365 7.40837 2.32422 7.17151C1.85309 7.02439 1.35979 7.05178 
3410.868048 7.07908C0.64774 7.09131 0.427745 7.10353 0.210196 7.10002C-0.0118208 7.08901 -0.0398298 7.05423 0.0423423 6.86031C0.0515751 6.83852 0.0607918 6.81671 0.0700108 6.7949C0.161816 6.57771 0.253837 6.36001 0.364012 6.15104C1.15461 4.6112 2.12412 4.26808 3.86821 4.62439L3.93866 3.89963C3.9066 3.88978 3.87442 3.87994 3.84216 3.87007C3.12674 3.65129 2.37164 3.42038 1.99441 2.75797C1.67691 2.17065 1.64758 1.47844 1.75849 0.838549C1.77425 0.636098 2.0401 -0.273934 2.34932 0.0815052C2.40926 0.175949 2.45703 0.277358 2.50472 0.378585C2.51866 0.408192 2.5326 0.437784 2.54684 0.467182C2.55822 0.490044 2.56964 0.513043 2.58112 0.536157C2.94214 1.26309 3.35918 2.1028 4.26179 2.30709C4.57049 2.3821 4.87509 2.47252 5.17929 2.56282C5.29344 2.59666 5.36797 2.58016 5.43849 2.48198C5.69871 2.1197 6.07415 1.94114 6.53235 1.93958C8.1938 1.93411 9.85526 1.93529 11.5167 1.93878C12.1106 1.92762 12.3702 2.20616 12.5504 2.39944C12.6607 2.51779 12.7412 2.60417 12.8504 2.57251C14.7059 2.13836 14.8372 1.86674 15.6194 0.247775L15.6224 0.241524C15.9294 -0.444655 16.2937 0.537798 16.3063 0.849251C16.3416 1.1365 16.3698 1.42904 16.3517 1.71654C16.3707 2.91768 15.3126 3.69588 14.1229 3.87326L14.2012 4.6196ZM10.3354 7.26365C10.3445 6.35884 11.834 6.3614 11.8169 7.26689C11.8173 8.22302 10.3307 8.16883 10.3354 7.26365ZM6.24842 7.27217C6.23412 6.36457 7.73712 6.35293 7.71898 7.27106C7.74341 8.19534 6.23134 8.17916 6.24842 7.27217Z" fill="#ccc"/></svg>',
342    }
343
344    const categorias = Array.isArray(leilao.categorialeilao) ? leilao.categorialeilao : Object.values(leilao.categorialeilao);
345
346    categorias.forEach((categoria) => {
347        const categoriaNome = categoria.nm_categoria.toLowerCase();
348
349        if (categoriaNome.includes('bens diversos')) {
350            categoriasLeilao += svgsCategoria.equipamentos;
351        } else if (categoriaNome.includes('imoveis') || categoriaNome.includes('imóveis')) {
352            categoriasLeilao += svgsCategoria.imoveis;
353        } else if (categoriaNome.includes('veiculos') || categoriaNome.includes('veículos')) {
354            categoriasLeilao += svgsCategoria.veiculos;
355        } else if (categoriaNome.includes('semoventes')) {
356            categoriasLeilao += svgsCategoria.semoventes;
357        } else {
358            categoriasLeilao += svgsCategoria.equipamentos;
359        }
360    });
361
362    // Determina data, hora e rótulo do leilão
363    if (leilao.leilao_id_primeiroleilao === null) { // Primeiro leilão
364        dt_vigente = leilao.dt_formatada;
365        hr_vigente = leilao.hr_formatada;
366    } else { // Segundo leilão
367        dt_vigente = leilao.dt_segundoleilao_data;
368        hr_vigente = leilao.dt_segundoleilao_hora;
369    }
370
371    leilao.datas.sort((a, b) => new Date(a.dt) - new Date(b.dt));
372
373    const totalDatas = leilao.datas && Array.isArray(leilao.datas) ? leilao.datas.length : 2;
374    const nm_tipoleilao1 = formataRotulo(buscaRotulo(leilao.datas, leilao.dt_formatada, leilao.hr_formatada), totalDatas);
375    const nm_tipoleilao2 = formataRotulo(buscaRotulo(leilao.datas, leilao.dt_segundoleilao_data, leilao.dt_segundoleilao_hora), totalDatas);
376    const nm_tipoleilao_atual = leilao.leilao_id_primeiroleilao === null ? nm_tipoleilao1 : nm_tipoleilao2;
377
378    const formattedHora = formataHoraVigente(hr_vigente);
379
380    let now = new Date();
381
382    if ([4, 5, 6, 8].includes(leilao.statusmontagem_id)) {
383        statusClass = 'bg-jrRed-100 text-white';
384    } else if ([2, 3].includes(leilao.statusmontagem_id)) {
385        statusClass = 'bg-white';
386    } else if (leilao.statusmontagem_id === 1) {
387        statusClass = 'bg-jrRed-50 text-white';
388    } else {
389        statusClass = 'bg-jrBlue-100 text-white';
390    }
391
392    if (leilao.nu_qtdelotes === 1) {
393        const lanceInicial = parseInt(leilao.vl_lanceinicial);
394        const lanceInicialSegundoLeilao = parseInt(leilao.vl_lanceinicialsegundoleilao);
395
396        if (lanceInicialSegundoLeilao > 0) {
397            desc = parseInt(100 - ((lanceInicialSegundoLeilao * 100) / lanceInicial));
398        }
399
400        if (desc > 0 && desc <= 60) {
401            if (desc > 0 && desc <= 10) {
402                classDesc = 'bg-jrGray-300 text-white';
403            } else if (desc > 10 && desc <= 20) {
404                classDesc = 'bg-jrGray-200 text-white';
405            } else if (desc > 20 && desc <= 30) {
406                classDesc = 'bg-jrGray-250 text-white';
407            } else if (desc > 30 && desc <= 40) {
408                classDesc = 'bg-white';
409            } else if (desc > 40 && desc <= 50) {
410                classDesc = 'bg-jrGreen-100';
411            } else if (desc <= 60) {
412                classDesc = 'bg-jrGreen-200 text-white';
413            }
414        }
415    }
416
417    if (statusLeilao === 'Venda Direta.') {
418        statusLeilao = 'Venda Direta';
419    } else if (statusLeilao === 'Judicial Presencial/Online') {
420        statusLeilao = 'Jud. Presencial/Online';
421    }
422
423    if (leilao.nm_logopath && leilao.nm_logopath.length > 0) {
424        logoLeilao = leilao.nm_logopath[0].includes('fotos/') ? urlLogos + '/public/' + leilao.nm_logopath[0] : urlLogos + '/public/banner_leilao/' + leilao.nm_logopath[0];
425    } else {
426        logoLeilao = `https://${leilao.s3_path}/layout/images/sem_foto.png`
427    }
428
429    const hoje = new Date().toISOString().split('T')[0];
430    const partes = dt_vigente.split('/');
431    const dtVigenteFormatada = `${partes[2]}-${partes[1]}-${partes[0]}`;
432
433    const isMontagemValida = ![6, 7, 8, 9].includes(leilao.statusmontagem_id);
434    const isStatusBloqueado = [1, 7, 9].includes(leilao.statusmontagem_id);
435    const isStatusFinalizado = [6, 8].includes(leilao.statusmontagem_id) && dtVigenteFormatada === hoje;
436
437
438    if (isMontagemValida || isStatusFinalizado) {
439        if (leilao.nm_link !== '') {
440            linkLeilao = /^http/.test(leilao.nm_link)
441                ? leilao.nm_link
442                : 'http://' + leilao.nm_link;
443            targetLink = '_blank';
444        } else if (leilao.lote_id && leilao.nu_qtdelotes === 1) {
445            linkLeilao = `/leilao/index/leilao_id/${leilao.id}/lote/${leilao.lote_id}`;
446        } else {
447            linkLeilao = `/leilao/index/leilao_id/${leilao.id}`;
448        }
449    }
450
451    if (isStatusBloqueado) {
452        linkLeilao = 'javascript:void(0)';
453        targetLink = '';
454    }
455
456    const contentCard = `
457        <li data-leilao-id="${leilao.id}" class="leilao w-full min-h-[415px] sm:w-1/2 lg:w-[270px] mb:w-[345px] ls:w-[320px] ls:flex-col xl:w-1/4 flex flex-col text-gray-800 bg-white rounded-xl overflow-hidden transition transform hover:scale-105 hover:shadow-xl">
458            <a href="${linkLeilao}" target="${targetLink}" class="relative">
459                <div class="relative h-[200px] imagem-content">
460                    <div class="px-3 py-1 rounded-lg font-bold nm_statusmontagem ${getStatusMontagemColor(leilao.nm_statusmontagem)}">${leilao.nm_statusmontagem ? leilao.nm_statusmontagem : leilao.nm_status}</div>
461                    <img src="${logoLeilao}" alt="Imagem do Leilão" class="object-cover w-full h-full rounded-xl" id="logo-leilao">
462                    ${desc > 0 ? `<div class="absolute top-2 right-2 bg-green-500 text-white text-xs px-2 py-1 rounded">${desc}% OFF</div>` : ''}
463                </div>
464            </a>
465        
466            <!-- Conteúdo do Card -->
467            <div class="flex flex-col justify-between flex-grow body-card">
468                <div class="categoria_share">
469                    <div id="categorias-leilao">${categoriasLeilao}</div>
470                    <div id="open-share-modal-${leilao.id}" class="share_leilao">
471                        <svg width="15"
472                            height="14"
473                            viewBox="0 0 16 16"
474                            fill="none"
475                            xmlns="http://www.w3.org/2000/svg">
476                            <path fill-rule="evenodd"
477                                clip-rule="evenodd"
478                                d="M12.8571 6.28571C14.5929 6.28571 16 4.87861 16 3.14286C16 1.40711 14.5929 0 12.8571 0C11.1214 0 9.71429 1.40711 9.71429 3.14286C9.71429 3.19283 9.71545 3.24254 9.71776 3.29194L5.14577 5.57793C4.60195 5.12771 3.904 4.85714 3.14286 4.85714C1.40711 4.85714 0 6.26425 0 8C0 9.73575 1.40711 11.1429 3.14286 11.1429C3.904 11.1429 4.60195 10.8723 5.14577 10.4221L9.71776 12.7081C9.71545 12.7575 9.71429 12.8072 9.71429 12.8571C9.71429 14.5929 11.1214 16 12.8571 16C14.5929 16 16 14.5929 16 12.8571C16 11.1214 14.5929 9.71429 12.8571 9.71429C11.9974 9.71429 11.2181 10.0596 10.6507 10.619L6.25757 8.42246C6.27613 8.28429 6.28571 8.14326 6.28571 8C6.28571 7.85674 6.27613 7.71571 6.25757 7.57754L10.6507 5.38097C11.2181 5.94043 11.9974 6.28571 12.8571 6.28571Z"
479                                fill="#ccc"
480                            />
481                        </svg>
482                    </div>
483
484                    <div id="share-modal-${leilao.id}" class="hidden fixed inset-0 bg-gray-900 bg-opacity-50 flex items-center justify-center z-50">
485                        <div class="bg-white p-6 rounded-lg shadow-lg max-w-md w-full">
486                            <h3 class="text-sm font-new font-semibold mb-4">Compartilhar Leilão</h3>
487                            <p id="share-title-${leilao.id}" class="mb-4 text-gray-700"></p>
488                            <div class="flex space-x-4">
489                                <a id="share-whatsapp-${leilao.id}" target="_blank" class="text-white bg-jrGreen-200 flex items-center font-new text-sm p-2 rounded">
490                                    <span class="icon-whatsapp" style="font-size: 24px;"></span>
491                                </a>
492                                <a id="share-email-${leilao.id}" target="_blank" class="text-white bg-jrBlue-100 font-new text-sm p-2 rounded">
493                                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
494                                        <g clip-path="url(#clip0_403_3028)">
495                                            <path d="M19 0.999878H5C3.67441 1.00147 2.40356 1.52876 1.46622 2.4661C0.528882 3.40344 0.00158786 4.67428 0 5.99988L0 17.9999C0.00158786 19.3255 0.528882 20.5963 1.46622 21.5337C2.40356 22.471 3.67441 22.9983 5 22.9999H19C20.3256 22.9983 21.5964 22.471 22.5338 21.5337C23.4711 20.5963 23.9984 19.3255 24 17.9999V5.99988C23.9984 4.67428 23.4711 3.40344 22.5338 2.4661C21.5964 1.52876 20.3256 1.00147 19 0.999878ZM5 2.99988H19C19.5988 3.00106 20.1835 3.18139 20.679 3.51768C21.1744 3.85397 21.5579 4.33082 21.78 4.88688L14.122 12.5459C13.5584 13.1072 12.7954 13.4223 12 13.4223C11.2046 13.4223 10.4416 13.1072 9.878 12.5459L2.22 4.88688C2.44215 4.33082 2.82561 3.85397 3.32105 3.51768C3.81648 3.18139 4.40121 3.00106 5 2.99988ZM19 20.9999H5C4.20435 20.9999 3.44129 20.6838 2.87868 20.1212C2.31607 19.5586 2 18.7955 2 17.9999V7.49988L8.464 13.9599C9.40263 14.8961 10.6743 15.4219 12 15.4219C13.3257 15.4219 14.5974 14.8961 15.536 13.9599L22 7.49988V17.9999C22 18.7955 21.6839 19.5586 21.1213 20.1212C20.5587 20.6838 19.7956 20.9999 19 20.9999Z" fill="#fff"/>
496                                        </g>
497                                        <defs>
498                                            <clipPath id="clip0_403_3028">
499                                                <rect width="24" height="24" fill="white"/>
500                                            </clipPath>
501                                        </defs>
502                                    </svg>
503                                </a>
504                                <button id="copy-link-${leilao.id}" class="text-white bg-jrGray-200 font-new text-sm p-2 rounded">
505                                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
506                                        <g clip-path="url(#clip0_403_3062)">
507                                            <path d="M21.1549 3.272L18.8709 0.913C18.5904 0.624966 18.2552 0.39584 17.885 0.239061C17.5147 0.0822824 17.1169 0.00100643 16.7149 0L11.9999 0C10.8477 0.00145452 9.7312 0.40009 8.83863 1.12872C7.94606 1.85735 7.33197 2.87141 7.09988 4H6.99988C5.67428 4.00159 4.40344 4.52888 3.4661 5.46622C2.52876 6.40356 2.00147 7.67441 1.99988 9V19C2.00147 20.3256 2.52876 21.5964 3.4661 22.5338C4.40344 23.4711 5.
50767428 23.9984 6.99988 24H12.9999C14.3255 23.9984 15.5963 23.4711 16.5337 22.5338C17.471 21.5964 17.9983 20.3256 17.9999 19V18.9C19.1285 18.6679 20.1425 18.0538 20.8712 17.1613C21.5998 16.2687 21.9984 15.1522 21.9999 14V5.36C22.0014 4.58042 21.6981 3.83112 21.1549 3.272ZM12.9999 22H6.99988C6.20423 22 5.44117 21.6839 4.87856 21.1213C4.31595 20.5587 3.99988 19.7956 3.99988 19V9C3.99988 8.20435 4.31595 7.44129 4.87856 6.87868C5.44117 6.31607 6.20423 6 6.99988 6V14C7.00147 15.3256 7.52876 16.5964 8.4661 17.5338C9.40344 18.4711 10.6743 18.9984 11.9999 19H15.9999C15.9999 19.7956 15.6838 20.5587 15.1212 21.1213C14.5586 21.6839 13.7955 22 12.9999 22ZM16.9999 17H11.9999C11.2042 17 10.4412 16.6839 9.87856 16.1213C9.31595 15.5587 8.99988 14.7956 8.99988 14V5C8.99988 4.20435 9.31595 3.44129 9.87856 2.87868C10.4412 2.31607 11.2042 2 11.9999 2H15.9999V4C15.9999 4.53043 16.2106 5.03914 16.5857 5.41421C16.9607 5.78929 17.4694 6 17.9999 6H19.9999V14C19.9999 14.7956 19.6838 15.5587 19.1212 16.1213C18.5586 16.6839 17.7955 17 16.9999 17Z" fill="#fff"/>
508                                        </g>
509                                        <defs>
510                                            <clipPath id="clip0_403_3062">
511                                                <rect width="24" height="24" fill="white"/>
512                                            </clipPath>
513                                        </defs>
514                                    </svg>
515                                </button>
516                            </div>
517                            <button id="close-share-modal-${leilao.id}" class="mt-6 text-white bg-jrRed-100 font-new text-sm p-2 rounded w-full">Fechar</button>
518                        </div>
519                    </div>
520                </div>
521                <!-- Título do Leilão -->
522                <div class="mb-2 flex items-center text-sm gap-3">
523                    <svg width="15" height="15" viewBox="0 0 16 15" fill="none" xmlns="http://www.w3.org/2000/svg">
524                        <path fill-rule="evenodd"
525                        clip-rule="evenodd"
526                        d="M4.11477 7.14603C3.47978 6.4649 3.47978 5.36056 4.11477 4.67942L8.00099 0.510852C8.63599 -0.170284 9.66554 -0.170284 10.3005 0.510852L12.0175 2.35259C12.6525 3.03373 12.6525 4.13807 12.0175 4.8192L10.655 6.28075L14.7619 10.686C15.0794 11.0266 15.0794 11.5787 14.7619 11.9193C14.4444 12.2598 13.9296 12.2598 13.6121 11.9193L9.5052 7.51406L8.1313 8.98777C7.49631 9.66891 6.46677 9.66891 5.83176 8.98777L4.11477 7.14603ZM1.35502 14.2558H0.81301C0.363997 14.2558 0 14.6463 0 15.1279C0 15.6095 0.363997 16 0.81301 16H8.94311C9.39212 16 9.75612 15.6095 9.75612 15.1279C9.75612 14.6463 9.39212 14.2558 8.94311 14.2558H8.4011V12.221C8.4011 11.9 8.15843 11.6396 7.85909 11.6396H1.89702C1.59768 11.6396 1.35502 11.9 1.35502 12.221V14.2558Z"
527                        fill="#1C2D47"/>
528                    </svg>
529                    <a href="${linkLeilao}" target="${targetLink}" class="relative">
530                        <h2 class="leading-tight title-hover" id="nm_leilao" title="${leilao.nm}">${leilao.nm.split('|'[0])}</h2>
531                    </a>
532                </div>
533                <!-- Lotes e Status -->
534                <div class="flex justify-between items-center mb-2">
535                    <div class="flex w-full text-sm lg:text-[12px] text-gray-600">
536                        <div class="flex items-center gap-3">
537                            <svg width="15" height="15" viewBox="0 0 16 15" fill="none" xmlns="http://www.w3.org/2000/svg">
538                                <path fill-rule="evenodd" 
539                                clip-rule="evenodd" 
540                                d="M8.23844 0.0513453C8.087 -0.0171151 7.91311 -0.0171151 7.76168 0.0513453L4.74514 1.41497L7.99789 2.8854L11.2528 1.414L8.23844 0.0513453ZM4.20253 5.91211V2.42465L7.42266 3.88033V7.73523L4.53938 6.43183C4.33421 6.33909 4.20253 6.13591 4.20253 5.91211ZM8.57313 13.5785V9.76345L11.625 11.143V14.9981L8.74176 13.6947C8.67783 13.6658 8.62103 13.6261 8.57313 13.5785ZM12.7755 15V11.143L16 9.68545V13.1749C16 13.3987 15.8683 13.6019 15.6631 13.6947L12.7755 15ZM7.42266 9.76338V13.5826C7.37565 13.6284 7.32029 13.6666 7.25821 13.6947L4.3706 15V11.143L7.42266 9.76338ZM3.22013 11.143V14.9981L0.336851 13.6947C0.131684 13.6019 0 13.3987 0 13.1749V9.6874L3.22013 11.143ZM8.57313 7.73718V3.88033L11.7976 2.4227V5.91211C11.7976 6.13591 11.666 6.33909 11.4607 6.43183L8.57313 7.73718ZM11.964 7.31412C12.1154 7.24567 12.2894 7.24567 12.4408 7.31412L15.4551 8.67677L12.2002 10.1481L8.94756 8.67774L11.964 7.31412ZM3.55914 7.31412C3.71059 7.24567 3.88447 7.24567 4.03592 7.31412L7.05025 8.67677L3.79537 10.1481L0.54265 8.67774L3.55914 7.31412Z"
541                                fill="#1C2D47"/>
542                            </svg>
543                            <div class="flex gap-1">
544                                <span>${leilao.nu_qtdelotes}</span>
545                                <span>lote(s)</span>
546                            </div>
547                        </div>
548                        <div class="estado-lote-span ml-2">${estadosLotes}</div>
549                    </div>
550                </div>
551                <!-- Data e Hora do Leilão -->
552                ${hideDate ? '' : `
553                <div class="flex items-center gap-2">
554                    <div class="flex items-center text-sm lg:text-[12px] text-gray-600 gap-3">
555                        <i class="icon-calendar"></i>
556                        <span>${nm_tipoleilao_atual} - ${dt_vigente}</span>
557                    </div>
558                    <div class="flex items-center text-sm lg:text-[12px] text-gray-600 gap-3">
559                        <i class="icon-time"></i>
560                        <span>${formattedHora}</span>
561                    </div>
562                </div>
563                `}
564            </div>
565            <div class="text-gray-500 nm_status">
566                <div class="leilao_id_span">Leilão ID<span class="ml-2">${leilao.id}</span></div>
567                <span title="${leilao.nm_status}">${statusLeilao}</span>
568            </div>
569        </li>`;
570
571    listaLeiloes.append(contentCard);
572
573    $(`li[data-leilao-id="${leilao.id}"] a`).on('click', function (e) {
574        const leilaoId = $(this).closest('li').data('leilao-id');
575        sessionStorage.setItem('leilaoClicado', leilaoId);
576
577        if ([6, 8].includes(leilao.statusmontagem_id) && dtVigenteFormatada !== hoje) {
578            e.preventDefault();
579            abrirModalLotes(leilaoId);
580        }
581
582        setTimeout(() => {
583            sessionStorage.removeItem('leilaoClicado');
584        }, 5000);
585    });
586
587    $(document).ready(function () {
588        const linkLeilaoCompleto = `https://${window.location.hostname}${linkLeilao}`;
589
590        const openShareModal = $(`#open-share-modal-${leilao.id}`);
591        const closeShareModal = $(`#close-share-modal-${leilao.id}`);
592        const shareModal = $(`#share-modal-${leilao.id}`);
593        const shareTitle = $(`#share-title-${leilao.id}`);
594        const shareWhatsapp = $(`#share-whatsapp-${leilao.id}`);
595        const shareEmail = $(`#share-email-${leilao.id}`);
596        const copyLink = $(`#copy-link-${leilao.id}`);
597
598        if (openShareModal.length && shareModal.length) {
599            openShareModal.on('click', function () {
600                shareModal.removeClass('hidden');
601                shareTitle.text(tituloCompleto);
602
603                const whatsappText = `Confira o leilão abaixo:\n\n${tituloCompleto}\n\n${linkLeilaoCompleto}`;
604                const whatsappUrl = `https://wa.me/?text=${encodeURIComponent(whatsappText)}`;
605                shareWhatsapp.attr('href', whatsappUrl);
606
607                const emailSubject = tituloCompleto;
608                const emailBody = `Confira o leilão abaixo:\n\n${tituloCompleto}\n\n${linkLeilaoCompleto}`;
609                const emailUrl = `mailto:?subject=${encodeURIComponent(emailSubject)}&body=${encodeURIComponent(emailBody)}`;
610                shareEmail.attr('href', emailUrl);
611            });
612
613            closeShareModal.on('click', function () {
614                shareModal.addClass('hidden');
615            });
616        } else {
617            console.error('O seletor de modal não foi encontrado');
618        }
619
620        copyLink.on('click', function () {
621            if (navigator.clipboard) {
622                navigator.clipboard.writeText(linkLeilaoCompleto).then(() => {
623                    alert('Link copiado para a área de transferência!');
624                }).catch((err) => {
625                    console.error('Falha ao copiar o link: ', err);
626                });
627            } else {
628                console.error('API de clipboard não está disponível.');
629            }
630        });
631    });
632
633    updateLoteStates(leilao.id).then(r => {
634    });
635}
636
637function getLotes() {
638    if (isLoading) {
639        return;
640    }
641    isLoading = true;
642    btnLoading.removeClass('hidden');
643    $('.filter-check-item').prop('disabled', true);
644    $('#lotes-list').empty();
645
646    fetchLotesData(currentPage, filters)
647        .done((response) => {
648            renderizarLotesComSucesso(response);
649        })
650        .fail((xhr) => {
651            try {
652                const response = JSON.parse(xhr.responseText);
653                if (response.items && response.items.length > 0) {
654                    renderizarLotesComSucesso(response);
655                    return;
656                }
657            } catch (e) {
658                // erro de parse, ignora
659            }
660
661            $('#lotes-list').append('<span class="text-red-600">Erro ao carregar lotes.</span>');
662            btnLoading.addClass('hidden');
663        })
664        .always(() => {
665            isLoading = false;
666        });
667}
668
669function renderizarLotesComSucesso(response) {
670    // updateFilters();
671
672    if (response.items && response.items.length > 0) {
673        response.items.forEach(item => mountLotes(item));
674
675        const loteIdClicado = sessionStorage.getItem('loteClicado');
676        if (loteIdClicado) {
677            const loteElement = $(`li[data-lote-id="${loteIdClicado}"]`);
678            if (loteElement.length) {
679                loteElement[0].scrollIntoView({behavior: 'smooth', block: 'center'});
680                loteElement.addClass('destaque');
681                setTimeout(() => {
682                    loteElement.removeClass('destaque');
683                    sessionStorage.removeItem('loteClicado');
684                }, 3000);
685            }
686        } else if (isSearchClicked || currentPage > 1) {
687            document.getElementById('scroll-here').scrollIntoView({behavior: 'smooth'});
688        }
689    } else {
690        $('#lotes-list').append('<span>Nenhum item encontrado</span>');
691    }
692
693    totalPages = response.totalPages || 1;
694    updatePagination(currentPage, totalPages);
695    btnLoading.addClass('hidden');
696}
697
698function mountLotes(item) {
699    let listaLotes = $('#lotes-list');
700    let linkLote = `/leilao/index/leilao_id/${item.leilao_id}/lote/${item.lote_id}`;
701    let numLote = parseInt(item.nu) < 10 ? '0' + parseInt(item.nu) : parseInt(item.nu);
702    let titulo = item.nm_titulo_lote;
703
704    const s3Base = item.s3_path ? `https://${item.s3_path}` : '';
705    const iconPin = s3Base ? `${s3Base}/layout/icons/pin.svg` : '/public/layout/icons/unknown.svg';
706    const iconDollar = s3Base ? `${s3Base}/layout/icons/dollar.svg` : '/public/layout/icons/unknown.svg';
707    const iconGravel = s3Base ? `${s3Base}/layout/icons/gravel.svg` : '/public/layout/icons/unknown.svg';
708    const iconInfo = s3Base ? `${s3Base}/layout/icons/info.svg` : '/public/layout/icons/unknown.svg';
709    const linkImagem = s3Base ? `${s3Base}/layout/images/sem_foto.png` : '/public/layout/images/sem_foto.png';
710
711    let urlFoto = item.fotos.length > 0 ? item.fotos[0].nm_path_completo : linkImagem;
712
713    const menorLance = parseFloat(item.vl_lanceinicial);
714    const menorLanceProxData = parseFloat(item.vl_lanceinicialsegundoleilao);
715    const temProximaDataValida = !isNaN(menorLanceProxData) && menorLanceProxData > 0;
716
717    const formatCurrency = (value) => {
718        return `R$ ${value.toFixed(2).replace('.', ',').replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.')}`;
719    };
720
721    const exibrAbaliacao = item.bn_exibeavaliacao === true || item.bn_exibeavaliacao == 1 || item.bn_exibeavaliacao == 't';
722
723    const botaoHabilitacaoExtra = Array.isArray(item.habilitacao_extra) && item.habilitacao_extra.length > 0 ?
724        `
725            <span class="btn-hab-extra" data-extra='${JSON.stringify(item.habilitacao_extra)}' title="Habilitação especial obrigatória">
726                <img src="https://${item.s3_path}/layout/icons/lock-solid.svg" alt="Habilitação especial"
727                     style="width: 15px; height: 15px;">
728                <span style="font-size: 0.7rem;">Requer habilitação especial</span>
729            </span>
730        ` : ''
731    ;
732
733    let contentCard = `
734        <li data-lote-id="${item.lote_id}" class="list-lote">
735            <a href="${linkLote}" class="list-lote">
736                <div class="status-num_lote">
737                    <span class="status_lote ${getStatusColor(item.nm_statuslote)}">${item.nm_statuslote}</span>
738                    <span class="num_lote">${numLote}</span>
739                    ${botaoHabilitacaoExtra}
740                </div>
741                <div class="content-img">
742                    <div class="img-lote">
743                        <img src="${urlFoto}" alt="Foto do lote">
744                    </div>
745                </div>
746                <div class="content-title">
747                    <img src="${iconGravel}" alt="icon-gravel">
748                    <span class="title_lote">${titulo}</span>
749                </div>
750                <div class="content_body">
751                    <div class="cidade-estado">
752                        <div class="icon-label">
753                            <img src="${iconPin}" alt="icon-pin">
754                            <span>${item.nm_cidade} / ${item.nm_estado}</span>
755                        </div>
756                    </div>
757                    ${
758                        exibrAbaliacao ? `
759                        <div class="vl-avaliacao">
760                            <div class="icon-label">
761                                <img src="${iconInfo}" alt="icon-info">
762                                <span>Avaliação:</span>
763                            </div>
764                            <span>${formatCurrency(parseFloat(item.vl_lanceminimo))}</span>
765                        </div>
766                        ` : ''
767                    }
768                    <div class="vl-lanceminimo">
769                        <div class="icon-label">
770                            <img src="${iconDollar}" alt="icon-dollar">
771                            <span>${temProximaDataValida && menorLance !== menorLanceProxData ? "Lance min. (Atual):" : "Lance mínimo:"}</span>
772                        </div>
773                        <span>${formatCurrency(menorLance)}</span>
774                    </div>
775                    ${temProximaDataValida && menorLance !== menorLanceProxData ? `
776                    <div class="vl-lanceminimo">
777                        <div class="icon-label">
778                            <img src="${iconDollar}" alt="icon-dollar">
779                            <span>Lance min. (Próx. data):</span>
780                        </div>
781                        <span>${formatCurrency(menorLanceProxData)}</span>
782                    </div>` : ''}
783                    <div class="vl-lanceatual">
784                        <div class="icon-label">
785                            <img src="${iconDollar}" alt="icon-dollar">
786                            <span>Último lance:</span>
787                        </div>
788                        <span>
789                            ${item.vl_lance ? formatCurrency(parseFloat(item.vl_lance)) : 'R$ 0,00'}
790                        </span>
791                    </div>
792                </div>
793                <div class="button-acessar-lote">Acessar Lote #${item.lote_id}</div>
794            </a>
795        </li>`;
796
797    listaLotes.append(contentCard);
798
799    $(`li[data-lote-id="${item.lote_id}"]`).on('click', function () {
800        const loteId = $(this).data('lote-id');
801        sessionStorage.setItem('loteClicado', loteId);
802
803        setTimeout(() => {
804            sessionStorage.removeItem('loteClicado');
805        }, 5000);
806    });
807
808    $(`li[data-lote-id="${item.lote_id}"] .btn-hab-extra`).on('click', function (e) {
809        e.preventDefault();
810        e.stopPropagation();
811        const extra = $(this).data('extra');
812        mostrarModalHabilitacaoExtra(extra);
813    });
814
815    $('#fecharModalLiberacao').on('click', function () {
816        fecharModalHabilitacaoExtra();
817    });
818}
819
820function mostrarModalHabilitacaoExtra(habilitacoes) {
821    if (!Array.isArray(habilitacoes) || habilitacoes.length === 0) return;
822
823    let navHtml = '<div class="hab-tabs-nav">';
824    habilitacoes.forEach((hab, idx) => {
825        navHtml += `
826            <div class="hab-tab-btn ${idx === 0 ? 'active' : ''}" data-idx="${idx}" style="padding: 5px; cursor: pointer; border-bottom: 1px solid #eee;">
827                ${hab.nm || 'Habilitação Especial'}
828            </div>
829        `;
830    });
831    navHtml += '</div>';
832
833    let contentHtml = '<div class="hab-tab-content" style="width: 70%; float: left; padding: 0 10px 0 10px;">';
834    habilitacoes.forEach((hab, idx) => {
835        contentHtml += `
836            <div class="hab-tab-pane" data-idx="${idx}" style="${idx === 0 ? '' : 'display:none;'}">
837                <p>${hab.nm_alerta || 'Necessário possuir habilitação especial para este lote.'}</p>
838            </div>
839        `;
840    });
841    contentHtml += '</div>';
842
843    let finalHtml = `
844        <div style="display: flex; flex-wrap: wrap;">
845            ${navHtml}
846            ${contentHtml}
847        </div>
848        <div style="clear: both;"></div>
849    `;
850
851    $('#nomeStatusLiberacao').text('');
852    $('#mensagemLiberacao').html(finalHtml);
853
854    const modal = $('#modalHabilitacaoExtra');
855    modal.addClass('show').attr('aria-hidden', 'false');
856    $('body').addClass('modal-open');
857
858    $('#mensagemLiberacao .hab-tab-btn').on('click', function () {
859        const idx = $(this).data('idx');
860
861        $('#mensagemLiberacao .hab-tab-btn').removeClass('active');
862        $(this).addClass('active');
863
864        $('#mensagemLiberacao .hab-tab-pane').hide();
865        $(`#mensagemLiberacao .hab-tab-pane[data-idx="${idx}"]`).show();
866    });
867}
868
869function fecharModalHabilitacaoExtra() {
870    const modal = $('#modalHabilitacaoExtra');
871
872    modal.removeClass('show').attr('aria-hidden', 'true');
873    $('body').removeClass('modal-open');
874}
875
876function getStatusMontagemColor(nm_statusmontagem) {
877    nm_statusmontagem = nm_statusmontagem.trim().toLowerCase();
878
879    switch (nm_statusmontagem) {
880        case 'aberto para lances':
881            return 'bg-jrGreen-150 text-white';
882        case 'listagem completa':
883            return 'bg-jrGreen-150 text-white';
884        default:
885            return 'bg-white text-black';
886    }
887}
888
889function getStatusColor(status) {
890    switch (status) {
891        case "Aberto para Lance":       return "text-white bg-mlGreen-new";
892        case "Em Pregão":               return "bg-mlWhite-new";
893        case "Dou-lhe Duas":            return "text-white bg-jrOrange-two";
894        case "Vendido":                 return "text-white bg-jrGray-150";
895        case "Condicional":             return "text-white bg-jrGray-300";
896        case "Repasse":                 return "text-white bg-jrGreen-200";
897        case "Não Vendido":             return "bg-mlWhite-new";
898        case "Não Homologado":          return "bg-jrGray-100";
899        case "Homologado":              return "text-white bg-jrBlue-100";
900        case "Retirado":                return "text-white bg-jrGray-300";
901        case "Repasse com Lance":       return "text-white bg-jrBlue-200";
902        case "Dou-lhe Uma":             return "bg-jrGray-100";
903        case "Cancelado":               return "text-white bg-jrRed-100";
904        case "Dou-lhe Três":            return "bg-mlWhite-new";
905        case "Excluido":                return "text-white bg-jrRed-100";
906        case "Arrematado Sub Judice":   return "bg-mlWhite-new";
907    }
908}
909
910let parametros = '';
911
912function renderCarousel(banners, imgContainerId, indicatorsContainerId, type) {
913    const imgContainer = document.getElementById(imgContainerId);
914    const indicatorsContainer = document.getElementById(indicatorsContainerId);
915
916    imgContainer.innerHTML = '';
917    indicatorsContainer.innerHTML = '';
918
919    if (!banners || banners.length <= 0) {
920        return;
921    }
922
923    banners.forEach((banner, index) => {
924        const link = banner.nm_link !== '#' ? `${banner.nm_link}` : '#';
925
926        const linkElement = document.createElement('a');
927        linkElement.href = link;
928
929        const imgElement = document.createElement('img');
930        imgElement.alt = 'banner';
931        imgElement.src = banner.img_path;
932        imgElement.className = 'absolute inset-0 duration-700 ease-in-out w-full object-cover object-center h-full';
933
934        if (index !== 0) {
935            imgElement.classList.add('hidden');
936        }
937
938        imgElement.id = `carousel-${type}-item-${index}`;
939        imgElement.setAttribute(`data-carousel-${type}-item`, '');
940
941        linkElement.appendChild(imgElement);
942        imgContainer.appendChild(linkElement);
943
944        if (banners.length > 1) {
945            const buttonElement = document.createElement('button');
946            buttonElement.type = 'button';
947            buttonElement.className = 'w-3 h-3 rounded-full bg-jrBlue-100';
948            buttonElement.id = `carousel-${type}-indicator-${index}`;
949            buttonElement.setAttribute('aria-current', index === 0 ? 'true' : 'false');
950            buttonElement.setAttribute('aria-label', `Slide ${index + 1}`);
951            buttonElement.setAttribute('data-carousel-slide-to', index);
952
953            indicatorsContainer.appendChild(buttonElement);
954        }
955    });
956}
957
958function initializeCarousels() {
959    const carouselDesktopEl = document.getElementById('banner-carousel-desktop');
960    const itemsDesktop = Array.from(document.querySelectorAll('[data-carousel-desktop-item]')).map((el, i) => ({
961        position: i,
962        el
963    }));
964
965    if (itemsDesktop.length > 1) {
966        const indicatorsDesktop = Array.from(document.querySelectorAll('[data-carousel-slide-to]')).filter(el => el.id.includes('desktop')).map((el, i) => ({
967            position: i,
968            el
969        }));
970
971        let optionsDesktop = {
972            defaultPosition: 0,
973            interval: 5000,
974        };
975
976        if (indicatorsDesktop.length > 0) {
977            optionsDesktop.indicators = {
978                items: indicatorsDesktop
979            };
980        }
981
982        const carouselDesktop = new Carousel(carouselDesktopEl, itemsDesktop, optionsDesktop);
983        carouselDesktop.cycle();
984    }
985
986    const carouselMobileEl = document.getElementById('banner-carousel-mobile');
987    const itemsMobile = Array.from(document.querySelectorAll('[data-carousel-mobile-item]')).map((el, i) => ({
988        position: i,
989        el
990    }));
991
992    if (itemsMobile.length > 1) {
993        const indicatorsMobile = Array.from(document.querySelectorAll('[data-carousel-slide-to]')).filter(el => el.id.includes('mobile')).map((el, i) => ({
994            position: i,
995            el
996        }));
997
998        let optionsMobile = {
999            defaultPosition: 0,
1000            interval: 5000,
1001        };
1002
1003        if (indicatorsMobile.length > 0) {
1004            optionsMobile.indicators = {
1005                items: indicatorsMobile
1006            };
1007        }
1008
1009        const carouselMobile = new Carousel(carouselMobileEl, itemsMobile, optionsMobile);
1010        carouselMobile.cycle();
1011    }
1012}
1013
1014async function dadosSite() {
1015    const hostName = window.location.origin;
1016
1017    try {
1018        const response = await fetch(`${hostName}/core/api/get-dados-site`);
1019        const dados = await response.json();
1020
1021        if (dados.banners) {
1022            const desktopBanners = dados.banners.filter(b => !b.nm_descricao.toLowerCase().includes('mobile'));
1023            const mobileBanners = dados.banners.filter(b => b.nm_descricao.toLowerCase().includes('mobile'));
1024
1025            renderCarousel(desktopBanners, 'banners-img-desktop', 'banners-indicators-desktop', 'desktop');
1026            renderCarousel(mobileBanners, 'banners-img-mobile', 'banners-indicators-mobile', 'mobile');
1027
1028            initializeCarousels();
1029        }
1030
1031        parametros = dados.parametros;
1032
1033        const param44 = parametros.find(p =>
1034            Number(p.statusparamsite_id) === 44 &&
1035            (p.bn === true || p.bn === "true")
1036        );
1037
1038        window.tem44ativo = !!param44;
1039
1040        try {
1041            Object.values(parametros).forEach(parametro => {
1042                if (parametro.nm !== undefined) {
1043                    if (Number(parametro.statusparamsite_id) === 55) {
1044                        // Google Analytics
1045                        const gaJs = document.createElement("script");
1046                        gaJs.type = "text/javascript";
1047                        gaJs.src = "https://www.googletagmanager.com/gtag/js?id=" + parametro.nm;
1048                        document.body.appendChild(gaJs);
1049
1050                        window.dataLayer = window.dataLayer || [];
1051
1052                        function gtag() {
1053                            dataLayer.push(arguments);
1054                        }
1055
1056                        gtag('js', new Date());
1057                        gtag('config', parametro.nm);
1058
1059                    } else if (Number(parametro.statusparamsite_id) === 97) {
1060                        // Google Site Verification
1061                        const metaTag = document.createElement("meta");
1062                        metaTag.name = "google-site-verification";
1063                        metaTag.content = parametro.nm;
1064                        document.getElementsByTagName('head')[0].appendChild(metaTag);
1065                    }
1066                }
1067            });
1068        } catch (error) {
1069            console.error('Erro ao processar e exibir dados:', error);
1070        }
1071
1072    } catch (error) {
1073        console.error('Erro ao obter dados do servidor:', error);
1074        throw error;
1075    }
1076}
1077
1078function gerenciaVisibilidadeFiltro(aba) {
1079    const filtro = $('.filter_container');
1080    const aviso = $('#aviso__encerrado');
1081
1082    if (aba === 'encerrados') {
1083        filtro.hide();
1084        aviso.show();
1085
1086    } else {
1087        filtro.show();
1088        aviso.hide();
1089    }
1090}
1091
1092function ativarAba(elemento) {
1093    const tipo = $(elemento).data('tipo');
1094    const abaAtual = sessionStorage.getItem('abaSelecionada');
1095
1096    if (tipo === abaAtual) {
1097        return;
1098    }
1099
1100    sessionStorage.setItem('abaSelecionada', tipo);
1101
1102    gerenciaVisibilidadeFiltro(tipo);
1103
1104    $('.tab-btn').removeClass('active');
1105    $(elemento).addClass('active');
1106
1107    currentPage = 1;
1108
1109    const url = new URL(window.location.href);
1110    url.searchParams.delete('page');
1111    url.searchParams.delete('pg');
1112    history.replaceState(null, '', url.toString());
1113
1114    getLeiloes(tipo);
1115}
1116
1117function abrirModalLotes(leilaoId, pagina = 1) {
1118    $('#modal-lotes').removeClass('hidden').addClass('flex');
1119    $('#modal-lotes-list').html('<p class="p-4 text-gray-600">Carregando lotes...</p>');
1120
1121    $.ajax({
1122        url: '/core/api/get-lotes-basic',
1123        type: 'GET',
1124        data: {
1125            leilao_id: leilaoId,
1126            pg: pagina,
1127        },
1128        success: function (res) {
1129            if (res.error) {
1130                $('#modal-lotes-list').html('<p class="p-4 text-red-600">' + res.error + '</p>');
1131                return;
1132            }
1133
1134            const itens = Array.isArray(res.items) ? res.items : Object.values(res.items || {});
1135
1136            if (itens.length > 0) {
1137                montarTabelaLotes(itens, res, leilaoId);
1138            } else {
1139                $('#modal-lotes-list').html('<p class="p-4 text-gray-600">Nenhum lote encontrado</p>');
1140            }
1141        },
1142        error: function (xhr) {
1143            try {
1144                const json = JSON.parse(xhr.responseText);
1145                const itens = Array.isArray(json.items) ? json.items : Object.values(json.items || {});
1146
1147                if (itens.length > 0) {
1148                    montarTabelaLotes(itens, json, leilaoId);
1149                    return;
1150                }
1151            } catch (e) {
1152                // ignora erro de parse
1153            }
1154
1155            if (xhr.status === 410) {
1156                $('#modal-lotes-list').html('<p class="p-4 text-red-600">Os lotes não estão mais disponíveis ou foram removidos.</p>');
1157            } else {
1158                $('#modal-lotes-list').html('<p class="p-4 text-red-600">Erro ao buscar lotes</p>');
1159            }
1160        }
1161    });
1162
1163    $('html').css({overflowY: 'hidden'});
1164}
1165
1166function montarTabelaLotes(itens, res, leilaoId) {
1167    const exibirVenda = itens.some(lote => lote.vl_venda && lote.vl_venda !== '0');
1168
1169    let selectOrdenacao = `
1170        <div class="flex items-center justify-end mb-2">
1171            <label class="mr-2 text-sm text-gray-600">Ordenar por:</label>
1172            <select id="select-ordenacao-lotes" class="border rounded px-2 py-1 text-sm">
1173                <option value="ordem">Número do Lote</option>
1174                <option value="valor-crescente">Lance mínimo (Crescente)</option>
1175                <option value="valor-decrescente">Lance mínimo (Decrescente)</option>
1176                <option value="avaliacao-crescente">Avaliação (Crescente)</option>
1177                <option value="avaliacao-decrescente">Avaliação (Decrescente)</option>
1178            </select>
1179        </div>
1180    `;
1181
1182    let estruturaTabela = `
1183        ${selectOrdenacao}
1184        <div class="overflow-x-auto w-fit">
1185            <table class="min-w-full mb:w-fit table-auto border border-gray-300 rounded">
1186                <thead class="bg-gray-100 text-sm text-left text-gray-600">
1187                    <tr>
1188                        <th class="px-4 py-2 border">Lote</th>
1189                        <th class="px-4 py-2 border">Título</th>
1190                        <th class="px-4 py-2 border">Descrição</th>
1191                        <th class="px-4 py-2 border">Avaliação</th>
1192                        <th class="px-4 py-2 border">Lance mínimo</th>
1193                        ${exibirVenda ? `<th class="px-4 py-2 border">Venda</th>` : ''}
1194                        <th class="px-4 py-2 border">Status</th>
1195                    </tr>
1196                </thead>
1197                <tbody class="text-sm text-gray-700"></tbody>
1198            </table>
1199        </div>
1200    `;
1201
1202    const currentPage = Number(res.currentPage) || 1;
1203    const nextPage = Number(res.nextPage) || currentPage;
1204    const previousPage = Number(res.previousPage) || currentPage;
1205    const totalPages = Number(res.totalPages) || currentPage;
1206
1207    if (totalPages > 1) {
1208        estruturaTabela += `
1209            <div class="flex justify-center items-center gap-2 mt-4">
1210                <button class="px-3 py-1 hover:bg-jrGray-50 rounded ${previousPage < currentPage ? 'bg-opacity-70 text-white font-bold bg-jrBlue-new' : ' bg-opacity-75 bg-jrGray-50 cursor-not-allowed'}" 
1211                    ${previousPage < currentPage ? `onclick="abrirModalLotes(${leilaoId}, ${previousPage})"` : 'disabled'}>
1212                    ◀ Anterior
1213                </button>
1214                <span class="text-sm text-gray-600">Página ${currentPage} de ${totalPages}</span>
1215                <button class="px-3 py-1 rounded ${nextPage > currentPage ? 'bg-opacity-70 text-white font-bold bg-jrBlue-new' : ' bg-opacity-75 bg-jrGray-50 cursor-not-allowed'}" 
1216                    ${nextPage > currentPage ? `onclick="abrirModalLotes(${leilaoId}, ${nextPage})"` : 'disabled'}>
1217                    Próxima ▶
1218                </button>
1219            </div>
1220        `;
1221    }
1222
1223    $('#modal-lotes-list').html(estruturaTabela);
1224
1225    const ordenacaoInicial = $('#select-ordenacao-lotes').val();
1226    ordenarLotes(itens, ordenacaoInicial);
1227    renderizarLotes(itens);
1228
1229    $('#select-ordenacao-lotes').on('change', function () {
1230        const criterio = $('#select-ordenacao-lotes').val();
1231        ordenarLotes(itens, criterio);
1232        renderizarLotes(itens);
1233    });
1234}
1235
1236function ordenarLotes(items, criterio) {
1237    switch (criterio) {
1238        case 'valor-crescente':
1239            items.sort((a, b) => (parseFloat(a.vl_lanceminimo) || 0) - (parseFloat(b.vl_lanceminimo) || 0));
1240            break;
1241
1242        case 'valor-decrescente':
1243            items.sort((a, b) => (parseFloat(b.vl_lanceminimo) || 0) - (parseFloat(a.vl_lanceminimo) || 0));
1244            break;
1245
1246        case 'avaliacao-crescente':
1247            items.sort((a, b) => (parseFloat(a.vl_lanceinicial) || 0) - (parseFloat(b.vl_lanceinicial) || 0));
1248            break;
1249
1250        case 'avaliacao-decrescente':
1251            items.sort((a, b) => (parseFloat(b.vl_lanceinicial) || 0) - (parseFloat(a.vl_lanceinicial) || 0));
1252            break;
1253
1254        case 'ordem':
1255        default:
1256            items.sort((a, b) => (parseInt(a.nu_ordem) || 0) - (parseInt(b.nu_ordem) || 0));
1257            break;
1258    }
1259}
1260
1261function renderizarLotes(items) {
1262    let linhas = '';
1263    const exibirVenda = items.some(lote => parseFloat(lote.vl_venda) > 0);
1264
1265    items.forEach(lote => {
1266        linhas += `
1267            <tr class="hover:bg-opacity-100 hover:bg-gray-25">
1268                <td class="px-4 py-2 border">${lote.nu || '-'}</td>
1269                <td class="px-4 py-2 border">${lote.nm_titulo_lote || '-'}</td>
1270                <td class="px-4 py-2 border truncate-multiline">${lote.nm_descricao || '-'}</td>
1271                <td class="px-4 py-2 border min-w-[147px] max-w-[147px]">R$ ${parseFloat(lote.vl_lanceminimo).toLocaleString('pt-BR', {minimumFractionDigits: 2})}</td>
1272                <td class="px-4 py-2 border min-w-[147px] max-w-[147px]">R$ ${parseFloat(lote.vl_lanceinicial).toLocaleString('pt-BR', {minimumFractionDigits: 2})}</td>
1273                ${exibirVenda ? `<td class="px-4 py-2 border min-w-[147px] max-w-[147px]">R$ ${parseFloat(lote.vl_venda || 0).toLocaleString('pt-BR', {minimumFractionDigits: 2})}</td>` : ''}
1274                <td class="px-4 py-2 border">${lote.nm_statuslote || '-'}</td>
1275            </tr>
1276        `;
1277    });
1278
1279    $('#modal-lotes-list table tbody').html(linhas);
1280}
1281
1282function restoreFiltersFromSession() {
1283    const storedFilters = sessionStorage.getItem('filtros');
1284    if (storedFilters) {
1285        try {
1286            filters = JSON.parse(storedFilters);
1287            hasFilters = Object.values(filters).some(value => value !== '' && value !== null && value !== 0);
1288
1289            if (hasFilters) {
1290                isSearchClicked = true;
1291
1292                $('#limpar_btn').removeClass('disabled').prop('disabled', false);
1293                $('#filter_alert').show();
1294            }
1295
1296            const storedPage = sessionStorage.getItem('currentPage');
1297            if (storedPage) {
1298                currentPage = parseInt(storedPage, 10);
1299            }
1300        } catch (e) {
1301            console.error("Erro ao restaurar filtros da sessão:", e);
1302            hasFilters = false;
1303            isSearchClicked = false;
1304        }
1305    }
1306}
1307
1308$(function () {
1309    if ($('#leiloes-list').length || $('#lotes-list').length) {
1310        restoreFiltersFromSession();
1311
1312        const urlParams = new URLSearchParams(window.location.search);
1313        const pageParam = urlParams.get('page');
1314        if (pageParam) {
1315            currentPage = parseInt(pageParam, 10);
1316        }
1317
1318        dadosSite().then(() => {
1319
1320            if (window.tem44ativo) {
1321                $('.tab-btn').removeClass('hidden');
1322            } else {
1323                $('.tab-btn').addClass('hidden');
1324            }
1325
1326            const abaSalva = sessionStorage.getItem('abaSelecionada') || 'proximos';
1327            $('.tab-btn').removeClass('active');
1328            $(`.tab-btn[data-tipo="${abaSalva}"]`).addClass('active');
1329            gerenciaVisibilidadeFiltro(abaSalva);
1330
1331            if (hasFilters) {
1332                getLotes();
1333            } else {
1334                getLeiloes(abaSalva);
1335            }
1336
1337            setTimeout(() => {
1338                if (typeof exibirPopup === "function") {
1339                    exibirPopup();
1340                }
1341            }, 2000);
1342        });
1343
1344        window.addEventListener('popstate', function (event) {
1345            if (event.state && event.state.page) {
1346                changePage(event.state.page, false);
1347            }
1348        });
1349    }
1350});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.