diff --git a/hallway.html b/hallway.html
deleted file mode 100644
index 56b4194..0000000
--- a/hallway.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- Hallway
-
-
-
-
-
diff --git a/scripts/hallway.js b/scripts/hallway.js
deleted file mode 100644
index 3f88979..0000000
--- a/scripts/hallway.js
+++ /dev/null
@@ -1,232 +0,0 @@
-'use strict'
-
-const reChannel = /(\s|^)\/([a-zA-Z0-9]+)/g
-const reUser = /((\s|^)@<[a-zA-Z0-9./:\-_+~#= ]*>)/g
-const reTag = /(^|\s)(#[a-z\d-]+)/ig
-const reUrl = /((https?):\/\/(([-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b)([-a-zA-Z0-9@:%_+.~#?&//=]*)))/g
-
-function Hallway (sites) {
- const feeds = {}
- this.sites = sites
- this._el = document.createElement('div')
- this._el.id = 'hallway'
- const filterAndPage = window.location.hash.split('^')
- this.finder = { filter: stripHash(filterAndPage[0]), page: filterAndPage[1] || 1 }
- this.cache = null
-
- this._main = document.createElement('main')
- this._main.id = 'entries'
- this._footer = document.createElement('footer')
- this._footer.id = 'footer'
- this.readme = 'The Hallway is a decentralized forum, to join the conversation, add a feed: field to your entry in the webring .
'
- this.nav = 'Information | The Portal | The Wiki | OPML
'
- this._footer.innerHTML = `${this.readme}${this.nav}`
-
- this.install = function (host) {
- this._el.appendChild(this._main)
- this._el.appendChild(this._footer)
- host.appendChild(this._el)
- this.findFeeds()
- }
-
- this.start = function () {
- this._main.innerHTML = 'Loading..'
- this.fetchFeeds()
- }
-
- this.refresh = function (feeds = this.cache) {
- const entries = this.findEntries(feeds)
- const localEntries = entries.filter(entry => this.filterExternals(entry))
- const channels = this.find(localEntries, 'channel')
- const users = this.find(localEntries, 'author')
- const tags = this.findTags(localEntries)
- const relevantEntries = localEntries
- .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)))
-
- const mainHtml = `
-
- ${relevantEntries.filter((_, id) => id < Number(this.finder.page) * 20 && id >= (Number(this.finder.page) - 1) * 20).reduce((acc, val) => acc + this.templateEntry(val) + '\n', '')}
-
-
-
`
-
- const aside = `
-
-
-
-
- ${Object.keys(users).slice(0, 15).reduce((acc, val) => acc + `${val} ${users[val]} \n`, '')}
-
-
- `
-
- this._main.innerHTML = `${mainHtml}${aside}`
-
- if (feeds) {
- this.cache = feeds
- }
- }
-
- // Entries
-
- this.filterExternals = function (entry) {
- const matches = entry.body.match(reUser)
- const locals = Object.keys(feeds)
- return matches ? matches.some(match => locals.some(local => match.indexOf(feeds[local].path) !== -1)) : true
- }
-
- this.find = function (entries, key) {
- const h = {}
- for (const entry of entries) {
- if (entry && entry[key]) {
- h[entry[key]] = h[entry[key]] ? h[entry[key]] + 1 : 1
- }
- }
- return h
- }
-
- this.findTags = function (entries) {
- const tags = {}
- for (const entry of entries) {
- entry.tags.map(tag => {
- tags[tag] = tags[tag] ? tags[tag] + 1 : 1
- })
- }
- return tags
- }
-
- this.findEntries = function (feeds) {
- const a = []
- for (const id in feeds) {
- for (const i in feeds[id].content) {
- a.push(feeds[id].content[i])
- }
- }
- return a.sort((a, b) => a.offset - b.offset)
- }
-
- this.findMention = function (found) {
- const mention = Object.keys(feeds).filter(user => found.indexOf(feeds[user].path) > -1)
- return ` ${mention[0]} `
- }
-
- this.templateEntry = function (entry) {
- entry.html = entry.body
- .replace(reChannel, '$1/$2 ')
- .replace(reUser, this.findMention)
- .replace(reTag, '$1$2 ')
- .replace(reUrl, '$1 ')
-
- const filter = window.location.hash.substr(1).replace(/\+/g, ' ').toLowerCase()
- const highlight = filter === entry.author.toLowerCase()
- const origin = feeds[entry.author].path
-
- return `${timeAgo(Date.parse(entry.date))} ${entry.author} ${entry.html} `
- }
-
- // Feeds
-
- this.findFeeds = function () {
- console.log('Finding feeds..')
- for (const site of sites) {
- if (site.feed && site.author) {
- feeds[site.author] = { path: site.feed }
- }
- }
- console.log(`Found ${Object.keys(feeds).length} feeds.`)
- }
-
- this.fetchFeeds = function () {
- console.log(`Fetching ${Object.keys(feeds).length} feeds..`)
- for (const id in feeds) {
- this.fetchFeed(id, feeds[id])
- }
- }
-
- this.fetchFeed = function (id, feed) {
- console.log(`Fetching ${id}(${feed.path})..`)
- fetch(feed.path, { cache: 'no-store' }).then(x => x.text()).then((content) => {
- feeds[id].content = parseFeed(id, content)
- this.refresh(feeds)
- }).catch((err) => {
- console.warn(`${id}`, err)
- })
- }
-
- // Utils
-
- function parseFeed (author, feed) {
- const lines = feed.split('\n').filter((line) => line.substr(0, 1) !== '#')
- const entries = []
- for (const id in lines) {
- const line = lines[id].trim()
- if (line === '') { continue }
- const parts = line.replace(' ', '\t').split('\t')
- const date = parts[0].trim()
- const body = escapeHtml(parts[1].trim()).trim()
- const channel = body.substr(0, 1) === '/' ? cleanTags(body.split(' ')[0].substr(1).toLowerCase()) : body.substr(0, 1) === '@' ? 'veranda' : 'lobby'
- const tags = (body.match(reTag) || []).map(a => cleanTags(a.substr(a.indexOf('#') + 1).toLowerCase()))
- const offset = new Date() - new Date(date)
- entries.push({ date, body, author, offset, channel, tags })
- }
- return entries
- }
-
- function timeAgo (dateParam) {
- const date = typeof dateParam === 'object' ? dateParam : new Date(dateParam)
- const today = new Date()
- const yesterday = new Date(today - 86400000)
- const seconds = Math.round((today - date) / 1000)
- const minutes = Math.round(seconds / 60)
- const isToday = today.toDateString() === date.toDateString()
- const isYesterday = yesterday.toDateString() === date.toDateString()
-
- if (seconds < 5) {
- return 'just now'
- } else if (seconds < 60) {
- return `${seconds} seconds ago`
- } else if (seconds < 90) {
- return 'a minute ago'
- } else if (minutes < 60) {
- return `${minutes} minutes ago`
- } else if (isToday) {
- return `${Math.floor(minutes / 60)} hours ago`
- } else if (isYesterday) {
- return 'yesterday'
- }
-
- return `${Math.floor(minutes / 1440)} days ago`
- }
-}
-
-function toggleVisibility (id) {
- const e = document.getElementById(id)
- if (e.style.display === 'block') { e.style.display = 'none' } else { e.style.display = 'block' }
-}
-
-function escapeHtml (unsafe) {
- return unsafe.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''')
-}
-
-function cleanTags (unsafe) {
- return unsafe.replace(/([^a-z0-9]+)/gi, '-')
-}
-
-function stripHash (hash) {
- const decoded = decodeURIComponent(hash)
- return decoded.charAt(0) === '#' ? decoded.substring(1) : decoded
-}
-
-function filter (name) {
- window.location.hash = name
- const filterAndPage = window.location.hash.split('^')
- hallway.finder = { filter: stripHash(filterAndPage[0]), page: filterAndPage[1] || 1 }
- hallway.refresh()
-}
diff --git a/scripts/indental.js b/scripts/indental.js
deleted file mode 100644
index 5193a08..0000000
--- a/scripts/indental.js
+++ /dev/null
@@ -1,57 +0,0 @@
-'use strict'
-
-function indental (data, Type) {
- function formatLine (line) {
- const a = []
- const h = {}
- for (const child of line.children) {
- if (child.key) {
- if (h[child.key]) { console.warn(`Redefined key: ${child.key}.`) }
- h[child.key] = child.value
- } else if (child.children.length === 0 && child.content) {
- a[a.length] = child.content
- } else {
- h[child.content.toUpperCase()] = formatLine(child)
- }
- }
- return a.length > 0 ? a : h
- }
-
- function makeLine (line) {
- return line.indexOf(' : ') > -1 ? {
- indent: line.search(/\S|$/),
- content: line.trim(),
- key: line.split(' : ')[0].trim().toUpperCase(),
- value: line.split(' : ')[1].trim()
- } : {
- indent: line.search(/\S|$/),
- content: line.trim(),
- children: []
- }
- }
-
- function skipLine (line) {
- return line.trim() !== '' && line.trim().substr(0, 1) !== ';' && line.trim().slice(-1) !== '`'
- }
-
- const lines = data.split('\n').filter(skipLine).map(makeLine)
-
- // Assoc
- const stack = {}
- for (const line of lines) {
- const target = stack[line.indent - 2]
- if (target) { target.children.push(line) }
- stack[line.indent] = line
- }
-
- // Format
- const h = {}
- for (const id in lines) {
- const line = lines[id]
- if (line.indent > 0) { continue }
- const key = line.content.toUpperCase()
- if (h[key]) { console.warn(`Redefined key: ${key}, line ${id}.`) }
- h[key] = Type ? new Type(key, formatLine(line)) : formatLine(line)
- }
- return h
-}
diff --git a/scripts/opml.js b/scripts/opml.js
deleted file mode 100644
index 5175225..0000000
--- a/scripts/opml.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const outlines = sites.filter(site => site.rss).map(site => {
- return ` `
-})
-
-const template = `${outlines.join('')} `
-
-window.addEventListener('DOMContentLoaded', () => {
- const a = document.getElementById('opml')
- if (a) {
- a.setAttribute('href', 'data:text/plain;charset=utf-8,' + window.encodeURIComponent(template))
- a.setAttribute('download', 'webring.opml')
- }
-})
diff --git a/scripts/portal.js b/scripts/portal.js
deleted file mode 100644
index a8a9fc9..0000000
--- a/scripts/portal.js
+++ /dev/null
@@ -1,121 +0,0 @@
-'use strict'
-
-function Portal (sites) {
- this.el = document.createElement('div')
- this.el.id = 'portal'
- this.sites = sites
-
- // Templates
-
- const _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 diaries, wikis & portfolios .
To add yourself to the ring, submit a Pull Request . If you found a broken link, please report it .
'
- const _buttons = 'Random | Information | The Hallway | The Wiki | OPML
'
-
- function _directory (sites) {
- const siteTypesArray = [...new Set(sites.map(site => site.type).filter(Boolean))]
- const siteLangsArray = [...new Set(sites
- .reduce((flattened, site) => flattened.concat(site.langs), [])
- .sort())]
-
- const siteTypes = siteTypesArray.reduce((output, siteType) =>
- `${output}<${siteType}> `,
- '<all> ')
-
- const siteLangs = siteLangsArray.reduce((output, siteLang) =>
- `${output}<${siteLang}> `,
- '<all> ')
-
- const listItems = sites.reduce((acc, site, id) =>
- `${acc}${_name(site)} `, '')
- return `${siteTypes} ${siteLangs} `
- }
-
- function _name (site) {
- return site.title || `${site.url.split('//')[1].replace(/\/+$/, '')}`
- }
-
- function _type (site) {
- return site.type ? `data-type="${site.type} "` : ''
- }
-
- function _lang (site) {
- return `data-lang="${site.langs.join(' ').trim()}"`
- }
-
- function _redirectView (site) {
- return `Redirecting to ${site.url}
-