Js = js.global
function Js:L(s)
return (load('return '..s) or load(s))()
end
function Await(promise)
local co = coroutine.running()
promise['then'](promise, function(_, ...)
coroutine.resume(co, ...)
end)
return coroutine.yield()
end
function Css(s)
Js.document.styleSheets[0]:insertRule(s)
end
function Elem(tag, parent, css)
parent = parent or Js.document.body
local ans = Js.document:createElement(tag)
parent:appendChild(ans)
for k,v in pairs(css or {}) do
ans.style[k] = v
end
return ans
end
if Js.navigator.userAgent:find('Mobi') then
Css[[
body {
color:#dddddd;
background-color:#000000;
font-family: 'open sans', sans-serif;
font-size: 30;
zoom: 2;
}
]]
else
Css[[
body {
color:#dddddd;
background-color:#000000;
font-family: 'open sans', sans-serif;
font-size: 13px;
}
]]
end
Css[[
input, textarea {
color:#dddddd;
background-color:#000000;
border: 1px solid #444444;
}
]]
Css[[
a:link {
text-decoration:none;
color: #ffa250;
}
]]
Css[[
a:visited {
color: #ffa250;
}
]]
Css[[
a:hover {
text-decoration:underline;
}
]]
function Header()
local div = Elem('div', nil, {
position = 'relative',
['margin-bottom'] = '10px',
})
Elem('img', div, {
width = '100%',
opacity = .2,
position = 'absolute',
['pointer-events'] = 'none',
['user-select'] = 'none',
}).src = math.random(1, 10) == 1 and '/static/ierusalimschy.jpg' or '/static/timeflies.png'
Elem('br', div)
for _,k in ipairs{'', 'presets', 'chat', 'music', 'threads'} do
local elem
if '/'..k == Js.location.pathname then
elem = Elem('span', div)
elem.style['font-size'] = '22px'
else
elem = Elem('a', div)
elem.href = '/'..k
end
div:appendChild(Js.document:createTextNode(' \194\160 '))
if k == '' then
elem.style.font = 'courier new'
elem.style['font-weight'] = 'bold'
elem.style['font-size'] = '50px'
elem.style.width = '60px'
local function f()
elem.innerText = 'EϘ'..(math.random(0, 1) == 0 and 'E' or 'Ǝ')
Js:setTimeout(f, math.random(1, 200))
end
f()
else
elem.innerText = k
end
end
Header = function() return div end
return Header()
end
EscHtml = function(s)
if s == nil then
s = ''
else
s = tostring(s)
:gsub('%>', '>')
:gsub('%<', '<')
end
return s
end
_G.Deeplink = function(url)
local youtubeId = url:match('https?%:%/%/youtube%.com%/watch%?v%=([%w%-%_]+)')
or url:match('https?%:%/%/www%.youtube%.com%/watch%?%v=([%w%-%_]+)')
or url:match('https?%:%/%/youtu%.be%/([%w%-%_]+)')
or url:match('https?%:%/%/www%.youtu%.be%/([%w%-%_]+)')
local function ext(t)
for _,v in pairs(t) do
if url:match('%.'..v..'$') or url:match('%.'..v..'%?[^.]+$') then
return true
end
end
end
local function href()
return url:gsub('(%")', '\\"')
end
if youtubeId then
return '\n\n'
elseif ext{'png', 'jpg', 'webp'} then
return ''
..''
..''
elseif ext{'mov', 'mp4', 'webm'} then
return ''
else
return ''..EscHtml(url)..''
end
end
local function linkmatcher(...)
local t = {...}
for i=1,#t do
local pre = t[i]:sub(1, 7)
if pre == 'http://' or pre == 'https:/' then
t[i] = Deeplink(t[i])
end
end
return table.concat(t)
end
_G.Markdown = function(s)
-- links
-- there's a bug where, if you have two links right next to eachother only separated by a single whitespace character,
-- it will only Deeplink on the first one and leave the 2nd one as plaintext. easy workaround is to have 2 space between
-- the links. but i probably need to properly fix this at some point
local o = '([%s%(%)])'
local l = '(https?%:%/%/[^%s]-)'
s = s:gsub(o..l..o, linkmatcher)
s = s:gsub('^'..l..o, linkmatcher)
s = s:gsub(o..l..'$', linkmatcher)
s = s:gsub('^'..l..'$', linkmatcher)
-- newlines
s = s:gsub('\n', ' ')
return s
end