big update
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.env
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
{
|
{
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"dev": "deno run --allow-read=./ --allow-net main.ts"
|
"dev": "deno run --allow-read=./ --allow-net --allow-env main.ts"
|
||||||
},
|
},
|
||||||
"imports": {
|
"imports": {
|
||||||
"@std/assert": "jsr:@std/assert@1",
|
"@std/assert": "jsr:@std/assert@1",
|
||||||
|
"@std/dotenv": "jsr:@std/dotenv@^0.225.6",
|
||||||
|
"@std/fs": "jsr:@std/fs@^1.0.21",
|
||||||
"@std/media-types": "jsr:@std/media-types@^1.1.0"
|
"@std/media-types": "jsr:@std/media-types@^1.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
23
deno.lock
generated
@@ -2,8 +2,11 @@
|
|||||||
"version": "5",
|
"version": "5",
|
||||||
"specifiers": {
|
"specifiers": {
|
||||||
"jsr:@std/assert@1": "1.0.16",
|
"jsr:@std/assert@1": "1.0.16",
|
||||||
|
"jsr:@std/dotenv@~0.225.6": "0.225.6",
|
||||||
|
"jsr:@std/fs@^1.0.21": "1.0.21",
|
||||||
"jsr:@std/internal@^1.0.12": "1.0.12",
|
"jsr:@std/internal@^1.0.12": "1.0.12",
|
||||||
"jsr:@std/media-types@^1.1.0": "1.1.0"
|
"jsr:@std/media-types@^1.1.0": "1.1.0",
|
||||||
|
"jsr:@std/path@^1.1.4": "1.1.4"
|
||||||
},
|
},
|
||||||
"jsr": {
|
"jsr": {
|
||||||
"@std/assert@1.0.16": {
|
"@std/assert@1.0.16": {
|
||||||
@@ -12,16 +15,34 @@
|
|||||||
"jsr:@std/internal"
|
"jsr:@std/internal"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"@std/dotenv@0.225.6": {
|
||||||
|
"integrity": "1d6f9db72f565bd26790fa034c26e45ecb260b5245417be76c2279e5734c421b"
|
||||||
|
},
|
||||||
|
"@std/fs@1.0.21": {
|
||||||
|
"integrity": "d720fe1056d78d43065a4d6e0eeb2b19f34adb8a0bc7caf3a4dbf1d4178252cd",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/internal",
|
||||||
|
"jsr:@std/path"
|
||||||
|
]
|
||||||
|
},
|
||||||
"@std/internal@1.0.12": {
|
"@std/internal@1.0.12": {
|
||||||
"integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027"
|
"integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027"
|
||||||
},
|
},
|
||||||
"@std/media-types@1.1.0": {
|
"@std/media-types@1.1.0": {
|
||||||
"integrity": "c9d093f0c05c3512932b330e3cc1fe1d627b301db33a4c2c2185c02471d6eaa4"
|
"integrity": "c9d093f0c05c3512932b330e3cc1fe1d627b301db33a4c2c2185c02471d6eaa4"
|
||||||
|
},
|
||||||
|
"@std/path@1.1.4": {
|
||||||
|
"integrity": "1d2d43f39efb1b42f0b1882a25486647cb851481862dc7313390b2bb044314b5",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/internal"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"jsr:@std/assert@1",
|
"jsr:@std/assert@1",
|
||||||
|
"jsr:@std/dotenv@~0.225.6",
|
||||||
|
"jsr:@std/fs@^1.0.21",
|
||||||
"jsr:@std/media-types@^1.1.0"
|
"jsr:@std/media-types@^1.1.0"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
76
main.ts
@@ -1,27 +1,22 @@
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
import { walk } from "@std/fs/walk";
|
||||||
|
import "@std/dotenv/load";
|
||||||
|
import { contentType } from "@std/media-types";
|
||||||
|
|
||||||
const NET_PORT = 4536;
|
const _PORT = Deno.env.get('NET_PORT');
|
||||||
const NET_HOST = '127.0.0.1';
|
if (!_PORT || isNaN(parseInt(_PORT))) throw new Error("No NET_PORT specified in env");
|
||||||
const WEB_ROOT = './res/';
|
const NET_PORT = parseInt(_PORT);
|
||||||
|
|
||||||
interface FileMapping {
|
const NET_HOST = Deno.env.get('NET_HOST');
|
||||||
endpoints: string[],
|
if (!NET_HOST) throw new Error("No NET_HOST specified in env");
|
||||||
path: string,
|
|
||||||
mime: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const mappings: FileMapping[] = [
|
const WEB_ROOT = Deno.env.get('WEB_ROOT');
|
||||||
{
|
if (!WEB_ROOT) throw new Error("No WEB_ROOT specified in env");
|
||||||
endpoints: ['/', '/index.html'],
|
|
||||||
path: "/index.html",
|
const DIR_ROOT = path.join(Deno.cwd(), WEB_ROOT);
|
||||||
mime: "text/html"
|
const FILES = (await Array.fromAsync(walk(DIR_ROOT))).filter(entry => entry.isFile).map(entry => entry.path.replaceAll(Deno.cwd(), '').replaceAll('\\', '/'));
|
||||||
},
|
|
||||||
{
|
console.log(FILES)
|
||||||
endpoints: ['/style.css'],
|
|
||||||
path: "/style.css",
|
|
||||||
mime: "text/css"
|
|
||||||
}
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
Deno.serve({
|
Deno.serve({
|
||||||
hostname: NET_HOST,
|
hostname: NET_HOST,
|
||||||
@@ -34,21 +29,34 @@ Deno.serve({
|
|||||||
headers: { "Content-Type": "text/plain" }
|
headers: { "Content-Type": "text/plain" }
|
||||||
});
|
});
|
||||||
|
|
||||||
const url = new URL(req.url);
|
try {
|
||||||
|
const url = new URL(req.url);
|
||||||
|
|
||||||
if (url.pathname == '/') url.pathname = '/index.html';
|
if (req.headers.get('user-agent')?.includes("Mobile") && url.pathname == '/') url.pathname = '/mobile.html';
|
||||||
|
else if (url.pathname == '/') url.pathname = '/index.html';
|
||||||
|
|
||||||
const mapping = mappings.find(val => val.endpoints.some(val => url.pathname === val));
|
const match = FILES.find(file => file.replace(WEB_ROOT, '') == url.pathname);
|
||||||
|
|
||||||
console.log(`${addr.remoteAddr.hostname}:${addr.remoteAddr.port} ${req.method} ${url.pathname} | mapping exists: ${typeof mapping !== 'undefined'}`);
|
console.log(`${addr.remoteAddr.hostname}:${addr.remoteAddr.port} ${req.method} ${url.pathname} | mapping exists: ${typeof match !== 'undefined'}`);
|
||||||
return new Promise<Response>(resolve => {
|
return new Promise<Response>(resolve => {
|
||||||
if (mapping) {
|
if (match) {
|
||||||
Deno.readFile(path.join(WEB_ROOT, mapping.path)).then(data => {
|
Deno.readFile(path.join(Deno.cwd(), match)).then(data => {
|
||||||
resolve(new Response(data, { headers: { "Content-Type": mapping.mime }}));
|
const headers = new Headers();
|
||||||
}).catch(reason => {
|
|
||||||
console.error(reason);
|
const last = match.split('/').at(-1);
|
||||||
resolve(notFound);
|
if (last) {
|
||||||
});
|
const mime = contentType(last.substring(last.indexOf('.')));
|
||||||
} else resolve(notFound);
|
if (mime) headers.set("Content-Type", mime);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
resolve(new Response(data, { headers }));
|
||||||
|
}).catch(reason => {
|
||||||
|
console.error(reason);
|
||||||
|
resolve(notFound);
|
||||||
|
});
|
||||||
|
} else resolve(notFound);
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
return notFound;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
BIN
res/imgs/Hatsune_Discord_Banner_BG_Only_Banner_Ratio_.png
Normal file
|
After Width: | Height: | Size: 12 MiB |
BIN
res/imgs/Miku_With_Tag.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
res/imgs/Miku_badge_transparent.png
Normal file
|
After Width: | Height: | Size: 10 MiB |
BIN
res/imgs/New_Drawing1.png
Normal file
|
After Width: | Height: | Size: 3.2 MiB |
BIN
res/imgs/Wing_of_Form.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
res/imgs/Wing_of_Sound.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
res/imgs/absolute_comfy.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
res/imgs/cmpfpf.png
Normal file
|
After Width: | Height: | Size: 241 KiB |
BIN
res/imgs/digiral/Affection_-_Miku_and_Heart_Pose.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
res/imgs/digiral/Angry_-_Miku_and_Punch.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
res/imgs/digiral/Excitement_-_Miku_and_Sparkling_Eyes.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
res/imgs/digiral/Ideas_-_Miku_and_Ideas.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
res/imgs/digiral/Joy_-_Miku_and_Air_Guitar.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
res/imgs/digiral/Relaxed_-_Miku_and_Strawberry_Milk_Tea.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
res/imgs/digiral/Supportive_-_Miku_and_Ganbatte.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
res/imgs/miku_hammer.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
res/imgs/miku_loading_please_wait.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
res/imgs/poco_eevee.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
@@ -8,7 +8,7 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0&icon_names=arrow_downward" />
|
<script src="./script.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@@ -22,19 +22,24 @@
|
|||||||
|
|
||||||
<div style="flex: 1;"></div>
|
<div style="flex: 1;"></div>
|
||||||
|
|
||||||
<h1 style="font-size: 2vw;">See Below</h1>
|
<span style="display: flex; flex-direction: column; align-items: center; width: auto;"><button class="attention" onclick="scrollToHighlights()">VIEW HIGHLIGHTS</button></span>
|
||||||
<span class="material-symbols-outlined" style="text-align: center; user-select: none; font-size: 2vw;">arrow_downward</span>
|
|
||||||
|
|
||||||
<div style="flex: 0.2;"></div>
|
<div style="flex: 0.2;"></div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<hr class="break"></hr>
|
<hr class="break" id="highlights"></hr>
|
||||||
|
|
||||||
<!-- top reactions -->
|
<!-- top reactions -->
|
||||||
<div style="padding: 0 5vw 0 5vw">
|
<div style="padding: 0 5vw 0 5vw">
|
||||||
<h2 style="font-size: 4vw; margin-bottom: 0;"><span style="font-weight: 300;">Is it just me,</span> or is it comfy in here?</h2>
|
<div style="display: flex; align-items: center;">
|
||||||
<h2 style="font-size: 2vw; margin-top: 0;">Here are the top 10 most used reactions:</h2>
|
<h2 style="font-size: 4vw; margin: 0;"><span style="font-weight: 300;">Is it just me,</span> or is it comfy in here?</h2>
|
||||||
<ul>
|
<img src="/imgs/digiral/Relaxed_-_Miku_and_Strawberry_Milk_Tea.png" style="max-height: 10vh; border-radius: 50%;">
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; align-items: center;">
|
||||||
|
<img src="/imgs/absolute_comfy.png" style="max-height: 8vh; border-radius: 50%;">
|
||||||
|
<h2 style="font-size: 2vw; margin: 0;">Here are the top 10 most used reactions:</h2>
|
||||||
|
</div>
|
||||||
|
<ol style="display: flex; align-items: center; flex-direction: column; padding: 0;">
|
||||||
<li class="emoji-line-center">
|
<li class="emoji-line-center">
|
||||||
<img class="emoji" src="https://cdn.discordapp.com/emojis/1136028749557678103.webp?size=128&animated=true" title=":squishycomfy:">
|
<img class="emoji" src="https://cdn.discordapp.com/emojis/1136028749557678103.webp?size=128&animated=true" title=":squishycomfy:">
|
||||||
<span style="padding-left: 10px;">x13,594</span>
|
<span style="padding-left: 10px;">x13,594</span>
|
||||||
@@ -75,16 +80,16 @@
|
|||||||
<img class="emoji" src="https://cdn.discordapp.com/emojis/1175603450852147262.webp?size=128" title=":40Sekai:">
|
<img class="emoji" src="https://cdn.discordapp.com/emojis/1175603450852147262.webp?size=128" title=":40Sekai:">
|
||||||
<span style="padding-left: 10px;">x2,460</span>
|
<span style="padding-left: 10px;">x2,460</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="break"></hr>
|
<hr class="break"></hr>
|
||||||
|
|
||||||
<!-- top emotes -->
|
<!-- top emotes -->
|
||||||
<div style="padding: 0 5vw 0 5vw">
|
<div style="padding: 0 5vw 0 5vw">
|
||||||
<h2 style="font-size: 4vw; margin-bottom: 0;">Add some spice to your message.</h2>
|
<h2 style="font-size: 4vw; margin: 0;">Add some spice to your message.</h2>
|
||||||
<h2 style="font-size: 2vw; margin-top: 0;">Here are the top 10 most used emojis:</h2>
|
<h2 style="font-size: 2vw; margin: 0;">Here are the top 10 most used emojis:</h2>
|
||||||
<ul>
|
<ol style="display: flex; align-items: center; flex-direction: column; padding: 0;">
|
||||||
<li class="emoji-line-center">
|
<li class="emoji-line-center">
|
||||||
<img class="emoji" src="https://cdn.discordapp.com/emojis/960550152689582171.webp?size=128" title=":mikukek:">
|
<img class="emoji" src="https://cdn.discordapp.com/emojis/960550152689582171.webp?size=128" title=":mikukek:">
|
||||||
<span style="padding-left: 10px;">x10,285</span>
|
<span style="padding-left: 10px;">x10,285</span>
|
||||||
@@ -125,16 +130,19 @@
|
|||||||
<img class="emoji" src="https://cdn.discordapp.com/emojis/1173317846676275230.webp?size=128" title=":Miku39Sekai:">
|
<img class="emoji" src="https://cdn.discordapp.com/emojis/1173317846676275230.webp?size=128" title=":Miku39Sekai:">
|
||||||
<span style="padding-left: 10px;">x2,394</span>
|
<span style="padding-left: 10px;">x2,394</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="break"></hr>
|
<hr class="break"></hr>
|
||||||
|
|
||||||
<!-- top stickers -->
|
<!-- top stickers -->
|
||||||
<div style="padding: 0 5vw 0 5vw">
|
<div style="padding: 0 5vw 0 5vw;">
|
||||||
<h2 style="font-size: 4vw; margin-bottom: 0;">Stickerbomb!</h2>
|
<div style="display: flex; align-items: center;">
|
||||||
<h2 style="font-size: 2vw; margin-top: 0;">Here are the top 10 most used stickers:</h2>
|
<h2 style="font-size: 4vw; margin: 0 10px 0 0;">Stickerbomb!</h2>
|
||||||
<ul>
|
<img src="/imgs/digiral/Joy_-_Miku_and_Air_Guitar.png" style="max-height: 10vh; border-radius: 50%;">
|
||||||
|
</div>
|
||||||
|
<h2 style="font-size: 2vw; margin: 0;">Here are the top 10 most used stickers:</h2>
|
||||||
|
<ol style="display: flex; align-items: center; flex-direction: column; padding: 0;">
|
||||||
<li class="emoji-line-center">
|
<li class="emoji-line-center">
|
||||||
<img class="emoji" src="https://media.discordapp.net/stickers/1421313906953158848.png?size=128&quality=lossless" title="Best Friend 39">
|
<img class="emoji" src="https://media.discordapp.net/stickers/1421313906953158848.png?size=128&quality=lossless" title="Best Friend 39">
|
||||||
<span style="padding-left: 10px;">x624</span>
|
<span style="padding-left: 10px;">x624</span>
|
||||||
@@ -175,27 +183,28 @@
|
|||||||
<img class="emoji" src="https://media.discordapp.net/stickers/1152286791706083389.png?size=128&quality=lossless" title="Show">
|
<img class="emoji" src="https://media.discordapp.net/stickers/1152286791706083389.png?size=128&quality=lossless" title="Show">
|
||||||
<span style="padding-left: 10px;">x110</span>
|
<span style="padding-left: 10px;">x110</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="break"></hr>
|
<hr class="break"></hr>
|
||||||
|
|
||||||
<!-- # of messages -->
|
<!-- # of messages -->
|
||||||
<div class="column-display" style="min-height: 75svh;">
|
<div class="column-display" style="min-height: 75svh; align-items: center;">
|
||||||
<div style="flex: 0.2;"></div>
|
|
||||||
<h1 style="font-size: 5vw; text-align: center; margin-bottom: 0;">Let's talk messages.</h1>
|
|
||||||
<h1 style="font-size: 6vw; text-align: center; font-weight: 300; margin-top: 0;">We sent <span style="font-weight: 900;">1,091,742 of them.</span></h1>
|
|
||||||
<h1 style="font-size: 2vw; text-align: center;">Jeez.</h1>
|
|
||||||
<div style="flex: 0.2;"></div>
|
<div style="flex: 0.2;"></div>
|
||||||
|
<h1 style="font-size: 5vw; text-align: center; margin: 0;">Let's talk messages.</h1>
|
||||||
|
<h1 style="font-size: 6vw; text-align: center; font-weight: 300; margin: 0;">We sent <span style="font-weight: 900;">1,091,742 of them.</span></h1>
|
||||||
|
<h1 style="font-size: 2vw; text-align: center; margin: 0;">We're glad you spent this much time with us.</h1>
|
||||||
|
<div style="flex: 0.1;"></div>
|
||||||
|
<img style="max-width: 16vw; border-radius: 50%;" src="/imgs/digiral/Excitement_-_Miku_and_Sparkling_Eyes.png">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="break"></hr>
|
<hr class="break"></hr>
|
||||||
|
|
||||||
<!-- top message reactions -->
|
<!-- top message reactions -->
|
||||||
<div style="padding: 0 5vw 0 5vw; font-size: 1.5vw;">
|
<div style="padding: 0 5vw 0 5vw; font-size: 1.5vw;">
|
||||||
<h2 style="font-size: 3.2vw; margin-bottom: 0;">Some of those messages were pretty popular.</h2>
|
<h2 style="font-size: 3.2vw; margin: 0;">Some of those messages were pretty popular.</h2>
|
||||||
<h2 style="font-size: 2vw; margin-top: 0;">Here are each month's most reacted messages:</h2>
|
<h2 style="font-size: 2vw; margin: 0;">Here are each month's most reacted messages:</h2>
|
||||||
<ul>
|
<ul style="display: flex; align-items: center; flex-direction: column; padding: 0;">
|
||||||
<li>January: <a href="https://discord.com/channels/959218185356328960/960712970831278180/1327391825639506022" style="color: white;">#general-01 by powerblade3</a> - 220</li>
|
<li>January: <a href="https://discord.com/channels/959218185356328960/960712970831278180/1327391825639506022" style="color: white;">#general-01 by powerblade3</a> - 220</li>
|
||||||
<li>February: <a href="https://discord.com/channels/959218185356328960/960712970831278180/1336869960051462214" style="color: white;">#general-01 by mikuoctoling39</a> - 119</li>
|
<li>February: <a href="https://discord.com/channels/959218185356328960/960712970831278180/1336869960051462214" style="color: white;">#general-01 by mikuoctoling39</a> - 119</li>
|
||||||
<li>March: <a href="https://discord.com/channels/959218185356328960/960712970831278180/1349444678029938739" style="color: white;">#general-01 by miku.hatsune</a> - 99</li>
|
<li>March: <a href="https://discord.com/channels/959218185356328960/960712970831278180/1349444678029938739" style="color: white;">#general-01 by miku.hatsune</a> - 99</li>
|
||||||
@@ -215,9 +224,9 @@
|
|||||||
|
|
||||||
<!-- top message counts -->
|
<!-- top message counts -->
|
||||||
<div style="padding: 0 5vw 0 5vw; font-size: 1.5vw;">
|
<div style="padding: 0 5vw 0 5vw; font-size: 1.5vw;">
|
||||||
<h2 style="font-size: 3.2vw; margin-bottom: 0;">We had several keyboard enthusiasts.</h2>
|
<h2 style="font-size: 3.2vw; margin: 0;">We had several keyboard enthusiasts.</h2>
|
||||||
<h2 style="font-size: 2vw; margin-top: 0;">Here are the top 10 users with the most messages:</h2>
|
<h2 style="font-size: 2vw; margin: 0;">Here are the top 10 users with the most messages:</h2>
|
||||||
<ul>
|
<ol style="display: flex; align-items: center; flex-direction: column; padding: 0;">
|
||||||
<li>@miraigummies - 52,746</li>
|
<li>@miraigummies - 52,746</li>
|
||||||
<li>@koolaidkan - 42,391</li>
|
<li>@koolaidkan - 42,391</li>
|
||||||
<li>@iam_stove - 35,365</li>
|
<li>@iam_stove - 35,365</li>
|
||||||
@@ -228,16 +237,19 @@
|
|||||||
<li>@zunda_nectar - 28,119</li>
|
<li>@zunda_nectar - 28,119</li>
|
||||||
<li>@simplename21 - 23,234</li>
|
<li>@simplename21 - 23,234</li>
|
||||||
<li>@kelcody - 22,782</li>
|
<li>@kelcody - 22,782</li>
|
||||||
</ul>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="break"></hr>
|
<hr class="break"></hr>
|
||||||
|
|
||||||
<!-- top 39 interactions -->
|
<!-- top 39 interactions -->
|
||||||
<div style="padding: 0 5vw 0 5vw; font-size: 1.5vw;">
|
<div style="padding: 0 5vw 0 5vw; font-size: 1.5vw;">
|
||||||
<h2 style="font-size: 3.2vw; margin-bottom: 0;">You were always here with us.</h2>
|
<div style="display: flex; align-items: center;">
|
||||||
<h2 style="font-size: 2vw; margin-top: 0;">Here are the top 10 users with the most '39' messages:</h2>
|
<h2 style="font-size: 4vw; margin: 0 10px 0 0;">You were always here with us.</h2>
|
||||||
<ul>
|
<img src="/imgs/digiral/Affection_-_Miku_and_Heart_Pose.png" style="max-height: 10vh; border-radius: 50%;">
|
||||||
|
</div>
|
||||||
|
<h2 style="font-size: 2vw; margin: 0;">Here are the top 10 users with the most '39' messages:</h2>
|
||||||
|
<ol style="display: flex; align-items: center; flex-direction: column; padding: 0;">
|
||||||
<li>@iam_stove - 3,790</li>
|
<li>@iam_stove - 3,790</li>
|
||||||
<li>@aozora39 - 3,445</li>
|
<li>@aozora39 - 3,445</li>
|
||||||
<li>@cfm_megurine_luka - 3,325</li>
|
<li>@cfm_megurine_luka - 3,325</li>
|
||||||
@@ -247,8 +259,8 @@
|
|||||||
<li>@the_apricity_effect - 1,706</li>
|
<li>@the_apricity_effect - 1,706</li>
|
||||||
<li>@yokoo99 - 1,354</li>
|
<li>@yokoo99 - 1,354</li>
|
||||||
<li>@_1v40_ - 1,294</li>
|
<li>@_1v40_ - 1,294</li>
|
||||||
<li>@iam_stove - 1,262</li>
|
<li>@39.mik - 1,262</li>
|
||||||
</ul>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="break"></hr>
|
<hr class="break"></hr>
|
||||||
@@ -256,6 +268,10 @@
|
|||||||
<h2 style="font-size: 2.6vw; text-align: center;">Thank you all for a great year! We're here to share the next with you.</h2>
|
<h2 style="font-size: 2.6vw; text-align: center;">Thank you all for a great year! We're here to share the next with you.</h2>
|
||||||
|
|
||||||
<footer style="padding: 3vh 0 3vh;">
|
<footer style="padding: 3vh 0 3vh;">
|
||||||
|
<div style="text-align: center;">
|
||||||
|
Credits for art on this page: @aozora39; @bready_todie; @miraigummies; @digiral; @miku.hatsune; among others of unknown origin.<br>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
<div style="text-align: center;">
|
<div style="text-align: center;">
|
||||||
<a href="https://gitea.proxnet.dev/zombieb/hatsune-2025-stats" style="color: white;">Open-source.</a>
|
<a href="https://gitea.proxnet.dev/zombieb/hatsune-2025-stats" style="color: white;">Open-source.</a>
|
||||||
100% human-generated. Page design by (@zombieb). Data by (@poco0317).
|
100% human-generated. Page design by (@zombieb). Data by (@poco0317).
|
||||||
|
|||||||
17
res/mobile.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Hatsune 2025 Stats</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="./style-mobile.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Please note that this page was designed for desktop viewing.</h2>
|
||||||
|
<a href="/index.html">Press here to continue.</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
9
res/script.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// deno-lint-ignore no-unused-vars
|
||||||
|
function scrollToHighlights() {
|
||||||
|
const element = document.getElementById("highlights");
|
||||||
|
element.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
block: 'start'
|
||||||
|
});
|
||||||
|
console.log("scroll")
|
||||||
|
}
|
||||||
14
res/style-mobile.css
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 5vw 0 5vw;
|
||||||
|
|
||||||
|
font-family: "DM Sans", sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
background-color: #323232;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
@@ -10,8 +10,7 @@ body {
|
|||||||
|
|
||||||
font-family: "DM Sans", sans-serif;
|
font-family: "DM Sans", sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
background: #12db9f;
|
background: linear-gradient(180deg, rgb(49, 49, 49) 98%, rgb(0, 61, 57) 100%);
|
||||||
background: linear-gradient(180deg,rgb(49, 49, 49) 99%, rgb(0, 61, 57) 100%);
|
|
||||||
|
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
@@ -40,3 +39,27 @@ body {
|
|||||||
.emoji {
|
.emoji {
|
||||||
width: 128px;
|
width: 128px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 12vw;
|
||||||
|
height: 6vh;
|
||||||
|
|
||||||
|
border: none;
|
||||||
|
border-radius: 12vw;
|
||||||
|
|
||||||
|
font-size: larger;
|
||||||
|
font-family: "DM Sans", sans-serif;
|
||||||
|
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
background-color: #0ca97a;
|
||||||
|
transition: background-color 100ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover,
|
||||||
|
focus,
|
||||||
|
active {
|
||||||
|
background-color: #0fc28c;
|
||||||
|
}
|
||||||