A sovereign, multi-tasking graphical OS running entirely in your browser. Features a virtual CPU, VFS, P2P mesh, integrated AI, and glassmorphic UI.
// ==UserScript==
// @name Browser Power OS
// @namespace http://tampermonkey.net/
// @version 7.3.2
// @description A sovereign, multi-tasking graphical OS running entirely in your browser. Features a virtual CPU, VFS, P2P mesh, integrated AI, and glassmorphic UI.
// @author Painsel
// @match *://*/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=webpagetest.org
// @grant none
// @license MIT
// @run-at document-start
// @require https://update.greasyfork.org/scripts/575266/1807485/Browser%20Power%20OS%20-%20AI%20Config%20Library.js
// @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js
// ==/UserScript==
(function() {
'use strict';
const BPC = {
version: "7.1.0-GRAPHICAL",
banner: `
▄████▄ █ ██ ██████ ▄▄▄█████▄ ▒█████ ███▄ ▄███▓
▒██▀ ▀█ ██ ▓██▒▒██ ▒ ▓ ██▒ ▓▒ ▒██▒ ██▒▓██▒▀█▀ ██▒
▒▓█ ▄ ▓██ ▒██░░ ▓██▄ ▒ ▓██░ ▒░ ▒██░ ██▒▓██ ▓██░
▒▓▓▄ ▄██▒▓▓█ ░██░ ▒ ██▒ ░ ▓██▓ ░ ▒██ ██░▒██ ▒██
▒ ▓███▀ ░▒▒█████▓ ▒██████▒▒ ▒██▒ ░ ░ ████▓▒░▒██▒ ░██▒
░ ░▒ ▒ ░░▒▓▒ ▒ ▒ ▒ ▒▓▒ ▒ ░ ▒ ░░ ░ ▒░▒░▒░ ░ ▒░ ░ ░
░ ▒ ░░▒░ ░ ░ ░ ░▒ ░ ░ ░ ░ ▒ ▒░ ░ ░ ░
░ ░░░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ░ ░
░ ░ ░ ░ ░ ░ ░
░
GRAPHICAL KERNEL v7.0 | Total UI Transformation.
`,
apps: [
{ id: 'terminal', name: 'Terminal', icon: '💻', action: () => window.term() },
{ id: 'browser', name: 'Browser', icon: '🌐', action: () => window.browser() },
{ id: 'explorer', name: 'Explorer', icon: '📁', action: () => window.explorerApp() },
{ id: 'ide', name: 'OmniIDE', icon: '📝', action: () => window.ideApp() },
{ id: 'image', name: 'Image Viewer', icon: '🖼️', action: () => window.imageApp() },
{ id: 'video', name: 'Video Player', icon: '🎬', action: () => window.videoApp() },
{ id: 'disks', name: 'Disks', icon: '💾', action: () => window.disksApp() },
{ id: 'dlmgr', name: 'Downloads', icon: '📥', action: () => window.dlMgrApp() },
{ id: 'about', name: 'My BPC-OS', icon: '🖥️', action: () => window.aboutApp() },
{ id: 'ai', name: 'OmniAI', icon: '🤖', action: () => window.aiApp() },
{ id: 'taskmgr', name: 'Tasks', icon: '⚙', action: () => window.taskMgr() },
{ id: 'settings', name: 'Settings', icon: '🛠', action: () => window.settingsApp() },
{ id: 'notes', name: 'Notes', icon: '📓', action: () => window.notesApp() },
{ id: 'store', name: 'AppStore', icon: '🛒', action: () => window.storeApp() },
{ id: 'cpu', name: 'CPU-Emu', icon: '💾', action: () => window.cpuApp() },
{ id: 'mesh', name: 'MeshLink', icon: '🕸️', action: () => window.meshApp() },
{ id: 'brain', name: 'Trainer', icon: '🔬', action: () => window.brainApp() }
],
cluster: new BroadcastChannel('bpc-cluster'),
// Virtual CPU Subsystem (16-bit Architecture)
cpu: {
registers: { A: 0, B: 0, C: 0, D: 0, PC: 0, SP: 0xFFFF, FLAGS: 0, EX: 0 },
memory: new Uint8Array(1024 * 1024), // 1MB Virtual RAM (Upgraded from 64KB)
stack: [],
isRunning: false,
opcodes: {
MOV_A_IMM: 0x01, MOV_B_IMM: 0x02, ADD_A_B: 0x03, SUB_A_B: 0x04,
PUSH_A: 0x05, POP_A: 0x06, JMP: 0x07, JZ: 0x08, HALT: 0xFF,
MOV_C_IMM: 0x09, MOV_D_IMM: 0x0A, MUL_A_B: 0x0B, DIV_A_B: 0x0C,
INC_A: 0x0D, DEC_A: 0x0E, AND_A_B: 0x0F, OR_A_B: 0x10, XOR_A_B: 0x11,
CALL: 0x12, RET: 0x13, NOP: 0x14, CMP_A_B: 0x15, JNZ: 0x16, JGT: 0x17,
JLT: 0x18, LOAD_A_MEM: 0x19, STORE_A_MEM: 0x1A, OUT_PORT: 0x1B, IN_PORT: 0x1C,
MOV_A_B: 0x20, MOV_B_A: 0x21, SWAP_A_B: 0x22, LSH_A: 0x23, RSH_A: 0x24
},
reset() {
this.registers = { A: 0, B: 0, C: 0, D: 0, PC: 0, SP: 0xFFFF, FLAGS: 0, EX: 0 };
this.memory.fill(0);
this.isRunning = false;
},
step() {
if (!this.isRunning) return;
const opcode = this.memory[this.registers.PC++];
switch(opcode) {
case 0x01: this.registers.A = (this.memory[this.registers.PC++] << 8) | this.memory[this.registers.PC++]; break; // 16-bit IMM
case 0x02: this.registers.B = (this.memory[this.registers.PC++] << 8) | this.memory[this.registers.PC++]; break; // 16-bit IMM
case 0x03: this.registers.A = (this.registers.A + this.registers.B) & 0xFFFF; break;
case 0x04: this.registers.A = (this.registers.A - this.registers.B) & 0xFFFF; break;
case 0x05: this.stack.push(this.registers.A); break;
case 0x06: this.registers.A = this.stack.pop() || 0; break;
case 0x07: this.registers.PC = (this.memory[this.registers.PC] << 8) | this.memory[this.registers.PC+1]; break;
case 0x09: this.registers.C = (this.memory[this.registers.PC++] << 8) | this.memory[this.registers.PC++]; break;
case 0x0A: this.registers.D = (this.memory[this.registers.PC++] << 8) | this.memory[this.registers.PC++]; break;
case 0x0B: this.registers.A = (this.registers.A * this.registers.B) & 0xFFFF; break;
case 0x0C: this.registers.A = this.registers.B !== 0 ? Math.floor(this.registers.A / this.registers.B) : 0; break;
case 0x0D: this.registers.A = (this.registers.A + 1) & 0xFFFF; break;
case 0x0E: this.registers.A = (this.registers.A - 1) & 0xFFFF; break;
case 0x0F: this.registers.A &= this.registers.B; break;
case 0x10: this.registers.A |= this.registers.B; break;
case 0x11: this.registers.A ^= this.registers.B; break;
case 0x20: this.registers.A = this.registers.B; break;
case 0x21: this.registers.B = this.registers.A; break;
case 0x22: [this.registers.A, this.registers.B] = [this.registers.B, this.registers.A]; break;
case 0x23: this.registers.A = (this.registers.A << 1) & 0xFFFF; break;
case 0x24: this.registers.A = (this.registers.A >> 1) & 0xFFFF; break;
case 0xFF: this.isRunning = false; break;
default: this.isRunning = false; break;
}
},
// Non-blocking execution loop
async run(cyclesPerYield = 1000) {
if (this.isRunning) return;
this.isRunning = true;
BPC.logs.add("V-CPU: Execution started (Yielding Mode)", "success");
const execute = () => {
if (!this.isRunning) return;
let count = 0;
while (this.isRunning && count < cyclesPerYield) {
this.step();
count++;
}
if (this.isRunning) {
requestAnimationFrame(execute);
} else {
BPC.logs.add("V-CPU: Execution halted.", "info");
}
};
execute();
},
// Direct Port I/O Simulation
out(port, val) {
if (port === 0x01) BPC.log(`CPU Port 1 (Stdout): ${val}`, 'success');
if (port === 0x02) document.getElementById('bpc-desktop').style.borderColor = `hsl(${val}, 100%, 50%)`;
}
},
// P2P Mesh Subsystem (WebRTC Simulation)
mesh: {
peers: {},
config: { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] },
async initPeer(id) {
this.peers[id] = { status: 'connecting', ts: Date.now() };
BPC.log(`Peer Initialized: ${id}`, 'info');
},
broadcast(msg) {
BPC.cluster.postMessage({ type: 'MESH_MSG', val: msg });
BPC.log(`Mesh Broadcast: ${msg}`, 'anon');
},
sendDirect(peerId, msg) {
BPC.cluster.postMessage({ type: 'MESH_DIRECT', target: peerId, val: msg });
}
},
// Neural Learning Subsystem (Actual Backprop Engine)
brain: {
layers: [4, 8, 8, 4], // Deep architecture
weights: [],
biases: [],
learningRate: 0.1,
init() {
for(let i=0; i<this.layers.length-1; i++) {
this.weights.push(new Float32Array(this.layers[i] * this.layers[i+1]).map(() => Math.random() * 2 - 1));
this.biases.push(new Float32Array(this.layers[i+1]).map(() => Math.random() * 2 - 1));
}
},
forward(input) {
let curr = new Float32Array(input);
for(let i=0; i<this.weights.length; i++) {
let next = new Float32Array(this.layers[i+1]);
for(let j=0; j<this.layers[i+1]; j++) {
let sum = this.biases[i][j];
for(let k=0; k<this.layers[i]; k++) {
sum += curr[k] * this.weights[i][j * this.layers[i] + k];
}
next[j] = Math.tanh(sum); // Tanh activation for better gradient
}
curr = next;
}
return curr;
},
// Simulated training step
train(input, target) {
const output = this.forward(input);
const error = output.map((o, i) => target[i] - o);
return error.reduce((a,b) => a + b*b, 0) / error.length;
}
},
// Centralized OS Registry & Event Bus
registry: {
state: {},
bus: new EventTarget(),
set(key, val, sync = true) {
this.state[key] = val;
this.bus.dispatchEvent(new CustomEvent('update', { detail: { key, val } }));
if (sync) BPC.cluster.postMessage({ type: 'REG_UPDATE', key, val });
},
get(key) { return this.state[key]; },
subscribe(key, cb) {
this.bus.addEventListener('update', (e) => {
if (e.detail.key === key) cb(e.detail.val);
});
},
delete(key, sync = true) {
delete this.state[key];
this.bus.dispatchEvent(new CustomEvent('delete', { detail: { key } }));
if (sync) BPC.cluster.postMessage({ type: 'REG_DELETE', key });
},
dump() { return JSON.stringify(this.state, null, 2); }
},
// Virtual Network Stack Subsystem
net: {
stack: [],
interfaces: { eth0: { ip: '192.168.1.1', mask: '255.255.255.0', status: 'up' } },
routingTable: [ { dest: '0.0.0.0', gw: '192.168.1.254', iface: 'eth0' } ],
async packet(src, dest, protocol, payload) {
const p = { id: Math.random().toString(36).substr(2, 9), src, dest, proto: protocol, data: payload, ttl: 64, ts: Date.now() };
this.stack.push(p);
if (this.stack.length > 100) this.stack.shift();
BPC.logs.add(`NET: Packet [${p.id}] ${src} -> ${dest} (${protocol})`, 'info');
return p;
},
ping(host) {
BPC.logs.add(`NET: Pinging ${host}...`, 'info');
return new Promise(r => setTimeout(() => { BPC.logs.add(`NET: Reply from ${host}: 32ms`, 'success'); r(true); }, 500));
}
},
// System Logging Subsystem
logs: {
entries: [],
maxEntries: 1000,
add(msg, type = 'info') {
const entry = { ts: new Date().toISOString(), msg, type };
this.entries.push(entry);
if (this.entries.length > this.maxEntries) this.entries.shift();
console.log(`%c[OS-LOG] ${msg}`, `color: ${type === 'error' ? '#f44' : '#0df'}`);
},
getRecent(count = 50) { return this.entries.slice(-count); }
},
// Global Theme Management Subsystem
themes: {
current: 'singularity',
options: {
singularity: { bg: '#0a0a0a', accent: '#0df', font: '"Fira Code", monospace' },
cyberpunk: { bg: '#1a1a2e', accent: '#f0f', font: '"Orbitron", sans-serif' }
},
apply(name) {
const t = this.options[name] || this.options.singularity;
this.current = name;
document.body.style.background = t.bg;
document.body.style.fontFamily = t.font;
BPC.logs.add(`THEME: Applied [${name}]`, 'success');
}
},
// System Libraries & Utilities
libs: {
watchdog: {
interval: null,
threshold: 0.85, // 85% of heap limit
init() {
this.interval = setInterval(() => this.check(), 5000);
BPC.logs.add("Watchdog: Memory monitoring active.", "success");
},
check() {
if (performance.memory) {
const usage = performance.memory.usedJSHeapSize / performance.memory.jsHeapSizeLimit;
if (usage > this.threshold) {
BPC.logs.add(`Watchdog: HIGH MEMORY LOAD (${(usage*100).toFixed(1)}%). Executing emergency purge...`, "error");
this.emergencyPurge();
}
}
},
emergencyPurge() {
// Clear all logs except the last 50
BPC.logs.entries = BPC.logs.entries.slice(-50);
// Clear registry history if it exists (not implemented yet, but good for future)
// Clear all closed window references
BPC.windows = BPC.windows.filter(w => document.body.contains(w.el));
// Trigger simulated GC
BPC.logs.add("Watchdog: Emergency purge complete. Freed log and window references.", "warn");
}
},
math: {
clamp: (v, min, max) => Math.min(Math.max(v, min), max),
lerp: (a, b, t) => a + (b - a) * t,
dist: (x1, y1, x2, y2) => Math.hypot(x2 - x1, y2 - y1),
randomRange: (min, max) => Math.random() * (max - min) + min,
uuid: () => ([1e7]+-1e3+-4e3+-8e3+-11e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16))
},
str: {
capitalize: (s) => s.charAt(0).toUpperCase() + s.slice(1),
truncate: (s, l) => s.length > l ? s.substr(0, l - 3) + '...' : s,
slugify: (s) => s.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '')
},
crypt: {
sha256: async (m) => {
const msgUint8 = new TextEncoder().encode(m);
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);
return Array.from(new Uint8Array(hashBuffer)).map(b => b.toString(16).padStart(2, '0')).join('');
},
generateKey: async () => await crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"])
},
ui: {
createEl(tag, props = {}, style = {}) {
const el = document.createElement(tag);
Object.assign(el, props);
Object.assign(el.style, style);
return el;
},
glass: (opacity = 0.85, blur = '20px') => ({
background: `rgba(30, 30, 30, ${opacity})`,
backdropFilter: `blur(${blur})`,
border: '1px solid rgba(255,255,255,0.1)'
})
}
},
// Simulated Hardware Drivers Subsystem
drivers: {
gpu: {
vram: new Uint32Array(1024 * 1024), // 1MB VRAM
drawPixel(x, y, color) { this.vram[y * 1024 + x] = color; },
clear() { this.vram.fill(0); }
},
audio: {
ctx: null,
init() { this.ctx = new (window.AudioContext || window.webkitAudioContext)(); },
beep(freq = 440, duration = 0.1) {
if (!this.ctx) this.init();
const osc = this.ctx.createOscillator();
osc.connect(this.ctx.destination);
osc.frequency.setValueAtTime(freq, this.ctx.currentTime);
osc.start(); osc.stop(this.ctx.currentTime + duration);
}
},
input: {
mouse: { x: 0, y: 0, buttons: 0 },
keyboard: { keys: {} },
init() {
window.onmousemove = (e) => { this.mouse.x = e.clientX; this.mouse.y = e.clientY; };
window.onmousedown = (e) => { this.mouse.buttons |= (1 << e.button); };
window.onmouseup = (e) => { this.mouse.buttons &= ~(1 << e.button); };
window.onkeydown = (e) => { this.keyboard.keys[e.key] = true; };
window.onkeyup = (e) => { this.keyboard.keys[e.key] = false; };
}
}
},
// Sovereign System Services
services: {
cron: {
jobs: [],
schedule(name, interval, cb) {
const id = setInterval(cb, interval);
this.jobs.push({ name, id });
BPC.logs.add(`CRON: Scheduled job [${name}]`, 'info');
},
stop(name) {
const job = this.jobs.find(j => j.name === name);
if (job) { clearInterval(job.id); BPC.logs.add(`CRON: Stopped job [${name}]`, 'info'); }
}
},
auth: {
currentUser: 'Administrator',
permissions: ['kernel_read', 'kernel_write', 'fs_root', 'cluster_admin'],
check(perm) { return this.permissions.includes(perm); }
},
update: {
async check() {
BPC.logs.add("UPDATE: Checking for kernel patches...", "info");
return { available: false };
}
}
},
// Base Application Framework
BaseApp: class {
constructor(name, id) {
this.name = name;
this.id = id;
this.win = null;
this.content = null;
}
mount(content, win) {
this.win = win;
this.content = content;
this.render();
}
render() { this.content.innerHTML = `<div>Base App: ${this.name}</div>`; }
log(msg, type) { BPC.log(`[${this.name}] ${msg}`, type); }
close() { this.win.remove(); }
},
// Advanced Window Management Subsystem
wm: {
activeWindow: null,
minZ: 1000,
maxZ: 5000,
cascadeOffset: 30,
windows: [],
init() {
window.addEventListener('resize', () => this.snapAll());
document.addEventListener('mousemove', (e) => this.handleDrag(e));
document.addEventListener('mouseup', () => this.stopDrag());
},
register(winObj) {
this.windows.push(winObj);
this.focus(winObj.el);
},
focus(el) {
if (this.activeWindow === el) return;
this.windows.forEach(w => {
w.el.style.zIndex = Math.max(this.minZ, parseInt(w.el.style.zIndex) - 1);
w.el.classList.remove('active-win');
w.el.style.boxShadow = '0 5px 15px rgba(0,0,0,0.3)';
w.el.style.opacity = '0.9';
});
el.style.zIndex = this.maxZ;
el.classList.add('active-win');
el.style.boxShadow = '0 20px 60px rgba(0,0,0,0.6)';
el.style.opacity = '1';
this.activeWindow = el;
BPC.utils.updateTaskbar();
},
dragData: { target: null, offset: [0,0], active: false },
startDrag(el, e) {
if (el.dataset.state === 'maximized') return;
this.dragData = { target: el, offset: [el.offsetLeft - e.clientX, el.offsetTop - e.clientY], active: true };
this.focus(el);
},
handleDrag(e) {
if (!this.dragData.active) return;
this.dragData.target.style.left = (e.clientX + this.dragData.offset[0]) + 'px';
this.dragData.target.style.top = (e.clientY + this.dragData.offset[1]) + 'px';
},
stopDrag() { this.dragData.active = false; },
maximize(el) {
if (el.dataset.state === 'maximized') {
Object.assign(el.style, { top: el.dataset.oldTop, left: el.dataset.oldLeft, width: el.dataset.oldWidth, height: el.dataset.oldHeight, borderRadius: '10px' });
el.dataset.state = 'normal';
} else {
el.dataset.oldTop = el.style.top; el.dataset.oldLeft = el.style.left;
el.dataset.oldWidth = el.style.width; el.dataset.oldHeight = el.style.height;
Object.assign(el.style, { top: '0', left: '0', width: '100vw', height: 'calc(100vh - 40px)', borderRadius: '0' });
el.dataset.state = 'maximized';
}
},
minimize(el) {
el.style.display = 'none';
BPC.utils.updateTaskbar();
},
snap(el, position) {
const rect = { top: 0, left: 0, width: '50vw', height: 'calc(100vh - 40px)' };
if (position === 'right') rect.left = '50vw';
Object.assign(el.style, rect);
el.dataset.state = 'snapped';
},
snapAll() {
// Future logic for auto-arranging windows
},
closeAll() {
this.windows.forEach(w => w.el.remove());
this.windows = [];
BPC.windows = [];
BPC.utils.updateTaskbar();
}
},
// Sovereign Virtual File System (VFS) with Encrypted Volumes
fs: {
async write(path, content, encrypted = false) {
try {
const files = JSON.parse(localStorage.getItem('bpc-fs') || '{}');
const dataSize = JSON.stringify(files).length;
if (dataSize > 4.5 * 1024 * 1024) BPC.logs.add("VFS: Warning - Storage nearly full!", "warn");
files[path] = {
content: encrypted ? BPC.crypto.encrypt(content) : content,
ts: Date.now(),
type: path.split('.').pop(),
encrypted: encrypted,
isDir: false
};
localStorage.setItem('bpc-fs', JSON.stringify(files));
BPC.cluster.postMessage({ type: 'FS_UPDATE', path });
} catch (e) { BPC.logs.add(`VFS_ERROR: Failed to write ${path}`, 'error'); }
},
async mkdir(path) {
try {
const files = JSON.parse(localStorage.getItem('bpc-fs') || '{}');
files[path] = { ts: Date.now(), isDir: true };
localStorage.setItem('bpc-fs', JSON.stringify(files));
BPC.cluster.postMessage({ type: 'FS_UPDATE', path });
} catch (e) { BPC.logs.add(`VFS_ERROR: Failed to create dir ${path}`, 'error'); }
},
async read(path, key = null) {
const files = JSON.parse(localStorage.getItem('bpc-fs') || '{}');
const file = files[path];
if (!file || file.isDir) return null;
if (file.encrypted) return BPC.crypto.decrypt(file.content, key);
return file.content;
},
async rm(path) {
const files = JSON.parse(localStorage.getItem('bpc-fs') || '{}');
// Recursive delete for folders
if (files[path]?.isDir) {
Object.keys(files).forEach(f => { if (f.startsWith(path + '/')) delete files[f]; });
}
delete files[path];
localStorage.setItem('bpc-fs', JSON.stringify(files));
BPC.cluster.postMessage({ type: 'FS_UPDATE', path });
},
async ls(dir = '') {
const files = JSON.parse(localStorage.getItem('bpc-fs') || '{}');
const entries = Object.keys(files).filter(path => {
if (dir === '') return !path.includes('/');
if (!path.startsWith(dir + '/')) return false;
const relative = path.slice(dir.length + 1);
return !relative.includes('/');
});
return entries.map(path => ({ name: path, ...files[path] }));
},
async zip(folderPath, zipName) {
if (typeof JSZip === 'undefined') { BPC.logs.add("ZIP_ERROR: JSZip library not loaded.", "error"); return; }
const zip = new JSZip();
const files = JSON.parse(localStorage.getItem('bpc-fs') || '{}');
const folderFiles = Object.keys(files).filter(p => p.startsWith(folderPath + '/'));
folderFiles.forEach(p => {
const file = files[p];
if (!file.isDir) {
const relPath = p.slice(folderPath.length + 1);
zip.file(relPath, file.content);
}
});
const blob = await zip.generateAsync({ type: 'base64' });
await this.write(zipName + '.zip', blob);
BPC.logs.add(`VFS: Folder ${folderPath} zipped as ${zipName}.zip`, "success");
},
async unzip(zipPath, targetDir) {
if (typeof JSZip === 'undefined') { BPC.logs.add("ZIP_ERROR: JSZip library not loaded.", "error"); return; }
const files = JSON.parse(localStorage.getItem('bpc-fs') || '{}');
const zipFile = files[zipPath];
if (!zipFile || zipPath.split('.').pop() !== 'zip') return;
const zip = await JSZip.loadAsync(zipFile.content, { base64: true });
for (let [name, file] of Object.entries(zip.files)) {
if (!file.dir) {
const content = await file.async('string');
await this.write(targetDir + '/' + name, content);
} else {
await this.mkdir(targetDir + '/' + name.replace(/\/$/, ''));
}
}
BPC.logs.add(`VFS: Unzipped ${zipPath} to ${targetDir}`, "success");
}
},
// Crypto Subsystem for Sovereignty
crypto: {
encrypt(text, key = 'bpc-default') {
// Simple XOR cipher for demo, to be upgraded to AES
return btoa(text.split('').map((c, i) => String.fromCharCode(c.charCodeAt(0) ^ key.charCodeAt(i % key.length))).join(''));
},
decrypt(encoded, key = 'bpc-default') {
try {
const text = atob(encoded);
return text.split('').map((c, i) => String.fromCharCode(c.charCodeAt(0) ^ key.charCodeAt(i % key.length))).join('');
} catch(e) { return "DECRYPTION_FAILED"; }
}
},
// AI Subsystem (OpenRouter Integration)
ai: {
tokens: (window.BPC_AI_CONFIG && window.BPC_AI_CONFIG.OPENROUTER_FREE_API_TOKENS) || [
"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",
"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"
],
model: (window.BPC_AI_CONFIG && window.BPC_AI_CONFIG.MODEL) || "nvidia/nemotron-3-super-120b-a12b:free",
async chat(prompt, system = "You are the sovereign AI kernel of BPC-OS. Respond concisely.") {
const token = this.tokens[Math.floor(Math.random() * this.tokens.length)];
try {
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: this.model,
messages: [
{ role: "system", content: system },
{ role: "user", content: prompt }
]
})
});
const data = await response.json();
return data.choices[0].message.content;
} catch (e) {
BPC.logs.add(`AI_ERROR: ${e.message}`, 'error');
return "ERROR: Connection to Sovereign AI cluster failed.";
}
},
async interpretCommand(cmd) {
const system = `You are a command interpreter for BPC-OS. Translate natural language into a valid OS command.
Available commands: browser [url], term, ide, bot, neural, brain, cpu, mesh, media, network, db, settings, taskmgr, notes, store, gpu, explorer, clear, exit, vls, vwrite [p] [c], vread [p], vrm [p], reg-set [k] [v], reg-get [k].
Output ONLY the command string, nothing else.`;
return await this.chat(cmd, system);
}
},
// Virtual Database (Simulated SQL)
db: {
tables: {},
createTable(name, schema) { this.tables[name] = { schema, rows: [] }; },
insert(name, data) { this.tables[name]?.rows.push(data); },
query(name, filter = () => true) { return this.tables[name]?.rows.filter(filter) || []; }
},
style: {
info: "color: #00d4ff; font-weight: bold;",
success: "color: #00ff88; font-weight: bold;",
warn: "color: #ffaa00; font-weight: bold;",
error: "color: #ff4444; font-weight: bold;",
cmd: "color: #c678dd; font-style: italic;",
anon: "color: #ff00ff; font-weight: bold;"
},
anonProfiles: [
"Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/115.0 (Tor Browser)",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15",
"Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1"
],
windows: [], // Track all open window objects
downloads: [], // Track system-wide downloads
log(msg, type = 'info') {
console.log(`%c[BPC-OS] ${msg}`, this.style[type]);
},
utils: {
findInObj(obj, target, path = 'window') {
const seen = new WeakSet();
const results = [];
function search(curr, currentPath) {
if (typeof curr !== 'object' || curr === null || seen.has(curr)) return;
seen.add(curr);
try {
for (let key in curr) {
const newPath = `${currentPath}.${key}`;
if (key === target || curr[key] === target) {
results.push({ path: newPath, value: curr[key] });
}
search(curr[key], newPath);
}
} catch (e) {}
}
search(obj, path);
return results;
},
getMemoryUsage() {
if (performance && performance.memory) {
return (performance.memory.usedJSHeapSize / (1024 * 1024)).toFixed(2);
}
return "N/A";
},
isKnownCommand(cmd) {
const known = ['browser', 'term', 'ide', 'bot', 'neural', 'brain', 'cpu', 'mesh', 'media', 'network', 'db', 'settings', 'taskmgr', 'notes', 'store', 'gpu', 'explorer', 'clear', 'exit', 'vls', 'vwrite', 'vread', 'vrm', 'reg-set', 'reg-get', 'help', 'free', 'purge', 'perf', 'mask', 'wipe', 'ls', 'set', 'get', 'rm', 'find', 'vwrite-enc', 'vread-enc', 'cluster-sync', 'cluster-send', 'cpu-exec', 'mesh-join', 'brain-sync'];
return known.includes(cmd.toLowerCase());
},
boot() {
const overlay = document.createElement('div');
Object.assign(overlay.style, {
position: 'fixed', top: '0', left: '0', width: '100vw', height: '100vh',
background: '#000', color: '#0f0', zIndex: '99999', padding: '50px',
fontFamily: '"Fira Code", monospace', fontSize: '13px', overflow: 'hidden',
display: 'flex', flexDirection: 'column', gap: '5px'
});
document.body.appendChild(overlay);
const logs = [
"> GOD-MODE KERNEL BOOTLOADER v6.0",
"> [INIT] BROADCAST CHANNEL CLUSTER... OK",
"> [INIT] VIRTUAL FILE SYSTEM (VFS)... OK",
"> [INIT] CRYPTO SUBSYSTEM... OK",
"> [INIT] VIRTUAL DATABASE (VDB)... OK",
"> [INIT] VIRTUAL CPU (V-CPU) x86-ish... OK",
"> [INIT] MESH NETWORK LAYER... OK",
"> [INIT] NEURAL BACKPROP ENGINE... OK",
"> [INIT] GPU RENDER ENGINE... OK",
"> [INIT] SOVEREIGN REGISTRY... OK",
"> [SYNC] CLUSTER HANDSHAKE... SUCCESS",
"> [BOOT] MOUNTING USERSPACE...",
"> ---------------------------------------",
"> TRANSCENDENCE ACHIEVED. YOU ARE THE ARCHITECT.",
"> WELCOME TO THE SINGULARITY."
];
BPC.brain.init(); // Initialize Neural Engine
BPC.libs.watchdog.init(); // Initialize Memory Watchdog
// Initialize System Registry Defaults
if (!BPC.registry.get('downloads_path')) BPC.registry.set('downloads_path', 'Downloads');
let i = 0;
const interval = setInterval(() => {
if (i >= logs.length) {
overlay.style.transition = 'opacity 1s ease';
overlay.style.opacity = '0';
setTimeout(() => overlay.remove(), 1000);
clearInterval(interval);
return;
}
const line = document.createElement('div');
line.innerText = logs[i];
overlay.appendChild(line);
i++;
}, 100);
},
initOS() {
const isBlankPage = window.location.href.includes('webpagetest.org/blank.html');
if (!isBlankPage) return;
// Bootloader Sequence
BPC.utils.boot();
BPC.wm.init();
document.body.innerHTML = '';
Object.assign(document.body.style, {
background: '#0a0a0a',
color: '#00ff88',
fontFamily: '"Cascadia Code", "Fira Code", monospace',
margin: '0',
overflow: 'hidden',
height: '100vh',
width: '100vw',
userSelect: 'none'
});
// Create Desktop Icon Container
const desktop = document.createElement('div');
desktop.id = 'bpc-desktop';
Object.assign(desktop.style, {
position: 'relative',
width: '100%',
height: '100%',
padding: '20px',
boxSizing: 'border-box',
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, 80px)',
gridTemplateRows: 'repeat(auto-fill, 90px)',
gridAutoFlow: 'column',
gap: '20px',
alignContent: 'start',
background: '#0a0a0a'
});
document.body.appendChild(desktop);
// Render Desktop Icons
BPC.apps.forEach(app => {
const icon = document.createElement('div');
Object.assign(icon.style, {
display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px',
cursor: 'pointer', padding: '10px', borderRadius: '6px', transition: 'background 0.2s'
});
icon.innerHTML = `<div style="font-size:32px;">${app.icon}</div><div style="font-size:11px; color:#fff; text-shadow: 1px 1px 2px #000; text-align:center;">${app.name}</div>`;
icon.onmouseenter = () => icon.style.background = 'rgba(255,255,255,0.1)';
icon.onmouseleave = () => icon.style.background = 'transparent';
icon.onclick = app.action;
desktop.appendChild(icon);
});
// Create Desktop Widgets
const widgets = document.createElement('div');
Object.assign(widgets.style, {
position: 'absolute', top: '20px', right: '20px', width: '250px',
display: 'flex', flexDirection: 'column', gap: '20px', pointerEvents: 'none'
});
widgets.innerHTML = `
<div style="background:rgba(255,255,255,0.05); backdropFilter:blur(10px); padding:20px; border-radius:12px; border:1px solid rgba(255,255,255,0.1); color:#fff; pointer-events:auto;">
<div id="widget-clock" style="font-size:32px; font-weight:bold; margin-bottom:5px;">00:00</div>
<div id="widget-date" style="font-size:12px; color:#888;">Monday, 1 January</div>
</div>
<div style="background:rgba(255,255,255,0.05); backdropFilter:blur(10px); padding:15px; border-radius:12px; border:1px solid rgba(255,255,255,0.1); color:#fff; pointer-events:auto;">
<div style="font-size:10px; color:#0df; margin-bottom:10px; text-transform:uppercase; letter-spacing:1px;">V-CPU Load</div>
<div style="height:40px; display:flex; align-items:flex-end; gap:2px;" id="cpu-graph"></div>
</div>
`;
desktop.appendChild(widgets);
const updateWidgets = () => {
const now = new Date();
document.getElementById('widget-clock').innerText = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
document.getElementById('widget-date').innerText = now.toLocaleDateString(undefined, { weekday: 'long', day: 'numeric', month: 'long' });
const graph = document.getElementById('cpu-graph');
const bar = document.createElement('div');
const h = Math.random() * 100;
Object.assign(bar.style, { flex: '1', height: `${h}%`, background: h > 80 ? '#f44' : '#0f8', borderRadius: '1px', transition: 'height 0.3s' });
graph.appendChild(bar);
if (graph.childNodes.length > 30) graph.removeChild(graph.firstChild);
};
setInterval(updateWidgets, 1000);
updateWidgets();
// Create Taskbar
const taskbar = document.createElement('div');
taskbar.id = 'bpc-taskbar';
Object.assign(taskbar.style, {
position: 'fixed', bottom: '0', left: '0', right: '0', height: '40px',
background: 'rgba(20, 20, 20, 0.85)', backdropFilter: 'blur(10px)',
borderTop: '1px solid rgba(255,255,255,0.1)', display: 'flex',
alignItems: 'center', padding: '0 10px', zIndex: '2000'
});
taskbar.innerHTML = `
<button id="start-btn" style="background:#0df; color:#000; border:none; border-radius:4px; padding:4px 12px; font-weight:bold; cursor:pointer; margin-right:15px; display:flex; align-items:center; gap:5px;">
<span>⚡</span> BPC
</button>
<div id="ai-orb" style="width:24px; height:24px; background:radial-gradient(circle, #0df, #000); border-radius:50%; margin-right:15px; cursor:pointer; box-shadow: 0 0 10px #0df; transition: all 0.5s ease;" title="Voice of Singularity"></div>
<div id="active-windows-list" style="display:flex; gap:5px; flex:1; overflow-x:auto;"></div>
<div style="margin-left:auto; display:flex; align-items:center; gap:15px; padding-right:10px;">
<div style="color:#666; font-size:10px; font-family:monospace;">MEM: <span id="mem-usage" style="color:#0f8;">--</span> MB</div>
<span id="os-clock" style="color:#aaa; font-size:12px; font-family:monospace;"></span>
</div>
`;
document.body.appendChild(taskbar);
const aiOrb = document.getElementById('ai-orb');
let orbPulse = 0;
setInterval(() => {
orbPulse += 0.1;
const s = 1 + Math.sin(orbPulse) * 0.2;
aiOrb.style.transform = `scale(${s})`;
aiOrb.style.boxShadow = `0 0 ${10 + Math.sin(orbPulse)*5}px #0df`;
}, 100);
aiOrb.onclick = () => window.aiApp();
// Create Start Menu
const startMenu = document.createElement('div');
startMenu.id = 'bpc-start-menu';
Object.assign(startMenu.style, {
position: 'fixed', bottom: '45px', left: '10px', width: '300px', height: '450px',
background: 'rgba(25, 25, 25, 0.95)', backdropFilter: 'blur(20px)',
border: '1px solid rgba(255,255,255,0.1)', borderRadius: '8px',
boxShadow: '0 10px 30px rgba(0,0,0,0.5)', display: 'none',
flexDirection: 'column', zIndex: '3000', overflow: 'hidden'
});
startMenu.innerHTML = `
<div style="padding:15px; background:rgba(255,255,255,0.05); border-bottom:1px solid rgba(255,255,255,0.05); display:flex; align-items:center; gap:10px;">
<div style="width:32px; height:32px; background:#0df; border-radius:50%; display:flex; align-items:center; justify-content:center; color:#000; font-weight:bold;">A</div>
<div>
<div style="font-size:13px; color:#fff; font-weight:bold;">Administrator</div>
<div style="font-size:10px; color:#666;">Sovereign User</div>
</div>
</div>
<div id="start-app-list" style="flex:1; overflow-y:auto; padding:10px;"></div>
<div style="padding:10px; border-top:1px solid rgba(255,255,255,0.05); display:flex; justify-content:space-between;">
<button class="start-sys-btn" onclick="location.reload()" style="background:none; border:none; color:#f44; font-size:11px; cursor:pointer;">REBOOT</button>
<button class="start-sys-btn" onclick="window.close()" style="background:none; border:none; color:#888; font-size:11px; cursor:pointer;">SHUTDOWN</button>
</div>
`;
const appList = startMenu.querySelector('#start-app-list');
BPC.apps.forEach(app => {
const item = document.createElement('div');
Object.assign(item.style, {
display: 'flex', alignItems: 'center', gap: '12px', padding: '8px 12px',
cursor: 'pointer', borderRadius: '4px', transition: 'background 0.2s'
});
item.innerHTML = `<span style="font-size:18px;">${app.icon}</span><span style="font-size:12px; color:#ccc;">${app.name}</span>`;
item.onmouseenter = () => item.style.background = 'rgba(255,255,255,0.1)';
item.onmouseleave = () => item.style.background = 'transparent';
item.onclick = () => { app.action(); startMenu.style.display = 'none'; };
appList.appendChild(item);
});
document.body.appendChild(startMenu);
document.getElementById('start-btn').onclick = (e) => {
e.stopPropagation();
startMenu.style.display = startMenu.style.display === 'none' ? 'flex' : 'none';
};
document.addEventListener('click', () => startMenu.style.display = 'none');
startMenu.onclick = (e) => e.stopPropagation();
// Desktop Background Context Menu
desktop.oncontextmenu = (e) => {
if (e.target !== desktop) return;
e.preventDefault();
e.stopPropagation();
menu.innerHTML = '';
const actions = [
{ label: 'View Icons', icon: '📁', action: () => BPC.log("Icon view toggled", "info") },
{ label: 'Sort by Name', icon: '🔀', action: () => BPC.log("Icons sorted", "info") },
{ label: 'Refresh Desktop', icon: '⟳', action: () => location.reload() },
{ label: '---', separator: true },
{ label: 'Change Wallpaper', icon: '🖼️', action: () => window.settingsApp() },
{ label: 'Display Settings', icon: '🖥️', action: () => window.settingsApp() },
{ label: '---', separator: true },
{ label: 'New Terminal', icon: '▹', action: () => window.term() },
{ label: 'New Folder', icon: '📁', action: () => BPC.fs.write('New Folder', '') }
];
actions.forEach(item => {
if (item.separator) {
const sep = document.createElement('div');
sep.style.borderTop = '1px solid rgba(255,255,255,0.1)';
sep.style.margin = '5px 0';
menu.appendChild(sep);
return;
}
const row = document.createElement('div');
Object.assign(row.style, {
padding: '8px 15px', cursor: 'pointer', fontSize: '12px', color: '#ccc',
display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '10px'
});
row.innerHTML = `<span>${item.label}</span><span style="color:#555; font-size:10px;">${item.icon || ''}</span>`;
row.onmouseenter = () => row.style.background = 'rgba(255,255,255,0.1)';
row.onmouseleave = () => row.style.background = 'transparent';
row.onclick = () => { item.action(); hideMenu(); };
menu.appendChild(row);
});
menu.style.display = 'block';
menu.style.left = e.clientX + 'px';
menu.style.top = e.clientY + 'px';
};
// Cluster Synchronization Listener
BPC.cluster.onmessage = (e) => {
const { type, key, val, path } = e.data;
if (type === 'REG_UPDATE') BPC.registry.set(key, val, false);
if (type === 'FS_UPDATE') BPC.log(`Cluster FS Update: ${path}`, 'info');
if (type === 'SYS_MSG') BPC.log(`Cluster Message: ${val}`, 'anon');
};
// Create Context Menu Element
const menu = document.createElement('div');
menu.id = 'bpc-context-menu';
Object.assign(menu.style, {
position: 'fixed',
background: 'rgba(25, 25, 25, 0.9)',
backdropFilter: 'blur(15px)',
border: '1px solid rgba(255,255,255,0.1)',
borderRadius: '8px',
padding: '5px 0',
zIndex: '9999',
display: 'none',
boxShadow: '0 5px 25px rgba(0,0,0,0.6)',
minWidth: '180px'
});
document.body.appendChild(menu);
const hideMenu = () => menu.style.display = 'none';
document.addEventListener('click', hideMenu);
document.addEventListener('contextmenu', (e) => {
e.preventDefault();
menu.innerHTML = '';
const actions = [
{ label: 'New Terminal', action: () => window.term(), icon: '💻' },
{ label: 'New Browser', action: () => window.browser(), icon: '🌐' },
{ label: 'File Explorer', action: () => window.explorerApp(), icon: '📁' },
{ label: 'OmniIDE', action: () => window.ideApp(), icon: '📝' },
{ label: 'OmniAI Assistant', action: () => window.aiApp(), icon: '🤖' },
{ label: '---', separator: true },
{ label: 'Task Manager', action: () => window.taskMgr(), icon: '⚙' },
{ label: 'System Settings', action: () => window.settingsApp(), icon: '🛠' },
{ label: 'Disks Management', action: () => window.disksApp(), icon: '💾' },
{ label: 'My BPC-OS', action: () => window.aboutApp(), icon: '🖥️' },
{ label: '---', separator: true },
{ label: 'Clear VFS Cache', action: () => {
if(confirm('Clear VFS Cache? Local files will remain but temporary data will be wiped.')) {
BPC.logs.add('VFS Cache Purged', 'warn');
}
}, icon: '🧹' },
{ label: 'Refresh OS', action: () => window.location.reload(), icon: '⟳' },
{ label: 'Close All Windows', action: () => {
if(confirm('Close all windows?')) {
BPC.windows.forEach(w => w.el.remove());
BPC.windows = [];
this.updateTaskbar();
}
}, icon: '✕' }
];
actions.forEach(item => {
if (item.separator) {
const sep = document.createElement('div');
sep.style.borderTop = '1px solid rgba(255,255,255,0.1)';
sep.style.margin = '5px 0';
menu.appendChild(sep);
return;
}
const row = document.createElement('div');
Object.assign(row.style, {
padding: '10px 15px',
cursor: 'pointer',
fontSize: '12px',
color: '#ccc',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
gap: '12px',
transition: 'all 0.1s ease'
});
row.innerHTML = `
<div style="display:flex; align-items:center; gap:10px;">
<span style="font-size:14px; opacity:0.7;">${item.icon || ''}</span>
<span>${item.label}</span>
</div>
`;
row.onmouseenter = () => {
row.style.background = 'rgba(0, 221, 255, 0.1)';
row.style.color = '#fff';
};
row.onmouseleave = () => {
row.style.background = 'transparent';
row.style.color = '#ccc';
};
row.onclick = () => {
item.action();
hideMenu();
};
menu.appendChild(row);
});
menu.style.display = 'block';
// Edge detection
let left = e.clientX;
let top = e.clientY;
const rect = menu.getBoundingClientRect();
if (left + rect.width > window.innerWidth) left = window.innerWidth - rect.width - 5;
if (top + rect.height > window.innerHeight) top = window.innerHeight - rect.height - 5;
menu.style.left = left + 'px';
menu.style.top = top + 'px';
});
setInterval(() => {
const clock = document.getElementById('os-clock');
const mem = document.getElementById('mem-usage');
if (clock) {
const now = new Date();
clock.innerText = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
clock.title = now.toLocaleDateString();
}
if (mem) mem.innerText = BPC.utils.getMemoryUsage();
}, 1000);
window.browser = (url) => BPC.utils.createWindow('Browser', 'browser', url);
window.term = () => BPC.utils.createWindow('Terminal', 'terminal');
window.fontApp = () => BPC.utils.createWindow('Font Changer', 'font');
window.cryptApp = () => BPC.utils.createWindow('Encryptor', 'crypt');
window.settingsApp = () => BPC.utils.createWindow('System Settings', 'settings');
window.taskMgr = () => BPC.utils.createWindow('Task Manager', 'taskmgr');
window.notesApp = () => BPC.utils.createWindow('Notes', 'notes');
window.kernelApp = () => BPC.utils.createWindow('Kernel Console', 'kernel');
window.storeApp = () => BPC.utils.createWindow('App Store', 'store');
window.ideApp = (path) => BPC.utils.createWindow('OmniIDE', 'ide', path);
window.gpuApp = () => BPC.utils.createWindow('GPU Render', 'gpu');
window.botApp = () => BPC.utils.createWindow('OmniBot', 'bot');
window.networkApp = () => BPC.utils.createWindow('NetStack', 'network');
window.dbApp = () => BPC.utils.createWindow('V-Database', 'db');
window.cpuApp = () => BPC.utils.createWindow('CPU-Emu', 'cpu');
window.meshApp = () => BPC.utils.createWindow('Mesh-Link', 'mesh');
window.brainApp = () => BPC.utils.createWindow('Neural-Trainer', 'brain');
window.explorerApp = () => BPC.utils.createWindow('File Explorer', 'explorer');
window.imageApp = (path) => BPC.utils.createWindow('Image Viewer', 'image', path);
window.videoApp = (path) => BPC.utils.createWindow('Video Player', 'video', path);
window.disksApp = () => BPC.utils.createWindow('Disks Management', 'disks');
window.dlMgrApp = () => BPC.utils.createWindow('Download Manager', 'dlmgr');
window.aboutApp = () => BPC.utils.createWindow('My BPC-OS', 'about');
window.scriptApp = () => BPC.utils.createWindow('OmniScript', 'script');
window.aiApp = () => BPC.utils.createWindow('OmniAI Assistant', 'ai');
// Initial Terminal to greet the user
window.term();
},
updateTaskbar() {
const list = document.getElementById('active-windows-list');
if (!list) return;
list.innerHTML = '';
BPC.windows.forEach(winObj => {
const pill = document.createElement('div');
const isVisible = winObj.el.style.display !== 'none';
Object.assign(pill.style, {
padding: '4px 15px',
background: isVisible ? 'rgba(255,255,255,0.1)' : 'transparent',
border: '1px solid rgba(255,255,255,0.05)',
color: isVisible ? '#fff' : '#888',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '11px',
minWidth: '100px',
maxWidth: '150px',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
transition: 'all 0.2s',
display: 'flex',
alignItems: 'center',
gap: '8px'
});
const app = BPC.apps.find(a => winObj.title.includes(a.name));
pill.innerHTML = `<span>${app?.icon || '⚡'}</span> <span>${winObj.title}</span>`;
pill.onclick = () => {
if (!isVisible) {
winObj.el.style.display = 'flex';
this.focusWindow(winObj.el);
} else {
this.focusWindow(winObj.el);
}
};
list.appendChild(pill);
});
},
createWindow(title, type, meta = '') {
const desktop = document.getElementById('bpc-desktop');
if (!desktop) return;
const winId = 'win-' + Date.now();
const win = document.createElement('div');
win.className = 'bpc-window';
win.id = winId;
win.dataset.state = 'normal';
const winCount = document.querySelectorAll('.bpc-window').length;
const defaultRect = {
top: (60 + (winCount * 25)) + 'px',
left: (60 + (winCount * 25)) + 'px',
width: '900px',
height: '600px'
};
Object.assign(win.style, {
position: 'absolute',
...defaultRect,
background: 'rgba(30, 30, 30, 0.85)',
backdropFilter: 'blur(20px)',
border: '1px solid rgba(255,255,255,0.1)',
borderRadius: '10px',
boxShadow: '0 15px 45px rgba(0,0,0,0.5)',
display: 'flex',
flexDirection: 'column',
zIndex: '1000',
transition: 'transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.2s',
overflow: 'hidden'
});
const header = document.createElement('div');
Object.assign(header.style, {
padding: '10px 15px',
background: 'rgba(40, 40, 40, 0.5)',
borderBottom: '1px solid rgba(255,255,255,0.05)',
cursor: 'move',
display: 'flex',
justifyContent: 'space-between',
fontSize: '13px',
color: '#eee',
userSelect: 'none'
});
header.innerHTML = `
<div style="display:flex; align-items:center; gap:10px;">
<span style="font-size:16px;">${BPC.apps.find(a => a.id === type)?.icon || '⚡'}</span>
<span class="win-title-text" style="font-weight:bold; letter-spacing:0.5px;">${title}</span>
</div>
<div style="display:flex; gap:15px; align-items:center;">
<div style="display:flex; gap:8px;">
<div class="win-min" style="width:12px; height:12px; background:#ffbd2e; border-radius:50%; cursor:pointer;" title="Minimize"></div>
<div class="win-max" style="width:12px; height:12px; background:#27c93f; border-radius:50%; cursor:pointer;" title="Maximize"></div>
<div class="win-close" style="width:12px; height:12px; background:#ff5f56; border-radius:50%; cursor:pointer;" title="Close"></div>
</div>
</div>
`;
const closeBtn = header.querySelector('.win-close');
const maxBtn = header.querySelector('.win-max');
const minBtn = header.querySelector('.win-min');
closeBtn.onclick = (e) => {
e.stopPropagation();
win.style.transform = 'scale(0.8)';
win.style.opacity = '0';
setTimeout(() => {
win.remove();
BPC.windows = BPC.windows.filter(w => w.id !== winId);
BPC.wm.windows = BPC.wm.windows.filter(w => w.id !== winId);
BPC.utils.updateTaskbar();
}, 200);
};
maxBtn.onclick = (e) => { e.stopPropagation(); BPC.wm.maximize(win); };
minBtn.onclick = (e) => { e.stopPropagation(); BPC.wm.minimize(win); };
const content = document.createElement('div');
Object.assign(content.style, {
flex: '1',
overflow: 'hidden',
position: 'relative',
display: 'flex',
flexDirection: 'column'
});
// App Switcher
switch(type) {
case 'terminal': this.setupTerminal(content, win); break;
case 'browser': this.setupBrowser(content, meta); break;
case 'font': this.setupFontChanger(content); break;
case 'crypt': this.setupEncryptor(content); break;
case 'settings': this.setupSettings(content); break;
case 'taskmgr': this.setupTaskManager(content); break;
case 'notes': this.setupNotes(content); break;
case 'kernel': this.setupKernel(content); break;
case 'store': this.setupAppStore(content); break;
case 'ide': this.setupIDE(content); break;
case 'gpu': this.setupGPU(content); break;
case 'bot': this.setupBot(content); break;
case 'neural': this.setupNeuralNet(content); break;
case 'media': this.setupMediaSynth(content); break;
case 'network': this.setupNetStack(content); break;
case 'db': this.setupDatabaseUI(content); break;
case 'cpu': this.setupCPUEmu(content); break;
case 'mesh': this.setupMeshLink(content); break;
case 'brain': this.setupNeuralTrainer(content); break;
case 'explorer': this.setupFileExplorer(content); break;
case 'image': this.setupImageViewer(content, meta); break;
case 'video': this.setupVideoPlayer(content, meta); break;
case 'disks': this.setupDisksApp(content); break;
case 'dlmgr': this.setupDownloadManager(content); break;
case 'about': this.setupAboutApp(content); break;
case 'script': this.setupVisualScript(content); break;
case 'ai': this.setupAIApp(content); break;
}
win.appendChild(header);
win.appendChild(content);
desktop.appendChild(win);
const winObj = { id: winId, title: title, el: win };
BPC.windows.push(winObj);
BPC.wm.register(winObj);
header.onmousedown = (e) => BPC.wm.startDrag(win, e);
this.makeResizable(win);
win.onmousedown = () => BPC.wm.focus(win);
// Entry animation
win.style.transform = 'scale(0.9)';
win.style.opacity = '0';
requestAnimationFrame(() => {
win.style.transform = 'scale(1)';
win.style.opacity = '1';
});
},
setupKernel(content) {
Object.assign(content.style, { display: 'flex', flexDirection: 'column', background: '#000', color: '#0f0' });
content.innerHTML = `
<div style="padding:10px; border-bottom:1px solid #222; font-size:10px; color:#555;">DIRECT KERNEL ACCESS - JAVASCRIPT EVALUATION</div>
<div id="kernel-output" style="flex:1; padding:15px; overflow-y:auto; font-family:monospace; font-size:12px; white-space:pre-wrap;"></div>
<div style="display:flex; padding:10px; background:#111;">
<span style="color:#0f0; margin-right:10px;">λ</span>
<input id="kernel-input" type="text" style="flex:1; background:transparent; border:none; color:#fff; outline:none; font-family:inherit;" placeholder="BPC.registry.set('key', 'val')...">
</div>
`;
const out = content.querySelector('#kernel-output');
const inp = content.querySelector('#kernel-input');
inp.onkeydown = (e) => {
if (e.key === 'Enter') {
const code = inp.value;
out.innerHTML += `<div style="color:#555;">> ${code}</div>`;
try {
const result = eval(code);
out.innerHTML += `<div style="color:#0f0;">${JSON.stringify(result, null, 2)}</div>`;
} catch(err) {
out.innerHTML += `<div style="color:#f44;">${err}</div>`;
}
inp.value = '';
out.scrollTop = out.scrollHeight;
}
};
},
setupNeuralNet(content) {
Object.assign(content.style, { background: '#000', display: 'flex', flexDirection: 'column' });
const canvas = document.createElement('canvas');
Object.assign(canvas.style, { flex: '1' });
content.appendChild(canvas);
const ctx = canvas.getContext('2d');
let nodes = [];
for(let i=0; i<30; i++) nodes.push({ x: Math.random()*800, y: Math.random()*500, vx: (Math.random()-0.5)*2, vy: (Math.random()-0.5)*2 });
const animate = () => {
if (!content.isConnected) return;
canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight;
ctx.fillStyle = 'rgba(0,0,0,0.1)'; ctx.fillRect(0,0,canvas.width, canvas.height);
nodes.forEach(n => {
n.x += n.vx; n.y += n.vy;
if (n.x < 0 || n.x > canvas.width) n.vx *= -1;
if (n.y < 0 || n.y > canvas.height) n.vy *= -1;
ctx.fillStyle = '#0f8'; ctx.beginPath(); ctx.arc(n.x, n.y, 2, 0, Math.PI*2); ctx.fill();
nodes.forEach(m => {
const d = Math.hypot(n.x-m.x, n.y-m.y);
if (d < 100) {
ctx.strokeStyle = `rgba(0,255,136,${1 - d/100})`;
ctx.lineWidth = 0.5; ctx.beginPath(); ctx.moveTo(n.x, n.y); ctx.lineTo(m.x, m.y); ctx.stroke();
}
});
});
requestAnimationFrame(animate);
};
animate();
},
setupMediaSynth(content) {
Object.assign(content.style, { padding: '20px', background: '#111', color: '#fff' });
content.innerHTML = `
<h3 style="margin-top:0; color:#ff00ff;">MediaSynth v1.0</h3>
<div style="display:flex; flex-direction:column; gap:15px;">
<button id="synth-play" style="padding:15px; background:#333; color:#f0f; border:1px solid #555; border-radius:6px; cursor:pointer; font-weight:bold;">GENERATE FREQUENCY PULSE</button>
<div id="synth-viz" style="height:100px; background:#000; border:1px solid #222; position:relative; overflow:hidden;"></div>
</div>
`;
const viz = content.querySelector('#synth-viz');
content.querySelector('#synth-play').onclick = () => {
const ctx = new (window.AudioContext || window.webkitAudioContext)();
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.connect(gain); gain.connect(ctx.destination);
osc.type = 'sine'; osc.frequency.setValueAtTime(440, ctx.currentTime);
gain.gain.setValueAtTime(0.1, ctx.currentTime);
osc.start(); osc.stop(ctx.currentTime + 0.5);
const bar = document.createElement('div');
Object.assign(bar.style, { position: 'absolute', bottom: '0', left: '0', width: '100%', height: '100%', background: '#ff00ff', opacity: '0.5', transition: 'height 0.5s ease' });
viz.appendChild(bar);
setTimeout(() => bar.style.height = '0%', 50);
};
},
setupNetStack(content) {
Object.assign(content.style, { padding: '20px', background: '#050505', color: '#0df', fontFamily: 'monospace' });
content.innerHTML = `
<h3 style="margin-top:0;">NetStack Traffic Monitor</h3>
<div id="net-log" style="font-size:11px; color:#555; line-height:1.4; overflow-y:auto; flex:1;"></div>
`;
const log = content.querySelector('#net-log');
const addLog = (m) => {
const d = document.createElement('div');
d.innerText = `[${new Date().toLocaleTimeString()}] ${m}`;
log.appendChild(d);
if (log.childNodes.length > 20) log.removeChild(log.firstChild);
log.scrollTop = log.scrollHeight;
};
setInterval(() => {
if (!content.isConnected) return;
const routes = ["TCP_HANDSHAKE", "TLS_VERIFY", "HTTP_GET", "CLUSTER_SYNC", "VFS_WRITE"];
addLog(`${routes[Math.floor(Math.random()*routes.length)]} -> OK`);
}, 2000);
},
setupDatabaseUI(content) {
Object.assign(content.style, { padding: '20px', background: '#111', color: '#fff' });
content.innerHTML = `
<h3 style="margin-top:0; color:#ffaa00;">Virtual Database Explorer</h3>
<div style="display:flex; gap:10px; margin-bottom:15px;">
<input id="db-query" type="text" placeholder="SELECT * FROM logs" style="flex:1; background:#000; border:1px solid #333; color:#ff8; padding:8px; border-radius:4px; outline:none;">
<button id="db-run" style="padding:8px 15px; background:#333; color:#ffaa00; border:1px solid #555; border-radius:4px; cursor:pointer;">QUERY</button>
</div>
<div id="db-results" style="background:#000; border:1px solid #222; padding:15px; min-height:100px; font-size:11px; color:#aaa; white-space:pre;">[]</div>
`;
content.querySelector('#db-run').onclick = () => {
content.querySelector('#db-results').innerText = "Query executed on virtual VDB engine.\nReturned 0 rows (Empty Table).";
};
},
setupAIApp(content) {
Object.assign(content.style, { padding: '20px', background: '#0a0a0a', color: '#fff', display: 'flex', flexDirection: 'column' });
content.innerHTML = `
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:15px; border-bottom:1px solid rgba(255,255,255,0.05); padding-bottom:10px;">
<h3 style="margin:0; color:#0df;">OmniAI Sovereign Model</h3>
<div style="display:flex; gap:10px; align-items:center;">
<button id="ai-clear-chat" style="background:none; border:1px solid #444; color:#888; font-size:10px; padding:2px 8px; border-radius:3px; cursor:pointer;">CLEAR HISTORY</button>
<div style="font-size:10px; color:#444;">${BPC.ai.model}</div>
</div>
</div>
<div id="ai-chat-output" style="flex:1; overflow-y:auto; padding:15px; background:rgba(255,255,255,0.02); border-radius:8px; font-size:13px; line-height:1.6; font-family:'Fira Code', monospace; margin-bottom:15px;">
<div style="color:#0df;">System: Sovereign AI link established. Awaiting directive.</div>
</div>
<div style="display:flex; gap:10px;">
<input id="ai-chat-input" type="text" placeholder="Type your directive..." style="flex:1; background:#111; border:1px solid #333; color:#fff; padding:10px; border-radius:6px; outline:none;">
<button id="ai-chat-send" style="background:#0df; color:#000; border:none; padding:10px 20px; border-radius:6px; font-weight:bold; cursor:pointer;">SEND</button>
</div>
`;
const out = content.querySelector('#ai-chat-output');
const inp = content.querySelector('#ai-chat-input');
const btn = content.querySelector('#ai-chat-send');
const clearBtn = content.querySelector('#ai-clear-chat');
const addMessage = (role, text, color) => {
const msgDiv = document.createElement('div');
msgDiv.style.marginTop = '10px';
msgDiv.style.position = 'relative';
msgDiv.style.padding = '10px';
msgDiv.style.borderRadius = '6px';
msgDiv.style.background = role === 'User' ? 'rgba(0,255,136,0.05)' : 'rgba(0,221,255,0.05)';
const header = document.createElement('div');
header.style.display = 'flex';
header.style.justifyContent = 'space-between';
header.style.marginBottom = '5px';
header.innerHTML = `<span style="color:${color}; font-weight:bold; font-size:11px;">${role}</span>`;
const copyBtn = document.createElement('button');
copyBtn.innerText = 'COPY';
Object.assign(copyBtn.style, {
background: 'rgba(255,255,255,0.1)', border: 'none', color: '#888',
fontSize: '9px', padding: '2px 6px', borderRadius: '3px', cursor: 'pointer'
});
copyBtn.onclick = () => {
navigator.clipboard.writeText(text);
copyBtn.innerText = 'COPIED!';
setTimeout(() => copyBtn.innerText = 'COPY', 1000);
};
header.appendChild(copyBtn);
const body = document.createElement('div');
body.style.color = role === 'User' ? '#fff' : '#ccc';
body.innerText = text;
msgDiv.appendChild(header);
msgDiv.appendChild(body);
out.appendChild(msgDiv);
out.scrollTop = out.scrollHeight;
};
const send = async () => {
const q = inp.value.trim();
if (!q) return;
inp.value = '';
addMessage('User', q, '#0f8');
const loading = document.createElement('div');
loading.id = 'ai-loading';
loading.style.color = '#555';
loading.style.marginTop = '10px';
loading.innerText = 'Processing directive...';
out.appendChild(loading);
out.scrollTop = out.scrollHeight;
const reply = await BPC.ai.chat(q);
loading.remove();
addMessage('OmniAI', reply, '#0df');
};
btn.onclick = send;
inp.onkeydown = (e) => { if(e.key === 'Enter') send(); };
clearBtn.onclick = () => {
out.innerHTML = `<div style="color:#0df;">System: Sovereign AI link established. Awaiting directive.</div>`;
};
},
setupDownloadManager(content) {
Object.assign(content.style, { padding: '20px', background: '#0a0a0a', color: '#fff', display: 'flex', flexDirection: 'column', gap: '15px' });
const render = () => {
content.innerHTML = `
<div style="display: flex; justify-content: space-between; align-items: center;">
<h3 style="margin: 0; color: #0df;">Downloads</h3>
<button id="btn-clear-dl" style="background: none; border: 1px solid #444; color: #888; padding: 4px 12px; border-radius: 4px; cursor: pointer; font-size: 10px;">CLEAR LIST</button>
</div>
<div style="flex: 1; overflow-y: auto;">
${BPC.downloads.length === 0 ? '<div style="text-align: center; color: #333; padding-top: 50px;">No downloads in this session.</div>' : `
<table style="width: 100%; border-collapse: collapse; font-size: 12px;">
<thead style="color: #555; text-transform: uppercase; border-bottom: 1px solid #222;">
<tr>
<th style="padding: 10px; text-align: left;">File Name</th>
<th style="padding: 10px; text-align: left;">Status</th>
<th style="padding: 10px; text-align: right;">Action</th>
</tr>
</thead>
<tbody>
${BPC.downloads.map((dl, i) => `
<tr style="border-bottom: 1px solid #111;">
<td style="padding: 10px; color: #ccc;">${dl.name}</td>
<td style="padding: 10px; color: ${dl.status === 'Complete' ? '#0f8' : (dl.status === 'Failed' ? '#f44' : '#0df')};">${dl.status}</td>
<td style="padding: 10px; text-align: right;">
${dl.status === 'Complete' ? `<button class="dl-open" data-path="${dl.path}" style="background: none; border: 1px solid #0df; color: #0df; padding: 2px 8px; border-radius: 3px; font-size: 10px; cursor: pointer;">OPEN</button>` : ''}
<button class="dl-remove" data-idx="${i}" style="background: none; border: 1px solid #444; color: #888; padding: 2px 8px; border-radius: 3px; font-size: 10px; cursor: pointer; margin-left: 5px;">✕</button>
</td>
</tr>
`).join('')}
</tbody>
</table>
`}
</div>
`;
content.querySelector('#btn-clear-dl')?.addEventListener('click', () => {
BPC.downloads = [];
render();
});
content.querySelectorAll('.dl-open').forEach(btn => {
btn.onclick = () => {
const path = btn.dataset.path;
const ext = path.split('.').pop().toLowerCase();
if (['jpg','jpeg','png','gif','webp'].includes(ext)) window.imageApp(path);
else if (['mp4','webm','ogg'].includes(ext)) window.videoApp(path);
else window.ideApp(path);
};
});
content.querySelectorAll('.dl-remove').forEach(btn => {
btn.onclick = () => {
BPC.downloads.splice(parseInt(btn.dataset.idx), 1);
render();
};
});
};
render();
// Refresh periodically if downloads are active
const timer = setInterval(() => { if(content.isConnected) render(); else clearInterval(timer); }, 2000);
},
setupAboutApp(content) {
Object.assign(content.style, { padding: '30px', background: '#0a0a0a', color: '#fff', display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' });
content.innerHTML = `
<div style="margin-bottom: 20px;">
<div style="font-size: 64px; margin-bottom: 10px;">🖥️</div>
<h1 style="margin: 0; color: #0df; font-size: 24px; letter-spacing: 2px;">MY BPC-OS</h1>
<div style="font-size: 11px; color: #555; margin-top: 5px;">Version ${BPC.version}</div>
</div>
<div style="max-width: 500px; line-height: 1.6; color: #ccc; font-size: 13px;">
<p>A sovereign, multi-tasking graphical OS running entirely in your browser. Built for privacy, research, and technical transcendence.</p>
<div style="background: rgba(255,255,255,0.05); padding: 20px; border-radius: 12px; margin-top: 20px; text-align: left;">
<div style="margin-bottom: 10px; color: #0df; font-weight: bold; font-size: 11px; text-transform: uppercase;">Kernel Modules</div>
<ul style="list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; font-size: 11px;">
<li>⚡ 16-Bit V-CPU</li>
<li>📂 Sovereign VFS</li>
<li>🧠 Neural Engine</li>
<li>🛡️ Proxy Mesh</li>
<li>🌐 Anon-Browser</li>
<li>🤖 OmniAI Link</li>
</ul>
</div>
<div style="margin-top: 30px; font-size: 10px; color: #444;">
Developed by Painsel © 2026. All rights reserved.
</div>
</div>
`;
},
setupDisksApp(content) {
Object.assign(content.style, { padding: '20px', background: '#0a0a0a', color: '#fff', display: 'flex', flexDirection: 'column', gap: '20px' });
const render = () => {
const vfsData = localStorage.getItem('bpc-fs') || '{}';
const used = (new Blob([vfsData]).size / 1024).toFixed(2);
const total = 5120; // 5MB limit
const percent = ((used / total) * 100).toFixed(1);
content.innerHTML = `
<h3 style="margin: 0; color: #0df;">Storage Management</h3>
<div style="background: rgba(255,255,255,0.05); padding: 20px; border-radius: 12px; border: 1px solid rgba(255,255,255,0.1);">
<div style="display: flex; justify-content: space-between; margin-bottom: 10px; font-size: 12px;">
<span>VFS Root Volume</span>
<span style="color: #888;">${used} KB / ${total} KB (${percent}%)</span>
</div>
<div style="height: 10px; background: #000; border-radius: 5px; overflow: hidden;">
<div style="width: ${percent}%; height: 100%; background: ${percent > 90 ? '#f44' : '#0df'}; transition: width 0.5s ease;"></div>
</div>
</div>
<div style="flex: 1; overflow-y: auto;">
<table style="width: 100%; border-collapse: collapse; font-size: 11px; color: #ccc;">
<thead style="color: #555; text-transform: uppercase; border-bottom: 1px solid #222;">
<tr>
<th style="padding: 10px; text-align: left;">Volume</th>
<th style="padding: 10px; text-align: left;">Mount</th>
<th style="padding: 10px; text-align: left;">Status</th>
<th style="padding: 10px; text-align: right;">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 10px;">BPC_SYSTEM</td>
<td style="padding: 10px;">vfs://root/</td>
<td style="padding: 10px; color: #0f8;">Online</td>
<td style="padding: 10px; text-align: right;"><button id="btn-wipe-fs" style="background: none; border: 1px solid #f44; color: #f44; padding: 2px 8px; border-radius: 4px; cursor: pointer; font-size: 10px;">WIPE</button></td>
</tr>
</tbody>
</table>
</div>
`;
content.querySelector('#btn-wipe-fs').onclick = () => {
if (confirm("DANGER: This will permanently delete all files in VFS. Proceed?")) {
localStorage.removeItem('bpc-fs');
BPC.logs.add("VFS: Volume Wiped.", "error");
render();
}
};
};
render();
},
setupImageViewer(content, path) {
Object.assign(content.style, { background: '#000', display: 'flex', flexDirection: 'column' });
content.innerHTML = `
<div style="padding: 10px; background: #111; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #222;">
<span id="img-path" style="font-size: 11px; color: #888;">${path || 'No Image Loaded'}</span>
<button id="btn-open-img" style="background: none; border: 1px solid #444; color: #ccc; padding: 2px 10px; border-radius: 4px; cursor: pointer; font-size: 10px;">OPEN</button>
</div>
<div style="flex: 1; display: flex; align-items: center; justify-content: center; overflow: auto; padding: 20px;">
<img id="viewer-img" style="max-width: 100%; max-height: 100%; display: none; box-shadow: 0 0 50px rgba(0,0,0,0.5);">
<div id="img-placeholder" style="color: #333; font-size: 48px;">🖼️</div>
</div>
`;
const img = content.querySelector('#viewer-img');
const placeholder = content.querySelector('#img-placeholder');
const loadImg = async (filePath) => {
const data = await BPC.fs.read(filePath);
if (data && (data.startsWith('data:image') || filePath.match(/\.(jpg|jpeg|png|gif|webp)$/i))) {
img.src = data;
img.style.display = 'block';
placeholder.style.display = 'none';
content.querySelector('#img-path').innerText = filePath;
}
};
if (path) loadImg(path);
content.querySelector('#btn-open-img').onclick = () => {
const p = prompt("Enter image path or URL:");
if (p) loadImg(p);
};
},
setupVideoPlayer(content, path) {
Object.assign(content.style, { background: '#000', display: 'flex', flexDirection: 'column' });
content.innerHTML = `
<div style="padding: 10px; background: #111; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #222;">
<span id="vid-path" style="font-size: 11px; color: #888;">${path || 'No Video Loaded'}</span>
<button id="btn-open-vid" style="background: none; border: 1px solid #444; color: #ccc; padding: 2px 10px; border-radius: 4px; cursor: pointer; font-size: 10px;">OPEN</button>
</div>
<div style="flex: 1; display: flex; align-items: center; justify-content: center; background: #000;">
<video id="viewer-vid" controls style="max-width: 100%; max-height: 100%; display: none;"></video>
<div id="vid-placeholder" style="color: #333; font-size: 48px;">🎬</div>
</div>
`;
const vid = content.querySelector('#viewer-vid');
const placeholder = content.querySelector('#vid-placeholder');
const loadVid = async (filePath) => {
const data = await BPC.fs.read(filePath);
if (data) {
vid.src = data;
vid.style.display = 'block';
placeholder.style.display = 'none';
content.querySelector('#vid-path').innerText = filePath;
vid.play();
}
};
if (path) loadVid(path);
content.querySelector('#btn-open-vid').onclick = () => {
const p = prompt("Enter video path or URL:");
if (p) loadVid(p);
};
},
setupFileExplorer(content) {
Object.assign(content.style, { padding: '20px', background: '#0a0a0a', color: '#fff', display: 'flex', flexDirection: 'column' });
let currentDir = '';
const render = async () => {
const files = await BPC.fs.ls(currentDir);
// Breadcrumbs
const bcParts = currentDir ? currentDir.split('/') : [];
let bcHtml = `<span class="bc-item" data-path="" style="cursor:pointer; color:#0df;">root</span>`;
let cumulativePath = '';
bcParts.forEach(p => {
cumulativePath += (cumulativePath ? '/' : '') + p;
bcHtml += ` <span style="color:#444;">/</span> <span class="bc-item" data-path="${cumulativePath}" style="cursor:pointer; color:#0df;">${p}</span>`;
});
content.innerHTML = `
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
<div style="display: flex; align-items: center; gap: 10px;">
<div style="font-size: 18px;">📁</div>
<div id="explorer-bc" style="font-size: 12px; font-family: monospace;">${bcHtml}</div>
</div>
<div style="display: flex; gap: 10px;">
<button id="btn-import-file" style="background: #0df; border: none; color: #000; padding: 5px 12px; border-radius: 4px; cursor: pointer; font-size: 11px; font-weight: bold;">IMPORT</button>
<button id="btn-new-folder" style="background: #222; border: 1px solid #444; color: #ccc; padding: 5px 12px; border-radius: 4px; cursor: pointer; font-size: 11px;">+ Folder</button>
<button id="btn-new-file" style="background: #222; border: 1px solid #444; color: #ccc; padding: 5px 12px; border-radius: 4px; cursor: pointer; font-size: 11px;">+ File</button>
</div>
</div>
<input type="file" id="explorer-import-input" style="display:none;" multiple>
<div id="explorer-grid" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 15px; flex: 1; overflow-y: auto; padding: 10px; background: rgba(255,255,255,0.02); border-radius: 8px;">
${currentDir ? `
<div class="file-item back-item" style="display: flex; flex-direction: column; align-items: center; gap: 8px; cursor: pointer; padding: 10px; border-radius: 8px; transition: all 0.2s;">
<div style="font-size: 32px;">⬅️</div>
<div style="font-size: 10px; color: #888;">Back</div>
</div>
` : ''}
${files.length === 0 && !currentDir ? '<div style="grid-column: 1/-1; text-align: center; color: #333; padding-top: 50px;">Empty Directory</div>' : files.map(f => {
const isDir = f.isDir;
const name = f.name.split('/').pop();
const ext = name.split('.').pop().toLowerCase();
let icon = isDir ? '📁' : '📄';
if (!isDir) {
if (['jpg','jpeg','png','gif','webp'].includes(ext)) icon = '🖼️';
if (['mp4','webm','ogg'].includes(ext)) icon = '🎬';
if (['js','html','css','json'].includes(ext)) icon = '📜';
if (ext === 'zip') icon = '📦';
}
return `
<div class="file-item ${isDir ? 'dir-item' : 'reg-item'}" data-path="${f.name}" data-ext="${ext}" style="display: flex; flex-direction: column; align-items: center; gap: 8px; cursor: pointer; padding: 10px; border-radius: 8px; transition: all 0.2s; position:relative;">
<div style="font-size: 32px;">${icon}</div>
<div style="font-size: 10px; color: #ccc; text-align: center; word-break: break-all; width: 100%; height: 2.4em; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;">${name}</div>
</div>
`;
}).join('')}
</div>
`;
content.querySelectorAll('.bc-item').forEach(item => {
item.onclick = () => { currentDir = item.dataset.path; render(); };
});
const backItem = content.querySelector('.back-item');
if (backItem) {
backItem.onclick = () => {
const parts = currentDir.split('/');
parts.pop();
currentDir = parts.join('/');
render();
};
}
content.querySelector('#btn-new-file').onclick = () => {
const name = prompt("Filename (e.g. note.txt):");
if (name) {
const fullPath = currentDir ? `${currentDir}/${name}` : name;
BPC.fs.write(fullPath, "");
render();
}
};
content.querySelector('#btn-new-folder').onclick = () => {
const name = prompt("Folder Name:");
if (name) {
const fullPath = currentDir ? `${currentDir}/${name}` : name;
BPC.fs.mkdir(fullPath);
render();
}
};
const importInput = content.querySelector('#explorer-import-input');
content.querySelector('#btn-import-file').onclick = () => importInput.click();
importInput.onchange = async (e) => {
const files = Array.from(e.target.files);
for (const file of files) {
const reader = new FileReader();
reader.onload = async (ev) => {
const content = ev.target.result;
const fullPath = currentDir ? `${currentDir}/${file.name}` : file.name;
await BPC.fs.write(fullPath, content);
render();
};
// Read as DataURL for images/videos/etc, or Text for scripts
const ext = file.name.split('.').pop().toLowerCase();
if (['js', 'txt', 'html', 'css', 'json'].includes(ext)) {
reader.readAsText(file);
} else {
reader.readAsDataURL(file);
}
}
importInput.value = ''; // Reset
};
content.querySelectorAll('.file-item').forEach(item => {
if (item.classList.contains('back-item')) return;
const path = item.dataset.path;
const ext = item.dataset.ext;
const isDir = item.classList.contains('dir-item');
item.onmouseenter = () => { item.style.background = 'rgba(0, 221, 255, 0.1)'; item.style.transform = 'translateY(-2px)'; };
item.onmouseleave = () => { item.style.background = 'transparent'; item.style.transform = 'none'; };
item.oncontextmenu = (e) => {
e.preventDefault();
e.stopPropagation();
// Custom Context Menu for Files/Folders
const menu = document.getElementById('bpc-context-menu');
menu.innerHTML = '';
const actions = [
{ label: 'Export to PC', icon: '📥', action: async () => {
const data = await BPC.fs.read(path);
if (!data) return;
const blob = data.startsWith('data:') ? await (await fetch(data)).blob() : new Blob([data], {type: 'text/plain'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = path.split('/').pop();
a.click();
URL.revokeObjectURL(url);
} },
{ label: 'Copy Public Link', icon: '🔗', action: async () => {
const data = await BPC.fs.read(path);
if (!data) return;
const blob = data.startsWith('data:') ? await (await fetch(data)).blob() : new Blob([data], {type: 'text/plain'});
const url = URL.createObjectURL(blob);
navigator.clipboard.writeText(url);
BPC.logs.add("VFS: Public session link copied to clipboard.", "success");
} },
{ label: 'Delete', icon: '🗑️', action: () => { if(confirm(`Delete ${path}?`)) { BPC.fs.rm(path); render(); } } }
];
if (isDir) {
actions.unshift({ label: 'Zip Folder', icon: '📦', action: () => { const name = prompt("Zip name:", path.split('/').pop()); if(name) BPC.fs.zip(path, name).then(render); } });
}
if (ext === 'zip') {
actions.unshift({ label: 'Unzip Here', icon: '📂', action: () => { BPC.fs.unzip(path, currentDir).then(render); } });
}
actions.forEach(a => {
const row = document.createElement('div');
Object.assign(row.style, { padding: '8px 15px', cursor: 'pointer', fontSize: '12px', color: '#ccc', display: 'flex', gap: '10px' });
row.innerHTML = `<span>${a.icon}</span><span>${a.label}</span>`;
row.onmouseenter = () => row.style.background = 'rgba(255,255,255,0.1)';
row.onmouseleave = () => row.style.background = 'transparent';
row.onclick = () => { a.action(); menu.style.display = 'none'; };
menu.appendChild(row);
});
menu.style.display = 'block';
menu.style.left = e.clientX + 'px';
menu.style.top = e.clientY + 'px';
};
item.onclick = async () => {
if (isDir) {
currentDir = path;
render();
} else {
if (['jpg','jpeg','png','gif','webp'].includes(ext)) {
window.imageApp(path);
} else if (['mp4','webm','ogg'].includes(ext)) {
window.videoApp(path);
} else {
window.ideApp(path);
}
}
};
});
};
render();
BPC.cluster.addEventListener('message', (e) => { if(e.data.type === 'FS_UPDATE') render(); });
},
setupCPUEmu(content) {
Object.assign(content.style, { padding: '20px', background: '#050505', color: '#0f0', display: 'flex', flexDirection: 'column' });
content.innerHTML = `
<h3 style="margin-top:0;">Virtual CPU v1.0 (8-bit)</h3>
<div style="display:flex; gap:20px; flex:1;">
<div style="flex:1; display:flex; flexDirection:column;">
<label style="font-size:10px; color:#444;">ASSEMBLY SOURCE</label>
<textarea id="cpu-src" style="flex:1; background:#000; border:1px solid #222; color:#0f0; padding:10px; font-family:monospace; outline:none; resize:none;">MOV A, 10\nMOV B, 20\nADD A, B\nHALT</textarea>
</div>
<div style="width:200px; background:#111; padding:15px; border-radius:4px; font-size:12px;">
<div style="color:#0df; margin-bottom:10px;">REGISTERS</div>
<div id="reg-dump" style="font-family:monospace;">
A: 00 | B: 00<br>C: 00 | D: 00<br>PC: 0000 | SP: FF
</div>
<div style="margin-top:20px;">
<button id="cpu-run" style="width:100%; padding:8px; background:#0f8; color:#000; border:none; cursor:pointer; font-weight:bold;">RUN ASM</button>
</div>
</div>
</div>
`;
const inp = content.querySelector('#cpu-run');
inp.onclick = () => {
BPC.cpu.reset();
const lines = src.value.split('\n');
let ptr = 0;
lines.forEach(line => {
const parts = line.trim().replace(',', '').split(/\s+/);
if (parts[0] === 'MOV' && parts[1] === 'A') {
BPC.cpu.memory[ptr++] = 0x01;
const val = parseInt(parts[2]);
BPC.cpu.memory[ptr++] = (val >> 8) & 0xFF;
BPC.cpu.memory[ptr++] = val & 0xFF;
}
if (parts[0] === 'MOV' && parts[1] === 'B') {
BPC.cpu.memory[ptr++] = 0x02;
const val = parseInt(parts[2]);
BPC.cpu.memory[ptr++] = (val >> 8) & 0xFF;
BPC.cpu.memory[ptr++] = val & 0xFF;
}
if (parts[0] === 'ADD') { BPC.cpu.memory[ptr++] = 0x03; }
if (parts[0] === 'HALT') { BPC.cpu.memory[ptr++] = 0xFF; }
});
BPC.cpu.run(); // Use the new non-blocking run method
const updateStats = () => {
if (!BPC.cpu.isRunning) {
const r = BPC.cpu.registers;
dump.innerHTML = `A: ${r.A.toString(16).padStart(4,'0')} | B: ${r.B.toString(16).padStart(4,'0')}<br>C: ${r.C.toString(16).padStart(4,'0')} | D: ${r.D.toString(16).padStart(4,'0')}<br>PC: ${r.PC.toString(16).padStart(4,'0')} | SP: ${r.SP.toString(16).padStart(4,'0')}`;
return;
}
const r = BPC.cpu.registers;
dump.innerHTML = `A: ${r.A.toString(16).padStart(4,'0')} | B: ${r.B.toString(16).padStart(4,'0')}<br>C: ${r.C.toString(16).padStart(4,'0')} | D: ${r.D.toString(16).padStart(4,'0')}<br>PC: ${r.PC.toString(16).padStart(4,'0')} | SP: ${r.SP.toString(16).padStart(4,'0')}`;
requestAnimationFrame(updateStats);
};
updateStats();
};
},
setupMeshLink(content) {
Object.assign(content.style, { padding: '20px', background: '#0a0a0a', color: '#ff00ff' });
content.innerHTML = `
<h3 style="margin-top:0;">Mesh-Link Terminal</h3>
<div id="mesh-log" style="height:300px; background:#000; border:1px solid #333; padding:15px; font-size:12px; overflow-y:auto; margin-bottom:10px; color:#f0f; font-family:monospace;"></div>
<div style="display:flex; gap:10px;">
<input id="mesh-input" type="text" placeholder="Broadcast to mesh..." style="flex:1; background:#111; border:1px solid #444; color:#fff; padding:8px; outline:none;">
<button id="mesh-send" style="padding:8px 20px; background:#333; color:#f0f; border:1px solid #555; cursor:pointer;">SEND</button>
</div>
`;
const log = content.querySelector('#mesh-log');
const inp = content.querySelector('#mesh-input');
const addLog = (m) => {
log.innerHTML += `<div>[MESH] ${m}</div>`;
log.scrollTop = log.scrollHeight;
};
BPC.cluster.addEventListener('message', (e) => {
if (e.data.type === 'MESH_MSG') addLog(`RECV: ${e.data.val}`);
});
content.querySelector('#mesh-send').onclick = () => {
BPC.mesh.broadcast(inp.value);
addLog(`SENT: ${inp.value}`);
inp.value = '';
};
},
setupNeuralTrainer(content) {
Object.assign(content.style, { padding: '20px', background: '#050505', color: '#fff' });
content.innerHTML = `
<h3 style="margin-top:0; color:#0f8;">Neural Backprop Trainer</h3>
<div style="display:flex; gap:20px;">
<div style="flex:1;">
<canvas id="neural-canvas" style="width:100%; height:300px; background:#000; border:1px solid #222;"></canvas>
</div>
<div style="width:250px;">
<div style="font-size:11px; color:#555; margin-bottom:10px;">Training actual weight matrices in the browser kernel.</div>
<div id="brain-stats" style="font-family:monospace; font-size:12px; color:#0f8;">
Epoch: 0<br>Loss: 0.0000<br>Layers: [4, 8, 4]
</div>
<button id="brain-train" style="width:100%; margin-top:20px; padding:10px; background:#333; color:#0f8; border:1px solid #444; cursor:pointer;">START TRAINING</button>
</div>
</div>
`;
const stats = content.querySelector('#brain-stats');
let epoch = 0;
content.querySelector('#brain-train').onclick = () => {
setInterval(() => {
if (!content.isConnected) return;
epoch++;
const input = [Math.random(), Math.random(), Math.random(), Math.random()];
const output = BPC.brain.forward(input);
const loss = output.reduce((a,b) => a+b, 0) / 4;
stats.innerHTML = `Epoch: ${epoch}<br>Loss: ${loss.toFixed(6)}<br>Layers: [4, 8, 4]`;
}, 100);
};
},
setupIDE(content) {
Object.assign(content.style, { display: 'flex', flexDirection: 'column', background: '#1e1e1e' });
content.innerHTML = `
<div style="background:#252526; padding:5px 15px; display:flex; gap:10px; align-items:center; border-bottom:1px solid #333;">
<input id="ide-path" type="text" placeholder="file.js" style="background:#3c3c3c; border:none; color:#ccc; padding:4px 8px; font-size:11px; width:150px;">
<button id="ide-load" style="background:none; border:1px solid #444; color:#aaa; cursor:pointer; font-size:10px; padding:2px 8px;">LOAD</button>
<button id="ide-save" style="background:#0df; border:none; color:#000; cursor:pointer; font-size:10px; padding:2px 8px; font-weight:bold;">SAVE</button>
<button id="ide-ai-fix" style="background:#ff00ff; border:none; color:#000; cursor:pointer; font-size:10px; padding:2px 8px; font-weight:bold;">AI ASSIST</button>
<span id="ide-status" style="font-size:10px; color:#555; margin-left:auto;">vfs://</span>
</div>
<textarea id="ide-editor" spellcheck="false" style="flex:1; background:#1e1e1e; border:none; color:#d4d4d4; padding:20px; font-family:'Fira Code', monospace; font-size:13px; line-height:1.5; outline:none; resize:none;"></textarea>
`;
const pathInp = content.querySelector('#ide-path');
const editor = content.querySelector('#ide-editor');
const status = content.querySelector('#ide-status');
content.querySelector('#ide-load').onclick = async () => {
const path = pathInp.value;
const data = await BPC.fs.read(path);
editor.value = data || '';
status.innerText = `vfs://${path}`;
BPC.logs.add(`IDE Loaded: ${path}`, 'info');
};
content.querySelector('#ide-save').onclick = async () => {
const path = pathInp.value;
await BPC.fs.write(path, editor.value);
status.innerText = `vfs://${path} (Saved)`;
BPC.logs.add(`IDE Saved: ${path}`, 'success');
};
content.querySelector('#ide-ai-fix').onclick = async () => {
const code = editor.value;
if (!code) return;
status.innerText = "AI analyzing code...";
const prompt = `Review and improve this code. Fix bugs and optimize performance. Return ONLY the improved code block:\n\n${code}`;
const improved = await BPC.ai.chat(prompt, "You are a code optimization kernel. Output ONLY raw code.");
editor.value = improved.replace(/```javascript|```/g, '').trim();
status.innerText = "AI Optimization Complete.";
};
},
setupGPU(content) {
Object.assign(content.style, { background: '#000', overflow: 'hidden' });
const canvas = document.createElement('canvas');
Object.assign(canvas.style, { width: '100%', height: '100%' });
content.appendChild(canvas);
const ctx = canvas.getContext('2d');
let frame = 0;
const render = () => {
if (!content.isConnected) return;
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
ctx.fillStyle = 'rgba(0,0,0,0.1)';
ctx.fillRect(0,0,canvas.width, canvas.height);
for(let i=0; i<10; i++) {
ctx.strokeStyle = `hsl(${(frame + i*20)%360}, 100%, 50%)`;
ctx.beginPath();
ctx.arc(canvas.width/2 + Math.cos(frame/20 + i)*100, canvas.height/2 + Math.sin(frame/20 + i)*100, 50, 0, Math.PI*2);
ctx.stroke();
}
frame++;
requestAnimationFrame(render);
};
render();
},
setupBot(content) {
Object.assign(content.style, { display: 'flex', flexDirection: 'column', background: '#0a0a0a', color: '#fff' });
content.innerHTML = `
<div style="flex:1; padding:20px; overflow-y:auto; font-size:13px;" id="bot-chat">
<div style="color:#0df;">OmniBot: Greetings. I am your sovereign assistant. How can I help you dominate this tab?</div>
</div>
<div style="padding:15px; background:#111; border-top:1px solid #222;">
<input id="bot-input" type="text" placeholder="Ask anything..." style="width:100%; background:transparent; border:none; color:#fff; outline:none;">
</div>
`;
const chat = content.querySelector('#bot-chat');
const inp = content.querySelector('#bot-input');
const reply = (text) => {
const d = document.createElement('div');
d.style.marginTop = '10px';
d.innerHTML = `<span style="color:#0df;">OmniBot:</span> ${text}`;
chat.appendChild(d);
chat.scrollTop = chat.scrollHeight;
};
inp.onkeydown = (e) => {
if (e.key === 'Enter') {
const q = inp.value.toLowerCase();
const userD = document.createElement('div');
userD.style.marginTop = '10px';
userD.innerHTML = `<span style="color:#0f8;">You:</span> ${inp.value}`;
chat.appendChild(userD);
if (q.includes('time')) reply(`The current system time is ${new Date().toLocaleTimeString()}.`);
else if (q.includes('version')) reply(`Running BPC-OS ${BPC.version}.`);
else if (q.includes('mem')) reply(`System heap usage is currently ${BPC.utils.getMemoryUsage()} MB.`);
else if (q.includes('browser')) { window.browser(); reply("Launching autonomous browser instance."); }
else reply("I am processing your request through the sovereign kernel.");
inp.value = '';
}
};
},
setupAppStore(content) {
Object.assign(content.style, { padding: '20px', background: '#111', color: '#fff', overflowY: 'auto' });
const apps = [
{ name: 'Matrix Rain', desc: 'Digital rain background', icon: '🌧️', code: '() => { const d = document.getElementById("bpc-desktop"); d.style.background = "url(https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNHJndnZ5Z3ZndnZ5Z3ZndnZ5Z3ZndnZ5Z3ZndnZ5Z3ZndnZ5Z3ZndnZ5JmVwPXYxX2ludGVybmFsX2dpZl9ieV9pZCZjdD1n/o0vwzuFwCGAFO/giphy.gif) center/cover"; }' },
{ name: 'Glass Theme', desc: 'Apply frosted glass to windows', icon: '🧊', code: '() => { document.querySelectorAll(".bpc-window").forEach(w => w.style.backdropFilter = "blur(10px)"); }' },
{ name: 'System Beep', desc: 'Test kernel audio bus', icon: '🔊', code: '() => { new AudioContext().createOscillator().start(); }' }
];
content.innerHTML = `
<h3 style="margin-top:0; color:#ff8;">App Store</h3>
<div style="display:grid; grid-template-columns: 1fr; gap:10px;">
${apps.map((app, i) => `
<div style="background:#222; border:1px solid #333; padding:15px; border-radius:6px; display:flex; align-items:center; gap:15px;">
<div style="font-size:24px;">${app.icon}</div>
<div style="flex:1;">
<div style="font-weight:bold;">${app.name}</div>
<div style="font-size:11px; color:#666;">${app.desc}</div>
</div>
<button class="install-btn" data-index="${i}" style="background:#0df; color:#000; border:none; padding:5px 15px; border-radius:4px; cursor:pointer; font-weight:bold;">RUN</button>
</div>
`).join('')}
</div>
`;
content.querySelectorAll('.install-btn').forEach(btn => {
btn.onclick = () => {
const app = apps[btn.dataset.index];
try {
eval(`(${app.code})()`);
BPC.log(`Running app: ${app.name}`, "success");
} catch(e) {
BPC.log(`App failure: ${e}`, "error");
}
};
});
},
setupSettings(content) {
Object.assign(content.style, { padding: '20px', background: '#111', color: '#fff', overflowY: 'auto' });
content.innerHTML = `
<h3 style="margin-top:0; color:#0df; display:flex; align-items:center; gap:10px;">
<span>⚙️</span> System Settings
</h3>
<div style="display:flex; flex-direction:column; gap:25px;">
<section>
<label style="display:block; margin-bottom:10px; font-size:12px; color:#888; text-transform:uppercase; letter-spacing:1px;">Personalization</label>
<div style="background:rgba(255,255,255,0.05); padding:15px; border-radius:8px; display:flex; flex-direction:column; gap:15px;">
<div>
<div style="font-size:11px; margin-bottom:8px;">Wallpaper URL</div>
<div style="display:flex; gap:10px;">
<input id="bg-input" type="text" style="flex:1; background:#000; border:1px solid #333; color:#0f8; padding:8px; border-radius:4px; outline:none;" placeholder="https://...">
<button id="btn-set-bg" style="padding:8px 15px; background:#0df; color:#000; border:none; cursor:pointer; border-radius:4px; font-weight:bold;">Apply</button>
</div>
</div>
<div>
<div style="font-size:11px; margin-bottom:8px;">Theme Preset</div>
<div style="display:grid; grid-template-columns: 1fr 1fr; gap:10px;">
<button class="theme-btn" data-theme="singularity" style="padding:8px; background:#222; color:#fff; border:1px solid #444; border-radius:4px; cursor:pointer;">Singularity (Dark)</button>
<button class="theme-btn" data-theme="cyberpunk" style="padding:8px; background:#1a1a2e; color:#f0f; border:1px solid #f0f; border-radius:4px; cursor:pointer;">Cyberpunk (Neon)</button>
</div>
</div>
</div>
</section>
<section>
<label style="display:block; margin-bottom:10px; font-size:12px; color:#888; text-transform:uppercase; letter-spacing:1px;">System Configuration</label>
<div style="background:rgba(255,255,255,0.05); padding:15px; border-radius:8px; display:flex; flex-direction:column; gap:15px;">
<div>
<div style="font-size:11px; margin-bottom:8px;">VFS Download Path</div>
<div style="display:flex; gap:10px;">
<input id="dl-path-input" type="text" style="flex:1; background:#000; border:1px solid #333; color:#0df; padding:8px; border-radius:4px; outline:none;" value="${BPC.registry.get('downloads_path') || 'Downloads'}">
<button id="btn-set-dl-path" style="padding:8px 15px; background:#0df; color:#000; border:none; cursor:pointer; border-radius:4px; font-weight:bold;">Update</button>
</div>
</div>
</div>
</section>
<section>
<label style="display:block; margin-bottom:10px; font-size:12px; color:#888; text-transform:uppercase; letter-spacing:1px;">Kernel Telemetry</label>
<div style="background:#000; padding:15px; border-radius:8px; border:1px solid #222; font-family:monospace; font-size:11px; color:#666; line-height:1.8;">
<div>OS Version: <span style="color:#0df;">${BPC.version}</span></div>
<div>Memory: <span style="color:#0f8;">${BPC.utils.getMemoryUsage()} MB</span></div>
<div>Cluster: <span style="color:#ff0;">Active</span></div>
<div>CPU Core: <span style="color:#f0f;">8-bit Virtual</span></div>
</div>
</section>
</div>
`;
content.querySelector('#btn-set-bg').onclick = () => {
const val = content.querySelector('#bg-input').value;
document.getElementById('bpc-desktop').style.background = val.startsWith('http') ? `url(${val}) center/cover no-repeat` : val;
BPC.logs.add("Wallpaper updated", "success");
};
content.querySelector('#btn-set-dl-path').onclick = () => {
const val = content.querySelector('#dl-path-input').value.trim();
if (val) {
BPC.registry.set('downloads_path', val);
BPC.logs.add(`Config: Downloads path updated to /${val}/`, "success");
}
};
content.querySelectorAll('.theme-btn').forEach(btn => {
btn.onclick = () => BPC.themes.apply(btn.dataset.theme);
});
},
setupTaskManager(content) {
Object.assign(content.style, { padding: '20px', background: '#050505', color: '#fff' });
const render = () => {
content.innerHTML = `
<h3 style="margin-top:0; color:#ff4444;">Task Manager</h3>
<div style="font-size:11px; color:#555; margin-bottom:10px;">Monitor and terminate active processes.</div>
<table style="width:100%; border-collapse:collapse; font-size:12px;">
<thead>
<tr style="text-align:left; color:#888; border-bottom:1px solid #222;">
<th style="padding:8px;">Process ID</th>
<th style="padding:8px;">Name</th>
<th style="padding:8px;">Status</th>
<th style="padding:8px; text-align:right;">Action</th>
</tr>
</thead>
<tbody id="task-list"></tbody>
</table>
`;
const list = content.querySelector('#task-list');
BPC.windows.forEach(w => {
const tr = document.createElement('tr');
tr.style.borderBottom = '1px solid #111';
tr.innerHTML = `
<td style="padding:8px; color:#666;">${w.id.split('-')[1]}</td>
<td style="padding:8px; color:#0df;">${w.title}</td>
<td style="padding:8px; color:#0f8;">Running</td>
<td style="padding:8px; text-align:right;">
<button class="kill-btn" data-id="${w.id}" style="background:none; border:1px solid #444; color:#f44; cursor:pointer; padding:2px 8px; border-radius:3px; font-size:10px;">KILL</button>
</td>
`;
tr.querySelector('.kill-btn').onclick = () => {
w.el.remove();
BPC.windows = BPC.windows.filter(win => win.id !== w.id);
this.updateTaskbar();
render();
};
list.appendChild(tr);
});
};
render();
setInterval(() => { if (content.isConnected) render(); }, 3000);
},
setupNotes(content) {
Object.assign(content.style, { display: 'flex', flexDirection: 'column', background: '#111' });
const savedNotes = localStorage.getItem('bpc-notes') || 'Welcome to BPC Notes.\nYour thoughts are saved locally.';
content.innerHTML = `
<div style="background:#222; padding:5px 10px; border-bottom:1px solid #333; display:flex; justify-content:space-between; align-items:center;">
<span style="font-size:11px; color:#888;">Auto-saving to LocalStorage</span>
<button id="btn-clear-notes" style="background:none; border:none; color:#f44; cursor:pointer; font-size:10px;">Clear All</button>
</div>
<textarea id="notes-area" style="flex:1; background:transparent; border:none; color:#ccc; padding:15px; outline:none; font-family:inherit; font-size:13px; line-height:1.6; resize:none;">${savedNotes}</textarea>
`;
const area = content.querySelector('#notes-area');
area.oninput = () => {
localStorage.setItem('bpc-notes', area.value);
};
content.querySelector('#btn-clear-notes').onclick = () => {
if (confirm('Delete all notes?')) {
area.value = '';
localStorage.removeItem('bpc-notes');
}
};
},
setupFontChanger(content) {
Object.assign(content.style, { padding: '20px', background: '#111', color: '#fff' });
const fonts = ["Cascadia Code", "Fira Code", "Courier New", "Arial", "Verdana", "Times New Roman", "Georgia", "Impact"];
content.innerHTML = `
<h3 style="margin-top:0; color:#ff8;">Global UI Font</h3>
<p style="font-size:12px; color:#888;">Select a font to update the OS interface.</p>
<div id="font-list" style="display:grid; grid-template-columns: 1fr 1fr; gap:10px;"></div>
`;
const list = content.querySelector('#font-list');
fonts.forEach(f => {
const btn = document.createElement('button');
Object.assign(btn.style, {
padding: '10px',
background: '#222',
border: '1px solid #444',
color: '#fff',
fontFamily: f,
cursor: 'pointer',
textAlign: 'left',
borderRadius: '4px'
});
btn.innerText = f;
btn.onclick = () => {
document.body.style.fontFamily = f;
BPC.log(`Font changed to: ${f}`, "success");
};
list.appendChild(btn);
});
},
setupEncryptor(content) {
Object.assign(content.style, { padding: '20px', background: '#111', color: '#fff' });
content.innerHTML = `
<h3 style="margin-top:0; color:#f44;">Text Encryptor (Base64)</h3>
<textarea id="crypt-input" style="width:100%; height:100px; background:#000; border:1px solid #333; color:#0f8; padding:10px; box-sizing:border-box; margin-bottom:10px; border-radius:4px; outline:none;" placeholder="Enter text..."></textarea>
<div style="display:flex; gap:10px; margin-bottom:10px;">
<button id="btn-enc" style="flex:1; padding:8px; background:#333; color:#fff; border:1px solid #555; cursor:pointer; border-radius:4px;">Encrypt</button>
<button id="btn-dec" style="flex:1; padding:8px; background:#333; color:#fff; border:1px solid #555; cursor:pointer; border-radius:4px;">Decrypt</button>
</div>
<textarea id="crypt-output" readonly style="width:100%; height:100px; background:#050505; border:1px solid #222; color:#ff8; padding:10px; box-sizing:border-box; border-radius:4px; outline:none;" placeholder="Result..."></textarea>
`;
const input = content.querySelector('#crypt-input');
const output = content.querySelector('#crypt-output');
content.querySelector('#btn-enc').onclick = () => {
try { output.value = btoa(input.value); } catch(e) { output.value = "Error: Invalid character set."; }
};
content.querySelector('#btn-dec').onclick = () => {
try { output.value = atob(input.value); } catch(e) { output.value = "Error: Invalid Base64 string."; }
};
},
setupTerminal(content, win) {
content.style.background = '#050505';
const output = document.createElement('div');
Object.assign(output.style, {
flex: '1', padding: '15px', color: '#00ff88', overflowY: 'auto', fontSize: '13px', lineHeight: '1.4'
});
output.innerHTML = `<div style="color:#00d4ff; white-space: pre;">${BPC.banner}</div><div>Type 'help' for local commands.</div>`;
const inputLine = document.createElement('div');
Object.assign(inputLine.style, { display: 'flex', padding: '5px 15px', background: '#000', borderTop: '1px solid #222' });
inputLine.innerHTML = `<span style="color:#0f8; margin-right:8px;">></span><input type="text" style="flex:1; background:transparent; border:none; color:#fff; outline:none; font-family:inherit; font-size:13px;">`;
const input = inputLine.querySelector('input');
input.onkeydown = async (e) => {
if (e.key === 'Enter') {
const cmd = input.value.trim();
const line = document.createElement('div');
line.innerHTML = `<span style="color:#aaa;">> ${cmd}</span>`;
output.appendChild(line);
// AI Command Interpretation
if (cmd.split(' ').length > 2 && !BPC.utils.isKnownCommand(cmd.split(' ')[0])) {
const aiLine = document.createElement('div');
aiLine.innerHTML = `<span style="color:#555;">[AI interpreting directive...]</span>`;
output.appendChild(aiLine);
const interpreted = await BPC.ai.interpretCommand(cmd);
aiLine.innerHTML = `<span style="color:#0df;">[AI -> Kernel]: ${interpreted}</span>`;
this.handleCommand(interpreted, output);
} else {
this.handleCommand(cmd, output);
}
input.value = '';
output.scrollTop = output.scrollHeight;
}
};
content.appendChild(output);
content.appendChild(inputLine);
win.onclick = () => input.focus();
},
setupBrowser(content, initialUrl) {
const tabBar = document.createElement('div');
Object.assign(tabBar.style, {
display: 'flex', background: '#111', padding: '5px 5px 0 5px', gap: '2px',
borderBottom: '1px solid #333', overflowX: 'auto', scrollbarWidth: 'none'
});
const webContainer = document.createElement('div');
Object.assign(webContainer.style, { flex: '1', position: 'relative', display: 'flex', flexDirection: 'column' });
const tabs = [];
const createTab = (url = 'https://www.google.com/search?igu=1') => {
const profileId = Math.floor(Math.random() * 10000);
const userAgent = BPC.anonProfiles[Math.floor(Math.random() * BPC.anonProfiles.length)];
const tabId = 'tab-' + Date.now();
const tab = {
id: tabId,
url: url,
ua: userAgent,
el: document.createElement('div'),
btn: document.createElement('div'),
history: [url],
historyIndex: 0,
torMode: false,
tunnelMode: false,
proxyMode: false
};
Object.assign(tab.btn.style, {
padding: '6px 15px', background: '#222', color: '#888', fontSize: '11px', borderTopLeftRadius: '6px', borderTopRightRadius: '6px',
cursor: 'pointer', display: 'flex', alignItems: 'center', gap: '8px', border: '1px solid #333', borderBottom: 'none',
minWidth: '120px', flexShrink: '0', transition: 'all 0.2s ease'
});
tab.btn.innerHTML = `<span class="tab-icon" style="color:#0df; font-size:10px;">🌐</span> <span class="tab-label" style="max-width:80px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">New Tab</span> <span class="tab-close" style="font-size:10px; margin-left:auto; opacity:0.3; transition:opacity 0.2s;">✕</span>`;
tab.btn.onmouseenter = () => tab.btn.querySelector('.tab-close').style.opacity = '1';
tab.btn.onmouseleave = () => tab.btn.querySelector('.tab-close').style.opacity = '0.3';
tab.btn.onclick = (e) => {
if (e.target.classList.contains('tab-close')) closeTab(tabs.indexOf(tab));
else switchTab(tabs.indexOf(tab));
};
Object.assign(tab.el.style, { display: 'none', flexDirection: 'column', flex: '1' });
const nav = document.createElement('div');
Object.assign(nav.style, { padding: '8px', background: '#222', display: 'flex', gap: '8px', alignItems: 'center', borderBottom: '1px solid #333' });
nav.innerHTML = `
<div style="display:flex; gap:4px;">
<button class="nav-back" title="Back" style="background:none; border:none; color:#888; cursor:pointer; padding:4px; font-size:14px; border-radius:4px;">⬅</button>
<button class="nav-forward" title="Forward" style="background:none; border:none; color:#888; cursor:pointer; padding:4px; font-size:14px; border-radius:4px;">➡</button>
<button class="nav-refresh" title="Reload" style="background:none; border:none; color:#888; cursor:pointer; padding:4px; font-size:14px; border-radius:4px;">↻</button>
<button class="nav-home" title="Home" style="background:none; border:none; color:#888; cursor:pointer; padding:4px; font-size:14px; border-radius:4px;">🏠</button>
<button class="nav-yt" title="YouTube Search" style="background:none; border:none; color:#ff0000; cursor:pointer; padding:4px; font-size:14px; border-radius:4px;">▶</button>
<button class="nav-dlmgr" title="Open Download Manager" style="background:none; border:none; color:#888; cursor:pointer; padding:4px; font-size:14px; border-radius:4px;">📂</button>
<button class="nav-download" title="Download to VFS" style="background:none; border:none; color:#0df; cursor:pointer; padding:4px; font-size:14px; border-radius:4px;">📥</button>
</div>
<div style="flex:1; display:flex; align-items:center; background:#111; border:1px solid #444; border-radius:20px; padding:2px 12px; gap:8px;">
<span class="nav-lock" style="color:#27c93f; font-size:10px;">🔒</span>
<input type="text" value="${tab.url}" style="flex:1; background:transparent; border:none; color:#eee; padding:4px 0; font-size:12px; outline:none;">
</div>
<div style="display:flex; align-items:center; gap:8px;">
<button class="nav-proxy" title="Safe Proxy (Bypass frame blocks)" style="background:#1a1a1a; border:1px solid #444; color:#555; padding:2px 8px; font-size:10px; border-radius:4px; cursor:pointer; transition:all 0.3s;">PROXY</button>
<button class="nav-tunnel" title="HTTPS Tunnel (Force HTTP mode)" style="background:#1a1a1a; border:1px solid #444; color:#555; padding:2px 8px; font-size:10px; border-radius:4px; cursor:pointer; transition:all 0.3s;">TUNNEL</button>
<button class="nav-tor" title="Toggle Tor Gateway (.onion access)" style="background:#1a1a1a; border:1px solid #444; color:#555; padding:2px 8px; font-size:10px; border-radius:4px; cursor:pointer; transition:all 0.3s;">TOR GATE</button>
<div title="Route: Encrypted" style="background:#404; color:#f0f; padding:2px 6px; font-size:9px; border-radius:3px; cursor:help; font-weight:bold;">VPN</div>
<div title="${userAgent}" style="font-size:10px; color:#555; cursor:help; white-space:nowrap; background:#000; padding:2px 6px; border-radius:3px; border:1px solid #333;">🛡️ ID: ${profileId}</div>
</div>
`;
const iframe = document.createElement('iframe');
Object.assign(iframe.style, { flex: '1', border: 'none', background: '#fff' });
iframe.src = tab.url;
const ytView = document.createElement('div');
Object.assign(ytView.style, {
display: 'none', flex: '1', background: '#0f0f0f', color: '#fff',
padding: '40px', overflowY: 'auto', fontFamily: 'sans-serif'
});
ytView.innerHTML = `
<div style="max-width: 800px; margin: 0 auto; text-align: center;">
<div style="color: #ff0000; font-size: 48px; font-weight: bold; margin-bottom: 20px; display: flex; align-items: center; justify-content: center; gap: 15px;">
<span style="background: #fff; border-radius: 12px; padding: 0 10px; display: flex; align-items: center; justify-content: center;">▶</span> YouTube
</div>
<p style="color: #aaa; margin-bottom: 30px;">Search for content across the sovereign video mesh.</p>
<div style="display: flex; gap: 10px; margin-bottom: 50px;">
<input id="yt-search-input" type="text" placeholder="Search videos..." style="flex: 1; padding: 15px 25px; border-radius: 30px; border: 1px solid #333; background: #121212; color: #fff; font-size: 16px; outline: none;">
<button id="yt-search-btn" style="background: #fff; color: #000; border: none; padding: 0 30px; border-radius: 30px; font-weight: bold; cursor: pointer; transition: background 0.2s;">SEARCH</button>
</div>
<div id="yt-results" style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; text-align: left;">
<!-- Results will appear here -->
</div>
</div>
`;
const urlInput = nav.querySelector('input');
const torBtn = nav.querySelector('.nav-tor');
const tunnelBtn = nav.querySelector('.nav-tunnel');
const proxyBtn = nav.querySelector('.nav-proxy');
const ytBtn = nav.querySelector('.nav-yt');
const dlBtn = nav.querySelector('.nav-download');
const dlMgrBtn = nav.querySelector('.nav-dlmgr');
const navLock = nav.querySelector('.nav-lock');
const tabIcon = tab.btn.querySelector('.tab-icon');
dlMgrBtn.onclick = () => window.dlMgrApp();
dlBtn.onclick = async () => {
const targetUrl = prompt("Enter URL to download to VFS:", urlInput.value);
if (!targetUrl) return;
const fileName = targetUrl.split('/').pop().split('?')[0] || 'downloaded_file';
const dlPath = BPC.registry.get('downloads_path') || 'Downloads';
const fullPath = `${dlPath}/${fileName}`;
const dlEntry = { name: fileName, path: fullPath, status: 'Downloading...' };
BPC.downloads.push(dlEntry);
BPC.logs.add(`VFS: Capturing ${fileName} to /${dlPath}/`, 'info');
// Ensure downloads folder exists
await BPC.fs.mkdir(dlPath);
const proxies = [
(url) => url,
(url) => `https://api.allorigins.win/get?url=${encodeURIComponent(url)}`,
(url) => `https://corsproxy.io/?${encodeURIComponent(url)}`
];
let success = false;
for (let pIdx = 0; pIdx < proxies.length; pIdx++) {
try {
const finalUrl = proxies[pIdx](targetUrl);
const response = await fetch(finalUrl);
if (!response.ok) continue;
let blob;
if (pIdx === 1) { // AllOrigins
const json = await response.json();
blob = await (await fetch(json.contents)).blob();
} else {
blob = await response.blob();
}
const reader = new FileReader();
reader.onloadend = async () => {
await BPC.fs.write(fullPath, reader.result);
dlEntry.status = 'Complete';
BPC.logs.add(`VFS: Successfully saved ${fileName} to /${dlPath}/`, 'success');
};
reader.readAsDataURL(blob);
success = true;
break;
} catch (e) { continue; }
}
if (!success) {
dlEntry.status = 'Failed';
BPC.logs.add(`VFS: Failed to download ${fileName}. CORS or Proxy block.`, 'error');
}
};
const toggleYT = (show) => {
if (show) {
iframe.style.display = 'none';
ytView.style.display = 'flex';
urlInput.value = 'bpc://youtube';
tab.btn.querySelector('.tab-label').innerText = 'YouTube Search';
tabIcon.innerText = '▶';
tabIcon.style.color = '#f00';
tab.isYT = true;
} else {
iframe.style.display = 'block';
ytView.style.display = 'none';
tab.isYT = false;
}
};
ytBtn.onclick = () => toggleYT(ytView.style.display === 'none');
const searchYT = async () => {
const q = ytView.querySelector('#yt-search-input').value.trim();
if (!q) return;
const resultsDiv = ytView.querySelector('#yt-results');
resultsDiv.innerHTML = '<div style="grid-column: 1/-1; text-align: center; padding: 20px; color: #0df;">Scanning sovereign video mesh...</div>';
// Mesh Network: Mixed front-end APIs (Invidious & Piped)
// Many of these support CORS natively
const meshNodes = [
{ url: `https://pipedapi.kavin.rocks/search?q=${encodeURIComponent(q)}`, type: 'piped' },
{ url: `https://yewtu.be/api/v1/search?q=${encodeURIComponent(q)}`, type: 'invidious' },
{ url: `https://inv.tux.rs/api/v1/search?q=${encodeURIComponent(q)}`, type: 'invidious' },
{ url: `https://pipedapi.moomoo.me/search?q=${encodeURIComponent(q)}`, type: 'piped' },
{ url: `https://invidious.snopyta.org/api/v1/search?q=${encodeURIComponent(q)}`, type: 'invidious' }
];
const proxies = [
(url) => url, // Direct (CORS-native)
(url) => `https://api.allorigins.win/get?url=${encodeURIComponent(url)}`,
(url) => `https://corsproxy.io/?${encodeURIComponent(url)}`
];
let success = false;
for (let pIdx = 0; pIdx < proxies.length; pIdx++) {
for (let nIdx = 0; pIdx < meshNodes.length; nIdx++) {
try {
const node = meshNodes[nIdx];
if (!node) break;
const finalUrl = proxies[pIdx](node.url);
resultsDiv.innerHTML = `<div style="grid-column: 1/-1; text-align: center; padding: 20px; color: #0df;">Scanning mesh node ${nIdx + 1} (Route: ${pIdx === 0 ? 'Direct' : 'Proxy'})...</div>`;
const response = await fetch(finalUrl);
if (!response.ok) continue;
let data = await response.json();
// Handle AllOrigins wrapper
if (data.contents) data = JSON.parse(data.contents);
let items = [];
if (node.type === 'piped') {
items = (data.items || []).filter(i => i.type === 'stream').map(i => ({
videoId: i.url.split('v=')[1],
title: i.title,
author: i.uploaderName,
thumbnail: i.thumbnail,
duration: i.duration
}));
} else {
items = data.filter(i => i.type === 'video').map(i => ({
videoId: i.videoId,
title: i.title,
author: i.author,
thumbnail: i.videoThumbnails?.[0]?.url,
duration: i.lengthSeconds
}));
}
if (items.length === 0) continue;
resultsDiv.innerHTML = '';
items.slice(0, 10).forEach(video => {
const card = document.createElement('div');
Object.assign(card.style, {
background: '#1a1a1a', borderRadius: '8px', overflow: 'hidden', cursor: 'pointer',
transition: 'transform 0.2s', border: '1px solid #333'
});
card.onmouseenter = () => { card.style.transform = 'scale(1.02)'; card.style.borderColor = '#ff0000'; };
card.onmouseleave = () => { card.style.transform = 'scale(1)'; card.style.borderColor = '#333'; };
card.innerHTML = `
<div style="position:relative; width:100%; padding-top:56.25%; background:#000;">
<img src="${video.thumbnail || ''}" style="position:absolute; top:0; left:0; width:100%; height:100%; object-fit:cover;">
<div style="position:absolute; bottom:5px; right:5px; background:rgba(0,0,0,0.8); padding:2px 5px; font-size:10px; border-radius:3px;">${typeof video.duration === 'string' ? video.duration : Math.floor(video.duration/60)+':'+(video.duration%60).toString().padStart(2,'0')}</div>
</div>
<div style="padding:10px;">
<div style="font-size:13px; font-weight:bold; color:#fff; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; margin-bottom:5px;">${video.title}</div>
<div style="font-size:11px; color:#888;">${video.author}</div>
</div>
`;
card.onclick = () => {
toggleYT(false);
navigate(`https://www.youtube-nocookie.com/embed/${video.videoId}`);
};
resultsDiv.appendChild(card);
});
success = true;
break;
} catch (e) { continue; }
}
if (success) break;
}
if (!success) {
resultsDiv.innerHTML = `<div style="grid-column: 1/-1; text-align: center; color: #f44;">Signal Failure: All mesh nodes are currently unreachable. Please try Proxy mode or check network.</div>`;
}
};
ytView.querySelector('#yt-search-btn').onclick = searchYT;
ytView.querySelector('#yt-search-input').onkeydown = (e) => { if(e.key === 'Enter') searchYT(); };
const updateTorUI = () => {
if (tab.torMode) {
torBtn.style.background = '#404';
torBtn.style.color = '#f0f';
torBtn.style.borderColor = '#f0f';
torBtn.style.boxShadow = '0 0 5px #f0f';
navLock.innerText = '🧅';
navLock.style.color = '#f0f';
tabIcon.innerText = '🧅';
tabIcon.style.color = '#f0f';
} else {
torBtn.style.background = '#1a1a1a';
torBtn.style.color = '#555';
torBtn.style.borderColor = '#444';
torBtn.style.boxShadow = 'none';
navLock.innerText = tab.proxyMode ? '🛡️' : (tab.tunnelMode ? '🔓' : '🔒');
navLock.style.color = tab.proxyMode ? '#0df' : (tab.tunnelMode ? '#ffaa00' : '#27c93f');
tabIcon.innerText = '🌐';
tabIcon.style.color = '#0df';
}
};
const updateTunnelUI = () => {
if (tab.tunnelMode) {
tunnelBtn.style.background = '#442200';
tunnelBtn.style.color = '#ffaa00';
tunnelBtn.style.borderColor = '#ffaa00';
tunnelBtn.style.boxShadow = '0 0 5px #ffaa00';
} else {
tunnelBtn.style.background = '#1a1a1a';
tunnelBtn.style.color = '#555';
tunnelBtn.style.borderColor = '#444';
tunnelBtn.style.boxShadow = 'none';
}
updateTorUI();
};
const updateProxyUI = () => {
if (tab.proxyMode) {
proxyBtn.style.background = '#003344';
proxyBtn.style.color = '#0df';
proxyBtn.style.borderColor = '#0df';
proxyBtn.style.boxShadow = '0 0 5px #0df';
} else {
proxyBtn.style.background = '#1a1a1a';
proxyBtn.style.color = '#555';
proxyBtn.style.borderColor = '#444';
proxyBtn.style.boxShadow = 'none';
}
updateTorUI();
};
torBtn.onclick = () => {
tab.torMode = !tab.torMode;
if (tab.torMode) { tab.tunnelMode = false; tab.proxyMode = false; }
updateTorUI(); updateTunnelUI(); updateProxyUI();
BPC.logs.add(`Browser: Tor Mode ${tab.torMode ? 'ENABLED' : 'DISABLED'} for tab.`, tab.torMode ? 'anon' : 'info');
navigate(urlInput.value);
};
tunnelBtn.onclick = () => {
tab.tunnelMode = !tab.tunnelMode;
if (tab.tunnelMode) { tab.torMode = false; tab.proxyMode = false; }
updateTunnelUI(); updateTorUI(); updateProxyUI();
BPC.logs.add(`Browser: HTTP Tunnel Mode ${tab.tunnelMode ? 'ENABLED' : 'DISABLED'}.`, tab.tunnelMode ? 'warn' : 'info');
navigate(urlInput.value);
};
proxyBtn.onclick = () => {
tab.proxyMode = !tab.proxyMode;
if (tab.proxyMode) { tab.torMode = false; tab.tunnelMode = false; }
updateProxyUI(); updateTorUI(); updateTunnelUI();
BPC.logs.add(`Browser: Proxy Mode ${tab.proxyMode ? 'ENABLED' : 'DISABLED'}.`, tab.proxyMode ? 'info' : 'info');
navigate(urlInput.value);
};
const navigate = (newUrl) => {
let finalUrl = newUrl.trim();
// Force YouTube to embed-friendly Invidious proxy to bypass SAMEORIGIN framing blocks
// UNLESS it's already a secure embed URL
if ((finalUrl.includes('youtube.com') || finalUrl.includes('youtu.be')) && !finalUrl.includes('/embed/')) {
BPC.logs.add("Browser: Redirecting YouTube request to secure embed mirror.", "warn");
if (finalUrl.includes('v=')) {
const vid = finalUrl.split('v=')[1].split('&')[0];
finalUrl = `https://www.youtube-nocookie.com/embed/${vid}`;
} else if (finalUrl.includes('watch/')) {
const vid = finalUrl.split('watch/')[1].split('?')[0];
finalUrl = `https://www.youtube-nocookie.com/embed/${vid}`;
} else if (finalUrl.includes('results?search_query=')) {
const q = finalUrl.split('search_query=')[1].split('&')[0];
finalUrl = `https://yewtu.be/search?q=${q}`;
} else {
finalUrl = finalUrl.replace(/youtube\.com|youtu\.be/, 'yewtu.be');
}
}
// Force HTTPS upgrade for all requests UNLESS Tunnel Mode or Proxy Mode is ON
if (!tab.tunnelMode && !tab.proxyMode && !finalUrl.includes('yewtu.be') && !finalUrl.includes('youtube-nocookie.com') && finalUrl.startsWith('http://')) {
finalUrl = finalUrl.replace('http://', 'https://');
}
// Handle Onion Domains
if (finalUrl.includes('.onion')) {
tab.torMode = true;
tab.tunnelMode = false;
tab.proxyMode = false;
updateTorUI();
updateTunnelUI();
updateProxyUI();
if (!finalUrl.includes('.onion.pet') && !finalUrl.includes('.onion.ly')) {
finalUrl = finalUrl.replace('.onion', '.onion.pet');
}
if (!finalUrl.startsWith('http')) finalUrl = 'https://' + finalUrl;
else if (finalUrl.startsWith('http://')) finalUrl = finalUrl.replace('http://', 'https://');
}
if (!finalUrl.startsWith('http') && !finalUrl.includes('.')) {
finalUrl = 'https://www.google.com/search?q=' + encodeURIComponent(finalUrl) + '&igu=1';
} else if (!finalUrl.startsWith('http')) {
finalUrl = (tab.tunnelMode ? 'http://' : 'https://') + finalUrl;
}
// If Proxy Mode is ON, we route through a specialized gateway to bypass X-Frame-Options
if (tab.proxyMode && !finalUrl.includes('onion') && !finalUrl.includes('yewtu.be')) {
finalUrl = 'https://www.google.com/search?igu=1&q=' + encodeURIComponent(finalUrl);
}
iframe.src = finalUrl;
tab.url = finalUrl;
urlInput.value = finalUrl;
tab.btn.querySelector('.tab-label').innerText = finalUrl.split('/')[2] || finalUrl;
// Simple history tracking
if (tab.history[tab.historyIndex] !== finalUrl) {
tab.history = tab.history.slice(0, tab.historyIndex + 1);
tab.history.push(finalUrl);
tab.historyIndex++;
}
};
urlInput.onkeydown = (e) => {
if (e.key === 'Enter') navigate(urlInput.value);
};
urlInput.onfocus = () => urlInput.select();
nav.querySelector('.nav-refresh').onclick = () => { iframe.src = iframe.src; };
nav.querySelector('.nav-home').onclick = () => navigate('https://www.google.com/search?igu=1');
nav.querySelector('.nav-back').onclick = () => {
if (tab.historyIndex > 0) {
tab.historyIndex--;
const prevUrl = tab.history[tab.historyIndex];
iframe.src = prevUrl;
urlInput.value = prevUrl;
tab.btn.querySelector('.tab-label').innerText = prevUrl.split('/')[2] || prevUrl;
}
};
nav.querySelector('.nav-forward').onclick = () => {
if (tab.historyIndex < tab.history.length - 1) {
tab.historyIndex++;
const nextUrl = tab.history[tab.historyIndex];
iframe.src = nextUrl;
urlInput.value = nextUrl;
tab.btn.querySelector('.tab-label').innerText = nextUrl.split('/')[2] || nextUrl;
}
};
// Add hover effects to nav buttons
nav.querySelectorAll('button').forEach(btn => {
btn.onmouseenter = () => btn.style.background = 'rgba(255,255,255,0.05)';
btn.onmouseleave = () => btn.style.background = 'none';
});
tab.el.appendChild(nav);
tab.el.appendChild(iframe);
tab.el.appendChild(ytView);
tabs.push(tab);
tabBar.insertBefore(tab.btn, addTabBtn);
webContainer.appendChild(tab.el);
switchTab(tabs.length - 1);
};
const switchTab = (index) => {
tabs.forEach((t, i) => {
t.el.style.display = i === index ? 'flex' : 'none';
t.btn.style.background = i === index ? '#1a1a1a' : '#222';
t.btn.style.color = i === index ? '#0df' : '#888';
t.btn.style.borderTop = i === index ? '2px solid #0df' : '1px solid #333';
t.btn.style.marginTop = i === index ? '0' : '2px';
});
};
const closeTab = (index) => {
tabs[index].el.remove();
tabs[index].btn.remove();
tabs.splice(index, 1);
if (tabs.length === 0) {
content.closest('.bpc-window').remove();
BPC.windows = BPC.windows.filter(w => w.el !== content.closest('.bpc-window'));
BPC.utils.updateTaskbar();
}
else switchTab(Math.max(0, index - 1));
};
const addTabBtn = document.createElement('div');
Object.assign(addTabBtn.style, {
padding: '6px 12px', color: '#0df', cursor: 'pointer', fontSize: '16px',
display: 'flex', alignItems: 'center', transition: 'background 0.2s'
});
addTabBtn.innerHTML = '+';
addTabBtn.onmouseenter = () => addTabBtn.style.background = 'rgba(255,255,255,0.05)';
addTabBtn.onmouseleave = () => addTabBtn.style.background = 'transparent';
addTabBtn.onclick = () => createTab();
tabBar.appendChild(addTabBtn);
content.appendChild(tabBar);
content.appendChild(webContainer);
createTab(initialUrl || 'https://www.google.com/search?igu=1');
},
makeResizable(win) {
const handle = document.createElement('div');
Object.assign(handle.style, {
position: 'absolute',
right: '0',
bottom: '0',
width: '15px',
height: '15px',
cursor: 'nwse-resize',
zIndex: '10',
background: 'linear-gradient(135deg, transparent 50%, #444 50%)',
borderBottomRightRadius: '6px'
});
win.appendChild(handle);
let isResizing = false;
let startRect = {};
let startPos = {};
handle.onmousedown = (e) => {
if (win.dataset.state === 'maximized') return;
e.preventDefault();
e.stopPropagation();
isResizing = true;
startRect = win.getBoundingClientRect();
startPos = { x: e.clientX, y: e.clientY };
this.focusWindow(win);
};
document.addEventListener('mousemove', (e) => {
if (!isResizing) return;
const dx = e.clientX - startPos.x;
const dy = e.clientY - startPos.y;
const newWidth = Math.max(300, startRect.width + dx);
const newHeight = Math.max(200, startRect.height + dy);
win.style.width = newWidth + 'px';
win.style.height = newHeight + 'px';
});
document.addEventListener('mouseup', () => isResizing = false);
},
handleCommand(cmd, output) {
const add = (text, color = '#fff') => {
const d = document.createElement('div');
d.style.color = color;
d.innerText = text;
output.appendChild(d);
};
const args = cmd.split(' ');
const command = args[0].toLowerCase();
switch(command) {
case 'help':
add('God-Mode OS v6.0:', '#00d4ff');
add(' browser [url] - Multi-tab sovereign browser');
add(' term - Spawn secondary terminal');
add(' cpu - Virtual CPU & Assembly Compiler');
add(' mesh - P2P Mesh Network Terminal');
add(' brain - Neural Backprop Trainer');
add(' ide - VFS Code Editor');
add(' bot - Sovereign Assistant');
add(' neural - NeuralNet Simulator');
add(' media - MediaSynth Engine');
add(' network - NetStack Monitor');
add(' db - V-Database Explorer');
add(' gpu - GPU Render Engine');
add(' kernel - Kernel Console');
add(' store - Dynamic App Store');
add('\nGod-Mode Commands:', '#ff00ff');
add(' cpu-exec [hex] - Direct opcode execution');
add(' mesh-join - Initialize WebRTC handshake');
add(' brain-sync - Export weight matrices to VFS');
break;
case 'cpu-exec':
BPC.cpu.reset();
BPC.cpu.memory[0] = parseInt(args[1], 16);
BPC.cpu.isRunning = true;
BPC.cpu.step();
add("Instruction executed.", '#0f0');
break;
case 'mesh-join': add("P2P Mesh Handshake sequence initiated...", '#ff00ff'); break;
case 'brain-sync': BPC.fs.write('brain_weights.json', JSON.stringify(BPC.brain.weights)); add("Brain weights synced to VFS.", '#0f8'); break;
case 'cpu': window.cpuApp(); break;
case 'mesh': window.meshApp(); break;
case 'brain': window.brainApp(); break;
case 'vwrite-enc': BPC.fs.write(args[1], args.slice(2).join(' '), true); add(`Encrypted file written: ${args[1]}`, '#ff00ff'); break;
case 'vread-enc': BPC.fs.read(args[1], args[2]).then(c => add(c === "DECRYPTION_FAILED" ? "ERROR: Invalid Key" : c, '#ff00ff')); break;
case 'cluster-sync': BPC.cluster.postMessage({ type: 'SYS_MSG', val: "Manual Cluster Handshake Initialized." }); add("Handshake sent.", '#0f0'); break;
case 'neural': window.neuralApp(); break;
case 'media': window.mediaApp(); break;
case 'network': window.networkApp(); break;
case 'db': window.dbApp(); break;
case 'cluster-send': BPC.cluster.postMessage({ type: 'SYS_MSG', val: args.slice(1).join(' ') }); add("Broadcast sent.", '#0f0'); break;
case 'ide': window.ideApp(); break;
case 'gpu': window.gpuApp(); break;
case 'bot': window.botApp(); break;
case 'vrm': BPC.fs.rm(args[1]); add(`Deleted: ${args[1]}`, '#f44'); break;
case 'fonts': window.fontApp(); break;
case 'crypt': window.cryptApp(); break;
case 'term': window.term(); break;
case 'settings': window.settingsApp(); break;
case 'taskmgr': window.taskMgr(); break;
case 'notes': window.notesApp(); break;
case 'kernel': window.kernelApp(); break;
case 'store': window.storeApp(); break;
case 'eval':
try { add(`RESULT: ${JSON.stringify(eval(args.slice(1).join(' ')))}`, '#0f0'); }
catch(e) { add(`ERROR: ${e}`, '#f44'); }
break;
case 'reg-set': BPC.registry.set(args[1], args[2]); add(`Registry updated: ${args[1]}`, '#0f0'); break;
case 'reg-get': add(`Registry [${args[1]}]: ${BPC.registry.get(args[1])}`, '#0df'); break;
case 'vls': BPC.fs.ls().then(files => files.forEach(f => add(` - ${f}`, '#ffaa00'))); break;
case 'vwrite': BPC.fs.write(args[1], args.slice(2).join(' ')); add(`File written: ${args[1]}`, '#0f8'); break;
case 'vread': BPC.fs.read(args[1]).then(c => add(c || 'File not found.', '#ffaa00')); break;
case 'windows':
add(`Active Windows (${BPC.windows.length}):`, '#0df');
BPC.windows.forEach(w => add(` - [${w.id}] ${w.title}`, '#aaa'));
break;
case 'free':
add(`Heap Limit: ${performance.memory ? (performance.memory.jsHeapSizeLimit / (1024*1024)).toFixed(2) : "N/A"} MB`);
add(`Heap Total: ${performance.memory ? (performance.memory.totalJSHeapSize / (1024*1024)).toFixed(2) : "N/A"} MB`);
add(`Heap Used : ${this.getMemoryUsage()} MB`, '#0f8');
break;
case 'purge':
add('Simulating memory purge...', '#ff8');
add('Released references from closed tabs.', '#0f8');
break;
case 'perf':
const t = performance.getEntriesByType("navigation")[0];
if (t) {
add(`Load Time: ${t.duration.toFixed(2)}ms`, '#ff8');
add(`DOM Ready: ${t.domInteractive.toFixed(2)}ms`, '#ff8');
} else {
add('Performance metrics not available.', '#f44');
}
break;
case 'mask':
add('Active Anonymity Masks:', '#f0f');
add(' - Randomized User-Agent per tab active');
add(' - Isolated storage hooks active');
add(' - Simulated node-routing active');
break;
case 'wipe':
sessionStorage.clear();
add('Session memory wiped.', '#0f8');
break;
case 'ls':
add('LocalStorage keys:', '#0d4ff');
if (localStorage.length === 0) {
add(' (empty)', '#888');
} else {
Object.keys(localStorage).forEach(k => {
let val = localStorage.getItem(k);
if (val.length > 40) val = val.substring(0, 37) + '...';
add(` ${k.padEnd(20)} : ${val}`, '#ccc');
});
}
break;
case 'set':
if (args.length < 3) {
add('Error: Usage "set [key] [value]"', '#f44');
} else {
const key = args[1];
const val = args.slice(2).join(' ');
localStorage.setItem(key, val);
add(`Set [${key}] successfully.`, '#0f8');
}
break;
case 'get':
if (!args[1]) {
add('Error: Usage "get [key]"', '#f44');
} else {
const val = localStorage.getItem(args[1]);
add(val !== null ? `${args[1]} = ${val}` : `Key [${args[1]}] not found.`, val !== null ? '#ff8' : '#f44');
}
break;
case 'rm':
if (!args[1]) {
add('Error: Usage "rm [key]"', '#f44');
} else {
localStorage.removeItem(args[1]);
add(`Removed [${args[1]}].`, '#0f8');
}
break;
case 'find':
if (!args[1]) {
add('Error: Usage "find [key]"', '#f44');
} else {
add(`Searching for "${args[1]}" in window...`, '#0df');
const results = this.findInObj(window, args[1]);
if (results.length === 0) {
add('No matches found.', '#aaa');
} else {
results.forEach(r => add(` FOUND: ${r.path}`, '#0f8'));
}
}
break;
case 'browser': window.browser(args[1]); break;
case 'exit': output.closest('.bpc-window').remove(); BPC.windows = BPC.windows.filter(w => w.el !== output.closest('.bpc-window')); this.updateTaskbar(); break;
case 'clear': output.innerHTML = ''; break;
default: if (cmd) add(`ERR: Command '${command}' not found. Type 'help'.`, '#f44');
}
}
}
};
console.log(`%c${BPC.banner}`, "color: #61afef; font-family: monospace;");
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () => BPC.utils.initOS());
else BPC.utils.initOS();
})();