diff --git a/package-lock.json b/package-lock.json
index 1090bd3..8b7a945 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,10 @@
"name": "speice.io",
"version": "0.0.0",
"dependencies": {
+ "@fontsource/jetbrains-mono": "^4.5.12",
+ "@fontsource/lato": "^4.5.10",
+ "normalize.css": "^8.0.1",
+ "prism-themes": "^1.9.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
@@ -16,9 +20,11 @@
"@mdx-js/rollup": "^2.3.0",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
+ "@types/remark-prism": "^1.3.4",
"@vitejs/plugin-react-swc": "^3.0.0",
"husky": "^8.0.0",
"pretty-quick": "^3.1.3",
+ "remark-prism": "^1.3.6",
"typescript": "^4.9.3",
"vite": "^4.2.0"
}
@@ -387,6 +393,16 @@
"node": ">=12"
}
},
+ "node_modules/@fontsource/jetbrains-mono": {
+ "version": "4.5.12",
+ "resolved": "https://registry.npmjs.org/@fontsource/jetbrains-mono/-/jetbrains-mono-4.5.12.tgz",
+ "integrity": "sha512-LJF1ala1/u+wXZmESFqIk08FA9yGX4/uAAleCHmXUMgEjvNAYFHUQQ7eK5hQQoBOwh99cU5suTrqYqEkgzwzPA=="
+ },
+ "node_modules/@fontsource/lato": {
+ "version": "4.5.10",
+ "resolved": "https://registry.npmjs.org/@fontsource/lato/-/lato-4.5.10.tgz",
+ "integrity": "sha512-2hYR6r661Cq9B8zugtu6yxuOKqrVhAgfOSaPSq8XoxbC4ebsl0KOTy/vPoP+9U7JuQVLfrmikirW4a9Z0nDUug=="
+ },
"node_modules/@mdx-js/mdx": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-2.3.0.tgz",
@@ -666,6 +682,15 @@
"node": ">=10"
}
},
+ "node_modules/@tootallnate/once": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/@types/acorn": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz",
@@ -761,6 +786,17 @@
"@types/react": "*"
}
},
+ "node_modules/@types/remark-prism": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@types/remark-prism/-/remark-prism-1.3.4.tgz",
+ "integrity": "sha512-nwb0sLwWuUD2DObMkxFtSfPFVA3frkyJRzDy9qfyv0Flq234p3FOlpRpaq64YdDX6fJ+snj3v2VZdneTBG/NiQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/mdast": "*",
+ "remark": "^14.0.2",
+ "unified": "^10.0.0"
+ }
+ },
"node_modules/@types/scheduler": {
"version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
@@ -785,6 +821,12 @@
"vite": "^4"
}
},
+ "node_modules/abab": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
+ "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
+ "dev": true
+ },
"node_modules/acorn": {
"version": "8.8.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
@@ -797,6 +839,28 @@
"node": ">=0.4.0"
}
},
+ "node_modules/acorn-globals": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
+ "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^7.1.1",
+ "acorn-walk": "^7.1.1"
+ }
+ },
+ "node_modules/acorn-globals/node_modules/acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
@@ -806,6 +870,27 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
+ "node_modules/acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -857,6 +942,12 @@
"astring": "bin/astring"
}
},
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true
+ },
"node_modules/bail": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
@@ -883,6 +974,12 @@
"concat-map": "0.0.1"
}
},
+ "node_modules/browser-process-hrtime": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+ "dev": true
+ },
"node_modules/ccount": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
@@ -946,6 +1043,12 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/classnames": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
+ "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==",
+ "dev": true
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -964,6 +1067,18 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/comma-separated-tokens": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
@@ -994,12 +1109,56 @@
"node": ">= 8"
}
},
+ "node_modules/css-selector-parser": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz",
+ "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==",
+ "dev": true
+ },
+ "node_modules/cssom": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+ "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+ "dev": true
+ },
+ "node_modules/cssstyle": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+ "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+ "dev": true,
+ "dependencies": {
+ "cssom": "~0.3.6"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cssstyle/node_modules/cssom": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+ "dev": true
+ },
"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
},
+ "node_modules/data-urls": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
+ "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==",
+ "dev": true,
+ "dependencies": {
+ "abab": "^2.0.3",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^8.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -1017,6 +1176,12 @@
}
}
},
+ "node_modules/decimal.js": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
+ "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
+ "dev": true
+ },
"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",
@@ -1030,6 +1195,21 @@
"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",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
@@ -1048,6 +1228,27 @@
"node": ">=0.3.1"
}
},
+ "node_modules/domexception": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
+ "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==",
+ "dev": true,
+ "dependencies": {
+ "webidl-conversions": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/domexception/node_modules/webidl-conversions": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
+ "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -1094,6 +1295,66 @@
"@esbuild/win32-x64": "0.17.16"
}
},
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "dev": true
+ },
+ "node_modules/escodegen": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
+ "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
+ "dev": true,
+ "dependencies": {
+ "esprima": "^4.0.1",
+ "estraverse": "^5.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1"
+ },
+ "bin": {
+ "escodegen": "bin/escodegen.js",
+ "esgenerate": "bin/esgenerate.js"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "optionalDependencies": {
+ "source-map": "~0.6.1"
+ }
+ },
+ "node_modules/escodegen/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
"node_modules/estree-util-attach-comments": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz",
@@ -1170,6 +1431,15 @@
"@types/estree": "^1.0.0"
}
},
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/execa": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
@@ -1199,6 +1469,12 @@
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"dev": true
},
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true
+ },
"node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
@@ -1212,6 +1488,20 @@
"node": ">=8"
}
},
+ "node_modules/form-data": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+ "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+ "dev": true,
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
@@ -1305,6 +1595,45 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/html-encoding-sniffer": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
+ "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==",
+ "dev": true,
+ "dependencies": {
+ "whatwg-encoding": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+ "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+ "dev": true,
+ "dependencies": {
+ "@tootallnate/once": "1",
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/human-signals": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
@@ -1329,6 +1658,18 @@
"url": "https://github.com/sponsors/typicode"
}
},
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@@ -1435,6 +1776,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true
+ },
"node_modules/is-reference": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.1.tgz",
@@ -1467,6 +1814,52 @@
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
+ "node_modules/jsdom": {
+ "version": "16.7.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
+ "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==",
+ "dev": true,
+ "dependencies": {
+ "abab": "^2.0.5",
+ "acorn": "^8.2.4",
+ "acorn-globals": "^6.0.0",
+ "cssom": "^0.4.4",
+ "cssstyle": "^2.3.0",
+ "data-urls": "^2.0.0",
+ "decimal.js": "^10.2.1",
+ "domexception": "^2.0.1",
+ "escodegen": "^2.0.0",
+ "form-data": "^3.0.0",
+ "html-encoding-sniffer": "^2.0.1",
+ "http-proxy-agent": "^4.0.1",
+ "https-proxy-agent": "^5.0.0",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.0",
+ "parse5": "6.0.1",
+ "saxes": "^5.0.1",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^4.0.0",
+ "w3c-hr-time": "^1.0.2",
+ "w3c-xmlserializer": "^2.0.0",
+ "webidl-conversions": "^6.1.0",
+ "whatwg-encoding": "^1.0.5",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^8.5.0",
+ "ws": "^7.4.6",
+ "xml-name-validator": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "canvas": "^2.5.0"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
"node_modules/kleur": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
@@ -1476,6 +1869,19 @@
"node": ">=6"
}
},
+ "node_modules/levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -1488,6 +1894,12 @@
"node": ">=8"
}
},
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
"node_modules/longest-streak": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
@@ -2298,6 +2710,27 @@
}
]
},
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
@@ -2368,6 +2801,11 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
+ "node_modules/normalize.css": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz",
+ "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg=="
+ },
"node_modules/npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@@ -2380,6 +2818,21 @@
"node": ">=8"
}
},
+ "node_modules/nwsapi": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.4.tgz",
+ "integrity": "sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g==",
+ "dev": true
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -2404,6 +2857,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "dependencies": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
"node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
@@ -2460,6 +2930,27 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/parse-numeric-range": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz",
+ "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==",
+ "dev": true
+ },
+ "node_modules/parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+ "dev": true
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "dev": true,
+ "dependencies": {
+ "parse5": "^6.0.1"
+ }
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -2537,6 +3028,15 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
"node_modules/prettier": {
"version": "2.8.7",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
@@ -2576,6 +3076,20 @@
"prettier": ">=2.0.0"
}
},
+ "node_modules/prism-themes": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/prism-themes/-/prism-themes-1.9.0.tgz",
+ "integrity": "sha512-tX2AYsehKDw1EORwBps+WhBFKc2kxfoFpQAjxBndbZKr4fRmMkv47XN0BghC/K1qwodB1otbe4oF23vUTFDokw=="
+ },
+ "node_modules/prismjs": {
+ "version": "1.29.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
+ "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/property-information": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz",
@@ -2586,6 +3100,12 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/psl": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
+ "dev": true
+ },
"node_modules/pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -2596,6 +3116,21 @@
"once": "^1.3.1"
}
},
+ "node_modules/punycode": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+ "dev": true
+ },
"node_modules/react": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
@@ -2651,6 +3186,22 @@
"react-dom": ">=16.8"
}
},
+ "node_modules/remark": {
+ "version": "14.0.2",
+ "resolved": "https://registry.npmjs.org/remark/-/remark-14.0.2.tgz",
+ "integrity": "sha512-A3ARm2V4BgiRXaUo5K0dRvJ1lbogrbXnhkJRmD0yw092/Yl0kOCZt1k9ZeElEwkZsWGsMumz6qL5MfNJH9nOBA==",
+ "dev": true,
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "remark-parse": "^10.0.0",
+ "remark-stringify": "^10.0.0",
+ "unified": "^10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/remark-mdx": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-2.3.0.tgz",
@@ -2680,6 +3231,23 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/remark-prism": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/remark-prism/-/remark-prism-1.3.6.tgz",
+ "integrity": "sha512-yYSXJ2MEK2DeD9UKDKFkQPcVqRx6aX2FYD1kE27ScogpZ/BBO8MoOO6gf/AKqfXvKGnP51wqvDEBmPseypgaug==",
+ "dev": true,
+ "dependencies": {
+ "classnames": "^2.3.1",
+ "css-selector-parser": "^1.4.1",
+ "escape-html": "^1.0.3",
+ "jsdom": "^16.5.3",
+ "parse-numeric-range": "^1.2.0",
+ "parse5": "^6.0.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.1",
+ "prismjs": "^1.23.0",
+ "unist-util-map": "^2.0.1"
+ }
+ },
"node_modules/remark-rehype": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz",
@@ -2696,6 +3264,27 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/remark-stringify": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.2.tgz",
+ "integrity": "sha512-6wV3pvbPvHkbNnWB0wdDvVFHOe1hBRAx1Q/5g/EpH4RppAII6J8Gnwe7VbHuXaoKIF6LAg6ExTel/+kNqSQ7lw==",
+ "dev": true,
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-to-markdown": "^1.0.0",
+ "unified": "^10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true
+ },
"node_modules/resolve": {
"version": "1.22.3",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz",
@@ -2741,6 +3330,24 @@
"node": ">=6"
}
},
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "node_modules/saxes": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
+ "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
+ "dev": true,
+ "dependencies": {
+ "xmlchars": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
@@ -2860,6 +3467,39 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true
+ },
+ "node_modules/tough-cookie": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
+ "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==",
+ "dev": true,
+ "dependencies": {
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+ "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/trim-lines": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
@@ -2880,6 +3520,18 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
"node_modules/typescript": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
@@ -2935,6 +3587,20 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/unist-util-map": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-map/-/unist-util-map-2.0.1.tgz",
+ "integrity": "sha512-VdNvk4BQUUU9Rgr8iUOvclHa/iN9O+6Dt66FKij8l9OVezGG37gGWCPU5KSax1R2degqXFvl3kWTkvzL79e9tQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "object-assign": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/unist-util-position": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz",
@@ -3017,6 +3683,25 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/url-parse": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+ "dev": true,
+ "dependencies": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
"node_modules/uvu": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
@@ -3128,6 +3813,66 @@
}
}
},
+ "node_modules/w3c-hr-time": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+ "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+ "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.",
+ "dev": true,
+ "dependencies": {
+ "browser-process-hrtime": "^1.0.0"
+ }
+ },
+ "node_modules/w3c-xmlserializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
+ "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
+ "dev": true,
+ "dependencies": {
+ "xml-name-validator": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+ "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.4"
+ }
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+ "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+ "dev": true,
+ "dependencies": {
+ "iconv-lite": "0.4.24"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+ "dev": true
+ },
+ "node_modules/whatwg-url": {
+ "version": "8.7.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
+ "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.7.0",
+ "tr46": "^2.1.0",
+ "webidl-conversions": "^6.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -3143,12 +3888,54 @@
"node": ">= 8"
}
},
+ "node_modules/word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
+ "node_modules/ws": {
+ "version": "7.5.9",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
+ "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+ "dev": true
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true
+ },
"node_modules/zwitch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
diff --git a/package.json b/package.json
index 4109590..754324d 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,10 @@
"prepare": "husky install"
},
"dependencies": {
+ "@fontsource/jetbrains-mono": "^4.5.12",
+ "@fontsource/lato": "^4.5.10",
+ "normalize.css": "^8.0.1",
+ "prism-themes": "^1.9.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
@@ -18,9 +22,11 @@
"@mdx-js/rollup": "^2.3.0",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
+ "@types/remark-prism": "^1.3.4",
"@vitejs/plugin-react-swc": "^3.0.0",
"husky": "^8.0.0",
"pretty-quick": "^3.1.3",
+ "remark-prism": "^1.3.6",
"typescript": "^4.9.3",
"vite": "^4.2.0"
}
diff --git a/pages/LayoutBase.tsx b/pages/LayoutBase.tsx
new file mode 100644
index 0000000..a83abca
--- /dev/null
+++ b/pages/LayoutBase.tsx
@@ -0,0 +1,20 @@
+import { PropsWithChildren } from "react";
+
+import "./style.css";
+
+const Sidebar: React.FC = () => (
+
+ Home/About
+
+);
+
+const Layout: React.FC = ({ children }) => (
+
+);
+
+export default Layout;
diff --git a/pages/LayoutPage.tsx b/pages/LayoutPage.tsx
new file mode 100644
index 0000000..d2a2cb7
--- /dev/null
+++ b/pages/LayoutPage.tsx
@@ -0,0 +1,12 @@
+import { PropsWithChildren } from "react";
+
+import Base from "./LayoutBase";
+
+const Layout: React.FC = ({ children }) => (
+
+ The Old Speice Guy
+ {children}
+
+);
+
+export default Layout;
diff --git a/pages/about.mdx b/pages/about.mdx
new file mode 100644
index 0000000..1626eaa
--- /dev/null
+++ b/pages/about.mdx
@@ -0,0 +1,8 @@
+import Layout from "./Page";
+export default Layout;
+
+Developer currently living in New York City
+
+Email: [bradlee@speice.io](mailto:bradlee@speice.io)
+
+LinkedIn: [bradleespeice](https://www.linkedin.com/in/bradleespeice/)
diff --git a/pages/index.tsx b/pages/index.tsx
index b4d60cf..8662119 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,9 +1,9 @@
-import React from "react";
+import Layout from "./LayoutPage";
-export default function Page() {
+export default function () {
return (
- <>
+
Is this thing on?
- >
+
);
}
diff --git a/pages/style.css b/pages/style.css
new file mode 100644
index 0000000..7527688
--- /dev/null
+++ b/pages/style.css
@@ -0,0 +1,72 @@
+@import "normalize.css";
+
+@import "@fontsource/lato";
+@import "@fontsource/jetbrains-mono";
+@import "prism-themes/themes/prism-material-dark";
+
+body {
+ font-family: "Lato", sans-serif;
+ font-size: 14pt;
+ line-height: 1.4;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ margin-top: 0.6em;
+ margin-bottom: 0;
+}
+
+p,
+ul {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+pre {
+ padding: 1em 0;
+}
+
+code,
+code[class*="language-"] {
+ font-family: "JetBrains Mono", monospace;
+}
+
+.gridOffset {
+ display: grid;
+ grid-template-columns:
+ [full-start] minmax(1em, 2fr)
+ [main-start] minmax(0, 45em) [main-end]
+ minmax(0, 1fr)
+ [side-start] minmax(0, 3fr) [side-end]
+ minmax(1em, 2fr) [full-end];
+}
+
+.gridOffset > :not(.gridOffsetSide) {
+ grid-column: main;
+}
+
+.gridOffset > div.remark-highlight,
+.gridOffset > div.remark-highlight > pre {
+ display: inherit;
+ grid-column: full;
+ grid-template-columns: inherit;
+}
+
+.gridOffset > div.remark-highlight > pre > code {
+ grid-column: main;
+}
+
+.gridOffsetSide {
+ grid-column: side;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.navbar > * {
+ margin-left: 0.5em;
+ margin-right: 0.5em;
+}
diff --git a/posts/2019/02/the-whole-world.mdx b/posts/2019/02/the-whole-world.mdx
new file mode 100644
index 0000000..9434abc
--- /dev/null
+++ b/posts/2019/02/the-whole-world.mdx
@@ -0,0 +1,336 @@
+import Blog from "../../LayoutBlog";
+export default Blog({
+ title: "Global Memory Usage: The Whole World",
+ description: "Static considered slightly less harmful.",
+ published: "2019-02-05",
+});
+
+The first memory type we'll look at is pretty special: when Rust can prove that a _value_ is fixed
+for the life of a program (`const`), and when a _reference_ is unique for the life of a program
+(`static` as a declaration, not
+[`'static`](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#the-static-lifetime) as a
+lifetime), we can make use of global memory. This special section of data is embedded directly in
+the program binary so that variables are ready to go once the program loads; no additional
+computation is necessary.
+
+Understanding the value/reference distinction is important for reasons we'll go into below, and
+while the
+[full specification](https://github.com/rust-lang/rfcs/blob/master/text/0246-const-vs-static.md) for
+these two keywords is available, we'll take a hands-on approach to the topic.
+
+# **const**
+
+When a _value_ is guaranteed to be unchanging in your program (where "value" may be scalars,
+`struct`s, etc.), you can declare it `const`. This tells the compiler that it's safe to treat the
+value as never changing, and enables some interesting optimizations; not only is there no
+initialization cost to creating the value (it is loaded at the same time as the executable parts of
+your program), but the compiler can also copy the value around if it speeds up the code.
+
+The points we need to address when talking about `const` are:
+
+- `Const` values are stored in read-only memory - it's impossible to modify.
+- Values resulting from calling a `const fn` are materialized at compile-time.
+- The compiler may (or may not) copy `const` values wherever it chooses.
+
+## Read-Only
+
+The first point is a bit strange - "read-only memory."
+[The Rust book](https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants)
+mentions in a couple places that using `mut` with constants is illegal, but it's also important to
+demonstrate just how immutable they are. _Typically_ in Rust you can use
+[interior mutability](https://doc.rust-lang.org/book/ch15-05-interior-mutability.html) to modify
+things that aren't declared `mut`.
+[`RefCell`](https://doc.rust-lang.org/std/cell/struct.RefCell.html) provides an example of this
+pattern in action:
+
+```rust
+use std::cell::RefCell;
+
+fn my_mutator(cell: &RefCell) {
+ // Even though we're given an immutable reference,
+ // the `replace` method allows us to modify the inner value.
+ cell.replace(14);
+}
+
+fn main() {
+ let cell = RefCell::new(25);
+ // Prints out 25
+ println!("Cell: {:?}", cell);
+ my_mutator(&cell);
+ // Prints out 14
+ println!("Cell: {:?}", cell);
+}
+```
+
+--
+[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8e4bea1a718edaff4507944e825a54b2)
+
+When `const` is involved though, interior mutability is impossible:
+
+```rust
+use std::cell::RefCell;
+
+const CELL: RefCell = RefCell::new(25);
+
+fn my_mutator(cell: &RefCell) {
+ cell.replace(14);
+}
+
+fn main() {
+ // First line prints 25 as expected
+ println!("Cell: {:?}", &CELL);
+ my_mutator(&CELL);
+ // Second line *still* prints 25
+ println!("Cell: {:?}", &CELL);
+}
+```
+
+--
+[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=88fe98110c33c1b3a51e341f48b8ae00)
+
+And a second example using [`Once`](https://doc.rust-lang.org/std/sync/struct.Once.html):
+
+```rust
+use std::sync::Once;
+
+const SURPRISE: Once = Once::new();
+
+fn main() {
+ // This is how `Once` is supposed to be used
+ SURPRISE.call_once(|| println!("Initializing..."));
+ // Because `Once` is a `const` value, we never record it
+ // having been initialized the first time, and this closure
+ // will also execute.
+ SURPRISE.call_once(|| println!("Initializing again???"));
+}
+```
+
+--
+[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c3cc5979b5e5434eca0f9ec4a06ee0ed)
+
+When the
+[`const` specification](https://github.com/rust-lang/rfcs/blob/26197104b7bb9a5a35db243d639aee6e46d35d75/text/0246-const-vs-static.md)
+refers to ["rvalues"](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3055.pdf), this
+behavior is what they refer to. [Clippy](https://github.com/rust-lang/rust-clippy) will treat this
+as an error, but it's still something to be aware of.
+
+## Initialization == Compilation
+
+The next thing to mention is that `const` values are loaded into memory _as part of your program
+binary_. Because of this, any `const` values declared in your program will be "realized" at
+compile-time; accessing them may trigger a main-memory lookup (with a fixed address, so your CPU may
+be able to prefetch the value), but that's it.
+
+```rust
+use std::cell::RefCell;
+
+const CELL: RefCell = RefCell::new(24);
+
+pub fn multiply(value: u32) -> u32 {
+ // CELL is stored at `.L__unnamed_1`
+ value * (*CELL.get_mut())
+}
+```
+
+-- [Compiler Explorer](https://godbolt.org/z/Th8boO)
+
+The compiler creates one `RefCell`, uses it everywhere, and never needs to call the `RefCell::new`
+function.
+
+## Copying
+
+If it's helpful though, the compiler can choose to copy `const` values.
+
+```rust
+const FACTOR: u32 = 1000;
+
+pub fn multiply(value: u32) -> u32 {
+ // See assembly line 4 for the `mov edi, 1000` instruction
+ value * FACTOR
+}
+
+pub fn multiply_twice(value: u32) -> u32 {
+ // See assembly lines 22 and 29 for `mov edi, 1000` instructions
+ value * FACTOR * FACTOR
+}
+```
+
+-- [Compiler Explorer](https://godbolt.org/z/ZtS54X)
+
+In this example, the `FACTOR` value is turned into the `mov edi, 1000` instruction in both the
+`multiply` and `multiply_twice` functions; the "1000" value is never "stored" anywhere, as it's
+small enough to inline into the assembly instructions.
+
+Finally, getting the address of a `const` value is possible, but not guaranteed to be unique
+(because the compiler can choose to copy values). I was unable to get non-unique pointers in my
+testing (even using different crates), but the specifications are clear enough: _don't rely on
+pointers to `const` values being consistent_. To be frank, caring about locations for `const` values
+is almost certainly a code smell.
+
+# **static**
+
+Static variables are related to `const` variables, but take a slightly different approach. When we
+declare that a _reference_ is unique for the life of a program, you have a `static` variable
+(unrelated to the `'static` lifetime). Because of the reference/value distinction with
+`const`/`static`, static variables behave much more like typical "global" variables.
+
+But to understand `static`, here's what we'll look at:
+
+- `static` variables are globally unique locations in memory.
+- Like `const`, `static` variables are loaded at the same time as your program being read into
+ memory.
+- All `static` variables must implement the
+ [`Sync`](https://doc.rust-lang.org/std/marker/trait.Sync.html) marker trait.
+- Interior mutability is safe and acceptable when using `static` variables.
+
+## Memory Uniqueness
+
+The single biggest difference between `const` and `static` is the guarantees provided about
+uniqueness. Where `const` variables may or may not be copied in code, `static` variables are
+guarantee to be unique. If we take a previous `const` example and change it to `static`, the
+difference should be clear:
+
+```rust
+static FACTOR: u32 = 1000;
+
+pub fn multiply(value: u32) -> u32 {
+ // The assembly to `mul dword ptr [rip + example::FACTOR]` is how FACTOR gets used
+ value * FACTOR
+}
+
+pub fn multiply_twice(value: u32) -> u32 {
+ // The assembly to `mul dword ptr [rip + example::FACTOR]` is how FACTOR gets used
+ value * FACTOR * FACTOR
+}
+```
+
+-- [Compiler Explorer](https://godbolt.org/z/uxmiRQ)
+
+Where [previously](#copying) there were plenty of references to multiplying by 1000, the new
+assembly refers to `FACTOR` as a named memory location instead. No initialization work needs to be
+done, but the compiler can no longer prove the value never changes during execution.
+
+## Initialization == Compilation
+
+Next, let's talk about initialization. The simplest case is initializing static variables with
+either scalar or struct notation:
+
+```rust
+#[derive(Debug)]
+struct MyStruct {
+ x: u32
+}
+
+static MY_STRUCT: MyStruct = MyStruct {
+ // You can even reference other statics
+ // declared later
+ x: MY_VAL
+};
+
+static MY_VAL: u32 = 24;
+
+fn main() {
+ println!("Static MyStruct: {:?}", MY_STRUCT);
+}
+```
+
+--
+[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b538dbc46076f12db047af4f4403ee6e)
+
+Things can get a bit weirder when using `const fn` though. In most cases, it just works:
+
+```rust
+#[derive(Debug)]
+struct MyStruct {
+ x: u32
+}
+
+impl MyStruct {
+ const fn new() -> MyStruct {
+ MyStruct { x: 24 }
+ }
+}
+
+static MY_STRUCT: MyStruct = MyStruct::new();
+
+fn main() {
+ println!("const fn Static MyStruct: {:?}", MY_STRUCT);
+}
+```
+
+--
+[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8c796a6e7fc273c12115091b707b0255)
+
+However, there's a caveat: you're currently not allowed to use `const fn` to initialize static
+variables of types that aren't marked `Sync`. For example,
+[`RefCell::new()`](https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.new) is a
+`const fn`, but because
+[`RefCell` isn't `Sync`](https://doc.rust-lang.org/std/cell/struct.RefCell.html#impl-Sync), you'll
+get an error at compile time:
+
+```rust
+use std::cell::RefCell;
+
+// error[E0277]: `std::cell::RefCell` cannot be shared between threads safely
+static MY_LOCK: RefCell = RefCell::new(0);
+```
+
+--
+[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c76ef86e473d07117a1700e21fd45560)
+
+It's likely that this will
+[change in the future](https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md) though.
+
+## **Sync**
+
+Which leads well to the next point: static variable types must implement the
+[`Sync` marker](https://doc.rust-lang.org/std/marker/trait.Sync.html). Because they're globally
+unique, it must be safe for you to access static variables from any thread at any time. Most
+`struct` definitions automatically implement the `Sync` trait because they contain only elements
+which themselves implement `Sync` (read more in the
+[Nomicon](https://doc.rust-lang.org/nomicon/send-and-sync.html)). This is why earlier examples could
+get away with initializing statics, even though we never included an `impl Sync for MyStruct` in the
+code. To demonstrate this property, Rust refuses to compile our earlier example if we add a
+non-`Sync` element to the `struct` definition:
+
+```rust
+use std::cell::RefCell;
+
+struct MyStruct {
+ x: u32,
+ y: RefCell,
+}
+
+// error[E0277]: `std::cell::RefCell` cannot be shared between threads safely
+static MY_STRUCT: MyStruct = MyStruct {
+ x: 8,
+ y: RefCell::new(8)
+};
+```
+
+--
+[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=40074d0248f056c296b662dbbff97cfc)
+
+## Interior Mutability
+
+Finally, while `static mut` variables are allowed, mutating them is an `unsafe` operation. If we
+want to stay in `safe` Rust, we can use interior mutability to accomplish similar goals:
+
+```rust
+use std::sync::Once;
+
+// This example adapted from https://doc.rust-lang.org/std/sync/struct.Once.html#method.call_once
+static INIT: Once = Once::new();
+
+fn main() {
+ // Note that while `INIT` is declared immutable, we're still allowed
+ // to mutate its interior
+ INIT.call_once(|| println!("Initializing..."));
+ // This code won't panic, as the interior of INIT was modified
+ // as part of the previous `call_once`
+ INIT.call_once(|| panic!("INIT was called twice!"));
+}
+```
+
+--
+[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3ba003a981a7ed7400240caadd384d59)
diff --git a/posts/LayoutBlog.tsx b/posts/LayoutBlog.tsx
new file mode 100644
index 0000000..f672c80
--- /dev/null
+++ b/posts/LayoutBlog.tsx
@@ -0,0 +1,35 @@
+import { PropsWithChildren } from "react";
+
+import Base from "../pages/LayoutBase";
+
+interface BlogProps {
+ title: string;
+ description: string;
+ published: string;
+ updated?: string;
+}
+
+export default function Layout({
+ title,
+ description,
+ published,
+ updated,
+}: BlogProps): React.FC {
+ const header = (
+
+
{title}
+
{description}
+
Published: {published}
+ {updated &&
Last updated: {updated}
}
+
+ );
+
+ const withChildren: React.FC = ({ children }) => (
+
+ {header}
+
+ {children}
+
+ );
+ return withChildren;
+}
diff --git a/vite.config.ts b/vite.config.ts
index 28c75b2..7d469dc 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -3,12 +3,16 @@ import blog from "@bspeice/vite-plugin-blog";
import mdx from "@mdx-js/rollup";
import react from "@vitejs/plugin-react-swc";
+import remarkPrism from "remark-prism";
+
export default defineConfig({
plugins: [
blog({
- "/": "/pages/index",
+ "/": "/pages/index.tsx",
+ "/about": "/pages/about.mdx",
+ "/2019/02/the-whole-world": "/posts/2019/02/the-whole-world.mdx",
}),
- mdx(),
+ mdx({ remarkPlugins: [remarkPrism] }),
react(),
],
});