PageSourceSearch

https://godofredoviana.ma.gov.br/js/main.js

js godofredoviana.ma.gov.br collected 2026-09-25 09:30:47 UTC 44,709 bytes, 1,447 lines download raw bytes

1jQuery(function ($) {
2	'use strict',
3
4		//#main-slider
5		$(function () {
6			$('#main-slider.carousel').carousel({
7				interval: 8000,
8			});
9		});
10
11
12	// $(".select_minimun").select2({
13	// 	minimumInputLength: 3 
14	// }); 
15
16
17	// accordian
18	$('.accordion-toggle').on('click', function () {
19		$(this).closest('.panel-group').children().each(function () {
20			$(this).find('>.panel-heading').removeClass('active');
21		});
22
23		$(this).closest('.panel-heading').toggleClass('active');
24	});
25
26	//Initiat WOW JS
27	new WOW().init();
28
29	// portfolio filter
30	$(window).load(function () {
31		'use strict';
32		var $portfolio_selectors = $('.portfolio-filter >li>a');
33		var $portfolio = $('.portfolio-items');
34		$portfolio.isotope({
35			itemSelector: '.portfolio-item',
36			layoutMode: 'fitRows'
37		});
38
39		$portfolio_selectors.on('click', function () {
40			$portfolio_selectors.removeClass('active');
41			$(this).addClass('active');
42			var selector = $(this).attr('data-filter');
43			$portfolio.isotope({ filter: selector });
44			return false;
45		});
46	});
47
48	// Contact form
49	var form = $('#main-contact-form');
50	form.submit(function (event) {
51		event.preventDefault();
52		var form_status = $('<div class="form_status"></div>');
53		$.ajax({
54			url: $(this).attr('action'),
55
56			beforeSend: function () {
57				form.prepend(form_status.html('<p><i class="fa fa-spinner fa-spin"></i> Email is sending...</p>').fadeIn());
58			}
59		}).done(function (data) {
60			form_status.html('<p class="text-success">' + data.message + '</p>').delay(3000).fadeOut();
61		});
62	});
63
64	$('.sendformchage').change(function () {
65		$("form").submit();
66	});
67
68	//goto top
69	$('.gototop').click(function (event) {
70		event.preventDefault();
71		$('html, body').animate({
72			scrollTop: $("body").offset().top
73		}, 500);
74	});
75
76	//Pretty Photo
77	$("a[rel^='prettyPhoto']").prettyPhoto({
78		social_tools: false
79	});
80
81	$(function () {
82
83		var toggle = $('.color-switcher .toggle');
84		var colorTile = $('.color-switcher a');
85		toggle.click(function () {
86			$(this).parent().toggleClass('open');
87		});
88
89	});
90
91	$(function () {
92		$(window).scroll(function () {
93			if ($(this).scrollTop() > 100) {
94				$("#top-bar").fadeOut();
95				$("#logo-top-bar").fadeOut();
96				$('#scroll').fadeIn();
97
98			} else {
99				$("#top-bar").fadeIn();
100				$("#logo-top-bar").fadeIn();
101				$('#scroll').fadeOut();
102			}
103		});
104		$('#scroll').click(function () {
105			$("html, body").animate({ scrollTop: 0 }, 600);
106			return false;
107		});
108	});
109
110	$(function () {
111		$('input[type="text"]').change(function () {
112			this.value = $.trim(this.value);
113		});
114	});
115
116
117	//Alterando botão whatsapp
118	const btnwwp = document.querySelector(".btn-wwp");
119	if (btnwwp) {
120		$(window).on("scroll", function (e) {
121			if ($(this).scrollTop() > 100) {
122				btnwwp.style.bottom = "115px";
123			} else {
124
125				btnwwp.style.bottom = "10px";
126			}
127		});
128	}
129
130
131	//Fim botão whatsapp
132	$('#nota2').on('click', function () {
133		$('#nota').val(2);
134		$('#FormSatisfacao').show();
135		$('.radio-satisfacao').removeAttr('style');
136		$("#nota2").css({ "color": "rgb(249,66,51)" });
137	});
138	$('#nota4').on('click', function () {
139		$('#nota').val(4);
140		$('#FormSatisfacao').show();
141		$('.radio-satisfacao').removeAttr('style');
142		$("#nota4").css({ "color": "rgb(238,137,62)" });
143	});
144	$('#nota6').on('click', function () {
145		$('#nota').val(6);
146		$('#FormSatisfacao').show();
147		$('.radio-satisfacao').removeAttr('style');
148		$("#nota6").css({ "color": "rgb(142,90,13)" });
149	});
150	$('#nota8').on('click', function () {
151		$('#nota').val(8);
152		$('#FormSatisfacao').show();
153		$('.radio-satisfacao').removeAttr('style');
154		$("#nota8").css({ "color": "rgb(0,191,101)" });
155	});
156	$('#nota10').on('click', function () {
157		$('#nota').val(10);
158		$('#FormSatisfacao').show();
159		$('.radio-satisfacao').removeAttr('style');
160		$("#nota10").css({ "color": "rgb(0,155,83)" });
161	});
162
163
164
165	var iconotanota2 = document.querySelector(".iconota-nota2");
166	var iconotanota4 = document.querySelector(".iconota-nota4");
167	var iconotanota6 = document.querySelector(".iconota-nota6");
168	var iconotanota8 = document.querySelector(".iconota-nota8");
169	var iconotanota10 = document.querySelector(".iconota-nota10");
170
171	$(".iconota-nota2").on("click", function () {
172		iconotanota2.style.background = "#c0392b";
173		iconotanota2.style.color = "#FCFCFC";
174		iconotanota2.style.border = "#c0392b";
175		iconotanota2.style.borderRadius = "35px"
176		iconotanota4.removeAttribute("style");
177		iconotanota6.removeAttribute("style");
178		iconotanota8.removeAttribute("style");
179		iconotanota10.removeAttribute("style");
180		$('#FormSatisfacao').show();
181	})
182
183	$(".iconota-nota4").on("click", function () {
184		iconotanota4.style.background = "#e74c3c";
185		iconotanota4.style.color = "#FCFCFC";
186		iconotanota4.style.border = "#e74c3c";
187		iconotanota4.style.borderRadius = "35px"
188		iconotanota2.removeAttribute("style");
189		iconotanota6.removeAttribute("style");
190		iconotanota8.removeAttribute("style");
191		iconotanota10.removeAttribute("style");
192		$('#FormSatisfacao').show();
193	})
194
195	$(".iconota-nota6").on("click", function () {
196		iconotanota6.style.background = "#d35400";
197		iconotanota6.style.color = "#FCFCFC";
198		iconotanota6.style.border = "#d35400";
199		iconotanota6.style.borderRadius = "35px"
200		iconotanota2.removeAttribute("style");
201		iconotanota4.removeAttribute("style");
202		iconotanota8.removeAttribute("style");
203		iconotanota10.removeAttribute("style");
204		$('#FormSatisfacao').show();
205	})
206
207	$(".iconota-nota8").on("click", function () {
208		iconotanota8.style.background = "#2ecc71";
209		iconotanota8.style.color = "#FCFCFC";
210		iconotanota8.style.border = "#535353";
211		iconotanota8.style.borderRadius = "35px"
212		iconotanota6.style.background = "#d35400";
213		iconotanota2.removeAttribute("style");
214		iconotanota6.removeAttribute("style");
215		iconotanota4.removeAttribute("style");
216		iconotanota10.removeAttribute("style");
217		$('#FormSatisfacao').show();
218	})
219
220	$(".iconota-nota10").on("click", function () {
221		iconotanota10.style.background = "#27ae60";
222		iconotanota10.style.color = "#FCFCFC";
223		iconotanota10.style.border = "#27ae60";
224		iconotanota10.style.borderRadius = "35px"
225		iconotanota2.removeAttribute("style");
226		iconotanota6.removeAttribute("style");
227		iconotanota4.removeAttribute("style");
228		iconotanota8.removeAttribute("style");
229		$('#FormSatisfacao').show();
230	})
231
232
233	$('#CancelSatisfacao').on('click', function () {
234		iconotanota2.removeAttribute("style");
235		iconotanota4.removeAttribute("style");
236		iconotanota6.removeAttribute("style");
237		iconotanota8.removeAttribute("style");
238		iconotanota10.removeAttribute("style");
239		$('#FormSatisfacao').hide();
240		iconotanota2.style.color = "#c0392b";
241		iconotanota4.style.color = "#e74c3c";
242		iconotanota6.style.color = "#d35400";
243		iconotanota8.style.color = "#2ecc71";
244		iconotanota10.style.color = "#27ae60";
245	});
246
247
248	$('#FormSatisfacao').submit(function (e) {
249
250		e.preventDefault();
251
252		$.ajax({
253			type: $('#FormSatisfacao').attr('method'),
254			url: $('#FormSatisfacao').attr('action'),
255			data: $('#FormSatisfacao').serialize(),
256			beforeSend: function () {
257				$('.load').show();
258				$('#btnSend').hide();
259			},
260			success: function (data) {
261				$("#Return").html(data);
262			},
263			error: function () {
264				alert('erro FormSatisfacao.submit');
265			},
266			complete: function () {
267				$('.load').hide();
268				$('#FormSatisfacao').empty();
269			}
270		});
271	});
272
273});
274
275
276/* ========== CARDS LICITAÇÃO INDEX - INÍCIO =============== */
277if ($('#cards_new').hasClass("card__content")) {
278	const cardsCarousel = document.querySelector('#cards_new.card__content');
279	const cardsCarouselScope = cardsCarousel.closest('.home-biddings-clean') || document;
280
281	let swiperCards = new Swiper(cardsCarousel, {
282		loop: true,
283		spaceBetween: 15,
284		grabCursor: true,
285		speed: 650,
286		autoplay: $(".home-biddings-clean #cards_new").length ? {
287			delay: 4500,
288			disableOnInteraction: false,
289			pauseOnMouseEnter: true,
290		} : false,
291
292		pagination: {
293			el: ".swiper-pagination",
294			clickable: true,
295			dynamicBullets: true,
296		},
297
298		navigation: {
299			nextEl: cardsCarouselScope.querySelector(".home-biddings-clean__next") || cardsCarouselScope.querySelector(".swiper-button-next"),
300			prevEl: cardsCarouselScope.querySelector(".home-biddings-clean__prev") || cardsCarouselScope.querySelector(".swiper-button-prev"),
301		},
302
303		breakpoints: {
304			600: {
305				slidesPerView: 2,
306			},
307			968: {
308				slidesPerView: 3,
309			},
310		},
311	});
312}
313/* ========== CARDS LICITAÇÃO INDEX - FIM =============== */
314
315/* ========== DATA DE ATUALIZAÇÃO =============== */
316
317
318// verifica se o elemento com ID 'informacaoAtualizada' existe
319if (document.getElementById("informacaoAtualizada")) {
320	let el = document.getElementById("informacaoAtualizada");
321	let acao = el.getAttribute("data-acao");
322	let id = el.getAttribute("data-id");
323
324	let domain = window.location.origin
325		.replace(/^https?:\/\//, '') // remove http:// ou https://
326		.replace(/^www\./, ''); // remove www.
327	$.getJSON("https://estatisticas.assesibrasil.com.br/atualizacao/" + acao + "/" + domain + "/" + id, function (response) {
328		$.each(response.data, function (k, v) {
329			$('#informacaoAtualizada').html("<i class='fa fa-clock-o'></i> <i>Informações atualizadas em: " + v.dataconvertida + "</i>");
330		});
331	});
332
333}
334
335/* ========== FIM DATA DE ATUALIZAÇÃO =============== */
336
337
338const pesq_geral_inicial = document.getElementById('busca_inicial');
339const form_geral_inicial = document.getElementById('form_pesq_geral');
340
341if (form_geral_inicial != null) {
342
343	form_geral_inicial.addEventListener('submit', function (event) {
344		event.preventDefault();
345
346		const value_get = pesq_geral_inicial.value;
347		window.location.href = '/pesquisa?pesquisa=' + encodeURIComponent(value_get);
348
349	});
350
351}
352
353$("#busca_inicial").mouseout(function () {
354
355	$("#pesquisa_inicial").attr('href', "/pesquisa?pesquisa=" + $(this).val());
356
357});
358
359function alternarTexto(botao) {
360	// Encontra a div de texto que está logo antes do botão clicado
361	const divTexto = botao.previousElementSibling;
362
363	// Alterna a classe 'expandido' na div de texto
364	divTexto.classList.toggle('expandido');
365
366	// Muda o texto do botão dependendo do estado
367	if (divTexto.classList.contains('expandido')) {
368		botao.innerText = 'Veja menos';
369	} else {
370		botao.innerText = 'Veja mais';
371	}
372}
373
374// Verifica se o texto ultrapassa 3 linhas e exibe o botão "Veja mais" se necessário
375function verificarTexto() {
376	document.querySelectorAll('.texto-limitado').forEach(function (divTexto) {
377		var botao = divTexto.nextElementSibling;
378
379		if (!botao || !botao.classList.contains('btn-veja-mais')) {
380			return;
381		}
382
383		var lineHeight = parseFloat(getComputedStyle(divTexto).lineHeight);
384		var limite = lineHeight * 3;
385
386		if (divTexto.scrollHeight > limite) {
387			botao.style.display = 'inline-block';
388		} else {
389			botao.style.display = 'none';
390		}
391	});
392}
393document.addEventListener('DOMContentLoaded', function () {
394	verificarTexto();
395});
396
397/* ========== FILTRAR CAMPOS VAZIOS - INÍCIO =============== */
398function filtrarCamposVazios(event) {
399	event.preventDefault(); // Impede o envio padrão
400
401	const form = event.target;
402	const params = new URLSearchParams();
403	const adicionados = new Set();
404
405	const campos = form.querySelectorAll("input[name], select[name], textarea[name]");
406
407	campos.forEach(campo => {
408		if (campo.disabled) return;
409
410		const nome = campo.name?.trim();
411		if (!nome) return;
412
413		const tipo = campo.type;
414		const tag = campo.tagName.toLowerCase();
415
416		let valor = "";
417
418		if (tipo === "checkbox") {
419			if (campo.checked) {
420				valor = campo.value.trim();
421			}
422		} else if (tipo === "radio") {
423			if (!adicionados.has(nome)) {
424				const selecionado = form.querySelector(`input[name="${nome}"]:checked`);
425				if (selecionado && selecionado.value.trim()) {
426					valor = selecionado.value.trim();
427					adicionados.add(nome);
428				}
429			}
430		} else {
431			valor = campo.value.trim();
432		}
433
434		if (valor) {
435			params.set(nome, valor); // substitui valor anterior
436		}
437	});
438
439	// Remove qualquer query string anterior (para evitar acumulação)
440	const baseUrl = (form.action || window.location.pathname).split('?')[0];
441	const novaUrl = params.toString() ? `${baseUrl}?${params.toString()}` : baseUrl;
442
443	// Redireciona para a nova URL limpa
444	window.location.href = novaUrl;
445}
446/* ========== FILTRAR CAMPOS VAZIOS - FIM =============== */
447
448/* ========== NEVE CAINDO - INÍCIO =============== */
449// verifica se o elemento com ID 'snow-containe' existe
450// if (document.getElementById("snow-container")) {
451// document.addEventListener('DOMContentLoaded', function () {
452//     const snowContainer = document.getElementById('snow-container');
453//     const numberOfSnowflakes = 150; // AUMENTADO: Mais flocos = mais chamativo
454//     const snowflakes = []; 
455
456//     // Variável para criar o efeito oscilatório de vento em todos os flocos
457//     let angle = 0; 
458//     const swaySpeed = 0.01; // Velocidade da oscilação do vento
459
460//     // Objeto Floco de Neve
461//     function Snowflake() {
462//         this.x = Math.random() * window.innerWidth;
463//         this.y = Math.random() * window.innerHeight; 
464//         this.radius = Math.random() * 3 + 1.5; // AUMENTADO: Tamanho (1.5px a 4.5px)
465//         this.speed = Math.random() * 0.8 + 0.7; // AUMENTADO: Queda um pouco mais rápida
466//         this.wind = Math.random() * 0.7 - 0.35; // Vento lateral inicial
467
468//         // Variável para o movimento ondulatório (cada floco balança de forma diferente)
469//         this.swayFactor = Math.random() * 20 + 10; 
470
471//         // Cria e estiliza o elemento DOM
472//         this.element = document.createElement('div');
473//         this.element.classList.add('snowflake');
474//         this.element.innerHTML = '&#10052;'; // Mantendo o caractere Unicode
475
476//         // Ajustamos o tamanho para combinar com o novo brilho
477//         this.element.style.fontSize = `${this.radius * 3 + 6}px`;
478//         this.element.style.opacity = this.radius / 5 + 0.5; // Opacidade baseada no tamanho, mais alta
479//         snowContainer.appendChild(this.element);
480
481//         // Método para atualizar a posição
482//         this.update = function () {
483//             // Movimento de queda e vento aleatório
484//             this.y += this.speed; 
485
486//             // NOVIDADE: Adiciona movimento senoidal para o balanço (mais natural)
487//             // O valor 'angle' cria a oscilação, e 'swayFactor' a torna única para cada floco
488//             this.x += this.wind + Math.sin(angle) * (this.radius / 2); 
489
490//             // Se sair da tela, reposiciona no topo (Reciclagem Garantida)
491//             if (this.y > window.innerHeight) {
492//                 this.y = -10; 
493//                 this.x = Math.random() * window.innerWidth; 
494//                 this.speed = Math.random() * 0.8 + 0.7; 
495//             }
496
497//             // Aplica a posição ao elemento
498//             this.element.style.top = `${this.y}px`;
499//             this.element.style.left = `${this.x}px`;
500//         };
501//     }
502
503//     // Inicializa todos os flocos
504//     for (let i = 0; i < numberOfSnowflakes; i++) {
505//         snowflakes.push(new Snowflake());
506//     }
507
508//     // Loop de Animação Principal (requestAnimationFrame)
509//     function animateSnow() {
510//         // INCREMENTO: Atualiza o ângulo para o movimento de balanço
511//         angle += swaySpeed; 
512
513//         for (let i = 0; i < snowflakes.length; i++) {
514//             snowflakes[i].update();
515//         }
516//         requestAnimationFrame(animateSnow);
517//     }
518
519//     // Inicia o ciclo
520//     animateSnow();
521// });
522// }
523/* ========== NEVE CAINDO - FIM =============== */
524
525const urlParams = new URLSearchParams(window.location.search);
526const source = urlParams.get('source');
527
528if (source) {
529
530	sessionStorage.clear();
531	sessionStorage.setItem('user_source', source);
532	console.log('Source saved:', source);
533
534
535	document.addEventListener('click', function (event) {
536
537		const link = event.target.closest('a');
538		const sourceSalva = sessionStorage.getItem('user_source');
539
540		if (link && sourceSalva && link.href.includes(window.location.hostname)) {
541
542			const url_destino = new URL(link.href);
543			url_destino.searchParams.set('source', sourceSalva);
544			link.href = url_destino.href;
545
546		}
547
548	});
549
550}
551
552if (source && urlParams.size > 0) {
553
554	const allparams = Object.fromEntries(urlParams.entries());
555
556	for (const [key, value] of Object.entries(allparams)) {
557		sessionStorage.removeItem('user_param_' + key);
558		sessionStorage.setItem('user_param_' + key, value);
559		console.log('Params to save:', key, ' -> ', value);
560	}
561
562
563
564	const buttonSubmit = document.querySelector('button[type="submit"]');
565
566
567	if (buttonSubmit && buttonSubmit.form) {
568
569		const form_submit = buttonSubmit.form;
570		console.log('Form submit found:', form_submit);
571
572		form_submit.addEventListener('submit', function (event) {
573
574
575			for (let i = 0; i < sessionStorage.length; i++) {
576				const key = sessionStorage.key(i);
577
578				// Verifica se a chave tem o prefixo correto
579				if (key.startsWith('user_param_')) {
580					const rawKey = key.replace('user_param_', '');
581					// if (key !== 'user_param_source') sessionStorage.removeItem(key); // Remove após usar
582					const value = sessionStorage.getItem(key);
583
584					// Verifica se o formulário JÁ tem esse campo para não duplicar
585					let input = form_submit.querySelector(`input[name="${rawKey}"]`);
586
587					if (input) {
588						// Se já existe (ex: campo email), você decide se sobrescreve ou mantém.
589						// Geralmente mantemos o que o usuário digitou, então não fazemos nada.
590						// Se quiser forçar o valor da URL, descomente a linha abaixo:
591						// input.value = value;
592					} else {
593						// Se não existe, cria um input hidden e adiciona ao form
594						console.log('Injetando campo oculto:', rawKey, value);
595						input = document.createElement('input');
596						input.type = 'hidden';
597						input.name = rawKey;
598						input.value = value;
599						form_submit.appendChild(input);
600					}
601				}
602			}
603
604
605			// Opcional: Salvar a URL final simulada para debug
606			const formData = new FormData(form_submit);
607			const finalQuery = new URLSearchParams(formData).toString();
608			sessionStorage.setItem('ultimaUrlEnviada', form_submit.action + '?' + finalQuery);
609
610		})
611
612	}
613
614}
615
616// PESQUISA
617 // Função para obter parâmetro da URL
618  function getParametroUrl(nome) {
619      var params = new URLSearchParams(window.location.search);
620      return params.get(nome);
621  }
622
623  var pesquisaUrl = getParametroUrl('pesquisa');
624
625  if (pesquisaUrl) {
626      document.getElementById('chat-input').value = pesquisaUrl;
627  }
628
629  $(function () {
630
631    // MONTAR RESULTADO
632      function montarResultado(item, index) {
633          var aberto = index === 0;
634
635          var resultado = $('<li>', {
636              'class': 'chat-resultado' + (aberto ? ' aberto' : '')
637          });
638
639          var linhaTitulo = $('<div>', {
640              'class': 'chat-resultado-titulo'
641          });
642
643          var botao = $('<button>', {
644              'type': 'button',
645              'class': 'chat-resultado-toggle'
646          });
647
648          var titulo = $('<b>').text(item.titulo || '');
649
650          var chevron = $('<span>', {
651              'class': 'chat-resultado-chevron'
652          }).html('<i class="bi bi-chevron-down"></i>');
653
654          botao.append(titulo).append(chevron);
655          linhaTitulo.append(botao);
656
657          if (item.datadesc) {
658              linhaTitulo.append(
659                  $('<span>', {
660                      'class': 'chat-resultado-data'
661                  }).html(
662                      '<i class="bi bi-calendar2"></i> ' +
663                      item.datadesc
664                  )
665              );
666          }
667
668          var conteudo = $('<div>', {
669              'class': 'chat-resultado-conteudo'
670          });
671
672          conteudo.append(
673              $('<p>', {
674                  'class': 'chat-resultado-descricao'
675              }).text(item.detalhamento || '')
676          );
677
678          if (item.link) {
679              conteudo.append(
680                  $('<a>', {
681                      'href': item.link,
682                      'target': '_blank',
683                      'rel': 'noopener noreferrer',
684                      'text': 'Ver resultado'
685                  })
686              );
687          }
688
689          resultado.append(linhaTitulo);
690          resultado.append(conteudo);
691
692          return resultado;
693      }
694      
695      // SCROLL
696      function scrollToBottom() {
697          var chat = document.getElementById('chat-messages');
698
699          if (chat !== null) {
700              chat.scrollTop = chat.scrollHeight;
701          }
702      }
703
704      var tematicas = [];
705      var pesquisa = 0;
706      var isProcessing = false;
707      var ultimaPergunta = '';
708      
709      // REMOVER LOADING INICIAL
710      // evita deixar o segundo ícone de robô na tela.
711
712      function removerLoadingTematicas() {
713          var $loading = $('#loading-tematicas');
714          if ($loading.length) {
715
716              var $linha = $loading.closest(
717                  '.chat-message-row'
718              );
719
720              if ($linha.length) {
721                  $linha.remove();
722              } else {
723                  $loading.remove();
724              }
725          }
726      }
727
728      // ESTADO DE PROCESSAMENTO
729      function setProcessingState(processing) {
730          isProcessing = processing;
731          var $input = $('#chat-input');
732          var $btn = $('.chat-send-btn');
733          var $container = $('.chat-container');
734
735          if (processing) {
736
737              $input
738                  .prop('disabled', true)
739                  .attr(
740                      'placeholder',
741                      'Processando consulta...'
742                  );
743
744              $btn
745                  .prop('disabled', true)
746                  .html(
747                      '<i class="fa fa-spinner fa-spin"></i>'
748                  );
749
750              $container.addClass('processing-overlay');
751
752              $('.tema-btn').prop('disabled', true);
753              $('.btn-carregar-mais').prop('disabled', true);
754
755          } else {
756              $input
757                  .prop('disabled', false)
758                  .attr(
759                      'placeholder',
760                      'Digite uma informação para pesquisa...'
761                  );
762
763              $btn
764                  .prop('disabled', false)
765                  .html(
766                      '<i class="bi bi-send"></i>'
767                  );
768
769              $container.removeClass('processing-overlay');
770
771              $('.tema-btn').prop('disabled', false);
772              $('.btn-carregar-mais').prop('disabled', false);
773          }
774      }
775
776      // CARREGAR TEMÁTICAS DISPONÍVEIS
777      function carregarTematicas() {
778          $.ajax({
779              url: 'data_pesquisa_plus.php',
780              type: 'POST',
781              dataType: 'json',
782              data: {
783                  carregar_tematicas: true
784              },
785
786              success: function (resp) {
787
788                  tematicas = resp.tematicas || [];
789
790                  // Só remove o loading depois que as temáticas
791                  // realmente terminaram de carregar.
792                  removerLoadingTematicas();
793              },
794
795              error: function (e) {
796
797                  removerLoadingTematicas();
798
799                  $('#chat-messages').append(
800                      $('<div>', {
801                          'class': 'chat-aia ia chat-mensagem-erro'
802                      }).text(
803                          'Erro ao carregar temáticas: ' +
804                          e.statusText
805                      )
806                  );
807
808                  scrollToBottom();
809                  setProcessingState(false);
810              }
811          });
812      }
813
814      // Carregar temáticas ao iniciar
815      carregarTematicas();
816
817      // BUSCAR RESULTADOS DE UMA TEMÁTICA
818      function buscarResultadosTema(
819          temaId,
820          temaNome,
821          pagina,
822          callback
823      ) {
824          $.ajax({
825              url: 'data_pesquisa_plus.php',
826              type: 'POST',
827              dataType: 'json',
828              data: {
829                  busca: ultimaPergunta,
830                  pagina: pagina,
831                  tema: temaId
832              },
833
834              success: function (resp) {
835                  callback(resp);
836              },
837
838              error: function (e) {
839                  callback({
840                      erro: true,
841                      mensagem:
842                          'Erro ao buscar resultados: ' +
843                          e.statusText +
844                          ' (Status: ' +
845                          e.status +
846                          ')'
847                  });
848              }
849          });
850      }
851
852  
853     // EXIBIR RESULTADOS DA TEMÁTICA      
854      function exibirResultadosTema(
855          resp,
856          temaId,
857          temaNome
858      ) {
859
860          $('#ia-typing').remove();
861
862          if (resp.erro) {
863
864              $('#chat-messages').append(
865                  $('<div>', {
866                      'class': 'chat-aia ia chat-mensagem-erro'
867                  }).text(
868                      'Erro: ' + resp.mensagem
869                  )
870              );
871
872              scrollToBottom();
873              setProcessingState(false);
874              return;
875          }
876
877          var $linhaResposta = $('<div>', {
878              'class': 'chat-message-row chat-resultados-row'
879          });
880
881          var $icone = $('<span>', {
882              'class': 'chat-messages-span'
883          }).append(
884              $('<i>', {
885                  'class': 'bi bi-robot'
886              })
887          );
888
889          var $resposta = $('<div>', {
890              'class': 'chat-aia ia'
891          });
892
893          if (
894              resp.total_registros > 0 &&
895              resp.data &&
896              resp.data.length > 0
897          ) {
898
899              $resposta.append(
900                  $('<b>').text(
901                      'Encontrei ' +
902                      resp.total_registros +
903                      ' resultado' +
904                      (resp.total_registros > 1 ? 's' : '') +
905                      ' em ' +
906                      temaNome +
907                      ':'
908                  )
909              );
910
911              var $lista = $('<ul>', {
912                  'class': 'chat-resultados'
913              });
914
915              resp.data
916                  .slice(0, 5)
917                  .forEach(function (item, index) {
918                      $lista.append(
919                          montarResultado(item, index)
920                      );
921                  });
922
923              $resposta.append($lista);
924
925              if (resp.total_registros > 5) {
926
927                  var restantes =
928                      resp.total_registros - 5;
929
930                  var $wrapper = $('<p>', {
931                      'class': 'chat-carregar-mais-wrapper'
932                  });
933
934                  var $btnMais = $('<button>', {
935                      'type': 'button',
936                      'class': 'btn-carregar-mais',
937                      'id': 'carregar-mais-' + temaId,
938                      'data-tema': temaId,
939                      'data-pagina': 0,
940                      'data-total': resp.total_registros
941                  });
942                  
943
944                  $btnMais.html(
945                      '<i class="fa fa-plus"></i> ' +
946                      'Ver mais resultados (' +
947                      restantes +
948                      ' restantes)'
949                  );
950
951                  $wrapper.append($btnMais);
952                  $resposta.append($wrapper);
953              }
954
955          } else {
956              $resposta.text(
957                  resp.mensagem ||
958                  'Não encontrei resultados para sua pergunta em ' +
959                  temaNome +
960                  '.'
961              );
962          }
963
964          $linhaResposta
965              .append($icone)
966              .append($resposta);
967
968          $('#chat-messages').append(
969              $linhaResposta
970          );
971
972          scrollToBottom();
973          setProcessingState(false);
974      }
975
976      // FORMULÁRIO DE PESQUISA
977      $('#chat-form').on(
978          'submit',
979          function (e) {
980              e.preventDefault();
981
982              if (isProcessing) {
983                  return false;
984              }
985
986              var pergunta =
987                  $('#chat-input')
988                      .val()
989                      .trim();
990
991              if (!pergunta) {
992                  return;
993              }
994
995              setProcessingState(true);
996              ultimaPergunta = pergunta;
997
998              // Pergunta do usuário
999              $('#chat-messages').append(
1000                  $('<div>', {
1001                      'class': 'chat-aia user'
1002                  }).text(pergunta)
1003              );
1004
1005              $('#chat-input').val('');
1006              scrollToBottom();
1007
1008              // Loading da análise
1009              $('#chat-messages').append(
1010                  $('<div>', {
1011                      'class': 'chat-aia ia',
1012                      'id': 'analisando-msg'
1013                  }).html(
1014                      '<i class="fa fa-spinner fa-spin"></i> ' +
1015                      'Analisando...'
1016                  )
1017              );
1018
1019              scrollToBottom();
1020
1021              pesquisa++;
1022
1023              var opcoes = 0;
1024              var temOpcao = false;
1025              var primeiraTematicaId = null;
1026              var primeiraTematicaNome = null;
1027              var primeiraTematicaCarregada = false;
1028
1029
1030              // CONSULTAR QUANTIDADE DA TEMÁTICA
1031              function consultarTema(tema, callback) {
1032                  $.ajax({
1033                      url: 'data_pesquisa_plus.php',
1034                      type: 'POST',
1035                      dataType: 'json',
1036                      data: {
1037                          busca: pergunta,
1038                          pagina: 0,
1039                          tema: tema.id,
1040                          carregar_quantidade: true
1041                      },
1042                      success: function (temaResp) {
1043
1044                          if (
1045                              temaResp.tematicas
1046                          ) {
1047
1048                              var temaEncontrado =
1049                                  temaResp.tematicas.find(
1050                                      function (t) {
1051                                          return t.id === tema.id;
1052                                      }
1053                                  );
1054
1055                              if (
1056                                  temaEncontrado &&
1057                                  temaEncontrado.total > 0
1058                              ) {
1059                                  // Primeira temática encontrada
1060                                  if (opcoes === 0) {
1061
1062                                      primeiraTematicaId =
1063                                          tema.id;
1064
1065                                      primeiraTematicaNome =
1066                                          tema.nome;
1067
1068                                      var $linhaTematicas =
1069                                          $('<div>', {
1070                                              'class': 'chat-message-row'
1071                                          });
1072
1073                                      var $iconeTematicas =
1074                                          $('<span>', {
1075                                              'class': 'chat-messages-span'
1076                                          }).append(
1077                                              $('<i>', {
1078                                                  'class': 'bi bi-robot'
1079                                              })
1080                                          );
1081
1082                                      var $mensagemTematicas =
1083                                          $('<div>', {
1084                                              'class': 'chat-aia ia',
1085                                              'id': 'chat-messages-' + pesquisa
1086                                          });
1087
1088                                      $mensagemTematicas.append(
1089                                          $('<b>').text(
1090                                              'Selecione uma temática.'
1091                                          )
1092                                      );
1093
1094                                      // O spinner fica dentro do primeiro
1095                                      // balão enquanto as demais temáticas
1096                                      // ainda estão sendo consultadas.
1097                                      $mensagemTematicas.append(
1098                                          ' <i id="carregando-tema-' +
1099                                          pesquisa +
1100                                          '" class="fa fa-spinner fa-spin"></i>'
1101                                      );
1102
1103                                      $linhaTematicas
1104                                          .append($iconeTematicas)
1105                                          .append($mensagemTematicas);
1106
1107                                      $('#chat-messages').append(
1108                                          $linhaTematicas
1109                                      );
1110                                  }
1111
1112                                  opcoes++;
1113                                  temOpcao = true;
1114
1115                                  var $botaoTema =
1116                                      $('<button>', {
1117                                          'type': 'button',
1118                                          'class': 'tema-btn button-color-default',
1119                                          'data-tema': tema.id
1120                                      }).text(
1121                                          tema.nome +
1122                                          ' (' +
1123                                          temaEncontrado.total +
1124                                          ')'
1125                                      );
1126
1127                                  $('#chat-messages-' + pesquisa).append(
1128                                      $botaoTema
1129                                  );
1130
1131                                  $('#analisando-msg').remove();
1132
1133                                  scrollToBottom();
1134
1135                                  // A primeira temática abre automaticamente
1136                                  // os resultados enquanto as outras continuam
1137                                  // sendo carregadas.
1138                                  if (
1139                                      tema.id === primeiraTematicaId &&
1140                                      !primeiraTematicaCarregada
1141                                  ) {
1142
1143                                      primeiraTematicaCarregada = true;
1144
1145                                      $('.tema-btn').prop(
1146                                          'disabled',
1147                                          true
1148                                      );
1149
1150                                      $botaoTema.addClass(
1151                                          'tema-btn-selecionado'
1152                                      );
1153
1154                                      $('#chat-messages').append(
1155                                          $('<div>', {
1156                                              'class': 'chat-aia ia',
1157                                              'id': 'ia-typing'
1158                                          }).html(
1159                                              '<i class="fa fa-spinner fa-spin"></i> ' +
1160                                              'Analisando ' +
1161                                              tema.nome +
1162                                              '...'
1163                                          )
1164                                      );
1165
1166                                      scrollToBottom();
1167
1168                                      buscarResultadosTema(
1169                                          tema.id,
1170                                          tema.nome,
1171                                          0,
1172                                          function (resp) {
1173                                              exibirResultadosTema(
1174                                                  resp,
1175                                                  tema.id,
1176                                                  tema.nome
1177                                              );
1178                                          }
1179                                      );
1180                                  }
1181                              }
1182                          }
1183
1184                          if (callback) {
1185                              callback();
1186                          }
1187                      },
1188
1189                      error: function (e) {
1190                          console.log(
1191                              'Erro ao buscar dados da temática ' +
1192                              tema.nome +
1193                              ': ' +
1194                              e.statusText
1195                          );
1196
1197                          if (callback) {
1198                              callback();
1199                          }
1200                      }
1201                  });
1202              }
1203
1204              // PROCESSAR TODAS AS TEMÁTICAS
1205              // já inicia os resultados e as demais continuam carregando.
1206              function processarTematicaAtual(indice) {
1207                  if (indice >= tematicas.length) {
1208                      $('#analisando-msg').remove();
1209                      $('#carregando-tema-' + pesquisa).remove();
1210
1211                      if (!temOpcao) {
1212                          $('#chat-messages').append(
1213                              $('<div>', {
1214                                  'class': 'chat-aia ia'
1215                              }).text(
1216                                  'Nenhuma temática encontrada com resultados.'
1217                              )
1218                          );
1219
1220                          scrollToBottom();
1221                          setProcessingState(false);
1222                          return;
1223                      }
1224
1225                      // Se a primeira temática não foi carregada,
1226                      // liberar o processamento normalmente.
1227                      if (!primeiraTematicaCarregada) {
1228                          setProcessingState(false);
1229                      }
1230
1231                      return;
1232                  }
1233
1234                  consultarTema(
1235                      tematicas[indice],
1236                      function () {
1237                          setTimeout(
1238                              function () {
1239                                  processarTematicaAtual(indice + 1);
1240                              },
1241                              200
1242                          );
1243                      }
1244                  );
1245              }
1246
1247              processarTematicaAtual(0);
1248          }
1249      );
1250
1251      // ABRIR / FECHAR RESULTADOS
1252      $('#chat-messages').on(
1253          'click',
1254          '.chat-resultado-toggle',
1255          function (e) {
1256
1257              e.preventDefault();
1258              e.stopPropagation();
1259
1260              var $resultado = $(this).closest(
1261                  '.chat-resultado'
1262              );
1263
1264              $resultado.toggleClass('aberto');
1265          }
1266      );
1267
1268      // CLIQUE NAS TEMÁTICAS
1269      $('#chat-messages').on(
1270          'click',
1271          '.tema-btn',
1272          function () {
1273              if (isProcessing) {
1274                  return false;
1275              }
1276
1277              var $botao = $(this);
1278              var temaId = $botao.data('tema');
1279              var temaNome = $botao.text();
1280
1281              $('.tema-btn')
1282                  .removeClass('tema-btn-selecionado');
1283
1284              $botao.addClass(
1285                  'tema-btn-selecionado'
1286              );
1287
1288              setProcessingState(true);
1289
1290              $('#chat-messages').append(
1291                  $('<div>', {
1292                      'class': 'chat-aia ia',
1293                      'id': 'ia-typing'
1294                  }).html(
1295                      '<i class="fa fa-spinner fa-spin"></i> ' +
1296                      'Analisando ' +
1297                      temaNome +
1298                      '...'
1299                  )
1300              );
1301
1302              scrollToBottom();
1303
1304              buscarResultadosTema(
1305                  temaId,
1306                  temaNome,
1307                  0,
1308                  function (resp) {
1309                      exibirResultadosTema(
1310                          resp,
1311                          temaId,
1312                          temaNome
1313                      );
1314                  }
1315              );
1316          }
1317      );
1318
1319
1320      
1321        // VER MAIS RESULTADOS
1322            $('#chat-messages').on(
1323                'click',
1324                '[id^="carregar-mais-"]',
1325                function () {
1326
1327                    if (isProcessing) {
1328                        return false;
1329                    }
1330
1331                    var $btn = $(this);
1332
1333                    var temaId = $btn.data('tema');
1334
1335                    var pagina = parseInt(
1336                        $btn.data('pagina'),
1337                        10
1338                    );
1339
1340                    var totalRegistros = parseInt(
1341                        $btn.data('total'),
1342                        10
1343                    );
1344
1345                    setProcessingState(true);
1346
1347                    $btn
1348                        .html(
1349                            '<i class="fa fa-spinner fa-spin"></i> Carregando...'
1350                        )
1351                        .prop(
1352                            'disabled',
1353                            true
1354                        );
1355
1356                    buscarResultadosTema(
1357                        temaId,
1358                        '',
1359                        pagina,
1360                        function (resp) {
1361
1362                            if (resp.erro) {
1363
1364                                $('#chat-messages').append(
1365                                    $('<div>', {
1366                                        'class':
1367                                            'chat-aia ia chat-mensagem-erro'
1368                                    }).text(
1369                                        'Erro: ' +
1370                                        resp.mensagem
1371                                    )
1372                                );
1373                                scrollToBottom();
1374                                setProcessingState(false);
1375                                return;
1376                            }
1377
1378                            if (
1379                                resp.data &&
1380                                resp.data.length > 0
1381                            ) {
1382                                
1383                                var $lista =
1384                                    $btn
1385                                        .closest('.chat-aia')
1386                                        .find('.chat-resultados');
1387
1388
1389                                resp.data.forEach(
1390                                    function (item) {
1391
1392                                        $lista.append(
1393                                            montarResultado(
1394                                                item,
1395                                                999
1396                                            )
1397                                        );
1398
1399                                    }
1400                                );
1401
1402                                var totalMostrados =
1403                                    5 +
1404                                    ((pagina + 1) * 5);
1405
1406
1407                                var restantes =
1408                                    totalRegistros -
1409                                    totalMostrados;
1410
1411
1412                                if (restantes > 0) {
1413                                    $btn
1414                                        .data(
1415                                            'pagina',
1416                                            pagina + 1
1417                                        )
1418                                        .html(
1419                                            '<i class="fa fa-plus"></i> ' +
1420                                            'Ver mais resultados (' +
1421                                            restantes +
1422                                            ' restantes)'
1423                                        )
1424                                        .prop(
1425                                            'disabled',
1426                                            false
1427                                        );
1428
1429                                } else {
1430                                    $btn.remove();
1431
1432                                }
1433
1434                            } else {
1435                                $btn.remove();
1436                            }
1437
1438                            scrollToBottom();
1439
1440                            setProcessingState(false);
1441
1442                        }
1443                    );
1444                }
1445            );
1446        });
1447// FIM PESQUISA

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.