1/* ORION tanıtım sitesi â ortak sayfa betiÄi. 2 index.html ve ürün sayfaları paylaÅır. Sayfaya özel parçalar 3 (sekmeler, senaryolar, çerçeve içi hareket, akıŠÅeridi) ilgili 4 eleman yoksa kendiliÄinden atlanıyor. */ 5(function () { 6 "use strict"; 7 var reduced = matchMedia("(prefers-reduced-motion: reduce)").matches; 8 if (!window.gsap) { document.documentElement.className = "no-js"; return; } 9 10 /* ââ ilerleme çubuÄu ââ */ 11 var prog = document.getElementById("prog"); 12 addEventListener("scroll", function () { 13 var h = document.documentElement.scrollHeight - innerHeight; 14 prog.style.width = (h > 0 ? (scrollY / h) * 100 : 0) + "%"; 15 }, { passive: true }); 16 17 18 /* menüdeki ıÅık imleci izlesin */ 19 var navIn = document.querySelector(".nav-in"); 20 if (navIn) { 21 navIn.addEventListener("pointermove", function (e) { 22 var r = navIn.getBoundingClientRect(); 23 navIn.style.setProperty("--mx", (e.clientX - r.left) + "px"); 24 navIn.style.setProperty("--my", (e.clientY - r.top) + "px"); 25 }); 26 } 27 28 29 /* ââ sekme baÅlıÄı: "ORION" sabit, saÄı dönüyor ââââââââââââââââââ 30 Cümleler sözlükte ZATEN olan anahtarlardan seçildi; böylece dil 31 deÄiÅince baÅlık da kendiliÄinden çevriliyor, ayrıca çeviri 32 yazmak gerekmiyor. */ 33 /* â ï¸ YALNIZCA ANA SAYFADA. Bu blok eskiden HER sayfada calisiyordu ve 34 document.title'i eziyordu: sekiz sayfanin sekizi de JS calistiktan 35 sonra "ORION â Yonetilen yayin." oluyordu (olculdu 2026-08-17). 36 37 Googlebot JavaScript'i CALISTIRIYOR. Yani arama motoru sekiz ayri 38 sayfayi ayni, sayfayla ilgisiz basligla goruyordu â baslik hem en 39 guclu sayfa-ici siralama sinyali hem de sonuc listesinde gorunen 40 metin. Urun ve arac sayfalarinin kendi basliklari hic sayilmiyordu. 41 42 Ic sayfalarda bayrak false kaldigi icin i18n baslıÄı devralir ve 43 sayfanin KENDI basligini dile cevirir (bkz. i18n.js, ic sayfa dali). */ 44 var ANA_SAYFA = location.pathname === "/" || location.pathname === "/index"; 45 if (ANA_SAYFA) { 46 var BASLIKLAR = [ 47 "KanıtlanmıŠmoderasyon.", 48 "Yönetilen yayın.", 49 "Sohbeti kim izliyor?", 50 "Yedi araç." 51 ]; 52 window.__orionTitleAnim = true; /* i18n baÅlıÄı ezmesin */ 53 (function () { 54 var i = 0; 55 function tik() { 56 var T = window.ORION_T || function (x) { return x; }; 57 document.title = "ORION â " + T(BASLIKLAR[i]); 58 i = (i + 1) % BASLIKLAR.length; 59 } 60 tik(); 61 if (!reduced) setInterval(tik, 3200); 62 })(); 63 } 64 65 /* ââ menü geçiÅleri âââââââââââââââââââââââââââââââââââââââââââââââ 66 Ãç parça: (1) altta kayan gösterge, (2) tıklayınca yumuÅatılmıŠ67 kaydırma, (3) varılan bölümün baÅlıÄının yeniden açılması. 68 69 â ï¸ GSAP'ın ScrollTo eklentisi YOK ve gerekmiyor: bir vekil nesnenin 70 `y` deÄerini tween'leyip her karede scrollTo çaÄırmak aynı iÅi 71 görüyor, fazladan dosya yüklemiyoruz. 72 â ï¸ CSS'teki `scroll-behavior:smooth` bu sırada KAPATILMALI, yoksa 73 her scrollTo çaÄrısı kendi baÅına yumuÅamaya çalıÅıp titriyor. */ 74 var navLinks = [].slice.call(document.querySelectorAll(".nav-links a")); 75 var navInd = document.getElementById("navInd"); 76 var NAV_H = 92; /* yüzen menünün kapladıÄı yükseklik */ 77 var scrolling = false; 78 79 function sectionOf(a) { 80 var id = (a.getAttribute("href") || "").slice(1); 81 return id ? document.getElementById(id) : null; 82 } 83 84 function moveInd(a) { 85 if (!navInd) return; 86 if (!a) { navInd.style.opacity = 0; return; } 87 var p = a.parentElement.getBoundingClientRect(), r = a.getBoundingClientRect(); 88 navInd.style.opacity = 1; 89 if (window.gsap && !reduced) { 90 gsap.to(navInd, { left: r.left - p.left, width: r.width, 91 duration: .45, ease: "power3.out" }); 92 } else { 93 navInd.style.left = (r.left - p.left) + "px"; 94 navInd.style.width = r.width + "px"; 95 } 96 } 97 98 function syncNav() { 99 if (scrolling) return; /* tıklama sırasında karıÅmasın */
100 var mid = innerHeight * 0.42, active = null; 101 navLinks.forEach(function (a) { 102 var el = sectionOf(a); if (!el) return; 103 var r = el.getBoundingClientRect(); 104 if (r.top <= mid && r.bottom >= mid) active = a; 105 }); 106 navLinks.forEach(function (a) { a.classList.toggle("on", a === active); }); 107 moveInd(active); 108 } 109 addEventListener("scroll", syncNav, { passive: true }); 110 addEventListener("resize", syncNav); 111 112 /* varılan bölümün baÅlıÄını bir kez daha aç â geldiÄin yer belli olsun */ 113 function replayHead(el) { 114 if (!el || !window.gsap || reduced) return; 115 var lines = el.querySelectorAll("h2 .ln > span"); 116 if (!lines.length) return; 117 gsap.fromTo(lines, 118 { yPercent: 135, filter: "blur(7px)" }, 119 { yPercent: 0, filter: "blur(0px)", duration: .8, stagger: .07, ease: "power3.out" }); 120 } 121 122 function goTo(el, link) { 123 if (!el) return; 124 var y = Math.max(0, el.getBoundingClientRect().top + scrollY - NAV_H); 125 navLinks.forEach(function (a) { a.classList.toggle("on", a === link); }); 126 moveInd(link); 127 128 if (!window.gsap || reduced) { scrollTo(0, y); replayHead(el); return; } 129 130 scrolling = true; 131 var o = { y: scrollY }; 132 gsap.to(o, { 133 y: y, duration: Math.min(1.15, 0.35 + Math.abs(y - scrollY) / 2600), 134 ease: "power2.inOut", 135 onUpdate: function () { scrollTo(0, o.y); }, 136 onComplete: function () { scrolling = false; replayHead(el); syncNav(); } 137 }); 138 } 139 140 if (window.gsap && !reduced) document.documentElement.classList.add("js-scroll"); 141 142 [].slice.call(document.querySelectorAll('a[href^="#"]')).forEach(function (a) { 143 var href = a.getAttribute("href"); 144 if (!href || href === "#") return; 145 a.addEventListener("click", function (e) { 146 var el = document.getElementById(href.slice(1)); 147 if (!el) return; 148 e.preventDefault(); 149 goTo(el, navLinks.indexOf(a) > -1 ? a : null); 150 history.replaceState(null, "", href); 151 }); 152 }); 153 154 addEventListener("load", syncNav); 155 setTimeout(syncNav, 300); 156 157 if (!reduced) { 158 gsap.registerPlugin(ScrollTrigger); 159 160 /* â ï¸ BaÅlangıcı GSAP'a kurdur â CSS'teki translateY(%) GSAP tarafından 161 piksel olarak okunuyor, sonra yPercent:0 onu yerinde bırakıyor. */ 162 gsap.set(".ln > span", { y: 0, yPercent: 135, filter: "blur(7px)" }); 163 gsap.set(".fade", { opacity: 0, y: 18 }); 164 165 document.querySelectorAll("h1, h2").forEach(function (h) { 166 var l = h.querySelectorAll(".ln > span"); 167 if (!l.length) return; 168 gsap.to(l, { 169 yPercent: 0, filter: "blur(0px)", duration: 0.95, stagger: 0.08, 170 ease: "power3.out", 171 scrollTrigger: { trigger: h, start: "top 82%", once: true } 172 }); 173 }); 174 175 /* â ï¸ `clearProps` ÅART â yoksa hover/basma efektleri SESSİZCE ÃLÃR. 176 GSAP animasyon boyunca öÄeye satır içi stil yazıyor ve `once: true` 177 olduÄu için bitince orada bırakıyordu: 178 179 translate: none; rotate: none; scale: none; 180 transform: translate(0px, 0px); 181 182 Satır içi stil her stylesheet kuralını ezer. Sonuç: `.extbar:hover 183 {transform:translateY(-2px)}` gibi kurallar hiç çalıÅmıyordu â CDP ile 184 hover'ı zorlayıp ölçtüm, hiçbir Åey olmuyordu. Yani sitenin kendi 185 hover efektleri `.fade` taÅıyan her öÄede ölüydü. 186 187 Animasyon bitince transform ailesini temizliyoruz; `opacity` satır içi 188 kalıyor (görünürlüÄü o taÅıyor). `.fade`in CSS'te transform'u yok, o 189 yüzden temizlemek öÄeyi doÄru yerinde bırakır. */ 190 gsap.utils.toArray(".fade").forEach(function (el) { 191 gsap.to(el, { 192 opacity: 1, y: 0, duration: 0.8, ease: "power3.out", 193 clearProps: "transform,translate,rotate,scale", 194 scrollTrigger: { trigger: el, start: "top 88%", once: true } 195 }); 196 }); 197 198 /* saÄ ray â kaydırdıkça aÅama ilerliyor */ 199 var rail = document.querySelectorAll(".rail div"); 200 ["#sorun", "#panel", "#urunler"].forEach(function (sel, i) { 201 var t = document.querySelector(sel); 202 if (!t) return; 203 ScrollTrigger.create({ 204 trigger: t, start: "top 60%", end: "bottom 40%", 205 onToggle: function (s) { 206 rail.forEach(function (d, j) { d.classList.toggle("on", s.isActive ? j === i : j === 0); }); 207 } 208 }); 209 }); 210 211 /* panel görsellerine hafif parallax */ 212 gsap.utils.toArray(".mock").forEach(function (img) { 213 gsap.fromTo(img, { yPercent: -1.6 }, { 214 yPercent: 1.6, ease: "none", 215 scrollTrigger: { trigger: img, start: "top bottom", end: "bottom top", scrub: true } 216 }); 217 }); 218 } else { 219 gsap.set(".ln > span", { yPercent: 0 }); 220 gsap.set(".fade", { opacity: 1, y: 0 }); 221 } 222 223 224 225 226 /* ââ akıŠÅeridi animasyonu ââââââââââââââââââââââââââââââââââââââ 227 Sinyal basamak basamak ilerliyor. Renk BEZEME DEÄİL, sıcaklık 228 eÄrisi â her basamak kararın ne kadar sertleÅtiÄini gösteriyor: 229 230 MESAJ çelik ham girdi, henüz hiçbir Åeye karar verilmedi 231 KURAL amber tartılıyor 232 KARAR turuncu karar sertleÅiyor 233 MÃDAHALE kızıl keskin uç (paletteki --crimson zaten "müdahale" 234 için ayrılmıÅtı; burada onun açık eÅi 235 --crimson-2 kullanılıyor, çünkü 12px mono 236 yazıda --crimson 4.4:1 ile AA eÅiÄinin altında 237 kalıyor â açık eÅi 6.2:1) 238 KAYIT mint oturdu, yazıldı 239 240 â ï¸ Renkler burada, CSS'te deÄil: baÄlayıcı çizgi iki komÅu basamak 241 arasında GEÃİŠyapıyor, yani her segmentin gradyanı kendi rengiyle 242 sonrakinin renginden kuruluyor. Tek yerde durmaları Åart. 243 â ï¸ Yalnızca bölüm görünürken çalıÅıyor; sayfanın altındayken boÅuna 244 kare harcamasın diye. */ 245 var AKIS_RENK = ["#7C9CC4", "#E3B341", "#F08B3C", "#FF4D68", "#5FD49B"]; 246 var AKIS_RGB = ["124,156,196", "227,179,65", "240,139,60", "255,77,104", "95,212,155"]; 247 248 var flow = document.getElementById("flow"); 249 if (flow && window.gsap && !reduced) { 250 var steps = [].slice.call(flow.querySelectorAll(".step")); 251 var SON = steps.length - 1; 252 /* son basamaktan fazla basamak varsa renkler baÅa dönsün, undefined olmasın */ 253 var renkAl = function (i) { return AKIS_RENK[i % AKIS_RENK.length]; }; 254 var rgbAl = function (i) { return AKIS_RGB[i % AKIS_RGB.length]; }; 255 256 /* Her segment kendi renginden sonrakine geçiyor. */ 257 steps.forEach(function (st, i) { 258 var fill = st.querySelector(".fill"); 259 if (fill && i < SON) { 260 fill.style.backgroundImage = "linear-gradient(90deg,rgba(" + rgbAl(i) + 261 ",.9),rgba(" + rgbAl(i + 1) + ",.9))"; 262 } 263 }); 264 265 var tl = gsap.timeline({ repeat: -1, repeatDelay: 1.1, paused: true }); 266 tl.set(steps.map(function (st) { return st.querySelector(".fill"); }), { scaleX: 0 }) 267 .set(steps.map(function (st) { return st.querySelector(".dot"); }), 268 { borderColor: "#26262F", backgroundColor: "#08080A", boxShadow: "
268none" }) 269 .set(steps.map(function (st) { return st.querySelector(".cap"); }), { color: "#8A8D97" }); 270 271 steps.forEach(function (st, i) { 272 var son = i === SON, renk = renkAl(i), rgb = rgbAl(i); 273 tl.to(st.querySelector(".dot"), { 274 borderColor: renk, 275 backgroundColor: son ? "rgba(" + rgb + ",.25)" : "#08080A", 276 boxShadow: "0 0 10px rgba(" + rgb + (son ? ",.55)" : ",.45)"), 277 duration: .28, ease: "power2.out" 278 }, i === 0 ? 0 : ">"); 279 tl.to(st.querySelector(".cap"), { color: renk, duration: .28 }, "<"); 280 if (!son) tl.to(st.querySelector(".fill"), { scaleX: 1, duration: .5, ease: "none" }); 281 }); 282 tl.to({}, { duration: 1.5 }); /* KAYIT'ta bekle */ 283 284 ScrollTrigger.create({ 285 trigger: flow, start: "top 90%", end: "bottom 10%", 286 onEnter: function () { tl.play(); }, 287 onEnterBack: function () { tl.play(); }, 288 onLeave: function () { tl.pause(); }, 289 onLeaveBack: function () { tl.pause(); } 290 }); 291 } else if (flow) { 292 /* Hareket kısıtlıysa Åerit tamamlanmıŠhâlde duruyor. Yoksa bütün 293 renk anlatımı kaybolur, beÅ gri nokta kalırdı. */ 294 [].slice.call(flow.querySelectorAll(".step")).forEach(function (st, i, hepsi) { 295 var renk = AKIS_RENK[i % AKIS_RENK.length]; 296 var rgb = AKIS_RGB[i % AKIS_RGB.length]; 297 var dot = st.querySelector(".dot"), fill = st.querySelector(".fill"); 298 if (dot) { 299 dot.style.borderColor = renk; 300 dot.style.boxShadow = "0 0 10px rgba(" + rgb + ",.4)"; 301 } 302 st.querySelector(".cap").style.color = renk; 303 if (fill && i < hepsi.length - 1) { 304 fill.style.backgroundImage = "linear-gradient(90deg,rgba(" + rgb + ",.9),rgba(" + 305 AKIS_RGB[(i + 1) % AKIS_RGB.length] + ",.9))"; 306 fill.style.transform = "scaleX(1)"; 307 } 308 }); 309 } 310 311 /* ââ çerçeve içi hareket âââââââââââââââââââââââââââââââââââââââââ 312 â ï¸ Yol uzunluÄu PİKSELDEN hesaplanıyor, yüzdeden deÄil: görüntü 313 yüzde tabanlı yükseklik almıyor (height:auto), yüzde kullanılsa 314 ekran geniÅliÄi deÄiÅince kayma miktarı yanlıŠoluyordu. */ 315 gsap.utils.toArray(".shotview").forEach(function (view) { 316 var img = view.querySelector("img"); 317 if (!img) return; 318 var tl = null; 319 320 function kur() { 321 if (tl) tl.kill(); 322 var vh = view.clientHeight, ih = img.clientHeight; 323 324 if (view.dataset.anim === "scroll") { 325 var yol = ih - vh; 326 if (yol < 40) return; /* kayacak yer yoksa hiç baÅlama */ 327 tl = gsap.timeline({ repeat: -1, defaults: { ease: "none" } }) 328 .set(img, { y: 0 }) 329 .to({}, { duration: 1.6 }) /* tepede bekle */ 330 .to(img, { y: -yol, duration: yol / 26 }) 331 .to({}, { duration: 1.6 }) /* dipte bekle */ 332 .to(img, { y: 0, duration: yol / 60 }); 333 } else { 334 var ptr = view.querySelector(".ptr"), rip = view.querySelector(".ripple"); 335 if (!ptr) return; 336 var hx = (+view.dataset.x / 100) * view.clientWidth; 337 var hy = (+view.dataset.y / 100) * vh; 338 /* yalnizca Kick butonuna git ve tikla */ 339 tl = gsap.timeline({ repeat: -1, repeatDelay: 1.4 }) 340 .set(ptr, { x: view.clientWidth * 0.18, y: vh * 0.88, opacity: 0, scale: 1 }) 341 .set(rip, { opacity: 0, scale: .3 }) 342 .to(ptr, { opacity: 1, duration: .35 }) 343 .to(ptr, { x: hx, y: hy, duration: 1.15, ease: "power2.inOut" }) 344 .to(ptr, { scale: .82, duration: .1, yoyo: true, repeat: 1 }) 345 .set(rip, { x: hx, y: hy, opacity: .9, scale: .3 }, "-=.15") 346 .to(rip, { scale: 1.6, opacity: 0, duration: .7, ease: "power2.out" }) 347 .to(ptr, { opacity: 0, duration: .45 }, "-=.3"); 348 } 349 } 350 351 if (img.complete) kur(); else img.addEventListener("load", kur); 352 var t; addEventListener("resize", function () { clearTimeout(t); t = setTimeout(kur, 220); }); 353 354 /* üzerine gelince dursun â bakmak isteyen baksın */ 355 view.addEventListener("pointerenter", function () { if (tl) tl.pause(); }); 356 view.addEventListener("pointerleave", function () { if (tl) tl.resume(); }); 357 }); 358 359 /* ââ kullanım senaryoları ââââââââââââââââââââââââââââââââââââââââ 360 Soldaki soru seçilince saÄdaki yanıt paneli deÄiÅiyor. Panelin 361 satırları da ORION_T'den geçiyor ki dil deÄiÅince çevrilsin. */ 362 var QA = [ 363 { t: "M4HO · susturma", r: [ 364 ["ok", "Kural", "tekrar eden mesaj · eÅik 3"],
365 ["", "Ãlçülen", "aynı mesaj 3 kez · 8 saniye içinde"], 366 ["warn", "Karar", "10 dk susturma"], 367 ["", "Uygulayan", "ORION · otomatik"], 368 ["ok", "Kayıt", "12:04 · gerekçesiyle yazıldı"] ] }, 369 { t: "KLP-0418 · klip", r: [ 370 ["", "Kaynak", "sohbet komutu · !klip"], 371 ["", "İsteyen", "tospik_fan"], 372 ["ok", "Süre", "0:32"], 373 ["ok", "Konum", "panel ⺠Klipler"], 374 ["", "Kayıt", "12:04 · panele kaydedildi"] ] }, 375 { t: "Heyliora · rol", r: [ 376 ["", "Sorulan", "Kick · abonelik durumu"], 377 ["warn", "Cevap", "abonelik sona ermiÅ"], 378 ["", "Karar", "rol geri alındı"], 379 ["ok", "Koruma", "cevap belirsiz olsaydı dokunulmazdı"], 380 ["ok", "Kayıt", "11:47 · Discord tarafına yazıldı"] ] }, 381 { t: "otomod eÅiÄi · deÄiÅiklik", r: [ 382 ["", "Ayar", "otomod eÅiÄi"], 383 ["", "Ãnceki", "3"], 384 ["warn", "Yeni", "5"], 385 ["ok", "DeÄiÅtiren", "tospik · yayıncı"], 386 ["ok", "Kayıt", "11:58 · panelden"] ] }, 387 { t: "uyarı kutusu · katman", r: [ 388 ["", "Katman", "uyarı kutusu"], 389 ["warn", "Durum", "OBS kaynaÄı yenilenmemiÅ"], 390 ["", "ORION", "katman yayında · veri akıyor"], 391 ["ok", "Ãözüm", "OBS ⺠kaynaÄı saÄ tık ⺠yenile"], 392 ["", "Kayıt", "son deÄiÅiklik 11:31"] ] } 393 ]; 394 395 var ansBody = document.getElementById("ansBody"), ansTitle = document.getElementById("ansTitle"); 396 if (ansBody) { 397 var qBtns = [].slice.call(document.querySelectorAll(".q")); 398 var TT = function (x) { return window.ORION_T ? window.ORION_T(x) : x; }; 399 var lastQ = 0; 400 window.__orionRepaintCases = function () { paintQ(lastQ); }; 401 402 function paintQ(i) { 403 var d = QA[i]; if (!d) return; 404 lastQ = i; 405 ansTitle.textContent = TT(d.t); 406 ansBody.innerHTML = d.r.map(function (x, k) { 407 return '<div class="arow ' + x[0] + '" style="animation-delay:' + (k * 45) + 'ms">' + 408 "<dt>" + TT(x[1]) + "</dt><dd>" + TT(x[2]) + "</dd></div>"; 409 }).join(""); 410 qBtns.forEach(function (b, j) { b.classList.toggle("on", j === i); }); 411 } 412 qBtns.forEach(function (b) { 413 b.addEventListener("click", function () { paintQ(+b.dataset.q); }); 414 }); 415 paintQ(0); 416 } 417 418 /* ââ panel sekmeleri âââââââââââââââââââââââââââââââââââââââââââââ 419 Soldaki liste gerçek sekme; saÄdaki içerik ona göre deÄiÅiyor. 420 Kullanıcı dokunmazsa kendi kendine ilerliyor, ilk tıklamada durur â 421 otomatik dönen bir Åeyi okumaya çalıÅmak sinir bozucu olurdu. */ 422 var TABS = { 423 /* â ï¸ Bu sekme ÃRNEK DEÄİL. `canli` bayraÄı olan sekmede satırlar 424 buradan çizilmiyor; dört Kick odasından gelen gerçek mesajlar tek 425 akıÅta birleÅiyor (assets/canli-sohbet.js â oda listesi orada). 426 Kanal adı bilerek hiçbir yerde yazmıyor: ziyaretçi tek bir "canlı 427 sohbet" görüyor, hangi odadan geldiÄini seçmesi gerekmiyor. 428 AÅaÄıdaki `r` yalnızca JavaScript kapalıyken görünen yedek. */ 429 sohbet: { t: "Canlı sohbet", c: "Kick · canlı akıÅ", canli: true, 430 f: "<b>Bu sekme örnek deÄil.</b> Mesajlar Kick'in herkese açık sohbet akıÅından, doÄrudan tarayıcına geliyor.", 431 r: [["g","Canlı sohbet için JavaScript gerekiyor.","â"]] }, 432 simdi: { t: "Son iki dakika", c: "Ãncelik · Durum · Kayıt", 433 f: "<b>Her satır kayıt altında.</b> Kimin, neden, ne zaman â sonradan sorulduÄunda aranmıyor.", 434 r: [["a","<b>M4HO</b> â tekrar eden mesaj · 10 dk susturuldu","Uygulandı"], 435 ["g","Klip <b>KLP-0418</b> alındı · 0:32 · panele kaydedildi","Hazır"], 436 ["g","Yeni abone <b>Heyliora</b> · Discord rolü açıldı","EÅlendi"], 437 ["g","Yeni abone <b>Noxgun</b> · Discord rolü açıldı","EÅlendi"],
438 ["r","BaÄlantı paylaÅımı <b>engellendi</b> · izin listesinde deÄil","Bekliyor"]] }, 439 mod: { t: "Moderasyon", c: "Bugün · son 24 saat", tip: "sayac", 440 f: "<b>Kurallar arka planda çalıÅır.</b> Sen yayına bakarken sohbet kendi kendine derleniyor.", 441 s: [["12","susturma"],["3","mesaj silme"],["1","kilit"]], 442 /* siddet: 1 hafif · 2 orta · 3 agir â soldaki cubuk buna gore doluyor */ 443 r: [[3,"Tekrar eden mesaj","M4HO susturuldu","10 dk"], 444 [2,"Yasaklı kelime","Beta mesajı silindi","Anlık"], 445 [1,"Yayıncı muafiyeti","tospik kurallardan muaf","Sürekli"], 446 [1,"Yayıncı muafiyeti","Armin kurallardan muaf","Sürekli"]] }, 447 klip: { t: "Klipler", c: "Son üç klip", tip: "kart", 448 f: "<b>Sohbetten komutla.</b> İzleyici <code>!klip</code> yazar, klip panele düÅer.", 449 k: [["KLP-0418","0:32","sohbet komutu","hazir","Hazır"], 450 ["KLP-0417","0:48","panelden","hazir","Hazır"], 451 ["KLP-0419","1:04","sohbet komutu","suruyor","İÅleniyor"]] }, 452 widget: { t: "Widget ve overlay", c: "OBS katmanları", tip: "katman", 453 f: "<b>OBS'te tek baÄlantı.</b> Katmanı panelden deÄiÅtir, yayında anında görünsün.", 454 w: [["Uyarı kutusu","abone · takip · bits",1], 455 ["Sohbet katmanı","son 12 mesaj",1], 456 ["Sadakat sayacı","puan tablosu",1], 457 ["Yayın hedefi","abone hedefi",0]] }, 458 kayit: { t: "Kayıt defteri", c: "Kim · Ne · Ne zaman", tip: "log", 459 f: "<b>SorulduÄunda aranmıyor.</b> Her eylem, uygulayanla birlikte yazılıyor.", 460 l: [["12:04","tospik","otomod eÅiÄini deÄiÅtirdi"], 461 ["12:04","ORION","M4HO susturdu · tekrar eden mesaj"], 462 ["12:03","Heyliora","Discord rolü açıldı · Kick aboneliÄi"], 463 ["11:58","Armin","yeni komut ekledi: !discord"]] } 464 }; 465 466 var rowsEl = document.getElementById("benchRows"); 467 if (rowsEl) { 468 var titleEl = document.getElementById("benchTitle"), 469 chipEl = document.getElementById("benchChip"), 470 footEl = document.getElementById("benchFoot"), 471 tabsEl = [].slice.call(document.querySelectorAll(".snav")), 472 auto, touched = false; 473 474 var lastKey = "simdi"; 475 /* Dil degisince sekme icerigi de yeniden cizilsin diye disari aciliyor */ 476 window.__orionRepaintTabs = function () { paint(lastKey); }; 477 478 function T(x) { return window.ORION_T ? window.ORION_T(x) : x; } 479 480 function paint(key) { 481 var d = TABS[key]; if (!d) return; 482 lastKey = key; 483 titleEl.textContent = T(d.t); 484 chipEl.textContent = T(d.c); 485 footEl.innerHTML = T(d.f); 486 487 /* BaÅka sekmeye geçilince sohbet kutusu bırakılıyor. Soket AÃIK 488 kalıyor ve mesajlar tamponda birikiyor â panel 3,6 saniyede bir 489 kendi kendine döndüÄü için kapatılsaydı canlı sohbet altı 490 sekmenin yalnızca birinde dinleniyor olurdu. BoÅuna akmasını 491 canli-sohbet.js'teki görünürlük sayacı engelliyor. */ 492 if (window.ORION_CANLI) window.ORION_CANLI.kapat(); 493 494 if (d.canli && window.ORION_CANLI) { 495 rowsEl.innerHTML = ""; 496 window.ORION_CANLI.ac(rowsEl); 497 } else if (d.tip === "sayac") { 498 rowsEl.innerHTML = 499 '<div class="sayaclar">' + d.s.map(function (x) { 500 return '<div><b>' + x[0] + '</b><span>' + T(x[1]) + '</span></div>'; 501 }).join("") + "</div>" + 502 d.r.map(function (x, i) { 503 return '<div class="mrow" style="animation-delay:' + (i * 45) + 'ms">' + 504 '<i class="sev sev' + x[0] + '"></i>' + 505 '<span class="kural">' + T(x[1]) + '</span>' + 506 '<span class="ey">' + T(x[2]) + '</span>' + 507 '<span class="st">' + T(x[3]) + '</span></div>'; 508 }).join(""); 509 } else if (d.tip === "kart") { 510 rowsEl.innerHTML = '<div class="klipler">' + d.k.map(function (x, i) { 511 return '<figure class="klip" style="animation-delay:' + (i * 60) + 'ms">' + 512 '<div class="onizleme"><span class="sure">' + x[1] + "</span></div>" + 513 '<figcaption><b>' + x[0] + "</b><span>" + T(x[2]) + "</span>" + 514 '<em class="' + x[3] + '">' + T(x[4]) + "</em></figcaption></figure>"; 515 }).join("") + "</div>"; 516 } else if (d.tip === "katman") { 517 rowsEl.innerHTML = d.w.map(function (x, i) { 518 return '<div class="katman' + (x[2] ? " acik" : "") + '" style="animation-delay:' + 519 (i * 45) + 'ms"><span class="anahtar" aria-hidden="true"><i></i></span>' + 520 '<span class="ad"><b>' + T(x[0]) + "</b><span>" + T(x[1]) + "</span></span>" + 521 '<span class="st">' + T(x[2] ? "Yayında" : "Kapalı") + "</span></div>"; 522 }).join(""); 523 } else if (d.tip === "log") { 524 rowsEl.innerHTML = '<div class="logdefter">
524' + d.l.map(function (x, i) { 525 return '<div class="lsatir" style="animation-delay:' + (i * 45) + 'ms">' + 526 '<span class="zaman">' + x[0] + '</span><span class="kim">' + x[1] + "</span>" + 527 '<span class="ne">' + T(x[2]) + "</span></div>"; 528 }).join("") + "</div>"; 529 } else { 530 rowsEl.innerHTML = d.r.map(function (x, i) { 531 return '<div class="row" style="animation-delay:' + (i * 45) + 'ms">' + 532 '<i class="' + x[0] + '"></i><span class="txt">' + T(x[1]) + '</span>' + 533 '<span class="st">' + T(x[2]) + '</span></div>'; 534 }).join(""); 535 } 536 tabsEl.forEach(function (b) { 537 var on = b.dataset.tab === key; 538 b.classList.toggle("on", on); 539 b.setAttribute("aria-selected", on ? "true" : "false"); 540 }); 541 } 542 543 tabsEl.forEach(function (b) { 544 b.addEventListener("click", function () { 545 touched = true; clearInterval(auto); paint(b.dataset.tab); 546 }); 547 }); 548 549 paint("simdi"); 550 if (!reduced) { 551 var keys = Object.keys(TABS), idx = 0; 552 auto = setInterval(function () { 553 if (touched) return clearInterval(auto); 554 idx = (idx + 1) % keys.length; 555 paint(keys[idx]); 556 }, 3600); 557 } 558 } 559 560 /* -- arka plan sahneleri --------------------------------------------- 561 TEK sabit canvas, TEK requestAnimationFrame dongusu. Yildizlar her 562 zaman cizilir; ustune bulundugun bolumun sahnesi biner. Sahneler 563 arasi gecis sert degil: her sahnenin kendi alfasi hedefine dogru 564 yumusakca kayiyor, boylece kaydirirken biri sonerken digeri doguyor. 565 566 !! Tek dongu olmasi onemli -- her bolume ayri canvas + ayri rAF 567 koymak bes paralel animasyon demekti, bosuna pil yakardi. */ 568 var c = document.getElementById("mesh"); 569 if (!c || reduced) return; 570 var g = c.getContext("2d"), W, H, dpr = Math.min(devicePixelRatio || 1, 2), tick = 0; 571 572 function rnd(a, b) { return a + Math.random() * (b - a); } 573 function line(a, b, col, al) { 574 g.strokeStyle = "rgba(" + col + "," + al + ")"; 575 g.beginPath(); g.moveTo(a[0], a[1]); g.lineTo(b[0], b[1]); g.stroke(); 576 } 577 578 /* -- yildizlar: her sahnede acik -- */ 579 var stars = []; 580 function buildStars() { 581 stars = []; 582 var n = Math.round(Math.min(230, W * H / 7000)); 583 for (var i = 0; i < n; i++) stars.push({ 584 x: Math.random() * W, y: Math.random() * H, 585 r: Math.random() < .12 ? 1.6 : Math.random() * .9 + .35, 586 a: Math.random() * .55 + .15, 587 sp: Math.random() * .0018 + .0005, ph: Math.random() * 6.2832 588 }); 589 } 590 function drawStars() { 591 for (var i = 0; i < stars.length; i++) { 592 var st = stars[i], tw = st.a * (0.5 + 0.5 * Math.sin(tick * st.sp + st.ph)); 593 g.fillStyle = "rgba(232,236,248," + tw + ")"; 594 g.beginPath(); g.arc(st.x, st.y, st.r, 0, 6.2832); g.fill(); 595 } 596 } 597 598 /* -- 1) YORUNGE - hero: arkada donen tel kafes kure -- 599 ð´ 2026-08-28 - kullanici: "daha farklisini yap, arkada donsun" ve 600 "arka plani en uste tasi". 601 602 Eskiden burada perspektif bir SEHIR vardi (drawCity). Ufuk cizgisi 603 `H*0.58`e sabitti, yani sahne her zaman ekranin ALT yarisinda kaliyor 604 ve hero yazisinin arkasi bombos duruyordu. Ustelik kamera sadece ileri 605 kayiyordu - "donme" hissi yoktu. 606 607 Yerine kendi ekseninde donen bir tel kafes kure + iki egik yorunge 608 halkasi kondu. Merkez `H*0.40`ta: hero basliginin tam arkasi. 609 610 â ï¸ Arka yuz DAHA SOLUK ciziliyor (alfa `z` derinligine bagli). Bu 611 olmadan kure duz bir daire gibi gorunuyor, donduÄu anlasilmiyor - 612 donme hissini veren tek sey bu. 613 614 â ï¸ Yazinin okunurlugu once gelir: en parlak cizgi bile 0.21 alfada. 615 `.hero::after` radyal karartmasi da ustune biniyor. */ 616 var SPHERE = { lonN: 12, latN: 6, seg: 26 }; 617 618 function drawOrbit(A) { 619 620 var cx = W / 2, cy = H * 0.40, R = Math.min(W, H) * 0.36; 621 var rot = tick * 0.00016; // yavas: hipnotik degil, sakin 622 var tc = Math.cos(0.38), ts = Math.sin(0.38); // sabit eksen egimi 623 var C = "152,160,182"; 624 625 /* Kure yuzeyindeki bir nokta -> ekran. Donus Y ekseni etrafinda, 626 sonra sabit egim. Donen `z` derinligi alfa icin geri veriliyor. */ 627 function pt(lat, lon) {
628 var cl = Math.cos(lat), 629 x = cl * Math.sin(lon + rot), 630 y = Math.sin(lat), 631 z = cl * Math.cos(lon + rot); 632 return [cx + x * R, cy + (y * tc - z * ts) * R, y * ts + z * tc]; 633 } 634 635 /* Derinlige gore alfa: on yuz belirgin, arka yuz silik. */ 636 function al(z, base) { return base * (0.28 + 0.72 * (z * 0.5 + 0.5)) * A; } 637 638 var i, j, a, b, HALF = Math.PI / 2; 639 640 // meridyenler (boylam) 641 for (i = 0; i < SPHERE.lonN; i++) { 642 var lon = (i / SPHERE.lonN) * Math.PI; // yarim tur yeter: kure simetrik 643 a = pt(-HALF, lon); 644 for (j = 1; j <= SPHERE.seg; j++) { 645 b = pt(-HALF + (j / SPHERE.seg) * Math.PI, lon); 646 line(a, b, C, al((a[2] + b[2]) / 2, 0.21)); 647 a = b; 648 } 649 } 650 651 // paraleller (enlem) 652 for (i = 1; i <= SPHERE.latN; i++) { 653 var lat = -HALF + (i / (SPHERE.latN + 1)) * Math.PI; 654 a = pt(lat, 0); 655 for (j = 1; j <= SPHERE.seg * 2; j++) { 656 b = pt(lat, (j / (SPHERE.seg * 2)) * 6.2832); 657 line(a, b, C, al((a[2] + b[2]) / 2, 0.17)); 658 a = b; 659 } 660 } 661 662 /* Iki egik yorunge halkasi + uzerinde kosan birer isik. 663 Kureden bagimsiz donuyorlar; sahneye derinlik veren sey bu. */ 664 var orbits = [{ tilt: 0.95, r: 1.30, sp: 0.00021, ph: 0 }, 665 { tilt: -0.62, r: 1.62, sp: -0.00013, ph: 2.1 }]; 666 667 for (i = 0; i < orbits.length; i++) { 668 var o = orbits[i], ot = Math.cos(o.tilt), os = Math.sin(o.tilt), 669 rr = R * o.r, spin = tick * o.sp + o.ph; 670 671 function opt(t) { 672 var x = Math.cos(t + spin), z = Math.sin(t + spin); 673 var y2 = -z * os, z2 = z * ot; 674 return [cx + x * rr, cy + (y2 * tc - z2 * ts) * rr, y2 * ts + z2 * tc]; 675 } 676 677 a = opt(0); 678 for (j = 1; j <= 72; j++) { 679 b = opt((j / 72) * 6.2832); 680 line(a, b, C, al((a[2] + b[2]) / 2, 0.16)); 681 a = b; 682 } 683 684 var d = opt(spin * 3.1); 685 g.fillStyle = "rgba(95,212,155," + (0.5 * A) + ")"; 686 g.beginPath(); g.arc(d[0], d[1], 1.9, 0, 6.2832); g.fill(); 687 } 688 } 689 690 /* -- 2) AG - sorun: birbirine baglanan noktalar -- 691 "Her sey ayri bir yerde" bolumunun altinda duruyor; kopuk noktalarin 692 ancak yaklasinca birlesmesi o bolumun anlattigi seyin gorsel karsiligi. */ 693 var web = []; 694 function buildWeb() { 695 web = []; 696 var n = Math.round(Math.min(95, W / 15)); 697 for (var i = 0; i < n; i++) web.push({ 698 x: Math.random() * W, y: Math.random() * H, 699 vx: rnd(-.16, .16), vy: rnd(-.16, .16) }); 700 } 701 function drawWeb(A) { 702 g.lineWidth = 1; 703 var R = 185; 704 for (var i = 0; i < web.length; i++) { 705 var a = web[i]; 706 a.x += a.vx; a.y += a.vy; 707 if (a.x < -40) a.x = W + 40; 708 if (a.x > W + 40) a.x = -40; 709 if (a.y < -40) a.y = H + 40; 710 if (a.y > H + 40) a.y = -40; 711 for (var j = i + 1; j < web.length; j++) { 712 var b = web[j], dx = a.x - b.x, dy = a.y - b.y, d = Math.sqrt(dx * dx + dy * dy); 713 if (d < R) line([a.x, a.y], [b.x, b.y], "150,160,190", (1 - d / R) * 0.26 * A); 714 } 715 g.fillStyle = "rgba(190,198,220," + (0.5 * A) + ")"; 716 g.beginPath(); g.arc(a.x, a.y, 1.5, 0, 6.2832); g.fill(); 717 } 718 } 719 720 /* -- 3) AKIS - panel: soldan saga akan veri cizgileri -- */ 721 var flows = []; 722 function buildFlow() { 723 flows = []; 724 for (var i = 0; i < 26; i++) flows.push({ 725 y: Math.random() * H, x: Math.random() * W, 726 len: rnd(60, 320), v: rnd(.5, 2.6), a: rnd(.05, .2), warm: Math.random() < .25 }); 727 } 728 function drawFlow(A) { 729 g.lineWidth = 1; 730 for (var i = 0; i < flows.length; i++) { 731 var f = flows[i], col = f.warm ? "95,212,155" : "160,170,195"; 732 var grd = g.createLinearGradient(f.x, f.y, f.x + f.len, f.y); 733 grd.addColorStop(0, "rgba(" + col + ",0)"); 734 grd.addColorStop(.6, "rgba(" + col + "," + (f.a * 1.8 * A) + ")"); 735 grd.addColorStop(1, "rgba(" + col + ",0)"); 736 g.strokeStyle = grd; 737 g.beginPath(); g.moveTo(f.x, f.y); g.lineTo(f.x + f.len, f.y); g.stroke(); 738 f.x += f.v; 739 if (f.x > W + 40) { f.x = -f.len - 40; f.y = Math.random() * H; } 740 } 741 } 742 743 /* -- 4) HUZME - urunler: yavas capraz isik -- */ 744 function drawRays(A) { 745 for (var i = 0; i < 7; i++) { 746 var ph = tick * 0.00006 + i * 0.9; 747 var x = ((Math.sin(ph) * 0.5 + 0.5) * (W + 700)) - 350; 748 var grd = g.createLinearGradient(x, -100, x + 260, H + 100); 749 grd.addColorStop(0, "rgba(150,160,195,0)"); 750 grd.addColorStop(.5, "rgba(150,160,195," + (0.055 * A) + ")"); 751 grd.addColorStop(1, "rgba(150,160,195,0)"); 752 g.fillStyle = grd; 753 g.beginPath(); 754 g.moveTo(x, -100); g.lineTo(x + 150, -100); 755 g.lineTo(x + 410, H + 100); g.lineTo(x + 260, H + 100); 756 g.closePath(); g.fill(); 757 } 758 } 759 760 /* -- 5) IZGARA - araclar: nabiz atan perspektif zemin -- */ 761 function drawGrid(A) { 762 g.lineWidth = 1; 763 var hz = H * 0.42, C = "150,158,182"; 764 for (var r = 1; r <= 20; r++) { 765 var t = r / 20, y = hz + Math.pow(t, 2.0) * (H - hz) * 1.15; 766 var pulse = 0.5 + 0.5 * Math.sin(tick * 0.0011 - r * 0.35); 767 line([0, y], [W, y], C, (0.05 + 0.09 * pulse) * (1 - t * .5) * A); 768 }
769 for (var i = -14; i <= 14; i++) { 770 line([W / 2 + i * 26, hz], [W / 2 + i * 300, H], C, 0.06 * A); 771 } 772 } 773 774 /* -- 6) NABIZ - islevler: merkezden yayilan halkalar -- 775 Radar atisi: her halka dogar, buyur, soner. Ic halkalar keskin, 776 disa dogru hem soluyor hem inceliyor - "yayilma" hissi bundan. */ 777 function drawPulse(A) { 778 var cx = W / 2, cy = H * 0.46, max = Math.max(W, H) * 0.66, N = 7, i; 779 for (i = 0; i < N; i++) { 780 var t = ((tick * 0.00011) + i / N) % 1; 781 var r = t * max, a = Math.pow(1 - t, 1.6) * 0.30 * A; 782 if (a < 0.004) continue; 783 g.lineWidth = 1 + (1 - t) * 1.1; 784 g.strokeStyle = "rgba(150,158,182," + a + ")"; 785 g.beginPath(); g.ellipse(cx, cy, r, r * 0.82, 0, 0, 6.2832); g.stroke(); 786 } 787 g.lineWidth = 1; 788 var cg = g.createRadialGradient(cx, cy, 0, cx, cy, 90); 789 cg.addColorStop(0, "rgba(95,212,155," + (0.13 * A) + ")"); 790 cg.addColorStop(1, "rgba(95,212,155,0)"); 791 g.fillStyle = cg; 792 g.beginPath(); g.arc(cx, cy, 90, 0, 6.2832); g.fill(); 793 } 794 795 /* -- 7) DALGA - akis: ust uste kayan sinus seritleri -- 796 Iki farkli frekans ust uste bindirildi; tek sinus fazla duzenli 797 duruyor, ikisi birlesince akarsu gibi dalgalaniyor. */ 798 function drawWave(A) { 799 for (var b = 0; b < 6; b++) { 800 var yb = H * (0.24 + b * 0.105), amp = 34 + b * 11, 801 sp = tick * (0.00040 + b * 0.00009), k = 0.0048 + b * 0.0008, 802 vurgu = (b === 2); // tek serit ORION yesili 803 g.lineWidth = vurgu ? 1.4 : 1; 804 g.strokeStyle = vurgu 805 ? "rgba(95,212,155," + (0.16 * A) + ")" 806 : "rgba(152,162,192," + ((0.20 - b * 0.021) * A) + ")"; 807 g.beginPath(); 808 for (var x = 0; x <= W; x += 12) { 809 var y = yb + Math.sin(x * k + sp) * amp 810 + Math.sin(x * k * 0.37 - sp * 1.7) * amp * 0.45; 811 if (x === 0) g.moveTo(x, y); else g.lineTo(x, y); 812 } 813 g.stroke(); 814 } 815 g.lineWidth = 1; 816 } 817 818 /* -- 8) YAGMUR - nefes: dusen veri cizgileri -- */ 819 var drops = []; 820 function buildDrops() { 821 drops = []; 822 var n = Math.round(Math.min(70, W / 22)); 823 for (var i = 0; i < n; i++) drops.push({ 824 x: Math.random() * W, y: Math.random() * H, 825 len: rnd(30, 110), v: rnd(.55, 1.7), a: rnd(.09, .26) 826 }); 827 } 828 function drawRain(A) { 829 g.lineWidth = 1; 830 for (var i = 0; i < drops.length; i++) { 831 var d = drops[i]; 832 var grd = g.createLinearGradient(d.x, d.y, d.x, d.y + d.len); 833 grd.addColorStop(0, "rgba(150,160,190,0)"); 834 grd.addColorStop(1, "rgba(150,160,190," + (d.a * 1.5 * A) + ")"); 835 g.strokeStyle = grd; 836 g.beginPath(); g.moveTo(d.x, d.y); g.lineTo(d.x, d.y + d.len); g.stroke(); 837 d.y += d.v; 838 if (d.y > H) { d.y = -d.len; d.x = Math.random() * W; } 839 } 840 } 841 842 /* -- 9) SARMAL - senaryolar: donen gokada -- 843 â ï¸ Ilk surumde 3x42 noktaydi ve ekranda "karalama" gibi duruyordu. 844 Kol basina nokta sayisi artirildi, yaricap buyutuldu, nokta boyu ve 845 alfasi merkezden disa dogru azaliyor - gokada his ancak boyle olusuyor. */ 846 function drawSpiral(A) { 847 var cx = W / 2, cy = H * 0.47, R = Math.min(W, H) * 0.66, rot = tick * 0.000075; 848 for (var arm = 0; arm < 3; arm++) { 849 var base = rot + arm * 2.094; 850 for (var i = 3; i < 96; i++) { 851 var t = i / 96, ang = base + Math.pow(t, 0.85) * 5.4, r = t * R; 852 var a = Math.pow(1 - t, 1.35) * 0.62 * A; 853 if (a < 0.004) continue; 854 // Her yedinci nokta yesil: gokadaya renk atiyor, tek duze olmuyor. 855 g.fillStyle = (i % 7 === 0) 856 ? "rgba(95,212,155," + (a * 0.8) + ")" 857 : "rgba(158,167,194," + a + ")"; 858 g.beginPath(); 859 g.arc(cx + Math.cos(ang) * r, cy + Math.sin(ang) * r * 0.42, 860 0.8 + (1 - t) * 1.9, 0, 6.2832); 861 g.fill(); 862 } 863 } 864 } 865 866 /* -- 10) PETEK - eklentiler: kayan altigen kafes -- 867 â ï¸ Ilk surumde kafes ekranin TAMAMINI esit parlaklikta kapliyordu ve 868 duvar kagidi gibi duruyordu. Artik merkezden disa dogru soluyor ve 869 icinde birkac hucre sirayla parliyor - desen degil, canli bir doku. */ 870 function drawHex(A) { 871 var R = 52, w = R * 1.732, h = R * 1.5, 872 off = (tick * 0.010) % w, cx = W / 2, cy = H * 0.47, 873 maxD = Math.max(W, H) * 0.62; 874 875 for (var row = -1; row * h < H + R; row++) { 876 for (var col = -1; col * w < W + w; col++) { 877 var x0 = col * w + (row % 2 ? w / 2 : 0) - off, y0 = row * h; 878 var d = Math.sqrt((x0 - cx) * (x0 - cx) + (y0 - cy) * (y0 - cy) * 1.6); 879 var f = 1 - Math.min(1, d / maxD); 880 if (f <= 0.02) continue; 881 882 // sirayla parlayan hucreler 883 var puls = 0.5 + 0.5 * Math.sin(tick * 0.0016 + (row * 3 + col) * 1.1); 884 var a = (0.05 + 0.13 * f) * (0.65 + 0.35 * puls) * A; 885 886 g.strokeStyle = "rgba(150,158,182," + a + ")"; 887 g.beginPath(); 888 for (var k = 0; k < 6; k++) { 889 var ang = (Math.PI / 3) * k - Math.PI / 6;
890 var x = x0 + Math.cos(ang) * R, y = y0 + Math.sin(ang) * R; 891 if (k === 0) g.moveTo(x, y); else g.lineTo(x, y); 892 } 893 g.closePath(); g.stroke(); 894 } 895 } 896 } 897 898 /* -- 11) TARAMA - guven: izgara uzerinde gecen tarama cizgisi -- 899 â ï¸ Ilk surumde tarama 240px'lik kalin yesil bir bulut olarak geciyordu; 900 ekranda bulasik bir leke gibi duruyordu. Artik INCE ve KESKIN bir cizgi 901 + arkasinda kisa bir kuyruk: tarayici his buradan geliyor. */ 902 function drawScan(A) { 903 var C = "150,158,182", i; 904 for (i = 1; i < 10; i++) line([0, H * i / 10], [W, H * i / 10], C, 0.05 * A); 905 for (i = 1; i < 15; i++) line([W * i / 15, 0], [W * i / 15, H], C, 0.042 * A); 906 907 var y = ((tick * 0.052) % (H + 200)) - 100; 908 909 // kuyruk: cizginin YUKARISINDA kalir, gectigi yeri belli eder 910 var grd = g.createLinearGradient(0, y - 130, 0, y); 911 grd.addColorStop(0, "rgba(95,212,155,0)"); 912 grd.addColorStop(1, "rgba(95,212,155," + (0.09 * A) + ")"); 913 g.fillStyle = grd; 914 g.fillRect(0, y - 130, W, 130); 915 916 // cizginin kendisi 917 g.strokeStyle = "rgba(95,212,155," + (0.34 * A) + ")"; 918 g.lineWidth = 1.2; 919 g.beginPath(); g.moveTo(0, y); g.lineTo(W, y); g.stroke(); 920 g.lineWidth = 1; 921 } 922 923 /* -- sahne yonetimi -- 924 ð´ 2026-08-28 - kullanici: "farkli farkli olsun her sayfada, sekmede". 925 926 ONCEDEN iki sorun vardi: 927 1. Bes sahne on bir bolume dagitilmisti, yani ayni arka plan sayfa 928 boyunca uc kez tekrar ediyordu. 929 2. ANA SAYFA DISINDAKI ONBIR SAYFADA hicbir bolum kimligi eslesmiyor, 930 `best` 0'da kaliyor ve HEPSINDE ayni sahne (hero'nunki) donuyordu. 931 932 Artik her bolumun ve her sayfanin kendine ait bir sahnesi var. Yeni bir 933 bolum ya da sayfa eklenirse buraya da bir satir eklenmeli - eslesme 934 bulunamazsa yine ilk sahneye dusulur. */ 935 var SCENES = [ 936 { id: "hero", draw: drawOrbit, a: 0, t: 0 }, // kure 937 { id: "urunler", draw: drawRays, a: 0, t: 0 }, // huzme 938 { id: "eklentiler", draw: drawHex, a: 0, t: 0 }, // petek 939 { id: "sorun", draw: drawWeb, a: 0, t: 0 }, // ag 940 { id: "panel", draw: drawFlow, a: 0, t: 0 }, // akis 941 { id: "islevler", draw: drawPulse, a: 0, t: 0 }, // nabiz 942 { id: "akis", draw: drawWave, a: 0, t: 0 }, // dalga 943 { id: "guven", draw: drawScan, a: 0, t: 0 }, // tarama 944 { id: "senaryolar", draw: drawSpiral, a: 0, t: 0 }, // sarmal 945 { id: "nefes", draw: drawRain, a: 0, t: 0 }, // yagmur 946 { id: "araclar", draw: drawGrid, a: 0, t: 0 } // izgara 947 ]; 948 949 function sceneIndex(id) { 950 for (var i = 0; i < SCENES.length; i++) if (SCENES[i].id === id) return i; 951 return 0; 952 } 953 954 /* Bolumu olmayan sayfalarin kendi sahnesi. Anahtar adres yolundan 955 cozuluyor; listede yoksa kure ile aciliyor. */ 956 var SAYFA_SAHNE = { 957 "/orionmod": "panel", // akis 958 "/orionmodes": "araclar", // izgara 959 "/orionmod-eklenti": "islevler", // nabiz 960 "/clip-helper": "guven", // tarama 961 "/kick-clipper": "akis", // dalga 962 "/kick-chat-overlay": "eklentiler", // petek 963 "/musivora": "senaryolar", // sarmal 964 "/link-hunter": "nefes", // yagmur 965 "/gizlilik": "sorun", // ag 966 "/kullanim-sartlari": "urunler", // huzme 967 "/404": "hero" // kure 968 }; 969 970 function sayfaVarsayilani() { 971 var yol = location.pathname.replace(/\.html$/, "").replace(/\/+$/, ""); 972 if (!yol) return sceneIndex("hero"); // ana sayfa 973 return SAYFA_SAHNE[yol] ? sceneIndex(SAYFA_SAHNE[yol]) : sceneIndex("hero"); 974 } 975 976 var VARSAYILAN = sayfaVarsayilani(); 977 SCENES[VARSAYILAN].a = 1; 978 SCENES[VARSAYILAN].t = 1; 979 980 function pickScene() { 981 var mid = innerHeight * 0.45, best = -1; 982 for (var i = 0; i < SCENES.length; i++) { 983 var el = SCENES[i].id === "hero" 984 ? document.querySelector(".hero") 985 : document.getElementById(SCENES[i].id); 986 if (!el) continue; 987 var r = el.getBoundingClientRect(); 988 if (r.top <= mid && r.bottom >
988= mid) best = i; 989 } 990 // Hicbir bolum orta noktada degil (ya da sayfada hic bolum yok): 991 // o sayfanin kendi sahnesi kalir - eskiden hep hero'nunki kaliyordu. 992 if (best < 0) best = VARSAYILAN; 993 for (var j = 0; j < SCENES.length; j++) SCENES[j].t = (j === best) ? 1 : 0; 994 } 995 996 addEventListener("scroll", pickScene, { passive: true }); 997 998 function rs() { 999 W = c.offsetWidth; H = c.offsetHeight; 1000 c.width = W * dpr; c.height = H * dpr; 1001 g.setTransform(dpr, 0, 0, dpr, 0, 0); 1002 buildStars(); buildWeb(); buildFlow(); buildDrops(); 1003 } 1004 1005 function frame() { 1006 g.clearRect(0, 0, W, H); 1007 drawStars(); 1008 for (var i = 0; i < SCENES.length; i++) { 1009 var sc = SCENES[i]; 1010 sc.a += (sc.t - sc.a) * 0.045; 1011 if (sc.a > 0.01) sc.draw(sc.a); 1012 } 1013 tick += 16; 1014 requestAnimationFrame(frame); 1015 } 1016 1017 rs(); pickScene(); frame(); 1018 var to; 1019 addEventListener("resize", function () { clearTimeout(to); to = setTimeout(rs, 160); }); 1020})();
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.