Compare commits

...

51 Commits

Author SHA1 Message Date
L3D 41feb31c7b Update dl_tweets.sh to ?limit=42 2021-12-30 19:28:20 +00:00
Ral 44e5af67f6 Fix JS for older browsers 2021-12-29 00:41:09 +01:00
Ral 17c6ca439c Redirects 2021-12-29 00:13:54 +01:00
Ral 964a3154f1 Add /schedule/ 2021-12-29 00:02:14 +01:00
Ral 990bf9f6cc Other cms data endpoint 2021-12-28 23:56:09 +01:00
Jan Koppe 1014b4c798 lalalala 2021-12-28 22:55:18 +00:00
Ral 70b666f456 Fix production config 2021-12-28 23:48:26 +01:00
Ral 960b3f9a28 Info endpoint /cms/ 2021-12-28 23:41:25 +01:00
Ral 3b94bb3fc4 Proper talk title display 2021-12-27 21:58:23 +01:00
Ral 316a9d05dd Rollback 2021-12-27 20:32:36 +01:00
Ral 9a607606b7 Show talk title in /hashtag/ 2021-12-27 20:18:41 +01:00
Ral 4c13cb96e9 Plainfy tweets 2021-12-27 18:46:10 +01:00
Ral 3e299cb240 Add OBS style injection class 2021-12-27 18:32:11 +01:00
Ral 49049693f6 Feature requests 2021-12-27 17:01:20 +01:00
Ral e2f6bfb51d New endpoints
Available info endpoints:

* /
* /music/
* /hashtag/
* /music-and-posts/
2021-12-27 16:11:53 +01:00
Ral be69a7b196 RC3_2 2021-12-27 00:46:53 +01:00
Ral 201ce27daf RC3 2021-12-27 00:26:02 +01:00
Ral a8c13b0dab Update music styling 2021-12-26 22:33:18 +01:00
Ral 331a42e306 RC2.6 2021-12-26 22:23:45 +01:00
Ral 2df36a0564 RC2.5 2021-12-26 21:23:15 +01:00
Ral bde8143c94 RC2 2021-12-26 06:05:20 +01:00
Ral a7d90d73cf RC1 2021-12-26 05:50:45 +01:00
Ral 08a51b5758 Infobeamer Update: RC0 2021-12-26 05:29:23 +01:00
Ral ca971c34ad Another try try 2021-12-26 03:45:32 +01:00
L3D 0be8ad07e8
adding link to https://gitlab.montage2.de/r3l/html-infobeamer-content.git 2021-12-26 03:43:23 +01:00
L3D f916f4f3ef
Adding link to hugo source 2021-12-26 03:40:27 +01:00
Ral 7903a8e666 Another try 2021-12-26 03:32:01 +01:00
Ral 6fb5072c20 Fixed it? 2021-12-26 03:09:19 +01:00
Ral f0c73384d9 Update Info Beamer 2021-12-26 02:57:42 +01:00
Ral ce57046d0a Fix typo 2021-12-25 22:44:44 +01:00
Ral 240916aa95 Infobeamer alpha release 2021-12-25 22:19:20 +01:00
Ral 4a271344cb Update InfoBeamer, somewhat less WiP 2021-12-25 07:28:56 +01:00
L3D 4b40ede8a7 Merge branch 'everything.schedule.json' into 'master'
download everything.schedule.json too

See merge request rc3/html-infobeamer!2
2021-12-25 04:36:37 +00:00
L3D 41e11eae47
download everything.schedule.json too 2021-12-25 05:32:51 +01:00
Ral 9723dba441 Dedicated music info page 2021-12-25 02:53:10 +01:00
Jan Koppe 0af3302785 yolo 2021-12-25 00:09:23 +00:00
Jan Koppe dcc125e87a quicker music fetch interval 2021-12-25 00:06:32 +00:00
Ral 448eb90f93 Fix broken in OBS css animation 2021-12-25 00:47:24 +01:00
Ral b184467b54 Update Content, still WiP 2021-12-24 23:18:02 +01:00
raoul c5f51e94ca Adapt to new json format 2021-12-24 02:28:07 +01:00
Ral ea5f956e3d Infobeamer rC3 2021 - WiP 2021-12-24 02:16:26 +01:00
Jan Koppe b377d00af3 fix network in docker 2021-12-23 17:37:57 +00:00
Jan Koppe a196a935ea proxy music.json to static nginx server that has access to obs-mcr-disks 2021-12-23 17:36:52 +00:00
L3D 02fe2db1f1
Download mastodon tweets from chaos.social too 2021-12-22 23:13:37 +01:00
L3D 19b8e1ffe1 Merge branch 'cleanup' into 'master'
cleanup README

See merge request rc3/html-infobeamer!1
2021-12-22 00:13:55 +00:00
L3D da2e1571e5
cleanup README 2021-12-22 00:45:26 +01:00
Jan Koppe 5012c42885
test 2021-12-21 23:27:57 +01:00
Jan Koppe 6dbe4dc344
dockerklklklkl 2021-12-21 23:16:00 +01:00
Jan Koppe 20d1581862
add webfonts 2021-12-21 23:10:43 +01:00
Jan Koppe d50384bf30
lololol 2021-12-21 22:48:21 +01:00
Jan Koppe 84a9dfe3bb
tralafifi 2021-12-21 22:37:19 +01:00
74 changed files with 6871 additions and 451 deletions

View File

@ -1,13 +1,10 @@
## URL parameters
You can set the room for the section 'Next up here' by specifying either the (frab-XML) room name or room-guid.
E.g. https://hacc.4future.dev/html-infobeamer/?room=60dd7f55-9f88-4de6-ad98-b9c4e2810300 or https://hacc.4future.dev/html-infobeamer/?room=hacc%20M%C3%BCnchen%20/%20about:future%20-%20M%C3%BCnchen
HTML5 info-beamer
====================
This is a HTML5 website that replaces the info-beamer. Due to hybrid and purely online events it became necessary to have an online version of the info-beamer that is not dependent on physical devices on site. So HTML5 pages like this one were created. This is the version of info-beamer for CHAOS-WEST TV Stage during rC3 2021.
## API
This repo pulls the external data from `api.oct.re` (Server hosted by octycs)
You can host everything yourself in case you have a Twitter API key.
`api.oct.re/tweets-rc3.json` -> `dl_tweets.sh`
`api.oct.re/fahrplan.json` -> `fahrplan.py`
## Learn more
This version of the HTML Infobeamer website is built in Static Side Generator Hugo. The matching git repo with the can be found at this location:
https://gitlab.montage2.de/r3l/html-infobeamer-content.git
## License
All parts of this software except the `fahrplan.py` downloader are licensed under the _Unlicense_ (see `License.md`)

77
default.conf Normal file
View File

@ -0,0 +1,77 @@
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
location /music.json {
proxy_pass http://s1.wup1.mon2.de:8989;
}
location /content/live {
proxy_pass https://infobeamer-cms.c3voc.de;
}
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

11
dl_tweets.sh Normal file → Executable file
View File

@ -1,4 +1,11 @@
#!/bin/bash
export BEARER_TOKEN=<Enter your Bearer Token here>
export BEARER_TOKEN=$(cat token)
curl -s -X GET -H "Authorization: Bearer $BEARER_TOKEN" \
"https://api.twitter.com/2/tweets/search/recent?query=%23rC3&tweet.fields=created_at&expansions=author_id,attachments.media_keys&media.fields=preview_image_url&user.fields=profile_image_url" > tweets-rc3.json
"https://api.twitter.com/2/tweets/search/recent?query=%23rC3cwtv&tweet.fields=created_at&expansions=author_id,attachments.media_keys&media.fields=preview_image_url&user.fields=profile_image_url" > public/tweets-rc3.json
# download mastodon toots from chaos.social
curl -s "https://chaos.social/api/v1/timelines/tag/rc3cwtv?limit=42" > public/toots-rc3-chaos.social.json
# curl -s "https://social.bau-ha.us/api/v1/timelines/tag/rc3cwtv" > public/toots-rc3-social.bau-ha.us.json
# curl -s "https://social.tchncs.de/api/v1/timelines/tag/rc3cwtv" > public/toots-rc3-social.tchncs.de.json
curl -s "https://data.c3voc.de/rC3_21/everything.schedule.json" > public/everything.schedule.json

22
docker-compose.yaml Normal file
View File

@ -0,0 +1,22 @@
version: "3.4"
services:
nginx:
image: nginx
restart: unless-stopped
networks:
- ingress
volumes:
- ./public:/usr/share/nginx/html:ro
- ./default.conf:/etc/nginx/conf.d/default.conf:ro
labels:
- "traefik.enable=true"
- "traefik.http.services.infobeamer.loadbalancer.server.port=80"
- "traefik.http.routers.infobeamer.rule=Host(`infobeamer.montage2.de`)"
- "traefik.http.routers.infobeamer.entrypoints=web,websecure"
- "traefik.http.routers.infobeamer.tls.certresolver=default"
networks:
ingress:
name: traefik
external: true

View File

@ -10,7 +10,7 @@ import subprocess
from lxml import etree
from urllib.request import urlopen
scheduleUrl = 'http://data.c3voc.de/rC3/everything.schedule.xml'
scheduleUrl = 'http://data.c3voc.de/rC3_21/everything.schedule.xml'
scheduleTree=None
@ -146,7 +146,7 @@ if __name__ == "__main__":
return ev_date + grace > now and ev_date + datetime.timedelta(minutes=ev["duration"]) > now
events = filter(is_upcoming, events)
with open("fahrplan.json", "w") as f:
with open("public/fahrplan.json", "w") as f:
json.dump(list(events), f)

163
index.css
View File

@ -1,163 +0,0 @@
/*
* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
*
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* For more information, please refer to <http://unlicense.org/>
*/
* { box-sizing: border-box; }
body {
background: #000;
color: #FFF;
font-family: 'Orbitron';
text-shadow: 3px 3px #000;
}
/* === FAHRPLAN === */
#schedule {
position: fixed;
left: 5%;
right: 5%;
top: 10%;
bottom: 10%;
font-family: 'Orbitron';
font-size: 34px;
}
#schedule .header {
margin-bottom: 40px;
}
#schedule .list .item {
margin-bottom: 10px;
border-left: 5px solid #7b7b7b;
padding-left: 10px;
}
#schedule .list .item .title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#schedule .list .item .sub {
color: #cbcbcb;
font-size: 26px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#schedule-here-container, #schedule-main-container, #schedule-other-container {
background-color: rgba(10, 10, 10, 0.5);
padding: 20px;
}
#schedule-here-container {
position: absolute;
right: 52%;
left: 0;
}
#schedule-main-container {
position: absolute;
right: 52%;
left: 0;
top: 50%;
}
#schedule-other-container {
position: absolute;
left: 52%;
right: 0;
}
#schedule-here-container .header {
color: #b145fb;
}
#schedule-main-container .header {
color: #6820e4;
}
#schedule-other-container .header {
color: #45b5e3;
}
/* === TICKER === */
#bottom-bar {
position: fixed;
bottom: 0;
margin-bottom: 20px;
font-size: 14px;
width: 100%;
overflow: hidden;
}
#ticker-wrap {
width: 100%;
padding-left: 100%; /* Push contents to right side of screen */
}
@keyframes ticker {
0% { transform: translate3d(-20%, 0, 0); }
100% { transform: translate3d(-100%, 0, 0); }
}
#ticker {
/* Basically move items from right side of screen to left in infinite loop */
display: inline-block;
white-space: nowrap;
padding-right: 100%;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-name: ticker;
animation-duration: 120s;
}
#ticker > .item{
display: inline-block; /* Lay items in a horizontal line */
padding: 10px 36px;
font-size: 30px;
}
#ticker > .item > img {
height: 32px;
vertical-align: middle;
}
#ticker > .item > span.user {
color: #fff;
margin: 0 20px;
vertical-align: middle;
}
#ticker > .item > span.content {
color: #fff;
vertical-align: middle;
}

View File

@ -1,72 +0,0 @@
<!--
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="index.css">
<!--<script src="recent.js"></script>-->
<title>rC3 Stream Overlay</title>
</head>
<body>
<main>
<div id="schedule">
<div id="schedule-here-container">
<div class="header">
Next up here:
</div>
<div class="list" id="schedule-here">
</div>
</div>
<div id="schedule-main-container">
<div class="header">
Next up on Main:
</div>
<div class="list" id="schedule-main">
</div>
</div>
<div id="schedule-other-container">
<div class="header">
Next up on other channels:
</div>
<div class="list" id="schedule-other">
</div>
</div>
</div>
<div id="bottom-bar" class="visible">
<div id="ticker-wrap">
<div id="ticker">
</div>
</div>
</div>
</main>
<script src="index.js"></script>
</body>
</html>

203
index.js
View File

@ -1,203 +0,0 @@
/*
* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
*
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* For more information, please refer to <http://unlicense.org/>
*/
var channel_here = "407d1fb0-068d-4605-99e8-435fe599bd10";
var channel_main_1 = "rC1";
var channel_main_2 = "rC2";
// Not included in Frab XML
slug_map = {
bitwaescherei: "feb91cb1-eb66-43f1-a86f-f8d43909fbe0",
c3lounge: "ffa2f0d2-ca0b-41b6-a5cc-78ffc3fe15ff",
chaoszone: "084fed6f-8da2-4870-b8c2-7a2b1dce88bd",
csh: "ebc42052-10f7-4aef-bbe9-cfe9026880cc",
cwtv: "48f5bce3-5b46-44d8-9f36-90bed9bd4be0",
hacc: "60dd7f55-9f88-4de6-ad98-b9c4e2810300",
r3s: "c4a577e2-52e7-4f6f-a5c0-e3822d64f84a",
sendezentrum: "feb91cb1-eb66-43f1-a86f-f8d43909fbe0",
}
var fahrplan = {};
var tweets = {};
/* === EXTERNAL DATA === */
function update_tweets() {
var request = new XMLHttpRequest();
request.open('GET', 'tweets-rc3.json', true);
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
tweets = JSON.parse(this.response);
update_tweet_ticker();
} else { console.log(this); }
};
request.onerror = function(e) { console.log(e); };
request.send();
}
function update_fahrplan() {
var request = new XMLHttpRequest();
request.open('GET', 'fahrplan.json', true);
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
fahrplan = JSON.parse(this.response);
update_fahrplan_html();
} else { console.log(this); }
};
request.onerror = function(e) { console.log(e); };
request.send();
}
/* === FAHRPLAN === */
var n_here = 3;
var n_main = 3;
var n_other = 8;
function parse_schedule() {
var fahrplan_parsed = {
"here": [],
"main": [],
"other": [],
}
for (var i in fahrplan) {
if (fahrplan_parsed.here.length < n_here
&& (fahrplan[i].roomguid == channel_here || fahrplan[i].room == channel_here)) {
fahrplan_parsed.here.push({
title: fahrplan[i].title,
sub: fahrplan[i].start + " D" + fahrplan[i].day + ", " + fahrplan[i].personnames,
});
} else if (fahrplan_parsed.main.length < n_main
&& (fahrplan[i].roomguid == channel_main_1 || fahrplan[i].room == channel_main_1
|| fahrplan[i].roomguid == channel_main_2 || fahrplan[i].room == channel_main_2)) {
fahrplan_parsed.main.push({
title: fahrplan[i].title,
sub: fahrplan[i].start + " D" + fahrplan[i].day + " @ " + fahrplan[i].room + ", " + fahrplan[i].personnames,
});
} else if (fahrplan_parsed.other.length < n_other
&& fahrplan[i].roomguid != channel_here && fahrplan[i].room != channel_here
&& fahrplan[i].roomguid != channel_main_1 && fahrplan[i].room != channel_main_1
&& fahrplan[i].roomguid != channel_main_2 && fahrplan[i].room != channel_main_2) {
fahrplan_parsed.other.push({
title: fahrplan[i].title,
sub: fahrplan[i].start + " D" + fahrplan[i].day + " @ " + fahrplan[i].room,
});
}
}
return fahrplan_parsed;
}
function update_fahrplan_html() {
fahrplan_parsed = parse_schedule();
var els = {
here: document.getElementById("schedule-here"),
main: document.getElementById("schedule-main"),
other: document.getElementById("schedule-other"),
}
els.here.innerHTML = "";
els.main.innerHTML = "";
els.other.innerHTML = "";
for (var group in els) {
for (var i in fahrplan_parsed[group]) {
var el = document.createElement("div");
el.className = "item";
var title = document.createElement("div");
title.className = "title";
title.innerText = fahrplan_parsed[group][i].title;
el.appendChild(title);
var sub = document.createElement("div");
sub.className = "sub";
sub.innerText = fahrplan_parsed[group][i].sub;
el.appendChild(sub);
els[group].appendChild(el);
}
}
}
/* === TWEETS === */
function update_tweet_ticker() {
var ticker = document.getElementById("ticker");
ticker.innerHTML = "";
for (var i in tweets.data) {
//console.log(tweets.data[i].text);
var item = document.createElement("div");
item.className = "item";
// Look up user
var user;
for (var useri in tweets.includes.users) {
if (tweets.includes.users[useri].id == tweets.data[i].author_id)
user = tweets.includes.users[useri];
}
var img = document.createElement("img");
img.src = user.profile_image_url;
item.appendChild(img);
var user_el = document.createElement("span");
user_el.className = "user";
var uname = user.username;
user_el.innerText = "@" + uname + ":";
item.appendChild(user_el);
var content = document.createElement("span");
content.className = "content";
var text = tweets.data[i].text;
text = text.replace(/\n/g, "↲");
content.innerText = text;
item.appendChild(content);
ticker.appendChild(item);
}
}
(function() {
var query = location.search.substr(1);
var result = {};
query.split("&").forEach(function(part) {
var item = part.split("=");
result[item[0]] = decodeURIComponent(item[1]);
});
if (result.room !== undefined)
channel_here = result.room;
if (slug_map[channel_here] !== undefined)
channel_here = slug_map[channel_here];
update_fahrplan();
update_tweets();
setInterval(update_fahrplan,60000);
setInterval(update_tweets, 60000);
})();

0
public/.gitkeep Normal file
View File

File diff suppressed because one or more lines are too long

19
public/cms/index.html Normal file
View File

@ -0,0 +1,19 @@
<!doctype html><html lang=en>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no">
<meta http-equiv=refresh content="180;url=/schedule/">
<title>rC3 NOWHERE</title>
<link href=/fork-awesome/css/fork-awesome.min.css rel=stylesheet type=text/css>
<link rel=stylesheet href=https://infobeamer.montage2.de/cms.min.82b6edb09ee1e67820c146ec17a3715d828149d79b6d6c7da84279be1934d777.css>
<script src=https://infobeamer.montage2.de/js/config.2fd38d4779fef41f713ebc0f66f431aa1d363b933809e3877abb8f4354f2bae1.js integrity="sha256-L9ONR3n+9B9xPrwPZvQxqh02O5M4CeOHeruPQ1TyuuE="></script>
</head>
<body>
<main id=main>
</main>
<script src=https://infobeamer.montage2.de/js/moment/moment.min.73de4254959530e4d1d9bec586379184f96b4953dacf9cd5e5e2bdd7bfeceef7.js integrity="sha256-c95CVJWVMOTR2b7FhjeRhPlrSVPaz5zV5eK917/s7vc="></script>
<script src=https://infobeamer.montage2.de/js/preact/preact.min.0c204e20934f1e09cfe86fbcf1d069d842f988fc71efe3a923021c08892c71c8.js integrity="sha256-DCBOIJNPHgnP6G+88dBp2EL5iPxx7+OpIwIcCIksccg="></script>
<script src=https://infobeamer.montage2.de/js/htm/htm.80e39afe20fd61183412eda89efa10532d57945e6364642aceacd50eb2384b4b.js integrity="sha256-gOOa/iD9YRg0Eu2onvoQUy1XlF5jZGQqzqzVDrI4S0s="></script>
<script src=https://infobeamer.montage2.de/main.92ebdf5660681a66f540837f65fda601f0c32c541bb3b060756cc5e4674a9558.js integrity="sha256-kuvfVmBoGmb1QIN/Zf2mAfDDLFQbs7BgdWzF5GdKlVg=" type=module></script>
</body>
</html>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,446 @@
/*!
Fork Awesome 1.1.7
License - https://forkaweso.me/Fork-Awesome/license
Copyright 2018 Dave Gandy & Fork Awesome
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
.fas,
.fab,
.far {
display: inline-block;
font: normal normal normal 14px/1 ForkAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.fas.fa-chart-area:before {
content: "\f1fe";
}
.fas.fa-arrows-alt:before {
content: "\f047";
}
.fas.fa-expand-arrows-alt:before {
content: "\f0b2";
}
.fas.fa-arrows-alt-h:before {
content: "\f07e";
}
.fas.fa-arrows-alt-v:before {
content: "\f07d";
}
.fas.fa-calendar-alt:before {
content: "\f073";
}
.fas.fa-circle-notch:before {
content: "\f1ce";
}
.fas.fa-cloud-download-alt:before {
content: "\f0ed";
}
.fas.fa-cloud-upload-alt:before {
content: "\f0ee";
}
.fas.fa-credit-card:before {
content: "\f283";
}
.fas.fa-dollar-sign:before {
content: "\f155";
}
.fas.fa-euro-sign:before {
content: "\f153";
}
.fas.fa-exchange-alt:before {
content: "\f0ec";
}
.fas.fa-external-link-alt:before {
content: "\f08e";
}
.fas.fa-external-link-square-alt:before {
content: "\f14c";
}
.fas.fa-eye-dropper:before {
content: "\f1fb";
}
.fas.fa-pound-sign:before {
content: "\f154";
}
.fas.fa-glass-martini:before {
content: "\f000";
}
.fas.fa-shekel-sign:before {
content: "\f20b";
}
.fas.fa-rupee-sign:before {
content: "\f156";
}
.fas.fa-won-sign:before {
content: "\f159";
}
.fas.fa-level-down-alt:before {
content: "\f149";
}
.fas.fa-level-up-alt:before {
content: "\f148";
}
.fas.fa-chart-line:before {
content: "\f201";
}
.fas.fa-long-arrow-alt-down:before {
content: "\f175";
}
.fas.fa-long-arrow-alt-left:before {
content: "\f177";
}
.fas.fa-long-arrow-alt-right:before {
content: "\f178";
}
.fas.fa-long-arrow-alt-up:before {
content: "\f176";
}
.fas.fa-map-marker-alt:before {
content: "\f041";
}
.fas.fa-mobile-alt:before {
content: "\f10b";
}
.fas.fa-pencil-alt:before {
content: "\f040";
}
.fas.fa-pen-square:before {
content: "\f14b";
}
.fas.fa-chart-pie:before {
content: "\f200";
}
.fas.fa-yen-sign:before {
content: "\f157";
}
.fas.fa-ruble-sign:before {
content: "\f158";
}
.fas.fa-shield-alt:before {
content: "\f132";
}
.fas.fa-sign-in-alt:before {
content: "\f090";
}
.fas.fa-sign-out-alt:before {
content: "\f08b";
}
.fas.fa-sliders-h:before {
content: "\f1de";
}
.fas.fa-tablet-alt:before {
content: "\f10a";
}
.fas.fa-tachometer-alt:before {
content: "\f0e4";
}
.fas.fa-thumbtack:before {
content: "\f08d";
}
.fas.fa-ticket-alt:before {
content: "\f145";
}
.fas.fa-trash-alt:before {
content: "\f1f8";
}
.fas.fa-lira-sign:before {
content: "\f195";
}
.fab.fa-linkedin-in:before {
content: "\fe01";
}
.fab.fa-linkedin:before {
content: "\f08c";
}
.far.fa-address-book:before {
content: "\f2ba";
}
.far.fa-address-card:before {
content: "\f2bc";
}
.far.fa-arrow-alt-circle-down:before {
content: "\f01a";
}
.far.fa-arrow-alt-circle-left:before {
content: "\f190";
}
.far.fa-arrow-alt-circle-right:before {
content: "\f18e";
}
.far.fa-arrow-alt-circle-up:before {
content: "\f01b";
}
.far.fa-bell:before {
content: "\f0f3";
}
.far.fa-bell-slash:before {
content: "\f1f7";
}
.far.fa-bookmark:before {
content: "\f097";
}
.far.fa-building:before {
content: "\f0f7";
}
.far.fa-calendar-check:before {
content: "\f274";
}
.far.fa-calendar-minus:before {
content: "\f272";
}
.far.fa-calendar:before {
content: "\f133";
}
.far.fa-calendar-plus:before {
content: "\f271";
}
.far.fa-calendar-times:before {
content: "\f273";
}
.far.fa-caret-square-down:before {
content: "\f150";
}
.far.fa-caret-square-left:before {
content: "\f191";
}
.far.fa-caret-square-right:before {
content: "\f152";
}
.far.fa-caret-square-up:before {
content: "\f151";
}
.far.fa-check-circle:before {
content: "\f05d";
}
.far.fa-check-square:before {
content: "\f046";
}
.far.fa-circle:before {
content: "\f10c";
}
.far.fa-clock:before {
content: "\f017";
}
.far.fa-comment:before {
content: "\f0e5";
}
.far.fa-comment-dots:before {
content: "\f27b";
}
.far.fa-comments:before {
content: "\f0e6";
}
.far.fa-dot-circle:before {
content: "\f192";
}
.far.fa-id-card:before {
content: "\f2c3";
}
.far.fa-envelope:before {
content: "\f003";
}
.far.fa-envelope-open:before {
content: "\f2b7";
}
.far.fa-file-archive:before {
content: "\f1c6";
}
.far.fa-file-audio:before {
content: "\f1c7";
}
.far.fa-file-code:before {
content: "\f1c9";
}
.far.fa-file-excel:before {
content: "\f1c3";
}
.far.fa-file-image:before {
content: "\f1c5";
}
.far.fa-file-video:before {
content: "\f1c8";
}
.far.fa-copy:before,
.far.fa-file:before {
content: "\f016";
}
.far.fa-file-pdf:before {
content: "\f1c1";
}
.far.fa-file-powerpoint:before {
content: "\f1c4";
}
.far.fa-file-alt:before {
content: "\f0f6";
}
.far.fa-file-word:before {
content: "\f1c2";
}
.far.fa-flag:before {
content: "\f11d";
}
.far.fa-save:before {
content: "\f0c7";
}
.far.fa-folder:before {
content: "\f114";
}
.far.fa-folder-open:before {
content: "\f115";
}
.far.fa-frown:before {
content: "\f119";
}
.far.fa-futbol:before {
content: "\f1e3";
}
.far.fa-hand-rock:before {
content: "\f255";
}
.far.fa-hand-lizard:before {
content: "\f258";
}
.far.fa-hand-point-down:before {
content: "\f0a7";
}
.far.fa-hand-point-left:before {
content: "\f0a5";
}
.far.fa-hand-point-right:before {
content: "\f0a4";
}
.far.fa-hand-point-up:before {
content: "\f0a6";
}
.far.fa-hand-paper:before {
content: "\256";
}
.far.fa-hand-pointer:before {
content: "\f25a";
}
.far.fa-hand-scissors:before {
content: "\f257";
}
.far.fa-hand-spock:before {
content: "\f259";
}
.far.fa-handshake:before {
content: "\f2b5";
}
.far.fa-hdd:before {
content: "\f0a0";
}
.far.fa-heart:before {
content: "\f08a";
}
.far.fa-hospital:before {
content: "\f0f8";
}
.far.fa-hourglass:before {
content: "\f250";
}
.far.fa-id-card:before {
content: "\f2c3";
}
.far.fa-keyboard:before {
content: "\f11c";
}
.far.fa-lemon:before {
content: "\f094";
}
.far.fa-lightbulb:before {
content: "\f0eb";
}
.far.fa-meh:before {
content: "\f11a";
}
.far.fa-minus-square:before {
content: "\f147";
}
.far.fa-money-bill-alt:before {
content: "\f0d6";
}
.far.fa-moon:before {
content: "\f186";
}
.far.fa-newspaper:before {
content: "\f1ea";
}
.far.fa-paper-plane:before {
content: "\f1d9";
}
.far.fa-pause-circle:before {
content: "\f28c";
}
.far.fa-edit:before {
content: "\f044";
}
.far.fa-image:before {
content: "\f03e";
}
.far.fa-play-circle:before {
content: "\f01d";
}
.far.fa-plus-square:before {
content: "\f196";
}
.far.fa-question-circle:before {
content: "\f92c";
}
.far.fa-share-square:before {
content: "\f045";
}
.far.fa-smile:before {
content: "\f118";
}
.far.fa-snowflake:before {
content: "\f2dc";
}
.far.fa-futbol:before {
content: "\f1e3";
}
.far.fa-star-half:before {
content: "\f089";
}
.far.fa-star:before {
content: "\f006";
}
.far.fa-sticky-note:before {
content: "\f24a";
}
.far.fa-stop-circle:before {
content: "\f28e";
}
.far.fa-sun:before {
content: "\f185";
}
.far.fa-thumbs-down:before {
content: "\f088";
}
.far.fa-thumbs-up:before {
content: "\f087";
}
.far.fa-times-circle:before {
content: "\f05c";
}
.far.fa-window-close:before {
content: "\f2d4";
}
.far.fa-trash-alt:before {
content: "\f014";
}
.far.fa-user-circle:before {
content: "\f2be";
}
.far.fa-user:before {
content: "\f2c0";
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":3,"sources":["v5-compat.css"],"names":[],"mappings":";;;;;;;;;;;AAaA,KACA,KAFA,KAGE,QAAA,aACA,KAAA,OAAA,OAAA,OAAA,KAAA,EAAA,YACA,UAAA,QACA,eAAA,KACA,uBAAA,YACA,wBAAA,UAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEuB,iCACvB,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAEwB,kCACxB,QAAA,QAEsB,gCACtB,QAAA,QAEiB,2BACjB,QAAA,QAEiB,2BACjB,QAAA,QAEe,yBACf,QAAA,QAEkB,4BAClB,QAAA,QAEuB,iCACvB,QAAA,QAE8B,wCAC9B,QAAA,QAEiB,2BACjB,QAAA,QAEgB,0BAChB,QAAA,QAEmB,6BACnB,QAAA,QAEiB,2BACjB,QAAA,QAEgB,0BAChB,QAAA,QAEc,wBACd,QAAA,QAEoB,8BACpB,QAAA,QAEkB,4BAClB,QAAA,QAEgB,0BAChB,QAAA,QAEyB,mCACzB,QAAA,QAEyB,mCACzB,QAAA,QAE0B,oCAC1B,QAAA,QAEuB,iCACvB,QAAA,QAEoB,8BACpB,QAAA,QAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEe,yBACf,QAAA,QAEc,wBACd,QAAA,QAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEiB,2BACjB,QAAA,QAEkB,4BAClB,QAAA,QAEe,yBACf,QAAA,QAEgB,0BAChB,QAAA,QAEoB,8BACpB,QAAA,QAEe,yBACf,QAAA,QAEgB,0BAChB,QAAA,QAEe,yBACf,QAAA,QAEe,yBACf,QAAA,QAEiB,2BACjB,QAAA,QAEc,wBACd,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAE2B,qCAC3B,QAAA,QAE2B,qCAC3B,QAAA,QAE4B,sCAC5B,QAAA,QAEyB,mCACzB,QAAA,QAEU,oBACV,QAAA,QAEgB,0BAChB,QAAA,QAEc,wBACd,QAAA,QAEc,wBACd,QAAA,QAEoB,8BACpB,QAAA,QAEoB,8BACpB,QAAA,QAEc,wBACd,QAAA,QAEmB,6BACnB,QAAA,QAEoB,8BACpB,QAAA,QAEuB,iCACvB,QAAA,QAEuB,iCACvB,QAAA,QAEwB,kCACxB,QAAA,QAEqB,+BACrB,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAEY,sBACZ,QAAA,QAEW,qBACX,QAAA,QAEa,uBACb,QAAA,QAEkB,4BAClB,QAAA,QAEc,wBACd,QAAA,QAEgB,0BAChB,QAAA,QAEa,uBACb,QAAA,QAEc,wBACd,QAAA,QAEmB,6BACnB,QAAA,QAEkB,4BAClB,QAAA,QAEgB,0BAChB,QAAA,QAEe,yBACf,QAAA,QAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEgB,0BAChB,QAAA,QAEU,oBACA,oBACV,QAAA,QAEc,wBACd,QAAA,QAEqB,+BACrB,QAAA,QAEc,wBACd,QAAA,QAEe,yBACf,QAAA,QAEU,oBACV,QAAA,QAEU,oBACV,QAAA,QAEY,sBACZ,QAAA,QAEiB,2BACjB,QAAA,QAEW,qBACX,QAAA,QAEY,sBACZ,QAAA,QAEe,yBACf,QAAA,QAEiB,2BACjB,QAAA,QAEqB,+BACrB,QAAA,QAEqB,+BACrB,QAAA,QAEsB,gCACtB,QAAA,QAEmB,6BACnB,QAAA,QAEgB,0BAChB,QAAA,OAEkB,4BAClB,QAAA,QAEmB,6BACnB,QAAA,QAEgB,0BAChB,QAAA,QAEe,yBACf,QAAA,QAES,mBACT,QAAA,QAEW,qBACX,QAAA,QAEc,wBACd,QAAA,QAEe,yBACf,QAAA,QAEa,uBACb,QAAA,QAEc,wBACd,QAAA,QAEW,qBACX,QAAA,QAEe,yBACf,QAAA,QAES,mBACT,QAAA,QAEkB,4BAClB,QAAA,QAEoB,8BACpB,QAAA,QAEU,oBACV,QAAA,QAEe,yBACf,QAAA,QAEiB,2BACjB,QAAA,QAEkB,4BAClB,QAAA,QAEU,oBACV,QAAA,QAEW,qBACX,QAAA,QAEiB,2BACjB,QAAA,QAEiB,2BACjB,QAAA,QAEqB,+BACrB,QAAA,QAEkB,4BAClB,QAAA,QAEW,qBACX,QAAA,QAEe,yBACf,QAAA,QAEY,sBACZ,QAAA,QAEe,yBACf,QAAA,QAEU,oBACV,QAAA,QAEiB,2BACjB,QAAA,QAEiB,2BACjB,QAAA,QAES,mBACT,QAAA,QAEiB,2BACjB,QAAA,QAEe,yBACf,QAAA,QAEkB,4BAClB,QAAA,QAEkB,4BAClB,QAAA,QAEe,yBACf,QAAA,QAEiB,2BACjB,QAAA,QAEU,oBACV,QAAA"}

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 470 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

18
public/hashtag/index.html Normal file
View File

@ -0,0 +1,18 @@
<!doctype html><html lang=en>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no">
<title>rC3 NOWHERE</title>
<link href=/fork-awesome/css/fork-awesome.min.css rel=stylesheet type=text/css>
<link rel=stylesheet href=https://infobeamer.montage2.de/hashtag.min.210a4b181230691ab2e54ee91c2473ca230b4b00cb44aee9c33158cb0ccaf8e5.css>
<script src=https://infobeamer.montage2.de/js/config.2fd38d4779fef41f713ebc0f66f431aa1d363b933809e3877abb8f4354f2bae1.js integrity="sha256-L9ONR3n+9B9xPrwPZvQxqh02O5M4CeOHeruPQ1TyuuE="></script>
</head>
<body>
<main id=main>
</main>
<script src=https://infobeamer.montage2.de/js/moment/moment.min.73de4254959530e4d1d9bec586379184f96b4953dacf9cd5e5e2bdd7bfeceef7.js integrity="sha256-c95CVJWVMOTR2b7FhjeRhPlrSVPaz5zV5eK917/s7vc="></script>
<script src=https://infobeamer.montage2.de/js/preact/preact.min.0c204e20934f1e09cfe86fbcf1d069d842f988fc71efe3a923021c08892c71c8.js integrity="sha256-DCBOIJNPHgnP6G+88dBp2EL5iPxx7+OpIwIcCIksccg="></script>
<script src=https://infobeamer.montage2.de/js/htm/htm.80e39afe20fd61183412eda89efa10532d57945e6364642aceacd50eb2384b4b.js integrity="sha256-gOOa/iD9YRg0Eu2onvoQUy1XlF5jZGQqzqzVDrI4S0s="></script>
<script src=https://infobeamer.montage2.de/main.92ebdf5660681a66f540837f65fda601f0c32c541bb3b060756cc5e4674a9558.js integrity="sha256-kuvfVmBoGmb1QIN/Zf2mAfDDLFQbs7BgdWzF5GdKlVg=" type=module></script>
</body>
</html>

18
public/index.html Normal file
View File

@ -0,0 +1,18 @@
<!doctype html><html lang=en>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no">
<title>rC3 NOWHERE</title>
<link href=/fork-awesome/css/fork-awesome.min.css rel=stylesheet type=text/css>
<link rel=stylesheet href=https://infobeamer.montage2.de/main.min.2bff15f19297e3f97fbde58195288bc7035285c53ef8f0c673ce787a4bd4cf6b.css>
<script src=https://infobeamer.montage2.de/js/config.2fd38d4779fef41f713ebc0f66f431aa1d363b933809e3877abb8f4354f2bae1.js integrity="sha256-L9ONR3n+9B9xPrwPZvQxqh02O5M4CeOHeruPQ1TyuuE="></script>
</head>
<body>
<main id=main>
</main>
<script src=https://infobeamer.montage2.de/js/moment/moment.min.73de4254959530e4d1d9bec586379184f96b4953dacf9cd5e5e2bdd7bfeceef7.js integrity="sha256-c95CVJWVMOTR2b7FhjeRhPlrSVPaz5zV5eK917/s7vc="></script>
<script src=https://infobeamer.montage2.de/js/preact/preact.min.0c204e20934f1e09cfe86fbcf1d069d842f988fc71efe3a923021c08892c71c8.js integrity="sha256-DCBOIJNPHgnP6G+88dBp2EL5iPxx7+OpIwIcCIksccg="></script>
<script src=https://infobeamer.montage2.de/js/htm/htm.80e39afe20fd61183412eda89efa10532d57945e6364642aceacd50eb2384b4b.js integrity="sha256-gOOa/iD9YRg0Eu2onvoQUy1XlF5jZGQqzqzVDrI4S0s="></script>
<script src=https://infobeamer.montage2.de/main.92ebdf5660681a66f540837f65fda601f0c32c541bb3b060756cc5e4674a9558.js integrity="sha256-kuvfVmBoGmb1QIN/Zf2mAfDDLFQbs7BgdWzF5GdKlVg=" type=module></script>
</body>
</html>

View File

@ -0,0 +1,30 @@
(() => {
// ns-params:@params
var cmsFetchInterval = 500;
var cmsURL = "/content/live";
var mastodonFetchInterval = 120;
var mastodonURL = "/toots-rc3-chaos.social.json";
var musicFetchInterval = 1;
var musicURL = "/music.json";
var scheduleFetchInterval = 60;
var scheduleURL = "/everything.schedule.json";
var twitterFetchInterval = 120;
var twitterURL = "/tweets-rc3.json";
var workerBaseURL = "/";
// <stdin>
window.infoBeamerConfig = /* @__PURE__ */ new Map();
window.infoBeamerConfig.set("workerBaseURL", workerBaseURL);
window.infoBeamerConfig.set("scheduleURL", scheduleURL);
window.infoBeamerConfig.set("scheduleFetchInterval", scheduleFetchInterval);
window.infoBeamerConfig.set("twitterURL", twitterURL);
window.infoBeamerConfig.set("twitterFetchInterval", twitterFetchInterval);
window.infoBeamerConfig.set("mastodonURL", mastodonURL);
window.infoBeamerConfig.set("mastodonFetchInterval", mastodonFetchInterval);
window.infoBeamerConfig.set("musicURL", musicURL);
window.infoBeamerConfig.set("musicFetchInterval", musicFetchInterval);
window.infoBeamerConfig.set("cmsURL", cmsURL);
window.infoBeamerConfig.set("cmsFetchInterval", cmsFetchInterval);
console.log("Info Beamer Configuration: ");
console.log(window.infoBeamerConfig);
})();

View File

@ -0,0 +1,36 @@
let fetchType;
let fetchInterval;
let fetchURL;
onmessage = function(e) {
let msgType = e.data.msgType;
// console.log("Configuration Message:");
console.log(e.data);
fetchType = e.data.fetchType;
fetchURL = e.data.fetchURL;
fetchInterval = 1000 * e.data.fetchInterval;
};
function doFetch() {
let now = new Date();
if (fetchURL) {
fetch(fetchURL).then(
b => b.json()).then(
j => postMessage({msgType: fetchType,
json: j,
timestamp: now}))
.catch(e => console.log(e.message));
}
}
// Periodic resource fetching
(function periodicFetch() {
doFetch();
setTimeout(periodicFetch, fetchInterval);
})();

View File

@ -0,0 +1 @@
!function(){var n=function(t,e,s,u){var r;e[0]=0;for(var h=1;h<e.length;h++){var p=e[h++],a=e[h]?(e[0]|=p?1:2,s[e[h++]]):e[++h];3===p?u[0]=a:4===p?u[1]=Object.assign(u[1]||{},a):5===p?(u[1]=u[1]||{})[e[++h]]=a:6===p?u[1][e[++h]]+=a+"":p?(r=t.apply(a,n(t,a,s,["",null])),u.push(r),a[0]?e[0]|=2:(e[h-2]=0,e[h]=r)):u.push(a)}return u},t=new Map,e=function(e){var s=t.get(this);return s||(s=new Map,t.set(this,s)),(s=n(this,s.get(e)||(s.set(e,s=function(n){for(var t,e,s=1,u="",r="",h=[0],p=function(n){1===s&&(n||(u=u.replace(/^\s*\n\s*|\s*\n\s*$/g,"")))?h.push(0,n,u):3===s&&(n||u)?(h.push(3,n,u),s=2):2===s&&"..."===u&&n?h.push(4,n,0):2===s&&u&&!n?h.push(5,0,!0,u):s>=5&&((u||!n&&5===s)&&(h.push(s,0,u,e),s=6),n&&(h.push(s,n,0,e),s=6)),u=""},a=0;a<n.length;a++){a&&(1===s&&p(),p(a));for(var o=0;o<n[a].length;o++)t=n[a][o],1===s?"<"===t?(p(),h=[h],s=3):u+=t:4===s?"--"===u&&">"===t?(s=1,u=""):u=t+u[0]:r?t===r?r="":u+=t:'"'===t||"'"===t?r=t:">"===t?(p(),s=1):s&&("="===t?(s=5,e=u,u=""):"/"===t&&(s<5||">"===n[a][o+1])?(p(),3===s&&(h=h[0]),s=h,(h=h[0]).push(2,0,s),s=0):" "===t||"\t"===t||"\n"===t||"\r"===t?(p(),s=2):u+=t),3===s&&"!--"===u&&(s=4,h=h[0])}return p(),h}(e)),s),arguments,[])).length>1?s:s[0]};"undefined"!=typeof module?module.exports=e:self.htm=e}();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,675 @@
"use strict";
(() => {
// ns-hugo:/home/raoul-web/rc3_2021/html-infobeamer-content/assets/js/services.js
var delay = 3 * 5 * 60 * 1e3;
var hereRoom = "Chaos-West TV";
var postsLimit = 20;
var postMaxAge = 32 * 24 * 60 * 60 * 1e3;
var defaultUrlSet = [
"https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png",
"https://chaos.social/avatars/original/missing.png"
];
var socialFilters = [
RegExp("http.://bit.ly/.*\\w+")
];
var socialReplacement = "\u2588\u2588\u2588\u2588\u2588";
var default_profile_image_url = () => "./nounicorn.png";
var social_limiter = (tweets, toots) => {
let posts = tweets.concat(toots);
console.log("Number tweets (unfiltered): " + tweets.length);
console.log("Number toots (unfiltered): " + toots.length);
let maxAge = (p) => Date.parse(p.time) >= Date.now() - postMaxAge;
let recentPosts = posts.filter(maxAge);
let byDate = (fst, snd) => Date.parse(fst.time) - Date.parse(snd.time);
let postsSorted = recentPosts.sort(byDate);
console.log("Number distinct social posts in loop: " + postsSorted.length);
if (postsSorted.length > 0) {
while (postsSorted.length < postsLimit) {
postsSorted = postsSorted.concat(postsSorted);
}
}
let postsLimited = postsSorted.reverse().slice(0, postsLimit);
return postsLimited;
};
var replace_default_image_url = (url) => defaultUrlSet.includes(url) === true ? default_profile_image_url() : url;
var censorship = (text) => {
socialFilters.forEach((f) => {
text = text.replace(f, socialReplacement);
});
return text;
};
var html_plainify = (html2) => {
let span = document.createElement("span");
span.innerHTML = html2;
let children = span.querySelectorAll("*");
children.forEach((child) => {
child.textContent += " ";
});
return span.textContent.toString().replace(/ +/g, " ");
};
var tweet_author = (data, tweet) => {
let authorId = tweet.author_id;
let users = data.includes.users;
let author = users.find((item) => item.id === authorId);
let userName = author !== void 0 ? author.username : "NoOne";
return userName;
};
var tweet_profile_image = (data, tweet) => {
let authorId = tweet.author_id;
let users = data.includes.users;
let author = users.find((item) => item.id === authorId);
let profileImageUrl = replace_default_image_url(author.profile_image_url);
return profileImageUrl;
};
var tweet_text = (tweet) => tweet.text;
var tweet_time = (tweet) => tweet.created_at;
var twitter_filter = (inputData) => {
let tweets;
inputData.forEach((d) => tweets = d.data.map((t) => {
return {
author: tweet_author(d, t),
image: tweet_profile_image(d, t),
text: censorship(html_plainify(tweet_text(t))),
time: tweet_time(t),
source: "twitter"
};
}));
return tweets;
};
var toot_author = (toot) => toot.account.username;
var toot_profile_image = (toot) => replace_default_image_url(toot.account.avatar_static);
var toot_text = (toot) => toot.content;
var toot_time = (toot) => toot.created_at;
var mastodon_filter = (idata) => {
let toots;
idata.forEach((d) => {
toots = d.map((t) => {
return {
author: toot_author(t),
image: toot_profile_image(t),
text: censorship(html_plainify(toot_text(t))),
time: toot_time(t),
source: "mastodon"
};
});
});
return toots;
};
var schedule_filter = (data) => {
let dataDays = data.schedule.conference.days;
let talksData = dataDays.map((d) => {
let rooms = Object.values(d.rooms);
rooms.flat().forEach((t) => {
t.day = d.index;
});
return rooms;
}).flat(2);
let byDate = (fst, snd) => Date.parse(fst.date) - Date.parse(snd.date);
let talksDataSorted = talksData.sort(byDate);
return talksDataSorted;
};
var is_own_event = (event) => event.room === hereRoom;
var future_events = (schedule, now) => schedule.filter((e) => Date.parse(e.date) >= now - delay);
var running_event = (schedule, now) => {
const preDelay = 5 * 60 * 1e3;
const postDelay = 3 * 5 * 60 * 1e3;
let talk_duration = (durationString) => {
const timeFormat = "hh:mm";
let dt = moment(durationString, timeFormat);
let minutes = 60 * dt.hours() + dt.minutes();
return minutes * 60 * 1e3;
};
let is_running = (e) => {
let start = Date.parse(e.date);
let end = start + talk_duration(e.duration);
return start - preDelay <= now && now <= end + postDelay === true;
};
return schedule.filter(is_own_event).filter(is_running).slice(0, 1);
};
var same_music_track = (track1, track2) => track1.artist === track2.artist && track1.title === track2.title;
var is_new_music = (musicA, musicB) => {
let isNewMusic;
if (musicA.length !== 0 && musicB.length !== 0) {
isNewMusic = same_music_track(musicA[0], musicB[0]);
} else if (musicA.length === 0 && musicB.length === 0) {
isNewMusic = true;
} else {
isNewMusic = false;
}
return !isNewMusic;
};
var music_update = (musicA, musicB) => {
if (is_new_music(musicA, musicB) === true) {
musicB.forEach((mb) => mb.since = Date.now());
} else {
musicA.forEach((ma) => {
musicB.forEach((mb) => mb.since = ma.since);
});
}
return musicB;
};
var cms_filter = (data) => {
return data.assets.filter((a) => a.filetype === "image");
};
// ns-hugo:/home/raoul-web/rc3_2021/html-infobeamer-content/assets/js/dom.js
var html = htm.bind(preact.h);
var hereRoom2 = "Chaos-West TV";
var number_events_all = 8;
var musicAge = 5 * 1e3;
var urgent = 5 * 60 * 1e3;
var stale = 3 * 5 * 60 * 1e3;
var lapse = 5 * 1e3;
var maxImageAge = 15 * 1e3;
var freshImage = 4 * 1e3;
var staleImage = 4 * 1e3;
var cmsBaseUrl = "https://infobeamer-cms.c3voc.de/";
var talk_day = (talk) => {
const lut = {
1: "I",
2: "II",
3: "III",
4: "IV"
};
return lut[talk.day];
};
var is_own_talk = (talk) => talk.room === hereRoom2;
var talk_start_time = (talk) => Date.parse(talk.date);
var is_urgent = (talk, time) => {
let timeDelta = talk_start_time(talk) - time;
return timeDelta >= 0 && timeDelta <= urgent;
};
var is_stale = (talk, time) => {
let timeDelta = talk_start_time(talk) - time;
return timeDelta < 0;
};
var is_lapse = (talk, time) => {
let timeDelta = talk_start_time(talk) - time;
return timeDelta <= -(stale - lapse);
};
var urgent_class = (talk, time) => is_urgent(talk, time) ? "urgent" : "";
var stale_class = (talk, time) => is_stale(talk, time) ? "stale" : "";
var lapse_class = (talk, time) => is_lapse(talk, time) ? "lapse" : "";
var speaker_names = (talk) => talk.persons.map((p) => p.public_name);
var speaker_dom = (talk) => {
const separator = ", ";
let names = speaker_names(talk);
let inner;
if (names.length > 0) {
let string = names.join(separator);
inner = html`<div class="speaker">${string}:</div>`;
} else {
inner = html``;
}
return inner;
};
var starting_dom = (talk, time) => {
const hrs3 = 3 * 60 * 60 * 1e3;
const min15 = 3 * 5 * 60 * 1e3;
const min2 = 2 * 60 * 1e3;
const min1 = 60 * 1e3;
let timeDelta = talk_start_time(talk) - time;
let minutes = Math.ceil(Math.abs(timeDelta / 1e3 / 60));
let inner;
if (timeDelta > hrs3) {
inner = html`<span class="start">Day ${talk_day(talk)} at ${talk.start}</span>`;
} else if (timeDelta > min15) {
inner = html`<span class="start">Starting at ${talk.start}</span>`;
} else if (timeDelta <= min15 && timeDelta > min1) {
inner = html`<span class="start">Starting in ${minutes} minutes</span>`;
} else if (timeDelta <= min1 && timeDelta >= 0) {
inner = html`<span class="start">Starting now!</span>`;
} else if (timeDelta < 0 && timeDelta >= -min1) {
inner = html`<span class="start">Just started!</span>`;
} else if (timeDelta < -min1 && timeDelta >= -min15) {
inner = html`<span class="start">Started ${minutes} minutes ago</span>`;
} else if (timeDelta < -min15) {
inner = html`<span class="start">Seriously missed</span>`;
}
return inner;
};
var to_minutes = (duration) => {
const timeFormat = "hh:mm";
let dt = moment(duration, timeFormat);
let minutes = 60 * dt.hours() + dt.minutes();
return minutes;
};
var duration_dom = (talk) => {
return html`<span class="duration">${to_minutes(talk.duration)} minutes</span>`;
};
var meta_here_dom = (schedule, time) => {
let inner = html`${schedule.map((talk) => html`
<div class="talk-here-meta-box ${urgent_class(talk, time)} ${stale_class(talk, time)}">
<div class="speaker">${speaker_dom(talk)}</div>
<div class="title"><span class="titletext">${talk.title}</span></div>
<div class="start-duration">
${starting_dom(talk, time)}
${duration_dom(talk)}
</div>
</div>
`)}`;
return inner;
};
var abstract_text_dom = (talk) => {
const placeHolder = "\xAF_(\u30C4)_/\xAF";
let inner;
if (talk.abstract !== null) {
let lang = talk.language !== void 0 ? talk.language : "en";
inner = html`<div class="text" lang="${lang}">${talk.abstract}</div>`;
} else {
inner = html``;
}
return inner;
};
var track_dom = (talk) => {
let inner;
if (talk.track !== null) {
inner = html`<div class="track">Track: ${talk.track}</div>`;
} else {
inner = html``;
}
return inner;
};
var abstract_here_dom = (schedule) => {
let inner = html``;
schedule.forEach((talk) => {
inner = html`
${abstract_text_dom(talk)}
${track_dom(talk)}`;
});
return inner;
};
var talk_day_dom = (talk) => html`<span class="day">Day ${talk_day(talk)}</span>`;
var highlight_class = (talk) => is_own_talk(talk) === true ? "highlight" : "";
var do_not_record_dom = (talk) => {
let icon = "fa-microphone-slash";
let inner;
if (talk.do_not_record === true) {
inner = html`<span class="do-not-record"><span class="fa ${icon}"></span></span>`;
} else {
inner = html``;
}
return inner;
};
var list_all_dom = (schedule, time) => {
let inner = html`
${schedule.map((talk) => html`
<div class="item ${highlight_class(talk)} ${urgent_class(talk, time)} ${stale_class(talk, time)} ${lapse_class(talk, time)}">
<div>
<div class="title">${talk.title}</div>
</div>
<div class="details">
<span class="start">${talk.start}</span>
${talk_day_dom(talk)}
${do_not_record_dom(talk)}
<span class="stage">${talk.room}</span>
</div>
</div>`)}`;
return inner;
};
var next_up_here_dom = (talks, time) => {
let inner;
if (talks.length > 0) {
inner = html`
<div class="panel meta">
<div class="header">Next Up Here</div>
<div class="content">${meta_here_dom(talks, time)}</div>
</div>`;
} else {
inner = html`
<div class="panel meta">
<div class="header">Next Up Here</div>
</div>`;
}
return inner;
};
var next_up_abstract_dom = (talks, time) => {
let inner;
if (talks.length > 0) {
inner = html`
<div class="panel abstract">
<div class="header">Abstract</div>
<div class="content">${abstract_here_dom(talks)}</div>
</div>`;
} else {
inner = html``;
}
return inner;
};
var next_up_list_all_dom = (talks, time) => {
let inner;
if (talks.length > 0) {
inner = html`
<div class="panel list">
<div class="header">Next Up at rC3</div>
<div class="content">${list_all_dom(talks, time)}</div>
</div>`;
} else {
inner = html`
<div class="panel list">
<div class="header">Next Up at rC3</div>
</div>`;
}
return inner;
};
var schedule_dom = (schedule, time) => {
let allTalks = schedule.slice(0, number_events_all);
let nextTalkHere = schedule.filter(is_own_talk).slice(0, 1);
return html`
<div class="slide">
<div class="schedule">
<div class="left">
${next_up_here_dom(nextTalkHere, time)}
${next_up_abstract_dom(nextTalkHere, time)}
</div>
<div class="right">
${next_up_list_all_dom(allTalks, time)}
</div>
</div>
</div>`;
};
var music_changed = (current, time) => time - current.since <= musicAge;
var changed_music_class = (current, time) => music_changed(current, time) ? "changed" : "";
var music_license_dom = (current) => current.license !== void 0 ? html`<span class="license">(${current.license})</span>` : html``;
var music_title_dom = (current) => current.license !== void 0 ? html`<span class="title">«${current.title}»</span>` : html``;
var music_artist_dom = (current) => current.license !== void 0 ? html`<span class="by">by</span><span class="artist">${current.artist}</span>` : html``;
var music_playing_now_dom = (music, time) => {
return html`
<div class="music-box">
${music.map((current) => html`
<div class="music ${changed_music_class(current, time)}">
<div class="line1">
<span>
<span class="note">
<span class="fa fa-music glyph"></span>
</span>
<span class="header">Now playing:</span>
</span>
${music_license_dom(current)}
</div>
<div class="line2">
${music_title_dom(current)}
${music_artist_dom(current)}
</div>
</div>`)}
</div>`;
};
var post_time = (date) => moment(date).format("H:mm, D. MMMM YYYY");
var social_network_dom = (post) => {
let icon = "";
if (post.source === "twitter") {
icon = "fa-twitter";
} else if (post.source === "mastodon") {
icon = "fa-mastodon";
}
return html`<span class="source fa ${icon}"></span>`;
};
var single_post_dom = (post) => {
let inner = html`
<div class="post slider">
<div class="container">
<img class="profile-image" src="${post.image}"/>
<div class="content">
<div class="meta">
${social_network_dom(post)}
<span class="username">@${post.author}</span>
<span class="time">${post_time(post.time)}</span>
</div>
<div class="text">${post.text}</div>
</div>
</div>
</div>`;
return inner;
};
var social_container_dom = (posts) => {
let inner = html`
<div id="bottom-bar" class="visible bottom-bar">
<div id="ticker-wrap" class="ticker-wrap">
<div class="ticker switcher">
${posts.map((p) => single_post_dom(p))}
</div>
</div>
</div>`;
return inner;
};
var hastag_talk_title_dom = (talk) => {
let inner = html`:`;
talk.forEach((t) => {
inner = html`<span><span class="text"> regarding the talk </span><span class="title">«${t.title}»</span>:</span>`;
});
return inner;
};
var hashtag_dom = (talk) => {
let inner = html`
<div class="hashtags short">
<div class="box">
<div class="header">For Questions:</div>
<div class="text">Please use the Hashtag <span class="hashtag">#rc3cwtv</span> or join our IRC Channel <span class="irc">#rc3-cwtv</span></div>
</div>
</div>
<div class="hashtags extended from-obs">
<div class="box">
<div class="header">For Questions${hastag_talk_title_dom(talk)}</div>
<div class="text">Please use the Hashtag <span class="hashtag">#rc3cwtv</span> on Twitter or Mastodon, or join our IRC channel <span class="irc">#rc3-cwtv</span>:irc.hackint.org</div>
</div>
</div>`;
return inner;
};
var random_integer = (n) => Math.floor(Math.random() * n);
var image_dom_element = () => document.getElementById("imageItem");
var image_index = () => {
const el = image_dom_element();
return el !== null ? Number.parseInt(el.dataset.index) : -1;
};
var image_birth_time = () => {
const el = image_dom_element();
return el !== null ? el.dataset.birth : 0;
};
var image_age = (time) => time - image_birth_time();
var cms_age_class = (index, age) => {
const direction = index % 2 === 0 ? "left" : "right";
let oldness;
if (age <= freshImage) {
oldness = "fresh";
} else if (age >= maxImageAge - staleImage) {
oldness = "stale";
} else {
oldness = "";
}
return oldness + " " + direction;
};
var cms_item_url = (item) => cmsBaseUrl + item.url;
var cms_item_author = (item) => item.user;
var cms_meta_dom = (item, index, age) => {
let inner = html`
<div class="cms">
<div class="meta-box">
<div class="meta ${cms_age_class(index, age)}">
<div class="line1">
<span>
<span class="icon">
<span class="fa fa-file-image-o"></span>
</span>
<span class="header">Community Advertisement</span>
<span> by </span><span class="author">${cms_item_author(item)}</span>
</span>
</div>
<div class="line2">
<span>Upload own content at: </span>
<span>https://infobeamer-cms.c3voc.de/</span>
</div>
</div>
</div>
</div>`;
return inner;
};
var cms_image_dom = (item) => html`<img class="cms-image" src=${cms_item_url(item)} />`;
var cms_item_dom = (item, index, birth, age) => {
return html`
<div class="item ${cms_age_class(index, age)}" data-index=${index} data-birth=${birth} id="imageItem">
${cms_image_dom(item)}
</div>`;
};
var cms_content_dom = (item, index, birth, age) => {
return html`
<div class="cms">
<div class="content">
<div class="items">
${cms_item_dom(item, index, birth, age)}
</div>
</div>
</div>`;
};
var cms_dom = (items, time) => {
let inner;
if (items.length > 0) {
let age = image_age(time);
let item;
let index;
let birth;
if (age > maxImageAge) {
index = random_integer(items.length);
item = items[index];
birth = time;
age = 0;
} else {
index = image_index();
item = items[index];
birth = image_birth_time();
}
inner = html`
${cms_content_dom(item, index, birth, age)}
${cms_meta_dom(item, index, age)}
`;
} else {
inner = html``;
}
return inner;
};
function update_main_slide(data, time) {
let schedule = data.futureSchedule;
let runningEvent = data.runningEvent;
let music = data.music;
let postings = data.posts;
let cms = data.cms;
let inner = html`
${schedule_dom(schedule, time)}
${hashtag_dom(runningEvent)}
${music_playing_now_dom(music, time)}
${social_container_dom(postings)}
${cms_dom(cms, time)}
`;
const anchorElId = "main";
const el = document.getElementById(anchorElId);
preact.render(inner, el);
}
// <stdin>
var scheduleData = [];
var musicData = [];
var twitterData = [];
var mastodonData = [];
var cmsData = [];
if (window.Worker) {
const workerBaseURL = window.infoBeamerConfig.get("workerBaseURL");
const fetchWorkerCode = workerBaseURL + "js/generic_fetch_worker.js";
const scheduleWorker = new Worker(fetchWorkerCode);
const scheduleType = "Schedule";
const scheduleURL = window.infoBeamerConfig.get("scheduleURL");
const scheduleFetchInterval = window.infoBeamerConfig.get("scheduleFetchInterval");
scheduleWorker.postMessage({
fetchType: scheduleType,
fetchURL: scheduleURL,
fetchInterval: scheduleFetchInterval
});
scheduleWorker.onmessage = function(e) {
if (e.data.msgType === scheduleType) {
scheduleData = schedule_filter(e.data.json);
update_screen();
}
};
const musicWorker = new Worker(fetchWorkerCode);
const musicType = "Music";
const musicURL = window.infoBeamerConfig.get("musicURL");
const musicFetchInterval = window.infoBeamerConfig.get("musicFetchInterval");
musicWorker.postMessage({
fetchType: musicType,
fetchURL: musicURL,
fetchInterval: musicFetchInterval
});
musicWorker.onmessage = function(e) {
if (e.data.msgType === musicType) {
let musicDataUpdate = [e.data.json];
musicData = music_update(musicData, musicDataUpdate);
update_screen();
}
};
const twitterWorker = new Worker(fetchWorkerCode);
const twitterType = "Twitter";
const twitterURL = window.infoBeamerConfig.get("twitterURL");
const twitterFetchInterval = window.infoBeamerConfig.get("twitterFetchInterval");
twitterWorker.postMessage({
fetchType: twitterType,
fetchURL: twitterURL,
fetchInterval: twitterFetchInterval
});
twitterWorker.onmessage = function(e) {
if (e.data.msgType === twitterType) {
twitterData = [e.data.json];
twitterData = twitter_filter(twitterData);
update_screen();
}
};
const mastodonWorker = new Worker(fetchWorkerCode);
const mastodonType = "Mastodon";
const mastodonURL = window.infoBeamerConfig.get("mastodonURL");
const mastodonFetchInterval = window.infoBeamerConfig.get("mastodonFetchInterval");
mastodonWorker.postMessage({
fetchType: mastodonType,
fetchURL: mastodonURL,
fetchInterval: mastodonFetchInterval
});
mastodonWorker.onmessage = function(e) {
if (e.data.msgType === mastodonType) {
mastodonData = [e.data.json];
mastodonData = mastodon_filter(mastodonData);
update_screen();
}
};
const cmsWorker = new Worker(fetchWorkerCode);
const cmsType = "CMS";
const cmsURL = window.infoBeamerConfig.get("cmsURL");
const cmsFetchInterval = window.infoBeamerConfig.get("cmsFetchInterval");
cmsWorker.postMessage({
fetchType: cmsType,
fetchURL: cmsURL,
fetchInterval: cmsFetchInterval
});
cmsWorker.onmessage = function(e) {
if (e.data.msgType === cmsType) {
cmsData = cms_filter(e.data.json);
console.log(cmsData);
update_screen();
}
};
} else {
console.log("Your browser doesn't support web workers.");
}
var fakeTimeDelta = 0;
function update_screen() {
let realTime = new Date();
let now = Date.now() + fakeTimeDelta;
update_main_slide({
futureSchedule: future_events(scheduleData, now),
runningEvent: running_event(scheduleData, now),
music: musicData,
posts: social_limiter(twitterData, mastodonData),
cms: cmsData
}, now);
}
function main_loop() {
update_screen();
setTimeout(main_loop, 1 * 1e3);
}
main_loop();
})();

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,18 @@
<!doctype html><html lang=en>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no">
<title>rC3 NOWHERE</title>
<link href=/fork-awesome/css/fork-awesome.min.css rel=stylesheet type=text/css>
<link rel=stylesheet href=https://infobeamer.montage2.de/music_and_posts.min.2ef379d059820a7aa8b66411626dd27949edd4538d1b3a32ccb631dce61b1287.css>
<script src=https://infobeamer.montage2.de/js/config.2fd38d4779fef41f713ebc0f66f431aa1d363b933809e3877abb8f4354f2bae1.js integrity="sha256-L9ONR3n+9B9xPrwPZvQxqh02O5M4CeOHeruPQ1TyuuE="></script>
</head>
<body>
<main id=main>
</main>
<script src=https://infobeamer.montage2.de/js/moment/moment.min.73de4254959530e4d1d9bec586379184f96b4953dacf9cd5e5e2bdd7bfeceef7.js integrity="sha256-c95CVJWVMOTR2b7FhjeRhPlrSVPaz5zV5eK917/s7vc="></script>
<script src=https://infobeamer.montage2.de/js/preact/preact.min.0c204e20934f1e09cfe86fbcf1d069d842f988fc71efe3a923021c08892c71c8.js integrity="sha256-DCBOIJNPHgnP6G+88dBp2EL5iPxx7+OpIwIcCIksccg="></script>
<script src=https://infobeamer.montage2.de/js/htm/htm.80e39afe20fd61183412eda89efa10532d57945e6364642aceacd50eb2384b4b.js integrity="sha256-gOOa/iD9YRg0Eu2onvoQUy1XlF5jZGQqzqzVDrI4S0s="></script>
<script src=https://infobeamer.montage2.de/main.92ebdf5660681a66f540837f65fda601f0c32c541bb3b060756cc5e4674a9558.js integrity="sha256-kuvfVmBoGmb1QIN/Zf2mAfDDLFQbs7BgdWzF5GdKlVg=" type=module></script>
</body>
</html>

File diff suppressed because one or more lines are too long

18
public/music/index.html Normal file
View File

@ -0,0 +1,18 @@
<!doctype html><html lang=en>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no">
<title>rC3 NOWHERE</title>
<link href=/fork-awesome/css/fork-awesome.min.css rel=stylesheet type=text/css>
<link rel=stylesheet href=https://infobeamer.montage2.de/music.min.d9b39d87a2831c3a80de9fe3d696ac9204b2a39148b51ead43a1579540f11850.css>
<script src=https://infobeamer.montage2.de/js/config.2fd38d4779fef41f713ebc0f66f431aa1d363b933809e3877abb8f4354f2bae1.js integrity="sha256-L9ONR3n+9B9xPrwPZvQxqh02O5M4CeOHeruPQ1TyuuE="></script>
</head>
<body>
<main id=main>
</main>
<script src=https://infobeamer.montage2.de/js/moment/moment.min.73de4254959530e4d1d9bec586379184f96b4953dacf9cd5e5e2bdd7bfeceef7.js integrity="sha256-c95CVJWVMOTR2b7FhjeRhPlrSVPaz5zV5eK917/s7vc="></script>
<script src=https://infobeamer.montage2.de/js/preact/preact.min.0c204e20934f1e09cfe86fbcf1d069d842f988fc71efe3a923021c08892c71c8.js integrity="sha256-DCBOIJNPHgnP6G+88dBp2EL5iPxx7+OpIwIcCIksccg="></script>
<script src=https://infobeamer.montage2.de/js/htm/htm.80e39afe20fd61183412eda89efa10532d57945e6364642aceacd50eb2384b4b.js integrity="sha256-gOOa/iD9YRg0Eu2onvoQUy1XlF5jZGQqzqzVDrI4S0s="></script>
<script src=https://infobeamer.montage2.de/main.92ebdf5660681a66f540837f65fda601f0c32c541bb3b060756cc5e4674a9558.js integrity="sha256-kuvfVmBoGmb1QIN/Zf2mAfDDLFQbs7BgdWzF5GdKlVg=" type=module></script>
</body>
</html>

File diff suppressed because one or more lines are too long

BIN
public/nounicorn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,19 @@
<!doctype html><html lang=en>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no">
<meta http-equiv=refresh content="60;url=/cms/">
<title>rC3 NOWHERE</title>
<link href=/fork-awesome/css/fork-awesome.min.css rel=stylesheet type=text/css>
<link rel=stylesheet href=https://infobeamer.montage2.de/main.min.2bff15f19297e3f97fbde58195288bc7035285c53ef8f0c673ce787a4bd4cf6b.css>
<script src=https://infobeamer.montage2.de/js/config.2fd38d4779fef41f713ebc0f66f431aa1d363b933809e3877abb8f4354f2bae1.js integrity="sha256-L9ONR3n+9B9xPrwPZvQxqh02O5M4CeOHeruPQ1TyuuE="></script>
</head>
<body>
<main id=main>
</main>
<script src=https://infobeamer.montage2.de/js/moment/moment.min.73de4254959530e4d1d9bec586379184f96b4953dacf9cd5e5e2bdd7bfeceef7.js integrity="sha256-c95CVJWVMOTR2b7FhjeRhPlrSVPaz5zV5eK917/s7vc="></script>
<script src=https://infobeamer.montage2.de/js/preact/preact.min.0c204e20934f1e09cfe86fbcf1d069d842f988fc71efe3a923021c08892c71c8.js integrity="sha256-DCBOIJNPHgnP6G+88dBp2EL5iPxx7+OpIwIcCIksccg="></script>
<script src=https://infobeamer.montage2.de/js/htm/htm.80e39afe20fd61183412eda89efa10532d57945e6364642aceacd50eb2384b4b.js integrity="sha256-gOOa/iD9YRg0Eu2onvoQUy1XlF5jZGQqzqzVDrI4S0s="></script>
<script src=https://infobeamer.montage2.de/main.92ebdf5660681a66f540837f65fda601f0c32c541bb3b060756cc5e4674a9558.js integrity="sha256-kuvfVmBoGmb1QIN/Zf2mAfDDLFQbs7BgdWzF5GdKlVg=" type=module></script>
</body>
</html>