Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
238ef3c9d3 | |||
b517e02bbe |
23
.github/workflows/main.yml
vendored
|
@ -8,7 +8,6 @@ name: Create and publish a Docker image
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ['main']
|
branches: ['main']
|
||||||
repository_dispatch:
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
REGISTRY: ghcr.io
|
REGISTRY: ghcr.io
|
||||||
|
@ -24,8 +23,6 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Log in to the Container registry
|
- name: Log in to the Container registry
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v1
|
||||||
|
@ -39,29 +36,11 @@ jobs:
|
||||||
uses: docker/metadata-action@v3
|
uses: docker/metadata-action@v3
|
||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
|
||||||
- name: Setup Python
|
|
||||||
uses: actions/setup-python@v4.0.0
|
|
||||||
with:
|
|
||||||
python-version: 3.12
|
|
||||||
|
|
||||||
|
|
||||||
- uses: paulhatch/semantic-version@v5.0.2
|
|
||||||
id: vnum
|
|
||||||
with:
|
|
||||||
# The prefix to use to identify tags
|
|
||||||
tag_prefix: ""
|
|
||||||
major_pattern: "(MAJOR)"
|
|
||||||
minor_pattern: "(MINOR)"
|
|
||||||
version_format: "${major}.${minor}.${patch}-${increment}"
|
|
||||||
bump_each_commit: true
|
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v2
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.vnum.outputs.version_tag }}
|
|
||||||
${{ steps.meta.outputs.tags }}
|
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
22
Dockerfile
|
@ -1,8 +1,18 @@
|
||||||
FROM ubuntu as build-env
|
# build environment
|
||||||
|
FROM node:13.12.0-alpine as build
|
||||||
|
WORKDIR /app
|
||||||
|
ENV PATH /app/node_modules/.bin:$PATH
|
||||||
|
COPY package.json ./
|
||||||
|
COPY package-lock.json ./
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
WORKDIR /site
|
RUN npm install react-scripts@3.4.1 -g --silent
|
||||||
COPY . .
|
COPY . ./
|
||||||
RUN /bin/bash compile.sh
|
RUN npm run build
|
||||||
|
|
||||||
FROM ghcr.io/nickorlow/anthracite:0.2.1
|
# production environment
|
||||||
COPY --from=build-env /site/out/ /www/
|
FROM nginx:stable-alpine
|
||||||
|
COPY --from=build /app/build /usr/share/nginx/html
|
||||||
|
COPY --from=build /app/nginx/nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
EXPOSE 80
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
# personal-site [![Build Status](https://github.com/nickorlow/personal-site/actions/workflows/main.yml/badge.svg)](https://github.com/nickorlow/personal-site/actions/workflows/main.yml)
|
# personal-site [![Build Status](https://github.com/nickorlow/personal-site/actions/workflows/main.yml/badge.svg)](https://github.com/nickorlow/personal-site/actions/workflows/main.yml)
|
||||||
My personal website!
|
My personal website!
|
||||||
Hosted by NWS
|
|
||||||
|
|
57
compile.sh
|
@ -1,57 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Check if the src directory exists
|
|
||||||
if [ ! -d "src" ]; then
|
|
||||||
echo "Error: 'src' directory not found."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create the out directory if it doesn't exist
|
|
||||||
mkdir -p "out"
|
|
||||||
|
|
||||||
# Define the template file and search pattern
|
|
||||||
template_file="src/structure.template.html"
|
|
||||||
filler_pattern="src/**/*.filler.html"
|
|
||||||
|
|
||||||
# Function to process the filler file and insert its content into the structure file
|
|
||||||
process_filler_file() {
|
|
||||||
local filler_file="$1"
|
|
||||||
local output_file="$2"
|
|
||||||
|
|
||||||
# Read the contents of the template file
|
|
||||||
template_content=$(<"$template_file")
|
|
||||||
|
|
||||||
# Read the contents of the filler file
|
|
||||||
filler_content=$(<"$filler_file")
|
|
||||||
filler_content=$(echo "$filler_content" | sed "s/\&/\\\&/g")
|
|
||||||
|
|
||||||
# Replace "{{ body_area }}" in the template with filler content
|
|
||||||
modified_content="${template_content/\{\{ body_area \}\}/$filler_content}"
|
|
||||||
|
|
||||||
# Write the modified content to the output file in the 'out' directory
|
|
||||||
echo "$modified_content" > "out/$output_file"
|
|
||||||
|
|
||||||
echo "Created: out/$output_file"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Loop through each filler file in the src directory and its subdirectories
|
|
||||||
shopt -s globstar
|
|
||||||
for filler_file in $filler_pattern; do
|
|
||||||
# Check if the filler file exists
|
|
||||||
if [ ! -e "$filler_file" ]; then
|
|
||||||
echo "Error: $filler_file not found."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the relative path of the filler file (removing the "src/" prefix)
|
|
||||||
relative_path="${filler_file#src/}"
|
|
||||||
|
|
||||||
# Extract the filename (excluding the extension)
|
|
||||||
filename="${relative_path%.filler.html}"
|
|
||||||
|
|
||||||
# Create the output file name in the 'out' directory
|
|
||||||
output_file="${filename}.html"
|
|
||||||
|
|
||||||
# Process the filler file and insert its content into the structure file
|
|
||||||
process_filler_file "$filler_file" "$output_file"
|
|
||||||
done
|
|
8
nginx/nginx.conf
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
try_files $uri $uri/ /index.html =404;
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 197 KiB |
Before Width: | Height: | Size: 438 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 194 KiB |
|
@ -1,25 +0,0 @@
|
||||||
<body style="width: 100%; height: 100%; background-color: #FF2222">
|
|
||||||
<div style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center;">
|
|
||||||
<div style="padding: 20px; min-height: 500px; max-width: 500px; background-color: white;">
|
|
||||||
<center>
|
|
||||||
<div>
|
|
||||||
<img src="./april-fools-images/nypd.png" width=200/>
|
|
||||||
<img src="./april-fools-images/amtrak.png" width=200/>
|
|
||||||
<img src="./april-fools-images/septa.png" width=200/>
|
|
||||||
<img src="./april-fools-images/uspis.png" width=200/>
|
|
||||||
</div>
|
|
||||||
<h1>THIS WEBSITE HAS BEEN SEIZED</h1>
|
|
||||||
<p>
|
|
||||||
This domain name has been seized by the <b>Southeastern Pennsylvania Transportation Authority (SEPTA)
|
|
||||||
Police Department</b> pursuant to a seizure warrant issued by the United States Supreme Court
|
|
||||||
under the authority of 18 U.S.C. § 918 and 2323.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<i>
|
|
||||||
(April fools! <a href="./index.html?af=false">Continue to my website</a>)
|
|
||||||
</i>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
Before Width: | Height: | Size: 252 KiB |
Before Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 622 KiB |
Before Width: | Height: | Size: 3.4 MiB |
Before Width: | Height: | Size: 21 MiB |
|
@ -1,37 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h1 style="margin-bottom: 0px;">Blog</h1>
|
|
||||||
<p style="margin-top: 0px;">A collection of my thoughts, some of them may be interesting</p>
|
|
||||||
<p><a href="./blogs/fpga-fun.html">[ FPGA Fun (CHIP-8 in hardware) ]</a> - April 20th, 2024</p>
|
|
||||||
<p><a href="./blogs/nws-postmortem-11-8-23.html">[ NWS Postmortem 11/08/23 ]</a> - November 16th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-10-20-23.html">[ Side Project Log 10/20/23 ]</a> - October 20th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-8-15-23.html">[ Side Project Log 8/15/23 ]</a> - August 15th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-8-8-23.html">[ Side Project Log 8/08/23 ]</a> - August 8th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-7-12-23.html">[ Side Project Log 7/12/23 ]</a> - July 12th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-4-29-23.html">[ Side Project Log 4/29/23 ]</a> - April 29th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-3-27-23.html">[ Side Project Log 3/27/23 ]</a> - March 27th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-3-20-23.html">[ Side Project Log 3/20/23 ]</a> - March 20th, 2023</p>
|
|
||||||
<p><a href="./blogs/spring-break-2023.html">[ Spring Break 2023 ]</a> - January 20th, 2023</p>
|
|
||||||
<p><a href="./blogs/doing-c-assignments-in-csharp.html">[ Doing C assignments in C# ]</a> - March 18th, 2022</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,79 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Doing C assignments in C#</h1>
|
|
||||||
<p>Thanks to Arpan Dhatt for doing most of the work on this (his blog here: <a href="https://arpan.one/posts/messing-with-gradescope/">https://arpan.one/posts/messing-with-gradescope/</a>)</p>
|
|
||||||
<p>At the end, he made this comment:</p>
|
|
||||||
<blockquote>
|
|
||||||
<p>And so, that's the end of this post. To whom it may concern, don't try doing your C assignment in C# (you know who you are).</p>
|
|
||||||
</blockquote>
|
|
||||||
<p>The reason for this comment (besides the fact that I talk about C# a lot) is due to the fact that C# requires a runtime to be installed for it to work. This is because C# does not compile to native bytecode but rather compiles to an intermediary language (dubbed CIL by Microsoft) and is then translated 'Just In Time' by the runtime. </p>
|
|
||||||
<p>This makes running assignments in a docker container where the runtime is not already installed considerably hard. One option we have is that we could just include the runtime in our submission. Sounds easy, right? Well it would be non-trivial to do but due to the fact that the .NET runtime is very large, I wouldn't consider this a good idea (Not to mention it's super boring). </p>
|
|
||||||
<p>The better solution is to use .NET's (experimental) AOT compilation feature (formerly called CoreRT). C# has had a number of attempts at an AOT compiler such as :</p>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://www.mono-project.com/docs/advanced/aot/">AOT</a> by Mono</li>
|
|
||||||
<li>LLD2CPP built by Unity</li>
|
|
||||||
<li><a href="https://docs.microsoft.com/en-us/dotnet/core/deploying/ready-to-run">Ready2Run</a> by Microsoft</li>
|
|
||||||
</ul>
|
|
||||||
<p>We'll be using the official Ready2Run AOT compilation built by Microsoft. In order to use it, all you have to do is add the following to your <code>nuget.config</code>:</p>
|
|
||||||
<pre><code class="lang-xml"><<span class="hljs-keyword">add</span> key=<span class="hljs-string">"nuget.org"</span> <span class="hljs-keyword">value</span>=<span class="hljs-string">"https://api.nuget.org/v3/index.json"</span> protocolVersion=<span class="hljs-string">"3"</span> />
|
|
||||||
</code></pre>
|
|
||||||
<p>and then install the package: <code>Microsoft.DotNet.ILCompiler</code>. After doing that if you run the command: <code>dotnet publish -r [Runtime] -c [Config]</code> and after waiting a considerable amount of time, you'll have a full-fledged C# application compiled directly to your target runtime's bytecode!</p>
|
|
||||||
<p>Compiling my simple Hello, Wold test to linux-x64 (<code>dotnet publish -r linux-x64 -c Release</code>) and adding it to my project files should let me run it using the same method Arpan used in his blog.</p>
|
|
||||||
<p>After doing that, we can follow the instructions followed by Arpan and viola! C# runs on Gradescope!</p>
|
|
||||||
<p>I don't recommend this but it was fun to do and I needed stuff to write in a blog. </p>
|
|
||||||
<h2 id="other-interesting-low-level-c-net-features">Other Interesting (Low Level) C#/.NET Features</h2>
|
|
||||||
<p>C# actually has many lower level features people don't expect it to have. Some of these include pointers and direct memory management. Pointers can be enabled by encasing your code in an unsafe code block.</p>
|
|
||||||
<p>Example (Written by <a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/unsafe-code">Microsoft</a>)</p>
|
|
||||||
<pre><code class="lang-csharp">
|
|
||||||
<span class="hljs-comment">// Normal pointer to an object.</span>
|
|
||||||
<span class="hljs-keyword">int</span>[] a = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[<span class="hljs-number">5</span>] { <span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>, <span class="hljs-number">40</span>, <span class="hljs-number">50</span> };
|
|
||||||
<span class="hljs-comment">// Must be in unsafe code to use interior pointers.</span>
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
<span class="hljs-comment">// Must pin object on heap so that it doesn't move while using interior pointers.</span>
|
|
||||||
fixed (<span class="hljs-keyword">int</span>* p = &a[<span class="hljs-number">0</span>])
|
|
||||||
{
|
|
||||||
<span class="hljs-comment">// p is pinned as well as object, so create another pointer to show incrementing it.</span>
|
|
||||||
<span class="hljs-keyword">int</span>* p2 = p;
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
|
|
||||||
<span class="hljs-comment">// Incrementing p2 bumps the pointer by four bytes due to its type ...</span>
|
|
||||||
p2 += <span class="hljs-number">1</span>;
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
|
|
||||||
p2 += <span class="hljs-number">1</span>;
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(<span class="hljs-string">"--------"</span>);
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p);
|
|
||||||
<span class="hljs-comment">// Dereferencing p and incrementing changes the value of a[0] ...</span>
|
|
||||||
*p += <span class="hljs-number">1</span>;
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p);
|
|
||||||
*p += <span class="hljs-number">1</span>;
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</code></pre>
|
|
||||||
<p>In .NET 6, the <code>NativeMemory</code> class was introduced which you can read about <a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativememory.alloc?view=net-6.0">here</a>. It allows for malloc-like memory allocation and freeing which can be important for high-performance workloads.</p>
|
|
||||||
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/dark.min.css">
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
|
||||||
<script>hljs.highlightAll();</script>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,111 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>NWS Incident Postmortem 11/08/2023</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
On November 8th, 2023 at approximately 09:47 UTC, NWS suffered
|
|
||||||
a complete outage. This outage resulted in the downtime of all
|
|
||||||
services hosted on NWS and the downtime of the NWS Management
|
|
||||||
Engine and the NWS dashboard.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The incident lasted 38 minutes after which it was automatically
|
|
||||||
resolved and all services were restored. This is NWS' first
|
|
||||||
outage event of 2023.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Cause</h2>
|
|
||||||
<p>
|
|
||||||
NWS utilizes several tactics to ensure uptime. A component of
|
|
||||||
this is load balancing and failover. This service is currently
|
|
||||||
provided by Cloudflare at the DNS level. Cloudflare sends
|
|
||||||
health check requests to NWS servers at specified intervals. If
|
|
||||||
it detects that one of the servers is down, it will remove the
|
|
||||||
A record from entry.nws.nickorlow.com for that server (this domain
|
|
||||||
is where all services on NWS direct their traffic via a
|
|
||||||
CNAME).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
At around 09:47 UTC, Cloudflare detected that our servers in
|
|
||||||
Texas (Austin and Hill Country) were down. It did not detect an
|
|
||||||
error, but rather an HTTP timeout. This is an indication that the
|
|
||||||
server may have lost network connectivity. When Cloudflare detected that the
|
|
||||||
servers were down, it removed their A records from the
|
|
||||||
entry.nws.nickorlow.com domain. Since NWS Pennsylvania servers
|
|
||||||
have been undergoing maintenance since August 2023, this left no
|
|
||||||
servers able to serve requests routed to entry.nws.nickorlow.com,
|
|
||||||
resulting in the outage.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
NWS utilizes UptimeRobot for monitoring the uptime statistics of
|
|
||||||
services on NWS and NWS servers. This is the source of the
|
|
||||||
statistics shown on the NWS status page.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
UptimeRobot did not detect either of the Texas NWS servers as being
|
|
||||||
offline for the duration of the outage. This is odd, as UptimeRobot
|
|
||||||
and Cloudflare did not agree on the status of NWS servers. Logs
|
|
||||||
on NWS servers showed that requests from UptimeRobot were being
|
|
||||||
served while no requests from Cloudflare were shown in the logs.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
No firewall rules existed that could have blocked the healthcheck traffic from Cloudflare
|
|
||||||
for either of the NWS servers. There was no other configuration
|
|
||||||
found that would have blocked these requests. As these servers
|
|
||||||
are on different networks inside different buildings in different
|
|
||||||
parts of Texas, their networking equipment is entirely separate.
|
|
||||||
This rules out any failure of networking equipment owned
|
|
||||||
by NWS. This leads us to believe that the issue may have been
|
|
||||||
caused due to an internet traffic anomaly, although we are currently
|
|
||||||
unable to confirm that this is the cause of the issue.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This is being actively investigated to find a more concrete root
|
|
||||||
cause. This postmortem will be updated if any new information is
|
|
||||||
found.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
A similar event occurred on November 12th, 2023 lasting for 2 seconds.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Fix</h2>
|
|
||||||
<p>
|
|
||||||
The common factor between both of these servers is that they both use
|
|
||||||
Spectrum for their ISP and that they are located near Austin, Texas.
|
|
||||||
The Pennsylvania server maintenance will be expedited so that we have
|
|
||||||
servers online that operate with no commonalities.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
NWS will also investigate other methods of failover and load
|
|
||||||
balancing.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>Last updated on November 16th, 2023</p>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,121 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Side Project Log 10/20/2023</h1>
|
|
||||||
<p>This side project log covers work done from 8/15/2023 - 10/20/2023</p>
|
|
||||||
|
|
||||||
<h2 id="anthracite">Anthracite</h2>
|
|
||||||
<a href="https://github.com/nickorlow/anthracite">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
Anthracite is a web server written in C++. The site you're reading this on
|
|
||||||
right now is hosted on Anthracite. I wrote it to deepen my knowledge of C++ and networking protocols. My
|
|
||||||
main focus of Anthracite is performance. While developing anthracite,
|
|
||||||
I have been exploring different optimization techniques and benchmarking
|
|
||||||
Anthracite against popular web servers such as NGINX and Apache.
|
|
||||||
Anthracite supports HTTP/1.1 and only supports GET requests to request
|
|
||||||
files stored on a server.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Anthracite currently performs on par with NGINX and Apache when making
|
|
||||||
1000 requests for a 50MB file using 100 threads in a Docker container.
|
|
||||||
To achieve this performance, I used memory profilers to find
|
|
||||||
out what caused large or repeated memory copies to occur. I then updated
|
|
||||||
those sections of code to remove or minimize these copies. I also
|
|
||||||
made it so that Anthracite caches all files it can serve in memory. This
|
|
||||||
avoids unnecessary and costly disk reads. The implementation of this is
|
|
||||||
subpar, as it requires that the server be restarted whenever the files
|
|
||||||
it is serving are changed for the updates to be detected by Anthracite.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I intend to make further performance improvements, specifically in the request
|
|
||||||
parser. I also plan to implement HTTP/2.0.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 id="yacemu">Yet Another Chip Eight Emulator (yacemu)</h2>
|
|
||||||
<a href="https://github.com/nickorlow/yacemu">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
YACEMU is an interpreter for the CHIP-8 instruction set written in C. My main
|
|
||||||
goal when writing it was to gain more insight into how emulation works. I had
|
|
||||||
previous experience with this from when I worked on an emulator for a slimmed-down
|
|
||||||
version of X86 called <a href="https://web.cse.ohio-state.edu/~reeves.92/CSE2421sp13/PracticeProblemsY86.pdf">Y86</a>.
|
|
||||||
So far, I've been able to get most instructions working. I need to work on adding
|
|
||||||
input support so that users can interact with programs running in yacemu. It has
|
|
||||||
been fairly uncomplicated and easy to write thus far. After I complete it, I would
|
|
||||||
like to work on an emulator for a real device such as the GameBoy (This might be
|
|
||||||
biting off more than I can chew).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 id="nick-vim">Nick VIM</h2>
|
|
||||||
<p>
|
|
||||||
Over the summer while I was interning, I began using VIM as my primary
|
|
||||||
text editor. I used a preconfigured version of it (<a href="https://nvchad.com/">NvChad</a>) to save time, as
|
|
||||||
setting everything up can take a while. After using it for a few months, I began
|
|
||||||
making my own configuration for VIM, taking what I liked from NvChad and leaving
|
|
||||||
behind the parts that I didn't like as much.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<img src="/blog-images/NickVIM_Screenshot.png" alt="Screenshot of an HTML file open for editing in NickVIM"/>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
One important part of Nick VIM was ensuring that it was portable between different
|
|
||||||
machines. I wanted the machine to have as few dependencies as possible so that I
|
|
||||||
could get NickVIM set up on any computer in a couple of minutes. This will be especially
|
|
||||||
useful when working on my School's lab machines and when switching to new computers
|
|
||||||
in the future. I achieved this by dockerizing Nick VIM. This is based on what one of
|
|
||||||
my co-workers does with their VIM setup. The Docker container contains
|
|
||||||
all the dependencies for each language server. Whenever you edit a file with Nick Vim,
|
|
||||||
the following script runs:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<code lang="bash">
|
|
||||||
echo Starting container...
|
|
||||||
cur_dir=`pwd`
|
|
||||||
container_name=${cur_dir////$'_'}
|
|
||||||
container_name="${container_name:1}_$RANDOM"
|
|
||||||
docker run --name $container_name --network host -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --mount type=bind,source="$(pwd)",target=/work -d nick-vim &> /dev/null
|
|
||||||
|
|
||||||
echo Execing into container...
|
|
||||||
docker exec -w /work -it $container_name bash
|
|
||||||
|
|
||||||
echo Stopping container in background...
|
|
||||||
docker stop $container_name &> /dev/null &
|
|
||||||
</code>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This code creates a new container, forwards the host's clipboard to the container, and
|
|
||||||
mounts the current directory inside the container for editing.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 id="secane">Secane</h2>
|
|
||||||
<p><a href="https://www.youtube.com/watch?v=tKRehO7FH_s">[ Video Demo ]</a></p>
|
|
||||||
<p>
|
|
||||||
Secane was a simple ChatGPT wrapper that I wrote to practice for the behavioral part of
|
|
||||||
job interviews. It takes your resume, information about the company, and information about
|
|
||||||
the role you're interviewing for. It also integrates with OpenAI's whisper, allowing you
|
|
||||||
to simulate talking out your answers. I made it with Next.JS.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
<p><strong>These projects had minimal/no work done on them:</strong> NWS, RingGold, SQUIRREL</p>
|
|
||||||
<p><strong>These projects I will no longer be working on:</strong> Olney</p>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,39 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Side Project Log 3/20/2023</h1>
|
|
||||||
<p>Spring break just wrapped up. I wrote a <a href="">blog</a> last week about the side projects that I was planning on
|
|
||||||
doing. I wanted to provide an update on what I got done, and figured I'd turn it into a recurring thing.</p>
|
|
||||||
<p>This side project log covers work done from 3/13/2023 - 3/20/2023</p>
|
|
||||||
<h2 id="-personal-website-facelift-https-github-com-nickorlow-personal-site-"><a href="https://github.com/nickorlow/personal-site">Personal Website Facelift</a></h2>
|
|
||||||
<p>I managed to move my website over to tab-based navigation pretty early on in the break. It just involved setting
|
|
||||||
up a navbar component and then using react-navigation to navigate between pages. I also managed to
|
|
||||||
update my projects page to be more compact and readable. </p>
|
|
||||||
<p>There is still work to be done on making it look better, but I mostly believe that
|
|
||||||
it's just going to be somewhat minor tweaks.</p>
|
|
||||||
<h2 id="-mahantongo-https-github-com-nickorlow-mahantongo-"><a href="https://github.com/nickorlow/mahantongo">Mahantongo</a></h2>
|
|
||||||
<p>I managed to finish this one. I learned a lot about Rust and I've gained an appreciation for
|
|
||||||
Rust's enforcement of good programming habits, and I really like how error handling is done.</p>
|
|
||||||
<p>Working with Serenity was pretty easy as it mirrored some of the other Discord SDKs I've used
|
|
||||||
before.</p>
|
|
||||||
<hr>
|
|
||||||
<p><strong>The below projects had minimal/no work done on them:</strong> RingGold, NWS Container Deployment Service, and VerifiedBot </p>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,39 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Side Project Log 3/27/2023</h1>
|
|
||||||
<p>This side project log covers work done from 3/20/2023 - 3/27/2023</p>
|
|
||||||
<h2 id="septa-site">SEPTA Site</h2>
|
|
||||||
<p>I started a new project that aimed to recreate parts of SEPTA's website with a more elegant UI, and using
|
|
||||||
SEPTA's new "SEPTA Metro" wayfinding. The main goal with this project was to help me learn Svelte. I also had
|
|
||||||
to reverse-engineer the APIs on septakey.org in order to authenticate a user and get their trip history. </p>
|
|
||||||
<p>In terms of Svelte, I really enjoyed working with it and overall I found it much more elegant and easier to work
|
|
||||||
with than React. I didn't like the way it handled client-server interaction with its serverside functions. </p>
|
|
||||||
<p>I have not made this open source yet and do not intend to until it's more polished.</p>
|
|
||||||
<h2 id="-verified-bot-https-github-com-benaubin-verified-bot-"><a href="https://github.com/benaubin/verified-bot">Verified Bot</a></h2>
|
|
||||||
<p>I made all the necessary changes and tests to get VerifiedBot working. It is now waiting on my friend Ben
|
|
||||||
to merge my PR with the changes outlined in my <a href="https://nickorlow.com/blog/spring-break-2023">spring break blog</a>.</p>
|
|
||||||
<h2 id="-mahantongo-https-github-com-nickorlow-mahantongo-"><a href="https://github.com/nickorlow/mahantongo">Mahantongo</a></h2>
|
|
||||||
<p>I created some QoL features, such as using Discord's embeds instead of sending regular text messages, showing which board
|
|
||||||
a post was on, and fixing some bugs.</p>
|
|
||||||
<hr>
|
|
||||||
<p><strong>The below projects had minimal/no work done on them:</strong> RingGold, and NWS Container Deployment Service </p>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,47 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Side Project Log 4/29/2023</h1>
|
|
||||||
<p>This side project log covers work done from 3/27/2023 - 4/29/2023</p>
|
|
||||||
<p>This side project log is a bit late due to it being a busy month of school, but today is my last day!</p>
|
|
||||||
<h2 id="septa-site">SEPTA Site</h2>
|
|
||||||
<p>This week, I published SEPTA Site on Github, you can find it here: <a href="https://github.com/nickorlow/septa-site">github.com/nickorlow/septa-site</a>.</p>
|
|
||||||
<p>I made a few tweaks to it in terms of styling and also wrote a descriptive README to give people instructions on how to run it as I don't want
|
|
||||||
to host it myself since it handles credentials from another service.</p>
|
|
||||||
<h2 id="squirrel">SQUIRREL</h2>
|
|
||||||
<p>SQUIRREL, short for SQL Query Util-Izing Rust's Reliable and Efficient Logic, is a SQL database that I am writing in Rust. Currently, it can
|
|
||||||
parse CREATE TABLE commands, and works with the data types varchar and int. I plan to implement basic CRUD operations, then add JOINs, and
|
|
||||||
then try to make it wire-compatible with Postgres.</p>
|
|
||||||
<p>This project is currently not open-sourced as I am waiting to add more features and polish it up more.</p>
|
|
||||||
<h2 id="swole-control">Swole Control</h2>
|
|
||||||
<p>This one isn't a <em>personal</em> project, however it is a project that I worked on with a group. We began working on it in February as a part of a
|
|
||||||
club at UT called Texas Convergent. We recently presented it at the club's demo day and won the prize for having the best business.</p>
|
|
||||||
<p>Swole Control is an app that monitors machine usage at a gym on a machine-by-machine level, providing gym goers with information about what machines
|
|
||||||
are free (this is a major pain point as a gym goer myself). It also provides gym owners with statistics on which machines are most popular, providing
|
|
||||||
them valuable insights into their business.</p>
|
|
||||||
<p>To achieve this, we built hardware that consisted of an ESP-32 micro controller and an ultrasonic distance sensor. This hardware is mounted on a gym machine
|
|
||||||
and it measures the distance to the nearest object. It then sends this measurement to a Rust backend which stores it in a Firestore database (although we had
|
|
||||||
a fork of it that worked with Postgres). The backend then uses these measurements and compares them to a baseline to determine if there is a user at a machine.
|
|
||||||
Our mobile app then reads this from the Firestore database (it's planned to have it read this from the API to have a better-defined application boundary). The
|
|
||||||
frontend is written in React Native.</p>
|
|
||||||
<hr>
|
|
||||||
<p><strong>These projects had minimal/no work done on them:</strong> RingGold, and NWS Container Deployment Service</p>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,92 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Side Project Log 7/12/2023</h1>
|
|
||||||
<p>This side project log covers work done from 4/29/2023 - 7/12/2023</p>
|
|
||||||
<p>This side project log is more than a bit late due to working a busy summer internship at <a href="https://futo.org">FUTO</a>!</p>
|
|
||||||
<h2 id="nws-container-deployment-service">NWS Container Deployment Service</h2>
|
|
||||||
<p>I have finally added SSL to NWS CDS. This was challenging, as it required handling ACME challenges and certificate
|
|
||||||
distribution across a set of geo-distributed Kubernetes clusters. I detail the complexities of this in a <a href="http://nickorlow.com/blog/ssl-in-nws-cds">previous blog
|
|
||||||
I wrote</a>. In order to implement auto-created/auto-renewing SSL, I implemented the below solution:</p>
|
|
||||||
<p><img src="/blog-images/NWS_SSL_Diagram.png" alt="Diagram of NWS SSL Architecture"></p>
|
|
||||||
<p>First, a user creates a request to add SSL to their NWS CDS service through the web UI which calls the NWS API (not pictured)</p>
|
|
||||||
<p>Then, the NWS API calls SSLiaison (in-house written software) which adds the domain to Caddy's list of domains. Caddy will then attempt to create
|
|
||||||
an SSL certificate from an ACME server (not pictured).</p>
|
|
||||||
<p>The ACME server will query NWS for the challenge response by requesting a file at <code>/.well-known/acme-challenge</code> on the
|
|
||||||
domain to be verified (this is the green arrows). </p>
|
|
||||||
<p>HAProxy will re-route these requests to NWS Hill Country, which is where the NWS Management Engine (NWSME) lives (this is
|
|
||||||
the orange arrows). <em>(NWSME controls what's deployed on each k8s cluster on NWS)</em></p>
|
|
||||||
<p>HAProxy in NWS Hill Country will then route this request to Caddy, which will solve the <a href="https://letsencrypt.org/docs/challenge-types/">http-01 challenge</a>, and then get the certificate
|
|
||||||
from the ACME server. Once it does this, it will write the certificate to a directory that is bind-mounted to both Caddy
|
|
||||||
and SSLiaison. </p>
|
|
||||||
<p>SSLiaison will detect this new file, parse it into a k8s manifest file, and then add it to our GitOps repo which is
|
|
||||||
hosted in GitHub.</p>
|
|
||||||
<p>From here, the certificate will be added to all the k8s clusters via Rancher Fleet.</p>
|
|
||||||
<hr>
|
|
||||||
<p>For next steps, I'd like to revise this solution such that it doesn't have a single point of failure.
|
|
||||||
Currently, if NWS Hill Country is down (which it is about 0.025% of the time), then SSL certificates
|
|
||||||
won't be able to be created or renewed. </p>
|
|
||||||
<p>To do this, I will have SSLiaison implement the ACME client specification so that it can create and respond do ACME HTTP challenges.
|
|
||||||
SSLiaison will run on NWS CDS (so that it's running on all of our k8s clusters and is HA) instead of running as a standalone docker container.
|
|
||||||
I'll have SSLiaison use some distributed database (probably CockroachDB) to store the HTTP challenges so that it doesn't matter
|
|
||||||
which k8s cluster the challenge request from the ACME server is routed to.</p>
|
|
||||||
<h2 id="next-steps-for-nws">Next Steps for NWS</h2>
|
|
||||||
<ul>
|
|
||||||
<li><strong>HA NWS Management Engine:</strong> Currently (as somewhat discussed above), the NWSME will go down when NWS Hill Country goes down. I'd like to
|
|
||||||
make it so that this isn't the case. This would likely just require that each NWS cluster runs its own instance of Rancher Fleet instead
|
|
||||||
of one central Rancher Fleet that manages all the clusters. It would also require the HA SSLiaison.</li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li><strong>IaC for Everything:</strong> Currently, all NWS CDS services are defined in yaml files in a git repo, however the underlying infrastructure that
|
|
||||||
it runs on is not. Ideally, I'd like every NWS machine to run Proxmox and then have Terraform & Ansible configs to define how to set up
|
|
||||||
vms on proxmox that will run the k8s clusters that support CDS services. This should eliminate my headaches of sshing into each machine
|
|
||||||
to apply config changes and make sure everything is standardized. It should also make the process of setting up new servers easy.</li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Monitoring:</strong> I've been working on setting up monitoring on a lot of our services at my current internship using the TIG stack (Telegraf,
|
|
||||||
InfluxDB, and Grafana). Now that I've been exposed to the usefulness of having a bunch of metrics on hand, I think it would be nice to have
|
|
||||||
some dashboards setup for NWS to monitor speed, resource usage, uptime, and traffic. Doing this would also make it possible to expose resource usage in the
|
|
||||||
NWS dashboard.</li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li><p><strong>Enhanced Infrastructure:</strong> This is kind of a blanket one for things I want to do that don't fit into other categories. It includes making
|
|
||||||
hardware upgrades (mostly adding more storage), make management more accessible (such as Dell IDRAC's WebSerial), some load testing to
|
|
||||||
identify painpoints, run an NWS machine in a cloud VM so I can say it's cross cloud (although my friends have told me this is cheating at creating
|
|
||||||
my own cloud), and trying to figure out how to set up an Anycast network. I don't think I can setup an Anycast network without selling
|
|
||||||
a kidney first. Renting a /24 CIDR alone would be more than I want to spend on a side project. I may look into setting it up with ipv6 only,
|
|
||||||
however I'd still have to jump through hoops to get an Autonomous System number from an RIR. I'll probably write a whole blog about Anycast
|
|
||||||
in the coming weeks.</p>
|
|
||||||
</li>
|
|
||||||
<li><p><strong>Reduced External Dependence:</strong> The main goal of NWS is to have no external dependence. In theory, everything but core internet infrastructure
|
|
||||||
should </p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<h2 id="olney">Olney</h2>
|
|
||||||
<p><code>Rust, ActixWeb, PostgreSQL</code></p>
|
|
||||||
<p>Olney is a new project I am starting with my friend <a href="https://sridharnandigam.com/">Sridhar Nandigam</a>. It aims to make
|
|
||||||
tracking your job applications easier. Most of my friends either use spreadsheets or Trello to track their job applications, I
|
|
||||||
think that we can make something that's a bit better for the job. Some features I'd like to have are: resume version attached to
|
|
||||||
your application, job posting notifications from job boards such as <a href="github.com/pittcsc/summer2024-internships">pittcsc</a>, and watching
|
|
||||||
your email for emails from recruiters. Currently, I have part of the backend setup with basic CRUD operations. Now that I'm done with
|
|
||||||
the latest batch of NWS work, this is next on my list to work on.</p>
|
|
||||||
<hr>
|
|
||||||
<p><strong>These projects had minimal/no work done on them:</strong> RingGold, SQUIRREL</p>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,82 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Side Project Log 8/15/2023</h1>
|
|
||||||
<p>This side project log covers work done from 8/8/2023 - 8/15/2023</p>
|
|
||||||
|
|
||||||
<h2 id="olney">Olney</h2>
|
|
||||||
<p>
|
|
||||||
I added a frontend to Olney and added a feature where it can automatically keep track of your job applications
|
|
||||||
by monitoring your email.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Frontend</h3>
|
|
||||||
<p>
|
|
||||||
The frontend was made with Svelte. I chose not to use any UI/CSS libraries as I wanted to keep the number of
|
|
||||||
dependencies low. This was another good opportunity to learn about Svelte.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Automatic Tracking via E-Mail</h3>
|
|
||||||
<p>
|
|
||||||
This is the killer feature that I initially set out to build Olney for. This works by having the user forward their
|
|
||||||
E-Mail to an instance of Olney. To receive E-Mail, Olney uses <a href="https://inbucket.org">Inbucket</a>, a mailserver
|
|
||||||
easily hostable within Docker. It listens on a websocket for incoming mail. Whenever a new mail message is received,
|
|
||||||
Olney uses the OpenAI API to get a summary of the email in the following format:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre><code class="language-json">
|
|
||||||
{
|
|
||||||
isRecruiting: bool, // is the message about recruiting?
|
|
||||||
recruitingInfo: null | {
|
|
||||||
location: string, // Location in City, Providence/State, Country format
|
|
||||||
company: string, // Casual name of company e.g: Google, Cisco, Apple
|
|
||||||
position: string, // Name of job position
|
|
||||||
type: "assessment" | "interview" | "offer" | "rejection" | "applied" // What the message is discussing
|
|
||||||
dateTime: string, // DateTime communication rec'd OR DateTime that is being discussed (i.e. interview date confirmation)
|
|
||||||
name: string // Name of event, giving more detail to type
|
|
||||||
} // null if message is not about recruiting, fill with values if it is
|
|
||||||
}
|
|
||||||
</code></pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Olney then takes some details from this data, namely: company, position, and location and then uses the OpenAI API to generate
|
|
||||||
an <a href="https://www.pinecone.io/learn/vector-embeddings/">embedding</a>. We then query the closest match out of the job applications
|
|
||||||
in the database (with <a href="https://github.com/pgvector/pgvector">pgvector</a>). Once we have the job application, we add
|
|
||||||
the event to the database, using the job application's id as a fkey.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I chose embedding as the lookup method so that we don't have to worry about the data parsed out of the email being an exact
|
|
||||||
match for what the user inputted. This also allows the lookup to work even when certain things such as location are missing from the
|
|
||||||
email.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Olney should be open-sourced/released within the next week or two.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<p><strong>These projects had minimal/no work done on them:</strong> NWS, RingGold, SQUIRREL</p>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/dark.min.css">
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
|
||||||
<script>hljs.highlightAll();</script>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,87 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Side Project Log 8/8/2023</h1>
|
|
||||||
<p>This side project log covers work done from 7/12/2023 - 8/8/2023</p>
|
|
||||||
|
|
||||||
<h2 id="squirrel">SQUIRREL</h2>
|
|
||||||
<p>
|
|
||||||
SQUIRREL has been updated to work with INSERT INTO and SELECT queries. I also refactored much of the codebase to do error handling more elegantly and to make the parser
|
|
||||||
more extensible. Here's a screenshot of table creation, data insertion, and data selection:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The biggest challenge of this part was working on the parser which has now been written three times. The approaches to the parsing were:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ol>
|
|
||||||
<li>
|
|
||||||
<b>Stepping through whitespace:</b> <p>This was my initial and naive approach to the problem. I split the input string by its whitespace
|
|
||||||
and then queried values by referencing their indexes in the split string. </p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<b>Regex:</b> <p>This approach was cleaner than the first and led to a small parser, however it required an external dependency (which I'm
|
|
||||||
trying to minimize), and would make it hard to add additional features to commands later down the line.</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<b>Finite state machine:</b> <p>This solution was more verbose than the others, however it allows for easier development. This method works
|
|
||||||
by splitting the query string into tokens. Tokens are the smallest piece of data that a parser recognizes. SQUIRREL gets them by splitting
|
|
||||||
the input by delimiters and using the split list as tokens (excluding whitespace) SQUIRREL recognizes the following characters as delimiters:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<code>
|
|
||||||
' ', ',', ';', '(', ')'
|
|
||||||
</code>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This means that the string "INSERT INTO test (id) VALUES (12);" would be parsed into the list: "INSERT", "INTO", "test", "(", "id", etc..
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Once we have our list of tokens, we iterate through them starting at a default state and perform a certain task for the given state, which
|
|
||||||
usually includes switching to another state. We do this until we reach the end state.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
For example, with the above insert statement, we would start in the IntoKeyword state which would ensure that "INTO" is the current token.
|
|
||||||
We would then transition to the TableName state which would read the table name and store it in the ParsedCommand struct we're returning. We
|
|
||||||
would then move to the ColumnListBegin state which would look for an opening parenthesis, and switch the state to ColumnName. This process
|
|
||||||
continues with the other parts of the query until the Semicolon state is reached which checks that the statement ends with a semicolon, then
|
|
||||||
returns the ParsedCommand struct.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Next steps for this are to add column selection to SELECT statements and add WHERE clauses to SELECT statements.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 id="olney">Olney</h2>
|
|
||||||
<p>
|
|
||||||
I added a feature to the Olney API which scans the <a href="https://github.com/SimplifyJobs/Summer2024-Internships">pittcsc (now Simplify) summer internships Github repo</a>
|
|
||||||
and parses the data into JSON format. I parsed the markdown file they have uisng regex which was relatively simple. There were some issues during development due to the
|
|
||||||
changing structure of the markdown file. These issues are being fixed on a rolling basis. I expect the changes to slowdown now that the transition from pittcsc to Simplify
|
|
||||||
is complete. You can access the JSON at <a href="https://olney.nickorlow.com/jobs">olney.nickorlow.com/jobs</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<p><strong>These projects had minimal/no work done on them:</strong> NWS, RingGold</p>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,79 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Spring Break 2023</h1>
|
|
||||||
<p>It's Spring Break, and that means I finally have time to spend all day working on side projects without having to worry about school.</p>
|
|
||||||
<p>I figured I should write out the side projects I plan to work on over the break</p>
|
|
||||||
<h2 id="ringgold">RingGold</h2>
|
|
||||||
<p><code>Rust, Swift, PostgreSQL</code></p>
|
|
||||||
<p>Last week, me and my cousin wanted to try out Apple's fitness competition feature that works with Apple Watch. It works
|
|
||||||
by giving you 1 point for every percent you complete of your move, exercise, and stand goals with a point cap of 600
|
|
||||||
per day. The issue with it was that it didn't work at all, not syncing on time if at all. I want to build a clone of it
|
|
||||||
with some additional features such as:</p>
|
|
||||||
<ul>
|
|
||||||
<li><p><strong>Notifications:</strong> I didn't like how it was possible to workout and gain a bunch of points and just completely blindside your opponent. Hopefully this would encourage users to workout even more.</p>
|
|
||||||
</li>
|
|
||||||
<li><p><strong>Widget/Watch Complication:</strong> Similar to the above, adding a homescreen widget or a watch complication would make it easier to keep up with your competitor's progress. </p>
|
|
||||||
</li>
|
|
||||||
<li><p><strong>Custom Competitions:</strong> I think it'd be nice to have competitions with custom rules and lengths so that you're not stuck with only one setting. Settings could include custom duration and custom caps on points.</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p>I'm building the web API for it in Rust and the mobile app in Swift. I chose these languages to gain more exposure to them, also
|
|
||||||
Swift was a good choice since the app is going to be platform specific to iOS due to its need to integrate with Apple Watch.
|
|
||||||
<em>(this is named after New Ringgold, PA)</em></p>
|
|
||||||
<h2 id="nws-container-deployment-service">NWS Container Deployment Service</h2>
|
|
||||||
<p><code>C#, Rancher</code></p>
|
|
||||||
<p>I've created my own hosting/cloud service called <a href="https://nws.nickorlow.com">Nick Web Services</a>. It currently allows people to deploy
|
|
||||||
dockerized applications on my geo-distributed k8s clusters running on Dell Poweredge servers. In order to actually deploy this, I
|
|
||||||
had to manually create the Kubernetes manifest files and then ssh into each individual server and apply them. I've setup
|
|
||||||
Rancher Fleet to automate this process by pulling the manifest from a git repo (this is something called gitops). I also
|
|
||||||
wrote an API to generate the manifest files and then upload them to a git repo. I have a video demo of this working that
|
|
||||||
you can watch <a href="https://youtu.be/WHdXWMFHuqA">here</a>.</p>
|
|
||||||
<p>Currently, the service works for deployment but only if you don't want to use SSL or you use Cloudflare's flexible SSL
|
|
||||||
technology. I wrote a separate blog post <a href="http://nickorlow.com/blog/ssl-in-nws-cds">here</a> about the challenges of doing this and how I plan on implementing it.
|
|
||||||
I'd like to complete part of this implementation during the break.</p>
|
|
||||||
<h2 id="verifiedbot">VerifiedBot</h2>
|
|
||||||
<p><code>JavaScript, Rust</code></p>
|
|
||||||
<p>This project isn't a personal project, as a lot of it was built by my friends <a href="https://arpan.one">Arpan</a> and <a href="https://benaubin.com/">Ben</a>.
|
|
||||||
A little over a year ago, we wanted to make a Discord bot to verify that people on some Discord servers we ran
|
|
||||||
went to the University of Texas. Initially, it worked by verifying you had a utexas.edu email address and then verifying
|
|
||||||
some additional information via LDAP. A few months ago Ben found out that using the SaaS survey software that the university uses
|
|
||||||
(qualtrics), we could have users verify themselves by using the university's SSO system. This works because qualtrics can send
|
|
||||||
data to a webhook when a survey is complete, and it can also require signing in with the university's SSO before filling out a survey.
|
|
||||||
It required that I write a <a href="https://github.com/Verified-Bot/aes-gcm-siv-wasm">wasm wrapper for an encryption library</a>. I wrote almost all the code for this function last year, but
|
|
||||||
due to a bug in qualtrics, it wasn't working properly. It seems that this bug has been fixed and we can start rolling it out.</p>
|
|
||||||
<h2 id="personal-website-facelift">Personal Website Facelift</h2>
|
|
||||||
<p><code>Typescript, React</code></p>
|
|
||||||
<p>My personal website (this one) is a little overdue for some design updates. My main focus will be making it more mobile
|
|
||||||
friendly. Last year, I made some improvements to make it usable on mobile but it still doesn't feel quite right. I also
|
|
||||||
think that it has some information overload in some areas such as the projects section. I think that to mitigate this I
|
|
||||||
might just have a small summary of each project and then you can click into each to learn more about it, similar to my
|
|
||||||
friend <a href="https://raulhigareda.com">Raul's Website</a>. I'm also considering a move to tab-based navigation so that I can have
|
|
||||||
more information in each section. Further down the line, I think I might re-write it using Svelte as I'm seeing it being used more and more
|
|
||||||
and would like to get some exposure to it.</p>
|
|
||||||
<h2 id="mahantongo">Mahantongo</h2>
|
|
||||||
<p><code>Rust, PostgreSQL</code></p>
|
|
||||||
<p>I'm one of the members of the Community Team that runs some UT Computer Science community Discord servers.
|
|
||||||
Currently, a Discord bot called Carlbot provides us a star-board, which is a specific channel where messages that 5 or more people
|
|
||||||
react to with a star emoji get posted. It's supposed to be a collection of the funniest and best messages sent on the server.
|
|
||||||
One of the things our server members have wanted is the addition of more '*-board' channels where you can create multiple star-board
|
|
||||||
like channels but with custom emojis. I'm writing it in Rust and I'm just hoping to use this project to get more acquainted with the language.</p>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,99 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h1 style="margin-bottom: 0px;">Extra</h1>
|
|
||||||
<p style="margin-top: 0px;">Extra bits of information about me</p>
|
|
||||||
|
|
||||||
<h2>Rail Photography</h2>
|
|
||||||
<p>
|
|
||||||
I take photos of trains and train stations fairly often.
|
|
||||||
If you would like to see these pictures, they are avaliable
|
|
||||||
<a href="https://www.instagram.com/nickorlow.on.rails/">here</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Bowling</h2>
|
|
||||||
<p>
|
|
||||||
I go bowling with some friends regularly. We track our scores
|
|
||||||
down to the throw in a csv. You can check out a website where
|
|
||||||
that data is compiled into a readable format
|
|
||||||
<a href="https://bart.nickorlow.com">here</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Personal Records</h2>
|
|
||||||
<table style="width: 100%;">
|
|
||||||
<tr>
|
|
||||||
<th>Activity</th>
|
|
||||||
<th>Effort</th>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>Location</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>1600m (1 mile)</td>
|
|
||||||
<td>4:34</td>
|
|
||||||
<td>November 14th, 2020</td>
|
|
||||||
<td>Williamson County Park</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Milk Mile</td>
|
|
||||||
<td>5:41</td>
|
|
||||||
<td>May 20th, 2021</td>
|
|
||||||
<td>Lake Travis High School</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>3200m (2 mile)</td>
|
|
||||||
<td>10:11</td>
|
|
||||||
<td>March 20th, 2021</td>
|
|
||||||
<td>Carroll High School</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>5000m XC</td>
|
|
||||||
<td>16:43</td>
|
|
||||||
<td>September 26th, 2020</td>
|
|
||||||
<td>Old Settler's Park</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Bench Press</td>
|
|
||||||
<td>280.5 Lbs</td>
|
|
||||||
<td>December 31st, 2024</td>
|
|
||||||
<td>Anytime Fitness - Pottsville, PA</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Squat</td>
|
|
||||||
<td>415 Lbs</td>
|
|
||||||
<td>August 10th, 2023</td>
|
|
||||||
<td>FUTO HQ</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Deadlift</td>
|
|
||||||
<td>415 Lbs</td>
|
|
||||||
<td>Augist 10th, 2023</td>
|
|
||||||
<td>FUTO HQ</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Bowling</td>
|
|
||||||
<td>170</td>
|
|
||||||
<td>April 19th, 2024</td>
|
|
||||||
<td>Texas Union Underground</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
BIN
out/favicon.ico
Before Width: | Height: | Size: 36 KiB |
|
@ -1,54 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h1 style="margin-bottom: 0px;">Nicholas Orlowsky</h1>
|
|
||||||
<p style="margin-top: 0px;">Software Engineer - Austin, TX</p>
|
|
||||||
<p>
|
|
||||||
<a href="https://git.nickorlow.com/nickorlow">[ Forgejo ]</a>
|
|
||||||
<a href="https://github.com/nickorlow">[ GitHub (mirrors) ]</a>
|
|
||||||
<a href="https://www.linkedin.com/in/nickorlow/">[ LinkedIn ]</a>
|
|
||||||
<a href="mailto:nickorlow@nickorlow.com">[ E-Mail ]</a>
|
|
||||||
<a href="https://github.com/nickorlow/resume/releases/download/latest/resume-nickorlow.pdf">[ Resume ]</a>
|
|
||||||
<!--<a href="https://old.nickorlow.com">[ My Old Website ]</a>-->
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="https://azuredevopspodcast.clear-measure.com/nick-orlowsky-deciding-to-major-in-computer-science-episode-197">[ Listen to me on the Azure DevOps podcast! ]</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I'm a computer science student at the University of Texas at Austin. I'm particularly
|
|
||||||
interested in infrastructure, distributed systems, and systems programming.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I run <a href="https://nws.nickorlow.com">Nick Web Services (NWS)</a>, a side project
|
|
||||||
that provides geo-distributed container hosting using Kubernetes on bare metal servers.
|
|
||||||
It achieved 100% uptime for over a year.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Outside of computers, I enjoy biking and weightlifting. I'm also a public transit enthusiast
|
|
||||||
and I take pictures of trains that I see, especially rare or special ones.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,24 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Rail Pictures</h1>
|
|
||||||
<p>All photos are Copyright © Nicholas Orlowsky</p>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,117 +0,0 @@
|
||||||
<head>
|
|
||||||
<title>Nicholas Orlowsky</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">[ Home ]</a>
|
|
||||||
<a href="/blog.html">[ Blog ]</a>
|
|
||||||
<a href="/projects.html">[ Projects ]</a>
|
|
||||||
<a href="/extra.html">[ Extra ]</a>
|
|
||||||
<hr/>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h1 style="margin-bottom: 0px;">Projects</h1>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>Nick Web Services (NWS)</h2>
|
|
||||||
<p><i>C#, Kubernetes, Rancher, and HAProxy</i></p>
|
|
||||||
<a href="https://nws.nickorlow.com">[ Project Website ]</a>
|
|
||||||
<p>
|
|
||||||
Nick Web Services is a cloud infrastructure provider service that I created and run.
|
|
||||||
It allows people to deploy containerized versions of their web apps across our multiple
|
|
||||||
servers. It provides geo-distributed high availability by default with no extra configuration
|
|
||||||
needed from users hosting their webapp with us.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Hardware-wise we use old Dell PowerEdge servers running Proxmox. We then have VMs running
|
|
||||||
in Proxmox that run Kubernetes clusters. We have 4 clusters currently: Austin, Hill Country,
|
|
||||||
Schuylkill, and Philadelphia. The deployments are managed through GitOps with Rancher Fleet.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>Anthracite Web Server</h2>
|
|
||||||
<p><i>C++ & Python</i></p>
|
|
||||||
<a href="https://github.com/nickorlow/anthracite">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
Anthracite is a simple web server written in C++. It currently supports HTTP/1.0 and HTTP/1.1.
|
|
||||||
The benchmarking tools for Anthracite are written in Python. Anthracite is optimized for performance
|
|
||||||
and rivals the performance of NGINX & Apache in our testing. It uses a thread-per-connection
|
|
||||||
architecture, allowing it to process many requests in paralell. Additionally, it caches all
|
|
||||||
files that it serves in memory to ensure that added latency from disk reads do not slow down requests.
|
|
||||||
Through writing Anthracite, I have learned to use different C++ profilers as well as some general
|
|
||||||
optimization techniques for C++.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>CavCash</h2>
|
|
||||||
<p><i>C#, Kubernetes, SQL Server, and MongoDB</i></p>
|
|
||||||
<a href="https://cavcash.com">[ Project Website ]</a>
|
|
||||||
<p>
|
|
||||||
CavCash was a company that I founded which built a debit-based payment system similar to
|
|
||||||
PayPal and Venmo. I assembled a 5 person team and took on a technical role in the company,
|
|
||||||
writing most of our backend codebase. Our backend used C#, ASP.NET, Microsoft SQL Server,
|
|
||||||
and MongoDB. Our infrastructure changed throughout the lifetime of the company, initially
|
|
||||||
it was on Microsoft Azure using Azure App Service. We then pivoted to AWS using Elastic
|
|
||||||
Beanstalk. We also ran on Google Cloud Platform using Compute Engine. Finally, we setup our
|
|
||||||
own servers in-house and managed our deployments with Kubernetes.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We launched in 2021, with the ability to send money between real banks using the ACH network.
|
|
||||||
We ended up processing a few hundred dollars in transaction volume before ultimately shutting
|
|
||||||
down due to a lack of funding. The website is now back up and everything works as it did in
|
|
||||||
2021, except adding funds from a bank account is not supported.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>SQUIRREL</h2>
|
|
||||||
<p><i>Rust</i></p>
|
|
||||||
<a href="https://github.com/nickorlow/squirrel">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
SQUIRREL stands for SQL Query Util-Izing Rust's Reliable and Efficient Logic. It is a SQL database
|
|
||||||
that I am writing in Rust. Currently, it can create tables, insert data into tables, and select all
|
|
||||||
data from a given table. The biggest challenge so far has been writing the parser. My next steps are
|
|
||||||
to add WHERE clauses to SELECT statements, allow column filtering in SELECT statements, and add DELETE
|
|
||||||
statements.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>Olney</h2>
|
|
||||||
<p><i>Rust, Postgres, Svelte, TypeScript, and OpenAI's API</i></p>
|
|
||||||
<a href="https://github.com/nickorlow/olney">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
Olney is a job application tracker that aims to be better than using a <a href="https://trello.com">Trello</a> board or a spreadsheet.
|
|
||||||
It allows users to create jobs and log custom events such as interviews, assessments, and other communication.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>SEPTA Site</h2>
|
|
||||||
<p><i>Svelte, TypeScript</i></p>
|
|
||||||
<a href="https://github.com/nickorlow/septa-site">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
SEPTA Site is a website that I created which can get your trip history, SEPTA Key balance,
|
|
||||||
and ridership statistics for your SEPTA Key. It utilizes SEPTA's new metro wayfinding instead
|
|
||||||
of their current wayfinding. I wrote the project to get a basic introduction to Svelte and
|
|
||||||
so that I could try to improve upon the UX of SEPTA's current website and mobile app.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="width: 100%; display: flex; justify-content: center; padding: 5px;">
|
|
||||||
<a href="https://github.com/nickorlow">[ See more projects on GitHub ]</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr />
|
|
||||||
<p style="margin-bottom: 0px;">Copyright © Nicholas Orlowsky 2025</p>
|
|
||||||
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
|
|
||||||
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
|
@ -1,22 +0,0 @@
|
||||||
* {
|
|
||||||
font-family: serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: #fefeaa;
|
|
||||||
margin: 20px auto;
|
|
||||||
max-width: 750px;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #114488;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
17821
package-lock.json
generated
Normal file
64
package.json
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
{
|
||||||
|
"name": "personal-site",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@material-ui/core": "^4.11.4",
|
||||||
|
"@testing-library/jest-dom": "^5.11.4",
|
||||||
|
"@testing-library/react": "^11.1.0",
|
||||||
|
"@testing-library/user-event": "^12.1.10",
|
||||||
|
"@types/jest": "^26.0.15",
|
||||||
|
"@types/node": "^12.0.0",
|
||||||
|
"@types/react": "^17.0.0",
|
||||||
|
"@types/react-animate-on-scroll": "^2.1.2",
|
||||||
|
"@types/react-dom": "^17.0.0",
|
||||||
|
"@types/react-slick": "^0.23.4",
|
||||||
|
"@types/react-tabs": "^2.3.2",
|
||||||
|
"@types/react-typing-animation": "^1.6.2",
|
||||||
|
"bootstrap": "^4.6.0",
|
||||||
|
"node-sass": "^6.0.1",
|
||||||
|
"pure-react-carousel": "^1.27.6",
|
||||||
|
"react": "^17.0.2",
|
||||||
|
"react-animate-on-scroll": "^2.1.5",
|
||||||
|
"react-bootstrap": "^1.6.1",
|
||||||
|
"react-dom": "^17.0.2",
|
||||||
|
"react-router": "^5.2.1",
|
||||||
|
"react-scripts": "4.0.3",
|
||||||
|
"react-slick": "^0.28.1",
|
||||||
|
"react-tabs": "^3.2.2",
|
||||||
|
"react-typing-animation": "^1.6.2",
|
||||||
|
"typescript": "^4.1.2",
|
||||||
|
"web-vitals": "^1.0.1"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "react-scripts start",
|
||||||
|
"build": "react-scripts build",
|
||||||
|
"test": "react-scripts test",
|
||||||
|
"eject": "react-scripts eject"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"extends": [
|
||||||
|
"react-app",
|
||||||
|
"react-app/jest"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"browserslist": {
|
||||||
|
"production": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"development": [
|
||||||
|
"last 1 chrome version",
|
||||||
|
"last 1 firefox version",
|
||||||
|
"last 1 safari version"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/webpack": "^5.28.0",
|
||||||
|
"babel-loader": "^8.1.0",
|
||||||
|
"ts-node": "^10.2.1",
|
||||||
|
"webpack": "^4.44.2",
|
||||||
|
"webpack-cli": "^4.8.0"
|
||||||
|
}
|
||||||
|
}
|
26
public/index.html
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="theme-color" content="#000000" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Nicholas Orlowsky's personal website"
|
||||||
|
/>
|
||||||
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
|
<title>Nicholas Orlowsky</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app. (are you using an outdated browser or just very privacy focused?) <!-- or are you looking at the source?--></noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
8
public/manifest.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"short_name": "personal-site",
|
||||||
|
"name": "My personal website",
|
||||||
|
"start_url": ".",
|
||||||
|
"display": "standalone",
|
||||||
|
"theme_color": "#000000",
|
||||||
|
"background_color": "#ffffff"
|
||||||
|
}
|
3
public/robots.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# https://www.robotstxt.org/robotstxt.html
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
165
src/App.css
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
.App {
|
||||||
|
text-align: center;
|
||||||
|
background-color: black;
|
||||||
|
min-height: 100vh;
|
||||||
|
width: 100vw !important;
|
||||||
|
max-width: 100vw !important;
|
||||||
|
font-size: calc(20px);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we do this because scroll snapping is broken on moz://a for some reason */
|
||||||
|
@supports (-moz-appearance:none){
|
||||||
|
html {
|
||||||
|
scroll-snap-type: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mobile won't play with snapping too well so we need to make it prox not mandatory */
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
html {
|
||||||
|
scroll-snap-type: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.child {
|
||||||
|
scroll-snap-align: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-up-anim {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(40px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity:1;
|
||||||
|
transform: translateY(0px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media only screen and (max-width: 993px) {
|
||||||
|
.fade-up-md {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fade-up-anim 2s forwards 200ms !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-up-md-2 {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fade-up-anim 2s forwards 400ms !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-up-md-3 {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fade-up-anim 2s forwards 600ms !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 768px) {
|
||||||
|
.fade-up {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fade-up-anim 2s forwards 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-up-2 {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fade-up-anim 2s forwards 400ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-up-3 {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fade-up-anim 2s forwards 600ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-up {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fade-up-anim 2s forwards 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-up-d3s {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fade-up-anim 2s forwards 3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-tx-anim {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity:1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-in-tx {
|
||||||
|
animation: fade-in-tx-anim 1s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-out{
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
z-index: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
99% {
|
||||||
|
opacity: .1;
|
||||||
|
z-index: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity:0;
|
||||||
|
z-index: -500;
|
||||||
|
display: none;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-out {
|
||||||
|
animation: fade-out 1s ease-in forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes move-left-atx-anim {
|
||||||
|
0% {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
margin-left: -17px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.move-left-atx {
|
||||||
|
animation: move-left-atx-anim 1s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-left: -35px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-snap-type: y proximity;
|
||||||
|
}
|
||||||
|
|
||||||
|
.child {
|
||||||
|
scroll-snap-align: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pfp {
|
||||||
|
border-radius: 100%;
|
||||||
|
width: 25%
|
||||||
|
}
|
9
src/App.test.tsx
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import App from './App';
|
||||||
|
|
||||||
|
test('renders learn react link', () => {
|
||||||
|
render(<App />);
|
||||||
|
const linkElement = screen.getByText(/learn react/i);
|
||||||
|
expect(linkElement).toBeInTheDocument();
|
||||||
|
});
|
45
src/App.tsx
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import React, {useState} from 'react';
|
||||||
|
import './App.css';
|
||||||
|
import Footer from "./components/footer/Footer";
|
||||||
|
import Hero from "./components/hero/Hero";
|
||||||
|
import AboutMe from "./components/about-me/AboutMe";
|
||||||
|
import Jobs from "./components/jobs/Jobs";
|
||||||
|
import Projects from "./components/projects/Projects";
|
||||||
|
import Hobbies from "./components/hobbies/Hobbies";
|
||||||
|
import Contact from "./components/contact/Contact";
|
||||||
|
import Terminal from "./components/terminal/Terminal";
|
||||||
|
import {
|
||||||
|
BrowserRouter as Router,
|
||||||
|
Switch,
|
||||||
|
Route,
|
||||||
|
Link
|
||||||
|
} from "react-router-dom";
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
|
||||||
|
const showTerm: boolean = new URLSearchParams(window.location.search).get("showTerm") === 'true';
|
||||||
|
const [isTerminalVisible, setIsTerminalVisible] = useState(showTerm);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Router basename={'/~nickorlo'}>
|
||||||
|
<Route path='*'>
|
||||||
|
<div className="App">
|
||||||
|
{showTerm && <Terminal isTerminalVisible={isTerminalVisible} setIsTerminalVisible={setIsTerminalVisible}/>}
|
||||||
|
{!isTerminalVisible &&
|
||||||
|
<div>
|
||||||
|
<Hero/>
|
||||||
|
<AboutMe/>
|
||||||
|
<Jobs/>
|
||||||
|
<Projects/>
|
||||||
|
<Hobbies/>
|
||||||
|
<Contact/>
|
||||||
|
<Footer/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</Route>
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
|
@ -1,15 +0,0 @@
|
||||||
<div>
|
|
||||||
<h1 style="margin-bottom: 0px;">Blog</h1>
|
|
||||||
<p style="margin-top: 0px;">A collection of my thoughts, some of them may be interesting</p>
|
|
||||||
<p><a href="./blogs/fpga-fun.html">[ FPGA Fun (CHIP-8 in hardware) ]</a> - April 20th, 2024</p>
|
|
||||||
<p><a href="./blogs/nws-postmortem-11-8-23.html">[ NWS Postmortem 11/08/23 ]</a> - November 16th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-10-20-23.html">[ Side Project Log 10/20/23 ]</a> - October 20th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-8-15-23.html">[ Side Project Log 8/15/23 ]</a> - August 15th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-8-8-23.html">[ Side Project Log 8/08/23 ]</a> - August 8th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-7-12-23.html">[ Side Project Log 7/12/23 ]</a> - July 12th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-4-29-23.html">[ Side Project Log 4/29/23 ]</a> - April 29th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-3-27-23.html">[ Side Project Log 3/27/23 ]</a> - March 27th, 2023</p>
|
|
||||||
<p><a href="./blogs/side-project-3-20-23.html">[ Side Project Log 3/20/23 ]</a> - March 20th, 2023</p>
|
|
||||||
<p><a href="./blogs/spring-break-2023.html">[ Spring Break 2023 ]</a> - January 20th, 2023</p>
|
|
||||||
<p><a href="./blogs/doing-c-assignments-in-csharp.html">[ Doing C assignments in C# ]</a> - March 18th, 2022</p>
|
|
||||||
</div>
|
|
|
@ -1,57 +0,0 @@
|
||||||
<h1>Doing C assignments in C#</h1>
|
|
||||||
<p>Thanks to Arpan Dhatt for doing most of the work on this (his blog here: <a href="https://arpan.one/posts/messing-with-gradescope/">https://arpan.one/posts/messing-with-gradescope/</a>)</p>
|
|
||||||
<p>At the end, he made this comment:</p>
|
|
||||||
<blockquote>
|
|
||||||
<p>And so, that's the end of this post. To whom it may concern, don't try doing your C assignment in C# (you know who you are).</p>
|
|
||||||
</blockquote>
|
|
||||||
<p>The reason for this comment (besides the fact that I talk about C# a lot) is due to the fact that C# requires a runtime to be installed for it to work. This is because C# does not compile to native bytecode but rather compiles to an intermediary language (dubbed CIL by Microsoft) and is then translated 'Just In Time' by the runtime. </p>
|
|
||||||
<p>This makes running assignments in a docker container where the runtime is not already installed considerably hard. One option we have is that we could just include the runtime in our submission. Sounds easy, right? Well it would be non-trivial to do but due to the fact that the .NET runtime is very large, I wouldn't consider this a good idea (Not to mention it's super boring). </p>
|
|
||||||
<p>The better solution is to use .NET's (experimental) AOT compilation feature (formerly called CoreRT). C# has had a number of attempts at an AOT compiler such as :</p>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://www.mono-project.com/docs/advanced/aot/">AOT</a> by Mono</li>
|
|
||||||
<li>LLD2CPP built by Unity</li>
|
|
||||||
<li><a href="https://docs.microsoft.com/en-us/dotnet/core/deploying/ready-to-run">Ready2Run</a> by Microsoft</li>
|
|
||||||
</ul>
|
|
||||||
<p>We'll be using the official Ready2Run AOT compilation built by Microsoft. In order to use it, all you have to do is add the following to your <code>nuget.config</code>:</p>
|
|
||||||
<pre><code class="lang-xml"><<span class="hljs-keyword">add</span> key=<span class="hljs-string">"nuget.org"</span> <span class="hljs-keyword">value</span>=<span class="hljs-string">"https://api.nuget.org/v3/index.json"</span> protocolVersion=<span class="hljs-string">"3"</span> />
|
|
||||||
</code></pre>
|
|
||||||
<p>and then install the package: <code>Microsoft.DotNet.ILCompiler</code>. After doing that if you run the command: <code>dotnet publish -r [Runtime] -c [Config]</code> and after waiting a considerable amount of time, you'll have a full-fledged C# application compiled directly to your target runtime's bytecode!</p>
|
|
||||||
<p>Compiling my simple Hello, Wold test to linux-x64 (<code>dotnet publish -r linux-x64 -c Release</code>) and adding it to my project files should let me run it using the same method Arpan used in his blog.</p>
|
|
||||||
<p>After doing that, we can follow the instructions followed by Arpan and viola! C# runs on Gradescope!</p>
|
|
||||||
<p>I don't recommend this but it was fun to do and I needed stuff to write in a blog. </p>
|
|
||||||
<h2 id="other-interesting-low-level-c-net-features">Other Interesting (Low Level) C#/.NET Features</h2>
|
|
||||||
<p>C# actually has many lower level features people don't expect it to have. Some of these include pointers and direct memory management. Pointers can be enabled by encasing your code in an unsafe code block.</p>
|
|
||||||
<p>Example (Written by <a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/unsafe-code">Microsoft</a>)</p>
|
|
||||||
<pre><code class="lang-csharp">
|
|
||||||
<span class="hljs-comment">// Normal pointer to an object.</span>
|
|
||||||
<span class="hljs-keyword">int</span>[] a = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[<span class="hljs-number">5</span>] { <span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>, <span class="hljs-number">40</span>, <span class="hljs-number">50</span> };
|
|
||||||
<span class="hljs-comment">// Must be in unsafe code to use interior pointers.</span>
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
<span class="hljs-comment">// Must pin object on heap so that it doesn't move while using interior pointers.</span>
|
|
||||||
fixed (<span class="hljs-keyword">int</span>* p = &a[<span class="hljs-number">0</span>])
|
|
||||||
{
|
|
||||||
<span class="hljs-comment">// p is pinned as well as object, so create another pointer to show incrementing it.</span>
|
|
||||||
<span class="hljs-keyword">int</span>* p2 = p;
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
|
|
||||||
<span class="hljs-comment">// Incrementing p2 bumps the pointer by four bytes due to its type ...</span>
|
|
||||||
p2 += <span class="hljs-number">1</span>;
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
|
|
||||||
p2 += <span class="hljs-number">1</span>;
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(<span class="hljs-string">"--------"</span>);
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p);
|
|
||||||
<span class="hljs-comment">// Dereferencing p and incrementing changes the value of a[0] ...</span>
|
|
||||||
*p += <span class="hljs-number">1</span>;
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p);
|
|
||||||
*p += <span class="hljs-number">1</span>;
|
|
||||||
<span class="hljs-built_in">Console</span>.WriteLine(*p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</code></pre>
|
|
||||||
<p>In .NET 6, the <code>NativeMemory</code> class was introduced which you can read about <a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativememory.alloc?view=net-6.0">here</a>. It allows for malloc-like memory allocation and freeing which can be important for high-performance workloads.</p>
|
|
||||||
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/dark.min.css">
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
|
||||||
<script>hljs.highlightAll();</script>
|
|
|
@ -1,183 +0,0 @@
|
||||||
<h1>FPGA Fun</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This semester at school, I took Advanced Computer Architecture. This has been
|
|
||||||
my favorite class in college so far. The class dives deeper into topics from
|
|
||||||
the regular Computer Architecture course, especially the parts that are
|
|
||||||
hand-waved over as being too complicated.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The class is project-based (mostly) and had 2 large-sized projects. One was
|
|
||||||
creating an out-of-order CPU in SystemVerilog, which I'll dive into in
|
|
||||||
another blog. The other was anything we wanted to do (so long as the instructor
|
|
||||||
approved it). My project was implementing the CHIP-8 and then GameBoy in
|
|
||||||
SystemVerilog.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The CHIP-8 part was initially easy, as I had
|
|
||||||
<a href="https://github.com/nickorlow/yacemu">previously written a CHIP-8
|
|
||||||
emulator in C</a>. My first stab at doing it in SV was done early in the
|
|
||||||
semester before I was too familiar with SV and how to write it properly.
|
|
||||||
The code resembled my C code, having one large case statement that would use
|
|
||||||
blocking assignments to complete instructions. I used
|
|
||||||
<a href="https://veripool.org/verilator">Verilator</a> to simulate and test
|
|
||||||
my design. Verilator was very nice as I could do FFI (Verilator calls it DPI)
|
|
||||||
to talk to C++ code from my SV code. This allowed me to use SDL2 to take
|
|
||||||
user input and to display the CHIP-8's screen on my laptop. I managed to get
|
|
||||||
a fully working version of it done in a few days.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
After this, I was able to borrow an FPGA from my instructor and set out to
|
|
||||||
run my CHIP-8 on real hardware. I ordered a ST7920 LCD display, a buzzer, and
|
|
||||||
a 16 key keypad off of Amazon the next day.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>ST7920 Driver "The Bomb"</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The most time-consuming part of this project so far was interfacing with the
|
|
||||||
ST7920 LCD I ordered. The display has 2 modes for data transmission: 8/4 pin
|
|
||||||
parallel, and serial. The specification for the parallel interface seemed to
|
|
||||||
be the most straightforward, so I went ahead with implementing my driver
|
|
||||||
with that.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The ST7920 has a
|
|
||||||
<a href="https://www.waveshare.com/datasheet/LCD_en_PDF/ST7920.pdf">fairly
|
|
||||||
straightforward interface</a> for drawing to the screen. It works by sending
|
|
||||||
8-bit instructions to the display controller. You first send a few
|
|
||||||
initialization instructions to clear the display's memory and reset its state.
|
|
||||||
After that you can select a mode (text or graphics). Both modes work similarly
|
|
||||||
to where you set the position of the cursor on the screen and then send
|
|
||||||
instructions that write pixels or text to that coordinate and then advances
|
|
||||||
the coordinate by one.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I ran into trouble where I couldn't get anything to show up. Not even a simple
|
|
||||||
"Hello World". To troubleshoot, I borrowed a friend's Arduino Mini which has
|
|
||||||
proper drivers written for it for interfacing with the LCD. After hooking the
|
|
||||||
display up to it, it also couldn't draw anything! It wasn't until I tried
|
|
||||||
running it in serial mode that it worked. As it turns out, some manufacturers
|
|
||||||
solder capacitors on the back that can disable certain features of the display
|
|
||||||
(such as parallel mode), and my display's manufacturer had done just that. For
|
|
||||||
this reason, I'd highly recommend buying from a big-name seller of electronic
|
|
||||||
components such as Adafruit instead of random Amazon sellers.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Now that I knew that only the serial interface worked, I had to rewrite my
|
|
||||||
driver to use it. This meant instead of putting all 8 bits of an instruction
|
|
||||||
onto 8 pins at once, I'd have 2 pins: a clock and a data pin. In order to send
|
|
||||||
an 8 bit instruction, I'd send a clock signal and set the data pin to either
|
|
||||||
1 or 0 based on whether the nth bit in my instruction would be a 1 or 0. There
|
|
||||||
are additional device-specific characteristics of the ST7920's serial interface
|
|
||||||
described in the above linked datasheet, but they're not relevant to getting
|
|
||||||
the general idea of SPI (Serial Parallel Interface).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div style="width: 100%; display: flex; justify-content: center; flex-flow: column; align-items: center;">
|
|
||||||
<img src="/blog-images/the-bomb-text.png" style="max-width: 500px; margin: 10px;">
|
|
||||||
<img src="/blog-images/the-bomb-graphical.jpg" style="max-width: 500px; margin: 10px;">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I implemented a serial driver with a little demo screen (see above image), and
|
|
||||||
then modified the code to accept a block of memory of which it would then
|
|
||||||
draw out to the display. This left me with a general-purpose ST7920 serial driver!
|
|
||||||
Implementing a serial driver for this display gave me a good amount of
|
|
||||||
experience in dealing with timing outside of simulations. It also taught
|
|
||||||
me about debouncing and metastability.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The driver is hosted on GitHub
|
|
||||||
<a href="https://github.com/nickorlow/the-bomb/">here</a>. The name "The Bomb"
|
|
||||||
was coined by my girlfriend who thought all the jumper wires and exposed
|
|
||||||
PCBs made it look like I was building a bomb. (I'd like to be clear that I have
|
|
||||||
never nor never intend to build a bomb)
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Rewriting CHIP-8 "yayacemu"</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
With my display driver finally done, I decided to try to hook my CHIP-8 code up
|
|
||||||
to it and run it on the FPGA. I was really excited to actually run something on
|
|
||||||
hardware. Then the build time started climbing and Intel Quartus crashed. I
|
|
||||||
knew that this was a sign that I messed up. Through other projects in the class
|
|
||||||
I learned a bit about Verilog and HDL best practices and knew that my giant
|
|
||||||
blocking assignment switch statement would not run well, even if it would
|
|
||||||
compile.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Rewriting the CHIP-8 to work in a way that's more consistent with how processors
|
|
||||||
actually work and not how emulators work was fairly easy as I had done similar
|
|
||||||
work previously. To do so, I turned the processor into a state machine where
|
|
||||||
there was a state for each of the
|
|
||||||
<a href="https://en.wikipedia.org/wiki/Classic_RISC_pipeline">traditional 5
|
|
||||||
stages of the classic RISC pipeline.</a> Each state would do what it needed
|
|
||||||
to do and then move it into the next state. This design actually made logic
|
|
||||||
very simple as I was able to combine the functionality for a lot of instructions.
|
|
||||||
For example, a register to register load and an immediate to register load could use the
|
|
||||||
same writeback logic, as by that stage they would be loading bits into a register.
|
|
||||||
I didn't make it pipelined or do any fancy optimizations, mostly due to the fact
|
|
||||||
that the CHIP-8 is supposed to run at ~480 Hz. It also wasn't in the scope of
|
|
||||||
this project, as this was more about learning how different parts of a
|
|
||||||
computer interact and how real-world ISA implementations are done.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
At this point, I had a working CHIP-8 implemented in hardware sans a buzzer
|
|
||||||
and user input. These parts I was able to knock out fairly quickly. The buzzer
|
|
||||||
was dead simple, I just set its positive pin to high whenever the sound timer
|
|
||||||
was greater than zero. The keypad was a little more challenging, but much
|
|
||||||
simpler than the display. The keypad has 8 pins that are split between
|
|
||||||
4 column pins and 4 row pins. The FPGA sets 1 column pin to low and the rest
|
|
||||||
to high on every clock cycle and reads the output from the row pins to
|
|
||||||
determine which key is pressed. For instance if the first column pin was the
|
|
||||||
one the FPGA had set to low, and then the FPGA read that the first row pin
|
|
||||||
was outputting high, it would know that the pressed key was at coordinate
|
|
||||||
(1,1) (i.e. the first key).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<video controls style="max-width: 500px;">
|
|
||||||
<source src="/blog-images/fpga-tetris.mp4" type="video/mp4">
|
|
||||||
Your browser does not support the video tag.
|
|
||||||
</video>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
And after doing all of that, we can play Tetris!
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The source code for
|
|
||||||
yayacemu is hosted <a href="https://github.com/nickorlow/yayacemu">here</a>.
|
|
||||||
The CHIP-8 emulator I wrote in C was called yacemu (Yet Another Chip-8 Emulator),
|
|
||||||
and the naming for this is yayacemu (Yet Another Yet Another Chip-8 Emulator).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>The GameBoy</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I started writing the GameBoy implementation around the same time as I got the
|
|
||||||
FPGA. As such, it's code structure heavily mirrored that of my first attempt
|
|
||||||
at the CHIP-8's. For the project, I made no commitments to running it on an
|
|
||||||
FPGA, and much of the GameBoy is implemented, so I'm pushing forward with
|
|
||||||
keeping that structure. So far, the GameBoy can successfully run the bootrom,
|
|
||||||
draw the background layer to the display, and run a little bit of the Tetris
|
|
||||||
ROM (not enough to show anything yet).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<video controls style="max-width: 500px;">
|
|
||||||
<source src="/blog-images/gameboy-boot.mp4" type="video/mp4">
|
|
||||||
Your browser does not support the video tag.
|
|
||||||
</video>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The emulator booting!
|
|
||||||
</p>
|
|
|
@ -1,89 +0,0 @@
|
||||||
<h1>NWS Incident Postmortem 11/08/2023</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
On November 8th, 2023 at approximately 09:47 UTC, NWS suffered
|
|
||||||
a complete outage. This outage resulted in the downtime of all
|
|
||||||
services hosted on NWS and the downtime of the NWS Management
|
|
||||||
Engine and the NWS dashboard.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The incident lasted 38 minutes after which it was automatically
|
|
||||||
resolved and all services were restored. This is NWS' first
|
|
||||||
outage event of 2023.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Cause</h2>
|
|
||||||
<p>
|
|
||||||
NWS utilizes several tactics to ensure uptime. A component of
|
|
||||||
this is load balancing and failover. This service is currently
|
|
||||||
provided by Cloudflare at the DNS level. Cloudflare sends
|
|
||||||
health check requests to NWS servers at specified intervals. If
|
|
||||||
it detects that one of the servers is down, it will remove the
|
|
||||||
A record from entry.nws.nickorlow.com for that server (this domain
|
|
||||||
is where all services on NWS direct their traffic via a
|
|
||||||
CNAME).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
At around 09:47 UTC, Cloudflare detected that our servers in
|
|
||||||
Texas (Austin and Hill Country) were down. It did not detect an
|
|
||||||
error, but rather an HTTP timeout. This is an indication that the
|
|
||||||
server may have lost network connectivity. When Cloudflare detected that the
|
|
||||||
servers were down, it removed their A records from the
|
|
||||||
entry.nws.nickorlow.com domain. Since NWS Pennsylvania servers
|
|
||||||
have been undergoing maintenance since August 2023, this left no
|
|
||||||
servers able to serve requests routed to entry.nws.nickorlow.com,
|
|
||||||
resulting in the outage.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
NWS utilizes UptimeRobot for monitoring the uptime statistics of
|
|
||||||
services on NWS and NWS servers. This is the source of the
|
|
||||||
statistics shown on the NWS status page.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
UptimeRobot did not detect either of the Texas NWS servers as being
|
|
||||||
offline for the duration of the outage. This is odd, as UptimeRobot
|
|
||||||
and Cloudflare did not agree on the status of NWS servers. Logs
|
|
||||||
on NWS servers showed that requests from UptimeRobot were being
|
|
||||||
served while no requests from Cloudflare were shown in the logs.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
No firewall rules existed that could have blocked the healthcheck traffic from Cloudflare
|
|
||||||
for either of the NWS servers. There was no other configuration
|
|
||||||
found that would have blocked these requests. As these servers
|
|
||||||
are on different networks inside different buildings in different
|
|
||||||
parts of Texas, their networking equipment is entirely separate.
|
|
||||||
This rules out any failure of networking equipment owned
|
|
||||||
by NWS. This leads us to believe that the issue may have been
|
|
||||||
caused due to an internet traffic anomaly, although we are currently
|
|
||||||
unable to confirm that this is the cause of the issue.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This is being actively investigated to find a more concrete root
|
|
||||||
cause. This postmortem will be updated if any new information is
|
|
||||||
found.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
A similar event occurred on November 12th, 2023 lasting for 2 seconds.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Fix</h2>
|
|
||||||
<p>
|
|
||||||
The common factor between both of these servers is that they both use
|
|
||||||
Spectrum for their ISP and that they are located near Austin, Texas.
|
|
||||||
The Pennsylvania server maintenance will be expedited so that we have
|
|
||||||
servers online that operate with no commonalities.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
NWS will also investigate other methods of failover and load
|
|
||||||
balancing.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>Last updated on November 16th, 2023</p>
|
|
|
@ -1,99 +0,0 @@
|
||||||
<h1>Side Project Log 10/20/2023</h1>
|
|
||||||
<p>This side project log covers work done from 8/15/2023 - 10/20/2023</p>
|
|
||||||
|
|
||||||
<h2 id="anthracite">Anthracite</h2>
|
|
||||||
<a href="https://github.com/nickorlow/anthracite">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
Anthracite is a web server written in C++. The site you're reading this on
|
|
||||||
right now is hosted on Anthracite. I wrote it to deepen my knowledge of C++ and networking protocols. My
|
|
||||||
main focus of Anthracite is performance. While developing anthracite,
|
|
||||||
I have been exploring different optimization techniques and benchmarking
|
|
||||||
Anthracite against popular web servers such as NGINX and Apache.
|
|
||||||
Anthracite supports HTTP/1.1 and only supports GET requests to request
|
|
||||||
files stored on a server.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Anthracite currently performs on par with NGINX and Apache when making
|
|
||||||
1000 requests for a 50MB file using 100 threads in a Docker container.
|
|
||||||
To achieve this performance, I used memory profilers to find
|
|
||||||
out what caused large or repeated memory copies to occur. I then updated
|
|
||||||
those sections of code to remove or minimize these copies. I also
|
|
||||||
made it so that Anthracite caches all files it can serve in memory. This
|
|
||||||
avoids unnecessary and costly disk reads. The implementation of this is
|
|
||||||
subpar, as it requires that the server be restarted whenever the files
|
|
||||||
it is serving are changed for the updates to be detected by Anthracite.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I intend to make further performance improvements, specifically in the request
|
|
||||||
parser. I also plan to implement HTTP/2.0.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 id="yacemu">Yet Another Chip Eight Emulator (yacemu)</h2>
|
|
||||||
<a href="https://github.com/nickorlow/yacemu">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
YACEMU is an interpreter for the CHIP-8 instruction set written in C. My main
|
|
||||||
goal when writing it was to gain more insight into how emulation works. I had
|
|
||||||
previous experience with this from when I worked on an emulator for a slimmed-down
|
|
||||||
version of X86 called <a href="https://web.cse.ohio-state.edu/~reeves.92/CSE2421sp13/PracticeProblemsY86.pdf">Y86</a>.
|
|
||||||
So far, I've been able to get most instructions working. I need to work on adding
|
|
||||||
input support so that users can interact with programs running in yacemu. It has
|
|
||||||
been fairly uncomplicated and easy to write thus far. After I complete it, I would
|
|
||||||
like to work on an emulator for a real device such as the GameBoy (This might be
|
|
||||||
biting off more than I can chew).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 id="nick-vim">Nick VIM</h2>
|
|
||||||
<p>
|
|
||||||
Over the summer while I was interning, I began using VIM as my primary
|
|
||||||
text editor. I used a preconfigured version of it (<a href="https://nvchad.com/">NvChad</a>) to save time, as
|
|
||||||
setting everything up can take a while. After using it for a few months, I began
|
|
||||||
making my own configuration for VIM, taking what I liked from NvChad and leaving
|
|
||||||
behind the parts that I didn't like as much.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<img src="/blog-images/NickVIM_Screenshot.png" alt="Screenshot of an HTML file open for editing in NickVIM"/>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
One important part of Nick VIM was ensuring that it was portable between different
|
|
||||||
machines. I wanted the machine to have as few dependencies as possible so that I
|
|
||||||
could get NickVIM set up on any computer in a couple of minutes. This will be especially
|
|
||||||
useful when working on my School's lab machines and when switching to new computers
|
|
||||||
in the future. I achieved this by dockerizing Nick VIM. This is based on what one of
|
|
||||||
my co-workers does with their VIM setup. The Docker container contains
|
|
||||||
all the dependencies for each language server. Whenever you edit a file with Nick Vim,
|
|
||||||
the following script runs:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<code lang="bash">
|
|
||||||
echo Starting container...
|
|
||||||
cur_dir=`pwd`
|
|
||||||
container_name=${cur_dir////$'_'}
|
|
||||||
container_name="${container_name:1}_$RANDOM"
|
|
||||||
docker run --name $container_name --network host -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --mount type=bind,source="$(pwd)",target=/work -d nick-vim &> /dev/null
|
|
||||||
|
|
||||||
echo Execing into container...
|
|
||||||
docker exec -w /work -it $container_name bash
|
|
||||||
|
|
||||||
echo Stopping container in background...
|
|
||||||
docker stop $container_name &> /dev/null &
|
|
||||||
</code>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This code creates a new container, forwards the host's clipboard to the container, and
|
|
||||||
mounts the current directory inside the container for editing.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 id="secane">Secane</h2>
|
|
||||||
<p><a href="https://www.youtube.com/watch?v=tKRehO7FH_s">[ Video Demo ]</a></p>
|
|
||||||
<p>
|
|
||||||
Secane was a simple ChatGPT wrapper that I wrote to practice for the behavioral part of
|
|
||||||
job interviews. It takes your resume, information about the company, and information about
|
|
||||||
the role you're interviewing for. It also integrates with OpenAI's whisper, allowing you
|
|
||||||
to simulate talking out your answers. I made it with Next.JS.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
<p><strong>These projects had minimal/no work done on them:</strong> NWS, RingGold, SQUIRREL</p>
|
|
||||||
<p><strong>These projects I will no longer be working on:</strong> Olney</p>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<h1>Side Project Log 3/20/2023</h1>
|
|
||||||
<p>Spring break just wrapped up. I wrote a <a href="">blog</a> last week about the side projects that I was planning on
|
|
||||||
doing. I wanted to provide an update on what I got done, and figured I'd turn it into a recurring thing.</p>
|
|
||||||
<p>This side project log covers work done from 3/13/2023 - 3/20/2023</p>
|
|
||||||
<h2 id="-personal-website-facelift-https-github-com-nickorlow-personal-site-"><a href="https://github.com/nickorlow/personal-site">Personal Website Facelift</a></h2>
|
|
||||||
<p>I managed to move my website over to tab-based navigation pretty early on in the break. It just involved setting
|
|
||||||
up a navbar component and then using react-navigation to navigate between pages. I also managed to
|
|
||||||
update my projects page to be more compact and readable. </p>
|
|
||||||
<p>There is still work to be done on making it look better, but I mostly believe that
|
|
||||||
it's just going to be somewhat minor tweaks.</p>
|
|
||||||
<h2 id="-mahantongo-https-github-com-nickorlow-mahantongo-"><a href="https://github.com/nickorlow/mahantongo">Mahantongo</a></h2>
|
|
||||||
<p>I managed to finish this one. I learned a lot about Rust and I've gained an appreciation for
|
|
||||||
Rust's enforcement of good programming habits, and I really like how error handling is done.</p>
|
|
||||||
<p>Working with Serenity was pretty easy as it mirrored some of the other Discord SDKs I've used
|
|
||||||
before.</p>
|
|
||||||
<hr>
|
|
||||||
<p><strong>The below projects had minimal/no work done on them:</strong> RingGold, NWS Container Deployment Service, and VerifiedBot </p>
|
|
|
@ -1,17 +0,0 @@
|
||||||
<h1>Side Project Log 3/27/2023</h1>
|
|
||||||
<p>This side project log covers work done from 3/20/2023 - 3/27/2023</p>
|
|
||||||
<h2 id="septa-site">SEPTA Site</h2>
|
|
||||||
<p>I started a new project that aimed to recreate parts of SEPTA's website with a more elegant UI, and using
|
|
||||||
SEPTA's new "SEPTA Metro" wayfinding. The main goal with this project was to help me learn Svelte. I also had
|
|
||||||
to reverse-engineer the APIs on septakey.org in order to authenticate a user and get their trip history. </p>
|
|
||||||
<p>In terms of Svelte, I really enjoyed working with it and overall I found it much more elegant and easier to work
|
|
||||||
with than React. I didn't like the way it handled client-server interaction with its serverside functions. </p>
|
|
||||||
<p>I have not made this open source yet and do not intend to until it's more polished.</p>
|
|
||||||
<h2 id="-verified-bot-https-github-com-benaubin-verified-bot-"><a href="https://github.com/benaubin/verified-bot">Verified Bot</a></h2>
|
|
||||||
<p>I made all the necessary changes and tests to get VerifiedBot working. It is now waiting on my friend Ben
|
|
||||||
to merge my PR with the changes outlined in my <a href="https://nickorlow.com/blog/spring-break-2023">spring break blog</a>.</p>
|
|
||||||
<h2 id="-mahantongo-https-github-com-nickorlow-mahantongo-"><a href="https://github.com/nickorlow/mahantongo">Mahantongo</a></h2>
|
|
||||||
<p>I created some QoL features, such as using Discord's embeds instead of sending regular text messages, showing which board
|
|
||||||
a post was on, and fixing some bugs.</p>
|
|
||||||
<hr>
|
|
||||||
<p><strong>The below projects had minimal/no work done on them:</strong> RingGold, and NWS Container Deployment Service </p>
|
|
|
@ -1,25 +0,0 @@
|
||||||
<h1>Side Project Log 4/29/2023</h1>
|
|
||||||
<p>This side project log covers work done from 3/27/2023 - 4/29/2023</p>
|
|
||||||
<p>This side project log is a bit late due to it being a busy month of school, but today is my last day!</p>
|
|
||||||
<h2 id="septa-site">SEPTA Site</h2>
|
|
||||||
<p>This week, I published SEPTA Site on Github, you can find it here: <a href="https://github.com/nickorlow/septa-site">github.com/nickorlow/septa-site</a>.</p>
|
|
||||||
<p>I made a few tweaks to it in terms of styling and also wrote a descriptive README to give people instructions on how to run it as I don't want
|
|
||||||
to host it myself since it handles credentials from another service.</p>
|
|
||||||
<h2 id="squirrel">SQUIRREL</h2>
|
|
||||||
<p>SQUIRREL, short for SQL Query Util-Izing Rust's Reliable and Efficient Logic, is a SQL database that I am writing in Rust. Currently, it can
|
|
||||||
parse CREATE TABLE commands, and works with the data types varchar and int. I plan to implement basic CRUD operations, then add JOINs, and
|
|
||||||
then try to make it wire-compatible with Postgres.</p>
|
|
||||||
<p>This project is currently not open-sourced as I am waiting to add more features and polish it up more.</p>
|
|
||||||
<h2 id="swole-control">Swole Control</h2>
|
|
||||||
<p>This one isn't a <em>personal</em> project, however it is a project that I worked on with a group. We began working on it in February as a part of a
|
|
||||||
club at UT called Texas Convergent. We recently presented it at the club's demo day and won the prize for having the best business.</p>
|
|
||||||
<p>Swole Control is an app that monitors machine usage at a gym on a machine-by-machine level, providing gym goers with information about what machines
|
|
||||||
are free (this is a major pain point as a gym goer myself). It also provides gym owners with statistics on which machines are most popular, providing
|
|
||||||
them valuable insights into their business.</p>
|
|
||||||
<p>To achieve this, we built hardware that consisted of an ESP-32 micro controller and an ultrasonic distance sensor. This hardware is mounted on a gym machine
|
|
||||||
and it measures the distance to the nearest object. It then sends this measurement to a Rust backend which stores it in a Firestore database (although we had
|
|
||||||
a fork of it that worked with Postgres). The backend then uses these measurements and compares them to a baseline to determine if there is a user at a machine.
|
|
||||||
Our mobile app then reads this from the Firestore database (it's planned to have it read this from the API to have a better-defined application boundary). The
|
|
||||||
frontend is written in React Native.</p>
|
|
||||||
<hr>
|
|
||||||
<p><strong>These projects had minimal/no work done on them:</strong> RingGold, and NWS Container Deployment Service</p>
|
|
|
@ -1,70 +0,0 @@
|
||||||
<h1>Side Project Log 7/12/2023</h1>
|
|
||||||
<p>This side project log covers work done from 4/29/2023 - 7/12/2023</p>
|
|
||||||
<p>This side project log is more than a bit late due to working a busy summer internship at <a href="https://futo.org">FUTO</a>!</p>
|
|
||||||
<h2 id="nws-container-deployment-service">NWS Container Deployment Service</h2>
|
|
||||||
<p>I have finally added SSL to NWS CDS. This was challenging, as it required handling ACME challenges and certificate
|
|
||||||
distribution across a set of geo-distributed Kubernetes clusters. I detail the complexities of this in a <a href="http://nickorlow.com/blog/ssl-in-nws-cds">previous blog
|
|
||||||
I wrote</a>. In order to implement auto-created/auto-renewing SSL, I implemented the below solution:</p>
|
|
||||||
<p><img src="/blog-images/NWS_SSL_Diagram.png" alt="Diagram of NWS SSL Architecture"></p>
|
|
||||||
<p>First, a user creates a request to add SSL to their NWS CDS service through the web UI which calls the NWS API (not pictured)</p>
|
|
||||||
<p>Then, the NWS API calls SSLiaison (in-house written software) which adds the domain to Caddy's list of domains. Caddy will then attempt to create
|
|
||||||
an SSL certificate from an ACME server (not pictured).</p>
|
|
||||||
<p>The ACME server will query NWS for the challenge response by requesting a file at <code>/.well-known/acme-challenge</code> on the
|
|
||||||
domain to be verified (this is the green arrows). </p>
|
|
||||||
<p>HAProxy will re-route these requests to NWS Hill Country, which is where the NWS Management Engine (NWSME) lives (this is
|
|
||||||
the orange arrows). <em>(NWSME controls what's deployed on each k8s cluster on NWS)</em></p>
|
|
||||||
<p>HAProxy in NWS Hill Country will then route this request to Caddy, which will solve the <a href="https://letsencrypt.org/docs/challenge-types/">http-01 challenge</a>, and then get the certificate
|
|
||||||
from the ACME server. Once it does this, it will write the certificate to a directory that is bind-mounted to both Caddy
|
|
||||||
and SSLiaison. </p>
|
|
||||||
<p>SSLiaison will detect this new file, parse it into a k8s manifest file, and then add it to our GitOps repo which is
|
|
||||||
hosted in GitHub.</p>
|
|
||||||
<p>From here, the certificate will be added to all the k8s clusters via Rancher Fleet.</p>
|
|
||||||
<hr>
|
|
||||||
<p>For next steps, I'd like to revise this solution such that it doesn't have a single point of failure.
|
|
||||||
Currently, if NWS Hill Country is down (which it is about 0.025% of the time), then SSL certificates
|
|
||||||
won't be able to be created or renewed. </p>
|
|
||||||
<p>To do this, I will have SSLiaison implement the ACME client specification so that it can create and respond do ACME HTTP challenges.
|
|
||||||
SSLiaison will run on NWS CDS (so that it's running on all of our k8s clusters and is HA) instead of running as a standalone docker container.
|
|
||||||
I'll have SSLiaison use some distributed database (probably CockroachDB) to store the HTTP challenges so that it doesn't matter
|
|
||||||
which k8s cluster the challenge request from the ACME server is routed to.</p>
|
|
||||||
<h2 id="next-steps-for-nws">Next Steps for NWS</h2>
|
|
||||||
<ul>
|
|
||||||
<li><strong>HA NWS Management Engine:</strong> Currently (as somewhat discussed above), the NWSME will go down when NWS Hill Country goes down. I'd like to
|
|
||||||
make it so that this isn't the case. This would likely just require that each NWS cluster runs its own instance of Rancher Fleet instead
|
|
||||||
of one central Rancher Fleet that manages all the clusters. It would also require the HA SSLiaison.</li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li><strong>IaC for Everything:</strong> Currently, all NWS CDS services are defined in yaml files in a git repo, however the underlying infrastructure that
|
|
||||||
it runs on is not. Ideally, I'd like every NWS machine to run Proxmox and then have Terraform & Ansible configs to define how to set up
|
|
||||||
vms on proxmox that will run the k8s clusters that support CDS services. This should eliminate my headaches of sshing into each machine
|
|
||||||
to apply config changes and make sure everything is standardized. It should also make the process of setting up new servers easy.</li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Monitoring:</strong> I've been working on setting up monitoring on a lot of our services at my current internship using the TIG stack (Telegraf,
|
|
||||||
InfluxDB, and Grafana). Now that I've been exposed to the usefulness of having a bunch of metrics on hand, I think it would be nice to have
|
|
||||||
some dashboards setup for NWS to monitor speed, resource usage, uptime, and traffic. Doing this would also make it possible to expose resource usage in the
|
|
||||||
NWS dashboard.</li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li><p><strong>Enhanced Infrastructure:</strong> This is kind of a blanket one for things I want to do that don't fit into other categories. It includes making
|
|
||||||
hardware upgrades (mostly adding more storage), make management more accessible (such as Dell IDRAC's WebSerial), some load testing to
|
|
||||||
identify painpoints, run an NWS machine in a cloud VM so I can say it's cross cloud (although my friends have told me this is cheating at creating
|
|
||||||
my own cloud), and trying to figure out how to set up an Anycast network. I don't think I can setup an Anycast network without selling
|
|
||||||
a kidney first. Renting a /24 CIDR alone would be more than I want to spend on a side project. I may look into setting it up with ipv6 only,
|
|
||||||
however I'd still have to jump through hoops to get an Autonomous System number from an RIR. I'll probably write a whole blog about Anycast
|
|
||||||
in the coming weeks.</p>
|
|
||||||
</li>
|
|
||||||
<li><p><strong>Reduced External Dependence:</strong> The main goal of NWS is to have no external dependence. In theory, everything but core internet infrastructure
|
|
||||||
should </p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<h2 id="olney">Olney</h2>
|
|
||||||
<p><code>Rust, ActixWeb, PostgreSQL</code></p>
|
|
||||||
<p>Olney is a new project I am starting with my friend <a href="https://sridharnandigam.com/">Sridhar Nandigam</a>. It aims to make
|
|
||||||
tracking your job applications easier. Most of my friends either use spreadsheets or Trello to track their job applications, I
|
|
||||||
think that we can make something that's a bit better for the job. Some features I'd like to have are: resume version attached to
|
|
||||||
your application, job posting notifications from job boards such as <a href="github.com/pittcsc/summer2024-internships">pittcsc</a>, and watching
|
|
||||||
your email for emails from recruiters. Currently, I have part of the backend setup with basic CRUD operations. Now that I'm done with
|
|
||||||
the latest batch of NWS work, this is next on my list to work on.</p>
|
|
||||||
<hr>
|
|
||||||
<p><strong>These projects had minimal/no work done on them:</strong> RingGold, SQUIRREL</p>
|
|
|
@ -1,60 +0,0 @@
|
||||||
<h1>Side Project Log 8/15/2023</h1>
|
|
||||||
<p>This side project log covers work done from 8/8/2023 - 8/15/2023</p>
|
|
||||||
|
|
||||||
<h2 id="olney">Olney</h2>
|
|
||||||
<p>
|
|
||||||
I added a frontend to Olney and added a feature where it can automatically keep track of your job applications
|
|
||||||
by monitoring your email.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Frontend</h3>
|
|
||||||
<p>
|
|
||||||
The frontend was made with Svelte. I chose not to use any UI/CSS libraries as I wanted to keep the number of
|
|
||||||
dependencies low. This was another good opportunity to learn about Svelte.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Automatic Tracking via E-Mail</h3>
|
|
||||||
<p>
|
|
||||||
This is the killer feature that I initially set out to build Olney for. This works by having the user forward their
|
|
||||||
E-Mail to an instance of Olney. To receive E-Mail, Olney uses <a href="https://inbucket.org">Inbucket</a>, a mailserver
|
|
||||||
easily hostable within Docker. It listens on a websocket for incoming mail. Whenever a new mail message is received,
|
|
||||||
Olney uses the OpenAI API to get a summary of the email in the following format:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre><code class="language-json">
|
|
||||||
{
|
|
||||||
isRecruiting: bool, // is the message about recruiting?
|
|
||||||
recruitingInfo: null | {
|
|
||||||
location: string, // Location in City, Providence/State, Country format
|
|
||||||
company: string, // Casual name of company e.g: Google, Cisco, Apple
|
|
||||||
position: string, // Name of job position
|
|
||||||
type: "assessment" | "interview" | "offer" | "rejection" | "applied" // What the message is discussing
|
|
||||||
dateTime: string, // DateTime communication rec'd OR DateTime that is being discussed (i.e. interview date confirmation)
|
|
||||||
name: string // Name of event, giving more detail to type
|
|
||||||
} // null if message is not about recruiting, fill with values if it is
|
|
||||||
}
|
|
||||||
</code></pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Olney then takes some details from this data, namely: company, position, and location and then uses the OpenAI API to generate
|
|
||||||
an <a href="https://www.pinecone.io/learn/vector-embeddings/">embedding</a>. We then query the closest match out of the job applications
|
|
||||||
in the database (with <a href="https://github.com/pgvector/pgvector">pgvector</a>). Once we have the job application, we add
|
|
||||||
the event to the database, using the job application's id as a fkey.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I chose embedding as the lookup method so that we don't have to worry about the data parsed out of the email being an exact
|
|
||||||
match for what the user inputted. This also allows the lookup to work even when certain things such as location are missing from the
|
|
||||||
email.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Olney should be open-sourced/released within the next week or two.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<p><strong>These projects had minimal/no work done on them:</strong> NWS, RingGold, SQUIRREL</p>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/dark.min.css">
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
|
||||||
<script>hljs.highlightAll();</script>
|
|
|
@ -1,65 +0,0 @@
|
||||||
<h1>Side Project Log 8/8/2023</h1>
|
|
||||||
<p>This side project log covers work done from 7/12/2023 - 8/8/2023</p>
|
|
||||||
|
|
||||||
<h2 id="squirrel">SQUIRREL</h2>
|
|
||||||
<p>
|
|
||||||
SQUIRREL has been updated to work with INSERT INTO and SELECT queries. I also refactored much of the codebase to do error handling more elegantly and to make the parser
|
|
||||||
more extensible. Here's a screenshot of table creation, data insertion, and data selection:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The biggest challenge of this part was working on the parser which has now been written three times. The approaches to the parsing were:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ol>
|
|
||||||
<li>
|
|
||||||
<b>Stepping through whitespace:</b> <p>This was my initial and naive approach to the problem. I split the input string by its whitespace
|
|
||||||
and then queried values by referencing their indexes in the split string. </p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<b>Regex:</b> <p>This approach was cleaner than the first and led to a small parser, however it required an external dependency (which I'm
|
|
||||||
trying to minimize), and would make it hard to add additional features to commands later down the line.</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<b>Finite state machine:</b> <p>This solution was more verbose than the others, however it allows for easier development. This method works
|
|
||||||
by splitting the query string into tokens. Tokens are the smallest piece of data that a parser recognizes. SQUIRREL gets them by splitting
|
|
||||||
the input by delimiters and using the split list as tokens (excluding whitespace) SQUIRREL recognizes the following characters as delimiters:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<code>
|
|
||||||
' ', ',', ';', '(', ')'
|
|
||||||
</code>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This means that the string "INSERT INTO test (id) VALUES (12);" would be parsed into the list: "INSERT", "INTO", "test", "(", "id", etc..
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Once we have our list of tokens, we iterate through them starting at a default state and perform a certain task for the given state, which
|
|
||||||
usually includes switching to another state. We do this until we reach the end state.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
For example, with the above insert statement, we would start in the IntoKeyword state which would ensure that "INTO" is the current token.
|
|
||||||
We would then transition to the TableName state which would read the table name and store it in the ParsedCommand struct we're returning. We
|
|
||||||
would then move to the ColumnListBegin state which would look for an opening parenthesis, and switch the state to ColumnName. This process
|
|
||||||
continues with the other parts of the query until the Semicolon state is reached which checks that the statement ends with a semicolon, then
|
|
||||||
returns the ParsedCommand struct.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Next steps for this are to add column selection to SELECT statements and add WHERE clauses to SELECT statements.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 id="olney">Olney</h2>
|
|
||||||
<p>
|
|
||||||
I added a feature to the Olney API which scans the <a href="https://github.com/SimplifyJobs/Summer2024-Internships">pittcsc (now Simplify) summer internships Github repo</a>
|
|
||||||
and parses the data into JSON format. I parsed the markdown file they have uisng regex which was relatively simple. There were some issues during development due to the
|
|
||||||
changing structure of the markdown file. These issues are being fixed on a rolling basis. I expect the changes to slowdown now that the transition from pittcsc to Simplify
|
|
||||||
is complete. You can access the JSON at <a href="https://olney.nickorlow.com/jobs">olney.nickorlow.com/jobs</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<p><strong>These projects had minimal/no work done on them:</strong> NWS, RingGold</p>
|
|
|
@ -1,176 +0,0 @@
|
||||||
<h1>How to get to Susquehanna on SEPTA</h1>
|
|
||||||
<!--<p>
|
|
||||||
As a preface, all of this is assuming you're an
|
|
||||||
intern trying to get to Susquehanna from the Windsor
|
|
||||||
Suites. If you're staying elsewhere in center
|
|
||||||
city, this guide is sill useful to you, however
|
|
||||||
the specific stations that I mention may be further
|
|
||||||
away from your hotel/apartment. I'd reccomend
|
|
||||||
checking to see if any of the routes I menton
|
|
||||||
have stops closer to you.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
SEPTA recently began replacing signs and renaming
|
|
||||||
lines as a part of their "<a href="https://wwww.septa.org/metro/">SEPTA Metro</a>" campaign.
|
|
||||||
This guide will use the older SEPTA terminology,
|
|
||||||
as it's mostly what's being used still. To avoid confusion:
|
|
||||||
<ul>
|
|
||||||
<li>The "B Line" refers to the Broad Street Line/Broad-Ridge Spur</li>
|
|
||||||
<li>The "L Line" (aka the "El") refers to the Market-Frankford Line</li>
|
|
||||||
<li>The "T Lines" refer to the trolley lines excluding Girard Av.</li>
|
|
||||||
</ul>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Other lines like the NHSL were also renamed, but they're not
|
|
||||||
discussed in this guide.
|
|
||||||
</p>-->
|
|
||||||
|
|
||||||
<h2>General SEPTA tips (please read!)</h2>
|
|
||||||
<ul>
|
|
||||||
<!--<li>
|
|
||||||
Look at your bus driver when the bus pulls up to the stop.
|
|
||||||
Make sure they see you, if they don't see anyone, they will
|
|
||||||
skip the stop.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Get to your stop (whether it's bus/rr/subway) at least
|
|
||||||
5 minutes early. If your ride is running early, they will
|
|
||||||
likely leave early as well.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Get a <a href="https://www.septakey.org/">SEPTA Key</a>. While you can use a credit card on SEPTA,
|
|
||||||
if you need to use Regional Rail on a trip starting in
|
|
||||||
center city, you MUST have a SEPTA Key. It's nice to have
|
|
||||||
so you're not in a rush if the bus is cancelled, and you
|
|
||||||
need to take the train.
|
|
||||||
</li>-->
|
|
||||||
<li>
|
|
||||||
Trains/subways are almost always more reliable than busses.
|
|
||||||
Operator avaliability and traffic cause the bus system to
|
|
||||||
have large unpredictable delays.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Get information about what time your bus/train will arrive from
|
|
||||||
the SEPTA app. Google Maps is very bad with showing delays/cancellations.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The <a href="https://transitapp.com/">Transit App</a> is another good and reliable app for transit
|
|
||||||
directions, and also the easiest to use.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Whenever riding <u>non regional rail</u> SEPTA services, you receive
|
|
||||||
2 free transfers to other <u>non regional rail</u> SEPTA services. This
|
|
||||||
means that if you take the bus/trolley/subway, you can take 2 more
|
|
||||||
bus/trolley/subway rides for free <u>within the next 2 hours</u>.
|
|
||||||
You do not need to transfer to the same mode of transit. For example:
|
|
||||||
you can transfer from bus to subway or bus to bus or anything else you'd
|
|
||||||
like. <u>You must pay with a SEPTA Key or a contactless credit/debit card
|
|
||||||
to receive this benefit, and you must use the same payment method
|
|
||||||
for all transfers</u>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The niceness/cleanliness of SEPTA's transit modes usually ranks:
|
|
||||||
<ol>
|
|
||||||
<li>Regional Rail</li>
|
|
||||||
<li>Bus/Trolley</li>
|
|
||||||
<li>Subway</li>
|
|
||||||
</ol>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Reccommended Routes</h2>
|
|
||||||
<p>You can take the reverse of these home</p>
|
|
||||||
|
|
||||||
<h3>44 Bus between "15th and JFK" and "City Av and Presidential"</h3>
|
|
||||||
<p>
|
|
||||||
<ul>
|
|
||||||
<li>Cost: $2.00</li>
|
|
||||||
<li>Transfers: 0</li>
|
|
||||||
<li>Frequency: Fairly frequent. Should still plan ahead.</li>
|
|
||||||
<li>On-time performance: Typically OK on busses before 7:30 am and after 6:00pm.</li>
|
|
||||||
<li>Time: 10 min walk to bus + 24 min bus ride = 34 min</li>
|
|
||||||
</ul>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>27 or 125 Bus between "15th and JFK" and "Wissahickon Transfer Center", then 65 Bus/Bike/Walk to "City Av and Presidential"</h3>
|
|
||||||
<p>
|
|
||||||
<ul>
|
|
||||||
<li>Cost: $2.00</li>
|
|
||||||
<li>Transfers: 0</li>
|
|
||||||
<li>Frequency: Fairly frequent. Should still plan ahead.</li>
|
|
||||||
<li>On-time performance: Same as 44 bus</li>
|
|
||||||
<li>Time: 10 min walk to bus + 24 min bus ride = 34 min</li>
|
|
||||||
</ul>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Manayunk/Norristown Regional Rail to "Wissahickon", then Route 65 Bus/Bike/Walk between "Wissahickon" and "City Av and Presidential"</h3>
|
|
||||||
<p><a href="https://schedules.septa.org/current/NOR.pdf">Manayunk/Norristown Schedule PDF</a></p>
|
|
||||||
<p>
|
|
||||||
<ul>
|
|
||||||
<li>Cost: $4.75 (bike/walk) - $6.75 (bus)</li>
|
|
||||||
<li>Transfers: 1</li>
|
|
||||||
<li>Frequency: Planning required, especially in non-peak hours.</li>
|
|
||||||
<li>On-time performance: Train leg is good, bus is usually good.</li>
|
|
||||||
<li>Time (bus): 10 min walk to suburban + 19 min train to wissahickon + 5-10 minute wait for bus + 8 minute bus ride = 42 - 47 min</li>
|
|
||||||
<li>Time (bike): 10 min walk to suburban + 19 min train to wissahickon + 19 min bike = 48 min</li>
|
|
||||||
<li>Time (walk): 10 min walk to suburban + 19 min train to wissahickon + 28 min walk = 57 min</li>
|
|
||||||
<li>Note: It's a pretty uphill walk/bike. I would avoid walking/biking unless using this route to go home</li>
|
|
||||||
</ul>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Cynwyd Regional Rail to Bala, then Bus/Bike/Walk to SIG</h3>
|
|
||||||
<p><a href="https://schedules.septa.org/current/CYN.pdf">Cynwyd Schedule PDF</a></p>
|
|
||||||
<ul>
|
|
||||||
<li>Cost: $4.75</li>
|
|
||||||
<li>Transfers: 0</li>
|
|
||||||
<li>On-time performance: Good</li>
|
|
||||||
<li>Frequency: Super infrequent. You have to plan to be on one of the one trains in each direction that leave at times aligned with Susquehanna's office hours.</li>
|
|
||||||
<li>Time (bus): 10 min walk to suburban + 22 min train to bala + 5-10 min wait for bus + 12 min bus = 49 - 54 min</li>
|
|
||||||
<li>Time (bike): 10 min walk to suburban + 22 min train to bala + 10 min bike = 42 min</li>
|
|
||||||
<li>Time (walk): 10 min walk to suburban + 22 min train to bala + 22 min walk = 54 min</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!--<h2>Non-Reccommended Routes</h2>
|
|
||||||
<p>I'd only take these in circumstances where all of the above are significantly delayed and
|
|
||||||
you can't take an uber for whatever reason</p>
|
|
||||||
|
|
||||||
<h3>Market-Frankford Line from "15th St Station" to "69th St Transportation Center" then Route 65 Bus to "City Av & Monument Road"</h3>
|
|
||||||
<ul>
|
|
||||||
<li>Cost: $2.00</li>
|
|
||||||
<li>Transfers: 1</li>
|
|
||||||
<li>On-time performance: MFL is good. Bus may vary.</li>
|
|
||||||
<li>Frequency: MFL is very frequent. Bus is scheduled every ~10 min.</li>
|
|
||||||
<li>Time: 10 min walk to 15th Street + 15 min subway ride + 5-15 min waiting for bus + 25 min bus ride = <u>55 min - 1hr 5 min</u></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>Route 10 Trolley from "15th St Trolley Station" to "Lansdowne Av & Lancaster Av" then Route 52 Bus to "Cardinal Av & City Av" then Route 65 Bus to "City Av & Monument Road"</h3>
|
|
||||||
<ul>
|
|
||||||
<li>Cost: $2.00</li>
|
|
||||||
<li>Transfers: 2</li>
|
|
||||||
<li>On-time performance: Unknown. Transfers complicate timing, as if one leg is late, you may miss your next leg.</li>
|
|
||||||
<li>Frequency: Somewhat frequent. Still plan ahead.</li>
|
|
||||||
<li>Time: 10 min walk to 15th Street Trolley + 22 min trolley ride + 10-15 min waiting for bus + 10 min bus ride + 5 min waiting for next bus + 10 min bus ride = <u>1hr 7min - 1hr 12min</u></li>
|
|
||||||
</ul>-->
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Useful links/resources</h2>
|
|
||||||
<p><a href="https://wwww.septa.org/fares/">SEPTA Website</a></p>
|
|
||||||
<!--<p><a href="https://www.isseptafucked.com/">"Is SEPTA Fucked?" </a> - Website that tracks delays</p>-->
|
|
||||||
<p><a href="https://wwww.septa.org/fares/">SEPTA Fare Information</a></p>
|
|
||||||
<p><a href="https://wwww.septa.org/bikes/">SEPTA Bicycle Information</a></p>
|
|
||||||
<p><a href="https://wwww.septa.org/alerts/">SEPTA Service Alerts</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/CYN.pdf">Cynwyd Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/NOR.pdf">Manayunk/Norristown Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/AIR.pdf">Airport Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/CHW.pdf">Chestnut Hill West Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/FOX.pdf">Fox Chase Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/MED.pdf">Media/Wawa Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/PAO.pdf">Paoli/Thorndale Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/WAR.pdf">Warminster Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/WTR.pdf">West Trenton Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/CHE.pdf">Chestnut Hill East Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/LAN.pdf">Lansdale/Doylestown Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/TRE.pdf">Trenton Schedule PDF</a></p>
|
|
||||||
<p><a href="https://schedules.septa.org/current/WIL.pdf">Wilmington/Newark Schedule PDF</a></p>
|
|
|
@ -1,57 +0,0 @@
|
||||||
<h1>Spring Break 2023</h1>
|
|
||||||
<p>It's Spring Break, and that means I finally have time to spend all day working on side projects without having to worry about school.</p>
|
|
||||||
<p>I figured I should write out the side projects I plan to work on over the break</p>
|
|
||||||
<h2 id="ringgold">RingGold</h2>
|
|
||||||
<p><code>Rust, Swift, PostgreSQL</code></p>
|
|
||||||
<p>Last week, me and my cousin wanted to try out Apple's fitness competition feature that works with Apple Watch. It works
|
|
||||||
by giving you 1 point for every percent you complete of your move, exercise, and stand goals with a point cap of 600
|
|
||||||
per day. The issue with it was that it didn't work at all, not syncing on time if at all. I want to build a clone of it
|
|
||||||
with some additional features such as:</p>
|
|
||||||
<ul>
|
|
||||||
<li><p><strong>Notifications:</strong> I didn't like how it was possible to workout and gain a bunch of points and just completely blindside your opponent. Hopefully this would encourage users to workout even more.</p>
|
|
||||||
</li>
|
|
||||||
<li><p><strong>Widget/Watch Complication:</strong> Similar to the above, adding a homescreen widget or a watch complication would make it easier to keep up with your competitor's progress. </p>
|
|
||||||
</li>
|
|
||||||
<li><p><strong>Custom Competitions:</strong> I think it'd be nice to have competitions with custom rules and lengths so that you're not stuck with only one setting. Settings could include custom duration and custom caps on points.</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p>I'm building the web API for it in Rust and the mobile app in Swift. I chose these languages to gain more exposure to them, also
|
|
||||||
Swift was a good choice since the app is going to be platform specific to iOS due to its need to integrate with Apple Watch.
|
|
||||||
<em>(this is named after New Ringgold, PA)</em></p>
|
|
||||||
<h2 id="nws-container-deployment-service">NWS Container Deployment Service</h2>
|
|
||||||
<p><code>C#, Rancher</code></p>
|
|
||||||
<p>I've created my own hosting/cloud service called <a href="https://nws.nickorlow.com">Nick Web Services</a>. It currently allows people to deploy
|
|
||||||
dockerized applications on my geo-distributed k8s clusters running on Dell Poweredge servers. In order to actually deploy this, I
|
|
||||||
had to manually create the Kubernetes manifest files and then ssh into each individual server and apply them. I've setup
|
|
||||||
Rancher Fleet to automate this process by pulling the manifest from a git repo (this is something called gitops). I also
|
|
||||||
wrote an API to generate the manifest files and then upload them to a git repo. I have a video demo of this working that
|
|
||||||
you can watch <a href="https://youtu.be/WHdXWMFHuqA">here</a>.</p>
|
|
||||||
<p>Currently, the service works for deployment but only if you don't want to use SSL or you use Cloudflare's flexible SSL
|
|
||||||
technology. I wrote a separate blog post <a href="http://nickorlow.com/blog/ssl-in-nws-cds">here</a> about the challenges of doing this and how I plan on implementing it.
|
|
||||||
I'd like to complete part of this implementation during the break.</p>
|
|
||||||
<h2 id="verifiedbot">VerifiedBot</h2>
|
|
||||||
<p><code>JavaScript, Rust</code></p>
|
|
||||||
<p>This project isn't a personal project, as a lot of it was built by my friends <a href="https://arpan.one">Arpan</a> and <a href="https://benaubin.com/">Ben</a>.
|
|
||||||
A little over a year ago, we wanted to make a Discord bot to verify that people on some Discord servers we ran
|
|
||||||
went to the University of Texas. Initially, it worked by verifying you had a utexas.edu email address and then verifying
|
|
||||||
some additional information via LDAP. A few months ago Ben found out that using the SaaS survey software that the university uses
|
|
||||||
(qualtrics), we could have users verify themselves by using the university's SSO system. This works because qualtrics can send
|
|
||||||
data to a webhook when a survey is complete, and it can also require signing in with the university's SSO before filling out a survey.
|
|
||||||
It required that I write a <a href="https://github.com/Verified-Bot/aes-gcm-siv-wasm">wasm wrapper for an encryption library</a>. I wrote almost all the code for this function last year, but
|
|
||||||
due to a bug in qualtrics, it wasn't working properly. It seems that this bug has been fixed and we can start rolling it out.</p>
|
|
||||||
<h2 id="personal-website-facelift">Personal Website Facelift</h2>
|
|
||||||
<p><code>Typescript, React</code></p>
|
|
||||||
<p>My personal website (this one) is a little overdue for some design updates. My main focus will be making it more mobile
|
|
||||||
friendly. Last year, I made some improvements to make it usable on mobile but it still doesn't feel quite right. I also
|
|
||||||
think that it has some information overload in some areas such as the projects section. I think that to mitigate this I
|
|
||||||
might just have a small summary of each project and then you can click into each to learn more about it, similar to my
|
|
||||||
friend <a href="https://raulhigareda.com">Raul's Website</a>. I'm also considering a move to tab-based navigation so that I can have
|
|
||||||
more information in each section. Further down the line, I think I might re-write it using Svelte as I'm seeing it being used more and more
|
|
||||||
and would like to get some exposure to it.</p>
|
|
||||||
<h2 id="mahantongo">Mahantongo</h2>
|
|
||||||
<p><code>Rust, PostgreSQL</code></p>
|
|
||||||
<p>I'm one of the members of the Community Team that runs some UT Computer Science community Discord servers.
|
|
||||||
Currently, a Discord bot called Carlbot provides us a star-board, which is a specific channel where messages that 5 or more people
|
|
||||||
react to with a star emoji get posted. It's supposed to be a collection of the funniest and best messages sent on the server.
|
|
||||||
One of the things our server members have wanted is the addition of more '*-board' channels where you can create multiple star-board
|
|
||||||
like channels but with custom emojis. I'm writing it in Rust and I'm just hoping to use this project to get more acquainted with the language.</p>
|
|
30
src/components/about-me/AboutMe.tsx
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function AboutMe() {
|
||||||
|
return (
|
||||||
|
<div className={"child"} style={{minHeight: "100vh"}}>
|
||||||
|
<div className={"row"} style={{
|
||||||
|
alignItems: "center",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
minHeight: "50rem"
|
||||||
|
}}>
|
||||||
|
<h1 className={"col-12"} style={{marginBottom: 20}}>About Me</h1>
|
||||||
|
<div className={"col-12"} style={{width: "100vw", justifyContent: "center", display: "flex"}}>
|
||||||
|
<p className={"col-12"} style={{maxWidth: 600}}>
|
||||||
|
I was born and raised in Austin, Texas. I've been writing code for nearly 7 years and I'm
|
||||||
|
currently going to <b>The University of Texas at Austin</b> and working as a <b>Software
|
||||||
|
Engineer</b> at <b>Chicks Gold</b>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"col-12"} style={{width: "100vw", justifyContent: "center", display: "flex"}}><p
|
||||||
|
style={{maxWidth: 600}}>Previously, I founded a startup called <b>CavCash</b> where I wrote a
|
||||||
|
majority of our software.</p></div>
|
||||||
|
<div className={"col-12"} style={{width: "100vw", justifyContent: "center", display: "flex"}}><p
|
||||||
|
style={{maxWidth: 600}}>I primarily do backend work and love working with databases. I'm also an
|
||||||
|
avid runner and entrepreneur.</p></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
15
src/components/contact/Contact.tsx
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function Contact() {
|
||||||
|
return (
|
||||||
|
<div className={"child"} style={{minHeight: "90vh"}}>
|
||||||
|
<div style={{minHeight: "90vh", display: "flex", alignItems: "center", justifyContent: "center"}}>
|
||||||
|
<div>
|
||||||
|
<h1>Contact</h1>
|
||||||
|
<p style={{maxWidth: 500}}>If you need: startup advice, tech/programming help, an employee (me!), or just someone to talk to, feel free to email me at:</p>
|
||||||
|
<a href={"mailto:nickorlow@nickorlow.com"}>nickorlow@nickorlow.com</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
14
src/components/footer/Footer.tsx
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<footer>
|
||||||
|
<div style={{minHeight: "10vh"}}>
|
||||||
|
<p className={"m-0"}>Copyright © 2021 Nicholas Orlowsky</p>
|
||||||
|
<p className={"m-0"}>Licensed under GNU General Public License v3</p>
|
||||||
|
<p className={"m-0"}>Original source available <a
|
||||||
|
href={"https://github.com/nickorlow/personal-site"}>here</a></p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
)
|
||||||
|
}
|
29
src/components/hero/Hero.tsx
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import TexasIcon from "../../static/images/texas-icon.png";
|
||||||
|
import SocialBar from "../social-bar/SocialBar";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function Hero() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={"child"} style={{
|
||||||
|
height: "95vh",
|
||||||
|
display: "flex",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center"
|
||||||
|
}}>
|
||||||
|
<img alt="github profile" src={"https://avatars.githubusercontent.com/u/85139485?v=4"}
|
||||||
|
style={{height: "30vh", width: "auto"}} className={"pfp"}/>
|
||||||
|
<h1 className={"m-0 font-weight-bold"}>Nicholas Orlowsky</h1>
|
||||||
|
<h4 className={"m-0"}>Software Engineer</h4>
|
||||||
|
<div className={"row"}>
|
||||||
|
<img alt={"github profile"} className={"fade-in-tx"} src={TexasIcon} style={{height: 50}}/>
|
||||||
|
<p className={"move-left-atx"} style={{marginTop: 11}}>Austin, Texas</p>
|
||||||
|
</div>
|
||||||
|
<SocialBar style={{justifyContent: "center", width: "60vmin"}}/>
|
||||||
|
</div>
|
||||||
|
<p className={"fade-up-d3s"}>scroll for more</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
23
src/components/hobbies/Hobbies.tsx
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import {AllHobbies} from "../../static/data/Hobbies";
|
||||||
|
import InfoCard from "../info-card/InfoCard";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function Hobbies () {
|
||||||
|
return (
|
||||||
|
<div className={"child"} style={{minHeight: "100vh"}}>
|
||||||
|
<div style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexDirection: "column",
|
||||||
|
width: "96vw",
|
||||||
|
minHeight: "100vh",
|
||||||
|
alignContent: "center",
|
||||||
|
alignItems: "center"
|
||||||
|
}}>
|
||||||
|
<h1>Other Hobbies</h1>
|
||||||
|
{AllHobbies.map((hobby) => <InfoCard style={{textAlign: "left", maxWidth: "50vmax", margin: 50}}
|
||||||
|
info={hobby}/>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
22
src/components/info-card/InfoCard.tsx
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import React from "react";
|
||||||
|
import InfoCardProps from "../../types/InfoCardProps";
|
||||||
|
|
||||||
|
export default function InfoCard(props: {style?: any, className?: string, info: InfoCardProps}) {
|
||||||
|
return (
|
||||||
|
<div style={props.style} className={props.className}>
|
||||||
|
<div style={{maxWidth: "100vw"}}>
|
||||||
|
<h3>{props.info.title}</h3>
|
||||||
|
<p>
|
||||||
|
{props.info.description}
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<h4>{props.info.listTitle}</h4>
|
||||||
|
<div className={"row"} style={{color: "green", fontFamily: "monospace"}}>
|
||||||
|
{props.info.list.map(s => <p className={"col-6 "+(props.info.listClassName || "col-md-4")} style={{fontSize: 16}}>{s}</p>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{props.info.link != null && <a href={props.info.link}>{props.info.linkTitle || "Relevant Link"}</a>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
13
src/components/job-card/JobCard.css
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
@media only screen and (min-width: 993px) {
|
||||||
|
.center-card {
|
||||||
|
border-left: .5px rgba(255,255,255,.25) solid;
|
||||||
|
border-right: .5px rgba(255,255,255,.25) solid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
|
||||||
|
.job-card {
|
||||||
|
margin-top: 100px;
|
||||||
|
}
|
||||||
|
}
|
21
src/components/job-card/JobCard.tsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import ScrollAnimation from "react-animate-on-scroll";
|
||||||
|
import React from "react";
|
||||||
|
import Job from "../../types/Job";
|
||||||
|
import "./JobCard.css";
|
||||||
|
|
||||||
|
export default function JobCard(props: {style?: any, className?: string, job: Job, isCenter: boolean}){
|
||||||
|
return (
|
||||||
|
<ScrollAnimation className={"job-card "+(props.isCenter ? "center-card " : "")+(props.className || "")} style={props.style} animateIn="fade-up" duration={2} animateOnce={true} offset={50} delay={200}>
|
||||||
|
<div style={{padding: 20}}>
|
||||||
|
<img alt={props.job.company+" company logo"} src={props.job.image} style={{maxHeight: 70, padding: 10,width: "auto", maxWidth: "100%"}}/>
|
||||||
|
<h2>{props.job.title}</h2>
|
||||||
|
{props.job.uri == null && <h5>{props.job.company}</h5>}
|
||||||
|
{props.job.uri != null && <a href={props.job.uri}><h5>{props.job.company}</h5></a>}
|
||||||
|
<p>{props.job.timespan}</p>
|
||||||
|
<ul>
|
||||||
|
{props.job.items.map((s) => <li>{s}</li>)}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</ScrollAnimation>
|
||||||
|
);
|
||||||
|
}
|
24
src/components/jobs/Jobs.css
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
.react-tabs__tab--selected {
|
||||||
|
transition: 1s;
|
||||||
|
border-top: 1px #00AA00 solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn {
|
||||||
|
background-color: #121212;
|
||||||
|
transition: 1s;
|
||||||
|
|
||||||
|
|
||||||
|
border-bottom: 1px #FFFFFF solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-beg {
|
||||||
|
border-bottom-left-radius: 10px;
|
||||||
|
border-top-left-radius: 10px;
|
||||||
|
border-left: 1px #FFFFFF solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-end {
|
||||||
|
border-bottom-right-radius: 10px;
|
||||||
|
border-top-right-radius: 10px;
|
||||||
|
border-right: 1px #FFFFFF solid;
|
||||||
|
}
|
18
src/components/jobs/Jobs.tsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import {AllJobs} from "../../static/data/Jobs";
|
||||||
|
import JobCard from "../job-card/JobCard";
|
||||||
|
import React from "react";
|
||||||
|
import "./Jobs.css";
|
||||||
|
|
||||||
|
export default function Jobs() {
|
||||||
|
return (
|
||||||
|
<div className={"child"} style={{minHeight: "100vh"}}>
|
||||||
|
<div className={"row"} style={{justifyContent: "center", alignItems: "center", alignContent: "center"}}>
|
||||||
|
<h1 className={"col-12"} style={{marginBottom: 20}}>Work</h1>
|
||||||
|
|
||||||
|
{AllJobs.map((job, i) =><JobCard className={"col-md-4"} job={job}
|
||||||
|
isCenter={i % 2 === 1}/>)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
29
src/components/projects/Projects.tsx
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import {AllProjects} from "../../static/data/Projects";
|
||||||
|
import InfoCard from "../info-card/InfoCard";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function Projects() {
|
||||||
|
return (
|
||||||
|
<div className={"child"} style={{minHeight: "100vh"}}>
|
||||||
|
|
||||||
|
<div style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexDirection: "column",
|
||||||
|
width: "100vw",
|
||||||
|
minHeight: "100vh",
|
||||||
|
alignContent: "center",
|
||||||
|
alignItems: "center"
|
||||||
|
}}>
|
||||||
|
<h1>Projects</h1>
|
||||||
|
<p>(writing code is my biggest hobby)</p>
|
||||||
|
<div className={"row m-0"} style={{justifyContent: "center", padding: 20}}>
|
||||||
|
{AllProjects.map((project) => <InfoCard className={"col-md-6"} style={{textAlign: "left",marginTop: 35, paddingLeft: 20, paddingRight: 20}}
|
||||||
|
info={project}/>)}
|
||||||
|
</div>
|
||||||
|
<a href={"https://github.com/nickorlow"}>More on GitHub</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
31
src/components/social-bar/SocialBar.css
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
.icon {
|
||||||
|
transition: 1s !important;
|
||||||
|
fill: #FFFFFF;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.insta-icon:hover {
|
||||||
|
fill: #DD2A7B;
|
||||||
|
}
|
||||||
|
|
||||||
|
.twitter-icon:hover {
|
||||||
|
fill: #1DA1F2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.github-icon:hover {
|
||||||
|
fill: #F1502F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linkedin-icon:hover {
|
||||||
|
fill: #0077B5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mail-icon:hover {
|
||||||
|
fill: #EA4335;
|
||||||
|
}
|
28
src/components/social-bar/SocialBar.tsx
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import React from "react";
|
||||||
|
import './SocialBar.css';
|
||||||
|
|
||||||
|
export default function SocialBar(props: {style: any}) {
|
||||||
|
return (
|
||||||
|
<div className={"row"} style={props.style}>
|
||||||
|
<div className={"col-md-2 col-4 fade-up-3 fade-up-md-2"} style={{display: "flex", justifyContent: "center"}}>
|
||||||
|
<svg onClick={ () => window.location.href="https://instagram.com/nickorlow"} className={"insta-icon icon"} viewBox="0 0 50 50" width="100px" height="100px"> <path d="M 16 3 C 8.83 3 3 8.83 3 16 L 3 34 C 3 41.17 8.83 47 16 47 L 34 47 C 41.17 47 47 41.17 47 34 L 47 16 C 47 8.83 41.17 3 34 3 L 16 3 z M 37 11 C 38.1 11 39 11.9 39 13 C 39 14.1 38.1 15 37 15 C 35.9 15 35 14.1 35 13 C 35 11.9 35.9 11 37 11 z M 25 14 C 31.07 14 36 18.93 36 25 C 36 31.07 31.07 36 25 36 C 18.93 36 14 31.07 14 25 C 14 18.93 18.93 14 25 14 z M 25 16 C 20.04 16 16 20.04 16 25 C 16 29.96 20.04 34 25 34 C 29.96 34 34 29.96 34 25 C 34 20.04 29.96 16 25 16 z"/></svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"col-md-2 col-4 fade-up-2 fade-up-md"} style={{display: "flex", justifyContent: "center"}}>
|
||||||
|
<svg onClick={ () => window.location.href="https://twitter.com/nickorIow"} className={"twitter-icon icon"} viewBox="0 0 50 50" width="100px" height="100px"><path d="M 50.0625 10.4375 C 48.214844 11.257813 46.234375 11.808594 44.152344 12.058594 C 46.277344 10.785156 47.910156 8.769531 48.675781 6.371094 C 46.691406 7.546875 44.484375 8.402344 42.144531 8.863281 C 40.269531 6.863281 37.597656 5.617188 34.640625 5.617188 C 28.960938 5.617188 24.355469 10.21875 24.355469 15.898438 C 24.355469 16.703125 24.449219 17.488281 24.625 18.242188 C 16.078125 17.8125 8.503906 13.71875 3.429688 7.496094 C 2.542969 9.019531 2.039063 10.785156 2.039063 12.667969 C 2.039063 16.234375 3.851563 19.382813 6.613281 21.230469 C 4.925781 21.175781 3.339844 20.710938 1.953125 19.941406 C 1.953125 19.984375 1.953125 20.027344 1.953125 20.070313 C 1.953125 25.054688 5.5 29.207031 10.199219 30.15625 C 9.339844 30.390625 8.429688 30.515625 7.492188 30.515625 C 6.828125 30.515625 6.183594 30.453125 5.554688 30.328125 C 6.867188 34.410156 10.664063 37.390625 15.160156 37.472656 C 11.644531 40.230469 7.210938 41.871094 2.390625 41.871094 C 1.558594 41.871094 0.742188 41.824219 -0.0585938 41.726563 C 4.488281 44.648438 9.894531 46.347656 15.703125 46.347656 C 34.617188 46.347656 44.960938 30.679688 44.960938 17.09375 C 44.960938 16.648438 44.949219 16.199219 44.933594 15.761719 C 46.941406 14.3125 48.683594 12.5 50.0625 10.4375 Z"/></svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"col-md-2 col-4 fade-up fade-up-md-2"} style={{display: "flex", justifyContent: "center"}}>
|
||||||
|
<svg onClick={ () => window.location.href="https://github.com/nickorlow"} className={"github-icon icon"} viewBox="0 0 50 50" width="100px" height="100px"> <path d="M17.791,46.836C18.502,46.53,19,45.823,19,45v-5.4c0-0.197,0.016-0.402,0.041-0.61C19.027,38.994,19.014,38.997,19,39 c0,0-3,0-3.6,0c-1.5,0-2.8-0.6-3.4-1.8c-0.7-1.3-1-3.5-2.8-4.7C8.9,32.3,9.1,32,9.7,32c0.6,0.1,1.9,0.9,2.7,2c0.9,1.1,1.8,2,3.4,2 c2.487,0,3.82-0.125,4.622-0.555C21.356,34.056,22.649,33,24,33v-0.025c-5.668-0.182-9.289-2.066-10.975-4.975 c-3.665,0.042-6.856,0.405-8.677,0.707c-0.058-0.327-0.108-0.656-0.151-0.987c1.797-0.296,4.843-0.647,8.345-0.714 c-0.112-0.276-0.209-0.559-0.291-0.849c-3.511-0.178-6.541-0.039-8.187,0.097c-0.02-0.332-0.047-0.663-0.051-0.999 c1.649-0.135,4.597-0.27,8.018-0.111c-0.079-0.5-0.13-1.011-0.13-1.543c0-1.7,0.6-3.5,1.7-5c-0.5-1.7-1.2-5.3,0.2-6.6 c2.7,0,4.6,1.3,5.5,2.1C21,13.4,22.9,13,25,13s4,0.4,5.6,1.1c0.9-0.8,2.8-2.1,5.5-2.1c1.5,1.4,0.7,5,0.2,6.6c1.1,1.5,1.7,3.2,1.6,5 c0,0.484-0.045,0.951-0.11,1.409c3.499-0.172,6.527-0.034,8.204,0.102c-0.002,0.337-0.033,0.666-0.051,0.999 c-1.671-0.138-4.775-0.28-8.359-0.089c-0.089,0.336-0.197,0.663-0.325,0.98c3.546,0.046,6.665,0.389,8.548,0.689 c-0.043,0.332-0.093,0.661-0.151,0.987c-1.912-0.306-5.171-0.664-8.879-0.682C35.112,30.873,31.557,32.75,26,32.969V33 c2.6,0,5,3.9,5,6.6V45c0,0.823,0.498,1.53,1.209,1.836C41.37,43.804,48,35.164,48,25C48,12.318,37.683,2,25,2S2,12.318,2,25 C2,35.164,8.63,43.804,17.791,46.836z"/></svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"col-md-2 col-4 fade-up-2 fade-up-md-3"} style={{display: "flex", justifyContent: "center"}}>
|
||||||
|
<svg onClick={ () => window.location.href="https://www.linkedin.com/in/nicholas-orlowsky-83b24ab8"} className={"linkedin-icon icon"} viewBox="0 0 50 50" width="100px" height="100px"> <path d="M41,4H9C6.24,4,4,6.24,4,9v32c0,2.76,2.24,5,5,5h32c2.76,0,5-2.24,5-5V9C46,6.24,43.76,4,41,4z M17,20v19h-6V20H17z M11,14.47c0-1.4,1.2-2.47,3-2.47s2.93,1.07,3,2.47c0,1.4-1.12,2.53-3,2.53C12.2,17,11,15.87,11,14.47z M39,39h-6c0,0,0-9.26,0-10 c0-2-1-4-3.5-4.04h-0.08C27,24.96,26,27.02,26,29c0,0.91,0,10,0,10h-6V20h6v2.56c0,0,1.93-2.56,5.81-2.56 c3.97,0,7.19,2.73,7.19,8.26V39z"/></svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"col-md-2 col-4 fade-up-3 fade-up-md-3"} style={{display: "flex", justifyContent: "center"}}>
|
||||||
|
<svg onClick={ () => window.location.href="mailto:nickorlow@nickorlow.com"} className={"mail-icon icon"} viewBox="0 0 100 100" width="100px" height="100px"><g id="surface12014155"><path d="M 28 8 C 16.976562 8 8 16.976562 8 28 L 8 72 C 8 83.023438 16.976562 92 28 92 L 72 92 C 83.023438 92 92 83.023438 92 72 L 92 28 C 92 16.976562 83.023438 8 72 8 Z M 26 32 L 74 32 C 74.359375 32 74.699219 32.039062 75.019531 32.140625 L 55.359375 51.78125 C 52.398438 54.742188 47.582031 54.742188 44.621094 51.78125 L 24.980469 32.140625 C 25.300781 32.039062 25.640625 32 26 32 Z M 22.140625 34.980469 L 37.179688 50 L 22.140625 65.019531 C 22.039062 64.699219 22 64.359375 22 64 L 22 36 C 22 35.640625 22.039062 35.300781 22.140625 34.980469 Z M 77.859375 34.980469 C 77.960938 35.300781 78 35.640625 78 36 L 78 64 C 78 64.359375 77.960938 64.699219 77.859375 65.019531 L 62.800781 50 Z M 40 52.820312 L 41.78125 54.621094 C 44.042969 56.882812 47.019531 58 49.980469 58 C 52.960938 58 55.917969 56.882812 58.179688 54.621094 L 59.980469 52.820312 L 75.019531 67.859375 C 74.699219 67.960938 74.359375 68 74 68 L 26 68 C 25.640625 68 25.300781 67.960938 24.980469 67.859375 Z M 40 52.820312 "/></g></svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
34
src/components/terminal/Terminal.tsx
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import Typing from "react-typing-animation";
|
||||||
|
import React, {Dispatch} from "react";
|
||||||
|
|
||||||
|
export default function Terminal(props: {isTerminalVisible: boolean, setIsTerminalVisible: Dispatch<boolean>}) {
|
||||||
|
return (
|
||||||
|
<div className={props.isTerminalVisible ? "" : "fade-out"} style={{position: "fixed", top: 0, left: 0, width: "99vw", height: "100vh", backgroundColor: "black",textAlign: "left"}}>
|
||||||
|
<p className={"d-inline"}>nickorlow@macbook ~# </p>
|
||||||
|
<Typing speed={20} className={"d-inline"} onFinishedTyping={() => props.setIsTerminalVisible(false)}>
|
||||||
|
<p className={"d-inline"}>git clone <p className={"d-inline"} style={{color: "#00aaee"}}>https://github.com/nickorlow/personal-site</p></p>
|
||||||
|
<Typing.Speed ms={0} />
|
||||||
|
<p/>
|
||||||
|
<p className={"m-0"}>Cloning into 'personal-site'...</p>
|
||||||
|
<p className={"m-0"}>remote: Enumerating objects: 334, done.</p>
|
||||||
|
<p className={"m-0"}>remote: Counting objects: 100% (334/334), done.</p>
|
||||||
|
<p className={"m-0"}>remote: Compressing objects: 100% (185/185), done.</p>
|
||||||
|
<p className={"m-0"}>remote: Total 334 (delta 132), reused 324 (delta 127), pack-reused 0</p>
|
||||||
|
<p className={"m-0"}>Receiving objects: 100% (334/334), 29.68 MiB | 5.50 MiB/s, done.</p>
|
||||||
|
<p className={"m-0"}>Resolving deltas: 100% (132/132), done.</p>
|
||||||
|
<p/>
|
||||||
|
<p className={"d-inline"}>nickorlow@macbook ~# </p>
|
||||||
|
<Typing.Speed ms={10} />
|
||||||
|
<p className={"d-inline"}>cd persona-site</p>
|
||||||
|
<Typing.Backspace speed={10} count={5}/>
|
||||||
|
<p className={"d-inline"}>l-site</p>
|
||||||
|
<p/>
|
||||||
|
<Typing.Speed ms={0} />
|
||||||
|
<p className={"d-inline"}>nickorlow@macbook ~# </p>
|
||||||
|
<Typing.Delay ms={200}/>
|
||||||
|
<Typing.Speed ms={100} />
|
||||||
|
<p className={"d-inline"}>npm run start</p>
|
||||||
|
</Typing>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,77 +0,0 @@
|
||||||
<div>
|
|
||||||
<h1 style="margin-bottom: 0px;">Extra</h1>
|
|
||||||
<p style="margin-top: 0px;">Extra bits of information about me</p>
|
|
||||||
|
|
||||||
<h2>Rail Photography</h2>
|
|
||||||
<p>
|
|
||||||
I take photos of trains and train stations fairly often.
|
|
||||||
If you would like to see these pictures, they are avaliable
|
|
||||||
<a href="https://www.instagram.com/nickorlow.on.rails/">here</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Bowling</h2>
|
|
||||||
<p>
|
|
||||||
I go bowling with some friends regularly. We track our scores
|
|
||||||
down to the throw in a csv. You can check out a website where
|
|
||||||
that data is compiled into a readable format
|
|
||||||
<a href="https://bart.nickorlow.com">here</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Personal Records</h2>
|
|
||||||
<table style="width: 100%;">
|
|
||||||
<tr>
|
|
||||||
<th>Activity</th>
|
|
||||||
<th>Effort</th>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>Location</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>1600m (1 mile)</td>
|
|
||||||
<td>4:34</td>
|
|
||||||
<td>November 14th, 2020</td>
|
|
||||||
<td>Williamson County Park</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Milk Mile</td>
|
|
||||||
<td>5:41</td>
|
|
||||||
<td>May 20th, 2021</td>
|
|
||||||
<td>Lake Travis High School</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>3200m (2 mile)</td>
|
|
||||||
<td>10:11</td>
|
|
||||||
<td>March 20th, 2021</td>
|
|
||||||
<td>Carroll High School</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>5000m XC</td>
|
|
||||||
<td>16:43</td>
|
|
||||||
<td>September 26th, 2020</td>
|
|
||||||
<td>Old Settler's Park</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Bench Press</td>
|
|
||||||
<td>280.5 Lbs</td>
|
|
||||||
<td>December 31st, 2024</td>
|
|
||||||
<td>Anytime Fitness - Pottsville, PA</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Squat</td>
|
|
||||||
<td>415 Lbs</td>
|
|
||||||
<td>August 10th, 2023</td>
|
|
||||||
<td>FUTO HQ</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Deadlift</td>
|
|
||||||
<td>415 Lbs</td>
|
|
||||||
<td>Augist 10th, 2023</td>
|
|
||||||
<td>FUTO HQ</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Bowling</td>
|
|
||||||
<td>170</td>
|
|
||||||
<td>April 19th, 2024</td>
|
|
||||||
<td>Texas Union Underground</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
13
src/index.css
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||||
|
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||||
|
sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||||
|
monospace;
|
||||||
|
}
|
|
@ -1,32 +0,0 @@
|
||||||
<div>
|
|
||||||
<h1 style="margin-bottom: 0px;">Nicholas Orlowsky</h1>
|
|
||||||
<p style="margin-top: 0px;">Software Engineer - Austin, TX</p>
|
|
||||||
<p>
|
|
||||||
<a href="https://git.nickorlow.com/nickorlow">[ Forgejo ]</a>
|
|
||||||
<a href="https://github.com/nickorlow">[ GitHub (mirrors) ]</a>
|
|
||||||
<a href="https://www.linkedin.com/in/nickorlow/">[ LinkedIn ]</a>
|
|
||||||
<a href="mailto:nickorlow@nickorlow.com">[ E-Mail ]</a>
|
|
||||||
<a href="https://github.com/nickorlow/resume/releases/download/latest/resume-nickorlow.pdf">[ Resume ]</a>
|
|
||||||
<!--<a href="https://old.nickorlow.com">[ My Old Website ]</a>-->
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="https://azuredevopspodcast.clear-measure.com/nick-orlowsky-deciding-to-major-in-computer-science-episode-197">[ Listen to me on the Azure DevOps podcast! ]</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I'm a computer science student at the University of Texas at Austin. I'm particularly
|
|
||||||
interested in infrastructure, distributed systems, and systems programming.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
I run <a href="https://nws.nickorlow.com">Nick Web Services (NWS)</a>, a side project
|
|
||||||
that provides geo-distributed container hosting using Kubernetes on bare metal servers.
|
|
||||||
It achieved 100% uptime for over a year.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Outside of computers, I enjoy biking and weightlifting. I'm also a public transit enthusiast
|
|
||||||
and I take pictures of trains that I see, especially rare or special ones.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
17
src/index.tsx
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import './index.css';
|
||||||
|
import App from './App';
|
||||||
|
import reportWebVitals from './reportWebVitals';
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>,
|
||||||
|
document.getElementById('root')
|
||||||
|
);
|
||||||
|
|
||||||
|
// If you want to start measuring performance in your app, pass a function
|
||||||
|
// to log results (for example: reportWebVitals(console.log))
|
||||||
|
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||||
|
reportWebVitals();
|
1
src/logo.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
|
After Width: | Height: | Size: 2.6 KiB |
|
@ -1,4 +0,0 @@
|
||||||
<h1>Rail Pictures</h1>
|
|
||||||
<p>All photos are Copyright © Nicholas Orlowsky</p>
|
|
||||||
|
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
<div>
|
|
||||||
<h1 style="margin-bottom: 0px;">Projects</h1>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>Nick Web Services (NWS)</h2>
|
|
||||||
<p><i>C#, Kubernetes, Rancher, and HAProxy</i></p>
|
|
||||||
<a href="https://nws.nickorlow.com">[ Project Website ]</a>
|
|
||||||
<p>
|
|
||||||
Nick Web Services is a cloud infrastructure provider service that I created and run.
|
|
||||||
It allows people to deploy containerized versions of their web apps across our multiple
|
|
||||||
servers. It provides geo-distributed high availability by default with no extra configuration
|
|
||||||
needed from users hosting their webapp with us.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Hardware-wise we use old Dell PowerEdge servers running Proxmox. We then have VMs running
|
|
||||||
in Proxmox that run Kubernetes clusters. We have 4 clusters currently: Austin, Hill Country,
|
|
||||||
Schuylkill, and Philadelphia. The deployments are managed through GitOps with Rancher Fleet.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>Anthracite Web Server</h2>
|
|
||||||
<p><i>C++ & Python</i></p>
|
|
||||||
<a href="https://github.com/nickorlow/anthracite">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
Anthracite is a simple web server written in C++. It currently supports HTTP/1.0 and HTTP/1.1.
|
|
||||||
The benchmarking tools for Anthracite are written in Python. Anthracite is optimized for performance
|
|
||||||
and rivals the performance of NGINX & Apache in our testing. It uses a thread-per-connection
|
|
||||||
architecture, allowing it to process many requests in paralell. Additionally, it caches all
|
|
||||||
files that it serves in memory to ensure that added latency from disk reads do not slow down requests.
|
|
||||||
Through writing Anthracite, I have learned to use different C++ profilers as well as some general
|
|
||||||
optimization techniques for C++.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>CavCash</h2>
|
|
||||||
<p><i>C#, Kubernetes, SQL Server, and MongoDB</i></p>
|
|
||||||
<a href="https://cavcash.com">[ Project Website ]</a>
|
|
||||||
<p>
|
|
||||||
CavCash was a company that I founded which built a debit-based payment system similar to
|
|
||||||
PayPal and Venmo. I assembled a 5 person team and took on a technical role in the company,
|
|
||||||
writing most of our backend codebase. Our backend used C#, ASP.NET, Microsoft SQL Server,
|
|
||||||
and MongoDB. Our infrastructure changed throughout the lifetime of the company, initially
|
|
||||||
it was on Microsoft Azure using Azure App Service. We then pivoted to AWS using Elastic
|
|
||||||
Beanstalk. We also ran on Google Cloud Platform using Compute Engine. Finally, we setup our
|
|
||||||
own servers in-house and managed our deployments with Kubernetes.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We launched in 2021, with the ability to send money between real banks using the ACH network.
|
|
||||||
We ended up processing a few hundred dollars in transaction volume before ultimately shutting
|
|
||||||
down due to a lack of funding. The website is now back up and everything works as it did in
|
|
||||||
2021, except adding funds from a bank account is not supported.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>SQUIRREL</h2>
|
|
||||||
<p><i>Rust</i></p>
|
|
||||||
<a href="https://github.com/nickorlow/squirrel">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
SQUIRREL stands for SQL Query Util-Izing Rust's Reliable and Efficient Logic. It is a SQL database
|
|
||||||
that I am writing in Rust. Currently, it can create tables, insert data into tables, and select all
|
|
||||||
data from a given table. The biggest challenge so far has been writing the parser. My next steps are
|
|
||||||
to add WHERE clauses to SELECT statements, allow column filtering in SELECT statements, and add DELETE
|
|
||||||
statements.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>Olney</h2>
|
|
||||||
<p><i>Rust, Postgres, Svelte, TypeScript, and OpenAI's API</i></p>
|
|
||||||
<a href="https://github.com/nickorlow/olney">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
Olney is a job application tracker that aims to be better than using a <a href="https://trello.com">Trello</a> board or a spreadsheet.
|
|
||||||
It allows users to create jobs and log custom events such as interviews, assessments, and other communication.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h2>SEPTA Site</h2>
|
|
||||||
<p><i>Svelte, TypeScript</i></p>
|
|
||||||
<a href="https://github.com/nickorlow/septa-site">[ GitHub Repo ]</a>
|
|
||||||
<p>
|
|
||||||
SEPTA Site is a website that I created which can get your trip history, SEPTA Key balance,
|
|
||||||
and ridership statistics for your SEPTA Key. It utilizes SEPTA's new metro wayfinding instead
|
|
||||||
of their current wayfinding. I wrote the project to get a basic introduction to Svelte and
|
|
||||||
so that I could try to improve upon the UX of SEPTA's current website and mobile app.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="width: 100%; display: flex; justify-content: center; padding: 5px;">
|
|
||||||
<a href="https://github.com/nickorlow">[ See more projects on GitHub ]</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
1
src/react-app-env.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/// <reference types="react-scripts" />
|
15
src/reportWebVitals.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { ReportHandler } from 'web-vitals';
|
||||||
|
|
||||||
|
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
||||||
|
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||||
|
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||||
|
getCLS(onPerfEntry);
|
||||||
|
getFID(onPerfEntry);
|
||||||
|
getFCP(onPerfEntry);
|
||||||
|
getLCP(onPerfEntry);
|
||||||
|
getTTFB(onPerfEntry);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default reportWebVitals;
|
5
src/setupTests.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||||
|
// allows you to do things like:
|
||||||
|
// expect(element).toHaveTextContent(/react/i)
|
||||||
|
// learn more: https://github.com/testing-library/jest-dom
|
||||||
|
import '@testing-library/jest-dom';
|
21
src/static/data/Hobbies.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import InfoCardProps from "../../types/InfoCardProps";
|
||||||
|
|
||||||
|
const RunningHobby: InfoCardProps = {
|
||||||
|
title: "Running",
|
||||||
|
description: "I started running cross country in 7th grade after wanting to beat my friend in the mile. I kept running all the way through to my senior year of high school. I made varsity my sophomore year. Today, I just run with friends casually along with other physical activity like lifting, biking, and kayaking.",
|
||||||
|
listTitle: "Personal Records",
|
||||||
|
list:["1600 - 4:34", "3200 - 10:11", "5K XC - 16:42"],
|
||||||
|
link: "https://tx.milesplit.com/athletes/7325388-nicholas-orlowsky/stats",
|
||||||
|
linkTitle: "Milesplit Profile",
|
||||||
|
listClassName: "col-12"
|
||||||
|
}
|
||||||
|
|
||||||
|
const VideogameHobby: InfoCardProps = {
|
||||||
|
title: "Video Games",
|
||||||
|
description: "Video games are what got me interested in programming in the first place. I tend to play them a lot less now in favor of programming though, I'll occasionally sink a couple hours into a game.",
|
||||||
|
listTitle: "Favorites",
|
||||||
|
list: ["Galaga", "Clone Hero", "Minecraft"]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AllHobbies: InfoCardProps[] = [RunningHobby, VideogameHobby];
|
||||||
|
|
51
src/static/data/Jobs.ts
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import Job from "../../types/Job";
|
||||||
|
import VrboImage from "../images/vrbo-logo-min.png";
|
||||||
|
import CavImage from "../images/cavcash-logo-min.png";
|
||||||
|
import ChicksImage from "../images/chicks-logo.svg";
|
||||||
|
|
||||||
|
const VrboJob: Job = {
|
||||||
|
title: "Data Scientist",
|
||||||
|
company: "Vrbo, a part of Expedia Group",
|
||||||
|
uri: "https://vrbo.com",
|
||||||
|
timespan: "August 2019 - January 2021",
|
||||||
|
items: [
|
||||||
|
"Worked on Natural Language Processing chatbot",
|
||||||
|
"Worked with team to identify dataset patterns",
|
||||||
|
"Helped reduce wait times",
|
||||||
|
"Reduced offsite booking attempts"
|
||||||
|
],
|
||||||
|
image: VrboImage
|
||||||
|
}
|
||||||
|
|
||||||
|
const CavCashJob: Job = {
|
||||||
|
title: "CEO & Software Engineer",
|
||||||
|
company: "CavCash Inc",
|
||||||
|
timespan: "May 2017 - Present",
|
||||||
|
items: [
|
||||||
|
"Founded the company",
|
||||||
|
"Wrote a C# webAPI",
|
||||||
|
"Managed mongoDB and MSSQL databases",
|
||||||
|
"Deployed and maintained k8s clusters on bare metal",
|
||||||
|
"Managed CI/CD & DevOps in Azure DevOps",
|
||||||
|
"Ran & migrated services between Azure, AWS, and GCP"
|
||||||
|
],
|
||||||
|
image: CavImage
|
||||||
|
}
|
||||||
|
|
||||||
|
const ChicksJob: Job = {
|
||||||
|
title: "Software Engineer",
|
||||||
|
company: "Chicks Gold",
|
||||||
|
uri: "https://chicksgold.com",
|
||||||
|
timespan: "April 2021 - Present",
|
||||||
|
items: [
|
||||||
|
"Added features & bugfixes to .NET 5 API",
|
||||||
|
"Added features & bugfixes to Aurelia website",
|
||||||
|
"Worked with team to create new feature & bug tickets",
|
||||||
|
"Deployed code to k8s cluster"
|
||||||
|
],
|
||||||
|
image: ChicksImage
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const AllJobs: Job[] = [VrboJob, CavCashJob, ChicksJob];
|
||||||
|
|
40
src/static/data/Projects.ts
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import InfoCardProps from "../../types/InfoCardProps";
|
||||||
|
|
||||||
|
const WebsiteProject: InfoCardProps = {
|
||||||
|
title: "personal-site (this website)",
|
||||||
|
description: "As a primairly backend guy, I wrote my last website as a JSON file (imatating a webAPI). Feedback showed that that was a bad idea so I made this pretty neat site (in my opinion). If you like it, feel free to use it yourself!",
|
||||||
|
listTitle: "Technologies & Resources used",
|
||||||
|
list:["React", "Typescript", "Bootstrap", "Icons8", "Docker", "Kubernetes"],
|
||||||
|
link: "https://github.com/nickorlow/personal-site",
|
||||||
|
linkTitle: "GitHub Repo"
|
||||||
|
}
|
||||||
|
|
||||||
|
const CavCashProject: InfoCardProps = {
|
||||||
|
title: "cavcash",
|
||||||
|
description: "CavCash started as a project in 2017 as a way to pay with flashdrives. After recruiting a few friends to help me, we build ourselves into a PayPal competitor but shutdown due to funding. I continued to re-write the platform as a cryptocurrency.",
|
||||||
|
listTitle: "Technologies Used",
|
||||||
|
list: ["C#", ".NET 5", "MSSQL", "mongoDB", "Kubernetes", "Docker", "nginx", "Azure DevOps", "React", "Cloudflare"],
|
||||||
|
link: "https://cavcash.com",
|
||||||
|
linkTitle: "Project Website"
|
||||||
|
}
|
||||||
|
|
||||||
|
const XenMapProject: InfoCardProps = {
|
||||||
|
title: "xenmap",
|
||||||
|
description: "I wanted to use an old iPad as a HUD in my car similar to tesla and it needed a map to complete it. I made this widget to show your current location as a XenHTML widget.",
|
||||||
|
listTitle: "Technologies Used",
|
||||||
|
list: ["HTML", "JavaScript", "CSS", "XenHTML Framework", "XenInfo API"],
|
||||||
|
link: "https://github.com/nickorlow/MapXenHTML",
|
||||||
|
linkTitle: "GitHub Repo"
|
||||||
|
}
|
||||||
|
|
||||||
|
const SPONODEProject: InfoCardProps = {
|
||||||
|
title: "sponode",
|
||||||
|
description: "App for Android & macOS that added songs people sent you to a playlist. Made so we could have a jukebox type setup during track workouts.",
|
||||||
|
listTitle: "Technologies Used",
|
||||||
|
list: ["Java", "Apple Script", "Spotify API", "node.js"],
|
||||||
|
link: "https://github.com/nickorlow/sponode",
|
||||||
|
linkTitle: "GitHub Repo"
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AllProjects: InfoCardProps[] = [WebsiteProject, CavCashProject, XenMapProject, SPONODEProject];
|
||||||
|
|
BIN
src/static/images/cavcash-logo-min.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
src/static/images/cavcash-logo.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
30
src/static/images/chicks-logo.svg
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" id="Chicks_Logo" width="152.29" height="31.163" viewBox="0 0 152.29 31.163">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.cls-1{fill:#b2b3b8}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<g id="Group_3877" transform="translate(-34.915 -20.729)">
|
||||||
|
<g id="Group_3879" transform="translate(223.269 -273.021)">
|
||||||
|
<g id="Group_3878" transform="translate(-80.713 293.75)">
|
||||||
|
<g id="Group_3928">
|
||||||
|
<path id="Rectangle_287" d="M0 0H8.855V1.373H0z" class="cls-1" transform="translate(3.777 14.783)"/>
|
||||||
|
<path id="Rectangle_288" d="M0 0H8.855V0.635H0z" class="cls-1" transform="translate(3.777 13.84)"/>
|
||||||
|
<path id="Path_3334" d="M468.273 297.634a.532.532 0 0 0-.212 1.019l-2.968 5.539h-.661l.876-7.74a.608.608 0 1 0-.14-.014l-2.332 7.7h-.652l-1.032-8.891a.757.757 0 1 0-.206 0l-.908 8.89h-.652l-2.408-7.727a.6.6 0 1 0-.209.039.615.615 0 0 0 .126-.013l.844 7.855h-.669l-3.324-5.652a.529.529 0 1 0-.231.054.509.509 0 0 0 .08-.008l3.166 8.488h8.855l2.578-8.488a.521.521 0 0 0 .079.008.532.532 0 0 0 0-1.064z" class="cls-1" transform="translate(-452.982 -293.75)"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g id="Group_3881" transform="translate(35.915 38.821)">
|
||||||
|
<path id="Path_3324" d="M-184.283 393.354a6.466 6.466 0 0 1 2.3.346 8.281 8.281 0 0 1 1.6.808q.423.266.646.062a1.66 1.66 0 0 0 .307-.968h.487q-.043.675-.064 1.625t-.021 2.531h-.487q-.148-.781-.286-1.279a3.235 3.235 0 0 0-.36-.852 3.223 3.223 0 0 0-.6-.693 3.539 3.539 0 0 0-1.5-.924 6.159 6.159 0 0 0-1.884-.284 3.9 3.9 0 0 0-1.905.453 3.95 3.95 0 0 0-1.387 1.287 6.4 6.4 0 0 0-.857 1.971 9.836 9.836 0 0 0-.3 2.486 9.262 9.262 0 0 0 .317 2.513 5.847 5.847 0 0 0 .921 1.936 4.151 4.151 0 0 0 1.461 1.243 4.171 4.171 0 0 0 1.916.435 5.988 5.988 0 0 0 1.8-.293 3.291 3.291 0 0 0 1.482-.9 2.8 2.8 0 0 0 .815-1.2 10.014 10.014 0 0 0 .37-1.82h.487q0 1.634.021 2.637t.064 1.7h-.487a1.75 1.75 0 0 0-.286-.959q-.2-.2-.667.053a11.757 11.757 0 0 1-1.662.808 6.219 6.219 0 0 1-2.254.346 8.265 8.265 0 0 1-3.662-.764 5.675 5.675 0 0 1-2.434-2.2 6.578 6.578 0 0 1-.868-3.463 6.605 6.605 0 0 1 .9-3.48 6.257 6.257 0 0 1 2.466-2.327 7.583 7.583 0 0 1 3.611-.834z" class="cls-1" transform="translate(190.269 -393.354)"/>
|
||||||
|
<path id="Path_3325" d="M-98.578 407.437v-.354a4.523 4.523 0 0 0 1.033-.142.657.657 0 0 0 .456-.425 3.1 3.1 0 0 0 .111-.957v-8.786a3.081 3.081 0 0 0-.111-.965.685.685 0 0 0-.466-.425 3.826 3.826 0 0 0-1.023-.133v-.354q.465.018 1.2.035t1.59.018q.77 0 1.509-.018t1.225-.035v.354a3.7 3.7 0 0 0-1.013.133.713.713 0 0 0-.466.425 2.833 2.833 0 0 0-.122.965v8.786a2.847 2.847 0 0 0 .122.957.685.685 0 0 0 .466.425 4.43 4.43 0 0 0 1.013.142v.354q-.486-.035-1.225-.044t-1.509-.009q-.851 0-1.59.009t-1.2.044zm3.017-6.129v-.354h8v.354zm5.488 6.129v-.354a4.524 4.524 0 0 0 1.033-.142.657.657 0 0 0 .456-.425 3.1 3.1 0 0 0 .111-.957v-8.786a3.081 3.081 0 0 0-.111-.965.685.685 0 0 0-.466-.425 3.827 3.827 0 0 0-1.023-.133v-.354q.506.018 1.266.035t1.509.018q.851 0 1.579-.018t1.175-.035v.354a3.7 3.7 0 0 0-1.013.133.713.713 0 0 0-.466.425 2.833 2.833 0 0 0-.122.965v8.786a2.847 2.847 0 0 0 .122.957.685.685 0 0 0 .466.425 4.428 4.428 0 0 0 1.013.142v.354q-.446-.035-1.175-.044t-1.579-.009q-.749 0-1.509.009t-1.265.044z" class="cls-1" transform="translate(113.581 -394.631)"/>
|
||||||
|
<path id="Path_3326" d="M9.551 394.895v.354a3.927 3.927 0 0 0-1.044.133.728.728 0 0 0-.481.425 2.753 2.753 0 0 0-.125.965v8.786a2.766 2.766 0 0 0 .125.957.7.7 0 0 0 .481.425 4.7 4.7 0 0 0 1.044.142v.354q-.5-.035-1.264-.044t-1.556-.009q-.877 0-1.64.009t-1.243.044v-.354a4.8 4.8 0 0 0 1.065-.142.67.67 0 0 0 .47-.425 3.006 3.006 0 0 0 .115-.957v-8.786a2.992 2.992 0 0 0-.115-.965.7.7 0 0 0-.48-.425 4.062 4.062 0 0 0-1.055-.133v-.354q.48.018 1.243.035t1.64.018q.794 0 1.556-.018t1.264-.035z" class="cls-1" transform="translate(27.92 -394.631)"/>
|
||||||
|
<path id="Path_3327" d="M66.723 393.354a5.757 5.757 0 0 1 2.161.346 7.627 7.627 0 0 1 1.5.808q.4.266.608.062a1.728 1.728 0 0 0 .289-.968h.458q-.04.675-.06 1.625t-.02 2.531H71.2q-.14-.781-.269-1.279a3.347 3.347 0 0 0-.339-.852 3.175 3.175 0 0 0-.568-.693 3.3 3.3 0 0 0-1.414-.924 5.482 5.482 0 0 0-1.773-.284 3.5 3.5 0 0 0-1.793.453 3.815 3.815 0 0 0-1.3 1.287 6.613 6.613 0 0 0-.807 1.971 10.423 10.423 0 0 0-.279 2.486 9.811 9.811 0 0 0 .3 2.513 6.012 6.012 0 0 0 .867 1.936 3.979 3.979 0 0 0 1.374 1.243 3.735 3.735 0 0 0 1.8.435 5.331 5.331 0 0 0 1.693-.293 3.072 3.072 0 0 0 1.394-.9 2.818 2.818 0 0 0 .767-1.2 10.582 10.582 0 0 0 .348-1.82h.458q0 1.634.02 2.637t.06 1.7h-.458a1.828 1.828 0 0 0-.269-.959q-.189-.2-.627.053a10.8 10.8 0 0 1-1.564.808 5.539 5.539 0 0 1-2.121.346 7.39 7.39 0 0 1-3.446-.764 5.471 5.471 0 0 1-2.291-2.2 7.663 7.663 0 0 1 .03-6.943 6.055 6.055 0 0 1 2.32-2.327 6.793 6.793 0 0 1 3.41-.834z" class="cls-1" transform="translate(-19.589 -393.354)"/>
|
||||||
|
<path id="Path_3328" d="M158.438 394.895v.354a3.787 3.787 0 0 0-1.025.133.719.719 0 0 0-.472.425 2.8 2.8 0 0 0-.123.965v8.786a2.815 2.815 0 0 0 .123.957.69.69 0 0 0 .472.425 4.534 4.534 0 0 0 1.025.142v.354q-.492-.035-1.24-.044t-1.527-.009q-.861 0-1.609.009t-1.22.044v-.354a4.632 4.632 0 0 0 1.045-.142.662.662 0 0 0 .461-.425 3.06 3.06 0 0 0 .113-.957v-8.786a3.046 3.046 0 0 0-.113-.965.691.691 0 0 0-.471-.425 3.917 3.917 0 0 0-1.035-.133v-.354q.471.018 1.22.035t1.609.018q.779 0 1.527-.018t1.24-.035zm6.724 0v.354a4.354 4.354 0 0 0-1.3.4 4.461 4.461 0 0 0-1.3 1.019l-3.936 4.251.7-1.081 4.92 6.165a2.918 2.918 0 0 0 .707.673 3.372 3.372 0 0 0 .974.407v.354q-.554-.035-1.333-.044t-1.374-.009q-.369 0-.912.009t-1.363.044v-.354a1.611 1.611 0 0 0 .933-.212q.174-.177-.154-.585l-2.973-3.986a5.2 5.2 0 0 0-.656-.753 1.442 1.442 0 0 0-.594-.337 3.651 3.651 0 0 0-.759-.1v-.372a3.387 3.387 0 0 0 1.486-.337 4.722 4.722 0 0 0 1.179-.868l1.7-1.86a4.328 4.328 0 0 0 .923-1.3.7.7 0 0 0-.1-.824 1.786 1.786 0 0 0-1.148-.3v-.354l1.281.035q.646.018 1.3.018 1.143 0 1.799-.053z" class="cls-1" transform="translate(-97.077 -394.631)"/>
|
||||||
|
<path id="Path_3329" d="M250.861 393.574a4.308 4.308 0 0 1 1.537.213 5.947 5.947 0 0 1 .93.461q.228.125.37.186a.683.683 0 0 0 .275.062q.3 0 .418-.781h.437q-.019.319-.048.754t-.038 1.145q-.01.71-.009 1.864h-.433a5.089 5.089 0 0 0-.408-1.687 3.272 3.272 0 0 0-1.025-1.332 2.749 2.749 0 0 0-1.718-.515 2.387 2.387 0 0 0-1.6.542 1.785 1.785 0 0 0-.636 1.429 2.025 2.025 0 0 0 .418 1.3 4.428 4.428 0 0 0 1.148.977q.73.453 1.661 1 .949.569 1.708 1.128a4.764 4.764 0 0 1 1.2 1.234 2.943 2.943 0 0 1 .437 1.634 3.046 3.046 0 0 1-.579 1.909 3.472 3.472 0 0 1-1.547 1.128 5.872 5.872 0 0 1-2.126.373 5.406 5.406 0 0 1-1.689-.213 7.37 7.37 0 0 1-1.063-.444 1.432 1.432 0 0 0-.645-.249q-.3 0-.418.781h-.437q.038-.39.047-.914t.019-1.376q.009-.852.009-2.148h.437a7.439 7.439 0 0 0 .427 2.06 3.389 3.389 0 0 0 1.082 1.536 3.05 3.05 0 0 0 1.945.577 2.787 2.787 0 0 0 1.689-.542 1.96 1.96 0 0 0 .74-1.7 2.315 2.315 0 0 0-.807-1.8 12.483 12.483 0 0 0-2.116-1.465q-.892-.532-1.67-1.065a4.485 4.485 0 0 1-1.243-1.243 3.007 3.007 0 0 1-.465-1.687 2.8 2.8 0 0 1 .541-1.776 3.237 3.237 0 0 1 1.4-1.03 5.042 5.042 0 0 1 1.845-.326z" class="cls-1" transform="translate(-173.97 -393.536)"/>
|
||||||
|
<path id="Path_3330" d="M374.908 393.354a5.04 5.04 0 0 1 2.031.346 8.087 8.087 0 0 1 1.424.808.759.759 0 0 0 .38.178q.36 0 .474-1.083h.437q-.038.675-.057 1.625t-.019 2.531h-.437a11.9 11.9 0 0 0-.351-1.581 2.834 2.834 0 0 0-.75-1.243 3.432 3.432 0 0 0-1.338-.888 4.615 4.615 0 0 0-1.68-.32 3.343 3.343 0 0 0-1.746.453 3.822 3.822 0 0 0-1.281 1.287 6.647 6.647 0 0 0-.8 1.962 10.447 10.447 0 0 0-.275 2.477 8.192 8.192 0 0 0 1.053 4.68 3.641 3.641 0 0 0 3.179 1.483 3.126 3.126 0 0 0 1.053-.16 4.082 4.082 0 0 0 .712-.319 1.127 1.127 0 0 0 .418-.417 1.3 1.3 0 0 0 .095-.542v-1.723a3.31 3.31 0 0 0-.142-1.128.833.833 0 0 0-.56-.5 4.558 4.558 0 0 0-1.215-.151v-.355q.361.018.854.027l1.034.018q.541.009.978.009.683 0 1.243-.018t.92-.036v.355a.963.963 0 0 0-.759.284 2.715 2.715 0 0 0-.171 1.243v3.516h-.38a2.508 2.508 0 0 0-.142-.657q-.124-.355-.37-.355a.783.783 0 0 0-.275.053 3.315 3.315 0 0 0-.484.266 6.792 6.792 0 0 1-1.386.684 4.845 4.845 0 0 1-1.632.257 6.4 6.4 0 0 1-4.745-1.678 6.316 6.316 0 0 1-1.671-4.662 7.329 7.329 0 0 1 .826-3.569 5.9 5.9 0 0 1 2.259-2.335 6.478 6.478 0 0 1 3.296-.822z" class="cls-1" transform="translate(-277.349 -393.354)"/>
|
||||||
|
<path id="Path_3331" d="M471.6 393.354a8.208 8.208 0 0 1 3.633.764 5.671 5.671 0 0 1 2.432 2.193 6.6 6.6 0 0 1 .863 3.472 6.7 6.7 0 0 1-.885 3.48 6.131 6.131 0 0 1-2.464 2.327 7.59 7.59 0 0 1-3.6.835 8.186 8.186 0 0 1-3.643-.764 5.655 5.655 0 0 1-2.422-2.2 7.293 7.293 0 0 1 .032-6.943 6.238 6.238 0 0 1 2.454-2.329 7.512 7.512 0 0 1 3.6-.835zm-.084.32a3.464 3.464 0 0 0-2.275.8 5.1 5.1 0 0 0-1.5 2.2 9.222 9.222 0 0 0-.526 3.25 8.367 8.367 0 0 0 .589 3.276 5.064 5.064 0 0 0 1.6 2.149 3.674 3.674 0 0 0 2.253.755 3.424 3.424 0 0 0 2.264-.8 5.222 5.222 0 0 0 1.5-2.211 9.077 9.077 0 0 0 .537-3.241 8.22 8.22 0 0 0-.6-3.285 5.191 5.191 0 0 0-1.6-2.14 3.634 3.634 0 0 0-2.242-.753z" class="cls-1" transform="translate(-357.18 -393.354)"/>
|
||||||
|
<path id="Path_3332" d="M569.04 394.895v.354a3.823 3.823 0 0 0-1.031.133.71.71 0 0 0-.47.425 2.863 2.863 0 0 0-.12.965v8.857a2.79 2.79 0 0 0 .11.9.627.627 0 0 0 .44.4 3.552 3.552 0 0 0 .951.1h1.3a3.777 3.777 0 0 0 1.841-.381 2.469 2.469 0 0 0 1.041-1.16 6.976 6.976 0 0 0 .52-1.984h.46a14.694 14.694 0 0 0-.06 1.488q0 .355.03 1.036t.11 1.408q-1.02-.035-2.3-.044t-2.281-.009h-1.651q-1.031 0-2.2.009t-2.191.044v-.354a4.421 4.421 0 0 0 1.021-.142.652.652 0 0 0 .45-.425 3.124 3.124 0 0 0 .11-.957v-8.786a3.109 3.109 0 0 0-.11-.965.68.68 0 0 0-.46-.425 3.736 3.736 0 0 0-1.01-.133v-.354q.46.018 1.191.035t1.571.018q.76 0 1.511-.018t1.227-.035z" class="cls-1" transform="translate(-438.334 -394.631)"/>
|
||||||
|
<path id="Path_3333" d="M652.231 394.895q3.652 0 5.429 1.585a5.772 5.772 0 0 1 1.777 4.544 6.419 6.419 0 0 1-.869 3.375 5.793 5.793 0 0 1-2.517 2.241 9.12 9.12 0 0 1-4 .8q-.435 0-1.293-.027t-1.51-.027q-.75 0-1.471.009t-1.175.044v-.354a4.306 4.306 0 0 0 1.007-.142.647.647 0 0 0 .444-.425 3.154 3.154 0 0 0 .109-.957v-8.786a3.14 3.14 0 0 0-.109-.965.674.674 0 0 0-.454-.425 3.641 3.641 0 0 0-1-.133v-.354l1.175.044q.721.027 1.431.009t1.589-.036q.885-.015 1.437-.02zm-.336.319a1.65 1.65 0 0 0-1.185.3 1.9 1.9 0 0 0-.276 1.222v8.857a1.847 1.847 0 0 0 .286 1.222 1.69 1.69 0 0 0 1.194.3 5.786 5.786 0 0 0 3.1-.7 3.749 3.749 0 0 0 1.559-2.046 10.332 10.332 0 0 0 .454-3.277 7.1 7.1 0 0 0-1.145-4.429q-1.144-1.449-3.982-1.449z" class="cls-1" transform="translate(-508.147 -394.631)"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 10 KiB |
1
src/static/images/icons/README.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
All of these .svg files are not used directly, instead the svg information is copied inline so we can apply CSS classes to them.
|
1
src/static/images/icons/icons8-docker.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"><path d="M 20 9 L 20 14 L 10 14 L 10 19 L 5 19 L 5 24 L 1.125 24 C 0.640625 24 0.242188 24.335938 0.15625 24.8125 C 0.148438 24.847656 0 25.683594 0 26.75 C 0 27.449219 0.0664063 28.210938 0.1875 28.96875 C 1.332031 28.695313 3.429688 28.285156 3.0625 26.9375 C 5.035156 29.222656 9.769531 28.53125 10.96875 27.40625 C 12.308594 29.347656 20.113281 28.605469 20.65625 27.09375 C 22.335938 29.0625 27.542969 29.0625 29.21875 27.09375 C 29.761719 28.605469 37.535156 29.347656 38.875 27.40625 C 39.300781 27.804688 40.1875 28.136719 41.21875 28.3125 C 41.566406 27.652344 41.886719 26.988281 42.1875 26.28125 C 48.539063 26.203125 49.910156 21.636719 49.96875 21.4375 C 50.078125 21.054688 49.929688 20.660156 49.625 20.40625 C 49.519531 20.316406 47.175781 18.414063 43.375 19.0625 C 42.308594 15.589844 39.5625 14.007813 39.4375 13.9375 C 39.078125 13.734375 38.632813 13.765625 38.3125 14.03125 C 38.210938 14.113281 35.847656 16.117188 36.21875 20.21875 C 36.3125 21.25 36.582031 22.160156 37 22.96875 C 36.179688 23.425781 34.769531 24 32.5 24 L 32 24 L 32 19 L 27 19 L 27 9 Z M 41.21875 28.3125 C 41.097656 28.546875 40.941406 28.773438 40.8125 29 L 49.84375 29 C 48.757813 28.726563 46.425781 28.359375 46.8125 26.9375 C 45.535156 28.414063 43.109375 28.632813 41.21875 28.3125 Z M 40.8125 29 L 0.1875 29 C 0.429688 30.46875 0.929688 32.007813 1.6875 33.5 C 7.117188 34.777344 12.816406 32.832031 12.875 32.8125 C 13.398438 32.628906 13.945313 32.917969 14.125 33.4375 C 14.308594 33.957031 14.050781 34.539063 13.53125 34.71875 C 13.339844 34.785156 9.90625 35.9375 5.6875 35.9375 C 4.851563 35.9375 3.972656 35.890625 3.09375 35.78125 C 5.71875 39.261719 10.167969 42 17 42 C 27.804688 42 36.113281 37.410156 40.8125 29 Z M 0.1875 29 C 0.183594 28.984375 0.191406 28.984375 0.1875 28.96875 C 0.121094 28.984375 0.0585938 28.984375 0 29 Z M 22 11 L 25 11 L 25 14 L 22 14 Z M 12 16 L 15 16 L 15 19 L 12 19 Z M 17 16 L 20 16 L 20 19 L 17 19 Z M 22 16 L 25 16 L 25 19 L 22 19 Z M 7 21 L 10 21 L 10 24 L 7 24 Z M 12 21 L 15 21 L 15 24 L 12 24 Z M 17 21 L 20 21 L 20 24 L 17 24 Z M 22 21 L 25 21 L 25 24 L 22 24 Z M 27 21 L 30 21 L 30 24 L 27 24 Z M 16 31 C 16.128906 31 16.261719 31.019531 16.375 31.0625 C 16.253906 31.132813 16.15625 31.253906 16.15625 31.40625 C 16.15625 31.632813 16.335938 31.84375 16.5625 31.84375 C 16.714844 31.84375 16.867188 31.75 16.9375 31.625 C 16.988281 31.742188 17 31.863281 17 32 C 17 32.550781 16.550781 33 16 33 C 15.449219 33 15 32.550781 15 32 C 15 31.449219 15.449219 31 16 31 Z"/></svg>
|
After Width: | Height: | Size: 2.6 KiB |
1
src/static/images/icons/icons8-github(2).svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0"?><svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"> <path d="M17.791,46.836C18.502,46.53,19,45.823,19,45v-5.4c0-0.197,0.016-0.402,0.041-0.61C19.027,38.994,19.014,38.997,19,39 c0,0-3,0-3.6,0c-1.5,0-2.8-0.6-3.4-1.8c-0.7-1.3-1-3.5-2.8-4.7C8.9,32.3,9.1,32,9.7,32c0.6,0.1,1.9,0.9,2.7,2c0.9,1.1,1.8,2,3.4,2 c2.487,0,3.82-0.125,4.622-0.555C21.356,34.056,22.649,33,24,33v-0.025c-5.668-0.182-9.289-2.066-10.975-4.975 c-3.665,0.042-6.856,0.405-8.677,0.707c-0.058-0.327-0.108-0.656-0.151-0.987c1.797-0.296,4.843-0.647,8.345-0.714 c-0.112-0.276-0.209-0.559-0.291-0.849c-3.511-0.178-6.541-0.039-8.187,0.097c-0.02-0.332-0.047-0.663-0.051-0.999 c1.649-0.135,4.597-0.27,8.018-0.111c-0.079-0.5-0.13-1.011-0.13-1.543c0-1.7,0.6-3.5,1.7-5c-0.5-1.7-1.2-5.3,0.2-6.6 c2.7,0,4.6,1.3,5.5,2.1C21,13.4,22.9,13,25,13s4,0.4,5.6,1.1c0.9-0.8,2.8-2.1,5.5-2.1c1.5,1.4,0.7,5,0.2,6.6c1.1,1.5,1.7,3.2,1.6,5 c0,0.484-0.045,0.951-0.11,1.409c3.499-0.172,6.527-0.034,8.204,0.102c-0.002,0.337-0.033,0.666-0.051,0.999 c-1.671-0.138-4.775-0.28-8.359-0.089c-0.089,0.336-0.197,0.663-0.325,0.98c3.546,0.046,6.665,0.389,8.548,0.689 c-0.043,0.332-0.093,0.661-0.151,0.987c-1.912-0.306-5.171-0.664-8.879-0.682C35.112,30.873,31.557,32.75,26,32.969V33 c2.6,0,5,3.9,5,6.6V45c0,0.823,0.498,1.53,1.209,1.836C41.37,43.804,48,35.164,48,25C48,12.318,37.683,2,25,2S2,12.318,2,25 C2,35.164,8.63,43.804,17.791,46.836z"/></svg>
|
After Width: | Height: | Size: 1.4 KiB |
1
src/static/images/icons/icons8-icons8.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0"?><svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"> <path d="M 5 4 C 4.448 4 4 4.447 4 5 L 4 45 C 4 45.553 4.448 46 5 46 L 24 46 C 24.552 46 25 45.553 25 45 L 25 35.5 L 25 14.5 L 25 5 C 25 4.447 24.552 4 24 4 L 5 4 z M 25 14.5 C 25 20.29 29.71 25 35.5 25 C 41.29 25 46 20.29 46 14.5 C 46 8.71 41.29 4 35.5 4 C 29.71 4 25 8.71 25 14.5 z M 35.5 25 C 29.71 25 25 29.71 25 35.5 C 25 41.29 29.71 46 35.5 46 C 41.29 46 46 41.29 46 35.5 C 46 29.71 41.29 25 35.5 25 z"/></svg>
|
After Width: | Height: | Size: 546 B |
1
src/static/images/icons/icons8-instagram(1).svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0"?><svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"> <path d="M 16 3 C 8.83 3 3 8.83 3 16 L 3 34 C 3 41.17 8.83 47 16 47 L 34 47 C 41.17 47 47 41.17 47 34 L 47 16 C 47 8.83 41.17 3 34 3 L 16 3 z M 37 11 C 38.1 11 39 11.9 39 13 C 39 14.1 38.1 15 37 15 C 35.9 15 35 14.1 35 13 C 35 11.9 35.9 11 37 11 z M 25 14 C 31.07 14 36 18.93 36 25 C 36 31.07 31.07 36 25 36 C 18.93 36 14 31.07 14 25 C 14 18.93 18.93 14 25 14 z M 25 16 C 20.04 16 16 20.04 16 25 C 16 29.96 20.04 34 25 34 C 29.96 34 34 29.96 34 25 C 34 20.04 29.96 16 25 16 z"/></svg>
|
After Width: | Height: | Size: 614 B |
1
src/static/images/icons/icons8-kubernetes.svg
Normal file
After Width: | Height: | Size: 10 KiB |
1
src/static/images/icons/icons8-linkedin.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0"?><svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"> <path d="M41,4H9C6.24,4,4,6.24,4,9v32c0,2.76,2.24,5,5,5h32c2.76,0,5-2.24,5-5V9C46,6.24,43.76,4,41,4z M17,20v19h-6V20H17z M11,14.47c0-1.4,1.2-2.47,3-2.47s2.93,1.07,3,2.47c0,1.4-1.12,2.53-3,2.53C12.2,17,11,15.87,11,14.47z M39,39h-6c0,0,0-9.26,0-10 c0-2-1-4-3.5-4.04h-0.08C27,24.96,26,27.02,26,29c0,0.91,0,10,0,10h-6V20h6v2.56c0,0,1.93-2.56,5.81-2.56 c3.97,0,7.19,2.73,7.19,8.26V39z"/></svg>
|
After Width: | Height: | Size: 518 B |
6
src/static/images/icons/icons8-mail.svg
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" width="100px" height="100px">
|
||||||
|
<g id="surface12014155">
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 28 8 C 16.976562 8 8 16.976562 8 28 L 8 72 C 8 83.023438 16.976562 92 28 92 L 72 92 C 83.023438 92 92 83.023438 92 72 L 92 28 C 92 16.976562 83.023438 8 72 8 Z M 26 32 L 74 32 C 74.359375 32 74.699219 32.039062 75.019531 32.140625 L 55.359375 51.78125 C 52.398438 54.742188 47.582031 54.742188 44.621094 51.78125 L 24.980469 32.140625 C 25.300781 32.039062 25.640625 32 26 32 Z M 22.140625 34.980469 L 37.179688 50 L 22.140625 65.019531 C 22.039062 64.699219 22 64.359375 22 64 L 22 36 C 22 35.640625 22.039062 35.300781 22.140625 34.980469 Z M 77.859375 34.980469 C 77.960938 35.300781 78 35.640625 78 36 L 78 64 C 78 64.359375 77.960938 64.699219 77.859375 65.019531 L 62.800781 50 Z M 40 52.820312 L 41.78125 54.621094 C 44.042969 56.882812 47.019531 58 49.980469 58 C 52.960938 58 55.917969 56.882812 58.179688 54.621094 L 59.980469 52.820312 L 75.019531 67.859375 C 74.699219 67.960938 74.359375 68 74 68 L 26 68 C 25.640625 68 25.300781 67.960938 24.980469 67.859375 Z M 40 52.820312 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/static/images/icons/icons8-react.svg
Normal file
After Width: | Height: | Size: 5.4 KiB |
1
src/static/images/icons/icons8-twitter.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"><path d="M 50.0625 10.4375 C 48.214844 11.257813 46.234375 11.808594 44.152344 12.058594 C 46.277344 10.785156 47.910156 8.769531 48.675781 6.371094 C 46.691406 7.546875 44.484375 8.402344 42.144531 8.863281 C 40.269531 6.863281 37.597656 5.617188 34.640625 5.617188 C 28.960938 5.617188 24.355469 10.21875 24.355469 15.898438 C 24.355469 16.703125 24.449219 17.488281 24.625 18.242188 C 16.078125 17.8125 8.503906 13.71875 3.429688 7.496094 C 2.542969 9.019531 2.039063 10.785156 2.039063 12.667969 C 2.039063 16.234375 3.851563 19.382813 6.613281 21.230469 C 4.925781 21.175781 3.339844 20.710938 1.953125 19.941406 C 1.953125 19.984375 1.953125 20.027344 1.953125 20.070313 C 1.953125 25.054688 5.5 29.207031 10.199219 30.15625 C 9.339844 30.390625 8.429688 30.515625 7.492188 30.515625 C 6.828125 30.515625 6.183594 30.453125 5.554688 30.328125 C 6.867188 34.410156 10.664063 37.390625 15.160156 37.472656 C 11.644531 40.230469 7.210938 41.871094 2.390625 41.871094 C 1.558594 41.871094 0.742188 41.824219 -0.0585938 41.726563 C 4.488281 44.648438 9.894531 46.347656 15.703125 46.347656 C 34.617188 46.347656 44.960938 30.679688 44.960938 17.09375 C 44.960938 16.648438 44.949219 16.199219 44.933594 15.761719 C 46.941406 14.3125 48.683594 12.5 50.0625 10.4375 Z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/static/images/icons/icons8-typescript.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px"><path d="M45,4H5C4.447,4,4,4.448,4,5v40c0,0.552,0.447,1,1,1h40c0.553,0,1-0.448,1-1V5C46,4.448,45.553,4,45,4z M29,26.445h-5V42h-4 V26.445h-5V23h14V26.445z M30.121,41.112v-4.158c0,0,2.271,1.712,4.996,1.712c2.725,0,2.62-1.782,2.62-2.026 c0-2.586-7.721-2.586-7.721-8.315c0-7.791,11.25-4.717,11.25-4.717l-0.14,3.704c0,0-1.887-1.258-4.018-1.258s-2.9,1.013-2.9,2.096 c0,2.795,7.791,2.516,7.791,8.141C42,44.955,30.121,41.112,30.121,41.112z"/></svg>
|
After Width: | Height: | Size: 545 B |
BIN
src/static/images/texas-icon.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/static/images/vrbo-logo-min.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
src/static/images/vrbo-logo.png
Normal file
After Width: | Height: | Size: 554 KiB |