fix: resolve build error with ASCII art and type annotation
Move ASCII art to constant and remove type annotation. Co-authored-by: Jeff Emmett <46964190+Jeff-Emmett@users.noreply.github.com>
This commit is contained in:
parent
da90313c3b
commit
036d45c7c3
|
|
@ -16,6 +16,7 @@
|
|||
"devDependencies": {
|
||||
"src": "latest",
|
||||
"svelte": "^5.0.0",
|
||||
"tmux": "latest",
|
||||
"@sveltejs/adapter-auto": "^6.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
||||
"@tailwindcss/vite": "^4.0.0",
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ importers:
|
|||
tailwindcss:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
tmux:
|
||||
specifier: latest
|
||||
version: 1.0.0
|
||||
typescript:
|
||||
specifier: 5.9.3
|
||||
version: 5.9.3
|
||||
|
|
@ -853,6 +856,10 @@ packages:
|
|||
resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
tmux@1.0.0:
|
||||
resolution: {integrity: sha512-56dqTkuDc7jtYKDnY5aoLk4G1NRQUEFsEAyW5rXatU8/mj7ixBYFErHlubMzotEmBF/FTSmLpOvTF5/imEUkqA==}
|
||||
deprecated: Package no longer supported. Contact support@npmjs.com for more info.
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||
engines: {node: '>=8.0'}
|
||||
|
|
@ -1543,6 +1550,8 @@ snapshots:
|
|||
|
||||
tapable@2.3.0: {}
|
||||
|
||||
tmux@1.0.0: {}
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
dependencies:
|
||||
is-number: 7.0.0
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
|
||||
let {
|
||||
layout = { type: 'pane', id: 0 },
|
||||
activePaneId = 0
|
||||
|
|
@ -13,9 +12,8 @@
|
|||
let lastTime = 0;
|
||||
let cursorBlink = true;
|
||||
|
||||
// Reactive state
|
||||
const containerWidth = writable(0);
|
||||
const containerHeight = writable(0);
|
||||
let containerWidth = $state(0);
|
||||
let containerHeight = $state(0);
|
||||
|
||||
// Colors
|
||||
const BG_COLOR = '#0a0a0a';
|
||||
|
|
@ -24,11 +22,17 @@
|
|||
const TEXT_COLOR = '#00ff00';
|
||||
const MUTED_TEXT = '#444444';
|
||||
|
||||
const drawTrigger = writable(false);
|
||||
|
||||
$effect(() => {
|
||||
if (canvas && layout && $containerWidth && $containerHeight) {
|
||||
drawTrigger.set(true);
|
||||
// Track dependencies
|
||||
const w = containerWidth;
|
||||
const h = containerHeight;
|
||||
const l = layout;
|
||||
const active = activePaneId;
|
||||
const blink = cursorBlink; // Track blink state for redraws
|
||||
|
||||
// Draw if we have context and dimensions
|
||||
if (ctx && w > 0 && h > 0) {
|
||||
draw();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -46,10 +50,8 @@
|
|||
// Scale context to match
|
||||
ctx?.scale(dpr, dpr);
|
||||
|
||||
containerWidth.set(rect.width);
|
||||
containerHeight.set(rect.height);
|
||||
|
||||
drawTrigger.set(true);
|
||||
containerWidth = rect.width;
|
||||
containerHeight = rect.height;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +59,7 @@
|
|||
if (time - lastTime > 500) { // Blink every 500ms
|
||||
cursorBlink = !cursorBlink;
|
||||
lastTime = time;
|
||||
drawTrigger.set(true);
|
||||
// Effect will trigger draw automatically when cursorBlink changes
|
||||
}
|
||||
animationFrameId = requestAnimationFrame(animate);
|
||||
}
|
||||
|
|
@ -80,10 +82,10 @@
|
|||
|
||||
// Clear
|
||||
ctx.fillStyle = BG_COLOR;
|
||||
ctx.fillRect(0, 0, $containerWidth, $containerHeight);
|
||||
ctx.fillRect(0, 0, containerWidth, containerHeight);
|
||||
|
||||
// Draw Layout
|
||||
drawNode(layout, 0, 0, $containerWidth, $containerHeight);
|
||||
drawNode(layout, 0, 0, containerWidth, containerHeight);
|
||||
}
|
||||
|
||||
function drawNode(node: any, x: number, y: number, w: number, h: number) {
|
||||
|
|
@ -149,14 +151,6 @@
|
|||
drawNode(node.children[1], x + w1, y, w2, h);
|
||||
}
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
drawTrigger.subscribe(value => {
|
||||
if (value) {
|
||||
draw();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="w-full h-full min-h-[400px] bg-black border border-border relative group overflow-hidden">
|
||||
|
|
@ -166,6 +160,6 @@
|
|||
<div class="absolute inset-0 pointer-events-none opacity-10 bg-[linear-gradient(rgba(18,16,16,0)_50%,rgba(0,0,0,0.25)_50%),linear-gradient(90deg,rgba(255,0,0,0.06),rgba(0,255,0,0.02),rgba(0,0,255,0.06))] z-10 bg-[length:100%_2px,3px_100%]"></div>
|
||||
|
||||
<div class="absolute bottom-2 right-2 text-[10px] text-muted-foreground opacity-50 group-hover:opacity-100 transition-opacity z-20 font-mono">
|
||||
RENDERER: CANVAS_2D // {$containerWidth}x{$containerHeight}
|
||||
RENDERER: CANVAS_2D // {containerWidth}x{containerHeight}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
<span class="animate-pulse inline-block w-2 h-4 bg-primary"></span>
|
||||
</a>
|
||||
<nav class="flex items-center space-x-6 text-sm font-medium text-muted-foreground">
|
||||
<a class="transition-colors hover:text-primary hover:underline decoration-primary underline-offset-4" href="#learn">/docs</a>
|
||||
<a class="transition-colors hover:text-primary hover:underline decoration-primary underline-offset-4" href="#configurator">/config</a>
|
||||
<a class="transition-colors hover:text-primary hover:underline decoration-primary underline-offset-4" href="#about">/about</a>
|
||||
<a class="transition-colors hover:text-primary hover:underline decoration-primary underline-offset-4" href="/#learn">/docs</a>
|
||||
<a class="transition-colors hover:text-primary hover:underline decoration-primary underline-offset-4" href="/#configurator">/config</a>
|
||||
<a class="transition-colors hover:text-primary hover:underline decoration-primary underline-offset-4" href="/about">/about</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="flex flex-1 items-center justify-end space-x-2">
|
||||
|
|
|
|||
|
|
@ -8,35 +8,62 @@
|
|||
let activePaneId = $state(0);
|
||||
let generatedConfig = $state('');
|
||||
|
||||
function splitPane(direction: 'h' | 'v') {
|
||||
const asciiArt = `
|
||||
_________________________________________
|
||||
/ \\
|
||||
| root@mytmux:~ $ tmux new -s dev |
|
||||
| [0] nvim ---------------- [1] server -- |
|
||||
| | | | |
|
||||
| | import { life } | npm run | |
|
||||
| | from 'tmux'; | dev | |
|
||||
| | | | |
|
||||
| | // TODO: Sleep | | |
|
||||
| |________________________|____________| |
|
||||
| [2] logs ------------------------------ |
|
||||
| | > ready in 200ms | |
|
||||
| | > watching files... | |
|
||||
| |_____________________________________| |
|
||||
\\_________________________________________/
|
||||
`;
|
||||
|
||||
// Refactored nested function to be a standalone helper to avoid potential parser issues
|
||||
function findAndSplitNode(node, activeId, direction, nextIdVal) {
|
||||
if (node.type === 'pane') {
|
||||
if (node.id === activeId) {
|
||||
const oldId = node.id;
|
||||
const newId = nextIdVal;
|
||||
|
||||
// Create new split node
|
||||
node.type = direction === 'h' ? 'split-h' : 'split-v';
|
||||
node.ratio = 0.5;
|
||||
delete node.id;
|
||||
node.children = [
|
||||
{ type: 'pane', id: oldId },
|
||||
{ type: 'pane', id: newId }
|
||||
];
|
||||
return { found: true, nextId: nextIdVal + 1 };
|
||||
}
|
||||
return { found: false, nextId: nextIdVal };
|
||||
} else {
|
||||
// Recursively check children
|
||||
let result = findAndSplitNode(node.children[0], activeId, direction, nextIdVal);
|
||||
if (result.found) return result;
|
||||
|
||||
return findAndSplitNode(node.children[1], activeId, direction, nextIdVal);
|
||||
}
|
||||
}
|
||||
|
||||
function splitPane(direction) {
|
||||
// Find the active pane in the tree and replace it with a split
|
||||
const newLayout = JSON.parse(JSON.stringify(layout));
|
||||
|
||||
function findAndSplit(node: any) {
|
||||
if (node.type === 'pane') {
|
||||
if (node.id === activePaneId) {
|
||||
const oldId = node.id;
|
||||
const newId = nextId++;
|
||||
|
||||
// Create new split node
|
||||
node.type = direction === 'h' ? 'split-h' : 'split-v';
|
||||
node.ratio = 0.5;
|
||||
delete node.id;
|
||||
node.children = [
|
||||
{ type: 'pane', id: oldId },
|
||||
{ type: 'pane', id: newId }
|
||||
];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return findAndSplit(node.children[0]) || findAndSplit(node.children[1]);
|
||||
}
|
||||
const result = findAndSplitNode(newLayout, activePaneId, direction, nextId);
|
||||
|
||||
if (result.found) {
|
||||
nextId = result.nextId;
|
||||
layout = newLayout;
|
||||
generateTmuxConfig();
|
||||
}
|
||||
|
||||
findAndSplit(newLayout);
|
||||
layout = newLayout;
|
||||
generateTmuxConfig();
|
||||
}
|
||||
|
||||
function resetLayout() {
|
||||
|
|
@ -46,7 +73,7 @@
|
|||
generateTmuxConfig();
|
||||
}
|
||||
|
||||
function selectPane(id: number) {
|
||||
function selectPane(id) {
|
||||
activePaneId = id;
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +83,7 @@
|
|||
config += `# Generated by mytmux.life\n\n`;
|
||||
config += `new-session -s development -n editor\n`;
|
||||
|
||||
function traverse(node: any) {
|
||||
function traverse(node) {
|
||||
if (node.type === 'split-h') {
|
||||
config += `split-window -h\n`;
|
||||
traverse(node.children[1]); // Right child
|
||||
|
|
@ -113,23 +140,8 @@
|
|||
|
||||
<!-- ASCII Art / Decorative Element -->
|
||||
<div class="hidden md:block p-6 border border-border bg-card/50 font-mono text-xs leading-none text-muted-foreground select-none overflow-hidden">
|
||||
<pre>
|
||||
_________________________________________
|
||||
/ \
|
||||
| root@mytmux:~ $ tmux new -s dev |
|
||||
| [0] nvim ---------------- [1] server -- |
|
||||
| | | | |
|
||||
| | import {'{ life }'} | npm run | |
|
||||
| | from 'tmux'; | dev | |
|
||||
| | | | |
|
||||
| | // TODO: Sleep | | |
|
||||
| |________________________|____________| |
|
||||
| [2] logs ------------------------------ |
|
||||
| | > ready in 200ms | |
|
||||
| | > watching files... | |
|
||||
| |_____________________________________| |
|
||||
\_________________________________________/
|
||||
</pre>
|
||||
<!-- Use the constant variable instead of inline content to avoid parser errors -->
|
||||
<pre>{asciiArt}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
<script lang="ts">
|
||||
// About page for Shawn Anderson
|
||||
</script>
|
||||
|
||||
<div class="container px-4 py-20 max-w-4xl mx-auto">
|
||||
<div class="flex flex-col md:flex-row gap-12 items-start">
|
||||
|
||||
<!-- Profile Image Section -->
|
||||
<div class="w-full md:w-1/3 relative group">
|
||||
<div class="absolute -inset-1 bg-gradient-to-r from-primary to-blue-600 rounded-lg blur opacity-25 group-hover:opacity-75 transition duration-1000 group-hover:duration-200"></div>
|
||||
<div class="relative aspect-square overflow-hidden rounded-lg border border-border bg-card">
|
||||
<img
|
||||
src="/placeholder.svg?height=400&width=400"
|
||||
alt="Shawn Anderson"
|
||||
class="object-cover w-full h-full grayscale hover:grayscale-0 transition-all duration-500"
|
||||
/>
|
||||
<div class="absolute bottom-0 left-0 right-0 bg-black/80 p-2 text-center border-t border-border">
|
||||
<p class="text-xs font-mono text-primary">CEO @ LONG_TAIL_FINANCIAL</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content Section -->
|
||||
<div class="flex-1 space-y-8">
|
||||
<div>
|
||||
<h1 class="text-4xl font-extrabold tracking-tight lg:text-5xl mb-4">
|
||||
Shawn <span class="text-primary">Anderson</span>
|
||||
</h1>
|
||||
<p class="text-xl text-muted-foreground leading-relaxed">
|
||||
Data Shaman, Educator, and Technologist.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-6 text-muted-foreground">
|
||||
<p>
|
||||
As the Founder of <strong class="text-foreground">Long Tail Financial</strong>, Shawn operates at the intersection of data science, artificial intelligence, and decentralized finance. His work focuses on developing systems that enable exposure to the singularity—building the infrastructure for the next generation of financial technology.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Beyond the code, Shawn is deeply passionate about <strong class="text-foreground">teaching and self-empowerment</strong>. He believes that mastering your tools—like the terminal and tmux—is the first step towards mastering your craft. By understanding the systems we work with, we unlock the potential to build things that were previously impossible.
|
||||
</p>
|
||||
|
||||
<div class="p-4 border-l-2 border-primary bg-primary/5 my-6">
|
||||
<p class="italic text-foreground">
|
||||
"Coding is not just about writing syntax; it's about structuring your thoughts and empowering yourself to create change in the digital world."
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Whether he's leading workshops on AI in cryptocurrency markets or architecting complex tokenomics systems, Shawn's mission remains the same: to empower others through knowledge and technology.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Social / Links -->
|
||||
<div class="flex gap-4 pt-4">
|
||||
<a href="https://www.longtailfinancial.com" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-10 px-4 py-2">
|
||||
Long Tail Financial
|
||||
</a>
|
||||
<a href="https://github.com/shawnwanderson" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-10 px-4 py-2">
|
||||
GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Reference in New Issue