on master help sign in
26 files changed+165−1850
since splitsnapshots
unifiedsplit
.github/ISSUE_TEMPLATE/broken-link.md−10 .github/ISSUE_TEMPLATE/hallway-issue.md−10 .github/ISSUE_TEMPLATE/inappropriate-content.md−14 .github/ISSUE_TEMPLATE/name-of-website.md+9 .github/ISSUE_TEMPLATE/portal-issue.md−10 .github/ISSUE_TEMPLATE/wiki-issue.md−10 .github/PULL_REQUEST_TEMPLATE/add-site.md−14 README.md+15−18 favicon.ico hallway.html−20 icon.black.large.svg−13 index.html+16−141 links/fonts.css+15 links/main.css+19−12 media/fonts/input_mono_medium.ttf media/fonts/input_mono_regular.ttf scripts/hallway.js−232 scripts/indental.js−57 scripts/opml.js−13 scripts/portal.js+23−81 scripts/progress.js−41 scripts/sites.js+68−922 scripts/wiki.js−176 tools/extract_twtxt.js−22 tools/twtxt.json−1 wiki.html−33
.github/ISSUE_TEMPLATE/broken-link.mddeleted−10
@@ -1,10 +0,0 @@
1−---
2−name: Broken link
3−about: Report a broken link in the webring
4−title: ''
5−labels: broken link
6−assignees: neauoire, kodedninja, joshavanier, ckipp01
7−
8−---
9−
10−**Name of the site:**
.github/ISSUE_TEMPLATE/hallway-issue.mddeleted−10
@@ -1,10 +0,0 @@
1−---
2−name: Hallway issue
3−about: Report an issue with the Hallway
4−title: ''
5−labels: hallway
6−assignees: neauoire, kodedninja, joshavanier, ckipp01
7−
8−---
9−
10−**Please describe the issue in the hallway:**
.github/ISSUE_TEMPLATE/inappropriate-content.mddeleted−14
@@ -1,14 +0,0 @@
1−---
2−name: Inappropriate content
3−about: Report inappropriate content in the webring
4−title: ''
5−labels: ''
6−assignees: neauoire, kodedninja, joshavanier, ckipp01
7−
8−---
9−
10−**Name of the site:**
11−
12−
13−
14−**Please explain what is inappropriate and link if necessary:**
.github/ISSUE_TEMPLATE/name-of-website.mdnew file+9
@@ -0,0 +1,9 @@
1+---
2+name: name.of.website
3+about: Describe this issue template's purpose here.
4+
5+---
6+
7+```
8+Position of webring icon on site: ex: footer, header
9+```
.github/ISSUE_TEMPLATE/portal-issue.mddeleted−10
@@ -1,10 +0,0 @@
1−---
2−name: Portal issue
3−about: Report an issue with the Portal
4−title: ''
5−labels: portal
6−assignees: neauoire, kodedninja, joshavanier, ckipp01
7−
8−---
9−
10−**Please describe the issue in the portal:**
.github/ISSUE_TEMPLATE/wiki-issue.mddeleted−10
@@ -1,10 +0,0 @@
1−---
2−name: Wiki issue
3−about: Report an issue with the Wiki
4−title: ''
5−labels: wiki
6−assignees: neauoire, kodedninja, joshavanier, ckipp01
7−
8−---
9−
10−**Please describe the issue in the wiki:**
.github/PULL_REQUEST_TEMPLATE/add-site.mddeleted−14
@@ -1,14 +0,0 @@
1−---
2−name: add.site
3−about: Submitting a new site to the webring
4−title: ''
5−labels: ''
6−assignees: neauoire, kodedninja, joshavanier, ckipp01
7−
8−---
9−
10−**Position of webring icon on site:**
11−
12−ex: footer, header
13−
14−**Make sure the contact key is also filled out in case we need to contact you**
README.md+15−18
@@ -1,6 +1,6 @@
11# Webring
22
3−This [webring](https://wiki.xxiivv.com/webring) is an attempt to inspire artists & developers to create and maintain their own website and share traffic among each other. The webring's aim is to share rich hand-crafted websites such as **diaries, wikis & portfolios**.
3+This [webring](https://wiki.xxiivv.com/webring) is an attempt to inspire artists & developers to create and maintain their own website and share traffic among each other. The webring's aim is to share hand-crafted websites such as **diaries, wikis & portfolios**, single pagers with nothing but outgoing links to social platforms will be rejected. To add yourself to the ring, submit an [edit](https://github.com/XXIIVV/webring/edit/master/scripts/sites.js) to this repository.
44
55## Join the webring
66
@@ -8,30 +8,27 @@ This [webring](https://wiki.xxiivv.com/webring) is an attempt to inspire artists
88<a href='https://webring.xxiivv.com/#random' target='_blank'><img src='https://webring.xxiivv.com/icon.black.svg'/></a>
99```
1010
11−1) Add the webring icon to your website html.
12−2) Add your website information to the [index.html](https://github.com/XXIIVV/webring/edit/master/index.html) file. Keep your link name short, and don't leave a trailing `/` in the href attribute. Use a sensible alphanumeric value for the id.
13−3) Submit a Pull Request with **the location of the webring icon** on your site. Pull requests with blank descriptions will be rejected.
11+- Add the webring icon to your website html.
12+- Add your website url to the [sites.js](https://github.com/XXIIVV/webring/edit/master/scripts/sites.js) file.
13+- Submit a Pull Request with the location of the webring icon on your site.
1414
15−Alternatively, if you your website has a dark background, use `icon.white.svg`. If your website is complaining about *https*, go ahead and host the icon yourself.
16−
17−### Webring criteria
18−
19−**Single page websites, websites acting only as portals to other social platforms, or websites with violent, racist, sexist or speciesist content will be rejected**.
20−
21−The aim of the webring is to display **hand-crafted personal** websites showcasing the creator's audio, visual or written work. Your business site is probably not the best fit for the webring, and will be rejected.
22−
23−If your website requires Javascript to display the majority of its content or to navigate, it will be rejected.
24−
25−If it's seen that your website is in violation to any of these rules your site will be removed from the webring. If you fix the issues, feel free to submit another PR to join back in.
15+Alternatively, if you your website has a dark background, use `icon.white.svg`. If your website is complaning about *https*, go ahead and host the icon yourself.
2616
2717### Circular Linking
2818
2919Instead of linking to the directory, you can also link to the next link in the ring by adding parts of your site or domain in the hash of the request url:
3020
3121```
32−<a href='https://webring.xxiivv.com/#xxiivv' target='_blank' rel="noopener noreferrer"><img src='https://webring.xxiivv.com/icon.black.svg'/></a>
22+<a href='https://webring.xxiivv.com/#wiki.xxiivv' target='_blank'><img src='https://webring.xxiivv.com/icon.black.svg'/></a>
3323```
3424
35−## Help
25+## API
26+
27+This repository does not contain mature API capabilities, but there is one way to request list of sites currently in the webring.
28+
29+- Request [sites.js on xxiivv](https://webring.xxiivv.com/scripts/sites.js) or [sites.js on github](https://raw.githubusercontent.com/XXIIVV/webring/master/scripts/sites.js)
30+- Parse it as text from `[` to `]`, split by `,` and then trim all whitespace and `"` in resulting array.
31+
32+## Need Help?
3633
37−The ring is managed by [@neauoire](https://twitter.com/neauoire), but any member of the network is also welcome to join this repository as a collaborator to help manage new links and Pull Requests. Read more about the webring [here](https://wiki.xxiivv.com/webring).
34+The ring is managed by [@neauoire](https://twitter.com/neauoire), but any member of the network is also welcome to join this repository as a collaborator to help manage new links and Pull Requests. Read more [here](https://wiki.xxiivv.com/webring).
favicon.icodeleted

Binary file not shown.

hallway.htmldeleted−20
@@ -1,20 +0,0 @@
1−<!DOCTYPE html>
2−<html lang="en">
3−<head>
4− <meta charset="utf-8">
5− <meta name="viewport" content="width=device-width, initial-scale=1.0">
6− <link rel="stylesheet" type="text/css" href="links/fonts.css"/>
7− <link rel="stylesheet" type="text/css" href="links/main.css"/>
8− <script type="text/javascript">const module = { exports:{} }</script>
9− <script src="scripts/hallway.js"></script>
10− <script src="scripts/sites.js"></script>
11− <title>Hallway</title>
12−</head>
13−<body>
14− <script>
15− const hallway = new Hallway(sites);
16− hallway.install(document.body);
17− hallway.start();
18− </script>
19−</body>
20−</html>
icon.black.large.svgdeleted−13
@@ -1,13 +0,0 @@
1−<svg class="vector" width="300px" height="300px" xmlns="http://www.w3.org/2000/svg" baseProfile="full" version="1.1" style="fill:none;stroke:black;stroke-width:5px;stroke-linecap:square;">
2− <g transform="translate(0,30)">
3− <g transform="translate(150,150),rotate(120,0,0)">
4− <path d="M0,-60 a60,60 0 1,0 0,120 l100,0"></path>
5− </g>
6− <g transform="translate(150,150),rotate(240,0,0)">
7− <path d="M0,-60 a60,60 0 1,0 0,120 l100,0"></path>
8− </g>
9− <g transform="translate(150,150),rotate(0,0,0)">
10− <path d="M0,-60 a60,60 0 1,0 0,120 l100,0"></path>
11− </g>
12− </g>
13−</svg>
index.html+16−141
@@ -1,144 +1,19 @@
11<!DOCTYPE html>
22<html lang="en">
3− <head>
4− <meta charset="utf-8">
5− <meta name="viewport" content="width=device-width, initial-scale=1.0">
6− <link rel="con" type="image/png" sizes="100x100" href="favicon.ico">
7− <link rel="apple-touch-icon" type="image/png" sizes="100x100" href="favicon.ico">
8− <link rel="stylesheet" type="text/css" href="links/main.css"/>
9− <title>Webring</title>
10− </head>
11− <body>
12− <ol>
13− <li data-type="wiki " data-lang="en" id="xxiivv"><a href="https://wiki.xxiivv.com">xxiivv</a></li>
14− <li data-lang="en" id="1"><a href="http://estevancarlos.com">estevancarlos</a></li>
15− <li data-type="blog " data-lang="en" id="2"><a href="https://electro.pizza">electro pizza</a></li>
16− <li data-type="wiki " data-lang="en" id="3"><a href="https://avanier.now.sh">Arachne</a></li>
17− <li data-type="blog " data-lang="en" id="4"><a href="http://kaemura.com">kaemura</a></li>
18− <li data-lang="en" id="5"><a href="https://liamcooke.com">liamcooke</a></li>
19− <li data-lang="en" id="6"><a href="https://hraew.autophagy.io">hraew.autophagy</a></li>
20− <li data-lang="en" id="7"><a href="http://evenunto.net">evenunto.net</a></li>
21− <li data-lang="en" id="8"><a href="https://anxl.faith">anxl.faith</a></li>
22− <li data-type="hybrid " data-lang="fr" id="9"><a href="https://xvw.github.io">planet</a></li>
23− <li data-lang="en el" id="10"><a href="https://heracl.es">heracl.es</a></li>
24− <li data-lang="en" id="11"><a href="https://turelio.github.io">turelio.github</a></li>
25− <li data-type="blog " data-lang="en" id="12"><a href="https://shards.lectronice.com">shards</a></li>
26− <li data-lang="en" id="13"><a href="https://craze.co.uk">craze.co.uk</a></li>
27− <li data-lang="en" id="14"><a href="https://shaneckel.com">shaneckel</a></li>
28− <li data-lang="en" id="15"><a href="https://cblgh.org">cblgh</a></li>
29− <li data-type="wiki " data-lang="en" id="16"><a href="https://ellugar.co">ellugar</a></li>
30− <li data-type="portfolio " data-lang="en" id="17"><a href="http://chigby.org">chigby</a></li>
31− <li data-lang="en" id="18"><a href="https://longest.voyage">longest.voyage</a></li>
32− <li data-type="portfolio " data-lang="en" id="19"><a href="https://palomakop.tv">palomakop.tv</a></li>
33− <li data-lang="en" id="20"><a href="https://v-os.ca">v-os.ca</a></li>
34− <li data-lang="en" id="21"><a href="https://jmandel.xyz">jmandel.xyz</a></li>
35− <li data-lang="en" id="22"><a href="https://2d4.dev">2d4.dev</a></li>
36− <li data-lang="en" id="23"><a href="https://nathanwentworth.co">nathanwentworth</a></li>
37− <li data-lang="en" id="24"><a href="https://uonai.space">uonai.space</a></li>
38− <li data-lang="en" id="25"><a href="http://controls.ee">controls.ee</a></li>
39− <li data-lang="en" id="26"><a href="https://wasin.io">wasin</a></li>
40− <li data-lang="en" id="27"><a href="https://inns.studio">inns.studio</a></li>
41− <li data-lang="en" id="28"><a href="http://kokorobot.ca">kokorobot.ca</a></li>
42− <li data-type="blog " data-lang="en" id="29"><a href="https://ameyama.com">ameyama</a></li>
43− <li data-lang="en" id="30"><a href="https://wake.st">wake.st</a></li>
44− <li data-lang="en" id="31"><a href="https://xarene.la">xarene.la</a></li>
45− <li data-lang="en" id="32"><a href="https://alex.zyzhang.me">alex.zyzhang.me</a></li>
46− <li data-lang="en" id="33"><a href="http://bildwissenschaft.vortok.info">vortok</a></li>
47− <li data-lang="en" id="34"><a href="https://jakofranko.github.com">jakofranko.github</a></li>
48− <li data-lang="en" id="35"><a href="https://aeriform.io">aeriform.io</a></li>
49− <li data-lang="en de" id="36"><a href="http://blog.lucasdidthis.com">blog.lucasdidthis</a></li>
50− <li data-lang="en" id="37"><a href="http://npisanti.com">npisanti.com</a></li>
51− <li data-lang="en" id="38"><a href="https://underscorediscovery.ca">underscorediscovery</a></li>
52− <li data-type="wiki " data-lang="en" id="39"><a href="https://drisc.io">drisc</a></li>
53− <li data-lang="en" id="40"><a href="https://ricky.codes">ricky.codes</a></li>
54− <li data-type="hybrid " data-lang="en" id="41"><a href="https://maxdeviant.com">maxdeviant</a></li>
55− <li data-lang="en" id="42"><a href="https://tynandebold.com">tynandebold</a></li>
56− <li data-lang="en" id="43"><a href="http://gytis.co">gytis.co</a></li>
57− <li data-lang="en" id="44"><a href="https://nomand.co">nomand.co</a></li>
58− <li data-lang="en" id="45"><a href="http://memoriata.com">memoriata</a></li>
59− <li data-lang="en" id="46"><a href="https://mmm.s-ol.nu">mmm.s-ol</a></li>
60− <li data-lang="en" id="47"><a href="https://chad.is">chad.is</a></li>
61− <li data-lang="en" id="48"><a href="https://smidgeo.com/bots">smidgeo.com/bots</a></li>
62− <li data-lang="en ru" id="49"><a href="https://iko.soy">iko.soy</a></li>
63− <li data-lang="en" id="50"><a href="http://atelieroilandsugar.com">atelieroilandsugar</a></li>
64− <li data-lang="en" id="51"><a href="https://magoz.is">magoz.is</a></li>
65− <li data-type="hybrid " data-lang="en" id="52"><a href="https://szymonkaliski.com">szymonkaliski</a></li>
66− <li data-type="blog " data-lang="en" id="53"><a href="https://phse.net">phse.net</a></li>
67− <li data-lang="en" id="54"><a href="https://rosano.ca">rosano.ca</a></li>
68− <li data-lang="en" id="56"><a href="https://gndclouds.cc">gndclouds.cc</a></li>
69− <li data-lang="en fr" id="57"><a href="https://xuv.be">xuv.be</a></li>
70− <li data-lang="en zh" id="58"><a href="https://dsdshcym.github.io">dsdshcym.github.io</a></li>
71− <li data-type="hybrid " data-lang="en" id="59"><a href="https://chris-kipp.io">chris-kipp</a></li>
72− <li data-lang="en" id="60"><a href="https://boffosocko.com">boffosocko</a></li>
73− <li data-lang="en" id="61"><a href="https://hex22.org">hex22</a></li>
74− <li data-lang="en" id="62"><a href="https://patrikarvidsson.com">patrikarvidsson</a></li>
75− <li data-lang="en" id="63"><a href="https://sophieleetmaa.com">sophieleetmaa</a></li>
76− <li data-lang="en" id="64"><a href="https://xinniw.github.io">xinniw.github</a></li>
77− <li data-type="wiki " data-lang="en" id="65"><a href="https://mboxed.github.io/sodatsu">sodatsu</a></li>
78− <li data-lang="en" id="66"><a href="https://letters.vexingworkshop.com">vexingworkshop</a></li>
79− <li data-type="portfolio " data-lang="en" id="67"><a href="https://tom.org.nz">Tom Hackshaw</a></li>
80− <li data-lang="en" id="68"><a href="https://teknari.com">Teknari</a></li>
81− <li data-type="blog " data-lang="es" id="69"><a href="https://colectivo-de-livecoders.gitlab.io">Colectivo de Livecoders</a></li>
82− <li data-type="blog " data-lang="es" id="70"><a href="https://www.madewithtea.com">madewithtea</a></li>
83− <li data-type="blog " data-lang="en" id="71"><a href="https://amorris.ca">amorris</a></li>
84− <li data-type="portfolio " data-lang="en" id="72"><a href="http://www.miha-co.ca">miha-co</a></li>
85− <li data-type="blog " data-lang="en" id="73"><a href="https://buzzert.net">buzzert.net</a></li>
86− <li data-type="wiki " data-lang="en" id="74"><a href="https://notes.stuartpb.com/">notes.stuartpb</a></li>
87− <li data-type="portfolio " data-lang="en" id="75"><a href="https://xxiii.co">xxiii</a></li>
88− <li data-type="wiki " data-lang="en" id="76"><a href="https://kor.nz">kor</a></li>
89− <li data-lang="en" id="77"><a href="https://lublin.se">lublin.se</a></li>
90− <li data-type="blog " data-lang="en" id="78"><a href="https://zanneth.com">zanneth</a></li>
91− <li data-type="blog " data-lang="en" id="79"><a href="https://eli.li">eli.li</a></li>
92− <li data-type="portfolio " data-lang="en" id="80"><a href="https://gueorgui.net">Gueorgui Tcherednitchenko</a></li>
93− <li data-type="portfolio " data-lang="en" id="81"><a href="https://www.tatecarson.com">Tate Carson</a></li>
94− <li data-type="wiki " data-lang="en" id="82"><a href="https://azlen.me">azlen.me</a></li>
95− <li data-lang="en" id="83"><a href="https://opinionatedguide.github.io/">OpGuides</a></li>
96− <li data-lang="en" id="84"><a href="https://chrismaughan.com/">CMaughan</a></li>
97− <li data-type="blog " data-lang="en es" id="85"><a href="https://oddworlds.org/">oddworlds soliloquy</a></li>
98− <li data-type="blog " data-lang="en" id="86"><a href="https://fundor333.com/">Fundor333</a></li>
99− <li data-lang="en" id="87"><a href="https://cass.si">cass.si</a></li>
100− <li data-lang="en" id="88"><a href="https://dotcomboom.somnolescent.net/">somnolescent.net</a></li>
101− <li data-lang="en" id="89"><a href="https://cadmican.neocities.org/">cadmican</a></li>
102− <li data-lang="en" id="90"><a href="https://jskjott.com">jskjott</a></li>
103− <li data-type="portfolio " data-lang="en" id="91"><a href="https://sixey.es/">sixey.es</a></li>
104− <li data-type="wiki " data-lang="en" id="92"><a href="https://tilde.town/~dustin/">0xdstn</a></li>
105− <li data-lang="en" id="93"><a href="https://jameschip.io/">James Chip</a></li>
106− <li data-type="portfolio " data-lang="en" id="94"><a href="https://patrick-is.cool">patrick-is.cool</a></li>
107− <li data-type="hybrid " data-lang="en" id="95"><a href="https://icyphox.sh">icyphox.sh</a></li>
108− <li data-type="portfolio " data-lang="en" id="96"><a href="https://royniang.com">roy niang</a></li>
109− <li data-type="portfolio " data-lang="en" id="97"><a href="https://www.raul.earth/">raul altosaar</a></li>
110− <li data-type="hybrid " data-lang="en" id="98"><a href="https://crlf.site">Cr;Lf;</a></li>
111− <li data-type="hybrid " data-lang="en" id="99"><a href="https://www.johannesg.com">Jóhannes G. Þorsteinsson</a></li>
112− <li data-type="hybrid " data-lang="en" id="100"><a href="https://provokeanalog.com">Provoke Analog</a></li>
113− <li data-lang="en" id="101"><a href="https://eti.tf">eti.tf</a></li>
114− <li data-type="hybrid " data-lang="en" id="102"><a href="https://rezmason.net">rezmason.net</a></li>
115− <li data-type="hybrid " data-lang="en cz" id="103"><a href="https://estfyr.net">estfyr.net</a></li>
116− <li data-lang="en" id="104"><a href="https://paysonwallach.com">paysonwallach.com</a></li>
117− <li data-type="portfolio " data-lang="en" id="105"><a href="https://natwelch.com">natwelch</a></li>
118− <li data-type="hybrid " data-lang="en" id="106"><a href="https://parkimminent.com">Park Imminent</a></li>
119− <li data-type="hybrid " data-lang="en" id="107"><a href="https://aklsh.github.io">aklsh.github</a></li>
120− <li data-type="hybrid " data-lang="en" id="108"><a href="https://paulglushak.com">paulglushak</a></li>
121− <li data-type="portfolio " data-lang="en ita" id="109"><a href="https://simone.computer">Simone's Computer</a></li>
122− <li data-type="blog " data-lang="en" id="110"><a href="https://xj9.io">dreamspace</a></li>
123− <li data-type="blog " data-lang="en" id="111"><a href="https://simply.personal.jenett.org">jenett. simply. personal.</a></li>
124− <li data-type="blog " data-lang="en" id="112"><a href="http://q.pfiffer.org/">q.pfiffer.org</a></li>
125− <li data-type="blog " data-lang="en" id="113"><a href="https://ashpex.neocities.org">ashpex</a></li>
126− <li data-type="blog " data-lang="en" id="114"><a href="https://zvava.org">zvava</a></li>
127− <li data-lang="en" id="115"><a href="https://amorphic.space">amorphic.space</a></li>
128− <li data-type="blog " data-lang="en nl" id="116"><a href="https://www.edwinwenink.xyz">Archive Fever</a></li>
129− <li data-type="hybrid " data-lang="en fr" id="117"><a href="https://www.mentalnodes.com">Mental Nodes</a></li>
130− <li data-type="blog, hybrid " data-lang="es" id="118"><a href="https://copiona.com">copiona</a></li>
131− </ol>
132− <footer>
133− <p class="readme">
134− This webring is an attempt to inspire artists &amp; developers to build their own website and share traffic among each other. The ring welcomes personalized websites such as <b>diaries, wikis &amp; portfolios</b>.
135− </p>
136− <p>
137− To add yourself to the ring, submit a <a href="https://github.com/XXIIVV/webring/edit/master/index.html" target="_blank">pull request</a>.<br />
138− If you found a broken link, please <a href="https://github.com/XXIIVV/webring/issues/new" target="_blank">report it</a>.<br />
139− Learn <a href="https://github.com/XXIIVV/webring" target="_blank">more</a>.
140− </p>
141− <img src="icon.black.large.svg" alt="icon"/>
142− </footer>
143− </body>
3+<head>
4+ <meta charset="utf-8">
5+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6+ <link rel="stylesheet" type="text/css" href="links/fonts.css"/>
7+ <link rel="stylesheet" type="text/css" href="links/main.css"/>
8+ <script src="scripts/portal.js"></script>
9+ <script src="scripts/sites.js"></script>
10+ <title>Webring</title>
11+</head>
12+<body>
13+ <script>
14+ const portal = new Portal(sites);
15+ portal.install(document.body);
16+ portal.start();
17+ </script>
18+</body>
14419</html>
links/fonts.cssnew file+15
@@ -0,0 +1,15 @@
1+/* Input Mono */
2+
3+@font-face {
4+ font-family: 'input_mono_regular';
5+ src: url('../media/fonts/input_mono_regular.ttf') format('truetype');
6+ font-weight: normal;
7+ font-style: normal;
8+}
9+
10+@font-face {
11+ font-family: 'input_mono_medium';
12+ src: url('../media/fonts/input_mono_medium.ttf') format('truetype');
13+ font-weight: normal;
14+ font-style: normal;
15+}
links/main.css+19−12
@@ -1,12 +1,19 @@
1−body { padding: 0; margin: 0 0 0 0; font-family: serif; max-width: 900px }
2−body a { color: black; text-decoration: none }
3−body a:hover { background-color: black; color: white }
4−body a:before { content:'{' }
5−body a:after { content:'}' }
6−body > ol { margin: 30px; padding: 0px 30px 30px; column-count: 3; display: block; border-bottom:2px solid black }
7−body > ol > li { padding-right: 30px; margin-right:30px }
8−body > ol > li:target { background:black }
9−body > ol > li:target a { color: white }
10−body > footer { margin:30px }
11−body > footer > p { max-width: 600px }
12−body > footer > img { display: inline-block; width:100px; margin-bottom: -5px; margin-bottom:30px; }
1+* { margin:0;padding:0;border:0;outline:0;text-decoration:none;font-weight:inherit;font-style:inherit;color:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;list-style:none;border-collapse:collapse;border-spacing:0; -webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}
2+
3+body { background:#f4f4f4; padding:0px; margin:0px; }
4+body div { display:block; background: #ddd;min-height: calc(100vh - 60px);width: calc(100vw - 60px);margin: 15px;color: #555;padding: 15px;font-family:'input_mono_regular', 'Monospaced','Courier New',courier;font-size:11px; position: relative; border-radius: 2px }
5+body div #icon { display: block;width: 30px;height: 30px;background-image: url(../icon.white.svg);background-size: cover;background-repeat: no-repeat;position: absolute;bottom: 10px;right:10px;background-position: center;padding:0px }
6+body div p { display:block; padding:0px 5px; line-height: 20px}
7+body div p a { color:black; text-decoration: none; text-decoration: underline;}
8+body div p a:hover { text-decoration: underline; }
9+body div p b { font-weight: normal; color:#000; font-family: 'input_mono_medium' }
10+body div p.readme { max-width:500px; }
11+body div ul { display:block; max-width: 800px; columns:3; border-bottom: 2px solid white;padding-bottom: 15px;margin-bottom:15px; overflow: hidden;}
12+body div ul li { width: 22em; display:block; padding-left:5px; overflow: hidden; text-overflow: ellipsis; }
13+body div ul li a { line-height: 20px; display: inline-block; color:#000; padding:0px 5px; text-decoration: none;}
14+body div ul li a:visited { color:#999; text-decoration: none;}
15+body div ul li a:hover { background:#ccc; color:#000; text-decoration: none; border-radius: 2px }
16+
17+@media (max-width: 950px){
18+ body div ul { columns: 2 }
19+}
media/fonts/input_mono_medium.ttfnew file

Binary file not shown.

media/fonts/input_mono_regular.ttfnew file

Binary file not shown.

scripts/hallway.jsdeleted−232
@@ -1,232 +0,0 @@
1−'use strict'
2−
3−const reChannel = /(\s|^)\/([a-zA-Z0-9]+)/g
4−const reUser = /((\s|^)@&lt;[a-zA-Z0-9./:\-_+~#= ]*&gt;)/g
5−const reTag = /(^|\s)(#[a-z\d-]+)/ig
6−const reUrl = /((https?):\/\/(([-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b)([-a-zA-Z0-9@:%_+.~#?&//=]*)))/g
7−
8−function Hallway (sites) {
9− const feeds = {}
10− this.sites = sites
11− this._el = document.createElement('div')
12− this._el.id = 'hallway'
13− const filterAndPage = window.location.hash.split('^')
14− this.finder = { filter: stripHash(filterAndPage[0]), page: filterAndPage[1] || 1 }
15− this.cache = null
16−
17− this._main = document.createElement('main')
18− this._main.id = 'entries'
19− this._footer = document.createElement('footer')
20− this._footer.id = 'footer'
21− this.readme = '<p>The <strong>Hallway</strong> is a decentralized forum, to join the conversation, add a <a href="https://github.com/XXIIVV/webring#joining-the-hallway">feed:</a> field to your entry in the <a href="https://github.com/XXIIVV/Webring/">webring</a>.</p>'
22− this.nav = '<p class="buttons"><a href="https://github.com/XXIIVV/webring">Information</a> | <a href="index.html">The Portal</a> | <a href="wiki.html">The Wiki</a> | <a id="opml">OPML</a></p>'
23− this._footer.innerHTML = `${this.readme}${this.nav}`
24−
25− this.install = function (host) {
26− this._el.appendChild(this._main)
27− this._el.appendChild(this._footer)
28− host.appendChild(this._el)
29− this.findFeeds()
30− }
31−
32− this.start = function () {
33− this._main.innerHTML = 'Loading..'
34− this.fetchFeeds()
35− }
36−
37− this.refresh = function (feeds = this.cache) {
38− const entries = this.findEntries(feeds)
39− const localEntries = entries.filter(entry => this.filterExternals(entry))
40− const channels = this.find(localEntries, 'channel')
41− const users = this.find(localEntries, 'author')
42− const tags = this.findTags(localEntries)
43− const relevantEntries = localEntries
44− .filter(entry => !this.finder.filter || (entry.author === this.finder.filter || entry.channel === this.finder.filter || entry.tags.includes(this.finder.filter) || entry.body.includes(this.finder.filter)))
45−
46− const mainHtml = `
47− <div><ul>
48− ${relevantEntries.filter((_, id) => id < Number(this.finder.page) * 20 && id >= (Number(this.finder.page) - 1) * 20).reduce((acc, val) => acc + this.templateEntry(val) + '\n', '')}
49− </ul>
50− <div id='pagination'>
51− ${[...Array(Math.ceil(relevantEntries.length / 20)).keys()].reduce((acc, num) => `${acc}<span class='${Number(hallway.finder.page) === num + 1 ? 'selected' : ''}' onclick='filter("${this.finder.filter}^${num + 1}")'>${num + 1}</span>`, '')}
52− </div>
53− <a id='showbar' onclick="toggleVisibility('aside');"></a></div>`
54−
55− const aside = `
56− <aside id='aside'>
57− <a id='hidebar' onclick="toggleVisibility('aside');"></a>
58− <ul id='channels'>
59− <li onclick='filter("")' class='${hallway.finder.filter === '' ? 'selected' : ''}'><a href='#'>hallway <span class='right'>${localEntries.length}</span></a></li>
60− ${Object.keys(channels).slice(0, 15).reduce((acc, val) => acc + `<li onclick='filter("${val}")' class='${hallway.finder.filter === val ? 'selected' : ''}'><a href='#${val}'>${val} <span class='right'>${channels[val]}</span></a></li>\n`, '')}
61− </ul>
62− <ul id='users'>
63− ${Object.keys(users).slice(0, 15).reduce((acc, val) => acc + `<li onclick='filter("${val}")' class='${hallway.finder.filter === val ? 'selected' : ''}' href='#${val}'>${val} <span class='right'>${users[val]}</span></li>\n`, '')}
64− </ul>
65− <ul id='tags'>
66− ${Object.keys(tags).slice(0, 15).reduce((acc, val) => acc + `<li onclick='filter("${val}")' class='${hallway.finder.filter === val ? 'selected' : ''}' href='#${val}'>#${val} <span class='right'>${tags[val]}</span></li>\n`, '')}
67− </ul>
68− </aside>`
69−
70− this._main.innerHTML = `${mainHtml}${aside}`
71−
72− if (feeds) {
73− this.cache = feeds
74− }
75− }
76−
77− // Entries
78−
79− this.filterExternals = function (entry) {
80− const matches = entry.body.match(reUser)
81− const locals = Object.keys(feeds)
82− return matches ? matches.some(match => locals.some(local => match.indexOf(feeds[local].path) !== -1)) : true
83− }
84−
85− this.find = function (entries, key) {
86− const h = {}
87− for (const entry of entries) {
88− if (entry && entry[key]) {
89− h[entry[key]] = h[entry[key]] ? h[entry[key]] + 1 : 1
90− }
91− }
92− return h
93− }
94−
95− this.findTags = function (entries) {
96− const tags = {}
97− for (const entry of entries) {
98− entry.tags.map(tag => {
99− tags[tag] = tags[tag] ? tags[tag] + 1 : 1
100− })
101− }
102− return tags
103− }
104−
105− this.findEntries = function (feeds) {
106− const a = []
107− for (const id in feeds) {
108− for (const i in feeds[id].content) {
109− a.push(feeds[id].content[i])
110− }
111− }
112− return a.sort((a, b) => a.offset - b.offset)
113− }
114−
115− this.findMention = function (found) {
116− const mention = Object.keys(feeds).filter(user => found.indexOf(feeds[user].path) > -1)
117− return ` <span class='user local'>${mention[0]}</span>`
118− }
119−
120− this.templateEntry = function (entry) {
121− entry.html = entry.body
122− .replace(reChannel, '$1<span class="channel">/$2</span>')
123− .replace(reUser, this.findMention)
124− .replace(reTag, '$1<span class="tag">$2</span>')
125− .replace(reUrl, '<a target="_blank" href="$1">$1</a>')
126−
127− const filter = window.location.hash.substr(1).replace(/\+/g, ' ').toLowerCase()
128− const highlight = filter === entry.author.toLowerCase()
129− const origin = feeds[entry.author].path
130−
131− return `<li class='entry ${highlight ? 'highlight' : ''}'><span class='date'>${timeAgo(Date.parse(entry.date))}</span> <a class='author' href='${origin}' target='_blank'>${entry.author}</a> <span class='body'>${entry.html}</span></li>`
132− }
133−
134− // Feeds
135−
136− this.findFeeds = function () {
137− console.log('Finding feeds..')
138− for (const site of sites) {
139− if (site.feed && site.author) {
140− feeds[site.author] = { path: site.feed }
141− }
142− }
143− console.log(`Found ${Object.keys(feeds).length} feeds.`)
144− }
145−
146− this.fetchFeeds = function () {
147− console.log(`Fetching ${Object.keys(feeds).length} feeds..`)
148− for (const id in feeds) {
149− this.fetchFeed(id, feeds[id])
150− }
151− }
152−
153− this.fetchFeed = function (id, feed) {
154− console.log(`Fetching ${id}(${feed.path})..`)
155− fetch(feed.path, { cache: 'no-store' }).then(x => x.text()).then((content) => {
156− feeds[id].content = parseFeed(id, content)
157− this.refresh(feeds)
158− }).catch((err) => {
159− console.warn(`${id}`, err)
160− })
161− }
162−
163− // Utils
164−
165− function parseFeed (author, feed) {
166− const lines = feed.split('\n').filter((line) => line.substr(0, 1) !== '#')
167− const entries = []
168− for (const id in lines) {
169− const line = lines[id].trim()
170− if (line === '') { continue }
171− const parts = line.replace(' ', '\t').split('\t')
172− const date = parts[0].trim()
173− const body = escapeHtml(parts[1].trim()).trim()
174− const channel = body.substr(0, 1) === '/' ? cleanTags(body.split(' ')[0].substr(1).toLowerCase()) : body.substr(0, 1) === '@' ? 'veranda' : 'lobby'
175− const tags = (body.match(reTag) || []).map(a => cleanTags(a.substr(a.indexOf('#') + 1).toLowerCase()))
176− const offset = new Date() - new Date(date)
177− entries.push({ date, body, author, offset, channel, tags })
178− }
179− return entries
180− }
181−
182− function timeAgo (dateParam) {
183− const date = typeof dateParam === 'object' ? dateParam : new Date(dateParam)
184− const today = new Date()
185− const yesterday = new Date(today - 86400000)
186− const seconds = Math.round((today - date) / 1000)
187− const minutes = Math.round(seconds / 60)
188− const isToday = today.toDateString() === date.toDateString()
189− const isYesterday = yesterday.toDateString() === date.toDateString()
190−
191− if (seconds < 5) {
192− return 'just now'
193− } else if (seconds < 60) {
194− return `${seconds} seconds ago`
195− } else if (seconds < 90) {
196− return 'a minute ago'
197− } else if (minutes < 60) {
198− return `${minutes} minutes ago`
199− } else if (isToday) {
200− return `${Math.floor(minutes / 60)} hours ago`
201− } else if (isYesterday) {
202− return 'yesterday'
203− }
204−
205− return `${Math.floor(minutes / 1440)} days ago`
206− }
207−}
208−
209−function toggleVisibility (id) {
210− const e = document.getElementById(id)
211− if (e.style.display === 'block') { e.style.display = 'none' } else { e.style.display = 'block' }
212−}
213−
214−function escapeHtml (unsafe) {
215− return unsafe.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;')
216−}
217−
218−function cleanTags (unsafe) {
219− return unsafe.replace(/([^a-z0-9]+)/gi, '-')
220−}
221−
222−function stripHash (hash) {
223− const decoded = decodeURIComponent(hash)
224− return decoded.charAt(0) === '#' ? decoded.substring(1) : decoded
225−}
226−
227−function filter (name) {
228− window.location.hash = name
229− const filterAndPage = window.location.hash.split('^')
230− hallway.finder = { filter: stripHash(filterAndPage[0]), page: filterAndPage[1] || 1 }
231− hallway.refresh()
232−}
scripts/indental.jsdeleted−57
@@ -1,57 +0,0 @@
1−'use strict'
2−
3−function indental (data, Type) {
4− function formatLine (line) {
5− const a = []
6− const h = {}
7− for (const child of line.children) {
8− if (child.key) {
9− if (h[child.key]) { console.warn(`Redefined key: ${child.key}.`) }
10− h[child.key] = child.value
11− } else if (child.children.length === 0 && child.content) {
12− a[a.length] = child.content
13− } else {
14− h[child.content.toUpperCase()] = formatLine(child)
15− }
16− }
17− return a.length > 0 ? a : h
18− }
19−
20− function makeLine (line) {
21− return line.indexOf(' : ') > -1 ? {
22− indent: line.search(/\S|$/),
23− content: line.trim(),
24− key: line.split(' : ')[0].trim().toUpperCase(),
25− value: line.split(' : ')[1].trim()
26− } : {
27− indent: line.search(/\S|$/),
28− content: line.trim(),
29− children: []
30− }
31− }
32−
33− function skipLine (line) {
34− return line.trim() !== '' && line.trim().substr(0, 1) !== ';' && line.trim().slice(-1) !== '`'
35− }
36−
37− const lines = data.split('\n').filter(skipLine).map(makeLine)
38−
39− // Assoc
40− const stack = {}
41− for (const line of lines) {
42− const target = stack[line.indent - 2]
43− if (target) { target.children.push(line) }
44− stack[line.indent] = line
45− }
46−
47− // Format
48− const h = {}
49− for (const id in lines) {
50− const line = lines[id]
51− if (line.indent > 0) { continue }
52− const key = line.content.toUpperCase()
53− if (h[key]) { console.warn(`Redefined key: ${key}, line ${id}.`) }
54− h[key] = Type ? new Type(key, formatLine(line)) : formatLine(line)
55− }
56− return h
57−}
scripts/opml.jsdeleted−13
@@ -1,13 +0,0 @@
1−const outlines = sites.filter(site => site.rss).map(site => {
2− return `<outline type="rss" xmlUrl="${site.rss}" title="${site.title}"/>`
3−})
4−
5−const template = `<?xml version="1.0" encoding="UTF-8"?><opml version="1.1"><head></head><body>${outlines.join('')}</body></opml>`
6−
7−window.addEventListener('DOMContentLoaded', () => {
8− const a = document.getElementById('opml')
9− if (a) {
10− a.setAttribute('href', 'data:text/plain;charset=utf-8,' + window.encodeURIComponent(template))
11− a.setAttribute('download', 'webring.opml')
12− }
13−})
scripts/portal.js+23−81
@@ -2,48 +2,26 @@
22
33function Portal (sites) {
44 this.el = document.createElement('div')
5− this.el.id = 'portal'
65 this.sites = sites
76
87 // Templates
98
10− const _readme = '<p class="readme">This webring is an attempt to inspire artists & developers to build their own website and share traffic among each other. The ring welcomes personalized websites such as <b>diaries, wikis & portfolios</b>.</p><p>To add yourself to the ring, submit a <a href="https://github.com/XXIIVV/webring/edit/master/scripts/sites.js" target="_blank">Pull Request</a>.<br />If you found a broken link, please <a href="https://github.com/XXIIVV/webring/issues/new" target="_blank">report it</a>.</p>'
11− const _buttons = '<p class="buttons"><a href="#random" onClick="portal.reload()">Random</a> | <a href="https://github.com/XXIIVV/webring">Information</a> <a id="icon" href="#random" onClick="portal.reload()"></a> | <a href="hallway.html">The Hallway</a> | <a href="wiki.html">The Wiki</a> | <a id="opml">OPML</a></p>'
12−
13− function _directory (sites) {
14− const siteTypesArray = [...new Set(sites.map(site => site.type).filter(Boolean))]
15− const siteLangsArray = [...new Set(sites
16− .reduce((flattened, site) => flattened.concat(site.langs), [])
17− .sort())]
18−
19− const siteTypes = siteTypesArray.reduce((output, siteType) =>
20− `${output}<a data-type="${siteType}" href="#" onclick="filterSites(event)">&lt;${siteType}&gt;</a>`,
21− '<a class="currentType" data-type="all" href="#" onclick="filterSites(event)">&lt;all&gt;</a>')
22−
23− const siteLangs = siteLangsArray.reduce((output, siteLang) =>
24− `${output}<a data-lang="${siteLang}" href="#" onclick="filterSites(event)">&lt;${siteLang}&gt;</a>`,
25− '<a class="currentLang" data-lang="all" href="#" onclick="filterSites(event)">&lt;all&gt;</a>')
26−
27− const listItems = sites.reduce((acc, site, id) =>
28− `${acc}<li ${_type(site)} ${_lang(site)} id='${id}'><a href='${site.url}'>${_name(site)}</a></li>`, '')
29− return `<nav>${siteTypes}</nav><nav>${siteLangs}</nav><main><ul>${listItems}</ul></main><footer>${_readme}${_buttons}</footer>`
9+ function _readme () {
10+ return `<p class='readme'>This webring is an attempt to inspire artists & developers to build their own website and share traffic among each other. The ring welcomes personalized websites such as <b>diaries, wikis & portfolios</b>.</p><p>To add yourself to the ring, submit a <a href='https://github.com/XXIIVV/webring/edit/master/scripts/sites.js' target='_blank'>Pull Request</a>.<br />If you found a broken link, please <a href='https://github.com/XXIIVV/webring/issues/new' target='_blank'>report it</a>.</p>`
3011 }
3112
32− function _name (site) {
33− return site.title || `${site.url.split('//')[1].replace(/\/+$/, '')}`
13+ function _buttons () {
14+ return `<p class='buttons'><a href='#random' onClick="portal.reload('random')">Random</a> | <a href='https://github.com/XXIIVV/webring'>Information</a> <a id='icon' href='#random' onClick="portal.reload('random')"></a></p>`
3415 }
3516
36− function _type (site) {
37− return site.type ? `data-type="${site.type} "` : ''
38− }
39−
40− function _lang (site) {
41− return `data-lang="${site.langs.join(' ').trim()}"`
17+ function _directory (sites) {
18+ return `
19+ <ul>${sites.reduce((acc, val, id) => { return `${acc}<li>${id}) <a href='${val}'>${val.split('//')[1]}</a></li>` }, '')}</ul>\n${_readme()}${_buttons()}`
4220 }
4321
44− function _redirectView (site) {
45− return `<main><p>Redirecting to <a href="${site.url}">${site.url}</a></p></main>
46− <footer><p class='buttons'><a href='#' onClick="portal.reload('')">Directory</a> | <a href='#${site.url}' onClick="portal.reload()">Skip</a> | <a href='#random' onClick="portal.reload()">Random</a> | <a href='https://github.com/XXIIVV/webring'>Information</a> <a id='icon' href='#random' onClick="portal.reload()"></a></p>`
22+ function _redirect (target) {
23+ return `<p>Redirecting to <b>${target}</b></p><meta http-equiv="refresh" content="3; url=${target}">
24+ <p class='buttons'><a href='#' onClick="portal.reload('')">Directory</a> | <a href='#${target}' onClick="portal.reload('random')">Skip</a> | <a href='#random' onClick="portal.reload('random')">Random</a> | <a href='https://github.com/XXIIVV/webring'>Information</a> <a id='icon' href='#random' onClick="portal.reload('random')"></a></p>`
4725 }
4826
4927 //
@@ -53,14 +31,7 @@ function Portal (sites) {
5331 }
5432
5533 this.start = function () {
56− const hash = window.location.hash
57− if (hash && hash.length > 4) {
58− const site = this.getSite(hash.replace('#', '').trim())
59− this.el.innerHTML = _redirectView(site)
60− setTimeout(() => { window.location = site.url }, 3000)
61− } else {
62− this.el.innerHTML = _directory(this.sites)
63− }
34+ this.el.innerHTML = window.location.hash && window.location.hash.length > 4 ? _redirect(this.next()) : _directory(this.sites)
6435 }
6536
6637 this.reload = function () {
@@ -71,51 +42,22 @@ function Portal (sites) {
7142 setTimeout(() => { window.location.href = target }, 3000)
7243 }
7344
74− this.navLangs = [...new Set(navigator.languages.map(lang => lang.split('-').shift()))]
75−
76− this.sitesMatchingLangs = this.sites
77− .filter(site => site.langs && site.langs.some(lang => this.navLangs.includes(lang)))
45+ this.locate = function () {
46+ const hash = window.location.hash.replace('#', '').trim()
7847
79− this.nextSiteIndex = (ceiling, index) => index === ceiling ? 0 : index + 1
80− this.randomSite = this.sitesMatchingLangs[Math.floor(Math.random() * this.sitesMatchingLangs.length)]
81−
82− this.getSite = function (hash) {
83− if (hash === 'random') {
84− return this.randomSite
85− } else {
86− const index = this.sitesMatchingLangs.findIndex(site => site.url.includes(hash))
87− return (index > -1)
88− ? this.sitesMatchingLangs[this.nextSiteIndex(this.sitesMatchingLangs.length, index)]
89− : this.randomSite
48+ if (hash == 'random') {
49+ return Math.floor(Math.random() * this.sites.length)
9050 }
91− }
92−}
93−
94−function filterSites (e) {
95− e.preventDefault()
96− const navLink = e.target
97− const currentFilter = navLink.dataset.lang ? 'Lang' : 'Type'
98−
99− document.querySelector(`nav a.current${currentFilter}`).classList.remove(`current${currentFilter}`)
100− navLink.classList.add(`current${currentFilter}`)
10151
102− const typeFilter = document.querySelector('nav a.currentType').dataset.type
103− const langFilter = document.querySelector('nav a.currentLang').dataset.lang
104−
105− const sites = document.querySelectorAll('main li')
106− sites.forEach(el => { el.style.display = 'block' })
107−
108− sites.forEach(el => {
109− if (typeFilter !== 'all') {
110− if (el.dataset.type) {
111− if (el.dataset.type.trim() !== typeFilter) el.style.display = 'none'
112− } else {
113− el.style.display = 'none'
52+ for (const id in this.sites) {
53+ if (this.sites[id].indexOf(hash) > -1) {
54+ return parseInt(id)
11455 }
11556 }
57+ return -1
58+ }
11659
117− if (langFilter !== 'all') {
118− if (!el.dataset.lang.includes(langFilter)) el.style.display = 'none'
119− }
120− })
60+ this.next = function (loc = this.locate()) {
61+ return loc == this.sites.length - 1 ? this.sites[0] : this.sites[loc + 1]
62+ }
12163}
scripts/progress.jsdeleted−41
@@ -1,41 +0,0 @@
1−'use strict'
2−
3−const Progress = keys => {
4− const stack = new Set(keys.filter(key => key))
5− const loaded = new Set()
6− const failed = new Set()
7−
8− this.ratio = () => {
9− return loaded.size / stack.size
10− }
11−
12− this.percentage = () => {
13− return (100 * this.ratio()).toFixed(2)
14− }
15−
16− const render = () => `
17− <div class='${loaded.size !== stack.size ? 'busy' : 'done'}'>
18− <p>
19− ${'|'.repeat(this.ratio() * 10)}
20− ${loaded.size !== stack.size ? this.percentage() + '% ' : ''}
21− ${loaded.size === stack.size ? 'Complete' : 'Loading'}
22− ${failed.size !== 0 ? `(${failed.size} failed)` : ''}
23− </p>
24− </div>`
25−
26− const didLoad = (key, success) => new Promise((resolve, reject) => {
27− if (stack.has(key)) {
28− loaded.add(key)
29− if (!success) failed.add(key)
30− return resolve()
31− } else {
32− return reject()
33− }
34− })
35−
36− return {
37− success: key => didLoad(key, true),
38− failure: key => didLoad(key, false),
39− toString: render
40− }
41−}
scripts/sites.js+68−922
@@ -1,924 +1,70 @@
1−'use strict'
1+'use strict';
22
3−const sites = [
4− {
5− author: 'neauoire',
6− contact: 'aliceffekt@gmail.com',
7− feed: 'https://wiki.xxiivv.com/twtxt.txt',
8− langs: ['en'],
9− rss: 'https://wiki.xxiivv.com/links/rss.xml',
10− title: 'xxiivv',
11− type: 'wiki',
12− url: 'https://wiki.xxiivv.com',
13− wiki: 'https://wiki.xxiivv.com/src/database/glossary.ndtl'
14− },
15−
16− {
17− langs: ['en'],
18− url: 'http://estevancarlos.com'
19− },
20−
21− {
22− author: 'rho',
23− feed: 'https://electro.pizza/twtxt.txt',
24− langs: ['en'],
25− title: 'electro pizza',
26− type: 'blog',
27− rss: 'https://electro.pizza/feed.xml',
28− url: 'https://electro.pizza'
29− },
30−
31− {
32− author: 'joshavanier',
33− contact: 'joshavanier@protonmail.com',
34− feed: 'https://avanier.now.sh/tw.txt',
35− langs: ['en'],
36− title: 'Arachne',
37− type: 'wiki',
38− url: 'https://avanier.now.sh'
39− },
40−
41− {
42− author: 'kaemura',
43− contact: 'chimera1190@gmail.com',
44− feed: 'https://kaemura.com/twttxt.txt',
45− langs: ['en'],
46− title: 'kaemura.com',
47− type: 'blog',
48− url: 'http://kaemura.com'
49− },
50−
51− {
52− author: 'slisne',
53− contact: '@slisne@merveilles.town',
54− feed: 'https://liamcooke.com/merveilles/tw.txt',
55− langs: ['en'],
56− title: 'liamcooke.com',
57− rss: 'https://liamcooke.com/feed.xml',
58− url: 'https://liamcooke.com',
59− wiki: 'https://liamcooke.com/merveilles/wiki.ndtl'
60− },
61−
62− {
63− langs: ['en'],
64− url: 'https://hraew.autophagy.io'
65− },
66−
67− {
68− langs: ['en'],
69− url: 'http://evenunto.net'
70− },
71−
72− {
73− langs: ['en'],
74− url: 'https://anxl.faith'
75− },
76−
77− {
78− author: 'xvw',
79− contact: 'xaviervdw@gmail.com',
80− langs: ['fr'],
81− feed: 'https://xvw.github.io/twtxt/hallway.txt',
82− rss: 'https://xvw.github.io/atom.xml',
83− title: 'planet',
84− type: 'hybrid',
85− url: 'https://xvw.github.io'
86− },
87−
88− {
89− langs: ['en', 'el'],
90− url: 'https://heracl.es'
91− },
92−
93− {
94− langs: ['en'],
95− url: 'https://turelio.github.io'
96− },
97−
98− {
99− author: 'lectronice',
100− contact: 'i.love.spam@lectronice.com',
101− feed: 'https://lectronice.com/hallway/twtxt.txt',
102− langs: ['en'],
103− title: 'shards',
104− type: 'blog',
105− url: 'https://shards.lectronice.com'
106− },
107−
108− {
109− langs: ['en'],
110− url: 'https://craze.co.uk'
111− },
112−
113− {
114− langs: ['en'],
115− url: 'https://shaneckel.com'
116− },
117−
118− {
119− author: 'cblgh',
120− contact: 'cabal://cblgh.org',
121− feed: 'https://cblgh.org/twtxt.txt',
122− langs: ['en'],
123− title: 'cblgh.org',
124− url: 'https://cblgh.org'
125− },
126−
127− {
128− author: 'afk',
129− contact: 'afk@ellugar.co',
130− langs: ['en'],
131− rss: 'http://feeds.ellugar.co/ellugar-logs',
132− title: 'ellugar',
133− type: 'wiki',
134− url: 'https://ellugar.co'
135− },
136−
137− {
138− author: 'Cameron Higby-Naquin',
139− contact: 'me@chigby.org',
140− langs: ['en'],
141− title: 'chigby.org',
142− type: 'portfolio',
143− url: 'http://chigby.org'
144− },
145−
146− {
147− langs: ['en'],
148− url: 'https://longest.voyage'
149− },
150−
151− {
152− author: 'Paloma Kop',
153− contact: 'doubleobelisk@gmail.com',
154− langs: ['en'],
155− title: 'palomakop.tv',
156− type: 'portfolio',
157− url: 'https://palomakop.tv'
158− },
159−
160− {
161− langs: ['en'],
162− url: 'https://v-os.ca'
163− },
164−
165− {
166− langs: ['en'],
167− url: 'https://jmandel.xyz'
168− },
169−
170− {
171− author: 'jda0',
172− contact: 'hi@2d4.dev',
173− feed: 'https://2d4.dev/tw.txt',
174− langs: ['en'],
175− title: '2d4.dev',
176− url: 'https://2d4.dev',
177− wiki: 'https://2d4.dev/wiki.ndtl'
178− },
179−
180− {
181− langs: ['en'],
182− url: 'https://nathanwentworth.co'
183− },
184−
185− {
186− langs: ['en'],
187− url: 'https://uonai.space'
188− },
189−
190− {
191− langs: ['en'],
192− url: 'http://controls.ee'
193− },
194−
195− {
196− langs: ['en'],
197− url: 'https://wasin.io'
198− },
199−
200− {
201− langs: ['en'],
202− url: 'https://inns.studio'
203− },
204−
205− {
206− langs: ['en'],
207− url: 'http://kokorobot.ca'
208− },
209−
210− {
211− author: 'jrc03c',
212− contact: 'josh@ameyama.com',
213− langs: ['en'],
214− title: 'ameyama',
215− type: 'blog',
216− rss: 'https://ameyama.com/blog/rss.xml',
217− url: 'https://ameyama.com',
218− wiki: 'https://ameyama.com/data/wiki.ndtl'
219− },
220−
221− {
222− author: 'wakest',
223− contact: '@liaizon@wake.st',
224− feed: 'https://wake.st/twtxt.txt',
225− langs: ['en'],
226− title: 'wake.st',
227− url: 'https://wake.st'
228− },
229−
230− {
231− langs: ['en'],
232− url: 'https://xarene.la'
233− },
234−
235− {
236− langs: ['en'],
237− url: 'https://alex.zyzhang.me'
238− },
239−
240− {
241− langs: ['en'],
242− url: 'http://bildwissenschaft.vortok.info'
243− },
244−
245− {
246− langs: ['en'],
247− url: 'https://jakofranko.github.com'
248− },
249−
250− {
251− langs: ['en'],
252− url: 'https://aeriform.io'
253− },
254−
255− {
256− langs: ['en', 'de'],
257− url: 'http://blog.lucasdidthis.com'
258− },
259−
260− {
261− author: 'npisanti',
262− contact: 'nicola@npisanti.com',
263− langs: ['en'],
264− rss: 'http://npisanti.com/journal/rss.xml',
265− title: 'npisanti.com',
266− url: 'http://npisanti.com'
267− },
268−
269− {
270− langs: ['en'],
271− url: 'https://underscorediscovery.ca'
272− },
273−
274− {
275− author: 'drisc',
276− contact: 'cory@drisc.io',
277− feed: 'https://drisc.io/hallway/twtxt.txt',
278− langs: ['en'],
279− title: 'drisc.io',
280− type: 'wiki',
281− url: 'https://drisc.io'
282− },
283−
284− {
285− langs: ['en'],
286− url: 'https://ricky.codes'
287− },
288−
289− {
290− author: 'Marshall Bowers',
291− contact: 'elliott.codes@gmail.com',
292− langs: ['en'],
293− title: 'maxdeviant.com',
294− type: 'hybrid',
295− url: 'https://maxdeviant.com'
296− },
297−
298− {
299− langs: ['en'],
300− url: 'https://tynandebold.com'
301− },
302−
303− {
304− langs: ['en'],
305− url: 'http://gytis.co'
306− },
307−
308− {
309− langs: ['en'],
310− url: 'https://nomand.co'
311− },
312−
313− {
314− langs: ['en'],
315− url: 'http://memoriata.com'
316− },
317−
318− {
319− langs: ['en'],
320− url: 'https://mmm.s-ol.nu'
321− },
322−
323− {
324− contact: 'ubuwaits@gmail.com',
325− langs: ['en'],
326− rss: 'https://chad.is/rss.xml',
327− url: 'https://chad.is'
328− },
329−
330− {
331− langs: ['en'],
332− url: 'https://smidgeo.com/bots'
333− },
334−
335− {
336− langs: ['en', 'ru'],
337− url: 'https://iko.soy'
338− },
339−
340− {
341− langs: ['en'],
342− url: 'http://atelieroilandsugar.com'
343− },
344−
345− {
346− langs: ['en'],
347− url: 'https://magoz.is'
348− },
349−
350− {
351− author: 'Szymon Kaliski',
352− langs: ['en'],
353− rss: 'https://szymonkaliski.com/feed.xml',
354− type: 'hybrid',
355− url: 'https://szymonkaliski.com'
356− },
357−
358− {
359− author: 'setphen',
360− feed: 'https://phse.net/twtxt/merv.txt',
361− langs: ['en'],
362− rss: 'https://phse.net/post/index.xml',
363− title: 'phse.net',
364− type: 'blog',
365− url: 'https://phse.net'
366− },
367−
368− {
369− author: 'rosano',
370− langs: ['en'],
371− url: 'https://rosano.ca',
372− wiki: 'https://rosano.ca/wiki.ndtl'
373− },
374−
375− {
376− langs: ['en'],
377− url: 'https://soyboysky.github.io'
378− },
379−
380− {
381− langs: ['en'],
382− url: 'https://gndclouds.cc'
383− },
384−
385− {
386− langs: ['en', 'fr'],
387− url: 'https://xuv.be'
388− },
389−
390− {
391− langs: ['en', 'zh'],
392− url: 'https://dsdshcym.github.io'
393− },
3+// Don't forget the comma! No trailing slashes
4+// protocole://url.domain.ext
3945
395− {
396− author: 'ckipp',
397− contact: 'ckipp@pm.me',
398− langs: ['en'],
399− title: 'chris-kipp.io',
400− type: 'hybrid',
401− url: 'https://chris-kipp.io'
402− },
403−
404− {
405− langs: ['en'],
406− url: 'https://boffosocko.com'
407− },
408−
409− {
410− author: 'kodedninja',
411− contact: 'karamanhunor@pm.me',
412− feed: 'https://t.seed.hex22.org/twtxt.txt',
413− langs: ['en'],
414− title: 'hex22',
415− url: 'https://hex22.org'
416− },
417−
418− {
419− langs: ['en'],
420− url: 'https://patrikarvidsson.com'
421− },
422−
423− {
424− langs: ['en'],
425− url: 'https://sophieleetmaa.com'
426− },
427−
428− {
429− langs: ['en'],
430− url: 'https://xinniw.github.io'
431− },
432−
433− {
434− author: 'm',
435− contact: 'mboxxed@gmail.com',
436− feed: 'https://mboxed.github.io/sodatsu/tw.txt',
437− langs: ['en'],
438− title: 'sodatsu',
439− type: 'wiki',
440− url: 'https://mboxed.github.io/sodatsu'
441− },
442−
443− {
444− langs: ['en'],
445− url: 'https://letters.vexingworkshop.com'
446− },
447−
448− {
449− author: 'tomupom',
450− contact: 'tom@tomhackshaw.com',
451− langs: ['en'],
452− title: 'Tom Hackshaw',
453− type: 'portfolio',
454− url: 'https://tom.org.nz',
455− feed: 'https://a.tom.org.nz/twtxt.txt',
456− wiki: 'https://a.tom.org.nz/glossary.ndtl'
457− },
458−
459− {
460− title: 'Teknari',
461− langs: ['en'],
462− url: 'https://teknari.com',
463− author: 'teknari',
464− contact: 'teknari@teknari.com',
465− rss: 'https://teknari.com/feed.xml'
466− },
467−
468− {
469− author: 'clic',
470− contact: 'https://t.me/clic_laplata',
471− langs: ['es'],
472− title: 'Colectivo de Livecoders',
473− type: 'blog',
474− url: 'https://colectivo-de-livecoders.gitlab.io'
475− },
476−
477− {
478− langs: ['es'],
479− title: 'madewithtea.com',
480− type: 'blog',
481− url: 'https://www.madewithtea.com'
482− },
483−
484− {
485− author: 'amorris',
486− feed: 'https://feed.amorris.ca/hallway.txt',
487− langs: ['en'],
488− title: 'amorris',
489− type: 'blog',
490− url: 'https://amorris.ca',
491− wiki: 'https://wiki.amorris.ca/glossary.ndtl'
492− },
493−
494− {
495− langs: ['en'],
496− title: 'miha-co',
497− type: 'portfolio',
498− url: 'http://www.miha-co.ca'
499− },
500−
501− {
502− author: 'buzzert',
503− langs: ['en'],
504− title: 'buzzert.net',
505− type: 'blog',
506− url: 'https://buzzert.net'
507− },
508−
509− {
510− author: 'stuartpb',
511− contact: 's@stuartpb.com',
512− feed: 'https://twtxt.stuartpb.com/xxiivv.txt',
513− langs: ['en'],
514− title: 'notes.stuartpb.com',
515− type: 'wiki',
516− url: 'https://notes.stuartpb.com/'
517− },
518−
519− {
520− author: 'serocell',
521− contact: 'psignal@s900.net',
522− feed: 'https://xxiii.co/twtxt.txt',
523− langs: ['en'],
524− rss: 'https://serocell.com/feeds/serocell.xml',
525− title: 'xxiii',
526− type: 'portfolio',
527− url: 'https://xxiii.co'
528− },
529−
530− {
531− author: 'kormyen',
532− contact: 'h@kor.nz',
533− feed: 'https://kor.nz/twtxt.txt',
534− langs: ['en'],
535− title: 'kor',
536− type: 'wiki',
537− url: 'https://kor.nz',
538− wiki: 'https://kor.nz/db/glossary.ndtl'
539− },
540−
541− {
542− author: 'quite',
543− contact: 'quite@hack.org',
544− feed: 'https://lublin.se/twtxt.txt',
545− langs: ['en'],
546− url: 'https://lublin.se'
547− },
548−
549− {
550− author: 'zanneth',
551− contact: 'root@zanneth.com',
552− langs: ['en'],
553− title: 'zanneth.com',
554− type: 'blog',
555− url: 'https://zanneth.com'
556− },
557−
558− {
559− author: 'eli_oat',
560− contact: 'hi@eli.li',
561− feed: 'https://txt.eli.li/twtxt/twtxt.txt',
562− langs: ['en'],
563− rss: 'https://eli.li/feed.rss',
564− title: 'eli.li',
565− type: 'blog',
566− url: 'https://eli.li'
567− },
568−
569− {
570− author: 'gueorgui',
571− contact: 'hello@gueorgui.net',
572− langs: ['en'],
573− title: 'Gueorgui Tcherednitchenko',
574− type: 'portfolio',
575− url: 'https://gueorgui.net'
576− },
577−
578− {
579− author: 'Tate Carson',
580− contact: 'tatecarson@gmail.com',
581− langs: ['en'],
582− title: 'Tate Carson',
583− type: 'portfolio',
584− url: 'https://www.tatecarson.com'
585− },
586−
587− {
588− author: 'azlen',
589− contact: 'webring@azlen.me',
590− feed: 'https://azlen.me/twtxt.txt',
591− langs: ['en'],
592− title: 'azlen.me',
593− type: 'wiki',
594− url: 'https://azlen.me',
595− wiki: 'https://azlen.me/glossary.ndtl'
596− },
597−
598− {
599− author: 'vega',
600− contact: 'vegac@protonmail.com',
601− feed: 'https://opinionatedguide.github.io/twtxt.txt',
602− langs: ['en'],
603− title: 'OpGuides',
604− url: 'https://opinionatedguide.github.io/'
605− },
606−
607− {
608− author: 'cmaughan',
609− contact: 'mornymorny@gmail.com',
610− feed: 'https://chrismaughan.com/twtxt.txt',
611− langs: ['en'],
612− title: 'CMaughan',
613− url: 'https://chrismaughan.com/'
614− },
615−
616− {
617− author: 'RaelZero',
618− contact: 'gaz.gong@gmail.com',
619− title: 'oddworlds soliloquy',
620− langs: ['en', 'es'],
621− type: 'blog',
622− url: 'https://oddworlds.org/'
623− },
624−
625− {
626− author: 'Fundor 333',
627− contact: 'blog@fundor333.com',
628− feed: 'https://fundor333.com/twtxt.txt',
629− langs: ['en'],
630− title: 'Fundor333',
631− type: 'blog',
632− url: 'https://fundor333.com/'
633− },
634−
635− {
636− contact: 'm@cass.si',
637− langs: ['en'],
638− url: 'https://cass.si'
639− },
640−
641− {
642− author: 'dcb',
643− contact: 'dotcomboom@somnolescent.net',
644− feed: 'https://dotcomboom.somnolescent.net/twtxt.txt',
645− langs: ['en'],
646− title: 'somnolescent.net',
647− url: 'https://dotcomboom.somnolescent.net/'
648− },
649−
650− {
651− author: 'Nihiltarier',
652− contact: 'arachi@airmail.cc',
653− langs: ['en'],
654− title: 'cadmican',
655− url: 'https://cadmican.neocities.org/'
656− },
657−
658− {
659− author: 'Jonathan Skjøtt',
660− contact: 'jonathan@jskjott.com',
661− langs: ['en'],
662− title: 'jskjott',
663− url: 'https://jskjott.com'
664− },
665−
666− {
667− author: 'sixeyes',
668− contact: 'elmusho@gmail.com',
669− langs: ['en'],
670− title: 'sixey.es',
671− type: 'portfolio',
672− url: 'https://sixey.es/'
673− },
674−
675− {
676− author: '0xdstn',
677− contact: '0xdstn@protonmail.com',
678− langs: ['en'],
679− title: '0xdstn',
680− type: 'wiki',
681− url: 'https://tilde.town/~dustin/'
682− },
683−
684− {
685− author: 'James',
686− contact: 'henderson.j@protonmail.com',
687− langs: ['en'],
688− rss: 'https://jameschip.io/index.xml',
689− title: 'James Chip',
690− url: 'https://jameschip.io/'
691− },
692−
693− {
694− author: 'Patrick Monaghan',
695− contact: '0x5f.manpat@gmail.com',
696− langs: ['en'],
697− type: 'portfolio',
698− url: 'https://patrick-is.cool'
699− },
700−
701− {
702− author: 'icyphox',
703− contact: 'x@icyphox.sh',
704− langs: ['en'],
705− rss: 'https://icyphox.sh/blog/feed.xml',
706− type: 'hybrid',
707− url: 'https://icyphox.sh'
708− },
709−
710− {
711− author: 'roy niang',
712− contact: 'roy@royniang.com',
713− feed: 'https://telecom.royniang.com/updates.txt',
714− langs: ['en'],
715− title: 'roy niang',
716− type: 'portfolio',
717− url: 'https://royniang.com',
718− wiki: 'https://telecom.royniang.com/usefulnotes.ndtl'
719− },
720−
721− {
722− author: 'raul altosaar',
723− contact: 'raul.altosaar@gmail.com',
724− langs: ['en'],
725− title: 'raul altosaar',
726− type: 'portfolio',
727− url: 'https://www.raul.earth/'
728− },
729−
730− {
731− author: 'Cristi Constantin',
732− langs: ['en'],
733− rss: 'https://crlf.site/feed.xml',
734− title: 'Cr;Lf;',
735− type: 'hybrid',
736− url: 'https://crlf.site'
737− },
738−
739− {
740− contact: 'johannesg@johannesg.com',
741− langs: ['en'],
742− title: 'Jóhannes Gunnar Þorsteinsson',
743− type: 'hybrid',
744− url: 'https://www.johannesg.com'
745− },
746−
747− {
748− author: 'Michael Rupert',
749− contact: 'michaelrupert@fastmail.com',
750− langs: ['en'],
751− title: 'Provoke Analog',
752− type: 'hybrid',
753− url: 'https://provokeanalog.com'
754− },
755−
756− {
757− author: 'eti',
758− contact: 'eti@eti.tf',
759− langs: ['en'],
760− url: 'https://eti.tf'
761− },
762−
763− {
764− author: 'rezmason',
765− contact: 'jeremysachs@rezmason.net',
766− langs: ['en'],
767− title: 'rezmason.net',
768− type: 'hybrid',
769− url: 'https://rezmason.net'
770− },
771−
772− {
773− contact: 'email@estfyr.net',
774− langs: ['en', 'cz'],
775− title: 'estfyr.net',
776− type: 'hybrid',
777− url: 'https://estfyr.net'
778− },
779−
780− {
781− author: 'Payson Wallach',
782− contact: 'payson@paysonwallach.com',
783− langs: ['en'],
784− url: 'https://paysonwallach.com'
785− },
786−
787− {
788− author: 'icco',
789− contact: 'nat@natwelch.com',
790− langs: ['en'],
791− type: 'portfolio',
792− url: 'https://natwelch.com'
793− },
794−
795− {
796− author: 'whtrbt',
797− contact: 'pi@benjamin.gray.land',
798− langs: ['en'],
799− title: 'Park Imminent',
800− type: 'hybrid',
801− url: 'https://parkimminent.com'
802− },
803−
804− {
805− author: 'aklsh',
806− contact: 'akileshkannan@gmail.com',
807− langs: ['en'],
808− url: 'https://aklsh.github.io',
809− type: 'hybrid'
810− },
811−
812− {
813− author: 'hxii',
814− contact: 'paul@glushak.net',
815− langs: ['en'],
816− type: 'hybrid',
817− url: 'https://paulglushak.com'
818− },
819−
820− {
821− author: 'syx',
822− contact: 'hello@simone.computer',
823− langs: ['en', 'ita'],
824− title: 'Simone\'s Computer',
825− type: 'portfolio',
826− url: 'https://simone.computer'
827− },
828−
829− {
830− author: 'xj9',
831− contact: 'xj9@sunshinegardens.org',
832− feed: 'https://xj9.io/.well-known/webring/tw.txt',
833− langs: ['en'],
834− title: 'dreamspace',
835− type: 'blog',
836− rss: 'https://xj9.io/rss.xml',
837− url: 'https://xj9.io',
838− wiki: 'https://xj9.io/.well-known/webring/wiki.ndtl'
839− },
840−
841− {
842− contact: 'joe.jenett@jenett.org',
843− langs: ['en'],
844− rss: 'https://simply.personal.jenett.org/feed',
845− title: 'jenett. simply. personal.',
846− type: 'blog',
847− url: 'https://simply.personal.jenett.org'
848− },
849−
850− {
851− author: 'Wally',
852− contact: 'qpfiffer+xxiivvwebring@gmail.com',
853− langs: ['en'],
854− rss: 'http://q.pfiffer.org/feed.xml',
855− type: 'blog',
856− url: 'http://q.pfiffer.org/'
857− },
858−
859− {
860− author: 'ashpex',
861− contact: 'ashpex@dismail.de',
862− langs: ['en'],
863− title: 'ashpex',
864− type: 'blog',
865− url: 'https://ashpex.neocities.org'
866− },
867−
868− {
869− author: 'zvava',
870− contact: 'notminin@pm.me',
871− langs: ['en'],
872− title: 'zvava',
873− type: 'blog',
874− url: 'https://zvava.org/'
875− },
876−
877− {
878− author: 'Amorphous',
879− contact: 'dl.amorphous@gmail.com',
880− langs: ['en'],
881− url: 'https://amorphic.space'
882− },
883−
884− {
885− author: 'Edwin Wenink',
886− contact: 'edwinwenink@hotmail.com',
887− langs: ['en', 'nl'],
888− rss: 'https://www.edwinwenink.xyz/index.xml',
889− title: 'Archive Fever',
890− type: 'blog',
891− url: 'https://www.edwinwenink.xyz/'
892− },
893−
894− {
895− author: 'Anne-Laure Le Cunff',
896− contact: 'alecunff@gmail.com',
897− langs: ['en', 'fr'],
898− rss: 'https://www.mentalnodes.com/sitemap.xml',
899− title: 'Mental Nodes',
900− type: 'hybrid',
901− url: 'https://www.mentalnodes.com'
902− },
903−
904− {
905− author: 'librenauta',
906− contact: 'librenauta@riseup.net',
907− langs: ['es'],
908− title: 'copiona',
909− type: 'blog, hybrid',
910− url: 'https://copiona.com'
911− }
912−]
913−
914−/*
915−Make sure you've read the README!
916−Don't forget the comma on the previous entry!
917−No trailing slashes or commas!
918−Alphabetize your keys!
919−protocol://url.domain.ext
920−*/
921−
922−if (module && module.exports) {
923− module.exports = sites
924−}
6+const sites = [
7+ "https://wiki.xxiivv.com"
8+ , "http://estevancarlos.com"
9+ , "https://electro.pizza"
10+ , "https://monochromatic.co"
11+ , "https://joshavanier.github.io"
12+ , "http://kaemura.com"
13+ , "https://liamcooke.com"
14+ , "https://electricgecko.de"
15+ , "https://wichniow.ski"
16+ , "https://hraew.autophagy.io"
17+ , "https://evenunto.net"
18+ , "https://anxl.faith"
19+ , "https://xvw.github.io"
20+ , "https://heracl.es"
21+ , "https://felipecortez.net"
22+ , "http://luminghao.com"
23+ , "https://theiceshelf.com"
24+ , "https://turelio.github.io"
25+ , "https://spaceshipsin.space"
26+ , "http://log.lectronice.com"
27+ , "https://craze.co.uk"
28+ , "https://shaneckel.com"
29+ , "https://cblgh.org"
30+ , "https://ellugar.co"
31+ , "http://hur.bet"
32+ , "http://chigby.org"
33+ , "https://longest.voyage"
34+ , "https://palomakop.tv"
35+ , "https://travisshears.com"
36+ , "https://v-os.ca"
37+ , "http://secretinternet.club"
38+ , "https://jmandel.xyz"
39+ , "https://systems.ws"
40+ , "https://jamesin.space"
41+ , "https://nathanwentworth.co"
42+ , "https://eswat.ca"
43+ , "https://uonai.space"
44+ , "http://controls.ee"
45+ , "https://wasin.io"
46+ , "https://inns.studio"
47+ , "http://kokorobot.ca"
48+ , "https://ameyama.com"
49+ , "https://wake.st"
50+ , "https://xarene.la"
51+ , "https://alex.zyzhang.me"
52+ , "http://bildwissenschaft.vortok.info"
53+ , "https://jakofranko.github.com"
54+ , "https://aeriform.io"
55+ , "http://blog.lucasdidthis.com"
56+ , "http://npisanti.com"
57+ , "https://underscorediscovery.ca"
58+ , "https://drisc.io"
59+ , "https://neufv.website"
60+ , "https://simbolo.xyz"
61+ , "https://ricky.codes"
62+ , "https://maxdeviant.com"
63+ , "https://tynandebold.com"
64+ , "http://gytis.co"
65+ , "https://nomand.co"
66+ , "http://memoriata.com"
67+ , "https://mmm.s-ol.nu"
68+ , "https://chad.is"
69+ , "https://smidgeo.com/bots"
70+];
scripts/wiki.jsdeleted−176
@@ -1,176 +0,0 @@
1−'use strict'
2−
3−const Wiki = sites => {
4− const entries = {}
5− const main = document.getElementById('main')
6− const aside = document.getElementById('aside')
7− const progress = document.getElementById('progress')
8− const progressCounter = Progress(sites.map(site => site.wiki))
9− const authors = new Set()
10− const terms = new Set()
11−
12− const encodeUrl = text => text.replace(/ /g, '+').trim().toLowerCase()
13−
14− const cleanEntry = entry => {
15− const temp = document.createElement('div')
16− temp.textContent = entry
17− return temp.innerHTML
18− }
19−
20− const storeEntry = (author, url, category, term, unCleanEntry) => {
21− const entry = Array.isArray(unCleanEntry)
22− ? unCleanEntry.map(x => cleanEntry(x))
23− : cleanEntry(unCleanEntry)
24−
25− if (!(category in entries)) {
26− entries[category] = {}
27− entries[category][term] = [{ entry, authors: [{ author, url }] }]
28− } else if (!(term in entries[category])) {
29− entries[category][term] = [{ entry, authors: [{ author, url }] }]
30− } else {
31− const possibleIndex = entries[category][term].findIndex(existing => existing.entry === entry)
32− possibleIndex > -1
33− ? entries[category][term][possibleIndex].authors.push({ author, url })
34− : entries[category][term].push({ entry, authors: [{ author, url }] })
35− }
36− terms.add(term)
37− authors.add(author)
38− }
39−
40− const storeEntries = (author, url, category, entries) => {
41− Array.isArray(entries)
42− ? storeEntry(author, url, category, `${category}-list-definition`, entries)
43− : Object.keys(entries).forEach(entry => storeEntry(author, url, category, entry, entries[entry]))
44− }
45−
46− const transform = (author, url, ndtl) => {
47− Object.keys(ndtl).forEach(category => storeEntries(author, url, category, ndtl[category]))
48− }
49−
50− const parse = (site, content) => {
51− console.log('Wiki', 'Parsing ' + site.wiki)
52− const ndtl = indental(content)
53− transform(site.author, site.url, ndtl)
54− }
55−
56− const selected = (key, category) => key.toLowerCase() === category.toLowerCase()
57− ? 'selected'
58− : ''
59−
60− const randomTerm = () => {
61− const keys = Object.keys(entries)
62− return keys[Math.floor(Math.random() * keys.length)]
63− }
64−
65− const formatSideBarCat = (key, entries) => (currentHtml, cat) => {
66− const catLength = Object.keys(entries[cat]).length
67− const newHtml = `<li class='${selected(key, cat)}'}'>
68− <a href='#${encodeUrl(cat)}' data-msgs='${catLength}'>${cat.toLowerCase()}</a>
69− </li>`
70− return `${currentHtml}${newHtml}`
71− }
72−
73− const formatLinks = text => text.replace(
74− /\b((https?|dat):\/\/[^"\s]+)/g,
75− '<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>'
76− )
77−
78− const formatAuthor = (authors, author) => {
79− return `${authors}<a class='author' target='_blank' href='${author.url}'> @${author.author}</a>`
80− }
81−
82− const formatEntry = (definitions, definition) => {
83− const formatEntryList = entryList => entryList.reduce((items, item) => `${items}<li>${formatLinks(item)}</li>`, '')
84−
85− const newHtml = typeof definition.entry === 'string'
86− ? `<li>${formatLinks(definition.entry)}
87− - ${definition.authors.reduce(formatAuthor, '')}
88− </li>`
89− : `<li><ul>${formatEntryList(definition.entry)}
90− - ${definition.authors.reduce(formatAuthor, '')}
91− </ul></li>`
92−
93− return `${definitions}${newHtml}`
94− }
95−
96− const formatEntries = entries => (currentHtml, category) => {
97− const definitions = entries[category].reduce(formatEntry, '')
98− const title = category.endsWith('list-definition')
99− ? ''
100− : `<li class='name'><strong>${category.toLowerCase()}</strong></li>`
101− return `${currentHtml}<ul class='term'>${title}${definitions}</ul>`
102− }
103−
104− const findRelated = key => {
105− const searchOtherCategories = entry => {
106− return Object.keys(entries)
107− .filter(category => Object.keys(entries[category]).some(otherCat => otherCat === entry))
108− }
109−
110− const foundMatches = Object.keys(entries[key])
111− .filter(entry => !entry.endsWith('list-definition'))
112− .map(searchOtherCategories)
113− const flattened = [].concat.apply([], foundMatches)
114− return Array.from(new Set(flattened)).filter(related => related !== key)
115− }
116−
117− const formatRelated = (allRelated, relatedCategory) => {
118− const newHtml = `<span><a href='#${encodeUrl(relatedCategory)}'>/${relatedCategory.toLowerCase()}</a> </span>`
119− return `${allRelated}${newHtml}`
120− }
121−
122− const refresh = key => {
123− if (key) {
124− if (entries[key] === undefined) return
125− const items = Object.keys(entries[key]).sort().reduce(formatEntries(entries[key]), '')
126− const relatedCategories = findRelated(key)
127− const relatedHtml = relatedCategories.length > 0
128− ? relatedCategories.reduce(formatRelated, 'Related categories: ')
129− : ''
130− main.innerHTML = `<div class='related'><h1>${key}</h1>${relatedHtml}</div>${items}`
131− } else {
132− const html = `Click a /topic to get started, or try a <a href='#${randomTerm()}'>random page</a>`
133− const stats = `The wiki contains ${terms.size} terms in ${Object.keys(entries).length} categories, from ${authors.size} authors.`
134− main.innerHTML = `<h1>WIKI</h1>${html}<br />${stats}`
135− }
136−
137− const homeCat = `<li class='${selected(key, '')}'>
138− <a href='#' data-msgs='${terms.size}'>home</a>
139− </li>`
140− const cats = Object.keys(entries).sort().reduce(formatSideBarCat(key, entries), homeCat)
141− aside.innerHTML = `<ul>${cats}</ul>`
142− }
143−
144− const refreshProgress = () => {
145− progress.innerHTML = `${progressCounter}`
146− }
147−
148− return {
149− initialize: hash => {
150− console.log('Wiki', 'Fetching...')
151− refreshProgress()
152− sites.filter(site => site.wiki && site.author).forEach(site => {
153− fetch(site.wiki, { cache: 'no-store' }).then(x => x.text()).then(content => {
154− parse(site, content)
155− refresh(stripHash(hash))
156− progressCounter.success(site.wiki).then(refreshProgress)
157− }).catch((err) => {
158− console.warn(`${site.wiki}`, err)
159− progressCounter.failure(site.wiki).then(refreshProgress)
160− })
161− })
162− },
163− refresh: key => { refresh(key) }
164− }
165−}
166−
167−const decodeUrl = text => text.replace(/\+/g, ' ').trim().toUpperCase()
168−
169−const stripHash = hash => {
170− const decoded = decodeURIComponent(hash)
171− return decoded.charAt(0) === '#' ? decodeUrl(decoded.substring(1)) : decoded
172−}
173−
174−window.addEventListener('hashchange', () => {
175− wiki.refresh(stripHash(window.location.hash))
176−})
tools/extract_twtxt.jsdeleted−22
@@ -1,22 +0,0 @@
1−'use strict'
2−
3−// extract twtxt feeds from sites.js
4−
5−const fs = require('fs')
6−const sites = require('../scripts/sites.js')
7−const record = { following: {} }
8−
9−for (const site of sites) {
10− if (!site.author || !site.feed) { continue }
11− record.following[site.author] = site.feed
12−}
13−
14−const json = JSON.stringify(record)
15−
16−fs.writeFile('twtxt.json', json, 'utf8', (err) => {
17− if (err) {
18− console.log('An error occured while writing JSON Object to File.')
19− return console.log(err)
20− }
21− console.log('Done.')
22−})
tools/twtxt.jsondeleted−1
@@ -1 +0,0 @@
1−{"following":{"neauoire":"https://wiki.xxiivv.com/twtxt.txt","rho":"https://electro.pizza/twtxt.txt","joshavanier":"https://avanier.now.sh/tw.txt","kaemura":"https://kaemura.com/twttxt.txt","slisne":"https://liamcooke.com/merveilles/tw.txt","xvw":"https://xvw.github.io/twtxt/hallway.txt","lectronice":"https://lectronice.com/hallway/twtxt.txt","cblgh":"https://cblgh.org/twtxt.txt","jda0":"https://2d4.dev/tw.txt","wakest":"https://wake.st/twtxt.txt","drisc":"https://drisc.io/hallway/twtxt.txt","setphen":"https://phse.net/twtxt/merv.txt","kodedninja":"https://t.seed.hex22.org/twtxt.txt","m":"https://mboxed.github.io/sodatsu/tw.txt","tomupom":"https://a.tom.org.nz/twtxt.txt","amorris":"https://feed.amorris.ca/hallway.txt","stuartpb":"https://twtxt.stuartpb.com/xxiivv.txt","serocell":"https://xxiii.co/twtxt.txt","kormyen":"https://kor.nz/twtxt.txt","quite":"https://lublin.se/twtxt.txt","eli_oat":"https://txt.eli.li/twtxt/twtxt.txt","azlen":"https://azlen.me/twtxt.txt","vega":"https://opinionatedguide.github.io/twtxt.txt","cmaughan":"https://chrismaughan.com/twtxt.txt","Fundor 333":"https://fundor333.com/twtxt.txt","dcb":"https://dotcomboom.somnolescent.net/twtxt.txt","roy niang":"https://telecom.royniang.com/updates.txt","xj9":"https://xj9.io/.well-known/webring/tw.txt"}}
wiki.htmldeleted−33
@@ -1,33 +0,0 @@
1−<!DOCTYPE html>
2−<html lang="en">
3−<head>
4− <meta charset="utf-8">
5− <meta name="viewport" content="width=device-width, initial-scale=1.0">
6− <link rel="stylesheet" type="text/css" href="links/fonts.css"/>
7− <link rel="stylesheet" type="text/css" href="links/main.css"/>
8− <script type="text/javascript">const module = { exports:{} }</script>
9− <script src="scripts/progress.js"></script>
10− <script src="scripts/wiki.js"></script>
11− <script src="scripts/sites.js"></script>
12− <script src="scripts/indental.js"></script>
13− <script src="scripts/opml.js"></script>
14− <title>Wiki</title>
15−</head>
16−<body>
17− <div id="wiki">
18− <main>
19− <div id="main"></div>
20− <aside id="aside"></aside>
21− </main>
22− <footer id="footer">
23− <p>The <strong>Wiki</strong> is a decentralized encyclopedia, to join the conversation, add a <a href="https://github.com/XXIIVV/webring#joining-the-wiki">wiki:</a> field to your entry in the <a href="https://github.com/XXIIVV/Webring/">webring</a>.</p>
24− <p class='buttons'><a href='https://github.com/XXIIVV/webring'>Information</a> | <a href="hallway.html">The Hallway</a> | <a href="index.html">The Portal</a> | <a id="opml">OPML</a></p>
25− <div id="progress"></div>
26− </footer>
27− </div>
28− <script>
29− const wiki = Wiki(sites)
30− wiki.initialize(window.location.hash)
31− </script>
32−</body>
33−</html>