internal corporate restructuring

This commit is contained in:
nin0dev 2025-03-15 22:03:19 -04:00
parent 22251c3b2b
commit 6015db1f4f
Signed by: nin0
SSH key fingerprint: SHA256:NOoDnFVvZNFvqfXCIhzr6oCTDImZAbTTuyAysZ8Ufk8
37 changed files with 1207 additions and 348 deletions

View file

@ -1,8 +1,18 @@
{
"plugins": ["prettier-plugin-astro"],
"overrides": [
{
"files": "*.astro",
"options": {
"parser": "astro"
}
}
],
"tabWidth": 4,
"useTabs": true,
"singleQuote": false,
"jsxSingleQuote": false,
"semi": true,
"arrowParens": "avoid"
"arrowParens": "avoid",
"trailingComma": "none"
}

4
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,4 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
}

View file

@ -3,8 +3,16 @@ import node from "@astrojs/node";
import cloudflare from "@astrojs/cloudflare";
import react from "@astrojs/react";
// https://astro.build/config
export default defineConfig({
output: "server",
adapter: cloudflare()
output: "server",
adapter: cloudflare(),
integrations: [react()],
vite: {
server: {
allowedHosts: ["nin0-pc.buri-roach.ts.net"]
}
}
});

View file

@ -13,10 +13,18 @@
"7.css": "^0.16.0",
"@astrojs/cloudflare": "^12.2.4",
"@astrojs/node": "^9.1.3",
"@astrojs/react": "^4.2.1",
"@fontsource-variable/noto-emoji": "^5.2.5",
"@fontsource/inter": "^5.2.5",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"astro": "^5.5.2",
"lanyard-wrapper": "^2.0.1"
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"prettier": "^3.5.3",
"prettier-plugin-astro": "^0.14.1",
"wrangler": "^3.112.0"
}
}

502
pnpm-lock.yaml generated
View file

@ -17,13 +17,37 @@ importers:
'@astrojs/node':
specifier: ^9.1.3
version: 9.1.3(astro@5.5.2(rollup@4.34.9)(typescript@5.8.2))
'@astrojs/react':
specifier: ^4.2.1
version: 4.2.1(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@fontsource-variable/noto-emoji':
specifier: ^5.2.5
version: 5.2.5
'@fontsource/inter':
specifier: ^5.2.5
version: 5.2.5
'@types/react':
specifier: ^19.0.10
version: 19.0.10
'@types/react-dom':
specifier: ^19.0.4
version: 19.0.4(@types/react@19.0.10)
astro:
specifier: ^5.5.2
version: 5.5.2(rollup@4.34.9)(typescript@5.8.2)
lanyard-wrapper:
specifier: ^2.0.1
version: 2.0.1
react:
specifier: ^19.0.0
version: 19.0.0
react-dom:
specifier: ^19.0.0
version: 19.0.0(react@19.0.0)
devDependencies:
prettier:
specifier: ^3.5.3
version: 3.5.3
prettier-plugin-astro:
specifier: ^0.14.1
version: 0.14.1
wrangler:
specifier: ^3.112.0
version: 3.112.0(@cloudflare/workers-types@4.20250303.0)
@ -33,6 +57,10 @@ packages:
7.css@0.16.0:
resolution: {integrity: sha512-qZleAhXgVqtAc8Wb4mAJRczbGBcUMv6i2wNogXzHgf9Dztky0CqrehWOJtzU05tMw9a9xLeyvumnJeD+WjLiNQ==}
'@ampproject/remapping@2.3.0':
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
'@astrojs/cloudflare@12.2.4':
resolution: {integrity: sha512-iFCVNKFpSNoeF1V6ck885uWZvPmbaiJAf2o+Dt6qUb4vYtUwS85nuMOwwwY8MkIc1pg0Zvhx6x6LAp2DWn4HZQ==}
peerDependencies:
@ -56,6 +84,15 @@ packages:
resolution: {integrity: sha512-GilTHKGCW6HMq7y3BUv9Ac7GMe/MO9gi9GW62GzKtth0SwukCu/qp2wLiGpEujhY+VVhaG9v7kv/5vFzvf4NYw==}
engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0}
'@astrojs/react@4.2.1':
resolution: {integrity: sha512-g0P6zxG7RPHNcbmMB15dJJ83+ApBVFBcgnf6BnMz/PVXM150Pa1vYKeuTcWhERqLNgmpI2uXuch5MecIhrUlqQ==}
engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0}
peerDependencies:
'@types/react': ^17.0.50 || ^18.0.21 || ^19.0.0
'@types/react-dom': ^17.0.17 || ^18.0.6 || ^19.0.0
react: ^17.0.2 || ^18.0.0 || ^19.0.0
react-dom: ^17.0.2 || ^18.0.0 || ^19.0.0
'@astrojs/telemetry@3.2.0':
resolution: {integrity: sha512-wxhSKRfKugLwLlr4OFfcqovk+LIFtKwLyGPqMsv+9/ibqqnW3Gv7tBhtKEb0gAyUAC4G9BTVQeQahqnQAhd6IQ==}
engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0}
@ -63,6 +100,40 @@ packages:
'@astrojs/underscore-redirects@0.6.0':
resolution: {integrity: sha512-dnJgFpaM955IFNIkEEmMaaIdWXRdeZs1ID6mlGBqdjh6NiCXfKmOdq7L4fd9Dd/tr18fkLrOJ25IUJSxRAEhjQ==}
'@babel/code-frame@7.26.2':
resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
engines: {node: '>=6.9.0'}
'@babel/compat-data@7.26.8':
resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==}
engines: {node: '>=6.9.0'}
'@babel/core@7.26.10':
resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==}
engines: {node: '>=6.9.0'}
'@babel/generator@7.26.10':
resolution: {integrity: sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==}
engines: {node: '>=6.9.0'}
'@babel/helper-compilation-targets@7.26.5':
resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==}
engines: {node: '>=6.9.0'}
'@babel/helper-module-imports@7.25.9':
resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==}
engines: {node: '>=6.9.0'}
'@babel/helper-module-transforms@7.26.0':
resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
'@babel/helper-plugin-utils@7.26.5':
resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==}
engines: {node: '>=6.9.0'}
'@babel/helper-string-parser@7.25.9':
resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
engines: {node: '>=6.9.0'}
@ -71,11 +142,39 @@ packages:
resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-option@7.25.9':
resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==}
engines: {node: '>=6.9.0'}
'@babel/helpers@7.26.10':
resolution: {integrity: sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==}
engines: {node: '>=6.9.0'}
'@babel/parser@7.26.10':
resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==}
engines: {node: '>=6.0.0'}
hasBin: true
'@babel/plugin-transform-react-jsx-self@7.25.9':
resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-transform-react-jsx-source@7.25.9':
resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/template@7.26.9':
resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==}
engines: {node: '>=6.9.0'}
'@babel/traverse@7.26.10':
resolution: {integrity: sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==}
engines: {node: '>=6.9.0'}
'@babel/types@7.26.10':
resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==}
engines: {node: '>=6.9.0'}
@ -420,6 +519,12 @@ packages:
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
engines: {node: '>=14'}
'@fontsource-variable/noto-emoji@5.2.5':
resolution: {integrity: sha512-p/poFM8KKkBpY/fumf8dKPwclakNNpSpw/ro+TvkEAC4/jESvRJfFpl54LSUmGF8iXpi3w3o8aOc7A3he8c+NA==}
'@fontsource/inter@5.2.5':
resolution: {integrity: sha512-kbsPKj0S4p44JdYRFiW78Td8Ge2sBVxi/PIBwmih+RpSXUdvS9nbs1HIiuUSPtRMi14CqLEZ/fbk7dj7vni1Sg==}
'@img/sharp-darwin-arm64@0.33.5':
resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
@ -525,13 +630,24 @@ packages:
cpu: [x64]
os: [win32]
'@jridgewell/gen-mapping@0.3.8':
resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
engines: {node: '>=6.0.0'}
'@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
'@jridgewell/set-array@1.2.1':
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
engines: {node: '>=6.0.0'}
'@jridgewell/sourcemap-codec@1.5.0':
resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
'@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
@ -663,6 +779,18 @@ packages:
'@shikijs/vscode-textmate@10.0.2':
resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
'@types/babel__core@7.20.5':
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
'@types/babel__generator@7.6.8':
resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==}
'@types/babel__template@7.4.4':
resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
'@types/babel__traverse@7.20.6':
resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==}
'@types/cookie@0.6.0':
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
@ -684,12 +812,26 @@ packages:
'@types/nlcst@2.0.3':
resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
'@types/react-dom@19.0.4':
resolution: {integrity: sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==}
peerDependencies:
'@types/react': ^19.0.0
'@types/react@19.0.10':
resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==}
'@types/unist@3.0.2':
resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==}
'@ungap/structured-clone@1.2.0':
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
'@vitejs/plugin-react@4.3.4':
resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
vite: ^4.2.0 || ^5.0.0 || ^6.0.0
acorn-walk@8.3.2:
resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
engines: {node: '>=0.4.0'}
@ -758,10 +900,18 @@ packages:
resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==}
engines: {node: '>=18'}
browserslist@4.24.4:
resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
camelcase@8.0.0:
resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==}
engines: {node: '>=16'}
caniuse-lite@1.0.30001704:
resolution: {integrity: sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew==}
ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
@ -817,6 +967,9 @@ packages:
confbox@0.1.8:
resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
cookie-es@1.2.2:
resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==}
@ -836,6 +989,9 @@ packages:
engines: {node: '>=4'}
hasBin: true
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
data-uri-to-buffer@2.0.2:
resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==}
@ -906,6 +1062,9 @@ packages:
ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
electron-to-chromium@1.5.119:
resolution: {integrity: sha512-Ku4NMzUjz3e3Vweh7PhApPrZSS4fyiCIbcIrG9eKrriYVLmbMepETR/v6SU7xPm98QTqMSYiCwfO89QNjXLkbQ==}
emoji-regex-xs@1.0.0:
resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==}
@ -936,6 +1095,10 @@ packages:
engines: {node: '>=18'}
hasBin: true
escalade@3.2.0:
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
engines: {node: '>=6'}
escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
@ -991,6 +1154,10 @@ packages:
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
gensync@1.0.0-beta.2:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
get-east-asian-width@1.2.0:
resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==}
engines: {node: '>=18'}
@ -1004,6 +1171,10 @@ packages:
glob-to-regexp@0.4.1:
resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
globals@11.12.0:
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
engines: {node: '>=4'}
h3@1.15.1:
resolution: {integrity: sha512-+ORaOBttdUm1E2Uu/obAyCguiI7MbBvsLTndc3gyK3zU+SYLoZXlyCP9Xgy0gikkGufFLTZXCXD6+4BsufnmHA==}
@ -1090,10 +1261,23 @@ packages:
resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
engines: {node: '>=16'}
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
jsesc@3.1.0:
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
engines: {node: '>=6'}
hasBin: true
json5@2.2.3:
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
engines: {node: '>=6'}
hasBin: true
kleur@3.0.3:
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
engines: {node: '>=6'}
@ -1102,15 +1286,15 @@ packages:
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
engines: {node: '>=6'}
lanyard-wrapper@2.0.1:
resolution: {integrity: sha512-wDMqGTEzc1AXvs3i2JaVkDHCzA7FCkpsdlJIpypOiDhhkIYJhhnDzOo91FQ3E6u5fQiF1Q8vfOOKm3kZ3peQSw==}
longest-streak@3.1.0:
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
magic-string@0.25.9:
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
@ -1299,6 +1483,9 @@ packages:
node-mock-http@1.0.0:
resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==}
node-releases@2.0.19:
resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
@ -1364,6 +1551,15 @@ packages:
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
engines: {node: ^10 || ^12 || >=14}
prettier-plugin-astro@0.14.1:
resolution: {integrity: sha512-RiBETaaP9veVstE4vUwSIcdATj6dKmXljouXc/DDNwBSPTp8FRkLGDSGFClKsAFeeg+13SB0Z1JZvbD76bigJw==}
engines: {node: ^14.15.0 || >=16.0.0}
prettier@3.5.3:
resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==}
engines: {node: '>=14'}
hasBin: true
printable-characters@1.0.42:
resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==}
@ -1388,6 +1584,19 @@ packages:
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
engines: {node: '>= 0.6'}
react-dom@19.0.0:
resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==}
peerDependencies:
react: ^19.0.0
react-refresh@0.14.2:
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
engines: {node: '>=0.10.0'}
react@19.0.0:
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
engines: {node: '>=0.10.0'}
readdirp@4.1.2:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
@ -1459,6 +1668,19 @@ packages:
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
s.color@0.0.15:
resolution: {integrity: sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==}
sass-formatter@0.7.9:
resolution: {integrity: sha512-CWZ8XiSim+fJVG0cFLStwDvft1VI7uvXdCNJYXhDvowiv+DsbD1nXLiQ4zrE5UBvj5DWZJ93cwN0NX5PMsr1Pw==}
scheduler@0.25.0:
resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
semver@7.7.1:
resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==}
engines: {node: '>=10'}
@ -1536,6 +1758,9 @@ packages:
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
engines: {node: '>=12'}
suf-log@2.5.3:
resolution: {integrity: sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==}
tinyexec@0.3.2:
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
@ -1680,6 +1905,12 @@ packages:
uploadthing:
optional: true
update-browserslist-db@1.1.3:
resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==}
hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
vfile-location@5.0.3:
resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
@ -1822,6 +2053,9 @@ packages:
xxhash-wasm@1.1.0:
resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==}
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
@ -1865,6 +2099,11 @@ snapshots:
7.css@0.16.0: {}
'@ampproject/remapping@2.3.0':
dependencies:
'@jridgewell/gen-mapping': 0.3.8
'@jridgewell/trace-mapping': 0.3.25
'@astrojs/cloudflare@12.2.4(astro@5.5.2(rollup@4.34.9)(typescript@5.8.2))':
dependencies:
'@astrojs/internal-helpers': 0.6.1
@ -1936,6 +2175,29 @@ snapshots:
dependencies:
prismjs: 1.29.0
'@astrojs/react@4.2.1(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@types/react': 19.0.10
'@types/react-dom': 19.0.4(@types/react@19.0.10)
'@vitejs/plugin-react': 4.3.4(vite@6.2.2)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
ultrahtml: 1.5.3
vite: 6.2.2
transitivePeerDependencies:
- '@types/node'
- jiti
- less
- lightningcss
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
- tsx
- yaml
'@astrojs/telemetry@3.2.0':
dependencies:
ci-info: 4.2.0
@ -1950,14 +2212,111 @@ snapshots:
'@astrojs/underscore-redirects@0.6.0': {}
'@babel/code-frame@7.26.2':
dependencies:
'@babel/helper-validator-identifier': 7.25.9
js-tokens: 4.0.0
picocolors: 1.1.1
'@babel/compat-data@7.26.8': {}
'@babel/core@7.26.10':
dependencies:
'@ampproject/remapping': 2.3.0
'@babel/code-frame': 7.26.2
'@babel/generator': 7.26.10
'@babel/helper-compilation-targets': 7.26.5
'@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10)
'@babel/helpers': 7.26.10
'@babel/parser': 7.26.10
'@babel/template': 7.26.9
'@babel/traverse': 7.26.10
'@babel/types': 7.26.10
convert-source-map: 2.0.0
debug: 4.4.0
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
transitivePeerDependencies:
- supports-color
'@babel/generator@7.26.10':
dependencies:
'@babel/parser': 7.26.10
'@babel/types': 7.26.10
'@jridgewell/gen-mapping': 0.3.8
'@jridgewell/trace-mapping': 0.3.25
jsesc: 3.1.0
'@babel/helper-compilation-targets@7.26.5':
dependencies:
'@babel/compat-data': 7.26.8
'@babel/helper-validator-option': 7.25.9
browserslist: 4.24.4
lru-cache: 5.1.1
semver: 6.3.1
'@babel/helper-module-imports@7.25.9':
dependencies:
'@babel/traverse': 7.26.10
'@babel/types': 7.26.10
transitivePeerDependencies:
- supports-color
'@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)':
dependencies:
'@babel/core': 7.26.10
'@babel/helper-module-imports': 7.25.9
'@babel/helper-validator-identifier': 7.25.9
'@babel/traverse': 7.26.10
transitivePeerDependencies:
- supports-color
'@babel/helper-plugin-utils@7.26.5': {}
'@babel/helper-string-parser@7.25.9': {}
'@babel/helper-validator-identifier@7.25.9': {}
'@babel/helper-validator-option@7.25.9': {}
'@babel/helpers@7.26.10':
dependencies:
'@babel/template': 7.26.9
'@babel/types': 7.26.10
'@babel/parser@7.26.10':
dependencies:
'@babel/types': 7.26.10
'@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.10)':
dependencies:
'@babel/core': 7.26.10
'@babel/helper-plugin-utils': 7.26.5
'@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.10)':
dependencies:
'@babel/core': 7.26.10
'@babel/helper-plugin-utils': 7.26.5
'@babel/template@7.26.9':
dependencies:
'@babel/code-frame': 7.26.2
'@babel/parser': 7.26.10
'@babel/types': 7.26.10
'@babel/traverse@7.26.10':
dependencies:
'@babel/code-frame': 7.26.2
'@babel/generator': 7.26.10
'@babel/parser': 7.26.10
'@babel/template': 7.26.9
'@babel/types': 7.26.10
debug: 4.4.0
globals: 11.12.0
transitivePeerDependencies:
- supports-color
'@babel/types@7.26.10':
dependencies:
'@babel/helper-string-parser': 7.25.9
@ -2146,6 +2505,10 @@ snapshots:
'@fastify/busboy@2.1.1': {}
'@fontsource-variable/noto-emoji@5.2.5': {}
'@fontsource/inter@5.2.5': {}
'@img/sharp-darwin-arm64@0.33.5':
optionalDependencies:
'@img/sharp-libvips-darwin-arm64': 1.0.4
@ -2221,10 +2584,23 @@ snapshots:
'@img/sharp-win32-x64@0.33.5':
optional: true
'@jridgewell/gen-mapping@0.3.8':
dependencies:
'@jridgewell/set-array': 1.2.1
'@jridgewell/sourcemap-codec': 1.5.0
'@jridgewell/trace-mapping': 0.3.25
'@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/set-array@1.2.1': {}
'@jridgewell/sourcemap-codec@1.5.0': {}
'@jridgewell/trace-mapping@0.3.25':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
'@jridgewell/trace-mapping@0.3.9':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
@ -2332,6 +2708,27 @@ snapshots:
'@shikijs/vscode-textmate@10.0.2': {}
'@types/babel__core@7.20.5':
dependencies:
'@babel/parser': 7.26.10
'@babel/types': 7.26.10
'@types/babel__generator': 7.6.8
'@types/babel__template': 7.4.4
'@types/babel__traverse': 7.20.6
'@types/babel__generator@7.6.8':
dependencies:
'@babel/types': 7.26.10
'@types/babel__template@7.4.4':
dependencies:
'@babel/parser': 7.26.10
'@babel/types': 7.26.10
'@types/babel__traverse@7.20.6':
dependencies:
'@babel/types': 7.26.10
'@types/cookie@0.6.0': {}
'@types/debug@4.1.12':
@ -2354,10 +2751,29 @@ snapshots:
dependencies:
'@types/unist': 3.0.2
'@types/react-dom@19.0.4(@types/react@19.0.10)':
dependencies:
'@types/react': 19.0.10
'@types/react@19.0.10':
dependencies:
csstype: 3.1.3
'@types/unist@3.0.2': {}
'@ungap/structured-clone@1.2.0': {}
'@vitejs/plugin-react@4.3.4(vite@6.2.2)':
dependencies:
'@babel/core': 7.26.10
'@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10)
'@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10)
'@types/babel__core': 7.20.5
react-refresh: 0.14.2
vite: 6.2.2
transitivePeerDependencies:
- supports-color
acorn-walk@8.3.2: {}
acorn@8.14.0: {}
@ -2504,8 +2920,17 @@ snapshots:
widest-line: 5.0.0
wrap-ansi: 9.0.0
browserslist@4.24.4:
dependencies:
caniuse-lite: 1.0.30001704
electron-to-chromium: 1.5.119
node-releases: 2.0.19
update-browserslist-db: 1.1.3(browserslist@4.24.4)
camelcase@8.0.0: {}
caniuse-lite@1.0.30001704: {}
ccount@2.0.1: {}
chalk@5.3.0: {}
@ -2552,6 +2977,8 @@ snapshots:
confbox@0.1.8: {}
convert-source-map@2.0.0: {}
cookie-es@1.2.2: {}
cookie@0.5.0: {}
@ -2564,6 +2991,8 @@ snapshots:
cssesc@3.0.0: {}
csstype@3.1.3: {}
data-uri-to-buffer@2.0.2: {}
debug@4.3.6:
@ -2609,6 +3038,8 @@ snapshots:
ee-first@1.1.1: {}
electron-to-chromium@1.5.119: {}
emoji-regex-xs@1.0.0: {}
emoji-regex@10.3.0: {}
@ -2674,6 +3105,8 @@ snapshots:
'@esbuild/win32-ia32': 0.25.0
'@esbuild/win32-x64': 0.25.0
escalade@3.2.0: {}
escape-html@1.0.3: {}
escape-string-regexp@4.0.0: {}
@ -2707,6 +3140,8 @@ snapshots:
fsevents@2.3.3:
optional: true
gensync@1.0.0-beta.2: {}
get-east-asian-width@1.2.0: {}
get-source@2.0.12:
@ -2718,6 +3153,8 @@ snapshots:
glob-to-regexp@0.4.1: {}
globals@11.12.0: {}
h3@1.15.1:
dependencies:
cookie-es: 1.2.2
@ -2878,20 +3315,28 @@ snapshots:
dependencies:
is-inside-container: 1.0.0
js-tokens@4.0.0: {}
js-yaml@4.1.0:
dependencies:
argparse: 2.0.1
jsesc@3.1.0: {}
json5@2.2.3: {}
kleur@3.0.3: {}
kleur@4.1.5: {}
lanyard-wrapper@2.0.1: {}
longest-streak@3.1.0: {}
lru-cache@10.4.3: {}
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
magic-string@0.25.9:
dependencies:
sourcemap-codec: 1.4.8
@ -3270,6 +3715,8 @@ snapshots:
node-mock-http@1.0.0: {}
node-releases@2.0.19: {}
normalize-path@3.0.0: {}
ofetch@1.4.1:
@ -3340,6 +3787,14 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
prettier-plugin-astro@0.14.1:
dependencies:
'@astrojs/compiler': 2.11.0
prettier: 3.5.3
sass-formatter: 0.7.9
prettier@3.5.3: {}
printable-characters@1.0.42: {}
prismjs@1.29.0: {}
@ -3357,6 +3812,15 @@ snapshots:
range-parser@1.2.1: {}
react-dom@19.0.0(react@19.0.0):
dependencies:
react: 19.0.0
scheduler: 0.25.0
react-refresh@0.14.2: {}
react@19.0.0: {}
readdirp@4.1.2: {}
regex-recursion@5.1.1:
@ -3506,6 +3970,16 @@ snapshots:
'@rollup/rollup-win32-x64-msvc': 4.34.9
fsevents: 2.3.3
s.color@0.0.15: {}
sass-formatter@0.7.9:
dependencies:
suf-log: 2.5.3
scheduler@0.25.0: {}
semver@6.3.1: {}
semver@7.7.1: {}
send@1.1.0:
@ -3618,6 +4092,10 @@ snapshots:
dependencies:
ansi-regex: 6.0.1
suf-log@2.5.3:
dependencies:
s.color: 0.0.15
tinyexec@0.3.2: {}
tinyglobby@0.2.12:
@ -3723,6 +4201,12 @@ snapshots:
ofetch: 1.4.1
ufo: 1.5.4
update-browserslist-db@1.1.3(browserslist@4.24.4):
dependencies:
browserslist: 4.24.4
escalade: 3.2.0
picocolors: 1.1.1
vfile-location@5.0.3:
dependencies:
'@types/unist': 3.0.2
@ -3803,6 +4287,8 @@ snapshots:
xxhash-wasm@1.1.0: {}
yallist@3.1.1: {}
yargs-parser@21.1.1: {}
yocto-queue@1.1.1: {}

BIN
public/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

View file

@ -1,9 +0,0 @@
---
const {position, text, url, id} = Astro.props;
---
<style>
button, a {
width: 100%;
}
</style>
{url ? <a href={url}><button id={id}>{text}</button></a> : <button id={id}>{text}</button>}

View file

@ -1,11 +0,0 @@
<style>
div {
display: grid;
grid-auto-flow: row;
row-gap: 5px;
}
</style>
<div class="button-collection">
<slot />
</div>

View file

@ -1,10 +0,0 @@
---
import Social from "./Social.astro"
const contacts: any = Object.values(import.meta.glob("../../info/contacts/*.md", {
eager: true
}));
---
<ul>
{contacts.map(contact => <Social platform={contact.frontmatter.platform} url={contact.frontmatter.url} name={contact.frontmatter.name} note={contact.frontmatter.note}/>)}
</ul>

View file

@ -1,23 +0,0 @@
<style>
div {
color: black;
background-color: lightcoral;
padding: 10px;
margin-bottom: 20px;
border-radius: 10px;
}
a {
color: blue;
}
</style>
<noscript>
<div>
<p>
<h4>ENABLE JAVASCRIPT OR I WILL KILL YOU</h4>
I will not. However, you seem to be living in fear of technology, as you have JavaScript disabled. This means that some features (eg. dragging, submitting forms) will not work. Enable JS to fully enjoy this website!
<br/>
Rest assured, there's no external tracking. You can check this site's source code on the <a href="https://git.nin0.dev/nin0/website">nin0/website</a> repository on my Forgejo.
</p>
</div>
</noscript>

View file

@ -1,16 +0,0 @@
---
const {name} = Astro.props
---
<style>
fieldset {
margin-top: 10px;
margin-bottom: 0px;
padding: 0px 15px;
}
</style>
<fieldset>
<legend>{name}</legend>
<slot />
</fieldset>

View file

@ -1,31 +0,0 @@
---
import Contacts from "../components/Contacts.astro";
import GroupBox from "../components/GroupBox.astro";
import Me from "../components/Me.astro";
import Presence from "../components/Presence.astro";
import Window from "../components/Window.astro";
import Button from "./Button.astro";
import ButtonCollection from "./ButtonCollection.astro";
import Spacer from "./Spacer.astro";
---
<Window title="Home" maxWidth="600px" showClose={true}>
<Me />
<Presence />
<GroupBox name="About me">
<p>
I'm a Canadian self-taught software developer.
<br/>
I also make things that some people use with varying degrees of usefulness.
</p>
</GroupBox>
<GroupBox name="Reach out">
<Contacts />
</GroupBox>
<ButtonCollection>
<Button position="left" text="Projects (soon)" url="/projects"/>
<Spacer />
<Button position="left" text="Code (soon)" url="/code"/>
<Spacer />
<Button position="left" text="Blog (ETA: 100 years)" url="/code"/>
</ButtonCollection>
</Window>

View file

@ -1,45 +0,0 @@
---
import {fetchUserData, type DiscordStatus} from "lanyard-wrapper";
const rawUserData = await fetchUserData("886685857560539176");
const statusColor = () => {
switch (rawUserData.discord_status) {
case "online":
return "#23a55a";
case "idle":
return "#f0b232";
case "dnd":
return "#f23f43";
case "offline":
return "#80848e";
default:
return "#80848e";
}
};
---
<style define:vars={{statusColor: statusColor()}}>
div {
display: flex;
}
h3 {
font-weight: 400;
margin-left: 20px;
margin-top: auto;
margin-bottom: auto;
}
img {
width: 90px;
height: 90px;
border-radius: 6px;
box-shadow: 10px black;
border-color: var(--statusColor);
border-style: solid;
border-width: 2px;
}
</style>
<div>
<img src="logo.png" alt="the nin0dev logo">
<h3>nin0 <span style="font-size: 0.4em;">(he/him)</span></h3>
</div>

View file

@ -1,55 +0,0 @@
---
import {fetchUserData} from "lanyard-wrapper";
const rawUserData = await fetchUserData("886685857560539176");
const activity = (() => {
let finalActivity = {
type: undefined,
name: undefined,
artist: undefined
};
rawUserData.activities.some((activity => {
if(activity.type === 0) {
finalActivity = {
type: "playing",
name: activity.name,
artist: undefined
};
return;
}
}));
if(finalActivity.type !== undefined) return finalActivity;
if(rawUserData.listening_to_spotify) {
finalActivity = {
type: "listening",
name: rawUserData.spotify.song,
artist: rawUserData.spotify.artist
};
};
return finalActivity;
})();
---
<style>
div {
margin-top: 10px;
display: flex;
}
p {
margin-top: auto;
margin-bottom: auto;
margin-left: 10px;
}
img {
width: 30px;
height: 30px;
}
</style>
{
activity.type !== undefined &&
<div>
<img src={activity.type === "playing" ? "/game.ico" : "/music.ico"}>
<p>{`${activity.type === "playing" ? "Playing" : "Listening to"} ${activity.name}${activity.type === "listening" ? ` - ${activity.artist}` : ""}`}</p>
</div>
}

View file

@ -1,16 +0,0 @@
---
const {platform, name, url, note} = Astro.props;
---
<style>
bl {
font-weight: 500;
}
it {
font-style: italic;
}
</style>
<li>
<bl>{platform}</bl>: {url ? <a href={url}>{name}</a> : name}{note && <it> ({note})</it>}
</li>

View file

@ -1 +0,0 @@
<span />

View file

@ -1,39 +0,0 @@
---
const {title, showClose, maxWidth} = Astro.props
---
<style define:vars={{ maxWidth }}>
.window {
max-width: var(--maxWidth);
position: absolute;
}
.window-body {
padding: 20px !important;
}
@media (pointer:coarse) {
.window {
position: absolute;
top: 0px;
left: 0px;
margin: 5%;
width: 90%;
}
}
</style>
<div class="background" class="window">
<div class="window glass active" style="max-width: 100%">
<div class="title-bar">
<div class="title-bar-text">{title}</div>
{
showClose &&
<div class="title-bar-controls">
<button aria-label="Close" onclick="window.close()"></button>
</div>
}
</div>
<div class="window-body has-space">
<slot />
</div>
</div>
</div>

View file

@ -0,0 +1,29 @@
---
const { position, text, url, id, onClick } = Astro.props;
---
<style>
button,
a {
width: 100%;
}
button {
background-color: #45475a;
border: 1px var(--text) solid;
border-radius: 10px;
color: var(--text);
padding: 8px 20px;
}
button:hover {
background-color: #585b70;
}
</style>
{
url ? (
<a href={url}>
<button id={id}>{text}</button>
</a>
) : (
<button id={id}>{text}</button>
)
}

View file

@ -0,0 +1,11 @@
<style>
div {
display: grid;
grid-auto-flow: row;
row-gap: 8px;
margin-top: 15px;
}
</style>
<div class="button-collection">
<slot />
</div>

View file

@ -0,0 +1,19 @@
---
const { name } = Astro.props;
---
<style>
div {
margin-top: 15px;
margin-bottom: 0px;
padding: 0px 15px;
border-radius: 15px;
border: 1px solid #313244;
background-color: #313244;
}
</style>
<div>
<h3>{name}</h3>
<slot />
</div>

View file

@ -0,0 +1 @@
<span></span>

View file

@ -0,0 +1,89 @@
---
const { title, showClose, maxWidth, hideByDefault, customClass, offset } =
Astro.props;
const randomID = customClass || Math.random().toString().replace(".", "");
---
<style define:vars={{ maxWidth, offset }}>
.window {
width: var(--maxWidth);
top: var(--offset);
left: var(--offset);
position: absolute;
}
.title-bar {
.title-bar-text {
margin-top: 2.5px !important;
}
display: flex;
justify-content: space-between;
background-color: #313244;
border-radius: 15px 15px 0 0;
padding: 9px 18px 9px 18px;
}
svg {
fill: var(--text);
margin: 0;
padding: 0;
height: 24px !important;
}
#close {
background: none;
color: inherit;
border: none;
padding: 0;
margin: 0;
height: 24px !important;
font: inherit;
cursor: pointer;
outline: inherit;
}
.window-body {
padding: 20px !important;
background-color: #1e1e2e;
border-radius: 0 0 20px 20px;
}
@media (pointer: coarse) {
.window {
position: absolute;
top: 0px;
left: 0px;
margin: 5%;
width: 90%;
}
}
</style>
<div
class="background"
id={`window-${randomID}`}
class="window"
style={hideByDefault && "display: none;"}
>
<div class="window" style="max-width: 100%">
<div class="title-bar">
<div class="title-bar-text">{title}</div>
{
showClose && (
<button
id="close"
aria-label="Close"
onclick={`document.querySelector("#window-${randomID}").style.display = "none";`}
>
<svg
xmlns="http://www.w3.org/2000/svg"
height="24px"
viewBox="0 -960 960 960"
>
<path d="m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z" />
</svg>
</button>
)
}
</div>
<div class="window-body">
<slot />
</div>
</div>
</div>

View file

@ -0,0 +1,34 @@
---
import GroupBox from "@components/GroupBox.astro";
import Window from "@components/Window.astro";
---
<Window
title="Code"
maxWidth="400px"
showClose={true}
hideByDefault={true}
customClass="code-window"
offset="55px"
>
<p>
As mentioned in the main page, I write code. Some used by a lot, some
not as much. You can find it on:
<GroupBox name="GitHub (@nin0-dev)">
Here, you'll find most of my external contributions. I rarely start
personal projects on GitHub.
<br />
<a href="https://gh.nin0.dev">Go!</a>
<br />
<br />
</GroupBox>
<GroupBox name="Forgejo (@nin0)">
Some more personal/niche projects can be found on my own instance
(git.nin0.dev), which will probably be down.
<br />
<a href="https://git.nin0.dev/nin0">Go!</a>
<br />
<br />
</GroupBox>
</p>
</Window>

View file

@ -0,0 +1,22 @@
---
import Social from "./Social.astro";
const contacts: any = Object.values(
import.meta.glob("../../../../info/contacts/*.md", {
eager: true
})
);
---
<ul>
{
contacts.map(contact => (
<Social
platform={contact.frontmatter.platform}
url={contact.frontmatter.url}
name={contact.frontmatter.name}
note={contact.frontmatter.note}
/>
))
}
</ul>

View file

@ -0,0 +1,28 @@
<style>
div {
color: black;
background-color: lightcoral;
padding: 10px;
margin-bottom: 20px;
border-radius: 10px;
}
a {
color: blue;
}
</style>
<noscript>
<div>
<p>
<h4>ENABLE JAVASCRIPT OR I WILL KILL YOU</h4>
I will not. However, you seem to be living in fear of technology, as
you have JavaScript disabled. This means that some features (eg. dragging,
submitting forms) will not work. Enable JS to fully enjoy this website!
<br />
Rest assured, there's no external tracking. You can check this site's
source code on the <a href="https://git.nin0.dev/nin0/website"
>nin0/website</a
> repository on my Forgejo.
</p>
</div>
</noscript>

View file

@ -0,0 +1,36 @@
---
import Contacts from "./Contacts.astro";
import GroupBox from "@components/GroupBox.astro";
import Me from "./Me";
import Window from "@components/Window.astro";
import Button from "@components/Button.astro";
import ButtonCollection from "@components/ButtonCollection.astro";
import Spacer from "@components/Spacer.astro";
---
<script>
document
.querySelector("#show-code-window")
.addEventListener("click", () => {
// @ts-ignore
document.querySelector("#window-code-window").style.display =
"block";
});
</script>
<Window title="Home" maxWidth="600px" showClose={false}>
<Me client:only />
<ButtonCollection>
<Button position="left" text="My code" id="show-code-window" />
</ButtonCollection>
<GroupBox name="About me">
<p>
I'm a Canadian self-taught software developer.
<br />
I also make things that some people use with varying degrees of usefulness.
</p>
</GroupBox>
<GroupBox name="Reach out">
<Contacts />
</GroupBox>
</Window>

View file

@ -0,0 +1,161 @@
import "@css/me.css";
import { initLanyard } from "@js/lanyard/lanyard";
import { type LanyardPresence } from "../../../js/lanyard/types";
import { useEffect, useState } from "react";
export default function Me() {
// me-e-eeeee
const [presence, setPresence] = useState<LanyardPresence | undefined>();
const [currentlyPlaying, setCurrentlyPlaying] = useState<
| {
title: string;
artist: string;
album: string;
albumArt: string;
loved: boolean;
streak: number;
}
| undefined
>();
useEffect(() => {
initLanyard(presence => {
console.log(presence);
setPresence(presence);
});
async function getLastFmTracks() {
const params = new URLSearchParams({
method: "user.getrecenttracks",
api_key: "3c5623fa1abbd11c49f53ca18e992ead",
user: "nin0dev",
limit: "50",
format: "json",
extended: "true"
});
const res = await (
await fetch(`https://ws.audioscrobbler.com/2.0/?${params}`)
).json();
if (
res.recenttracks.track.some(t => {
try {
return t["@attr"].nowplaying === "true";
} catch (e) {
return false;
}
})
) {
const currentlyPlayingTrack = res.recenttracks.track[0];
setCurrentlyPlaying({
title: currentlyPlayingTrack.name,
artist: currentlyPlayingTrack.artist.name,
album: currentlyPlayingTrack.album["#text"],
albumArt: currentlyPlayingTrack.image[1]["#text"],
loved: currentlyPlayingTrack.loved === "1",
streak: (() => {
let current = 0;
for (const track of res.recenttracks.track) {
if (track.name === currentlyPlayingTrack.name)
current++;
else return current;
}
})()
});
} else {
setCurrentlyPlaying(undefined);
}
}
getLastFmTracks();
setInterval(getLastFmTracks, 10000);
}, []);
return (
<>
<div className="me-container">
<img src="logo.png" alt="the nin0 logo" />
<h3>
nin0 <span style={{ fontSize: "0.9rem" }}>(he/him)</span>
</h3>
</div>
{currentlyPlaying && (
<div className="spotify-card">
<h3>Listening to</h3>
<div
className="spotify-card-background"
style={{
backgroundImage: `url(${currentlyPlaying.albumArt})`
}}
></div>
<div
className="spotify-card-content"
style={{
display: "flex",
alignItems: "center",
marginBottom: "10px"
}}
>
<img
src={currentlyPlaying.albumArt}
style={{
marginRight: "10px",
width: "50px",
borderRadius: "5px"
}}
/>
<div>
<p style={{ margin: "0", fontWeight: "600" }}>
{currentlyPlaying.title}
</p>
<p style={{ margin: "0" }}>
<span className="prefix">by </span>
{currentlyPlaying.artist}
</p>
<p style={{ margin: "0" }}>
<span className="prefix">on </span>
{currentlyPlaying.album}
</p>
</div>
</div>
<p style={{ fontSize: "0.9rem" }} className="emoji">
{(() => {
const flags: {
color: string;
data: string;
}[] = [];
if (currentlyPlaying.loved)
flags.push({
color: "#f38ba8",
data: "💞 Loved track"
});
if (currentlyPlaying.streak > 1) {
flags.push({
color: "#f9e2af",
data: `⚡ Played ${currentlyPlaying.streak} times in a row`
});
}
return flags.map(flag => (
<span
style={{ color: flag.color }}
className="emoji"
key={flag.color}
>
{flag.data}{" "}
{flags.indexOf(flag) !==
flags.length - 1 && (
<span style={{ color: "white" }}>
{" "}{" "}
</span>
)}
</span>
));
})()}
</p>
</div>
)}
</>
);
}

View file

@ -0,0 +1,18 @@
---
const { platform, name, url, note } = Astro.props;
---
<style>
bl {
font-weight: 500;
}
it {
font-style: italic;
}
</style>
<li>
<bl>{platform}</bl>: {url ? <a href={url}>{name}</a> : name}{
note && <it> ({note})</it>
}
</li>

48
src/css/me.css Normal file
View file

@ -0,0 +1,48 @@
.me-container {
display: flex;
h3 {
color: #89b4fa;
font-weight: 400;
font-size: 2rem;
margin-left: 20px;
margin-top: auto;
margin-bottom: auto;
}
img {
width: 80px;
height: 80px;
border-radius: 6px;
box-shadow: 10px black;
border-style: solid;
border-width: 2px;
}
}
.spotify-card {
h3 {
margin: 13px 0;
}
.prefix {
color: #a6adc8 !important;
}
.spotify-card-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
border-radius: 15px;
filter: brightness(0.3) blur(8px);
background-size: cover;
background-position: center;
overflow: hidden;
}
position: relative;
background-color: transparent;
padding: 5px 15px;
margin-top: 15px;
border-radius: 15px;
border: 2px solid #cdd6f4;
z-index: 0;
overflow: hidden;
}

View file

@ -1,11 +1,26 @@
:root {
--background: url("/background.png");
--text: #cdd6f4;
}
* {
font-family: Inter, sans-serif;
}
body {
background-color: #56a0d1;
background: var(--background);
font-size: 0.95rem;
color: var(--text);
padding: 30px;
font-family: sans-serif !important;
overflow: hidden;
}
a {
color: #89b4fa;
}
@media (pointer: coarse) {
body {
overflow: scroll;
}
}
.emoji {
font-family: "Inter", "Noto Emoji Variable";
}

View file

@ -1,6 +1,6 @@
// wow i love being fake programmer
// source: https://jams.hackclub.com/batch/webOS/part-3
function dragElement(element) {
export function dragElement(element) {
var initialX = 0;
var initialY = 0;
var currentX = 0;
@ -26,8 +26,6 @@ function dragElement(element) {
currentY = initialY - e.clientY;
initialX = e.clientX;
initialY = e.clientY;
console.log(element.offsetTop);
console.log(currentX);
element.style.top = element.offsetTop - currentY + "px";
element.style.left = element.offsetLeft - currentX + "px";
}
@ -35,7 +33,5 @@ function dragElement(element) {
function stopDragging() {
document.onmouseup = null;
document.onmousemove = null;
console.log(element.offsetTop - currentY);
console.log(element.offsetLeft - currentX);
}
}

1
src/js/lanyard/lanyard.d.ts vendored Normal file
View file

@ -0,0 +1 @@
declare module "@js/lanyard/lanyard";

56
src/js/lanyard/lanyard.ts Normal file
View file

@ -0,0 +1,56 @@
import type {
AnyLanyardPayload,
LanyardInitStatePayload,
LanyardPayload,
LanyardPresence,
LanyardPresenceUpdatePayload
} from "./types";
function sendToSocket(socket: WebSocket, data: AnyLanyardPayload) {
socket.send(JSON.stringify(data));
}
export function initLanyard(
updateCallback: (presence: LanyardPresence) => void
) {
const socket = new WebSocket("wss://api.lanyard.rest/socket");
socket.onmessage = data => {
const payload: LanyardPayload = JSON.parse(data.data);
switch (payload.op) {
case 1: {
// Initialize
sendToSocket(socket, {
op: 2,
d: {
subscribe_to_ids: ["886685857560539176"]
}
});
sendToSocket(socket, {
op: 3
});
setInterval(
() => {
sendToSocket(socket, {
op: 3
});
},
"heartbeat_interval" in payload.d
? payload.d.heartbeat_interval
: 30000
);
break;
}
case 0: {
const typedPayload = payload as
| LanyardInitStatePayload
| LanyardPresenceUpdatePayload;
updateCallback(
typedPayload.t === "INIT_STATE"
? typedPayload.d["886685857560539176"]
: typedPayload.d
);
}
}
};
}

65
src/js/lanyard/types.ts Normal file
View file

@ -0,0 +1,65 @@
export interface LanyardPresence {
listening_to_spotify: boolean;
spotify: {
track_id: string;
timestamps: {
start: number;
end: number;
};
song: string;
artist: string;
album_art_url: string;
album: string;
};
discord_status: string;
activities: {
type: number;
timestamps: {
start: number;
end: number;
};
state: string;
name: string;
id: string;
details: string;
assets: {
small_text: string;
small_image: string;
large_text: string;
large_image: string;
};
application_id: string;
}[];
}
export interface AnyLanyardPayload {
op: 0 | 1 | 2 | 3;
d?: object;
}
export interface LanyardHelloPayload {
op: 1;
d: {
heartbeat_interval: number;
};
}
export interface LanyardInitStatePayload {
op: 0;
t: "INIT_STATE";
d: {
[user_id: string]: LanyardPresence;
};
}
export interface LanyardPresenceUpdatePayload {
op: 0;
t: "PRESENCE_UPDATE";
d: LanyardPresence;
}
export type LanyardPayload =
| LanyardHelloPayload
| LanyardInitStatePayload
| LanyardPresenceUpdatePayload
| AnyLanyardPayload;

View file

@ -1,76 +1,29 @@
---
import "7.css/dist/7.css";
import "../css/style.css";
import "@fontsource/inter";
import "@fontsource-variable/noto-emoji";
const {tabTitle} = Astro.props;
const { tabTitle } = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{tabTitle}</title>
</head>
<body>
<slot />
<script>
function dragElement(element) {
// Step 2: Set up variables to keep track of the element's position.
var initialX = 0;
var initialY = 0;
var currentX = 0;
var currentY = 0;
// Step 3: Check if there is a special header element associated with the draggable element.
if (document.getElementById("title-bar")) {
// Step 4: If present, assign the `dragMouseDown` function to the header's `onmousedown` event.
// This allows you to drag the window around by its header.
document.getElementById("title-bar").onmousedown = startDragging;
} else {
// Step 5: If not present, assign the function directly to the draggable element's `onmousedown` event.
// This allows you to drag the window by holding down anywhere on the window.
element.onmousedown = startDragging;
}
// Step 6: Define the `startDragging` function to capture the initial mouse position and set up event listeners.
function startDragging(e) {
e = e || window.event;
e.preventDefault();
// Step 7: Get the mouse cursor position at startup.
initialX = e.clientX;
initialY = e.clientY;
// Step 8: Set up event listeners for mouse movement (`elementDrag`) and mouse button release (`closeDragElement`).
document.onmouseup = stopDragging;
document.onmousemove = dragElement;
}
// Step 9: Define the `elementDrag` function to calculate the new position of the element based on mouse movement.
function dragElement(e) {
e = e || window.event;
e.preventDefault();
// Step 10: Calculate the new cursor position.
currentX = initialX - e.clientX;
currentY = initialY - e.clientY;
initialX = e.clientX;
initialY = e.clientY;
// Step 11: Update the element's new position by modifying its `top` and `left` CSS properties.
element.style.top = (element.offsetTop - currentY) + "px";
element.style.left = (element.offsetLeft - currentX) + "px";
}
// Step 12: Define the `stopDragging` function to stop tracking mouse movement by removing the event listeners.
function stopDragging() {
document.onmouseup = null;
document.onmousemove = null;
}
}
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".window").forEach(window => {
dragElement(window);
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{tabTitle}</title>
</head>
<body>
<slot />
<script>
import { dragElement } from "@js/drag";
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".window").forEach(window => {
dragElement(window);
});
});
});
</script>
</body>
</script>
</body>
</html>

View file

@ -1,10 +1,13 @@
---
import FearOfTechnology from "../components/FearOfTechnology.astro";
import MainWindow from "../components/MainWindow.astro";
import FearOfTechnology from "@windows/mainWindow/FearOfTechnology.astro";
import MainWindow from "@windows/mainWindow/MainWindow.astro";
import BaseLayout from "../layouts/BaseLayout.astro";
import Window from "@components/Window.astro";
import CodeWindow from "@windows/code/CodeWindow.astro";
---
<BaseLayout tabTitle="Home - nin0dev">
<BaseLayout tabTitle="nin0.dev">
<FearOfTechnology />
<MainWindow />
<CodeWindow />
</BaseLayout>

View file

@ -1,3 +1,17 @@
{
"extends": "astro/tsconfigs/base"
}
"extends": "astro/tsconfigs/base",
"compilerOptions": {
"baseUrl": "./src/",
"paths": {
"@components/*": ["components/commonComponents/*"],
"@windows/*": ["components/windows/*"],
"@layouts/*": ["layouts/*"],
"@css/*": ["css/*"],
"@js/*": ["js/*"],
"@info/*": ["info/*"]
},
"jsx": "react-jsx",
"jsxImportSource": "react"
},
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.astro"]
}