Merge pull request 'Added core content for hardware test engineer page' (#17) from website-content-updates into main
Reviewed-on: #17
@@ -4,6 +4,7 @@ ASSEM
|
||||
astrojs
|
||||
Atmel
|
||||
barebones
|
||||
Bitwarden
|
||||
Candian
|
||||
caperren
|
||||
CEOAS
|
||||
@@ -13,6 +14,9 @@ CONSERV
|
||||
Corwin
|
||||
dangerousthings
|
||||
Dechorionator
|
||||
dockerization
|
||||
dockerizing
|
||||
drumheller
|
||||
ebox
|
||||
fhhs
|
||||
flowbite
|
||||
@@ -25,6 +29,7 @@ iceops
|
||||
ITAR
|
||||
Jetson
|
||||
KFSK
|
||||
Labjack
|
||||
leconte
|
||||
Loctite
|
||||
luxon
|
||||
@@ -36,9 +41,11 @@ offroad
|
||||
Onshape
|
||||
OSSM
|
||||
OSURC
|
||||
Passthroughs
|
||||
Perren
|
||||
Perren's
|
||||
Pixhawk
|
||||
Protocase
|
||||
pubpath
|
||||
RFID
|
||||
RSSI
|
||||
@@ -46,15 +53,19 @@ SARL
|
||||
Shuttlebox
|
||||
sinnhuber
|
||||
sitemapindex
|
||||
Smartsheet
|
||||
ssds
|
||||
Starlink
|
||||
steller
|
||||
Steller
|
||||
Teamcenter
|
||||
timelapse
|
||||
triaging
|
||||
trivago
|
||||
Unstow
|
||||
uuidv
|
||||
vaapi
|
||||
vitest
|
||||
Waterjet
|
||||
Zebrafish
|
||||
zscan
|
||||
|
||||
|
After Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 10 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 3.3 MiB |
|
After Width: | Height: | Size: 10 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 10 MiB |
|
After Width: | Height: | Size: 14 MiB |
|
After Width: | Height: | Size: 12 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 600 KiB |
|
After Width: | Height: | Size: 701 KiB |
BIN
src/assets/hobby/homelab/offsite-backup-rack/installed.jpg
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
@@ -1,13 +1,26 @@
|
||||
---
|
||||
import type { videoConfig } from "@interfaces/video.ts";
|
||||
import type { videoConfig } from "@interfaces/yt-video.ts";
|
||||
|
||||
const config: videoConfig = Astro.props.videoConfig;
|
||||
interface Props extends videoConfig {}
|
||||
|
||||
const {
|
||||
videoPath,
|
||||
videoTitle,
|
||||
width = "1920",
|
||||
height = "1080",
|
||||
autoPlay = false,
|
||||
} = Astro.props;
|
||||
|
||||
const aspect = `${width} / ${height}`;
|
||||
---
|
||||
|
||||
<iframe
|
||||
class="h-128 w-full max-w-1/2"
|
||||
src={config.videoPath}
|
||||
title={config.videoTitle ?? ""}
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen></iframe>
|
||||
<div class="mx-auto my-auto w-full" style={`aspect-ratio: ${aspect};`}>
|
||||
<iframe
|
||||
src={videoPath}
|
||||
title={videoTitle}
|
||||
class="h-full w-full"
|
||||
allow={"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; " +
|
||||
(autoPlay ? "autoplay;" : "")}
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,6 @@ export const siteLayout: navLink[] = [
|
||||
path: "spacex",
|
||||
children: [
|
||||
{
|
||||
enabled: false,
|
||||
navText: "Hardware Test Engineer I/II",
|
||||
path: "hardware-test-engineer-i-ii",
|
||||
},
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
export interface videoConfig {
|
||||
videoTitle?: string;
|
||||
videoPath: string;
|
||||
videoType?: string;
|
||||
}
|
||||
9
src/interfaces/yt-video.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export interface videoConfig {
|
||||
videoPath: string;
|
||||
videoTitle?: string;
|
||||
|
||||
width?: number; // “design” width
|
||||
height?: number; // “design” height
|
||||
|
||||
autoPlay?: boolean;
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import type { timelineEntry } from "@interfaces/timeline.ts";
|
||||
|
||||
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 ross_battery_box from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-battery-box.jpg";
|
||||
import ross_ebox_4p0 from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-ebox-4p0.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";
|
||||
@@ -42,6 +43,7 @@ const headerCarouselGroup: carouselGroup = {
|
||||
ross_on_vessel_at_night,
|
||||
ross_ebox_4p0,
|
||||
electronics_box,
|
||||
ross_battery_box,
|
||||
jet_drive,
|
||||
ui,
|
||||
],
|
||||
@@ -104,7 +106,7 @@ const categorizedSkills: categorySkills[] = [
|
||||
skills: [
|
||||
{ item: "Git" },
|
||||
{
|
||||
item: "Programming Languages",
|
||||
item: "Programming",
|
||||
subItems: [
|
||||
{ item: "Python 2/3" },
|
||||
{ item: "Bash Shell Scripting" },
|
||||
|
||||
@@ -1,279 +1,71 @@
|
||||
---
|
||||
import H2 from "@components/H2.astro";
|
||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||
import YtVideo from "@components/Media/YtVideo.astro";
|
||||
import PageGroup from "@components/PageGroup.astro";
|
||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||
import type { videoConfig } from "@interfaces/video.ts";
|
||||
import type { videoConfig } from "@interfaces/yt-video.ts";
|
||||
import ExperienceLayout from "@layouts/ExperienceLayout.astro";
|
||||
|
||||
import circ_champions from "@assets/experience/osu-robotics-club/mars-rover-software-lead/circ-champions.jpg";
|
||||
import corwin_at_competition from "@assets/experience/osu-robotics-club/mars-rover-software-lead/corwin-at-competition.jpg";
|
||||
import drumheller_team_photo from "@assets/experience/osu-robotics-club/mars-rover-software-lead/drumheller-team-photo.jpg";
|
||||
import final_ground_station_gui from "@assets/experience/osu-robotics-club/mars-rover-software-lead/final-ground-station-gui.png";
|
||||
import ground_station_at_competition from "@assets/experience/osu-robotics-club/mars-rover-software-lead/ground-station-at-competition.jpg";
|
||||
import iris_pcb_assembly_timelapse_converted from "@assets/experience/osu-robotics-club/mars-rover-software-lead/iris-pcb-assembly-timelapse-converted.mp4";
|
||||
import iris_pcb_working from "@assets/experience/osu-robotics-club/mars-rover-software-lead/iris-pcb-working.jpg";
|
||||
import rover_at_competition_from_above from "@assets/experience/osu-robotics-club/mars-rover-software-lead/rover-at-competition-from-above.jpg";
|
||||
import rover_at_competition_pickup_test from "@assets/experience/osu-robotics-club/mars-rover-software-lead/rover-at-competition-pickup-test.jpg";
|
||||
import rover_gimbal_test_converted from "@assets/experience/osu-robotics-club/mars-rover-software-lead/rover-gimbal-test-converted.mp4";
|
||||
import rover_pose_with_dinosaur from "@assets/experience/osu-robotics-club/mars-rover-software-lead/rover-pose-with-dinosaur.jpg";
|
||||
import rover_with_arm_pose_in_desert from "@assets/experience/osu-robotics-club/mars-rover-software-lead/rover-with-arm-pose-in-desert.jpg";
|
||||
import silly_poke from "@assets/experience/osu-robotics-club/mars-rover-software-lead/silly-poke.gif";
|
||||
import Video from "@components/Media/Video.astro";
|
||||
|
||||
const headerCarouselGroup: carouselGroup = {
|
||||
animation: "slide",
|
||||
images: [],
|
||||
images: [
|
||||
circ_champions,
|
||||
drumheller_team_photo,
|
||||
rover_with_arm_pose_in_desert,
|
||||
rover_pose_with_dinosaur,
|
||||
corwin_at_competition,
|
||||
rover_at_competition_from_above,
|
||||
rover_at_competition_pickup_test,
|
||||
final_ground_station_gui,
|
||||
ground_station_at_competition,
|
||||
iris_pcb_working,
|
||||
silly_poke,
|
||||
],
|
||||
};
|
||||
|
||||
const videoList: videoConfig[] = [
|
||||
{
|
||||
videoTitle: "Ground Station Software Quick Overview",
|
||||
videoPath: "https://www.youtube-nocookie.com/embed/ZjGW-HWapVA",
|
||||
},
|
||||
{
|
||||
videoTitle: "Rover Software Environment And Full Code Overview",
|
||||
videoPath: "https://www.youtube-nocookie.com/embed/sceA2ZbEV8Y",
|
||||
},
|
||||
const videos: videoConfig[] = [
|
||||
{ videoPath: iris_pcb_assembly_timelapse_converted },
|
||||
{ videoPath: rover_gimbal_test_converted },
|
||||
{ videoPath: "https://www.youtube-nocookie.com/embed/ZjGW-HWapVA" },
|
||||
{ videoPath: "https://www.youtube-nocookie.com/embed/sceA2ZbEV8Y0" },
|
||||
];
|
||||
---
|
||||
|
||||
<ExperienceLayout title="OSURC - Software Team Lead">
|
||||
<Carousel carouselGroup={headerCarouselGroup} />
|
||||
|
||||
<h2 class="my-4 font-bold underline md:text-2xl">
|
||||
Ground Station Readouts & Features
|
||||
</h2>
|
||||
<ul class="list-inside list-disc space-y-1">
|
||||
<li>Clock</li>
|
||||
<li>Event Timer</li>
|
||||
<li>
|
||||
Status Indication
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Rover Connection</li>
|
||||
<li>Controller Connection Info</li>
|
||||
<li>Radio Stats</li>
|
||||
<li>GPS Stats</li>
|
||||
<li>NVidia Jetson TX2 Computer Stats</li>
|
||||
<li>Battery Voltage w/Low Battery Warning</li>
|
||||
<li>Wheel Connections</li>
|
||||
<li>Camera Connections</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Radio Direction Finding
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Raw Radio RSSI Indication</li>
|
||||
<li>Radio RSSI Pulse Frequency w/Validity Indication</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Arm
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>
|
||||
Special Movements
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Stow Arm</li>
|
||||
<li>Unstow Arm</li>
|
||||
<li>Upright Arm</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Calibrate Arm</li>
|
||||
<li>Clear Arm Fault</li>
|
||||
<li>Reset Arm Motor Drivers</li>
|
||||
<li>
|
||||
Task Movements
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Approach Oxygen Tank</li>
|
||||
<li>Depart Oxygen Tank</li>
|
||||
<li>Approach Light Beacon</li>
|
||||
<li>Depart Light Beacon</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Mining/Science
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Bucket Weight Measurement</li>
|
||||
<li>Bucket Lift/Tilt Position Readouts</li>
|
||||
<li>
|
||||
Preset Bucket Movements
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Mining Transport</li>
|
||||
<li>Mining Measure</li>
|
||||
<li>Mining Scoop</li>
|
||||
<li>Science Panorama</li>
|
||||
<li>Mining Sample</li>
|
||||
<li>Mining Probe</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Science Probe Readings
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Temp in C</li>
|
||||
<li>Moisture %</li>
|
||||
<li>Loss Tangent</li>
|
||||
<li>Soil Electrical Conductivity</li>
|
||||
<li>Real Dielectric Permittivity</li>
|
||||
<li>Imaginary Dielectric Permittivity</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Science Camera Controls
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>
|
||||
Video Output Selection
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Network Video</li>
|
||||
<li>Camera LCD</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Photo Controls
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Zoom In One Step</li>
|
||||
<li>Zoom Out One Step</li>
|
||||
<li>Full Zoom In</li>
|
||||
<li>Full Zoom Out</li>
|
||||
<li>Shoot Photo</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
SSH Console
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>SSH Terminal Display</li>
|
||||
<li>SSH Command Entry</li>
|
||||
<li>
|
||||
Preset Commands
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Network Host Scan</li>
|
||||
<li>List Wifi Networks</li>
|
||||
<li>Equipment Login and Help</li>
|
||||
<li>Equipment Logout</li>
|
||||
<li>Equipment Status</li>
|
||||
<li>Equipment Start</li>
|
||||
<li>Equipment Stop</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Connect/Disconnect Rover Wifi by SSID</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Settings
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Map Selection</li>
|
||||
<li>Map Zoom Level</li>
|
||||
<li>Rover Wifi Radio Channel Selection</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Mapping Display
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Shows Google Map Terrain</li>
|
||||
<li>Shows Rover Location And Orientation</li>
|
||||
<li>Shows Rover GPS Coordinates</li>
|
||||
<li>Shows Saved Waypoints</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Waypoint Entry / Editing
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Name Entry For Landmarks</li>
|
||||
<li>GPS Entry in Decimal</li>
|
||||
<li>GPS Entry in Degree/Minute/Second</li>
|
||||
<li>Waypoint Color Choice</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Navigation Waypoints
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Shows And Allows Editing Of Nav Waypoints</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Landmark Waypoints
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Shows And Allows Editing Of Landmark Waypoints</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Arm Joint Positions
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Positions Of Six Arm Joints In Revolutions</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Gripper Joint Positions
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Positions Shown As Raw Encoder Positions</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Arm Motor Drive Statuses
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Communication/Movement/Fault Statuses For All Six Arm Joints</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Gripper Mode Readouts
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Gripper Mode Control State</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Xbox Control Mode
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Showed Whether Xbox Controller Moving Arm Or Mining</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Heading and Goal Indication w/Compass
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Raw Heading Indication</li>
|
||||
<li>Goal Indication (Unused)</li>
|
||||
<li>Compass Heading Indication</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Low Resolution Mode
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Controlled Low Resolution Fallback Mode During Radio Failure</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Current Speed
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>GPS Speed</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Speed Limit
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>% Of Max Rover Speed As Limit</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Tank Drive Output
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>% Of Total Power To Left/Right Rover Drive Systems</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
IMU Readings
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>Pitch/Roll Readings In +/- 1 Readout</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Triple Camera Displays
|
||||
<ul class="list-inside list-disc space-y-1 ps-5">
|
||||
<li>One Primary Video Display</li>
|
||||
<li>Two Secondary Video Displays</li>
|
||||
<li>Named Display For Currently Viewed Camera</li>
|
||||
<li>Ability To Set Each Display To Any Camera</li>
|
||||
<li>Ability to Disable Any Camera</li>
|
||||
<li>Ability to Pan/Tilt Any Camera</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 class="my-4 font-bold underline md:text-2xl">
|
||||
Rover Demos and Software Overviews
|
||||
</h2>
|
||||
{
|
||||
videoList.map((video) => (
|
||||
<div>
|
||||
<h3 class="my-4 font-bold md:text-lg">{video.videoTitle}</h3>
|
||||
<YtVideo videoConfig={video} />
|
||||
</div>
|
||||
))
|
||||
}
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Videos</H2></Fragment>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
{
|
||||
videos.map((video) =>
|
||||
video.videoPath.startsWith("https://www.youtube") ? (
|
||||
<YtVideo
|
||||
videoPath={video.videoPath}
|
||||
width={video.width}
|
||||
height={video.height}
|
||||
/>
|
||||
) : (
|
||||
<Video videoPath={video.videoPath} />
|
||||
),
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</PageGroup>
|
||||
</ExperienceLayout>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
import H2 from "@components/H2.astro";
|
||||
import H3 from "@components/H3.astro";
|
||||
import InlineLink from "@components/InlineLink.astro";
|
||||
import Li from "@components/Li.astro";
|
||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||
import PageGroup from "@components/PageGroup.astro";
|
||||
@@ -15,7 +16,6 @@ import ExperienceLayout from "@layouts/ExperienceLayout.astro";
|
||||
import spring_2019_interns from "@assets/experience/spacex/avionics-test-engineering-internship/spring-2019-interns.jpg";
|
||||
import swag from "@assets/experience/spacex/avionics-test-engineering-internship/swag.jpg";
|
||||
|
||||
import InlineLink from "@components/InlineLink.astro";
|
||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||
import type { categorySkills } from "@interfaces/skill-matrix.ts";
|
||||
import type { timelineEntry } from "@interfaces/timeline.ts";
|
||||
@@ -42,13 +42,18 @@ const categorizedSkills: categorySkills[] = [
|
||||
skills: [
|
||||
{ item: "Git" },
|
||||
{
|
||||
item: "Programming Languages",
|
||||
item: "Programming",
|
||||
subItems: [
|
||||
{ item: "Python 2/3" },
|
||||
{ item: "Bash Shell Scripting" },
|
||||
{ item: "Microsoft SQL" },
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Methodologies",
|
||||
subItems: [{ item: "Test Driven Development" }, { item: "Agile" }],
|
||||
},
|
||||
|
||||
{
|
||||
item: "Atlassian Suite",
|
||||
subItems: [
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
---
|
||||
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 H2 from "@components/H2.astro";
|
||||
import H3 from "@components/H3.astro";
|
||||
import InlineLink from "@components/InlineLink.astro";
|
||||
import Li from "@components/Li.astro";
|
||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||
import PageGroup from "@components/PageGroup.astro";
|
||||
import Paragraph from "@components/Paragraph.astro";
|
||||
import Paragraphs from "@components/Paragraphs.astro";
|
||||
import SkillMatrix from "@components/SkillMatrix/SkillMatrix.astro";
|
||||
import Timeline from "@components/Timeline/Timeline.astro";
|
||||
import Ul from "@components/Ul.astro";
|
||||
|
||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||
import type { categorySkills } from "@interfaces/skill-matrix.ts";
|
||||
import type { timelineEntry } from "@interfaces/timeline.ts";
|
||||
|
||||
import five_year_patch from "@assets/experience/spacex/hardware-test-engineer-i-ii/five-year-patch.jpg";
|
||||
import starlink_headquarters_selfie from "@assets/experience/spacex/hardware-test-engineer-i-ii/starlink-headquarters-selfie.jpg";
|
||||
import starlink_patch from "@assets/experience/spacex/hardware-test-engineer-i-ii/starlink-patch.jpg";
|
||||
|
||||
const headerCarouselGroup: carouselGroup = {
|
||||
animation: "slide",
|
||||
images: [starlink_headquarters_selfie],
|
||||
images: [starlink_headquarters_selfie, five_year_patch, starlink_patch],
|
||||
};
|
||||
|
||||
const timeline: timelineEntry[] = [
|
||||
@@ -43,56 +56,399 @@ const timeline: timelineEntry[] = [
|
||||
"Celebrated five and a half years of helping put thousands of satellites, and dozens of rockets, into orbit",
|
||||
},
|
||||
];
|
||||
|
||||
const categorizedSkills: categorySkills[] = [
|
||||
{
|
||||
category: "Software & Environments",
|
||||
skills: [
|
||||
{
|
||||
item: "Version Control",
|
||||
subItems: [{ item: "Git" }, { item: "Subversion" }],
|
||||
},
|
||||
{
|
||||
item: "Programming",
|
||||
subItems: [
|
||||
{
|
||||
item: "Languages",
|
||||
subItems: [
|
||||
{ item: "Python 2/3" },
|
||||
{ item: "Bash Shell Scripting" },
|
||||
{ item: "High-Level Embedded C/C++ (Arduino/Teensy)" },
|
||||
{ item: "HTML" },
|
||||
{ item: "CSS" },
|
||||
{ item: "Typescript/Javascript" },
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Databases",
|
||||
subItems: [
|
||||
{ item: "Postgres" },
|
||||
{ item: "Microsoft SQL" },
|
||||
{ item: "MySQL" },
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "DevOps",
|
||||
subItems: [
|
||||
{ item: "Docker" },
|
||||
{ item: "Ansible" },
|
||||
{ item: "Kubernetes" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Methodologies",
|
||||
subItems: [{ item: "Test Driven Development" }, { item: "Agile" }],
|
||||
},
|
||||
{
|
||||
item: "Operating Systems",
|
||||
subItems: [
|
||||
{
|
||||
item: "Linux",
|
||||
subItems: [{ item: "Centos" }, { item: "Ubuntu" }],
|
||||
},
|
||||
{ item: "Microsoft Windows" },
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Applications",
|
||||
subItems: [
|
||||
{
|
||||
item: "Atlassian",
|
||||
subItems: [
|
||||
{ item: "Jira" },
|
||||
{ item: "Bitbucket" },
|
||||
{ item: "Confluence" },
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Monitoring/Metrics",
|
||||
subItems: [
|
||||
{ item: "Grafana" },
|
||||
{ item: "Sentry" },
|
||||
{ item: "OpsGenie" },
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Secrets",
|
||||
subItems: [{ item: "Bitwarden" }, { item: "Hashicorp Vault" }],
|
||||
},
|
||||
{
|
||||
item: "Other",
|
||||
subItems: [
|
||||
{ item: "Microsoft Office Suite" },
|
||||
{ item: "Smartsheet" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
category: "Electrical",
|
||||
skills: [
|
||||
{
|
||||
item: "Schematic & PCB Design",
|
||||
subItems: [
|
||||
{
|
||||
item: "Software",
|
||||
subItems: [
|
||||
{ item: "Altium Designer" },
|
||||
{ item: "Mentor Graphics PADS" },
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "PCB Features",
|
||||
subItems: [
|
||||
{ item: "Multi-layer (up to 16)" },
|
||||
{ item: "Impedance Controlled Designs" },
|
||||
{ item: "High Power Designs" },
|
||||
{ item: "Power Simulation" },
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Manufacturing",
|
||||
subItems: [
|
||||
{ item: "Gerber Export" },
|
||||
{ item: "BOM Management" },
|
||||
{ item: "Board-House Assembly" },
|
||||
{ item: "In-House Assembly" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Electrical Diagnostics",
|
||||
subItems: [
|
||||
{ item: "Multimeters" },
|
||||
{ item: "Electronic Loads" },
|
||||
{ item: "Oscilloscopes" },
|
||||
{ item: "Logic Analyzers" },
|
||||
{ item: "LCR Meters" },
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Harnessing Fabrication",
|
||||
subItems: [
|
||||
{ item: "DC Low-Power & Signal" },
|
||||
{ item: "DC High-Power" },
|
||||
{ item: "Sub-Microwave RF" },
|
||||
{ item: "Vacuum Rated Harnesses" },
|
||||
{ item: "Vacuum Chamber Harness Passthroughs" },
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Test Rack Equipment",
|
||||
subItems: [
|
||||
{ item: "Custom Fixture Design/Fabrication" },
|
||||
{ item: "Single/Bi-Directional Power Supplies" },
|
||||
{ item: "Electronic Loads" },
|
||||
{ item: "NI Test Hardware" },
|
||||
{ item: "Labjack" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
category: "Mechanical",
|
||||
skills: [
|
||||
{ item: "Siemens Teamcenter PLM" },
|
||||
{
|
||||
item: "3D Modeling",
|
||||
subItems: [
|
||||
{ item: "Siemens NX" },
|
||||
|
||||
{ item: "Protocase Designer" },
|
||||
{ item: "FreeCAD" },
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Fabrication",
|
||||
subItems: [
|
||||
{ item: "Laser Cutting" },
|
||||
{ item: "3D Printing" },
|
||||
{ item: "CNC" },
|
||||
{ item: "Waterjet" },
|
||||
{ item: "Hand Tools" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
category: "Other",
|
||||
skills: [
|
||||
{
|
||||
item: "Specialty Tests",
|
||||
subItems: [
|
||||
{ item: "Highly Accelerated Life Testing" },
|
||||
{ item: "Thermal Vacuum Chamber Testing" },
|
||||
{ item: "Vibration Testing" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
---
|
||||
|
||||
<ExperienceLayout title="SpaceX - Hardware Test Engineer I/II">
|
||||
<ExperienceLayout
|
||||
title="Hardware Test Engineer I/II"
|
||||
subTitles={["Space Exploration Technologies Corporation"]}
|
||||
>
|
||||
<Carousel carouselGroup={headerCarouselGroup} />
|
||||
<h2 class="my-4 font-bold md:text-2xl">Summary</h2>
|
||||
<h3 class="my-4 font-bold md:text-lg">Timeline</h3>
|
||||
<Timeline timeline={timeline} />
|
||||
<h3 class="my-4 font-bold md:text-lg">Key Takeaways</h3>
|
||||
<ul class="list-inside list-disc">
|
||||
<li>
|
||||
Created test systems which validated ~4500 Starlink satellite flight
|
||||
computers, and ~4000 power boards
|
||||
</li>
|
||||
<li>
|
||||
Developed program-critical infrastructure that enabled efficient triage,
|
||||
management, and tracking of hardware failures
|
||||
</li>
|
||||
<li>
|
||||
Designed and deployed automated, unified, and containerized infrastructure
|
||||
to greatly increase application reliability and development speed
|
||||
</li>
|
||||
</ul>
|
||||
<h3 class="my-4 font-bold md:text-lg">Skills Used</h3>
|
||||
<div
|
||||
class="border-caperren-green relative grid grid-flow-row gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
|
||||
>
|
||||
<div>
|
||||
<div class="text-sm font-extrabold">Software</div>
|
||||
<hr class="text-caperren-green" />
|
||||
<ul class="list-inside list-disc text-sm">
|
||||
<li>Python</li>
|
||||
<li>Test Driven Development</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-sm font-extrabold">Electrical</div>
|
||||
<hr class="text-caperren-green" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-sm font-extrabold">Mechanical</div>
|
||||
<hr class="text-caperren-green" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-sm font-extrabold">Other</div>
|
||||
<hr class="text-caperren-green" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="my-4 font-bold md:text-2xl">Details By Team</h2>
|
||||
<h3 class="my-4 font-bold md:text-lg">Starlink Hardware Test</h3>
|
||||
<h3 class="my-4 font-bold md:text-lg">Build Reliability Engineering</h3>
|
||||
<h3 class="my-4 font-bold md:text-lg">Components Test Infrastructure</h3>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Summary</H2></Fragment>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>Timeline</H3></Fragment>
|
||||
<Timeline timeline={timeline} />
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>Key Takeaways</H3></Fragment>
|
||||
<Ul>
|
||||
<Li
|
||||
>Created test systems which validated ~4500 Starlink satellite flight
|
||||
computers, and ~4000 power boards</Li
|
||||
>
|
||||
<Li
|
||||
>Developed program-critical infrastructure that enabled efficient
|
||||
triage, management, tracking, and metrics of hardware failures</Li
|
||||
>
|
||||
<Li
|
||||
>Designed and deployed automated, unified, and containerized
|
||||
infrastructure to greatly increase application reliability and
|
||||
development speed</Li
|
||||
>
|
||||
<Li
|
||||
>Provided on-call support for on-orbit hardware,
|
||||
satellite-test/components-test systems, and
|
||||
satellite-test/components-test infrastructure</Li
|
||||
>
|
||||
</Ul>
|
||||
</PageGroup>
|
||||
<SkillMatrix categorizedSkills={categorizedSkills} />
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Details</H2></Fragment>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>Starlink Test Engineering</H3></Fragment>
|
||||
<Paragraphs>
|
||||
<Paragraph>
|
||||
Starting at SpaceX, I'd joined the hardware test engineering team for
|
||||
the Starlink program in Redmond, WA. With my first day being in early
|
||||
September of 2019, the V0.9 revision satellites had only just been
|
||||
shot into space a few months prior. This meant my start coincided with
|
||||
earnest preparations to launch V1.0, as well as ramping production to
|
||||
rates previously thought impossible for space industries. My initial
|
||||
task at the company was simple; offload the current hardware test
|
||||
engineer for flight computer in any way possible, as he was
|
||||
significantly overloaded.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
I put my all into this task, immediately taking over quite a few
|
||||
production code debug and improvement tasks, as well as running EMI
|
||||
compliance testing, while absorbing as much as I could about the
|
||||
product, its test systems, and test procedures. During this time, I
|
||||
was extremely happy to have already done a <InlineLink
|
||||
href="/experience/spacex/avionics-test-engineering-internship"
|
||||
>test engineering internship</InlineLink
|
||||
> with the company, as it made ramping up much faster and easier than it
|
||||
would have been otherwise. Around three months after joining the team, ownership
|
||||
of these test systems were transferred to me in their entirety. What followed
|
||||
was nearly three years of the kind of intensity you'd expect out of a company
|
||||
like SpaceX, but with the unique addition of higher production rates than
|
||||
anywhere else in the company, or space industry.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
When I say I took ownership of flight computer test systems, I mean
|
||||
this very literally, and specifically a multi-disciplinary sense. I
|
||||
handled high-level test rack designs, purchasing, test fixture
|
||||
enclosure design, test fixture PCB design, test fixture firmware
|
||||
development, test rack networking configuration, test rack server
|
||||
configuration and tuning, DUT harness design, prototype DUT harness
|
||||
fabrication, along with test software development to cover not only
|
||||
production tests, but also more strenuous qualification tests which
|
||||
often required their own custom rack design compared to their
|
||||
production counterparts. This barely scratches the surface in reality,
|
||||
and doesn't include the countless nights on the production floor,
|
||||
personally running hundreds of boards through functional and
|
||||
environmental testing, slowly and consistently improving the quality,
|
||||
rate, and coverage of the tests. It also doesn't include the whole
|
||||
year where I was on-call 24/7 for a full week, every other week,
|
||||
triaging on-orbit alerts for flight computer, reviewing data, and
|
||||
sending commands to recover where needed.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
As time progressed, I began to burn out and requested transfer to a
|
||||
different product. Flight computer was a particularly intense due to
|
||||
having little-to-no overlap with the rest of the satellite
|
||||
sub-systems, and being doubly critical functionality-wise to satellite
|
||||
operation. I was given a new test system for power boards, but due to
|
||||
unfortunate timing, the new owner for flight computer changed
|
||||
companies and I ended up having to temporarily take over test rack
|
||||
hardware design, alongside permanently handling the software for
|
||||
flight computer through the end of this overall phase at SpaceX. This
|
||||
turned out to be the most intense period of time at the company for
|
||||
me, with some of the longest hours and latest nights that I'd rather
|
||||
not share the durations of. However, as with all the time previously,
|
||||
I successfully delivered multiple test system derivations for power
|
||||
board, alongside all the software for multiple of the next generation
|
||||
of flight computer.
|
||||
</Paragraph>
|
||||
</Paragraphs>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>Build Reliability Engineering</H3></Fragment
|
||||
>
|
||||
<Paragraphs>
|
||||
<Paragraph>
|
||||
In early 2022, I decided I was going to move in with my
|
||||
long-distance partner down in Oregon. SpaceX is not normally known
|
||||
for allowing remote work, but I floated the idea a few months before
|
||||
my August deadline for leaving, just in case. My good friend, and
|
||||
head of the build reliability engineering team at the time, also
|
||||
proposed a project for me to work on that would enable fast triage
|
||||
and disposition of hardware failures coming out of test. I'd
|
||||
previously taught him some basic web development to get a prototype
|
||||
version of the app up and running, but it was fast approaching its
|
||||
usability limits and needed professional support. They approved me
|
||||
to work on this for three months, with the stipulation that I came
|
||||
in person for one week a month. Since it was going to be short term,
|
||||
I agreed and began working on this website!
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
This level of web development was rather new to me, at the time, as
|
||||
I'd always said I'd never become a full time web developer since
|
||||
before even starting college. Still, that wasn't going to stop me,
|
||||
and I quickly began making improvements. One thing SpaceX had
|
||||
already taught me was that development velocity was paramount, and
|
||||
that there should be as little friction as possible between changes
|
||||
getting made, becoming validated, and then deployed. So, I started
|
||||
by creating a fully automated development/staging/production devops
|
||||
environment, and moved the application to docker with a RESTful
|
||||
flask backend and Bootstrap frontend. After three months were up,
|
||||
they decided to let me keep working remote so long as I still came
|
||||
in a week a month. For the next year and a half, this tool grew and
|
||||
improved, gaining hundreds of users a day both in and out of the
|
||||
reliability team. It turned out that many features of my website
|
||||
ended up providing a better experience than the ones developed by
|
||||
SpaceX's core applications engineering team, at least for Starlink's
|
||||
use-case. This did not go unnoticed, and that team ended up reaching
|
||||
out to create an equivalent, and officially supported, first-party
|
||||
tool in the SpaceX application ecosystem. They even created a small
|
||||
team dedicated to its creation and maintenance. This also came at a
|
||||
perfect time, as I was losing my ability to keep up with my custom
|
||||
website as a solo developer. Oh, and did I mentioned I'd been
|
||||
supporting satellite hardware test remotely for the latter nine
|
||||
months at this time, as well?
|
||||
</Paragraph>
|
||||
</Paragraphs>
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>Components Test Engineering</H3></Fragment>
|
||||
<Paragraphs>
|
||||
<Paragraph>
|
||||
In March of 2024, the team lead for components test software (the
|
||||
components team being the parent group of satellite hardware test by
|
||||
that point) reached out and asked me if I wanted to join a small two
|
||||
person infrastructure team. Considering my remote nature, this made
|
||||
a lot more sense than trying to continue supporting satellite
|
||||
hardware tests, and I was going to be able to provide a lot of
|
||||
experience with devops infrastructure and docker that could greatly
|
||||
benefit the team. I agreed, and began working on dockerization and
|
||||
unification of the team's tools into a monorepo. I also began
|
||||
supporting a relatively new tool for running test software that the
|
||||
team was developing, along with a small slew of miscellaneous tools
|
||||
such as those to image and provision servers over PXE.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
After dockerizing all the infrastructure and moving them into the
|
||||
monorepo, my next push was to improve velocity and reliability by
|
||||
adding automated build, test, and deploy tasks for new development,
|
||||
staging, and production environments across them all. I did this by
|
||||
combining a unified set of Makefile interfaces, with automated runs
|
||||
via ansible from pull requests and main branch merges. Application
|
||||
and server monitoring was also added via tools such as Sentry and
|
||||
Grafana, which were piped into OpsGenie so the infra team could be
|
||||
pinged during outages. Backups were also made of production
|
||||
databases during deployments, with restore tooling that could be
|
||||
used for emulating production data during staging, development, and
|
||||
local deploys. Overall, these changes greatly improved the speed at
|
||||
which the team could develop, and helped ensure that what we were
|
||||
deploying was validated as thoroughly as possible in advance.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
At the end of January 2025, I was notified by the company that my
|
||||
remote work exception would no longer be valid as of April 4th. I
|
||||
was now living in northern Washington state and close to a two hour
|
||||
drive, each way, from the closest SpaceX facility. I therefore opted
|
||||
to quit after roughly six years with them in total. Considering the
|
||||
average is two to three years, I'd say I did quite well, and am very
|
||||
proud of what I managed to achieve with the company in that time! If
|
||||
you'd like to know more, feel free to contact me, and I'm happy to
|
||||
share what I'm allowed! This summary was ultimately just the tip of
|
||||
the iceberg for an experience that made six years feel like twelve.
|
||||
</Paragraph>
|
||||
</Paragraphs>
|
||||
</PageGroup>
|
||||
</PageGroup>
|
||||
</PageGroup>
|
||||
</ExperienceLayout>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
---
|
||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||
import HobbyLayout from "@layouts/HobbyLayout.astro";
|
||||
|
||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||
|
||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||
|
||||
import enclosure_front_pc_panel_open from "@assets/hobby/homelab/offsite-backup-rack/enclosure-front-pc-panel-open.jpg";
|
||||
@@ -10,6 +11,7 @@ import enclosure_left from "@assets/hobby/homelab/offsite-backup-rack/enclosure-
|
||||
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_with_ups from "@assets/hobby/homelab/offsite-backup-rack/enclosure-with-ups.jpg";
|
||||
import installed from "@assets/hobby/homelab/offsite-backup-rack/installed.jpg";
|
||||
import power_adapter_tray_and_dc_dc from "@assets/hobby/homelab/offsite-backup-rack/power-adapter-tray-and-dc-dc.jpg";
|
||||
import power_supply_closeup from "@assets/hobby/homelab/offsite-backup-rack/power-supply-closeup.jpg";
|
||||
import power_supply_mounting_location from "@assets/hobby/homelab/offsite-backup-rack/power-supply-mounting-location.jpg";
|
||||
@@ -20,6 +22,7 @@ import up_and_running from "@assets/hobby/homelab/offsite-backup-rack/up-and-run
|
||||
const headerCarouselGroup: carouselGroup = {
|
||||
animation: "slide",
|
||||
images: [
|
||||
installed,
|
||||
enclosure_front,
|
||||
enclosure_front_pc_panel_open,
|
||||
enclosure_left,
|
||||
@@ -38,6 +41,4 @@ const headerCarouselGroup: carouselGroup = {
|
||||
|
||||
<HobbyLayout title="Homelab - Offsite Backup Rack">
|
||||
<Carousel carouselGroup={headerCarouselGroup} />
|
||||
|
||||
<!--<h2 class="font-bold md:text-2xl my-4">Prior Homelab</h2>-->
|
||||
</HobbyLayout>
|
||||
|
||||
@@ -32,7 +32,7 @@ const categorizedSkills: categorySkills[] = [
|
||||
],
|
||||
},
|
||||
{
|
||||
item: "Programming Languages",
|
||||
item: "Programming",
|
||||
subItems: [
|
||||
{ item: "HTML" },
|
||||
{ item: "CSS" },
|
||||
|
||||
@@ -11,8 +11,8 @@ import Paragraphs from "@components/Paragraphs.astro";
|
||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||
|
||||
import alaska_bike_mountain_ocean from "@assets/about/alaska-bike-mountain-ocean.jpg";
|
||||
import circ_champions from "@assets/about/circ-champions.jpg";
|
||||
import headshot from "@assets/about/headshot.jpg";
|
||||
import circ_champions from "@assets/experience/osu-robotics-club/mars-rover-software-lead/circ-champions.jpg";
|
||||
|
||||
const headerCarouselGroup: carouselGroup = {
|
||||
animation: "slide",
|
||||
|
||||