1const cabecalho = document.querySelector("#cabecalho"); 2const menu = document.querySelector("#menu-principal"); 3const botaoMenu = document.querySelector(".menu-botao"); 4const elementosAnimados = document.querySelectorAll(".animar"); 5const secaoHero = document.querySelector("#inicio"); 6const secaoSuite = document.querySelector("#suite"); 7const secaoCateyes = document.querySelector("#cateyes"); 8const secaoMaestro = document.querySelector("#nct-maestro"); 9const rodape = document.querySelector("#contato"); 10const linksMenu = document.querySelectorAll(".menu a[href^='#']"); 11const secoesNavegacao = Array.from(linksMenu) 12 .map((link) => document.querySelector(link.getAttribute("href"))) 13 .filter(Boolean); 14const menuContexto = document.createElement("div"); 15let alvoContexto = null; 16const catEyesLojas = Object.freeze({ 17 chrome: "https://chromewebstore.google.com/detail/cat-eyes/abhlihknahkcmopioedcnimnfnifgcon?authuser=2&hl=pt-BR", 18 firefox: "https://addons.mozilla.org/pt-BR/firefox/addon/cateyes-netcattest/", 19}); 20 21document.body.classList.add("animacoes-ativas"); 22 23function dadosNavegadorCateyes() { 24 const agente = navigator.userAgent.toLowerCase(); 25 const firefox = agente.includes("firefox") || agente.includes("fxios"); 26 const edge = agente.includes("edg/") || agente.includes("edgios") || agente.includes("edga"); 27 const opera = agente.includes("opr/") || agente.includes("opera"); 28 const brave = agente.includes("brave") || Boolean(navigator.brave); 29 const vivaldi = agente.includes("vivaldi"); 30 const yandex = agente.includes("yabrowser"); 31 const chromium = agente.includes("chromium"); 32 33 if (firefox) { 34 return { 35 navegador: "firefox", 36 loja: "firefox", 37 rotulo: "Adicionar ao Firefox", 38 url: catEyesLojas.firefox, 39 }; 40 } 41 42 return { 43 navegador: edge ? "edge" : opera ? "opera" : brave ? "brave" : vivaldi ? "vivaldi" : yandex ? "yandex" : chromium ? "chromium" : "chrome", 44 loja: "chrome", 45 rotulo: edge ? "Adicionar ao Edge" : opera ? "Adicionar ao Opera" : brave ? "Adicionar ao Brave" : vivaldi ? "Adicionar ao Vivaldi" : yandex ? "Adicionar ao Yandex" : chromium ? "Adicionar ao Chromium" : "Adicionar ao Chrome", 46 url: catEyesLojas.chrome, 47 }; 48} 49 50const cateyesBrowser = dadosNavegadorCateyes(); 51const linksTemaTopo = Array.from(document.querySelectorAll('.menu a[href="#suite"], .menu a[href="#cateyes"], .menu a[href="#nct-maestro"]')); 52 53document.querySelectorAll("[data-cateyes-add-browser]").forEach((botao) => { 54 botao.textContent = cateyesBrowser.rotulo; 55 botao.setAttribute("aria-label", cateyesBrowser.rotulo); 56 botao.setAttribute("href", cateyesBrowser.url); 57 botao.setAttribute("target", "_blank"); 58 botao.setAttribute("rel", "noopener noreferrer"); 59}); 60 61console.log( 62 "%cNETCAT TEST%c Cat Suite gratuito", 63 "color:#38e8ff;background:#03050b;font-size:34px;font-weight:900;letter-spacing:3px;padding:10px 14px;border:1px solid #38e8ff;border-radius:6px 0 0 6px;text-shadow:0 0 12px rgba(56,232,255,.8);", 64 "color:#050505;background:#fff200;font-size:14px;font-weight:900;padding:17px 14px;border:1px solid #38e8ff;border-left:0;border-radius:0 6px 6px 0;", 65); 66console.log("Cat Suite: sem cobrança, feito para estudo e testes autorizados em ambientes próprios."); 67console.log("NCT Maestro: plataforma C2 em desenvolvimento, lançamento em breve."); 68 69function atualizarCabecalho() { 70 if (!cabecalho) { 71 return; 72 } 73 74 cabecalho.classList.toggle("ativo", window.scrollY > 40); 75 76 const alturaJanela = window.innerHeight; 77 const heroAltura = secaoHero ? secaoHero.offsetHeight : 0; 78 const ocultarNoHero = window.scrollY < heroAltura * 0.55; 79 const ocultarNoRodape = rodape ? rodape.getBoundingClientRect().top < alturaJanela * 0.72 : false; 80 const suiteRect = secaoSuite ? secaoSuite.getBoundingClientRect() : null; 81 const cateyesRect = secaoCateyes ? secaoCateyes.getBoundingClientRect() : null; 82 const maestroRect = secaoMaestro ? secaoMaestro.getBoundingClientRect() : null; 83 const suiteAtiva = suiteRect 84 ? suiteRect.top < alturaJanela * 0.58 && suiteRect.bottom > alturaJanela * 0.36 85 : false;
86 const cateyesAtiva = cateyesRect 87 ? cateyesRect.top < alturaJanela * 0.58 && cateyesRect.bottom > alturaJanela * 0.36 88 : false; 89 const maestroAtiva = maestroRect 90 ? maestroRect.top < alturaJanela * 0.58 && maestroRect.bottom > alturaJanela * 0.36 91 : false; 92 93 document.body.classList.toggle("nav-oculta", ocultarNoHero || ocultarNoRodape); 94 document.body.classList.toggle("suite-ativa", suiteAtiva); 95 document.body.classList.toggle("cateyes-ativa", cateyesAtiva); 96 document.body.classList.toggle("nct-maestro-ativa", maestroAtiva); 97 document.documentElement.classList.toggle("suite-ativa", suiteAtiva); 98 document.documentElement.classList.toggle("cateyes-ativa", cateyesAtiva); 99 document.documentElement.classList.toggle("nct-maestro-ativa", maestroAtiva); 100} 101 102function fecharMenu() { 103 document.body.classList.remove("menu-aberto"); 104 105 if (menu) { 106 menu.classList.remove("aberto"); 107 } 108 109 if (botaoMenu) { 110 botaoMenu.setAttribute("aria-expanded", "false"); 111 } 112} 113 114function centralizarItemDock(link) { 115 if (!menu || !link || !window.matchMedia("(max-width: 1020px)").matches) { 116 return; 117 } 118 119 link.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" }); 120} 121 122window.addEventListener("scroll", atualizarCabecalho); 123window.addEventListener("resize", atualizarCabecalho); 124atualizarCabecalho(); 125requestAnimationFrame(() => { 126 document.body.classList.remove("nav-sem-transicao"); 127}); 128 129linksTemaTopo.forEach((link) => { 130 const href = link.getAttribute("href"); 131 const tema = href === "#suite" ? "suite" : href === "#cateyes" ? "cateyes" : "nct-maestro"; 132 const classe = `nav-preview-${tema}`; 133 const ativarTema = () => { 134 document.body.classList.add(classe); 135 document.documentElement.classList.add(classe); 136 }; 137 const removerTema = () => { 138 document.body.classList.remove(classe); 139 document.documentElement.classList.remove(classe); 140 }; 141 142 link.addEventListener("mouseenter", ativarTema); 143 link.addEventListener("focus", ativarTema); 144 link.addEventListener("mouseleave", removerTema); 145 link.addEventListener("blur", removerTema); 146}); 147 148if (botaoMenu) { 149 botaoMenu.addEventListener("click", () => { 150 const aberto = menu.classList.toggle("aberto"); 151 document.body.classList.toggle("menu-aberto", aberto); 152 botaoMenu.setAttribute("aria-expanded", String(aberto)); 153 }); 154} 155 156document.querySelectorAll('a[href^="#"]').forEach((link) => { 157 link.addEventListener("click", (evento) => { 158 const destino = document.querySelector(link.getAttribute("href")); 159 160 if (!destino) { 161 return; 162 } 163 164 evento.preventDefault(); 165 fecharMenu(); 166 centralizarItemDock(link); 167 destino.scrollIntoView({ behavior: "smooth", block: "start" }); 168 }); 169}); 170 171function revelarElementosNoViewport(observador = null) { 172 const topoVisivel = window.innerHeight * 0.08; 173 const limiteEntrada = window.innerHeight * 0.86; 174 175 elementosAnimados.forEach((elemento) => { 176 if (elemento.classList.contains("visivel")) { 177 return; 178 } 179 180 const retangulo = elemento.getBoundingClientRect(); 181 const estaNaAreaDeRevelacao = retangulo.top < limiteEntrada && retangulo.bottom > topoVisivel; 182 183 if (!estaNaAreaDeRevelacao) { 184 return; 185 } 186 187 elemento.classList.add("visivel"); 188 189 if (observador) { 190 observador.unobserve(elemento); 191 } 192 }); 193} 194 195if ("IntersectionObserver" in window) { 196 const observador = new IntersectionObserver((entradas) => { 197 entradas.forEach((entrada) => { 198 if (entrada.isIntersecting) { 199 entrada.target.classList.add("visivel"); 200 observador.unobserve(entrada.target); 201 } 202 }); 203 }, { threshold: 0.18 }); 204 205 elementosAnimados.forEach((elemento) => observador.observe(elemento)); 206 207 window.addEventListener("scroll", () => revelarElementosNoViewport(observador), { passive: true }); 208 window.addEventListener("resize", () => revelarElementosNoViewport(observador)); 209 window.setTimeout(() => revelarElementosNoViewport(observador), 300); 210 211 if (secoesNavegacao.length) { 212 const observadorNavegacao = new IntersectionObserver((entradas) => { 213 entradas.forEach((entrada) => { 214 if (!entrada.isIntersecting) { 215 return; 216 } 217 218 linksMenu.forEach((link) => { 219 link.classList.toggle("link-ativo", link.getAttribute("href") === `#${entrada.target.id}`); 220 }); 221 centralizarItemDock(document.querySelector(`.menu a[href="#${entrada.target.id}"]`)); 222 }); 223 }, { rootMargin: "-40% 0px -48% 0px", threshold: 0 }); 224
225 secoesNavegacao.forEach((secao) => observadorNavegacao.observe(secao)); 226 } 227} else { 228 elementosAnimados.forEach((elemento) => elemento.classList.add("visivel")); 229} 230 231menuContexto.className = "menu-contexto"; 232menuContexto.setAttribute("role", "menu"); 233menuContexto.setAttribute("aria-hidden", "true"); 234document.body.appendChild(menuContexto); 235 236function ocultarMenuContexto() { 237 menuContexto.classList.remove("ativo"); 238 menuContexto.classList.remove("menu-contexto--suite"); 239 menuContexto.classList.remove("menu-contexto--cateyes"); 240 menuContexto.classList.remove("menu-contexto--maestro"); 241 menuContexto.setAttribute("aria-hidden", "true"); 242 alvoContexto = null; 243} 244 245function criarItemContexto(rotulo, acao) { 246 const botao = document.createElement("button"); 247 botao.type = "button"; 248 botao.textContent = rotulo; 249 botao.dataset.contextoAcao = acao; 250 botao.setAttribute("role", "menuitem"); 251 252 return botao; 253} 254 255function criarSeparadorContexto() { 256 const separador = document.createElement("span"); 257 separador.className = "menu-contexto__separador"; 258 separador.setAttribute("aria-hidden", "true"); 259 260 return separador; 261} 262 263function posicionarMenuContexto(evento) { 264 const margem = 10; 265 const retangulo = menuContexto.getBoundingClientRect(); 266 const esquerda = Math.min(evento.clientX, window.innerWidth - retangulo.width - margem); 267 const topo = Math.min(evento.clientY, window.innerHeight - retangulo.height - margem); 268 269 menuContexto.style.left = `${Math.max(margem, esquerda)}px`; 270 menuContexto.style.top = `${Math.max(margem, topo)}px`; 271} 272 273function mostrarMenuContexto(evento) { 274 const link = evento.target.closest("a[href]"); 275 const imagem = evento.target.closest("img"); 276 const suite = evento.target.closest("#suite, .secao--suite"); 277 const cateyes = evento.target.closest("#cateyes, .secao--cateyes"); 278 const maestro = evento.target.closest("#nct-maestro, .secao--maestro"); 279 const secoes = [ 280 ["InÃcio", "#inicio"], 281 ["Manual", "#manual"], 282 ["Aulas", "#videoaulas"], 283 ["Cat Suite", "#suite"], 284 ["Redes", "#redes"], 285 ["Blog", "#blog"], 286 ["Cat Eyes", "#cateyes"], 287 ["NCT Maestro", "#nct-maestro"], 288 ]; 289 290 evento.preventDefault(); 291 alvoContexto = { link, imagem, suite, cateyes, maestro }; 292 menuContexto.replaceChildren(); 293 menuContexto.classList.toggle("menu-contexto--suite", Boolean(suite)); 294 menuContexto.classList.toggle("menu-contexto--cateyes", Boolean(cateyes)); 295 menuContexto.classList.toggle("menu-contexto--maestro", Boolean(maestro)); 296 297 if (link) { 298 menuContexto.append( 299 criarItemContexto("Abrir link", "abrir-link"), 300 criarItemContexto("Copiar link", "copiar-link"), 301 criarSeparadorContexto(), 302 ); 303 } 304 305 if (imagem) { 306 menuContexto.append( 307 criarItemContexto("Abrir imagem", "abrir-imagem"), 308 criarItemContexto("Copiar URL da imagem", "copiar-imagem"), 309 criarSeparadorContexto(), 310 ); 311 } 312 313 if (maestro) { 314 menuContexto.append( 315 criarItemContexto("NCT Maestro", "maestro-topo"), 316 criarItemContexto("Abrir página dedicada", "abrir-maestro"), 317 criarItemContexto("Copiar seção Maestro", "copiar-maestro"), 318 criarSeparadorContexto(), 319 criarItemContexto("Ver arquitetura", "abrir-maestro-arquitetura"), 320 criarItemContexto("Disponibilidade", "maestro-em-breve"), 321 ); 322 } else if (cateyes) { 323 menuContexto.append( 324 criarItemContexto("Cat Eyes", "cateyes-topo"), 325 criarItemContexto(cateyesBrowser.rotulo, "cateyes-download"), 326 criarItemContexto("Copiar seção Cat Eyes", "copiar-cateyes"), 327 criarSeparadorContexto(), 328 criarItemContexto("Privacidade Cat Eyes", "abrir-cateyes-privacidade"), 329 criarItemContexto("Suporte Cat Eyes", "abrir-cateyes-suporte"), 330 ); 331 } else if (suite) { 332 menuContexto.append( 333 criarItemContexto("Cat Suite", "suite-topo"), 334 criarItemContexto("Download Play Store", "suite-download"), 335 criarItemContexto("Copiar seção Cat Suite", "copiar-suite"), 336 criarSeparadorContexto(), 337 criarItemContexto("Ver manual gratuito", "abrir-manual"), 338 criarItemContexto("Ver videoaulas", "abrir-aulas"), 339 ); 340 } else {
341 secoes.forEach(([rotulo, destino]) => { 342 const item = criarItemContexto(rotulo, "ir-secao"); 343 item.dataset.destino = destino; 344 menuContexto.appendChild(item); 345 }); 346 } 347 348 menuContexto.append( 349 criarSeparadorContexto(), 350 criarItemContexto("Recarregar", "recarregar"), 351 criarItemContexto("Copiar endereço da página", "copiar-pagina"), 352 ); 353 354 menuContexto.classList.add("ativo"); 355 menuContexto.setAttribute("aria-hidden", "false"); 356 posicionarMenuContexto(evento); 357} 358 359async function copiarTexto(texto) { 360 if (!texto) { 361 return; 362 } 363 364 try { 365 await navigator.clipboard.writeText(texto); 366 } catch (erro) { 367 const campo = document.createElement("textarea"); 368 campo.value = texto; 369 campo.style.position = "fixed"; 370 campo.style.opacity = "0"; 371 document.body.appendChild(campo); 372 campo.select(); 373 document.execCommand("copy"); 374 campo.remove(); 375 } 376} 377 378menuContexto.addEventListener("click", (evento) => { 379 const item = evento.target.closest("[data-contexto-acao]"); 380 381 if (!item) { 382 return; 383 } 384 385 const acao = item.dataset.contextoAcao; 386 const linkHref = alvoContexto?.link?.href; 387 const imagemSrc = alvoContexto?.imagem?.currentSrc || alvoContexto?.imagem?.src; 388 389 if (acao === "abrir-link" && linkHref) { 390 window.location.href = linkHref; 391 } 392 393 if (acao === "copiar-link" && linkHref) { 394 copiarTexto(linkHref); 395 } 396 397 if (acao === "abrir-imagem" && imagemSrc) { 398 window.open(imagemSrc, "_blank", "noopener"); 399 } 400 401 if (acao === "copiar-imagem" && imagemSrc) { 402 copiarTexto(imagemSrc); 403 } 404 405 if (acao === "ir-secao") { 406 const destino = document.querySelector(item.dataset.destino); 407 408 if (destino) { 409 fecharMenu(); 410 destino.scrollIntoView({ behavior: "smooth", block: "start" }); 411 } 412 } 413 414 if (acao === "recarregar") { 415 window.location.reload(); 416 } 417 418 if (acao === "copiar-pagina") { 419 copiarTexto(window.location.href); 420 } 421 422 if (acao === "suite-topo") { 423 document.querySelector("#suite")?.scrollIntoView({ behavior: "smooth", block: "start" }); 424 } 425 426 if (acao === "suite-download") { 427 document.querySelector(".suite__download")?.click(); 428 } 429 430 if (acao === "copiar-suite") { 431 copiarTexto(`${window.location.origin}${window.location.pathname}#suite`); 432 } 433 434 if (acao === "abrir-manual") { 435 window.location.href = "/livro/manual-de-operacoes-anonimas"; 436 } 437 438 if (acao === "abrir-aulas") { 439 window.location.href = "/aulas"; 440 } 441 442 if (acao === "cateyes-topo") { 443 document.querySelector("#cateyes")?.scrollIntoView({ behavior: "smooth", block: "start" }); 444 } 445 446 if (acao === "cateyes-download") { 447 window.location.href = cateyesBrowser.url; 448 } 449 450 if (acao === "copiar-cateyes") { 451 copiarTexto(`${window.location.origin}${window.location.pathname}#cateyes`); 452 } 453 454 if (acao === "abrir-cateyes-privacidade") { 455 window.location.href = "/cateyes/privacidade"; 456 } 457 458 if (acao === "abrir-cateyes-suporte") { 459 window.location.href = "/cateyes/suporte"; 460 } 461 462 if (acao === "maestro-topo") { 463 document.querySelector("#nct-maestro")?.scrollIntoView({ behavior: "smooth", block: "start" }); 464 } 465 466 if (acao === "abrir-maestro") { 467 window.location.href = "/nct-maestro"; 468 } 469 470 if (acao === "copiar-maestro") { 471 copiarTexto(`${window.location.origin}${window.location.pathname}#nct-maestro`); 472 } 473 474 if (acao === "abrir-maestro-arquitetura") { 475 window.location.href = "/nct-maestro#arquitetura"; 476 } 477 478 if (acao === "maestro-em-breve") { 479 copiarTexto("NCT Maestro sera disponibilizado em breve."); 480 } 481 482 ocultarMenuContexto(); 483}); 484 485document.addEventListener("contextmenu", mostrarMenuContexto); 486document.addEventListener("click", ocultarMenuContexto); 487window.addEventListener("blur", ocultarMenuContexto); 488window.addEventListener("resize", ocultarMenuContexto); 489window.addEventListener("scroll", ocultarMenuContexto, { passive: true }); 490window.addEventListener("keydown", (evento) => { 491 if (evento.key === "Escape") { 492 ocultarMenuContexto(); 493 } 494});
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.