LeConte deployments page complete, better auto-formatting and import sorting, new inline link, popover definitions, and paragraph components, improvements to component interfaces
Some checks failed
Build and Test - Staging / test (pull_request) Failing after 2m31s
Build and Test - Staging / build_and_push (pull_request) Has been skipped
Build and Test - Staging / deploy_staging (pull_request) Has been skipped

This commit is contained in:
2025-12-05 01:02:18 -08:00
parent 91cd9af0f8
commit 3aa75e1a10
46 changed files with 617 additions and 76 deletions

View File

@@ -1,2 +1,7 @@
[**.{js,ts,astro}] [*]
charset = utf-8
insert_final_newline = true
end_of_line = lf
indent_style = space
indent_size = 2 indent_size = 2
max_line_length = 80

View File

@@ -1,5 +1,23 @@
{ {
"plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"], "astroOrganizeImportsMode": "All",
"importOrder": [
"^@core/(.*)$",
"^@server/(.*)$",
"^@ui/(.*)$",
"^@layouts/(.*)$",
"^@components/(.*)$",
"^@interfaces/(.*)$",
"^@assets/(.*)$",
"^[./]"
],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true,
"plugins": [
"prettier-plugin-astro",
"prettier-plugin-tailwindcss",
"@trivago/prettier-plugin-sort-imports",
"prettier-plugin-astro-organize-imports"
],
"overrides": [ "overrides": [
{ {
"files": "*.astro", "files": "*.astro",

View File

@@ -13,7 +13,9 @@
spelling-add-new-words \ spelling-add-new-words \
spelling-check \ spelling-check \
cleanup-check \ cleanup-check \
cleanup-code cleanup-code \
convert_video \
convert_video_times
default: dev default: dev
@@ -62,3 +64,28 @@ cleanup-check:
cleanup-code: cleanup-code:
npx prettier . --write npx prettier . --write
convert_video:
ffmpeg \
-init_hw_device vaapi=va:/dev/dri/renderD128 \
-filter_hw_device va \
-i $(input) \
-vf 'format=nv12,hwupload,scale_vaapi=-2:720' \
-c:v h264_vaapi \
-rc_mode CQP \
-qp 28 \
-an \
$(extra_args) \
$(output)
convert_video_times:
ffmpeg \
-init_hw_device vaapi=va:/dev/dri/renderD128 \
-filter_hw_device va \
-i $(input) \
-vf 'format=nv12,hwupload,scale_vaapi=-2:720,trim=start=$(start):end=$(end)' \
-c:v h264_vaapi \
-rc_mode CQP \
-qp 28 \
-an \
$(output)

View File

@@ -1,11 +1,11 @@
// @ts-check // @ts-check
import { defineConfig } from "astro/config";
import sitemap from "@astrojs/sitemap"; import sitemap from "@astrojs/sitemap";
import tailwindcss from "@tailwindcss/vite"; import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "astro/config";
// We don't have access to short imports this early in the build chain // We don't have access to short imports this early in the build chain
// noinspection ES6PreferShortImport // noinspection ES6PreferShortImport
import { siteLayout, getPaths } from "./src/data/site-layout.ts"; import { getPaths, siteLayout } from "./src/data/site-layout.ts";
const disabledPaths = getPaths(siteLayout, [], true); const disabledPaths = getPaths(siteLayout, [], true);

243
package-lock.json generated
View File

@@ -20,10 +20,12 @@
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.56.1", "@playwright/test": "^1.56.1",
"@trivago/prettier-plugin-sort-imports": "^6.0.0",
"@types/luxon": "^3.7.1", "@types/luxon": "^3.7.1",
"@types/node": "^24.10.0", "@types/node": "^24.10.0",
"prettier": "3.7.3", "prettier": "3.7.3",
"prettier-plugin-astro": "0.14.1", "prettier-plugin-astro": "0.14.1",
"prettier-plugin-astro-organize-imports": "^0.4.11",
"prettier-plugin-tailwindcss": "0.7.1", "prettier-plugin-tailwindcss": "0.7.1",
"vitest": "^4.0.7" "vitest": "^4.0.7"
} }
@@ -110,6 +112,48 @@
"node": "18.20.8 || ^20.3.0 || >=22.0.0" "node": "18.20.8 || ^20.3.0 || >=22.0.0"
} }
}, },
"node_modules/@babel/code-frame": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.27.1",
"js-tokens": "^4.0.0",
"picocolors": "^1.1.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/generator": {
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
"integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.5",
"@babel/types": "^7.28.5",
"@jridgewell/gen-mapping": "^0.3.12",
"@jridgewell/trace-mapping": "^0.3.28",
"jsesc": "^3.0.2"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-globals": {
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
"integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": { "node_modules/@babel/helper-string-parser": {
"version": "7.27.1", "version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
@@ -143,6 +187,40 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/@babel/template": {
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/parser": "^7.27.2",
"@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
"integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
"@babel/helper-globals": "^7.28.0",
"@babel/parser": "^7.28.5",
"@babel/template": "^7.27.2",
"@babel/types": "^7.28.5",
"debug": "^4.3.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/types": { "node_modules/@babel/types": {
"version": "7.28.5", "version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
@@ -2342,6 +2420,47 @@
"vite": "^5.2.0 || ^6 || ^7" "vite": "^5.2.0 || ^6 || ^7"
} }
}, },
"node_modules/@trivago/prettier-plugin-sort-imports": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-6.0.0.tgz",
"integrity": "sha512-Xarx55ow0R8oC7ViL5fPmDsg1EBa1dVhyZFVbFXNtPPJyW2w9bJADIla8YFSaNG9N06XfcklA9O9vmw4noNxkQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@babel/generator": "^7.28.0",
"@babel/parser": "^7.28.0",
"@babel/traverse": "^7.28.0",
"@babel/types": "^7.28.0",
"javascript-natural-sort": "^0.7.1",
"lodash-es": "^4.17.21",
"minimatch": "^9.0.0",
"parse-imports-exports": "^0.2.4"
},
"engines": {
"node": ">= 20"
},
"peerDependencies": {
"@vue/compiler-sfc": "3.x",
"prettier": "2.x - 3.x",
"prettier-plugin-ember-template-tag": ">= 2.0.0",
"prettier-plugin-svelte": "3.x",
"svelte": "4.x || 5.x"
},
"peerDependenciesMeta": {
"@vue/compiler-sfc": {
"optional": true
},
"prettier-plugin-ember-template-tag": {
"optional": true
},
"prettier-plugin-svelte": {
"optional": true
},
"svelte": {
"optional": true
}
}
},
"node_modules/@types/chai": { "node_modules/@types/chai": {
"version": "5.2.3", "version": "5.2.3",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
@@ -2922,6 +3041,13 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/base-64": { "node_modules/base-64": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz",
@@ -2976,6 +3102,16 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/brotli": { "node_modules/brotli": {
"version": "1.3.3", "version": "1.3.3",
"resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz",
@@ -4419,6 +4555,13 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/javascript-natural-sort": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
"integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==",
"dev": true,
"license": "MIT"
},
"node_modules/jiti": { "node_modules/jiti": {
"version": "2.6.1", "version": "2.6.1",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
@@ -4428,6 +4571,13 @@
"jiti": "lib/jiti-cli.mjs" "jiti": "lib/jiti-cli.mjs"
} }
}, },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true,
"license": "MIT"
},
"node_modules/js-yaml": { "node_modules/js-yaml": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
@@ -4440,6 +4590,19 @@
"js-yaml": "bin/js-yaml.js" "js-yaml": "bin/js-yaml.js"
} }
}, },
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"dev": true,
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
},
"engines": {
"node": ">=6"
}
},
"node_modules/kleur": { "node_modules/kleur": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
@@ -4704,6 +4867,13 @@
"url": "https://opencollective.com/parcel" "url": "https://opencollective.com/parcel"
} }
}, },
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"dev": true,
"license": "MIT"
},
"node_modules/longest-streak": { "node_modules/longest-streak": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
@@ -5562,6 +5732,22 @@
"mini-svg-data-uri": "cli.js" "mini-svg-data-uri": "cli.js"
} }
}, },
"node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/mrmime": { "node_modules/mrmime": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
@@ -5762,6 +5948,16 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/parse-imports-exports": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz",
"integrity": "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"parse-statements": "1.0.11"
}
},
"node_modules/parse-latin": { "node_modules/parse-latin": {
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz",
@@ -5780,6 +5976,13 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/parse-statements": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/parse-statements/-/parse-statements-1.0.11.tgz",
"integrity": "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==",
"dev": true,
"license": "MIT"
},
"node_modules/parse5": { "node_modules/parse5": {
"version": "7.3.0", "version": "7.3.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
@@ -5920,6 +6123,45 @@
"node": "^14.15.0 || >=16.0.0" "node": "^14.15.0 || >=16.0.0"
} }
}, },
"node_modules/prettier-plugin-astro-organize-imports": {
"version": "0.4.11",
"resolved": "https://registry.npmjs.org/prettier-plugin-astro-organize-imports/-/prettier-plugin-astro-organize-imports-0.4.11.tgz",
"integrity": "sha512-qJQZ7qgnTVmk8ALe1SXpCVGa2QNanhsKn6ivfGQqWH8SCgQY1/poxLVras0Q4fqRBugR3xPRGxovODk1tmkbwA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@astrojs/compiler": "^2.8.0",
"typescript": "^5.4.5"
},
"peerDependencies": {
"prettier": "^3.0",
"prettier-plugin-astro": "*",
"prettier-plugin-tailwindcss": "*"
},
"peerDependenciesMeta": {
"prettier-plugin-astro": {
"optional": true
},
"prettier-plugin-tailwindcss": {
"optional": true
}
}
},
"node_modules/prettier-plugin-sort-imports": {
"version": "1.8.9",
"resolved": "https://registry.npmjs.org/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-1.8.9.tgz",
"integrity": "sha512-DWGenlVAOqUZzlCpksqfmBMtgZAAofj6wV91rwoGh3ibVuVoOjxxTL3PnPzEzRru88AOUGShxi5RgTfSWpzMrA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"prettier": "^3.1.1"
},
"peerDependencies": {
"typescript": ">4.0.0"
}
},
"node_modules/prettier-plugin-tailwindcss": { "node_modules/prettier-plugin-tailwindcss": {
"version": "0.7.1", "version": "0.7.1",
"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.7.1.tgz", "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.7.1.tgz",
@@ -6761,7 +7003,6 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"

View File

@@ -1,7 +1,6 @@
{ {
"name": "caperren-com", "name": "caperren-com",
"type": "module", "type": "module",
"version": "0.0.1",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev",
"dev-hosted": "astro dev --host", "dev-hosted": "astro dev --host",
@@ -15,7 +14,6 @@
"@astrojs/sitemap": "^3.6.0", "@astrojs/sitemap": "^3.6.0",
"@tailwindcss/vite": "^4.1.11", "@tailwindcss/vite": "^4.1.11",
"astro": "^5.16.3", "astro": "^5.16.3",
"cspell": "^9.3.2",
"flowbite": "^3.1.2", "flowbite": "^3.1.2",
"leader-line-new": "^1.1.9", "leader-line-new": "^1.1.9",
"luxon": "^3.7.2", "luxon": "^3.7.2",
@@ -24,10 +22,13 @@
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.56.1", "@playwright/test": "^1.56.1",
"@trivago/prettier-plugin-sort-imports": "^6.0.0",
"@types/luxon": "^3.7.1", "@types/luxon": "^3.7.1",
"@types/node": "^24.10.0", "@types/node": "^24.10.0",
"cspell": "^9.3.2",
"prettier": "3.7.3", "prettier": "3.7.3",
"prettier-plugin-astro": "0.14.1", "prettier-plugin-astro": "0.14.1",
"prettier-plugin-astro-organize-imports": "^0.4.11",
"prettier-plugin-tailwindcss": "0.7.1", "prettier-plugin-tailwindcss": "0.7.1",
"vitest": "^4.0.7" "vitest": "^4.0.7"
} }

View File

@@ -1,3 +1,4 @@
ADCP
ASSEM ASSEM
astrojs astrojs
Candian Candian
@@ -14,6 +15,8 @@ flowbite
HDFS HDFS
headshot headshot
Homelab Homelab
hwupload
iceops
ITAR ITAR
Jetson Jetson
leconte leconte
@@ -36,7 +39,13 @@ sinnhuber
sitemapindex sitemapindex
ssds ssds
Starlink Starlink
steller
Steller
timelapse
trivago
Unstow Unstow
uuidv
vaapi
vitest vitest
Zebrafish Zebrafish
zscan zscan

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 MiB

View File

@@ -2,4 +2,4 @@
--- ---
<h3 class="my-4 font-bold md:text-lg">{Astro.props.text}</h3> <h3 class="mt-4 mb-2 font-bold md:text-lg">{Astro.props.text}</h3>

View File

@@ -0,0 +1,14 @@
---
interface Props {
href: string;
target?: string;
}
const { href, target = "_blank" } = Astro.props;
---
<>
<a class="text-blue-500 hover:text-blue-300" href={href} target={target}>
<slot />
</a>
</>

View File

@@ -1,11 +1,18 @@
--- ---
interface Props {
title: string;
href: string;
target?: string;
}
const { title, href, target = "_blank" } = Astro.props;
--- ---
<a <a
class="text-caperren-green border-caperren-green hover:border-caperren-green-light hover:text-caperren-green-light rounded-2xl border-2 bg-black p-2" class="text-caperren-green border-caperren-green hover:border-caperren-green-light hover:text-caperren-green-light rounded-2xl border-2 bg-black p-2"
href={Astro.props.href} href={href}
target={Astro.props.target || "_blank"} target={target}
> >
{Astro.props.title} {title}
</a> </a>

View File

@@ -1,7 +1,7 @@
import { import {
Carousel, Carousel,
type CarouselItem,
type CarouselInterface, type CarouselInterface,
type CarouselItem,
type CarouselOptions, type CarouselOptions,
type IndicatorItem, type IndicatorItem,
Modal, Modal,

View File

@@ -1,11 +1,34 @@
--- ---
import { type videoConfig } from "@interfaces/video.ts"; interface Props {
videoPath: string;
videoType?: string;
const config: videoConfig = Astro.props.videoConfig; controls?: boolean;
console.log(config); autoPlay?: boolean;
loop?: boolean;
playsInline?: boolean;
}
const {
videoPath,
videoType = "video/mp4",
controls = true,
autoPlay = false,
loop = false,
playsInline = false,
} = Astro.props;
--- ---
<video class="h-auto w-full max-w-1/2" controls> <div class="mx-auto my-auto">
<source src={config.videoPath} type={config.videoType ?? "video/mp4"} /> <video
class="h-auto w-full"
controls={controls}
autoplay={autoPlay}
loop={loop}
playsinline={playsInline}
>
<source src={videoPath} type={videoType} />
Your browser does not support the video tag. Your browser does not support the video tag.
</video> </video>
</div>

View File

@@ -0,0 +1,7 @@
---
---
<div class="">
<slot />
</div>

View File

@@ -0,0 +1,7 @@
---
---
<div class="space-y-2">
<slot />
</div>

View File

@@ -0,0 +1,43 @@
---
import { v4 as uuidv4 } from "uuid";
const popoverUUID = uuidv4();
const keys: { [key: string]: string } = {
ADCP: "Acoustic doppler current profiler",
COTS: "Consumer off-the-shelf",
CTD: "Conductivity, temperature, and depth sensor",
};
const key: string | undefined = Astro.props.key;
let word: string | undefined = Astro.props.word;
let definition: string | undefined = Astro.props.definition;
if (key && keys.hasOwnProperty(key)) {
word = key;
definition = keys[key];
}
---
<>
<a
href="#"
class="text-fg-brand decoration-caperren-green font-medium underline decoration-dashed hover:no-underline"
data-popover-target={popoverUUID}>{word}</a
>
<div
data-popover
id={popoverUUID}
role="tooltip"
class="text-body border-caperren-green invisible absolute z-90 inline-block w-fit max-w-96 rounded-lg border border-dashed bg-black p-3 text-sm opacity-0 shadow-xs transition-opacity duration-300"
>
<div>
<h3
class="text-heading border-b-caperren-green-dark mb-1 border-b font-semibold"
>
{word}
</h3>
<p>{definition}</p>
</div>
</div>
</>

View File

@@ -8,14 +8,17 @@ export const siteLayout: navLink[] = [
path: "experience", path: "experience",
children: [ children: [
{ {
enabled: false,
navText: "SpaceX", navText: "SpaceX",
path: "spacex", path: "spacex",
children: [ children: [
{ {
enabled: false,
navText: "Hardware Test Engineer I/II", navText: "Hardware Test Engineer I/II",
path: "hardware-test-engineer-i-ii", path: "hardware-test-engineer-i-ii",
}, },
{ {
enabled: false,
navText: "Avionics Test Engineering Internship", navText: "Avionics Test Engineering Internship",
path: "avionics-test-engineering-internship", path: "avionics-test-engineering-internship",
}, },
@@ -26,6 +29,7 @@ export const siteLayout: navLink[] = [
path: "osu-ceoas-ocean-mixing-group", path: "osu-ceoas-ocean-mixing-group",
children: [ children: [
{ {
enabled: false,
navText: "Robotics Oceanographic Surface Sampler", navText: "Robotics Oceanographic Surface Sampler",
path: "robotic-oceanographic-surface-sampler", path: "robotic-oceanographic-surface-sampler",
}, },

View File

@@ -1,15 +1,23 @@
--- ---
import "@styles/global.css"; import "@styles/global.css";
import Navbar from "@components/Navbar.astro";
import Footer from "@components/Footer.astro"; import Footer from "@components/Footer.astro";
import Navbar from "@components/Navbar.astro";
import { pathToMetadata } from "@data/site-layout.ts"; import { pathToMetadata } from "@data/site-layout.ts";
interface Props {
title?: string;
subTitles?: string[];
showTitle?: boolean;
}
const { title, subTitles, showTitle = true } = Astro.props;
const pageTitle = Astro.props.title const pageTitle = Astro.props.title
? `${Astro.props.title} - Corwin Perren` ? `${Astro.props.title} - Corwin Perren`
: "Corwin Perren"; : "Corwin Perren";
const showTitle = Astro.props.showTitle ?? true;
const pageEnabled = pathToMetadata(Astro.url.pathname).enabled ?? true; const pageEnabled = pathToMetadata(Astro.url.pathname).enabled ?? true;
--- ---
@@ -38,12 +46,31 @@ const pageEnabled = pathToMetadata(Astro.url.pathname).enabled ?? true;
<Navbar /> <Navbar />
<main class="mx-6 my-6"> <main class="mx-6 my-6">
{ {
Astro.props.title && showTitle && pageEnabled && ( title && showTitle && pageEnabled && (
<h1 class="font-extrabold md:mb-6 md:text-3xl"> <h1
{Astro.props.title} class={
"text-xl font-extrabold md:text-3xl " +
(subTitles ? "" : "md:mb-6")
}
>
{title}
</h1> </h1>
) )
} }
{
showTitle &&
pageEnabled &&
subTitles?.map((subTitle, index) => (
<p
class={
"text-sm font-bold md:text-xl " +
(index == subTitles.length - 1 ? "mb-2 md:mb-6" : "")
}
>
{subTitle}
</p>
))
}
{pageEnabled && <slot />} {pageEnabled && <slot />}
</main> </main>
</div> </div>

View File

@@ -2,6 +2,6 @@
import BaseLayout from "./BaseLayout.astro"; import BaseLayout from "./BaseLayout.astro";
--- ---
<BaseLayout title={Astro.props.title}> <BaseLayout {...Astro.props}>
<slot /> <slot />
</BaseLayout> </BaseLayout>

View File

@@ -2,6 +2,6 @@
import BaseLayout from "./BaseLayout.astro"; import BaseLayout from "./BaseLayout.astro";
--- ---
<BaseLayout title={Astro.props.title}> <BaseLayout {...Astro.props}>
<slot /> <slot />
</BaseLayout> </BaseLayout>

View File

@@ -1,9 +1,9 @@
--- ---
import BaseLayout from "@layouts/BaseLayout.astro";
import PdfViewer from "@components/Media/PdfViewer.astro"; import PdfViewer from "@components/Media/PdfViewer.astro";
import BaseLayout from "@layouts/BaseLayout.astro";
--- ---
<BaseLayout title={Astro.props.title}> <BaseLayout {...Astro.props}>
<div class="h-dvh"> <div class="h-dvh">
<PdfViewer class="mx-auto" pdf={Astro.props.resume} /> <PdfViewer class="mx-auto" pdf={Astro.props.resume} />
</div> </div>

View File

@@ -1,8 +1,8 @@
--- ---
import BaseLayout from "@layouts/BaseLayout.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro"; import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import Timeline from "@components/Timeline/Timeline.astro";
import Table from "@components/Table.astro"; import Table from "@components/Table.astro";
import Timeline from "@components/Timeline/Timeline.astro";
import BaseLayout from "@layouts/BaseLayout.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts"; import type { carouselGroup } from "@interfaces/image-carousel.ts";
import type { tableData } from "@interfaces/table.ts"; import type { tableData } from "@interfaces/table.ts";

View File

@@ -1,12 +1,15 @@
--- ---
import ExperienceLayout from "@layouts/ExperienceLayout.astro"; import ExperienceLayout from "@layouts/ExperienceLayout.astro";
import H3 from "@components/CustomHtmlWrappers/H3.astro";
import Timeline from "@components/Timeline/Timeline.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import H2 from "@components/CustomHtmlWrappers/H2.astro"; import H2 from "@components/CustomHtmlWrappers/H2.astro";
import H3 from "@components/CustomHtmlWrappers/H3.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import Paragraph from "@components/Paragraph.astro";
import Timeline from "@components/Timeline/Timeline.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts";
import { deploymentTimeline } from "./osu-ceoas-ocean-mixing-group.ts"; import { deploymentTimeline } from "./osu-ceoas-ocean-mixing-group.ts";
import type { carouselGroup } from "@interfaces/image-carousel.ts";
import building from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/building.jpg"; import building from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/building.jpg";
import glacier_selfie from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/glacier-selfie.jpg"; import glacier_selfie from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/glacier-selfie.jpg";
@@ -15,16 +18,34 @@ import iced_in from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-gla
import pushing_icebergs from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/pushing-icebergs.jpg"; import pushing_icebergs from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/pushing-icebergs.jpg";
import ross_at_terminus from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/ross-at-terminus.png"; import ross_at_terminus from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/ross-at-terminus.png";
import ross_on_the_docks from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/ross-on-the-docks.jpg"; import ross_on_the_docks from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/ross-on-the-docks.jpg";
import ross_steller_ice_operations from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/ross-steller-ice-operations.png";
import steller_at_terminus from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/steller-at-terminus.png";
import steller_in_ice_from_above from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/steller-in-ice-from-above.jpg";
import whole_glacier from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/whole-glacier.jpg"; import whole_glacier from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/whole-glacier.jpg";
import working_at_the_docks from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/working-at-the-docks.jpg"; import working_at_the_docks from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/working-at-the-docks.jpg";
import working_trailer from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/working-trailer.jpg"; import working_trailer from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/working-trailer.jpg";
import massive_calving from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/videos/massive-calving-compressed.mp4";
import petersburg_working_timelapse from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/videos/petersburg-working-timelapse-compressed.mp4";
import ross_iceops from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/videos/ross-iceops-compressed.mp4";
import ross_terminus_calving from "@assets/experience/osu-ceoas-ocean-mixing-group/leconte-glacier-deployments/videos/ross-terminus-calving-compressed.mp4";
const videos = [
ross_terminus_calving,
ross_iceops,
massive_calving,
petersburg_working_timelapse,
];
const headerCarouselGroup: carouselGroup = { const headerCarouselGroup: carouselGroup = {
animation: "slide", animation: "slide",
images: [ images: [
ross_at_terminus, ross_at_terminus,
ground_station, ross_steller_ice_operations,
steller_at_terminus,
steller_in_ice_from_above,
whole_glacier, whole_glacier,
ground_station,
glacier_selfie, glacier_selfie,
iced_in, iced_in,
pushing_icebergs, pushing_icebergs,
@@ -34,12 +55,84 @@ const headerCarouselGroup: carouselGroup = {
working_trailer, working_trailer,
], ],
}; };
import InlineLink from "@components/InlineLink.astro";
import Video from "@components/Media/Video.astro";
import Paragraphs from "@components/Paragraphs.astro";
import PopoverWordDefinition from "@components/PopoverWordDefinition.astro";
import { subTitles } from "./osu-ceoas-ocean-mixing-group.ts";
--- ---
<ExperienceLayout title="CEOAS - LeConte Glacier Deployments"> <ExperienceLayout title="LeConte Glacier Deployments" subTitles={subTitles}>
<Carousel carouselGroup={headerCarouselGroup} /> <Carousel carouselGroup={headerCarouselGroup} />
<H2 text="Summary" /> <H2 text="Summary" />
<H3 text="Timeline" /> <H3 text="Timeline" />
<Timeline timeline={deploymentTimeline} /> <Timeline timeline={deploymentTimeline} />
<H3 text="Details" /> <H3 text="Location" />
<iframe
class="w-full"
width="600"
height="450"
src="https://maps.google.com/maps?q=leconte%20glacier&t=k&z=11&ie=UTF8&iwloc=B&output=embed"
></iframe>
<H2 text="Details" />
<Paragraphs>
<Paragraph>
As part of my time working on the
<InlineLink
href="/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler"
>
Robotic Oceanographic Surface Sampler</InlineLink
>, I had the fantastic opportunity to be deployed at the LeConte Glacier
in Alaska! This started in early 2017 with setup and ocean trials in
nearby Petersburg. The team had sent multiple shipping containers with our
robotic platforms and most equipment to assemble, test, and debug them a
few months prior, allowing us to get to work the moment we arrived. We
spent multiple weeks at the docks with our makeshift workstations built
from plywood and pelican cases, validating the hardware we'd sent, and
making adjustments with improved hardware we'd hand-carried on our
flights. This also provided a great opportunity to work out any final
firmware and/or software bugs while the vehicles were still relatively
easy to retrieve. After a short trip back home to recover, and prep any
last minute items we'd forgotten, our research team flew back and headed
for the glacier!
</Paragraph>
<Paragraph>
The towering mountain of ice sits roughly 30 miles from Petersburg, so
we'd commissioned an off-season fishing vessel, Steller, and it's crew, to
take us as close to it as was reasonably safe. The team worked 24 hours a
day, on two shifts, deploying and retrieving the ROSS platforms,
performing repairs (as needed), recovering/processing collected data,
manually deploying the ship's <PopoverWordDefinition key="CTD" />, and
occasionally spending considerable time pushing icebergs the size of
houses away from an <PopoverWordDefinition key="ADCP" /> mounted to Steller
using fiberglass poles. Many hardware failures had to be solved during these
long days, and it was a very rewarding and creative experience to work around
the limitations of this isolated (and salty) environment.
</Paragraph>
<Paragraph>
On top of being a unique engineering and team building experience, LeConte
lives among the most beautiful places I've yet to experience in this life.
There's something special about being somewhere so incredibly remote and
untouched by humans. The pristine evergreen forests, eerie blue-green hues
of the glacier and icebergs, ancient towering mountains, and genuinely
curious looks from local land and marine life unfamiliar with human
presence made it humbly clear that for once we as humans were the odd
ones out. These trips were ones that I will treasure and think back on
fondly on for the rest of my life.
</Paragraph>
</Paragraphs>
<H2 text="Videos" />
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
{
videos.map((video) => (
<Video
videoPath={video}
autoPlay={true}
loop={true}
playsInline={true}
/>
))
}
</div>
</ExperienceLayout> </ExperienceLayout>

View File

@@ -22,3 +22,8 @@ export const deploymentTimeline: timelineEntry[] = [
date: "September 2017", date: "September 2017",
}, },
]; ];
export const subTitles = [
"Oregon State University",
"College of Earth, Ocean, and Atmospheric Sciences",
];

View File

@@ -1,26 +1,29 @@
--- ---
import ExperienceLayout from "@layouts/ExperienceLayout.astro"; import ExperienceLayout from "@layouts/ExperienceLayout.astro";
import H2 from "@components/CustomHtmlWrappers/H2.astro";
import H3 from "@components/CustomHtmlWrappers/H3.astro";
import LinkButton from "@components/LinkButton.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import PdfViewer from "@components/Media/PdfViewer.astro";
import PopoverWordDefinition from "@components/PopoverWordDefinition.astro";
import Timeline from "@components/Timeline/Timeline.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts"; import type { carouselGroup } from "@interfaces/image-carousel.ts";
import type { timelineEntry } from "@interfaces/timeline.ts"; import type { timelineEntry } from "@interfaces/timeline.ts";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import H2 from "@components/CustomHtmlWrappers/H2.astro";
import H3 from "@components/CustomHtmlWrappers/H3.astro";
import LinkButton from "@components/LinkButton.astro";
import PdfViewer from "@components/Media/PdfViewer.astro";
import Timeline from "@components/Timeline/Timeline.astro";
import publication from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-publication.pdf";
import electronics_box from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/electronics-box.jpg"; import electronics_box from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/electronics-box.jpg";
import jet_drive from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/jet-drive.jpg"; import jet_drive from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/jet-drive.jpg";
import ross_on_vessel from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-on-vessel.jpg";
import ross_on_vessel_at_night from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-on-vessel-at-night.jpg"; import ross_on_vessel_at_night from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-on-vessel-at-night.jpg";
import ross_on_vessel from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-on-vessel.jpg";
import publication from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-publication.pdf";
import ross_team from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-team.jpg"; import ross_team from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-team.jpg";
import ui from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ui.jpg"; import ui from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ui.jpg";
import { deploymentTimeline } from "./osu-ceoas-ocean-mixing-group.ts"; import {
deploymentTimeline,
subTitles,
} from "./osu-ceoas-ocean-mixing-group.ts";
const headerCarouselGroup: carouselGroup = { const headerCarouselGroup: carouselGroup = {
animation: "slide", animation: "slide",
@@ -49,7 +52,10 @@ const timeline: timelineEntry[] = [
]; ];
--- ---
<ExperienceLayout title="CEOAS - Robotic Oceanographic Surface Sampler"> <ExperienceLayout
title="Robotic Oceanographic Surface Sampler"
subTitles={subTitles}
>
<Carousel carouselGroup={headerCarouselGroup} /> <Carousel carouselGroup={headerCarouselGroup} />
<div class="mt-4 flex items-center justify-center"> <div class="mt-4 flex items-center justify-center">
<LinkButton <LinkButton
@@ -62,7 +68,13 @@ const timeline: timelineEntry[] = [
<Timeline timeline={timeline} /> <Timeline timeline={timeline} />
<H3 text="Key Takeaways" /> <H3 text="Key Takeaways" />
<ul class="list-inside list-disc"> <ul class="list-inside list-disc">
<li>One</li> <li>
<div class="inline-block">
Assembled, fabricated, and debugged both custom and
<PopoverWordDefinition key="COTS" />
hardware and electronics.
</div>
</li>
<li>Two</li> <li>Two</li>
<li>Three</li> <li>Three</li>
</ul> </ul>

View File

@@ -1,9 +1,9 @@
--- ---
import ExperienceLayout from "@layouts/ExperienceLayout.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro"; import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts";
import YtVideo from "@components/Media/YtVideo.astro"; import YtVideo from "@components/Media/YtVideo.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts";
import type { videoConfig } from "@interfaces/video.ts"; import type { videoConfig } from "@interfaces/video.ts";
import ExperienceLayout from "@layouts/ExperienceLayout.astro";
const headerCarouselGroup: carouselGroup = { const headerCarouselGroup: carouselGroup = {
animation: "slide", animation: "slide",

View File

@@ -1,7 +1,7 @@
--- ---
import ExperienceLayout from "@layouts/ExperienceLayout.astro";
import Timeline from "@components/Timeline/Timeline.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro"; import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import Timeline from "@components/Timeline/Timeline.astro";
import ExperienceLayout from "@layouts/ExperienceLayout.astro";
import spring_2019_interns from "@assets/experience/spacex/avionics-test-engineering-internship/spring-2019-interns.jpg"; import spring_2019_interns from "@assets/experience/spacex/avionics-test-engineering-internship/spring-2019-interns.jpg";

View File

@@ -1,7 +1,7 @@
--- ---
import ExperienceLayout from "@layouts/ExperienceLayout.astro";
import Timeline from "@components/Timeline/Timeline.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro"; import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import Timeline from "@components/Timeline/Timeline.astro";
import ExperienceLayout from "@layouts/ExperienceLayout.astro";
import starlink_headquarters_selfie from "@assets/experience/spacex/hardware-test-engineer-i-ii/starlink-headquarters-selfie.jpg"; import starlink_headquarters_selfie from "@assets/experience/spacex/hardware-test-engineer-i-ii/starlink-headquarters-selfie.jpg";

View File

@@ -1,6 +1,6 @@
--- ---
import HobbyLayout from "@layouts/HobbyLayout.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro"; import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import HobbyLayout from "@layouts/HobbyLayout.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts"; import type { carouselGroup } from "@interfaces/image-carousel.ts";

View File

@@ -1,6 +1,6 @@
--- ---
import HobbyLayout from "@layouts/HobbyLayout.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro"; import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import HobbyLayout from "@layouts/HobbyLayout.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts"; import type { carouselGroup } from "@interfaces/image-carousel.ts";

View File

@@ -1,6 +1,6 @@
--- ---
import HobbyLayout from "@layouts/HobbyLayout.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro"; import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import HobbyLayout from "@layouts/HobbyLayout.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts"; import type { carouselGroup } from "@interfaces/image-carousel.ts";

View File

@@ -1,11 +1,11 @@
--- ---
import HobbyLayout from "@layouts/HobbyLayout.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro"; import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import HobbyLayout from "@layouts/HobbyLayout.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts"; import type { carouselGroup } from "@interfaces/image-carousel.ts";
import enclosure_front from "@assets/hobby/homelab/offsite-backup-rack/enclosure-front.jpg";
import enclosure_front_pc_panel_open from "@assets/hobby/homelab/offsite-backup-rack/enclosure-front-pc-panel-open.jpg"; import enclosure_front_pc_panel_open from "@assets/hobby/homelab/offsite-backup-rack/enclosure-front-pc-panel-open.jpg";
import enclosure_front from "@assets/hobby/homelab/offsite-backup-rack/enclosure-front.jpg";
import enclosure_left from "@assets/hobby/homelab/offsite-backup-rack/enclosure-left.jpg"; import enclosure_left from "@assets/hobby/homelab/offsite-backup-rack/enclosure-left.jpg";
import enclosure_rear from "@assets/hobby/homelab/offsite-backup-rack/enclosure-rear.jpg"; import enclosure_rear from "@assets/hobby/homelab/offsite-backup-rack/enclosure-rear.jpg";
import enclosure_right from "@assets/hobby/homelab/offsite-backup-rack/enclosure-right.jpg"; import enclosure_right from "@assets/hobby/homelab/offsite-backup-rack/enclosure-right.jpg";

View File

@@ -1,16 +1,16 @@
--- ---
import HobbyLayout from "@layouts/HobbyLayout.astro";
import LinkButton from "@components/LinkButton.astro"; import LinkButton from "@components/LinkButton.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro"; import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import HobbyLayout from "@layouts/HobbyLayout.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts"; import type { carouselGroup } from "@interfaces/image-carousel.ts";
import bottom_fasteners_installed from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/bottom-fasteners-installed.jpg"; import bottom_fasteners_installed from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/bottom-fasteners-installed.jpg";
import closed_seam from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/closed-seam.jpg"; import closed_seam from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/closed-seam.jpg";
import closed_top_buttons_installed from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/closed-top-buttons-installed.jpg"; import closed_top_buttons_installed from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/closed-top-buttons-installed.jpg";
import inside_top_and_bottom from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/inside-top-and-bottom.jpg";
import inside_top_and_bottom_buttons_installed from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/inside-top-and-bottom-buttons-installed.jpg"; import inside_top_and_bottom_buttons_installed from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/inside-top-and-bottom-buttons-installed.jpg";
import inside_top_and_bottom_with_buttons from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/inside-top-and-bottom-with-buttons.jpg"; import inside_top_and_bottom_with_buttons from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/inside-top-and-bottom-with-buttons.jpg";
import inside_top_and_bottom from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/inside-top-and-bottom.jpg";
import installed_on_bike_handlebars_reference from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/installed-on-bike-handlebars-reference.jpg"; import installed_on_bike_handlebars_reference from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/installed-on-bike-handlebars-reference.jpg";
import installed_on_bike_riders_position from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/installed-on-bike-riders-position.jpg"; import installed_on_bike_riders_position from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/installed-on-bike-riders-position.jpg";
import top_and_bottom from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/top-and-bottom.jpg"; import top_and_bottom from "@assets/hobby/motorcycling/custom-accessories/chubby-buttons-2-mount/top-and-bottom.jpg";

View File

@@ -1,14 +1,14 @@
--- ---
import HobbyLayout from "@layouts/HobbyLayout.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro"; import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import HobbyLayout from "@layouts/HobbyLayout.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts"; import type { carouselGroup } from "@interfaces/image-carousel.ts";
import kz750 from "@assets/hobby/motorcycling/lineup/1979-kawasaki-kz750-senior-photo.jpg"; import kz750 from "@assets/hobby/motorcycling/lineup/1979-kawasaki-kz750-senior-photo.jpg";
import ninja600 from "@assets/hobby/motorcycling/lineup/1991-kawasaki-ninja-600r.jpg"; import ninja600 from "@assets/hobby/motorcycling/lineup/1991-kawasaki-ninja-600r.jpg";
import concours from "@assets/hobby/motorcycling/lineup/1999-kawasaki-concours.jpg";
import concours_offroad from "@assets/hobby/motorcycling/lineup/1999-kawasaki-concours-offroad.jpg"; import concours_offroad from "@assets/hobby/motorcycling/lineup/1999-kawasaki-concours-offroad.jpg";
import concours_trailer from "@assets/hobby/motorcycling/lineup/1999-kawasaki-concours-with-trailer.jpg"; import concours_trailer from "@assets/hobby/motorcycling/lineup/1999-kawasaki-concours-with-trailer.jpg";
import concours from "@assets/hobby/motorcycling/lineup/1999-kawasaki-concours.jpg";
import drz400 from "@assets/hobby/motorcycling/lineup/2005-suzuki-drz-400.jpg"; import drz400 from "@assets/hobby/motorcycling/lineup/2005-suzuki-drz-400.jpg";
import fjr1300 from "@assets/hobby/motorcycling/lineup/2015-fjr-1300-mountaintop.jpg"; import fjr1300 from "@assets/hobby/motorcycling/lineup/2015-fjr-1300-mountaintop.jpg";
import sg400 from "@assets/hobby/motorcycling/lineup/2021-csc-sg400.jpg"; import sg400 from "@assets/hobby/motorcycling/lineup/2021-csc-sg400.jpg";

View File

@@ -1,6 +1,6 @@
--- ---
import BaseLayout from "../layouts/BaseLayout.astro";
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro"; import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
import BaseLayout from "../layouts/BaseLayout.astro";
import type { carouselGroup } from "@interfaces/image-carousel.ts"; import type { carouselGroup } from "@interfaces/image-carousel.ts";

View File

@@ -1,6 +1,6 @@
--- ---
import ResumeLayout from "@layouts/ResumeLayout.astro";
import resume from "@assets/resume/corwin_perren_2019-07-01_hardware_test_engineer.pdf"; import resume from "@assets/resume/corwin_perren_2019-07-01_hardware_test_engineer.pdf";
import ResumeLayout from "@layouts/ResumeLayout.astro";
--- ---
<ResumeLayout title="2019-07-01 - Hardware Test Engineer" resume={resume} /> <ResumeLayout title="2019-07-01 - Hardware Test Engineer" resume={resume} />

View File

@@ -1,6 +1,6 @@
--- ---
import ResumeLayout from "@layouts/ResumeLayout.astro";
import resume from "@assets/resume/corwin_perren_2025-10-27-infrastructure_engineer.pdf"; import resume from "@assets/resume/corwin_perren_2025-10-27-infrastructure_engineer.pdf";
import ResumeLayout from "@layouts/ResumeLayout.astro";
--- ---
<ResumeLayout title="2025-10-27 - Infrastructure Engineer" resume={resume} /> <ResumeLayout title="2025-10-27 - Infrastructure Engineer" resume={resume} />

View File

@@ -1,6 +1,5 @@
import { test, expect } from "@playwright/test";
import { getPaths } from "@data/site-layout.ts"; import { getPaths } from "@data/site-layout.ts";
import { expect, test } from "@playwright/test";
for (const pagePath of getPaths()) { for (const pagePath of getPaths()) {
test(`${pagePath}: Navigable`, async ({ page }) => { test(`${pagePath}: Navigable`, async ({ page }) => {

View File

@@ -1,7 +1,6 @@
import { getPaths, siteLayout } from "@data/site-layout.ts";
import { expect, test } from "vitest"; import { expect, test } from "vitest";
import { siteLayout, getPaths } from "@data/site-layout.ts";
export const setDifference = <T>(a: Set<T>, b: Set<T>) => export const setDifference = <T>(a: Set<T>, b: Set<T>) =>
new Set([...a].filter((x) => !b.has(x))); new Set([...a].filter((x) => !b.has(x)));

View File

@@ -1,5 +1,5 @@
import path from "path";
import { getViteConfig } from "astro/config"; import { getViteConfig } from "astro/config";
import path from "path";
export default getViteConfig( export default getViteConfig(
{ {