Add images to the header, remove dir.php, it's bloat

This commit is contained in:
speedie 2023-06-20 04:15:06 +02:00
parent 450919b1b3
commit 54c5e89af1
10 changed files with 177 additions and 419 deletions

View file

@ -5,6 +5,7 @@
margin: 0px;
position: sticky;
top: 0;
align-items:center;
}
.warning {
@ -21,9 +22,15 @@
}
.navbar a:hover {
display: inline;
text-decoration: underline;
}
.navbar span {
padding: 5px;
display: inline;
}
.navbar img {
transform: translate(+30%, +25%)
}

418
dir.php
View file

@ -1,418 +0,0 @@
<?php
// MINIXED is a minimal but nice-looking PHP directory indexer.
// More at https://github.com/lorenzos/Minixed
// =============================
// Configuration
// =============================
$browseDirectories = true; // Navigate into sub-folders
$title = 'Index of {{path}}';
$subtitle = '{{files}} objects in this folder, {{size}} total'; // Empty to disable
$breadcrumbs = false; // Make links in {{path}}
$showParent = false; // Display a (parent directory) link
$showDirectories = true;
$showDirectoriesFirst = true; // Lists directories first when sorting by name
$showHiddenFiles = true; // Display files starting with "." too
$alignment = 'left'; // You can use 'left' or 'center'
$showIcons = false;
$dateFormat = 'd/m/y H:i'; // Used in date() function
$sizeDecimals = 1;
$robots = 'noindex, nofollow'; // Avoid robots by default
$showFooter = true; // Display the "Powered by" footer
$openIndex = $browseDirectories && true; // Open index files present in the current directory if $browseDirectories is enabled
$browseDefault = null; // Start on a different "default" directory if $browseDirectories is enabled
$ignore = array("index.php", ".git"); // Names of files and folders to not list (case-sensitive)
// =============================
// =============================
// Who am I?
$_self = basename($_SERVER['PHP_SELF']);
$_path = str_replace('\\', '/', dirname($_SERVER['PHP_SELF']));
$_total = 0;
$_total_size = 0;
// Directory browsing
$_browse = null;
if ($browseDirectories) {
if (!empty($browseDefault) && !isset($_GET['b'])) $_GET['b'] = $browseDefault;
$_GET['b'] = trim(str_replace('\\', '/', (string)@$_GET['b']), '/ ');
$_GET['b'] = str_replace(array('/..', '../'), '', (string)@$_GET['b']); // Avoid going up into filesystem
if (!empty($_GET['b']) && $_GET['b'] != '..' && is_dir($_GET['b'])) {
$browseIgnored = false;
foreach (explode('/', $_GET['b']) as $browseName) {
if (!empty($ignore) && is_array($ignore) && in_array($browseName, $ignore)) {
$browseIgnored = true;
break;
}
}
if (!$browseIgnored) $_browse = $_GET['b']; // Avoid browsing ignored folder names
}
}
// Index open
if (!empty($_browse) && $openIndex) {
$_index = null;
if (file_exists($_browse . "/index.htm")) $_index = "/index.htm";
if (file_exists($_browse . "/index.html")) $_index = "/index.html";
if (file_exists($_browse . "/index.php")) $_index = "/index.php";
if (!empty($_index)) {
header('Location: ' . $_browse . $_index);
exit();
}
}
// Encoded images generator
if (!empty($_GET['i'])) {
header('Content-type: image/png');
switch ($_GET['i']) {
case 'asc': exit(base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAFUlEQVQImWNgoBT8x4JxKsBpAhUAAPUACPhuMItPAAAAAElFTkSuQmCC'));
case 'desc': exit(base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAF0lEQVQImWNgoBb4j0/iPzYF/7FgCgAADegI+OMeBfsAAAAASUVORK5CYII='));
case 'directory': exit(base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAASklEQVQYlYWPwQ3AMAgDb3Tv5AHdR5OqTaBB8gM4bAGApACPRr/XuujA+vqVcAI3swDYjqRSH7B9oHI8grbTgWN+g3+xq0k6TegCNtdPnJDsj8sAAAAASUVORK5CYII='));
case 'file': exit(base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAPklEQVQYlcXQsQ0AIAhE0b//GgzDWGdjDCJoKck13CsIALi7gJxyVmFmyrsXLHEHD7zBmBbezvoJm4cL0OwYouM4O3J+UDYAAAAASUVORK5CYII='));
}
}
// I'm not sure this function is really needed...
function ls($path, $show_folders = false, $show_hidden = false) {
global $_self, $_total, $_total_size, $ignore;
$ls = array();
$ls_d = array();
if (($dh = @opendir($path)) === false) return $ls;
if (substr($path, -1) != '/') $path .= '/';
while (($file = readdir($dh)) !== false) {
if ($file == $_self) continue;
if ($file == '.' || $file == '..') continue;
if (!$show_hidden) if (substr($file, 0, 1) == '.') continue;
if (!empty($ignore) && is_array($ignore) && in_array($file, $ignore)) continue;
$isdir = is_dir($path . $file);
if (!$show_folders && $isdir) continue;
$item = array('name' => $file, 'isdir' => $isdir, 'size' => $isdir ? 0 : filesize($path . $file), 'time' => filemtime($path . $file));
if ($isdir) $ls_d[] = $item; else $ls[] = $item;
$_total++;
$_total_size += $item['size'];
}
return array_merge($ls_d, $ls);
}
// Get the list of files
$items = ls('.' . (empty($_browse) ? '' : '/' . $_browse), $showDirectories, $showHiddenFiles);
// Sort it
function sortByName($a, $b) { global $showDirectoriesFirst; return ($a['isdir'] == $b['isdir'] || !$showDirectoriesFirst ? strtolower($a['name']) > strtolower($b['name']) : $a['isdir'] < $b['isdir']) ? 1 : -1; }
function sortBySize($a, $b) { return ($a['isdir'] == $b['isdir'] ? $a['size'] > $b['size'] : $a['isdir'] < $b['isdir']) ? 1 : -1; }
function sortByTime($a, $b) { return ($a['time'] > $b['time']) ? 1 : -1; }
switch (@$_GET['s']) {
case 'size': $_sort = 'size'; usort($items, 'sortBySize'); break;
case 'time': $_sort = 'time'; usort($items, 'sortByTime'); break;
default : $_sort = 'name'; usort($items, 'sortByName'); break;
}
// Reverse?
$_sort_reverse = (@$_GET['r'] == '1');
if ($_sort_reverse) $items = array_reverse($items);
// Add parent
if ($showParent && $_path != '/' && empty($_browse)) array_unshift($items, array(
'name' => '..',
'isparent' => true,
'isdir' => true,
'size' => 0,
'time' => 0
));
// Add parent in case of browsing a sub-folder
if (!empty($_browse)) array_unshift($items, array(
'name' => '..',
'isparent' => false,
'isdir' => true,
'size' => 0,
'time' => 0
));
// 37.6 MB is better than 39487001
function humanizeFilesize($val, $round = 0) {
$unit = array('','K','M','G','T','P','E','Z','Y');
do { $val /= 1024; array_shift($unit); } while ($val >= 1000);
return sprintf('%.'.intval($round).'f', $val) . ' ' . array_shift($unit) . 'B';
}
// Titles parser
function getTitleHTML($title, $breadcrumbs = false) {
global $_path, $_browse, $_total, $_total_size, $sizeDecimals;
$title = htmlentities(str_replace(array('{{files}}', '{{size}}'), array($_total, humanizeFilesize($_total_size, $sizeDecimals)), $title));
$path = htmlentities($_path);
if ($breadcrumbs) $path = sprintf('<a href="%s">%s</a>', htmlentities(buildLink(array('b' => ''))), $path);
if (!empty($_browse)) {
if ($_path != '/') $path .= '/';
$browseArray = explode('/', trim($_browse, '/'));
foreach ($browseArray as $i => $part) {
if ($breadcrumbs) {
$path .= sprintf('<a href="%s">%s</a>', htmlentities(buildLink(array('b' => implode('/', array_slice($browseArray, 0, $i + 1))))), htmlentities($part));
} else {
$path .= htmlentities($part);
}
if (count($browseArray) > ($i + 1)) $path .= '/';
}
}
return str_replace('{{path}}', $path, $title);
}
// Link builder
function buildLink($changes) {
global $_self;
$params = $_GET;
foreach ($changes as $k => $v) if (is_null($v)) unset($params[$k]); else $params[$k] = $v;
foreach ($params as $k => $v) $params[$k] = urlencode($k) . '=' . urlencode($v);
return empty($params) ? $_self : $_self . '?' . implode('&', $params);
}
?>
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta name="robots" content="<?php echo htmlentities($robots) ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo getTitleHTML($title) ?></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
border: none;
}
body {
text-align: center;
font-family: monospace;
font-size: 8px;
color: #ffffff;
background-color: #000000;
}
#wrapper {
max-width: 600px;
*width: 600px;
margin: 0 auto;
text-align: left;
}
body#left {
text-align: left;
}
body#left #wrapper {
margin: 0 20px;
}
h1 {
font-size: 10px;
padding: 0 10px;
margin: 0px 0 0;
background-color: #222222;
position: sticky;
top: 0;
font-weight: bold;
}
h2 {
font-size: 8px;
padding: 0 10px;
margin: 10px 0 0;
color: #666666;
font-weight: normal;
}
a {
color: #6666ff;
text-decoration: none;
}
a:hover {
color: #6666ff;
text-decoration: underline;
}
ul#header {
margin-top: 20px;
}
ul li {
display: block;
list-style-type: none;
overflow: hidden;
padding: 10px;
}
ul li:hover {
background-color: #222222;
}
ul li .date {
text-align: center;
width: 120px;
}
ul li .size {
text-align: right;
width: 90px;
}
ul li .date, ul li .size {
float: right;
font-size: 8px;
display: block;
color: #666666;
}
ul#header li {
font-size: 8px;
font-weight: bold;
border-bottom: 1px solid #cccccc;
}
ul#header li:hover {
background-color: transparent;
}
ul#header li * {
color: #777777;
font-size: 8px;
}
ul#header li a:hover {
color: #ffffff;
}
ul#header li .asc span, ul#header li .desc span {
padding-right: 15px;
background-position: right center;
background-repeat: no-repeat;
color: #ffffff;
}
ul#header li .asc span {
background-image: url('<?php echo $_self ?>?i=asc');
}
ul#header li .desc span {
background-image: url('<?php echo $_self ?>?i=desc');
}
ul li.item {
border-top: 1px solid #f3f3f3;
}
ul li.item:first-child {
border-top: none;
}
ul li.item .name {
font-weight: bold;
}
ul li.item .directory, ul li.item .file {
padding-left: 20px;
background-position: left center;
background-repeat: no-repeat;
}
ul li.item .directory {
background-image: url('<?php echo $_self ?>?i=directory');
}
ul li.item .file {
background-image: url('<?php echo $_self ?>?i=file');
}
#footer {
color: #cccccc;
font-size: 10px;
margin-top: 40px;
margin-bottom: 20px;
padding: 0 10px;
text-align: left;
}
#footer a {
color: #cccccc;
font-weight: bold;
}
#footer a:hover {
color: #999999;
}
</style>
<link rel="stylesheet" href="/ls.css">
</head>
<body <?php if ($alignment == 'left') echo 'id="left"' ?>>
<div id="wrapper">
<h1><?php echo getTitleHTML($title, $breadcrumbs) ?></h1>
<h2><?php echo getTitleHTML($subtitle, $breadcrumbs) ?></h2>
<ul id="header">
<li>
<a href="<?php echo buildLink(array('s' => 'size', 'r' => (!$_sort_reverse && $_sort == 'size') ? '1' : null)) ?>" class="size <?php if ($_sort == 'size') echo $_sort_reverse ? 'desc' : 'asc' ?>"><span>Size</span></a>
<a href="<?php echo buildLink(array('s' => 'time', 'r' => (!$_sort_reverse && $_sort == 'time') ? '1' : null)) ?>" class="date <?php if ($_sort == 'time') echo $_sort_reverse ? 'desc' : 'asc' ?>"><span>Last modified</span></a>
<a href="<?php echo buildLink(array('s' => null , 'r' => (!$_sort_reverse && $_sort == 'name') ? '1' : null)) ?>" class="name <?php if ($_sort == 'name') echo $_sort_reverse ? 'desc' : 'asc' ?>"><span>Name</span></a>
</li>
</ul>
<ul>
<?php foreach ($items as $item): ?>
<li class="item">
<span class="size"><?php echo $item['isdir'] ? '-' : humanizeFilesize($item['size'], $sizeDecimals) ?></span>
<span class="date"><?php echo (@$item['isparent'] || empty($item['time'])) ? '-' : date($dateFormat, $item['time']) ?></span>
<?php
if ($item['isdir'] && $browseDirectories && !@$item['isparent']) {
if ($item['name'] == '..') {
$itemURL = buildLink(array('b' => substr($_browse, 0, strrpos($_browse, '/'))));
} else {
$itemURL = buildLink(array('b' => (empty($_browse) ? '' : (string)$_browse . '/') . $item['name']));
}
} else {
$itemURL = (empty($_browse) ? '' : str_replace(['%2F', '%2f'], '/', rawurlencode((string)$_browse)) . '/') . rawurlencode($item['name']);
}
?>
<a href="<?php echo htmlentities($itemURL) ?>" class="name <?php if ($showIcons) echo $item['isdir'] ? 'directory' : 'file' ?>"><?php echo htmlentities($item['name']) . ($item['isdir'] ? ' /' : '') ?></a>
</li>
<?php endforeach; ?>
</ul>
<?php if ($showFooter): ?>
<p id="footer">
<a href="https://speedie.site">Home</a>
-
<a href="https://git.speedie.site">Git</a>
-
<a href="https://speedie.site/donate">Donate</a>
</p>
<?php endif; ?>
</div>
</body>
</html>

BIN
img/blog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
img/chat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

1
img/git.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="92pt" height="92pt" viewBox="0 0 92 92"><defs><clipPath id="a"><path d="M0 .113h91.887V92H0Zm0 0"/></clipPath></defs><g clip-path="url(#a)"><path style="stroke:none;fill-rule:nonzero;fill:#f03c2e;fill-opacity:1" d="M90.156 41.965 50.036 1.848a5.918 5.918 0 0 0-8.372 0l-8.328 8.332 10.566 10.566a7.03 7.03 0 0 1 7.23 1.684 7.034 7.034 0 0 1 1.669 7.277l10.187 10.184a7.028 7.028 0 0 1 7.278 1.672 7.04 7.04 0 0 1 0 9.957 7.05 7.05 0 0 1-9.965 0 7.044 7.044 0 0 1-1.528-7.66l-9.5-9.497V59.36a7.04 7.04 0 0 1 1.86 11.29 7.04 7.04 0 0 1-9.957 0 7.04 7.04 0 0 1 0-9.958 7.06 7.06 0 0 1 2.304-1.539V33.926a7.049 7.049 0 0 1-3.82-9.234L29.242 14.272 1.73 41.777a5.925 5.925 0 0 0 0 8.371L41.852 90.27a5.925 5.925 0 0 0 8.37 0l39.934-39.934a5.925 5.925 0 0 0 0-8.371"/></g></svg>

After

Width:  |  Height:  |  Size: 819 B

BIN
img/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

5
img/monero.svg Normal file
View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" >
<path fill="#f2651c" d="M2.629115 66 Q0 58.2 0 50 C0 22.4 22.4 0 50 0 77.6 0 100 22.4 100 50 Q100 58.2 97.370885 66 H82 V22 L50 58.5 18 22 V66 H2.629115 Z" />
<path fill="#4d4d4d" d="M7.291676 76 Q22 100 50 100 Q78 100 92.708324 76 H72 V48 L50 74 28 48 V76 H7.291676 Z" />
</svg>

After

Width:  |  Height:  |  Size: 391 B

BIN
img/projects.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

148
img/rss.svg Normal file
View file

@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="256"
height="256"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.47 r22583"
sodipodi:docname="rss-feed.svg"
version="1.0"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient2555">
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"
offset="0"
id="stop2557" />
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 0;"
offset="1"
id="stop2559" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2555"
id="linearGradient2449"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.5914583,0,0,0.5914584,210.0216,142.2324)"
x1="-344.15295"
y1="274.711"
x2="-395.84943"
y2="425.39993" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="430.42472"
inkscape:cy="131.48311"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:window-width="782"
inkscape:window-height="674"
inkscape:window-x="1"
inkscape:window-y="281"
showgrid="false"
inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:creator>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag />
</dc:subject>
<cc:license
rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
<dc:description />
<dc:contributor>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-373.642,-318.344)">
<rect
inkscape:export-ydpi="7.7063322"
inkscape:export-xdpi="7.7063322"
inkscape:export-filename="C:\Documents and Settings\Molumen\Desktop\path3511111.png"
transform="scale(-1,1)"
ry="35.487503"
rx="35.487503"
y="328.84921"
x="-619.14587"
height="234.98955"
width="235.00784"
id="rect1942"
style="fill:#e15a00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.87500000000000000;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.87500000000000000, 1.75000000000000000;stroke-dashoffset:0;stroke-opacity:1" />
<path
inkscape:export-ydpi="7.7063322"
inkscape:export-xdpi="7.7063322"
inkscape:export-filename="C:\Documents and Settings\Molumen\Desktop\path3511111.png"
sodipodi:nodetypes="ccccsssc"
id="path1950"
d="M 557.05665,338.89518 L 446.22721,338.89518 C 416.89033,338.89518 393.27256,362.70492 393.27256,392.28025 L 393.27256,500.40761 C 394.22216,523.49366 397.87485,508.89915 404.82758,483.3329 C 412.90814,453.61975 439.22406,427.65003 471.27219,408.1872 C 495.73352,393.33195 523.11328,383.84595 572.95174,382.94353 C 601.21656,382.43177 598.72124,346.26062 557.05665,338.89518 z"
style="opacity:0.60747664;fill:url(#linearGradient2449);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.87500000000000000;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.87500000000000000, 1.75000000000000000;stroke-dashoffset:0;stroke-opacity:1" />
<path
sodipodi:type="arc"
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:12;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path5270"
sodipodi:cx="360.35715"
sodipodi:cy="200.64285"
sodipodi:rx="24.642859"
sodipodi:ry="23.928572"
d="m 385.00001,200.64285 c 0,13.21539 -11.03299,23.92857 -24.64286,23.92857 -13.60988,0 -24.64286,-10.71318 -24.64286,-23.92857 0,-13.21538 11.03298,-23.92857 24.64286,-23.92857 13.60987,0 24.64286,10.71319 24.64286,23.92857 z"
transform="matrix(0.8699574,0,0,0.8699574,135.15631,330.52863)" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 427.83482,455.05681 L 427.76203,424.78365 C 492.4681,428.1591 528.38081,474.45682 529.26224,526.72326 L 498.944,526.72326 C 498.44099,480.78249 467.20335,456.72804 427.83482,455.05681 z"
id="path5805"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 428.20143,404.57149 L 427.32264,373.81385 C 526.75104,378.43011 580.00028,450.58197 580.67143,526.72326 L 549.4744,526.28386 C 550.83932,477.58037 514.80871,406.01731 428.20143,404.57149 z"
id="path5807"
sodipodi:nodetypes="ccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

View file

@ -8,6 +8,21 @@
</head>
<body>
<div class="navbar">
<span>speedie's page <a href="https://speedie.site">Home</a> <a href="/project-list.php">Projects</a> <a href="/blog.php">Blog</a> <a href="https://git.speedie.site">Git</a> <a href="https://matrix.speedie.site">Matrix space</a> <a href="/donate.php">Donate</a> <a href="/dir.php">Directory Listing</a></span>
<span>speedie's page
<img src="/img/home.png" width="16" height="16">
<a href="https://speedie.site">Home</a>
<img src="/img/projects.png" width="16" height="16">
<a href="/project-list.php">Projects</a>
<img src="/img/blog.png" width="16" height="16">
<a href="/blog.php">Blog</a>
<img src="/img/rss.svg" width="16" height="16">
<a href="/rss.xml">RSS</a>
<img src="/img/git.svg" width="16" height="16">
<a href="https://git.speedie.site">Git</a>
<img src="/img/chat.png" width="16" height="16">
<a href="https://matrix.speedie.site">Matrix space</a>
<img src="/img/monero.svg" width="16" height="16">
<a href="/donate.php">Donate</a>
</span>
</div>
<div class="content">