at main 914 lines 36 kB view raw
1#! /usr/bin/env python3 2 3import datetime 4import os 5import shutil 6import subprocess 7 8 9def run(*args): 10 subprocess.call(args) 11 12 13def main(): 14 time = datetime.datetime.now() 15 time_id = time.strftime('%Y%m%d%H%M%S') 16 style = 'css' 17 script = 'js' 18 root = os.path.dirname(os.path.realpath(__file__)) 19 input_directory = os.path.join(root, 'in') 20 out = os.path.join(root, 'out') 21 web = os.path.join(out, 'web') 22 if os.path.exists(web): 23 shutil.rmtree(web) 24 os.makedirs(web) 25 gen = os.path.join(web, time_id) 26 css = os.path.join(gen, style) 27 js = os.path.join(gen, script) 28 # 29 run('rsync', '--archive', f'{input_directory}/', f'{web}/') 30 for directory in [css, js]: 31 os.makedirs(directory) 32 # 33 link_gv = os.path.join(root, 'link.gv') 34 link_svg = os.path.join(gen, 'link.svg') 35 run('dot', link_gv, '-Tsvg', '-o', link_svg) 36 with open(link_svg, 'br') as f: 37 link_text = f.read().decode('u8') 38 page_file = os.path.join(web, 'index.html') 39 page_text = f'''\ 40<!DOCTYPE html> 41 42<html> 43 44<head> 45<meta charset="UTF-8" /> 46<meta name="viewport" content="initial-scale=1,width=device-width" /> 47<link rel="stylesheet" href="{time_id}/{style}/index.css" /> 48<script src="{time_id}/{script}/index.js"></script> 49<title>Marc Beninca</title> 50</head> 51 52<body onload="main()"> 53 54<main> 55 56<div class="tabs"> 57 <input type="radio" onclick="update(id)" 58 name="tab" id="tab/my" /> 59 <label for="tab/my">My/</label> 60 <div><div class="tabs"> 61<!-- 62 <input type="radio" onclick="update(id)" 63 name="tab/my" id="tab/my/about" /> 64 <label for="tab/my/about">About</label> 65 <div>{tabs['about']}</div> 66 <input type="radio" onclick="update(id)" 67 name="tab/my" id="tab/my/bio" /> 68 <label for="tab/my/bio">Bio</label> 69 <div>{tabs['bio']}</div> 70--> 71 <input type="radio" onclick="update(id)" 72 name="tab/my" id="tab/my/cv" /> 73 <label for="tab/my/cv">CV</label> 74 <div>{tabs['cv']}</div> 75 <input type="radio" onclick="update(id)" 76 name="tab/my" id="tab/my/profiles" /> 77 <label for="tab/my/profiles">Profiles</label> 78 <div>{tabs['profiles']}</div> 79 <input type="radio" onclick="update(id)" 80 name="tab/my" id="tab/my/projects" /> 81 <label for="tab/my/projects">Projects</label> 82 <div><div class="tabs"> 83 <input type="radio" onclick="update(id)" 84 name="tab/my/projects" id="tab/my/projects/lsgm" /> 85 <label for="tab/my/projects/lsgm">LSGM</label> 86 <div>{tabs['lsgm']}</div> 87 <input type="radio" onclick="update(id)" 88 name="tab/my/projects" id="tab/my/projects/ofsp" /> 89 <label for="tab/my/projects/ofsp">OFSP</label> 90 <div>{tabs['ofsp']}</div> 91 </div></div> 92 <input type="radio" onclick="update(id)" 93 name="tab/my" id="tab/my/tasks" /> 94 <label for="tab/my/tasks">Tasks</label> 95 <div>{tabs['tasks']}</div> 96 <input type="radio" onclick="update(id)" 97 name="tab/my" id="tab/my/trips" /> 98 <label for="tab/my/trips">Trips</label> 99 <div>{tabs['trips']}</div> 100 <input type="radio" onclick="update(id)" 101 name="tab/my" id="tab/my/sub" /> 102 <label for="tab/my/sub">…/</label> 103 <div><div class="tabs"> 104 <input type="radio" onclick="update(id)" 105 name="tab/my/sub" id="tab/my/sub/id" /> 106 <label for="tab/my/sub/id">Identity</label> 107 <div>{tabs['id']}</div> 108 <input type="radio" onclick="update(id)" 109 name="tab/my/sub" id="tab/my/sub/links" /> 110 <label for="tab/my/sub/links">Links</label> 111 <div>{tabs['links']}</div> 112 <input type="radio" onclick="update(id)" 113 name="tab/my/sub" id="tab/my/sub/repos" /> 114 <label for="tab/my/sub/repos">Repos</label> 115 <div>{tabs['repos']}</div> 116 <input type="radio" onclick="update(id)" 117 name="tab/my/sub" id="tab/my/sub/others" /> 118 <label for="tab/my/sub/others">…</label> 119 <div>{tabs['others']}</div> 120 </div></div> 121 </div></div> 122 <input type="radio" onclick="update(id)" 123 name="tab" id="tab/learn" /> 124 <label for="tab/learn">Learn</label> 125 <div>{tabs['learn']}</div> 126 <input type="radio" onclick="update(id)" 127 name="tab" id="tab/music" /> 128 <label for="tab/music">Music</label> 129 <div>{tabs['music']}</div> 130 <input type="radio" onclick="update(id)" 131 name="tab" id="tab/sites" /> 132 <label for="tab/sites">Sites/</label> 133 <div><div class="tabs"> 134 <input type="radio" onclick="update(id)" 135 name="tab/sites" id="tab/sites/books" /> 136 <label for="tab/sites/books">Books</label> 137 <div>{tabs['books']}</div> 138 <input type="radio" onclick="update(id)" 139 name="tab/sites" id="tab/sites/buy" /> 140 <label for="tab/sites/buy">Buy</label> 141 <div>{tabs['buy']}</div> 142 <input type="radio" onclick="update(id)" 143 name="tab/sites" id="tab/sites/social" /> 144 <label for="tab/sites/social">Social</label> 145 <div>{tabs['social']}</div> 146 <input type="radio" onclick="update(id)" 147 name="tab/sites" id="tab/sites/software" /> 148 <label for="tab/sites/software">Software</label> 149 <div>{tabs['software']}</div> 150 </div></div> 151 <input type="radio" onclick="update(id)" 152 name="tab" id="tab/videos" /> 153 <label for="tab/videos">Videos/</label> 154 <div><div class="tabs"> 155 <input type="radio" onclick="update(id)" 156 name="tab/videos" id="tab/videos/comments" /> 157 <label for="tab/videos/comments">Comments</label> 158 <div>{tabs['comments']}</div> 159 <input type="radio" onclick="update(id)" 160 name="tab/videos" id="tab/videos/health" /> 161 <label for="tab/videos/health">Health</label> 162 <div>{tabs['health']}</div> 163 <input type="radio" onclick="update(id)" 164 name="tab/videos" id="tab/videos/vegan" /> 165 <label for="tab/videos/vegan">Vegan</label> 166 <div>{tabs['vegan']}</div> 167 </div></div> 168 <input type="radio" onclick="update(id)" 169 name="tab" id="tab/sub" /> 170 <label for="tab/sub">…/</label> 171 <div><div class="tabs"> 172 <input type="radio" onclick="update(id)" 173 name="tab/sub" id="tab/sub/style" /> 174 <label for="tab/sub/style">Style</label> 175 <div>{tabs['style']}</div> 176 <input type="radio" onclick="update(id)" 177 name="tab/sub" id="tab/sub/unsorted" /> 178 <label for="tab/sub/unsorted">…</label> 179 <div>{tabs['unsorted']}</div> 180 </div></div> 181</div> 182 183</main> 184 185<footer> 186<hr /> 187Last update: {time.strftime('%Y/%m/%d %H:%M:%S')} 188</footer> 189 190</body> 191 192</html> 193''' 194 css_file = os.path.join(css, 'index.css') 195 css_text = f'''\ 196@media screen and (max-aspect-ratio: 10/16) {{ 197 198body {{ 199font-size: 2em; 200}} 201 202}} 203 204body {{ 205background: rgb(255,255,255); 206color: rgb(0,0,0); 207font-family: sans; 208margin: .5em; 209}} 210body.dark {{ 211background: rgb(0,0,0); 212color: rgb(160,160,160); 213}} 214 215header {{ 216background-image: url("../img/debian.jpeg"); 217background-position: center; 218background-size: cover; 219display: flex; 220flex-wrap: wrap; 221}} 222 223.tabs {{ 224display: flex; 225flex-wrap: wrap; 226}} 227.tabs .tabs {{ 228padding: .5em 0 0 0; 229}} 230.tabs > input {{ 231display: none; 232}} 233.tabs > input:checked + label + div {{ 234display: block; 235}} 236.tabs > label {{ 237order: 1; 238}} 239.tabs > div {{ 240display: none; 241flex-basis: 100%; 242order: 2; 243}} 244 245.tabs {{ 246margin: 0; 247}} 248.tabs > input:checked + label {{ 249background: linear-gradient(rgba(128,128,128,1), rgba(128,128,128,0)); 250}} 251.tabs > label {{ 252background: linear-gradient(rgba(64,64,64,1), rgba(64,64,64,0)); 253border-color: rgb(128,128,128); 254border-radius: .5em; 255border-style: solid; 256border-width: 1px 1px 0 1px; 257font-weight: bold; 258margin: 0; 259padding: .5em 1.5em; 260}} 261.tabs > label:hover {{ 262background: linear-gradient(rgba(64,64,64,0), rgba(64,64,64,1)); 263color: rgb(192,0,0); 264}} 265.tabs > div {{ 266margin: 0; 267}} 268 269a {{ 270color: rgb(0,192,192); 271text-decoration: none; 272}} 273a:hover {{ 274color: rgb(192,0,0); 275}} 276a:visited {{ 277color: rgb(0,160,160); 278}} 279 280img {{ 281border: 1px solid; 282border-color: rgb(192,192,192); 283border-radius: 1em; 284height: 8em; 285}} 286 287table {{ 288empty-cells: hide; 289}} 290th,td {{ 291border-radius: .2em; 292}} 293th:hover,td:hover {{ 294background: rgb(48,0,0); 295}} 296th {{ 297background: rgb(64,64,64); 298color: rgb(128,128,0); 299}} 300td {{ 301background: rgb(48,48,48); 302border: 1px solid; 303border-color: rgb(192,192,192); 304text-align: center; 305}} 306 307.cards {{ 308display: flex; 309}} 310.card {{ 311list-style: none; 312margin: 0 1em; 313text-align: center; 314}} 315.card img {{ 316border: none; 317height: 3em; 318}} 319 320.debug {{ 321border-color: rgb(255,0,255); 322border-style: solid; 323border-width: 1px; 324}} 325''' 326 js_file = os.path.join(js, 'index.js') 327 js_text = f'''\ 328function check(tab) {{ 329 const tabs = tab.split('/') 330 let id = 'tab' 331 let element 332 for (tab of tabs) {{ 333 id = `${{id}}/${{tab}}` 334 element = document.getElementById(id) 335 if (element) {{ 336 element.checked = true 337 }} 338 }} 339}} 340 341function debug() {{ 342 for (element of document.getElementsByTagName('*')) {{ 343 element.classList.toggle('debug') 344 }} 345}} 346 347function push(tab) {{ 348 window.history.pushState(null, null, `?tab=${{tab}}`) 349}} 350 351function update(id) {{ 352 const tab = id.split('/').slice(1).join('/') 353 push(tab) 354}} 355 356function main() {{ 357 let tab = (new URL(document.location)).searchParams.get('tab') 358 if (tab) {{ 359 check(tab) 360 }} else {{ 361 tab = 'my/profiles' 362 check(tab) 363 push(tab) 364 }} 365 const dark = document.getElementById('dark') 366 if (dark) {{ 367 dark.click() 368 }} 369}} 370 371function swap() {{ 372 document.body.classList.toggle('dark') 373}} 374''' 375# {link_text} 376 with open(page_file, 'bw') as f: 377 f.write(page_text.encode('u8')) 378 with open(css_file, 'bw') as f: 379 f.write(css_text.encode('u8')) 380 with open(js_file, 'bw') as f: 381 f.write(js_text.encode('u8')) 382 383 384tabs = { 385#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 386 'about': f'''\ 387About… 388''', 389#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 390 'bio': f'''\ 391<h1>Marc Beninca</h1> 392Welcome to a recap attempt of my IT life! 393 394<h2>The early days</h2> 395In my primary school days I started to interact with computers at home, 396mainly Amstrad CPC 464 & 6128 machines.<br /> 397It was the occasion for me to: 398<ul> 399<li>discover computer architectures</li> 400<li>learn how to program in BASIC</li> 401<li>suffer the noise and speed of tape recorders</li> 402<li>experience the revolution of floppy disks transfer rates</li> 403</ul> 404 405<h2>Diving in</h2> 406Right before beginning high school, I was introduced to the PC platform.<br /> 407The “system programming PC bible” was my reference for a long time.<br /> 408I had the occasion to develop projects in: 409<ul> 410<li>Pascal (for example my own hexadecimal file editor)</li> 411<li>Assembly (mainly for critical subroutines performance)</li> 412<li>AutoLISP (automation in LISP of AutoCAD elements processing)</li> 413</ul> 414 415To be continued… 416''', 417#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 418 'books': f'''\ 419<ul> 420<li><a href="https://www.tradepub.com">TradePub</a></li> 421</ul> 422''', 423#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 424 'buy': f'''\ 425<ul> 426<li><a href="https://www.i-comparateur.com">i-comparateur</a></li> 427</ul> 428<hr /> 429<ul> 430<li><a href="https://www.amazon.fr">Amazon</a><ul> 431 <li><a href="https://www.amazon.fr/SanDisk-Extreme-externe-000-Mo-mousqueton/dp/B08RX3343D">SanDisk Extreme Pro</a></li> 432</ul></li> 433</ul> 434<hr /> 435<ul> 436<li><a href="https://www.gl-inet.com/products">GL-iNet</a></li> 437<li>OVH<ul> 438 <li><a href="https://checkservers.ovh">check servers</a></li> 439 <li><a href="https://eco.ovhcloud.com/fr/#filterValue=kimsufi,so">eco</a></li> 440</ul></li> 441<li><a href="https://www.thinkpenguin.com">ThinkPenguin</a></li> 442<li><a href="https://www.tuxedocomputers.com">Tuxedo Computers</a></li> 443<li><a href="https://vollebak.com/collections">Vollebak</a></li> 444</ul> 445<hr /> 446<ul> 447<li><a href="https://www.leboncoin.fr">Le bon coin</a></li> 448</ul> 449''', 450#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 451 'comments': f'''\ 452<ul> 453<li><a href="https://www.youtube.com/@LogicallyAnswered/videos">Logically Answered</a></li> 454</ul> 455''', 456#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 457 'cv': f'''\ 458<ul class="cards"> 459<li class="card"><a href="https://cv.marc.beninca.link/en"> 460<img src="img/en.svg" /><br />English</a></li> 461<li class="card"><a href="https://cv.marc.beninca.link/fr"> 462<img src="img/fr.svg" /><br />Français</a></li> 463</ul> 464''', 465#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 466 'repos': f'''\ 467<ul> 468<li><a href="https://forge.rwx.work/marc.beninca">RWX</a></li> 469</ul><ul> 470<li><a href="https://codeberg.org/marc.beninca">CodeBerg</a></li> 471<li><a href="https://git.disroot.org/marc.beninca">DisRoot</a></li> 472<li><a href="https://git.froggi.es/marc.beninca">Froggies</a></li> 473<li><a href="https://gitdab.com/marc.beninca">GitDab</a></li> 474<li><a href="https://gitnet.fr/marc.beninca">GitNet</a></li> 475<li><a href="https://git.nixnet.services/marc.beninca">NixNet</a></li> 476</ul><hr /><ul> 477<li><a href="https://framagit.org/marc.beninca">FramaGit</a></li> 478<li><a href="https://gitgud.io/marc.beninca">GitGud</a></li> 479<li><a href="https://git.insomnia247.nl/marc.beninca">Insomnia</a></li> 480<li><a href="https://forge.tedomum.net/marc.beninca">TeDomum</a></li> 481</ul><hr /><ul> 482<li><a href="https://git.42l.fr/marc.beninca">42l</a></li> 483<li><a href="https://git.afpy.org/marc.beninca">AFPy</a></li> 484<li><a href="https://forge.chapril.org/marc.beninca">Chapril</a></li> 485<li><a href="https://git.envs.net/marc.beninca">Envs</a></li> 486<li><a href="https://git.fsfe.org/marc.beninca">FSFE</a></li> 487<li><a href="https://git.projectsegfau.lt/marc.beninca">ProjectSegfault</a></li> 488<!--<li><a href="https://silica.codes/marc.beninca">SilicaCodes</a></li>--> 489<li><a href="https://tildegit.org/marc.beninca">TildeGit</a></li> 490</ul> 491 492<hr /> 493 494<ul> 495<li><a href="https://notabug.org/marc.beninca">NotABug</a></li> 496<li><a href="https://pagure.io/user/marc-beninca">Pagure</a></li> 497<li><a href="https://rocketgit.com/marc.beninca">RocketGit</a></li> 498<li><a href="https://sr.ht/~marc_beninca/rwx.work/sources">SourceHut</a></li> 499<li><a href="https://git.tilde.institute/mspe">TildeInstitute</a></li> 500</ul> 501 502<hr /> 503 504<ul> 505<li>Gforge</li> 506</ul> 507''', 508#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 509 'health': f'''\ 510<ul> 511<li><a href="https://www.youtube.com/@chubbyemu/videos">Chubby Emu</a></li> 512<li><a href="https://www.youtube.com/@drekberg/videos">Sten Ekberg</a></li> 513</ul> 514<ul> 515<li><a href="https://www.youtube.com/@KianaDocherty/videos">Kiana Docherty</a></li> 516<li><a href="https://www.youtube.com/@ThomasDeLauerOfficial/videos">Thomas DeLauer</a></li> 517</ul> 518<hr /> 519<ul> 520<li><a href="https://www.youtube.com/@ivredevie/videos">Ivre de vie</a></li> 521</ul> 522''', 523#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 524 'id': f'''\ 525<table> 526 527<tr><th colspan="2">OpenPGP</th><td colspan="3" rowspan="4"><img src="img/marc.jpeg" /></td></tr> 528<tr><td colspan="2">marc.beninca.link<br><a href="marc.beninca.pgp">binary</a> | <a href="marc.beninca.asc">textual</a></td></tr> 529<tr><td colspan="2"><a href="https://meta.sr.ht/~marc_beninca.pgp">meta.sr.ht</a></td></tr> 530<tr><td colspan="2"><a href="https://keys.openpgp.org/search?q=marc@beninca.link">keys.openpgp.org</a></td></tr> 531 532<tr> 533<th><a href="https://keyoxide.org/08EDA7006234A0EB29A3A8471DBD5EC4BADA5579">KeyOxide<br>PGP</a></th> 534<th><a href="https://keyoxide.org/aspe:keyoxide.org:WUD5YVN52J3RJ6CD4ZCWYL6S54">KeyOxide<br>ASP</a></th> 535<th><a href="https://liberapay.com/marc.beninca">Libera<br>Pay</a></th> 536<th><a href="https://patreon.com/marc_beninca">Patreon</a></th> 537<th><a href="https://tipeee.com/marc-beninca">Tip<br>eee</a></th> 538</tr> 539 540<tr> 541<td colspan="3"><a href="https://mastodon.cloud/@marc_beninca">Mastodon</a></td> 542<td colspan="2"><a href="https://discord.gg/v6p7CtZ4Zh">Discord</a></td> 543</tr><tr> 544<td colspan="3"><a href="https://devs.live/users/marc_beninca">Pleroma</a></td> 545<td><a href="https://vimeo.com/marcbeninca">Vimeo</a></td> 546</tr><tr> 547<td colspan="2"><a href="https://videos.trom.tf/@marc_beninca">PeerTube</a></td> 548<td><a href="https://openstreetmap.org/user/Marc Beninca">OpenStreetMap</a></td> 549<td><a href="https://youtube.com/@marc.beninca">YouTube</a></td> 550</tr><tr> 551<td colspan="2"><a href="https://pixelfed.social/marc.beninca">PixelFed</a></td> 552<td><a href="https://linuxfr.org/users/marc-beninca">LinuxFR</a></td> 553<td><a href="https://instagram.com/marc.beninca">Instagram</a></td> 554</tr><tr> 555<td colspan="2"><a href="https://rant.li/marc-beninca">WriteFreely</a></td> 556</tr><tr> 557<td colspan="2"><a href="https://programming.dev/u/marc_beninca">Lemmy</a></td> 558</tr><tr> 559<td colspan="2"><a href="https://lobste.rs/u/marc_beninca">Lobsters</a></td> 560</tr><tr> 561<td colspan="2"><a href="https://news.ycombinator.com/user?id=marc_beninca">HackerNews</a></td> 562</tr> 563 564<tr><th colspan="2">DNS</th></tr> 565 566<tr><td colspan="2"><a href="https://beninca.link">beninca.link</a></td></tr> 567<tr><td colspan="2">computing.land</td></tr> 568<tr><td colspan="2">marc-beninca.fr</td></tr> 569<tr><td colspan="2"><a href="https://rwx.work">rwx.work</a></td></tr> 570<tr><td colspan="2"><a href="https://tilde.link">tilde.link</a></td></tr> 571 572<tr><th colspan="2">Git / Forgejo</th></tr> 573 574<tr><td colspan="2"><a href="https://forge.rwx.work/marc.beninca">forge.rwx.work</a></td></tr> 575 576</table> 577''', 578#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 579 'learn': f'''\ 580<ul> 581<li><a href="https://roadmap.sh">Roadmap</a></li> 582<li><a href="https://teachyourselfcs.com">Teach Yourself Computer Science</a></li> 583</ul> 584<hr /> 585<ul> 586<li><a href="https://www.youtube.com/@ExternCode/videos">Extern Code</a></li> 587<li><a href="https://www.youtube.com/@freecodecamp/videos">FreeCodeCamp</a></li> 588<li><a href="https://debian-facile.org/projets/lescahiersdudebutant">Les cahiers du débutant sur Debian</a></li> 589<li><a href="https://www.youtube.com/@SimplicodeOfficial/videos">SimpliCode</a></li> 590</ul> 591<hr /> 592<ul> 593<li><a href="https://overthewire.org">Over The Wire</a></li> 594</ul> 595''', 596#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 597 'links': f'''\ 598<ul> 599<li><a href="https://marc-beninca.8b.io">8bio</a></li> 600<li><a href="https://allmylinks.com/marc-beninca">AllMyLinks</a></li> 601<li><a href="https://beacons.ai/marc.beninca">Beacons</a></li> 602<li><a href="https://biglink.to/marc_beninca">BigLinkTo</a></li> 603<li><a href="https://bioin.link/marc.beninca">BioInLink</a></li> 604<li><a href="https://marc_beninca.bio.link">Bio.Link</a></li> 605<li><a href="https://biolinky.co/marcbeninca">BioLinky</a></li> 606<li><a href="https://marc_beninca.c8ke.com">C8ke</a></li> 607<li><a href="https://campsite.bio/marc.beninca">CampSite</a></li> 608<li><a href="https://marc-beninca.carrd.co">Carrd</a></li> 609<li><a href="https://direct.me/marc_beninca">DirectMe</a></li> 610<li><a href="https://everlink.tools/marc.beninca">EverLink</a></li> 611<li><a href="https://feedlink.io/marcbeninca">FeedLink</a></li> 612<li><a href="https://flow.page/marc.beninca">FlowPage</a></li> 613<li><a href="https://heylink.me/marc.beninca">HeyLinkMe</a></li> 614<li><a href="https://hy.page/marcbeninca">HyPage</a></li> 615<li><a href="https://ichi.gg/marc.beninca">Ichi.GG</a></li> 616<li><a href="https://linkfly.to/marc-beninca">LinkFly</a></li> 617<li><a href="https://instabio.cc/marc-beninca">LinkInBio</a></li> 618<li><a href="https://linkpluto.com/marc-beninca">LinkPluto</a></li> 619<li><a href="https://linkpop.com/marc-beninca">LinkPop</a></li> 620<li><a href="https://linkr.bio/marc.beninca">Linkr.Bio</a></li> 621<li><a href="https://linksight.me/marc_beninca">LinkSight</a></li> 622<li><a href="https://link.space/@marc_beninca">LinkSpace</a></li> 623<li><a href="https://linkstack.fr/@marc.beninca">LinkStack</a></li> 624<li><a href="https://linktr.ee/marc.beninca">LinkTree</a></li> 625<li><a href="https://lnk.bio/marc.beninca">Lnk.Bio</a></li> 626<li><a href="https://lu.ma/marc.beninca">Luma</a></li> 627<li><a href="https://nano.site/marc.beninca">NanoSite</a></li> 628<li><a href="https://marcbeninca.podia.com">Podia</a></li> 629<li><a href="https://solo.to/marc.beninca">SoloTo</a></li> 630<li><a href="https://marc-beninca.start.page">StartPage</a></li> 631<li><a href="https://tap.bio/marc.beninca">Tap.Bio</a></li> 632<li><a href="https://marc-beninca.taplink.ws">TapLink</a></li> 633<li><a href="https://url.bio/marc_beninca">URL.Bio</a></li> 634<li><a href="https://vu.fr/marc-beninca">Vu.Fr</a></li> 635<li><a href="https://zaap.bio/marc.beninca">Zaap</a></li> 636</ul> 637''', 638#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 639 'music': f'''\ 640<ul> 641<li><a href="https://www.youtube.com/watch?v=_ITiwPMUzho">3 AM Coding Session</a></li> 642</ul> 643<hr /> 644<ul> 645<li><a href="https://www.youtube.com/@Daniellabjarnhof/videos">Daniella Bjarnhof</a></li> 646<li><a href="https://www.youtube.com/@DJGroove/videos">DJ Groove</a></li> 647<li><a href="https://www.youtube.com/@flavourtrip/videos">Flavour Trip</a></li> 648<li><a href="https://www.youtube.com/@garsimusic/videos">Garsi</a></li> 649<li><a href="https://www.youtube.com/@jabig/videos">Ja Big</a></li> 650<li><a href="https://www.youtube.com/@johnny_m/videos">Johnny M (GR)</a></li> 651<li><a href="https://www.youtube.com/@johnnymgrchannelc3145/videos">Johnny M (GR) (Channel C')</a></li> 652<li><a href="https://www.youtube.com/@djmissmonique/videos">Miss Monique</a></li> 653<li><a href="https://www.youtube.com/@DJRaphaelPPRV/videos">Raphael</a></li> 654</ul> 655<hr /> 656<ul> 657<li><a href="https://www.youtube.com/watch?v=lP26UCnoH9s">Coffee Shop Radio</a></li> 658<li><a href="https://www.youtube.com/watch?v=8wHjuR2gagI">Sad songs for sad people</a></li> 659</ul> 660<hr /> 661<ul> 662<li><a href="http://radio.garden/visit/pessac">Radio Garden</a></li> 663</ul> 664''', 665#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 666 'profiles': f'''\ 667<ul class="cards"> 668<li class="card"><a href="https://forge.rwx.work/marc.beninca"> 669<img src="img/ForgeJo.svg" /><br />ForgeJo</a></li> 670<li class="card"><a href="https://keyoxide.org/08EDA7006234A0EB29A3A8471DBD5EC4BADA5579"> 671<img src="img/KeyOxide.png" /><br />KeyOxide / PGP</a></li> 672<li class="card"><a href="https://keyoxide.org/aspe:keyoxide.org:WUD5YVN52J3RJ6CD4ZCWYL6S54"> 673<img src="img/KeyOxide.png" /><br />KeyOxide / ASP</a></li> 674</ul> 675<hr /> 676<ul class="cards"> 677<li class="card"><a href="https://videos.trom.tf/@marc.beninca"> 678<img src="img/PeerTube.png" /><br />PeerTube</a></li> 679<li class="card"><a href="https://pixelfed.social/marc.beninca"> 680<img src="img/PixelFed.svg" /><br />PixelFed</a></li> 681</ul> 682<hr /> 683<ul class="cards"> 684<li class="card"><a href="https://linkedin.com/in/marc-beninca"> 685<img src="img/LinkedIn.png" /><br />LinkedIn</a></li> 686<li class="card"><a href="https://youtube.com/@marc.beninca"> 687<img src="img/YouTube.png" /><br />YouTube</a></li> 688<li class="card"><a href="https://instagram.com/marc.beninca"> 689<img src="img/InstaGram.png" /><br />InstaGram</a></li> 690</ul> 691''', 692#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 693 'lsgm': f'''\ 694<h1>Live Scan Grub Menu</h1> 695Setup a whole EFI System Partition: 696<ul> 697<li>generate customized GRUB EFI & BIOS images</li> 698<li>scan data partition(s) for SquashFS image files</li> 699<li>display generated boot menu</li> 700<li>live boot selected kernel, initial ramdisk and file system image</li> 701</ul> 702BASH experimenting: 703<ul> 704<li><a href="https://youtu.be/mx2lhm7qClc">2023/05/04: 1st boot into QCOW storage with encrypted data partition</a></li> 705</ul> 706''', 707 'ofsp': f'''\ 708<h1>Operating File System Profile</h1> 709Build from mirror a full operating system bootable file image: 710<ul> 711<li>bootstrap base file system</li> 712<li>configure common core basics</li> 713<li>install TUI packages</li> 714<li>install GUI packages</li> 715<li>copy kernel and initial ramdisk for bootloader</li> 716<li>archive final file system as SquashFS file</li> 717</ul> 718BASH experimenting: 719<ul> 720<li><a href="https://youtu.be/phArr81weUw">2023/07/27: 3rd party repos, repoless .deb, tarball archives</a></li> 721</ul> 722<hr /> 723<ul> 724<li><a href="https://youtu.be/5Isf02MKFgM">2023/07/20: both TUI and GUI images</a></li> 725<li><a href="https://youtu.be/YhoY2gisXg4">2023/06/20: Graphical User Interface too</a></li> 726<li><a href="https://youtu.be/PSHswxc9oU8">2023/06/13: Textual User Interface only</a></li> 727</ul> 728''', 729#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 730 'social': f'''\ 731<ul> 732<li><a href="https://calckey.org">Calckey</a></li> 733<li><a href="https://joinmastodon.org">Mastodon</a></li> 734<li><a href="https://pixelfed.org">Pixelfed</a></li> 735</ul> 736<hr /> 737<ul> 738<li><a href="https://bsky.app">Bluesky</a></li> 739<li><a href="https://revolt.chat">Revolt</a></li> 740</ul> 741<hr /> 742<ul> 743<li><a href="https://discord.com">Discord</a></li> 744<li><a href="https://www.facebook.com">FaceBook</a></li> 745<li><a href="https://www.instagram.com">InstaGram</a></li> 746<li><a href="https://www.linkedin.com">LinkedIn</a></li> 747<li><a href="https://www.reddit.com">Reddit</a></li> 748<li><a href="https://www.tiktok.com">TikTok</a></li> 749<li><a href="https://www.twitch.tv">Twitch</a></li> 750<li><a href="https://twitter.com">Twitter</a></li> 751<li><a href="https://www.youtube.com">YouTube</a></li> 752</ul> 753<hr /> 754<ul> 755<li><a href="https://nextdoor.com">NextDoor</a></li> 756</ul> 757''', 758#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 759 'software': f'''\ 760<ul> 761<li><a href="https://developer.puri.sm/Librem5">Librem 5</a></li> 762</ul> 763<hr /> 764<ul> 765<li><a href="https://docs.zfsbootmenu.org">ZFS Boot Menu</a></li> 766</ul> 767<hr /> 768<ul> 769<li><a href="https://carbon.sh">CarbonOS</a></li> 770<li><a href="https://fedoraproject.org/silverblue">Fedora Silverblue</a></li> 771<li><a href="https://www.flatcar.org">Flatcar Container Linux</a></li> 772<li><a href="https://nixos.org">NixOS</a></li> 773<li><a href="https://guix.gnu.org">Guix</a></li> 774<li><a href="https://microos.opensuse.org">OpenSUSE MicroOS</a></li> 775<li><a href="https://vanillaos.org">Vanilla OS</a></li> 776<li><a href="https://github.com/bottlerocket-os/bottlerocket">Bottlerocket OS</a></li> 777<li><a href="https://blendos.co">BlendOS</a></li> 778<li><a href="https://www.talos.dev">Talos Linux</a></li> 779<li><a href="https://www.endlessos.org/os">Endless OS</a></li> 780</ul> 781''', 782#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 783 'style': f'''\ 784<ul> 785<li><input type="checkbox" id="dark" onclick="swap()">Dark</input></li> 786<li><input type="checkbox" id="debug" onclick="debug()">Debug</input></li> 787</ul> 788''', 789#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 790 'tasks': f'''\ 791<ul> 792<li>categorize music</li> 793</ul> 794<ul> 795<li>fix dark switch</li> 796<li>style list items</li> 797<li>switch fonts</li> 798<li>use CSS variables</li> 799</ul> 800<ul> 801<li>implement search</li> 802</ul> 803''', 804#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 805 'trips': f'''\ 806<ul> 807<li>Belgium<ul> 808 <li>Brussels</li> 809</ul></li> 810<li>Estonia<ul> 811 <li>Lahemaa</li> 812 <li>Narva</li> 813 <li>Pärnu</li> 814 <li>Saaremaa</li> 815 <li>Tallinn</li> 816 <li>Tartu</li> 817</ul></li> 818<li>Germany<ul> 819 <li>Berlin</li> 820</ul></li> 821<li>Japan<ul> 822 <li>Hiroshima</li> 823 <li>Kyoto</li> 824 <li>Okinawa</li> 825 <li>Osaka</li> 826 <li>Tokyo</li> 827</ul></li> 828<li>Netherlands<ul> 829 <li>Amsterdam</li> 830 <li>Rotterdam</li> 831</ul></li> 832<li>Switzerland</li> 833<li>United States of America<ul> 834 <li>California<ul> 835 <li>Los Angeles</li> 836 <li>San Francisco</li> 837 </ul></li> 838 <li>Georgia</li> 839 <li>Hawaii</li> 840 <li>Indiana</li> 841 <li>Kentucky</li> 842 <li>New York</li> 843 <li>Ohio</li> 844 <li>Tennessee</li> 845</ul></li> 846</ul> 847''', 848#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 849 'vegan': f'''\ 850<ul> 851<li><a href="https://www.youtube.com/@CheapLazyVegan/videos">Cheap Lazy Vegan</a></li> 852<li><a href="https://www.youtube.com/@gazoakleychef/videos">Gaz Oakley</a></li> 853<li><a href="https://www.youtube.com/@MerleONeal/videos">Merle O'Neal</a></li> 854<li><a href="https://www.youtube.com/@peacefulcuisine/videos">Peaceful Cuisine</a></li> 855<li><a href="https://www.youtube.com/@PickUpLimes/videos">Pick Up Limes</a></li> 856<li><a href="https://www.youtube.com/@RainbowPlantLife/videos">Rainbow Plant Life</a></li> 857<li><a href="https://www.youtube.com/@TheKoreanVegan/videos">The Korean Vegan</a></li> 858<li><a href="https://www.youtube.com/@Thevietvegan/videos">The Viet Vegan</a></li> 859<li><a href="https://www.youtube.com/@YEUNGMANCOOKING/videos">Yeung Man Cooking</a></li> 860</ul> 861<ul> 862<li><a href="https://www.youtube.com/@SauceStache/videos">Sauce Stache</a></li> 863<li><a href="https://www.youtube.com/@TheeBurgerDude/videos">Thee Burger Dude</a></li> 864</ul> 865<hr /> 866<ul> 867<li><a href="https://www.youtube.com/@doucefrugalite/videos">Douce frugalité</a></li> 868<li><a href="https://www.youtube.com/@Evalespetitsplats/videos">Eva les petits plats</a></li> 869<li><a href="https://www.youtube.com/@LapetiteOkara/videos">La petite Okara</a></li> 870<li><a href="https://www.youtube.com/@MarieSweetandSour/videos">Marie Sweet and Sour</a></li> 871<li><a href="https://www.youtube.com/@SebastienKardinal/videos">Sébastien Kardinal</a></li> 872</ul> 873''', 874#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 875 'others': f'''\ 876<ul> 877<li><a href="https://bsky.app/profile/marc-beninca.bsky.social">Blue Sky</a></li> 878<li><a href="https://buymeacoffee.com/marc.beninca">Buy Me A Coffee</a></li> 879<li><a href="https://cohost.org/marc-beninca">CoHost</a></li> 880<li><a href="https://dev.to/marc_beninca">Dev</a></li> 881<li><a href="https://diaspora-fr.org/people/00f4f8e04b11013b46b20025900e4586">Diaspora</a></li> 882<li><a href="https://hashnode.com/@marc-beninca">HashNode</a></li> 883<li><a href="https://medium.com/@marc-beninca">Medium</a></li> 884<li><a href="https://marc-beninca.micro.blog/about">MicroBlog</a></li> 885<li><a href="https://minds.com/marc_beninca">Minds</a></li> 886<li><a href="https://odysee.com/@marc.beninca">Odysee</a></li> 887<li><a href="https://paypal.me/MarcBeninca">PayPal</a></li> 888<li><a href="https://pinterest.com/marc_beninca">Pinterest</a></li> 889<li><a href="https://marcbeninca.podia.com">Podia</a></li> 890<li><a href="https://app.revolt.chat/invite/01FREKCG3P2P0YMAHQSCPSW4GD">Revolt</a></li> 891<li><a href="https://tiktok.com/@marc.beninca">TikTok</a></li> 892<li><a href="https://twtxt.net/user/marc_beninca">YarnSocial</a></li> 893</ul> 894<hr /> 895<ul> 896<li><a href="https://dlive.tv/marc.beninca">Dlive</a></li> 897<li><a href="https://kick.com/marc_beninca">Kick</a></li> 898</ul> 899<hr /> 900<ul> 901<li><a href="">KissBank</a></li> 902</ul> 903''', 904#⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 905 'unsorted': f'''\ 906<ul> 907<li><a href="https://foss.events">FOSS Events</a></li> 908</ul> 909''', 910} 911 912 913if __name__ == '__main__': 914 main()