@anglefeint/astro-theme 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,347 @@
1
+ function randHex() {
2
+ var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
3
+ return chars[Math.floor(Math.random() * chars.length)];
4
+ }
5
+
6
+ function randKeyLine(pairs) {
7
+ var s = [];
8
+ for (var i = 0; i < pairs; i++) s.push(randHex() + randHex());
9
+ return s.join(' ');
10
+ }
11
+
12
+ function randPass() {
13
+ var s = '';
14
+ for (var i = 0; i < 6; i++) s += randHex().toLowerCase();
15
+ s += '@' + randHex() + randHex() + randHex() + randHex() + randHex();
16
+ return s;
17
+ }
18
+
19
+ export function initAboutModals(runtimeConfig, prefersReducedMotion) {
20
+ var modalOverlay = document.getElementById('hacker-modal');
21
+ var modalBody = document.getElementById('hacker-modal-body');
22
+ var modalTitle = document.querySelector('.hacker-modal-title');
23
+ if (!modalOverlay || !modalBody || !modalTitle) return;
24
+
25
+ var decryptorKeysLabel = runtimeConfig.decryptorKeysLabel || 'keys tested';
26
+ var decryptorInterval = null;
27
+ var helpCharCount = 0;
28
+
29
+ function startDecryptorFlash() {
30
+ if (prefersReducedMotion) return;
31
+ if (decryptorInterval) clearInterval(decryptorInterval);
32
+ var keys = 0;
33
+ var sec = 1;
34
+ decryptorInterval = setInterval(function() {
35
+ if (!modalOverlay.classList.contains('open')) {
36
+ clearInterval(decryptorInterval);
37
+ decryptorInterval = null;
38
+ return;
39
+ }
40
+ keys += 1 + Math.floor(Math.random() * 3);
41
+ sec = Math.min(59, Math.floor(keys / 15) + 1);
42
+ var el = document.getElementById('dec-keys');
43
+ if (el) el.textContent = '[00:00:' + String(sec).padStart(2, '0') + '] ' + keys + ' ' + decryptorKeysLabel;
44
+ el = document.getElementById('dec-pass');
45
+ if (el) el.textContent = randPass();
46
+ el = document.getElementById('dec-master1');
47
+ if (el) el.textContent = randKeyLine(8);
48
+ el = document.getElementById('dec-master2');
49
+ if (el) el.textContent = randKeyLine(8);
50
+ el = document.getElementById('dec-trans1');
51
+ if (el) el.textContent = randKeyLine(7);
52
+ el = document.getElementById('dec-trans2');
53
+ if (el) el.textContent = randKeyLine(7);
54
+ el = document.getElementById('dec-trans3');
55
+ if (el) el.textContent = randKeyLine(8);
56
+ el = document.getElementById('dec-trans4');
57
+ if (el) el.textContent = randKeyLine(8);
58
+ }, 180);
59
+ }
60
+
61
+ function buildHelpKeyboard() {
62
+ var keyboardConfig = runtimeConfig.keyboard || {};
63
+ var statsLabel = keyboardConfig.statsLabel || 'Stats & Achievements';
64
+ var typedPrefix = keyboardConfig.typedPrefix || 'You typed:';
65
+ var typedSuffix = keyboardConfig.typedSuffix || 'characters';
66
+ var rows = [
67
+ ['`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 'Backspace'],
68
+ ['Tab', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']'],
69
+ ['CapsLock', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', "'", 'Enter'],
70
+ ['Shift', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 'ShiftRight'],
71
+ ['Ctrl', 'Alt', 'Space', 'AltRight', 'CtrlRight'],
72
+ ];
73
+ var codeMap = {
74
+ '`': 'Backquote',
75
+ '1': 'Digit1',
76
+ '2': 'Digit2',
77
+ '3': 'Digit3',
78
+ '4': 'Digit4',
79
+ '5': 'Digit5',
80
+ '6': 'Digit6',
81
+ '7': 'Digit7',
82
+ '8': 'Digit8',
83
+ '9': 'Digit9',
84
+ '0': 'Digit0',
85
+ '-': 'Minus',
86
+ '=': 'Equal',
87
+ Backspace: 'Backspace',
88
+ Tab: 'Tab',
89
+ Q: 'KeyQ',
90
+ W: 'KeyW',
91
+ E: 'KeyE',
92
+ R: 'KeyR',
93
+ T: 'KeyT',
94
+ Y: 'KeyY',
95
+ U: 'KeyU',
96
+ I: 'KeyI',
97
+ O: 'KeyO',
98
+ P: 'KeyP',
99
+ '[': 'BracketLeft',
100
+ ']': 'BracketRight',
101
+ CapsLock: 'CapsLock',
102
+ A: 'KeyA',
103
+ S: 'KeyS',
104
+ D: 'KeyD',
105
+ F: 'KeyF',
106
+ G: 'KeyG',
107
+ H: 'KeyH',
108
+ J: 'KeyJ',
109
+ K: 'KeyK',
110
+ L: 'KeyL',
111
+ ';': 'Semicolon',
112
+ "'": 'Quote',
113
+ Enter: 'Enter',
114
+ Shift: 'ShiftLeft',
115
+ ShiftRight: 'ShiftRight',
116
+ Z: 'KeyZ',
117
+ X: 'KeyX',
118
+ C: 'KeyC',
119
+ V: 'KeyV',
120
+ B: 'KeyB',
121
+ N: 'KeyN',
122
+ M: 'KeyM',
123
+ ',': 'Comma',
124
+ '.': 'Period',
125
+ '/': 'Slash',
126
+ Ctrl: 'ControlLeft',
127
+ CtrlRight: 'ControlRight',
128
+ Alt: 'AltLeft',
129
+ AltRight: 'AltRight',
130
+ Space: 'Space',
131
+ };
132
+
133
+ var html = '<div class="hacker-vkeyboard-wrap" id="help-keyboard">';
134
+ html += '<div class="hacker-vkeyboard hacker-vkeyboard-main">';
135
+ rows.forEach(function(row) {
136
+ html += '<div class="hacker-vkeyboard-row">';
137
+ row.forEach(function(k) {
138
+ var code = codeMap[k] || k;
139
+ var cls = 'hacker-vkey';
140
+ if (k === 'Tab' || k === 'CapsLock' || k === 'Enter') cls += ' wide';
141
+ if (k === 'Space') cls += ' space';
142
+ if (k === 'Backspace') cls += ' acc backspace';
143
+ var label =
144
+ k === 'Space'
145
+ ? '&nbsp;'
146
+ : k === 'ShiftRight'
147
+ ? 'Shift'
148
+ : k === 'CtrlRight'
149
+ ? 'Ctrl'
150
+ : k === 'AltRight'
151
+ ? 'Alt'
152
+ : k === 'Backspace'
153
+ ? 'Back ⌫'
154
+ : k;
155
+ html +=
156
+ '<span class="' +
157
+ cls +
158
+ '" data-code="' +
159
+ code +
160
+ '" data-key="' +
161
+ (k === 'ShiftRight' ? 'Shift' : k === 'CtrlRight' ? 'Ctrl' : k === 'AltRight' ? 'Alt' : k === 'Backspace' ? 'Backspace' : k).replace("'", "\\'") +
162
+ '"' +
163
+ (k === 'Backspace' ? ' title="Backspace or ESC"' : '') +
164
+ '>' +
165
+ label +
166
+ '</span>';
167
+ });
168
+ html += '</div>';
169
+ });
170
+ html += '</div>';
171
+ html += '<div class="hacker-vkeyboard-side">';
172
+ html += '<div class="hacker-vkeyboard-side-block">';
173
+ html += '<div class="hacker-vkeyboard-side-row"><span class="hacker-vkey" data-code="Insert" data-key="Ins">Insert</span><span class="hacker-vkey nav-home" data-code="Home" data-key="Home">Home</span><span class="hacker-vkey" data-code="PageUp" data-key="PgUp">PgUp</span></div>';
174
+ html += '<div class="hacker-vkeyboard-side-row"><span class="hacker-vkey" data-code="Delete" data-key="Del">Delete</span><span class="hacker-vkey nav-end" data-code="End" data-key="End">End</span><span class="hacker-vkey" data-code="PageDown" data-key="PgDn">PgDn</span></div>';
175
+ html += '</div>';
176
+ html += '<div class="hacker-vkeyboard-side-row"><span class="hacker-vkey" data-code="Purge" data-key="Purge">Purge</span></div>';
177
+ html += '<div class="hacker-vkeyboard-arrows-wrap">';
178
+ html += '<div class="hacker-vkeyboard-arrows">';
179
+ html += '<span class="hacker-vkey arr-u" data-code="ArrowUp" data-key="↑">↑</span>';
180
+ html += '<span class="hacker-vkey arr-l" data-code="ArrowLeft" data-key="←">←</span>';
181
+ html += '<span class="hacker-vkey arr-r" data-code="ArrowRight" data-key="→">→</span>';
182
+ html += '<span class="hacker-vkey arr-d" data-code="ArrowDown" data-key="↓">↓</span>';
183
+ html += '</div>';
184
+ html += '</div></div></div>';
185
+ html += '<div class="hacker-vkeyboard-stats"><span class="hacker-vkeyboard-stats-label">' + statsLabel + '</span><br>' + typedPrefix + ' <span id="help-char-count">0</span> ' + typedSuffix + '</div>';
186
+ return html;
187
+ }
188
+
189
+ function highlightKey(code) {
190
+ if (code === 'Escape') code = 'Backspace';
191
+ var el = modalBody.querySelector('.hacker-vkey[data-code="' + code + '"]');
192
+ if (!el) {
193
+ if (code === 'ShiftRight') el = modalBody.querySelector('.hacker-vkey[data-code="ShiftLeft"]');
194
+ else if (code === 'ControlRight') el = modalBody.querySelector('.hacker-vkey[data-code="ControlLeft"]');
195
+ else if (code === 'AltRight') el = modalBody.querySelector('.hacker-vkey[data-code="AltLeft"]');
196
+ }
197
+ if (el) {
198
+ el.classList.add('highlight');
199
+ setTimeout(function() {
200
+ el.classList.remove('highlight');
201
+ }, 150);
202
+ }
203
+ }
204
+
205
+ function initHelpKeyboard() {
206
+ helpCharCount = 0;
207
+ var charEl = document.getElementById('help-char-count');
208
+ if (charEl) charEl.textContent = '0';
209
+ modalBody.querySelectorAll('.hacker-vkey').forEach(function(k) {
210
+ k.addEventListener('click', function() {
211
+ var code = k.getAttribute('data-code');
212
+ highlightKey(code);
213
+ var key = k.getAttribute('data-key');
214
+ var navKeys = ['Shift', 'Ctrl', 'Alt', 'CapsLock', 'Tab', 'Enter', 'Backspace', 'Space', 'Ins', 'Home', 'PgUp', 'Del', 'End', 'PgDn', 'Purge', '↑', '↓', '←', '→'];
215
+ if (key && navKeys.indexOf(key) === -1) {
216
+ helpCharCount++;
217
+ charEl = document.getElementById('help-char-count');
218
+ if (charEl) charEl.textContent = helpCharCount;
219
+ } else if (key === 'Space') {
220
+ helpCharCount++;
221
+ charEl = document.getElementById('help-char-count');
222
+ if (charEl) charEl.textContent = helpCharCount;
223
+ }
224
+ });
225
+ });
226
+ }
227
+
228
+ function handleHelpKeydown(e) {
229
+ if (!modalOverlay.classList.contains('open') || !modalBody.classList.contains('hacker-modal-keyboard')) return;
230
+ if (e.key === 'Escape') return;
231
+ e.preventDefault();
232
+ highlightKey(e.code);
233
+ if (e.key.length === 1) {
234
+ helpCharCount++;
235
+ var charEl = document.getElementById('help-char-count');
236
+ if (charEl) charEl.textContent = helpCharCount;
237
+ }
238
+ }
239
+
240
+ var scriptsTpl = document.getElementById('hacker-scripts-folders-tpl');
241
+ var fallbackModalContent = {
242
+ 'dl-data': { title: 'Downloading...', body: '<div class="hacker-modal-download"><div class="modal-subtitle">Critical Data</div><div class="hacker-modal-progress" id="dl-progress"></div></div>', type: 'progress' },
243
+ ai: { title: 'AI', body: '<pre>~ $ model --status\n\ninference: stable\ncontext: 8k tokens\nlatency: &lt; 200ms\n\n&gt;&gt; system online</pre>' },
244
+ decryptor: { title: 'Password Decryptor', body: '<pre class="hacker-decryptor-pre">Calculating Hashes\n\n<span id="dec-keys">[00:00:01] 0 keys tested</span>\n\nCurrent passphrase: <span id="dec-pass">********</span>\n\nMaster key\n<span id="dec-master1"></span>\n<span id="dec-master2"></span>\n\nTransient key\n<span id="dec-trans1"></span>\n<span id="dec-trans2"></span>\n<span id="dec-trans3"></span>\n<span id="dec-trans4"></span></pre>', type: 'decryptor' },
245
+ help: { title: 'Help', body: '', type: 'keyboard' },
246
+ 'all-scripts': { title: '/root/bash/scripts', body: '', type: 'scripts' },
247
+ };
248
+
249
+ var modalContent = runtimeConfig.modalContent || fallbackModalContent;
250
+ document.querySelectorAll('.hacker-folder[data-modal]').forEach(function(btn) {
251
+ btn.addEventListener('click', function() {
252
+ var id = btn.getAttribute('data-modal');
253
+ var data = modalContent[id];
254
+ if (!data) return;
255
+
256
+ var modalEl = modalOverlay.querySelector('.hacker-modal');
257
+ if (modalEl) modalEl.classList.remove('hacker-modal-wide');
258
+ modalTitle.textContent = data.title;
259
+ modalBody.innerHTML = data.body;
260
+ modalBody.className =
261
+ 'hacker-modal-body' +
262
+ (data.type === 'progress' ? ' hacker-modal-download' : '') +
263
+ (data.type === 'keyboard' ? ' hacker-modal-keyboard' : '') +
264
+ (data.type === 'scripts' ? ' hacker-modal-scripts-wrap' : '');
265
+
266
+ if (data.type === 'progress') {
267
+ var bar = document.getElementById('dl-progress');
268
+ if (bar) {
269
+ bar.innerHTML = '';
270
+ for (var i = 0; i < 48; i++) bar.appendChild(document.createElement('span'));
271
+ var idx = 0;
272
+ function fillNext() {
273
+ if (idx < 48) {
274
+ bar.children[idx].classList.add('filled');
275
+ idx++;
276
+ setTimeout(fillNext, 80 + Math.random() * 60);
277
+ }
278
+ }
279
+ fillNext();
280
+ }
281
+ } else if (data.type === 'decryptor') {
282
+ var el = document.getElementById('dec-keys');
283
+ if (el) el.textContent = '[00:00:01] 0 ' + decryptorKeysLabel;
284
+ el = document.getElementById('dec-pass');
285
+ if (el) el.textContent = randPass();
286
+ el = document.getElementById('dec-master1');
287
+ if (el) el.textContent = randKeyLine(8);
288
+ el = document.getElementById('dec-master2');
289
+ if (el) el.textContent = randKeyLine(8);
290
+ el = document.getElementById('dec-trans1');
291
+ if (el) el.textContent = randKeyLine(7);
292
+ el = document.getElementById('dec-trans2');
293
+ if (el) el.textContent = randKeyLine(7);
294
+ el = document.getElementById('dec-trans3');
295
+ if (el) el.textContent = randKeyLine(8);
296
+ el = document.getElementById('dec-trans4');
297
+ if (el) el.textContent = randKeyLine(8);
298
+ startDecryptorFlash();
299
+ } else if (data.type === 'keyboard') {
300
+ modalBody.innerHTML = buildHelpKeyboard();
301
+ if (modalEl) modalEl.classList.add('hacker-modal-wide');
302
+ initHelpKeyboard();
303
+ document.addEventListener('keydown', handleHelpKeydown);
304
+ } else if (data.type === 'scripts' && scriptsTpl) {
305
+ modalBody.innerHTML = '';
306
+ if ('content' in scriptsTpl && scriptsTpl.content) {
307
+ modalBody.appendChild(scriptsTpl.content.cloneNode(true));
308
+ } else {
309
+ modalBody.appendChild(scriptsTpl.cloneNode(true));
310
+ var cloned = modalBody.querySelector('#hacker-scripts-folders-tpl');
311
+ if (cloned) {
312
+ cloned.removeAttribute('id');
313
+ cloned.hidden = false;
314
+ cloned.removeAttribute('aria-hidden');
315
+ }
316
+ }
317
+ if (modalEl) modalEl.classList.add('hacker-modal-wide');
318
+ }
319
+
320
+ modalOverlay.classList.add('open');
321
+ modalOverlay.setAttribute('aria-hidden', 'false');
322
+ });
323
+ });
324
+
325
+ function closeModal() {
326
+ if (decryptorInterval) {
327
+ clearInterval(decryptorInterval);
328
+ decryptorInterval = null;
329
+ }
330
+ document.removeEventListener('keydown', handleHelpKeydown);
331
+ var modalEl = modalOverlay.querySelector('.hacker-modal');
332
+ if (modalEl) modalEl.classList.remove('hacker-modal-wide');
333
+ modalOverlay.classList.remove('open');
334
+ modalOverlay.setAttribute('aria-hidden', 'true');
335
+ }
336
+
337
+ var closeButton = document.querySelector('.hacker-modal-close');
338
+ if (closeButton) closeButton.addEventListener('click', closeModal);
339
+
340
+ modalOverlay.addEventListener('click', function(e) {
341
+ if (e.target === modalOverlay) closeModal();
342
+ });
343
+
344
+ document.addEventListener('keydown', function(e) {
345
+ if (e.key === 'Escape' && modalOverlay.classList.contains('open')) closeModal();
346
+ });
347
+ }
@@ -0,0 +1,60 @@
1
+ export function initAboutReadingUi(runtimeConfig, prefersReducedMotion) {
2
+ var progress = document.querySelector('.hacker-progress');
3
+ var toast = document.querySelector('.hacker-toast');
4
+ var fallbackToasts = {
5
+ p30: 'context parsed',
6
+ p60: 'inference stable',
7
+ p90: 'output finalized',
8
+ };
9
+ var toastMessages = runtimeConfig.effects && runtimeConfig.effects.scrollToasts
10
+ ? runtimeConfig.effects.scrollToasts
11
+ : fallbackToasts;
12
+ var stageSeen = { p30: false, p60: false, p90: false };
13
+ var toastTimer = 0;
14
+ var hasScrolled = false;
15
+
16
+ function showToast(msg) {
17
+ if (!toast) return;
18
+ toast.textContent = '> ' + msg;
19
+ toast.classList.add('visible');
20
+ clearTimeout(toastTimer);
21
+ toastTimer = setTimeout(function() {
22
+ toast.classList.remove('visible');
23
+ }, 900);
24
+ }
25
+
26
+ if (progress) {
27
+ function onScroll() {
28
+ var scrollTop = window.scrollY || document.documentElement.scrollTop;
29
+ var scrollHeight = document.documentElement.scrollHeight - window.innerHeight;
30
+ var p = scrollHeight > 0 ? Math.min(1, scrollTop / scrollHeight) : 1;
31
+ progress.style.setProperty('--read-progress', String(p));
32
+ var btn = document.querySelector('.hacker-back-to-top');
33
+ if (btn) btn.classList.toggle('visible', scrollTop > 400);
34
+ if (!hasScrolled && scrollTop > 6) hasScrolled = true;
35
+ if (!hasScrolled) return;
36
+ if (!stageSeen.p30 && p >= 0.3) {
37
+ stageSeen.p30 = true;
38
+ showToast(toastMessages.p30 || fallbackToasts.p30);
39
+ }
40
+ if (!stageSeen.p60 && p >= 0.6) {
41
+ stageSeen.p60 = true;
42
+ showToast(toastMessages.p60 || fallbackToasts.p60);
43
+ }
44
+ if (!stageSeen.p90 && p >= 0.9) {
45
+ stageSeen.p90 = true;
46
+ showToast(toastMessages.p90 || fallbackToasts.p90);
47
+ }
48
+ }
49
+
50
+ onScroll();
51
+ window.addEventListener('scroll', onScroll, { passive: true });
52
+ }
53
+
54
+ var backTop = document.querySelector('.hacker-back-to-top');
55
+ if (backTop) {
56
+ backTop.addEventListener('click', function() {
57
+ window.scrollTo({ top: 0, behavior: prefersReducedMotion ? 'auto' : 'smooth' });
58
+ });
59
+ }
60
+ }
@@ -0,0 +1,20 @@
1
+ export function readAboutRuntimeConfig() {
2
+ var runtimeConfig = {};
3
+ var runtimeConfigEl = document.getElementById('hacker-runtime-config');
4
+ if (runtimeConfigEl && runtimeConfigEl.textContent) {
5
+ try {
6
+ runtimeConfig = JSON.parse(runtimeConfigEl.textContent);
7
+ } catch (_err) {
8
+ runtimeConfig = {};
9
+ }
10
+ }
11
+ return runtimeConfig;
12
+ }
13
+
14
+ export function isReducedMotion() {
15
+ try {
16
+ return !!(window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches);
17
+ } catch (_e) {
18
+ return false;
19
+ }
20
+ }