From a106f282571d0e0080675a41768d1b6a2c6a913d Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Wed, 24 Jun 2026 22:25:08 -0500 Subject: [PATCH] flags local --- app/components/Flag.tsx | 9 +- lib/feeds.ts | 2 +- package-lock.json | 519 +++++++++++++++++++++++++++++++++++ package.json | 5 +- public/crests/1060.svg | 1 + public/crests/1836.svg | 1 + public/crests/1930.svg | 24 ++ public/crests/1934.svg | 1 + public/crests/1935.svg | 1 + public/crests/758.svg | 1 + public/crests/759.svg | 6 + public/crests/760.svg | 581 ++++++++++++++++++++++++++++++++++++++++ public/crests/761.svg | 1 + public/crests/762.svg | Bin 0 -> 1086 bytes public/crests/763.svg | 6 + public/crests/764.svg | 1 + public/crests/765.svg | 66 +++++ public/crests/766.svg | 4 + public/crests/769.svg | 1 + public/crests/770.svg | 7 + public/crests/771.svg | 1 + public/crests/772.svg | Bin 0 -> 2404 bytes public/crests/773.svg | 5 + public/crests/774.svg | 1 + public/crests/778.svg | 5 + public/crests/779.svg | 1 + public/crests/783.svg | 1 + public/crests/788.svg | 5 + public/crests/791.svg | 519 +++++++++++++++++++++++++++++++++++ public/crests/792.svg | 5 + public/crests/798.svg | 5 + public/crests/799.svg | 240 +++++++++++++++++ public/crests/801.svg | 1 + public/crests/802.svg | 9 + public/crests/803.svg | 6 + public/crests/8030.svg | 1 + public/crests/804.svg | 1 + public/crests/8049.svg | Bin 0 -> 914 bytes public/crests/805.svg | 5 + public/crests/8062.svg | 1 + public/crests/8070.svg | Bin 0 -> 745 bytes public/crests/815.svg | 1 + public/crests/816.svg | 4 + public/crests/818.svg | 5 + public/crests/825.svg | 78 ++++++ public/crests/828.svg | 1 + public/crests/836.svg | 1 + public/crests/840.svg | 31 +++ public/crests/8601.svg | 5 + public/crests/8872.svg | 7 + public/crests/8873.svg | 1 + public/crests/9460.svg | 16 ++ scripts/fetch-crests.ts | 83 ++++++ 53 files changed, 2276 insertions(+), 6 deletions(-) create mode 100644 public/crests/1060.svg create mode 100644 public/crests/1836.svg create mode 100644 public/crests/1930.svg create mode 100644 public/crests/1934.svg create mode 100644 public/crests/1935.svg create mode 100644 public/crests/758.svg create mode 100644 public/crests/759.svg create mode 100644 public/crests/760.svg create mode 100644 public/crests/761.svg create mode 100644 public/crests/762.svg create mode 100644 public/crests/763.svg create mode 100644 public/crests/764.svg create mode 100644 public/crests/765.svg create mode 100644 public/crests/766.svg create mode 100644 public/crests/769.svg create mode 100644 public/crests/770.svg create mode 100644 public/crests/771.svg create mode 100644 public/crests/772.svg create mode 100644 public/crests/773.svg create mode 100644 public/crests/774.svg create mode 100644 public/crests/778.svg create mode 100644 public/crests/779.svg create mode 100644 public/crests/783.svg create mode 100644 public/crests/788.svg create mode 100644 public/crests/791.svg create mode 100644 public/crests/792.svg create mode 100644 public/crests/798.svg create mode 100644 public/crests/799.svg create mode 100644 public/crests/801.svg create mode 100644 public/crests/802.svg create mode 100644 public/crests/803.svg create mode 100644 public/crests/8030.svg create mode 100644 public/crests/804.svg create mode 100644 public/crests/8049.svg create mode 100644 public/crests/805.svg create mode 100644 public/crests/8062.svg create mode 100644 public/crests/8070.svg create mode 100644 public/crests/815.svg create mode 100644 public/crests/816.svg create mode 100644 public/crests/818.svg create mode 100644 public/crests/825.svg create mode 100644 public/crests/828.svg create mode 100644 public/crests/836.svg create mode 100644 public/crests/840.svg create mode 100644 public/crests/8601.svg create mode 100644 public/crests/8872.svg create mode 100644 public/crests/8873.svg create mode 100644 public/crests/9460.svg create mode 100644 scripts/fetch-crests.ts diff --git a/app/components/Flag.tsx b/app/components/Flag.tsx index 9d92f0b..d365a9d 100644 --- a/app/components/Flag.tsx +++ b/app/components/Flag.tsx @@ -1,15 +1,17 @@ "use client"; +import { useState } from "react"; import { Team } from "@/lib/types"; // Zeigt die Flagge/das Wappen eines Teams. Fällt auf ein neutrales Rund -// zurück, wenn keine crest-URL vorliegt. SVG-Crests (football-data) skalieren -// sauber; das Rendern als rundes Bild gibt den Flaggen-Look aus dem Screenshot. +// zurück, wenn keine crest-URL vorliegt oder das Bild nicht geladen werden kann. export default function Flag({ team, size = 22, }: { team?: Team; size?: number }) { + const [imgFailed, setImgFailed] = useState(false); const style = { width: size, height: size } as const; - if (team?.crest) { + + if (team?.crest && !imgFailed) { return ( setImgFailed(true)} /> ); } diff --git a/lib/feeds.ts b/lib/feeds.ts index d1a65c9..74cc72b 100644 --- a/lib/feeds.ts +++ b/lib/feeds.ts @@ -129,7 +129,7 @@ export async function fetchMatchesAndTeams(): Promise<{ matches: Match[]; teams: if (!teamMap.has(id)) { teamMap.set(id, { id, name: side.name, code: side.tla ?? "", group, - crest: side.crest ?? null, + crest: `/crests/${id}.svg`, localisedName: localisedTeamName(side.tla ?? "", side.name ?? ""), }); } diff --git a/package-lock.json b/package-lock.json index 0ec24e5..48c7758 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@types/node": "22.10.7", "@types/react": "19.0.7", "@types/react-dom": "19.0.3", + "tsx": "^4.22.4", "typescript": "5.7.3" } }, @@ -29,6 +30,448 @@ "tslib": "^2.4.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", @@ -668,6 +1111,63 @@ "node": ">=8" } }, + "node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/is-arrayish": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", @@ -918,6 +1418,25 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tsx": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.22.4.tgz", + "integrity": "sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.28.0" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/typescript": { "version": "5.7.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", diff --git a/package.json b/package.json index 7ef31fe..e403b17 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,10 @@ "react-dom": "19.0.0" }, "devDependencies": { - "typescript": "5.7.3", "@types/node": "22.10.7", "@types/react": "19.0.7", - "@types/react-dom": "19.0.3" + "@types/react-dom": "19.0.3", + "tsx": "^4.22.4", + "typescript": "5.7.3" } } diff --git a/public/crests/1060.svg b/public/crests/1060.svg new file mode 100644 index 0000000..45845f0 --- /dev/null +++ b/public/crests/1060.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/1836.svg b/public/crests/1836.svg new file mode 100644 index 0000000..d6ddb3f --- /dev/null +++ b/public/crests/1836.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/1930.svg b/public/crests/1930.svg new file mode 100644 index 0000000..1f61248 --- /dev/null +++ b/public/crests/1930.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crests/1934.svg b/public/crests/1934.svg new file mode 100644 index 0000000..862681e --- /dev/null +++ b/public/crests/1934.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/1935.svg b/public/crests/1935.svg new file mode 100644 index 0000000..7563a18 --- /dev/null +++ b/public/crests/1935.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/758.svg b/public/crests/758.svg new file mode 100644 index 0000000..a01a172 --- /dev/null +++ b/public/crests/758.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/759.svg b/public/crests/759.svg new file mode 100644 index 0000000..a42f059 --- /dev/null +++ b/public/crests/759.svg @@ -0,0 +1,6 @@ + +Flag of Germany + + + + diff --git a/public/crests/760.svg b/public/crests/760.svg new file mode 100644 index 0000000..760fe0d --- /dev/null +++ b/public/crests/760.svg @@ -0,0 +1,581 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crests/761.svg b/public/crests/761.svg new file mode 100644 index 0000000..7e41611 --- /dev/null +++ b/public/crests/761.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/762.svg b/public/crests/762.svg new file mode 100644 index 0000000000000000000000000000000000000000..af454c2e7f352ed8b6df7210c13a607bd450e840 GIT binary patch literal 1086 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k8A#4*i(3Pvq5^zET!D1ys@wnn|6h3Y+5dn4 zfb865H-RJs9l8BJZ`sY-M&8V{*hWIyFL3_`S+bjs+oB8htlegu3?Y6*Bld%?A6~S6`x|d z??e_piJFS9Kh@%D_jHD{=RN!|p}yeH%kmuYMLeN0jUQL9b+TYM#=#iX5Fc&El_)bU z(aJf?VH>l>hqHEycNzi~eBpViv3O}}&1UZtj92*7(oQYxcby@jW^Z;=b;*epGZ+7ozB4=t?E)K>96Yoxp8HWzSy^fGD05@>?5xq`)7jMms+vk6JE^`ZSDyTenNJ(3JR9j)G z_6waw)7D(uaQvj++Ea{tBAGr$(|62Mat%7S>XP}-AF@U2Tu$jVlIzODY?3)$66gD` zofxgK0_Fg*4@QuJCUr8^`DG}!+NXp>~o9>-0=3- z|A~T14wEGh@lL39ZgX~PJhSBf8?jH~a-ZZ|_U!BopP%>0F21;`R+vCK#+mZ(s6To8 mJG$ccDbySU%uw%MaId=Y`1rFbulc~N%HZkh=d#Wzp$Py5N(`I; literal 0 HcmV?d00001 diff --git a/public/crests/763.svg b/public/crests/763.svg new file mode 100644 index 0000000..6017337 --- /dev/null +++ b/public/crests/763.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/crests/764.svg b/public/crests/764.svg new file mode 100644 index 0000000..a07bcf7 --- /dev/null +++ b/public/crests/764.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/765.svg b/public/crests/765.svg new file mode 100644 index 0000000..c3e79d1 --- /dev/null +++ b/public/crests/765.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crests/766.svg b/public/crests/766.svg new file mode 100644 index 0000000..6299e73 --- /dev/null +++ b/public/crests/766.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/crests/769.svg b/public/crests/769.svg new file mode 100644 index 0000000..018c462 --- /dev/null +++ b/public/crests/769.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/770.svg b/public/crests/770.svg new file mode 100644 index 0000000..52e2702 --- /dev/null +++ b/public/crests/770.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/crests/771.svg b/public/crests/771.svg new file mode 100644 index 0000000..9201215 --- /dev/null +++ b/public/crests/771.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/772.svg b/public/crests/772.svg new file mode 100644 index 0000000000000000000000000000000000000000..cf5f3a66742ab93e4f241344053c36c1cadb16c4 GIT binary patch literal 2404 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 + + + + diff --git a/public/crests/774.svg b/public/crests/774.svg new file mode 100644 index 0000000..9fd94ac --- /dev/null +++ b/public/crests/774.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/778.svg b/public/crests/778.svg new file mode 100644 index 0000000..e1165a7 --- /dev/null +++ b/public/crests/778.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/crests/779.svg b/public/crests/779.svg new file mode 100644 index 0000000..bab7eb4 --- /dev/null +++ b/public/crests/779.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/783.svg b/public/crests/783.svg new file mode 100644 index 0000000..db87a7f --- /dev/null +++ b/public/crests/783.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/788.svg b/public/crests/788.svg new file mode 100644 index 0000000..5ea9eea --- /dev/null +++ b/public/crests/788.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/crests/791.svg b/public/crests/791.svg new file mode 100644 index 0000000..b673e6e --- /dev/null +++ b/public/crests/791.svg @@ -0,0 +1,519 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crests/792.svg b/public/crests/792.svg new file mode 100644 index 0000000..9223d14 --- /dev/null +++ b/public/crests/792.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/crests/798.svg b/public/crests/798.svg new file mode 100644 index 0000000..db03aba --- /dev/null +++ b/public/crests/798.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/crests/799.svg b/public/crests/799.svg new file mode 100644 index 0000000..39b2287 --- /dev/null +++ b/public/crests/799.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crests/801.svg b/public/crests/801.svg new file mode 100644 index 0000000..d9a6ce8 --- /dev/null +++ b/public/crests/801.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/802.svg b/public/crests/802.svg new file mode 100644 index 0000000..a86d3d4 --- /dev/null +++ b/public/crests/802.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/crests/803.svg b/public/crests/803.svg new file mode 100644 index 0000000..7f55856 --- /dev/null +++ b/public/crests/803.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/crests/8030.svg b/public/crests/8030.svg new file mode 100644 index 0000000..b750f07 --- /dev/null +++ b/public/crests/8030.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/804.svg b/public/crests/804.svg new file mode 100644 index 0000000..7e34312 --- /dev/null +++ b/public/crests/804.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/8049.svg b/public/crests/8049.svg new file mode 100644 index 0000000000000000000000000000000000000000..d0284e2352aadad574effd78ac845bd1860e873d GIT binary patch literal 914 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k8A#4*i(3PvN&|dCT!D1Dn-P1ZZ8oO}kS!)F z!%%F(P-P2b14%AMrgMU75cdE7|Ie_=+~ikVdVbf-moI_J#KgoH>g}$Xd9<19g|i8$ zXIOGFGCoKv`F`!@zi;0+^C`YruwpB};+K=>p7l)o_2}tFKE*jJrin>P9#c;E3pA9w zB*-tAValR8e|~&huXxr3=B*MJzX3_DsH{Kda>xTfk0~_b8v#dRHiLVS>nmk z7609zyjjv0oS_^qvDmiwU-y%s&%I@9-87d@3GzZFG^)S8({(-j@b~oH-&sr_Iymmk zc4BxsySmF!LxXMO9sU_W+W5%d2FWLaPuqh}@f6x8uq|AmBk+9pCWkriG5CT`1=`$4 zey%$s@SQnLfa?@f;XZAkdKed~9Xl6fB}lJ~BFpw90WPo$7A}xzX##W1mfwl_yX)p| zZ3naEEgv8MW874$`MvNx&!$?=DZeW;)h8Go>_=9ZltbTy*cR z#I~hxI8Hj-tUrC*(aG9ni*Sm}vdx?`cG=}0d!clTH>p42w?k&5N2w9drn=k3tG<|p zIU59r{!9+Ldv~q&$wsuTnZ9 z|Jbv`{g|-8{GR;^agy~8e~jcDZH&(;?2}aQC_l!0#QyPp2fp^Qu2vZbzK5UB^Z&k{ zbN)wF_210zapt#;^Va`&=VfOW;A2ye;c>8#XecmXc$mO&=paK&Gb0DBC7v8TZ7yPp flIlQ-@aT>FPn@>|7JS^21j;y`u6{1-oD!M + + + + diff --git a/public/crests/8062.svg b/public/crests/8062.svg new file mode 100644 index 0000000..f806fcb --- /dev/null +++ b/public/crests/8062.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/8070.svg b/public/crests/8070.svg new file mode 100644 index 0000000000000000000000000000000000000000..b22b8fbbfdbbb3f490d84d2b8543077858ea8d1b GIT binary patch literal 745 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k8A#4*i(3Pv0t0+PT!A#h%&l@;t>EPU|NsB} z`Sbqg@4KJAe!q6}#LM?9?>_6fa5rWDMel8=6qoK3*>4R}zi=;53&Z4%2^GfI%-vg^ zBF_n_-C&k|tYTyWG?T3)$S;^-&Vp6Hf7^YQzsSJA(0Ob&Yu;I7plf7rfRDmcy9A?i)(h(g7Ph)uVp}vg9C?tn?3KF*teH4IYkL4 zrKO$aHjECMv&`~sz1z8`U#B{q`SeCrzIb7p;XkcgYriga((!M8@;K^-PnY76E&Kod zui2q_WYTn#r;m)!I&xLk*Cx8^@J(8_^$o9g(5Am%OPzE)FO{Uon;o~f{qL8N;xu>9 zI@>M%In%sfpVksm;a%Cuo#Nkd^zgA&tx#X+pSmQsgA3-;t-&JZG(~Rh%5M zi@EQ~>erj6O*eV7^~A)QP{(UgZl1~ejN?NmY&BCnJ@@CTrZroC1i1oLNo@-IC}lZm zz1E4S+bc!io~tRXy>?5;i~swH;BUE|*Ee6AD7~@w%k1`NhpzSNhZS$U8$C0d)$_5u z`iGk}p@(BmZ<_ujUdwX!daaq+f7d?A*|#cf-BfkY7PSYi`SN#dM8R>ylMY* zwbiqz+hNyCDm8Ns-{1UmRoBjI?^ms{JgUBY{@L)*Gh5@bG9R;YuD`cRcvDH!?`xdz z+|_ripZlQAub_F?0%gTTN~MikH;7$36cxdpov6E}6({HGF)gS5E7z6ftq<0|Z>g(0 z^l_>1o#lQ7^Q{>bIUG;u^}n0grNE;2g~Lg}sXsxt<$`hqH;^al$YJZ`3KR+u1PX<) sDCVzm-?j3@Zodcb?cgyFVl42kV>% \ No newline at end of file diff --git a/public/crests/816.svg b/public/crests/816.svg new file mode 100644 index 0000000..a0a161d --- /dev/null +++ b/public/crests/816.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/crests/818.svg b/public/crests/818.svg new file mode 100644 index 0000000..6cb2061 --- /dev/null +++ b/public/crests/818.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/crests/825.svg b/public/crests/825.svg new file mode 100644 index 0000000..e53e54a --- /dev/null +++ b/public/crests/825.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crests/828.svg b/public/crests/828.svg new file mode 100644 index 0000000..f03177d --- /dev/null +++ b/public/crests/828.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/836.svg b/public/crests/836.svg new file mode 100644 index 0000000..8fb20cf --- /dev/null +++ b/public/crests/836.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/840.svg b/public/crests/840.svg new file mode 100644 index 0000000..59b51b5 --- /dev/null +++ b/public/crests/840.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/crests/8601.svg b/public/crests/8601.svg new file mode 100644 index 0000000..baed368 --- /dev/null +++ b/public/crests/8601.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/crests/8872.svg b/public/crests/8872.svg new file mode 100644 index 0000000..4765e85 --- /dev/null +++ b/public/crests/8872.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/crests/8873.svg b/public/crests/8873.svg new file mode 100644 index 0000000..3c68d59 --- /dev/null +++ b/public/crests/8873.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/crests/9460.svg b/public/crests/9460.svg new file mode 100644 index 0000000..f2c9853 --- /dev/null +++ b/public/crests/9460.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/scripts/fetch-crests.ts b/scripts/fetch-crests.ts new file mode 100644 index 0000000..e17fed2 --- /dev/null +++ b/scripts/fetch-crests.ts @@ -0,0 +1,83 @@ +/** + * Einmal-Skript: Lädt alle Team-Crests von football-data.org herunter + * und speichert sie unter public/crests/{teamId}.svg. + * + * Ausführung: npx tsx --env-file=.env scripts/fetch-crests.ts + */ +import * as fs from "node:fs"; +import * as path from "node:path"; + +const CREST_BASE = "https://crests.football-data.org"; +const OUT_DIR = path.resolve(import.meta.dirname, "..", "public", "crests"); +const FD_BASE = "https://api.football-data.org/v4"; +const FD_COMP = "WC"; + +function fdHeaders(): Record { + const token = process.env.FOOTBALL_DATA_TOKEN; + if (!token) { + console.error("[fehler] FOOTBALL_DATA_TOKEN nicht gesetzt. Bitte .env prüfen."); + process.exit(1); + } + return { "X-Auth-Token": token }; +} + +interface FdTeam { + id: number; + name: string; + tla?: string | null; + crest?: string | null; +} + +async function main() { + console.log("[fetch-crests] Rufe Team-Daten von football-data.org ab…"); + + const res = await fetch(`${FD_BASE}/competitions/${FD_COMP}/teams`, { + headers: fdHeaders(), + }); + if (!res.ok) { + console.error(`[fehler] football-data API: ${res.status} ${res.statusText}`); + process.exit(1); + } + + const data = (await res.json()) as { teams: FdTeam[] }; + const teams = data.teams ?? []; + console.log(`[fetch-crests] ${teams.length} Teams gefunden.`); + + fs.mkdirSync(OUT_DIR, { recursive: true }); + + let ok = 0; + let failed = 0; + const failures: string[] = []; + + for (const t of teams) { + const id = String(t.id); + const url = t.crest ?? `${CREST_BASE}/${id}.svg`; + const outPath = path.join(OUT_DIR, `${id}.svg`); + + try { + const imgRes = await fetch(url); + if (!imgRes.ok) { + failed++; + failures.push(`${t.name} (id=${id}): HTTP ${imgRes.status}`); + continue; + } + const buf = Buffer.from(await imgRes.arrayBuffer()); + fs.writeFileSync(outPath, buf); + ok++; + } catch (err) { + failed++; + failures.push(`${t.name} (id=${id}): ${err instanceof Error ? err.message : String(err)}`); + } + } + + console.log(`\n[fetch-crests] Fertig: ${ok} geladen, ${failed} fehlgeschlagen.`); + if (failures.length > 0) { + console.log("[fetch-crests] Fehlgeschlagene:"); + for (const f of failures) console.log(` - ${f}`); + } +} + +main().catch((err) => { + console.error("[fehler]", err); + process.exit(1); +});