Compare commits

...

48 Commits
master ... main

Author SHA1 Message Date
043d121847 Fix versions numbering 2025-06-07 22:51:14 -07:00
525064596f Version Bump 2025-06-07 22:47:28 -07:00
𓍼
7beb269867 version 2025-06-08 00:44:18 -05:00
𓍼
20d49560e9 stuff 2025-06-08 00:43:31 -05:00
𓍼
396b81929a forgot the dot 2025-06-07 22:13:23 -05:00
𓍼
b2ad89c28a remove subjects 2025-06-07 17:17:38 -05:00
𓍼
ee3092a590 Smaller 2025-06-07 16:56:39 -05:00
𓍼
265de4f542 UPDATEEEE 2025-06-07 16:54:12 -05:00
𓍼
c2a6cb8639 uh 2025-06-06 19:06:46 -05:00
𓍼
6fd71fa6fa ? 2025-06-06 19:02:40 -05:00
𓍼
994cb17641 hi 2025-06-06 19:01:51 -05:00
𓍼
c265e724c9 Fix latest commit 2025-06-06 12:52:49 -05:00
𓍼
dc72461a68 Fix latest commit 2025-06-06 12:44:31 -05:00
2b1a912478 Update others/scaler.mjs 2025-06-05 21:26:40 -07:00
78fbc42a0c Add others/scaler.mjs 2025-06-05 21:25:37 -07:00
65bc526a91 Delete others/scaler.mjs 2025-06-05 21:24:46 -07:00
bc878dfb64 Add others/scaler.mjs 2025-06-05 21:23:14 -07:00
a083758325 Delete others/scaler.mjs 2025-06-05 21:22:22 -07:00
b622f3cb9b Cool Thingy 2025-06-05 21:18:57 -07:00
ff50de3064 Update index.mjs 2025-06-05 21:12:54 -07:00
c13a708584 Update others/scaler.mjs 2025-06-05 21:12:21 -07:00
8845426001 60000 2025-06-05 21:10:10 -07:00
𓍼
89279a6735 Something 2025-06-05 22:52:01 -05:00
𓍼
526ec4f236 Merge branch 'main' of https://gitea.sentt.lol/sent/waves 2025-06-05 22:50:24 -05:00
𓍼
f78a14b79c Something 2025-06-05 22:49:17 -05:00
e50b65dde1 Update public/$.html 2025-06-01 19:53:00 -07:00
f0529b100e Update public/assets/js/register.js 2025-06-01 19:49:22 -07:00
4658e475ef idk 2025-06-01 19:40:51 -07:00
𓍼
7b3737d44c Rename the API 2025-05-25 17:41:29 -05:00
𓍼
91e44ce19a Remove ads on 1v1.LOL 2025-05-25 14:43:27 -05:00
𓍼
ac7cc48119 ok 2025-05-25 14:27:15 -05:00
𓍼
d9de280d3d Last update for today 2025-05-25 14:25:58 -05:00
𓍼
1fb3876cd4 Fixes 2025-05-25 14:24:32 -05:00
𓍼
c568949e74 cool 2025-05-25 12:48:11 -05:00
𓍼
6f84c2a9e5 okay 2025-05-25 12:34:36 -05:00
𓍼
97a6a4a94a Remove lat updated label and only keep latest commit id 2025-05-25 12:27:18 -05:00
𓍼
e1b5f73c31 Whoops 2025-05-25 09:50:37 -05:00
𓍼
87f8a54656 Wrong one 2025-05-25 09:49:18 -05:00
𓍼
84b0c084de only get latest update 2025-05-25 09:47:27 -05:00
𓍼
6a269bbaae Accidentaly remove the banned ad 2025-05-25 09:36:22 -05:00
𓍼
9f9a892798 wv 2025-05-25 09:33:51 -05:00
𓍼
ff7390d3ae Top 2025-05-25 09:32:20 -05:00
𓍼
7ae9abb1ad Remove a game (it wasn't supposed to be push) and update the verification script 2025-05-25 09:30:11 -05:00
𓍼
cd4c462e62 Small Update 🤍 2025-05-25 09:20:08 -05:00
𓍼
b5a927077a Back to DuckDuckGo 2025-05-22 11:48:45 -05:00
𓍼
5996c1a6e0 Brave? 2025-05-21 23:33:19 -05:00
𓍼
ffe52a61e7 Colors Change 2025-05-21 23:30:03 -05:00
4551ab18c1 Merge pull request 'Small Little Update' (#2) from master into main
Reviewed-on: https://gitea.sentt.lol/sent/waves/pulls/2
2025-05-21 21:24:35 -07:00
33 changed files with 2807 additions and 37096 deletions

View File

@ -4,7 +4,9 @@
The following versions of this project that are currently supported and unsupported:
- **Version 2.3.5** Supported ✅
- **Version 2.8.9** Supported ✅
- **Version 2.8.7** Supported ✅
- **Version 2.8.5** Supported ✅
- **Version 2.3.1** Supported ✅
- **Version 2.3.0** Supported ✅
- **Version 2.2.0** Supported ✅
@ -17,4 +19,4 @@ The following versions of this project that are currently supported and unsuppor
## Support
If you are experiencing an issue with Waves unrelated to security, feel free to join our [Discord](https://discord.gg/dJvdkPRheV) server and open a ticket.
If you are experiencing an issue with Waves unrelated to security, feel free to join our [Discord Server](https://discord.gg/dJvdkPRheV) and open a ticket.

191
index.mjs
View File

@ -2,8 +2,8 @@ import cluster from "cluster";
import os from "os";
import net from "net";
import fs from "fs";
import { spawnSync } from "child_process";
import path from "path";
import { spawnSync } from "child_process";
import express from "express";
import { createServer } from "http";
import compression from "compression";
@ -23,28 +23,22 @@ function applySurgeAndRestartIfNeeded() {
try {
const config = JSON.parse(fs.readFileSync(surgeConfigPath, "utf-8"));
process.env.UV_THREADPOOL_SIZE = String(config.uvThreadpoolSize);
} catch {
}
} catch {}
return;
}
console.log('[~] Running Surge...');
const result = spawnSync("node", ["./others/surge.mjs"], { stdio: "inherit" });
if (result.error) {
console.error('[!] Surger failed:', result.error);
process.exit(1);
}
if (result.error) process.exit(1);
const config = JSON.parse(fs.readFileSync(surgeConfigPath, "utf-8"));
const nodeArgs = config.nodeFlags.concat([path.resolve("index.mjs"), "--surged"]);
const nodeArgs = [...config.nodeFlags, path.resolve("index.mjs"), "--surged"];
const env = {
...process.env,
UV_THREADPOOL_SIZE: String(config.uvThreadpoolSize),
ALREADY_SURGED: "true"
};
console.log(`[~] Relaunching with Node flags: ${config.nodeFlags.join(' ')}`);
const relaunch = spawnSync(process.execPath, nodeArgs, { stdio: 'inherit', env });
const relaunch = spawnSync(process.execPath, nodeArgs, { stdio: "inherit", env });
process.exit(relaunch.status || 0);
}
@ -53,39 +47,40 @@ applySurgeAndRestartIfNeeded();
if (global.gc) {
setInterval(() => {
const { heapUsed, heapTotal } = process.memoryUsage();
if (heapTotal > 0 && heapUsed / heapTotal > 0.7) {
global.gc();
console.info('[~] Performed GC due to high heap usage');
}
}, 60_000);
if (heapTotal > 0 && heapUsed / heapTotal > 0.8) global.gc();
}, 120000);
}
import './others/scaler.mjs';
import './others/warmup.mjs';
const cache = new LRUCache({
maxSize: 1000,
ttl: 4 * 24 * 60 * 60 * 1000,
allowStale: false,
});
import "./others/scaler.mjs";
import "./others/warmup.mjs";
const port = parseInt(process.env.PORT || "3000", 10);
function logInfo(msg) { console.info(`[~] ${msg}`); }
function logSuccess(msg) { console.info(`[+] ${msg}`); }
function logError(err) { console.error(`[!] ${err instanceof Error ? err.message : err}`); }
function logInfo(msg) {
console.info(`[~] ${msg}`);
}
function logSuccess(msg) {
console.info(`[+] ${msg}`);
}
function logError(err) {
console.error(`[!] ${err instanceof Error ? err.message : err}`);
}
process.on("uncaughtException", err => logError(`Unhandled Exception: ${err}`));
process.on("unhandledRejection", reason => logError(`Unhandled Rejection: ${reason}`));
if (cluster.isPrimary) {
const cpus = os.cpus().length;
const workers = Math.max(1, cpus - 1);
logInfo(`Master: forking ${workers} of ${cpus} cores`);
for (let i = 0; i < workers; i++) cluster.fork();
const workers = Math.max(1, os.cpus().length - 1);
logInfo(`Master: forking ${workers} workers`);
cluster.on("exit", (worker, code, signal) => {
logError(`Worker ${worker.process.pid} exited (code=${code}, signal=${signal}). Restarting...`);
for (let i = 0; i < workers; i++) {
cluster.fork();
}
cluster.on("exit", worker => {
logError(`Worker ${worker.process.pid} exited. Restarting...`);
cluster.fork();
});
@ -98,23 +93,31 @@ if (cluster.isPrimary) {
});
server.on("error", err => logError(`Server error: ${err}`));
server.listen(port, () => logSuccess(`Server listening on port ${port}`));
server.listen(port, () => logSuccess(`Server listening on ${port}`));
} else {
const __dirname = process.cwd();
const publicPath = path.join(__dirname, "public");
const app = express();
const cache = new LRUCache({
max: 500,
ttl: 60_000,
allowStale: false
});
const latencySamples = new Array(200);
app.use(compression({ level: 4, memLevel: 4, threshold: 1024 }));
app.use((req, res, next) => {
if (req.path.startsWith("/api/")) return next();
const key = req.originalUrl;
const val = cache.get(key);
if (val) {
res.setHeader("X-Cache", "HIT");
return res.send(val);
}
res.sendResponse = res.send.bind(res);
res.sendResponse = res.send;
res.send = body => {
cache.set(key, body);
res.setHeader("X-Cache", "MISS");
@ -123,67 +126,97 @@ if (cluster.isPrimary) {
next();
});
const staticOpts = { maxAge: "7d", immutable: true };
const staticOpts = { maxAge: "7d", immutable: true, etag: false };
app.use("/baremux/", express.static(baremuxPath, staticOpts));
app.use("/epoxy/", express.static(epoxyPath, staticOpts));
app.use("/libcurl/", express.static(libcurlPath, staticOpts));
app.use(express.static(publicPath, staticOpts));
app.use("/wah/", express.static(uvPath, staticOpts));
app.use(express.json());
const sendHtml = file => (_req, res) => res.sendFile(path.join(publicPath, file));
const sendHtml = file => (req, res) => res.sendFile(path.join(publicPath, file));
app.get('/', sendHtml('$.html'));
app.get('/g', sendHtml('!.html'));
app.get('/a', sendHtml('!!.html'));
app.get('/resent', (req, res) => res.sendFile(path.join(publicPath, 'resent', 'index.html')));
app.use((req, res) => res.status(404).sendFile(path.join(publicPath, '404.html')));
app.get("/", sendHtml("$.html"));
app.get("/g", sendHtml("!.html"));
app.get("/s", sendHtml("!!.html"));
app.get("/resent", (_req, res) => res.sendFile(path.join(publicPath, "resent", "index.html")));
const server = createServer(app);
server.keepAliveTimeout = 0;
server.headersTimeout = 0;
const pingWSS = new WebSocket.Server({ noServer: true, maxPayload: 4 * 1024 * 1024, perMessageDeflate: false });
pingWSS.on("connection", (ws, req) => {
const remote = req.socket.remoteAddress || 'unknown';
let lat = [];
const interval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify({ type: 'ping', timestamp: Date.now() }));
}, 1000);
ws.on('message', msg => {
try {
const data = JSON.parse(msg);
if (data.type === 'pong' && data.timestamp) {
const d = Date.now() - data.timestamp;
lat.push(d);
if (lat.length > 5) lat.shift();
ws.send(JSON.stringify({ type: 'latency', latency: d }));
}
} catch(e) { logError(`Ping error: ${e}`); }
});
ws.on('close', () => {
clearInterval(interval);
const avg = lat.length ? (lat.reduce((a,b)=>a+b)/lat.length).toFixed(2) : 0;
logInfo(`WS ${remote} closed. Avg latency ${avg}ms`);
app.get("/api/info", (_req, res) => {
const validSamples = latencySamples.filter(s => s !== undefined);
const average = validSamples.length ? validSamples.reduce((a, b) => a + b, 0) / validSamples.length : 0;
res.json({
speed: average < 200 ? "Fast" : average > 500 ? "Slow" : "Medium",
averageLatency: average.toFixed(2),
timestamp: Date.now()
});
});
server.on('upgrade', (req, sock, head) => {
if (req.url === '/w/ping') {
pingWSS.handleUpgrade(req, sock, head, ws => pingWSS.emit('connection', ws, req));
} else if (req.url.startsWith('/w/')) {
app.use((_req, res) => res.status(404).sendFile(path.join(publicPath, "404.html")));
const server = createServer(app);
server.keepAliveTimeout = 5000;
server.headersTimeout = 10000;
const pingWSS = new WebSocket.Server({
noServer: true,
maxPayload: 16384,
perMessageDeflate: false
});
pingWSS.on("connection", (ws, req) => {
const remote = req.socket.remoteAddress || "unknown";
const lat = [];
let sampleIndex = 0;
const sendPing = () => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: "ping", timestamp: Date.now() }));
}
};
const pingInterval = setInterval(sendPing, 500);
sendPing();
ws.on("message", msg => {
try {
const data = JSON.parse(msg);
if (data.type === "pong" && data.timestamp) {
const d = Date.now() - data.timestamp;
lat.push(d);
if (lat.length > 10) lat.shift();
latencySamples[sampleIndex % latencySamples.length] = d;
sampleIndex = (sampleIndex + 1) % latencySamples.length;
ws.send(JSON.stringify({ type: "latency", latency: d }), { compress: false });
}
} catch {}
});
ws.on("close", () => {
clearInterval(pingInterval);
const avg = lat.length ? (lat.reduce((a, b) => a + b) / lat.length).toFixed(2) : 0;
logInfo(`WS ${remote} closed. Avg: ${avg}ms`);
});
});
server.on("upgrade", (req, sock, head) => {
if (req.url === "/w/ping") {
pingWSS.handleUpgrade(req, sock, head, ws =>
pingWSS.emit("connection", ws, req)
);
} else if (req.url.startsWith("/w/")) {
wisp.routeRequest(req, sock, head);
} else {
sock.end();
sock.destroy();
}
});
server.on('error', err => logError(`Worker server error: ${err}`));
server.on("error", err => logError(`Worker error: ${err}`));
server.listen(0, () => logSuccess(`Worker ${process.pid} ready`));
process.on('message', (msg, conn) => {
if (msg === 'sticky-session:connection' && conn) {
server.emit('connection', conn);
process.on("message", (msg, conn) => {
if (msg === "sticky-session:connection" && conn) {
server.emit("connection", conn);
conn.resume();
}
});

View File

@ -6,7 +6,7 @@ let cache = makeCache(maxKeys);
function makeCache(maxEntries) {
return new LRUCache({
maxSize: maxEntries,
ttl: 4 * 24 * 60 * 60 * 1_000,
ttl: 60_000,
allowStale: false,
updateAgeOnGet: false,
updateAgeOnHas: false,

3340
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +1,41 @@
{
"name": "waves",
"version": "2.8.5",
"description": "A sleek and minimalist Web Proxy.",
"type": "module",
"engines": {
"npm": ">=7.0.0",
"node": ">=16.0.0"
},
"scripts": {
"start": "node index.mjs",
"dev": "nodemon index.mjs",
"lint": "eslint ."
},
"author": {
"name": "sent",
"email": "sentttt@proton.me"
},
"dependencies": {
"@mercuryworkshop/bare-mux": "latest",
"@mercuryworkshop/epoxy-transport": "latest",
"@mercuryworkshop/libcurl-transport": "latest",
"@titaniumnetwork-dev/ultraviolet": "latest",
"axios": "^1.8.2",
"cache": "^3.0.0",
"compression": "latest",
"cors": "^2.8.5",
"express": "latest",
"express-rate-limit": "^7.5.0",
"fs": "^0.0.1-security",
"node": "^23.9.0",
"lru-cache": "^11.1.0",
"node-fetch": "latest",
"wisp-server-node": "latest",
"ws": "latest"
},
"devDependencies": {
"eslint": "latest",
"glob": "latest",
"nodemon": "latest",
"prettier": "latest",
"rimraf": "latest"
}
}
"name": "waves",
"version": "2.8.9",
"description": "A sleek and minimalist Web Proxy.",
"type": "module",
"engines": {
"npm": ">=7.0.0",
"node": ">=16.0.0"
},
"scripts": {
"start": "node index.mjs",
"dev": "nodemon index.mjs",
"lint": "eslint ."
},
"author": {
"name": "sent",
"email": "sentttt@proton.me"
},
"dependencies": {
"@mercuryworkshop/bare-mux": "latest",
"@mercuryworkshop/epoxy-transport": "latest",
"@mercuryworkshop/libcurl-transport": "latest",
"@titaniumnetwork-dev/ultraviolet": "latest",
"axios": "latest",
"cache": "latest",
"compression": "latest",
"cors": "latest",
"express": "latest",
"express-rate-limit": "latest",
"lru-cache": "latest",
"wisp-server-node": "latest",
"ws": "latest"
},
"devDependencies": {
"eslint": "latest",
"glob": "latest",
"nodemon": "latest",
"prettier": "latest",
"rimraf": "latest"
}
}

View File

@ -1,110 +1,155 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content="Waves. - Apps"/>
<meta property="og:description" content="A sleek and minimalist web proxy."/>
<meta property="og:image" content="/assets/images/icons/favicon.ico"/>
<meta name="theme-color" content="#ffffff"/>
<meta name="msapplication-TileColor" content="#ffffff"/>
<title>Waves.</title>
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico">
<link rel="stylesheet" href="/assets/css/$.css">
<link rel="stylesheet" href="/assets/css/settings.css">
<link rel="stylesheet" href="/assets/css/toast.css">
<link rel="stylesheet" href="/assets/css/a.css">
<link href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-WGJ2192JZY');</script>
<script type='text/javascript' src='//pl26200262.effectiveratecpm.com/f0/e8/15/f0e81559842363ebf19aa99900ff2d02.js'></script>
</head>
<body>
<script src="/baremux/index.js"></script>
<script src="/wah/uv.bundle.js" defer></script>
<script src="/wah/cute1.js" defer></script>
<script src="/assets/js/navbar.js?v=2.8.4" defer></script>
<script src="/assets/js/load.js?v=2.8.4" defer></script>
<script src="/assets/js/eruda.js?v=2.8.4" defer></script>
<script src="/assets/js/register.js?v=2.8.5" defer></script>
<script src="/assets/js/settings.js?v=2.8.5" defer></script>
<script src="/assets/js/greetings.js?v=2.8.5" defer></script>
<script src="/assets/js/shortcuts.js?v=2.8.4" defer></script>
<script src="/assets/js/$.js?v=2.8.4" defer></script>
<script src="/assets/js/a.js?v=2.8.4" defer></script>
<div class="relative flex flex-col h-[100vh] items-center justify-center bg-black transition-bg">
<div class="absolute inset-0 overflow-hidden">
<div class="god-rays absolute -inset-[10px] opacity-50"></div>
</div>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content="Waves." />
<meta property="og:description" content="A sleek and minimalist web proxy." />
<meta property="og:image" content="/assets/images/icons/favicon.ico" />
<meta name="theme-color" content="#ffffff" />
<meta name="msapplication-TileColor" content="#ffffff" />
<title>Waves.</title>
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico" />
<link rel="stylesheet" href="/assets/css/$.css" />
<link rel="preload" href="/assets/css/settings.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel="preload" href="/assets/css/toast.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel="preload" href="/assets/css/nprogress.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel="preload" href="/assets/css/s.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<noscript>
<link rel="stylesheet" href="/assets/css/settings.css" />
<link rel="stylesheet" href="/assets/css/toast.css" />
<link rel="stylesheet" href="/assets/css/nprogress.css" />
<link rel="stylesheet" href="/assets/css/s.css" />
</noscript>
<link rel="preload" as="style" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" onload="this.onload=null;this.rel='stylesheet'" />
<noscript>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" />
</noscript>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "G-WGJ2192JZY");
</script>
</head>
<body>
<script src="/baremux/index.js" defer></script>
<script src="/assets/js/nprogress.js?v=0.2.0" defer></script>
<script src="/wah/uv.bundle.js" defer></script>
<script src="/wah/cute1.js" defer></script>
<script src="/assets/js/eruda.js?v=2.8.4" defer></script>
<script src="/assets/js/register.js?v=2.8.9" defer></script>
<script src="/assets/js/settings.js?v=2.8.9" defer></script>
<script src="/assets/js/greetings.js?v=2.8.9" defer></script>
<script src="/assets/js/shortcuts.js?v=2.8.9" defer></script>
<script src="/assets/js/$.js?v=2.8.9" defer></script>
<script src="/assets/js/s.js?v=2.8.9" defer></script>
<script src="/assets/js/wv.js?v=1.4.1" defer></script>
<div class="relative flex flex-col h-[100vh] items-center justify-center bg-black transition-bg">
<div class="absolute inset-0 overflow-hidden">
<div class="god-rays absolute -inset-[10px] opacity-50"></div>
</div>
<div class="home-navbar">
<img src="/assets/images/icons/favicon.ico" class="favicon">
<span id="waves">Waves.</span>
<a href="/" id="home">Home</a>
<a href="/g" id="games">Games</a>
<a href="/a" id="apps" style="color: #ffffff;">Apps</a>
<a href="#" id="movies">Movies</a>
<a href="#" id="ai">AI</a>
<a href="#" id="settings-icon">
<i class="settings-icon fa-regular fa-gear"></i>
</a>
</div>
<div class="home-navbar">
<img src="/assets/images/icons/favicon.ico" class="favicon" alt="favicon" />
<span id="waves">Waves.</span>
<a href="/" id="home">Home</a>
<a href="/g" id="games">Games</a>
<a href="/s" id="shortcuts" style="color: #ffffff;">Shortcuts</a>
<a href="#" id="movies">Movies</a>
<a href="#" id="ai">AI</a>
<a href="#" id="settings-icon">
<i class="settings-icon fa-regular fa-gear"></i>
</a>
</div>
<div id="settings-menu" class="settings-menu"></div>
<div class="navbar">
<ul class="nav-buttons">
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li>
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li>
<li>
<div class="small-searchbar" style="position: relative;">
<i id="lockIcon" class="fa-solid fa-lock"></i>
<input class="waves" type="text" id="searchInputt" placeholder="Search for a query or enter a URL..." autocomplete="off" style="padding-left: 40px;" />
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/s"><i class="fa-regular fa-rocket"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
</div>
<div class="content shortcuts-page">
<h1>Shortcuts</h1>
<div class="shortcuts-search-bar">
<input type="text" id="shortcutSearchInput" placeholder="Search shortcuts..." autocomplete="off" />
<span class="shortcut-indicator-4">Ctrl + S</span>
</div>
<div id="settings-menu" class="settings-menu"></div>
<div class="navbar">
<ul class="nav-buttons">
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li>
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li>
<li>
<div class="small-searchbar" style="position: relative;">
<i id="lockIcon" class="fa-solid fa-lock"></i>
<input class="waves" type="text" id="searchInputt"
placeholder="Search for a query or enter a URL..." autocomplete="off"
style="padding-left: 40px;">
<span class="shortcut-indicator-2">Ctrl + S</span>
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/a"><i class="fa-regular fa-grid-2"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
<div class="shortcuts-grid"></div>
</div>
<div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div>
<div id="overlay" class="overlay"></div>
<div id="namePrompt" class="popup">
<div class="input-container">
<label for="userName">Please enter a name so we know what to call you:</label>
<div class="input-wrapper">
<input type="text" id="userName" placeholder="Your name" autocomplete="off" />
</div>
<button id="doneButton" onclick="submitName()" disabled><i class="fa-regular fa-check"></i> Done</button>
</div>
<div class="content apps-page">
<h1>Apps</h1>
<div class="apps-search-bar">
<input type="text" id="appSearchInput" placeholder="Search apps..." autocomplete="off" />
<span class="shortcut-indicator-4">Ctrl + S</span>
</div>
<div class="apps-grid">
</div>
</div>
<div id="overlay" class="overlay"></div>
<div id="namePrompt" class="popup">
<div class="input-container">
<label for="userName">Please enter a name so we know what to call you:</label>
<div class="input-wrapper">
<input type="text" id="userName" placeholder="Your name" oninput="checkInput()" autocomplete="off" />
</div>
<button id="doneButton" onclick="submitName()" disabled>
<i class="fas fa-check"></i> Done
</button>
</div>
</div>
<div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div>
<iframe id="cool-iframe" class="iframe"></iframe>
<script type='text/javascript' src='//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js'></script>
<script type="text/javascript">
atOptions = {
'key' : '26bce7e7832b24b139944832990cf69d',
'format' : 'iframe',
'height' : 300,
'width' : 160,
'params' : {}
};
</script>
<script type="text/javascript" src="//spaniardinformationbookworm.com/26bce7e7832b24b139944832990cf69d/invoke.js"></script>
</body>
</div>
<iframe id="cool-iframe" class="iframe"></iframe>
<script defer>
document.addEventListener("DOMContentLoaded", function () {
NProgress.configure({ showSpinner: false });
NProgress.start();
const titleElement = document.querySelector(".search-title");
if (titleElement) {
const text = titleElement.textContent.trim();
titleElement.textContent = "";
text.split("").forEach((letter, i) => {
const span = document.createElement("span");
span.textContent = letter;
span.style.animationDelay = `${i * 0.05}s`;
titleElement.appendChild(span);
});
}
window.addEventListener("load", function () {
NProgress.done();
});
});
</script>
<script>
requestIdleCallback(() => {
const ad = document.createElement("script");
ad.src = "//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js";
ad.async = true;
document.body.appendChild(ad);
});
</script>
</body>
</html>

View File

@ -1,110 +1,155 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content="Waves. - Games"/>
<meta property="og:description" content="A sleek and minimalist web proxy."/>
<meta property="og:image" content="/assets/images/icons/favicon.ico"/>
<meta name="theme-color" content="#ffffff"/>
<meta name="msapplication-TileColor" content="#ffffff"/>
<title>Waves.</title>
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico">
<link rel="stylesheet" href="/assets/css/$.css">
<link rel="stylesheet" href="/assets/css/settings.css">
<link rel="stylesheet" href="/assets/css/toast.css">
<link rel="stylesheet" href="/assets/css/g.css">
<link href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-WGJ2192JZY');</script>
<script type='text/javascript' src='//pl26200262.effectiveratecpm.com/f0/e8/15/f0e81559842363ebf19aa99900ff2d02.js'></script>
</head>
<body>
<script src="/baremux/index.js"></script>
<script src="/wah/uv.bundle.js" defer></script>
<script src="/wah/cute1.js" defer></script>
<script src="/assets/js/navbar.js?v=2.8.4" defer></script>
<script src="/assets/js/load.js?v=2.8.4" defer></script>
<script src="/assets/js/eruda.js?v=2.8.4" defer></script>
<script src="/assets/js/register.js?v=2.8.5" defer></script>
<script src="/assets/js/settings.js?v=2.8.5" defer></script>
<script src="/assets/js/greetings.js?v=2.8.5" defer></script>
<script src="/assets/js/shortcuts.js?v=2.8.4" defer></script>
<script src="/assets/js/$.js?v=2.8.4" defer></script>
<script src="/assets/js/g.js?v=2.8.4" defer></script>
<div class="relative flex flex-col h-[100vh] items-center justify-center bg-black transition-bg">
<div class="absolute inset-0 overflow-hidden">
<div class="god-rays absolute -inset-[10px] opacity-50"></div>
</div>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content="Waves." />
<meta property="og:description" content="A sleek and minimalist web proxy." />
<meta property="og:image" content="/assets/images/icons/favicon.ico" />
<meta name="theme-color" content="#ffffff" />
<meta name="msapplication-TileColor" content="#ffffff" />
<title>Waves.</title>
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico" />
<link rel="stylesheet" href="/assets/css/$.css" />
<link rel="preload" href="/assets/css/settings.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel="preload" href="/assets/css/toast.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel="preload" href="/assets/css/nprogress.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel="preload" href="/assets/css/g.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<noscript>
<link rel="stylesheet" href="/assets/css/settings.css" />
<link rel="stylesheet" href="/assets/css/toast.css" />
<link rel="stylesheet" href="/assets/css/nprogress.css" />
<link rel="stylesheet" href="/assets/css/g.css" />
</noscript>
<link rel="preload" as="style" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" onload="this.onload=null;this.rel='stylesheet'" />
<noscript>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" />
</noscript>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "G-WGJ2192JZY");
</script>
</head>
<body>
<script src="/baremux/index.js" defer></script>
<script src="/assets/js/nprogress.js?v=0.2.0" defer></script>
<script src="/wah/uv.bundle.js" defer></script>
<script src="/wah/cute1.js" defer></script>
<script src="/assets/js/eruda.js?v=2.8.4" defer></script>
<script src="/assets/js/register.js?v=2.8.9" defer></script>
<script src="/assets/js/settings.js?v=2.8.9" defer></script>
<script src="/assets/js/greetings.js?v=2.8.9" defer></script>
<script src="/assets/js/shortcuts.js?v=2.8.9" defer></script>
<script src="/assets/js/$.js?v=2.8.9" defer></script>
<script src="/assets/js/g.js?v=2.8.9" defer></script>
<script src="/assets/js/wv.js?v=1.4.1" defer></script>
<div class="relative flex flex-col h-[100vh] items-center justify-center bg-black transition-bg">
<div class="absolute inset-0 overflow-hidden">
<div class="god-rays absolute -inset-[10px] opacity-50"></div>
</div>
<div class="home-navbar">
<img src="/assets/images/icons/favicon.ico" class="favicon">
<span id="waves">Waves.</span>
<a href="/" id="home">Home</a>
<a href="/g" id="games" style="color: #ffffff;">Games</a>
<a href="/a" id="apps">Apps</a>
<a href="#" id="movies">Movies</a>
<a href="#" id="ai">AI</a>
<a href="#" id="settings-icon">
<i class="settings-icon fa-regular fa-gear"></i>
</a>
</div>
<div class="home-navbar">
<img src="/assets/images/icons/favicon.ico" class="favicon" alt="favicon" />
<span id="waves">Waves.</span>
<a href="/" id="home">Home</a>
<a href="/g" id="games" style="color: #ffffff;">Games</a>
<a href="/s" id="apps">Shortcuts</a>
<a href="#" id="movies">Movies</a>
<a href="#" id="ai">AI</a>
<a href="#" id="settings-icon">
<i class="settings-icon fa-regular fa-gear"></i>
</a>
</div>
<div id="settings-menu" class="settings-menu"></div>
<div class="navbar">
<ul class="nav-buttons">
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li>
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li>
<li>
<div class="small-searchbar" style="position: relative;">
<i id="lockIcon" class="fa-solid fa-lock"></i>
<input class="waves" type="text" id="searchInputt" placeholder="Search for a query or enter a URL..." autocomplete="off" style="padding-left: 40px;" />
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/s"><i class="fa-regular fa-rocket"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
</div>
<div class="content games-page">
<h1>Games</h1>
<div class="games-search-bar">
<input type="text" id="gameSearchInput" placeholder="Search games..." autocomplete="off" />
<span class="shortcut-indicator-3">Ctrl + S</span>
</div>
<div id="settings-menu" class="settings-menu"></div>
<div class="navbar">
<ul class="nav-buttons">
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li>
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li>
<li>
<div class="small-searchbar" style="position: relative;">
<i id="lockIcon" class="fa-solid fa-lock"></i>
<input class="waves" type="text" id="searchInputt"
placeholder="Search for a query or enter a URL..." autocomplete="off"
style="padding-left: 40px;">
<span class="shortcut-indicator-2">Ctrl + S</span>
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/a"><i class="fa-regular fa-grid-2"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
<div class="games-grid"></div>
</div>
<div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div>
<div id="overlay" class="overlay"></div>
<div id="namePrompt" class="popup">
<div class="input-container">
<label for="userName">Please enter a name so we know what to call you:</label>
<div class="input-wrapper">
<input type="text" id="userName" placeholder="Your name" autocomplete="off" />
</div>
<button id="doneButton" onclick="submitName()" disabled><i class="fa-regular fa-check"></i> Done</button>
</div>
<div class="content games-page">
<h1>Games</h1>
<div class="games-search-bar">
<input type="text" id="gameSearchInput" placeholder="Search games..." autocomplete="off" />
<span class="shortcut-indicator-3">Ctrl + S</span>
</div>
<div class="games-grid">
</div>
</div>
<div id="overlay" class="overlay"></div>
<div id="namePrompt" class="popup">
<div class="input-container">
<label for="userName">Please enter a name so we know what to call you:</label>
<div class="input-wrapper">
<input type="text" id="userName" placeholder="Your name" oninput="checkInput()" autocomplete="off" />
</div>
<button id="doneButton" onclick="submitName()" disabled>
<i class="fas fa-check"></i> Done
</button>
</div>
</div>
<div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div>
<iframe id="cool-iframe" class="iframe"></iframe>
<script type='text/javascript' src='//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js'></script>
<script type="text/javascript">
atOptions = {
'key' : '26bce7e7832b24b139944832990cf69d',
'format' : 'iframe',
'height' : 300,
'width' : 160,
'params' : {}
};
</script>
<script type="text/javascript" src="//spaniardinformationbookworm.com/26bce7e7832b24b139944832990cf69d/invoke.js"></script>
</body>
</div>
<iframe id="cool-iframe" class="iframe"></iframe>
<script defer>
document.addEventListener("DOMContentLoaded", function () {
NProgress.configure({ showSpinner: false });
NProgress.start();
const titleElement = document.querySelector(".search-title");
if (titleElement) {
const text = titleElement.textContent.trim();
titleElement.textContent = "";
text.split("").forEach((letter, i) => {
const span = document.createElement("span");
span.textContent = letter;
span.style.animationDelay = `${i * 0.05}s`;
titleElement.appendChild(span);
});
}
window.addEventListener("load", function () {
NProgress.done();
});
});
</script>
<script>
requestIdleCallback(() => {
const ad = document.createElement("script");
ad.src = "//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js";
ad.async = true;
document.body.appendChild(ad);
});
</script>
</body>
</html>

View File

@ -1,114 +1,172 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="og:title" content="Waves."/>
<meta property="og:description" content="A sleek and minimalist web proxy."/>
<meta property="og:image" content="/assets/images/icons/favicon.ico"/>
<meta name="theme-color" content="#ffffff"/>
<meta name="msapplication-TileColor" content="#ffffff"/>
<title>Waves.</title>
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico">
<link rel="stylesheet" href="/assets/css/$.css">
<link rel="stylesheet" href="/assets/css/settings.css">
<link rel="stylesheet" href="/assets/css/toast.css">
<link href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-WGJ2192JZY');</script>
<script type='text/javascript' src='//pl26200262.effectiveratecpm.com/f0/e8/15/f0e81559842363ebf19aa99900ff2d02.js'></script>
<style>
body {
overflow: hidden;
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content="Waves." />
<meta property="og:description" content="A sleek and minimalist web proxy." />
<meta property="og:image" content="/assets/images/icons/favicon.ico" />
<meta name="theme-color" content="#ffffff" />
<meta name="msapplication-TileColor" content="#ffffff" />
<title>Waves.</title>
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico" />
<link rel="stylesheet" href="/assets/css/$.css" />
<link rel="preload" href="/assets/css/settings.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel="preload" href="/assets/css/toast.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel="preload" href="/assets/css/nprogress.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<noscript>
<link rel="stylesheet" href="/assets/css/settings.css" />
<link rel="stylesheet" href="/assets/css/toast.css" />
<link rel="stylesheet" href="/assets/css/nprogress.css" />
</noscript>
<link rel="preload" as="style" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" onload="this.onload=null;this.rel='stylesheet'" />
<noscript>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" />
</noscript>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
</style>
</head>
<body>
<script src="/baremux/index.js"></script>
<script src="/wah/uv.bundle.js" defer></script>
<script src="/wah/cute1.js" defer></script>
<script src="/assets/js/navbar.js?v=2.8.4" defer></script>
<script src="/assets/js/load.js?v=2.8.4" defer></script>
<script src="/assets/js/eruda.js?v=2.8.4" defer></script>
<script src="/assets/js/register.js?v=2.8.5" defer></script>
<script src="/assets/js/settings.js?v=2.8.5" defer></script>
<script src="/assets/js/ping.js?v=2.8.4" defer></script>
<script src="/assets/js/greetings.js?v=2.8.5" defer></script>
<script src="/assets/js/shortcuts.js?v=2.8.4" defer></script>
<script src="/assets/js/$.js?v=2.8.4" defer></script>
<div class="relative flex flex-col h-[100vh] items-center justify-center bg-white transition-bg">
<div class="absolute inset-0 overflow-hidden">
<div class="god-rays absolute -inset-[10px] opacity-50"></div>
</div>
gtag("js", new Date());
gtag("config", "G-WGJ2192JZY");
</script>
</head>
<body>
<script src="/baremux/index.js"></script>
<script src="/assets/js/nprogress.js?v=0.2.0" defer></script>
<script src="/wah/uv.bundle.js" defer></script>
<script src="/wah/cute1.js" defer></script>
<script src="/assets/js/eruda.js?v=2.8.4" defer></script>
<script src="/assets/js/register.js?v=2.8.9" defer></script>
<script src="/assets/js/settings.js?v=2.8.9" defer></script>
<script src="/assets/js/ping.js?v=2.8.9" defer></script>
<script src="/assets/js/greetings.js?v=2.8.9" defer></script>
<script src="/assets/js/shortcuts.js?v=2.8.9" defer></script>
<script src="/assets/js/$.js?v=2.8.9" defer></script>
<script src="/assets/js/wv.js?v=1.4.1" defer></script>
<div class="relative flex flex-col h-[100vh] items-center justify-center bg-black transition-bg">
<div class="absolute inset-0 overflow-hidden">
<div class="god-rays absolute -inset-[10px] opacity-50"></div>
</div>
<div class="home-navbar">
<img src="/assets/images/icons/favicon.ico" class="favicon">
<span id="waves">Waves.</span>
<a href="/" id="home" style="color: #ffffff;">Home</a>
<a href="/g" id="games">Games</a>
<a href="/a" id="apps">Apps</a>
<a href="#" id="movies">Movies</a>
<a href="#" id="ai">AI</a>
<a href="#" id="settings-icon">
<i id="settings-icon" class="settings-icon fa-regular fa-gear"></i>
</a>
</div>
<div class="home-navbar">
<img src="/assets/images/icons/favicon.ico" class="favicon" />
<span id="waves">Waves.</span>
<a href="/" id="home" style="color: #ffffff;">Home</a>
<a href="/g" id="games">Games</a>
<a href="/s" id="apps">Shortcuts</a>
<a href="#" id="movies">Movies</a>
<a href="#" id="ai">AI</a>
<a href="#" id="settings-icon"><i class="settings-icon fa-regular fa-gear"></i></a>
</div>
<div id="settings-menu" class="settings-menu"></div>
<div class="navbar">
<ul class="nav-buttons">
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li>
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li>
<li>
<div class="small-searchbar" style="position: relative;">
<i id="lockIcon" class="fa-solid fa-lock"></i>
<input class="waves" type="text" id="searchInputt" placeholder="Search for a query or enter a URL..." autocomplete="off" style="padding-left: 40px;" />
<span class="shortcut-indicator-2">Ctrl + S</span>
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/s"><i class="fa-regular fa-rocket"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
</div>
<div class="search-container">
<div class="search-title">Waves.</div>
<div class="search-bar">
<input class="waves" type="text" id="searchInput" placeholder="What's been on your mind lately?" autocomplete="off" />
<span class="shortcut-indicator">Ctrl + S</span>
</div>
<div id="settings-menu" class="settings-menu"></div>
<div class="navbar">
<ul class="nav-buttons">
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li>
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li>
<li>
<div class="small-searchbar" style="position: relative;">
<i id="lockIcon" class="fa-solid fa-lock"></i>
<input class="waves" type="text" id="searchInputt"
placeholder="Search for a query or enter a URL..." autocomplete="off"
style="padding-left: 40px;">
<span class="shortcut-indicator-2">Ctrl + S</span>
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/a"><i class="fa-regular fa-grid-2"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
</div>
<div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div>
<div id="overlay" class="overlay"></div>
<div id="namePrompt" class="popup">
<div class="input-container">
<label for="userName">Please enter a name so we know what to call you:</label>
<div class="input-wrapper">
<input type="text" id="userName" placeholder="Your name" autocomplete="off" />
</div>
<button id="doneButton" onclick="submitName()" disabled><i class="fa-regular fa-check"></i> Done</button>
</div>
<div class="search-container">
<div class="search-title">Waves.</div>
<div class="search-bar">
<input class="waves" type="text" id="searchInput" placeholder="What's been on your mind lately?" autocomplete="off">
<span class="shortcut-indicator">Ctrl + S</span>
</div>
</div>
<div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div>
<div id="overlay" class="overlay"></div>
<div id="namePrompt" class="popup">
<div class="input-container">
<label for="userName">Please enter a name so we know what to call you:</label>
<div class="input-wrapper">
<input type="text" id="userName" placeholder="Your name" autocomplete="off">
</div>
<button id="doneButton" onclick="submitName()" disabled>
<i class="fa-regular fa-check"></i> Done
</button>
</div>
</div>
<div id="pingDisplay">Ping: Connecting...</div>
<div id="greeting"></div>
<iframe id="cool-iframe" class="iframe"></iframe>
<script type='text/javascript' src='//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js'></script>
<script type="text/javascript">
atOptions = {
'key' : '26bce7e7832b24b139944832990cf69d',
'format' : 'iframe',
'height' : 300,
'width' : 160,
'params' : {}
};
</script>
<script type="text/javascript" src="//spaniardinformationbookworm.com/26bce7e7832b24b139944832990cf69d/invoke.js"></script>
</body>
</div>
<div id="pingDisplay"><i class="fas fa-satellite-dish"></i> Ping: Connecting...</div>
<div id="greeting"></div>
<iframe id="cool-iframe" class="iframe"></iframe>
<div id="hi">Hii,</div>
<div id="copyright">
<i class="fa-regular fa-copyright"></i> 2025
<a class="hover-link" href="https://discord.gg/ire" target="_blank" rel="noopener noreferrer"><span class="copyrightname">Waves Services</span></a>.
All Rights Reserved.
</div>
<div id="discord">
<a class="hover-link" href="https://discord.gg/ire" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-discord"></i> Discord
</a>
</div>
<div id="github">
<a class="hover-link" href="https://github.com/xojw/waves" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-github"></i> Github
</a>
</div>
<script defer>
document.addEventListener("DOMContentLoaded", function () {
NProgress.configure({ showSpinner: false });
NProgress.start();
const titleElement = document.querySelector(".search-title");
if (titleElement) {
const text = titleElement.textContent.trim();
titleElement.textContent = "";
text.split("").forEach((letter, i) => {
const span = document.createElement("span");
span.textContent = letter;
span.style.animationDelay = `${i * 0.05}s`;
titleElement.appendChild(span);
});
}
window.addEventListener("load", function () {
NProgress.done();
});
});
</script>
<script>
requestIdleCallback(() => {
const ad = document.createElement("script");
ad.src = "//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js";
ad.async = true;
document.body.appendChild(ad);
});
</script>
</body>
</html>

View File

@ -1 +0,0 @@
google.com, pub-7835554576835583, DIRECT, f08c47fec0942fa0

View File

@ -7,6 +7,7 @@ body {
color: #e0e0e0;
overflow-x: hidden;
transition: background-color 0.3s ease;
animation: fadeIn 0.3s ease;
scroll-behavior: smooth;
position: relative;
z-index: 1;
@ -54,7 +55,7 @@ body {
color: #ffffff;
display: inline-block;
text-align: left;
margin: 1px 80px 0 10px;
margin: 1px 75px 0 10px;
white-space: nowrap;
cursor: default;
transition: all 0.3s ease;
@ -62,7 +63,7 @@ body {
.home-navbar {
transform: translateX(-50%);
width: 670px;
width: 700px;
top: 1%;
margin-bottom: -10px;
margin-left: 50%;
@ -71,7 +72,6 @@ body {
height: 35px;
color: #818181;
padding: 10px;
animation: fadeIn 2s ease;
text-align: center;
font-size: 18px;
font-weight: bold;
@ -86,14 +86,14 @@ body {
}
.home-navbar .favicon {
width: 24px;
width: 28px;
height: 24px;
margin-right: -10px;
margin-right: -9px;
vertical-align: middle;
}
.home-navbar a {
color: #afafaf;
color: #7c7c7c;
text-decoration: none;
padding: 8px 16px;
font-size: 14px;
@ -104,7 +104,8 @@ body {
}
.home-navbar a:hover {
font-size: 16px;
color: #bbbbbb;
font-size: 18px;
}
.home-navbar a:active {
@ -113,8 +114,8 @@ body {
.home-navbar i {
color: #ffffff;
margin-right: -15px;
margin-left: 115px;
margin-right: -19px;
margin-left: 119px;
}
.navbar {
@ -222,6 +223,26 @@ body {
color: #818181;
}
.shortcut-indicator {
position: absolute;
top: 50%;
left: 50%;
transform: translate(calc(-50% + 235px), -50%);
font-size: 12px;
font-weight: 500;
color: #000000;
background-color: #c4c4c4;
padding: 2px 6px;
border-radius: 7px;
cursor: pointer;
transition: all 0.3s ease;
animation: fadeIn 0.3s ease;
}
.shortcut-indicator:hover {
background-color: #ffffff;
}
.shortcut-indicator-2 {
position: absolute;
top: 50%;
@ -235,12 +256,20 @@ body {
border-radius: 7px;
cursor: pointer;
transition: all 0.3s ease;
animation: fadeUp 0.3s ease;
}
.shortcut-indicator-2:hover {
background-color: #ffffff;
}
.arrow-mode {
display: inline-block;
margin-left: 17px;
transition: all 0.3s ease;
animation: fadeIn 0.3s ease;
}
#lockIcon {
position: absolute;
left: 25px;
@ -255,7 +284,6 @@ body {
margin-top: 20%;
left: 50%;
transform: translate(-50%, -50%);
animation: fadeIn 2s ease;
text-align: center;
width: 90%;
}
@ -265,25 +293,22 @@ body {
font-weight: bolder;
text-align: center;
display: inline-block;
background: linear-gradient(-45deg, #4e4e4e, #ffffff);
background: linear-gradient(-45deg, #8d8d8d, #ffffff);
-webkit-background-clip: text;
background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
color: transparent;
cursor: default;
transition: all 0.3s ease;
}
}
.search-title span {
.search-title span {
display: inline-block;
background: inherit;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
opacity: 0;
transform: translateX(-50px);
animation: fadeInFromLeft 0.5s ease-in-out forwards;
background: inherit;
color: transparent;
transform: translateY(4rem);
animation: fadeSlideIn 0.6s forwards;
}
.search-bar {
@ -323,25 +348,6 @@ body {
color: #ffffff69;
}
.shortcut-indicator {
position: absolute;
top: 50%;
left: 50%;
transform: translate(calc(-50% + 235px), -50%);
font-size: 12px;
font-weight: 500;
color: #000000;
background-color: #c4c4c4;
padding: 2px 6px;
border-radius: 7px;
cursor: pointer;
transition: all 0.3s ease;
}
.shortcut-indicator:hover {
background-color: #ffffff;
}
#erudaLoadingScreen {
position: fixed;
top: 50%;
@ -387,13 +393,13 @@ body {
}
.hover-link {
color: #949494;
color: #b3b3b3;
text-decoration: none;
transition: color 0.3s ease;
}
.hover-link:hover {
color: #dadada;
color: #ffffff;
}
#pingDisplay {
@ -401,10 +407,9 @@ body {
margin-top: -46px;
left: 50%;
transform: translate(-50%, -50%);
font-weight: bold;
font-weight: 550;
color: #888888;
cursor: default;
animation: fadeIn 2s ease;
padding: 5px 10px;
transition: all 0.3s ease;
z-index: -1;
@ -412,7 +417,7 @@ body {
}
#pingDisplay:hover {
color: #b6b6b6;
color: #d3d3d3;
}
.god-rays {
@ -426,7 +431,6 @@ body {
background-image: var(--stripes), var(--rays);
background-size: 300%, 200%;
background-position: 50% 50%, 50% 50%;
animation: fadeIn 2s ease;
mask-image: radial-gradient(ellipse at 100% 0%, transparent 40%, transparent 70%);
-webkit-mask-image: radial-gradient(ellipse at 100% 0%, white 40%, transparent 70%);
pointer-events: none;
@ -456,7 +460,7 @@ body {
display: none;
opacity: 0;
transition: opacity 0.3s ease-in-out;
animation: fadeInOverlay 0.3s ease-in-out forwards;
animation: fadeIn 0.3s ease-in-out forwards;
}
#namePrompt {
@ -572,7 +576,6 @@ body {
position: fixed;
left: 50%;
transform: translate(-50%, -50%);
animation: fadeIn 2s ease;
opacity: 0;
transition: all 0.3s ease;
cursor: default;
@ -580,42 +583,98 @@ body {
}
#greeting:hover {
color: #b6b6b6;
color: #d3d3d3;
}
#namePrompt.fade-out {
animation: fadeOutPrompt 0.3s ease-in-out forwards;
animation: fadeOut 0.3s ease-in-out forwards;
}
@keyframes fadeInFromLeft {
0% {
opacity: 0;
transform: translateX(-50px);
}
100% {
opacity: 1;
transform: translateX(0);
}
#hi {
position: fixed;
bottom: 10px;
left: 10px;
z-index: 9999;
background-color: #08080894;
border: 1px solid #ffffff21;
color: #aaaaaa;
font-weight: 540;
transition: all 0.3s ease;
cursor: default;
padding: 8px 12px;
border-radius: 15px;
font-size: 14px;
}
@keyframes fadeIn {
from {
opacity: 0;
}
#hi:hover {
color: #ffffff;
}
#copyright {
position: fixed;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
z-index: 9999;
background-color: #08080894;
border: 1px solid #ffffff21;
color: #858585;
font-weight: 540;
transition: all 0.3s ease;
cursor: default;
padding: 8px 12px;
border-radius: 15px;
font-size: 14px;
}
#copyright:hover {
color: #afafaf;
}
#discord {
position: fixed;
bottom: 10px;
right: 100px;
z-index: 9999;
background-color: #08080894;
border: 1px solid #ffffff21;
color: #858585;
font-weight: 540;
transition: all 0.3s ease;
cursor: default;
padding: 8px 12px;
border-radius: 15px;
font-size: 14px;
}
#github {
position: fixed;
bottom: 10px;
right: 10px;
z-index: 9999;
background-color: #08080894;
border: 1px solid #ffffff21;
color: #858585;
font-weight: 540;
transition: all 0.3s ease;
cursor: default;
padding: 8px 12px;
border-radius: 15px;
font-size: 14px;
}
.fadeIn {
animation: fadeIn 0.3s ease-in-out forwards;
}
.fadeOut {
animation: fadeOut 0.3s ease-in-out forwards;
}
@keyframes fadeSlideIn {
to {
opacity: 1;
}
}
@keyframes fadeInOverlay {
0% {
opacity: 0;
}
100% {
opacity: 1;
transform: translateY(0);
}
}
@ -631,7 +690,17 @@ body {
}
}
@keyframes fadeOutPrompt {
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeOut {
0% {
opacity: 1;
}
@ -651,47 +720,6 @@ body {
}
}
@keyframes swing {
0%,
100% {
transform: rotate(3deg);
}
50% {
transform: rotate(-3deg);
}
}
@keyframes steamLarge {
0% {
stroke-dashoffset: 13;
opacity: 0.6;
}
100% {
stroke-dashoffset: 39;
opacity: 0;
}
}
@keyframes steamSmall {
10% {
stroke-dashoffset: 9;
opacity: 0.6;
}
80% {
stroke-dashoffset: 27;
opacity: 0;
}
100% {
stroke-dashoffset: 27;
opacity: 0;
}
}
@keyframes spin {
0% {
transform: rotate(0deg);

View File

@ -5,7 +5,6 @@
}
.games-page h1 {
animation: fadeIn 2s ease;
font-size: 2.5rem;
margin-bottom: 20px;
color: #fff;
@ -82,7 +81,6 @@
margin-top: 20px;
margin-bottom: 20px;
color: #a8a8a8;
animation: fadeIn 2s ease;
position: relative;
}

View File

@ -0,0 +1 @@
#nprogress{pointer-events:none}#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translate(0,-4px);-ms-transform:rotate(3deg) translate(0,-4px);transform:rotate(3deg) translate(0,-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:nprogress-spinner 400ms linear infinite;animation:nprogress-spinner 400ms linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}

View File

@ -1,17 +1,16 @@
.apps-page {
.shortcuts-page {
padding: 100px 20px 40px;
text-align: center;
position: relative;
}
.apps-page h1 {
animation: fadeIn 2s ease;
.shortcuts-page h1 {
font-size: 2.5rem;
margin-bottom: 20px;
color: #fff;
}
.apps-grid {
.shortcuts-grid {
display: flex;
flex-wrap: wrap;
justify-content: center;
@ -22,14 +21,14 @@
margin: 0 auto;
}
.content.apps-page {
.content.shortcuts-page {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.app-card {
.shortcut-card {
background-color: #08080894;
border-radius: 25px;
padding: 15px 20px;
@ -49,7 +48,7 @@
animation: fadeIn 2s ease;
}
.app-card img {
.shortcut-card img {
width: 100%;
height: 200px;
object-fit: cover;
@ -58,40 +57,39 @@
transition: all 0.3s ease;
}
.app-card:hover img {
.shortcut-card:hover img {
filter: brightness(1);
}
.app-card:hover {
.shortcut-card:hover {
background-color: #333333;
}
.app-card h2 {
.shortcut-card h2 {
font-size: 1rem;
margin: 10px 0;
color: #fff;
}
.app-card p {
.shortcut-card p {
font-size: 1rem;
color: #ccc;
}
.apps-search-bar {
.shortcuts-search-bar {
text-align: center;
margin-top: 20px;
margin-bottom: 20px;
color: #a8a8a8;
animation: fadeIn 2s ease;
position: relative;
}
#appSearchInput {
#shortcutSearchInput {
padding: 14px 30px;
border: 1px solid #ffffff1a;
background-image: url('/assets/images/icons/search.png');
background-size: 35px 35px;
background-position: 10px center;
background-position: 5px center;
background-repeat: no-repeat;
padding-left: 45px;
border-radius: 20px;
@ -104,12 +102,12 @@
transition: all 0.3s ease;
}
#appSearchInput:focus,
#appSearchInput:hover {
#shortcutSearchInput:focus,
#shortcutSearchInput:hover {
border: 1px solid #ffffff69;
}
#appSearchInput::placeholder {
#shortcutSearchInput::placeholder {
color: #a8a8a8;
}

View File

@ -63,7 +63,7 @@
#close-settings:hover {
transform: rotate(90deg);
color: #d3d3d3;
color: #ffffff;
}
#close-settings i {
@ -91,11 +91,12 @@
max-width: 300px;
margin-bottom: 15px;
}
.transport-selected {
background-color: #141414;
border: 1px solid #ffffff1a;
color: #e0e0e0;
padding: 10px;
border: 1px solid #4141411a;
border-radius: 15px;
cursor: pointer;
display: flex;
@ -136,8 +137,7 @@
opacity: 0;
}
.transport-options.transport-show,
.server-options.transport-show {
.transport-options.transport-show {
max-height: 200px;
opacity: 1;
}
@ -159,7 +159,7 @@
margin-left: -80px;
background-color: #141414;
color: #e0e0e0;
border: 1px solid #4141411a;
border: 1px solid #ffffff1a;
border-radius: 15px;
font-size: 15px;
outline: none;

View File

@ -32,6 +32,10 @@
display: inline-block;
}
.toast i {
margin-right: 8px;
}
.toast.show {
animation: slideIn 0.3s forwards;
}
@ -51,6 +55,21 @@
animation: progress 3s linear forwards;
}
.toast .toast-close {
background: none;
border: none;
color: #888888;
font-size: 18px;
cursor: pointer;
padding: 0;
margin-left: 10px;
transition: 0.3s;
}
.toast-close:hover {
color: #ffffff;
}
@keyframes slideIn {
0% {
right: -300px;
@ -79,19 +98,4 @@
100% {
width: 0%;
}
}
.toast .toast-close {
background: none;
border: none;
color: #888888;
font-size: 18px;
cursor: pointer;
padding: 0;
margin-left: 10px;
transition: 0.3s;
}
.toast-close:hover {
color: #d3d3d3;
}

View File

@ -1,5 +1,5 @@
{
"apps": [
"shortcuts": [
{
"icon": "/assets/images/a/crazygames.jpg",
"title": "Crazy Games",
@ -51,4 +51,4 @@
"link": "https://store.steampowered.com"
}
]
}
}

View File

@ -13,7 +13,6 @@
<script>
var gameLoaded = false;
window.addEventListener("beforeunload", function (e) {
if (adsVisible || !gameLoaded || !lockedOccured) return null;
var confirmationMessage = "Are you sure you want to leave? ";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
@ -86,52 +85,10 @@
},
});
</script>
<!-- MIDROLL/INTERSTITIAL VIDEO API -->
<script src="js/cpmstar.js"></script>
</head>
<body>
<div class="ads">
<div class="ad-smallscreen">
<div class="ad ad-rectangle-bottom"></div>
</div>
<div class="ad ad-rectangle-upper" id="adRectangleUpper">
<!-- 300X250B PLACEMENT TAG - PLACE INTO BODY (ZONE TAG REQUIRED) -->
<script>
(function (w, pid) {
var r = function (c, m) {
c = c.split("").reduce(function (a, b) {
return ((a << 5) - a + b.charCodeAt(0)) >>> m;
}, 0);
return (10 + ((c * 7) % 26)).toString(36) + c.toString(36);
},
y = r(w.location.href.split("#")[0], 1),
c = r(w.location.href.split("#")[0] + pid, 0);
w.document.write('<div style="width:300px;height:250px" class="' + c + '"></div>');
})(window, 83023);
</script>
</div>
<div class="ad-largescreen">
<div class="ad ad-leaderboard-bottom">
<!-- 300X600B PLACEMENT TAG - PLACE INTO BODY (ZONE TAG REQUIRED) -->
<script>
(function (w, pid) {
var r = function (c, m) {
c = c.split("").reduce(function (a, b) {
return ((a << 5) - a + b.charCodeAt(0)) >>> m;
}, 0);
return (10 + ((c * 7) % 26)).toString(36) + c.toString(36);
},
y = r(w.location.href.split("#")[0], 1),
c = r(w.location.href.split("#")[0] + pid, 0);
w.document.write('<div style="width:300px;height:600px" class="' + c + '"></div>');
})(window, 85420);
</script>
</div>
</div>
</div>
<!-- <div id="interAdsContainer" style="display: none;"></div> -->
<div id="gameContainer"></div>
<div id="loader">
<img class="logo" src="logo.png" />
@ -222,55 +179,6 @@
var refreshNextTime = true;
function showAds() {
document.getElementsByClassName("ad-rectangle-bottom")[0].style.display = "block";
document.getElementsByClassName("ad-leaderboard-bottom")[0].style.display = "block";
document.getElementById("adRectangleUpper").style.display = "block";
if (typeof counter === "undefined") {
startCounter();
resumeCounter();
} else {
resumeCounter();
refresh();
}
}
function hideAds() {
document.getElementsByClassName("ad-rectangle-bottom")[0].style.display = "none";
document.getElementsByClassName("ad-leaderboard-bottom")[0].style.display = "none";
document.getElementById("adRectangleUpper").style.display = "none";
pauseCounter();
}
// hide ads
hideAds();
function refresh() {
//console.log("time since ads refresh = " + timeSinceRefresh + " seconds");
//console.log("time ads visible = " + timeAdsVisible + " seconds");
if (timeSinceRefresh <= 30 || timeAdsVisible <= 2) {
//console.log("don't refresh");
return;
}
if (document.getElementById("adRectangleBottom") != null && window.getComputedStyle(document.getElementsByClassName("ad-smallscreen")[0]).display != "none") {
cpmstarAPI({ kind: "adcmd", module: "POOL 83023", command: "refresh" });
}
if (document.getElementById("adLeaderboardBottom") != null && window.getComputedStyle(document.getElementsByClassName("ad-largescreen")[0]).display != "none") {
cpmstarAPI({ kind: "adcmd", module: "POOL 85420", command: "refresh" });
}
cpmstarAPI({ kind: "adcmd", module: "POOL 83025", command: "refresh" });
timeSinceRefresh = 0;
timeAdsVisible = 0;
//console.log("refresh ads");
}
window.onfocus = function () {
//console.log("onfocus");
resumeCounter();
@ -283,26 +191,16 @@
};
var timeSinceRefresh = 0;
var timeAdsVisible = 0;
var counter;
var adsVisible = false;
function startCounter() {
timeSinceRefresh++;
if (adsVisible) timeAdsVisible++;
counter = setTimeout(function () {
startCounter();
}, 1000);
}
function resumeCounter() {
adsVisible = true;
}
function pauseCounter() {
adsVisible = false;
}
</script>
<!-- Firebase App (the core Firebase SDK) is always required and must be listed first -->
<script src="firebase/firebase-app.js"></script>
@ -341,4 +239,4 @@
fixMacUserAgent();
</script>
</body>
</html>
</html>

View File

@ -1,293 +1,478 @@
document.addEventListener('DOMContentLoaded', () => {
const historyStack = []
let currentIndex = -1
const refreshIcon = document.getElementById('refreshIcon')
const fullscreenIcon = document.getElementById('fullscreenIcon')
const backIcon = document.getElementById('backIcon')
const forwardIcon = document.getElementById('forwardIcon')
const iframe = document.getElementById('cool-iframe')
const erudaLoadingScreen = document.getElementById('erudaLoadingScreen')
if (!refreshIcon || !fullscreenIcon || !backIcon || !forwardIcon || !iframe) return
const originalTitle = document.title
let loadingHidden = false
function showLoadingScreen(withToast = true, showEruda = false) {
loadingHidden = false
NProgress.start()
document.title = 'Loading... <3'
if (withToast) {
showToast(
'Consider joining our <a href="https://discord.gg/dJvdkPRheV" target="_blank" class="hover-link">Discord</a>&nbsp;<3',
'success',
'heart'
)
}
}
function hideLoadingScreen() {
if (loadingHidden) return
loadingHidden = true
NProgress.done()
document.title = originalTitle
}
refreshIcon.addEventListener('click', () => {
refreshIcon.classList.add('spin')
if (iframe.tagName === 'IFRAME') {
const currentUrl = iframe.contentWindow.location.href
if (normalizeUrl(currentUrl) !== normalizeUrl(historyStack[currentIndex] || '')) {
addToHistory(currentUrl)
}
iframe.contentWindow.location.reload(true)
}
setTimeout(() => refreshIcon.classList.remove('spin'), 300)
})
fullscreenIcon.addEventListener('click', () => {
if (iframe.requestFullscreen) iframe.requestFullscreen()
else if (iframe.mozRequestFullScreen) iframe.mozRequestFullScreen()
else if (iframe.webkitRequestFullscreen) iframe.webkitRequestFullscreen()
else if (iframe.msRequestFullscreen) iframe.msRequestFullscreen()
})
backIcon.addEventListener('click', () => {
if (currentIndex > 0) {
currentIndex--
iframe.src = historyStack[currentIndex]
showLoadingScreen(false, false)
updateNavButtons()
updateDecodedSearchInput()
}
})
forwardIcon.addEventListener('click', () => {
if (currentIndex < historyStack.length - 1) {
currentIndex++
iframe.src = historyStack[currentIndex]
showLoadingScreen(false, false)
updateNavButtons()
updateDecodedSearchInput()
}
})
function normalizeUrl(urlStr) {
try {
const url = new URL(urlStr)
url.searchParams.delete('ia')
return url.toString()
} catch {
return urlStr
}
}
function addToHistory(url) {
const normalized = normalizeUrl(url)
if (currentIndex >= 0 && normalizeUrl(historyStack[currentIndex]) === normalized) return
if (currentIndex < historyStack.length - 1) historyStack.splice(currentIndex + 1)
historyStack.push(url)
currentIndex++
updateNavButtons()
updateDecodedSearchInput()
}
function updateNavButtons() {
backIcon.disabled = currentIndex <= 0
forwardIcon.disabled = currentIndex >= historyStack.length - 1
backIcon.classList.toggle('disabled', currentIndex <= 0)
forwardIcon.classList.toggle('disabled', currentIndex >= historyStack.length - 1)
}
function updateDecodedSearchInput() {
const searchInput2 = document.getElementById('searchInputt')
if (!searchInput2) return
let url = ''
if (currentIndex >= 0 && historyStack[currentIndex]) {
url = historyStack[currentIndex]
} else if (iframe.src) {
url = iframe.src
}
searchInput2.value = decodeUrl(url)
const lockIcon = document.getElementById('lockIcon')
if (lockIcon) {
lockIcon.className = decodeUrl(url).startsWith('https://') ?
'fa-regular fa-lock' :
'fa-regular fa-lock-open'
lockIcon.style.color = ''
}
}
iframe.addEventListener('load', () => {
try {
hideLoadingScreen()
} catch {
hideLoadingScreen()
} finally {
if (erudaLoadingScreen) erudaLoadingScreen.style.display = 'none'
}
})
iframe.addEventListener('error', () => {
hideLoadingScreen()
})
iframe.addEventListener('loadstart', () => {
const navBar = document.querySelector('.navbar')
const navbarToggle = document.getElementById('navbar-toggle')
if (navbarToggle && navbarToggle.checked && navBar) navBar.style.display = 'block'
showLoadingScreen(false, false)
})
const navBar = document.querySelector('.navbar')
const topBar = document.querySelector('.topbar')
const searchInput1 = document.getElementById('searchInput')
const searchInput2 = document.getElementById('searchInputt')
const movies = document.getElementById('movies')
const ai = document.getElementById('ai')
const navbarToggle = document.getElementById('navbar-toggle')
if (navbarToggle && navBar) {
const savedNavbarState = localStorage.getItem('navbarToggled')
navbarToggle.checked = savedNavbarState === null ? true : savedNavbarState === 'true'
navBar.style.display = iframe.style.display === 'block' && navbarToggle.checked ? 'block' : 'none'
navbarToggle.addEventListener('change', () => {
localStorage.setItem('navbarToggled', navbarToggle.checked)
navBar.style.display = iframe.style.display === 'block' && navbarToggle.checked ? 'block' : 'none'
})
}
iframe.style.display = 'none'
window.addEventListener('load', hideLoadingScreen)
;[searchInput1, searchInput2].forEach(input => {
if (input) {
input.addEventListener('keyup', e => {
if (e.key === 'Enter') {
const val = input.value.trim()
if (val) handleSearch(val)
else showToast('Please enter something in the Search Bar.', 'error', 'warning')
}
})
}
})
if (movies) movies.addEventListener('click', e => {
e.preventDefault()
handleSearch('https://movies.usewaves.site/')
})
if (ai) ai.addEventListener('click', e => {
e.preventDefault()
handleSearch('https://ai.usewaves.site/')
})
function clearBackground() {
const preserved = [
document.querySelector('.navbar'),
document.getElementById('cool-iframe'),
document.querySelector('.loading-screen'),
erudaLoadingScreen
]
Array.from(document.body.children).forEach(child => {
if (!preserved.includes(child)) child.remove()
})
}
async function handleSearch(query) {
if (!query || !query.trim()) {
showToast('Please enter something in the Search Bar.', 'error', 'warning')
return
}
clearBackground()
let searchURL
if (
query.startsWith('/assets/g/') ||
query.startsWith(window.location.origin + '/assets/g/')
) {
searchURL = query
} else {
searchURL = generateSearchUrl(query)
}
if (searchInput2) searchInput2.value = searchURL
historyStack.length = 0
currentIndex = -1
showLoadingScreen(true, false)
iframe.style.display = 'block'
if (topBar) topBar.style.display = 'none'
backIcon.disabled = forwardIcon.disabled = true
let finalUrl
try {
const u = new URL(searchURL, window.location.origin)
if (u.origin === window.location.origin && u.pathname.startsWith('/assets/g/')) {
finalUrl = u.href
} else {
finalUrl = await getUrl(searchURL)
}
} catch {
finalUrl = await getUrl(searchURL)
}
iframe.src = finalUrl
iframe.onload = () => {
hideLoadingScreen()
if (navbarToggle && navbarToggle.checked && navBar) navBar.style.display = 'block'
generateSubject()
updateDecodedSearchInput()
}
iframe.onerror = () => {
hideLoadingScreen()
}
}
window.handleSearch = handleSearch
function generateSearchUrl(query) {
try {
return new URL(query).toString()
} catch {
try {
const u = new URL(`https://${query}`)
if (u.hostname.includes('.')) return u.toString()
} catch {}
}
return `https://duckduckgo.com/?q=${encodeURIComponent(query)}&ia=web`
}
function showToast(message, type = 'success', iconType = 'check') {
const toast = document.createElement('div')
toast.className = `toast show ${type}`
const icons = {
success: '<i class="fa-regular fa-check-circle" style="margin-right: 8px;"></i>',
error: '<i class="fa-regular fa-times-circle" style="margin-right: 8px;"></i>',
info: '<i class="fa-regular fa-info-circle" style="margin-right: 8px;"></i>',
warning: '<i class="fa-regular fa-exclamation-triangle" style="margin-right: 8px;"></i>',
heart: '<i class="fa-regular fa-heart" style="margin-right: 8px;"></i>'
}
const icon = icons[iconType] || icons.heart
toast.innerHTML = `${icon}${message} `
const progressBar = document.createElement('div')
progressBar.className = 'progress-bar'
toast.appendChild(progressBar)
const closeBtn = document.createElement('button')
closeBtn.className = 'toast-close'
closeBtn.innerHTML = '<i class="fa-solid fa-xmark" style="margin-left: 8px; font-size: 0.8em;"></i>'
closeBtn.addEventListener('click', () => {
toast.classList.add('hide')
setTimeout(() => toast.remove(), 500)
})
toast.appendChild(closeBtn)
document.body.appendChild(toast)
setTimeout(() => {
toast.classList.add('hide')
setTimeout(() => toast.remove(), 500)
}, 3000)
}
function preloadResources(url) {
if (!url) return
try {
const link = document.createElement('link')
link.rel = 'preload'
link.href = url
link.as = 'fetch'
link.crossOrigin = 'anonymous'
document.head.appendChild(link)
} catch {}
}
function getUrl(url) {
return Promise.resolve(__uv$config.prefix + __uv$config.encodeUrl(url))
}
function generateSubject() {
const subjects = ['math', 'science', 'history', 'art', 'programming', 'philosophy']
const random = subjects[Math.floor(Math.random() * subjects.length)]
history.replaceState({}, '', '/learning?subject=' + random)
}
function decodeUrl(enc) {
try {
const o = new URL(enc, window.location.origin)
const p = (__uv$config && __uv$config.prefix) || '/wa/a/'
if (o.pathname.startsWith(p)) {
const part = o.pathname.slice(p.length)
return (__uv$config.decodeUrl ? __uv$config.decodeUrl(part) : decodeURIComponent(part))
}
} catch {}
return enc
}
window.decodeUrl = decodeUrl
window.addToHistory = addToHistory
window.updateDecodedSearchInput = updateDecodedSearchInput
window.normalizeUrl = normalizeUrl
})
window.APP = {};
const iframe = document.getElementById('cool-iframe');
const erudaLoadingScreen = document.getElementById('erudaLoadingScreen');
const searchInput1 = document.getElementById('searchInput');
const movies = document.getElementById('movies');
const ai = document.getElementById('ai');
const topBar = document.querySelector('.topbar');
const refreshIcon = document.getElementById('refreshIcon');
const fullscreenIcon = document.getElementById('fullscreenIcon');
const backIcon = document.getElementById('backIcon');
const forwardIcon = document.getElementById('forwardIcon');
const searchInput2 = document.getElementById('searchInputt');
const lockIcon = document.getElementById('lockIcon');
const navbarToggle = document.getElementById('navbar-toggle');
const navBar = document.querySelector('.navbar');
const historyStack = [];
let currentIndex = -1;
const originalTitle = document.title;
let isLoading = false;
if (!iframe || !refreshIcon || !fullscreenIcon || !backIcon || !forwardIcon) {
return;
}
const animationStyle = document.createElement('style');
animationStyle.textContent = `
@keyframes slideLeft {0% { transform: translateX(0); } 50% { transform: translateX(-5px); } 100% { transform: translateX(0); }}
@keyframes slideRight {0% { transform: translateX(0); } 50% { transform: translateX(5px); } 100% { transform: translateX(0); }}
.button-animate-back { animation: slideLeft 0.3s ease-in-out; }
.button-animate-forward { animation: slideRight 0.3s ease-in-out; }
.spin { animation: spinAnimation 0.3s linear; }
@keyframes spinAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
`;
document.head.appendChild(animationStyle);
function showLoadingScreen(withToast = true) {
if (isLoading) return;
isLoading = true;
if (typeof NProgress !== 'undefined') NProgress.start();
if (withToast) {
showToast(
'Consider joining our <a href="https://discord.gg/dJvdkPRheV" target="_blank" class="hover-link">Discord</a>&nbsp;<3',
'success',
'heart'
);
}
}
function hideLoadingScreen() {
if (!isLoading) return;
if (typeof NProgress !== 'undefined') NProgress.done();
document.title = originalTitle;
isLoading = false;
if (erudaLoadingScreen) erudaLoadingScreen.style.display = 'none';
}
function normalizeUrl(urlStr) {
if (!urlStr || urlStr === 'about:blank') return urlStr;
try {
const url = new URL(urlStr);
url.searchParams.delete('ia');
return url.toString();
} catch {
return urlStr;
}
}
function decodeUrl(encodedUrl) {
if (!encodedUrl) return '';
try {
const prefix = (typeof __uv$config !== 'undefined' && __uv$config.prefix) ? __uv$config.prefix : '/wa/a/';
const decodeFunction = (typeof __uv$config !== 'undefined' && __uv$config.decodeUrl) ? __uv$config.decodeUrl : decodeURIComponent;
const urlObject = new URL(encodedUrl, window.location.origin);
if (urlObject.pathname.startsWith(prefix)) {
const encodedPart = urlObject.pathname.slice(prefix.length);
return decodeFunction(encodedPart) + urlObject.search + urlObject.hash;
}
} catch {}
try {
return decodeURIComponent(encodedUrl);
} catch {
return encodedUrl;
}
}
function updateNavButtons() {
if (!backIcon || !forwardIcon) return;
const canGoBack = currentIndex > 0;
const canGoForward = currentIndex < historyStack.length - 1;
backIcon.disabled = !canGoBack;
forwardIcon.disabled = !canGoForward;
backIcon.classList.toggle('disabled', !canGoBack);
forwardIcon.classList.toggle('disabled', !canGoForward);
}
function updateDecodedSearchInput() {
if (!searchInput2) return;
let currentUrl = '';
if (currentIndex >= 0 && historyStack[currentIndex]) {
currentUrl = historyStack[currentIndex];
} else if (iframe.src && iframe.src !== 'about:blank') {
currentUrl = iframe.src;
}
const decoded = decodeUrl(currentUrl);
searchInput2.value = decoded;
if (lockIcon) {
const isSecure = decoded.startsWith('https://');
lockIcon.className = isSecure ? 'fa-regular fa-lock' : 'fa-regular fa-lock-open';
}
}
function addToHistory(url, isReplacingCurrent = false) {
if (!url || url === 'about:blank') return;
const normalizedNewUrl = normalizeUrl(url);
const currentHistoryEntry = historyStack[currentIndex];
const normalizedCurrentHistoryEntry = currentIndex >= 0 ? normalizeUrl(currentHistoryEntry) : null;
if (isReplacingCurrent && currentIndex >= 0) {
if (normalizedCurrentHistoryEntry !== normalizedNewUrl || currentHistoryEntry !== url) {
historyStack[currentIndex] = url;
} else {
return;
}
} else {
if (normalizedCurrentHistoryEntry === normalizedNewUrl && currentHistoryEntry === url) {
return;
}
if (currentIndex < historyStack.length - 1) {
historyStack.splice(currentIndex + 1);
}
historyStack.push(url);
currentIndex++;
}
updateNavButtons();
updateDecodedSearchInput();
}
function generateSubject() {
const subjects = ['math', 'science', 'history', 'art', 'programming', 'philosophy'];
const randomSubject = subjects[Math.floor(Math.random() * subjects.length)];
try {
history.replaceState({}, '', `/learning?subject=${randomSubject}`);
} catch (e) {}
}
function setupIframeNavigationListeners() {
try {
const iframeWindow = iframe.contentWindow;
if (!iframeWindow || iframeWindow === window || iframeWindow.location.href === 'about:blank') return;
const handleNav = (isReplace = false) => {
setTimeout(() => {
try {
const newUrlInIframe = iframeWindow.location.href;
if (newUrlInIframe === 'about:blank' && historyStack[currentIndex] === 'about:blank') return;
addToHistory(newUrlInIframe, isReplace);
} catch (e) {}
}, 0);
};
if (!iframeWindow.history.pushState.__isPatched) {
const originalPushState = iframeWindow.history.pushState;
iframeWindow.history.pushState = function(...args) {
originalPushState.apply(this, args);
handleNav(false);
};
iframeWindow.history.pushState.__isPatched = true;
}
if (!iframeWindow.history.replaceState.__isPatched) {
const originalReplaceState = iframeWindow.history.replaceState;
iframeWindow.history.replaceState = function(...args) {
originalReplaceState.apply(this, args);
handleNav(true);
};
iframeWindow.history.replaceState.__isPatched = true;
}
iframeWindow.removeEventListener('popstate', iframeWindow.__popstateHandler);
iframeWindow.__popstateHandler = () => handleNav(false);
iframeWindow.addEventListener('popstate', iframeWindow.__popstateHandler);
iframeWindow.removeEventListener('hashchange', iframeWindow.__hashchangeHandler);
iframeWindow.__hashchangeHandler = () => handleNav(false);
iframeWindow.addEventListener('hashchange', iframeWindow.__hashchangeHandler);
} catch (error) {}
}
iframe.addEventListener('loadstart', () => {
showLoadingScreen(false);
if (navbarToggle && navbarToggle.checked && navBar) {
navBar.style.display = 'block';
}
});
iframe.addEventListener('load', () => {
hideLoadingScreen();
try {
const newUrl = iframe.contentWindow ? iframe.contentWindow.location.href : iframe.src;
if (newUrl && newUrl !== 'about:blank') {
if (currentIndex === -1 || normalizeUrl(historyStack[currentIndex]) !== normalizeUrl(newUrl) || historyStack[currentIndex] !== newUrl) {
addToHistory(newUrl);
} else if (historyStack[currentIndex] !== newUrl) {
addToHistory(newUrl, true);
}
} else if (newUrl === 'about:blank' && historyStack.length > 0 && historyStack[currentIndex] !== 'about:blank') {
if (currentIndex > 0) {
const previousUrl = historyStack[currentIndex - 1];
currentIndex--;
iframe.src = previousUrl;
return;
}
}
setupIframeNavigationListeners();
generateSubject();
if (navbarToggle && navbarToggle.checked && navBar) {
navBar.style.display = 'block';
}
} catch (error) {} finally {
updateNavButtons();
updateDecodedSearchInput();
}
});
iframe.addEventListener('error', () => {
hideLoadingScreen();
showToast('Error: Could not load page content.', 'error', 'times-circle');
updateNavButtons();
updateDecodedSearchInput();
});
function toggleButtonAnimation(button, animationClass) {
if (button) {
button.classList.add(animationClass);
setTimeout(() => button.classList.remove(animationClass), 200);
}
}
backIcon.addEventListener('click', () => {
toggleButtonAnimation(backIcon, 'button-animate-back');
if (currentIndex > 0) {
currentIndex--;
showLoadingScreen(false);
iframe.src = historyStack[currentIndex];
updateNavButtons();
updateDecodedSearchInput();
}
});
forwardIcon.addEventListener('click', () => {
toggleButtonAnimation(forwardIcon, 'button-animate-forward');
if (currentIndex < historyStack.length - 1) {
currentIndex++;
showLoadingScreen(false);
iframe.src = historyStack[currentIndex];
updateNavButtons();
updateDecodedSearchInput();
}
});
refreshIcon.addEventListener('click', () => {
if (refreshIcon) refreshIcon.classList.add('spin');
if (iframe.contentWindow) {
showLoadingScreen(false);
const currentIframeUrl = iframe.contentWindow.location.href;
if (normalizeUrl(currentIframeUrl) !== normalizeUrl(historyStack[currentIndex] || '')) {
addToHistory(currentIframeUrl);
}
iframe.contentWindow.location.reload(true);
}
if (refreshIcon) setTimeout(() => refreshIcon.classList.remove('spin'), 300);
});
fullscreenIcon.addEventListener('click', () => {
if (iframe.requestFullscreen) iframe.requestFullscreen();
else if (iframe.mozRequestFullScreen) iframe.mozRequestFullScreen();
else if (iframe.webkitRequestFullscreen) iframe.webkitRequestFullscreen();
else if (iframe.msRequestFullscreen) iframe.msRequestFullscreen();
});
function generateSearchUrl(query) {
query = query.trim();
if (!query) return `https://duckduckgo.com/?q=&ia=web`;
if (/^[a-zA-Z]+:\/\//.test(query)) {
try {
new URL(query);
return query;
} catch (e) {}
}
if (/^(localhost|(\d{1,3}\.){3}\d{1,3})(:\d+)?(\/.*)?$/.test(query) || query.toLowerCase() === "localhost") {
if (!query.toLowerCase().startsWith("http:") && !query.toLowerCase().startsWith("https:")) {
return `http://${query}`;
}
return query;
}
try {
const urlWithHttps = new URL(`https://${query}`);
if (urlWithHttps.hostname &&
urlWithHttps.hostname.includes('.') &&
!urlWithHttps.hostname.endsWith('.') &&
urlWithHttps.hostname !== '.' &&
urlWithHttps.hostname.split('.').pop().length >= 2 &&
!/^\d+$/.test(urlWithHttps.hostname.split('.').pop())
) {
return urlWithHttps.toString();
}
} catch (e) {}
return `https://duckduckgo.com/?q=${encodeURIComponent(query)}&ia=web`;
}
async function getUrl(url) {
if (typeof __uv$config !== 'undefined' && __uv$config.encodeUrl) {
return Promise.resolve(__uv$config.prefix + __uv$config.encodeUrl(url));
}
return Promise.resolve(url);
}
function clearBackground() {
const preservedElements = [
navBar, iframe, document.querySelector('.loading-screen'),
erudaLoadingScreen, topBar
].filter(el => el != null);
Array.from(document.body.children).forEach(child => {
if (!preservedElements.includes(child) && child.tagName !== 'SCRIPT' && child.tagName !== 'STYLE' && !child.classList.contains('toast')) {
child.remove();
}
});
}
async function handleSearch(query) {
if (!query || !query.trim()) {
showToast('Please enter something in the Search Bar.', 'error', 'warning');
return;
}
clearBackground();
let searchURL = generateSearchUrl(query);
historyStack.length = 0;
currentIndex = -1;
updateNavButtons();
showLoadingScreen(true);
iframe.style.display = 'block';
if (topBar) topBar.style.display = 'flex';
if (navBar && navbarToggle && navbarToggle.checked) navBar.style.display = 'block';
let finalUrlToLoad;
if (searchURL.startsWith(window.location.origin + '/assets/g/')) {
finalUrlToLoad = searchURL;
} else if (searchURL.startsWith('/assets/g/')) {
finalUrlToLoad = new URL(searchURL, window.location.origin).href;
} else {
try {
const tempUrl = new URL(searchURL);
if (tempUrl.origin === window.location.origin && tempUrl.pathname.startsWith('/assets/g/')) {
finalUrlToLoad = tempUrl.href;
} else {
finalUrlToLoad = await getUrl(searchURL);
}
} catch (e) {
finalUrlToLoad = await getUrl(searchURL);
}
}
if (searchInput2) searchInput2.value = decodeUrl(finalUrlToLoad);
iframe.src = finalUrlToLoad;
}
window.APP.handleSearch = handleSearch;
[searchInput1, searchInput2].forEach(input => {
if (input) {
input.addEventListener('keyup', e => {
if (e.key === 'Enter') {
const queryValue = input.value.trim();
if (queryValue) {
APP.handleSearch(queryValue);
if (input === searchInput1) searchInput1.value = '';
} else {
showToast('Please enter something in the Search Bar.', 'error', 'warning');
}
}
});
if (input === searchInput2) {
input.addEventListener('focus', updateDecodedSearchInput);
}
}
});
if (movies) movies.addEventListener('click', e => {
e.preventDefault();
APP.handleSearch('https://movies.usewaves.site/');
});
if (ai) ai.addEventListener('click', e => {
e.preventDefault();
APP.handleSearch('https://ai.usewaves.site/');
});
function showToast(message, type = 'success', iconType = 'check') {
const toast = document.createElement('div');
toast.className = `toast show ${type}`;
const icons = {
'check': 'fa-regular fa-check-circle',
'times-circle': 'fa-regular fa-times-circle',
'info': 'fa-regular fa-info-circle',
'warning': 'fa-regular fa-exclamation-triangle',
'heart': 'fa-solid fa-heart'
};
toast.innerHTML = `<i class="${icons[iconType] || icons.heart}" style="margin-right: 8px;"></i>${message}`;
const progressBar = document.createElement('div');
progressBar.className = 'progress-bar';
toast.appendChild(progressBar);
const closeBtn = document.createElement('button');
closeBtn.className = 'toast-close';
closeBtn.innerHTML = '<i class="fa-solid fa-xmark" style="margin-left: 8px; font-size: 0.8em;"></i>';
closeBtn.onclick = () => {
toast.classList.add('hide');
setTimeout(() => toast.remove(), 500);
};
toast.appendChild(closeBtn);
document.body.appendChild(toast);
setTimeout(() => {
toast.classList.add('hide');
setTimeout(() => toast.remove(), 500);
}, 3000);
}
if (navbarToggle && navBar && iframe) {
const savedNavbarState = localStorage.getItem('navbarToggled');
navbarToggle.checked = savedNavbarState !== 'false';
const updateNavbarDisplayBasedOnToggle = () => {
if (iframe.style.display === 'block') {
navBar.style.display = navbarToggle.checked ? 'block' : 'none';
} else {
navBar.style.display = 'none';
}
};
updateNavbarDisplayBasedOnToggle();
navbarToggle.addEventListener('change', () => {
localStorage.setItem('navbarToggled', navbarToggle.checked.toString());
updateNavbarDisplayBasedOnToggle();
});
window.APP.updateNavbarDisplay = updateNavbarDisplayBasedOnToggle;
}
window.addEventListener('load', () => {
let iframeInitiallyHidden = true;
if (iframe.src && iframe.src !== 'about:blank') {
iframeInitiallyHidden = false;
}
if (iframeInitiallyHidden) {
hideLoadingScreen();
if (topBar) topBar.style.display = 'flex';
iframe.style.display = 'none';
} else {
if (topBar) topBar.style.display = 'flex';
iframe.style.display = 'block';
}
if (window.APP.updateNavbarDisplay) window.APP.updateNavbarDisplay();
updateNavButtons();
updateDecodedSearchInput();
});
window.APP.decodeUrl = decodeUrl;
window.APP.normalizeUrl = normalizeUrl;
});

View File

@ -1,45 +0,0 @@
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('appSearchInput');
const grid = document.querySelector('.apps-grid');
let appsData = [];
fetch('/assets/data/a.json')
.then(response => response.json())
.then(data => {
appsData = data.apps;
searchInput.placeholder = `Search through ${appsData.length} Apps…`;
displayApps(appsData);
searchInput.addEventListener('input', function() {
const query = searchInput.value.toLowerCase();
const filteredApps = appsData.filter(app => {
const title = app.title ? app.title.toLowerCase() : '';
const description = app.description ? app.description.toLowerCase() : '';
return title.includes(query) || description.includes(query);
});
displayApps(filteredApps);
});
})
.catch(err => console.error('Error loading apps data:', err));
function displayApps(apps) {
grid.innerHTML = '';
if (apps.length === 0) {
grid.innerHTML = '<p>Zero apps were found matching your search :(</p>';
}
apps.forEach(app => {
const card = document.createElement('div');
card.classList.add('app-card');
card.innerHTML = `
<img src="${app.icon}" alt="${app.title} Icon" />
<h2>${app.title}</h2>
`;
card.addEventListener('click', function() {
window.handleSearch(app.link);
});
grid.appendChild(card);
});
}
});

View File

@ -1,98 +1,69 @@
document.addEventListener('DOMContentLoaded', () => {
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('gameSearchInput');
const grid = document.querySelector('.games-grid');
let gamesData = [];
let filteredData = [];
const BATCH_SIZE = 50;
let renderedCount = 0;
const grid = document.querySelector('.games-grid');
const sentinel = document.createElement('div');
sentinel.className = 'sentinel';
grid.after(sentinel);
let allGames = [];
let filteredGames = [];
let renderedCount = 0;
const BATCH_SIZE = 20;
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
renderNextBatch();
}
});
}, { rootMargin: '200px', threshold: 0.1 });
function debounce(fn, wait = 200) {
let t;
return (...args) => {
clearTimeout(t);
t = setTimeout(() => fn.apply(this, args), wait);
};
}
if (entries[0].isIntersecting) loadNextBatch();
}, { rootMargin: '500px' });
fetch('/assets/data/g.json')
.then(r => r.json())
.then(res => res.json())
.then(data => {
gamesData = data;
filteredData = data;
searchInput.placeholder = `Search through ${data.length} Games…`;
allGames = data;
filteredGames = data;
searchInput.placeholder = `Search through ${allGames.length} Games…`;
grid.parentNode.appendChild(sentinel);
observer.observe(sentinel);
renderNextBatch();
searchInput.addEventListener('input', debounce(() => {
const q = searchInput.value.trim().toLowerCase();
filteredData = gamesData.filter(g =>
(g.name || '').toLowerCase().includes(q)
);
resetRendering();
}, 250));
resetAndRender();
})
.catch(console.error);
.catch(err => console.error(err));
function resetRendering() {
searchInput.addEventListener('input', function() {
const q = this.value.toLowerCase();
filteredGames = allGames.filter(game =>
(game.name || '').toLowerCase().includes(q)
);
resetAndRender();
});
function resetAndRender() {
grid.innerHTML = '';
renderedCount = 0;
observer.observe(sentinel);
renderNextBatch();
}
function renderNextBatch() {
const batch = filteredData.slice(renderedCount, renderedCount + BATCH_SIZE);
if (!batch.length) {
renderedCount = 0;
if (filteredGames.length === 0) {
grid.innerHTML = '<p>Zero games were found matching your search :(</p>';
observer.unobserve(sentinel);
return;
}
observer.observe(sentinel);
loadNextBatch();
}
const frag = document.createDocumentFragment();
batch.forEach(game => {
function loadNextBatch() {
const nextCount = Math.min(renderedCount + BATCH_SIZE, filteredGames.length);
for (let i = renderedCount; i < nextCount; i++) {
const game = filteredGames[i];
const card = document.createElement('div');
card.className = 'game-card';
card.classList.add('game-card');
card.innerHTML = `
<img
loading="lazy"
src="/assets/g/${game.directory}/${game.image}"
alt="${game.name} Icon"
/>
<img src="/assets/g/${game.directory}/${game.image}" alt="${game.name} Icon" />
<h2>${game.name}</h2>
`;
card.addEventListener('click', () => {
window.handleSearch(`/assets/g/${game.directory}`);
const gameUrl = window.location.origin + `/assets/g/${game.directory}`;
APP.handleSearch(gameUrl);
});
frag.appendChild(card);
});
grid.appendChild(frag);
renderedCount += batch.length;
preloadNextImages(5);
if (renderedCount >= filteredData.length) {
grid.appendChild(card);
}
renderedCount = nextCount;
if (renderedCount >= filteredGames.length) {
observer.unobserve(sentinel);
} else {
grid.parentNode.appendChild(sentinel);
}
}
function preloadNextImages(limit = 3) {
const next = filteredData.slice(renderedCount, renderedCount + limit);
next.forEach(({ directory, image }) => {
const img = new Image();
img.src = `/assets/g/${directory}/${image}`;
});
}
});

View File

@ -1,6 +1,7 @@
window.onload = function() {
const storedName = localStorage.getItem('userName');
const path = window.location.pathname;
if (!storedName) {
document.getElementById('overlay').style.display = 'block';
document.getElementById('namePrompt').style.display = 'block';
@ -12,24 +13,29 @@ window.onload = function() {
});
return;
}
const welcomeMsg = getWelcomeMessage(storedName);
const iconType = getIconType(path);
const iconType = getIconType(path);
showToast(welcomeMsg, 'success', iconType);
const greetingElement = document.getElementById('greeting');
if (greetingElement) {
updateGreeting(storedName);
}
updateHi(storedName);
};
function submitName() {
const name = document.getElementById('userName').value.trim();
if (!name) return;
localStorage.setItem('userName', name);
updateGreeting(name);
updateHi(name);
document.getElementById('namePrompt').classList.add('fade-out');
showToast(`Hey, ${name}! Welcome to Waves!`, 'success', 'wave');
const path = window.location.pathname;
setTimeout(() => {
document.getElementById('namePrompt').style.display = 'none';
document.getElementById('overlay').style.display = 'none';
@ -40,8 +46,8 @@ function getWelcomeMessage(name) {
const path = window.location.pathname;
if (path === '/g') {
return `Have fun playing games, ${name}!`;
} else if (path === '/a') {
return `Enjoy our collection of apps, ${name}!`;
} else if (path === '/s') {
return `Enjoy our collection of, ${name}!`;
} else {
return `Welcome back, ${name}!`;
}
@ -49,21 +55,79 @@ function getWelcomeMessage(name) {
function getIconType(path) {
if (path === '/g') return 'game';
if (path === '/a') return 'apps';
if (path === '/s') return 'shortcuts';
return 'wave';
}
function updateGreeting(name) {
const { text, icon } = getGreeting();
const generalGreetings = [
{ text: 'Have fun', icon: '<i class="fa-regular fa-party-horn"></i>', suffix: '!' },
{ text: 'Hope you enjoy Waves', icon: '<i class="fa-solid fa-heart"></i>', suffix: ' <3' },
{ text: 'Consider joining our Discord (discord.gg/ire)', icon: '<i class="fa-solid fa-smile"></i>', suffix: '!' },
{ text: 'How you doing today', icon: '<i class="fa-regular fa-question"></i>', suffix: '?' }
];
const timeGreetings = [];
timeGreetings.push(
{ text: 'Good morning, sunshine', icon: '<i class="fa-regular fa-sun"></i>', suffix: ' :D' },
{ text: 'Heres to a bright morning', icon: '<i class="fa-regular fa-cloud-sun"></i>', suffix: '.' },
{ text: 'Enjoy your morning', icon: '<i class="fa-regular fa-mug-hot"></i>', suffix: '!' },
{ text: 'Your day starts here', icon: '<i class="fa-regular fa-star"></i>', suffix: '!' }
);
timeGreetings.push(
{ text: 'Good afternoon', icon: '<i class="fa-regular fa-leaf"></i>', suffix: '!' },
{ text: 'Hope your day is going well', icon: '<i class="fa-regular fa-coffee"></i>', suffix: '.' },
{ text: 'Keep up the pace', icon: '<i class="fa-regular fa-book"></i>', suffix: '!' },
{ text: 'Stay on track today', icon: '<i class="fa-regular fa-sun"></i>', suffix: '.' }
);
timeGreetings.push(
{ text: 'Good evening', icon: '<i class="fa-regular fa-cloud-moon"></i>', suffix: '!' },
{ text: 'Time to unwind', icon: '<i class="fa-regular fa-fire"></i>', suffix: '.' },
{ text: 'Evenings here—relax', icon: '<i class="fa-regular fa-star"></i>', suffix: '.' },
{ text: 'Breathe and recharge', icon: '<i class="fa-regular fa-moon"></i>', suffix: '…' }
);
timeGreetings.push(
{ text: 'Good night', icon: '<i class="fa-regular fa-bed"></i>', suffix: '!' },
{ text: 'Rest well', icon: '<i class="fa-regular fa-blanket"></i>', suffix: '.' },
{ text: 'Sweet dreams', icon: '<i class="fa-regular fa-star-and-crescent"></i>', suffix: '!' },
{ text: 'See you tomorrow', icon: '<i class="fa-regular fa-moon"></i>', suffix: '!' }
);
function getGreeting() {
const now = new Date();
const hour = now.getHours();
let pool = [];
if (hour >= 5 && hour < 12) {
pool = timeGreetings.slice(0, 4);
} else if (hour < 17) {
pool = timeGreetings.slice(4, 8);
} else if (hour < 21) {
pool = timeGreetings.slice(8, 12);
} else {
pool = timeGreetings.slice(12, 16);
}
if (Math.random() < 0.5) {
pool = generalGreetings;
}
return pool[Math.floor(Math.random() * pool.length)];
}
function updateGreeting(name) {
const { text, icon, suffix } = getGreeting();
const el = document.getElementById('greeting');
if (el) {
if (text === 'Hope you enjoy Waves') {
el.innerHTML = `${icon} ${text}, ${name} <3`;
} else {
el.innerHTML = `${icon} ${text}, ${name}!`;
}
el.style.opacity = 1;
if (!el) return;
el.innerHTML = `${icon} ${text}, ${name}${suffix}`;
el.style.opacity = 1;
}
function updateHi(name) {
const hiEl = document.getElementById('hi');
if (hiEl) {
hiEl.textContent = `Hii, ${name}!!`;
}
}
@ -78,7 +142,7 @@ function showToast(message, type = 'success', iconType = 'wave') {
warning: '<i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i>',
wave: '<i class="fa-regular fa-hand-wave" style="margin-right: 8px;"></i>',
game: '<i class="fa-regular fa-gamepad" style="margin-right: 8px;"></i>',
apps: '<i class="fa-regular fa-th" style="margin-right: 8px;"></i>',
apps: '<i class="fa-regular fa-th" style="margin-right: 8px;"></i>'
};
toast.innerHTML = `${icons[iconType] || icons.wave}${message}`;
@ -97,59 +161,9 @@ function showToast(message, type = 'success', iconType = 'wave') {
toast.appendChild(closeBtn);
document.body.appendChild(toast);
setTimeout(() => {
toast.classList.add('hide');
setTimeout(() => toast.remove(), 500);
}, 3000);
}
function getGreeting() {
const now = new Date();
const hour = now.getHours();
const timeGreetings = [];
const generalGreetings = [
{ text: 'Welcome aboard', icon: '<i class="fa-regular fa-rocket"></i>' },
{ text: 'Lets do something great', icon: '<i class="fa-regular fa-lightbulb"></i>' },
{ text: 'Hope you enjoy Waves', icon: '<i class="fa-regular fa-heart"></i>' },
{ text: 'Time to explore', icon: '<i class="fa-regular fa-compass"></i>' },
{ text: 'Lets roll', icon: '<i class="fa-regular fa-tire"></i>' },
{ text: 'Another great visit', icon: '<i class="fa-regular fa-thumbs-up"></i>' },
{ text: 'The adventure continues', icon: '<i class="fa-regular fa-map"></i>' }
];
if (hour >= 5 && hour < 12) {
timeGreetings.push(
{ text: 'Good morning, sunshine', icon: '<i class="fa-regular fa-sun"></i>' },
{ text: 'Heres to a bright morning', icon: '<i class="fa-regular fa-cloud-sun"></i>' },
{ text: 'Enjoy your morning', icon: '<i class="fa-regular fa-mug-hot"></i>' },
{ text: 'Your day starts here', icon: '<i class="fa-regular fa-star"></i>' }
);
} else if (hour < 17) {
timeGreetings.push(
{ text: 'Good afternoon', icon: '<i class="fa-regular fa-leaf"></i>' },
{ text: 'Hope your day is going well', icon: '<i class="fa-regular fa-coffee"></i>' },
{ text: 'Keep up the pace', icon: '<i class="fa-regular fa-book"></i>' },
{ text: 'Stay on track today', icon: '<i class="fa-regular fa-sun"></i>' }
);
} else if (hour < 21) {
timeGreetings.push(
{ text: 'Good evening', icon: '<i class="fa-regular fa-cloud-moon"></i>' },
{ text: 'Time to unwind', icon: '<i class="fa-regular fa-fire"></i>' },
{ text: 'Evenings here—relax', icon: '<i class="fa-regular fa-star"></i>' },
{ text: 'Breathe and recharge', icon: '<i class="fa-regular fa-moon"></i>' }
);
} else {
timeGreetings.push(
{ text: 'Good night', icon: '<i class="fa-regular fa-bed"></i>' },
{ text: 'Rest well', icon: '<i class="fa-regular fa-blanket"></i>' },
{ text: 'Sweet dreams', icon: '<i class="fa-regular fa-star-and-crescent"></i>' },
{ text: 'See you tomorrow', icon: '<i class="fa-regular fa-moon"></i>' }
);
}
const useGeneral = Math.random() < 0.5;
const pool = useGeneral ? generalGreetings : timeGreetings;
return pool[Math.floor(Math.random() * pool.length)];
}

View File

@ -1,21 +0,0 @@
document.addEventListener('DOMContentLoaded', function () {
NProgress.configure({ showSpinner: false });
NProgress.start();
});
window.addEventListener('load', function () {
NProgress.done();
});
const titleElement = document.querySelector('.search-title');
if (titleElement) {
const text = titleElement.textContent;
titleElement.innerHTML = '';
text.split('').forEach((letter, index) => {
const span = document.createElement('span');
span.textContent = letter;
span.style.animationDelay = `${index * 0.2}s`;
titleElement.appendChild(span);
});
}

View File

@ -1,183 +0,0 @@
const style = document.createElement('style');
style.textContent = `
@keyframes slideLeft {0% { transform: translateX(0); } 50% { transform: translateX(-5px); } 100% { transform: translateX(0); }}
@keyframes slideRight {0% { transform: translateX(0); } 50% { transform: translateX(5px); } 100% { transform: translateX(0); }}
.button-animate-back { animation: slideLeft 0.3s ease-in-out; }
.button-animate-forward { animation: slideRight 0.3s ease-in-out; }
`;
document.head.appendChild(style);
const historyStack = [];
let currentIndex = -1;
const elements = {
refreshIcon: document.getElementById('refreshIcon'),
fullscreenIcon: document.getElementById('fullscreenIcon'),
backIcon: document.getElementById('backIcon'),
forwardIcon: document.getElementById('forwardIcon'),
searchInput2: document.getElementById('searchInputt'),
iframe: document.getElementById('cool-iframe')
};
const originalTitle = document.title;
let loadingFallbackTimeout;
elements.refreshIcon.addEventListener('click', handleRefresh);
elements.fullscreenIcon.addEventListener('click', handleFullscreen);
elements.backIcon.addEventListener('click', handleBack);
elements.forwardIcon.addEventListener('click', handleForward);
function showLoadingScreen() {
if (typeof NProgress !== 'undefined') {
NProgress.start();
document.title = 'Loading... <3';
setTimeout(() => {
if (typeof NProgress !== 'undefined') NProgress.done();
}, 10000);
}
}
function hideLoadingScreen() {
if (typeof NProgress !== 'undefined') NProgress.done();
document.title = originalTitle;
}
function handleRefresh() {
elements.refreshIcon.classList.add('spin');
const iframe = elements.iframe;
const currentUrl = iframe.contentWindow.location.href;
if (normalizeUrl(currentUrl) !== normalizeUrl(historyStack[currentIndex] || '')) {
addToHistory(currentUrl);
}
iframe.contentWindow.location.reload(true);
setTimeout(() => elements.refreshIcon.classList.remove('spin'), 300);
}
function handleFullscreen() {
const iframe = elements.iframe;
if (iframe && iframe.tagName === 'IFRAME') iframe.requestFullscreen();
}
function handleBack() {
toggleButtonAnimation(elements.backIcon, 'button-animate-back');
if (currentIndex > 0) {
currentIndex--;
updateIframeSrc();
}
}
function handleForward() {
toggleButtonAnimation(elements.forwardIcon, 'button-animate-forward');
if (currentIndex < historyStack.length - 1) {
currentIndex++;
updateIframeSrc();
}
}
function toggleButtonAnimation(button, animationClass) {
button.classList.add(animationClass);
setTimeout(() => button.classList.remove(animationClass), 200);
}
function normalizeUrl(urlStr) {
try {
const url = new URL(urlStr);
url.searchParams.delete('ia');
return url.toString();
} catch (e) {
return urlStr;
}
}
function addToHistory(url) {
const normalized = normalizeUrl(url);
if (currentIndex >= 0 && normalizeUrl(historyStack[currentIndex]) === normalized) return;
if (currentIndex < historyStack.length - 1) historyStack.splice(currentIndex + 1);
historyStack.push(url);
currentIndex++;
updateNavButtons();
updateDecodedSearchInput();
}
function updateIframeSrc() {
showLoadingScreen();
elements.iframe.src = historyStack[currentIndex];
updateNavButtons();
updateDecodedSearchInput();
}
function updateNavButtons() {
const isAtStart = currentIndex <= 0;
const isAtEnd = currentIndex >= historyStack.length - 1;
elements.backIcon.disabled = isAtStart;
elements.forwardIcon.disabled = isAtEnd;
elements.backIcon.classList.toggle('disabled', isAtStart);
elements.forwardIcon.classList.toggle('disabled', isAtEnd);
}
function updateDecodedSearchInput() {
if (elements.searchInput2) {
const url = historyStack[currentIndex] || elements.iframe.src;
elements.searchInput2.value = decodeUrl(url);
}
}
function decodeUrl(url) {
try {
return decodeURIComponent(url);
} catch (e) {
return url;
}
}
window.addToHistory = addToHistory;
window.updateDecodedSearchInput = updateDecodedSearchInput;
window.normalizeUrl = normalizeUrl;
function detectIframeNavigation() {
try {
const iframeWindow = elements.iframe.contentWindow;
const pushState = iframeWindow.history.pushState;
const replaceState = iframeWindow.history.replaceState;
iframeWindow.history.pushState = function() {
pushState.apply(this, arguments);
handleIframeNavigation(iframeWindow.location.href);
};
iframeWindow.history.replaceState = function() {
replaceState.apply(this, arguments);
handleIframeNavigation(iframeWindow.location.href);
};
iframeWindow.addEventListener('popstate', () => handleIframeNavigation(iframeWindow.location.href));
iframeWindow.addEventListener('hashchange', () => handleIframeNavigation(iframeWindow.location.href));
} catch (error) {}
}
function handleIframeNavigation(rawUrl) {
let urlStr = rawUrl;
try {
urlStr = decodeUrl(rawUrl);
} catch {}
try {
const u = new URL(urlStr);
if (u.hostname.endsWith('duckduckgo.com')) {
if (typeof NProgress !== 'undefined') NProgress.done();
return;
}
} catch (e) {}
if (normalizeUrl(urlStr) !== normalizeUrl(historyStack[currentIndex] || '')) {
showLoadingScreen();
addToHistory(urlStr);
} else {
hideLoadingScreen();
}
}
elements.iframe.addEventListener('load', () => {
try {
detectIframeNavigation();
if (historyStack.length === 0) {
addToHistory(elements.iframe.contentWindow.location.href);
} else {
handleIframeNavigation(elements.iframe.contentWindow.location.href);
}
} catch (error) {}
hideLoadingScreen();
});

View File

@ -0,0 +1 @@
!function(n,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():n.NProgress=e()}(this,function(){function n(n,e,t){return e>n?e:n>t?t:n}function e(n){return 100*(-1+n)}function t(n,t,r){var i;return i="translate3d"===c.positionUsing?{transform:"translate3d("+e(n)+"%,0,0)"}:"translate"===c.positionUsing?{transform:"translate("+e(n)+"%,0)"}:{"margin-left":e(n)+"%"},i.transition="all "+t+"ms "+r,i}function r(n,e){var t="string"==typeof n?n:o(n);return t.indexOf(" "+e+" ")>=0}function i(n,e){var t=o(n),i=t+e;r(t,e)||(n.className=i.substring(1))}function s(n,e){var t,i=o(n);r(n,e)&&(t=i.replace(" "+e+" "," "),n.className=t.substring(1,t.length-1))}function o(n){return(" "+(n.className||"")+" ").replace(/\s+/gi," ")}function a(n){n&&n.parentNode&&n.parentNode.removeChild(n)}var u={};u.version="0.2.0";var c=u.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};u.configure=function(n){var e,t;for(e in n)t=n[e],void 0!==t&&n.hasOwnProperty(e)&&(c[e]=t);return this},u.status=null,u.set=function(e){var r=u.isStarted();e=n(e,c.minimum,1),u.status=1===e?null:e;var i=u.render(!r),s=i.querySelector(c.barSelector),o=c.speed,a=c.easing;return i.offsetWidth,l(function(n){""===c.positionUsing&&(c.positionUsing=u.getPositioningCSS()),f(s,t(e,o,a)),1===e?(f(i,{transition:"none",opacity:1}),i.offsetWidth,setTimeout(function(){f(i,{transition:"all "+o+"ms linear",opacity:0}),setTimeout(function(){u.remove(),n()},o)},o)):setTimeout(n,o)}),this},u.isStarted=function(){return"number"==typeof u.status},u.start=function(){u.status||u.set(0);var n=function(){setTimeout(function(){u.status&&(u.trickle(),n())},c.trickleSpeed)};return c.trickle&&n(),this},u.done=function(n){return n||u.status?u.inc(.3+.5*Math.random()).set(1):this},u.inc=function(e){var t=u.status;return t?("number"!=typeof e&&(e=(1-t)*n(Math.random()*t,.1,.95)),t=n(t+e,0,.994),u.set(t)):u.start()},u.trickle=function(){return u.inc(Math.random()*c.trickleRate)},function(){var n=0,e=0;u.promise=function(t){return t&&"resolved"!==t.state()?(0===e&&u.start(),n++,e++,t.always(function(){e--,0===e?(n=0,u.done()):u.set((n-e)/n)}),this):this}}(),u.render=function(n){if(u.isRendered())return document.getElementById("nprogress");i(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=c.template;var r,s=t.querySelector(c.barSelector),o=n?"-100":e(u.status||0),l=document.querySelector(c.parent);return f(s,{transition:"all 0 linear",transform:"translate3d("+o+"%,0,0)"}),c.showSpinner||(r=t.querySelector(c.spinnerSelector),r&&a(r)),l!=document.body&&i(l,"nprogress-custom-parent"),l.appendChild(t),t},u.remove=function(){s(document.documentElement,"nprogress-busy"),s(document.querySelector(c.parent),"nprogress-custom-parent");var n=document.getElementById("nprogress");n&&a(n)},u.isRendered=function(){return!!document.getElementById("nprogress")},u.getPositioningCSS=function(){var n=document.body.style,e="WebkitTransform"in n?"Webkit":"MozTransform"in n?"Moz":"msTransform"in n?"ms":"OTransform"in n?"O":"";return e+"Perspective"in n?"translate3d":e+"Transform"in n?"translate":"margin"};var l=function(){function n(){var t=e.shift();t&&t(n)}var e=[];return function(t){e.push(t),1==e.length&&n()}}(),f=function(){function n(n){return n.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(n,e){return e.toUpperCase()})}function e(n){var e=document.body.style;if(n in e)return n;for(var t,r=i.length,s=n.charAt(0).toUpperCase()+n.slice(1);r--;)if(t=i[r]+s,t in e)return t;return n}function t(t){return t=n(t),s[t]||(s[t]=e(t))}function r(n,e,r){e=t(e),n.style[e]=r}var i=["Webkit","O","Moz","ms"],s={};return function(n,e){var t,i,s=arguments;if(2==s.length)for(t in e)i=e[t],void 0!==i&&e.hasOwnProperty(t)&&r(n,t,i);else r(n,s[1],s[2])}}();return u});

View File

@ -10,7 +10,7 @@
ws = new WebSocket(wsUrl);
ws.onopen = function() {
pingDisplay.innerHTML = '<i class="fas fa-wifi"></i> Ping: Waiting...';
pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> Ping: Waiting...';
};
ws.onmessage = function(event) {
@ -23,7 +23,7 @@
}));
}
if (data.type === "latency" && typeof data.latency === "number") {
pingDisplay.innerHTML = '<i class="fa-regular fa-wifi"></i> Ping: ' + data.latency + ' ms';
pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> ' + 'Ping: ' + '~' + data.latency + 'ms';
}
} catch (err) {
console.error("Error parsing message:", err);
@ -31,11 +31,11 @@
};
ws.onerror = function() {
pingDisplay.innerHTML = '<i class="fa-regular fa-wifi"></i> Ping: Error';
pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> Ping: Error';
};
ws.onclose = function() {
pingDisplay.innerHTML = '<i class="fa-regular fa-wifi"></i> Ping: Disconnected';
pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> Ping: Disconnected';
setTimeout(createWebSocket, 1000);
};
}

View File

@ -1,124 +1,80 @@
document.addEventListener('DOMContentLoaded', function() {
const originalLog = console.log;
const originalWarn = console.warn;
const originalError = console.error;
const scriptLogs = [];
;(function(){
const origLog = console.log.bind(console);
document.addEventListener("DOMContentLoaded", () => {
origLog(
"%c\n" +
" ᶻ 𝗓 𐰁 .ᐟ\n" +
" |\\ _,,,---,,_\n" +
" /, `.-'`' -. ;-;;,_\n" +
" |,4- ) )-,_..;\\ ( `'-'\n" +
" '---''(_/--' `-`\\_)\n discord.gg/dJvdkPRheV",
"color: hotpink; font-size: 16px; display: block; white-space: pre; text-align: center; padding-left: 28%;"
);
});
function isScriptLog(args) {
return args[0] && (args[0].includes('%c[+]%c') || args[0].includes('%c[*]%c') || args[0].includes('%c[#]%c') || args[0].includes('%c[-]%c') || args[0].includes('%c[!]%c'));
}
const labelStyle = "background: white; color: black; font-weight: bold; padding: 2px 4px; border-radius: 2px";
const messageStyle = "background: black; color: white; padding: 2px 4px; border-radius: 2px";
["log","info","warn","error","debug"].forEach(method => {
const orig = console[method].bind(console);
console[method] = (...args) => {
const text = args.map(a => typeof a === 'string' ? a : JSON.stringify(a)).join(' ');
orig(`%cWaves:%c ${text}`, labelStyle, messageStyle);
};
});
console.log = function(...args) {
if (isScriptLog(args)) {
scriptLogs.push(args);
}
originalLog.apply(console, args);
};
document.addEventListener("DOMContentLoaded", function(){
const defaultWispUrl = `${window.location.protocol==="https:"?"wss":"ws"}://${window.location.host}/w/`;
let currentWispUrl = localStorage.getItem("customWispUrl") || defaultWispUrl;
const wispUrl = currentWispUrl;
const connection = new BareMux.BareMuxConnection("/baremux/worker.js");
console.warn = function(...args) {
if (isScriptLog(args)) {
scriptLogs.push(args);
}
originalWarn.apply(console, args);
};
registerSW();
console.error = function(...args) {
if (isScriptLog(args)) {
scriptLogs.push(args);
}
originalError.apply(console, args);
};
async function registerSW(){
try {
if (!navigator.serviceWorker) return console.error("Service Workers are not supported by this browser.");
await ensureWebSocketConnection(wispUrl);
console.log("Registering Service Worker...");
await navigator.serviceWorker.register("/wah/sw.js", { scope: "/wah/a/" });
console.log("Service Worker registered successfully.");
const savedTransport = localStorage.getItem("transport") || "epoxy";
switchTransport(savedTransport);
updateTransportUI(savedTransport);
console.log(`Using ${capitalizeTransport(savedTransport)} transport.`);
} catch (e) {
console.error(`An error occurred during Service Worker registration or WebSocket connection: ${e.message||e}`);
}
}
setInterval(() => {
const currentLogs = [...scriptLogs];
console.clear();
currentLogs.forEach(log => originalLog.apply(console, log));
}, 400);
async function ensureWebSocketConnection(url){
return new Promise((resolve, reject) => {
console.log("Establishing WebSocket connection...");
const ws = new WebSocket(url);
ws.onopen = () => { console.log("WebSocket connection established."); resolve(ws); };
ws.onerror = e => { console.error(`Failed to establish WebSocket connection: ${e.message||e}`); reject(e); };
ws.onclose = ev => {
if (ev.code !== 1000) console.warn(`WebSocket connection closed. Reason: ${ev.reason||"No reason provided"}`);
else console.warn("WebSocket connection closed normally.");
};
});
}
const defaultWispUrl = `${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.host}/w/`;
let currentWispUrl = localStorage.getItem('customWispUrl') || defaultWispUrl;
const wispUrl = currentWispUrl;
const connection = new BareMux.BareMuxConnection("/baremux/worker.js");
function switchTransport(t){
const m = { epoxy: "/epoxy/index.mjs", libcurl: "/libcurl/index.mjs" }[t];
if (m) connection.setTransport(m, [{ wisp: wispUrl }]);
}
async function registerSW() {
try {
if (!navigator.serviceWorker) {
console.log("%c[!]%c Service Workers are not supported by this browser.", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
return;
}
await ensureWebSocketConnection(wispUrl);
console.log("%c[+]%c Registering Service Worker...", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
await navigator.serviceWorker.register("/wah/sw.js", { scope: '/wah/a/' });
console.log("%c[*]%c Service Worker registered successfully.", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
const savedTransport = localStorage.getItem('transport') || "epoxy";
switchTransport(savedTransport);
updateTransportUI(savedTransport);
console.log(`%c[#]%c Using ${capitalizeTransport(savedTransport)} transport.`, "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
} catch (error) {
logError(error, 'An error occurred during Service Worker registration or WebSocket connection');
}
}
function updateTransportUI(t){
document.querySelector(".transport-selected").textContent = capitalizeTransport(t);
}
async function ensureWebSocketConnection(url) {
return new Promise((resolve, reject) => {
console.log("%c[+]%c Establishing WebSocket connection...", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
const ws = new WebSocket(url);
ws.onopen = () => {
console.log("%c[*]%c WebSocket connection established.", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
resolve(ws);
};
ws.onerror = (error) => {
logError(error, 'Failed to establish WebSocket connection');
reject(error);
};
ws.onclose = (event) => {
if (event.code !== 1000) {
console.warn(`%c[-]%c WebSocket connection closed. Reason: ${event.reason || "No reason provided"}`, "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
} else {
console.warn("%c[-]%c WebSocket connection closed normally.", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
}
};
});
}
function capitalizeTransport(t){
return t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();
}
function logError(error, message) {
console.error(`%c[!]%c ${message}: ${error.message || error}`, "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
}
function switchTransport(transport) {
const transportMap = {
"epoxy": "/epoxy/index.mjs",
"libcurl": "/libcurl/index.mjs"
};
const transportFile = transportMap[transport];
if (transportFile) {
connection.setTransport(transportFile, [{ wisp: wispUrl }]);
}
}
async function changeTransport(newTransport) {
try {
localStorage.setItem('transport', newTransport);
switchTransport(newTransport);
updateTransportUI(newTransport);
} catch (error) {
logError(error, 'An error occurred while storing transport preference');
}
}
function updateTransportUI(transport) {
const transportSelected = document.querySelector(".transport-selected");
transportSelected.textContent = capitalizeTransport(transport);
}
function capitalizeTransport(transport) {
return transport.charAt(0).toUpperCase() + transport.slice(1).toLowerCase();
}
document.addEventListener('wispUrlChanged', function(e) {
currentWispUrl = e.detail;
switchTransport(localStorage.getItem('transport') || "epoxy");
});
registerSW();
});
document.addEventListener("wispUrlChanged", function(e){
currentWispUrl = e.detail;
switchTransport(localStorage.getItem("transport") || "epoxy");
});
});
})();

45
public/assets/js/s.js Normal file
View File

@ -0,0 +1,45 @@
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('shortcutSearchInput');
const grid = document.querySelector('.shortcuts-grid');
let shortcutsData = [];
fetch('/assets/data/s.json')
.then(response => response.json())
.then(data => {
shortcutsData = data.shortcuts;
searchInput.placeholder = `Search through ${shortcutsData.length} Shortcuts...`;
displayShortcuts(shortcutsData);
searchInput.addEventListener('input', function() {
const query = searchInput.value.toLowerCase();
const filteredShortcuts = shortcutsData.filter(shortcut => {
const title = shortcut.title ? shortcut.title.toLowerCase() : '';
const description = shortcut.description ? shortcut.description.toLowerCase() : '';
return title.includes(query) || description.includes(query);
});
displayShortcuts(filteredShortcuts);
});
})
.catch(err => console.error('Error loading shortcuts data:', err));
function displayShortcuts(shortcuts) {
grid.innerHTML = '';
if (shortcuts.length === 0) {
grid.innerHTML = '<p>Zero shortcuts were found matching your search :(</p>';
}
shortcuts.forEach(shortcut => {
const card = document.createElement('div');
card.classList.add('shortcut-card');
card.innerHTML = `
<img src="${shortcut.icon}" alt="${shortcut.title} Icon" />
<h2>${shortcut.title}</h2>
`;
card.addEventListener('click', function() {
APP.handleSearch(shortcut.link);
});
grid.appendChild(card);
});
}
});

View File

@ -1,210 +1,350 @@
document.addEventListener('DOMContentLoaded', function() {
const settingsMenu = document.getElementById('settings-menu');
settingsMenu.innerHTML = `
<h2>Settings</h2>
<div class="settings-tabs">
<button class="tab-button active" id="proxy-tab"><i class="fa-regular fa-server"></i> Proxy</button>
<button class="tab-button" id="cloak-tab"><i class="fa-regular fa-user-secret"></i> Cloak</button>
<button class="tab-button" id="appearance-tab"><i class="fa-regular fa-palette"></i> Appearance</button>
<button class="tab-button" id="info-tab"><i class="fa-regular fa-info"></i> Info</button>
</div>
<div id="proxy-content" class="tab-content">
<label for="transport-selector">Transport</label>
<p>Transport is how the proxy will send information.</p>
<div class="transport-selector">
<div class="transport-selected">Epoxy</div>
<div class="transport-options">
<div>Epoxy</div>
<div>Libcurl</div>
const settingsMenu = document.getElementById('settings-menu');
settingsMenu.innerHTML = `
<h2>Settings</h2>
<div class="settings-tabs">
<button class="tab-button active" id="proxy-tab">
<i class="fa-regular fa-server"></i> Proxy
</button>
<button class="tab-button" id="cloak-tab">
<i class="fa-regular fa-user-secret"></i> Cloak
</button>
<button class="tab-button" id="appearance-tab">
<i class="fa-regular fa-palette"></i> Appearance
</button>
<button class="tab-button" id="info-tab">
<i class="fa-regular fa-info"></i> Info
</button>
</div>
<div id="proxy-content" class="tab-content">
<label for="transport-selector">Transport</label>
<p>Transport is how the proxy will send information.</p>
<div class="transport-selector">
<div class="transport-selected">Epoxy</div>
<div class="transport-options">
<div>Epoxy</div>
<div>Libcurl</div>
</div>
</div>
<label for="wisp-server">Wisp Server</label>
<p>Enter a different Wisp Server to connect to.</p>
<p>Recommended to keep this as default.</p>
<input type="text" id="wisp-server" placeholder="Wisp Server URL Here..." autocomplete="off">
<button id="save-wisp-url">Save</button>
</div>
<div id="cloak-content" class="tab-content">
<label for="aboutblank-toggle">Auto About:Blank</label>
<p>Turn this on to go into about:blank every time the page loads (Recommended).</p>
<input type="checkbox" id="aboutblank-toggle">
</div>
<div id="appearance-content" class="tab-content">
<label for="navbar-toggle">Navigation Bar</label>
<p>Keep this on for the navigation bar when searching (Recommended).</p>
<input type="checkbox" id="navbar-toggle">
</div>
<div id="info-content" class="tab-content">
<label>Version 2.8.9</label>
<label
onmouseover="this.querySelector('span').style.color='lime'"
onmouseout="this.querySelector('span').style.color='green'">
Server Status:
<span style="color: green; transition: color 0.3s ease; font-size: 0.95em;">Running</span>
</label>
<label
onmouseover="this.querySelector('span').style.color='lime'"
onmouseout="this.querySelector('span').style.color='green'">
Server Speed:
<span id="server-speed" style="color: green; transition: color 0.3s ease; font-size: 0.95em;">Checking...</span>
</label>
<label
onmouseover="this.querySelector('span').style.color='#dadada'"
onmouseout="this.querySelector('span').style.color='#949494'">
Server Uptime:
<span id="server-uptime" style="color: #949494; transition: color 0.3s ease; font-size: 0.95em;">Calculating...</span>
</label>
<label
onmouseover="this.querySelector('span').style.color='#dadada'"
onmouseout="this.querySelector('span').style.color='#949494'">
Server Specs:
<span id="server-specs" style="color: #949494; transition: color 0.3s ease; font-size: 0.95em;">Loading...</span>
</label>
<p>Having any problems? Join our Discord Server below or open an issue on GitHub for support.</p>
<div style="display: flex; gap: 10px; justify-content: left; align-items: left; margin-top: 10px; margin-bottom: -20px;">
<label>
<a href="https://discord.gg/dJvdkPRheV" target="_blank" class="hover-link">
<i class="fab fa-discord" style="font-size: 20px;"></i>
</a>
</label>
<label>
<a href="https://github.com/xojw/waves" target="_blank" class="hover-link">
<i class="fab fa-github" style="font-size: 20px;"></i>
</a>
</label>
</div>
</div>
<label for="wisp-server">Wisp Server</label>
<p>Enter a different Wisp Server to connect to.</p>
<p>Recommended to keep this as default.</p>
<input type="text" id="wisp-server" placeholder="Wisp Server URL Here..." autocomplete="off">
<button id="save-wisp-url">Save</button>
</div>
<div id="cloak-content" class="tab-content">
<label for="aboutblank-toggle">About:Blank</label>
<p>Turn this on to go into about:blank every time the page loads (Recommended).</p>
<input type="checkbox" id="aboutblank-toggle">
</div>
<div id="appearance-content" class="tab-content">
<label for="navbar-toggle">Navigation Bar</label>
<p>Keep this on for the navigation bar when searching (Recommended).</p>
<input type="checkbox" id="navbar-toggle">
</div>
<div id="info-content" class="tab-content">
<label>Version 2.8.5</label>
<label onmouseover="this.querySelector('span').style.color='lime'" onmouseout="this.querySelector('span').style.color='green'">
Server Status: <span style="color: green; transition: color 0.3s ease;">Running</span>
</label>
<p>If you want to see Waves status please visit <a href="https://status.usewaves.site" target="_blank" class="hover-link">https://status.usewaves.site</a>.</p>
<div style="display: flex; gap: 10px; justify-content: left; align-items: left; margin-top: 10px; margin-bottom: -20px;">
<label><a href="https://discord.gg/dJvdkPRheV" target="_blank" class="hover-link"><i class="fab fa-discord" style="font-size: 20px;"></i></a></label>
<label><a href="https://github.com/xojw/waves" target="_blank" class="hover-link"><i class="fab fa-github" style="font-size: 20px;"></i></a></label>
</div>
</div>
<button id="close-settings"><i class="fa-regular fa-times"></i></button>
<button id="close-settings">
<i class="fa-regular fa-times"></i>
</button>
`;
const settingsIcon = document.getElementById('settings-icon');
const closeSettingsButton = document.getElementById('close-settings');
const saveButton = document.getElementById('save-wisp-url');
const transportSelector = document.querySelector('.transport-selector');
const transportSelected = transportSelector.querySelector('.transport-selected');
const transportOptions = transportSelector.querySelector('.transport-options');
const navbarToggle = document.getElementById('navbar-toggle');
const defaultWispUrl = `${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.host}/w/`;
let currentWispUrl = localStorage.getItem('customWispUrl') || defaultWispUrl;
const wispInput = document.querySelector("#wisp-server");
wispInput.value = currentWispUrl;
function isValidUrl(url) {
try {
const parsedUrl = new URL(url);
return (parsedUrl.protocol === "wss:" || parsedUrl.protocol === "ws:") && url.endsWith('/');
} catch (_) {
return false;
}
}
const settingsIcon = document.getElementById('settings-icon');
const closeSettingsBtn = document.getElementById('close-settings');
const saveWispBtn = document.getElementById('save-wisp-url');
const transportSelector = document.querySelector('.transport-selector');
const transportSelected = transportSelector.querySelector('.transport-selected');
const transportOptions = transportSelector.querySelector('.transport-options');
const navbarToggle = document.getElementById('navbar-toggle');
const defaultWispUrl = `${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.host}/w/`;
let currentWispUrl = localStorage.getItem('customWispUrl') || defaultWispUrl;
const wispInput = document.querySelector("#wisp-server");
wispInput.value = currentWispUrl;
let isToggling = false;
function updateWispServerUrl(url) {
if (isValidUrl(url)) {
currentWispUrl = url;
localStorage.setItem('customWispUrl', url);
document.dispatchEvent(new CustomEvent('wispUrlChanged', { detail: currentWispUrl }));
wispInput.value = currentWispUrl;
showToast('success', `WISP URL successfully updated to: ${currentWispUrl}`);
location.reload();
} else {
currentWispUrl = defaultWispUrl;
localStorage.setItem('customWispUrl', defaultWispUrl);
wispInput.value = defaultWispUrl;
showToast('error', "Invalid URL. Reverting back to default...");
location.reload();
}
}
saveButton.addEventListener('click', () => {
updateWispServerUrl(wispInput.value.trim());
});
settingsIcon.addEventListener('click', (event) => {
event.preventDefault();
toggleSettingsMenu();
});
closeSettingsButton.addEventListener('click', toggleSettingsMenu);
navbarToggle.checked = localStorage.getItem('navbarToggled') !== 'false';
function toggleSettingsMenu() {
const icon = document.querySelector('#settings-icon i.settings-icon');
if (settingsMenu.classList.contains('open')) {
settingsMenu.classList.add('close');
icon.classList.replace('fa-solid', 'fa-regular');
setTimeout(() => settingsMenu.classList.remove('open', 'close'), 300);
} else {
settingsMenu.classList.add('open');
icon.classList.replace('fa-regular', 'fa-solid');
setTimeout(() => settingsMenu.classList.remove('close'), 300);
}
}
transportSelected.addEventListener('click', function(e) {
e.stopPropagation();
transportOptions.classList.toggle('transport-show');
this.classList.toggle('transport-arrow-active');
});
Array.from(transportOptions.getElementsByTagName('div')).forEach(option => {
option.addEventListener('click', function(e) {
e.stopPropagation();
const selectedValue = this.textContent;
transportSelected.textContent = selectedValue;
localStorage.setItem('transport', selectedValue.toLowerCase());
transportOptions.classList.remove('transport-show');
transportSelected.classList.remove('transport-arrow-active');
document.dispatchEvent(new Event('newTransport', { detail: selectedValue.toLowerCase() }));
showToast('success', `Transport successfully changed to ${selectedValue}`);
location.reload();
});
});
document.getElementById('proxy-content').classList.add('active');
function isValidUrl(url) {
try {
const p = new URL(url);
return (p.protocol === "wss:" || p.protocol === "ws:") && url.endsWith('/');
} catch (_) {
return false;
}
}
function switchTab(activeTabId, activeContentId, ...others) {
[others[1], others[3], others[5]].forEach(id => document.getElementById(id).classList.remove('active'));
[others[0], others[2], others[4]].forEach(id => document.getElementById(id).classList.remove('active'));
document.getElementById(activeContentId).classList.add('active');
document.getElementById(activeTabId).classList.add('active');
}
document.getElementById('proxy-tab').addEventListener('click', function() {
switchTab('proxy-tab', 'proxy-content', 'appearance-tab', 'appearance-content', 'cloak-tab', 'cloak-content', 'info-tab', 'info-content');
});
document.getElementById('cloak-tab').addEventListener('click', function() {
switchTab('cloak-tab', 'cloak-content', 'proxy-tab', 'proxy-content', 'appearance-tab', 'appearance-content', 'info-tab', 'info-content');
});
document.getElementById('appearance-tab').addEventListener('click', function() {
switchTab('appearance-tab', 'appearance-content', 'proxy-tab', 'proxy-content', 'cloak-tab', 'cloak-content', 'info-tab', 'info-content');
});
document.getElementById('info-tab').addEventListener('click', function() {
switchTab('info-tab', 'info-content', 'proxy-tab', 'proxy-content', 'appearance-tab', 'appearance-content', 'cloak-tab', 'cloak-content');
});
document.querySelectorAll('.tab-button').forEach(btn => {
btn.addEventListener('click', function() {
const icon = this.querySelector('i');
if (icon.classList.contains('fa-bounce')) return;
icon.classList.add('fa-bounce');
setTimeout(() => icon.classList.remove('fa-bounce'), 750);
});
});
navbarToggle.addEventListener('change', function() {
showToast(this.checked ? 'success' : 'error', `Navigation Bar is now ${this.checked ? 'enabled' : 'disabled'}.`);
});
function runScriptIfChecked() {
let inFrame;
try { inFrame = window !== top; } catch (e) { inFrame = true; }
const aboutBlankChecked = JSON.parse(localStorage.getItem("aboutBlankChecked")) || false;
if (!aboutBlankChecked || inFrame) return;
const title = localStorage.getItem("siteTitle") || "Google.";
const icon = localStorage.getItem("faviconURL") || "https://www.google.com/favicon.ico";
const popup = window.open("", "_blank");
if (!popup || popup.closed) {
alert("Failed to load automask. Please allow popups and try again.");
return;
}
popup.document.head.innerHTML = `<title>${title}</title><link rel="icon" href="${icon}">`;
popup.document.body.innerHTML = `<iframe style="height:100%;width:100%;border:none;position:fixed;top:0;right:0;left:0;bottom:0;" src="/"></iframe>`;
window.location.replace("https://bisd.schoology.com/home");
}
document.getElementById("aboutblank-toggle").addEventListener("change", function() {
localStorage.setItem("aboutBlankChecked", JSON.stringify(this.checked));
showToast(this.checked ? 'success' : 'error', `About:Blank is now ${this.checked ? 'enabled' : 'disabled'}.`);
runScriptIfChecked();
});
window.addEventListener("load", function() {
const aboutBlankChecked = JSON.parse(localStorage.getItem("aboutBlankChecked")) || false;
document.getElementById("aboutblank-toggle").checked = aboutBlankChecked;
runScriptIfChecked();
});
function showToast(type, message) {
const toast = document.createElement('div');
toast.className = `toast ${type} show`;
const icons = {
success: '<i class="fa-regular fa-check-circle" style="margin-right:8px;"></i>',
error: '<i class="fa-regular fa-times-circle" style="margin-right:8px;"></i>',
info: '<i class="fa-regular fa-info-circle" style="margin-right:8px;"></i>',
warning: '<i class="fa-regular fa-exclamation-triangle" style="margin-right:8px;"></i>'
};
toast.innerHTML = `${icons[type] || ''}${message}`;
const progressBar = document.createElement('div');
progressBar.className = 'progress-bar';
toast.appendChild(progressBar);
const closeBtn = document.createElement('button');
closeBtn.className = 'toast-close';
closeBtn.innerHTML = '<i class="fa-regular fa-xmark" style="margin-left:8px;font-size:0.8em;"></i>';
closeBtn.addEventListener('click', () => {
toast.classList.replace('show', 'hide');
setTimeout(() => toast.remove(), 500);
});
toast.appendChild(closeBtn);
document.body.appendChild(toast);
setTimeout(() => {
toast.classList.replace('show', 'hide');
setTimeout(() => toast.remove(), 500);
}, 3000);
}
function runScriptIfChecked() {
let inFrame;
try {
inFrame = window !== top;
} catch (e) {
inFrame = true;
}
const aboutBlankChecked = JSON.parse(localStorage.getItem("aboutBlankChecked")) || false;
if (!aboutBlankChecked || inFrame) {
return;
}
const defaultTitle = "Google.";
const defaultIcon = "https://www.google.com/favicon.ico";
const title = localStorage.getItem("siteTitle") || defaultTitle;
const icon = localStorage.getItem("faviconURL") || defaultIcon;
const iframeSrc = "/";
const popup = window.open("", "_blank");
if (!popup || popup.closed) {
alert("Failed to load automask. Please allow popups and try again.");
return;
}
popup.document.head.innerHTML = `
<title>${title}</title>
<link rel="icon" href="${icon}">
`;
popup.document.body.innerHTML = `
<iframe style="height: 100%; width: 100%; border: none; position: fixed; top: 0; right: 0; left: 0; bottom: 0;" src="${iframeSrc}"></iframe>
`;
window.location.replace("https://bisd.schoology.com/home");
}
document.getElementById("aboutblank-toggle").addEventListener("change", function() {
localStorage.setItem("aboutBlankChecked", JSON.stringify(this.checked));
if (this.checked) {
showToast('success', 'Auto About:Blank is now enabled.');
} else {
showToast('error', 'Auto About:Blank is now disabled.');
}
runScriptIfChecked();
});
window.addEventListener("load", function() {
const aboutBlankChecked = JSON.parse(localStorage.getItem("aboutBlankChecked")) || false;
document.getElementById("aboutblank-toggle").checked = aboutBlankChecked;
runScriptIfChecked();
});
function updateWispServerUrl(url) {
if (isValidUrl(url)) {
currentWispUrl = url;
localStorage.setItem('customWispUrl', url);
document.dispatchEvent(new CustomEvent('wispUrlChanged', {
detail: currentWispUrl
}));
showToast('success', `Wisp Server URL changed to: ${currentWispUrl}`);
} else {
currentWispUrl = defaultWispUrl;
localStorage.setItem('customWispUrl', defaultWispUrl);
document.dispatchEvent(new CustomEvent('wispUrlChanged', {
detail: currentWispUrl
}));
showToast('error', "Invalid URL. Reverting to default...");
}
}
function updateServerInfo() {
const speedSpan = document.getElementById('server-speed');
const uptimeSpan = document.getElementById('server-uptime');
const specsSpan = document.getElementById('server-specs');
let uptimeInterval;
fetch('/api/info')
.then(response => {
if (!response.ok) throw new Error();
return response.json();
})
.then(data => {
if (data?.speed) {
const updateUptimeDisplay = () => {
const uptime = Date.now() - data.startTime;
const days = Math.floor(uptime / 86400000);
const hours = Math.floor((uptime % 86400000) / 3600000);
const minutes = Math.floor((uptime % 3600000) / 60000);
const seconds = Math.floor((uptime % 60000) / 1000);
uptimeSpan.textContent = `${days}d ${hours}h ${minutes}m ${seconds}s`;
};
updateUptimeDisplay();
clearInterval(uptimeInterval);
uptimeInterval = setInterval(updateUptimeDisplay, 1000);
speedSpan.textContent = `${data.speed} (${data.averageLatency}ms)`;
specsSpan.textContent = data.specs;
}
setTimeout(updateServerInfo, 10000);
})
.catch(() => {
speedSpan.textContent = 'Connection error';
setTimeout(updateServerInfo, 30000);
});
}
function initializeInfo() {
const infoTab = document.getElementById('info-tab');
const infoContent = document.getElementById('info-content');
const startMonitoring = () => {
updateServerInfo();
infoTab.removeEventListener('click', startMonitoring);
};
if (infoContent.classList.contains('active')) {
updateServerInfo();
} else {
infoTab.addEventListener('click', startMonitoring, {
once: true
});
}
}
function showToast(type, message) {
const toast = document.createElement('div');
toast.className = `toast ${type} show`;
const icons = {
success: '<i class="fa-regular fa-check-circle"></i>',
error: '<i class="fa-regular fa-times-circle"></i>',
info: '<i class="fa-regular fa-info-circle"></i>',
warning: '<i class="fa-regular fa-exclamation-triangle"></i>'
};
toast.innerHTML = `${icons[type]||''}${message}`;
const progressBar = document.createElement('div');
progressBar.className = 'progress-bar';
toast.appendChild(progressBar);
const closeBtn = document.createElement('button');
closeBtn.className = 'toast-close';
closeBtn.innerHTML = '<i class="fa-regular fa-xmark"></i>';
closeBtn.addEventListener('click', () => {
toast.classList.replace('show', 'hide');
setTimeout(() => toast.remove(), 500);
});
toast.appendChild(closeBtn);
document.body.appendChild(toast);
setTimeout(() => {
toast.classList.replace('show', 'hide');
setTimeout(() => toast.remove(), 500);
}, 3000);
}
saveWispBtn.addEventListener('click', () => updateWispServerUrl(wispInput.value.trim()));
settingsIcon.addEventListener('click', e => {
e.preventDefault();
toggleSettingsMenu();
});
closeSettingsBtn.addEventListener('click', toggleSettingsMenu);
function toggleSettingsMenu() {
if (isToggling) return;
isToggling = true;
const icon = document.querySelector('#settings-icon i.settings-icon');
if (settingsMenu.classList.contains('open')) {
settingsMenu.classList.add('close');
icon.classList.replace('fa-solid', 'fa-regular');
setTimeout(() => {
settingsMenu.classList.remove('open', 'close');
isToggling = false;
}, 300);
} else {
settingsMenu.classList.add('open');
icon.classList.replace('fa-regular', 'fa-solid');
setTimeout(() => {
settingsMenu.classList.remove('close');
isToggling = false;
}, 300);
}
}
transportSelected.addEventListener('click', e => {
e.stopPropagation();
transportOptions.classList.toggle('transport-show');
transportSelected.classList.toggle('transport-arrow-active');
});
Array.from(transportOptions.getElementsByTagName('div')).forEach(option => {
option.addEventListener('click', function(e) {
e.stopPropagation();
const val = this.textContent;
transportSelected.textContent = val;
localStorage.setItem('transport', val.toLowerCase());
transportOptions.classList.remove('transport-show');
transportSelected.classList.remove('transport-arrow-active');
document.dispatchEvent(new CustomEvent('newTransport', {
detail: val.toLowerCase()
}));
showToast('success', `Transport changed to ${val}`);
});
});
document.getElementById('proxy-content').classList.add('active');
function switchTab(activeTab, activeContent, ...others) {
others.forEach(id => document.getElementById(id).classList.remove('active'));
document.getElementById(activeTab).classList.add('active');
document.getElementById(activeContent).classList.add('active');
}
document.getElementById('proxy-tab').addEventListener('click', () => switchTab('proxy-tab', 'proxy-content', 'cloak-tab', 'cloak-content', 'appearance-tab', 'appearance-content', 'info-tab', 'info-content'));
document.getElementById('cloak-tab').addEventListener('click', () => switchTab('cloak-tab', 'cloak-content', 'proxy-tab', 'proxy-content', 'appearance-tab', 'appearance-content', 'info-tab', 'info-content'));
document.getElementById('appearance-tab').addEventListener('click', () => switchTab('appearance-tab', 'appearance-content', 'proxy-tab', 'proxy-content', 'cloak-tab', 'cloak-content', 'info-tab', 'info-content'));
document.getElementById('info-tab').addEventListener('click', () => switchTab('info-tab', 'info-content', 'proxy-tab', 'proxy-content', 'cloak-tab', 'cloak-content', 'appearance-tab', 'appearance-content'));
document.querySelectorAll('.tab-button').forEach(btn => {
btn.addEventListener('click', function() {
const icon = this.querySelector('i');
if (!icon.classList.contains('fa-bounce')) {
icon.classList.add('fa-bounce');
setTimeout(() => icon.classList.remove('fa-bounce'), 750);
}
});
});
navbarToggle.addEventListener('change', function() {
localStorage.setItem('navbarToggled', this.checked.toString());
showToast(this.checked ? 'success' : 'error', `Navigation Bar ${this.checked ? 'enabled' : 'disabled'}`);
if (window.APP && typeof window.APP.updateNavbarDisplay === 'function') {
window.APP.updateNavbarDisplay();
}
});
initializeInfo();
});

View File

@ -1,109 +1,147 @@
(function () {
document.addEventListener('DOMContentLoaded', function () {
function getSearchInputs() {
return [
document.getElementById('searchInput'),
document.getElementById('searchInputt'),
document.getElementById('gameSearchInput'),
document.getElementById('appSearchInput')
].filter(Boolean);
(function(){
document.addEventListener('DOMContentLoaded', function(){
const indicators = document.querySelectorAll('.shortcut-indicator, .shortcut-indicator-2, .shortcut-indicator-3, .shortcut-indicator-4');
const arrowIndicators = document.querySelectorAll('.shortcut-indicator, .shortcut-indicator-2');
indicators.forEach(el => {
if (!el.dataset.original) el.dataset.original = el.innerHTML;
});
function getSearchInputs(){
return [
document.getElementById('searchInput'),
document.getElementById('searchInputt'),
document.getElementById('gameSearchInput'),
document.getElementById('shortcutSearchInput')
].filter(Boolean);
}
function isVisible(el){
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
}
function focusFirstVisibleInput(){
const inputs = getSearchInputs();
for (let inp of inputs) {
if (isVisible(inp)) {
inp.focus();
return inp;
}
}
function isVisible(el) {
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
if (inputs[0]) {
inputs[0].focus();
return inputs[0];
}
return null;
}
function focusFirstVisibleInput() {
const inputs = getSearchInputs();
for (const input of inputs) {
if (isVisible(input)) {
input.focus();
return;
}
}
if (inputs.length) {
inputs[0].focus();
}
let arrowMode = false;
function updateIndicatorState(){
const hasText = getSearchInputs().some(i => i.value.trim() !== '');
if (hasText === arrowMode) return;
arrowMode = hasText;
arrowIndicators.forEach(ind => {
ind.classList.remove('fadeIn');
ind.classList.add('fadeOut');
setTimeout(() => {
if (hasText) {
ind.innerHTML = '<i class="fa-solid fa-arrow-right"></i>';
ind.classList.add('arrow-mode');
} else {
ind.innerHTML = ind.dataset.original;
ind.classList.remove('arrow-mode');
}
ind.classList.remove('fadeOut');
ind.classList.add('fadeIn');
}, 100);
});
}
function triggerSubmit(input){
const query = input.value.trim();
if (!query) {
showToast('Please enter something in the Search Bar.','error','warning');
return;
}
if (window.APP && typeof APP.handleSearch === 'function') {
APP.handleSearch(query);
if (input.id === 'searchInput') input.value = '';
}
}
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') {
const inputs = getSearchInputs();
const active = document.activeElement;
if (inputs.includes(active)) {
active.blur();
e.preventDefault();
return;
}
}
function handleIndicatorAction(){
const inputs = getSearchInputs().filter(isVisible);
const active = document.activeElement;
if (inputs.includes(active) && active.value.trim()) {
triggerSubmit(active);
return;
}
const withText = inputs.find(i => i.value.trim());
if (withText) {
triggerSubmit(withText);
return;
}
focusFirstVisibleInput();
}
if (e.ctrlKey && e.key.toLowerCase() === 's') {
e.preventDefault();
focusFirstVisibleInput();
}
});
updateIndicatorState();
getSearchInputs().forEach(i => i.addEventListener('input', updateIndicatorState));
document.querySelectorAll(
'.shortcut-indicator, .shortcut-indicator-2, .shortcut-indicator-3, .shortcut-indicator-4'
).forEach(function (el) {
el.addEventListener('click', function (e) {
e.preventDefault();
focusFirstVisibleInput();
});
});
document.addEventListener('keydown', e => {
if (e.key === 'Escape') {
const act = document.activeElement;
if (getSearchInputs().includes(act)) {
act.blur();
e.preventDefault();
}
}
if (e.ctrlKey && e.key.toLowerCase() === 's') {
e.preventDefault();
focusFirstVisibleInput();
}
});
document.body.addEventListener('click', function (e) {
if (
e.target.classList.contains('shortcut-indicator') ||
e.target.classList.contains('shortcut-indicator-2') ||
e.target.classList.contains('shortcut-indicator-3') ||
e.target.classList.contains('shortcut-indicator-4')
) {
e.preventDefault();
focusFirstVisibleInput();
}
});
document.body.addEventListener('click', e => {
const ind = e.target.closest('.shortcut-indicator, .shortcut-indicator-2, .shortcut-indicator-3, .shortcut-indicator-4');
if (!ind) return;
e.preventDefault();
if (ind.classList.contains('arrow-mode')) {
handleIndicatorAction();
} else {
focusFirstVisibleInput();
}
});
const coolIframe = document.getElementById('cool-iframe');
if (coolIframe) {
coolIframe.addEventListener('load', function () {
const doc = coolIframe.contentWindow.document;
doc.addEventListener('keydown', function (e) {
if (e.key === 'Escape') {
if (doc.activeElement && doc.activeElement.blur) {
doc.activeElement.blur();
e.preventDefault();
return;
}
}
if (e.ctrlKey && e.key.toLowerCase() === 's') {
e.preventDefault();
document.dispatchEvent(new KeyboardEvent('keydown', {
key: 's',
ctrlKey: true
}));
}
const coolIframe = document.getElementById('cool-iframe');
if (coolIframe){
coolIframe.addEventListener('load', () => {
const doc = coolIframe.contentWindow.document;
doc.addEventListener('keydown', innerE => {
if (innerE.key === 'Escape') {
if (doc.activeElement.blur) doc.activeElement.blur();
innerE.preventDefault();
}
if (innerE.ctrlKey && innerE.key.toLowerCase() === 's') {
innerE.preventDefault();
document.dispatchEvent(new KeyboardEvent('keydown', { key: 's', ctrlKey: true, bubbles: true }));
}
});
doc.querySelectorAll('.shortcut-indicator, .shortcut-indicator-2, .shortcut-indicator-3, .shortcut-indicator-4')
.forEach(el => {
el.addEventListener('click', ev => {
ev.preventDefault();
window.parent.postMessage({ type: 'iframe-focus-search' }, '*');
});
doc.querySelectorAll(
'.shortcut-indicator, .shortcut-indicator-2, .shortcut-indicator-3, .shortcut-indicator-4'
).forEach(function (iframeEl) {
iframeEl.addEventListener('click', function (e) {
e.preventDefault();
window.parent.postMessage({
type: 'iframe-focus-search'
}, '*');
});
});
});
}
window.addEventListener('message', function (event) {
const msg = event.data;
if (msg.type === 'iframe-focus-search') {
focusFirstVisibleInput();
}
});
});
});
}
window.addEventListener('message', msgEvt => {
if (msgEvt.data?.type === 'iframe-focus-search'){
const inp = focusFirstVisibleInput();
if (inp && inp.value.trim()) triggerSubmit(inp);
}
});
});
})();

59
public/assets/js/wv.js Normal file
View File

@ -0,0 +1,59 @@
(async()=>{
const storageKey = 'wv-verified';
const last = localStorage.getItem(storageKey);
if(last && Date.now() - last < 2592000000) return;
const style = document.createElement('style');
style.textContent = `
:root{--bg:#000;--card:rgba(0,0,0,0.85);--accent:#fff;--radius:12px;--trans:.3s}
#wv-overlay{position:fixed;inset:0!important;pointer-events:auto;user-select:none;background:var(--bg);display:flex;align-items:center;justify-content:center;font-family:system-ui;z-index:2147483647!important;opacity:1;transition:opacity .4s}
#wv-card{background:var(--card);backdrop-filter:blur(12px);border-radius:var(--radius);padding:32px;width:320px;text-align:center;color:var(--accent)}
#wv-progress{width:100%;height:6px;background:#333;border-radius:var(--radius);overflow:hidden;margin:16px 0}
#wv-bar{width:0;height:100%;background:var(--accent);transition:width var(--trans)}
#wv-info{font-size:.95rem;opacity:.8}
#wv-complete{display:none;}
#wv-complete.show{display:block;}
`;
document.head.appendChild(style);
const overlay = document.createElement('div'); overlay.id='wv-overlay';
overlay.innerHTML = `
<div id="wv-card">
<h2><i class="fas fa-shield-alt"></i> Verifying Browser</h2>
<div id="wv-progress"><div id="wv-bar"></div></div>
<div id="wv-info"></div>
</div>
<div id="wv-complete"><h2><i class="fas fa-check-circle"></i> Success!</h2><p>You May Continue.</p></div>
`;
document.body.appendChild(overlay);
const info = document.getElementById('wv-info');
const bar = document.getElementById('wv-bar');
const tests = [
{msg:'Automation',pass:!navigator.webdriver},
{msg:'Headless',pass:!/headless|phantomjs|puppeteer|selenium/i.test(navigator.userAgent)},
{msg:'Languages',pass:Array.isArray(navigator.languages) && navigator.languages.length>0},
{msg:'Plugins',pass:navigator.plugins.length>0},
{msg:'WebGL',pass:(()=>{try{const c=document.createElement('canvas');const g=c.getContext('webgl')||c.getContext('experimental-webgl');return!!g;}catch{return false;}})()}
];
let failures = [];
for(let i=0;i<tests.length;i++){
const t=tests[i];
info.textContent = `${t.msg}...`;
if(!t.pass) failures.push(t.msg);
bar.style.width = `${((i+1)/tests.length)*100}%`;
await new Promise(r=>setTimeout(r,200));
}
if(failures.length===0){
localStorage.setItem(storageKey, Date.now());
document.getElementById('wv-card').style.display='none';
const done = document.getElementById('wv-complete'); done.classList.add('show');
setTimeout(()=>overlay.style.opacity='0',500);
setTimeout(()=>overlay.remove(),800);
} else {
info.innerHTML = `Failed:<br>${failures.map(f=>`${f}`).join('<br>')}`;
bar.style.background='red';
}
})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff