From 2c7bd14f481f9008854c178a690ec812b0222eeb Mon Sep 17 00:00:00 2001 From: Steffen Illium Date: Mon, 29 Sep 2025 10:57:58 +0200 Subject: [PATCH] Dynamic server side qr code generation --- app/connect/page.tsx | 79 +++++--- app/resume.tsx | 2 +- components/element-qr.tsx | 14 ++ components/ui/shadcn-io/qr-code/index.tsx | 88 +++++++++ components/ui/shadcn-io/qr-code/server.tsx | 42 ++++ package.json | 4 + pnpm-lock.yaml | 216 +++++++++++++++++++++ public/images/qr.png | Bin 26505 -> 0 bytes 8 files changed, 412 insertions(+), 33 deletions(-) create mode 100644 components/element-qr.tsx create mode 100644 components/ui/shadcn-io/qr-code/index.tsx create mode 100644 components/ui/shadcn-io/qr-code/server.tsx delete mode 100644 public/images/qr.png diff --git a/app/connect/page.tsx b/app/connect/page.tsx index bdc42d04..40eea163 100644 --- a/app/connect/page.tsx +++ b/app/connect/page.tsx @@ -5,24 +5,32 @@ import { Button } from "@/components/ui/button"; import { BlurFade } from "@/components/magicui/blur-fade"; import { TrackedLink } from "@/components/util-tracked-link"; import { Metadata } from "next"; +import MyQrCode from "@/components/element-qr"; +import Link from "next/link"; -const BLUR_FADE_DELAY = 0.01; +const BLUR_FADE_DELAY = 0.05; export const metadata: Metadata = { alternates: { canonical: `${DATA.url}/connect`, }, -} +}; export default function ConnectPage() { - const featuredSocials = ["Email", "LinkedIn", "GoogleScholar", "arXiv", "ResearchGate", "Gitea"]; - const socialLinks = Object.entries(DATA.contact.social) - .filter(([name]) => featuredSocials.includes(name)); + const featuredSocials = [ + "Email", + "LinkedIn", + "GoogleScholar", + "arXiv", + "ResearchGate", + "Gitea", + ]; + const socialLinks = Object.entries(DATA.contact.social).filter(([name]) => + featuredSocials.includes(name) + ); return ( -
+
-

Dr. Steffen Illium

+ + +
+
+ -
+

Contact

+ + +
{socialLinks.map(([name, social]) => ( - - - + + + ))}
- -
- - - - QR Code to connect - - -
+ +
+
+ + + + +
); -} \ No newline at end of file +} diff --git a/app/resume.tsx b/app/resume.tsx index c2a09c75..3582af33 100644 --- a/app/resume.tsx +++ b/app/resume.tsx @@ -11,7 +11,7 @@ const domain: string = "steffenillium.de"; export const DATA = { name: "Steffen Illium", initials: "SI", - url: `https://${domain}.de`, + url: `https://${domain}`, domain: `${domain}`, location: "Augsburg, Germany", locationLink: "https://www.google.com/maps/place/Augsburg", diff --git a/components/element-qr.tsx b/components/element-qr.tsx new file mode 100644 index 00000000..f073d1f5 --- /dev/null +++ b/components/element-qr.tsx @@ -0,0 +1,14 @@ +import { DATA } from "@/app/resume"; +import { QRCode } from "@/components/ui/shadcn-io/qr-code"; + +const BACKGROUND_COLOR = "hsl(var(--background))"; +const FOREGROUND_COLOR = "hsl(var(--foreground))"; + +const MyQrCode = () => ( + +); +export default MyQrCode; diff --git a/components/ui/shadcn-io/qr-code/index.tsx b/components/ui/shadcn-io/qr-code/index.tsx new file mode 100644 index 00000000..e5099e16 --- /dev/null +++ b/components/ui/shadcn-io/qr-code/index.tsx @@ -0,0 +1,88 @@ +'use client'; + +import { formatHex, oklch } from 'culori'; +import QR from 'qrcode'; +import { type HTMLAttributes, useEffect, useState } from 'react'; +import { cn } from '@/lib/utils'; + +export type QRCodeProps = HTMLAttributes & { + data: string; + foreground?: string; + background?: string; + robustness?: 'L' | 'M' | 'Q' | 'H'; +}; + +const oklchRegex = /oklch\(([0-9.]+)\s+([0-9.]+)\s+([0-9.]+)\)/; + +const getOklch = (color: string, fallback: [number, number, number]) => { + const oklchMatch = color.match(oklchRegex); + + if (!oklchMatch) { + return { l: fallback[0], c: fallback[1], h: fallback[2] }; + } + + return { + l: Number.parseFloat(oklchMatch[1]), + c: Number.parseFloat(oklchMatch[2]), + h: Number.parseFloat(oklchMatch[3]), + }; +}; + +export const QRCode = ({ + data, + foreground, + background, + robustness = 'M', + className, + ...props +}: QRCodeProps) => { + const [svg, setSVG] = useState(null); + + useEffect(() => { + const generateQR = async () => { + try { + const styles = getComputedStyle(document.documentElement); + const foregroundColor = + foreground ?? styles.getPropertyValue('--foreground'); + const backgroundColor = + background ?? styles.getPropertyValue('--background'); + + const foregroundOklch = getOklch( + foregroundColor, + [0.21, 0.006, 285.885] + ); + const backgroundOklch = getOklch(backgroundColor, [0.985, 0, 0]); + + const newSvg = await QR.toString(data, { + type: 'svg', + color: { + dark: formatHex(oklch({ mode: 'oklch', ...foregroundOklch })), + light: formatHex(oklch({ mode: 'oklch', ...backgroundOklch })), + }, + width: 200, + errorCorrectionLevel: robustness, + margin: 0, + }); + + setSVG(newSvg); + } catch (err) { + console.error(err); + } + }; + + generateQR(); + }, [data, foreground, background, robustness]); + + if (!svg) { + return null; + } + + return ( +
+ ); +}; diff --git a/components/ui/shadcn-io/qr-code/server.tsx b/components/ui/shadcn-io/qr-code/server.tsx new file mode 100644 index 00000000..45e0cc98 --- /dev/null +++ b/components/ui/shadcn-io/qr-code/server.tsx @@ -0,0 +1,42 @@ +import QR from 'qrcode'; +import type { HTMLAttributes } from 'react'; +import { cn } from '@/lib/utils'; + +export type QRCodeProps = HTMLAttributes & { + data: string; + foreground: string; + background: string; + robustness?: 'L' | 'M' | 'Q' | 'H'; +}; + +export const QRCode = async ({ + data, + foreground, + background, + robustness = 'M', + className, + ...props +}: QRCodeProps) => { + const svg = await QR.toString(data, { + type: 'svg', + color: { + dark: foreground, + light: background, + }, + width: 200, + errorCorrectionLevel: robustness, + }); + + if (!svg) { + throw new Error('Failed to generate QR code'); + } + + return ( +
+ ); +}; diff --git a/package.json b/package.json index d73a8201..d8e8b017 100644 --- a/package.json +++ b/package.json @@ -21,12 +21,14 @@ "cheerio": "^1.1.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "culori": "^4.0.2", "gray-matter": "^4.0.3", "lucide-react": "^0.544.0", "mdx-bundler": "^10.1.1", "motion": "^12.23.16", "next": "15.5.3", "next-themes": "^0.4.6", + "qrcode": "^1.5.4", "react": "19.1.1", "react-dom": "19.1.1", "react-icons": "^5.5.0", @@ -48,7 +50,9 @@ "devDependencies": { "@eslint/eslintrc": "^3.3.1", "@tailwindcss/postcss": "^4.1.13", + "@types/culori": "^4.0.1", "@types/node": "^24.5.2", + "@types/qrcode": "^1.5.5", "@types/react": "^19.1.13", "@types/react-dom": "^19.1.9", "eslint": "^9.36.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c48bbe8..85c6c8b6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: clsx: specifier: ^2.1.1 version: 2.1.1 + culori: + specifier: ^4.0.2 + version: 4.0.2 gray-matter: specifier: ^4.0.3 version: 4.0.3 @@ -62,6 +65,9 @@ importers: next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + qrcode: + specifier: ^1.5.4 + version: 1.5.4 react: specifier: 19.1.1 version: 19.1.1 @@ -120,9 +126,15 @@ importers: '@tailwindcss/postcss': specifier: ^4.1.13 version: 4.1.13 + '@types/culori': + specifier: ^4.0.1 + version: 4.0.1 '@types/node': specifier: ^24.5.2 version: 24.5.2 + '@types/qrcode': + specifier: ^1.5.5 + version: 1.5.5 '@types/react': specifier: ^19.1.13 version: 19.1.13 @@ -1076,6 +1088,9 @@ packages: '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/culori@4.0.1': + resolution: {integrity: sha512-43M51r/22CjhbOXyGT361GZ9vncSVQ39u62x5eJdBQFviI8zWp2X5jzqg7k4M6PVgDQAClpy2bUe2dtwEgEDVQ==} + '@types/d3-array@3.2.2': resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} @@ -1133,6 +1148,9 @@ packages: '@types/node@24.5.2': resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} + '@types/qrcode@1.5.5': + resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==} + '@types/react-dom@19.1.9': resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} peerDependencies: @@ -1347,6 +1365,10 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -1451,6 +1473,10 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + caniuse-lite@1.0.30001743: resolution: {integrity: sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==} @@ -1490,6 +1516,9 @@ packages: client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -1532,6 +1561,10 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + culori@4.0.2: + resolution: {integrity: sha512-1+BhOB8ahCn4O0cep0Sh2l9KCOfOdY+BXJnKMHFFzDEouSr/el18QwXEMRlOj9UY5nCeA8UN3a/82rUWRBeyBw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + d3-array@3.2.4: resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} engines: {node: '>=12'} @@ -1608,6 +1641,10 @@ packages: supports-color: optional: true + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + decimal.js-light@2.5.1: resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} @@ -1636,6 +1673,9 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + discontinuous-range@1.0.0: resolution: {integrity: sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==} @@ -1660,6 +1700,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} @@ -1927,6 +1970,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -1970,6 +2017,10 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -2185,6 +2236,10 @@ packages: resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} engines: {node: '>= 0.4'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-generator-function@1.1.0: resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} engines: {node: '>= 0.4'} @@ -2376,6 +2431,10 @@ packages: resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} engines: {node: '>= 12.0.0'} + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -2719,14 +2778,26 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2768,6 +2839,10 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -2798,6 +2873,11 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qrcode@1.5.4: + resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} + engines: {node: '>=10.13.0'} + hasBin: true + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -2935,6 +3015,13 @@ packages: remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + reselect@5.1.1: resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} @@ -2999,6 +3086,9 @@ packages: engines: {node: '>=10'} hasBin: true + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -3063,6 +3153,10 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + string.prototype.includes@2.0.1: resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} engines: {node: '>= 0.4'} @@ -3089,6 +3183,10 @@ packages: stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + strip-bom-string@1.0.0: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} @@ -3307,6 +3405,9 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + which-typed-array@1.1.19: resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} engines: {node: '>= 0.4'} @@ -3327,6 +3428,13 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + yallist@5.0.0: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} @@ -3336,6 +3444,14 @@ packages: engines: {node: '>= 14.6'} hasBin: true + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -4154,6 +4270,8 @@ snapshots: tslib: 2.8.1 optional: true + '@types/culori@4.0.1': {} + '@types/d3-array@3.2.2': {} '@types/d3-color@3.1.3': {} @@ -4208,6 +4326,10 @@ snapshots: dependencies: undici-types: 7.12.0 + '@types/qrcode@1.5.5': + dependencies: + '@types/node': 24.5.2 + '@types/react-dom@19.1.9(@types/react@19.1.13)': dependencies: '@types/react': 19.1.13 @@ -4433,6 +4555,8 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-regex@5.0.1: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 @@ -4564,6 +4688,8 @@ snapshots: callsites@3.1.0: {} + camelcase@5.3.1: {} + caniuse-lite@1.0.30001743: {} ccount@2.0.1: {} @@ -4612,6 +4738,12 @@ snapshots: client-only@0.0.1: {} + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + clsx@2.1.1: {} collapse-white-space@2.1.0: {} @@ -4648,6 +4780,8 @@ snapshots: csstype@3.1.3: {} + culori@4.0.2: {} + d3-array@3.2.4: dependencies: internmap: 2.0.3 @@ -4714,6 +4848,8 @@ snapshots: dependencies: ms: 2.1.3 + decamelize@1.2.0: {} + decimal.js-light@2.5.1: {} decode-named-character-reference@1.2.0: @@ -4742,6 +4878,8 @@ snapshots: dependencies: dequal: 2.0.3 + dijkstrajs@1.0.3: {} + discontinuous-range@1.0.0: {} doctrine@2.1.0: @@ -4772,6 +4910,8 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} encoding-sniffer@0.2.1: @@ -5224,6 +5364,11 @@ snapshots: dependencies: to-regex-range: 5.0.1 + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -5264,6 +5409,8 @@ snapshots: functions-have-names@1.2.3: {} + get-caller-file@2.0.5: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -5552,6 +5699,8 @@ snapshots: dependencies: call-bound: 1.0.4 + is-fullwidth-code-point@3.0.0: {} + is-generator-function@1.1.0: dependencies: call-bound: 1.0.4 @@ -5722,6 +5871,10 @@ snapshots: lightningcss-win32-arm64-msvc: 1.30.1 lightningcss-win32-x64-msvc: 1.30.1 + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -6359,14 +6512,24 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 + p-try@2.2.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -6408,6 +6571,8 @@ snapshots: picomatch@4.0.3: {} + pngjs@5.0.0: {} + possible-typed-array-names@1.1.0: {} postcss-selector-parser@6.0.10: @@ -6439,6 +6604,12 @@ snapshots: punycode@2.3.1: {} + qrcode@1.5.4: + dependencies: + dijkstrajs: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + queue-microtask@1.2.3: {} railroad-diagrams@1.0.0: {} @@ -6680,6 +6851,10 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 + require-directory@2.1.1: {} + + require-main-filename@2.0.0: {} + reselect@5.1.1: {} resolve-from@4.0.0: {} @@ -6740,6 +6915,8 @@ snapshots: semver@7.7.2: {} + set-blocking@2.0.0: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -6852,6 +7029,12 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + string.prototype.includes@2.0.1: dependencies: call-bind: 1.0.8 @@ -6907,6 +7090,10 @@ snapshots: character-entities-html4: 2.1.0 character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + strip-bom-string@1.0.0: {} strip-bom@3.0.0: {} @@ -7204,6 +7391,8 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 + which-module@2.0.1: {} + which-typed-array@1.1.19: dependencies: available-typed-arrays: 1.0.7 @@ -7224,10 +7413,37 @@ snapshots: word-wrap@1.2.5: {} + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + y18n@4.0.3: {} + yallist@5.0.0: {} yaml@2.8.1: {} + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + yocto-queue@0.1.0: {} zwitch@2.0.4: {} diff --git a/public/images/qr.png b/public/images/qr.png deleted file mode 100644 index 1ac71b70be3417625f0336c50a44576f4621f2f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26505 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