From 14aad2e352c5337945b6f60126f19079474e460f Mon Sep 17 00:00:00 2001 From: ION606 Date: Wed, 11 Jun 2025 16:05:15 -0400 Subject: [PATCH] updated resume --- README.css => CSS/README.css | 103 +++++++++++++ links.css => CSS/links.css | 0 pageMenu.css => CSS/pageMenu.css | 0 projects.css => CSS/projects.css | 0 style.css => CSS/style.css | 0 README.js => JS/README.js | 66 ++++---- JS/glitch.js | 134 ++++++++++++++++ pageMenu.js => JS/pageMenu.js | 0 script.js => JS/script.js | 0 terminal.js => JS/terminal.js | 255 +++++++++++++++++++++++-------- README.html | 28 +++- index.html | 71 +++++---- links.html | 135 +++++++++------- projects.html | 19 ++- 14 files changed, 609 insertions(+), 202 deletions(-) rename README.css => CSS/README.css (86%) rename links.css => CSS/links.css (100%) rename pageMenu.css => CSS/pageMenu.css (100%) rename projects.css => CSS/projects.css (100%) rename style.css => CSS/style.css (100%) rename README.js => JS/README.js (82%) create mode 100644 JS/glitch.js rename pageMenu.js => JS/pageMenu.js (100%) rename script.js => JS/script.js (100%) rename terminal.js => JS/terminal.js (59%) diff --git a/README.css b/CSS/README.css similarity index 86% rename from README.css rename to CSS/README.css index d458b67..1fae20a 100644 --- a/README.css +++ b/CSS/README.css @@ -471,4 +471,107 @@ body[data-theme="day"] #dev-console li::before { margin: 0.5rem 0; font-family: monospace; border-left: 3px solid #ff4d4d; +} + +/* lower-case comment: stage 2 shake */ +@keyframes shake-anim { + + 0%, + 100% { + transform: translate(0, 0); + } + + 20% { + transform: translate(-5px, 5px); + } + + 40% { + transform: translate(5px, -5px); + } + + 60% { + transform: translate(-5px, -5px); + } + + 80% { + transform: translate(5px, 5px); + } +} + +body.shake { + animation: shake-anim 0.2s infinite; +} + +@keyframes flicker-anim { + + 0%, + 100% { + opacity: 1; + } + + 50% { + opacity: 0.5; + } +} + +body.flicker { + animation: flicker-anim 0.1s infinite; +} + +#virusHex { + color: #0f0; + background: black; +} + + +/* glitching text effect */ +@keyframes text-glitch { + 0% { + opacity: 1; + clip: rect(0, 9999px, 0, 0); + } + + 10% { + clip: rect(5px, 9999px, 10px, 0); + } + + 20% { + clip: rect(15px, 9999px, 20px, 0); + } + + 30% { + clip: rect(25px, 9999px, 30px, 0); + } + + 40% { + clip: rect(35px, 9999px, 40px, 0); + } + + 50% { + clip: rect(45px, 9999px, 50px, 0); + } + + 60% { + clip: rect(55px, 9999px, 60px, 0); + } + + 70% { + clip: rect(65px, 9999px, 70px, 0); + } + + 80% { + clip: rect(75px, 9999px, 80px, 0); + } + + 90% { + clip: rect(85px, 9999px, 90px, 0); + } + + 100% { + clip: rect(0, 9999px, 0, 0); + } +} + +#virusMsg { + text-align: center; } \ No newline at end of file diff --git a/links.css b/CSS/links.css similarity index 100% rename from links.css rename to CSS/links.css diff --git a/pageMenu.css b/CSS/pageMenu.css similarity index 100% rename from pageMenu.css rename to CSS/pageMenu.css diff --git a/projects.css b/CSS/projects.css similarity index 100% rename from projects.css rename to CSS/projects.css diff --git a/style.css b/CSS/style.css similarity index 100% rename from style.css rename to CSS/style.css diff --git a/README.js b/JS/README.js similarity index 82% rename from README.js rename to JS/README.js index 9e8ad9a..707750a 100644 --- a/README.js +++ b/JS/README.js @@ -169,38 +169,36 @@ const observer = new IntersectionObserver( { threshold: 0.1 } ); -document.addEventListener("DOMContentLoaded", () => { - document.querySelectorAll(".section").forEach((section, index) => { - observer.observe(section); - section.style.animationDelay = `${index * 0.2}s`; - }); - - createStarfield(); - typewriterEffect(); - particleEffectOnScroll(); - - let hovered = false; - const modTitle = document.querySelector("#moduleTitle"), - modules = modTitle.parentElement.querySelectorAll(".module"); - - modules.forEach((el) => { - el.addEventListener("mouseenter", () => el.classList.add("hovered")); - el.addEventListener("mouseleave", () => el.classList.remove("hovered")); - }); - - modTitle.addEventListener("mouseenter", async () => { - if (hovered) return; - hovered = true; - - for (const el of modules) { - el.classList.add("hovered"); - - // anim is .2 seconds - setTimeout(() => el.classList.remove("hovered"), 200); - - await new Promise((resolve) => setTimeout(resolve, 100)); - } - }); - - modTitle.addEventListener("mouseleave", () => (hovered = false)); +document.querySelectorAll(".section").forEach((section, index) => { + observer.observe(section); + section.style.animationDelay = `${index * 0.2}s`; }); + +createStarfield(); +typewriterEffect(); +particleEffectOnScroll(); + +let hovered = false; +const modTitle = document.querySelector("#moduleTitle"), + modules = modTitle.parentElement.querySelectorAll(".module"); + +modules.forEach((el) => { + el.addEventListener("mouseenter", () => el.classList.add("hovered")); + el.addEventListener("mouseleave", () => el.classList.remove("hovered")); +}); + +modTitle.addEventListener("mouseenter", async () => { + if (hovered) return; + hovered = true; + + for (const el of modules) { + el.classList.add("hovered"); + + // anim is .2 seconds + setTimeout(() => el.classList.remove("hovered"), 200); + + await new Promise((resolve) => setTimeout(resolve, 100)); + } +}); + +modTitle.addEventListener("mouseleave", () => (hovered = false)); diff --git a/JS/glitch.js b/JS/glitch.js new file mode 100644 index 0000000..5ea86a8 --- /dev/null +++ b/JS/glitch.js @@ -0,0 +1,134 @@ +async function triggerVirus() { + const stage1 = 3000; // 3 s red alert + const stage2 = 3000; // next 3 s data corruption + + const snapshot = await html2canvas(document.body); + const img = PIXI.Sprite.from(snapshot.toDataURL()); + + // wipe page & set black background + document.body.innerHTML = ""; + document.documentElement.style.cssText = + "background: black; margin: 0; padding: 0; overflow: hidden;"; + + // container for overlays/canvas + const container = document.createElement("div"); + container.id = "virusContainer"; + Object.assign(container.style, { + position: "fixed", top: 0, left: 0, + width: "100vw", height: "100vh", + display: "flex", alignItems: "center", + justifyContent: "center", flexDirection: "column", + color: "white", fontFamily: "monospace", + }); + document.body.appendChild(container); + + // -- stage 1: red alert + countdown -- + const alert = document.createElement("div"); + alert.id = "virusAlert"; + container.appendChild(alert); + + let countdown = 10; + alert.textContent = `⚠️ SYSTEM PURGE IN ${countdown} ⚠️`; + alert.style.cssText = "font-size: 3rem; color: #f00;"; + + const timerId = setInterval(() => { + countdown -= 1; + alert.textContent = `⚠️ SYSTEM PURGE IN ${countdown} ⚠️`; + // flash effect + alert.style.visibility = + alert.style.visibility === "hidden" ? "visible" : "hidden"; + }, 500); + + // after stage1 ms → stage 2 + setTimeout(() => { + clearInterval(timerId); + container.removeChild(alert); + + // -- stage 2: hex stream + shake/flicker -- + const hex = document.createElement("pre"); + hex.id = "virusHex"; + hex.style.cssText = "font-size:1rem; width:80vw; height:100vh; overflow:hidden;"; + container.appendChild(hex); + + // stream fake hex + const hexChars = "0123456789ABCDEF"; + const streamId = setInterval(() => { + let line = ""; + for (let i = 0; i < 64; i++) { + line += hexChars.charAt(Math.random() * 16 | 0); + } + hex.textContent += line + "\n"; + hex.scrollTop = hex.scrollHeight; + }, 50); + + document.body.classList.add("shake", "flicker"); + + setTimeout(() => { + console.debug("▶️ entering stage 3 (glitch filter)"); + + clearInterval(streamId); + container.removeChild(hex); + + // -- stage 3: pixi.js glitch filter on canvas -- + const canvas = document.createElement("canvas"); + canvas.id = "virusCanvas"; + + canvas.addEventListener('webglcontextlost', event => { + event.preventDefault(); // opt into manual recovery + console.warn('⚠️ my WebGL context was lost'); + }, false); + + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + + Object.assign(canvas.style, { + position: "fixed", top: 0, left: 0, + width: "100vw", height: "100vh", zIndex: 9999, + }); + + + container.appendChild(canvas); + + // initialize PixiJS application + const app = new PIXI.Application({ + view: canvas, + resizeTo: window, + resolution: 1, // force 1× device pixel ratio + autoDensity: true // keep CSS size but lower GPU size + }); + + app.renderer.view.addEventListener('webglcontextlost', (e) => { + e.preventDefault(); + console.warn('WebGL lost, falling back to CanvasRenderer'); + app.destroy(true, { children: true }); + }); + + + // Create a full-screen white rectangle as the sprite + img.width = window.innerWidth; + img.height = window.innerHeight; + app.stage.addChild(img); + + // apply realistic glitch filter + const filter = new PIXI.filters.GlitchFilter({ slices: 20, offset: 10 }); + app.stage.filters = [filter]; + + // animate the filter + app.ticker.add(() => { + filter.slices = 10 + Math.random() * 30; + filter.offset = Math.random() * 20; + }); + + console.log(app.renderer) + + // block all input + const block = (e) => { e.preventDefault(); e.stopImmediatePropagation(); }; + window.addEventListener("keydown", block, true); + window.addEventListener("mousedown", block, true); + window.addEventListener("touchstart", block, true); + + }, stage2); + }, stage1); + + return ""; +} diff --git a/pageMenu.js b/JS/pageMenu.js similarity index 100% rename from pageMenu.js rename to JS/pageMenu.js diff --git a/script.js b/JS/script.js similarity index 100% rename from script.js rename to JS/script.js diff --git a/terminal.js b/JS/terminal.js similarity index 59% rename from terminal.js rename to JS/terminal.js index 5b2b86d..bc0569e 100644 --- a/terminal.js +++ b/JS/terminal.js @@ -1,3 +1,27 @@ +const projectLinks = { + "bluesky-client": "https://github.com/ION606/bluesky-client", + "workout-app": "https://workout.ion606.com/", + "AI-overlord": "https://github.com/ION606/AI-overlord", + "black-hole-sim": "https://github.com/ION606/black-hole-sim", + "chatjs-main": "https://github.com/Proto-Chat/chatJS-main", + "custom_discordjs": "https://github.com/ION606/custom_discordjs", + "learn": "https://github.com/ION606/learn", + "ion-lang": "https://github.com/The-ION-Language/ION-Lang", + "vcs": "https://github.com/ION606/VCS", + "ml-pipeline": "https://github.com/ION606/ML-pipeline", + "browser-chromium": "https://github.com/ION606/browser-chromium", + "static-site-hosting": "https://github.com/ION606/static-site-hosting", + "procgen": "https://github.com/ION606/ProcGen", + "linkedin-api": "https://github.com/ION606/linkedin-api", + "github-to-fs": "https://github.com/ION606/github-to-fs", + "web-to-fish": "https://github.com/ION606/web-to-fish", + "commit_grabber": "https://github.com/ION606/commit_grabber", + "youtube-music-meta-extract": "https://github.com/ION606/youtube-music-meta-extract", + "mailpocket": "https://github.com/ION606/MailPocket", +}; + +const glitchText = 'T̵̙̻̭̤̺̱̥̖̤̭̗̜͓̓̈́̏͋̔̕̚͠h̴ͽ̳͎̳̱̘̎͛͆̓̐͑͛̈́̕̕͝͝é̷̛̮̥̲͇̊̅͋̏̊̅͊͝͝ ̵̡̛̪̮̦̘̘̼̼̺̪̪̋͋̀̌̇̉̋͌̾̿̓͝͝V̶̡̨̧̨̟̙̻͓̪͇̻̞̥͑̎͋͗̿́̓̌͒͊̈́́̚͠ơ̴̛̱̞̾̎̒̋̾̔̈́̓͑̋̉ȋ̴̡̛͔̙̘̝̙̬̠̹̙̻͖̽̿̓̑̈́͋́̐̕͠d̷̲̲̘̈́̑́̿̆̓̔͋́̓̋̅̏̚'; + // secret developer console toggle (using backtick key) const devConsoleToggle = () => { const devConsole = document.querySelector("#dev-console"); @@ -46,7 +70,7 @@ class TerminalFS { if (!cmdContent) { consoleOutput.innerHTML += `
🚨 Unknown command: \`${cmd}\`
`; } else if (cmdContent != true) { - consoleOutput.innerHTML += cmdContent; + consoleOutput.innerHTML += `
${cmdContent}
`; } } } @@ -97,12 +121,7 @@ class TerminalFS { }, "/projects": { type: "dir", - children: [ - "bluesky-client", - "workout-app", - "AI-overlord", - "black-hole-sim", - ], + children: Object.keys(projectLinks), }, "/fun": { type: "dir", @@ -120,59 +139,115 @@ class TerminalFS { this.files = { "/home/ion606/todo.txt": ` - 1. Take over the world - 2. Make coffee ☕ - 3. Fix CSS in production - 4. ???? - 5. PROFIT! - `, - "/fun/joke.txt": ` - Why do Java developers wear glasses? - Because they can't C#! - - (•_•) - ( •_•)>⌐■-■ - (⌐■_■) - `, - "/etc/motd": ` - WARNING: This system is powered by ✨imagination✨ - Unauthorized access will result in T̵̙̻̭̤̺̱̥̖̤̭̗̜͓͎̓̈́̏͋̔̕̚͠h̴̳͎̳̱̘̽̎͛͆̓̐͑͛̈́̕̕͝͝é̷̛̮̥̲͇̊̅͋̏̊̅͊͝͝ ̵̡̛̪̮̦̘̘̼̼̺̪̪̋͋̀̌̇̉̋͌̾̿̓͝͝V̶̡̨̧̨̟̙̻͓̪͇̻̞̥͑̎͋͗̿́̓̌͒͊̈́́̚͠ơ̴̛̱̞̾̎̒̋̾̔̈́̓͑̋̉ȋ̴̡̛̙̘̝̙̬̠̹̙̻͖̔̽̿̓͑̈́͋́̐̕͠d̷̲̲̘̈́̑́̿̆̓̔͋́̓̋̅̏̚ - `, +1. Take over the world +2. Make coffee ☕ +3. Fix CSS in production +4. ???? +5. PROFIT! +`, + "/home/ion606/resume.txt": ` +ION606 - Resume + +Skills: +- Programming: C, C++, Python, JavaScript, TypeScript, Rust, Go, Java, etc. +- Web: HTML, CSS, React, Vue, Express.js, Node.js, Flask, FastAPI +- ML: TensorFlow, scikit-learn +- Databases: MongoDB, PostgreSQL, MySQL, SQLite, Redis +- Tools: Git, Docker, Kubernetes, Vagrant, Electron, Next.js + +Contact: ion606@protonmail.com +`, "/home/ion606/.secret_config": ` - [disco_settings] - sparkle_level=9001 - rainbow_mode=enabled - pink_nodders: online - `, - "/fun/uwu.md": ` - # Nya~ Welcome to my secret docs! - - (´• ω •\`)ノ Here's some important stuff: - - Pet all the cats 🐈 - - Drink more water 💧 - - Remember to uwu-ify your code - `, - "/etc/joke_of_the_day": ` - Why do programmers prefer dark mode? - Because light attracts bugs! 🐛 - - How many programmers does it take to change a light bulb? - None, that's a hardware problem! - `, +[disco_settings] +sparkle_level=9001 +rainbow_mode=enabled +pink_nodders: online +`, "/home/ion606/diary.md": ` - Dear Diary, - - Today I discovered the Konami code activates a UFO. - Also, typing "make me a sandwich" works sometimes... - Note to self: Buy more coffee. - `, - "/home/ion606/resume": document - .querySelector("html") - .outerHTML.replace(/&/g, "&") - .replace(//g, ">") - .replace(/"/g, """) - .replace(/'/g, "'"), +Dear Diary, + +Today I discovered the Konami code activates a UFO. +Also, typing "make me a sandwich" works sometimes... +Note to self: Buy more coffee. +`, + "/fun/joke.txt": ` +Why do Java developers wear glasses? +Because they can't C#! + +(•_•) +( •_•)>⌐■-■ +(⌐■_■) +`, + "/fun/konami.seq": ` +↑ ↑ ↓ ↓ ← → ← → B A + +Hint: Try entering this sequence on the main page! +`, + "/fun/uwu.md": ` +# Nya~ Welcome to my secret docs! + +(´• ω •\`)ノ Here's some important stuff: +- Pet all the cats 🐈 +- Drink more water 💧 +- Remember to uwu-ify your code +`, + "/fun/hackerman.gif": ` +[Imagine a cool ASCII art of Hackerman here!] +You are now... HACKERMAN. +`, + "/projects/bluesky-client": ` +bluesky-client + +My Bluesky client. See: https://github.com/ION606/bluesky-client +`, + "/projects/workout-app": ` +ION Workout App + +An open source workout app! See: https://workout.ion606.com/ +`, + "/projects/AI-overlord": ` +AI Overlord + +A project to automate everything (and maybe take over the world). +`, + "/projects/black-hole-sim": ` +Black Hole Simulator + +A physics simulation of black holes and gravitational lensing. +`, + "/projects/virus.exe": ` +VIRUS.EXE + +WARNING: This file is highly suspicious. Running it may cause unexpected behavior! +`, + "/etc/motd": ` +WARNING: This system is powered by ✨imagination✨ +Unauthorized access will result in ${glitchText} +`, + "/etc/syslog": ` +[INFO] System booted successfully. +[INFO] User 'ion606' logged in. +[WARN] Too much imagination detected. +[INFO] All systems nominal. +`, + "/etc/joke_of_the_day": ` +Why do programmers prefer dark mode? +Because light attracts bugs! 🐛 + +How many programmers does it take to change a light bulb? +None, that's a hardware problem! +`, + "/sys/self-destruct.exe": ` +*** WARNING *** +You have attempted to access the self-destruct sequence. +This feature is disabled for your safety. +`, + "/sys/disco-bootloader": ` +Disco Bootloader v1.0 + +Initializing disco mode... +Boot sequence: 🕺💃🪩 +`, }; } @@ -257,15 +332,28 @@ class TerminalFS { "404: Humor not found... just kidding!", "This file is in another castle! 🍄", ]; - return ( - `${jokes[Math.floor(Math.random() * jokes.length)]}\n` + - ` ╚═(███)═╝\n` + - ` ╚═(███)═╝\n` + - ` ╚═(███)═╝\n` + - ` ██╚═╝██\n` + - ` ███████\n` + - ` ███████` - ); + const asciiArts = [ + ` +
+         .--.
+        |o_o |
+        |:_/ |
+       //   \\ \\
+      (|     | )
+     /'\\_   _/\\\`
+     \\___)=(___/
+
+`, + ` +
+      (╯°□°)╯︵ ┻━┻
+
+` + ]; + + const joke = jokes[Math.floor(Math.random() * jokes.length)], + art = asciiArts[Math.floor(Math.random() * asciiArts.length)]; + return `
${joke}
${art}`; } return `
${this.files[absPath].trim()}
`; @@ -284,6 +372,7 @@ class TerminalFS {
  • starfield - Regenerate stars
  • random - Activate random color chaos!
  • secret - Activate disco mode!
  • +
  • run [file] - Run a file (e.g., .exe)
  • `, exit: devConsoleToggle, @@ -342,6 +431,38 @@ class TerminalFS { document.body.classList.toggle("disco-mode"); return "🎆 Disco mode activated!"; }, + + run: (filePath) => { + const absPath = terminalFS.resolvePath(filePath.trim()); + console.log(absPath, filePath); + + // Project links + if ( + absPath.startsWith("/projects/") && + projectLinks[filePath.replace("/projects/", "")] + ) { + window.open(projectLinks[filePath], "_blank"); + return `🚀 Opening project: ${projectLinks[filePath]}`; + } + + // Multi-stage "virus.exe" + if (absPath === "/projects/virus.exe") { + triggerVirus() + setTimeout(1000, () => { + const el = document.querySelector('.consoleout').lastChild; + el.textContent = glitchText; + }) + return "Error running " + } + + if (absPath === "/sys/self-destruct.exe") { + return `💥 Self-destruct is disabled for your safety.`; + } + if (absPath.endsWith(".exe")) { + return `🛑 Cannot execute: ${filePath}`; + } + return `Nothing to run for: ${filePath}`; + }, }; } diff --git a/README.html b/README.html index 1e9819d..07d56f9 100644 --- a/README.html +++ b/README.html @@ -7,7 +7,30 @@ - + + + + + + + + + + + + @@ -604,8 +627,5 @@
    - - - diff --git a/index.html b/index.html index 6dc5955..abfa1dd 100644 --- a/index.html +++ b/index.html @@ -1,38 +1,45 @@ + + + + + + + + + + - - - - - - - - - - + Home - ION606.com + - Home - ION606.com - + + + - - - + + + - - - - - -
    -
    -

    Welcome to my Personal Website!

    -

    My (user)name's ION606, feel free to looks at my stuff

    - - - -
    -
    - - - \ No newline at end of file + +
    +
    +

    Welcome to my Personal Website!

    +

    My (user)name's ION606, feel free to looks at my stuff

    + + + +
    +
    + + diff --git a/links.html b/links.html index b9e2c66..4e9c13d 100644 --- a/links.html +++ b/links.html @@ -1,70 +1,87 @@ + + + + + + + + + Links - ION606.com - - - - - - - - - Links - ION606.com + - + + - // Create a new ripple every 2 seconds - setInterval(createRipple, 2000); - }); - - - - - - -
    -
    -
    -
    -
    -
    -
    - - - \ No newline at end of file + + +
    +
    +
    +
    +
    +
    +
    + + diff --git a/projects.html b/projects.html index dfafc4b..4a05360 100644 --- a/projects.html +++ b/projects.html @@ -17,13 +17,13 @@ href="https://avatars.githubusercontent.com/u/58801387" type="image/jpeg" /> - - + + - +