Files
reverse-engineering-anything/website/public/index.html
T

898 lines
35 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>REA — Reverse Engineer Anything</title>
<meta
name="description"
content="Inspect apps, binaries and runtime behavior with your coding agent or terminal. REA connects local analysis tools through CLI and MCP."
/>
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="assets/favicon.svg" type="image/svg+xml" />
<link rel="stylesheet" href="assets/styles.css" />
<script src="assets/main.js" defer></script>
<script src="assets/home.js" defer></script>
<script type="module" src="assets/dino-demo.js"></script>
</head>
<body id="top">
<a class="skip-link" href="#main">Skip to content</a>
<header class="site-header">
<div class="container header-inner">
<a class="brand" href="./" aria-label="REA home"
><span class="brand-name">REA</span
><span class="brand-caption">Reverse Engineer Anything</span></a
>
<nav class="navigation" aria-label="Main navigation">
<a href="showcase/">Showcases</a>
<a class="nav-start" href="get-started/">Get started</a>
<a href="guides/">Guides</a>
<a href="faq/">FAQ</a>
</nav>
<a
class="nav-github"
href="https://github.com/morluto/rea"
aria-label="REA on GitHub"
title="REA on GitHub"
>
<svg
width="22"
height="22"
viewBox="0 0 16 16"
aria-hidden="true"
focusable="false"
>
<path
fill="currentColor"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82a7.65 7.65 0 0 1 2-.27c.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z"
/>
</svg>
<span class="nav-github-count" hidden aria-hidden="true"></span>
</a>
</div>
</header>
<main id="main">
<section class="container hero home-hero">
<div class="home-start-grid">
<div>
<p class="eyebrow">Reverse engineering, with your coding agent</p>
<h1>Find out how<br />software works.</h1>
<p class="lede">
REA gives your agent the tools to inspect a program and explain
what it does.
</p>
<div class="actions">
<a class="button" href="#what-is-re">See how REA works ↓</a>
<a class="text-link" href="get-started/">Setup guide</a>
</div>
</div>
<div class="home-setup">
<h2>Set up REA</h2>
<p>Copy this into your coding agent:</p>
<div class="agent-terminal">
<div class="terminal-header">
<span class="terminal-title"
><span class="terminal-dots" aria-hidden="true"
><i></i><i></i><i></i></span
>Your coding agent</span
>
<button
class="copy-button"
type="button"
data-copy="home-install-prompt"
aria-label="Copy REA installation prompt"
>
Copy
</button>
</div>
<p class="terminal-prompt">
<span class="prompt-symbol" aria-hidden="true">›</span
><span id="home-install-prompt"
>Install REA and connect it to this coding agent using npx
rea-agents@latest setup. Show me the setup plan for approval,
then verify the installation.</span
><span class="terminal-cursor" aria-hidden="true"></span>
</p>
</div>
<p class="caption">Or run this in your terminal:</p>
<div class="code-block code-inline">
<code id="setup-command">npx rea-agents@latest setup</code>
<button
class="copy-button"
type="button"
data-copy="setup-command"
aria-label="Copy setup command"
>
Copy
</button>
</div>
<p class="caption">
Approve the setup plan, then restart your agent.
</p>
</div>
</div>
</section>
<section class="section" id="what-is-re">
<div class="container">
<div class="home-definition">
<h2>What is reverse engineering?</h2>
<p class="lede">
Finding out how software works by
<strong>examining the program itself.</strong>
</p>
</div>
<p class="home-purpose">
The goal: understand a feature well enough to
<mark class="prose-highlight">explain it</mark>,
<mark class="prose-highlight">change it</mark> or
<mark class="prose-highlight">rebuild it.</mark>
</p>
<figure class="home-role-comparison">
<div class="manual-investigation">
<p class="comparison-label">Before REA · You investigate</p>
<ol class="manual-steps">
<li>
<span>01</span>
<div>
<strong>Find the relevant code.</strong
><small
>Locate the loaded script or the binary function.</small
>
</div>
</li>
<li>
<span>02</span>
<div>
<strong>Work out its rules.</strong
><small>Follow the inputs, calls and settings.</small>
</div>
</li>
<li>
<span>03</span>
<div>
<strong>Use and check the result.</strong
><small
>Explain the behavior, rebuild it or make a change.</small
>
</div>
</li>
</ol>
</div>
<div class="agent-investigation" id="ask-your-agent">
<p class="comparison-label">With REA · You ask your agent</p>
<div class="agent-terminal home-analysis-terminal">
<div class="terminal-header">
<span class="terminal-title"
><span class="terminal-dots" aria-hidden="true"
><i></i><i></i><i></i></span
>Example question · Dinosaur game</span
>
<button
class="copy-button"
type="button"
data-copy="home-analysis-prompt"
aria-label="Copy dinosaur speed question"
>
Copy
</button>
</div>
<p class="terminal-prompt">
<span class="prompt-symbol" aria-hidden="true">›</span
><span id="home-analysis-prompt"
>Use REA to inspect this dinosaur game. Why does it get
faster? Show the speed rule.</span
><span class="terminal-cursor" aria-hidden="true"></span>
</p>
<div class="agent-reply">
<p class="reply-label">
Example explanation from the findings
</p>
<p>
The game adds a little speed on each update. Its script sets
<strong
>the starting speed, the increment and the stopping
point.</strong
>
</p>
</div>
</div>
</div>
<figcaption>
<strong
>REA supplies code and observations from the program.</strong
>
Your agent uses that evidence to explain, rebuild or test a
feature.
</figcaption>
</figure>
</div>
</section>
<section class="section" id="dinosaur">
<div class="container">
<div class="section-heading">
<p class="eyebrow">Example 01 · Chrome’s dinosaur game</p>
<h2>Why does the dinosaur get faster?</h2>
</div>
<dl class="case-brief">
<div>
<dt>Goal</dt>
<dd>
Rebuild the game with
<mark class="prose-highlight">adjustable speed.</mark>
</dd>
</div>
<div>
<dt>Why reverse engineer it?</dt>
<dd>
To reproduce its acceleration, we need
<strong>the rule in the running game</strong>: how fast it
starts, how much it increases and when it stops.
</dd>
</div>
</dl>
<div class="home-example-grid dino-example-grid">
<figure class="dino-demo" data-dino-demo>
<p class="figure-title">Play the reconstruction</p>
<div class="dino-stage">
<svg
class="dino-fallback"
viewBox="0 0 600 180"
role="img"
aria-label="A small dinosaur running toward a cactus. Recovered speed: starts at 6, increases by 0.001 per update while below 13."
>
<path
d="M0 150H600 M55 113v-30h17V65h27v24H85v17H72v16H62v13h-7v-22m-5-8v-8h-8v-9h-6v22h19m14 15v15h8v-7h-4v-8 M420 150v-48h10v48m-10-15h-12v-22h7v15h5m10-4h12v-22h-7v15h-5"
fill="currentColor"
/>
<text
x="300"
y="65"
text-anchor="middle"
fill="currentColor"
font-size="18"
>
6 → 10 → 13
</text>
</svg>
<canvas
width="600"
height="180"
tabindex="0"
aria-label="Dinosaur mini-game. Use the Jump button or press Space while the game is focused."
hidden
></canvas>
</div>
<div class="dino-controls" hidden>
<div class="dino-buttons">
<button class="button" type="button" data-dino-start>
Play
</button>
<button type="button" data-dino-jump>Jump ↑</button>
<button type="button" data-dino-reset>Restart</button>
</div>
<label class="dino-speed-label"
>Speed <output data-dino-speed>6.0</output
><input
type="range"
min="2"
max="18"
step="0.1"
value="6"
data-dino-slider
/></label>
<label class="dino-auto-label"
><input type="checkbox" data-dino-auto checked /> Use the
recovered acceleration rule</label
>
</div>
<p class="dino-status" data-dino-status role="status">
Original rule: start at 6, then increase toward 13.
</p>
<figcaption>
Move the slider to set your own speed. Space or Jump clears a
cactus.
</figcaption>
<noscript
><p class="caption">
Enable JavaScript to play the reconstruction. The code and
explanation above remain readable.
</p></noscript
>
</figure>
<div>
<div class="rea-finding">
<p class="finding-label">REA returned</p>
<p>
<strong>The script actually running in the page.</strong> The
agent reads its update function and speed settings, then uses
that rule in a new game.
</p>
</div>
<div class="agent-terminal home-analysis-terminal">
<div class="terminal-header">
<span class="terminal-title"
><span class="terminal-dots" aria-hidden="true"
><i></i><i></i><i></i></span
>Example prompt · Dinosaur game</span
>
<button
class="copy-button"
type="button"
data-copy="dino-analysis-prompt"
aria-label="Copy dinosaur analysis prompt"
>
Copy
</button>
</div>
<p class="terminal-prompt">
<span class="prompt-symbol" aria-hidden="true">›</span
><span id="dino-analysis-prompt"
>Use REA to inspect this dinosaur game. Why does it get
faster? Show the speed rule, then build a small version with
an adjustable speed.</span
><span class="terminal-cursor" aria-hidden="true"></span>
</p>
</div>
<p class="caption">
Inspected target:
<a href="https://wayou.github.io/t-rex-runner/"
>wayou’s Chromium-derived browser edition</a
>.
</p>
<div class="code-block">
<div class="code-header">
<span>REA · loaded index.js · selected lines</span>
</div>
<pre><code>if (this.currentSpeed &lt; this.config.MAX_SPEED) {
<span class="code-key">this.currentSpeed += this.config.ACCELERATION;</span>
}</code></pre>
</div>
<p class="dino-rule">
<strong>Start at 6.</strong> Add <strong>0.001</strong> each
update without a collision, while speed is below
<strong>13</strong>.
</p>
<a class="text-link" href="examples/dino-lab/"
>Open the speed lab →</a
>
</div>
</div>
<figure class="workflow-figure dino-loop">
<p class="figure-title">What each part does</p>
<ol class="flow-steps">
<li>
<span class="flow-label">01 · REA</span
><span class="flow-node">Read the running game’s script</span
><span class="flow-note"
>Return its actual code and settings to the agent.</span
>
</li>
<li>
<span class="flow-label">02 · Your agent</span
><span class="flow-node">Rebuild the rule, add a control</span
><span class="flow-note"
>Use the recovered acceleration in a small game with a speed
slider.</span
>
</li>
<li>
<span class="flow-label">03 · You</span
><span class="flow-node">Change the speed and play</span
><span class="flow-note"
>Try the original acceleration, then choose your own
pace.</span
>
</li>
</ol>
</figure>
<details class="home-evidence-details">
<summary>
See the script, checks and how to try the analysis
</summary>
<p>
REA inspected the HTTP browser edition through a local debugging
connection and returned the loaded <code>index.js</code>,
including its source and digest.
</p>
<div class="code-block">
<div class="code-header">
<span>Selected settings from the inspected script</span>
</div>
<pre><code>ACCELERATION: 0.001,
MAX_SPEED: 13,
SPEED: 6</code></pre>
</div>
<p>
We called the original game’s update function in a controlled
browser check, with obstacles and automatic scheduling disabled.
After 4,000 updates, speed was 10.0; after 10,000, it was 13.0,
rounded to one decimal.
</p>
<p>
The new mini-game keeps that speed rule. Its drawing, jumping and
collision code are a small teaching implementation.
<a href="examples/dino-lab/">Open the lab</a> to see the new code
and run the same speed check.
</p>
<p>
To inspect the target yourself, follow the
<a href="guides/browser/#prepare">browser connection steps</a>
using
<a href="https://wayou.github.io/t-rex-runner/"
>the dinosaur page</a
>. Give your agent that page URL and your local debugging
endpoint, then copy the prompt above.
</p>
<p class="caption">
<a
href="https://github.com/wayou/t-rex-runner/blob/5455bfa408ec6b707c7300ff194b7390733a766d/index.js#L565-L571"
>Inspected speed code</a
>
·
<a href="assets/licenses/dinosaur.txt"
>Chromium Authors · BSD license</a
>
</p>
</details>
</div>
</section>
<section class="section" id="calculator">
<div class="container">
<div class="section-heading">
<p class="eyebrow">Example 02 · Windows Calculator</p>
<h2>Why does 200 + 10% give 220?</h2>
</div>
<dl class="case-brief">
<div>
<dt>Goal</dt>
<dd>
Explain the result and
<mark class="prose-highlight"
>recreate Calculator’s % rule.</mark
>
</dd>
</div>
<div>
<dt>Why reverse engineer it?</dt>
<dd>
The same button uses
<strong>different rules after + and ×.</strong> We inspect the
installed app to find which number the percentage is applied to.
</dd>
</div>
</dl>
<div class="home-example-grid">
<figure class="percent-figure" data-percent-demo>
<p class="figure-title">Try the calculation</p>
<div
class="percent-operation"
role="group"
aria-label="Choose the calculation"
hidden
>
<button
type="button"
data-percent-operation="add"
aria-pressed="true"
>
200 + 10%
</button>
<button
type="button"
data-percent-operation="multiply"
aria-pressed="false"
>
200 × 10%
</button>
</div>
<div class="percent-display">
<span class="percent-expression" data-percent-expression
>200 +</span
>
<strong data-percent-display>20</strong>
</div>
<div class="percent-controls" hidden>
<button
type="button"
class="percent-key"
data-percent-key="percent"
>
%
</button>
<button
type="button"
class="percent-key"
data-percent-key="equals"
disabled
>
=
</button>
<button
type="button"
class="percent-reset"
data-percent-key="reset"
>
Reset
</button>
</div>
<p class="percent-status" data-percent-status role="status">
10% of 200 = 20. Then 200 + 20 = 220.
</p>
<figcaption>
Interactive illustration of the inspected percentage rule.
</figcaption>
</figure>
<div class="percent-explanation">
<div class="rea-finding">
<p class="finding-label">REA returned</p>
<p>
<strong
>The % handler’s original instructions and decompiled
code.</strong
>
The agent reads the two branches and explains which rule each
operator uses.
</p>
</div>
<p>
For this example, <code>previous = 200</code> and
<code>current = 10</code>.
</p>
<div class="agent-terminal">
<div class="terminal-header">
<span class="terminal-title"
><span class="terminal-dots" aria-hidden="true"
><i></i><i></i><i></i></span
>Example prompt · Calculator</span
>
<button
class="copy-button"
type="button"
data-copy="calculator-analysis-prompt"
aria-label="Copy Calculator analysis prompt"
>
Copy
</button>
</div>
<p class="terminal-prompt">
<span class="prompt-symbol" aria-hidden="true">›</span
><span id="calculator-analysis-prompt"
>Use REA to inspect Windows Calculator. Why does 200 + 10%
give 220? Show the code behind the % button.</span
><span class="terminal-cursor" aria-hidden="true"></span>
</p>
</div>
<div class="code-block">
<div class="code-header">
<span>Readable summary of the % handler</span>
</div>
<pre><code>if (operation == multiply || operation == divide) {
percent = current / 100;
} else {
<span class="code-key">percent = current * previous / 100;</span>
}</code></pre>
</div>
<dl class="percent-rules">
<div>
<dt>With +</dt>
<dd>
<strong>Take 10% of the first number.</strong
><code>10% of 200 = 20 → 200 + 20 = 220</code>
</dd>
</div>
<div>
<dt>With ×</dt>
<dd>
<strong>Turn 10% into 0.1.</strong
><code>200 × 0.1 = 20</code>
</dd>
</div>
</dl>
</div>
</div>
<figure class="workflow-figure calculator-trace">
<p class="figure-title">From the installed app to an explanation</p>
<ol class="flow-steps">
<li>
<span class="flow-label">01 · REA reads calc.exe</span
><span class="flow-node">It launches the Calculator app</span
><span class="flow-note"
>The code opens <code>ms-calculator:</code>. The agent then
selects the installed app’s library.</span
>
</li>
<li>
<span class="flow-label">02 · REA reads the library</span
><span class="flow-node">Return the % handler’s code</span
><span class="flow-note"
>The function checks the operator and uses the constant
<code>100</code>.</span
>
</li>
<li>
<span class="flow-label">03 · Your agent interprets it</span
><span class="flow-node">Explain and reproduce the rules</span
><span class="flow-note"
>Crosscheck the branch with Microsoft’s source, then try + and
× above.</span
>
</li>
</ol>
</figure>
<details class="home-evidence-details">
<summary>See the real code and how the answer was checked</summary>
<div class="code-comparison">
<div class="code-block">
<div class="code-header">
<span>REA · selected original instructions</span>
</div>
<pre><code>0x180124945: MOV EAX, dword ptr [R13 + 0x18]
0x180124949: <span class="code-key">CMP EAX, 0x5c</span>
0x18012494c: JZ 0x180124aba
0x180124952: <span class="code-key">CMP EAX, 0x5b</span>
0x180124955: JZ 0x180124aba
0x18012495b: <span class="code-key">MOV EDX, 0x64</span></code></pre>
</div>
<div class="code-block">
<div class="code-header">
<span>Operator IDs · Microsoft’s source</span>
</div>
<pre><code>#define IDC_MUL 92 // 0x5c
#define IDC_DIV 91 // 0x5b
#define IDC_PERCENT 118 // 0x76
0x64 = 100</code></pre>
</div>
</div>
<p class="caption">
Inspected with REA 4.1.0: Windows Calculator 11.2508.4.0, x64. The
readable summary uses names from Microsoft’s public source to
explain the recovered branch.
</p>
<p class="caption">
<a
href="https://github.com/microsoft/calculator/blob/d125246a4e19842ce1332e6c7839cf0e110027d8/src/CalcManager/CEngine/scifunc.cpp#L98-L111"
>Percentage implementation</a
>
·
<a
href="https://github.com/microsoft/calculator/blob/d125246a4e19842ce1332e6c7839cf0e110027d8/src/CalculatorUnitTests/CalculatorManagerTest.cpp#L350-L370"
>Microsoft’s test cases</a
>
· <a href="guides/native/">Native setup guide</a>
</p>
</details>
</div>
</section>
<section class="section" id="try-rea">
<div class="container start-row">
<div>
<p class="eyebrow">Your first investigation</p>
<h2>Try REA on a small app.</h2>
<p>
Download our Notes example, trace its CSV export, and check one
changed input.
</p>
</div>
<a class="button" href="first-investigation/"
>Try the guided example</a
>
</div>
</section>
<section class="section">
<div class="container">
<div class="section-heading">
<h2>What REA can analyze</h2>
<p>
Choose a guide for your binary, JavaScript app or browser session.
</p>
</div>
<div class="workflows">
<div>
<h3>Native binaries</h3>
<p>
Inspect functions, strings, references and call relationships in
executables and libraries.
</p>
<a href="guides/native/">Native analysis guide</a>
</div>
<div>
<h3>JavaScript &amp; Electron</h3>
<p>
Map modules, routes, IPC and native dependencies from an
application folder or ASAR archive.
</p>
<a href="guides/javascript/">Application workflows</a>
</div>
<div>
<h3>Browser &amp; runtime activity</h3>
<p>
Capture selected browser or process activity, then compare the
results across runs.
</p>
<a href="guides/browser/">Browser observation guide</a>
</div>
</div>
</div>
</section>
<section class="section">
<div class="container feature-case">
<div>
<p class="eyebrow">Case study · Native</p>
<h2>Rebuilding DX-Ball</h2>
<p>
DX-Ball is a 1996 Windows game. The project is reconstructing it
in C, using REA to inspect the executable and independent tests to
check the recovered behavior.
</p>
<p>
<a class="text-link" href="showcase/dx-ball/"
>Follow the investigation</a
>
</p>
<p class="case-note">
Work so far covers boards, resources, brick hits, animations,
particles and bonus production. The playable game is still in
progress.
</p>
</div>
<dl class="stats case-stats">
<div>
<dt>55</dt>
<dd>functions in maintained C</dd>
</div>
<div>
<dt>45,380</dt>
<dd>original-x86 differential cases</dd>
</div>
<div>
<dt>33</dt>
<dd>complete functions with matching compiled bytes</dd>
</div>
</dl>
</div>
</section>
<section class="section">
<div class="container feature-case">
<div>
<p class="eyebrow">Case study · Electron</p>
<h2>Notion's Electron clipboard</h2>
<p>
A copy operation crosses from the page to Electron's main process.
Inspect Notion's packaged JavaScript with REA, then follow one
channel through the wrappers to the system clipboard.
</p>
<p>
Short code excerpts show each handoff. A second figure explains
how an HTML marker connects ordinary clipboard text to Notion's
structured block data.
</p>
<a class="text-link" href="showcase/notion/"
>Follow the clipboard bridge</a
>
</div>
<figure class="workflow-figure case-preview">
<p class="figure-title">Clipboard IPC channel</p>
<div class="code-block">
<div class="code-header"><span>Preload · send</span></div>
<pre><code>invokerInMain(
<span class="notion-channel">"notion:clipboard:write"</span>
)</code></pre>
</div>
<div class="code-block">
<div class="code-header"><span>Main process · receive</span></div>
<pre><code>addListener(
<span class="notion-channel">"notion:clipboard:write"</span>,
handler
)</code></pre>
</div>
<figcaption>
Matching names give the investigation a path to follow.
</figcaption>
</figure>
</div>
</section>
<section class="section">
<div class="container feature-case">
<div>
<p class="eyebrow">Case study · PC-98 DOS</p>
<h2>TH04's aimed bullet rings</h2>
<p>
Inspect a 16-bit DOS function with REA. Follow its angle
calculation from original instructions to readable C++, then see
how adding the player's direction turns a ring of bullets.
</p>
<a class="text-link" href="showcase/th04/"
>See the bullet calculation</a
>
</div>
<figure class="workflow-figure case-preview th04-preview">
<p class="figure-title">Fixed and aimed rings</p>
<img
src="assets/figures/th04-bullet-ring.svg"
width="1000"
height="520"
alt="TH04's fixed and aimed 16-bullet rings side by side. The first bullet is highlighted in blue; adding the player direction rotates every bullet while preserving the spacing."
loading="lazy"
decoding="async"
/>
<figcaption>
Adding the player's direction rotates every bullet by the same
angle.
</figcaption>
</figure>
</div>
</section>
<section class="section">
<div class="container feature-case">
<div>
<p class="eyebrow">Case study · CTF</p>
<h2>Solve a CTF flag checker</h2>
<p>
Use REA to inspect an easy DownUnderCTF binary. Extract its
checking rules, solve for the flag and confirm that the original
program accepts it.
</p>
<a class="text-link" href="showcase/ctf/">See the CTF solution</a>
</div>
<figure class="workflow-figure case-preview">
<p class="figure-title">One check reveals one character</p>
<div class="code-block">
<div class="code-header">
<span>From REA's code and data</span>
</div>
<pre><code>Mask: skip 21, select 1, skip 14
Target: 55
code[21] = 55 → '7'</code></pre>
</div>
<figcaption>
Each mask selects characters whose codes must add up to a stored
number. This one selects a single character.
</figcaption>
</figure>
</div>
</section>
<section class="section">
<div class="container start-row">
<div>
<h2>What would you like to understand?</h2>
<p>
Connect REA to your coding agent, or run your first analysis from
the terminal.
</p>
</div>
<a class="button" href="get-started/">Get started</a>
</div>
</section>
</main>
<footer class="site-footer">
<div class="container footer-inner">
<p>REA · Reverse Engineer Anything</p>
<div class="footer-links">
<a href="https://github.com/morluto/rea">Source</a
><a href="https://github.com/morluto/rea/blob/main/LICENSE"
>MIT license</a
><a href="https://discord.gg/GkcryMnJDM">Community</a>
</div>
</div>
</footer>
<p class="sr-only" id="copy-status" role="status" aria-live="polite"></p>
<a class="back-to-top" href="#top" aria-label="Back to top">
<span aria-hidden="true">↑</span> Top
</a>
</body>
</html>