PageSourceSearch

https://webcade.fun/konami.js?v=1025436e

js webcade.fun collected 2026-10-08 08:27:09 UTC 2,556 bytes, 62 lines download raw bytes

1// ↑ ↑ ↓ ↓ ← → ← → B A.
2//
3// The code cycles the CRT phosphor: standard → green → amber → standard. It
4// recolors every game screen on the site — the cabinet canvases and the home
5// card previews — and the choice persists, because someone who dug up the
6// Konami code and picked amber meant it.
7//
8// Applied at load on every page that includes this file, so the mode follows
9// the player around the arcade. Purely cosmetic: a CSS class on <html>, a
10// filter on the canvases, and nothing the games or the server ever see.
11(() => {
12  const KEY = 'webcade-phosphor';
13  const MODES = ['', 'green', 'amber'];
14  const NAMES = { green: 'GREEN PHOSPHOR', amber: 'AMBER PHOSPHOR', '': 'STANDARD CRT' };
15
16  const saved = () => { try { return localStorage.getItem(KEY) || ''; } catch (_) { return ''; } };
17  const remember = m => { try { m ? localStorage.setItem(KEY, m) : localStorage.removeItem(KEY); } catch (_) {} };
18
19  function apply(mode) {
20    const root = document.documentElement;
21    for (const m of MODES) if (m) root.classList.remove('phosphor-' + m);
22    if (mode) root.classList.add('phosphor-' + mode);
23  }
24
25  apply(saved());
26
27  function toast(text) {
28    const old = document.getElementById('konami-toast');
29    if (old) old.remove();
30    const t = document.createElement('div');
31    t.id = 'konami-toast';
32    t.textContent = text;
33    document.body.appendChild(t);
34    setTimeout(() => t.remove(), 2600);
35  }
36
37  const SEQ = ['arrowup', 'arrowup', 'arrowdown', 'arrowdown',
38               'arrowleft', 'arrowright', 'arrowleft', 'arrowright', 'b', 'a'];
39  let at = 0;
40
41  // Capture phase, deliberately: the home page's attract code swallows the
42  // arrow keys with stopPropagation in ITS capture listener so the demos'
43  // handlers never scroll-lock the page — and stopPropagation still runs the
44  // remaining listeners on the same node, so listening on document in capture
45  // is the one register that hears the code everywhere.
46  document.addEventListener('keydown', e => {
47    const k = String(e.key || '').toLowerCase();
48    if (k === SEQ[at]) {
49      at++;
50      if (at < SEQ.length) return;
51      at = 0;
52      const next = MODES[(MODES.indexOf(saved()) + 1) % MODES.length];
53      remember(next);
54      apply(next);
55      if (window.SFX) SFX.play('fanfare');
56      toast(next ? '★ ' + NAMES[next] + ' UNLOCKED ★' : NAMES[''] + ' RESTORED');
57    } else {
58      // a broken run can still be the start of a new one (↑↑↑↑↓↓... counts)
59      at = k === SEQ[0] ? 1 : 0;
60    }
61  }, true);
62})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.