deps: upgrade takumi to v1, fix visual bugs

This commit is contained in:
2026-05-06 02:15:41 +07:00 Unverified
parent a32172c3de
commit 0c90d47120
5 changed files with 72 additions and 59 deletions
+14 -17
View File
@@ -7,12 +7,12 @@
"dependencies": { "dependencies": {
"@elysiajs/openapi": "^1.4.14", "@elysiajs/openapi": "^1.4.14",
"@napi-rs/canvas": "^0.1.96", "@napi-rs/canvas": "^0.1.96",
"@takumi-rs/image-response": "^0.71.7",
"@types/react": "^19.2.14", "@types/react": "^19.2.14",
"elysia": "latest", "elysia": "latest",
"enka.ts": "^1.1.10", "enka.ts": "^1.1.10",
"react": "^19.2.4", "react": "^19.2.4",
"react-dom": "^19.2.4", "react-dom": "^19.2.4",
"takumi-js": "1",
}, },
"devDependencies": { "devDependencies": {
"@elysia/cors": "^1.4.2", "@elysia/cors": "^1.4.2",
@@ -23,9 +23,6 @@
}, },
}, },
}, },
"patchedDependencies": {
"@takumi-rs/[email protected]": "patches/@takumi-rs%[email protected]",
},
"packages": { "packages": {
"@borewit/text-codec": ["@borewit/[email protected]", "", {}, "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw=="], "@borewit/text-codec": ["@borewit/[email protected]", "", {}, "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw=="],
@@ -135,29 +132,27 @@
"@sinclair/typebox": ["@sinclair/[email protected]", "", {}, "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA=="], "@sinclair/typebox": ["@sinclair/[email protected]", "", {}, "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA=="],
"@takumi-rs/core": ["@takumi-rs/core@0.71.7", "", { "optionalDependencies": { "@takumi-rs/core-darwin-arm64": "0.71.7", "@takumi-rs/core-darwin-x64": "0.71.7", "@takumi-rs/core-linux-arm64-gnu": "0.71.7", "@takumi-rs/core-linux-arm64-musl": "0.71.7", "@takumi-rs/core-linux-x64-gnu": "0.71.7", "@takumi-rs/core-linux-x64-musl": "0.71.7", "@takumi-rs/core-win32-arm64-msvc": "0.71.7", "@takumi-rs/core-win32-x64-msvc": "0.71.7" } }, "sha512-5wWs4GNMOcHsJQ6dhpAe0Fk/2mUy40AL2cETSqrt/H21xsGGSsCacGpPpPoIqK4DwdoJyFxoxLwhDGId8WrzOA=="], "@takumi-rs/core": ["@takumi-rs/core@1.1.2", "", { "dependencies": { "@takumi-rs/helpers": "1.1.2" }, "optionalDependencies": { "@takumi-rs/core-darwin-arm64": "1.1.2", "@takumi-rs/core-darwin-x64": "1.1.2", "@takumi-rs/core-linux-arm64-gnu": "1.1.2", "@takumi-rs/core-linux-arm64-musl": "1.1.2", "@takumi-rs/core-linux-x64-gnu": "1.1.2", "@takumi-rs/core-linux-x64-musl": "1.1.2", "@takumi-rs/core-win32-arm64-msvc": "1.1.2", "@takumi-rs/core-win32-x64-msvc": "1.1.2" } }, "sha512-JI0kUis5MCPzOt2sCahBZLVJERpp1t1fXTRBaBbCGploUa/hqRA9HW6Nr+tccDM/C6wy9FDrJnI4SB56W0HfDA=="],
"@takumi-rs/core-darwin-arm64": ["@takumi-rs/core-darwin-arm64@0.71.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-mcW/ikpqj4QToZfvC6JY1nxnCpnvioOUm9QsXiGnjmr7z/zei1Xf4GKl67P/3dEXU6bi7gqsmEf+XOc66E6taQ=="], "@takumi-rs/core-darwin-arm64": ["@takumi-rs/core-darwin-arm64@1.1.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-CLPzikYAND2xFm0Lg5HKImCOnl+Sue4F/WIcm1Z2ykL7h2r9rWDBzcFqGhAEFj9onMJH6c60Mph8kDa1jdj2rQ=="],
"@takumi-rs/core-darwin-x64": ["@takumi-rs/core-darwin-x64@0.71.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-xvhulaXxTWxpMsj7Fqm88KpltQstz6cR2gW1CijdPQd/DEi+k5xso3AM/kH/E80qxCXYItbyyZlLlG7gog9mzg=="], "@takumi-rs/core-darwin-x64": ["@takumi-rs/core-darwin-x64@1.1.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-eH351x+BJOMdLQgUoVKEIfTQbBjR6Dv7rzTLZUdWwbbwjEe38geCNsxQunHQ96nsB7M+0sGc8aJjOkd+0qoK3g=="],
"@takumi-rs/core-linux-arm64-gnu": ["@takumi-rs/core-linux-arm64-gnu@0.71.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-H3JBWt0DlfCMinAMvQyaG3cUF1hI6/f+tSzgXSezg/J8f+vYJaOBOBAE8YXLtBb/+VZe5RzyvMgNsT1+6LNrMw=="], "@takumi-rs/core-linux-arm64-gnu": ["@takumi-rs/core-linux-arm64-gnu@1.1.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-2cuSnKWAfQjQwS+7aprz0LRkztPVsGqWGTto0TydVI81z7sNyC4kZWoJMTpkNb3439HB03UBStQVacgUeVOL+w=="],
"@takumi-rs/core-linux-arm64-musl": ["@takumi-rs/core-linux-arm64-musl@0.71.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-QkFSh0qabNioGGvZYmXqkTCeuyUAlfkhClo7sl6jfnU2wodG2f0sIcvVLPLshRQBUbY6Rf8ktjp75TVQZFw1HQ=="], "@takumi-rs/core-linux-arm64-musl": ["@takumi-rs/core-linux-arm64-musl@1.1.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-7OIdvVy6lbr49LIBe96uvlOg4Awmye5w+DgL4d0rRi1Zv7bmY23ciBCGaM+7jjkZgcThGrlZKz1Ecopx56pPqA=="],
"@takumi-rs/core-linux-x64-gnu": ["@takumi-rs/core-linux-x64-gnu@0.71.7", "", { "os": "linux", "cpu": "x64" }, "sha512-CNSR1x2OPjlnpqY6nksTsp0bTp+41IbXE85TwippLST5NrRokL9xKJ6EM+AFaSfLH/0gy+XMgtOQoD1C+TFDUA=="], "@takumi-rs/core-linux-x64-gnu": ["@takumi-rs/core-linux-x64-gnu@1.1.2", "", { "os": "linux", "cpu": "x64" }, "sha512-IXEhQjGSGye+kwawDad00kN2cLpj1rPF5u0K4KsANvWxa/dho32Nnw+RX8cCtPGiuvEKhtENxtdc7pVSx1E84g=="],
"@takumi-rs/core-linux-x64-musl": ["@takumi-rs/core-linux-x64-musl@0.71.7", "", { "os": "linux", "cpu": "x64" }, "sha512-xDtS7YuFkr6UtaJ812cxbkx8d0ShzxavQwz59YSTCB1Q0aiW9fnAu7WZeP9rrPRctn3y5sp3DUVyzONvwfCa1w=="], "@takumi-rs/core-linux-x64-musl": ["@takumi-rs/core-linux-x64-musl@1.1.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Q2vuZCwQ/XmHwwbJxSKNNEKdWdhsvBMhTF8pyyGti5s44yx7W6+a0MkDdMRAkStzDhH6HeZlpknpHcUk4R4g8w=="],
"@takumi-rs/core-win32-arm64-msvc": ["@takumi-rs/core-win32-arm64-msvc@0.71.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-2AhdKHby2Hor+d3yrhiZNpght7YXItWN1WXNiK/m/uqKKlmrq7oqgUmdn0/5ks5cZ/JaLjfsLFlgIB2uPReFYA=="], "@takumi-rs/core-win32-arm64-msvc": ["@takumi-rs/core-win32-arm64-msvc@1.1.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-CKpslxYCltih/lL+h7xkVzsfIZtDcXp3WGk01fudgx82Ic87b/jjRMX5KE4f/exkgrKxshRF4yCQGGeQ3vIhiw=="],
"@takumi-rs/core-win32-x64-msvc": ["@takumi-rs/core-win32-x64-msvc@0.71.7", "", { "os": "win32", "cpu": "x64" }, "sha512-jZLSrrCv118zP1yAXURjHdHtpWswEiml3mwbJ+ypHKPaLppstpPtQVwRyOUe2GBC/OIGjz1lLl8dEKucJ+P67Q=="], "@takumi-rs/core-win32-x64-msvc": ["@takumi-rs/core-win32-x64-msvc@1.1.2", "", { "os": "win32", "cpu": "x64" }, "sha512-c+n2vPpDscMuTHZ29eJp8did5tlJ/KKBKicc51D6AdkA5jhr7MLeryzIKe3ob59iQttWYd/1j4+tUwoO6yEusg=="],
"@takumi-rs/helpers": ["@takumi-rs/helpers@0.71.7", "", {}, "sha512-OipwcnYZjfZz6OJ/sUdvUDkVfe/n5TksdB4sBuSmN+qoCpu42usdd3VPOHHdARZyHgbahxaNmnPSqfE5HGI47w=="], "@takumi-rs/helpers": ["@takumi-rs/helpers@1.1.2", "", { "peerDependencies": { "react": "^19.2.5", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["react", "react-dom"] }, "sha512-Edvmk7UzPhlbUCYpIqeBBfq9h/lAeWAhtwIhJJ10vxv7qNWjgfIPakzNWeAYhFVj8KT5y47S3RLT3cKVniqI5g=="],
"@takumi-rs/image-response": ["@takumi-rs/[email protected]1.7", "", { "dependencies": { "@takumi-rs/core": "0.71.7", "@takumi-rs/helpers": "0.71.7", "@takumi-rs/wasm": "0.71.7" } }, "sha512-CRdhVEJqKse9+eovVc8CGHisCAXxPNRuZZJ2tUHzrDBFGaNp99+tX6hAim7wUWbo+NEXN7KOkaESqp/MCrhUbw=="], "@takumi-rs/wasm": ["@takumi-rs/wasm@1.1.2", "", { "dependencies": { "@takumi-rs/helpers": "1.1.2" } }, "sha512-in2kLgFp6nuXie5q7blvRk8m/3UuvNDtc5SEFUh6Eu2yn20PcElj1VMdXhQhn+IN0h119BUWWdJ3AuEuh8PiDg=="],
"@takumi-rs/wasm": ["@takumi-rs/[email protected]", "", {}, "sha512-yoau96mSOvG4kSSdypWfpvAacjK4r5tHlg90kOkAcXDp/UFe3npEwNsGe5DzHdKqTpHWsr2tzmEdhjnZW4v2VQ=="],
"@tokenizer/inflate": ["@tokenizer/[email protected]", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="], "@tokenizer/inflate": ["@tokenizer/[email protected]", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="],
@@ -207,6 +202,8 @@
"strtok3": ["[email protected]", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="], "strtok3": ["[email protected]", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="],
"takumi-js": ["[email protected]", "", { "dependencies": { "@takumi-rs/core": "1.1.2", "@takumi-rs/helpers": "1.1.2", "@takumi-rs/wasm": "1.1.2" } }, "sha512-S8Ff0zBUQJ8VC40r7y1RPBo5QXFXV3U868M+T8B8JGt5Tko8l83DVEr1BYLOxqUenEeev853S708oE0aD50eZA=="],
"tinypool": ["[email protected]", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="], "tinypool": ["[email protected]", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="],
"token-types": ["[email protected]", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="], "token-types": ["[email protected]", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="],
+26 -11
View File
@@ -164,13 +164,30 @@
const me = edgeAt(mineData, x, y); const me = edgeAt(mineData, x, y);
const oe = edgeAt(origData, x, y); const oe = edgeAt(origData, x, y);
const mr = me > t ? 255 : 0; const mineEdge = me > t;
const og = oe > t ? 255 : 0; const origEdge = oe > t;
o[i] = mr; // mine = red if (mineEdge && origEdge) {
o[i + 1] = og; // original = green // matching = green
o[i + 2] = 0; o[i] = 0;
o[i + 3] = Math.max(mr, og); o[i + 1] = 255;
o[i + 2] = 0;
o[i + 3] = 255;
} else if (origEdge) {
// original missing from mine = red
o[i] = 255;
o[i + 1] = 0;
o[i + 2] = 0;
o[i + 3] = 255;
} else if (mineEdge) {
// extra in mine = yellow
o[i] = 255;
o[i + 1] = 255;
o[i + 2] = 0;
o[i + 3] = 255;
} else {
o[i + 3] = 0;
}
} }
else if (mode.value === "diff") { else if (mode.value === "diff") {
@@ -207,7 +224,6 @@
ctx.fillText(String(err), 20, 30); ctx.fillText(String(err), 20, 30);
}); });
// ENTER = refresh (anywhere, unless typing in input)
window.addEventListener("keydown", (e) => { window.addEventListener("keydown", (e) => {
if (e.key === "Enter" && !["INPUT", "SELECT"].includes(e.target.tagName)) { if (e.key === "Enter" && !["INPUT", "SELECT"].includes(e.target.tagName)) {
e.preventDefault(); e.preventDefault();
@@ -215,10 +231,9 @@
} }
}); });
// WINDOW FOCUS = refresh // window.addEventListener("focus", () => {
window.addEventListener("focus", () => { // refresh();
refresh(); // });
});
</script> </script>
</body> </body>
+2 -2
View File
@@ -10,12 +10,12 @@
"dependencies": { "dependencies": {
"@elysiajs/openapi": "^1.4.14", "@elysiajs/openapi": "^1.4.14",
"@napi-rs/canvas": "^0.1.96", "@napi-rs/canvas": "^0.1.96",
"@takumi-rs/image-response": "^0.71.7",
"@types/react": "^19.2.14", "@types/react": "^19.2.14",
"elysia": "latest", "elysia": "latest",
"enka.ts": "^1.1.10", "enka.ts": "^1.1.10",
"react": "^19.2.4", "react": "^19.2.4",
"react-dom": "^19.2.4" "react-dom": "^19.2.4",
"takumi-js": "1"
}, },
"devDependencies": { "devDependencies": {
"@elysia/cors": "^1.4.2", "@elysia/cors": "^1.4.2",
+29 -28
View File
@@ -1,6 +1,5 @@
import { feature } from "bun:bundle"; import { feature } from "bun:bundle";
import { ImageResponse } from "@takumi-rs/image-response";
import { file, hash, inspect } from "bun"; import { file, hash, inspect } from "bun";
import { status, t } from "elysia"; import { status, t } from "elysia";
import { import {
@@ -13,6 +12,7 @@ import {
RatelimitError, RatelimitError,
TTLCache, TTLCache,
} from "enka.ts"; } from "enka.ts";
import { ImageResponse } from "takumi-js/response";
import { generateBackground } from "@/assets/background"; import { generateBackground } from "@/assets/background";
import { ConstsSvg } from "@/assets/consts"; import { ConstsSvg } from "@/assets/consts";
@@ -469,22 +469,23 @@ export function card(app: App) {
// #region Rendering // #region Rendering
const res = new ImageResponse( const res = new ImageResponse(
<div tw={`text-[${30.466 * (height / 1024)}px]`}> <div
tw={`flex text-[${30.466 * (height / 1024)}px] font-[ShinShin]`}
>
<SubstatDisplay <SubstatDisplay
substat={rollSummary} substat={rollSummary}
element={avatar.Element} element={avatar.Element}
> >
<div <div
tw={`relative text-white rounded-[.5em] overflow-hidden aspect-[1218/508] h-[${height}px]`} tw={`flex relative text-white rounded-[.5em] overflow-hidden aspect-[1218/508] h-[${height}px]`}
> >
<div tw="aspect-[1218/508] h-full"> <div tw="flex aspect-[1218/508] h-full">
<img <img
src={`/bg-${avatar.Element}`} src={`/bg-${avatar.Element}`}
alt="background" alt="background"
tw="w-full h-full object-cover" tw="w-full h-full object-cover"
/> />
</div> </div>
{/* left section */} {/* left section */}
<div <div
tw="absolute top-0 bottom-0 left-0 w-[30.4em] p-[1.6em] flex flex-col" tw="absolute top-0 bottom-0 left-0 w-[30.4em] p-[1.6em] flex flex-col"
@@ -504,13 +505,13 @@ export function card(app: App) {
}} }}
/> />
{/* left side vignette */} {/* left side vignette */}
<div tw="absolute top-0 left-0 bottom-0 right-0"> <div tw="flex absolute top-0 left-0 bottom-0 right-0">
<img src="shade" alt="shade" tw="opacity-40" /> <img src="shade" alt="shade" tw="opacity-40" />
</div> </div>
{/* char and username */} {/* char and username */}
<div tw="text-[120%] pb-[.5%] flex items-center gap-[.5em]"> <div tw="text-[120%] pb-[.5%] flex items-center gap-[.5em]">
{char.avatar.name} {char.avatar.name}
<div tw="text-[0.75em] opacity-80 flex items-center gap-[.7em] pl-[.4em] pt-[.5em]"> <div tw="text-[0.77em] opacity-80 flex items-center gap-[.7em] pl-[.28em] pt-[.5em]">
<svg <svg
width="16" width="16"
height="16" height="16"
@@ -527,12 +528,12 @@ export function card(app: App) {
</div> </div>
</div> </div>
{/* level */} {/* level */}
<div tw="text-[105%] pt-[.2em]"> <div tw="flex text-[102%] pt-[.3em]">
Lv. <span tw="px-[.3em]">{charLvl}</span> / Lv. <span tw="px-[.1em]">{charLvl}</span> /
<span tw="opacity-60 pl-[.3em]">{charLvlMax}</span> <span tw="opacity-60 pl-[.3em]">{charLvlMax}</span>
</div> </div>
{/* fren */} {/* fren */}
<div tw="text-[110%] flex gap-[.3em] items-end pt-[.3em]"> <div tw="text-[110%] flex gap-[.3em] items-end pt-[.35em]">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
tw="h-[1.2em] mb-[.2em]" tw="h-[1.2em] mb-[.2em]"
@@ -546,9 +547,8 @@ export function card(app: App) {
</svg> </svg>
{char.fetterInfo?.expLevel ?? 0} {char.fetterInfo?.expLevel ?? 0}
</div> </div>
{/* sep */} {/* sep */}
<div tw="grow" /> <div tw="flex grow" />
{/* constellation */} {/* constellation */}
<div <div
tw="flex align-start flex-col text-[1.12em]" tw="flex align-start flex-col text-[1.12em]"
@@ -558,7 +558,8 @@ export function card(app: App) {
<div <div
style={{ style={{
position: "relative", position: "relative",
margin: "-.5em 0 0em -.6em", display: "flex",
margin: "-.55em 0 0em -.6em",
}} }}
> >
<ConstsSvg <ConstsSvg
@@ -602,7 +603,7 @@ export function card(app: App) {
const talentLevel = const talentLevel =
(char.skillLevelMap?.[key] ?? 0) + extra; (char.skillLevelMap?.[key] ?? 0) + extra;
return ( return (
<div tw="mt-[.6em] relative"> <div tw="mt-[.6em] relative flex">
<TalentSvg <TalentSvg
tw={`Talents ${avatar.Element} w-[3.6em] opacity-60 text-black mb-[.5em] -mt-[.25em]`} tw={`Talents ${avatar.Element} w-[3.6em] opacity-60 text-black mb-[.5em] -mt-[.25em]`}
/> />
@@ -610,11 +611,11 @@ export function card(app: App) {
key={key} key={key}
src={src} src={src}
alt={`Talent ${key}`} alt={`Talent ${key}`}
tw="w-[2.5em] absolute left-[.15em] top-[.15em] m-[.4em_0_0_.4em]" tw="w-[2.5em] absolute left-[.15em] top-[.05em] m-[.4em_0_0_.4em]"
/> />
<div tw="absolute -bottom-[.1em] w-full flex justify-center"> <div tw="absolute -bottom-[.1em] w-full flex justify-center">
<div <div
tw={`${extra ? "bg-[#45deffcc]" : "bg-[#323232b3]"} pt-[5%] pb-[2%] text-[.8em] rounded-[1.4em]`} tw={`${extra ? "bg-[#45deffcc]" : "bg-[#323232b3]"} pt-[5%] pb-[2%] text-[.85em] rounded-[1.4em]`}
> >
<span tw="px-[.6em]">{talentLevel}</span> <span tw="px-[.6em]">{talentLevel}</span>
</div> </div>
@@ -623,7 +624,7 @@ export function card(app: App) {
); );
})} })}
</div> </div>
<div tw="mb-[-1em] ml-[-.3em] mt-[.3em] text-[.96em] opacity-80"> <div tw="flex mb-[-1em] ml-[-.3em] mt-[.3em] text-[.96em] opacity-80">
{data.uid} {data.uid}
</div> </div>
</div> </div>
@@ -632,7 +633,7 @@ export function card(app: App) {
{/* weapon */} {/* weapon */}
<div tw="flex flex-start" className="Weapon"> <div tw="flex flex-start" className="Weapon">
{/* display */} {/* display */}
<div tw="w-[27%] leading-none shrink-0 min-h-[5.5em] relative"> <div tw="flex w-[27%] leading-none shrink-0 min-h-[5.5em] relative">
<img src="/weapon" alt="Weapon" tw="w-full" /> <img src="/weapon" alt="Weapon" tw="w-full" />
<WeaponGlazeSvg <WeaponGlazeSvg
tw="absolute top-[90%] -left-[15%] w-[130%]" tw="absolute top-[90%] -left-[15%] w-[130%]"
@@ -655,7 +656,7 @@ export function card(app: App) {
{/* caption */} {/* caption */}
<div tw="px-[5%] grow text-white self-center flex flex-col"> <div tw="px-[5%] grow text-white self-center flex flex-col">
<div <div
tw="text-[108%] leading-[1.3]" tw="flex text-[108%] leading-[1.3]"
style={{ style={{
textShadow: textShadow:
"0 .08em .1em rgba(0,0,0,.4),0 .1em .3em rgba(0,0,0,.4)", "0 .08em .1em rgba(0,0,0,.4),0 .1em .3em rgba(0,0,0,.4)",
@@ -740,11 +741,11 @@ export function card(app: App) {
</div> </div>
</div> </div>
{i < 3 && ( {i < 3 && (
<div tw="text-[.83em] opacity-70 absolute w-full -bottom-[.75em]"> <div tw="flex text-[.83em] opacity-70 absolute w-full -bottom-[.75em]">
<div tw="flex grow justify-end"> <div tw="flex grow justify-end">
<div> <div tw="flex">
{Math.round(r.base)} {Math.round(r.base)}
<div tw="text-[#82ff9a] pl-1"> <div tw="flex text-[#82ff9a] pl-1">
+{Math.round(r.delta)} +{Math.round(r.delta)}
</div> </div>
</div> </div>
@@ -770,7 +771,7 @@ export function card(app: App) {
<div tw="grow flex justify-center items-center leading-none text-[#90ee90] whitespace-nowrap overflow-ellipsis overflow-hidden px-[.3em]"> <div tw="grow flex justify-center items-center leading-none text-[#90ee90] whitespace-nowrap overflow-ellipsis overflow-hidden px-[.3em]">
{s.set} {s.set}
</div> </div>
<div tw="bg-[#00000030] rounded-[.2em] justify-center items-center w-[2em] ml-[.5em] shrink-0 pt-[.2em]"> <div tw="flex bg-[#00000030] rounded-[.2em] justify-center items-center w-[2em] ml-[.5em] shrink-0 pt-[.2em]">
{s.count} {s.count}
</div> </div>
</div> </div>
@@ -842,7 +843,7 @@ export function card(app: App) {
}} }}
> >
{Array(p.Position).fill( {Array(p.Position).fill(
<div tw="bg-[#fff8] w-1 h-1 mr-[3px] mb-[3px] rounded-full" />, <div tw="flex bg-[#fff8] w-1 h-1 mr-[3px] mb-[3px] rounded-full" />,
)} )}
</div> </div>
))} ))}
@@ -852,7 +853,7 @@ export function card(app: App) {
icon={s.appendPropId} icon={s.appendPropId}
tw="h-[1.1em] w-[1.1em]" tw="h-[1.1em] w-[1.1em]"
/> />
<div tw="text-[1.05em]"> <div tw="flex text-[1.05em]">
+ +
{PercentageFightProp.includes( {PercentageFightProp.includes(
s.appendPropId as (typeof PercentageFightProp)[number], s.appendPropId as (typeof PercentageFightProp)[number],
@@ -865,7 +866,7 @@ export function card(app: App) {
</div> </div>
</div> </div>
) : ( ) : (
<div tw="h-[18%] bg-[#0000004f] rounded-[.3em] opacity-20" /> <div tw="flex h-[18%] bg-[#0000004f] rounded-[.3em] opacity-20" />
), ),
)} )}
</div> </div>
@@ -1056,7 +1057,7 @@ function SubstatDisplay({
return ( return (
<div tw="flex flex-col-reverse"> <div tw="flex flex-col-reverse">
<div <div
tw="h-[2.3em] bg-current relative -top-[.5em] pt-[.5em] -mb-[.5em] rounded-b-[.5em]" tw="flex h-[2.3em] bg-current relative -top-[.5em] pt-[.5em] -mb-[.5em] rounded-b-[.5em]"
className={`Talents ${element}`} className={`Talents ${element}`}
> >
<div tw="text-white w-full flex items-center flex-wrap justify-end bg-black/25"> <div tw="text-white w-full flex items-center flex-wrap justify-end bg-black/25">
@@ -1067,7 +1068,7 @@ function SubstatDisplay({
<div tw="ml-[.2em] mb-[.1em] text-[.75em] flex flex-col items-center font-[Open_Sans]"> <div tw="ml-[.2em] mb-[.1em] text-[.75em] flex flex-col items-center font-[Open_Sans]">
{s.efficiency} {s.efficiency}
{/* hr */} {/* hr */}
<div tw="w-full h-[1px] bg-white"></div> <div tw="flex w-full h-[1px] bg-white"></div>
{s.level} {s.level}
</div> </div>
<EnkaIcon icon={s.id} tw="h-[1em]" /> <EnkaIcon icon={s.id} tw="h-[1em]" />
+1 -1
View File
@@ -1,8 +1,8 @@
import { feature } from "bun:bundle"; import { feature } from "bun:bundle";
import ImageResponse from "@takumi-rs/image-response";
import type { MaybePromise } from "bun"; import type { MaybePromise } from "bun";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import ImageResponse from "takumi-js/response";
import { font, iconFont, sansFont } from "@/assets/fonts"; import { font, iconFont, sansFont } from "@/assets/fonts";
import { createLogger } from "@/lib/logger"; import { createLogger } from "@/lib/logger";