mirror of
https://github.com/web3privacy/w3ps1.git
synced 2024-10-15 16:26:26 +02:00
Reformat
This commit is contained in:
parent
012de9d209
commit
26fee8006e
9 changed files with 245 additions and 179 deletions
|
@ -7,6 +7,7 @@ Website and data repository for the Web3Privacy Summit #1 that will take place i
|
||||||
- Twitter: [@web3privacy](http://twitter.com/web3privacy)
|
- Twitter: [@web3privacy](http://twitter.com/web3privacy)
|
||||||
|
|
||||||
JSON data about `w3ps1`:
|
JSON data about `w3ps1`:
|
||||||
|
|
||||||
- source: ([src/lib/config.yaml](src/lib/config.yaml))
|
- source: ([src/lib/config.yaml](src/lib/config.yaml))
|
||||||
- build: [prague.web3privacy.info/config.json](https://prague.web3privacy.info/config.json)
|
- build: [prague.web3privacy.info/config.json](https://prague.web3privacy.info/config.json)
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,8 @@
|
||||||
.table-custom th {
|
.table-custom th {
|
||||||
@apply text-mild;
|
@apply text-mild;
|
||||||
}
|
}
|
||||||
.table-custom tbody tr:hover td, .table-custom tbody tr:hover td span {
|
.table-custom tbody tr:hover td,
|
||||||
|
.table-custom tbody tr:hover td span {
|
||||||
@apply bg-white text-black;
|
@apply bg-white text-black;
|
||||||
}
|
}
|
||||||
.table-custom tbody tr:hover td .description {
|
.table-custom tbody tr:hover td .description {
|
||||||
|
@ -82,7 +83,10 @@
|
||||||
.person-item:hover img {
|
.person-item:hover img {
|
||||||
@apply grayscale-0 invert-0 blur-none;
|
@apply grayscale-0 invert-0 blur-none;
|
||||||
}
|
}
|
||||||
.person-item:hover .text-mild, .person-item:hover .text-supermild, .topic-item:hover .text-mild, .topic-item:hover .text-supermild {
|
.person-item:hover .text-mild,
|
||||||
|
.person-item:hover .text-supermild,
|
||||||
|
.topic-item:hover .text-mild,
|
||||||
|
.topic-item:hover .text-supermild {
|
||||||
@apply text-black;
|
@apply text-black;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
</head>
|
</head>
|
||||||
<body data-sveltekit-preload-data="hover">
|
<body data-sveltekit-preload-data="hover">
|
||||||
<div style="display: contents">%sveltekit.body%</div>
|
<div style="display: contents">%sveltekit.body%</div>
|
||||||
<script defer data-domain="prague.web3privacy.info" src="https://x.gwei.cz/js/script.js"></script>
|
<script
|
||||||
|
defer
|
||||||
|
data-domain="prague.web3privacy.info"
|
||||||
|
src="https://x.gwei.cz/js/script.js"
|
||||||
|
></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
export let items;
|
export let items;
|
||||||
export let people;
|
export let people;
|
||||||
export let size = 'normal';
|
export let size = 'normal';
|
||||||
|
|
||||||
import SvelteMarkdown from 'svelte-markdown';
|
import SvelteMarkdown from 'svelte-markdown';
|
||||||
import { animateText } from '$lib/helpers';
|
import { animateText } from '$lib/helpers';
|
||||||
|
@ -13,21 +13,27 @@
|
||||||
return `https://twitter.com/${handle}`;
|
return `https://twitter.com/${handle}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function animateSpeaker (el) {
|
function animateSpeaker(el) {
|
||||||
for(const e of el.target.getElementsByClassName('animate-speaker')) {
|
for (const e of el.target.getElementsByClassName('animate-speaker')) {
|
||||||
animateText({ target: e })
|
animateText({ target: e });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#each items.map(getPerson) as item}
|
{#each items.map(getPerson) as item}
|
||||||
<div class="hover:bg-white hover:text-black p-2 {size === 'small' ? 'w-2/3 sm:w-48' : 'w-2/3 sm:w-64'} person-item" on:mouseenter={animateSpeaker}>
|
<div
|
||||||
|
class="hover:bg-white hover:text-black p-2 {size === 'small'
|
||||||
|
? 'w-2/3 sm:w-48'
|
||||||
|
: 'w-2/3 sm:w-64'} person-item"
|
||||||
|
on:mouseenter={animateSpeaker}
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<img src="/people/{item.img}" class="grayscale invert aspect-square object-cover w-full" />
|
<img src="/people/{item.img}" class="grayscale invert aspect-square object-cover w-full" />
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4 speaker-name animate-speaker text-xl">{item.name.toUpperCase()}</div>
|
<div class="mt-4 speaker-name animate-speaker text-xl">{item.name.toUpperCase()}</div>
|
||||||
<div class="text-lg text-mild">
|
<div class="text-lg text-mild">
|
||||||
<a href={twitterLink(item.twitter)} class="hover:underline animate-speaker">@{item.twitter}</a>
|
<a href={twitterLink(item.twitter)} class="hover:underline animate-speaker">@{item.twitter}</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
{#if item.caption}
|
{#if item.caption}
|
||||||
<div class="mt-2 text-base text-supermild"><SvelteMarkdown source={item.caption} /></div>
|
<div class="mt-2 text-base text-supermild"><SvelteMarkdown source={item.caption} /></div>
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
title: Web3Privacy Prague 2023
|
title: Web3Privacy Prague 2023
|
||||||
shortname: "Web3Privacy Summit #1"
|
shortname: 'Web3Privacy Summit #1'
|
||||||
date: 5. June 2023
|
date: 5. June 2023
|
||||||
venue: X10, Prague
|
venue: X10, Prague
|
||||||
domain: prague.web3privacy.info
|
domain: prague.web3privacy.info
|
||||||
image: "/web3privacy.png"
|
image: '/web3privacy.png'
|
||||||
logo: "/web3privacy-cropped.jpg"
|
logo: '/web3privacy-cropped.jpg'
|
||||||
twitter: web3privacy
|
twitter: web3privacy
|
||||||
parent: Web3Privacy Now
|
parent: Web3Privacy Now
|
||||||
venueMapUrl: https://goo.gl/maps/VCSC7wcNueEKgt996
|
venueMapUrl: https://goo.gl/maps/VCSC7wcNueEKgt996
|
||||||
parentUrl: https://web3privacy.info
|
parentUrl: https://web3privacy.info
|
||||||
desc: June 5, 2023 - A lunarpunk conference focused on privacy in the Web3 industry as a complement to the Web3Privacy Now research.
|
desc: June 5, 2023 - A lunarpunk conference focused on privacy in the Web3 industry as a complement to the Web3Privacy Now research.
|
||||||
authors: "💛 Collaboration of [Web3Privacy Now](https://web3privacy.info) & [ETHBrno](https://ethbrno.cz) team"
|
authors: '💛 Collaboration of [Web3Privacy Now](https://web3privacy.info) & [ETHBrno](https://ethbrno.cz) team'
|
||||||
license: This web is built with [SvelteKit](https://kit.svelte.dev/) and is [open-source](https://github.com/web3privacy/w3ps1) under CC0 license
|
license: This web is built with [SvelteKit](https://kit.svelte.dev/) and is [open-source](https://github.com/web3privacy/w3ps1) under CC0 license
|
||||||
slogan: Diving into the culture of the Web3 privacy industry
|
slogan: Diving into the culture of the Web3 privacy industry
|
||||||
aggregator: Prague Blockchain Week 2023
|
aggregator: Prague Blockchain Week 2023
|
||||||
|
@ -18,15 +18,15 @@ aggregatorUrl: http://prgblockweek.com/
|
||||||
sponsorUrl: https://matrix.to/#/@tree:gwei.cz
|
sponsorUrl: https://matrix.to/#/@tree:gwei.cz
|
||||||
intro: |
|
intro: |
|
||||||
If privacy is a human right, then we need to protect it.
|
If privacy is a human right, then we need to protect it.
|
||||||
|
|
||||||
Privacy advocates worldwide are coming together to discuss how to mainstream privacy within the Web3 industry. So it will become a cultural phenomenon embodying both decentralisation & anti-surveillance capitalism practices.
|
Privacy advocates worldwide are coming together to discuss how to mainstream privacy within the Web3 industry. So it will become a cultural phenomenon embodying both decentralisation & anti-surveillance capitalism practices.
|
||||||
|
|
||||||
The conference complements the research project [Web3Privacy Now](http://web3privacy.info/) and was created by joining forces with the production team of the privacy hackathon [ETHBrno](https://ethbrno.cz/).
|
The conference complements the research project [Web3Privacy Now](http://web3privacy.info/) and was created by joining forces with the production team of the privacy hackathon [ETHBrno](https://ethbrno.cz/).
|
||||||
themes:
|
themes:
|
||||||
- title: Regulations vs Privacy
|
- title: Regulations vs Privacy
|
||||||
desc: 2023 will be a year of privacy regulations. Privacy coins will be banned, mixer's team become anon etc. How do we defend our rights for privacy?
|
desc: 2023 will be a year of privacy regulations. Privacy coins will be banned, mixer's team become anon etc. How do we defend our rights for privacy?
|
||||||
- title: MAINSTREAM ON-CHAIN PRIVACY
|
- title: MAINSTREAM ON-CHAIN PRIVACY
|
||||||
desc: Majority of privacy services are tech oriented. It's hard to use them among non-technical people. What should industry do help people onboard into privacy with ease?
|
desc: Majority of privacy services are tech oriented. It's hard to use them among non-technical people. What should industry do help people onboard into privacy with ease?
|
||||||
- title: Human rights DAOs (pro-privacy)
|
- title: Human rights DAOs (pro-privacy)
|
||||||
desc: How privacy-enhancing tools could protect DAOs working within non-democratic countries.
|
desc: How privacy-enhancing tools could protect DAOs working within non-democratic countries.
|
||||||
- title: Identity (ID)
|
- title: Identity (ID)
|
||||||
|
@ -37,15 +37,15 @@ themes:
|
||||||
desc: We need resilient privacy-preserving, p2p communication layers for Web3, that allows free and uncensored human-to-human, machine-to-machine or hybrid communication.
|
desc: We need resilient privacy-preserving, p2p communication layers for Web3, that allows free and uncensored human-to-human, machine-to-machine or hybrid communication.
|
||||||
- title: Lunarpunk vs Solarpunk
|
- title: Lunarpunk vs Solarpunk
|
||||||
desc: For solarpunk to succeed it must integrate the lunarpunk unconscious. The only hope for solarpunk is to [go dark](https://www.egirlcapital.com/writings/107533289). Do you agree?
|
desc: For solarpunk to succeed it must integrate the lunarpunk unconscious. The only hope for solarpunk is to [go dark](https://www.egirlcapital.com/writings/107533289). Do you agree?
|
||||||
- title: "R&D: ZK, MPC, THE"
|
- title: 'R&D: ZK, MPC, THE'
|
||||||
desc: There are many different cryptography technics for privacy preservation. How to balance them all & avoid 1-tool chokepoint?
|
desc: There are many different cryptography technics for privacy preservation. How to balance them all & avoid 1-tool chokepoint?
|
||||||
- title: Privacy readiness levels
|
- title: Privacy readiness levels
|
||||||
desc: Introduction of the privacy scoring mechanism to help non-tech people understand security level of the solution
|
desc: Introduction of the privacy scoring mechanism to help non-tech people understand security level of the solution
|
||||||
- title: Privacy wars
|
- title: Privacy wars
|
||||||
desc: Why are privacy-blockchain socials so toxic? How could we stop hating each other & work together
|
desc: Why are privacy-blockchain socials so toxic? How could we stop hating each other & work together
|
||||||
- title: Privacy workforce
|
- title: Privacy workforce
|
||||||
- title: "Privacy activism"
|
- title: 'Privacy activism'
|
||||||
desc: "Mapping down tools to protect privacy industry: from builders like Alexey Pertsev to projects."
|
desc: 'Mapping down tools to protect privacy industry: from builders like Alexey Pertsev to projects.'
|
||||||
- title: Network states (with a privacy focus)
|
- title: Network states (with a privacy focus)
|
||||||
desc: Time ot imagine the network state-as-a-grassroots movement for privacy, freedom & better future.
|
desc: Time ot imagine the network state-as-a-grassroots movement for privacy, freedom & better future.
|
||||||
- title: Veksl
|
- title: Veksl
|
||||||
|
@ -58,22 +58,22 @@ tickets:
|
||||||
- title: All-day Access
|
- title: All-day Access
|
||||||
price: €99
|
price: €99
|
||||||
includes:
|
includes:
|
||||||
- All talks & panels
|
- All talks & panels
|
||||||
- Food and drinks included
|
- Food and drinks included
|
||||||
- Web3Privacy t-shirt
|
- Web3Privacy t-shirt
|
||||||
- Networking drinks with speakers & attendees
|
- Networking drinks with speakers & attendees
|
||||||
- "#Lunarpunk party"
|
- '#Lunarpunk party'
|
||||||
hint: |
|
hint: |
|
||||||
[Apply for a discount →](https://attend.web3privacy.info)<br />(as independent developer, student, privacy advocate, open-source contributor..)
|
[Apply for a discount →](https://attend.web3privacy.info)<br />(as independent developer, student, privacy advocate, open-source contributor..)
|
||||||
- title: "#Lunarpunk Party"
|
- title: '#Lunarpunk Party'
|
||||||
price: €15
|
price: €15
|
||||||
includes:
|
includes:
|
||||||
- 8pm - morning
|
- 8pm - morning
|
||||||
- Prague rave from top DJs
|
- Prague rave from top DJs
|
||||||
- VJs and projections
|
- VJs and projections
|
||||||
- "\"Privacy experience\""
|
- '"Privacy experience"'
|
||||||
- Networking with attendees, speakers & sponsors
|
- Networking with attendees, speakers & sponsors
|
||||||
note: "*Party access is included in the All-day Pass"
|
note: '*Party access is included in the All-day Pass'
|
||||||
faq:
|
faq:
|
||||||
- title: What is Web3Privacy Now?
|
- title: What is Web3Privacy Now?
|
||||||
text: |
|
text: |
|
||||||
|
@ -94,44 +94,44 @@ faq:
|
||||||
- title: Will the talks be livestreamed and/or recorded?
|
- title: Will the talks be livestreamed and/or recorded?
|
||||||
text: Yes, we're planning both. A livestream of the conference and recordings of the talks and panels will be publicly available after the conference.
|
text: Yes, we're planning both. A livestream of the conference and recordings of the talks and panels will be publicly available after the conference.
|
||||||
- title: I have another question, where can I contact you?
|
- title: I have another question, where can I contact you?
|
||||||
text: "You can contact the organizing team or the community around the event in our public Signal group: [chat.web3privacy.info](https://chat.web3privacy.info/)"
|
text: 'You can contact the organizing team or the community around the event in our public Signal group: [chat.web3privacy.info](https://chat.web3privacy.info/)'
|
||||||
people:
|
people:
|
||||||
- id: mykola
|
- id: mykola
|
||||||
name: Mykola Siusko
|
name: Mykola Siusko
|
||||||
twitter: nicksvyaznoy
|
twitter: nicksvyaznoy
|
||||||
img: mykola.png
|
img: mykola.png
|
||||||
caption: Web3 privacy advocate
|
caption: Web3 privacy advocate
|
||||||
country: es
|
country: es
|
||||||
- id: tree
|
- id: tree
|
||||||
name: Tree
|
name: Tree
|
||||||
twitter: treecz
|
twitter: treecz
|
||||||
img: tree.jpeg
|
img: tree.jpeg
|
||||||
caption: Creator of lunarpunk hackathons & events
|
caption: Creator of lunarpunk hackathons & events
|
||||||
country: cz
|
country: cz
|
||||||
- id: juraj-bednar
|
- id: juraj-bednar
|
||||||
name: Juraj Bednar
|
name: Juraj Bednar
|
||||||
twitter: jurbed
|
twitter: jurbed
|
||||||
img: juraj-bednar.jpeg
|
img: juraj-bednar.jpeg
|
||||||
caption: Educator, writer, cryptoanarchist & biohacker
|
caption: Educator, writer, cryptoanarchist & biohacker
|
||||||
country: sk
|
country: sk
|
||||||
- id: mario-havel
|
- id: mario-havel
|
||||||
name: Mario Havel
|
name: Mario Havel
|
||||||
twitter: TMIYChao
|
twitter: TMIYChao
|
||||||
img: mario-havel.jpeg
|
img: mario-havel.jpeg
|
||||||
caption: Hacker, Co-Founder of [Bordel Hackerspace](https://bordel.paralelnipolis.cz/#/)
|
caption: Hacker, Co-Founder of [Bordel Hackerspace](https://bordel.paralelnipolis.cz/#/)
|
||||||
country: cz
|
country: cz
|
||||||
- id: guy-zyskind
|
- id: guy-zyskind
|
||||||
name: Guy Zyskind
|
name: Guy Zyskind
|
||||||
twitter: GuyZys
|
twitter: GuyZys
|
||||||
img: guy-zyskind.jpeg
|
img: guy-zyskind.jpeg
|
||||||
caption: Founder of [Secret Network](https://scrt.network/), CEO [SCRT Labs](https://www.scrtlabs.com/)
|
caption: Founder of [Secret Network](https://scrt.network/), CEO [SCRT Labs](https://www.scrtlabs.com/)
|
||||||
country: is
|
country: is
|
||||||
- id: manu-alzuru
|
- id: manu-alzuru
|
||||||
name: Manu Alzuru
|
name: Manu Alzuru
|
||||||
twitter: ManuAlzuru
|
twitter: ManuAlzuru
|
||||||
img: manu-alzuru.jpeg
|
img: manu-alzuru.jpeg
|
||||||
caption: Humanist, solarpunk, Founder of [DoinGud](https://doingud.com/) & [ETH Barcelona](https://ethbarcelona.com/)
|
caption: Humanist, solarpunk, Founder of [DoinGud](https://doingud.com/) & [ETH Barcelona](https://ethbarcelona.com/)
|
||||||
country: es
|
country: es
|
||||||
speakersNote: We keep adding more and more speakers, stay tuned ...
|
speakersNote: We keep adding more and more speakers, stay tuned ...
|
||||||
speakers:
|
speakers:
|
||||||
- guy-zyskind
|
- guy-zyskind
|
||||||
|
@ -154,7 +154,7 @@ program:
|
||||||
- time: 9:30 - 9:35
|
- time: 9:30 - 9:35
|
||||||
title: Welcome to Web3Privacy
|
title: Welcome to Web3Privacy
|
||||||
speakers:
|
speakers:
|
||||||
- name: TBA
|
- name: TBA
|
||||||
desc: Welcoming visitors to our private-centric research, community and conference
|
desc: Welcoming visitors to our private-centric research, community and conference
|
||||||
- time: 9:35 - 10:55
|
- time: 9:35 - 10:55
|
||||||
title: Talks I. - TBA
|
title: Talks I. - TBA
|
||||||
|
@ -181,7 +181,7 @@ program:
|
||||||
title: Networking & Drinks
|
title: Networking & Drinks
|
||||||
type: other
|
type: other
|
||||||
- time: 20:00 - 4:00
|
- time: 20:00 - 4:00
|
||||||
title: "#Lunarpunk party"
|
title: '#Lunarpunk party'
|
||||||
desc: Enjoy our afterparty in Lunarpunk style with quality Prague rave DJs, which will take place in the same venue until the morning (4am).
|
desc: Enjoy our afterparty in Lunarpunk style with quality Prague rave DJs, which will take place in the same venue until the morning (4am).
|
||||||
second:
|
second:
|
||||||
- time: 09:35 - 10:55
|
- time: 09:35 - 10:55
|
||||||
|
@ -200,4 +200,4 @@ program:
|
||||||
title: 25min Coffee Break
|
title: 25min Coffee Break
|
||||||
type: other
|
type: other
|
||||||
- time: 16:10 - 18:30
|
- time: 16:10 - 18:30
|
||||||
title: Workshops IV.
|
title: Workshops IV.
|
||||||
|
|
|
@ -1,53 +1,65 @@
|
||||||
|
import removeMd from 'remove-markdown';
|
||||||
import removeMd from 'remove-markdown'
|
|
||||||
|
|
||||||
export function rand(length) {
|
export function rand(length) {
|
||||||
let result = '';
|
let result = '';
|
||||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
const charactersLength = characters.length;
|
const charactersLength = characters.length;
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
while (counter < length) {
|
while (counter < length) {
|
||||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||||
counter += 1;
|
counter += 1;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function animateText (ev, interval = 50) {
|
export function animateText(ev, interval = 50) {
|
||||||
if (!ev.target.getAttribute('data-text')) {
|
if (!ev.target.getAttribute('data-text')) {
|
||||||
ev.target.setAttribute('data-text', ev.target.innerHTML)
|
ev.target.setAttribute('data-text', ev.target.innerHTML);
|
||||||
}
|
}
|
||||||
if (ev.target.getAttribute('data-animate') === "1") {
|
if (ev.target.getAttribute('data-animate') === '1') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ev.target.setAttribute('data-animate', "1")
|
ev.target.setAttribute('data-animate', '1');
|
||||||
const orig = removeMd(ev.target.getAttribute('data-text')).replace('&', '&')
|
const orig = removeMd(ev.target.getAttribute('data-text')).replace('&', '&');
|
||||||
const steps = orig.length
|
const steps = orig.length;
|
||||||
|
|
||||||
const genRand = (pos = 0, len = null) => orig.substring(pos, len).split(' ').map(x => rand(x.length)).join(' ')
|
const genRand = (pos = 0, len = null) =>
|
||||||
const random = genRand(0, orig.length)
|
orig
|
||||||
|
.substring(pos, len)
|
||||||
|
.split(' ')
|
||||||
|
.map((x) => rand(x.length))
|
||||||
|
.join(' ');
|
||||||
|
const random = genRand(0, orig.length);
|
||||||
|
|
||||||
ev.target.innerHTML = random
|
ev.target.innerHTML = random;
|
||||||
|
|
||||||
for (let i = 0; i <= steps; i++) {
|
for (let i = 0; i <= steps; i++) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
ev.target.innerHTML = orig.substring(0, i) + genRand(i, orig.length)
|
ev.target.innerHTML = orig.substring(0, i) + genRand(i, orig.length);
|
||||||
//console.log(ev.target.innerHTML)
|
//console.log(ev.target.innerHTML)
|
||||||
|
|
||||||
if (i === steps) {
|
if (i === steps) {
|
||||||
ev.target.setAttribute('data-animate', "0")
|
ev.target.setAttribute('data-animate', '0');
|
||||||
}
|
}
|
||||||
}, interval * i)
|
}, interval * i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function handleAnchorClick (event) {
|
export async function handleAnchorClick(event) {
|
||||||
event.preventDefault()
|
event.preventDefault();
|
||||||
const link = event.currentTarget
|
const link = event.currentTarget;
|
||||||
const anchorId = new URL(link.href).hash.replace('#', '')
|
const anchorId = new URL(link.href).hash.replace('#', '');
|
||||||
const anchor = document.getElementById(anchorId || 'intro')
|
const anchor = document.getElementById(anchorId || 'intro');
|
||||||
return window.scrollTo({
|
return window.scrollTo({
|
||||||
top: anchor.offsetTop,
|
top: anchor.offsetTop,
|
||||||
behavior: 'smooth'
|
behavior: 'smooth'
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function animateSection(interval = 50) {
|
||||||
|
return (el) => {
|
||||||
|
for (const e of el.target.getElementsByClassName('animate-section')) {
|
||||||
|
animateText({ target: e }, interval);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
import SvelteMarkdown from 'svelte-markdown';
|
import SvelteMarkdown from 'svelte-markdown';
|
||||||
import { animateText, handleAnchorClick } from '$lib/helpers';
|
import { animateText, animateSection, handleAnchorClick } from '$lib/helpers';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
let navbar = false;
|
let navbar = false;
|
||||||
let choosed = null;
|
let choosed = null;
|
||||||
let lastScrollTop = null;
|
let lastScrollTop = null;
|
||||||
|
|
||||||
|
@ -23,34 +23,34 @@
|
||||||
];
|
];
|
||||||
|
|
||||||
const homepageAnimation = () => {
|
const homepageAnimation = () => {
|
||||||
const collection = document.getElementsByClassName('animation-crypt')
|
const collection = document.getElementsByClassName('animation-crypt');
|
||||||
for (const el of collection) {
|
for (const el of collection) {
|
||||||
animateText({ target: el })
|
animateText({ target: el });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function locationHashUpdateTick () {
|
function locationHashUpdateTick() {
|
||||||
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
|
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||||
if (lastScrollTop === scrollTop) {
|
if (lastScrollTop === scrollTop) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
lastScrollTop = scrollTop
|
lastScrollTop = scrollTop;
|
||||||
}
|
}
|
||||||
const arr = []
|
const arr = [];
|
||||||
for (const mi of menu) {
|
for (const mi of menu) {
|
||||||
if (mi.external) continue;
|
if (mi.external) continue;
|
||||||
const el = document.getElementById(mi.title.toLowerCase())
|
const el = document.getElementById(mi.title.toLowerCase());
|
||||||
const pos = el.getBoundingClientRect()
|
const pos = el.getBoundingClientRect();
|
||||||
//console.log(mi.title, pos.top, pos.bottom)
|
//console.log(mi.title, pos.top, pos.bottom)
|
||||||
if (pos.top <= 100 && pos.bottom > 100) {
|
if (pos.top <= 100 && pos.bottom > 100) {
|
||||||
arr.push([ mi, pos.top, pos.bottom ])
|
arr.push([mi, pos.top, pos.bottom]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
choosed = arr[arr.length-1]
|
choosed = arr[arr.length - 1];
|
||||||
if (choosed) {
|
if (choosed) {
|
||||||
//console.log('choosed = ', choosed[0].title)
|
//console.log('choosed = ', choosed[0].title)
|
||||||
const currentHash = window.location.hash
|
const currentHash = window.location.hash;
|
||||||
const hash = choosed[0].url
|
const hash = choosed[0].url;
|
||||||
if (hash !== currentHash) {
|
if (hash !== currentHash) {
|
||||||
if (hash === '') {
|
if (hash === '') {
|
||||||
history.replaceState(null, null, ' ');
|
history.replaceState(null, null, ' ');
|
||||||
|
@ -62,28 +62,38 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
setTimeout(homepageAnimation, 0) // initial animation
|
setTimeout(homepageAnimation, 0); // initial animation
|
||||||
setInterval(homepageAnimation, 10000) // every 10 seconds
|
setInterval(homepageAnimation, 10000); // every 10 seconds
|
||||||
setInterval(locationHashUpdateTick, 1000) // every 1 seconds
|
setInterval(locationHashUpdateTick, 1000); // every 1 seconds
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="relative w-full min-h-screen text-white">
|
<div class="relative w-full min-h-screen text-white">
|
||||||
<div class="fixed w-full h-18 bg-black pt-2 pb-2 z-40">
|
<div class="fixed w-full h-18 bg-black pt-2 pb-2 z-40">
|
||||||
<div class="middle-pane-big bg-black">
|
<div class="middle-pane-big bg-black">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="flex items-center gap-4 grow">
|
<div class="flex items-center gap-4 grow">
|
||||||
<div class="w-16 py-2">
|
<div class="w-16 py-2">
|
||||||
<a href={data.config.parentUrl} target="_blank"><img src={data.config.logo} alt={data.config.parent} /></a>
|
<a href={data.config.parentUrl} target="_blank"
|
||||||
|
><img src={data.config.logo} alt={data.config.parent} /></a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<!--h1 class="text-2xl uppercase">{data.config.title}</h1-->
|
<!--h1 class="text-2xl uppercase">{data.config.title}</h1-->
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-6 text-xl">
|
<div class="flex items-center gap-6 text-xl">
|
||||||
<button class="md:hidden text-3xl" on:click={(ev) => (navbar = !navbar)}>☰</button>
|
<button class="md:hidden text-3xl" on:click={(ev) => (navbar = !navbar)}>☰</button>
|
||||||
{#each menu.filter(i => !i.hidden) as mi}
|
{#each menu.filter((i) => !i.hidden) as mi}
|
||||||
<div class="hidden md:block">
|
<div class="hidden md:block">
|
||||||
<a class="{mi.class ? mi.class : 'hover:underline'} {choosed && mi.url === choosed[0].url ? 'font-bold underline' : null} {mi.external ? 'external' : ''}" href={mi.url} on:mouseenter={animateText} on:click={!mi.external ? handleAnchorClick : null} target={mi.external ? '_blank' : ''}>
|
<a
|
||||||
|
class="{mi.class ? mi.class : 'hover:underline'} {choosed &&
|
||||||
|
mi.url === choosed[0].url
|
||||||
|
? 'font-bold underline'
|
||||||
|
: null} {mi.external ? 'external' : ''}"
|
||||||
|
href={mi.url}
|
||||||
|
on:mouseenter={animateText}
|
||||||
|
on:click={!mi.external ? handleAnchorClick : null}
|
||||||
|
target={mi.external ? '_blank' : ''}
|
||||||
|
>
|
||||||
{mi.name?.toUpperCase() || mi.title.toUpperCase()}
|
{mi.name?.toUpperCase() || mi.title.toUpperCase()}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -92,24 +102,35 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#if navbar}
|
{#if navbar}
|
||||||
<div class="w-full md:hidden p-4">
|
<div class="w-full md:hidden p-4">
|
||||||
{#each menu.filter(i => !i.hidden) as mi}
|
{#each menu.filter((i) => !i.hidden) as mi}
|
||||||
<div class="my-3 mx-4">
|
<div class="my-3 mx-4">
|
||||||
<a href={mi.url} on:click={() => navbar = false}><button class="{mi.class} uppercase text-xl {mi.external ? 'external' : ''}">{mi.title}</button></a>
|
<a href={mi.url} on:click={() => (navbar = false)}
|
||||||
|
><button class="{mi.class} uppercase text-xl {mi.external ? 'external' : ''}"
|
||||||
|
>{mi.title}</button
|
||||||
|
></a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full h-screen" id="intro">
|
<div class="w-full h-screen" id="intro">
|
||||||
<div class="w-full h-full flex items-center text-center">
|
<div class="w-full h-full flex items-center text-center">
|
||||||
<div class="mx-auto px-4">
|
<div class="mx-auto px-4">
|
||||||
<div class="text-5xl md:text-8xl font-bold mb-4 md:mb-8 animation-crypt" on:mouseenter={animateText}>
|
<div
|
||||||
|
class="text-5xl md:text-8xl font-bold mb-4 md:mb-8 animation-crypt"
|
||||||
|
on:mouseenter={animateText}
|
||||||
|
>
|
||||||
{data.config.shortname.toUpperCase()}
|
{data.config.shortname.toUpperCase()}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-3xl md:text-5xl md:mb-4 uppercase">
|
<div class="text-3xl md:text-5xl md:mb-4 uppercase">
|
||||||
<span class="">{data.config.date}</span> @ <a href={data.config.venueMapUrl} target="_blank" class="underline hover:no-underline">{data.config.venue}</a></div>
|
<span class="">{data.config.date}</span> @
|
||||||
|
<a href={data.config.venueMapUrl} target="_blank" class="underline hover:no-underline"
|
||||||
|
>{data.config.venue}</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
<div class="mt-8 text-lg text-mild mx-4">
|
<div class="mt-8 text-lg text-mild mx-4">
|
||||||
<p class="">{data.config.slogan}</p>
|
<p class="">{data.config.slogan}</p>
|
||||||
<p>
|
<p>
|
||||||
|
@ -132,11 +153,13 @@
|
||||||
<div class="flex gap-4">
|
<div class="flex gap-4">
|
||||||
<div class="grow">
|
<div class="grow">
|
||||||
<div class="w-32 sm:w-40">
|
<div class="w-32 sm:w-40">
|
||||||
<a href={data.config.parentUrl}><img src={data.config.logo} alt={data.config.parent} /></a>
|
<a href={data.config.parentUrl}
|
||||||
|
><img src={data.config.logo} alt={data.config.parent} /></a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<div class="">
|
<div class="" on:mouseenter={animateSection()}>
|
||||||
<a class="inline-block w-5 mr-1" href="https://twitter.com/{data.config.twitter}">
|
<a class="inline-block w-5 mr-1" href="https://twitter.com/{data.config.twitter}">
|
||||||
<svg viewBox="0 0 29 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 29 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path
|
<path
|
||||||
|
@ -145,7 +168,11 @@
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://twitter.com/{data.config.twitter}" class="text-2xl no-underline hover:underline external" target="_blank">
|
<a
|
||||||
|
href="https://twitter.com/{data.config.twitter}"
|
||||||
|
class="text-2xl no-underline hover:underline external animate-section"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
@{data.config.twitter}
|
@{data.config.twitter}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,28 +1,20 @@
|
||||||
<script>
|
<script>
|
||||||
import SvelteMarkdown from 'svelte-markdown';
|
import SvelteMarkdown from 'svelte-markdown';
|
||||||
import PeopleList from '$lib/components/PeopleList.svelte';
|
import PeopleList from '$lib/components/PeopleList.svelte';
|
||||||
import { animateText } from '$lib/helpers';
|
import { animateText, animateSection } from '$lib/helpers';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
function animateSection (interval = 50) {
|
|
||||||
return (el) => {
|
|
||||||
for(const e of el.target.getElementsByClassName('animate-section')) {
|
|
||||||
animateText({ target: e }, interval)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>{data.config.title} | {data.config.date}</title>
|
<title>{data.config.title} | {data.config.date}</title>
|
||||||
<meta name="description" content={data.config.desc} />
|
<meta name="description" content={data.config.desc} />
|
||||||
<meta name="twitter:card" content="summary" />
|
<meta name="twitter:card" content="summary" />
|
||||||
<meta name="twitter:site" content="@{data.config.twitter}" />
|
<meta name="twitter:site" content="@{data.config.twitter}" />
|
||||||
<meta name="twitter:title" content={data.config.title} />
|
<meta name="twitter:title" content={data.config.title} />
|
||||||
<meta name="twitter:description" content={data.config.desc} />
|
<meta name="twitter:description" content={data.config.desc} />
|
||||||
<meta name="twitter:image" content="https://{data.config.domain}{data.config.image}" />
|
<meta name="twitter:image" content="https://{data.config.domain}{data.config.image}" />
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div class="bg-black" id="about">
|
<div class="bg-black" id="about">
|
||||||
|
@ -33,7 +25,10 @@
|
||||||
<div class="section-header" on:mouseenter={animateText}>Key themes</div>
|
<div class="section-header" on:mouseenter={animateText}>Key themes</div>
|
||||||
<div class="grid md:grid-cols-3 gap-4 md:gap-10">
|
<div class="grid md:grid-cols-3 gap-4 md:gap-10">
|
||||||
{#each data.config.themes as ti}
|
{#each data.config.themes as ti}
|
||||||
<div class="bg-[#0d1117] hover:text-black hover:bg-white px-4 py-6 topic-item" on:mouseenter={animateSection(35)}>
|
<div
|
||||||
|
class="bg-[#0d1117] hover:text-black hover:bg-white px-4 py-6 topic-item"
|
||||||
|
on:mouseenter={animateSection(35)}
|
||||||
|
>
|
||||||
<div class="text-2xl animate-section">{ti.title.toUpperCase()}</div>
|
<div class="text-2xl animate-section">{ti.title.toUpperCase()}</div>
|
||||||
<div class="mt-4 text-lg text-mild markdown">
|
<div class="mt-4 text-lg text-mild markdown">
|
||||||
<SvelteMarkdown source={ti.desc} />
|
<SvelteMarkdown source={ti.desc} />
|
||||||
|
@ -76,7 +71,9 @@
|
||||||
<div class="text-lg text-supermild mb-16">{data.config.programNote}</div>
|
<div class="text-lg text-supermild mb-16">{data.config.programNote}</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="program xl:flex gap-10 xl:gap-4">
|
<div class="program xl:flex gap-10 xl:gap-4">
|
||||||
{#each data.config.stages.map(s => ({ ...s, program: data.config.program[s.id]})).filter(s => s.program) as stage}
|
{#each data.config.stages
|
||||||
|
.map((s) => ({ ...s, program: data.config.program[s.id] }))
|
||||||
|
.filter((s) => s.program) as stage}
|
||||||
<div class="w-auto xl:w-1/2 mb-10 xl:mb-0">
|
<div class="w-auto xl:w-1/2 mb-10 xl:mb-0">
|
||||||
<div class="text-3xl font-bold mb-4">{stage.name}</div>
|
<div class="text-3xl font-bold mb-4">{stage.name}</div>
|
||||||
<table class="table-auto table-custom w-full mx-0 lg:mx-8">
|
<table class="table-auto table-custom w-full mx-0 lg:mx-8">
|
||||||
|
@ -90,14 +87,22 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each stage.program as pi}
|
{#each stage.program as pi}
|
||||||
<tr class="" on:mouseenter={animateSection(35)}>
|
<tr class="" on:mouseenter={animateSection(35)}>
|
||||||
<td class="text-right time xl:whitespace-nowrap sm:w-16 xl:w-36 {pi.type==="other" ? 'text-mild' : ''}"
|
<td
|
||||||
|
class="text-right time xl:whitespace-nowrap sm:w-16 xl:w-36 {pi.type === 'other'
|
||||||
|
? 'text-mild'
|
||||||
|
: ''}"
|
||||||
>{@html pi.time
|
>{@html pi.time
|
||||||
.split('-')
|
.split('-')
|
||||||
.map((x) => x)
|
.map((x) => x)
|
||||||
.join('<div class="xl:inline-block hidden mx-1">-</div>')}
|
.join('<div class="xl:inline-block hidden mx-1">-</div>')}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-left">
|
<td class="text-left">
|
||||||
<div class="text-xl"><span class="animate-section {pi.type==="other" ? 'text-mild' : ''}">{pi.title}</span> {pi.speakers ? '― ' + pi.speakers[0]?.name : ''}</div>
|
<div class="text-xl">
|
||||||
|
<span class="animate-section {pi.type === 'other' ? 'text-mild' : ''}"
|
||||||
|
>{pi.title}</span
|
||||||
|
>
|
||||||
|
{pi.speakers ? '― ' + pi.speakers[0]?.name : ''}
|
||||||
|
</div>
|
||||||
{#if pi.desc}
|
{#if pi.desc}
|
||||||
<div class="mt-2 text-base description text-mild markdown">
|
<div class="mt-2 text-base description text-mild markdown">
|
||||||
<SvelteMarkdown source={pi.desc} />
|
<SvelteMarkdown source={pi.desc} />
|
||||||
|
@ -120,8 +125,8 @@
|
||||||
<div>
|
<div>
|
||||||
<a href={data.config.sponsorUrl}
|
<a href={data.config.sponsorUrl}
|
||||||
><button
|
><button
|
||||||
class="py-2 px-5 bg-white text-black hover:bg-black border border-bg-white hover:text-white" on:mouseenter={animateText}
|
class="py-2 px-5 bg-white text-black hover:bg-black border border-bg-white hover:text-white"
|
||||||
>Become a Sponsor</button
|
on:mouseenter={animateText}>Become a Sponsor</button
|
||||||
></a
|
></a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -135,12 +140,19 @@
|
||||||
<div class="grid lg:grid-cols-2 gap-10 md:w-2/3 mx-auto">
|
<div class="grid lg:grid-cols-2 gap-10 md:w-2/3 mx-auto">
|
||||||
{#each data.config.tickets as tt}
|
{#each data.config.tickets as tt}
|
||||||
<div
|
<div
|
||||||
class="bg-[#0d1117] hover:border-0 py-10 px-10 hover:text-black hover:bg-white {data.config.ticketing ? "cursor-pointer" : ""}"
|
class="bg-[#0d1117] hover:border-0 py-10 px-10 hover:text-black hover:bg-white {data
|
||||||
|
.config.ticketing
|
||||||
|
? 'cursor-pointer'
|
||||||
|
: ''}"
|
||||||
on:mouseenter={animateSection(40)}
|
on:mouseenter={animateSection(40)}
|
||||||
on:click={() => data.config.ticketing ? goto(data.config.ticketingUrl) : false}
|
on:click={() => (data.config.ticketing ? goto(data.config.ticketingUrl) : false)}
|
||||||
>
|
>
|
||||||
<div class="text-3xl uppercase"><a href={data.config.ticketingUrl} class="animate-section">{tt.title}</a></div>
|
<div class="text-3xl uppercase">
|
||||||
<div class="text-xl mt-6 font-bold"><a href={data.config.ticketingUrl}>{tt.price}</a></div>
|
<a href={data.config.ticketingUrl} class="animate-section">{tt.title}</a>
|
||||||
|
</div>
|
||||||
|
<div class="text-xl mt-6 font-bold">
|
||||||
|
<a href={data.config.ticketingUrl}>{tt.price}</a>
|
||||||
|
</div>
|
||||||
<ul class="mt-6 text-lg text-left list-disc px-6">
|
<ul class="mt-6 text-lg text-left list-disc px-6">
|
||||||
{#each tt.includes as ti}
|
{#each tt.includes as ti}
|
||||||
<li>{ti}</li>
|
<li>{ti}</li>
|
||||||
|
@ -157,9 +169,12 @@
|
||||||
</div>
|
</div>
|
||||||
{#if data.config.ticketing}
|
{#if data.config.ticketing}
|
||||||
<div class="mt-10">
|
<div class="mt-10">
|
||||||
<a href={data.config.ticketingUrl}><button
|
<a href={data.config.ticketingUrl}
|
||||||
class="py-2 px-5 bg-white text-black hover:bg-black border border-bg-white hover:text-white" on:mouseenter={animateText}
|
><button
|
||||||
>Buy a ticket</button></a>
|
class="py-2 px-5 bg-white text-black hover:bg-black border border-bg-white hover:text-white"
|
||||||
|
on:mouseenter={animateText}>Buy a ticket</button
|
||||||
|
></a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if data.config.ticketsNote}
|
{#if data.config.ticketsNote}
|
||||||
|
|
|
@ -3,8 +3,5 @@ import { defineConfig } from 'vite';
|
||||||
import ViteYaml from '@modyfi/vite-plugin-yaml';
|
import ViteYaml from '@modyfi/vite-plugin-yaml';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [ViteYaml(), sveltekit()]
|
||||||
ViteYaml(),
|
|
||||||
sveltekit()
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue