fix: commit
This commit is contained in:
parent
50357563e4
commit
8ac9ba5dad
176
.gitignore
vendored
Normal file
176
.gitignore
vendored
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
|
||||||
|
logs
|
||||||
|
_.log
|
||||||
|
npm-debug.log_
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
|
||||||
|
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
|
||||||
|
pids
|
||||||
|
_.pid
|
||||||
|
_.seed
|
||||||
|
\*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
|
||||||
|
coverage
|
||||||
|
\*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
|
||||||
|
\*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
|
||||||
|
\*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
|
||||||
|
.cache/
|
||||||
|
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
|
||||||
|
.temp
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.\*
|
||||||
|
|
||||||
|
# IntelliJ based IDEs
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Finder (MacOS) folder config
|
||||||
|
.DS_Store
|
||||||
|
|
8
.prettierrc.cjs
Normal file
8
.prettierrc.cjs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
module.exports = {
|
||||||
|
tabWidth: 2,
|
||||||
|
trailingComma: 'all',
|
||||||
|
singleQuote: true,
|
||||||
|
semi: false,
|
||||||
|
arrowParens: 'avoid',
|
||||||
|
plugins: [],
|
||||||
|
}
|
15
README.md
Normal file
15
README.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# resume
|
||||||
|
|
||||||
|
To install dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun install
|
||||||
|
```
|
||||||
|
|
||||||
|
To run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun run index.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
This project was created using `bun init` in bun v1.0.3. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
|
BIN
assets/IosevkaAile-Bold.woff2
Normal file
BIN
assets/IosevkaAile-Bold.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-BoldItalic.woff2
Normal file
BIN
assets/IosevkaAile-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-BoldOblique.woff2
Normal file
BIN
assets/IosevkaAile-BoldOblique.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-ExtraBold.woff2
Normal file
BIN
assets/IosevkaAile-ExtraBold.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-ExtraBoldItalic.woff2
Normal file
BIN
assets/IosevkaAile-ExtraBoldItalic.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-ExtraBoldOblique.woff2
Normal file
BIN
assets/IosevkaAile-ExtraBoldOblique.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-ExtraLight.woff2
Normal file
BIN
assets/IosevkaAile-ExtraLight.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-ExtraLightItalic.woff2
Normal file
BIN
assets/IosevkaAile-ExtraLightItalic.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-ExtraLightOblique.woff2
Normal file
BIN
assets/IosevkaAile-ExtraLightOblique.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-Heavy.woff2
Normal file
BIN
assets/IosevkaAile-Heavy.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-HeavyItalic.woff2
Normal file
BIN
assets/IosevkaAile-HeavyItalic.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-HeavyOblique.woff2
Normal file
BIN
assets/IosevkaAile-HeavyOblique.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-Italic.woff2
Normal file
BIN
assets/IosevkaAile-Italic.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-Light.woff2
Normal file
BIN
assets/IosevkaAile-Light.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-LightItalic.woff2
Normal file
BIN
assets/IosevkaAile-LightItalic.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-LightOblique.woff2
Normal file
BIN
assets/IosevkaAile-LightOblique.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-Medium.woff2
Normal file
BIN
assets/IosevkaAile-Medium.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-MediumItalic.woff2
Normal file
BIN
assets/IosevkaAile-MediumItalic.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-MediumOblique.woff2
Normal file
BIN
assets/IosevkaAile-MediumOblique.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-Oblique.woff2
Normal file
BIN
assets/IosevkaAile-Oblique.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-Regular.woff2
Normal file
BIN
assets/IosevkaAile-Regular.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-SemiBold.woff2
Normal file
BIN
assets/IosevkaAile-SemiBold.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-SemiBoldItalic.woff2
Normal file
BIN
assets/IosevkaAile-SemiBoldItalic.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-SemiBoldOblique.woff2
Normal file
BIN
assets/IosevkaAile-SemiBoldOblique.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-Thin.woff2
Normal file
BIN
assets/IosevkaAile-Thin.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-ThinItalic.woff2
Normal file
BIN
assets/IosevkaAile-ThinItalic.woff2
Normal file
Binary file not shown.
BIN
assets/IosevkaAile-ThinOblique.woff2
Normal file
BIN
assets/IosevkaAile-ThinOblique.woff2
Normal file
Binary file not shown.
233
assets/iosevka.css
Normal file
233
assets/iosevka.css
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 100;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
src: url('./IosevkaAile-Thin.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 100;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: oblique;
|
||||||
|
src: url('./IosevkaAile-ThinOblique.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 100;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: italic;
|
||||||
|
src: url('./IosevkaAile-ThinItalic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 200;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
src: url('./IosevkaAile-ExtraLight.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 200;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: oblique;
|
||||||
|
src: url('./IosevkaAile-ExtraLightOblique.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 200;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: italic;
|
||||||
|
src: url('./IosevkaAile-ExtraLightItalic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 300;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
src: url('./IosevkaAile-Light.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 300;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: oblique;
|
||||||
|
src: url('./IosevkaAile-LightOblique.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 400;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
src: url('./IosevkaAile-Regular.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 400;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: oblique;
|
||||||
|
src: url('./IosevkaAile-Oblique.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 400;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: italic;
|
||||||
|
src: url('./IosevkaAile-Italic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 500;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
src: url('./IosevkaAile-Medium.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 500;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: oblique;
|
||||||
|
src: url('./IosevkaAile-MediumOblique.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 500;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: italic;
|
||||||
|
src: url('./IosevkaAile-MediumItalic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 600;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
src: url('./IosevkaAile-SemiBold.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 600;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: oblique;
|
||||||
|
src: url('./IosevkaAile-SemiBoldOblique.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 600;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: italic;
|
||||||
|
src: url('./IosevkaAile-SemiBoldItalic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 700;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
src: url('./IosevkaAile-Bold.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 700;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: oblique;
|
||||||
|
src: url('./IosevkaAile-BoldOblique.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 700;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: italic;
|
||||||
|
src: url('./IosevkaAile-BoldItalic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 800;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
src: url('./IosevkaAile-ExtraBold.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 800;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: oblique;
|
||||||
|
src: url('./IosevkaAile-ExtraBoldOblique.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 800;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: italic;
|
||||||
|
src: url('./IosevkaAile-ExtraBoldItalic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 900;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
src: url('./IosevkaAile-Heavy.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 900;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: oblique;
|
||||||
|
src: url('./IosevkaAile-HeavyOblique.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 900;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: italic;
|
||||||
|
src: url('./IosevkaAile-HeavyItalic.woff2') format('woff2');
|
||||||
|
}
|
BIN
assets/orion.jpg
Normal file
BIN
assets/orion.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 111 KiB |
BIN
assets/star_0.0.png
Normal file
BIN
assets/star_0.0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
BIN
assets/star_0.5.png
Normal file
BIN
assets/star_0.5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
BIN
assets/star_1.0.png
Normal file
BIN
assets/star_1.0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
15
bun/fmt.js
Normal file
15
bun/fmt.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/** @type {(parser: string, ps: string[]) => import("bun").Subprocess} */
|
||||||
|
const prettier = (parser, ps) =>
|
||||||
|
Bun.spawn(['bun', 'x', 'prettier', '--write', '--parser', parser, ...ps], {
|
||||||
|
stdout: 'inherit',
|
||||||
|
stderr: 'inherit',
|
||||||
|
})
|
||||||
|
|
||||||
|
const procs = [
|
||||||
|
prettier('babel', ['./index.js', './bun/**/*.js', './.prettierrc.cjs']),
|
||||||
|
prettier('json', ['./package.json', './jsconfig.json']),
|
||||||
|
prettier('html', ['./resume.html']),
|
||||||
|
prettier('css', ['./assets/iosevka.css']),
|
||||||
|
]
|
||||||
|
|
||||||
|
await Promise.all(procs.map(p => p.exited))
|
41
index.js
Normal file
41
index.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { $ } from 'zx'
|
||||||
|
import * as Fs from 'fs'
|
||||||
|
import * as Path from 'path'
|
||||||
|
import * as Stream from 'stream/promises'
|
||||||
|
import * as Puppeteer from 'puppeteer'
|
||||||
|
|
||||||
|
/** @type {import('puppeteer').PDFOptions} */
|
||||||
|
const PDF_OPTIONS = {
|
||||||
|
format: 'letter',
|
||||||
|
printBackground: true,
|
||||||
|
margin: { bottom: '0.25in', top: '0.25in', left: '0.25in', right: '0.25in' },
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEBUG = !!process.env['DEBUG']
|
||||||
|
|
||||||
|
const root = 'file://' + Path.resolve(import.meta.dir, './dist')
|
||||||
|
console.log(root)
|
||||||
|
|
||||||
|
await $`bun bundle --public-url ${root}`
|
||||||
|
|
||||||
|
const pup = await Puppeteer.launch({ headless: DEBUG ? false : 'new' })
|
||||||
|
const page = await pup.newPage()
|
||||||
|
await page.goto(root + '/resume.html')
|
||||||
|
await page.waitForNetworkIdle()
|
||||||
|
const pdf = await page.createPDFStream(PDF_OPTIONS)
|
||||||
|
const out = Fs.createWriteStream('./resume.pdf', { flags: 'w+' })
|
||||||
|
await Stream.pipeline(pdf, out)
|
||||||
|
if (!DEBUG) await pup.close()
|
||||||
|
console.log('wrote ./resume.pdf')
|
||||||
|
|
||||||
|
process.on('SIGINT', () => {
|
||||||
|
pup.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
process.on('SIGHUP', () => {
|
||||||
|
pup.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
process.on('exit', () => {
|
||||||
|
pup.close()
|
||||||
|
})
|
16
jsconfig.json
Normal file
16
jsconfig.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"types": ["bun-types"],
|
||||||
|
"lib": ["esnext"],
|
||||||
|
"target": "esnext",
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"jsx": "react",
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"strict": true
|
||||||
|
},
|
||||||
|
"include": ["index.js", "bun/**/*.js"]
|
||||||
|
}
|
21
package.json
Normal file
21
package.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "resume",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"bundle": "parcel build --no-cache ./resume.html",
|
||||||
|
"export": "bun index.js",
|
||||||
|
"fmt": "bun bun/fmt.js"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"bun-types": "latest",
|
||||||
|
"prettier": "^3.1.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"parcel": "latest",
|
||||||
|
"puppeteer": "^21.7.0",
|
||||||
|
"zx": "^7.2.3"
|
||||||
|
}
|
||||||
|
}
|
932
resume.html
Normal file
932
resume.html
Normal file
@ -0,0 +1,932 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css?family=DM+Serif+Display"
|
||||||
|
/>
|
||||||
|
<link rel="stylesheet" href="./assets/iosevka.css" />
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
gap: 10pt;
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
body * {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,
|
||||||
|
p,
|
||||||
|
span,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
div {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul, li {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3 {
|
||||||
|
font-family: 'DM Serif Display';
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 48pt;
|
||||||
|
margin-top: -8pt;
|
||||||
|
margin-bottom: -6pt;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 32pt;
|
||||||
|
margin-top: -4pt;
|
||||||
|
margin-bottom: -4pt;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
font-size: 24pt;
|
||||||
|
margin-top: -4pt;
|
||||||
|
margin-bottom: -3pt;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-size: 16pt;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-top: -1pt;
|
||||||
|
margin-bottom: -2pt;
|
||||||
|
}
|
||||||
|
h5 {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-size: 12pt;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-top: -1pt;
|
||||||
|
margin-bottom: -2pt;
|
||||||
|
}
|
||||||
|
h6 {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-size: 10pt;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-top: -1pt;
|
||||||
|
margin-bottom: -1pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
span, li {
|
||||||
|
font-family: 'Iosevka Aile';
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nowrap {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
a:visited {
|
||||||
|
text-decoration: none;
|
||||||
|
font-style: none;
|
||||||
|
color: hsl(251deg, 60%, 40%);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.star-1\.0 {
|
||||||
|
background-image: url('./assets/star_1.0.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
div.star-0\.5 {
|
||||||
|
background-image: url('./assets/star_0.5.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
div.star-0\.0 {
|
||||||
|
background-image: url('./assets/star_0.0.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
div.star-1\.0,
|
||||||
|
div.star-0\.5,
|
||||||
|
div.star-0\.0 {
|
||||||
|
height: 12pt;
|
||||||
|
width: 12pt;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.hr {
|
||||||
|
height: 2pt;
|
||||||
|
width: 100%;
|
||||||
|
background-color: hsl(0deg 0% 80%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.break {
|
||||||
|
page-break-after: always;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.col {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 3pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.row,
|
||||||
|
div.col {
|
||||||
|
break-inside: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.col.right {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.row.packed,
|
||||||
|
div.col.packed {
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grow-x {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grow-y {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col > *,
|
||||||
|
.row > * {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.space {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.cols_2 {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-auto-rows: min-content;
|
||||||
|
gap: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.cols_4 {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
grid-auto-rows: min-content;
|
||||||
|
gap: 5pt;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="row space">
|
||||||
|
<h1 style="display: inline">Orion Kindel</h1>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col right">
|
||||||
|
<a href="mailto:orionkindel@gmail.com">
|
||||||
|
<h5>orionkindel@gmail.com</h5></a
|
||||||
|
>
|
||||||
|
<a href="https://git.orionkindel.com">
|
||||||
|
<h5>git.orionkindel.com</h5></a
|
||||||
|
>
|
||||||
|
<a href="https://linkedin.com/in/orion-kindel">
|
||||||
|
<h5>linkedin.com/in/orion-kindel</h5></a
|
||||||
|
>
|
||||||
|
<a href="https://instagram.com/orion.kindel">
|
||||||
|
<p>instagram.com/orion.kindel</p></a
|
||||||
|
>
|
||||||
|
<a href="tel:9894430197"> <p>+1 989 443 0197</p></a>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
style="display: inline; height: 72pt; width: 72pt"
|
||||||
|
src="./assets/orion.jpg"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hr"></div>
|
||||||
|
<h2>Brief</h2>
|
||||||
|
<h5>
|
||||||
|
A flexible and experienced tech professional who can reliably leverage his
|
||||||
|
insights to empower and accelerate teams and organizations.
|
||||||
|
</h5>
|
||||||
|
<h5>
|
||||||
|
Orion is a powerful force multiplier with 7 years’ experience as a
|
||||||
|
software engineer, leader, systems architect, and product manager.
|
||||||
|
</h5>
|
||||||
|
<div class="hr"></div>
|
||||||
|
<div class="row space">
|
||||||
|
<h2>Key Skills</h2>
|
||||||
|
<div class="col right">
|
||||||
|
<div class="row">
|
||||||
|
<h5>Expert</h5>
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<h5>Very Strong</h5>
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<h5>Strong</h5>
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.0"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="cols_2">
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">Javascript</h5>
|
||||||
|
<span class="nowrap">8 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Designed and implemented full-stack high scale production systems at
|
||||||
|
every position held.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Deep understanding of language semantics, exception handling,
|
||||||
|
runtimes, performance characteristics and tooling.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Architected & implemented complex production interfaces in React, as
|
||||||
|
well as angular, vue and svelte. Deep experience using hooks &
|
||||||
|
functional components to manage state and complexity as the product
|
||||||
|
scales.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Guided teams to best practices, building systems with 5-40 active
|
||||||
|
contributors handling 1MM requests / second with %99.999 uptime
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">Rust</h5>
|
||||||
|
<span class="nowrap">6 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Active Open Source community member; language contributions and
|
||||||
|
discussions.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Deep understanding of language semantics, exception handling,
|
||||||
|
runtimes, performance characteristics and tooling.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Owner of the primary implementation of the CoAP networking protocol,
|
||||||
|
which brings high performance REST semantics to bare metal and
|
||||||
|
distributed systems.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Built teams using the language, training teammates reaching productive
|
||||||
|
and capable in <2mo.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">Purescript</h5>
|
||||||
|
<span class="nowrap">5 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Active Open Source community member; language contributions,
|
||||||
|
discussions, discord member.
|
||||||
|
</p>
|
||||||
|
<p>Owner of many popular packages and abstractions.</p>
|
||||||
|
<p>
|
||||||
|
Deep understanding of language semantics, exception handling,
|
||||||
|
runtimes, performance characteristics, abstractions and tooling.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Built teams using the language, training teammates reaching productive
|
||||||
|
and capable in <2mo.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">Git</h5>
|
||||||
|
<span class="nowrap">7 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Manage 100s of open source repositories, highly active open source
|
||||||
|
member and contributor.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Managed & built git teams at scale, with some repos having hundreds of
|
||||||
|
daily contributors.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">Systems Architecture</h5>
|
||||||
|
<span class="nowrap">6 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Have designed, implemented and modified systems across scales and
|
||||||
|
stacks.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Have designed and implemented Distributed (Microservices or Services),
|
||||||
|
Monolithic, and Event Driven systems - choosing the model based on the
|
||||||
|
product and organization’s requirements, capacity, and time
|
||||||
|
constraints.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">Docker</h5>
|
||||||
|
<span class="nowrap">6 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Use docker in most projects for 4 years for making version management,
|
||||||
|
reproducible deploy artifacts, pull-based deployment models and
|
||||||
|
security isolation.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Have used kubernetes to manage deployments of complex distributed
|
||||||
|
systems handling millions of requests and $500K MRR with high
|
||||||
|
reliability.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">CICD</h5>
|
||||||
|
<span class="nowrap">6 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Use comprehensive automated testing and CI platforms to automate
|
||||||
|
quality checks and deployment, significantly accelerating product
|
||||||
|
development.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">Linux</h5>
|
||||||
|
<span class="nowrap">6 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Have used linux personally & in production. Choose VMs (EC2) in lieu
|
||||||
|
of kubernetes or managed environments for almost all production needs
|
||||||
|
for many reasons.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Deep understanding of systems semantics, filesystems, security model,
|
||||||
|
networking, resource management, shells, scripting and tooling.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Guided teams to best practices, building systems with 5-40 active
|
||||||
|
contributors handling 1MM requests / second with %99.999 uptime
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">SQL</h5>
|
||||||
|
<span class="nowrap">7 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Have designed & implemented highly normalized and scalable relational
|
||||||
|
schemas (both for monolithic and distributed systems)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Have used read replication, partitioning and indexing to manage pain
|
||||||
|
points inherent in maintaining a relational database while the product
|
||||||
|
and organization scale.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Have used many strategies to integrate relational databases with
|
||||||
|
dynamic and strongly-typed business logic layers from highly-managed
|
||||||
|
ORMs (ex. Flask, Entity Framework, PrismaJS) to mini-ORMs.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">Player-Coach</h5>
|
||||||
|
<span class="nowrap">6 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Have managed teams of sizes 3-10 as a team lead (player-coach),
|
||||||
|
accountable for success of individual team members as well as the
|
||||||
|
team. Able to consistenly make & meet data-driven commitments, develop
|
||||||
|
and maintain excellent relationships with team members and
|
||||||
|
stakeholders based on accountability, candor and transparency.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Use tools like CICD, Scrum, TDD and pair programming to increase team
|
||||||
|
velocity without applying pressure to individual team members.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Use frequent touchpoints with team members and a shared understanding
|
||||||
|
of my expectations and their goals, decomposing them into measurable
|
||||||
|
actionable steps and holding them accountable.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">AWS</h5>
|
||||||
|
<span class="nowrap">7 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Have used AWS to deploy and manage systems at scale, both persistent
|
||||||
|
and on-demand (serverless) applications.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Deep understanding of networking model (VPC), database hosting (RDS),
|
||||||
|
persistent managed or unmanaged servers (EC2), on-demand compute
|
||||||
|
(Lambda), event-driven architecture (SQS), machine learning
|
||||||
|
(SageMaker), permissions management (IAM).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row grow-x">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h5 class="grow-x">Scrum</h5>
|
||||||
|
<span class="nowrap">7 years</span>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Have led 5 scrum-informed process transformations to improve team
|
||||||
|
performance, transparency and clarity.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Trained and mentored product managers on their role and
|
||||||
|
responsibilities, solving many sources of friction and conflict on
|
||||||
|
under-performing teams.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Have filled roles of scrum master and product owner on several product
|
||||||
|
teams to much success.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3>Other Skills</h3>
|
||||||
|
<div class="cols_4">
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>REST</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>HATEOAS</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>JIRA</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Figma</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Slack API</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>OSS Mgmt</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>OAuth, OIDC</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Networking</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Python</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Scala</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Java</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h6>OCaml</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h6>C#</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Java</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h6>GraphQL</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h6>NoSQL</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Data Insights</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.5"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Machine Learning</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Cryptography</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Terraform</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>gRPC</h6>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row packed">
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-1.0"></div>
|
||||||
|
<div class="star-0.0"></div>
|
||||||
|
</div>
|
||||||
|
<h6>Embedded</h6>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hr break"></div>
|
||||||
|
<div class="hr"></div>
|
||||||
|
<h2>Experience</h2>
|
||||||
|
<div class="col">
|
||||||
|
<h3>thunderstrike.ai</h3>
|
||||||
|
<h4>Technical Founder & CTO</h4>
|
||||||
|
<p>2023 - Present</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Built product MVP in Purescript & Rust in 4mo fully covered by
|
||||||
|
automated testing, automated deployments, load testing @ 100K messages
|
||||||
|
/ second yields <100ms latency
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
With CEO have signed over $100K in contract value with customers since
|
||||||
|
foundation in October
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Perform competitor analysis, user interviews, and develop KPIs to
|
||||||
|
continuously refresh our understanding of the problem we’re solving -
|
||||||
|
pivoting when necessary.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Maintain living backlog in JIRA* for transparency and accountability
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Manage 2 junior engineers, placed directly from bootcamp graduation
|
||||||
|
2mo ago who are now formidable and productive in Rust and Purescript.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Develop and manage local Chicago tech community presence both for
|
||||||
|
networking and startup representation.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h3>Qwick</h3>
|
||||||
|
<h4>Senior Software Engineer</h4>
|
||||||
|
<p>2021 - 2023</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Overhauled onboarding process, helping accelerate new junior hires
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Architected invoicing system to handle $500K MRR with near-zero
|
||||||
|
downtime
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Oversaw team of 4 junior engineers & 1 senior engineer executing on
|
||||||
|
invoicing system. Was responsible for individual & team outcomes.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Led initiative to decouple and modularize existing monolithic
|
||||||
|
architecture, transforming into a services model with several
|
||||||
|
event-driven components, adding independent deployability and
|
||||||
|
automated testing. This increased developer velocity by 40%,
|
||||||
|
reliability up from %99.9 to %99.999 in 6mo
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Led agile & scrum transformation with CTO, contributing to velocity
|
||||||
|
increase of 40%
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Led DevSecOps team, adding automated testing, CICD, system
|
||||||
|
rearchitecture, documentation, DX improvements
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Mentored product managers helping them relax into a role of vision and
|
||||||
|
user-advocacy, allowing dev teams to execute on well-structured
|
||||||
|
problem statements
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Led Google Design Sprints to quickly define and validate new product
|
||||||
|
initiatives, introducing data-driven and qualitative user research
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Organized grassroots presentations, helped team members develop and
|
||||||
|
present their own topics
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h3>TheoremOne</h3>
|
||||||
|
<h4>Senior Lead Software Engineer</h4>
|
||||||
|
<p>2020 - 2021</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Architected robust systems on AWS in Python, Ruby, React, Typescript
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Developed excellent relationships with stakeholders, communicating
|
||||||
|
clear and frequent progress updates via demos, gathering feedback and
|
||||||
|
requirements
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Managed 2 teams of 5-6, overhauling process increasing velocity by
|
||||||
|
30-40%.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h4>Software Engineering Manager</h4>
|
||||||
|
<p>2021</p>
|
||||||
|
<ul>
|
||||||
|
<li>Onboarded new Client Coordinator & Product Manager</li>
|
||||||
|
<li>
|
||||||
|
Managed team of 4 full-stack engineers, 1 QA, 1 GIS engineer working
|
||||||
|
on seed-stage MVP
|
||||||
|
</li>
|
||||||
|
<li>Negotiated deadlines and rebuilt damaged trust with client</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h4>Product Manager</h4>
|
||||||
|
<p>2021</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Owned living backlog with aggressive culling of speculative epics and
|
||||||
|
stories so as to reduce noise and keep meaningful
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Communicated frequently with client to continually adjust forecasts,
|
||||||
|
refine backlog and improve understanding of requirements
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Held dev team accountable for refining tickets into tasks and having
|
||||||
|
implementation discussions with 1-2 sprint lead time.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Ensured prior to Planning, tickets had accurate estimates, subtasks,
|
||||||
|
and had been seen and touched by everyone who could execute on it,
|
||||||
|
making it a 15min ceremony.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h3>Strongmind</h3>
|
||||||
|
<h4>Software Engineer</h4>
|
||||||
|
<p>2017 - 2020</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Architected & executed on robust production systems in .NET, JS, TS,
|
||||||
|
Python & Rust on AWS & Azure. Several greenfield and legacy projects
|
||||||
|
incl. complex distributed systems, OLAP data pipeline, data warehouse,
|
||||||
|
mobile app development and learning management system (Canvas LMS)
|
||||||
|
integration.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Led several team process transformations, using process changes and
|
||||||
|
product vision improvements to increase team velocity and happiness.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Led adoption of new technical practices, improving maintainability and
|
||||||
|
velcoity. Ex. transitioning from TFVC to git, automating deployment
|
||||||
|
and UAT, containerizing products, introducing automated testing.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Mentored several junior engineers, led 2 teams developing production
|
||||||
|
systems that are still used with few changes today.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="hr"></div>
|
||||||
|
<h2>Education</h2>
|
||||||
|
<div class="col">
|
||||||
|
<h4>Associate’s of Science, Physics</h4>
|
||||||
|
<p>Scottsdale Community College, 2014 - 2016</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h4>Certified Scrum Developer</h4>
|
||||||
|
<p>Scrum Alliance, 2019</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<h4>Certified Scrum Product Owner</h4>
|
||||||
|
<p>Scrum Alliance, 2020</p>
|
||||||
|
</div>
|
||||||
|
<div class="hr"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
resume.pdf
Normal file
BIN
resume.pdf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user