Start
15
docs/.eslintrc.yml
Normal file
@ -0,0 +1,15 @@
|
||||
env:
|
||||
browser: true
|
||||
es2021: true
|
||||
extends:
|
||||
- eslint:recommended
|
||||
- plugin:@typescript-eslint/recommended
|
||||
overrides: []
|
||||
parser: "@typescript-eslint/parser"
|
||||
parserOptions:
|
||||
ecmaVersion: latest
|
||||
sourceType: module
|
||||
plugins:
|
||||
- "@typescript-eslint"
|
||||
rules:
|
||||
"@typescript-eslint/no-non-null-assertion": off
|
||||
21
docs/.gitignore
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# build output
|
||||
dist/
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
7
docs/.prettierrc.yml
Normal file
@ -0,0 +1,7 @@
|
||||
$schema: "https://json.schemastore.org/prettierrc"
|
||||
tabWidth: 4
|
||||
semi: true
|
||||
singleQuote: false
|
||||
trailingComma: none
|
||||
printWidth: 100
|
||||
endOfLine: lf
|
||||
4
docs/.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"recommendations": ["astro-build.astro-vscode"],
|
||||
"unwantedRecommendations": []
|
||||
}
|
||||
11
docs/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"command": "./node_modules/.bin/astro dev",
|
||||
"name": "Development server",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
12
docs/Pipfile
@ -1,12 +0,0 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
|
||||
[dev-packages]
|
||||
menagerie-docs = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.11"
|
||||
613
docs/Pipfile.lock
generated
@ -1,613 +0,0 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "e93f7f7087f635da529dc8dbaa56be872c12a26be4d8cfcaa9393f12fe7f1bda"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.11"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {},
|
||||
"develop": {
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836",
|
||||
"sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==22.2.0"
|
||||
},
|
||||
"beautifulsoup4": {
|
||||
"hashes": [
|
||||
"sha256:2130a5ad7f513200fae61a17abb5e338ca980fa28c439c0571014bc0217e9591",
|
||||
"sha256:c5fceeaec29d09c84970e47c65f2f0efe57872f7cff494c9691a26ec0ff13234"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==4.12.0"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3",
|
||||
"sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2022.12.7"
|
||||
},
|
||||
"charset-normalizer": {
|
||||
"hashes": [
|
||||
"sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6",
|
||||
"sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1",
|
||||
"sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e",
|
||||
"sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373",
|
||||
"sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62",
|
||||
"sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230",
|
||||
"sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be",
|
||||
"sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c",
|
||||
"sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0",
|
||||
"sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448",
|
||||
"sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f",
|
||||
"sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649",
|
||||
"sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d",
|
||||
"sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0",
|
||||
"sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706",
|
||||
"sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a",
|
||||
"sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59",
|
||||
"sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23",
|
||||
"sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5",
|
||||
"sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb",
|
||||
"sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e",
|
||||
"sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e",
|
||||
"sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c",
|
||||
"sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28",
|
||||
"sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d",
|
||||
"sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41",
|
||||
"sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974",
|
||||
"sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce",
|
||||
"sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f",
|
||||
"sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1",
|
||||
"sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d",
|
||||
"sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8",
|
||||
"sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017",
|
||||
"sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31",
|
||||
"sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7",
|
||||
"sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8",
|
||||
"sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e",
|
||||
"sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14",
|
||||
"sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd",
|
||||
"sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d",
|
||||
"sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795",
|
||||
"sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b",
|
||||
"sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b",
|
||||
"sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b",
|
||||
"sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203",
|
||||
"sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f",
|
||||
"sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19",
|
||||
"sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1",
|
||||
"sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a",
|
||||
"sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac",
|
||||
"sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9",
|
||||
"sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0",
|
||||
"sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137",
|
||||
"sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f",
|
||||
"sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6",
|
||||
"sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5",
|
||||
"sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909",
|
||||
"sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f",
|
||||
"sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0",
|
||||
"sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324",
|
||||
"sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755",
|
||||
"sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb",
|
||||
"sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854",
|
||||
"sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c",
|
||||
"sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60",
|
||||
"sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84",
|
||||
"sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0",
|
||||
"sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b",
|
||||
"sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1",
|
||||
"sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531",
|
||||
"sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1",
|
||||
"sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11",
|
||||
"sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326",
|
||||
"sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df",
|
||||
"sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.0'",
|
||||
"version": "==3.1.0"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
|
||||
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==8.1.3"
|
||||
},
|
||||
"dataclasses-json": {
|
||||
"hashes": [
|
||||
"sha256:bc285b5f892094c3a53d558858a88553dd6a61a11ab1a8128a0e554385dcc5dd",
|
||||
"sha256:c2c11bc8214fbf709ffc369d11446ff6945254a7f09128154a7620613d8fda90"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.5.7"
|
||||
},
|
||||
"elementpath": {
|
||||
"hashes": [
|
||||
"sha256:2b1b524223d70fd6dd63a36b9bc32e4919c96a272c2d1454094c4d85086bc6f8",
|
||||
"sha256:dbd7eba3cf0b3b4934f627ba24851a3e0798ef2bc9104555a4cd831f2e6e8e14"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==4.1.0"
|
||||
},
|
||||
"htmlmin": {
|
||||
"hashes": [
|
||||
"sha256:50c1ef4630374a5d723900096a961cff426dff46b48f34d194a81bbe14eca178"
|
||||
],
|
||||
"version": "==0.1.12"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4",
|
||||
"sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==3.4"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852",
|
||||
"sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.1.2"
|
||||
},
|
||||
"json-minify": {
|
||||
"hashes": [
|
||||
"sha256:268e6966c0f1dcb32ac54e1d047b83deba9ce711c0763ceba63f26d3aeedf656",
|
||||
"sha256:499717626144a533d64ed4a1513976cf2212958b6806a66e07dd8e22207df559"
|
||||
],
|
||||
"version": "==0.3.0"
|
||||
},
|
||||
"json-schema-for-humans": {
|
||||
"hashes": [
|
||||
"sha256:1e34f1ae053c0884a52bcfc415f8de10a9dc918554523912f53015d202549f37",
|
||||
"sha256:62a72dd2edb064fb6f2cb6939670185b80a79317b1e7cdb2132634287b142493"
|
||||
],
|
||||
"markers": "python_version >= '3.7' and python_version < '4.0'",
|
||||
"version": "==0.44.4"
|
||||
},
|
||||
"jsonschema": {
|
||||
"hashes": [
|
||||
"sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d",
|
||||
"sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==4.17.3"
|
||||
},
|
||||
"libsass": {
|
||||
"hashes": [
|
||||
"sha256:081e256ab3c5f3f09c7b8dea3bf3bf5e64a97c6995fd9eea880639b3f93a9f9a",
|
||||
"sha256:3ab5ad18e47db560f4f0c09e3d28cf3bb1a44711257488ac2adad69f4f7f8425",
|
||||
"sha256:65455a2728b696b62100eb5932604aa13a29f4ac9a305d95773c14aaa7200aaf",
|
||||
"sha256:89c5ce497fcf3aba1dd1b19aae93b99f68257e5f2026b731b00a872f13324c7f",
|
||||
"sha256:f1efc1b612299c88aec9e39d6ca0c266d360daa5b19d9430bdeaffffa86993f9"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.22.0"
|
||||
},
|
||||
"markdown": {
|
||||
"hashes": [
|
||||
"sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49",
|
||||
"sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.3.4"
|
||||
},
|
||||
"markdown2": {
|
||||
"hashes": [
|
||||
"sha256:7d49ca871d3e0e412c65d7d21fcbc13ae897f7876f3e5f14dd4db3b7fbf27f10",
|
||||
"sha256:90475aca3d9c8e7df6d70c51de5bbbe9edf7fcf6a380bd1044d321500f5445da"
|
||||
],
|
||||
"markers": "python_version >= '3.5' and python_version < '4'",
|
||||
"version": "==2.4.8"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed",
|
||||
"sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc",
|
||||
"sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2",
|
||||
"sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460",
|
||||
"sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7",
|
||||
"sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0",
|
||||
"sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1",
|
||||
"sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa",
|
||||
"sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03",
|
||||
"sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323",
|
||||
"sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65",
|
||||
"sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013",
|
||||
"sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036",
|
||||
"sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f",
|
||||
"sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4",
|
||||
"sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419",
|
||||
"sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2",
|
||||
"sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619",
|
||||
"sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a",
|
||||
"sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a",
|
||||
"sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd",
|
||||
"sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7",
|
||||
"sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666",
|
||||
"sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65",
|
||||
"sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859",
|
||||
"sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625",
|
||||
"sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff",
|
||||
"sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156",
|
||||
"sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd",
|
||||
"sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba",
|
||||
"sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f",
|
||||
"sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1",
|
||||
"sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094",
|
||||
"sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a",
|
||||
"sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513",
|
||||
"sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed",
|
||||
"sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d",
|
||||
"sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3",
|
||||
"sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147",
|
||||
"sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c",
|
||||
"sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603",
|
||||
"sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601",
|
||||
"sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a",
|
||||
"sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1",
|
||||
"sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d",
|
||||
"sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3",
|
||||
"sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54",
|
||||
"sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2",
|
||||
"sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6",
|
||||
"sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.1.2"
|
||||
},
|
||||
"marshmallow": {
|
||||
"hashes": [
|
||||
"sha256:90032c0fd650ce94b6ec6dc8dfeb0e3ff50c144586462c389b81a07205bedb78",
|
||||
"sha256:93f0958568da045b0021ec6aeb7ac37c81bfcccbb9a0e7ed8559885070b3a19b"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.19.0"
|
||||
},
|
||||
"marshmallow-enum": {
|
||||
"hashes": [
|
||||
"sha256:38e697e11f45a8e64b4a1e664000897c659b60aa57bfa18d44e226a9920b6e58",
|
||||
"sha256:57161ab3dbfde4f57adeb12090f39592e992b9c86d206d02f6bd03ebec60f072"
|
||||
],
|
||||
"version": "==1.5.1"
|
||||
},
|
||||
"menagerie-docs": {
|
||||
"hashes": [
|
||||
"sha256:ad6ff178b3edc493b7e031d932616e4aaef788c2e796494e729fb2fb96c334eb",
|
||||
"sha256:bfd5b78c8a2931983a1941ee2e96204b93e5ff90f5bbc0e0178c763de42b844f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.1.14"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:cabaa341ad0389ea83c17a94566a53ae4c9d07349861ecb14dc6d0345cf9ac5d",
|
||||
"sha256:d2bc7f02446e86a68911e58ded76d6561eea00cddfb2a91e7019bbb586c799f3"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==9.1.0"
|
||||
},
|
||||
"mypy-extensions": {
|
||||
"hashes": [
|
||||
"sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d",
|
||||
"sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==1.0.0"
|
||||
},
|
||||
"ndicts": {
|
||||
"hashes": [
|
||||
"sha256:010b0c94180fe89e7e0d5fa89909c4bd7784c52d56908d4d776337c9358378e9",
|
||||
"sha256:1a1f31cdb770c037c9cc9bc27a8493e43bfe035a606d3630c2e3d14eabe7bfbf"
|
||||
],
|
||||
"markers": "python_version >= '3.8' and python_version < '4.0'",
|
||||
"version": "==0.3.0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2",
|
||||
"sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==23.0"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:013016af6b3a12a2f40b704677f8b51f72cb007dac785a9933d5c86a72a7fe33",
|
||||
"sha256:0845adc64fe9886db00f5ab68c4a8cd933ab749a87747555cec1c95acea64b0b",
|
||||
"sha256:0884ba7b515163a1a05440a138adeb722b8a6ae2c2b33aea93ea3118dd3a899e",
|
||||
"sha256:09b89ddc95c248ee788328528e6a2996e09eaccddeeb82a5356e92645733be35",
|
||||
"sha256:0dd4c681b82214b36273c18ca7ee87065a50e013112eea7d78c7a1b89a739153",
|
||||
"sha256:0e51f608da093e5d9038c592b5b575cadc12fd748af1479b5e858045fff955a9",
|
||||
"sha256:0f3269304c1a7ce82f1759c12ce731ef9b6e95b6df829dccd9fe42912cc48569",
|
||||
"sha256:16a8df99701f9095bea8a6c4b3197da105df6f74e6176c5b410bc2df2fd29a57",
|
||||
"sha256:19005a8e58b7c1796bc0167862b1f54a64d3b44ee5d48152b06bb861458bc0f8",
|
||||
"sha256:1b4b4e9dda4f4e4c4e6896f93e84a8f0bcca3b059de9ddf67dac3c334b1195e1",
|
||||
"sha256:28676836c7796805914b76b1837a40f76827ee0d5398f72f7dcc634bae7c6264",
|
||||
"sha256:2968c58feca624bb6c8502f9564dd187d0e1389964898f5e9e1fbc8533169157",
|
||||
"sha256:3f4cc516e0b264c8d4ccd6b6cbc69a07c6d582d8337df79be1e15a5056b258c9",
|
||||
"sha256:3fa1284762aacca6dc97474ee9c16f83990b8eeb6697f2ba17140d54b453e133",
|
||||
"sha256:43521ce2c4b865d385e78579a082b6ad1166ebed2b1a2293c3be1d68dd7ca3b9",
|
||||
"sha256:451f10ef963918e65b8869e17d67db5e2f4ab40e716ee6ce7129b0cde2876eab",
|
||||
"sha256:46c259e87199041583658457372a183636ae8cd56dbf3f0755e0f376a7f9d0e6",
|
||||
"sha256:46f39cab8bbf4a384ba7cb0bc8bae7b7062b6a11cfac1ca4bc144dea90d4a9f5",
|
||||
"sha256:519e14e2c49fcf7616d6d2cfc5c70adae95682ae20f0395e9280db85e8d6c4df",
|
||||
"sha256:53dcb50fbdc3fb2c55431a9b30caeb2f7027fcd2aeb501459464f0214200a503",
|
||||
"sha256:54614444887e0d3043557d9dbc697dbb16cfb5a35d672b7a0fcc1ed0cf1c600b",
|
||||
"sha256:575d8912dca808edd9acd6f7795199332696d3469665ef26163cd090fa1f8bfa",
|
||||
"sha256:5dd5a9c3091a0f414a963d427f920368e2b6a4c2f7527fdd82cde8ef0bc7a327",
|
||||
"sha256:5f532a2ad4d174eb73494e7397988e22bf427f91acc8e6ebf5bb10597b49c493",
|
||||
"sha256:60e7da3a3ad1812c128750fc1bc14a7ceeb8d29f77e0a2356a8fb2aa8925287d",
|
||||
"sha256:653d7fb2df65efefbcbf81ef5fe5e5be931f1ee4332c2893ca638c9b11a409c4",
|
||||
"sha256:6663977496d616b618b6cfa43ec86e479ee62b942e1da76a2c3daa1c75933ef4",
|
||||
"sha256:6abfb51a82e919e3933eb137e17c4ae9c0475a25508ea88993bb59faf82f3b35",
|
||||
"sha256:6c6b1389ed66cdd174d040105123a5a1bc91d0aa7059c7261d20e583b6d8cbd2",
|
||||
"sha256:6d9dfb9959a3b0039ee06c1a1a90dc23bac3b430842dcb97908ddde05870601c",
|
||||
"sha256:765cb54c0b8724a7c12c55146ae4647e0274a839fb6de7bcba841e04298e1011",
|
||||
"sha256:7a21222644ab69ddd9967cfe6f2bb420b460dae4289c9d40ff9a4896e7c35c9a",
|
||||
"sha256:7ac7594397698f77bce84382929747130765f66406dc2cd8b4ab4da68ade4c6e",
|
||||
"sha256:7cfc287da09f9d2a7ec146ee4d72d6ea1342e770d975e49a8621bf54eaa8f30f",
|
||||
"sha256:83125753a60cfc8c412de5896d10a0a405e0bd88d0470ad82e0869ddf0cb3848",
|
||||
"sha256:847b114580c5cc9ebaf216dd8c8dbc6b00a3b7ab0131e173d7120e6deade1f57",
|
||||
"sha256:87708d78a14d56a990fbf4f9cb350b7d89ee8988705e58e39bdf4d82c149210f",
|
||||
"sha256:8a2b5874d17e72dfb80d917213abd55d7e1ed2479f38f001f264f7ce7bae757c",
|
||||
"sha256:8f127e7b028900421cad64f51f75c051b628db17fb00e099eb148761eed598c9",
|
||||
"sha256:94cdff45173b1919350601f82d61365e792895e3c3a3443cf99819e6fbf717a5",
|
||||
"sha256:99d92d148dd03fd19d16175b6d355cc1b01faf80dae93c6c3eb4163709edc0a9",
|
||||
"sha256:9a3049a10261d7f2b6514d35bbb7a4dfc3ece4c4de14ef5876c4b7a23a0e566d",
|
||||
"sha256:9d9a62576b68cd90f7075876f4e8444487db5eeea0e4df3ba298ee38a8d067b0",
|
||||
"sha256:9e5f94742033898bfe84c93c831a6f552bb629448d4072dd312306bab3bd96f1",
|
||||
"sha256:a1c2d7780448eb93fbcc3789bf3916aa5720d942e37945f4056680317f1cd23e",
|
||||
"sha256:a2e0f87144fcbbe54297cae708c5e7f9da21a4646523456b00cc956bd4c65815",
|
||||
"sha256:a4dfdae195335abb4e89cc9762b2edc524f3c6e80d647a9a81bf81e17e3fb6f0",
|
||||
"sha256:a96e6e23f2b79433390273eaf8cc94fec9c6370842e577ab10dabdcc7ea0a66b",
|
||||
"sha256:aabdab8ec1e7ca7f1434d042bf8b1e92056245fb179790dc97ed040361f16bfd",
|
||||
"sha256:b222090c455d6d1a64e6b7bb5f4035c4dff479e22455c9eaa1bdd4c75b52c80c",
|
||||
"sha256:b52ff4f4e002f828ea6483faf4c4e8deea8d743cf801b74910243c58acc6eda3",
|
||||
"sha256:b70756ec9417c34e097f987b4d8c510975216ad26ba6e57ccb53bc758f490dab",
|
||||
"sha256:b8c2f6eb0df979ee99433d8b3f6d193d9590f735cf12274c108bd954e30ca858",
|
||||
"sha256:b9b752ab91e78234941e44abdecc07f1f0d8f51fb62941d32995b8161f68cfe5",
|
||||
"sha256:ba6612b6548220ff5e9df85261bddc811a057b0b465a1226b39bfb8550616aee",
|
||||
"sha256:bd752c5ff1b4a870b7661234694f24b1d2b9076b8bf337321a814c612665f343",
|
||||
"sha256:c3c4ed2ff6760e98d262e0cc9c9a7f7b8a9f61aa4d47c58835cdaf7b0b8811bb",
|
||||
"sha256:c5c1362c14aee73f50143d74389b2c158707b4abce2cb055b7ad37ce60738d47",
|
||||
"sha256:cb362e3b0976dc994857391b776ddaa8c13c28a16f80ac6522c23d5257156bed",
|
||||
"sha256:d197df5489004db87d90b918033edbeee0bd6df3848a204bca3ff0a903bef837",
|
||||
"sha256:d3b56206244dc8711f7e8b7d6cad4663917cd5b2d950799425076681e8766286",
|
||||
"sha256:d5b2f8a31bd43e0f18172d8ac82347c8f37ef3e0b414431157718aa234991b28",
|
||||
"sha256:d7081c084ceb58278dd3cf81f836bc818978c0ccc770cbbb202125ddabec6628",
|
||||
"sha256:db74f5562c09953b2c5f8ec4b7dfd3f5421f31811e97d1dbc0a7c93d6e3a24df",
|
||||
"sha256:df41112ccce5d47770a0c13651479fbcd8793f34232a2dd9faeccb75eb5d0d0d",
|
||||
"sha256:e1339790c083c5a4de48f688b4841f18df839eb3c9584a770cbd818b33e26d5d",
|
||||
"sha256:e621b0246192d3b9cb1dc62c78cfa4c6f6d2ddc0ec207d43c0dedecb914f152a",
|
||||
"sha256:e8c5cf126889a4de385c02a2c3d3aba4b00f70234bfddae82a5eaa3ee6d5e3e6",
|
||||
"sha256:e9d7747847c53a16a729b6ee5e737cf170f7a16611c143d95aa60a109a59c336",
|
||||
"sha256:eaef5d2de3c7e9b21f1e762f289d17b726c2239a42b11e25446abf82b26ac132",
|
||||
"sha256:ed3e4b4e1e6de75fdc16d3259098de7c6571b1a6cc863b1a49e7d3d53e036070",
|
||||
"sha256:ef21af928e807f10bf4141cad4746eee692a0dd3ff56cfb25fce076ec3cc8abe",
|
||||
"sha256:f09598b416ba39a8f489c124447b007fe865f786a89dbfa48bb5cf395693132a",
|
||||
"sha256:f0caf4a5dcf610d96c3bd32932bfac8aee61c96e60481c2a0ea58da435e25acd",
|
||||
"sha256:f6e78171be3fb7941f9910ea15b4b14ec27725865a73c15277bc39f5ca4f8391",
|
||||
"sha256:f715c32e774a60a337b2bb8ad9839b4abf75b267a0f18806f6f4f5f1688c4b5a",
|
||||
"sha256:fb5c1ad6bad98c57482236a21bf985ab0ef42bd51f7ad4e4538e89a997624e12"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==9.4.0"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297",
|
||||
"sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.14.0"
|
||||
},
|
||||
"pyrsistent": {
|
||||
"hashes": [
|
||||
"sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8",
|
||||
"sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440",
|
||||
"sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a",
|
||||
"sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c",
|
||||
"sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3",
|
||||
"sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393",
|
||||
"sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9",
|
||||
"sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da",
|
||||
"sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf",
|
||||
"sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64",
|
||||
"sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a",
|
||||
"sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3",
|
||||
"sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98",
|
||||
"sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2",
|
||||
"sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8",
|
||||
"sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf",
|
||||
"sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc",
|
||||
"sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7",
|
||||
"sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28",
|
||||
"sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2",
|
||||
"sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b",
|
||||
"sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a",
|
||||
"sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64",
|
||||
"sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19",
|
||||
"sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1",
|
||||
"sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9",
|
||||
"sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.19.3"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588",
|
||||
"sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"
|
||||
],
|
||||
"version": "==2023.3"
|
||||
},
|
||||
"pyyaml": {
|
||||
"hashes": [
|
||||
"sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf",
|
||||
"sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293",
|
||||
"sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b",
|
||||
"sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57",
|
||||
"sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b",
|
||||
"sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4",
|
||||
"sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07",
|
||||
"sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba",
|
||||
"sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9",
|
||||
"sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287",
|
||||
"sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513",
|
||||
"sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0",
|
||||
"sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782",
|
||||
"sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0",
|
||||
"sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92",
|
||||
"sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f",
|
||||
"sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2",
|
||||
"sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc",
|
||||
"sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1",
|
||||
"sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c",
|
||||
"sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86",
|
||||
"sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4",
|
||||
"sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c",
|
||||
"sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34",
|
||||
"sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b",
|
||||
"sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d",
|
||||
"sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c",
|
||||
"sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb",
|
||||
"sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7",
|
||||
"sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737",
|
||||
"sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3",
|
||||
"sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d",
|
||||
"sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358",
|
||||
"sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53",
|
||||
"sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78",
|
||||
"sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803",
|
||||
"sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a",
|
||||
"sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f",
|
||||
"sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174",
|
||||
"sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==6.0"
|
||||
},
|
||||
"rcssmin": {
|
||||
"hashes": [
|
||||
"sha256:271e3d2f8614a6d4637ed8fff3d90007f03e2a654cd9444f37d888797662ba72",
|
||||
"sha256:35da6a6999e9e2c5b0e691b42ed56cc479373e0ecab33ef5277dfecce625e44a",
|
||||
"sha256:42576d95dfad53d77df2e68dfdec95b89b10fad320f241f1af3ca1438578254a",
|
||||
"sha256:4f9400b4366d29f5f5446f58e78549afa8338e6a59740c73115e9f6ac413dc64",
|
||||
"sha256:705c9112d0ed54ea40aecf97e7fd29bdf0f1c46d278a32d8f957f31dde90778a",
|
||||
"sha256:79421230dd67c37ec61ed9892813d2b839b68f2f48ef55c75f976e81701d60b4",
|
||||
"sha256:868215e1fd0e92a6122e0ed5973dfc7bb8330fe1e92274d05b2585253b38c0ca",
|
||||
"sha256:8a26fec3c1e6b7a3765ccbaccc20fbb5c0ed3422cc381e01a2607f08d7621c44",
|
||||
"sha256:8fcfd10ae2a1c4ce231a33013f2539e07c3836bf17cc945cc25cc30bf8e68e45",
|
||||
"sha256:908fe072efd2432fb0975a61124609a8e05021367f6a3463d45f5e3e74c4fdda",
|
||||
"sha256:914e589f40573035006913861ed2adc28fbe70082a8b6bff5be7ee430b7b5c2e",
|
||||
"sha256:a04d58a2a21e9a089306d3f99c4b12bf5b656a79c198ef2321e80f8fd9afab06",
|
||||
"sha256:a417735d4023d47d048a6288c88dbceadd20abaaf65a11bb4fda1e8458057019",
|
||||
"sha256:c30f8bc839747b6da59274e0c6e4361915d66532e26448d589cb2b1846d7bf11",
|
||||
"sha256:c7278c1c25bb90d8e554df92cfb3b6a1195004ead50f764653d3093933ee0877",
|
||||
"sha256:c7728e3b546b1b6ea08cab721e8e21409dbcc11b881d0b87d10b0be8930af2a2",
|
||||
"sha256:cf74d7ea5e191f0f344b354eed8b7c83eeafbd9a97bec3a579c3d26edf11b005",
|
||||
"sha256:d0afc6e7b64ef30d6dcde88830ec1a237b9f16a39f920a8fd159928684ccf8db",
|
||||
"sha256:d4e263fa9428704fd94c2cb565c7519ca1d225217943f71caffe6741ab5b9df1",
|
||||
"sha256:e923c105100ab70abde1c01d3196ddd6b07255e32073685542be4e3a60870c8e",
|
||||
"sha256:ee386bec6d62f8c814d65c011d604a7c82d24aa3f718facd66e850eea8d6a5a1",
|
||||
"sha256:f15673e97f0a68b4c378c4d15b088fe96d60bc106d278c88829923118833c20f",
|
||||
"sha256:f7a1fcdbafaacac0530da04edca4a44303baab430ea42e7d59aece4b3f3e9a51"
|
||||
],
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa",
|
||||
"sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"
|
||||
],
|
||||
"markers": "python_version >= '3.7' and python_version < '4'",
|
||||
"version": "==2.28.2"
|
||||
},
|
||||
"rjsmin": {
|
||||
"hashes": [
|
||||
"sha256:113132a40ce7d03b2ced4fac215f0297338ed1c207394b739266efab7831988b",
|
||||
"sha256:122aa52bcf7ad9f12728d309012d1308c6ecfe4d6b09ea867a110dcad7b7728c",
|
||||
"sha256:145c6af8df42d8af102d0d39a6de2e5fa66aef9e38947cfb9d65377d1b9940b2",
|
||||
"sha256:1f982be8e011438777a94307279b40134a3935fc0f079312ee299725b8af5411",
|
||||
"sha256:3453ee6d5e7a2723ec45c2909e2382371783400e8d51952b692884c6d850a3d0",
|
||||
"sha256:35827844d2085bd59d34214dfba6f1fc42a215c455887437b07dbf9c73019cc1",
|
||||
"sha256:35f21046504544e2941e04190ce24161255479133751550e36ddb3f4af0ecdca",
|
||||
"sha256:5d67ec09da46a492186e35cabca02a0d092eda5ef5b408a419b99ee4acf28d5c",
|
||||
"sha256:747bc9d3bc8a220f40858e6aad50b2ae2eb7f69c924d4fa3803b81be1c1ddd02",
|
||||
"sha256:7dd58b5ed88233bc61dc80b0ed87b93a1786031d9977c70d335221ef1ac5581a",
|
||||
"sha256:812af25c08d6a5ae98019a2e1b47ebb47f7469abd351670c353d619eaeae4064",
|
||||
"sha256:8a6710e358c661dcdcfd027e67de3afd72a6af4c88101dcf110de39e9bbded39",
|
||||
"sha256:8c340e251619c97571a5ade20f147f1f7e8664f66a2d6d7319e05e3ef6a4423c",
|
||||
"sha256:99c074cd6a8302ff47118a9c3d086f89328dc8e5c4b105aa1f348fb85c765a30",
|
||||
"sha256:b8464629a18fe69f70677854c93a3707976024b226a0ce62707c618f923e1346",
|
||||
"sha256:bbd7a0abaa394afd951f5d4e05249d306fec1c9674bfee179787674dddd0bdb7",
|
||||
"sha256:bc5bc2f94e59bc81562c572b7f1bdd6bcec4f61168dc68a2993bad2d355b6e19",
|
||||
"sha256:bd1faedc425006d9e86b23837d164f01d105b7a8b66b767a9766d0014773db2a",
|
||||
"sha256:ca90630b84fe94bb07739c3e3793e87d30c6ee450dde08653121f0d9153c8d0d",
|
||||
"sha256:d332e44a1b21ad63401cc7eebc81157e3d982d5fb503bb4faaea5028068d71e9",
|
||||
"sha256:eb770aaf637919b0011c4eb87b9ac6317079fb9800eb17c90dda05fc9de4ebc3",
|
||||
"sha256:f0895b360dccf7e2d6af8762a52985e3fbaa56778de1bf6b20dbc96134253807",
|
||||
"sha256:f7cd33602ec0f393a0058e883284496bb4dbbdd34e0bbe23b594c8933ddf9b65"
|
||||
],
|
||||
"version": "==1.2.1"
|
||||
},
|
||||
"soupsieve": {
|
||||
"hashes": [
|
||||
"sha256:49e5368c2cda80ee7e84da9dbe3e110b70a4575f196efb74e51b94549d921955",
|
||||
"sha256:e28dba9ca6c7c00173e34e4ba57448f0688bb681b7c5e8bf4971daafc093d69a"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.4"
|
||||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb",
|
||||
"sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==4.5.0"
|
||||
},
|
||||
"typing-inspect": {
|
||||
"hashes": [
|
||||
"sha256:5fbf9c1e65d4fa01e701fe12a5bca6c6e08a4ffd5bc60bfac028253a447c5188",
|
||||
"sha256:8b1ff0c400943b6145df8119c41c244ca8207f1f10c9c057aeed1560e4806e3d"
|
||||
],
|
||||
"version": "==0.8.0"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305",
|
||||
"sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
|
||||
"version": "==1.26.15"
|
||||
},
|
||||
"xmlschema": {
|
||||
"hashes": [
|
||||
"sha256:0caa96668807b4b51c42a0fe2b6610752bc59f069615df3e34dcfffb962973fd",
|
||||
"sha256:557f3632b54b6ff10576736bba62e43db84eb60f6465a83818576cd9ffcc1799"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.2.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
179
docs/README.md
Normal file
@ -0,0 +1,179 @@
|
||||
# Astro Starter Kit: Docs Site
|
||||
|
||||
```bash
|
||||
npm create astro@latest -- --template docs
|
||||
```
|
||||
|
||||
[](https://stackblitz.com/github/withastro/astro/tree/latest/examples/docs)
|
||||
[](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/docs)
|
||||
[](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/docs/devcontainer.json)
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- ✅ **Full Markdown support**
|
||||
- ✅ **Responsive mobile-friendly design**
|
||||
- ✅ **Sidebar navigation**
|
||||
- ✅ **Search (powered by Algolia)**
|
||||
- ✅ **Multi-language i18n**
|
||||
- ✅ **Automatic table of contents**
|
||||
- ✅ **Automatic list of contributors**
|
||||
- ✅ (and, best of all) **dark mode**
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :------------------------ | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:3000` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro -- --help` | Get help using the Astro CLI |
|
||||
|
||||
To deploy your site to production, check out our [Deploy an Astro Website](https://docs.astro.build/guides/deploy) guide.
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
||||
|
||||
## Customize This Theme
|
||||
|
||||
### Site metadata
|
||||
|
||||
`src/consts.ts` contains several data objects that describe metadata about your site like title, description, default language, and Open Graph details. You can customize these to match your project.
|
||||
|
||||
### CSS styling
|
||||
|
||||
The theme's look and feel is controlled by a few key variables that you can customize yourself. You'll find them in the `src/styles/theme.css` CSS file.
|
||||
|
||||
If you've never worked with CSS variables before, give [MDN's guide on CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) a quick read.
|
||||
|
||||
This theme uses a "cool blue" accent color by default. To customize this for your project, change the `--theme-accent` variable to whatever color you'd like:
|
||||
|
||||
```diff
|
||||
/* src/styles/theme.css */
|
||||
:root {
|
||||
color-scheme: light;
|
||||
- --theme-accent: hsla(var(--color-blue), 1);
|
||||
+ --theme-accent: hsla(var(--color-red), 1); /* or: hsla(#FF0000, 1); */
|
||||
```
|
||||
|
||||
## Page metadata
|
||||
|
||||
Astro uses frontmatter in Markdown pages to choose layouts and pass properties to those layouts. If you are using the default layout, you can customize the page in many different ways to optimize SEO and other things. For example, you can use the `title` and `description` properties to set the document title, meta title, meta description, and Open Graph description.
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: Example title
|
||||
description: Really cool docs example that uses Astro
|
||||
layout: ../../layouts/MainLayout.astro
|
||||
---
|
||||
|
||||
# Page content...
|
||||
```
|
||||
|
||||
For more SEO related properties, look at `src/components/HeadSEO.astro`
|
||||
|
||||
### Sidebar navigation
|
||||
|
||||
The sidebar navigation is controlled by the `SIDEBAR` variable in your `src/consts.ts` file. You can customize the sidebar by modifying this object. A default, starter navigation has already been created for you.
|
||||
|
||||
```ts
|
||||
export const SIDEBAR = {
|
||||
en: {
|
||||
'Section Header': [
|
||||
{ text: 'Introduction', link: 'en/introduction' },
|
||||
{ text: 'Page 2', link: 'en/page-2' },
|
||||
{ text: 'Page 3', link: 'en/page-3' },
|
||||
],
|
||||
'Another Section': [{ text: 'Page 4', link: 'en/page-4' }],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Note the top-level `en` key: This is needed for multi-language support. You can change it to whatever language you'd like, or add new languages as you go. More details on this below.
|
||||
|
||||
### Multiple Languages support
|
||||
|
||||
The Astro docs template supports multiple languages out of the box. The default theme only shows `en` documentation, but you can enable multi-language support features by adding a second language to your project.
|
||||
|
||||
To add a new language to your project, you'll want to extend the current `src/content/docs/[lang]/...` layout:
|
||||
|
||||
```diff
|
||||
📂 src/content/docs
|
||||
┣ 📂 en
|
||||
┃ ┣ 📜 page-1.md
|
||||
┃ ┣ 📜 page-2.md
|
||||
┃ ┣ 📜 page-3.astro
|
||||
+ ┣ 📂 es
|
||||
+ ┃ ┣ 📜 page-1.md
|
||||
+ ┃ ┣ 📜 page-2.md
|
||||
+ ┃ ┣ 📜 page-3.astro
|
||||
```
|
||||
|
||||
You'll also need to add the new language name to the `KNOWN_LANGUAGES` map in your `src/consts.ts` file. This will enable your new language switcher in the site header.
|
||||
|
||||
```diff
|
||||
// src/consts.ts
|
||||
export const KNOWN_LANGUAGES = {
|
||||
English: 'en',
|
||||
+ Spanish: 'es',
|
||||
};
|
||||
```
|
||||
|
||||
Last step: you'll need to add a new entry to your sidebar, to create the table of contents for that language. While duplicating every page might not sound ideal to everyone, this extra control allows you to create entirely custom content for every language.
|
||||
|
||||
> Make sure the sidebar `link` value points to the correct language!
|
||||
|
||||
```diff
|
||||
// src/consts.ts
|
||||
export const SIDEBAR = {
|
||||
en: {
|
||||
'Section Header': [
|
||||
{ text: 'Introduction', link: 'en/introduction' },
|
||||
// ...
|
||||
],
|
||||
// ...
|
||||
},,
|
||||
+ es: {
|
||||
+ 'Encabezado de sección': [
|
||||
+ { text: 'Introducción', link: 'en/introduction' },
|
||||
+ // ...
|
||||
+ ],
|
||||
+ // ...
|
||||
+ },
|
||||
};
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
If you plan to use Spanish as the default language, you just need to modify the redirect path in `src/pages/index.astro`:
|
||||
|
||||
```diff
|
||||
<script>
|
||||
- window.location.pathname = `/en/introduction`;
|
||||
+ window.location.pathname = `/es/introduction`;
|
||||
</script>
|
||||
```
|
||||
|
||||
You can also remove the above script and write a landing page in Spanish instead.
|
||||
|
||||
### What if I don't plan to support multiple languages?
|
||||
|
||||
That's totally fine! Not all projects need (or can support) multiple languages. You can continue to use this theme without ever adding a second language.
|
||||
|
||||
If that single language is not English, you can just replace `en` in directory layouts and configurations with the preferred language.
|
||||
|
||||
### Search (Powered by Algolia)
|
||||
|
||||
[Algolia](https://www.algolia.com/) offers a free service to qualified open source projects called [DocSearch](https://docsearch.algolia.com/). If you are accepted to the DocSearch program, provide your API Key & index name in `src/consts.ts` and a search box will automatically appear in your site header.
|
||||
|
||||
Note that Algolia and Astro are not affiliated. We have no say over acceptance to the DocSearch program.
|
||||
|
||||
If you'd prefer to remove Algolia's search and replace it with your own, check out the `src/components/Header.astro` component to see where the component is added.
|
||||
@ -1,41 +0,0 @@
|
||||
# Setup to build docs
|
||||
|
||||
## Requirements
|
||||
- Python 3.10
|
||||
|
||||
## Clone the repo
|
||||
Clone the entire repo and navigate to the docs folder
|
||||
```shell
|
||||
git clone https://github.com/xen-42/outer-wilds-new-horizons
|
||||
cd outer-wilds-new-horizons/docs
|
||||
```
|
||||
|
||||
## Setup Pipenv
|
||||
Install pipenv if you haven't already
|
||||
```shell
|
||||
pip install --user pipenv
|
||||
```
|
||||
Install dependencies
|
||||
```shell
|
||||
pipenv install --dev
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
- URL_PREFIX: Path to put before all links and static files, see below for recommended values
|
||||
- Production and Local Builds: "/"
|
||||
- PyCharm Development Server: "/outer-wilds-new-horizons/docs/out/"
|
||||
|
||||
## Copy Schemas
|
||||
Create a folder called `schemas` in the `docs/content/pages/` folder and copy all schemas to generate into it, make sure not to add this folder to git.
|
||||
Production build automatically copies over schemas.
|
||||
|
||||
## Generating
|
||||
Run `generate` with pipenv
|
||||
```shell
|
||||
pipenv run menagerie generate
|
||||
```
|
||||
|
||||
## Opening
|
||||
- Production: Go to the site
|
||||
- Local: Go into `docs/out` in a new terminal window and run `py -m http.server 8080` and then connect to http://localhost:8080/
|
||||
- PyCharm Development Server: Right click `out/index.html` -> Open In -> Browser -> Default
|
||||
14
docs/astro.config.mjs
Normal file
@ -0,0 +1,14 @@
|
||||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
import react from '@astrojs/react';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [
|
||||
// Enable Preact to support Preact JSX components.
|
||||
preact(),
|
||||
// Enable React for the Algolia search component.
|
||||
react(),
|
||||
],
|
||||
site: `https://astro.build`,
|
||||
});
|
||||
@ -1,72 +0,0 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/Bwc9876/menagerie/master/menagerie/schemas/config_schema.json",
|
||||
"cache_enabled": false,
|
||||
"base_url": "https://nh.outerwildsmods.com/",
|
||||
"themes": {
|
||||
"bootstrap": "https://bootswatch.com/5/darkly/bootstrap.min.css",
|
||||
"highlight_js": "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/styles/github-dark-dimmed.min.css",
|
||||
"theme": "dark"
|
||||
},
|
||||
"styles": {
|
||||
"base": "styles/nh_base.css"
|
||||
},
|
||||
"search": {
|
||||
"enabled": false,
|
||||
"site": "nh.outerwildsmods.com"
|
||||
},
|
||||
"brand": {
|
||||
"app_name": "New Horizons",
|
||||
"favicon_folder": "fav/",
|
||||
"navbar_icon": "images/icon.webp",
|
||||
"navbar_icon_size": [
|
||||
29,
|
||||
29
|
||||
],
|
||||
"socials": [
|
||||
{
|
||||
"name": "Discord",
|
||||
"link": "https://discord.gg/wusTQYbYTc",
|
||||
"icon": "discord"
|
||||
},
|
||||
{
|
||||
"name": "GitHub",
|
||||
"link": "https://github.com/xen-42/outer-wilds-new-horizons",
|
||||
"icon": "github"
|
||||
},
|
||||
{
|
||||
"name": "Patreon",
|
||||
"link": "https://patreon.com/ownh",
|
||||
"icon": "coin"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"search_console_code": "SafYg2zgXPfpW4MZbkBTpAtuNs5W7N-upr08Kv6tyMo",
|
||||
"description": "Documentation on how to use the New Horizons planet creation tool for Outer Wilds.",
|
||||
"keywords": [
|
||||
"New Horizons",
|
||||
"Outer Wilds",
|
||||
"Modding",
|
||||
"C#",
|
||||
"Unity"
|
||||
],
|
||||
"categories": [
|
||||
"games",
|
||||
"utilities"
|
||||
],
|
||||
"image": "images/home/home_logo.webp",
|
||||
"image_alt": "The New Horizons Logo",
|
||||
"theme_color": "#ffab8a",
|
||||
"bg_color": "#1a1a1a"
|
||||
},
|
||||
"footer": {
|
||||
"show_made_with": false,
|
||||
"links": [
|
||||
{
|
||||
"link": "https://github.com/xen-42/outer-wilds-new-horizons/issues/new/choose",
|
||||
"text": "Report an issue",
|
||||
"external": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
---
|
||||
Title: Page not Found
|
||||
Hide_In_Nav: True
|
||||
Render_TOC: False
|
||||
---
|
||||
|
||||
# Page Not Found
|
||||
|
||||
The page you requested could not be found.
|
||||
|
||||
@ -1,65 +0,0 @@
|
||||
---
|
||||
Title: Config Editor
|
||||
Sort_Priority: 50
|
||||
---
|
||||
|
||||
# Config Editor
|
||||
|
||||
Are you tired of manually editing JSON? Do you want richer validation than a JSON schema? Well then the config editor may be for you!
|
||||
|
||||
This page outlines how to install and use the config editor.
|
||||
|
||||
## Installation
|
||||
|
||||
To get started, head over to the [releases page for the editor](https://github.com/Outer-Wilds-New-Horizons/nh-config-editor/releases/latest) and install the file for your OS:
|
||||
|
||||
- Windows: The .msi file (not the .msi.zip and .msi.zip.sig file)
|
||||
- MacOS: The .AppImage file (not the .AppImage.tar.gz or the .AppImage.tar.gz.sig file)
|
||||
|
||||
Follow the installer instructions to complete setup
|
||||
|
||||
## Creating a New Project
|
||||
|
||||
Creating a new project is as simple as clicking the button.
|
||||
Fill out the form with thr info for your mod and a new project will be made at the specified path.
|
||||
|
||||
## Editing Files
|
||||
|
||||
To edit a file, navigate to it in the left panel and click on it.
|
||||
|
||||
### JSON files
|
||||
|
||||
JSON files (planets, systems, etc) have a graphical interface for editing, **this will clear comments!**
|
||||
|
||||
If you don't want comments to be cleared, use the text editor
|
||||
|
||||
#### Using the Text Editor
|
||||
|
||||
Already familiar with JSON and prefer text-based editing? Simply open up settings (File -> Settings) and turn on the "Always use Text Editor" option.
|
||||
|
||||
### Image and Audio Files
|
||||
|
||||
You can view images and play audio files with this editor.
|
||||
|
||||
### XML Files
|
||||
|
||||
Right now, XML support is limited. You'll get syntax highlighting but no error checking or autofill.
|
||||
|
||||
|
||||
## Running the Game
|
||||
|
||||
You can start the game from the editor by selecting Project -> Run Project this will open a new window where you can run the game
|
||||
|
||||
### Log Port
|
||||
|
||||
If you're using the mod manager and would like logs to appear there, you need to get the log port from the console, it's always the first entry in the logs. Keep in mind this port changes whenever you restart the manager.
|
||||
|
||||

|
||||
|
||||
|
||||
## Building
|
||||
|
||||
The editor also provides a system for building your mod to a zip file, which can then be uploaded to GitHub in a release. To do this, press Project -> Build (Release)
|
||||
|
||||
|
||||
|
||||
@ -1,88 +0,0 @@
|
||||
{#~ Title:FAQ ~#}
|
||||
{#~ Sort_Priority:95 ~#}
|
||||
{#~ Render_TOC:False ~#}
|
||||
|
||||
|
||||
{% macro faq(id, q, a) %}
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button id="{{ id }}-heading" class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ id }}" aria-expanded="false" aria-controls="{{ id }}">
|
||||
Q: {{ q }}
|
||||
</button>
|
||||
</h2>
|
||||
<div id="{{ id }}" class="accordion-collapse collapse" aria-labelledby="{{ id }}-heading" data-bs-parent="#accordionFAQ">
|
||||
<div class="accordion-body">
|
||||
{{ ("A: " + a)|simple_md|replace('<p>', '<p class="my-0 ms-2">')|safe }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
<h1 class="text-center pb-2">FAQ</h1>
|
||||
|
||||
<div class="accordion" id="accordionFAQ">
|
||||
{{
|
||||
faq(
|
||||
"is-easy",
|
||||
"How easy is it to make a planet mod?",
|
||||
"Easy, you don't even need to know how to code! Just start off slowly and make a single planet with a few surface details. Don't try to make a full DLC-scale story mod on your first try."
|
||||
)
|
||||
}}
|
||||
{{
|
||||
faq(
|
||||
"model-whole-planet",
|
||||
"Can I model my entire planet in Blender and put it into the game?",
|
||||
"Yes! Follow the instructions on the Detailing page. All you have to do is add that model as a single detail prop at the center of the planet."
|
||||
)
|
||||
}}
|
||||
{{
|
||||
faq(
|
||||
"why-no-planet",
|
||||
"Why doesn't my planet show up in game?",
|
||||
"Have you checked the logs for errors? Are you using a program like [VSCode](https://code.visualstudio.com/){ target='_blank' } to write your configs that validates them against our schema to catch your errors? Do you incrementally test each new planet that you add, or did you write 10 json files and then try them all at once? If you're still not sure, come by our [Discord channel](https://discord.gg/wusTQYbYTc){ target='_blank' } (`#nh-addon-discussion`) and we'll try to help out!"
|
||||
)
|
||||
}}
|
||||
{{
|
||||
faq(
|
||||
"ui-program",
|
||||
"Will you make a UI program to generate json files in the future?",
|
||||
"Yes! It's available [on GitHub](https://github.com/Outer-Wilds-New-Horizons/nh-config-editor){ target='_blank' }."
|
||||
)
|
||||
}}
|
||||
{{
|
||||
faq(
|
||||
"when-version-1",
|
||||
"When will New Horizons get to version 1.0.0.",
|
||||
"It already did **BOZO**!!!!!"
|
||||
)
|
||||
}}
|
||||
{{
|
||||
faq(
|
||||
"feature-request",
|
||||
"When will (*insert feature request here*) be implemented into New Horizons?",
|
||||
"If it's on the road-map, eventually. If it's not on the road-map let us know and we'll see if it's something we can consider adding."
|
||||
)
|
||||
}}
|
||||
{{
|
||||
faq(
|
||||
"i-dont-use-reload-configs",
|
||||
"It takes so long to test my mod because I keep having to restart my game whenever I change something in a config.",
|
||||
"That's not a question. But go into your mod settings in game and enable Debug mode on New Horizons. Now there will be a “Reload Configs” button in your options screen that will reload all your planets without restarting your game!"
|
||||
)
|
||||
}}
|
||||
{{
|
||||
faq(
|
||||
"rails",
|
||||
"Will you ditch the physics simulation and instead track planet positions on their orbits as a function of time, effectively putting the planets on rails and thereby making the game more efficient and accurate at the expense of the game's original vision as being an actual simulation of orbital mechanics?",
|
||||
"**No.**"
|
||||
)
|
||||
}}
|
||||
{{
|
||||
faq(
|
||||
"jammer",
|
||||
"Will Jammer Be Added?",
|
||||
"Yes! Check **your front door**"
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"$schema": "https://github.com/Bwc9876/menagerie/raw/master/menagerie/schemas/folder_schema.json",
|
||||
"sort_priority": 15
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
---
|
||||
Title: Bramble Colors
|
||||
Render_TOC: False
|
||||
---
|
||||
|
||||
| Dimension | Fog color | Node fog color |
|
||||
|-------------|------------------------------------------|------------------------------------------|
|
||||
| Cluster | {"r": 126, "g": 119, "b": 101, "a": 255} | {"r": 255, "g": 245, "b": 217, "a": 255} |
|
||||
| Vessel | {"r": 206, "g": 187, "b": 137, "a": 255} | {"r": 191, "g": 171, "b": 133, "a": 255} |
|
||||
| Small Nest | {"r": 131, "g": 128, "b": 121, "a": 255} | {"r": 255, "g": 245, "b": 217, "a": 255} |
|
||||
| Pioneer | {"r": 106, "g": 116, "b": 99, "a": 255} | {"r": 255, "g": 245, "b": 217, "a": 255} |
|
||||
| Hub | {"r": 84, "g": 83, "b": 73, "a": 255} | {"r": 84, "g": 83, "b": 73, "a": 255} |
|
||||
| Exit Only | {"r": 113, "g": 107, "b": 81, "a": 255} | {"r": 255, "g": 245, "b": 217, "a": 255} |
|
||||
| Escape Pod | {"r": 83, "g": 99, "b": 87, "a": 255} | {"r": 255, "g": 245, "b": 217, "a": 255} |
|
||||
| Angler Nest | {"r": 113, "g": 107, "b": 81, "a": 255} | {"r": 255, "g": 129, "b": 83, "a": 255} |
|
||||
@ -1,25 +0,0 @@
|
||||
---
|
||||
Title: Hidden Page
|
||||
Description: Hehe funny secret
|
||||
Hide_In_Nav: True
|
||||
---
|
||||
|
||||
# Hello!!
|
||||
|
||||
Uh idk what to put here thought it would be funny haha
|
||||
|
||||

|
||||
|
||||
## It's Morbin' Time
|
||||
|
||||

|
||||
|
||||
## Test
|
||||
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
|
||||
## 9/2/22
|
||||
|
||||
Where were you when new horizons docs died, im going gorbo mode
|
||||
|
||||
|
||||
@ -1,84 +0,0 @@
|
||||
---
|
||||
Title: Reading Schemas
|
||||
Sort_Priority: 90
|
||||
---
|
||||
|
||||
# Reading Schema Pages
|
||||
|
||||
Reading and understanding the schema pages are key to knowing how to create planets. While these tutorials may be helpful, they won't cover everything, and new features may be added before the tutorial on them can be written.
|
||||
|
||||
## Celestial Body Schema
|
||||
|
||||
The [celestial body schema]({{ "Celestial Body Schema"|route }}) is the schema for making planets, there are other schemas which will be explained later but for now let's focus on this one.
|
||||
|
||||

|
||||
|
||||
As you can see the type of this is `object`, which we talked about in the previous section.
|
||||
We can also observe a blue badge that says "No Additional Properties", this signifies that you can't add keys to the object that aren't in the schema, for example:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Wetrock",
|
||||
"coolKey": "Look at my cool key!"
|
||||
}
|
||||
```
|
||||
|
||||
Will result in a warning in VSCode. Now, this will *not* prevent the planet from being loaded, however you should still avoid doing it.
|
||||
|
||||
## Simple Properties
|
||||
|
||||

|
||||
|
||||
Next up let's look at `name`, this field is required, meaning you *have* to have it for a planet to load.
|
||||
When we click on name we first see a breadcrumb, this is essentially a guide of where you are in the schema, right now we're in the name property of the root (topmost) object.
|
||||
We can also see it's description, its type is `string`, and that it requires at least one character (so you can't just put `""`).
|
||||
|
||||
Badges can also show stuff such as the default value, the minimum and maximum values, and more.
|
||||
|
||||
## Object Properties
|
||||
|
||||

|
||||
|
||||
Next let's look at an `object` within our root `object`, let's use `Base` as the example.
|
||||
|
||||
Here we can see it's similar to our root object, in that it doesn't allow additional properties.
|
||||
We can also see all of its properties listed out.
|
||||
|
||||
## Array Properties
|
||||
|
||||
Now let's take a look over at [removeChildren]({{ "Celestial Body Schema"|route }}#removeChildren) to see how arrays work (if you're wondering how you can get the page to scroll to a specific property, simply click on the property and copy the URL in your URL bar)
|
||||
|
||||

|
||||
|
||||
Here we can see that the type is an `array`, and each item in this array must be a `string`
|
||||
|
||||
## Enum Properties
|
||||
|
||||
Enum properties simply mean that they must be of one of the values shown, for example [Ring fluid type]({{ "Celestial Body Schema"|route }}#Ring_fluidType) has to be one of these values.
|
||||
|
||||

|
||||
|
||||
## Some Vocabulary
|
||||
|
||||
- GameObject: Essentially just any object in, well, the game. You can view these object in a tree-like structure with the [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer) mod. Every GameObject has a path, which is sort of like a file path in that it's a list of parent GameObjects seperated by forward slashes followed by the GameObject's name.
|
||||
- Component: By themselves, a GameObject doesn't actually *do* anything, components provide stuff like collision, rendering, and logistics to GameObjects
|
||||
- Config: Just another name for a JSON file "planet config" simply means a json file that describes a planet
|
||||
- Module: A specific section of the config (e.g. Base, Atmosphere, etc), these usually start with capital letters
|
||||
|
||||
## Note About File Paths
|
||||
|
||||
Whenever a description refers to the "relative path" of a file, it means relative to the mod's directory, this means you **must** include the `planets` folder in the path:
|
||||
|
||||
```json
|
||||
"planets/assets/images/MyCoolImage.png"
|
||||
```
|
||||
|
||||
## Other Schemas
|
||||
|
||||
There are other schemas available, some are for JSON, and some are for XML.
|
||||
|
||||
## Moving Forward
|
||||
|
||||
Now that you know how to read the schema pages, you can understand the rest of this site. A lot of the other tutorials here will often tell you to take a look at schemas to explain what certain properties do.
|
||||
|
||||
**Next Up: [Creating An Addon]({{ "Creating An Addon"|route }})**
|
||||
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 15 KiB |
@ -1,54 +0,0 @@
|
||||
pre > code {
|
||||
background-color: #1a1a1a !important;
|
||||
border-radius: .25rem !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--bs-dark);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--bs-secondary);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #555;
|
||||
}
|
||||
|
||||
.accordion-button {
|
||||
background-color: #2b2b2b !important;
|
||||
}
|
||||
|
||||
.accordion-button:not(.collapsed)::after {
|
||||
color: #effff7 !important;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
|
||||
}
|
||||
|
||||
.accordion-item {
|
||||
border: 1px solid rgba(0, 0, 0, 0.4) !important;
|
||||
}
|
||||
|
||||
.accordion-button:not(.collapsed) {
|
||||
color: #effff7;
|
||||
background-color: #2b2b2b;
|
||||
}
|
||||
|
||||
.accordion-button:not(.collapsed)::after {
|
||||
color: #effff7;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
|
||||
}
|
||||
|
||||
.accordion-item {
|
||||
border: 1px solid rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.accordion-body {
|
||||
background-color: #353535 !important;
|
||||
}
|
||||
36
docs/package.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "docs",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@algolia/client-search": "^4.17.0",
|
||||
"@apidevtools/json-schema-ref-parser": "^10.1.0",
|
||||
"@astrojs/preact": "^2.2.1",
|
||||
"@astrojs/react": "^2.2.1",
|
||||
"@docsearch/css": "^3.3.4",
|
||||
"@docsearch/react": "^3.3.4",
|
||||
"@types/node": "^18.16.3",
|
||||
"@types/react": "^18.2.5",
|
||||
"@types/react-dom": "^18.2.3",
|
||||
"astro": "^2.5.6",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"fast-xml-parser": "^4.2.3",
|
||||
"preact": "^10.13.2",
|
||||
"prettier": "^2.8.8",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"xml-js": "^1.6.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.8",
|
||||
"html-escaper": "^3.0.3"
|
||||
}
|
||||
}
|
||||
4178
docs/pnpm-lock.yaml
generated
Normal file
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 660 B After Width: | Height: | Size: 660 B |
3
docs/public/make-scrollable-code-focusable.js
Normal file
@ -0,0 +1,3 @@
|
||||
Array.from(document.getElementsByTagName('pre')).forEach((element) => {
|
||||
element.setAttribute('tabindex', '0');
|
||||
});
|
||||
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
175
docs/src/components/Footer/AvatarList.astro
Normal file
@ -0,0 +1,175 @@
|
||||
---
|
||||
// fetch all commits for just this page's path
|
||||
type Props = {
|
||||
path: string;
|
||||
};
|
||||
const { path } = Astro.props;
|
||||
const resolvedPath = `docs/${path}`;
|
||||
const url = `https://api.github.com/repos/Outer-Wilds-New-Horizons/new-horizons/commits?path=${resolvedPath}`;
|
||||
const commitsURL = `https://github.com/Outer-Wilds-New-Horizons/new-horizons/commits/main/${resolvedPath}`;
|
||||
|
||||
type Commit = {
|
||||
author: {
|
||||
id: string;
|
||||
login: string;
|
||||
};
|
||||
};
|
||||
|
||||
async function getCommits(url: string) {
|
||||
try {
|
||||
const token = import.meta.env.GITHUB_TOKEN ?? "hello";
|
||||
if (!token) {
|
||||
throw new Error('Cannot find "GITHUB_TOKEN" used for escaping rate-limiting.');
|
||||
}
|
||||
|
||||
const auth = `Basic ${Buffer.from(token, "binary").toString("base64")}`;
|
||||
|
||||
const res = await fetch(url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: auth,
|
||||
"User-Agent": "astro-docs/1.0"
|
||||
}
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(
|
||||
`Request to fetch commits failed. Reason: ${res.statusText}
|
||||
Message: ${data.message}`
|
||||
);
|
||||
}
|
||||
|
||||
return data as Commit[];
|
||||
} catch (e) {
|
||||
console.warn(`[error] /src/components/AvatarList.astro
|
||||
${(e as any)?.message ?? e}`);
|
||||
return [] as Commit[];
|
||||
}
|
||||
}
|
||||
|
||||
function removeDups(arr: Commit[]) {
|
||||
const map = new Map<string, Commit["author"]>();
|
||||
|
||||
for (let item of arr) {
|
||||
const author = item.author;
|
||||
// Deduplicate based on author.id
|
||||
map.set(author.id, { login: author.login, id: author.id });
|
||||
}
|
||||
|
||||
return [...map.values()];
|
||||
}
|
||||
|
||||
const data = await getCommits(url);
|
||||
const unique = removeDups(data);
|
||||
const recentContributors = unique.slice(0, 3); // only show avatars for the 3 most recent contributors
|
||||
const additionalContributors = unique.length - recentContributors.length; // list the rest of them as # of extra contributors
|
||||
---
|
||||
|
||||
<!-- Thanks to @5t3ph for https://smolcss.dev/#smol-avatar-list! -->
|
||||
<div class="contributors">
|
||||
<ul class="avatar-list" style={`--avatar-count: ${recentContributors.length}`}>
|
||||
{
|
||||
recentContributors.map((item) => (
|
||||
<li>
|
||||
<a href={`https://github.com/${item.login}`}>
|
||||
<img
|
||||
alt={`Contributor ${item.login}`}
|
||||
title={`Contributor ${item.login}`}
|
||||
width="64"
|
||||
height="64"
|
||||
src={`https://avatars.githubusercontent.com/u/${item.id}`}
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
{
|
||||
additionalContributors > 0 && (
|
||||
<span>
|
||||
<a href={commitsURL}>{`and ${additionalContributors} additional contributor${
|
||||
additionalContributors > 1 ? "s" : ""
|
||||
}.`}</a>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
{unique.length === 0 && <a href={commitsURL}>Contributors</a>}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.avatar-list {
|
||||
--avatar-size: 2.5rem;
|
||||
--avatar-count: 3;
|
||||
|
||||
display: grid;
|
||||
list-style: none;
|
||||
/* Default to displaying most of the avatar to
|
||||
enable easier access on touch devices, ensuring
|
||||
the WCAG touch target size is met or exceeded */
|
||||
grid-template-columns: repeat(
|
||||
var(--avatar-count),
|
||||
max(44px, calc(var(--avatar-size) / 1.15))
|
||||
);
|
||||
/* `padding` matches added visual dimensions of
|
||||
the `box-shadow` to help create a more accurate
|
||||
computed component size */
|
||||
padding: 0.08em;
|
||||
font-size: var(--avatar-size);
|
||||
}
|
||||
|
||||
@media (any-hover: hover) and (any-pointer: fine) {
|
||||
.avatar-list {
|
||||
/* We create 1 extra cell to enable the computed
|
||||
width to match the final visual width */
|
||||
grid-template-columns: repeat(
|
||||
calc(var(--avatar-count) + 1),
|
||||
calc(var(--avatar-size) / 1.75)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-list li {
|
||||
width: var(--avatar-size);
|
||||
height: var(--avatar-size);
|
||||
}
|
||||
|
||||
.avatar-list li:hover ~ li a,
|
||||
.avatar-list li:focus-within ~ li a {
|
||||
transform: translateX(33%);
|
||||
}
|
||||
|
||||
.avatar-list img,
|
||||
.avatar-list a {
|
||||
display: block;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.avatar-list a {
|
||||
transition: transform 180ms ease-in-out;
|
||||
}
|
||||
|
||||
.avatar-list img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 0 0.05em #fff, 0 0 0 0.08em rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.avatar-list a:focus {
|
||||
outline: 2px solid transparent;
|
||||
/* Double-layer trick to work for dark and light backgrounds */
|
||||
box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white;
|
||||
}
|
||||
|
||||
.contributors {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.contributors > * + * {
|
||||
margin-left: 0.75rem;
|
||||
}
|
||||
</style>
|
||||
19
docs/src/components/Footer/Footer.astro
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
import AvatarList from './AvatarList.astro';
|
||||
type Props = {
|
||||
path: string;
|
||||
};
|
||||
const { path } = Astro.props;
|
||||
---
|
||||
|
||||
<footer>
|
||||
<AvatarList path={path} />
|
||||
</footer>
|
||||
|
||||
<style>
|
||||
footer {
|
||||
margin-top: auto;
|
||||
padding: 2rem;
|
||||
border-top: 3px solid var(--theme-divider);
|
||||
}
|
||||
</style>
|
||||
44
docs/src/components/HeadCommon.astro
Normal file
@ -0,0 +1,44 @@
|
||||
---
|
||||
import "../styles/theme.css";
|
||||
import "../styles/index.css";
|
||||
---
|
||||
|
||||
<!-- Global Metadata -->
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
|
||||
<link rel="sitemap" href="/sitemap.xml" />
|
||||
|
||||
<!-- Preload Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital@0;1&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<!-- Scrollable a11y code helper -->
|
||||
<script src="/make-scrollable-code-focusable.js" is:inline></script>
|
||||
|
||||
<!-- This is intentionally inlined to avoid FOUC -->
|
||||
<script is:inline>
|
||||
const root = document.documentElement;
|
||||
const theme = localStorage.getItem("theme");
|
||||
if (theme === "dark" || (!theme && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
|
||||
root.classList.add("theme-dark");
|
||||
} else {
|
||||
root.classList.remove("theme-dark");
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<!-- <script async src="https://www.googletagmanager.com/gtag/js?id=G-TEL60V1WM9" is:inline></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'G-TEL60V1WM9');
|
||||
</script> -->
|
||||
39
docs/src/components/HeadSEO.astro
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import { SITE, OPEN_GRAPH } from "../consts";
|
||||
|
||||
type Props = { canonicalUrl: URL } & CollectionEntry<"docs">["data"];
|
||||
|
||||
const { ogLocale, image, title, description, canonicalUrl } = Astro.props;
|
||||
const formattedContentTitle = `${title} 🚀 ${SITE.title}`;
|
||||
const imageSrc = image?.src ?? OPEN_GRAPH.image.src;
|
||||
const canonicalImageSrc = new URL(imageSrc, Astro.site);
|
||||
const imageAlt = image?.alt ?? OPEN_GRAPH.image.alt;
|
||||
---
|
||||
|
||||
<!-- Page Metadata -->
|
||||
<link rel="canonical" href={canonicalUrl} />
|
||||
|
||||
<!-- OpenGraph Tags -->
|
||||
<meta property="og:title" content={formattedContentTitle} />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content={canonicalUrl} />
|
||||
<meta property="og:locale" content={ogLocale ?? SITE.defaultLanguage} />
|
||||
<meta property="og:image" content={canonicalImageSrc} />
|
||||
<meta property="og:image:alt" content={imageAlt} />
|
||||
<meta name="description" property="og:description" content={description ?? SITE.description} />
|
||||
<meta property="og:site_name" content={SITE.title} />
|
||||
|
||||
<!-- Twitter Tags -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={formattedContentTitle} />
|
||||
<meta name="twitter:description" content={description ?? SITE.description} />
|
||||
<meta name="twitter:image" content={canonicalImageSrc} />
|
||||
<meta name="twitter:image:alt" content={imageAlt} />
|
||||
|
||||
<!--
|
||||
TODO: Add json+ld data, maybe https://schema.org/APIReference makes sense?
|
||||
Docs: https://developers.google.com/search/docs/advanced/structured-data/intro-structured-data
|
||||
https://www.npmjs.com/package/schema-dts seems like a great resource for implementing this.
|
||||
Even better, there's a React component that integrates with `schema-dts`: https://github.com/google/react-schemaorg
|
||||
-->
|
||||
8
docs/src/components/Header/AstroLogo.astro
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
type Props = {
|
||||
size: number;
|
||||
};
|
||||
const { size } = Astro.props;
|
||||
---
|
||||
|
||||
<img src="/icon.webp" width="40" height="40" />
|
||||
149
docs/src/components/Header/Header.astro
Normal file
@ -0,0 +1,149 @@
|
||||
---
|
||||
import { getLanguageFromURL, KNOWN_LANGUAGE_CODES } from '../../languages';
|
||||
import { SITE } from '../../consts';
|
||||
import AstroLogo from './AstroLogo.astro';
|
||||
import SkipToContent from './SkipToContent.astro';
|
||||
import SidebarToggle from './SidebarToggle';
|
||||
import LanguageSelect from './LanguageSelect';
|
||||
import Search from './Search';
|
||||
|
||||
type Props = {
|
||||
currentPage: string;
|
||||
};
|
||||
|
||||
const { currentPage } = Astro.props;
|
||||
const lang = getLanguageFromURL(currentPage);
|
||||
---
|
||||
|
||||
<header>
|
||||
<SkipToContent />
|
||||
<nav class="nav-wrapper" title="Top Navigation">
|
||||
<div class="menu-toggle">
|
||||
<SidebarToggle client:idle />
|
||||
</div>
|
||||
<div class="logo flex">
|
||||
<a href="/">
|
||||
<AstroLogo size={40} />
|
||||
<h1>{SITE.title ?? 'Documentation'}</h1>
|
||||
</a>
|
||||
</div>
|
||||
<div style="flex-grow: 1;"></div>
|
||||
{KNOWN_LANGUAGE_CODES.length > 1 && <LanguageSelect lang={lang} client:idle />}
|
||||
<div class="search-item">
|
||||
<Search client:idle />
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<style>
|
||||
header {
|
||||
z-index: 11;
|
||||
height: var(--theme-navbar-height);
|
||||
width: 100%;
|
||||
background-color: var(--theme-navbar-bg);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
width: 30px;
|
||||
font-size: 2rem;
|
||||
flex-shrink: 0;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
color: hsla(var(--color-base-white), 100%, 1);
|
||||
gap: 0.25em;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.logo a {
|
||||
display: flex;
|
||||
padding: 0.5em 0.25em;
|
||||
margin: -0.5em -0.25em;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.logo a {
|
||||
transition: color 100ms ease-out;
|
||||
color: var(--theme-text);
|
||||
}
|
||||
|
||||
.logo a:hover,
|
||||
.logo a:focus {
|
||||
color: var(--theme-text-accent);
|
||||
}
|
||||
|
||||
.logo h1 {
|
||||
display: none;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 1em;
|
||||
width: 100%;
|
||||
max-width: 82em;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
@media (min-width: 50em) {
|
||||
header {
|
||||
position: static;
|
||||
padding: 2rem 0rem;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: auto;
|
||||
margin: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.logo h1 {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/** Style Algolia */
|
||||
:root {
|
||||
--docsearch-primary-color: var(--theme-accent);
|
||||
--docsearch-logo-color: var(--theme-text);
|
||||
}
|
||||
|
||||
.search-item {
|
||||
display: none;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
flex-grow: 1;
|
||||
padding-right: 0.7rem;
|
||||
display: flex;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
@media (min-width: 50em) {
|
||||
.search-item {
|
||||
max-width: 400px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style is:global>
|
||||
.search-item > * {
|
||||
flex-grow: 1;
|
||||
}
|
||||
</style>
|
||||
47
docs/src/components/Header/LanguageSelect.css
Normal file
@ -0,0 +1,47 @@
|
||||
.language-select {
|
||||
flex-grow: 1;
|
||||
width: 48px;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0.33em 0.5em;
|
||||
overflow: visible;
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
font-family: inherit;
|
||||
line-height: inherit;
|
||||
background-color: var(--theme-bg);
|
||||
border-color: var(--theme-text-lighter);
|
||||
color: var(--theme-text-light);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 0.25rem;
|
||||
outline: 0;
|
||||
cursor: pointer;
|
||||
transition-timing-function: ease-out;
|
||||
transition-duration: 0.2s;
|
||||
transition-property: border-color, color;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
padding-left: 30px;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.language-select-wrapper .language-select:hover,
|
||||
.language-select-wrapper .language-select:focus {
|
||||
color: var(--theme-text);
|
||||
border-color: var(--theme-text-light);
|
||||
}
|
||||
.language-select-wrapper {
|
||||
color: var(--theme-text-light);
|
||||
position: relative;
|
||||
}
|
||||
.language-select-wrapper > svg {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
left: 10px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (min-width: 50em) {
|
||||
.language-select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
49
docs/src/components/Header/LanguageSelect.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
/** @jsxImportSource react */
|
||||
import type { FunctionComponent } from 'react';
|
||||
import './LanguageSelect.css';
|
||||
import { KNOWN_LANGUAGES, langPathRegex } from '../../languages';
|
||||
|
||||
const LanguageSelect: FunctionComponent<{ lang: string }> = ({ lang }) => {
|
||||
return (
|
||||
<div className="language-select-wrapper">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 88.6 77.3"
|
||||
height="1.2em"
|
||||
width="1.2em"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M61,24.6h7.9l18.7,51.6h-7.7l-5.4-15.5H54.3l-5.6,15.5h-7.2L61,24.6z M72.6,55l-8-22.8L56.3,55H72.6z"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M53.6,60.6c-10-4-16-9-22-14c0,0,1.3,1.3,0,0c-6,5-20,13-20,13l-4-6c8-5,10-6,19-13c-2.1-1.9-12-13-13-19h8 c4,9,10,14,10,14c10-8,10-19,10-19h8c0,0-1,13-12,24l0,0c5,5,10,9,19,13L53.6,60.6z M1.6,16.6h56v-8h-23v-7h-9v7h-24V16.6z"
|
||||
/>
|
||||
</svg>
|
||||
<select
|
||||
className="language-select"
|
||||
value={lang}
|
||||
onChange={(e) => {
|
||||
const newLang = e.target.value;
|
||||
let actualDest = window.location.pathname.replace(langPathRegex, '/');
|
||||
if (actualDest == '/') actualDest = `/introduction`;
|
||||
window.location.pathname = '/' + newLang + actualDest;
|
||||
}}
|
||||
>
|
||||
{Object.entries(KNOWN_LANGUAGES).map(([key, value]) => {
|
||||
return (
|
||||
<option value={value} key={value}>
|
||||
{key}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LanguageSelect;
|
||||
75
docs/src/components/Header/Search.css
Normal file
@ -0,0 +1,75 @@
|
||||
/** Style Algolia */
|
||||
:root {
|
||||
--docsearch-primary-color: var(--theme-accent);
|
||||
--docsearch-logo-color: var(--theme-text);
|
||||
}
|
||||
.search-input {
|
||||
flex-grow: 1;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0.33em 0.5em;
|
||||
overflow: visible;
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
font-family: inherit;
|
||||
line-height: inherit;
|
||||
background-color: var(--theme-divider);
|
||||
border-color: var(--theme-divider);
|
||||
color: var(--theme-text-light);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 0.25rem;
|
||||
outline: 0;
|
||||
cursor: pointer;
|
||||
transition-timing-function: ease-out;
|
||||
transition-duration: 0.2s;
|
||||
transition-property: border-color, color;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
.search-input:hover,
|
||||
.search-input:focus {
|
||||
color: var(--theme-text);
|
||||
border-color: var(--theme-text-light);
|
||||
}
|
||||
.search-input:hover::placeholder,
|
||||
.search-input:focus::placeholder {
|
||||
color: var(--theme-text-light);
|
||||
}
|
||||
.search-input::placeholder {
|
||||
color: var(--theme-text-light);
|
||||
}
|
||||
.search-hint {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: 19px;
|
||||
padding: 3px 5px;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
letter-spacing: 0.125em;
|
||||
font-size: 13px;
|
||||
font-family: var(--font-mono);
|
||||
pointer-events: none;
|
||||
border-color: var(--theme-text-lighter);
|
||||
color: var(--theme-text-light);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 0.25rem;
|
||||
line-height: 14px;
|
||||
}
|
||||
|
||||
@media (min-width: 50em) {
|
||||
.search-hint {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ *\
|
||||
DocSearch (Algolia)
|
||||
\* ------------------------------------------------------------ */
|
||||
|
||||
.DocSearch-Modal .DocSearch-Hit a {
|
||||
box-shadow: none;
|
||||
border: 1px solid var(--theme-accent);
|
||||
}
|
||||
97
docs/src/components/Header/Search.tsx
Normal file
@ -0,0 +1,97 @@
|
||||
/** @jsxImportSource react */
|
||||
import { useState, useCallback, useRef } from 'react';
|
||||
import { ALGOLIA } from '../../consts';
|
||||
import '@docsearch/css';
|
||||
import './Search.css';
|
||||
|
||||
import { createPortal } from 'react-dom';
|
||||
import * as docSearchReact from '@docsearch/react';
|
||||
|
||||
/** FIXME: This is still kinda nasty, but DocSearch is not ESM ready. */
|
||||
const DocSearchModal =
|
||||
docSearchReact.DocSearchModal || (docSearchReact as any).default.DocSearchModal;
|
||||
const useDocSearchKeyboardEvents =
|
||||
docSearchReact.useDocSearchKeyboardEvents ||
|
||||
(docSearchReact as any).default.useDocSearchKeyboardEvents;
|
||||
|
||||
export default function Search() {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const searchButtonRef = useRef<HTMLButtonElement>(null);
|
||||
const [initialQuery, setInitialQuery] = useState('');
|
||||
|
||||
const onOpen = useCallback(() => {
|
||||
setIsOpen(true);
|
||||
}, [setIsOpen]);
|
||||
|
||||
const onClose = useCallback(() => {
|
||||
setIsOpen(false);
|
||||
}, [setIsOpen]);
|
||||
|
||||
const onInput = useCallback(
|
||||
(e) => {
|
||||
setIsOpen(true);
|
||||
setInitialQuery(e.key);
|
||||
},
|
||||
[setIsOpen, setInitialQuery]
|
||||
);
|
||||
|
||||
useDocSearchKeyboardEvents({
|
||||
isOpen,
|
||||
onOpen,
|
||||
onClose,
|
||||
onInput,
|
||||
searchButtonRef,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<button type="button" ref={searchButtonRef} onClick={onOpen} className="search-input">
|
||||
<svg width="24" height="24" fill="none">
|
||||
<path
|
||||
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<span>Search</span>
|
||||
|
||||
<span className="search-hint">
|
||||
<span className="sr-only">Press </span>
|
||||
|
||||
<kbd>/</kbd>
|
||||
|
||||
<span className="sr-only"> to search</span>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{isOpen &&
|
||||
createPortal(
|
||||
<DocSearchModal
|
||||
initialQuery={initialQuery}
|
||||
initialScrollY={window.scrollY}
|
||||
onClose={onClose}
|
||||
indexName={ALGOLIA.indexName}
|
||||
appId={ALGOLIA.appId}
|
||||
apiKey={ALGOLIA.apiKey}
|
||||
transformItems={(items) => {
|
||||
return items.map((item) => {
|
||||
// We transform the absolute URL into a relative URL to
|
||||
// work better on localhost, preview URLS.
|
||||
const a = document.createElement('a');
|
||||
a.href = item.url;
|
||||
const hash = a.hash === '#overview' ? '' : a.hash;
|
||||
return {
|
||||
...item,
|
||||
url: `${a.pathname}${hash}`,
|
||||
};
|
||||
});
|
||||
}}
|
||||
/>,
|
||||
document.body
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
44
docs/src/components/Header/SidebarToggle.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
/** @jsxImportSource preact */
|
||||
import type { FunctionalComponent } from 'preact';
|
||||
import { useState, useEffect } from 'preact/hooks';
|
||||
|
||||
const MenuToggle: FunctionalComponent = () => {
|
||||
const [sidebarShown, setSidebarShown] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const body = document.querySelector('body')!;
|
||||
if (sidebarShown) {
|
||||
body.classList.add('mobile-sidebar-toggle');
|
||||
} else {
|
||||
body.classList.remove('mobile-sidebar-toggle');
|
||||
}
|
||||
}, [sidebarShown]);
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
aria-pressed={sidebarShown ? 'true' : 'false'}
|
||||
id="menu-toggle"
|
||||
onClick={() => setSidebarShown(!sidebarShown)}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em"
|
||||
height="1em"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 6h16M4 12h16M4 18h16"
|
||||
/>
|
||||
</svg>
|
||||
<span className="sr-only">Toggle sidebar</span>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default MenuToggle;
|
||||
26
docs/src/components/Header/SkipToContent.astro
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
type Props = {};
|
||||
---
|
||||
|
||||
<a href="#article" class="sr-only focus:not-sr-only skiplink"><span>Skip to Content</span></a>
|
||||
|
||||
<style>
|
||||
.skiplink,
|
||||
.skiplink:focus,
|
||||
.skiplink:focus-visible {
|
||||
position: absolute;
|
||||
padding: 0.25em;
|
||||
font-size: larger;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 9;
|
||||
display: block;
|
||||
text-align: center;
|
||||
background-color: var(--theme-text-accent);
|
||||
color: var(--theme-bg);
|
||||
border-radius: 0.25em;
|
||||
outline: var(--theme-bg) solid 1px;
|
||||
outline-offset: 0;
|
||||
}
|
||||
</style>
|
||||
119
docs/src/components/LeftSidebar/LeftSidebar.astro
Normal file
@ -0,0 +1,119 @@
|
||||
---
|
||||
import { getLanguageFromURL } from '../../languages';
|
||||
import { SIDEBAR } from '../../consts';
|
||||
|
||||
type Props = {
|
||||
currentPage: string;
|
||||
};
|
||||
|
||||
const { currentPage } = Astro.props;
|
||||
const currentPageMatch = currentPage.endsWith('/')
|
||||
? currentPage.slice(1, -1)
|
||||
: currentPage.slice(1);
|
||||
const langCode = getLanguageFromURL(currentPage);
|
||||
const sidebar = SIDEBAR[langCode];
|
||||
---
|
||||
|
||||
<nav aria-labelledby="grid-left">
|
||||
<ul class="nav-groups">
|
||||
{
|
||||
Object.entries(sidebar).map(([header, children]) => (
|
||||
<li>
|
||||
<div class="nav-group">
|
||||
<h2 class="nav-group-title">{header}</h2>
|
||||
<ul>
|
||||
{children.map((child) => {
|
||||
const url = Astro.site?.pathname + child.link;
|
||||
return (
|
||||
<li class="nav-link">
|
||||
<a href={url} aria-current={currentPageMatch === child.link ? 'page' : false}>
|
||||
{child.text}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<script is:inline>
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
var target = document.querySelector('[aria-current="page"]');
|
||||
if (target && target.offsetTop > window.innerHeight - 100) {
|
||||
document.querySelector('.nav-groups').scrollTop = target.offsetTop;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
nav {
|
||||
width: 100%;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.nav-groups {
|
||||
height: 100%;
|
||||
padding: 2rem 0;
|
||||
overflow-x: visible;
|
||||
overflow-y: auto;
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
.nav-groups > li + li {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.nav-groups > :first-child {
|
||||
padding-top: var(--doc-padding);
|
||||
}
|
||||
|
||||
.nav-groups > :last-child {
|
||||
padding-bottom: 2rem;
|
||||
margin-bottom: var(--theme-navbar-height);
|
||||
}
|
||||
|
||||
.nav-group-title {
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
padding: 0.1rem 1rem;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-link a {
|
||||
font-size: 1rem;
|
||||
margin: 1px;
|
||||
padding: 0.3rem 1rem;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav-link a:hover,
|
||||
.nav-link a:focus {
|
||||
background-color: var(--theme-bg-hover);
|
||||
}
|
||||
|
||||
.nav-link a[aria-current='page'] {
|
||||
color: var(--theme-text-accent);
|
||||
background-color: var(--theme-bg-accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media (min-width: 50em) {
|
||||
.nav-groups {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style is:global>
|
||||
:root.theme-dark .nav-link a[aria-current='page'] {
|
||||
color: hsla(var(--color-base-white), 100%, 1);
|
||||
}
|
||||
</style>
|
||||
51
docs/src/components/PageContent/PageContent.astro
Normal file
@ -0,0 +1,51 @@
|
||||
---
|
||||
import type { MarkdownHeading } from 'astro';
|
||||
import MoreMenu from '../RightSidebar/MoreMenu.astro';
|
||||
import TableOfContents from '../RightSidebar/TableOfContents';
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
headings: MarkdownHeading[];
|
||||
githubEditUrl: string;
|
||||
};
|
||||
|
||||
const { title, headings, githubEditUrl } = Astro.props;
|
||||
---
|
||||
|
||||
<article id="article" class="content">
|
||||
<section class="main-section">
|
||||
<h1 class="content-title" id="overview">{title}</h1>
|
||||
<nav class="block sm:hidden">
|
||||
<TableOfContents client:media="(max-width: 50em)" headings={headings} />
|
||||
</nav>
|
||||
<slot />
|
||||
</section>
|
||||
<nav class="block sm:hidden">
|
||||
<MoreMenu editHref={githubEditUrl} />
|
||||
</nav>
|
||||
</article>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
padding: 0;
|
||||
max-width: 75ch;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.content > section {
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (min-width: 50em) {
|
||||
.sm\:hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
79
docs/src/components/RightSidebar/MoreMenu.astro
Normal file
@ -0,0 +1,79 @@
|
||||
---
|
||||
import ThemeToggleButton from './ThemeToggleButton';
|
||||
import { COMMUNITY_INVITE_URL } from '../../consts';
|
||||
|
||||
type Props = {
|
||||
editHref: string;
|
||||
};
|
||||
|
||||
const { editHref } = Astro.props;
|
||||
const showMoreSection = Boolean(COMMUNITY_INVITE_URL);
|
||||
---
|
||||
|
||||
{showMoreSection && <h2 class="heading">More</h2>}
|
||||
<ul>
|
||||
{
|
||||
editHref && (
|
||||
<li class={`header-link depth-2`}>
|
||||
<a class="edit-on-github" href={editHref} target="_blank">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="pen"
|
||||
class="svg-inline--fa fa-pen fa-w-16"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
height="1em"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M290.74 93.24l128.02 128.02-277.99 277.99-114.14 12.6C11.35 513.54-1.56 500.62.14 485.34l12.7-114.22 277.9-277.88zm207.2-19.06l-60.11-60.11c-18.75-18.75-49.16-18.75-67.91 0l-56.55 56.55 128.02 128.02 56.55-56.55c18.75-18.76 18.75-49.16 0-67.91z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Edit this page</span>
|
||||
</a>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
{
|
||||
COMMUNITY_INVITE_URL && (
|
||||
<li class={`header-link depth-2`}>
|
||||
<a href={COMMUNITY_INVITE_URL} target="_blank">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="comment-alt"
|
||||
class="svg-inline--fa fa-comment-alt fa-w-16"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
height="1em"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 9.8 11.2 15.5 19.1 9.7L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Join our community</span>
|
||||
</a>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
</ul>
|
||||
<div style="margin: 2rem 0; text-align: center;">
|
||||
<ThemeToggleButton client:visible />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.edit-on-github {
|
||||
text-decoration: none;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
font-size: 1rem;
|
||||
}
|
||||
</style>
|
||||
34
docs/src/components/RightSidebar/RightSidebar.astro
Normal file
@ -0,0 +1,34 @@
|
||||
---
|
||||
import type { MarkdownHeading } from 'astro';
|
||||
import TableOfContents from './TableOfContents';
|
||||
import MoreMenu from './MoreMenu.astro';
|
||||
|
||||
type Props = {
|
||||
headings: MarkdownHeading[];
|
||||
githubEditUrl: string;
|
||||
};
|
||||
|
||||
const { headings, githubEditUrl } = Astro.props;
|
||||
---
|
||||
|
||||
<nav class="sidebar-nav" aria-labelledby="grid-right">
|
||||
<div class="sidebar-nav-inner">
|
||||
<TableOfContents client:media="(min-width: 50em)" headings={headings} />
|
||||
<MoreMenu editHref={githubEditUrl} />
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<style>
|
||||
.sidebar-nav {
|
||||
width: 100%;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.sidebar-nav-inner {
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
padding-top: var(--doc-padding);
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
93
docs/src/components/RightSidebar/TableOfContents.tsx
Normal file
@ -0,0 +1,93 @@
|
||||
import type { MarkdownHeading } from 'astro';
|
||||
import type { FunctionalComponent } from 'preact';
|
||||
import { unescape } from 'html-escaper';
|
||||
import { useState, useEffect, useRef } from 'preact/hooks';
|
||||
|
||||
type ItemOffsets = {
|
||||
id: string;
|
||||
topOffset: number;
|
||||
};
|
||||
|
||||
const TableOfContents: FunctionalComponent<{ headings: MarkdownHeading[] }> = ({
|
||||
headings = [],
|
||||
}) => {
|
||||
const toc = useRef<HTMLUListElement>();
|
||||
const onThisPageID = 'on-this-page-heading';
|
||||
const itemOffsets = useRef<ItemOffsets[]>([]);
|
||||
const [currentID, setCurrentID] = useState('overview');
|
||||
useEffect(() => {
|
||||
const getItemOffsets = () => {
|
||||
const titles = document.querySelectorAll('article :is(h1, h2, h3, h4)');
|
||||
itemOffsets.current = Array.from(titles).map((title) => ({
|
||||
id: title.id,
|
||||
topOffset: title.getBoundingClientRect().top + window.scrollY,
|
||||
}));
|
||||
};
|
||||
|
||||
getItemOffsets();
|
||||
window.addEventListener('resize', getItemOffsets);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', getItemOffsets);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!toc.current) return;
|
||||
|
||||
const setCurrent: IntersectionObserverCallback = (entries) => {
|
||||
for (const entry of entries) {
|
||||
if (entry.isIntersecting) {
|
||||
const { id } = entry.target;
|
||||
if (id === onThisPageID) continue;
|
||||
setCurrentID(entry.target.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const observerOptions: IntersectionObserverInit = {
|
||||
// Negative top margin accounts for `scroll-margin`.
|
||||
// Negative bottom margin means heading needs to be towards top of viewport to trigger intersection.
|
||||
rootMargin: '-100px 0% -66%',
|
||||
threshold: 1,
|
||||
};
|
||||
|
||||
const headingsObserver = new IntersectionObserver(setCurrent, observerOptions);
|
||||
|
||||
// Observe all the headings in the main page content.
|
||||
document.querySelectorAll('article :is(h1,h2,h3)').forEach((h) => headingsObserver.observe(h));
|
||||
|
||||
// Stop observing when the component is unmounted.
|
||||
return () => headingsObserver.disconnect();
|
||||
}, [toc.current]);
|
||||
|
||||
const onLinkClick = (e) => {
|
||||
setCurrentID(e.target.getAttribute('href').replace('#', ''));
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 id={onThisPageID} className="heading">
|
||||
On this page
|
||||
</h2>
|
||||
<ul ref={toc}>
|
||||
{headings
|
||||
.filter(({ depth }) => depth > 1 && depth < 4)
|
||||
.map((heading) => (
|
||||
<li
|
||||
className={`header-link depth-${heading.depth} ${
|
||||
currentID === heading.slug ? 'current-header-link' : ''
|
||||
}`.trim()}
|
||||
>
|
||||
<a href={`#${heading.slug}`} onClick={onLinkClick}>
|
||||
{unescape(heading.text)}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default TableOfContents;
|
||||
37
docs/src/components/RightSidebar/ThemeToggleButton.css
Normal file
@ -0,0 +1,37 @@
|
||||
.theme-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25em;
|
||||
padding: 0.33em 0.67em;
|
||||
border-radius: 99em;
|
||||
background-color: var(--theme-code-inline-bg);
|
||||
}
|
||||
|
||||
.theme-toggle > label:focus-within {
|
||||
outline: 2px solid transparent;
|
||||
box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white;
|
||||
}
|
||||
|
||||
.theme-toggle > label {
|
||||
color: var(--theme-code-inline-text);
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.theme-toggle .checked {
|
||||
color: var(--theme-accent);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
input[name='theme-toggle'] {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
82
docs/src/components/RightSidebar/ThemeToggleButton.tsx
Normal file
@ -0,0 +1,82 @@
|
||||
import type { FunctionalComponent } from 'preact';
|
||||
import { useState, useEffect } from 'preact/hooks';
|
||||
import './ThemeToggleButton.css';
|
||||
|
||||
const themes = ['light', 'dark'];
|
||||
|
||||
const icons = [
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>,
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
|
||||
</svg>,
|
||||
];
|
||||
|
||||
const ThemeToggle: FunctionalComponent = () => {
|
||||
const [theme, setTheme] = useState(() => {
|
||||
if (import.meta.env.SSR) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof localStorage !== undefined && localStorage.getItem('theme')) {
|
||||
return localStorage.getItem('theme');
|
||||
}
|
||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
return 'dark';
|
||||
}
|
||||
return 'light';
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
if (theme === 'light') {
|
||||
root.classList.remove('theme-dark');
|
||||
} else {
|
||||
root.classList.add('theme-dark');
|
||||
}
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
<div className="theme-toggle">
|
||||
{themes.map((t, i) => {
|
||||
const icon = icons[i];
|
||||
const checked = t === theme;
|
||||
return (
|
||||
<label className={checked ? ' checked' : ''}>
|
||||
{icon}
|
||||
<input
|
||||
type="radio"
|
||||
name="theme-toggle"
|
||||
checked={checked}
|
||||
value={t}
|
||||
title={`Use ${t} theme`}
|
||||
aria-label={`Use ${t} theme`}
|
||||
onChange={() => {
|
||||
localStorage.setItem('theme', t);
|
||||
setTheme(t);
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeToggle;
|
||||
73
docs/src/components/Schemas/Content.astro
Normal file
@ -0,0 +1,73 @@
|
||||
---
|
||||
import type { JSONSchema } from "@apidevtools/json-schema-ref-parser/dist/lib/types";
|
||||
|
||||
export interface Props {
|
||||
name: string;
|
||||
slug: string;
|
||||
schema: JSONSchema;
|
||||
parentSchema: JSONSchema;
|
||||
}
|
||||
|
||||
const { name, slug, schema, parentSchema } = Astro.props;
|
||||
|
||||
const getTag = () => {
|
||||
switch (schema.type) {
|
||||
default:
|
||||
return Fragment;
|
||||
}
|
||||
};
|
||||
|
||||
const Tag = getTag();
|
||||
|
||||
const displayType = schema.$ref?.split("/").at(-1) ?? schema.type;
|
||||
|
||||
const required =
|
||||
parentSchema.required &&
|
||||
Array.isArray(parentSchema.required) &&
|
||||
parentSchema.required.includes(name);
|
||||
---
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="header">
|
||||
<h2 id={slug}>{name}</h2>
|
||||
<div class="badges">
|
||||
{required && <span class="required">Required</span>}
|
||||
<span>Type: {displayType}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
{schema.description}
|
||||
</p>
|
||||
<Tag schema={schema} />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
h2 {
|
||||
margin-top: 0.5rem !important;
|
||||
}
|
||||
|
||||
div.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
div.wrapper {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
span {
|
||||
background-color: var(--theme-bg-accent);
|
||||
font-size: small;
|
||||
padding: 0.3rem;
|
||||
margin-right: 0.3rem;
|
||||
border: solid 2px var(--theme-accent);
|
||||
border-radius: 5rem;
|
||||
}
|
||||
|
||||
span.required {
|
||||
background-color: hsla(var(--color-yellow), var(--theme-accent-opacity));
|
||||
border-color: hsla(var(--color-yellow), 1);
|
||||
}
|
||||
</style>
|
||||
12
docs/src/components/Schemas/Ref.astro
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
import type { JSONSchema } from "@apidevtools/json-schema-ref-parser/dist/lib/types";
|
||||
|
||||
export interface Props {
|
||||
name: string;
|
||||
parentSlug: string;
|
||||
}
|
||||
|
||||
const { name, parentSlug } = Astro.props;
|
||||
---
|
||||
|
||||
<a href={`/schemas/defs/${parentSlug}/${name}`}>View {name}</a>
|
||||
59
docs/src/consts.ts
Normal file
@ -0,0 +1,59 @@
|
||||
export const SITE = {
|
||||
title: 'New Horizons',
|
||||
description: 'Documentation on how to use the New Horizons planet creation tool for Outer Wilds.',
|
||||
defaultLanguage: 'en-us',
|
||||
} as const;
|
||||
|
||||
export const OPEN_GRAPH = {
|
||||
image: {
|
||||
src: 'https://nh.outerwildsmods.com/public/home_logo.webp',
|
||||
alt:
|
||||
'The New Horizons Logo'
|
||||
}
|
||||
};
|
||||
|
||||
export const KNOWN_LANGUAGES = {
|
||||
English: 'en',
|
||||
} as const;
|
||||
export const KNOWN_LANGUAGE_CODES = Object.values(KNOWN_LANGUAGES);
|
||||
|
||||
export const GITHUB_EDIT_URL = `https://github.com/Outer-Wilds-New-Horizons/new-horizons/tree/main/docs`;
|
||||
|
||||
export const COMMUNITY_INVITE_URL = `https://discord.gg/wusTQYbYTc`;
|
||||
|
||||
// See "Algolia" section of the README for more information.
|
||||
export const ALGOLIA = {
|
||||
indexName: 'XXXXXXXXXX',
|
||||
appId: 'XXXXXXXXXX',
|
||||
apiKey: 'XXXXXXXXXX',
|
||||
};
|
||||
|
||||
export type Sidebar = Record<
|
||||
(typeof KNOWN_LANGUAGE_CODES)[number],
|
||||
Record<string, { text: string; link: string }[]>
|
||||
>;
|
||||
export const SIDEBAR: Sidebar = {
|
||||
en: {
|
||||
'Intro': [
|
||||
{ text: 'Introduction', link: 'en/introduction' },
|
||||
],
|
||||
'Guides': [
|
||||
{ text: 'Getting Started', link: 'en/getting-started' },
|
||||
{ text: 'Creating An Addon', link: 'en/creating-addons' },
|
||||
{ text: 'Updating Existing Planets', link: 'en/updating-planets' },
|
||||
{ text: 'Creating New Planets', link: 'en/planet-generation' },
|
||||
{ text: 'Detailing Planets', link: 'en/details' },
|
||||
{ text: 'Custom Star Systems', link: 'en/star-systems' },
|
||||
{ text: 'Adding Translations', link: 'en/translation' },
|
||||
{ text: 'Understanding XML', link: 'en/xml' },
|
||||
{ text: 'Ship Log', link: 'en/ship-log' },
|
||||
{ text: 'Dialogue', link: 'en/dialogue' },
|
||||
{ text: 'API', link: 'en/api' },
|
||||
{ text: 'Extending Configs', link: 'en/extending-configs' },
|
||||
{ text: 'Publishing Your Addon', link: 'en/publishing' },
|
||||
],
|
||||
"Schemas": [
|
||||
{ text: "Celestial Body Schema", link: "schemas/body-schema" }
|
||||
]
|
||||
},
|
||||
};
|
||||
20
docs/src/content/config.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { defineCollection, z } from 'astro:content';
|
||||
import { SITE } from '../consts';
|
||||
|
||||
const docs = defineCollection({
|
||||
schema: z.object({
|
||||
title: z.string().default(SITE.title),
|
||||
description: z.string().default(SITE.description),
|
||||
lang: z.literal('en-us').default(SITE.defaultLanguage),
|
||||
dir: z.union([z.literal('ltr'), z.literal('rtl')]).default('ltr'),
|
||||
image: z
|
||||
.object({
|
||||
src: z.string(),
|
||||
alt: z.string(),
|
||||
})
|
||||
.optional(),
|
||||
ogLocale: z.string().optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const collections = { docs };
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
Title: API
|
||||
Sort_Priority: 20
|
||||
title: API
|
||||
description: A guide on using New Horizons' API
|
||||
---
|
||||
|
||||
## How to use the API
|
||||
@ -1,10 +1,8 @@
|
||||
---
|
||||
Title: Creating An Addon
|
||||
Sort_Priority: 85
|
||||
title: Creating An Addon
|
||||
description: A guide to creating addons for New Horizons
|
||||
---
|
||||
|
||||
# Creating An Addon
|
||||
|
||||
Up until now, you've been using the sandbox feature of New Horizons (simply placing your files in the `xen.NewHorizons` folder).
|
||||
While this is the easiest way to get started, you won't be able to publish your work like this. In this tutorial we will:
|
||||
|
||||
@ -15,7 +13,7 @@ While this is the easiest way to get started, you won't be able to publish your
|
||||
## Making a GitHub Repository
|
||||
|
||||
To get started, we need a place to store our code. GitHub is one of the most popular websites to store source code, and it's also what the mod database uses to let people access our mod.
|
||||
First you're going to want to [create a GitHub account](https://github.com/signup){ target="_blank" }, and then head to [this repository](https://github.com/xen-42/ow-new-horizons-config-template){ target="_blank" }.
|
||||
First you're going to want to [create a GitHub account](https://github.com/signup), and then head to [this repository](https://github.com/xen-42/ow-new-horizons-config-template).
|
||||
Now, click the green "Use This Template" button.
|
||||
|
||||
- Set the Name to your username followed by a dot (`.`), followed by your mod's name in PascalCase (no spaces, new words have capital letters). So for example if my username was "Test" and my mod's name was "Really Cool Addon", I would name the repo `Test.ReallyCoolAddon`.
|
||||
@ -25,7 +23,7 @@ Now, click the green "Use This Template" button.
|
||||
## Cloning the Repository
|
||||
|
||||
Now that we've created our GitHub repository (or "repo"), we need to clone (or download) it onto our computer.
|
||||
To do this we recommend using the [GitHub Desktop App](https://desktop.github.com/){ target="_blank" }, as it's much easier to use than having to fight with the command line.
|
||||
To do this we recommend using the [GitHub Desktop App](https://desktop.github.com/), as it's much easier to use than having to fight with the command line.
|
||||
|
||||
Once we open GitHub desktop we're going to log in, select File -> Options -> Accounts and sign in to your newly created GitHub account.
|
||||
Now we're ready to clone the repo, select File -> Clone Repository. Your repository should appear in the list.
|
||||
@ -52,7 +50,7 @@ To get started editing the files, simply click "Open in Visual Studio Code" in G
|
||||
- You can leave `version`, `owmlVersion`, and `dependencies` alone
|
||||
- NewHorizonsConfig.dll: This is the heart of your addon, make sure to never move or rename it.
|
||||
- README.md: This file is displayed on the mod website when you go to a specific mod's page, you can delete the current contents.
|
||||
- This file is a [markdown](https://www.markdowntutorial.com/){ target="_blank" } file, if you're not comfortable writing an entire README right now, just write a small description of your mod.
|
||||
- This file is a [markdown](https://www.markdowntutorial.com/) file, if you're not comfortable writing an entire README right now, just write a small description of your mod.
|
||||
|
||||
### Committing The Changes
|
||||
|
||||
@ -76,8 +74,14 @@ You should see your mod there with the downloads counter set as a dash and the v
|
||||
|
||||
Now when you click "Start Game" and load into the solar system, you should be able to notice that the quantum moon is gone entirely, this means that your addon and its configs were successfully loaded.
|
||||
|
||||
## Note About File Paths
|
||||
|
||||
Whenever something refers to the "relative path" of a file, it means relative to your mod's directory, this means you **must** include the `planets` folder in the path:
|
||||
|
||||
```json
|
||||
"planets/assets/images/MyCoolImage.png"
|
||||
```
|
||||
|
||||
## Going Forward
|
||||
|
||||
Now instead of using the New Horizons mod folder, you can use your own mod's folder instead.
|
||||
|
||||
**Next Up: [Planet Generation]({{ "Planet Generation"|route }})**
|
||||
@ -1,11 +1,9 @@
|
||||
---
|
||||
Title: Detailing
|
||||
Sort_Priority: 80
|
||||
title: Detailing
|
||||
description: A guide to adding details to planets in New Horizons
|
||||
---
|
||||
|
||||
# Details/Scatterer
|
||||
|
||||
For physical objects there are currently two ways of setting them up: specify an asset bundle and path to load a custom asset you created, or specify the path to the item you want to copy from the game in the scene hierarchy. Use the [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer){ target="_blank" } mod to find an object you want to copy onto your new body. Some objects work better than others for this. Good luck. Some pointers:
|
||||
For physical objects there are currently two ways of setting them up: specify an asset bundle and path to load a custom asset you created, or specify the path to the item you want to copy from the game in the scene hierarchy. Use the [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer) mod to find an object you want to copy onto your new body. Some objects work better than others for this. Good luck. Some pointers:
|
||||
|
||||
- Use "Object Explorer" to search
|
||||
- Generally you can find planets by writing their name with no spaces/punctuation followed by "_Body".
|
||||
@ -22,20 +20,6 @@ The Prop Placer is a convenience tool that lets you manually place details from
|
||||
1. This menu scrolls. If you do not see your mod, it may be further down the list.
|
||||
3. The Prop Placer is now active! Unpause the game, and you can now place Nomai vases using "G"
|
||||
|
||||
### How to Save
|
||||
|
||||
1. In the Prop Placer Menu, you will see a greyed out button titled "Update your mod's configs".
|
||||
2. Click the small button to the left of it.
|
||||
3. Click "Update your mod's configs" to save!
|
||||
|
||||
!!! alert-danger "IMPORTANT"
|
||||
Your updated configs will save *only* to your mod's build folder, eg "AppData\Roaming\OuterWildsModManager\OWML\Mods\you.yourModName"
|
||||
|
||||
!!! alert-warning "WARNING"
|
||||
Dying in-game will cause you to lose all work since you last saved. Make sure to save often.
|
||||
|
||||
What's that? You want to place something other than just vases? Well I can't say I agree with your choices, but here's how you would do that.
|
||||
|
||||
### How to Select Props
|
||||
|
||||
1. Pause the game again. The prop placer menu should still be visible.
|
||||
@ -56,13 +40,13 @@ What's that? You want to place something other than just vases? Well I can't say
|
||||
|
||||
## Asset Bundles
|
||||
|
||||
Here is a template project: [Outer Wilds Unity Template](https://github.com/xen-42/outer-wilds-unity-template){ target="_blank" }
|
||||
Here is a template project: [Outer Wilds Unity Template](https://github.com/xen-42/outer-wilds-unity-template)
|
||||
|
||||
The template project contains ripped versions of all the game scripts, meaning you can put things like DirectionalForceVolumes in your Unity project to have artificial gravity volumes loaded right into the game.
|
||||
|
||||
If for whatever reason you want to set up a Unity project manually instead of using the template, follow these instructions:
|
||||
|
||||
1. Start up a Unity 2017 project (I use Unity 2017.4.40f1 (64-bit), so if you use something else I can't guarantee it will work). The DLC updated Outer Wilds to 2019.4.27 so that probably works, but I personally haven't tried it.
|
||||
1. Start up a Unity 2019.4.39f1 project
|
||||
2. In the "Assets" folder in Unity, create a new folder called "Editor". In it create a file called "CreateAssetBundle.cs" with the following code in it:
|
||||
|
||||
```cs
|
||||
@ -87,10 +71,11 @@ public class CreateAssetBundles
|
||||
|
||||
3. Create your object in the Unity scene and save it as a prefab.
|
||||
4. Add all files used (models, prefabs, textures, materials, etc.) to an asset bundle by selecting them and using the dropdown in the bottom right. Here I am adding a rover model to my "rss" asset bundle for the Real Solar System add-on.
|
||||

|
||||
|
||||
5. In the top left click the "Assets" drop-down and select "Build AssetBundles". This should create your asset bundle in a folder in the root directory called "StreamingAssets".
|
||||
6. Copy the asset bundle and asset bundle .manifest files from StreamingAssets into your mod's "planets" folder. If you did everything properly they should work in game. To double-check everything is included, open the .manifest file in a text editor to see the files included and their paths.
|
||||

|
||||
|
||||
1. In the top left click the "Assets" drop-down and select "Build AssetBundles". This should create your asset bundle in a folder in the root directory called "StreamingAssets".
|
||||
2. Copy the asset bundle and asset bundle .manifest files from StreamingAssets into your mod's "planets" folder. If you did everything properly they should work in game. To double-check everything is included, open the .manifest file in a text editor to see the files included and their paths.
|
||||
|
||||
## Importing a planet's surface from Unity
|
||||
|
||||
@ -1,14 +1,11 @@
|
||||
---
|
||||
Title: Dialogue
|
||||
Description: Guide to making dialogue in New Horizons
|
||||
Sort_Priority: 30
|
||||
title: Dialogue
|
||||
description: Guide to making dialogue in New Horizons
|
||||
---
|
||||
|
||||
# Dialogue
|
||||
|
||||
This page goes over how to use dialogue in New Horizons.
|
||||
|
||||
You may want to view [Understanding XML]({{ "Understanding XML"|route }}) if you haven't already.
|
||||
You may want to view [Understanding XML](/en/xml) if you haven't already.
|
||||
|
||||
## Understanding Dialogue
|
||||
|
||||
@ -134,7 +131,7 @@ To use the dialogue XML you have created, you simply need to reference it in the
|
||||
|
||||
## Dialogue Config
|
||||
|
||||
To view the options for the dialogue prop, check [the schema]({{ "Celestial Body Schema"|route }}#Props_dialogue)
|
||||
To view the options for the dialogue prop, check [the schema](/schemas/body-schema#Props_dialogue)
|
||||
|
||||
## Controlling Conditions
|
||||
|
||||
@ -151,7 +148,7 @@ You can set condition in dialogue with the `<SetCondition>` and `<SetPersistentC
|
||||
|
||||
## Dialogue Options
|
||||
|
||||
There are many control structures for dialogue options to hide/reveal them if conditions are met. Take a look at [the DialogueOption schema]({{ "Dialogue Schema"|route }}#DialogueTree-DialogueNode-DialogueOptionsList-DialogueOption-DialogueTarget) for more info.
|
||||
There are many control structures for dialogue options to hide/reveal them if conditions are met. Take a look at [the DialogueOption schema](/schemas/dialogue-schema#DialogueTree-DialogueNode-DialogueOptionsList-DialogueOption-DialogueTarget) for more info.
|
||||
|
||||
## Controlling Flow
|
||||
|
||||
@ -163,4 +160,4 @@ Defining `<DialogueTarget>` in the `<DialogueNode>` tag instead of a `<DialogueO
|
||||
|
||||
### DialogueTargetShipLogCondition
|
||||
|
||||
Used in tandem with `DialogueTarget`, makes it so you must have a [ship log fact]({{ "Ship Log"|route }}#explore-facts) to go to the next node.
|
||||
Used in tandem with `DialogueTarget`, makes it so you must have a [ship log fact](/en/ship-log#explore-facts) to go to the next node.
|
||||
@ -1,11 +1,8 @@
|
||||
---
|
||||
Title: Extending Configs
|
||||
Description: A guide on extending config files with the New Horizons API
|
||||
Sort_Priority: 5
|
||||
title: Extending Configs
|
||||
description: A guide on extending config files with the New Horizons API
|
||||
---
|
||||
|
||||
# Extending Configs
|
||||
|
||||
This guide will explain how to use the API to add new features to New Horizons.
|
||||
|
||||
## How Extending Works
|
||||
@ -1,23 +1,21 @@
|
||||
---
|
||||
Title: Getting Started
|
||||
Sort_Priority: 100
|
||||
title: Getting Started
|
||||
description: A guide for getting started with New Horizons
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
||||
Congrats on taking the first step to becoming an addon developer!
|
||||
This tutorial will outline how to begin learning to use new horizons.
|
||||
|
||||
## Recommended Tools
|
||||
|
||||
It's strongly recommended you get [VSCode](https://code.visualstudio.com/){ target="_blank" } to edit your files, as it can provide syntax and error highlighting.
|
||||
It's strongly recommended you get [VSCode](https://code.visualstudio.com/) to edit your files, as it can provide syntax and error highlighting.
|
||||
|
||||
## Using The Sandbox
|
||||
|
||||
Making an entirely separate addon can get a little complicated, so New Horizons provides a way to play around without the need to set up a full addon.
|
||||
To get started, navigate to your mod manager and click the ⋮ symbol, then select "Show In Explorer".
|
||||
|
||||

|
||||

|
||||
|
||||
Now, create a new folder named "planets". As the name suggests, New Horizons will search the files in this folder for planets to generate.
|
||||
|
||||
@ -207,22 +205,22 @@ Alright so now that we understand how the file is structures, let's look into wh
|
||||
- `name` simply sets the name of the planet
|
||||
- `$schema` we'll get to in a second
|
||||
- `starSystem` specifies what star system this planet is located in, in this case we're using the base game star system, so we put "SolarSystem"
|
||||
- Then it has an object called `Base`
|
||||
- Base has a `groundSize` of 100, this generates a perfect sphere that is 100 units in radius as the ground of our planet
|
||||
- It also has a `surfaceSize` of 101, surface size is used in many calculations, it's generally good to set it to a bit bigger than ground size.
|
||||
- `surfaceGravity` describes the strength of gravity on this planet, in this case it's 12 which is the same as Timber Hearth
|
||||
- `hasMapMarker` tells new horizons that we want this planet to have a marker on the map screen
|
||||
- Next it has another object called `Orbit`
|
||||
- `semiMajorAxis` specifies the radius of the orbit (how far away the body is from its parent)
|
||||
- `primaryBody` is set to TIMBER_HEARTH, this makes our planet orbit timber hearth
|
||||
- `isMoon` simply tells the game how close you have to be to the planet in map mode before its name appears
|
||||
- `isTidallyLocked` makes sure that one side of our planet is always facing timber hearth (the primary body)
|
||||
- Finally, we have `Atmosphere`
|
||||
- Its `size` is 150, this simply sets how far away from the planet our atmosphere stretches
|
||||
- Its `fogTint` is set to a color which is an object with r, g, b, and a properties (properties is another word for keys)
|
||||
- `fogSize` determines how far away the fog stretches from the planet
|
||||
- `fogDensity` is simply how dense the fog is
|
||||
- `hasRain` makes rainfall on the planet
|
||||
- Then it has an object called `Base`
|
||||
- Base has a `groundSize` of 100, this generates a perfect sphere that is 100 units in radius as the ground of our planet
|
||||
- It also has a `surfaceSize` of 101, surface size is used in many calculations, it's generally good to set it to a bit bigger than ground size.
|
||||
- `surfaceGravity` describes the strength of gravity on this planet, in this case it's 12 which is the same as Timber Hearth
|
||||
- `hasMapMarker` tells new horizons that we want this planet to have a marker on the map screen
|
||||
- Next it has another object called `Orbit`
|
||||
- `semiMajorAxis` specifies the radius of the orbit (how far away the body is from its parent)
|
||||
- `primaryBody` is set to TIMBER_HEARTH, this makes our planet orbit timber hearth
|
||||
- `isMoon` simply tells the game how close you have to be to the planet in map mode before its name appears
|
||||
- `isTidallyLocked` makes sure that one side of our planet is always facing timber hearth (the primary body)
|
||||
- Finally, we have `Atmosphere`
|
||||
- Its `size` is 150, this simply sets how far away from the planet our atmosphere stretches
|
||||
- Its `fogTint` is set to a color which is an object with r, g, b, and a properties (properties is another word for keys)
|
||||
- `fogSize` determines how far away the fog stretches from the planet
|
||||
- `fogDensity` is simply how dense the fog is
|
||||
- `hasRain` makes rainfall on the planet
|
||||
|
||||
### What's a Schema?
|
||||
|
||||
@ -242,7 +240,7 @@ If you run into issues please make sure:
|
||||
- You placed the JSON file in a folder called `planets` in the New Horizons mod folder
|
||||
- There are no red or yellow squiggly lines in your file
|
||||
|
||||
## Experiment!
|
||||
## Experiment
|
||||
|
||||
With that, try tweaking some value like groundSize and semiMajorAxis, get a feel for how editing JSON works.
|
||||
|
||||
@ -255,5 +253,3 @@ You may also notice blue and yellow logs start appearing in your console, this i
|
||||
## Modules
|
||||
|
||||
Base, Atmosphere, and Orbit are all modules, which define the different aspects of your planet, modules are represented by JSON objects
|
||||
|
||||
**Next Up: [Reading Schemas]({{ "Reading Schemas"|route }})**
|
||||