Живой фон + тема + авто-репутация. Оптимизировано для мобилок.
// ==UserScript==
// @name BR | Ultimate V5
// @namespace https://forum.blackrussia.online
// @version 16.0.0
// @description Живой фон + тема + авто-репутация. Оптимизировано для мобилок.
// @author Akzholch1k
// @match https://forum.blackrussia.online/*
// @grant GM_xmlhttpRequest
// @grant GM.xmlHttpRequest
// @connect api.groq.com
// @run-at document-start
// @license MIT
// ==/UserScript==
(function(){
'use strict';
// ═══════════════════════════════
// КОНФИГ
// ═══════════════════════════════
var MY_NICK = "Bruno Verona";
var GROQ_KEY = "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";
var THEMES = {
red: {name:'🔴 Красный', c:'#ff3333', bg:'#080005'},
gold: {name:'🟡 Золотой', c:'#ffd700', bg:'#080600'},
green: {name:'🟢 Неон зелёный', c:'#00ff88', bg:'#000805'},
violet: {name:'🟣 Фиолетовый', c:'#cc44ff', bg:'#06000f'},
blue: {name:'🔵 Синий неон', c:'#00cfff', bg:'#00060f'},
pink: {name:'🌸 Розовый', c:'#ff69b4', bg:'#080006'},
cyber: {name:'⚡ Cyberpunk', c:'#ffee00', bg:'#050003'},
aqua: {name:'💎 Аква', c:'#00ffee', bg:'#000808'},
orange: {name:'🟠 Оранжевый', c:'#ff8800', bg:'#080400'},
ice: {name:'🧊 Ледяной', c:'#88ddff', bg:'#00040e'},
lime: {name:'🍏 Лайм', c:'#aaff00', bg:'#020800'},
white: {name:'⬜ Белый', c:'#ffffff', bg:'#080808'}
};
var BG_LIST = [
['rain', '🌧️ Дождь'],
['storm', '⛈️ Гроза + молния'],
['sakura', '🌸 Сакура'],
['sakura_storm', '🌸⚡ Сакура + гроза'],
['snow', '❄️ Снег + горы'],
['blizzard', '🌨️ Метель'],
['fire', '🔥 Огонь'],
['cosmos', '🌌 Космос'],
['particles', '✨ Частицы'],
['nature', '🌿 Природа'],
['city', '🏙️ Ночной город'],
['matrix', '💻 Матрица'],
['waves', '🌊 Волны']
];
// ═══════════════════════════════
// ХРАНИЛИЩЕ
// ═══════════════════════════════
var S = {
g: function(k,d){ try{ var v=localStorage.getItem('brv5_'+k); return v!==null?JSON.parse(v):d; }catch(e){return d;} },
s: function(k,v){ try{ localStorage.setItem('brv5_'+k,JSON.stringify(v)); }catch(e){} }
};
var tk = S.g('theme','red');
var T = THEMES[tk] || THEMES.red;
var bg = S.g('bg','rain');
var FPS = S.g('fps', 24);
// Сброс дневной статы
var today = new Date().toDateString();
if(S.g('day','')!==today){ S.s('day',today); S.s('likes',0); S.s('bumps',0); S.s('cites',0); }
// ═══════════════════════════════
// СТИЛИ — ВСТАВЛЯЕМ ДО ЗАГРУЗКИ
// Используем !important на html/body
// и прозрачность на все обёртки форума
// ═══════════════════════════════
function injectCSS(){
var id = 'brv5-css';
if(document.getElementById(id)) return;
var s = document.createElement('style');
s.id = id;
// Ключевой трюк: html и body получают нужный цвет фона
// Все контейнеры форума — прозрачные
// z-index на canvas -9999 чтобы быть ПОЗАДИ всего
s.textContent = '\
html{background:'+T.bg+'!important}\
body{background:'+T.bg+'!important;position:relative!important}\
#brv5-canvas{position:fixed!important;top:0!important;left:0!important;\
width:100vw!important;height:100vh!important;\
z-index:-9999!important;pointer-events:none!important;\
display:block!important;opacity:1!important}\
.p-pageWrapper,.p-body,.p-body-pageContent,.p-body-inner,\
.p-body-sidebar,.p-body-main,.p-body-content,\
.p-body-contentInner{background:transparent!important}\
.p-header,.p-header-inner,.p-headerRow{\
background:rgba(0,0,0,0.93)!important;\
border-bottom:2px solid '+T.c+'!important;\
backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important}\
.p-nav-wrapper{background:rgba(0,0,0,0.88)!important}\
.p-footer{background:rgba(0,0,0,0.85)!important}\
.block{background:rgba(6,6,20,0.83)!important;\
border-color:'+T.c+'22!important;border-radius:11px!important}\
.block-outer,.block-outer--m,.block-outer--b,\
.block-container,.block-body,.block-row{\
background:transparent!important}\
.node,.node-body,.node-main,.node-stats,.node-meta{\
background:rgba(6,6,20,0.78)!important;\
border:1px solid '+T.c+'22!important;\
border-radius:10px!important;margin-bottom:5px!important}\
.node:hover{border-color:'+T.c+'88!important;\
box-shadow:0 0 10px '+T.c+'33!important}\
.message,.message-inner{\
background:rgba(5,5,18,0.86)!important;\
border:1px solid '+T.c+'33!important;\
border-radius:12px!important;margin-bottom:8px!important}\
.message:hover{border-color:'+T.c+'77!important}\
.structItem--thread{\
background:rgba(5,5,18,0.8)!important;\
border:1px solid '+T.c+'22!important;\
border-radius:9px!important;margin-bottom:4px!important;\
transition:border-color .2s,transform .2s!important}\
.structItem--thread:hover{\
border-color:'+T.c+'!important;transform:translateX(3px)!important}\
.username,.p-navEl-link{color:'+T.c+'!important;font-weight:bold!important}\
a{color:'+T.c+'!important}\
.button--primary,.button--cta{\
background:'+T.c+'!important;color:#000!important;\
font-weight:bold!important;border-radius:9px!important;\
border-color:'+T.c+'!important}\
.fr-box{background:rgba(4,4,15,0.96)!important;border-radius:9px!important}\
.fr-element{color:#ddd!important;background:transparent!important}\
.fr-toolbar{background:rgba(4,4,15,0.96)!important}\
.p-title-value,.p-pageHeader-title{color:#fff!important}\
.message-userDetails{border-right:2px solid '+T.c+'33!important}\
tr,td,th{background:transparent!important;border-color:'+T.c+'11!important}\
.dataList{background:transparent!important}\
.dataList-row{background:rgba(5,5,18,0.72)!important}\
.sidebar-container,.p-nav-list li a{background:transparent!important}\
::-webkit-scrollbar{width:3px}\
::-webkit-scrollbar-thumb{background:'+T.c+';border-radius:3px}\
@keyframes brIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}\
.message{animation:brIn .28s ease forwards!important}\
.structItem--thread{animation:brIn .18s ease forwards!important}\
';
// Вставляем в самое начало head
var head = document.head || document.documentElement;
head.insertBefore(s, head.firstChild);
}
// Применяем сразу
injectCSS();
// ═══════════════════════════════
// CANVAS — правильная инициализация
// ═══════════════════════════════
var canvas = null;
var ctx = null;
var drawFn = null;
var rafId = null;
var lastT = 0;
var mspf = Math.round(1000 / FPS); // миллисекунд на кадр
function initCanvas(){
if(document.getElementById('brv5-canvas')) return;
canvas = document.createElement('canvas');
canvas.id = 'brv5-canvas';
// Стиль задан через CSS выше, но дублируем для надёжности
canvas.setAttribute('style',
'position:fixed!important;top:0!important;left:0!important;'+
'width:100vw!important;height:100vh!important;'+
'z-index:-9999!important;pointer-events:none!important;display:block!important'
);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Вставляем ПЕРВЫМ дочерним элементом body
if(document.body.firstChild){
document.body.insertBefore(canvas, document.body.firstChild);
} else {
document.body.appendChild(canvas);
}
// alpha:false = браузер не смешивает прозрачность = быстрее на 30-40%
ctx = canvas.getContext('2d', {alpha: false, desynchronized: true});
// Ресайз с дебаунсом 300мс
var resizeTimer;
window.addEventListener('resize', function(){
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function(){
if(!canvas) return;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}, 300);
});
// Стоп анимации когда вкладка скрыта — главная экономия батареи
document.addEventListener('visibilitychange', function(){
if(document.hidden){
if(rafId){ cancelAnimationFrame(rafId); rafId=null; }
} else {
if(!rafId && drawFn) startRAF();
}
});
startBG();
}
function startRAF(){
rafId = requestAnimationFrame(function tick(ts){
if(document.hidden){ rafId=null; return; }
if(ts - lastT >= mspf){
lastT = ts;
if(drawFn && canvas) drawFn(canvas.width, canvas.height);
}
rafId = requestAnimationFrame(tick);
});
}
function setDraw(fn){
drawFn = fn;
if(rafId) cancelAnimationFrame(rafId);
startRAF();
}
// ═══════════════════════════════
// ФОНЫ
// ═══════════════════════════════
function startBG(){
var map = {
rain: bgRain,
storm: bgStorm,
sakura: bgSakura,
sakura_storm: bgSakuraStorm,
snow: bgSnow,
blizzard: bgBlizzard,
fire: bgFire,
cosmos: bgCosmos,
particles: bgParticles,
nature: bgNature,
city: bgCity,
matrix: bgMatrix,
waves: bgWaves
};
(map[bg] || bgRain)();
}
// --- ДОЖДЬ ---
function bgRain(){
var drops=[], splashes=[];
function init(W,H){
drops=[];
for(var i=0;i<90;i++) drops.push({
x:Math.random()*W, y:Math.random()*H,
s:Math.random()*9+6, l:Math.random()*16+7,
a:Math.random()*.4+.14
});
}
var initd=false;
setDraw(function(W,H){
if(!initd){init(W,H);initd=true;}
ctx.fillStyle='rgba(0,4,12,0.3)';
ctx.fillRect(0,0,W,H);
ctx.strokeStyle=T.c; ctx.lineWidth=.7;
for(var i=0;i<drops.length;i++){
var d=drops[i]; ctx.globalAlpha=d.a;
ctx.beginPath(); ctx.moveTo(d.x,d.y); ctx.lineTo(d.x-1.4,d.y+d.l); ctx.stroke();
d.y+=d.s; d.x-=1.4;
if(d.y>H){ splashes.push({x:d.x,y:H,r:0,a:.42}); d.y=-8; d.x=Math.random()*W; }
}
for(var i=splashes.length-1;i>=0;i--){
var s=splashes[i];
ctx.beginPath(); ctx.arc(s.x,s.y,s.r,0,Math.PI*2);
ctx.strokeStyle=T.c; ctx.globalAlpha=s.a; ctx.lineWidth=.5; ctx.stroke();
s.r+=1.5; s.a-=.07;
if(s.a<=0) splashes.splice(i,1);
}
ctx.globalAlpha=1;
// Лимит брызг
if(splashes.length>60) splashes.splice(0,10);
});
}
// --- ГРОЗА ---
function bgStorm(){
var drops=[], splashes=[];
var flash={a:0,timer:0,bolts:[]};
function makeBolt(sx,W,H){
var p=[{x:sx,y:0}],cx=sx,cy=0;
while(cy<H*.72){cy+=Math.random()*38+16;cx+=(Math.random()-.5)*65;p.push({x:cx,y:cy});}
return p;
}
function init(W,H){
drops=[];
for(var i=0;i<120;i++) drops.push({x:Math.random()*W,y:Math.random()*H,s:Math.random()*14+8,l:Math.random()*22+10,a:Math.random()*.5+.16});
}
var initd=false;
setDraw(function(W,H){
if(!initd){init(W,H);initd=true;}
ctx.fillStyle='rgba(0,2,10,0.24)'; ctx.fillRect(0,0,W,H);
flash.timer--;
if(flash.timer<=0){
flash.timer=Math.floor(Math.random()*150+50);
flash.a=1; flash.bolts=[];
for(var k=0;k<Math.floor(Math.random()*2)+1;k++) flash.bolts.push(makeBolt(Math.random()*W,W,H));
}
if(flash.a>0){
ctx.fillStyle='rgba(150,180,255,'+flash.a*.1+')'; ctx.fillRect(0,0,W,H);
for(var b=0;b<flash.bolts.length;b++){
var bl=flash.bolts[b];
ctx.beginPath(); ctx.moveTo(bl[0].x,bl[0].y);
for(var p=1;p<bl.length;p++) ctx.lineTo(bl[p].x,bl[p].y);
ctx.strokeStyle='rgba(215,230,255,'+flash.a+')'; ctx.lineWidth=1.8; ctx.globalAlpha=1; ctx.stroke();
ctx.strokeStyle='rgba(130,165,255,'+(flash.a*.32)+')'; ctx.lineWidth=8; ctx.stroke();
}
flash.a-=.045;
}
ctx.strokeStyle='rgba(165,195,255,0.6)'; ctx.lineWidth=.85;
for(var i=0;i<drops.length;i++){
var d=drops[i]; ctx.globalAlpha=d.a;
ctx.beginPath(); ctx.moveTo(d.x,d.y); ctx.lineTo(d.x-2.2,d.y+d.l); ctx.stroke();
d.y+=d.s; d.x-=2;
if(d.y>H){ splashes.push({x:d.x,y:H,r:0,a:.5}); d.y=-10; d.x=Math.random()*W; }
}
for(var i=splashes.length-1;i>=0;i--){
var s=splashes[i];
ctx.beginPath(); ctx.ellipse(s.x,s.y,s.r,s.r*.26,0,0,Math.PI*2);
ctx.strokeStyle='rgba(165,195,255,'+s.a+')'; ctx.globalAlpha=1; ctx.lineWidth=.55; ctx.stroke();
s.r+=1.9; s.a-=.07;
if(s.a<=0) splashes.splice(i,1);
}
ctx.globalAlpha=1;
if(splashes.length>60) splashes.splice(0,10);
});
}
// --- САКУРА ---
function bgSakura(){
var cols=['#ffb7c5','#ff90a8','#ffc8d5','#ff69b4','#ffaabb'];
var petals=[];
function init(W,H){
petals=[];
for(var i=0;i<45;i++) petals.push({
x:Math.random()*W, y:Math.random()*H,
sz:Math.random()*10+5, sp:Math.random()*1.1+.35,
sw:Math.random()*2.2-1.1, ang:Math.random()*Math.PI*2,
rot:(Math.random()-.5)*.038, a:Math.random()*.62+.28,
col:cols[Math.floor(Math.random()*cols.length)],
t:Math.random()*100
});
}
var initd=false;
setDraw(function(W,H){
if(!initd){init(W,H);initd=true;}
ctx.fillStyle='rgba(8,0,5,0.22)'; ctx.fillRect(0,0,W,H);
for(var i=0;i<petals.length;i++){
var p=petals[i]; p.t+=.011;
ctx.save(); ctx.translate(p.x,p.y); ctx.rotate(p.ang); ctx.globalAlpha=p.a;
ctx.fillStyle=p.col;
ctx.beginPath(); ctx.ellipse(0,0,p.sz/2,p.sz/1.4,0,0,Math.PI*2); ctx.fill();
ctx.fillStyle='rgba(255,255,255,0.18)';
ctx.beginPath(); ctx.ellipse(-p.sz/5,-p.sz/5,p.sz/4,p.sz/5,Math.PI/4,0,Math.PI*2); ctx.fill();
ctx.restore();
p.y+=p.sp; p.x+=Math.sin(p.t)*p.sw*.42; p.ang+=p.rot;
if(p.y>H+14){p.y=-14;p.x=Math.random()*W;}
if(p.x>W+14)p.x=-14; if(p.x<-14)p.x=W+14;
}
ctx.globalAlpha=1;
});
}
// --- САКУРА + ГРОЗА ---
function bgSakuraStorm(){
var cols=['#ffb7c5','#ff69b4','#ffc8d5'];
var petals=[], drops=[];
var ft=0,fa=0;
function init(W,H){
petals=[];
for(var i=0;i<38;i++) petals.push({x:Math.random()*W,y:Math.random()*H,sz:Math.random()*10+4,vx:(Math.random()-.5)*3.5,vy:Math.random()*1.8+.8,ang:Math.random()*Math.PI*2,rot:(Math.random()-.5)*.08,a:Math.random()*.7+.22,col:cols[Math.floor(Math.random()*cols.length)]});
drops=[];
for(var i=0;i<80;i++) drops.push({x:Math.random()*W,y:Math.random()*H,s:Math.random()*8+5,l:Math.random()*14+6,a:Math.random()*.3+.1});
}
var initd=false;
setDraw(function(W,H){
if(!initd){init(W,H);initd=true;}
ctx.fillStyle='rgba(5,0,8,0.26)'; ctx.fillRect(0,0,W,H);
ft--; if(ft<=0){ft=Math.floor(Math.random()*170+65);fa=.75;}
if(fa>0){ctx.fillStyle='rgba(185,165,255,'+fa*.09+')';ctx.fillRect(0,0,W,H);fa-=.04;}
ctx.strokeStyle='rgba(195,170,255,0.35)'; ctx.lineWidth=.6;
for(var i=0;i<drops.length;i++){
var d=drops[i]; ctx.globalAlpha=d.a;
ctx.beginPath(); ctx.moveTo(d.x,d.y); ctx.lineTo(d.x-1.6,d.y+d.l); ctx.stroke();
d.y+=d.s; d.x-=1.6; if(d.y>H){d.y=-8;d.x=Math.random()*W;}
}
for(var i=0;i<petals.length;i++){
var p=petals[i];
ctx.save(); ctx.translate(p.x,p.y); ctx.rotate(p.ang); ctx.globalAlpha=p.a;
ctx.fillStyle=p.col;
ctx.beginPath(); ctx.ellipse(0,0,p.sz/2,p.sz/1.4,0,0,Math.PI*2); ctx.fill();
ctx.restore();
p.x+=p.vx; p.y+=p.vy; p.ang+=p.rot;
p.vx+=(Math.random()-.5)*.22; p.vx=Math.max(-4.5,Math.min(4.5,p.vx));
if(p.y>H+14||p.x<-14||p.x>W+14){p.y=-14;p.x=Math.random()*W;p.vx=(Math.random()-.5)*3.5;p.vy=Math.random()*1.8+.8;}
}
ctx.globalAlpha=1;
});
}
// --- СНЕГ ---
function bgSnow(){
var flakes=[], wt=0;
function init(W,H){
flakes=[];
for(var i=0;i<90;i++) flakes.push({
x:Math.random()*W, y:Math.random()*H,
r:Math.random()*3+.7, s:Math.random()*1+.24,
sw:Math.random()*1.6-.8, a:Math.random()*.62+.28,
rot:Math.random()*Math.PI*2, rs:(Math.random()-.5)*.028,
t:Math.random()*100, tp:Math.floor(Math.random()*3)
});
}
var initd=false;
setDraw(function(W,H){
if(!initd){init(W,H);initd=true;}
var sky=ctx.createLinearGradient(0,0,0,H);
sky.addColorStop(0,'#020810'); sky.addColorStop(1,'#081726');
ctx.fillStyle=sky; ctx.fillRect(0,0,W,H);
// Горы (рисуем один раз — они статичные)
ctx.fillStyle='#0c1e34';
ctx.beginPath(); ctx.moveTo(0,H);
ctx.lineTo(0,H*.56); ctx.lineTo(W*.12,H*.28); ctx.lineTo(W*.28,H*.53);
ctx.lineTo(W*.43,H*.22); ctx.lineTo(W*.58,H*.49); ctx.lineTo(W*.73,H*.18);
ctx.lineTo(W*.88,H*.43); ctx.lineTo(W,H*.32); ctx.lineTo(W,H);
ctx.closePath(); ctx.fill();
ctx.fillStyle='rgba(200,224,255,0.58)';
[[W*.12,H*.28,W*.065,H*.39],[W*.43,H*.22,W*.065,H*.35],[W*.73,H*.18,W*.065,H*.31]].forEach(function(m){
ctx.beginPath(); ctx.moveTo(m[0],m[1]); ctx.lineTo(m[0]-m[2],m[3]); ctx.lineTo(m[0]+m[2],m[3]); ctx.closePath(); ctx.fill();
});
ctx.fillStyle='#0c1e34'; ctx.fillRect(0,H*.85,W,H*.15);
ctx.fillStyle='rgba(190,216,255,0.48)'; ctx.fillRect(0,H*.85,W,5);
wt+=.007; var wind=Math.sin(wt)*.42;
for(var i=0;i<flakes.length;i++){
var f=flakes[i]; f.t+=.01; f.rot+=f.rs;
ctx.save(); ctx.translate(f.x,f.y); ctx.rotate(f.rot); ctx.globalAlpha=f.a;
if(f.tp===0){
ctx.beginPath(); ctx.arc(0,0,f.r,0,Math.PI*2); ctx.fillStyle='#ddeeff'; ctx.fill();
} else if(f.tp===1){
ctx.strokeStyle='#cce8ff'; ctx.lineWidth=.7;
for(var a=0;a<6;a++){ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(Math.cos(a*Math.PI/3)*f.r*2,Math.sin(a*Math.PI/3)*f.r*2);ctx.stroke();}
} else {
ctx.strokeStyle='#ddeeff'; ctx.lineWidth=.7;
ctx.beginPath();ctx.moveTo(-f.r*1.4,0);ctx.lineTo(f.r*1.4,0);ctx.moveTo(0,-f.r*1.4);ctx.lineTo(0,f.r*1.4);ctx.stroke();
}
ctx.restore();
f.y+=f.s; f.x+=wind+Math.sin(f.t)*f.sw*.26;
if(f.y>H+7){f.y=-7;f.x=Math.random()*W;}
if(f.x>W+7)f.x=-7; if(f.x<-7)f.x=W+7;
}
ctx.globalAlpha=1;
});
}
// --- МЕТЕЛЬ ---
function bgBlizzard(){
var flakes=[], wt=0;
function init(W,H){ flakes=[]; for(var i=0;i<140;i++) flakes.push({x:Math.random()*W,y:Math.random()*H,r:Math.random()*2.2+.5,sx:Math.random()*6+3,sy:Math.random()*2+.7,a:Math.random()*.6+.22,rot:Math.random()*Math.PI*2,rs:(Math.random()-.5)*.055}); }
var initd=false;
setDraw(function(W,H){
if(!initd){init(W,H);initd=true;}
ctx.fillStyle='rgba(2,7,18,0.24)'; ctx.fillRect(0,0,W,H);
wt+=.013; var gust=Math.sin(wt)*2.5+3.2;
for(var i=0;i<flakes.length;i++){
var f=flakes[i]; f.rot+=f.rs;
ctx.save(); ctx.translate(f.x,f.y); ctx.rotate(f.rot); ctx.globalAlpha=f.a;
ctx.strokeStyle='#cce8ff'; ctx.lineWidth=.65;
for(var a=0;a<6;a++){ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(Math.cos(a*Math.PI/3)*f.r*1.9,Math.sin(a*Math.PI/3)*f.r*1.9);ctx.stroke();}
ctx.restore();
f.x-=f.sx+gust; f.y+=f.sy;
if(f.x<-7){f.x=W+7;f.y=Math.random()*H;}
if(f.y>H+7){f.y=-7;f.x=Math.random()*W;}
}
ctx.globalAlpha=1;
});
}
// --- ОГОНЬ ---
function bgFire(){
var particles=[];
setDraw(function(W,H){
ctx.fillStyle='rgba(7,0,0,0.18)'; ctx.fillRect(0,0,W,H);
// Спавним не более 3 новых за кадр
for(var i=0;i<3;i++) particles.push({
x:W/2+(Math.random()-.5)*W*.88, y:H,
vy:-(Math.random()*3+1.7), vx:(Math.random()-.5)*1.5,
life:1, dec:Math.random()*.013+.006, sz:Math.random()*17+8
});
for(var i=particles.length-1;i>=0;i--){
var p=particles[i];
var g=ctx.createRadialGradient(p.x,p.y,0,p.x,p.y,p.sz);
g.addColorStop(0,'rgba(255,255,165,'+p.life+')');
g.addColorStop(.38,'rgba(255,105,0,'+(p.life*.8)+')');
g.addColorStop(.72,'rgba(255,22,0,'+(p.life*.36)+')');
g.addColorStop(1,'rgba(60,0,0,0)');
ctx.beginPath(); ctx.arc(p.x,p.y,p.sz,0,Math.PI*2); ctx.fillStyle=g; ctx.fill();
p.x+=p.vx; p.y+=p.vy; p.life-=p.dec; p.sz*=.993;
if(p.life<=0) particles.splice(i,1);
}
// Жёсткий лимит частиц — главная защита от лагов
if(particles.length>100) particles.length=100;
});
}
// --- КОСМОС ---
function bgCosmos(){
var stars=[], shooters=[];
function init(W,H){ stars=[]; for(var i=0;i<160;i++) stars.push({x:Math.random()*W,y:Math.random()*H,r:Math.random()*1.5+.2,a:Math.random(),s:Math.random()*.015+.004,d:Math.random()>.5?1:-1}); }
var nc=['#8800ff','#0044ff','#ff0088',T.c];
var initd=false;
setDraw(function(W,H){
if(!initd){init(W,H);initd=true;}
ctx.fillStyle='#000008'; ctx.fillRect(0,0,W,H);
// Туманности (3 штуки — оптимально)
for(var n=0;n<3;n++){
var nx=W*(n*.32+.08), ny=H*.27+Math.sin(n)*H*.27;
var g=ctx.createRadialGradient(nx,ny,0,nx,ny,W*.2);
g.addColorStop(0,nc[n]+'36'); g.addColorStop(1,'transparent');
ctx.beginPath(); ctx.ellipse(nx,ny,W*.2,H*.13,n*.5,0,Math.PI*2);
ctx.fillStyle=g; ctx.globalAlpha=.07; ctx.fill();
}
// Падающие звёзды
if(Math.random()<.006) shooters.push({x:Math.random()*W*.5,y:0,vx:Math.random()*4.5+2.2,vy:Math.random()*3.5+2.2,len:Math.random()*75+35,a:1});
for(var i=shooters.length-1;i>=0;i--){
var s=shooters[i];
ctx.beginPath(); ctx.moveTo(s.x,s.y); ctx.lineTo(s.x-s.vx*(s.len/10),s.y-s.vy*(s.len/10));
ctx.strokeStyle='#fff'; ctx.globalAlpha=s.a; ctx.lineWidth=1.3; ctx.stroke();
s.x+=s.vx; s.y+=s.vy; s.a-=.013;
if(s.a<=0||s.x>W||s.y>H) shooters.splice(i,1);
}
for(var i=0;i<stars.length;i++){
var s=stars[i]; s.a+=s.s*s.d; if(s.a>=1||s.a<=0)s.d*=-1;
ctx.beginPath(); ctx.arc(s.x,s.y,s.r,0,Math.PI*2); ctx.fillStyle='#fff'; ctx.globalAlpha=s.a; ctx.fill();
}
ctx.globalAlpha=1;
});
}
// --- ЧАСТИЦЫ ---
function bgParticles(){
var pts=[];
function init(W,H){ pts=[]; for(var i=0;i<50;i++) pts.push({x:Math.random()*W,y:Math.random()*H,vx:(Math.random()-.5)*.65,vy:(Math.random()-.5)*.65,r:Math.random()*1.7+.7}); }
var initd=false;
setDraw(function(W,H){
if(!initd){init(W,H);initd=true;}
ctx.fillStyle=T.bg; ctx.fillRect(0,0,W,H);
for(var i=0;i<pts.length;i++){
for(var j=i+1;j<pts.length;j++){
var dx=pts[i].x-pts[j].x, dy=pts[i].y-pts[j].y, d=Math.sqrt(dx*dx+dy*dy);
if(d<95){ctx.beginPath();ctx.strokeStyle=T.c;ctx.globalAlpha=(1-d/95)*.2;ctx.lineWidth=.5;ctx.moveTo(pts[i].x,pts[i].y);ctx.lineTo(pts[j].x,pts[j].y);ctx.stroke();}
}
var p=pts[i]; ctx.beginPath(); ctx.arc(p.x,p.y,p.r,0,Math.PI*2); ctx.fillStyle=T.c; ctx.globalAlpha=.55; ctx.fill();
p.x+=p.vx; p.y+=p.vy;
if(p.x<0||p.x>W)p.vx*=-1; if(p.y<0||p.y>H)p.vy*=-1;
}
ctx.globalAlpha=1;
});
}
// --- ПРИРОДА ---
function bgNature(){
var leaves=[], wt=0;
var treeDef=[[.05,172],[.17,212],[.3,155],[.44,232],[.59,192],[.74,178],[.87,208],[.96,165]];
var treeCols=['#1e4a0e','#2d6a1a','#1a5510','#255c14'];
function drawTree(x,h,col,W,H){ ctx.fillStyle=col; ctx.beginPath(); ctx.moveTo(x,H); ctx.lineTo(x-20,H-h*.38); ctx.lineTo(x-9,H-h*.38); ctx.lineTo(x-30,H-h*.68); ctx.lineTo(x-13,H-h*.68); ctx.lineTo(x,H-h); ctx.lineTo(x+13,H-h*.68); ctx.lineTo(x+30,H-h*.68); ctx.lineTo(x+9,H-h*.38); ctx.lineTo(x+20,H-h*.38); ctx.closePath(); ctx.fill(); }
function init(W,H){ leaves=[]; for(var i=0;i<30;i++) leaves.push({x:Math.random()*W,y:Math.random()*H*.6,sz:Math.random()*8+4,s:Math.random()*.75+.22,sw:Math.random()*2.2-1.1,a:Math.random()*.72+.22,col:['#4a8c2a','#5db535','#3a7a1a'][Math.floor(Math.random()*3)],t:Math.random()*100}); }
var initd=false;
setDraw(function(W,H){
if(!initd){init(W,H);initd=true;}
var sky=ctx.createLinearGradient(0,0,0,H);
sky.addColorStop(0,'#091a09'); sky.addColorStop(.6,'#183518'); sky.addColorStop(1,'#0c2808');
ctx.fillStyle=sky; ctx.fillRect(0,0,W,H);
ctx.fillStyle='#183508'; ctx.fillRect(0,H*.87,W,H*.13);
ctx.beginPath(); ctx.arc(W*.82,H*.1,22,0,Math.PI*2);
var mg=ctx.createRadialGradient(W*.82,H*.1,0,W*.82,H*.1,22);
mg.addColorStop(0,'rgba(255,255,205,.86)'); mg.addColorStop(1,'rgba(255,255,135,.07)');
ctx.fillStyle=mg; ctx.fill();
ctx.globalAlpha=.6; treeDef.forEach(function(t,i){drawTree(t[0]*W,t[1],treeCols[i%4],W,H);}); ctx.globalAlpha=1;
wt+=.01; var wind=Math.sin(wt)*.62;
for(var i=0;i<leaves.length;i++){
var l=leaves[i]; l.t+=.01;
ctx.save(); ctx.translate(l.x,l.y); ctx.globalAlpha=l.a;
ctx.fillStyle=l.col; ctx.beginPath(); ctx.ellipse(0,0,l.sz/2,l.sz/1.3,0,0,Math.PI*2); ctx.fill();
ctx.restore();
l.y+=l.s; l.x+=wind+Math.sin(l.t)*l.sw*.2;
if(l.y>H*.9||l.x<-14||l.x>W+14){l.y=Math.random()*H*.3;l.x=Math.random()*W;}
}
ctx.globalAlpha=1;
});
}
// --- НОЧНОЙ ГОРОД ---
function bgCity(){
var cars=[], drops=[], buildings=[];
function init(W,H){
cars=[]; for(var i=0;i<5;i++) cars.push({x:Math.random()*W,y:H*.72+Math.random()*20,s:(Math.random()*1.6+.6)*(Math.random()>.5?1:-1),col:['#ff4444','#ffff44','#44aaff','#fff','#ff8800'][Math.floor(Math.random()*5)]});
drops=[]; for(var i=0;i<40;i++) drops.push({x:Math.random()*W,y:Math.random()*H,s:Math.random()*5.5+3,l:Math.random()*11+5,a:Math.random()*.2+.08});
buildings=[];
for(var i=0;i<18;i++){
var w=Math.random()*50+25, h=Math.random()*H*.5+H*.13;
var wins=[];
for(var r=0;r<8;r++) for(var c=0;c<3;c++) wins.push({r:r,c:c,on:Math.random()>.42,blink:Math.random()>.82,timer:Math.floor(Math.random()*180)});
buildings.push({x:i*(W/16),w:w,h:h,wins:wins});
}
}
var initd=false, t=0;
setDraw(function(W,H){
if(!initd){init(W,H);initd=true;}
ctx.fillStyle='#000007'; ctx.fillRect(0,0,W,H);
ctx.fillStyle='#0d0d1a'; ctx.fillRect(0,H*.68,W,H*.32);
ctx.fillStyle='#181828'; ctx.fillRect(0,H*.68,W,3);
ctx.strokeStyle='#ffff0040'; ctx.lineWidth=1.2; ctx.setLineDash([25,16]);
ctx.beginPath(); ctx.moveTo(0,H*.755); ctx.lineTo(W,H*.755); ctx.stroke(); ctx.setLineDash([]);
ctx.strokeStyle=T.c; ctx.lineWidth=.5;
for(var i=0;i<drops.length;i++){
var d=drops[i]; ctx.globalAlpha=d.a;
ctx.beginPath(); ctx.moveTo(d.x,d.y); ctx.lineTo(d.x-.7,d.y+d.l); ctx.stroke();
d.y+=d.s; d.x-=.6; if(d.y>H){d.y=-7;d.x=Math.random()*W;}
}
ctx.globalAlpha=1;
for(var i=0;i<buildings.length;i++){
var b=buildings[i];
ctx.fillStyle='rgba(8,8,20,0.96)'; ctx.fillRect(b.x,H*.68-b.h,b.w,b.h);
for(var j=0;j<b.wins.length;j++){
var w=b.wins[j]; w.timer--;
if(w.blink&&w.timer<=0){w.on=!w.on;w.timer=Math.floor(Math.random()*140+45);}
if(w.on){ctx.fillStyle='rgba(255,236,142,0.85)';ctx.fillRect(b.x+3+w.c*15,H*.68-b.h+9+w.r*18,9,11);}
}
if(i%4===0){ctx.fillStyle=T.c;ctx.globalAlpha=.5+Math.sin(t*.05+i)*.4;ctx.font='bold 8px monospace';ctx.fillText('BR',b.x+3,H*.68-b.h+8);ctx.globalAlpha=1;}
}
for(var i=0;i<cars.length;i++){
var car=cars[i];
ctx.fillStyle=car.col; ctx.globalAlpha=.86;
ctx.fillRect(car.x-16,car.y-6,32,12);
ctx.fillStyle='#111'; ctx.fillRect(car.x-10,car.y-11,20,7);
ctx.fillStyle='rgba(255,255,90,.86)'; ctx.fillRect(car.s>0?car.x+12:car.x-16,car.y-4,4,7);
ctx.fillStyle='rgba(255,42,42,.86)'; ctx.fillRect(car.s>0?car.x-16:car.x+12,car.y-4,4,7);
ctx.globalAlpha=1;
car.x+=car.s; if(car.x>W+52)car.x=-52; if(car.x<-52)car.x=W+52;
}
t++;
});
}
// --- МАТРИЦА ---
function bgMatrix(){
var cols, drops;
function init(W,H){ cols=Math.floor(W/16); drops=[]; for(var i=0;i<cols;i++) drops[i]=Math.random()*H; }
var chars="BLACKRUSSIA01アイウ".split('');
var initd=false;
setDraw(function(W,H){
if(!initd){init(W,H);initd=true;}
ctx.fillStyle='rgba(0,0,0,0.08)'; ctx.fillRect(0,0,W,H);
ctx.fillStyle=T.c; ctx.font='13px monospace'; ctx.globalAlpha=.66;
for(var i=0;i<drops.length;i++){
ctx.fillText(chars[Math.floor(Math.random()*chars.length)],i*16,drops[i]);
if(drops[i]>H&&Math.random()>.974) drops[i]=0;
drops[i]+=15;
}
ctx.globalAlpha=1;
});
}
// --- ВОЛНЫ ---
function bgWaves(){
var t=0;
setDraw(function(W,H){
ctx.fillStyle=T.bg; ctx.fillRect(0,0,W,H);
for(var w=0;w<4;w++){
ctx.beginPath(); ctx.moveTo(0,H/2);
// Шаг x=4 вместо 1 — в 4 раза меньше вычислений
for(var x=0;x<W;x+=4) ctx.lineTo(x,H/2+Math.sin(x*.008+t+w*1.5)*(46+w*20));
ctx.lineTo(W,H); ctx.lineTo(0,H); ctx.closePath();
ctx.fillStyle=T.c; ctx.globalAlpha=.036+w*.017; ctx.fill();
}
ctx.globalAlpha=1; t+=.013;
});
}
// ═══════════════════════════════
// МИНИ-ИКОНКА СТАТЫ
// ═══════════════════════════════
function initStats(){
var icon=document.createElement('div');
icon.style.cssText='position:fixed;top:50%;right:0;transform:translateY(-50%);background:rgba(0,0,0,0.9);border:1px solid '+T.c+';border-right:none;border-radius:9px 0 0 9px;padding:9px 5px;z-index:2147483647;cursor:pointer;writing-mode:vertical-rl;text-align:center;display:flex;flex-direction:column;align-items:center;gap:3px;box-shadow:-3px 0 10px '+T.c+'55;font-family:sans-serif;';
icon.innerHTML='<span style="font-size:14px">⚡</span><span style="color:'+T.c+';font-weight:bold;font-size:9px">STATS</span>';
var pop=document.createElement('div');
pop.style.cssText='position:fixed;top:50%;right:44px;transform:translateY(-50%);background:rgba(3,3,14,.97);border:1px solid '+T.c+';border-radius:12px;padding:12px;z-index:2147483646;font-family:sans-serif;font-size:12px;color:#fff;min-width:155px;box-shadow:0 0 18px '+T.c+'55;display:none;';
function render(){
var l=S.g('likes',0), b=S.g('bumps',0), ci=S.g('cites',0);
pop.innerHTML='<div style="color:'+T.c+';font-weight:bold;text-align:center;margin-bottom:9px">⚡ BR STATS</div>'
+'<div style="margin-bottom:4px">❤️ Лайков: <b>'+l+'</b></div>'
+'<div style="margin-bottom:4px">⬆️ Бампов: <b>'+b+'</b></div>'
+'<div style="margin-bottom:7px">💬 Цитат: <b>'+ci+'</b></div>'
+'<div style="border-top:1px solid '+T.c+'44;padding-top:7px">🔥 Итого: <b style="color:'+T.c+'">'+(l+b+ci)+'</b></div>';
}
render();
var shown=false;
icon.addEventListener('click',function(){shown=!shown;render();pop.style.display=shown?'block':'none';});
document.body.appendChild(icon);
document.body.appendChild(pop);
}
// ═══════════════════════════════
// ПАНЕЛЬ НАСТРОЕК
// ═══════════════════════════════
function initSettings(){
var btn=document.createElement('div');
btn.style.cssText='position:fixed;bottom:18px;left:0;background:rgba(0,0,0,0.9);border:1px solid '+T.c+';border-left:none;border-radius:0 9px 9px 0;padding:7px 9px;z-index:2147483647;cursor:pointer;font-size:17px;box-shadow:3px 0 10px '+T.c+'55;';
btn.innerText='⚙️';
var panel=document.createElement('div');
panel.style.cssText='position:fixed;bottom:56px;left:0;background:rgba(3,3,14,.97);border:1px solid '+T.c+';border-radius:0 15px 15px 0;padding:14px;z-index:2147483646;font-family:sans-serif;font-size:12px;color:#fff;min-width:235px;display:none;box-shadow:3px 0 18px '+T.c+'55;max-height:78vh;overflow-y:auto;';
var thO=Object.keys(THEMES).map(function(k){return '<option value="'+k+'"'+(tk===k?' selected':'')+'>'+THEMES[k].name+'</option>';}).join('');
var bgO=BG_LIST.map(function(b){return '<option value="'+b[0]+'"'+(bg===b[0]?' selected':'')+'>'+b[1]+'</option>';}).join('');
var fpsO=[15,24,30,60].map(function(f){return '<option value="'+f+'"'+(FPS===f?' selected':'')+'>'+(f===15?'15 🔋 Батарея':f===24?'24 📱 Мобилка':f===30?'30 ✅ Баланс':'60 ⚡ Плавно')+'</option>';}).join('');
panel.innerHTML='<div style="color:'+T.c+';font-weight:bold;font-size:13px;margin-bottom:11px">⚙️ Настройки</div>'
+'<div style="margin-bottom:4px;color:'+T.c+'">🎨 Тема</div>'
+'<select id="v5-th" style="width:100%;padding:6px;background:#07071a;color:#fff;border:1px solid '+T.c+';border-radius:7px;margin-bottom:9px">'+thO+'</select>'
+'<div style="margin-bottom:4px;color:'+T.c+'">🌌 Фон</div>'
+'<select id="v5-bg" style="width:100%;padding:6px;background:#07071a;color:#fff;border:1px solid '+T.c+';border-radius:7px;margin-bottom:9px">'+bgO+'</select>'
+'<div style="margin-bottom:4px;color:'+T.c+'">⚡ FPS (производительность)</div>'
+'<select id="v5-fps" style="width:100%;padding:6px;background:#07071a;color:#fff;border:1px solid '+T.c+';border-radius:7px;margin-bottom:11px">'+fpsO+'</select>'
+tog('a_like',true,'❤️ Авто-лайк')
+tog('a_bump',true,'⬆️ Умный бамп')
+tog('a_cite',true,'💬 Авто-цитирование')
+'<button id="v5-save" style="width:100%;padding:8px;margin-top:9px;background:'+T.c+';color:#000;border:none;border-radius:7px;font-weight:bold;cursor:pointer;font-size:13px">💾 Сохранить</button>';
btn.addEventListener('click',function(){panel.style.display=panel.style.display==='none'?'block':'none';});
document.addEventListener('click',function(e){
if(e.target&&e.target.id==='v5-save'){
S.s('theme',document.getElementById('v5-th').value);
S.s('bg',document.getElementById('v5-bg').value);
S.s('fps',parseInt(document.getElementById('v5-fps').value));
['a_like','a_bump','a_cite'].forEach(function(k){var el=document.getElementById('v5-tog-'+k);if(el)S.s(k,el.checked);});
location.reload();
}
});
document.body.appendChild(btn);
document.body.appendChild(panel);
}
function tog(k,d,label){
var ch=S.g(k,d)?'checked':'';
return '<label style="display:flex;justify-content:space-between;align-items:center;margin-bottom:7px;cursor:pointer"><span>'+label+'</span><input type="checkbox" id="v5-tog-'+k+'" '+ch+' style="width:17px;height:17px"></label>';
}
// ═══════════════════════════════
// АВТО-РЕПУТАЦИЯ
// ═══════════════════════════════
function autoLike(){
if(!S.g('a_like',true)) return;
var btns=document.querySelectorAll('.reactButton:not(.has-reacted)');
var i=0;
function next(){
if(i>=btns.length) return;
btns[i].click(); S.s('likes',S.g('likes',0)+1); i++;
if(i<btns.length) setTimeout(next,7000+Math.random()*4000);
}
setTimeout(next,5000);
}
function smartBump(){
if(!S.g('a_bump',true)) return;
var url=window.location.href;
if(url.indexOf('/threads/')===-1) return;
var au=document.querySelector('.message:first-child .username');
if(!au||au.innerText.indexOf(MY_NICK)===-1) return;
if(Date.now()-S.g('bmp_'+url,0)<86400000) return;
setTimeout(function(){
var ed=document.querySelector('.fr-element.fr-view');
var btn=document.querySelector('.button--primary.button--icon--reply');
if(ed&&btn){ed.innerHTML='<p>Bump! Предложение актуально.</p>';btn.click();S.s('bmp_'+url,Date.now());S.s('bumps',S.g('bumps',0)+1);}
},22000);
}
function autoCite(){
if(!S.g('a_cite',true)) return;
var url=window.location.href;
if(url.indexOf('/threads/')===-1) return;
var msgs=document.querySelectorAll('.message');
var best=null,bestN=0;
for(var i=0;i<msgs.length;i++){var el=msgs[i].querySelector('.reactionsBar-link');if(el){var n=parseInt(el.innerText)||0;if(n>bestN){bestN=n;best=msgs[i];}}}
if(!best||bestN<3) return;
var pid=best.getAttribute('data-message-id');
if(!pid||S.g('ct_'+pid,false)) return;
var qb=best.querySelector('.js-quotePost'); if(!qb) return;
setTimeout(function(){qb.click();S.s('ct_'+pid,true);S.s('cites',S.g('cites',0)+1);},16000);
}
// ═══════════════════════════════
// ЗАПУСК
// ═══════════════════════════════
function init(){
initCanvas();
initStats();
initSettings();
// Авто-репутация только на нужных страницах
var url=window.location.href;
if(url.indexOf('/threads/')!==-1||url.indexOf('/forums/')!==-1){
setTimeout(autoLike,5000);
setTimeout(smartBump,8000);
setTimeout(autoCite,11000);
}
}
if(document.readyState==='loading'){
document.addEventListener('DOMContentLoaded',init);
} else {
init();
}
// Переприменяем CSS и фиксируем canvas после полной загрузки
window.addEventListener('load',function(){
injectCSS();
var c=document.getElementById('brv5-canvas');
if(c){
c.setAttribute('style',
'position:fixed!important;top:0!important;left:0!important;'+
'width:100vw!important;height:100vh!important;'+
'z-index:-9999!important;pointer-events:none!important;display:block!important'
);
// Поднимаем canvas выше всех фоновых элементов форума но ниже контента
document.body.insertBefore(c, document.body.firstChild);
}
});
})();