🪻 distributed transcription service
thistle.dunkirk.sh
1<!-- vim: setlocal noexpandtab nowrap: -->
2<!doctype html>
3<html lang="en">
4
5<head>
6 <meta charset="UTF-8" />
7 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8 <title>C:\KIERANK.EXE - kierank.hackclub.app</title>
9 <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
10 <style>
11 @import url("https://fonts.googleapis.com/css2?family=Courier+Prime:wght@400;700&display=swap");
12
13 body {
14 background: #008080;
15 font-family: "Courier Prime", "Courier New", monospace;
16 color: #000000;
17 margin: 0;
18 padding: 20px;
19 line-height: 1.4;
20 font-size: 14px;
21 }
22
23 .hidden {
24 display: none !important;
25 }
26
27 .terminal {
28 background: #ffffff;
29 border: 2px solid #808080;
30 box-shadow:
31 inset -2px -2px #c0c0c0,
32 inset 2px 2px #404040,
33 4px 4px 0px #000000;
34 max-width: 750px;
35 margin: 0 auto;
36 padding: 0;
37 }
38
39 .title-bar {
40 background: linear-gradient(90deg, #000080, #1084d0);
41 color: #ffffff;
42 padding: 4px 8px;
43 font-weight: bold;
44 border-bottom: 1px solid #808080;
45 font-size: 12px;
46 display: flex;
47 justify-content: space-between;
48 align-items: center;
49 }
50
51 .title-buttons {
52 display: flex;
53 gap: 2px;
54 }
55
56 .title-btn {
57 width: 16px;
58 height: 14px;
59 background: #c0c0c0;
60 border: 1px outset #ffffff;
61 font-size: 10px;
62 line-height: 12px;
63 text-align: center;
64 cursor: pointer;
65 }
66
67 .content {
68 padding: 15px;
69 background: #ffffff;
70 }
71
72 .prompt {
73 color: #000000;
74 margin: 0 0 10px 0;
75 }
76
77 .cursor {
78 background: #000000;
79 color: #ffffff;
80 animation: blink 1s infinite;
81 }
82
83 @keyframes blink {
84
85 0%,
86 50% {
87 opacity: 1;
88 }
89
90 51%,
91 100% {
92 opacity: 0;
93 }
94 }
95
96 /* Markdown rendered content styles */
97 #readme-content h3 {
98 color: #000080;
99 font-size: 20px;
100 margin: 15px 0 10px 0;
101 border-bottom: 2px solid #c0c0c0;
102 padding-bottom: 5px;
103 }
104
105 #readme-content h4 {
106 color: #000000;
107 font-size: 14px;
108 margin: 20px 0 8px 0;
109 text-transform: uppercase;
110 background: #c0c0c0;
111 padding: 4px 8px;
112 display: inline-block;
113 }
114
115 #readme-content p {
116 margin: 8px 0;
117 }
118
119 #readme-content ul {
120 margin: 8px 0;
121 padding-left: 20px;
122 list-style: none;
123 }
124
125 #readme-content ul li {
126 margin: 6px 0;
127 position: relative;
128 }
129
130 #readme-content ul li::before {
131 content: "► ";
132 color: #000080;
133 }
134
135 #readme-content a {
136 color: #000080;
137 text-decoration: underline;
138 }
139
140 #readme-content a:hover {
141 color: #0000ff;
142 background: #ffffcc;
143 }
144
145 #readme-content code {
146 background: #000080;
147 color: #ffffff;
148 padding: 1px 4px;
149 font-family: "Courier Prime", "Courier New", monospace;
150 }
151
152 #readme-content pre {
153 background: #000080;
154 color: #cbcbcb;
155 padding: 12px;
156 border: 2px inset #404040;
157 overflow-x: auto;
158 font-size: 12px;
159 line-height: 1.3;
160 }
161
162 #readme-content pre code {
163 background: transparent;
164 color: inherit;
165 padding: 0;
166 }
167
168 #readme-content strong {
169 color: #333333;
170 }
171
172 #readme-content em {
173 color: #808080;
174 font-style: italic;
175 }
176
177 .status-bar {
178 background: #c0c0c0;
179 color: #000000;
180 padding: 3px 8px;
181 border-top: 2px groove #ffffff;
182 font-size: 11px;
183 display: flex;
184 justify-content: space-between;
185 }
186
187 .separator {
188 color: #808080;
189 margin: 15px 0;
190 text-align: center;
191 }
192
193 .loading {
194 text-align: center;
195 padding: 20px;
196 color: #808080;
197 }
198
199 .loading::after {
200 content: "";
201 animation: dots 1.5s steps(4, end) infinite;
202 }
203
204 @keyframes dots {
205
206 0%,
207 20% {
208 content: "";
209 }
210
211 40% {
212 content: ".";
213 }
214
215 60% {
216 content: "..";
217 }
218
219 80%,
220 100% {
221 content: "...";
222 }
223 }
224
225 .error-box {
226 background: #ff0000;
227 color: #ffffff;
228 padding: 10px;
229 border: 2px inset #800000;
230 margin: 10px 0;
231 }
232
233 .ascii-header {
234 color: #000080;
235 font-size: 10px;
236 line-height: 1.1;
237 white-space: pre;
238 margin: 10px 0 15px 0;
239 text-align: center;
240 }
241 </style>
242</head>
243
244<body>
245 <div class="terminal">
246 <div class="title-bar">
247 <span>C:\KIERANK.EXE - kierank.hackclub.app</span>
248 <div class="title-buttons">
249 <div class="title-btn">_</div>
250 <div class="title-btn">□</div>
251 <div class="title-btn">×</div>
252 </div>
253 </div>
254
255 <div class="content">
256 <p class="prompt">
257 C:\KIERANK> README.EXE<span class="cursor"> </span>
258 </p>
259
260 <!-- biome-ignore format: ascii art -->
261 <pre class="ascii-header">
262██╗ ██╗██╗███████╗██████╗ █████╗ ███╗ ██╗
263██║ ██║██║██╔════╝██╔══██╗██╔══██╗████╗ ██║
264█████╔╝██║█████╗ ██████╔╝███████║██╔██╗ ██║
265██╔═██╗██║██╔══╝ ██╔══██╗██╔══██║██║╚██╗██║
266██║ ██║██║███████╗██║ ██║██║ ██║██║ ╚████║
267╚═╝ ╚═╝╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝
268 </pre>
269
270 <div class="separator">
271 ════════════════════════════════════════════════════
272 </div>
273
274 <div id="readme-content">
275 <div class="loading" style="display: none">Loading README from GitHub</div>
276
277 <noscript>
278 <div class="error-box">
279 JavaScript is disabled so not rendering markdown.
280 </div>
281 <p>
282 View the README on GitHub:
283 <a href="https://github.com/taciturnaxolotl/taciturnaxolotl/blob/main/README.md">
284 taciturnaxolotl/README.md
285 </a>
286 </p>
287 </noscript>
288 </div>
289
290 <div class="separator">
291 ════════════════════════════════════════════════════
292 </div>
293
294 <p style="font-size: 11px; color: #808080; text-align: center">
295 Hosted on <a href="https://hackclub.com/nest/">Hack Club Nest</a> |
296 <a href="https://github.com/taciturnaxolotl">GitHub</a> |
297 <a href="https://dunkirk.sh">dunkirk.sh</a>
298 </p>
299 </div>
300
301 <div class="status-bar">
302 <span id="status">Fetching README...</span>
303 <span id="time"></span>
304 </div>
305 </div>
306
307 <script>
308 const README_URL =
309 "https://raw.githubusercontent.com/taciturnaxolotl/taciturnaxolotl/refs/heads/main/README.md"
310
311 async function loadReadme() {
312 const contentDiv = document.getElementById("readme-content");
313 const statusSpan = document.getElementById("status");
314 const loadingEl = contentDiv.querySelector(".loading");
315
316 // Show loading
317 if (loadingEl) loadingEl.classList.remove("hidden");
318
319
320 try {
321 const response = await fetch(README_URL);
322 if (!response.ok) {
323 throw new Error(`HTTP ${response.status}`);
324 }
325
326 const markdown = await response.text();
327
328 // Configure marked for GFM
329 marked.setOptions({
330 gfm: true,
331 breaks: true,
332 });
333
334 contentDiv.innerHTML = marked.parse(markdown);
335
336 // Strip emojis from headers
337 contentDiv.querySelectorAll("h3, h4").forEach((header) => {
338 const text = header.textContent;
339
340 // Regex targets:
341 // - \p{Extended_Pictographic}: most modern emoji/pictographs
342 // - \p{Emoji_Presentation}: characters default-rendered as emoji
343 // - Variation Selector-16 (U+FE0F): emoji presentation modifier
344 // - Common symbol blocks that often carry emoji-like glyphs
345 const emojiRegex =
346 /[\p{Extended_Pictographic}\p{Emoji_Presentation}\uFE0F]|[\u2600-\u26FF\u2700-\u27BF]/gu;
347
348 // Strip emojis
349 let cleaned = text.replace(emojiRegex, "");
350
351 // Collapse multiple whitespace into single spaces
352 cleaned = cleaned.replace(/\s+/g, " ");
353
354 // Remove spaces before punctuation (e.g., "Hello !" -> "Hello!")
355 cleaned = cleaned.replace(/\s+([!?,.;:])/g, "$1");
356
357 // Trim leading/trailing whitespace
358 cleaned = cleaned.trim();
359
360 // Replace header content safely
361 header.textContent = cleaned;
362 });
363
364 statusSpan.textContent = "README loaded successfully";
365 } catch (error) {
366 contentDiv.innerHTML = `
367 <div class="error-box">
368 ERROR: Failed to load README<br>
369 ${error.message}
370 </div>
371 <p>Try refreshing the page or visit
372 <a href="https://github.com/taciturnaxolotl">github.com/taciturnaxolotl</a> directly.</p>
373 `;
374 statusSpan.textContent = "Error loading README";
375 }
376 }
377
378 function updateTime() {
379 const now = new Date();
380 const timeStr = now.toLocaleTimeString("en-US", {
381 hour: "2-digit",
382 minute: "2-digit",
383 hour12: true,
384 });
385 document.getElementById("time").textContent = timeStr;
386 }
387
388 // Initialize
389 updateTime();
390 setInterval(updateTime, 1000);
391 loadReadme();
392 </script>
393</body>
394
395</html>
396
397</html>
398
399</html>