BR | Ultimate V5

Живой фон + тема + авто-репутация. Оптимизировано для мобилок.

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==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);
    }
});

})();