diff --git a/package-lock.json b/package-lock.json index 24f5d83..2160d69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,10 @@ "dependencies": { "next": "13.5.4", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "react-markdown": "^9.0.0", + "rehype-raw": "^7.0.0", + "remark-breaks": "^4.0.0" }, "devDependencies": { "@types/node": "^20", @@ -329,12 +332,41 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/debug": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.10.tgz", + "integrity": "sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.2.tgz", + "integrity": "sha512-B5hZHgHsXvfCoO3xgNJvBnX7N8p86TqQeGKXcokW4XXi+qY4vxxPSFYofytvVmpFxzPv7oxDQzjg5Un5m2/xiw==", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/mdast": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.2.tgz", + "integrity": "sha512-tYR83EignvhYO9iU3kDg8V28M0jqyh9zzp5GV+EO+AYnyUl3P5ltkTeJuTiFZQFz670FSb3EwT/6LQdX+UdKfw==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "0.7.33", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.33.tgz", + "integrity": "sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ==" + }, "node_modules/@types/node": { "version": "20.8.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.5.tgz", @@ -347,14 +379,12 @@ "node_modules/@types/prop-types": { "version": "15.7.8", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz", - "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==", - "dev": true + "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==" }, "node_modules/@types/react": { "version": "18.2.28", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.28.tgz", "integrity": "sha512-ad4aa/RaaJS3hyGz0BGegdnSRXQBkd1CCYDCdNjBPg90UUpLgo+WlJqb9fMYUxtehmzF3PJaTWqRZjko6BRzBg==", - "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -373,8 +403,12 @@ "node_modules/@types/scheduler": { "version": "0.16.4", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz", - "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==", - "dev": true + "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==" + }, + "node_modules/@types/unist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.1.tgz", + "integrity": "sha512-ue/hDUpPjC85m+PM9OQDMZr3LywT+CT6mPsQq8OJtCLiERkGRcQUFvu9XASF5XWqyZFXbf15lvb3JFJ4dRLWPg==" }, "node_modules/@typescript-eslint/parser": { "version": "6.7.5", @@ -478,6 +512,11 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -729,6 +768,15 @@ "dequal": "^2.0.3" } }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -825,6 +873,15 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -848,6 +905,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -871,8 +937,7 @@ "node_modules/csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "dev": true + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -884,7 +949,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -897,6 +961,18 @@ } } }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -938,11 +1014,22 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, "engines": { "node": ">=6" } }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -986,6 +1073,17 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/es-abstract": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", @@ -1531,6 +1629,11 @@ "node": ">=0.10.0" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1928,6 +2031,145 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.1.tgz", + "integrity": "sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.2.0.tgz", + "integrity": "sha512-wSlp23N45CMjDg/BPW8zvhEi3R+8eRE1qFbjEyAUzMCzu2l1Wzwakq+Tlia9nkCtEl5mDxa7nKHsvYJ6Gfn21A==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-url-attributes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.0.tgz", + "integrity": "sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -1978,6 +2220,11 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, "node_modules/internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -2190,6 +2437,17 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -2474,6 +2732,99 @@ "node": ">=10" } }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", + "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-newline-to-break": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-newline-to-break/-/mdast-util-newline-to-break-2.0.0.tgz", + "integrity": "sha512-MbgeFca0hLYIEx/2zGsszCSEJJ1JSCdiY5xQxRcLDDGa8EPvlLPupJ4DSajbMPAnC0je8jfb9TiUATnxxrHUog==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-find-and-replace": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.0.2.tgz", + "integrity": "sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2483,6 +2834,427 @@ "node": ">= 8" } }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", + "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.0.tgz", + "integrity": "sha512-pIgcsGxpHEtTG/rPJRz/HOLSqp5VTuIIjXlPI+6JSDlK2oljApusG6KzpS8AF0ENUMCHlC/IBb5B9xdFiVlm5Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", + "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -2520,8 +3292,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.3.6", @@ -2777,6 +3548,17 @@ "node": ">=6" } }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2883,6 +3665,15 @@ "react-is": "^16.13.1" } }, + "node_modules/property-information": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.3.0.tgz", + "integrity": "sha512-gVNZ74nqhRMiIUYWGQdosYetaKc83x8oT41a0LlV3AAFCAZwCpg4vmGkq8t34+cUhp3cnM4XDiU/7xlgK7HGrg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -2941,6 +3732,32 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, + "node_modules/react-markdown": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-9.0.0.tgz", + "integrity": "sha512-v6yNf3AB8GfJ8lCpUvzxAXKxgsHpdmWPlcVRQ6Nocsezp255E/IDrF31kLQsPJeB/cKto/geUwjU36wH784FCA==", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", @@ -2984,6 +3801,65 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-breaks": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-breaks/-/remark-breaks-4.0.0.tgz", + "integrity": "sha512-IjEjJOkH4FuJvHZVIW0QCDWxcG96kCq7An/KVH2NfJe6rKZU2AsHeB3OEjPNRxi4QC34Xdx7I2KGYn6IpT7gxQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-newline-to-break": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.0.0.tgz", + "integrity": "sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -3188,6 +4064,15 @@ "node": ">=0.10.0" } }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -3294,6 +4179,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, "node_modules/styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -3367,6 +4260,24 @@ "node": ">=8.0" } }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", + "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ts-api-utils": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", @@ -3519,6 +4430,87 @@ "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==", "dev": true }, + "node_modules/unified": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.3.tgz", + "integrity": "sha512-jlCV402P+YDcFcB2VcN/n8JasOddqIiaxv118wNBoZXEhOn+lYG7BR4Bfg2BwxvlK58dwbuH2w7GX2esAjL6Mg==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3528,6 +4520,46 @@ "punycode": "^2.1.0" } }, + "node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", + "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -3540,6 +4572,15 @@ "node": ">=10.13.0" } }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3654,6 +4695,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index f5e07d4..3f36a18 100644 --- a/package.json +++ b/package.json @@ -9,16 +9,19 @@ "lint": "next lint" }, "dependencies": { + "next": "13.5.4", "react": "^18", "react-dom": "^18", - "next": "13.5.4" + "react-markdown": "^9.0.0", + "rehype-raw": "^7.0.0", + "remark-breaks": "^4.0.0" }, "devDependencies": { - "typescript": "^5", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "eslint": "^8", - "eslint-config-next": "13.5.4" + "eslint-config-next": "13.5.4", + "typescript": "^5" } } diff --git a/public/88x31/disqordia-approved-border.png b/public/88x31/disqordia-approved-border.png new file mode 100644 index 0000000..1b7dc7f Binary files /dev/null and b/public/88x31/disqordia-approved-border.png differ diff --git a/public/88x31/dotart.png b/public/88x31/dotart.png new file mode 100644 index 0000000..1832880 Binary files /dev/null and b/public/88x31/dotart.png differ diff --git a/public/88x31/firefox4.gif b/public/88x31/firefox4.gif new file mode 100644 index 0000000..94621d5 Binary files /dev/null and b/public/88x31/firefox4.gif differ diff --git a/public/88x31/ipg.png b/public/88x31/ipg.png new file mode 100644 index 0000000..e64f0ab Binary files /dev/null and b/public/88x31/ipg.png differ diff --git a/public/88x31/ivorybutton.gif b/public/88x31/ivorybutton.gif new file mode 100644 index 0000000..1d2579f Binary files /dev/null and b/public/88x31/ivorybutton.gif differ diff --git a/public/88x31/kaboom3.gif b/public/88x31/kaboom3.gif new file mode 100644 index 0000000..47aaf6f Binary files /dev/null and b/public/88x31/kaboom3.gif differ diff --git a/public/88x31/kkdiagt.png b/public/88x31/kkdiagt.png new file mode 100644 index 0000000..225749e Binary files /dev/null and b/public/88x31/kkdiagt.png differ diff --git a/public/88x31/pjfrix2023.png b/public/88x31/pjfrix2023.png new file mode 100644 index 0000000..72a0c1d Binary files /dev/null and b/public/88x31/pjfrix2023.png differ diff --git a/public/88x31/spacy_webbutton.png b/public/88x31/spacy_webbutton.png new file mode 100644 index 0000000..6c5c46e Binary files /dev/null and b/public/88x31/spacy_webbutton.png differ diff --git a/public/88x31/sun_88x31_dual_border.png b/public/88x31/sun_88x31_dual_border.png new file mode 100644 index 0000000..2dcd1f7 Binary files /dev/null and b/public/88x31/sun_88x31_dual_border.png differ diff --git a/public/88x31/tla.png b/public/88x31/tla.png new file mode 100644 index 0000000..d4df1bf Binary files /dev/null and b/public/88x31/tla.png differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..c703ff6 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/fonts/Renogare/Renogare.otf b/public/fonts/Renogare/Renogare.otf new file mode 100644 index 0000000..3e11402 Binary files /dev/null and b/public/fonts/Renogare/Renogare.otf differ diff --git a/public/fonts/Renogare/Renogare.woff b/public/fonts/Renogare/Renogare.woff new file mode 100644 index 0000000..d6a7258 Binary files /dev/null and b/public/fonts/Renogare/Renogare.woff differ diff --git a/public/fonts/Renogare/Renogare.woff2 b/public/fonts/Renogare/Renogare.woff2 new file mode 100644 index 0000000..c7e1223 Binary files /dev/null and b/public/fonts/Renogare/Renogare.woff2 differ diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index d2f8422..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/app/api/status/index.tsx b/src/app/api/status/index.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/app/favicon.ico b/src/app/favicon.ico deleted file mode 100644 index 718d6fe..0000000 Binary files a/src/app/favicon.ico and /dev/null differ diff --git a/src/app/globals.css b/src/app/globals.css deleted file mode 100644 index d4f491e..0000000 --- a/src/app/globals.css +++ /dev/null @@ -1,107 +0,0 @@ -:root { - --max-width: 1100px; - --border-radius: 12px; - --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', - 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', - 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace; - - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; - - --primary-glow: conic-gradient( - from 180deg at 50% 50%, - #16abff33 0deg, - #0885ff33 55deg, - #54d6ff33 120deg, - #0071ff33 160deg, - transparent 360deg - ); - --secondary-glow: radial-gradient( - rgba(255, 255, 255, 1), - rgba(255, 255, 255, 0) - ); - - --tile-start-rgb: 239, 245, 249; - --tile-end-rgb: 228, 232, 233; - --tile-border: conic-gradient( - #00000080, - #00000040, - #00000030, - #00000020, - #00000010, - #00000010, - #00000080 - ); - - --callout-rgb: 238, 240, 241; - --callout-border-rgb: 172, 175, 176; - --card-rgb: 180, 185, 188; - --card-border-rgb: 131, 134, 135; -} - -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - - --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); - --secondary-glow: linear-gradient( - to bottom right, - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0.3) - ); - - --tile-start-rgb: 2, 13, 46; - --tile-end-rgb: 2, 5, 19; - --tile-border: conic-gradient( - #ffffff80, - #ffffff40, - #ffffff30, - #ffffff20, - #ffffff10, - #ffffff10, - #ffffff80 - ); - - --callout-rgb: 20, 20, 20; - --callout-border-rgb: 108, 108, 108; - --card-rgb: 100, 100, 100; - --card-border-rgb: 200, 200, 200; - } -} - -* { - box-sizing: border-box; - padding: 0; - margin: 0; -} - -html, -body { - max-width: 100vw; - overflow-x: hidden; -} - -body { - color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); -} - -a { - color: inherit; - text-decoration: none; -} - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index ae84562..6dbd13b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,22 +1,26 @@ -import './globals.css' -import type { Metadata } from 'next' -import { Inter } from 'next/font/google' - -const inter = Inter({ subsets: ['latin'] }) +import "@/styles/globals.css"; +import fonts from "@/utility/fonts"; +import type { Metadata } from "next"; export const metadata: Metadata = { - title: 'Create Next App', - description: 'Generated by create next app', -} + title: "MeowcaTheoRange", + description: "hehe :3c", +}; export default function RootLayout({ children, }: { - children: React.ReactNode + children: React.ReactNode; }) { return ( - - {children} + + + + + {children} - ) + ); } diff --git a/src/app/page.module.css b/src/app/page.module.css deleted file mode 100644 index 6676d2c..0000000 --- a/src/app/page.module.css +++ /dev/null @@ -1,229 +0,0 @@ -.main { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - padding: 6rem; - min-height: 100vh; -} - -.description { - display: inherit; - justify-content: inherit; - align-items: inherit; - font-size: 0.85rem; - max-width: var(--max-width); - width: 100%; - z-index: 2; - font-family: var(--font-mono); -} - -.description a { - display: flex; - justify-content: center; - align-items: center; - gap: 0.5rem; -} - -.description p { - position: relative; - margin: 0; - padding: 1rem; - background-color: rgba(var(--callout-rgb), 0.5); - border: 1px solid rgba(var(--callout-border-rgb), 0.3); - border-radius: var(--border-radius); -} - -.code { - font-weight: 700; - font-family: var(--font-mono); -} - -.grid { - display: grid; - grid-template-columns: repeat(4, minmax(25%, auto)); - max-width: 100%; - width: var(--max-width); -} - -.card { - padding: 1rem 1.2rem; - border-radius: var(--border-radius); - background: rgba(var(--card-rgb), 0); - border: 1px solid rgba(var(--card-border-rgb), 0); - transition: background 200ms, border 200ms; -} - -.card span { - display: inline-block; - transition: transform 200ms; -} - -.card h2 { - font-weight: 600; - margin-bottom: 0.7rem; -} - -.card p { - margin: 0; - opacity: 0.6; - font-size: 0.9rem; - line-height: 1.5; - max-width: 30ch; -} - -.center { - display: flex; - justify-content: center; - align-items: center; - position: relative; - padding: 4rem 0; -} - -.center::before { - background: var(--secondary-glow); - border-radius: 50%; - width: 480px; - height: 360px; - margin-left: -400px; -} - -.center::after { - background: var(--primary-glow); - width: 240px; - height: 180px; - z-index: -1; -} - -.center::before, -.center::after { - content: ''; - left: 50%; - position: absolute; - filter: blur(45px); - transform: translateZ(0); -} - -.logo { - position: relative; -} -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - .card:hover { - background: rgba(var(--card-rgb), 0.1); - border: 1px solid rgba(var(--card-border-rgb), 0.15); - } - - .card:hover span { - transform: translateX(4px); - } -} - -@media (prefers-reduced-motion) { - .card:hover span { - transform: none; - } -} - -/* Mobile */ -@media (max-width: 700px) { - .content { - padding: 4rem; - } - - .grid { - grid-template-columns: 1fr; - margin-bottom: 120px; - max-width: 320px; - text-align: center; - } - - .card { - padding: 1rem 2.5rem; - } - - .card h2 { - margin-bottom: 0.5rem; - } - - .center { - padding: 8rem 0 6rem; - } - - .center::before { - transform: none; - height: 300px; - } - - .description { - font-size: 0.8rem; - } - - .description a { - padding: 1rem; - } - - .description p, - .description div { - display: flex; - justify-content: center; - position: fixed; - width: 100%; - } - - .description p { - align-items: center; - inset: 0 0 auto; - padding: 2rem 1rem 1.4rem; - border-radius: 0; - border: none; - border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25); - background: linear-gradient( - to bottom, - rgba(var(--background-start-rgb), 1), - rgba(var(--callout-rgb), 0.5) - ); - background-clip: padding-box; - backdrop-filter: blur(24px); - } - - .description div { - align-items: flex-end; - pointer-events: none; - inset: auto 0 0; - padding: 2rem; - height: 200px; - background: linear-gradient( - to bottom, - transparent 0%, - rgb(var(--background-end-rgb)) 40% - ); - z-index: 1; - } -} - -/* Tablet and Smaller Desktop */ -@media (min-width: 701px) and (max-width: 1120px) { - .grid { - grid-template-columns: repeat(2, 50%); - } -} - -@media (prefers-color-scheme: dark) { - .vercelLogo { - filter: invert(1); - } - - .logo { - filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70); - } -} - -@keyframes rotate { - from { - transform: rotate(360deg); - } - to { - transform: rotate(0deg); - } -} diff --git a/src/app/page.tsx b/src/app/page.tsx index 9ddf9b9..380d6e4 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,95 +1,776 @@ -import Image from 'next/image' -import styles from './page.module.css' +/* eslint-disable react/jsx-no-comment-textnodes */ +/* eslint-disable react/no-unescaped-entities */ +"use client"; +import ColourChip from "@/components/ColourChip/ColourChip"; +import Eighty from "@/components/Eighty/Eighty"; +import Floaty from "@/components/Floaty/Floaty"; +import Page from "@/components/Page/Page"; +import ProjectList, { Project } from "@/components/ProjectList/ProjectList"; +import ScrollBackInd from "@/components/ScrollBackInd/ScrollBackInd"; +import SpeedDial from "@/components/SpeedDial/SpeedDial"; +import Time from "@/components/Time/Time"; +import LastFM from "@/components/net/LastFM/LastFM"; +import { Color3 } from "@/utility/color"; +import { Space_Grotesk } from "next/font/google"; +import { useEffect, useRef, useState } from "react"; + +const space_grotesk = Space_Grotesk({ + subsets: ["latin"], + variable: "--font-Space-Grotesk", +}); export default function Home() { + const [page, setPage] = useState(0); + const body = useRef(null); + + // TIME + const dateObj = new Date(); + const [time, setTime] = useState("00:00:00 PM"); + const [date, setDate] = useState("0/0/0000"); + let animFrame = useRef(0); + + // hot reloading memory saver + useEffect(() => { + window.cancelAnimationFrame(animFrame.current); + }, []); + useEffect(() => { + function setTheTime() { + dateObj.setTime(Date.now()); + setTime( + dateObj.toLocaleTimeString("en-US", { + minute: "2-digit", + hour: "2-digit", + timeZone: "America/Chicago", + }) + ); + setDate( + dateObj.toLocaleDateString("en-US", { + weekday: "long", + day: "2-digit", + month: "long", + timeZone: "America/Chicago", + }) + ); + animFrame.current = window.requestAnimationFrame(setTheTime); + } + animFrame.current = window.requestAnimationFrame(setTheTime); + }, []); + + // LAST FM + let [player, setPlayer] = useState<{ [key: string]: any } | null | undefined>( + null + ); + const FMGate = useRef(true); + useEffect(() => { + async function LastFMGet() { + FMGate.current = false; + const api_key = "8f9b0255cc55a19f82d37c22600aff1a"; + const LAST_FM_URL = `https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=MeowcaTheoRange&api_key=${api_key}&format=json&extended=1&limit=1`; + const res = await fetch(LAST_FM_URL); + setPlayer(await res.json()); + setTimeout(() => LastFMGet(), 20000); + } + if (FMGate.current) LastFMGet(); + }, []); + + // Gallery + let [images, setImages] = useState([ + { + name: "See More", + description: "blog.abtmtr.link", + url: "https://blog.abtmtr.link/", + }, + ]); + const ImageGate = useRef(true); + useEffect(() => { + async function ImageGet() { + ImageGate.current = false; + const IMAGE_URL = `https://img.abtmtr.link/api/collections/mtr/posts`; + const res = await fetch(IMAGE_URL); + const gallery = (await res.json()).data; + setImages([ + ...gallery.posts?.map((imagePost: any) => ({ + name: imagePost.title, + description: imagePost.body.replace( + /^!\[.*?\]\((.*?)\).*(?:\n\nCharacters:.*?\n\n)(.*)\n\n.*$/gs, + "$2" + ), + image: imagePost.images[0] ?? null, + url: "https://img.abtmtr.link/" + imagePost.slug, + })), + { + name: "See More", + description: "img.abtmtr.link", + url: "https://img.abtmtr.link/", + }, + ]); + } + if (ImageGate.current) ImageGet(); + }, []); + + // Gallery + let [blog, setBlog] = useState([ + { + name: "See More", + description: "blog.abtmtr.link", + url: "https://blog.abtmtr.link/mtr/", + }, + ]); + const BlogGate = useRef(true); + useEffect(() => { + async function BlogGet() { + BlogGate.current = false; + const BLOG_URL = `https://blog.abtmtr.link/api/collections/mtr/posts`; + const res = await fetch(BLOG_URL); + const blogss = (await res.json()).data; + setBlog([ + ...blogss.posts?.map((blogPost: any) => ({ + name: blogPost.title, + description: blogPost.body.replace(/#\w*/g, ""), + url: "https://blog.abtmtr.link/mtr/" + blogPost.slug, + })), + { + name: "See More", + description: "blog.abtmtr.link", + url: "https://blog.abtmtr.link/mtr/", + }, + ]); + } + if (BlogGate.current) BlogGet(); + }, []); + + // Gallery + let [repos, setRepos] = useState([ + { + name: "See More", + description: "github.com", + url: "https://github.com/MeowcaTheoRange", + }, + ]); + const GithubGate = useRef(true); + useEffect(() => { + async function GithubGet() { + GithubGate.current = false; + const GITHUB_URL = `https://api.github.com/users/meowcatheorange/starred`; + const res = await fetch(GITHUB_URL); + const reposs = (await res.json())?.filter( + (x: any) => x.owner.login == "MeowcaTheoRange" + ); + console.log(reposs); + setRepos([ + ...reposs?.map((repository: any) => ({ + name: repository.name, + description: repository.description ?? "No description", + url: repository.html_url, + })), + { + name: "See More", + description: "github.com", + url: "https://github.com/MeowcaTheoRange", + }, + ]); + } + if (GithubGate.current) GithubGet(); + }, []); + return ( -
-
+
{ + const target = e.target as HTMLDivElement; + const curPage = Math.round(target.scrollTop / target.clientHeight); + if (curPage != page) setPage(curPage); + }} + > + + +

+ ABTMTR + + .LINK +

+ + + +
+ +

Welcome 👋

- Get started by editing  - src/app/page.tsx + I'm MeowcaTheoRange (miau-kuh-thee~oh-ray~nj). +
+ I'm a web developer, Fediverse enthusiast, and compulsory Minnesotan.

- -
- -
- Next.js Logo + I'm also known as Iszac or Theo as + well. +

+

he/they/it

+

Male

+

Minor

+

Autistic

+

I run this domain and all of the services on it.

+

+ My favourite hobbies are programming,{" "} + drawing,{" "} + occasionally making small bits of music,{" "} + obsessing over fonts, and{" "} + being pedantic. +

+

+ You may see parts of all of these aspects within this website. Please + tread carefully. +

+

+ Some other important things I think you should know about me are... +

+
    +
  • Please be patient with me.
  • +
  • + Please be understanding! Ask me for clarification if required. +
  • +
  • + I don't really like small talk - keep if brief if you want to check + up on me, please. +
  • +
  • + I'm not one to pick sides at first, usually. Being an "all or + nothing" kind of person isn't my thing, and if you don't like that, + feel free to tell me why your side is good. +
  • +
  • + I like getting tangled up in drama, but I'm not a spiteful person - + I'm usually only in it for the correlations. +
  • +
  • + You may see me hyperfixate on random stuff, like{" "} + + certain fonts + {" "} + or public transit. +
  • +
+

I believe in...

+
    +
  • Self-hosting important or personal infrastructure
  • +
  • Free and open-source material
  • +
  • Privacy as a basic human right
  • +
  • Trans rights & gay rights
  • +
  • + Autistic superiority /joke +
  • +
+

Check me out on:

+ -
+ + +

What's on this domain?

+

+ Here's a quick list of all of the web services on this domain right + now. +

+ +

Planned services

+

What I would like to put on this domain sometime in the future.

+ +

+ L10n (localization) +

+

What services I'd like to put on my server computer at home.

+ +
+ +

Current Obsessions

+

+ I'm into a lot of stuff. As of this site's publication, you'll + probably see me indulging in: +

+
    +
  • + + @winter@translunar.academy + + 's fic{" "} + + Ætherglow + +
  • +
  • Discussion of autism
  • +
  • Discussion and usage of the Fediverse
  • +
  • + + Homestuck + {" "} + and related properties +
  • +
  • + Adventures on{" "} + + MSPFA + + , sometimes +
  • +
  • Using React or Next.js
  • +
  • Creating alternatives to both because I'm just that cool
  • +
  • Anti-JS practices
  • +
  • Art and drawing
  • +
  • Using Blender
  • +
  • The MetroTransit bus system
  • +
+

and possibly much more that I can't even remember.

+

+ Want to know more? Below is my display of some of these things in + sections. Enjoy! +

+
+ +

Programming

+

I like using what some call "programming languages".

+

+ What do I call them? None of your business. All you have to know is + that I use TypeScript, React, and{" "} + Haxe. +

+

+ I also know JavaScript and some Bash{" "} + in case of emergency. +

+ +
+ +

Fonts

+

I also like UI and UI design. This includes fonts, quite a bit.

+

+ Currently, I'm liking the look of Renogare, Lexend Deca, + and Space Grotesk. This may change. +

+

+ I first used Space Grotesk for general-purpose + applications. This was on my old portfolio site and it's on TrollCall + right now. I think it just fits TrollCall; it's quirky, geometric, a + bit alien - it's right at home with the intended vibe of the site. +

+

+ On this website, I'm using Renogare as a header/title + font, and Lexend Deca for everything else. +

+

+ I found Renogare while playing{" "} + Celeste - yaknow, the game where you climb a huge + mountain for a few days? +

+

+ Renogare is a bold, geometric, display-optimized + font. It's super cool and I am in love with how it looks. +

+

+ Lexend Deca is a very strong second to{" "} + Renogare, primarily used when I can't use{" "} + Renogare, shouldn't use Renogare, or + am using Renogare but need something that{" "} + isn't Renogare. +

+

+ Lexend Deca is similar-looking to{" "} + Renogare, with a few major differences.{" "} + Lexend Deca loses the geometry, instead opting for a + beamed I, flat-top A, M, N, et al. t loses its curve, instead going + straight down. +

+

+ It also has different weights and proper OTF support - plus a bonus + series of different letter spacing choices under the{" "} + Lexend name. Deca is the tightest, + which is why I chose it. +

+

+ All in all, Lexend Deca is a good general-purpose + font, while still leaving room for Renogare to be a + great display font. +

+ +
+

+ AaIiLlMm +

+

+ Renogare +

+
+
+

+ AaIiLlMm +

+

+ Lexend Deca +

+
+
+

+ AaIiLlMm +

+

+ Space Grotesk +

+
+
+
+ +

Artistry

+

+ Artistry usually includes writing and drawing. These are the purposes + for{" "} + + my blog + {" "} + and{" "} + + my public gallery + + . +

+ + +
+ +

Branding

+

+ I don't really have strict branding guidelines, but I do have a few + important rules if you would like to refer to me in a professional or + formal context. +

+

Name

+

+ If you would like to refer to me online, you'll usually be able to use + my username MeowcaTheoRange. If that's too long, you can always + shorten it to MTR. +

+

+ Please make sure to keep the styling. It's MeowcaTheoRange, not{" "} + MeowcatHeOrange, MeowcaTheOrange, + nor Meowca Theo Range. +

+

+ The styling meowcatheorange is OK if necessary. +

+

+ If you would like to refer to me in a more professional context, my + name Iszac or the moniker Theo Range{" "} + will work just as well. +

+

+ If you are a local organization and would like to refer to me by my + legal name, please{" "} + + contact me + {" "} + and we can probably figure something out. +
+ Local means within Minnesota, by the way. +

+

Colours

+

+ If you would like to use colours to refer to me, whether that be the + primary color on a card or the color of my name, I recommend you use + these colours: +

- -
- ) + + Iszac Blue +
+ Primary +
+ + Rocco Orange +
+ Primary Negative +
+

+ Iszac Blue is literally Rocco Orange but + inverted. This colour is named after Iszac, an OC of + mine that I came up with, for the setting of Ætherglow. +
+ + ...and then I shortly named myself after said character... + +
+ If you were to use any of these colours to represnt me as a{" "} + person, use this one. +

+

+ Rocco Orange is my favourite colour orange, but now more red. + The name comes from my character Rocco, whose hair is + this colour - though this colour has been applied to more characters + like BLEND-1020.
+ If you were to use any of these colours to represnt me as an{" "} + entity, use this one whenever possible. +

+
+ + Grape Soda +
+ Secondary +
+ + Avalonian Waste +
+ Secondary Negative +
+

+ Grape Soda represents my love for grape soda. +
+ My favourite is Fanta Grape. :] +

+

+ Avalonian Waste is also literally Grape Soda{" "} + but inverted. This represents some{" "} + + old lore + {" "} + that I'm still screwing with. +

+ + + +

+ ABTMTR + + .LINK +

+ + + + + + + + + + + +

© MeowcaTheoRange 2023

+
+ + ); } diff --git a/src/components/ColourChip/ColourChip.module.css b/src/components/ColourChip/ColourChip.module.css new file mode 100644 index 0000000..074a6aa --- /dev/null +++ b/src/components/ColourChip/ColourChip.module.css @@ -0,0 +1,9 @@ +.ColourChip { + background-color: var(--mainColour); + display: inline-block; + width: 9em; + aspect-ratio: 1 / 1; + padding: 16px; + vertical-align: top; + margin: 1em; +} diff --git a/src/components/ColourChip/ColourChip.tsx b/src/components/ColourChip/ColourChip.tsx new file mode 100644 index 0000000..8bcb3c0 --- /dev/null +++ b/src/components/ColourChip/ColourChip.tsx @@ -0,0 +1,28 @@ +import { Color3 } from "@/utility/color"; +import styles from "./ColourChip.module.css"; + +export default function ColourChip({ + colour, + children, +}: { + colour: Color3; + children?: React.ReactNode; +}) { + const calcTextColor = +(Math.max(...colour.toRGB()) <= 127); + return ( +
+ {children} +

{"#" + colour.toHex()}

+
+ ); +} diff --git a/src/components/Eighty/Eighty.module.css b/src/components/Eighty/Eighty.module.css new file mode 100644 index 0000000..3bd5f66 --- /dev/null +++ b/src/components/Eighty/Eighty.module.css @@ -0,0 +1,11 @@ +.Eighty { + display: inline-block; + margin: 5px 6px; + transform-origin: center; +} + +.Eighty img { + display: inline-block; + width: 88px; + height: 31px; +} diff --git a/src/components/Eighty/Eighty.tsx b/src/components/Eighty/Eighty.tsx new file mode 100644 index 0000000..40bee3d --- /dev/null +++ b/src/components/Eighty/Eighty.tsx @@ -0,0 +1,22 @@ +import Link from "next/link"; +import styles from "./Eighty.module.css"; + +export default function Eighty({ + url, + img, + alt, +}: { + url?: string; + img: string; + alt?: string; +}) { + return url ? ( + + {alt} + + ) : ( + + {alt} + + ); +} diff --git a/src/components/Floaty/Floaty.module.css b/src/components/Floaty/Floaty.module.css new file mode 100644 index 0000000..7159d5f --- /dev/null +++ b/src/components/Floaty/Floaty.module.css @@ -0,0 +1,55 @@ +.Floaty { + display: inline-block; + max-width: calc(50vw - 64px); + min-width: 373px; + /* height: calc(50vh - 64px); */ + position: absolute !important; + right: 64px; + bottom: 64px; + text-align: end; + /* background-color: #0001; + box-shadow: 0 0 8px currentColor; + padding: 16px; */ + box-sizing: border-box; +} + +.FloatySticky { + position: sticky; +} + +.Floaty:dir(rtl) { + right: unset; + left: 64px; +} + +.FloatyTop { + bottom: unset; + top: 64px; +} + +.FloatyStart { + right: unset; + left: 64px; + text-align: start; +} + +.FloatyStart:dir(rtl) { + left: unset; + right: 64px; +} + +@media only screen and (max-width: 875px) { + .Floaty { + position: static !important; + text-align: start; + display: block; + margin: 2em 0; + max-width: none; + } + .FloatyKeep { + position: absolute !important; + text-align: unset; + display: inline-block; + margin: 0; + } +} diff --git a/src/components/Floaty/Floaty.tsx b/src/components/Floaty/Floaty.tsx new file mode 100644 index 0000000..ebd8ac6 --- /dev/null +++ b/src/components/Floaty/Floaty.tsx @@ -0,0 +1,27 @@ +import styles from "./Floaty.module.css"; + +export default function Floaty({ + children, + top = false, + start = false, + keepFloat = false, + sticky = false, +}: { + children?: React.ReactNode; + top?: boolean; + start?: boolean; + keepFloat?: boolean; + sticky?: boolean; +}) { + return ( +
+ {children} +
+ ); +} diff --git a/src/components/Nav/Nav.module.css b/src/components/Nav/Nav.module.css new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Nav/Nav.tsx b/src/components/Nav/Nav.tsx new file mode 100644 index 0000000..fb49b91 --- /dev/null +++ b/src/components/Nav/Nav.tsx @@ -0,0 +1,22 @@ +import { Color3 } from "@/utility/color"; +import styles from "./Nav.module.css"; + +export default function Nav({ + children, + color, +}: { + children?: React.ReactNode; + color?: Color3; +}) { + return ( +
+ {children} +
+ ); +} diff --git a/src/components/Page/Page.module.css b/src/components/Page/Page.module.css new file mode 100644 index 0000000..b5737c8 --- /dev/null +++ b/src/components/Page/Page.module.css @@ -0,0 +1,59 @@ +.Page { + box-sizing: border-box; + width: 100vw; + min-height: 100vh; + /* overflow-y: auto; */ + overflow: hidden; + padding: 64px; + scroll-snap-align: start; + scroll-snap-stop: always; + position: relative; + background-attachment: fixed; + z-index: 1; + scroll-margin-bottom: calc(64px + (3rem + 1.5rem)); +} + +.Page > * { + position: relative; + z-index: 3; +} + +.Page .PageBgElements { + z-index: 2; + /* opacity: 0.5; */ + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 200%; + /* transform: translateY(-50%); */ + overflow: hidden; + user-select: none; + pointer-events: none; + speak: none; +} + +.PagePreview { + min-height: calc(100vh - (64px + (3rem + 1.5rem))); +} + +.PageFooter { + min-height: 50vh; + scroll-snap-align: end; +} + +.PageSpace { + padding-right: 128px; +} + +@media only screen and (max-width: 1024px) { + .Page { + font-size: 16px; + } +} + +@media only screen and (max-width: 875px) { + .PageSpace { + padding-right: 64px; + } +} diff --git a/src/components/Page/Page.tsx b/src/components/Page/Page.tsx new file mode 100644 index 0000000..2870194 --- /dev/null +++ b/src/components/Page/Page.tsx @@ -0,0 +1,57 @@ +import { Color3 } from "@/utility/color"; +import { useEffect, useRef } from "react"; +import styles from "./Page.module.css"; + +export default function Page({ + children, + color, + bg, + scroll, + preview = false, + footer = false, + floaty = false, + id, +}: { + children?: React.ReactNode; + color?: Color3; + bg?: string; + scroll: HTMLElement | null; + preview?: boolean; + footer?: boolean; + floaty?: boolean; + id?: string; +}) { + const pageobj = useRef(null); + const pageScrollAnim = useRef(0); + useEffect(() => { + if (scroll == null) return; + const handler = () => { + if (pageobj.current == null) return; + pageobj.current.style.backgroundPositionY = + -(pageobj.current.offsetTop - scroll.scrollTop) / 2 + "px"; + pageScrollAnim.current = requestAnimationFrame(handler); + }; + pageScrollAnim.current = requestAnimationFrame(handler); + // return cancelAnimationFrame(pageScrollAnim.current); + }, [scroll]); + return ( +
+ {children} +
+ ); +} diff --git a/src/components/ProjectList/ProjectList.module.css b/src/components/ProjectList/ProjectList.module.css new file mode 100644 index 0000000..f5dcd6a --- /dev/null +++ b/src/components/ProjectList/ProjectList.module.css @@ -0,0 +1,113 @@ +.ProjectList { + display: grid; + grid-auto-flow: column; + grid-auto-columns: 300px; + gap: 16px; + width: calc(100% + 128px); + box-sizing: border-box; + flex-wrap: nowrap; + justify-content: flex-start; + align-items: center; + margin-left: -64px; + padding: 8px 16px; + overflow-x: scroll; +} + +.ProjectListDoubleWide { + grid-auto-columns: 616px; +} + +.ProjectList .ProjectListProject { + display: inline-block; + padding: 8px; + aspect-ratio: 1 / 1; + flex-shrink: 0; + border: 1px solid var(--color); + background-color: var(--backgroundColor); + color: var(--color); + box-shadow: 0 0 0 var(--color); + font-size: 1rem; + text-align: left; + background-position: center; + background-size: cover; + position: relative; + overflow: hidden; + transition: box-shadow 0.125s, transform 0.125s; +} + +.ProjectListDoubleWide .ProjectListProject { + aspect-ratio: 2 / 1; +} + +.ProjectList .ProjectListProject:hover { + box-shadow: 0 8px 0 var(--color); + transform: translateY(-8px); +} + +.ProjectList .ProjectListProject:active { + box-shadow: 0 4px 0 var(--color); + transform: translateY(-4px); + font-weight: unset; +} + +.ProjectListProject .ProjectListProjectImage { + position: absolute; + left: -8px; + top: -8px; + width: calc(100% + 16px); + height: calc(100% + 16px); + object-fit: cover; + filter: blur(4px) brightness(30%); + transition: top 0.125s, filter 0.125s; + /* opacity: 0.75; */ +} + +.ProjectListProject:hover .ProjectListProjectImage { + top: 0px; + filter: blur(8px) brightness(30%); + /* opacity: 0.75; */ +} + +.ProjectListProject .ProjectListProjectDescription { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + padding: 16px; + box-sizing: border-box; +} + +.ProjectListProjectDescription .ProjectListProjectDescriptionTitle { + display: inline-block; + margin: 0; + font-family: "Renogare"; + font-size: 1.5em; + max-lines: 2; + line-clamp: 2; + line-height: 1.25em; + text-overflow: ellipsis; + overflow-x: hidden; + max-width: 100%; + white-space: nowrap; +} + +.ProjectListProjectDescription .ProjectListProjectDescriptionDescription { + margin: 0; + margin-top: 0.25em; + font-family: "Lexend Deca"; + font-size: 1em; +} + +@media only screen and (max-width: 750px) { + .ProjectList { + grid-auto-columns: calc(50% - 8px); + } + + .ProjectListDoubleWide { + grid-auto-columns: 100%; + } + + .ProjectList .ProjectListProject { + } +} diff --git a/src/components/ProjectList/ProjectList.tsx b/src/components/ProjectList/ProjectList.tsx new file mode 100644 index 0000000..0b6f581 --- /dev/null +++ b/src/components/ProjectList/ProjectList.tsx @@ -0,0 +1,71 @@ +/* eslint-disable @next/next/no-img-element */ +import { useRouter } from "next/navigation"; +import ReactMarkdown from "react-markdown"; +import rehypeRaw from "rehype-raw"; +import remarkBreaks from "remark-breaks"; +import styles from "./ProjectList.module.css"; + +export type Project = { + name: string; + url: string; + description: string; + image?: string; +}; + +export default function ProjectList({ + projects, + markdown = false, + double = false, +}: { + projects: Project[]; + markdown?: boolean; + double?: boolean; +}) { + const router = useRouter(); + return ( + + ); +} diff --git a/src/components/ScrollBackInd/ScrollBackInd.module.css b/src/components/ScrollBackInd/ScrollBackInd.module.css new file mode 100644 index 0000000..3348bd2 --- /dev/null +++ b/src/components/ScrollBackInd/ScrollBackInd.module.css @@ -0,0 +1,65 @@ +.ScrollBackInd { + position: fixed; + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + gap: 16px; + left: 50vw; + transform: translateX(-50%); + bottom: 64px; + /* width: 64px; */ + height: 64px; + z-index: 9; + background-color: #0008; + color: #fff; + border-radius: 16px; + border: none; + cursor: pointer; + padding: 8px; + transition: opacity 0.25s; +} + +.ScrollBackInd span:first-child { + display: inline-block; + width: 32px; + border-radius: 8px; + font-size: 24px; + transition: text-shadow 0.25s; + font-family: "Material Symbols Outlined"; +} + +.ScrollBackInd:hover span:first-child { + text-shadow: 0 0 8px #fff; +} + +.ScrollBackInd span { + font-size: 1rem; + padding: 0 8px; + font-family: var(--font-Lexend-Deca); +} + +.ScrollBackInd img { + width: 48px; + height: 48px; + border-radius: 8px; + border: 1px solid transparent; + background: conic-gradient( + from -90deg at 50% 50%, + transparent 0%, + transparent 25%, + currentColor 30%, + currentColor 45%, + transparent 50%, + transparent 75%, + currentColor 80%, + currentColor 95%, + transparent 100% + ) + border-box; +} + +.ScrollBackIndHidden { + opacity: 0; + pointer-events: none; +} diff --git a/src/components/ScrollBackInd/ScrollBackInd.tsx b/src/components/ScrollBackInd/ScrollBackInd.tsx new file mode 100644 index 0000000..ed2e0e0 --- /dev/null +++ b/src/components/ScrollBackInd/ScrollBackInd.tsx @@ -0,0 +1,36 @@ +"use client"; +import styles from "./ScrollBackInd.module.css"; + +export default function ScrollBackInd({ + hide = false, + scroll, + player, + time, +}: { + hide?: boolean; + scroll: HTMLElement | null; + player: { [key: string]: any } | null | undefined; + time: string; +}) { + return ( + + ); +} diff --git a/src/components/Sides/Sides.module.css b/src/components/Sides/Sides.module.css new file mode 100644 index 0000000..8210f2c --- /dev/null +++ b/src/components/Sides/Sides.module.css @@ -0,0 +1,27 @@ +.Sides { + display: grid; + grid-template-columns: auto max-content; + gap: 16px; +} + +.Sides .SidesStart { + text-align: start; + max-width: 100%; +} + +.Sides .SidesEnd { + text-align: end; + max-width: 100%; +} + +@media only screen and (max-width: 750px) { + .Sides { + display: inline-block; + max-width: 100%; + } + + .Sides .SidesEnd { + text-align: start; + margin-top: 2em; + } +} diff --git a/src/components/Sides/Sides.tsx b/src/components/Sides/Sides.tsx new file mode 100644 index 0000000..94627df --- /dev/null +++ b/src/components/Sides/Sides.tsx @@ -0,0 +1,16 @@ +import styles from "./Sides.module.css"; + +export default function Sides({ + start, + end, +}: { + start?: React.ReactNode; + end?: React.ReactNode; +}) { + return ( +
+
{start}
+
{end}
+
+ ); +} diff --git a/src/components/SpeedDial/SpeedDial.module.css b/src/components/SpeedDial/SpeedDial.module.css new file mode 100644 index 0000000..32f17b9 --- /dev/null +++ b/src/components/SpeedDial/SpeedDial.module.css @@ -0,0 +1,18 @@ +.SpeedDial { + /* display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 0 0.5em; */ +} + +.SpeedDialService { + /* display: inline-block; */ +} + +.SpeedDialServiceGolden { + font-weight: bolder; +} + +.SpeedDialServicePurpose { + margin: 0; +} diff --git a/src/components/SpeedDial/SpeedDial.tsx b/src/components/SpeedDial/SpeedDial.tsx new file mode 100644 index 0000000..6581a96 --- /dev/null +++ b/src/components/SpeedDial/SpeedDial.tsx @@ -0,0 +1,34 @@ +import styles from "./SpeedDial.module.css"; + +export default function SpeedDial({ + services, +}: { + services: { + name: string; + url: string; + golden?: boolean; + purpose?: string; + }[]; +}) { + return ( +
    + {services.map((service, iter) => ( +
  • + {service.purpose ? ( +

    {service.purpose}

    + ) : ( + <> + )} + + {service.name} + +
  • + ))} +
+ ); +} diff --git a/src/components/Time/Time.module.css b/src/components/Time/Time.module.css new file mode 100644 index 0000000..32fe106 --- /dev/null +++ b/src/components/Time/Time.module.css @@ -0,0 +1,2 @@ +.Time { +} diff --git a/src/components/Time/Time.tsx b/src/components/Time/Time.tsx new file mode 100644 index 0000000..13e6f47 --- /dev/null +++ b/src/components/Time/Time.tsx @@ -0,0 +1,11 @@ +import styles from "./Time.module.css"; + +export default function Time({ time, date }: { time: string; date: string }) { + return ( +
+

{time}

+

{date}

+

Central Time (Minnesota)

+
+ ); +} diff --git a/src/components/net/LastFM/LastFM.module.css b/src/components/net/LastFM/LastFM.module.css new file mode 100644 index 0000000..25b431d --- /dev/null +++ b/src/components/net/LastFM/LastFM.module.css @@ -0,0 +1,55 @@ +.LastFM { + display: inline-grid; + grid-template-columns: auto 96px; + align-items: center; + gap: 16px; + border: 1px solid transparent; + /* background: linear-gradient( + 0deg, + var(--backgroundColor) 0%, + var(--backgroundColor) 100% + ) + padding-box, + conic-gradient( + from -90deg at 50% 50%, + transparent 0%, + transparent 35%, + currentColor 40%, + currentColor 45%, + transparent 50%, + transparent 85%, + currentColor 90%, + currentColor 95%, + transparent 100% + ) + border-box; */ + /* box-shadow: 0 0 4px currentColor; */ + box-sizing: border-box; + /* padding: 16px; */ +} + +.LastFM .LastFMAlbumArt { + border-radius: 8px; +} + +.LastFM .LastFMMetadata { +} + +.LastFM .LastFMMetadata .LastFMMetadataTitle { + font-size: 1.5em; +} + +.LastFMError { + opacity: 0.5; +} + +@media only screen and (max-width: 875px) { + .LastFM { + grid-auto-flow: column; + grid-template-columns: 96px auto; + } + + .LastFM .LastFMAlbumArt { + order: -1; + } +} diff --git a/src/components/net/LastFM/LastFM.tsx b/src/components/net/LastFM/LastFM.tsx new file mode 100644 index 0000000..6b04f88 --- /dev/null +++ b/src/components/net/LastFM/LastFM.tsx @@ -0,0 +1,38 @@ +"use client"; +import styles from "./LastFM.module.css"; + +export default function LastFM({ + player, +}: { + player: { [key: string]: any } | null | undefined; +}) { + return player != null ? ( + <> + {player?.recenttracks.track[0]["@attr"]?.nowplaying === "true" ? ( +

Currently listening to

+ ) : ( +

Last listened to

+ )} +
+
+

+ {player?.recenttracks.track[0].name} +

+

+ {player?.recenttracks.track[0].artist.name} -{" "} + {player?.recenttracks.track[0].album["#text"]} +

+
+ +
+ + ) : ( +

Hold on...

+ ); +} diff --git a/src/styles/globals.css b/src/styles/globals.css new file mode 100644 index 0000000..4b1faf9 --- /dev/null +++ b/src/styles/globals.css @@ -0,0 +1,178 @@ +:root { + font-family: var(--font-Lexend-Deca); + font-size: 20px; +} + +body, +html { + margin: 0; + box-sizing: border-box; +} + +div.body { + width: 100vw; + height: 100vh; + background-color: black; + color: white; + overflow-y: scroll; + scroll-snap-type: y mandatory; +} + +/* Markup */ + +.block > h1, +.block > h2, +.block > h3, +.block > h4 { + max-width: 85%; +} +.block > p, +.block > ul, +.block > ol { + max-width: 65%; +} + +h1 { + font-family: var(--font-Renogare); + font-size: 3rem; + margin: 0 0; + margin-bottom: 1rem; + text-wrap: balance; + font-weight: normal; +} + +h2 { + font-family: var(--font-Renogare); + font-size: 2rem; + margin: 1rem 0; + margin-bottom: 1rem; + text-wrap: balance; + font-weight: normal; +} + +h3 { + font-family: var(--font-Renogare); + font-size: 1.5rem; + margin: 1rem 0; + margin-bottom: 0.5rem; + text-wrap: balance; + font-weight: normal; +} + +h4 { + font-family: var(--font-Renogare); + font-size: 1rem; + margin: 1rem 0; + margin-bottom: 0.5rem; + text-wrap: balance; + font-weight: normal; +} + +p { + font-size: 1rem; + margin: 0.5rem 0; + line-height: 1.5rem; +} + +ul, +ol { + font-size: 1rem; + margin: 0.5rem 1em; + line-height: 1.5rem; +} + +li { + margin: 0.5em 0; +} + +small { + font-size: 0.75em; +} + +b { + font-size: 1.25em; + line-height: 1em; +} + +a { + display: inline-block; + position: relative; + color: currentColor; + transform: skew(0); + transform-origin: bottom left; + transition: all 0.125s; +} + +a.special::after { + content: " >>>"; + position: absolute; + display: inline-block; + font-weight: bold; + width: 1ch; + overflow: hidden; + transform: scaleX(0); + top: 0; + right: 0; + transition: all 0.125s; +} + +a:hover { + text-decoration-color: transparent; + transform: skew(-15deg, 0); +} + +a.special:hover { + letter-spacing: 0.25ch; + margin-right: 2ch; + font-weight: bold; + text-decoration-color: transparent; + transform: skew(-15deg, 0); +} + +a.special:hover::after { + right: -2ch; + transform: scaleX(1); +} + +a:active { + font-weight: bold; +} + +a.special:active { + transform: skew(-30deg, 0); + letter-spacing: 0.5ch; + margin-right: 5ch; +} + +a.special:active::after { + width: 4ch; + right: -5ch; +} + +.icon { + font-family: "Material Symbols Outlined"; + font-size: 24px; + line-height: 24px; +} + +/* Stinky styling */ + +.hv { + opacity: 0.5; +} + +.chip { + display: inline-block; + background-color: var(--backgroundColor); + color: var(--color); + padding: 0 1em; + margin-left: 0.25em; + margin-right: 0.25em; + border-radius: 1em; +} + +@media only screen and (max-width: 1024px) { + :root { + font-size: 16px; + } +} diff --git a/src/utility/color.ts b/src/utility/color.ts new file mode 100644 index 0000000..9f8de2b --- /dev/null +++ b/src/utility/color.ts @@ -0,0 +1,94 @@ +export type ColorTypes = [number, number, number]; + +const clamp = (n: number, mi: number, ma: number) => + Math.max(mi, Math.min(n, ma)); + +export class Color3 { + R: number; + G: number; + B: number; + constructor(red: number, green: number, blue: number) { + this.R = red; + this.G = green; + this.B = blue; + } + static clone(color3: Color3) { + return new Color3(color3.R, color3.G, color3.B); + } + static fromRGB(red: number, green: number, blue: number) { + return new Color3(red / 255, green / 255, blue / 255); + } + static fromHex(hex: string) { + // @ts-ignore + const hexSplit: [number, number, number] = ( + hex.match(new RegExp(`[0-9a-f]{1,${hex.length / 3}}`, "gi")) ?? [ + "0", + "0", + "0", + ] + ).map((x) => parseInt(x, 16) / 255); + return new Color3(...hexSplit); + } + static fromInt(int: number) { + return new Color3( + (int & 0xff0000) >> 16, + (int & 0x00ff00) >> 8, + int & 0x0000ff + ); + } + static assumeColor( + value: [number, number, number] | string | number, + rgb?: boolean + ) { + if (Color3.isColor(value)) { + if (Array.isArray(value)) + return rgb ? Color3.fromRGB(...value) : new Color3(...value); + else if (typeof value === "string") return Color3.fromHex(value); + else if (typeof value === "number") return Color3.fromInt(value); + } + throw new Error("Not a valid color type"); + } + static isColor( + value: [number, number, number] | string | number, + rgb?: boolean + ) { + return ( + (Array.isArray(value) && + value.length === 3 && + value.every((x) => typeof x === "number" && !isNaN(x))) || + (typeof value === "string" && !isNaN(parseInt(value, 16))) || + (typeof value === "number" && !isNaN(value)) + ); + } + + toHex() { + return this.toInt().toString(16).padStart(6, "0"); + } + toInt() { + return ( + (Math.round(this.R * 255) << 16) + + (Math.round(this.G * 255) << 8) + + Math.round(this.B * 255) + ); + } + toRGB(): [number, number, number] { + return [this.R * 255, this.G * 255, this.B * 255]; + } + multiply(mult: number) { + return new Color3(this.R * mult, this.G * mult, this.B * mult); + } + lighten(mult: number) { + return new Color3( + clamp(this.R + (mult / 100) * (1 - this.R), 0, 1), + clamp(this.G + (mult / 100) * (1 - this.G), 0, 1), + clamp(this.B + (mult / 100) * (1 - this.B), 0, 1) + ); + } + darken(mult: number) { + return new Color3( + clamp(this.R - (mult / 100) * this.R, 0, 1), + clamp(this.G - (mult / 100) * this.G, 0, 1), + clamp(this.B - (mult / 100) * this.B, 0, 1) + ); + } +} diff --git a/src/utility/fonts.ts b/src/utility/fonts.ts new file mode 100644 index 0000000..5faba9f --- /dev/null +++ b/src/utility/fonts.ts @@ -0,0 +1,19 @@ +import { Lexend_Deca } from "next/font/google"; +import Renogare from "next/font/local"; + +const lexend_deca = Lexend_Deca({ + subsets: ["latin"], + variable: "--font-Lexend-Deca", +}); +const lexend_deca_backup = Lexend_Deca({ + // some dumb error + subsets: ["latin"], + variable: "--font-Lexend-Deca", +}); +const renogare = Renogare({ + src: "./../../public/fonts/Renogare/Renogare.woff2", + variable: "--font-Renogare", +}); + +const fonts = `${lexend_deca.variable} ${lexend_deca_backup.variable} ${renogare.variable}`; +export default fonts;