Compare commits
11 Commits
cbdf039eab
...
developmen
| Author | SHA1 | Date | |
|---|---|---|---|
| ea8b1a6642 | |||
| ba9b82cf21 | |||
| 1bb39463e4 | |||
| 31479019f5 | |||
| 36bb49aa80 | |||
| bcda82b065 | |||
| 4e315c993a | |||
| db94e9fe49 | |||
| 9389d0c7e4 | |||
| daf54267b4 | |||
| acd6d2e9e2 |
@ -5,3 +5,7 @@ ANNOUNCEMENT_KEY=text.
|
||||
GROQ_API_KEY=["groq_api"]
|
||||
NTFY_ALERT=ntfy_channel
|
||||
DATA_PATH=where_to_store_data
|
||||
NODE_ENV=production
|
||||
DISCORD_AI_WEBHOOK=discord_webhook_url
|
||||
PROCESSING_SERVER=https://git.ceres.rip/selenite/processing
|
||||
PROCESSING_SERVER_SECRET=secret
|
||||
@ -1,3 +1,3 @@
|
||||
import { accs, friends } from "../database.js";
|
||||
// import { accs, friends } from "../database.js";
|
||||
|
||||
export { };
|
||||
153
accounts/music.js
Normal file
153
accounts/music.js
Normal file
@ -0,0 +1,153 @@
|
||||
import Soundcloud from 'lucida/streamers/soundcloud/main.js'
|
||||
let clientId = process.env.SOUNDCLOUD_CLIENT_ID;
|
||||
|
||||
let sc = new Soundcloud({
|
||||
// oauthToken: clientId
|
||||
})
|
||||
|
||||
async function search(query) {
|
||||
let data = sc.search(query);
|
||||
return data;
|
||||
}
|
||||
// so um fuck lucida
|
||||
// based on https://github.com/imputnet/cobalt/blob/58ea4aed01383ead74d5e32e75335eddc2f015be/api/src/processing/services/soundcloud.js
|
||||
|
||||
const cachedID = {
|
||||
version: '',
|
||||
id: ''
|
||||
}
|
||||
|
||||
async function findClientID() {
|
||||
try {
|
||||
const sc = await fetch('https://soundcloud.com/').then(r => r.text()).catch(() => {});
|
||||
const scVersion = String(sc.match(/<script>window\.__sc_version="[0-9]{10}"<\/script>/)[0].match(/[0-9]{10}/));
|
||||
|
||||
if (cachedID.version === scVersion) {
|
||||
return cachedID.id;
|
||||
}
|
||||
|
||||
const scripts = sc.matchAll(/<script.+src="(.+)">/g);
|
||||
|
||||
let clientid;
|
||||
for (let script of scripts) {
|
||||
const url = script[1];
|
||||
|
||||
if (!url?.startsWith('https://a-v2.sndcdn.com/')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scrf = await fetch(url).then(r => r.text()).catch(() => {});
|
||||
const id = scrf.match(/\("client_id=[A-Za-z0-9]{32}"\)/);
|
||||
|
||||
if (id && typeof id[0] === 'string') {
|
||||
clientid = id[0].match(/[A-Za-z0-9]{32}/)[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
cachedID.version = scVersion;
|
||||
cachedID.id = clientid;
|
||||
|
||||
return clientid;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const findBestForPreset = (transcodings, preset) => {
|
||||
let inferior;
|
||||
for (const entry of transcodings) {
|
||||
const protocol = entry?.format?.protocol;
|
||||
|
||||
if (entry.snipped || protocol?.includes('encrypted')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry?.preset?.startsWith(`${preset}_`)) {
|
||||
if (protocol === 'progressive') {
|
||||
return entry;
|
||||
}
|
||||
|
||||
inferior = entry;
|
||||
}
|
||||
}
|
||||
|
||||
return inferior;
|
||||
}
|
||||
async function download(obj) {
|
||||
const clientId = await findClientID();
|
||||
if (!clientId) return { error: "fetch.fail" };
|
||||
|
||||
let link = obj;
|
||||
|
||||
const resolveURL = new URL("https://api-v2.soundcloud.com/resolve");
|
||||
resolveURL.searchParams.set("url", link);
|
||||
resolveURL.searchParams.set("client_id", clientId);
|
||||
|
||||
const json = await fetch(resolveURL).then(r => r.json()).catch(() => {});
|
||||
if (!json) return { error: "fetch.fail" };
|
||||
|
||||
if (json.duration > 60 * 30 * 1000) {
|
||||
return { error: "content.too_long" };
|
||||
}
|
||||
|
||||
if (json.policy === "BLOCK") {
|
||||
return { error: "content.region" };
|
||||
}
|
||||
|
||||
if (json.policy === "SNIP") {
|
||||
return { error: "content.paid" };
|
||||
}
|
||||
|
||||
if (!json.media?.transcodings || !json.media?.transcodings.length === 0) {
|
||||
return { error: "fetch.empty" };
|
||||
}
|
||||
|
||||
let bestAudio = "opus",
|
||||
selectedStream = findBestForPreset(json.media.transcodings, "opus");
|
||||
|
||||
const mp3Media = findBestForPreset(json.media.transcodings, "mp3");
|
||||
|
||||
// use mp3 if present if user prefers it or if opus isn't available
|
||||
if (mp3Media && (obj.format === "mp3" || !selectedStream)) {
|
||||
selectedStream = mp3Media;
|
||||
bestAudio = "mp3"
|
||||
}
|
||||
|
||||
if (!selectedStream) {
|
||||
return { error: "fetch.empty" };
|
||||
}
|
||||
|
||||
const fileUrl = new URL(selectedStream.url);
|
||||
fileUrl.searchParams.set("client_id", clientId);
|
||||
fileUrl.searchParams.set("track_authorization", json.track_authorization);
|
||||
|
||||
const file = await fetch(fileUrl)
|
||||
.then(async r => new URL((await r.json()).url))
|
||||
.catch(() => {});
|
||||
|
||||
if (!file) return { error: "fetch.empty" };
|
||||
|
||||
const artist = json.user?.username?.trim();
|
||||
const fileMetadata = {
|
||||
title: json.title?.trim(),
|
||||
album: json.publisher_metadata?.album_title?.trim(),
|
||||
artist,
|
||||
album_artist: artist,
|
||||
composer: json.publisher_metadata?.writer_composer?.trim(),
|
||||
genre: json.genre?.trim(),
|
||||
date: json.display_date?.trim().slice(0, 10),
|
||||
copyright: json.license?.trim(),
|
||||
}
|
||||
|
||||
return {
|
||||
urls: file.toString(),
|
||||
filenameAttributes: {
|
||||
service: "soundcloud",
|
||||
id: json.id,
|
||||
...fileMetadata
|
||||
},
|
||||
bestAudio,
|
||||
fileMetadata,
|
||||
isHLS: file.pathname.endsWith('.m3u8'),
|
||||
}
|
||||
}
|
||||
|
||||
export { search, download };
|
||||
@ -4,9 +4,11 @@ import sanitizeHtml from "sanitize-html";
|
||||
import sharp from "sharp";
|
||||
import { accs } from "../database.js";
|
||||
import { getUserFromCookie, isBanned, decryptCookie, verifyCookie } from "./manage.js";
|
||||
import { download } from "./music.js";
|
||||
|
||||
import dayjs from "dayjs";
|
||||
import relativeTime from "dayjs/plugin/relativeTime.js";
|
||||
import { error } from "node:console";
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
const sanitizeConfig = {
|
||||
@ -193,21 +195,62 @@ async function editProfile(body, token, admin) {
|
||||
let fileType = (await fileTypeFromBuffer(pfp))["ext"];
|
||||
if (["png", "jpg", "gif", "avif", "webp", "tiff"].includes(fileType)) {
|
||||
let url;
|
||||
let dir = `${process.env.DATA_PATH}/data/${existingAccount.id}/`;
|
||||
let dir = `${process.env.DATA_PATH}/data/${userData.id}/`;
|
||||
let uuid = crypto.randomUUID();
|
||||
let path = `${process.env.DATA_PATH}/data/${existingAccount.id}/${uuid}.webp`;
|
||||
url = `/data/${existingAccount.id}/${uuid}.webp`;
|
||||
let path = `${process.env.DATA_PATH}/data/${userData.id}/${uuid}.webp`;
|
||||
url = `/data/${userData.id}/${uuid}.webp`;
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
fs.writeFileSync(path, "");
|
||||
await sharp(pfp, { animated: fileType == "gif" })
|
||||
.resize({ width: 300, withoutEnlargement: true })
|
||||
.resize({ width: 400, withoutEnlargement: true })
|
||||
.webp({ quality: 70, effort: 4 })
|
||||
.toFile(path);
|
||||
await fs.unlink(`${__dirname}/${existingAccount.pfp_url}`, () => {});
|
||||
await fs.unlink(`${__dirname}/${userData.pfp_url}`, () => {});
|
||||
const updateAccount = accs.query(`UPDATE accounts SET pfp_url = $url WHERE username = $user`)
|
||||
updateAccount.get({ $url: url, $user: user });
|
||||
}
|
||||
}
|
||||
if (body.artist) {
|
||||
let checkStatus = new Request({
|
||||
url: process.env.PROCESSING_SERVER + "/status"
|
||||
});
|
||||
let checkStatusRequest = await fetch(checkStatus);
|
||||
if(checkStatusRequest.status != 200) {
|
||||
return { success: false, err: "processing server is down, try again later"};
|
||||
}
|
||||
let data = await download(body.url);
|
||||
if(data.error) {
|
||||
if(data.error == "content.too_long") {
|
||||
return { success: false, err: "the song was too long, pick something shorter!"};
|
||||
} else if(data.error == "content.region") {
|
||||
return { success: false, err: "the song could not be downloaded due to the region of the server."};
|
||||
} else if(data.error == "content.paid") {
|
||||
return { success: false, err: "the song is go+ only, and we're too poor to pay for that :( pick another song"};
|
||||
} else if(data.error == "fetch.empty") {
|
||||
return { success: false, err: "we could not fetch this song successfully"};
|
||||
} else {
|
||||
return { success: false, err: "an unknown error happened! error code: " + error};
|
||||
}
|
||||
}
|
||||
let streamingURL = data.urls;
|
||||
let request = new Request({
|
||||
url: process.env.PROCESSING_SERVER + "/process",
|
||||
method: "POST",
|
||||
body: JSON.stringify({url: streamingURL}),
|
||||
headers: {
|
||||
"X-Authentication": process.env.PROCESSING_SERVER_SECRET
|
||||
}
|
||||
});
|
||||
let oggFile = await fetch(request);
|
||||
let filePath = `/data/${userData.id}/${crypto.randomUUID()}.ogg`;
|
||||
await Bun.write(process.env.DATA_PATH + filePath, oggFile);
|
||||
const updateAccount = accs.query(`UPDATE accounts SET music = $music WHERE username = $user`)
|
||||
updateAccount.get({ $music: JSON.stringify({
|
||||
path: filePath,
|
||||
name: body.title,
|
||||
artist: body.artist
|
||||
}), $user: user });
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
@ -228,6 +271,7 @@ async function generateAccountPage(name, cookie, admin) {
|
||||
}
|
||||
|
||||
let modifiedHTML = rawProfileHTML;
|
||||
let songData = JSON.parse(userData.music) || false;
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ name }}", sanitizeHtml(userData.name, allowNone));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ join_date }}", dayjs(userData.createdAt).fromNow());
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ about }}", sanitizeHtml(userData.about, sanitizeConfig) || "No about me available..");
|
||||
@ -235,7 +279,15 @@ async function generateAccountPage(name, cookie, admin) {
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ user_pfp }}", userData.pfp_url || "/img/user.svg");
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ custom_css }}", userData.custom_css || "");
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ online_time }}", dayjs(userData.last_login).fromNow());
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ played_games }}", buildGameHTML(userData));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ username }}", sanitizeHtml(userData.username, allowNone));
|
||||
if(songData) {
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ song_title }}", sanitizeHtml(songData.name, allowNone));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ song_artist }}", sanitizeHtml(songData.artist, allowNone));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ song_url }}", sanitizeHtml(songData.path, allowNone));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ is_music }}", "true");
|
||||
} else {
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ is_music }}", "false");
|
||||
}
|
||||
let badges_html = "";
|
||||
|
||||
if (userData.badges !== null) {
|
||||
@ -260,6 +312,7 @@ async function generateAccountPage(name, cookie, admin) {
|
||||
return modified_ban;
|
||||
}
|
||||
let modifiedHTML = rawEditProfileHTML;
|
||||
let songData = JSON.parse(userData.music) || false;
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ name }}", sanitizeHtml(userData.name, sanitizeConfig));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ username }}", userData.username);
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ join_date }}", dayjs(userData.createdAt).fromNow());
|
||||
@ -269,7 +322,17 @@ async function generateAccountPage(name, cookie, admin) {
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ url_gen }}", `https://selenite.cc/u/${userData.username}`);
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ online_time }}", dayjs(userData.last_login).fromNow());
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ css_edit }}", (userData.badges ? userData.badges.length : 0) > 0 ? '<img src="/img/edit.svg" id="edit" />' : "");
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ played_games }}", buildGameHTML(userData));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ staff_buttons }}", await isAdmin(cookie) ? "<a href='/admin'>admin panel</a>" : "");
|
||||
if(songData) {
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ song_title }}", sanitizeHtml(songData.name, allowNone));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ song_artist }}", sanitizeHtml(songData.artist, allowNone));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ song_url }}", sanitizeHtml(songData.path, allowNone));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ is_music }}", "true");
|
||||
} else {
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ is_music }}", "false");
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ song_title }}", "no song selected...");
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ song_artist }}", "");
|
||||
}
|
||||
let badges_html = "";
|
||||
|
||||
if (userData.badges !== null) {
|
||||
@ -282,43 +345,7 @@ async function generateAccountPage(name, cookie, admin) {
|
||||
return modifiedHTML;
|
||||
}
|
||||
}
|
||||
function buildGameHTML(existingAccount) {
|
||||
if (existingAccount.playedgames) {
|
||||
let games = JSON.parse(existingAccount.playedgames);
|
||||
let sortedGames = Object.keys(games).sort((a, b) => games[b] - games[a]);
|
||||
let return_data = [];
|
||||
if (Object.keys(games).length < 10) {
|
||||
for (let i = 0; i < sortedGames.length; i++) {
|
||||
try {
|
||||
let origin = gamesExceptions[sortedGames[i]] ? "sppa" : "semag";
|
||||
sortedGames[i] = gamesExceptions[sortedGames[i]] ? gamesExceptions[sortedGames[i]] : sortedGames[i];
|
||||
return_data[i] = { name: profileReadyJSON[sortedGames[i]].name, image: profileReadyJSON[sortedGames[i]].image, path: sortedGames[i], origin: origin, valid: true };
|
||||
} catch (e) {
|
||||
return_data[i] = { valid: false };
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
try {
|
||||
let origin = gamesExceptions[sortedGames[i]] ? "sppa" : "semag";
|
||||
sortedGames[i] = gamesExceptions[sortedGames[i]] ? gamesExceptions[sortedGames[i]] : sortedGames[i];
|
||||
return_data[i] = { name: profileReadyJSON[sortedGames[i]].name, image: profileReadyJSON[sortedGames[i]].image, path: sortedGames[i], origin: origin, valid: true };
|
||||
} catch (e) {
|
||||
return_data[i] = { valid: false };
|
||||
}
|
||||
}
|
||||
}
|
||||
let return_html = "";
|
||||
for (let i = 0; i < Object.keys(return_data).length; i++) {
|
||||
if (return_data[i].valid) {
|
||||
return_html += `<div class="played-game"><img src="/${return_data[i].origin}/${return_data[i].path}/${return_data[i].image}"/><p>${return_data[i].name}</p></div>`;
|
||||
}
|
||||
}
|
||||
return return_html;
|
||||
} else {
|
||||
return "<h3>Play some games to view things appear here!</h3>";
|
||||
}
|
||||
}
|
||||
|
||||
async function getUsers(page, search) {
|
||||
let amount = 12;
|
||||
if (!page) {
|
||||
|
||||
23
ai.js
23
ai.js
@ -1,6 +1,21 @@
|
||||
import OpenAI from "openai";
|
||||
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
|
||||
import { generateText } from 'ai';
|
||||
|
||||
const client = new OpenAI({
|
||||
apiKey: process.env.GROQ_API_KEY,
|
||||
baseURL: "https://api.groq.com/openai/v1"
|
||||
const model = createOpenAICompatible({
|
||||
name: 'model',
|
||||
apiKey: process.env.OPENAI_API_KEY,
|
||||
baseURL: process.env.OPENAI_BASE_URL,
|
||||
includeUsage: true, // Include usage information in streaming responses
|
||||
});
|
||||
|
||||
async function callAI(chatHistory) {
|
||||
console.log("call ai called")
|
||||
let { text } = await generateText({
|
||||
model: model(process.env.OPENAI_MODEL),
|
||||
system: "You are Zen, a helpful AI assistant built by Selenite. Your response should be accurate without hallucination." +
|
||||
"Over the course of conversation, adapt to the user's tone and preferences. Try to match the user's vibe, tone, and generally how they are speaking. You want the conversation to feel natural. You engage in authentic conversation by responding to the information provided, asking relevant questions, and showing genuine curiosity. If natural, use information you know about the user to personalize your responses and ask a follow up question.",
|
||||
messages: chatHistory
|
||||
});
|
||||
console.log(text);
|
||||
}
|
||||
export { callAI };
|
||||
417
bun.lock
Normal file
417
bun.lock
Normal file
@ -0,0 +1,417 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "rewrite",
|
||||
"dependencies": {
|
||||
"@ai-sdk/openai-compatible": "^1.0.22",
|
||||
"ai": "^5.0.68",
|
||||
"axios": "^1.12.2",
|
||||
"body-parser": "^2.2.0",
|
||||
"chalk": "^5.6.2",
|
||||
"compression": "^1.8.1",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"dayjs": "^1.11.18",
|
||||
"dotenv": "^16.6.1",
|
||||
"express": "^5.1.0",
|
||||
"file-type": "^19.6.0",
|
||||
"lucida": "^2.0.0-54",
|
||||
"mime-types": "^2.1.35",
|
||||
"rword": "^3.2.1",
|
||||
"sanitize-html": "^2.17.0",
|
||||
"sharp": "^0.33.5",
|
||||
"ws": "^8.18.3",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@ai-sdk/gateway": ["@ai-sdk/gateway@1.0.39", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.12", "@vercel/oidc": "3.0.2" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ijYCKG2sbn2RBVfIgaXNXvzHAf2HpFXxQODtjMI+T7Z4CLryflytchsZZ9qrGtsjiQVopKOV6m6kj4lq5fnbsg=="],
|
||||
|
||||
"@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.22", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.12" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Q+lwBIeMprc/iM+vg1yGjvzRrp74l316wDpqWdbmd4VXXlllblzGsUgBLTeKvcEapFTgqk0FRETvSb58Y6dsfA=="],
|
||||
|
||||
"@ai-sdk/provider": ["@ai-sdk/provider@2.0.0", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA=="],
|
||||
|
||||
"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.12", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.5" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ZtbdvYxdMoria+2SlNarEk6Hlgyf+zzcznlD55EAl+7VZvJaSg2sqPvwArY7L6TfDEDJsnCq0fdhBSkYo0Xqdg=="],
|
||||
|
||||
"@borewit/text-codec": ["@borewit/text-codec@0.1.1", "", {}, "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA=="],
|
||||
|
||||
"@emnapi/runtime": ["@emnapi/runtime@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ=="],
|
||||
|
||||
"@fastify/busboy": ["@fastify/busboy@2.1.1", "", {}, "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="],
|
||||
|
||||
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="],
|
||||
|
||||
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="],
|
||||
|
||||
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.0.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg=="],
|
||||
|
||||
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.0.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ=="],
|
||||
|
||||
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.0.5", "", { "os": "linux", "cpu": "arm" }, "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g=="],
|
||||
|
||||
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA=="],
|
||||
|
||||
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.0.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA=="],
|
||||
|
||||
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw=="],
|
||||
|
||||
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA=="],
|
||||
|
||||
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw=="],
|
||||
|
||||
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.0.5" }, "os": "linux", "cpu": "arm" }, "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ=="],
|
||||
|
||||
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.0.4" }, "os": "linux", "cpu": "arm64" }, "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA=="],
|
||||
|
||||
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.0.4" }, "os": "linux", "cpu": "s390x" }, "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q=="],
|
||||
|
||||
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.0.4" }, "os": "linux", "cpu": "x64" }, "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA=="],
|
||||
|
||||
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" }, "os": "linux", "cpu": "arm64" }, "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g=="],
|
||||
|
||||
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.0.4" }, "os": "linux", "cpu": "x64" }, "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw=="],
|
||||
|
||||
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.33.5", "", { "dependencies": { "@emnapi/runtime": "^1.2.0" }, "cpu": "none" }, "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg=="],
|
||||
|
||||
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.33.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ=="],
|
||||
|
||||
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.33.5", "", { "os": "win32", "cpu": "x64" }, "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="],
|
||||
|
||||
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
|
||||
|
||||
"@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="],
|
||||
|
||||
"@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="],
|
||||
|
||||
"@protobufjs/codegen": ["@protobufjs/codegen@2.0.4", "", {}, "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="],
|
||||
|
||||
"@protobufjs/eventemitter": ["@protobufjs/eventemitter@1.1.0", "", {}, "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="],
|
||||
|
||||
"@protobufjs/fetch": ["@protobufjs/fetch@1.1.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" } }, "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ=="],
|
||||
|
||||
"@protobufjs/float": ["@protobufjs/float@1.0.2", "", {}, "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="],
|
||||
|
||||
"@protobufjs/inquire": ["@protobufjs/inquire@1.1.0", "", {}, "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="],
|
||||
|
||||
"@protobufjs/path": ["@protobufjs/path@1.1.2", "", {}, "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="],
|
||||
|
||||
"@protobufjs/pool": ["@protobufjs/pool@1.1.0", "", {}, "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="],
|
||||
|
||||
"@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="],
|
||||
|
||||
"@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="],
|
||||
|
||||
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
|
||||
|
||||
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
||||
|
||||
"@types/node": ["@types/node@20.14.8", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA=="],
|
||||
|
||||
"@vercel/oidc": ["@vercel/oidc@3.0.2", "", {}, "sha512-JekxQ0RApo4gS4un/iMGsIL1/k4KUBe3HmnGcDvzHuFBdQdudEJgTqcsJC7y6Ul4Yw5CeykgvQbX2XeEJd0+DA=="],
|
||||
|
||||
"accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
|
||||
|
||||
"ai": ["ai@5.0.68", "", { "dependencies": { "@ai-sdk/gateway": "1.0.39", "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.12", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-SB6r+4TkKVlSg2ozGBSfuf6Is5hrcX/bpGBzOoyHIN3b4ILGhaly0IHEvP8+3GGIHXqtkPVEUmR6V05jKdjNlg=="],
|
||||
|
||||
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
||||
|
||||
"axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="],
|
||||
|
||||
"blowfish-cbc": ["blowfish-cbc@1.0.1", "", { "dependencies": { "node-addon-api": "^8.1.0" } }, "sha512-o1JN6g6+ATW/4k7q1BZzy14VqLxwYa1mCii47qT4kmAaYD0NAfdM6/pz6uizbhTra/xunsPQI27LZt08OQS4sA=="],
|
||||
|
||||
"body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
|
||||
|
||||
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
|
||||
|
||||
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
||||
|
||||
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
|
||||
|
||||
"chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
||||
|
||||
"color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="],
|
||||
|
||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
|
||||
"color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="],
|
||||
|
||||
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
|
||||
|
||||
"compressible": ["compressible@2.0.18", "", { "dependencies": { "mime-db": ">= 1.43.0 < 2" } }, "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg=="],
|
||||
|
||||
"compression": ["compression@1.8.1", "", { "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", "debug": "2.6.9", "negotiator": "~0.6.4", "on-headers": "~1.1.0", "safe-buffer": "5.2.1", "vary": "~1.1.2" } }, "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w=="],
|
||||
|
||||
"content-disposition": ["content-disposition@1.0.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg=="],
|
||||
|
||||
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
|
||||
|
||||
"cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
|
||||
|
||||
"cookie-parser": ["cookie-parser@1.4.7", "", { "dependencies": { "cookie": "0.7.2", "cookie-signature": "1.0.6" } }, "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw=="],
|
||||
|
||||
"cookie-signature": ["cookie-signature@1.0.6", "", {}, "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="],
|
||||
|
||||
"cors": ["cors@2.8.5", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g=="],
|
||||
|
||||
"dayjs": ["dayjs@1.11.18", "", {}, "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA=="],
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
||||
|
||||
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
||||
|
||||
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
||||
|
||||
"destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="],
|
||||
|
||||
"detect-libc": ["detect-libc@2.0.3", "", {}, "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw=="],
|
||||
|
||||
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
|
||||
|
||||
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
|
||||
|
||||
"domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||
|
||||
"domutils": ["domutils@3.1.0", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA=="],
|
||||
|
||||
"dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
|
||||
|
||||
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
||||
|
||||
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
|
||||
|
||||
"encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
|
||||
|
||||
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
||||
|
||||
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
||||
|
||||
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
|
||||
|
||||
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
|
||||
|
||||
"escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
|
||||
|
||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||
|
||||
"etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
|
||||
|
||||
"eventsource-parser": ["eventsource-parser@3.0.6", "", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="],
|
||||
|
||||
"express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="],
|
||||
|
||||
"file-type": ["file-type@19.6.0", "", { "dependencies": { "get-stream": "^9.0.1", "strtok3": "^9.0.1", "token-types": "^6.0.0", "uint8array-extras": "^1.3.0" } }, "sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ=="],
|
||||
|
||||
"finalhandler": ["finalhandler@2.1.0", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q=="],
|
||||
|
||||
"follow-redirects": ["follow-redirects@1.15.6", "", {}, "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="],
|
||||
|
||||
"form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="],
|
||||
|
||||
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
|
||||
|
||||
"fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
|
||||
|
||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||
|
||||
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
||||
|
||||
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
||||
|
||||
"get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="],
|
||||
|
||||
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
||||
|
||||
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
|
||||
|
||||
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
|
||||
|
||||
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
||||
|
||||
"htmlparser2": ["htmlparser2@8.0.2", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "entities": "^4.4.0" } }, "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA=="],
|
||||
|
||||
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
|
||||
|
||||
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||
|
||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||
|
||||
"image-size": ["image-size@1.2.1", "", { "dependencies": { "queue": "6.0.2" }, "bin": "bin/image-size.js" }, "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw=="],
|
||||
|
||||
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||
|
||||
"ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
|
||||
|
||||
"is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="],
|
||||
|
||||
"is-plain-object": ["is-plain-object@5.0.0", "", {}, "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="],
|
||||
|
||||
"is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
|
||||
|
||||
"is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="],
|
||||
|
||||
"json-schema": ["json-schema@0.4.0", "", {}, "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="],
|
||||
|
||||
"librespot": ["librespot@0.2.22", "", { "dependencies": { "protobufjs": "^7.2.5", "undici": "^5.27.0" } }, "sha512-szLknWSrgF+mRuypNXQTmdq8PGGhgPRAazm8sJmD8wiCAbtO9LYHihZhQcRmCzmVz818sRHZM/BU6K6XslXSHQ=="],
|
||||
|
||||
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
|
||||
|
||||
"lucida": ["lucida@2.0.0-54", "", { "dependencies": { "blowfish-cbc": "^1.0.1", "image-size": "^1.1.1", "librespot": "^0.2.21", "undici": "^6.19.4", "xmldom-qsa": "^1.1.3" } }, "sha512-3Y24WkCI1Ks6EjOAElYAeYXkxT/HtunEW+SnhDKFb681B/QEMhS/EzLzFi8D5l95/pOVODUZQMMxYNKmMMC1fQ=="],
|
||||
|
||||
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||
|
||||
"media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
|
||||
|
||||
"merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="],
|
||||
|
||||
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
||||
|
||||
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"nanoid": ["nanoid@3.3.8", "", { "bin": "bin/nanoid.cjs" }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="],
|
||||
|
||||
"negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="],
|
||||
|
||||
"node-addon-api": ["node-addon-api@8.4.0", "", {}, "sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg=="],
|
||||
|
||||
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
||||
|
||||
"object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
|
||||
|
||||
"on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
|
||||
|
||||
"on-headers": ["on-headers@1.1.0", "", {}, "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A=="],
|
||||
|
||||
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
|
||||
|
||||
"parse-srcset": ["parse-srcset@1.0.2", "", {}, "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q=="],
|
||||
|
||||
"parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
|
||||
|
||||
"path-to-regexp": ["path-to-regexp@8.1.0", "", {}, "sha512-Bqn3vc8CMHty6zuD+tG23s6v2kwxslHEhTj4eYaVKGIEB+YX/2wd0/rgXLFD9G9id9KCtbVy/3ZgmvZjpa0UdQ=="],
|
||||
|
||||
"peek-readable": ["peek-readable@5.4.2", "", {}, "sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg=="],
|
||||
|
||||
"picocolors": ["picocolors@1.0.1", "", {}, "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="],
|
||||
|
||||
"postcss": ["postcss@8.4.39", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", "source-map-js": "^1.2.0" } }, "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw=="],
|
||||
|
||||
"protobufjs": ["protobufjs@7.5.3", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw=="],
|
||||
|
||||
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
|
||||
|
||||
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
|
||||
|
||||
"qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
|
||||
|
||||
"queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "~2.0.3" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="],
|
||||
|
||||
"range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
|
||||
|
||||
"raw-body": ["raw-body@3.0.0", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.6.3", "unpipe": "1.0.0" } }, "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g=="],
|
||||
|
||||
"router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
|
||||
|
||||
"rword": ["rword@3.2.1", "", {}, "sha512-E1PhzHCM8enXQJoVv0ZKvqMNojkbRqMsv66pD0P4mRl1imb+0g+3Q19CtXobZIqOhi3zNZi1br//U87vc/s6OA=="],
|
||||
|
||||
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||
|
||||
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||
|
||||
"sanitize-html": ["sanitize-html@2.17.0", "", { "dependencies": { "deepmerge": "^4.2.2", "escape-string-regexp": "^4.0.0", "htmlparser2": "^8.0.0", "is-plain-object": "^5.0.0", "parse-srcset": "^1.0.2", "postcss": "^8.3.11" } }, "sha512-dLAADUSS8rBwhaevT12yCezvioCA+bmUTPH/u57xKPT8d++voeYE6HeluA/bPbQ15TwDBG2ii+QZIEmYx8VdxA=="],
|
||||
|
||||
"semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
||||
|
||||
"send": ["send@1.1.0", "", { "dependencies": { "debug": "^4.3.5", "destroy": "^1.2.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^0.5.2", "http-errors": "^2.0.0", "mime-types": "^2.1.35", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA=="],
|
||||
|
||||
"serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="],
|
||||
|
||||
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
|
||||
|
||||
"sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="],
|
||||
|
||||
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
|
||||
|
||||
"side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
|
||||
|
||||
"side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
|
||||
|
||||
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
|
||||
|
||||
"simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.0", "", {}, "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg=="],
|
||||
|
||||
"statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
|
||||
|
||||
"strtok3": ["strtok3@9.1.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^5.3.1" } }, "sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw=="],
|
||||
|
||||
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
|
||||
|
||||
"token-types": ["token-types@6.1.1", "", { "dependencies": { "@borewit/text-codec": "^0.1.0", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ=="],
|
||||
|
||||
"tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="],
|
||||
|
||||
"type-is": ["type-is@2.0.0", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw=="],
|
||||
|
||||
"uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
|
||||
|
||||
"undici": ["undici@6.21.3", "", {}, "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw=="],
|
||||
|
||||
"undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
|
||||
|
||||
"unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
|
||||
|
||||
"vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
|
||||
|
||||
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
|
||||
|
||||
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
|
||||
|
||||
"xmldom-qsa": ["xmldom-qsa@1.1.3", "", {}, "sha512-IJBOczBpAYrIBJFFsmCBwfBhwe4zdMR3Xz0ZBX0OFtgO49rLy/BWbhkegOwsthdBWb1gUtFK6ZZnGdT8ZqPRBA=="],
|
||||
|
||||
"zod": ["zod@4.1.12", "", {}, "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ=="],
|
||||
|
||||
"accepts/mime-types": ["mime-types@3.0.0", "", { "dependencies": { "mime-db": "^1.53.0" } }, "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w=="],
|
||||
|
||||
"accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
|
||||
|
||||
"compression/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||
|
||||
"express/cookie-signature": ["cookie-signature@1.2.1", "", {}, "sha512-78KWk9T26NhzXtuL26cIJ8/qNHANyJ/ZYrmEXFzUmhZdjpBv+DlWlOANRTGBt48YcyslsLrj0bMLFTmXvLRCOw=="],
|
||||
|
||||
"express/mime-types": ["mime-types@3.0.0", "", { "dependencies": { "mime-db": "^1.53.0" } }, "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w=="],
|
||||
|
||||
"express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
|
||||
|
||||
"librespot/undici": ["undici@5.29.0", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="],
|
||||
|
||||
"send/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
|
||||
|
||||
"send/fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="],
|
||||
|
||||
"serve-static/send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="],
|
||||
|
||||
"type-is/mime-types": ["mime-types@3.0.0", "", { "dependencies": { "mime-db": "^1.53.0" } }, "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w=="],
|
||||
|
||||
"accepts/mime-types/mime-db": ["mime-db@1.53.0", "", {}, "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg=="],
|
||||
|
||||
"compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
||||
|
||||
"express/mime-types/mime-db": ["mime-db@1.53.0", "", {}, "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg=="],
|
||||
|
||||
"serve-static/send/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
|
||||
|
||||
"type-is/mime-types/mime-db": ["mime-db@1.53.0", "", {}, "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg=="],
|
||||
|
||||
"serve-static/send/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
|
||||
}
|
||||
}
|
||||
55
database.js
55
database.js
@ -1,15 +1,50 @@
|
||||
import fs from "bun:fs";
|
||||
import { Database } from "bun:sqlite";
|
||||
|
||||
const accs = new Database(`${process.env.DATA_PATH}/accounts.sqlite`);
|
||||
const infdb = new Database(`${process.env.DATA_PATH}/infinitecraft.sqlite`);
|
||||
const friends = new Database(`${process.env.DATA_PATH}/friends.sqlite`);
|
||||
const polytrack = new Database(`${process.env.DATA_PATH}/polytrack.sqlite`);
|
||||
const ai_chats = new Database(`${process.env.DATA_PATH}/ai_chats.sqlite`);
|
||||
if(!await (Bun.file(process.env.DATA_PATH)).exists()) {
|
||||
fs.mkdirSync(process.env.DATA_PATH, { recursive: true });
|
||||
}
|
||||
|
||||
const accs = new Database(`${process.env.DATA_PATH}/accounts.sqlite`, { create: true });
|
||||
// const infdb = new Database(`${process.env.DATA_PATH}/infinitecraft.sqlite`);
|
||||
// const friends = new Database(`${process.env.DATA_PATH}/friends.sqlite`);
|
||||
// const polytrack = new Database(`${process.env.DATA_PATH}/polytrack.sqlite`);
|
||||
// const ai_chats = new Database(`${process.env.DATA_PATH}/ai_chats.sqlite`);
|
||||
|
||||
infdb.exec("PRAGMA journal_mode = WAL;");
|
||||
accs.exec("PRAGMA journal_mode = WAL;");
|
||||
friends.exec("PRAGMA journal_mode = WAL;");
|
||||
polytrack.exec("PRAGMA journal_mode = WAL;");
|
||||
ai_chats.exec("PRAGMA journal_mode = WAL;");
|
||||
// infdb.exec("PRAGMA journal_mode = WAL;");
|
||||
// friends.exec("PRAGMA journal_mode = WAL;");
|
||||
// polytrack.exec("PRAGMA journal_mode = WAL;");
|
||||
// ai_chats.exec("PRAGMA journal_mode = WAL;");
|
||||
|
||||
export { accs, infdb, friends, polytrack, ai_chats };
|
||||
let accountColumns = [
|
||||
`"id" INTEGER`,
|
||||
`"username" TEXT UNIQUE`,
|
||||
`"name" TEXT`,
|
||||
`"hashed_pass" INTEGER NOT NULL`,
|
||||
`"secret_key" TEXT`,
|
||||
`"about" TEXT`,
|
||||
`"badges" TEXT`,
|
||||
`"last_login" TEXT`,
|
||||
`"type" TEXT`,
|
||||
`"pfp_url" TEXT`,
|
||||
`"createdAt" DATETIME NOT NULL`,
|
||||
`"updatedAt" DATETIME NOT NULL`,
|
||||
`"banned" TEXT`,
|
||||
`"music" TEXT`,
|
||||
`PRIMARY KEY("id")`,
|
||||
];
|
||||
let createAccountQuery = `CREATE TABLE IF NOT EXISTS "accounts" (`
|
||||
accountColumns.forEach((e) => {
|
||||
if(createAccountQuery.length == 39) {
|
||||
createAccountQuery+=`${e}`
|
||||
} else {
|
||||
createAccountQuery+=`,${e}`
|
||||
}
|
||||
});
|
||||
createAccountQuery+=`)`
|
||||
// console.log(createAccountQuery)
|
||||
accs.query(createAccountQuery).run();
|
||||
|
||||
// export { accs, infdb, friends, polytrack, ai_chats };
|
||||
export { accs };
|
||||
143
html/admin.html
143
html/admin.html
@ -5,92 +5,67 @@
|
||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||
|
||||
<!-- initialize externals -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
|
||||
<script src=" https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js "></script>
|
||||
<meta property="og:title" content="Selenite" />
|
||||
<meta property="description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||
<meta content="/favicon.png" property="og:image" />
|
||||
<meta content="#c77dff" data-react-helmet="true" name="theme-color" />
|
||||
<meta name="googlebot" content="index, follow, snippet" />
|
||||
<link rel="canonical" href="https://selenite.cc/" />
|
||||
<meta property="og:description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||
<meta property="og:title" content="Selenite">
|
||||
<meta property="og:type" content="website">
|
||||
|
||||
<!-- initialize my stuff -->
|
||||
<script src="/js/all.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
|
||||
<!-- seo + other things -->
|
||||
<title>Profile</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</head>
|
||||
<alerts> </alerts>
|
||||
<body id="noscroll">
|
||||
<header>
|
||||
<a href="/index.html">Home</a>
|
||||
<a href="/bookmarklets.html">Bookmarklets</a>
|
||||
<a href="/projects.html">Games</a>
|
||||
<a href="/apps.html">Apps</a>
|
||||
<a href="/settings.html">Settings</a>
|
||||
<a id="blank" href="#">Open Blank</a>
|
||||
<a href="/u/" class="usericon"><img src="/img/user.svg" /></a>
|
||||
</header>
|
||||
<script>
|
||||
async function addBadge() {
|
||||
let name = prompt("username");
|
||||
let badge = prompt("badge name");
|
||||
|
||||
let run = await fetch("/api/admin/badge", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
username: name,
|
||||
badge: badge
|
||||
}),
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8",
|
||||
},
|
||||
});
|
||||
alert(JSON.stringify(run));
|
||||
}
|
||||
function announce() {
|
||||
let key = prompt("enter key");
|
||||
let announcement = prompt("enter announcement");
|
||||
socket.send(`${key}.${announcement}`)
|
||||
}
|
||||
async function removeAccount() {
|
||||
let name = prompt("enter username");
|
||||
let run = await fetch("/api/admin/removeAcc", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
username: name
|
||||
}),
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8",
|
||||
},
|
||||
});
|
||||
}
|
||||
async function ban() {
|
||||
let name = prompt("enter username");
|
||||
let reason = prompt("enter reason");
|
||||
let run = await fetch("/api/admin/ban", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
reason: reason,
|
||||
}),
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8",
|
||||
},
|
||||
});
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "Selenite",
|
||||
"alternateName": "selenite.cc",
|
||||
"url": "https://selenite.cc",
|
||||
"logo": "https://selenite.cc/favicon.png",
|
||||
"sameAs": [
|
||||
"https://github.com/selenite-cc",
|
||||
"https://youtube.com/@selenitecc",
|
||||
"https://tiktok.com/@selenitecc",
|
||||
"https://selenite.cc",
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<main>
|
||||
<button onclick="addBadge()">Add a badge</button>
|
||||
<button onclick="announce()">Send announcement</button>
|
||||
<button onclick="removeAccount()">remove account</button>
|
||||
<button onclick="ban()">ban account</button>
|
||||
</main>
|
||||
<footer class="noscroll">
|
||||
<a href="https://gitlab.com/skysthelimit.dev/selenite">Source</a>
|
||||
<a href="https://discord.gg/7jyufnwJNf">Discord</a>
|
||||
<a href="/suggest.html">Suggestions & Bugs</a>
|
||||
<a href="/contact.html">Contact</a>
|
||||
<a href="/support.html">Donate</a>
|
||||
<a href="/about.html">About</a>
|
||||
</footer>
|
||||
|
||||
<!-- initialize my stuff -->
|
||||
<script src="/js/all.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css" />
|
||||
<link rel="stylesheet" href="/css/pages.css" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<!-- seo + other things -->
|
||||
<title>Selenite</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415518411898563" crossorigin="anonymous"></script>
|
||||
<script>
|
||||
function sendAnnouncement() {
|
||||
let title = prompt("title");
|
||||
let message = prompt("message");
|
||||
if(prompt("are you sure (y/N)") == "y") {
|
||||
let cookies = document.cookie.split("; ");
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
if (cookies[i].trim().startsWith("token=")) {
|
||||
let socket = new WebSocket("/socket");
|
||||
socket.addEventListener("open", () => {
|
||||
socket.send(`annc;;${cookies[i].trim().split("=")[1]};;${title};;${message}`);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<alerts> </alerts>
|
||||
<body>
|
||||
<h1 class="title">admin page</h1>
|
||||
<sections>
|
||||
<button onclick="sendAnnouncement()">send announcement</button>
|
||||
</sections>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -4,64 +4,137 @@
|
||||
<!-- initialize theme vars
|
||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||
|
||||
<meta content="{{ name }}" property="og:title" />
|
||||
<meta content="{{ about_none }}" property="og:description" />
|
||||
<meta content="{{ user_pfp }}" property="og:image" />
|
||||
<meta content="#c77dff" data-react-helmet="true" name="theme-color" />
|
||||
<!-- initialize externals -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
|
||||
<script src=" https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js "></script>
|
||||
<meta property="og:title" content="Selenite" />
|
||||
<meta property="description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||
|
||||
<meta content="/favicon.png" property="og:image" />
|
||||
<meta content="#c77dff" data-react-helmet="true" name="theme-color" />
|
||||
<meta name="googlebot" content="index, follow, snippet" />
|
||||
<link rel="canonical" href="https://selenite.cc/" />
|
||||
<meta property="og:description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||
<meta property="og:title" content="Selenite">
|
||||
<meta property="og:type" content="website">
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "Selenite",
|
||||
"alternateName": "selenite.cc",
|
||||
"url": "https://selenite.cc",
|
||||
"logo": "https://selenite.cc/favicon.png",
|
||||
"sameAs": [
|
||||
"https://github.com/selenite-cc",
|
||||
"https://youtube.com/@selenitecc",
|
||||
"https://tiktok.com/@selenitecc",
|
||||
"https://selenite.cc",
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- initialize my stuff -->
|
||||
<script src="/js/all.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css" />
|
||||
<link rel="stylesheet" href="/css/pages.css" />
|
||||
<link rel="stylesheet" href="/css/profile.css" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<!-- seo + other things -->
|
||||
<style>{{ custom_css }}</style>
|
||||
<title>{{ name }}'s Profile | Selenite</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415518411898563" crossorigin="anonymous"></script>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", ()=>{
|
||||
let music = {{ is_music }};
|
||||
let audioObject;
|
||||
if(music) {
|
||||
document.body.classList = "enter-on";
|
||||
let url = "{{ song_url }}";
|
||||
audioObject = new Audio(url);
|
||||
audioObject.addEventListener("loadeddata", () => {
|
||||
document.getElementById("totalLength").innerText = `${Math.floor(audioObject.duration/60)}:${String(Math.floor(audioObject.duration%60)).padStart(2, "0")}`;
|
||||
document.getElementById("playbar").value = 0;
|
||||
})
|
||||
document.getElementById("enter").addEventListener("click", async ()=>{
|
||||
document.getElementById("enter").style.backgroundColor = "#00000000"
|
||||
document.getElementById("enter").style.backdropFilter = "blur(0px)"
|
||||
document.getElementById("enter").style.opacity = "0";
|
||||
setTimeout(() => {
|
||||
audioObject.play();
|
||||
audioObject.loop = true;
|
||||
document.body.classList = "";
|
||||
}, 500)
|
||||
setTimeout( () => {
|
||||
document.getElementById("enter").style.display = "none";
|
||||
}, 950);
|
||||
});
|
||||
} else {
|
||||
document.getElementById("enter").style.display = "none";
|
||||
document.querySelectorAll("section")[0].querySelectorAll(".profile-element")[1].style.display = "none";
|
||||
}
|
||||
document.getElementById("playPause").addEventListener("click", ()=>{
|
||||
if(audioObject.paused) {
|
||||
document.getElementById("playPause").src = "/img/pause.svg";
|
||||
audioObject.play();
|
||||
} else {
|
||||
document.getElementById("playPause").src = "/img/play.svg";
|
||||
audioObject.pause();
|
||||
}
|
||||
});
|
||||
document.getElementById("mute").addEventListener("click", ()=>{
|
||||
if(audioObject.volume == 0) {
|
||||
document.getElementById("mute").src = "/img/volume.svg";
|
||||
audioObject.volume = 1;
|
||||
} else {
|
||||
document.getElementById("mute").src = "/img/muted.svg";
|
||||
audioObject.volume = 0;
|
||||
}
|
||||
});
|
||||
document.getElementById("playbar").addEventListener("input", (e) => {
|
||||
audioObject.currentTime = document.getElementById("playbar").value/1000*audioObject.duration;
|
||||
});
|
||||
audioObject.addEventListener("timeupdate", (e) => {
|
||||
document.getElementById("totalLength").innerText = `${Math.floor(audioObject.duration/60)}:${String(Math.floor(audioObject.duration%60)).padStart(2, "0")}`
|
||||
document.getElementById("curPos").innerText = `${Math.floor(audioObject.currentTime/60)}:${String(Math.floor(audioObject.currentTime%60)).padStart(2, "0")}`
|
||||
document.getElementById("playbar").value = (audioObject.currentTime / audioObject.duration) * 1000;
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<alerts> </alerts>
|
||||
<body class="profile">
|
||||
<header>
|
||||
<a href="/index.html">Home</a>
|
||||
<a href="/bookmarklets.html">Bookmarklets</a>
|
||||
<a href="/projects.html">Games</a>
|
||||
<a href="/apps.html">Apps</a>
|
||||
<a href="/settings.html">Settings</a>
|
||||
<a id="blank" href="#">Open Blank</a>
|
||||
<a href="/u/" class="usericon"><img src="/img/user.svg" /></a>
|
||||
</header>
|
||||
<main>
|
||||
<div class="profile top">
|
||||
<body>
|
||||
<div id="enter"><h1 class="title">click to enter</h1><p>this user selected a song, please mute the tab if you don't want to listen</p></div>
|
||||
<h1 class="title">{{ name }}'s profile</h1>
|
||||
<section>
|
||||
<img src="{{ user_pfp }}" class="pfp" />
|
||||
<div class="profile top text">
|
||||
<div class="profile-element">
|
||||
<h1>{{ name }}</h1>
|
||||
<div class="samerow">{{ badges }}</div>
|
||||
<p>/u/{{ username }}</p>
|
||||
<div class="badges">{{ badges }}</div>
|
||||
</div>
|
||||
<div class="profile-element">
|
||||
<h2>{{ song_title }}</h2>
|
||||
<h3>{{ song_artist }}</h3>
|
||||
<div class="samerow">
|
||||
<p id="curPos">0:00</p>
|
||||
<input type="range" id="playbar" min="1" max="1000" />
|
||||
<p id="totalLength">9:99</p>
|
||||
</div>
|
||||
<div class="samerow">
|
||||
<img id="playPause" src="/img/pause.svg" class="controls"/>
|
||||
<img id="mute" src="/img/volume.svg" class="controls"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="profile-element">
|
||||
<h2>Joined {{ join_date }}</h2>
|
||||
<h2>Last online {{ online_time }}</h2>
|
||||
</div>
|
||||
<div class="profile top text right">
|
||||
<h1>About Me</h1>
|
||||
<h2 class="about">{{ about }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="profile played">
|
||||
<h2>Top Games:</h2>
|
||||
<div id="played-games">
|
||||
{{ played_games }}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
<a href="https://gitlab.com/skysthelimit.dev/selenite">Source</a>
|
||||
<a href="https://discord.gg/7jyufnwJNf">Discord</a>
|
||||
<a href="/suggest.html">Suggestions & Bugs</a>
|
||||
<a href="/contact.html">Contact</a>
|
||||
<a href="/support.html">Donate</a>
|
||||
<a href="/about.html">About</a>
|
||||
</footer>
|
||||
</section>
|
||||
<section class="column" id="about">
|
||||
<h1>about me</h1>
|
||||
<p>{{ about }}</p>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -5,21 +5,69 @@
|
||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||
|
||||
<!-- initialize externals -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
|
||||
<script src=" https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js "></script>
|
||||
<meta property="og:title" content="Selenite" />
|
||||
<meta property="description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||
|
||||
<meta content="/favicon.png" property="og:image" />
|
||||
<meta content="#c77dff" data-react-helmet="true" name="theme-color" />
|
||||
<meta name="googlebot" content="index, follow, snippet" />
|
||||
<link rel="canonical" href="https://selenite.cc/" />
|
||||
<meta property="og:description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||
<meta property="og:title" content="Selenite">
|
||||
<meta property="og:type" content="website">
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "Selenite",
|
||||
"alternateName": "selenite.cc",
|
||||
"url": "https://selenite.cc",
|
||||
"logo": "https://selenite.cc/favicon.png",
|
||||
"sameAs": [
|
||||
"https://github.com/selenite-cc",
|
||||
"https://youtube.com/@selenitecc",
|
||||
"https://tiktok.com/@selenitecc",
|
||||
"https://selenite.cc",
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- initialize my stuff -->
|
||||
<script src="/js/all.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css" />
|
||||
<link rel="stylesheet" href="/css/pages.css" />
|
||||
<link rel="stylesheet" href="/css/profile.css" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<!-- seo + other things -->
|
||||
<title>{{ name }}'s Profile | Selenite</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415518411898563" crossorigin="anonymous"></script>
|
||||
<!-- <script>
|
||||
let audioObject;
|
||||
document.addEventListener("DOMContentLoaded", ()=>{
|
||||
let music = false; // {{ is_music }}
|
||||
if(music) {
|
||||
let url = "/api/music/download?url=https://soundcloud.com/archive5077/fostered-alcoholism-grayskies"; // {{ music_url }}
|
||||
let audioObject = new Audio(url);
|
||||
document.getElementById("enter").addEventListener("click", async ()=>{
|
||||
document.getElementById("enter").style.backgroundColor = "#00000000"
|
||||
document.getElementById("enter").style.backdropFilter = "blur(0px)"
|
||||
document.getElementById("enter").style.opacity = "0";
|
||||
setTimeout( () => {
|
||||
document.getElementById("enter").style.display = "none";
|
||||
audioObject.play();
|
||||
}, 700);
|
||||
});
|
||||
}
|
||||
})
|
||||
</script> -->
|
||||
<script>
|
||||
let username = "{{ username }}";
|
||||
let userData;
|
||||
let songData;
|
||||
(async () => {
|
||||
userData = await (await fetch("/u/raw")).json();
|
||||
})();
|
||||
@ -53,6 +101,9 @@
|
||||
console.log("promise finished");
|
||||
body = { pfp: fileData };
|
||||
console.log("body set");
|
||||
} else if (state == "song") {
|
||||
body = songData;
|
||||
console.log("body set");
|
||||
} else if (state == "clearpfp") {
|
||||
body = { pfp: "del" };
|
||||
} else if (state == "close") {
|
||||
@ -79,10 +130,12 @@
|
||||
document.getElementById("title").innerText = "Upload successful!";
|
||||
document.getElementById("text").style.display = "none";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
} else {
|
||||
document.getElementById("title").innerText = "Upload failed. This probably means something bad happened, send an email to support@selenite.cc or ping @skysthelimit.dev";
|
||||
document.getElementById("text").style.display = "none";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
}
|
||||
return;
|
||||
} else if (state == "download") {
|
||||
@ -105,11 +158,13 @@
|
||||
document.getElementById("title").innerText = "Download successful!";
|
||||
document.getElementById("text").style.display = "none";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
} else {
|
||||
document.getElementById("title").innerText = "Download failed.";
|
||||
document.getElementById("body-text").innerText = data.reason;
|
||||
document.getElementById("body-text").style.display = "flex";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
}
|
||||
console.log(data);
|
||||
data = JSON.parse(data.data);
|
||||
@ -131,7 +186,19 @@
|
||||
}
|
||||
console.log("sending");
|
||||
body.username = username;
|
||||
await fetch("/api/profile/edit", {
|
||||
document.getElementById("title").innerText = "processing...";
|
||||
document.getElementById("pfp_upload").style.display = "none";
|
||||
document.getElementById("pfp_reminder").style.display = "none";
|
||||
document.getElementById("body-text").style.display = "none";
|
||||
document.getElementById("clear").style.display = "none";
|
||||
document.getElementById("text").style.display = "none";
|
||||
document.getElementById("counter").style.display = "none";
|
||||
document.getElementById("submit").style.display = "none";
|
||||
document.getElementById("search").style.display = "none";
|
||||
document.querySelector("results").style.display = "none";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
let data = await fetch("/api/profile/edit", {
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8",
|
||||
@ -140,9 +207,24 @@
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
});
|
||||
console.log("sent");
|
||||
document.getElementById("popup").style.display = "none";
|
||||
let resp = await data.json();
|
||||
if(data.status == 200) {
|
||||
location.reload();
|
||||
} else {
|
||||
document.getElementById("title").innerText = "error!";
|
||||
document.getElementById("pfp_upload").style.display = "none";
|
||||
document.getElementById("pfp_reminder").style.display = "none";
|
||||
document.getElementById("body-text").style.display = "flex";
|
||||
document.getElementById("body-text").innerText = resp.err;
|
||||
document.getElementById("clear").style.display = "none";
|
||||
document.getElementById("text").style.display = "none";
|
||||
document.getElementById("counter").style.display = "none";
|
||||
document.getElementById("submit").style.display = "none";
|
||||
document.getElementById("search").style.display = "none";
|
||||
document.querySelector("results").style.display = "none";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
}
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
document.getElementById("pfp_upload").addEventListener("change", (e) => {
|
||||
@ -153,12 +235,24 @@
|
||||
});
|
||||
document.getElementById("submit").addEventListener("click", await setProfile);
|
||||
document.getElementById("clear").addEventListener("click", async()=>{state="clearpfp";await setProfile()});
|
||||
document.querySelectorAll("#edit").forEach((element) => {
|
||||
element.addEventListener("click", (e) => {
|
||||
console.log(e.target.parentElement.children[0].id);
|
||||
if (e.target.parentElement.children[0].id == "name") {
|
||||
document.getElementById("pfp").addEventListener("click", () => {
|
||||
state = "pfp";
|
||||
document.getElementById("title").innerText = "upload a new profile picture";
|
||||
document.getElementById("pfp_upload").style.display = "flex";
|
||||
document.getElementById("pfp_reminder").style.display = "flex";
|
||||
document.getElementById("body-text").style.display = "none";
|
||||
document.getElementById("clear").style.display = "flex";
|
||||
document.getElementById("text").style.display = "none";
|
||||
document.getElementById("counter").style.display = "none";
|
||||
document.getElementById("submit").style.display = "flex";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
document.getElementById("search").style.display = "none";
|
||||
document.querySelector("results").style.display = "none";
|
||||
});
|
||||
document.getElementById("name").addEventListener("click", () => {
|
||||
state = "name";
|
||||
document.getElementById("title").innerText = "Set your name.";
|
||||
document.getElementById("title").innerText = "change your name";
|
||||
document.getElementById("text").setAttribute("maxlength", "20");
|
||||
document.getElementById("pfp_upload").style.display = "none";
|
||||
document.getElementById("pfp_reminder").style.display = "none";
|
||||
@ -170,9 +264,13 @@
|
||||
document.getElementById("counter").style.display = "flex";
|
||||
document.getElementById("submit").style.display = "flex";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
} else if (e.target.parentElement.children[0].id == "bio") {
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
document.getElementById("search").style.display = "none";
|
||||
document.querySelector("results").style.display = "none";
|
||||
});
|
||||
document.getElementById("about").addEventListener("click", () => {
|
||||
state = "bio";
|
||||
document.getElementById("title").innerText = "Set your about me.";
|
||||
document.getElementById("title").innerText = "change your about me";
|
||||
document.getElementById("text").setAttribute("maxlength", "200");
|
||||
document.getElementById("pfp_upload").style.display = "none";
|
||||
document.getElementById("pfp_reminder").style.display = "none";
|
||||
@ -184,40 +282,61 @@
|
||||
document.getElementById("counter").style.display = "flex";
|
||||
document.getElementById("submit").style.display = "flex";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
} else if (e.target.parentElement.children[0].id == "custom") {
|
||||
state = "custom";
|
||||
document.getElementById("title").innerText = "Set your custom CSS.";
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
document.getElementById("search").style.display = "none";
|
||||
document.querySelector("results").style.display = "none";
|
||||
});
|
||||
document.getElementById("song").addEventListener("click", () => {
|
||||
state = "song";
|
||||
document.getElementById("title").innerText = "pick a song";
|
||||
document.getElementById("text").setAttribute("maxlength", "2048");
|
||||
document.getElementById("pfp_upload").style.display = "none";
|
||||
document.getElementById("pfp_reminder").style.display = "none";
|
||||
document.getElementById("body-text").style.display = "none";
|
||||
document.getElementById("clear").style.display = "none";
|
||||
document.getElementById("text").style.display = "flex";
|
||||
document.getElementById("text").value = userData["css"];
|
||||
document.getElementById("counter").innerText = `${document.getElementById("text").value.length} / ${document.getElementById("text").attributes.maxlength.value}`;
|
||||
document.getElementById("counter").style.display = "flex";
|
||||
document.getElementById("submit").style.display = "flex";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
} else if (e.target.parentElement.children[0].id == "pfp") {
|
||||
state = "pfp";
|
||||
document.getElementById("title").innerText = "Set your new profile picture.";
|
||||
document.getElementById("pfp_upload").style.display = "flex";
|
||||
document.getElementById("pfp_reminder").style.display = "flex";
|
||||
document.getElementById("body-text").style.display = "none";
|
||||
document.getElementById("clear").style.display = "flex";
|
||||
document.getElementById("text").style.display = "none";
|
||||
document.getElementById("counter").style.display = "none";
|
||||
document.getElementById("submit").style.display = "flex";
|
||||
document.getElementById("submit").style.display = "none";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
}
|
||||
});
|
||||
});
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
document.getElementById("search").style.display = "flex";
|
||||
document.querySelector("results").style.display = "flex";
|
||||
})
|
||||
document.getElementById("close").addEventListener("click", () => {
|
||||
document.getElementById("popup").style.display = "none";
|
||||
document.getElementById("blur").style.display = "none";
|
||||
});
|
||||
document.getElementById("text").addEventListener("input", () => {
|
||||
document.getElementById("counter").innerText = `${document.getElementById("text").value.length} / ${document.getElementById("text").attributes.maxlength.value}`;
|
||||
});
|
||||
document.getElementById("search").addEventListener("input", async ()=>{
|
||||
if(document.getElementById("search").value.length > 0) {
|
||||
let query = document.getElementById("search").value;
|
||||
let results = await fetch("/api/music/search?q=" + encodeURIComponent(document.getElementById("search").value));
|
||||
let json = await results.json();
|
||||
if(document.getElementById("search").value == query) {
|
||||
document.querySelector("results").display = "flex";
|
||||
console.log("searched")
|
||||
let i = 0;
|
||||
json.tracks.forEach((e)=>{
|
||||
document.querySelectorAll("result")[i].querySelector("h2").innerText = e.title;
|
||||
document.querySelectorAll("result")[i].querySelectorAll("p")[0].innerText = e.artists[0].name;
|
||||
document.querySelectorAll("result")[i].querySelectorAll("p")[1].innerText = e.url.slice(22);
|
||||
document.querySelectorAll("result")[i].setAttribute("data-url", e.url);
|
||||
document.querySelectorAll("result")[i].style.display = "flex";
|
||||
i++;
|
||||
})
|
||||
}
|
||||
} else {
|
||||
document.querySelectorAll("result").forEach((e) => {
|
||||
e.removeAttribute("data-url");
|
||||
e.querySelector("h2").innerText = null;
|
||||
e.querySelectorAll("p")[0].innerText = null;
|
||||
e.querySelectorAll("p")[1].innerText = null;
|
||||
e.style.display = "none";
|
||||
})
|
||||
}
|
||||
})
|
||||
document.getElementById("upload").addEventListener("click", async () => {
|
||||
state = "upload";
|
||||
document.getElementById("title").innerText = "Warning";
|
||||
@ -230,6 +349,7 @@
|
||||
document.getElementById("counter").style.display = "none";
|
||||
document.getElementById("submit").style.display = "flex";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
});
|
||||
document.getElementById("download").addEventListener("click", async () => {
|
||||
state = "download";
|
||||
@ -243,64 +363,41 @@
|
||||
document.getElementById("counter").style.display = "none";
|
||||
document.getElementById("submit").style.display = "flex";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("blur").style.display = "flex";
|
||||
});
|
||||
document.querySelectorAll("result").forEach(async e => {
|
||||
e.addEventListener("click", async (element) => {
|
||||
songData = {
|
||||
url: e.getAttribute("data-url"),
|
||||
title: e.childNodes[0].innerText,
|
||||
artist: e.childNodes[1].innerText,
|
||||
}
|
||||
console.log(songData);
|
||||
await setProfile();
|
||||
})
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<alerts> </alerts>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/index.html">Home</a>
|
||||
<a href="/bookmarklets.html">Bookmarklets</a>
|
||||
<a href="/projects.html">Games</a>
|
||||
<a href="/apps.html">Apps</a>
|
||||
<a href="/settings.html">Settings</a>
|
||||
<a id="blank" href="#">Open Blank</a>
|
||||
<a href="/u/" class="usericon"><img src="/img/user.svg" /></a>
|
||||
</header>
|
||||
<main>
|
||||
<!-- <a class="friend-icon" href="/friends"><img src="/img/friend.svg"></a> -->
|
||||
<input type="text" readonly value="{{ url_gen }}" />
|
||||
<div class="samerow">
|
||||
<button id="download">Download Backup</button>
|
||||
<button id="upload">Upload Backup</button>
|
||||
</div>
|
||||
<div>
|
||||
<div id="custom"></div>
|
||||
{{ css_edit }}
|
||||
</div>
|
||||
<div class="profile top">
|
||||
<img src="{{ user_pfp }}" class="pfp" id="pfp" />
|
||||
<img src="/img/edit.svg" id="edit" />
|
||||
<div class="profile top text">
|
||||
<div class="samerow edit" id="name">
|
||||
<h1 id="name">{{ name }}</h1>
|
||||
<img src="/img/edit.svg" id="edit" />
|
||||
</div>
|
||||
<div class="samerow">{{ badges }}</div>
|
||||
<h2>Joined {{ join_date }}</h2>
|
||||
<h2>Last online {{ online_time }}</h2>
|
||||
</div>
|
||||
<div class="profile top text right">
|
||||
<div class="samerow edit" id="about">
|
||||
<h1 id="bio">Bio</h1>
|
||||
<img src="/img/edit.svg" id="edit" />
|
||||
</div>
|
||||
<h2 id="about">{{ about }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="profile played">
|
||||
<h2>Top Games:</h2>
|
||||
<div id="played-games">
|
||||
{{ played_games }}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<popups>
|
||||
<div id="blur"></div>
|
||||
<div id="popup" style="display: none">
|
||||
<h1 id="title"></h1>
|
||||
<p id="body-text"></p>
|
||||
<input type="text" id="text" />
|
||||
<input type="text" id="search" placeholder="search a song title here.."/>
|
||||
<results id="results">
|
||||
<result><h2></h2><p></p><p></p></result>
|
||||
<result><h2></h2><p></p><p></p></result>
|
||||
<result><h2></h2><p></p><p></p></result>
|
||||
<result><h2></h2><p></p><p></p></result>
|
||||
<result><h2></h2><p></p><p></p></result>
|
||||
<result><h2></h2><p></p><p></p></result>
|
||||
<result><h2></h2><p></p><p></p></result>
|
||||
<result><h2></h2><p></p><p></p></result>
|
||||
<result><h2></h2><p></p><p></p></result>
|
||||
<result><h2></h2><p></p><p></p></result>
|
||||
</results>
|
||||
<p id="counter">0 / 0</p>
|
||||
<input type="file" id="pfp_upload" name="filename" accept=".png,.jpg,.jpeg,.gif,.avif,.webp,.tiff,.svg" />
|
||||
<p id="pfp_reminder">4 MB file upload max</p>
|
||||
@ -308,14 +405,33 @@
|
||||
<button id="submit">Submit</button>
|
||||
<button id="close">X</button>
|
||||
</div>
|
||||
</popups>
|
||||
<footer>
|
||||
<a href="https://gitlab.com/skysthelimit.dev/selenite">Source</a>
|
||||
<a href="https://discord.gg/7jyufnwJNf">Discord</a>
|
||||
<a href="/suggest.html">Suggestions & Bugs</a>
|
||||
<a href="/contact.html">Contact</a>
|
||||
<a href="/support.html">Donate</a>
|
||||
<a href="/about.html">About</a>
|
||||
</footer>
|
||||
<div class="samerow">
|
||||
<button id="download">download cloud backup</button>
|
||||
<button id="upload">upload cloud backup</button>
|
||||
</div>
|
||||
<h1 class="title">{{ name }}'s profile</h1>
|
||||
<h3>click on an area to edit</h3>
|
||||
<p style="font-size: 16px;">share your profile at {{ url_gen }}</p>
|
||||
{{ staff_buttons }}
|
||||
<section>
|
||||
<img src="{{ user_pfp }}" class="pfp edit" id="pfp" />
|
||||
<div class="profile-element edit" id="name">
|
||||
<h1>{{ name }}</h1>
|
||||
<p>/u/{{ username }}</p>
|
||||
<div class="badges">{{ badges }}</div>
|
||||
</div>
|
||||
<div class="profile-element edit" id="song">
|
||||
<h2>{{ song_title }}</h2>
|
||||
<h3>{{ song_artist }}</h3>
|
||||
</div>
|
||||
<div class="profile-element">
|
||||
<h2>Joined {{ join_date }}</h2>
|
||||
<h2>Last online {{ online_time }}</h2>
|
||||
</div>
|
||||
</section>
|
||||
<section class="column edit" id="about">
|
||||
<h1>about me</h1>
|
||||
<p class="about">{{ about }}</p>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- initialize theme vars
|
||||
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
|
||||
|
||||
<!-- initialize externals -->
|
||||
<meta property="og:title" content="Selenite" />
|
||||
<meta property="description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||
<meta content="/favicon.png" property="og:image" />
|
||||
<meta content="#c77dff" data-react-helmet="true" name="theme-color" />
|
||||
<meta name="googlebot" content="index, follow, snippet" />
|
||||
<link rel="canonical" href="https://selenite.cc/" />
|
||||
<meta property="og:description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||
<meta property="og:title" content="Selenite">
|
||||
<meta property="og:type" content="website">
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "Selenite",
|
||||
"alternateName": "selenite.cc",
|
||||
"url": "https://selenite.cc",
|
||||
"logo": "https://selenite.cc/favicon.png",
|
||||
"sameAs": [
|
||||
"https://github.com/selenite-cc",
|
||||
"https://youtube.com/@selenitecc",
|
||||
"https://tiktok.com/@selenitecc",
|
||||
"https://selenite.cc",
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- initialize my stuff -->
|
||||
<script src="/js/all.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css" />
|
||||
<link rel="stylesheet" href="/css/pages.css" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<!-- seo + other things -->
|
||||
<title>Selenite</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415518411898563" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<alerts> </alerts>
|
||||
<body>
|
||||
<h1 class="title">stats</h1>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<!-- initialize externals -->
|
||||
<meta property="og:title" content="Selenite" />
|
||||
<meta property="description" content="Selenite is the best unblocked games site. With over 400 games and an account system, no other websites come close to Selenite." />
|
||||
<meta name="keywords" content="proxy, web proxy, unblock websites, unblock chromebook, free web proxy, proxy list, proxy sites, un block chromebook, online proxy, proxy server, proxysite, proxy youtube, bypass securly, bypass iboss, bypass lightspeed filter, chromebooks, unblock youtube, youtube proxy, unblocked youtube, youtube unblocked, unblock games, selenite, unblocked games, free games">
|
||||
|
||||
<meta content="/favicon.png" property="og:image" />
|
||||
<meta content="#c77dff" data-react-helmet="true" name="theme-color" />
|
||||
<meta name="googlebot" content="index, follow, snippet" />
|
||||
@ -34,7 +34,7 @@
|
||||
</script>
|
||||
|
||||
<!-- initialize my stuff -->
|
||||
<script src="/js/all.js"></script>
|
||||
<script src="/js/all.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
<!-- <script src="/js/widget.js"></script> -->
|
||||
<script>
|
||||
@ -42,17 +42,93 @@
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css" />
|
||||
<link rel="stylesheet" href="/css/pages.css" />
|
||||
<link rel="stylesheet" href="/css/users.css" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<!-- seo + other things -->
|
||||
<title>Selenite</title>
|
||||
<script>
|
||||
async function loadUsers(query, page) {
|
||||
let above = false;
|
||||
let below = false;
|
||||
let data = await (await fetch(`/api/getUsers?page=${page - 1}&query=${query}`)).json();
|
||||
let users = data['users'];
|
||||
let url = new URL(location.href);
|
||||
|
||||
pages = Math.ceil(data.count / 12);
|
||||
document.getElementById("users").innerHTML = "";
|
||||
for (let i = 0; i < Object.keys(users).length; i++) {
|
||||
document.getElementById("users").innerHTML += `<a href="/u/${users[i].username}" class="users"><img class="pfp" src="${users[i].pfp_url}"/><div class="user_info"><h1>${users[i].name}</h1><p>${users[i].about}</p></div></a>`;
|
||||
}
|
||||
document.getElementById("pages").innerHTML = "";
|
||||
for (let i = 1; i < pages + 1; i++) {
|
||||
if (i + 6 > page && i - 6 < page) {
|
||||
let curPage = parseInt(page);
|
||||
let element = document.createElement("a");
|
||||
if (!(i == curPage)) {
|
||||
url.searchParams.set("page", i);
|
||||
element.setAttribute("href", url);
|
||||
}
|
||||
element.setAttribute("class", `pages-btn`);
|
||||
element.innerText = i;
|
||||
document.getElementById("pages").append(element);
|
||||
} else {
|
||||
if (i + 6 > page) {
|
||||
above = true;
|
||||
}
|
||||
if (i - 6 < page) {
|
||||
below = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (above) {
|
||||
let element = document.createElement("a");
|
||||
element.setAttribute("class", "pages-btn");
|
||||
element.innerText = "...";
|
||||
document.getElementById("pages").append(element);
|
||||
}
|
||||
if (below) {
|
||||
let element = document.createElement("a");
|
||||
element.setAttribute("class", "pages-btn");
|
||||
element.innerText = "...";
|
||||
document.getElementById("pages").prepend(element);
|
||||
}
|
||||
}
|
||||
let pages;
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
let params = location.search.substring(1).split("&");
|
||||
let query;
|
||||
let page;
|
||||
if (params) {
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
if (params[i].startsWith("query")) {
|
||||
query = params[i].substring(6);
|
||||
}
|
||||
if (params[i].startsWith("page")) {
|
||||
page = params[i].substring(5);
|
||||
if (isNaN(page)) {
|
||||
page = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
await loadUsers(query ? query : "", page ? page : 0);
|
||||
document.getElementById("search").addEventListener("keydown", async (e) => {
|
||||
if (e.key == "Enter") {
|
||||
let url = new URL(location.href);
|
||||
url.searchParams.set("query", document.getElementById("search").value);
|
||||
url.searchParams.set("page", 1);
|
||||
location.href = url;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415518411898563" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<alerts> </alerts>
|
||||
<body>
|
||||
<h1 class="title">users</h1>
|
||||
<div id="users">
|
||||
|
||||
</div>
|
||||
<div id="users"></div>
|
||||
<div id="pages"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
224
index.js
224
index.js
@ -1,4 +1,3 @@
|
||||
const io = require('@pm2/io')
|
||||
import { log } from "./log.js";
|
||||
import bodyParser from "body-parser";
|
||||
import express from "express";
|
||||
@ -8,12 +7,14 @@ import { fileURLToPath } from "url";
|
||||
import path, { dirname } from "node:path";
|
||||
import mime from "mime-types";
|
||||
import compression from "compression";
|
||||
import { accs, infdb, polytrack } from "./database.js";
|
||||
// import { accs, infdb, polytrack } from "./database.js";
|
||||
import { accs } from "./database.js";
|
||||
import { } from "./accounts/friend.js";
|
||||
import { search, download } from "./accounts/music.js";
|
||||
import { banUser, removeAccount, verifyCookie, getUserFromCookie, createAccount, resetPassword, loginAccount, addBadge } from "./accounts/manage.js";
|
||||
import { } from "./accounts/misc.js";
|
||||
import { getRawData, generateAccountPage, editProfile, saveData, getUsers, isAdmin, retrieveData } from "./accounts/profile.js";
|
||||
// import { infiniteCraft, chatBot } from "./ai.js";
|
||||
import { callAI } from "./ai.js";
|
||||
import os from "node:os";
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
@ -21,88 +22,59 @@ const __dirname = dirname(__filename);
|
||||
const port = process.env.PORT || 3000;
|
||||
|
||||
const app = express();
|
||||
// why the fuck does this have to exist?
|
||||
app.use("/resources/semag/hotline-miami/", (req,res,next) => {
|
||||
if(req.method == "HEAD") {
|
||||
req.socket.destroy();
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
app.use(compression());
|
||||
app.use(cookieParser());
|
||||
app.use(express.json({ limit: "10mb" }));
|
||||
app.use(express.urlencoded({ extended: false }));
|
||||
app.use(express.text());
|
||||
let requests = 0;
|
||||
const requestsPerSec = io.meter({
|
||||
name: 'req/sec',
|
||||
id: 'app/requests/sec'
|
||||
});
|
||||
const requestsPerMin = io.meter({
|
||||
name: 'req/min',
|
||||
id: 'app/requests/min'
|
||||
});
|
||||
app.use("/", (req, res, next) => {
|
||||
requestsPerSec.mark();
|
||||
requestsPerMin.mark();
|
||||
next();
|
||||
});
|
||||
const sockets = io.metric({
|
||||
name: 'Open Websockets',
|
||||
id: 'app/requests/sockets',
|
||||
});
|
||||
// app.use("/", (req, res, next) => {
|
||||
// next();
|
||||
// });
|
||||
// setInterval(()=>{
|
||||
|
||||
// }, 1000)
|
||||
import WebSocket, { WebSocketServer } from "ws";
|
||||
import { request } from "node:http";
|
||||
const wss = new WebSocketServer({ noServer: true });
|
||||
let openSockets = 0;
|
||||
// let openSockets = 0;
|
||||
wss.on("connection", function connection(ws, req, res) {
|
||||
openSockets++;
|
||||
sockets.set(openSockets);
|
||||
ws.send(`online=${wss.clients.size}`);
|
||||
setInterval(() => {
|
||||
ws.send("ping");
|
||||
}, 30000);
|
||||
ws.send(`online=${wss.clients.size}`);
|
||||
}, 10000);
|
||||
|
||||
ws.on("error", console.error);
|
||||
|
||||
ws.on("message", async function message(data, isBinary) {
|
||||
let message = Buffer.from(data).toString();
|
||||
if (message.startsWith(process.env.ANNOUNCEMENT_KEY)) {
|
||||
wss.clients.forEach(function each(client) {
|
||||
if (client.readyState === WebSocket.OPEN) {
|
||||
client.send(message.replace(process.env.ANNOUNCEMENT_KEY, "announce."));
|
||||
}
|
||||
});
|
||||
} else if (message.startsWith("token") && (await verifyCookie(message.substring(6)))) {
|
||||
if (message.startsWith("token") && (await verifyCookie(message.substring(6)))) {
|
||||
ws.id = await getUserFromCookie(message.substring(6));
|
||||
ws.send(ws.id);
|
||||
const updateAccount = accs.query(`UPDATE accounts SET last_login = $login WHERE username = $user`)
|
||||
updateAccount.get({ $login: new Date().toUTCString(), $user: ws.id });
|
||||
} else if (message.startsWith("pong")) {
|
||||
} else if (message.startsWith("1")) {
|
||||
if (ws.id) {
|
||||
const updateAccount = accs.query(`UPDATE accounts SET last_login = $login WHERE username = $user`)
|
||||
updateAccount.get({ $login: new Date().toUTCString(), $user: ws.id });
|
||||
if (message.substring(4)) {
|
||||
const existingAccount = accs.query(`SELECT * FROM accounts WHERE username LIKE $1`)
|
||||
let userData = existingAccount.get({ $1: ws.id });
|
||||
if (userData == null) {
|
||||
return { success: false, reason: "The account doesn't exist." };
|
||||
}
|
||||
let games;
|
||||
if (userData.playedgames) {
|
||||
games = JSON.parse(userData.playedgames);
|
||||
} else {
|
||||
games = {};
|
||||
}
|
||||
if (games[message.substring(4)]) {
|
||||
games[message.substring(4)] += 30;
|
||||
} else {
|
||||
games[message.substring(4)] = 30;
|
||||
}
|
||||
const updateAccount = accs.query(`UPDATE accounts SET playedgames = $playedgames WHERE username = $user`)
|
||||
updateAccount.get({ $playedgames: JSON.stringify(games), $user: ws.id });
|
||||
}
|
||||
} else if (message.startsWith("annc")) {
|
||||
let splitMessage = message.split(";;");
|
||||
if(await isAdmin(splitMessage[1])) {
|
||||
wss.clients.forEach(client => {
|
||||
client.send(`annc;;${splitMessage[2]};;${splitMessage[3]}`);
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ws.on("close", () => {openSockets--;
|
||||
sockets.set(openSockets);});
|
||||
ws.on("close", () => {});
|
||||
});
|
||||
app.post(
|
||||
"/api/event",
|
||||
@ -120,11 +92,6 @@ app.post(
|
||||
})
|
||||
}
|
||||
);
|
||||
// app.use("*.json", async (req, res, next) => {
|
||||
// optimize json
|
||||
// console.log("got data");
|
||||
// next()
|
||||
// });
|
||||
app.post("/register", async (req, res) => {
|
||||
let status = await createAccount(req.body.username, req.body.password, req.body["h-captcha-response"]);
|
||||
if (status["success"]) {
|
||||
@ -173,24 +140,16 @@ app.post("/api/account/upload", async (req, res, next) => {
|
||||
res.status(400).send(status);
|
||||
}
|
||||
} else {
|
||||
return "KILL YOURSELF";
|
||||
// return "KILL YOURSELF";
|
||||
}
|
||||
});
|
||||
|
||||
// ai endpoints
|
||||
app.post("/api/ai/createChat", async (req, res) => {
|
||||
// create chat in database and store some metadata about it
|
||||
// ie: last model, time created, etc etc
|
||||
})
|
||||
app.post("/api/ai/sendMessage", async (req, res) => {
|
||||
// take in chat id and message
|
||||
// stream back reply
|
||||
})
|
||||
app.get("/api/ai/messages", async (req, res) => {
|
||||
// take in chat id
|
||||
// use unique uuid to store every chat
|
||||
// return messages
|
||||
})
|
||||
|
||||
|
||||
// friends endpoints
|
||||
app.get("/api/friends/list", async (req, res) => {
|
||||
// use auth token to get user
|
||||
@ -227,110 +186,6 @@ app.get("/api/chat/recent", async (req, res) => {
|
||||
// get last 50 recent messages
|
||||
// offset by a page param
|
||||
})
|
||||
app.get("/api/infinite/get", async (req, res, next) => {
|
||||
if (req.query[1] && req.query[2]) {
|
||||
let success = false;
|
||||
let data;
|
||||
try {
|
||||
let search1Query = infdb.query(`SELECT * FROM caches WHERE 1 = $one AND 2 = $two`)
|
||||
let search1 = await search1Query.get({ $one: req.query[1], $two: req.query[2] });
|
||||
console.log(search1);
|
||||
if (search1 && search1.length > 0) {
|
||||
data = { item: search1[0].result_item, emoji: search1[0].result_emoji, new: false };
|
||||
success = true;
|
||||
} else {
|
||||
let search2Query = infdb.query(`SELECT * FROM caches WHERE 1 = $two AND 2 = $one`)
|
||||
let search2 = await search2Query.get({ $one: req.query[1], $two: req.query[2] });
|
||||
console.log(search2);
|
||||
if (search2 && search2.length > 0) {
|
||||
data = { item: search2[0].result_item, emoji: search2[0].result_emoji, new: false };
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
if (success) {
|
||||
console.log("success");
|
||||
res.send(data);
|
||||
return;
|
||||
}
|
||||
data = await infiniteCraft(req.query[1], req.query[2]);
|
||||
try {
|
||||
let parse = JSON.parse(data);
|
||||
let keys = Object.keys(parse);
|
||||
if (keys.indexOf("item") > -1 && keys.indexOf("emoji") > -1) {
|
||||
parse.new = true;
|
||||
data = parse;
|
||||
const createCached = infdb.query(`INSERT INTO caches (1, 2, result_item, result_emoji) VALUES ($one, $two, $item, $emoji)`)
|
||||
createCached.run({ $one: req.query[1], $two: req.query[2], $item: data.item, $emoji: data.emoji });
|
||||
res.send(data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
data = { item: "N/A", emoji: "N/A" };
|
||||
res.send(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
app.use("/semag/polytrack/data/", async (req, res, next) => {
|
||||
let path = req.path.substring(1, req.path.length);
|
||||
if(path == "user") {
|
||||
res.sendStatus(200);
|
||||
} else if(path == "leaderboard") {
|
||||
let data = {};
|
||||
|
||||
if(req.method == "POST") {
|
||||
req.body.split("&").forEach((item) => {
|
||||
data[item.split("=")[0]] = item.split("=")[1]
|
||||
});
|
||||
console.log(data);
|
||||
const getExistingRuns = polytrack.query(`SELECT * FROM polytrack WHERE userid = $usrid AND trackid = $trackid`);
|
||||
let existingRuns = getExistingRuns.all({ $usrid: data["userToken"], $trackid: data["trackId"] });
|
||||
let saveRun = true;
|
||||
if(existingRuns !== null) {
|
||||
existingRuns.forEach((item) => {
|
||||
if(saveRun) {
|
||||
if(data.frames > item.frames) {
|
||||
saveRun = false;
|
||||
} else {
|
||||
let deleteRun = polytrack.query(`DELETE FROM polytrack WHERE id = $id`);
|
||||
deleteRun.run({ $id: item.id })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if(saveRun) {
|
||||
const addRun = polytrack.query(`INSERT INTO polytrack (trackid, username, colors, recording, frames, userid) VALUES ($id, $usr, $clr, $record, $frames, $usrid)`)
|
||||
let runData = addRun.run({ $id: data["trackId"], $usr: data["name"], $clr: data["carColors"], $record: data["recording"], $usrid: data["userToken"], $frames: data["frames"] });
|
||||
console.log("run", runData);
|
||||
res.send(runData.lastInsertRowid);
|
||||
}
|
||||
} else {
|
||||
let leaderboard = polytrack.query(`SELECT * FROM polytrack WHERE trackid = $id LIMIT $limit OFFSET $offset`).all({ $id: req.query.trackId, $limit: req.query.amount, $offset: req.query.skip })
|
||||
console.log(leaderboard);
|
||||
let returnValue = {"total": leaderboard.length, "entries":[]}
|
||||
for(let i = 0; i<leaderboard.length;i++) {
|
||||
returnValue["entries"][i] = {};
|
||||
returnValue["entries"][i]["id"] = leaderboard[i]["id"];
|
||||
returnValue["entries"][i]["name"] = decodeURIComponent(leaderboard[i]["username"]);
|
||||
returnValue["entries"][i]["carColors"] = leaderboard[i]["colors"];
|
||||
returnValue["entries"][i]["frames"] = leaderboard[i]["frames"];
|
||||
returnValue["entries"][i]["verifiedState"] = true;
|
||||
returnValue["entries"][i]["isSelf"] = false;
|
||||
}
|
||||
res.send(returnValue);
|
||||
}
|
||||
} else if(path == "recording") {
|
||||
let recordingQuery = polytrack.query(`SELECT * FROM polytrack WHERE id = $id`).get({ $id: req.query.recordingId });
|
||||
res.send({
|
||||
"recording": recordingQuery.recording,
|
||||
"frames": recordingQuery.frames,
|
||||
"verifiedState": true,
|
||||
"carColors": recordingQuery.colors
|
||||
});
|
||||
}
|
||||
})
|
||||
app.use("/api/account/load", async (req, res, next) => {
|
||||
if (req.cookies.token && (await verifyCookie(req.cookies.token))) {
|
||||
let status = await retrieveData(req.cookies.token);
|
||||
@ -370,7 +225,6 @@ app.use("/api/stats", async (req, res, next) => {
|
||||
// "cpu": os.cpus(),
|
||||
"ram": `${(os.totalmem()-os.freemem())/1000000000}GB / ${os.totalmem()/1000000000}GB`,
|
||||
"cpuUsage": os.loadavg(),
|
||||
"openWebSockets": openSockets,
|
||||
"uptime": `${os.uptime()}s`
|
||||
});
|
||||
} else {
|
||||
@ -395,11 +249,12 @@ app.use("/data/:id/:file", async (req, res) => {
|
||||
const filePath = path.join(process.env.DATA_PATH, "data", id, file);
|
||||
try {
|
||||
await fs.access(filePath);
|
||||
|
||||
const image = await fs.readFile(filePath);
|
||||
if (mime.lookup(filePath) == "image/webp") {
|
||||
res.type("image/webp");
|
||||
res.status(200).send(image);
|
||||
res.status(200).send(await fs.readFile(filePath));
|
||||
} else if (mime.lookup(filePath) == "audio/ogg") {
|
||||
res.type("audio/ogg");
|
||||
res.status(200).send(await fs.readFile(filePath));
|
||||
} else {
|
||||
res.status(404).send("File not found");
|
||||
}
|
||||
@ -477,6 +332,15 @@ app.post("/api/admin/ban", async (req, res) => {
|
||||
let status = await banUser(req.body.name, req.body.reason, req.cookies.token);
|
||||
res.status(200).send(status);
|
||||
});
|
||||
|
||||
|
||||
app.use("/api/music/search", async (req, res, next) => {
|
||||
res.status(200).send(await search(req.query.q))
|
||||
});
|
||||
|
||||
app.use("/api/music/download", async (req, res, next) => {
|
||||
res.status(200).send(await download(req.query.url))
|
||||
});
|
||||
const server = app.listen(port, () => {
|
||||
console.log(log.success("Express is online."));
|
||||
console.log("- " + log.info("http://localhost:" + port));
|
||||
|
||||
1081
package-lock.json
generated
1081
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
@ -12,25 +12,23 @@
|
||||
"license": "ISC",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@pm2/io": "^6.1.0",
|
||||
"axios": "^1.3.1",
|
||||
"body-parser": "^2.0.2",
|
||||
"chalk": "^5.3.0",
|
||||
"compression": "^1.7.4",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"dayjs": "^1.11.11",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^5.0.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"file-type": "^19.0.0",
|
||||
"install": "^0.13.0",
|
||||
"@ai-sdk/openai-compatible": "^1.0.22",
|
||||
"ai": "^5.0.68",
|
||||
"axios": "^1.12.2",
|
||||
"body-parser": "^2.2.0",
|
||||
"chalk": "^5.6.2",
|
||||
"compression": "^1.8.1",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"dayjs": "^1.11.18",
|
||||
"dotenv": "^16.6.1",
|
||||
"express": "^5.1.0",
|
||||
"file-type": "^19.6.0",
|
||||
"lucida": "^2.0.0-54",
|
||||
"mime-types": "^2.1.35",
|
||||
"node-html-parser": "^6.1.13",
|
||||
"openai": "^4.85.3",
|
||||
"rword": "^3.2.1",
|
||||
"sanitize-html": "^2.13.0",
|
||||
"sequelize": "^6.37.3",
|
||||
"sharp": "^0.33.4",
|
||||
"ws": "^8.18.0"
|
||||
"sanitize-html": "^2.17.0",
|
||||
"sharp": "^0.33.5",
|
||||
"ws": "^8.18.3"
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,4 +2,8 @@ module.exports = {
|
||||
name: "Selenite", // Name of your application
|
||||
script: "index.js", // Entry point of your application
|
||||
interpreter: "bun", // Path to the Bun interpreter
|
||||
watch: true,
|
||||
cron_restart: '0 0 * * *',
|
||||
instances : "max",
|
||||
exec_mode : "cluster"
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user