File Explorer

/proc/2/root/proc/4/cwd/_ssr

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

0 dirs
9 files
routes-BaK3zTFM.mjs44.0 KB · 1251 lines
import { i as __toESM } from "../_runtime.mjs";import { P as require_react, g as require_jsx_runtime, h as useRouter, m as Link } from "../_libs/@tanstack/react-router+[...].mjs";import { n as createServerFn } from "./ssr.mjs";import { C as Check, S as ChevronRight, T as ArrowLeft, _ as FileImage, a as RotateCw, b as CornerLeftUp, c as Info, d as Folder, f as FolderOpen, g as FileLock2, h as FileTerminal, i as Save, l as Hash, m as FileText, n as SquareTerminal, o as Pencil, p as FileType, r as Search, s as Lock, t as X, u as HardDrive, v as FileCode, w as Braces, x as Copy, y as FileCog } from "../_libs/lucide-react.mjs";import { n as createSsrRpc, t as Route } from "./routes-CPlVcNZL.mjs";//#region node_modules/.nitro/vite/services/ssr/assets/routes-BaK3zTFM.jsvar import_react = /* @__PURE__ */ __toESM(require_react());var import_jsx_runtime = require_jsx_runtime();var runCommand = createServerFn({ method: "POST" }).validator((d) => d).handler(createSsrRpc("43655b12b2525448f49cc143e8e0a1f9d366816530f47cde443331fced610278"));var saveFile = createServerFn({ method: "POST" }).validator((d) => d).handler(createSsrRpc("3e9ad7efb5ff1b6ad57a93cc9f3882a022f3d539053d163dfd6fb95a332c1f69"));var MAP = {	js: FileCode,	jsx: FileCode,	mjs: FileCode,	cjs: FileCode,	ts: FileCode,	tsx: FileCode,	mts: FileCode,	cts: FileCode,	py: FileCode,	rb: FileCode,	go: FileCode,	rs: FileCode,	java: FileCode,	kt: FileCode,	c: FileCode,	h: FileCode,	cpp: FileCode,	cc: FileCode,	hpp: FileCode,	cs: FileCode,	php: FileCode,	swift: FileCode,	lua: FileCode,	dart: FileCode,	vue: FileCode,	svelte: FileCode,	astro: FileCode,	html: FileCode,	htm: FileCode,	css: FileCode,	scss: FileCode,	sass: FileCode,	less: FileCode,	xml: FileCode,	sql: FileCode,	graphql: FileCode,	gql: FileCode,	ex: FileCode,	exs: FileCode,	scala: FileCode,	json: Braces,	jsonc: Braces,	yml: Braces,	yaml: Braces,	toml: Braces,	csv: FileType,	tsv: FileType,	sh: FileTerminal,	bash: FileTerminal,	zsh: FileTerminal,	fish: FileTerminal,	env: FileCog,	ini: FileCog,	cfg: FileCog,	conf: FileCog,	cnf: FileCog,	properties: FileCog,	gitignore: FileCog,	editorconfig: FileCog,	dockerfile: FileCog,	makefile: FileCog,	service: FileCog,	rules: FileCog,	pem: FileLock2,	crt: FileLock2,	key: FileLock2,	pub: FileLock2,	md: FileText,	markdown: FileText,	mdx: FileText,	txt: FileText,	log: FileText,	lock: FileText,	list: FileText,	png: FileImage,	jpg: FileImage,	jpeg: FileImage,	gif: FileImage,	webp: FileImage,	svg: FileImage,	ico: FileImage,	bmp: FileImage,	avif: FileImage};function FileGlyph({ type, ext, className }) {	if (type === "dir") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Folder, {		className,		strokeWidth: 1.6	});	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MAP[ext] ?? (ext ? Hash : FileText), {		className,		strokeWidth: 1.6	});}var CODE_RULES = [	{		type: "comment",		re: /^\/\*[\s\S]*?\*\//	},	{		type: "comment",		re: /^\/\/[^\n]*/	},	{		type: "comment",		re: /^#[^\n]*/	},	{		type: "string",		re: /^`(?:\\.|[^`\\])*`/	},	{		type: "string",		re: /^"(?:\\.|[^"\\])*"/	},	{		type: "string",		re: /^'(?:\\.|[^'\\])*'/	},	{		type: "number",		re: /^\b\d[\d_]*(?:\.\d+)?(?:[eE][+-]?\d+)?\b/	},	{		type: "keyword",		re: new RegExp(`\\b(${[			"const",			"let",			"var",			"function",			"return",			"if",			"else",			"for",			"while",			"do",			"switch",			"case",			"break",			"continue",			"new",			"class",			"extends",			"import",			"export",			"from",			"default",			"async",			"await",			"yield",			"try",			"catch",			"finally",			"throw",			"typeof",			"instanceof",			"in",			"of",			"void",			"delete",			"this",			"super",			"static",			"get",			"set",			"public",			"private",			"protected",			"readonly",			"interface",			"type",			"enum",			"namespace",			"implements",			"as",			"is",			"keyof",			"true",			"false",			"null",			"undefined",			"def",			"elif",			"lambda",			"pass",			"with",			"and",			"or",			"not",			"None",			"True",			"False",			"self",			"fn",			"let",			"mut",			"pub",			"struct",			"impl",			"match",			"use",			"mod",			"package",			"func",			"go",			"defer",			"chan",			"map",			"string",			"int",			"bool",			"float",			"double",			"char",			"long",			"short",			"select",			"insert",			"update",			"delete",			"where",			"join",			"values"		].join("|")})\\b`)	},	{		type: "func",		re: /^[A-Za-z_$][\w$]*(?=\s*\()/	},	{		type: "punct",		re: /^[{}()[\];,.:?=<>+\-*/%&|!~^]+/	}];function tokenizeCode(src) {	const out = [];	let i = 0;	let buf = "";	const flush = () => {		if (buf) {			out.push({				type: "plain",				value: buf			});			buf = "";		}	};	while (i < src.length) {		const rest = src.slice(i);		let matched = false;		for (const rule of CODE_RULES) {			const m = rule.re.exec(rest);			if (m && m.index === 0 && m[0].length > 0) {				flush();				out.push({					type: rule.type,					value: m[0]				});				i += m[0].length;				matched = true;				break;			}		}		if (!matched) {			buf += src[i];			i++;		}	}	flush();	return out;}function tokenizeMarkup(src) {	const out = [];	const re = /(<!--[\s\S]*?-->)|(<\/?[A-Za-z][\w:-]*)|([A-Za-z_:][\w:.-]*)(?==)|("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')|(>)/g;	let last = 0;	let m;	while (m = re.exec(src)) {		if (m.index > last) out.push({			type: "plain",			value: src.slice(last, m.index)		});		if (m[1]) out.push({			type: "comment",			value: m[1]		});		else if (m[2]) out.push({			type: "tag",			value: m[2]		});		else if (m[3]) out.push({			type: "attr",			value: m[3]		});		else if (m[4]) out.push({			type: "string",			value: m[4]		});		else if (m[5]) out.push({			type: "tag",			value: m[5]		});		last = re.lastIndex;	}	if (last < src.length) out.push({		type: "plain",		value: src.slice(last)	});	return out;}function tokenizeJson(src) {	const out = [];	const re = /("(?:\\.|[^"\\])*")(\s*:)?|(\b-?\d[\d.eE+-]*\b)|(\btrue\b|\bfalse\b|\bnull\b)|([{}[\],:])/g;	let last = 0;	let m;	while (m = re.exec(src)) {		if (m.index > last) out.push({			type: "plain",			value: src.slice(last, m.index)		});		if (m[1]) {			out.push({				type: m[2] ? "key" : "string",				value: m[1]			});			if (m[2]) out.push({				type: "punct",				value: m[2]			});		} else if (m[3]) out.push({			type: "number",			value: m[3]		});		else if (m[4]) out.push({			type: "keyword",			value: m[4]		});		else if (m[5]) out.push({			type: "punct",			value: m[5]		});		last = re.lastIndex;	}	if (last < src.length) out.push({		type: "plain",		value: src.slice(last)	});	return out;}var COLOR = {	plain: "text-[#c9d3e3]",	comment: "text-[#5b6577] italic",	string: "text-[#9ece9a]",	number: "text-[#d4af37]",	keyword: "text-[#8b95f6]",	func: "text-[#7fb4e8]",	punct: "text-[#7c879b]",	tag: "text-[#8b95f6]",	attr: "text-[#d4af37]",	key: "text-[#7fb4e8]"};var MARKUP_EXTS = new Set([	"html",	"htm",	"xml",	"svg",	"vue",	"svelte",	"astro"]);var JSON_EXTS = new Set(["json", "jsonc"]);var PLAIN_EXTS = new Set([	"txt",	"log",	"csv",	"tsv",	"md",	"markdown",	"mdx",	"env"]);function highlight(code, ext) {	if (PLAIN_EXTS.has(ext)) return code;	let tokens;	if (JSON_EXTS.has(ext)) tokens = tokenizeJson(code);	else if (MARKUP_EXTS.has(ext)) tokens = tokenizeMarkup(code);	else tokens = tokenizeCode(code);	return tokens.map((t, idx) => t.type === "plain" ? t.value : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {		className: COLOR[t.type],		children: t.value	}, idx));}function formatBytes(n) {	if (n <= 0) return "0 B";	const units = [		"B",		"KB",		"MB",		"GB",		"TB"	];	const i = Math.min(Math.floor(Math.log(n) / Math.log(1024)), units.length - 1);	const v = n / Math.pow(1024, i);	return `${i === 0 ? String(n) : v.toFixed(v >= 100 || v === Math.floor(v) ? 0 : 1)} ${units[i]}`;}function joinRel(dir, name) {	return dir ? `${dir}/${name}` : name;}function parentRel(relPath) {	if (!relPath) return "";	const parts = relPath.split("/").filter(Boolean);	parts.pop();	return parts.join("/");}function cn(...inputs) {	return inputs.filter(Boolean).join(" ");}function Explorer() {	const { list, file, env } = Route.useLoaderData();	const router = useRouter();	const [query, setQuery] = (0, import_react.useState)("");	const [termOpen, setTermOpen] = (0, import_react.useState)(false);	const [noticeDismissed, setNoticeDismissed] = (0, import_react.useState)(false);	(0, import_react.useEffect)(() => {		setQuery("");	}, [list.relPath]);	const filtered = (0, import_react.useMemo)(() => {		const q = query.trim().toLowerCase();		if (!q) return list.entries;		return list.entries.filter((e) => e.name.toLowerCase().includes(q));	}, [list.entries, query]);	const atRoot = list.relPath === "";	const dirCount = list.entries.filter((e) => e.type === "dir").length;	const fileCount = list.entries.length - dirCount;	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {		className: "mx-auto flex min-h-dvh w-full max-w-3xl flex-col px-4 pb-[max(5.5rem,calc(env(safe-area-inset-bottom)+5rem))] pt-[max(1.25rem,env(safe-area-inset-top))] sm:px-6",		children: [			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Header, {				relPath: list.relPath,				onRefresh: () => router.invalidate()			}),			!env.workspaceUser && !noticeDismissed && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {				className: "mt-3 flex items-start gap-2.5 rounded-xl border border-[var(--gold)]/25 bg-[var(--gold-soft)] px-3.5 py-3",				children: [					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Info, {						className: "mt-0.5 size-4 shrink-0 text-[var(--gold)]",						"aria-hidden": "true"					}),					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {						className: "min-w-0 flex-1",						children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {							className: "text-[13px] leading-snug text-[var(--ink)]",							children: [								"This explorer reads the filesystem of the server it runs on, so",								" ",								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {									className: "font-mono text-[12px]",									children: "/workspace/user"								}),								" isn't present here. Browsing and the terminal still work against this server's own disk from",								" ",								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {									className: "font-mono text-[12px]",									children: "/"								}),								"."							]						})					}),					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {						type: "button",						onClick: () => setNoticeDismissed(true),						"aria-label": "Dismiss notice",						className: "grid size-6 shrink-0 place-items-center rounded-lg text-[var(--gold)]/80 transition-colors hover:bg-white/5 hover:text-[var(--gold)] active:scale-[0.95]",						style: { touchAction: "manipulation" },						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-3.5" })					})				]			}),			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Breadcrumbs, {				segments: list.segments,				atRoot			}),			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Toolbar, {				atRoot,				parentPath: parentRel(list.relPath),				dirCount,				fileCount,				query,				onQuery: setQuery			}),			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {				className: "mt-3 flex-1",				children: list.error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Notice, {					icon: list.error === "Permission denied" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Lock, { className: "size-5" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-5" }),					title: list.error,					body: list.error === "Permission denied" ? "This location can't be read in the current environment." : "This path could not be opened."				}) : filtered.length === 0 ? query ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Notice, {					icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Search, { className: "size-5" }),					title: "No matches",					body: `Nothing here matches "${query}".`				}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Notice, {					icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FolderOpen, { className: "size-5" }),					title: "Empty folder",					body: "There's nothing inside this directory."				}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {					className: "overflow-hidden rounded-2xl border border-[var(--edge)] bg-[var(--panel)]",					children: filtered.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EntryRow, {						entry,						dir: list.relPath,						first: i === 0					}, entry.name))				})			}),			file ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Viewer, {				file,				dirPath: list.relPath			}) : null,			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {				type: "button",				onClick: () => setTermOpen(true),				className: "fixed bottom-[max(1rem,env(safe-area-inset-bottom))] left-1/2 z-30 flex -translate-x-1/2 items-center gap-2 rounded-full border border-[var(--edge-strong)] bg-[var(--bg-bottom)]/95 px-4 py-2.5 text-[13px] font-medium text-[var(--ink)] shadow-[0_10px_30px_-8px_rgba(0,0,0,0.8)] backdrop-blur transition-colors hover:border-[var(--indigo)]/50 hover:bg-[var(--panel-hover)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--indigo)] active:scale-[0.97]",				style: { touchAction: "manipulation" },				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SquareTerminal, { className: "size-4 text-[var(--indigo)]" }), "Terminal"]			}),			termOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Terminal, {				cwd: list.relPath,				onClose: () => setTermOpen(false)			}) : null		]	});}function Header({ relPath, onRefresh }) {	const here = relPath ? "/" + relPath : "/";	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {		className: "flex items-start justify-between gap-4",		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {			className: "flex min-w-0 flex-col gap-1",			children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {				className: "flex items-center gap-2",				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {					className: "grid size-6 place-items-center rounded-md bg-[var(--indigo-soft)] text-[var(--indigo)]",					"aria-hidden": "true",					children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HardDrive, {						className: "size-3.5",						strokeWidth: 2					})				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {					className: "text-[15px] font-medium tracking-tight text-[var(--ink)]",					children: "File Explorer"				})]			}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {				className: "truncate font-mono text-[11px] text-[var(--muted)]",				title: here,				dir: "rtl",				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("bdi", { children: here })			})]		}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {			type: "button",			onClick: onRefresh,			"aria-label": "Refresh this folder",			className: "grid size-9 shrink-0 place-items-center rounded-xl border border-[var(--edge)] bg-[var(--panel)] text-[var(--muted)] shadow-xs transition-colors hover:border-[var(--edge-strong)] hover:bg-[var(--panel-hover)] hover:text-[var(--ink)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--indigo)] active:scale-[0.97]",			style: { touchAction: "manipulation" },			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RotateCw, { className: "size-4" })		})]	});}function Breadcrumbs({ segments, atRoot }) {	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("nav", {		"aria-label": "Breadcrumb",		className: "-mx-1 mt-4 flex items-center gap-1 overflow-x-auto px-1 py-1",		style: { scrollbarWidth: "none" },		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Crumb, {			to: "",			label: "root",			isRoot: true,			active: atRoot		}), segments.map((seg, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {			className: "flex shrink-0 items-center gap-1",			children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, {				className: "size-3.5 shrink-0 text-[var(--muted)]/60",				"aria-hidden": "true"			}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Crumb, {				to: seg.relPath,				label: seg.name,				active: i === segments.length - 1			})]		}, seg.relPath))]	});}function Crumb({ to, label, active, isRoot }) {	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {		to: "/",		search: to ? { path: to } : {},		className: cn("shrink-0 rounded-lg px-2 py-1 text-[12.5px] font-medium transition-colors active:scale-[0.97]", isRoot && "font-mono", active ? "bg-[var(--gold-soft)] text-[var(--gold)]" : "text-[var(--muted)] hover:bg-[var(--panel-hover)] hover:text-[var(--ink)]"),		style: { touchAction: "manipulation" },		children: isRoot ? "/" : label	});}function Toolbar({ atRoot, parentPath, dirCount, fileCount, query, onQuery }) {	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {		className: "mt-3 flex items-center gap-2",		children: [			atRoot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {				className: "grid size-10 shrink-0 place-items-center rounded-xl border border-[var(--edge)]/60 text-[var(--muted)]/40",				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CornerLeftUp, {					className: "size-4",					"aria-hidden": "true"				})			}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {				to: "/",				search: parentPath ? { path: parentPath } : {},				"aria-label": "Go up one folder",				className: "grid size-10 shrink-0 place-items-center rounded-xl border border-[var(--edge)] bg-[var(--panel)] text-[var(--ink)] shadow-xs transition-colors hover:border-[var(--edge-strong)] hover:bg-[var(--panel-hover)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--indigo)] active:scale-[0.97]",				style: { touchAction: "manipulation" },				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowLeft, { className: "size-4" })			}),			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {				className: "relative flex-1",				children: [					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Search, {						className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-[var(--muted)]",						"aria-hidden": "true"					}),					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {						type: "text",						inputMode: "search",						value: query,						onChange: (e) => onQuery(e.target.value),						placeholder: "Filter this folder…",						"aria-label": "Filter items in this folder",						autoCorrect: "off",						autoCapitalize: "off",						spellCheck: false,						className: "h-10 w-full rounded-xl border border-[var(--edge)] bg-[var(--panel)] pl-9 pr-9 text-[15px] text-[var(--ink)] shadow-xs outline-none transition-colors placeholder:text-[var(--muted)] focus:border-[var(--indigo)]/60 focus:bg-[var(--panel-hover)]",						style: { touchAction: "manipulation" }					}),					query && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {						type: "button",						onClick: () => onQuery(""),						"aria-label": "Clear filter",						className: "absolute right-1.5 top-1/2 grid size-7 -translate-y-1/2 place-items-center rounded-lg text-[var(--muted)] transition-colors hover:bg-[var(--panel-hover)] hover:text-[var(--ink)] active:scale-[0.97]",						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-4" })					})				]			}),			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {				className: "nums shrink-0 whitespace-nowrap text-right text-[11px] leading-tight text-[var(--muted)]",				children: [					dirCount,					" dir",					dirCount === 1 ? "" : "s",					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),					fileCount,					" file",					fileCount === 1 ? "" : "s"				]			})		]	});}function EntryRow({ entry, dir, first }) {	const childRel = joinRel(dir, entry.name);	const isDir = entry.type === "dir";	const search = isDir ? { path: childRel } : {		path: dir || void 0,		file: childRel	};	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", {		className: cn(!first && "border-t border-[var(--line)]"),		children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Link, {			to: "/",			search,			className: "group flex items-center gap-3 px-3.5 py-3 transition-colors hover:bg-[var(--panel-hover)] focus-visible:bg-[var(--panel-hover)] focus-visible:outline-none active:scale-[0.995]",			style: { touchAction: "manipulation" },			children: [				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileGlyph, {					type: entry.type,					ext: entry.ext,					className: cn("size-[18px] shrink-0", isDir ? "text-[var(--indigo)]" : "text-[var(--muted)]")				}),				/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {					className: "min-w-0 flex-1 truncate text-[15px] text-[var(--ink)]",					children: entry.name				}),				isDir ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "size-4 shrink-0 text-[var(--muted)]/60 transition-transform group-hover:translate-x-0.5" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {					className: "nums shrink-0 text-[11px] text-[var(--muted)]",					children: formatBytes(entry.size)				})			]		})	});}function Notice({ icon, title, body }) {	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {		className: "flex flex-col items-center gap-3 rounded-2xl border border-dashed border-[var(--edge)] px-6 py-14 text-center",		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {			className: "grid size-11 place-items-center rounded-xl bg-[var(--panel)] text-[var(--muted)]",			children: icon		}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {			className: "flex flex-col gap-1",			children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {				className: "text-[15px] font-medium text-[var(--ink)]",				children: title			}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {				className: "text-[13px] text-[var(--muted)]",				children: body			})]		})]	});}function Viewer({ file, dirPath }) {	const router = useRouter();	const [copied, setCopied] = (0, import_react.useState)(false);	const [editing, setEditing] = (0, import_react.useState)(false);	const [draft, setDraft] = (0, import_react.useState)(file.content ?? "");	const [saving, setSaving] = (0, import_react.useState)(false);	const [saveMsg, setSaveMsg] = (0, import_react.useState)(null);	const closeSearch = dirPath ? { path: dirPath } : {};	(0, import_react.useEffect)(() => {		setCopied(false);		setEditing(false);		setDraft(file.content ?? "");		setSaveMsg(null);	}, [file.relPath, file.content]);	(0, import_react.useEffect)(() => {		const prev = document.body.style.overflow;		document.body.style.overflow = "hidden";		return () => {			document.body.style.overflow = prev;		};	}, []);	(0, import_react.useEffect)(() => {		const onKey = (e) => {			if (e.key === "Escape" && !editing) router.navigate({				to: "/",				search: closeSearch			});		};		window.addEventListener("keydown", onKey);		return () => window.removeEventListener("keydown", onKey);	}, [dirPath, editing]);	const copy = async () => {		if (!file.content || file.kind !== "text") return;		try {			await navigator.clipboard.writeText(editing ? draft : file.content);			setCopied(true);			setTimeout(() => setCopied(false), 1600);		} catch {}	};	const save = async () => {		setSaving(true);		setSaveMsg(null);		try {			const res = await saveFile({ data: {				path: file.relPath,				content: draft			} });			if (res.ok) {				setSaveMsg({					ok: true,					text: "Saved"				});				setEditing(false);				router.invalidate();				setTimeout(() => setSaveMsg(null), 1800);			} else setSaveMsg({				ok: false,				text: res.error ?? "Could not save"			});		} catch {			setSaveMsg({				ok: false,				text: "Could not save"			});		} finally {			setSaving(false);		}	};	const dirty = editing && draft !== (file.content ?? "");	const canEdit = file.kind === "text";	const requestClose = () => {		if (dirty && !window.confirm("Discard unsaved changes?")) return;		router.navigate({			to: "/",			search: closeSearch		});	};	const lineCount = (0, import_react.useMemo)(() => file.content && file.kind === "text" ? file.content.split("\n").length : 0, [file.content, file.kind]);	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {		className: "fixed inset-0 z-40 flex flex-col bg-black/55 backdrop-blur-sm",		style: { overscrollBehavior: "contain" },		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {			type: "button",			"aria-label": "Close file viewer",			className: "absolute inset-0 cursor-default",			tabIndex: -1,			onClick: requestClose		}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {			className: "relative mx-auto mt-auto flex h-[92dvh] w-full max-w-3xl flex-col overflow-hidden rounded-t-3xl border-x border-t border-[var(--edge-strong)] bg-[var(--bg-bottom)] shadow-[0_-20px_60px_-15px_rgba(0,0,0,0.7)]",			children: [				/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {					className: "flex justify-center pt-2.5",					"aria-hidden": "true",					children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "h-1 w-10 rounded-full bg-white/15" })				}),				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {					className: "flex items-center gap-2.5 border-b border-[var(--line)] px-4 py-3",					children: [						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileGlyph, {							type: "file",							ext: file.ext,							className: "size-[18px] shrink-0 text-[var(--gold)]"						}),						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {							className: "flex min-w-0 flex-1 flex-col",							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {								className: "truncate text-[15px] font-medium text-[var(--ink)]",								children: file.name							}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {								className: "nums truncate text-[11px] text-[var(--muted)]",								children: [									formatBytes(file.size),									file.kind === "text" && lineCount > 0 ? ` · ${lineCount} lines` : "",									file.truncated ? " · preview" : "",									editing ? " · editing" : ""								]							})]						}),						saveMsg && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {							role: "status",							"aria-live": "polite",							className: cn("shrink-0 rounded-lg px-2 py-1 text-[11px] font-medium", saveMsg.ok ? "bg-[var(--gold-soft)] text-[var(--gold)]" : "bg-red-500/15 text-red-300"),							children: saveMsg.text						}),						editing ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {							type: "button",							onClick: () => {								if (dirty && !window.confirm("Discard unsaved changes?")) return;								setDraft(file.content ?? "");								setEditing(false);								setSaveMsg(null);							},							className: "shrink-0 rounded-xl border border-[var(--edge)] bg-[var(--panel)] px-3 py-2 text-[13px] font-medium text-[var(--muted)] shadow-xs transition-colors hover:bg-[var(--panel-hover)] hover:text-[var(--ink)] active:scale-[0.97]",							style: { touchAction: "manipulation" },							children: "Cancel"						}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {							type: "button",							onClick: save,							disabled: saving || !dirty,							className: "flex shrink-0 items-center gap-1.5 rounded-xl bg-[var(--indigo)] px-3 py-2 text-[13px] font-medium text-white shadow-[0_1px_0_rgba(255,255,255,0.18)_inset,0_4px_12px_-4px_rgba(99,102,241,0.7)] transition-colors hover:bg-[#7679f3] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--indigo)] active:scale-[0.97] disabled:opacity-50",							style: { touchAction: "manipulation" },							children: [saving ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "size-3.5 animate-spin rounded-full border-2 border-white/40 border-t-white" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Save, { className: "size-3.5" }), saving ? "Saving…" : "Save"]						})] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [							canEdit && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {								type: "button",								onClick: () => {									setDraft(file.content ?? "");									setEditing(true);									setSaveMsg(null);								},								"aria-label": "Edit file",								className: "flex shrink-0 items-center gap-1.5 rounded-xl border border-[var(--edge)] bg-[var(--panel)] px-3 py-2 text-[13px] font-medium text-[var(--ink)] shadow-xs transition-colors hover:border-[var(--edge-strong)] hover:bg-[var(--panel-hover)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--indigo)] active:scale-[0.97]",								style: { touchAction: "manipulation" },								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pencil, { className: "size-3.5" }), "Edit"]							}),							file.kind === "text" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {								type: "button",								onClick: copy,								"aria-label": copied ? "Copied" : "Copy file contents",								className: "grid size-9 shrink-0 place-items-center rounded-xl border border-[var(--edge)] bg-[var(--panel)] text-[var(--muted)] shadow-xs transition-colors hover:border-[var(--edge-strong)] hover:bg-[var(--panel-hover)] hover:text-[var(--ink)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--indigo)] active:scale-[0.97]",								style: { touchAction: "manipulation" },								children: copied ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Check, { className: "size-4 text-[var(--gold)]" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Copy, { className: "size-4" })							}),							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {								type: "button",								onClick: requestClose,								"aria-label": "Close",								className: "grid size-9 shrink-0 place-items-center rounded-xl border border-[var(--edge)] bg-[var(--panel)] text-[var(--ink)] shadow-xs transition-colors hover:border-[var(--edge-strong)] hover:bg-[var(--panel-hover)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--indigo)] active:scale-[0.97]",								style: { touchAction: "manipulation" },								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-4" })							})						] })					]				}),				editing ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {					value: draft,					onChange: (e) => setDraft(e.target.value),					autoCorrect: "off",					autoCapitalize: "off",					autoComplete: "off",					spellCheck: false,					wrap: "off",					className: "scroll-thin flex-1 resize-none bg-transparent px-4 py-3 font-mono text-[13px] leading-[1.65] text-[var(--ink)] outline-none",					style: {						touchAction: "manipulation",						WebkitTextSizeAdjust: "100%"					},					"aria-label": `Edit ${file.name}`				}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ViewerBody, { file })			]		})]	});}function ViewerBody({ file }) {	if (file.kind === "image" && file.content) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {		className: "scroll-thin flex flex-1 items-center justify-center overflow-auto bg-[repeating-conic-gradient(rgba(255,255,255,0.025)_0%_25%,transparent_0%_50%)] bg-[length:20px_20px] p-4",		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {			src: file.content,			alt: file.name,			className: "max-h-full max-w-full rounded-lg object-contain shadow-lg"		})	});	if (file.kind === "text" && file.content !== null) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {		className: "scroll-thin flex-1 overflow-auto",		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {			className: "min-w-full py-3 text-[12.5px] leading-[1.65]",			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", {				className: "block",				children: file.content.split("\n").map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {					className: "flex",					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {						"aria-hidden": "true",						className: "nums sticky left-0 mr-3 inline-block w-12 shrink-0 select-none border-r border-[var(--line)] bg-[var(--bg-bottom)] pr-2.5 text-right text-[var(--muted)]/50",						children: i + 1					}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {						className: "whitespace-pre pr-4",						children: highlight(line.length ? line : " ", file.ext)					})]				}, i))			})		}), file.truncated && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {			className: "border-t border-[var(--line)] px-4 py-3 text-center text-[12px] text-[var(--muted)]",			children: "Preview truncated. File is larger than the inline limit."		})]	});	const map = {		binary: {			icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HardDrive, { className: "size-5" }),			title: "Binary file",			body: "This file isn't text and can't be shown here."		},		"too-large": {			icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HardDrive, { className: "size-5" }),			title: "File too large",			body: "This file exceeds the inline viewer limit."		},		denied: {			icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Lock, { className: "size-5" }),			title: "Permission denied",			body: "This file can't be read in the current environment."		},		missing: {			icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-5" }),			title: "Can't open file",			body: "This file is no longer available."		}	};	const m = map[file.kind] ?? map.missing;	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {		className: "flex flex-1 items-center justify-center p-8",		children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {			className: "flex flex-col items-center gap-3 text-center",			children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {				className: "grid size-11 place-items-center rounded-xl bg-[var(--panel)] text-[var(--muted)]",				children: m.icon			}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {				className: "flex flex-col gap-1",				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {					className: "text-[15px] font-medium text-[var(--ink)]",					children: m.title				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {					className: "max-w-xs text-[13px] text-[var(--muted)]",					children: m.body				})]			})]		})	});}function Terminal({ cwd: initialCwd, onClose }) {	const [input, setInput] = (0, import_react.useState)("");	const [blocks, setBlocks] = (0, import_react.useState)([]);	const [busy, setBusy] = (0, import_react.useState)(false);	const [history, setHistory] = (0, import_react.useState)([]);	const [histIdx, setHistIdx] = (0, import_react.useState)(-1);	const [cwd, setCwd] = (0, import_react.useState)(initialCwd);	const scrollRef = (0, import_react.useRef)(null);	const inputRef = (0, import_react.useRef)(null);	const idRef = (0, import_react.useRef)(0);	(0, import_react.useEffect)(() => {		const prev = document.body.style.overflow;		document.body.style.overflow = "hidden";		return () => {			document.body.style.overflow = prev;		};	}, []);	(0, import_react.useEffect)(() => {		const el = scrollRef.current;		if (el) el.scrollTop = el.scrollHeight;	}, [blocks]);	const prompt = cwd ? "/" + cwd : "/";	const submit = async () => {		const command = input.trim();		if (!command || busy) return;		if (command === "clear" || command === "cls") {			setBlocks([]);			setInput("");			return;		}		const runCwd = cwd;		const id = ++idRef.current;		setBlocks((b) => [...b, {			id,			cwd: runCwd,			command,			stdout: "",			stderr: "",			code: null,			durationMs: 0,			truncated: false,			pending: true		}]);		setHistory((h) => h[h.length - 1] === command ? h : [...h, command]);		setHistIdx(-1);		setInput("");		setBusy(true);		try {			const res = await runCommand({ data: {				command,				cwd: runCwd			} });			if (res.newCwd !== null) setCwd(res.newCwd);			setBlocks((b) => b.map((bl) => bl.id === id ? {				...bl,				...res,				pending: false			} : bl));		} catch {			setBlocks((b) => b.map((bl) => bl.id === id ? {				...bl,				stderr: "Command failed to run.",				code: 1,				pending: false			} : bl));		} finally {			setBusy(false);			requestAnimationFrame(() => inputRef.current?.focus());		}	};	const onKeyDown = (e) => {		if (e.key === "Enter") {			e.preventDefault();			submit();		} else if (e.key === "ArrowUp") {			if (!history.length) return;			e.preventDefault();			const next = histIdx < 0 ? history.length - 1 : Math.max(0, histIdx - 1);			setHistIdx(next);			setInput(history[next]);		} else if (e.key === "ArrowDown") {			if (histIdx < 0) return;			e.preventDefault();			const next = histIdx + 1;			if (next >= history.length) {				setHistIdx(-1);				setInput("");			} else {				setHistIdx(next);				setInput(history[next]);			}		}	};	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {		className: "fixed inset-0 z-50 flex flex-col bg-[var(--bg-top)]",		style: { overscrollBehavior: "contain" },		children: [			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {				className: "flex items-center gap-2.5 border-b border-[var(--edge)] px-4 py-3 pt-[max(0.75rem,env(safe-area-inset-top))]",				children: [					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SquareTerminal, { className: "size-[18px] shrink-0 text-[var(--indigo)]" }),					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {						className: "flex min-w-0 flex-1 flex-col",						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {							className: "text-[14px] font-medium text-[var(--ink)]",							children: "Terminal"						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {							className: "truncate font-mono text-[11px] text-[var(--muted)]",							dir: "rtl",							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("bdi", { children: prompt })						})]					}),					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {						type: "button",						onClick: () => setBlocks([]),						className: "shrink-0 rounded-xl border border-[var(--edge)] bg-[var(--panel)] px-3 py-2 text-[12px] font-medium text-[var(--muted)] shadow-xs transition-colors hover:bg-[var(--panel-hover)] hover:text-[var(--ink)] active:scale-[0.97]",						style: { touchAction: "manipulation" },						children: "Clear"					}),					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {						type: "button",						onClick: onClose,						"aria-label": "Close terminal",						className: "grid size-9 shrink-0 place-items-center rounded-xl border border-[var(--edge)] bg-[var(--panel)] text-[var(--ink)] shadow-xs transition-colors hover:bg-[var(--panel-hover)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--indigo)] active:scale-[0.97]",						style: { touchAction: "manipulation" },						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-4" })					})				]			}),			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {				ref: scrollRef,				className: "scroll-thin flex-1 overflow-auto px-4 py-3 font-mono text-[12.5px] leading-[1.6]",				children: [blocks.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {					className: "text-[var(--muted)]",					children: [						"Runs bash in ",						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {							className: "text-[var(--gold)]",							children: prompt						}),						". Try ",						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {							className: "text-[var(--ink)]",							children: "ls -la"						}),						",",						" ",						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {							className: "text-[var(--ink)]",							children: "cat file"						}),						", ",						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {							className: "text-[var(--ink)]",							children: "grep"						}),						", or",						" ",						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {							className: "text-[var(--ink)]",							children: "cd folder"						}),						" to move around. Type ",						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {							className: "text-[var(--ink)]",							children: "clear"						}),						" to reset."					]				}), blocks.map((b) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {					className: "mb-3",					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {						className: "flex items-start gap-2 break-all",						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {							className: "shrink-0 select-none whitespace-nowrap text-[var(--muted)]",							children: [								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {									className: "text-[var(--gold)]/70",									children: b.cwd ? "/" + b.cwd : "/"								}),								" ",								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {									className: "text-[var(--indigo)]",									children: "$"								})							]						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {							className: "whitespace-pre-wrap break-all text-[var(--ink)]",							children: b.command						})]					}), b.pending ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {						className: "mt-1 text-[var(--muted)]",						children: "running…"					}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [						b.stdout && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {							className: "mt-1 whitespace-pre-wrap break-all text-[var(--ink)]/90",							children: b.stdout						}),						b.stderr && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {							className: "mt-1 whitespace-pre-wrap break-all text-red-300/90",							children: b.stderr						}),						!b.stdout && !b.stderr && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {							className: "mt-1 text-[var(--muted)]/60",							children: "(no output)"						}),						(b.code ?? 0) !== 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {							className: "mt-0.5 text-[11px] text-[var(--muted)]",							children: ["exit ", b.code]						}),						b.truncated && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {							className: "mt-0.5 text-[11px] text-[var(--muted)]",							children: "[output truncated]"						})					] })]				}, b.id))]			}),			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {				className: "flex items-center gap-2 border-t border-[var(--edge)] px-3 py-2.5 pb-[max(0.625rem,env(safe-area-inset-bottom))]",				children: [					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {						className: "shrink-0 pl-1 font-mono text-[14px] text-[var(--indigo)]",						children: "$"					}),					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {						ref: inputRef,						type: "text",						value: input,						onChange: (e) => setInput(e.target.value),						onKeyDown,						placeholder: "type a command…",						"aria-label": "Terminal command input",						autoCorrect: "off",						autoCapitalize: "off",						autoComplete: "off",						spellCheck: false,						enterKeyHint: "go",						inputMode: "text",						autoFocus: true,						className: "min-w-0 flex-1 bg-transparent font-mono text-[15px] text-[var(--ink)] outline-none placeholder:text-[var(--muted)]/70",						style: {							touchAction: "manipulation",							WebkitTextSizeAdjust: "100%"						}					}),					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {						type: "button",						onClick: submit,						disabled: busy || !input.trim(),						"aria-label": "Run command",						className: "grid size-9 shrink-0 place-items-center rounded-xl bg-[var(--indigo)] text-white shadow-[0_1px_0_rgba(255,255,255,0.18)_inset] transition-colors hover:bg-[#7679f3] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--indigo)] active:scale-[0.95] disabled:opacity-40",						style: { touchAction: "manipulation" },						children: busy ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "size-4 animate-spin rounded-full border-2 border-white/40 border-t-white" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "size-5" })					})				]			})		]	});}//#endregionexport { Explorer as component };