Merge branch 'main' into text

This commit is contained in:
graham 2024-04-30 19:25:25 -04:00 committed by GitHub
commit 6e47fa3a1d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 382 additions and 79 deletions

View file

@ -40,7 +40,6 @@ export default function RsvpForm() {
<Input
{...useField('address_line_1')}
placeholder="1 Hacker Way"
required
sx={{ border: '1px solid', borderColor: 'muted' }}
/>
</Label>
@ -49,7 +48,6 @@ export default function RsvpForm() {
<Input
{...useField('address_zip')}
placeholder="01337"
required
sx={{ border: '1px solid', borderColor: 'muted' }}
/>
</Label>

View file

@ -0,0 +1,103 @@
import CardModel from './card-model'
import { Box, Flex, Grid, Image, Text } from 'theme-ui'
import Buttons from './button'
/** @jsxImportSource theme-ui */
export default function Apocalypse() {
return (
<CardModel
color="white"
sx={{
backgroundSize: 'cover',
backgroundColor: '#95C9E5'
}}
position={[null, 'bottom', 'bottom']}
image="https://cloud-1132qsbcy-hack-club-bot.vercel.app/0image__6_.png"
>
<Grid columns={[1, 1, 2]} sx={{ position: 'relative', zIndex: 2 }}>
<Flex
sx={{
flexDirection: 'column',
justifyContent: 'space-between'
}}
>
<Image
src="https://cloud-lvxa0tab7-hack-club-bot.vercel.app/0apotitle_cropped.png"
sx={{
width: ['200px', '250px', '300px'],
mt: ['-5px', '-5px', '-5px'],
mb: ['30px', '30px', '30px'],
position: 'relative',
zIndex: 2,
fontSize: ['36px', 4, 5],
color: 'white'
}}
alt="Apocalypse"
/>
<Flex
sx={{
flexDirection: ['row', 'row', 'column'],
justifyContent: 'space-between'
}}
>
<Text
as="p"
variant="subheadline"
sx={{
ml: ['0px', '0px', '10px'],
mt: ['0px', '0px', '-10px'],
mb: ['0px', '0px', '20px'],
zIndex: 2,
color: 'white',
fontSize: ['24px !important'],
textShadow: '0 0 20px #fbbae4'
}}
>
Downtown Toronto
<br />
May 1719
</Text>
<Buttons
icon="flag-fill"
href="https://apocalypse.hackclub.com/"
target="_blank"
rel="noopener"
primary="#FE5CA8"
id="43"
sx={{ color: '#fff' }}
>
Join Us
</Buttons>
</Flex>
</Flex>
<Box>
<Text
as="p"
variant="subtitle"
sx={{
fontSize: ['22px', '20px', '18px']
}}
>
It's 2034, and zombies have taken over! But tech still operates.
What would you do?
</Text>
<Text
as="p"
variant="subtitle"
sx={{
fontSize: ['22px', '20px', '18px']
}}
>
Join 150 high schoolers for 44 hours at Apocalypse! Take yourself
out of the real world and build wacky projects to spark a new age of
humanity.
</Text>
</Box>
</Grid>
</CardModel>
)
}

View file

@ -159,7 +159,7 @@ function Game({ game, gameImage, gameImage1, ...props }) {
mb: 1
}}
>
<RelativeTime value={game['added on']} titleFormat="YYYY-MM-DD" />
<RelativeTime value={game['addedOn']} titleFormat="YYYY-MM-DD" />
</Text>
</Box>
</Box>
@ -257,7 +257,7 @@ export default function Sprig({ stars, game, gameImage, gameImage1 }) {
>
<Game
game={game[0]}
// gameImage={gameImage}
// gameImage={gameImage}
/>
<Game
game={game[1]}

View file

@ -2,7 +2,7 @@ const projects = [
{
title: 'Brainwave device for thought-based computer interaction.',
description:
'The team of teens behind BCI is building both the hardware and software for a brainwave reading device to interact with computers using thoughts',
'The team of teens behind Monolith BCI is building both the hardware and software for a brainwave reading device to interact with computers using thoughts',
img: 'bci',
color: ['#ec3750', '#F58695'],
itemId: 0

View file

@ -185,6 +185,11 @@ const nextConfig = {
source: '/daysofservice/',
destination: 'https://daysofservice.hackclub.com',
permanent: true
},
{
source: '/blot/',
destination: 'https://blot.hackclub.com',
permanent: false
}
]
},

View file

@ -12,7 +12,7 @@
"format": "prettier --write ."
},
"dependencies": {
"@apollo/client": "^3.9.9",
"@apollo/client": "^3.9.11",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@github/time-elements": "^4.0.0",
@ -25,18 +25,19 @@
"@octokit/auth-app": "^6.0.1",
"@octokit/core": "^5.1.0",
"@octokit/rest": "^20.0.2",
"@sendgrid/mail": "^8.1.1",
"@tracespace/core": "^5.0.0-alpha.0",
"@tracespace/identify-layers": "^5.0.0-alpha.0",
"@tracespace/parser": "^5.0.0-next.0",
"@tracespace/plotter": "^5.0.0-alpha.0",
"@tracespace/renderer": "^5.0.0-alpha.0",
"@tracespace/xml-id": "^4.2.7",
"@sendgrid/mail": "^8.1.1",
"add": "^2.0.6",
"airtable-plus": "^1.0.4",
"animated-value": "^0.2.4",
"animejs": "^3.2.2",
"axios": "^1.6.7",
"camelcase": "^8.0.0",
"cookies-next": "^4.0.0",
"country-list": "^2.3.0",
"country-list-js": "^3.1.8",
@ -74,7 +75,8 @@
"react-ticker": "^1.3.2",
"react-tooltip": "^4.5.1",
"react-tsparticles": "^2.12.2",
"react-use-websocket": "^4.7.0",
"react-type-animation": "^3.2.0",
"react-use-websocket": "^4.8.1",
"react-wrap-balancer": "^1.1.0",
"recharts": "2.12.2",
"remark": "^15.0.1",

104
pages/api/bin/wokwi/new.js Normal file
View file

@ -0,0 +1,104 @@
import AirtablePlus from "airtable-plus"
const createProject = async (partsList=[]) => {
const airtable = new AirtablePlus({
apiKey: process.env.AIRTABLE_API_KEY,
baseID: 'appKjALSnOoA0EmPk',
tableName: 'Supported Parts'
})
const parts = [
{ "type": "board-pi-pico-w", "id": "pico", "top": 0, "left": 0, "attrs": {} }
]
await Promise.all(partsList.map(async (part) => {
const airPart = await airtable.read({
filterByFormula: `{Wokwi Name}= "${part}"`,
maxRecords: 1
})
return airPart[0].fields['Wokwi Name'].split(',').forEach((name, i) => {
parts.push({
type: name,
id: name + '-' + i,
left: i * 100, // this is roughtly the width of most parts
})
})
}))
const body = JSON.stringify({
name: "The Bin!",
unlisted: false,
files: [{
name: "help.md",
content: `# Welcome to The Bin! 🦝
Now that you've thrown some parts into The Bin, it's time to turn that trash into treasure! 🗑💎
Wire up your parts and write some code to make them work together.
If you'd like a tutorial, check out some sample projects:
https://jams.hackclub.com/tags/the-bin
You can get help by chatting with other high schoolers on the Hack Club Slack in the #electronics channel:
👉 https://hackclub.com/slack 👈
Once you're ready build your design IRL, click the "Share" button and submit your design:
https://hackclub.com/bin/submit
`
},
{
name: "sketch.ino",
content: `// Now turn this trash into treasure!
// Want some help? You can chat with us on the Hack Club Slack in the #electronics channel
void setup() {
// put your setup code here, to run once:
Serial1.begin(115200);
Serial1.println("Hello, Raspberry Pi Pico W!");
}
void loop() {
// put your main code here, to run repeatedly:
delay(1); // this speeds up the simulation
}`
}, {
name: "diagram.json",
content: JSON.stringify({
"version": 1,
"author": "The Bin - Hack Club",
"editor": "wokwi",
"parts": parts,
"connections": [["pico:GP0", "$serialMonitor:RX", "", []], ["pico:GP1", "$serialMonitor:TX", "", []]], "dependencies": {}
}, null, 2)
}],
})
const response = await fetch('https://wokwi.com/api/projects/save', {
method: 'POST',
cors: 'no-cors',
headers: {
'Content-Type': 'application/json',
'Referer': 'https://wokwi.com/projects/new/pi-pico-w',
'User-Agent': 'Hack Club - contact max@hackclub.com for any complaints!'
},
body
}).catch((e) => {
console.log(e)
})
const data = await response.json()
const { projectId } = data
return `https://wokwi.com/projects/${projectId}`
}
export default async function handler(req, res) {
if (req.method === 'POST') {
const { parts } = req.body
const shareLink = await createProject(parts)
if (shareLink) {
res.status(200).json({ shareLink })
} else {
res.status(500).json({ error: 'Failed to create project' })
}
}
}

View file

@ -0,0 +1,29 @@
import AirtablePlus from "airtable-plus"
import camelcase from "camelcase"
const camelizeObject = (obj) => {
Object.keys(obj).forEach(key => {
obj[camelcase(key)] = obj[key]
if (key !== camelcase(key)) {
delete obj[key]
}
})
return obj
}
const wokwiParts = async () => {
const airtable = new AirtablePlus({
apiKey: process.env.AIRTABLE_API_KEY,
baseID: 'appKjALSnOoA0EmPk',
tableName: 'Supported Parts'
})
const records = await airtable.read()
const parts = records.map(record => camelizeObject(record.fields))
return parts
}
export default async function handler(req, res) {
const data = await wokwiParts()
res.status(200).json(data)
}

View file

@ -1,10 +1,7 @@
export async function getGames() {
let games = await fetch(
'https://raw.githubusercontent.com/hackclub/sprig/main/games/metadata.json'
'https://sprig.hackclub.com/api/gallery?new'
).then(res => res.json())
games = games
.sort((a, b) => new Date(b.addedOn) - new Date(a.addedOn))
.slice(-4)
return games
}

View file

@ -10,11 +10,18 @@ export const getAllOnboardProjects = async () => {
}
}
const res = await fetch(url, fetchOptions).then(r => r.json())
let res;
try { res = await fetch(url, fetchOptions).then(r => r.json()) }
catch (e) {
console.error('Failed to fetch projects from GitHub', e)
return []
}
if (res.message && res.message.startsWith('API rate limit exceeded')) {
console.error('GitHub API rate limit exceeded')
return []
}
if(!res) return []
const projects = []

View file

@ -23,9 +23,10 @@ import JSConfetti from 'js-confetti'
import Sparkles from '../components/sparkles'
import Icon from "@hackclub/icons"
import Announcement from '../components/announcement'
import { TypeAnimation } from 'react-type-animation'
const RsvpCount = () => {
const targetRSVPs = 200
const targetRSVPs = 500
const [rsvpCount, setRsvpCount] = useState(0)
useEffect(async () => {
// const url = 'https://api2.hackclub.com/v0.1/The Bin/rsvp' <- switch to this once we have api2 back up and running
@ -154,11 +155,19 @@ function crunch() {
audio.play()
}
const ExpiresAt = ({ children, expirationDate = new Date() - 1 }) => {
console.log(expirationDate, new Date())
if (expirationDate > new Date()) {
return children
} else {
return null
}
}
function spinIt(el) {
el.classList.add("spin");
setTimeout(() => el.classList.remove("spin"), 500);
}
export default function Bin() {
const confettiInstance = useRef(null);
function fireConfetti() {
@ -182,21 +191,20 @@ export default function Bin() {
<Box sx={{ background: 'url(https://cloud-jxq5r0yyp-hack-club-bot.vercel.app/0bg.png)', backgroundSize: 'cover', py: '3em' }}>
<Container sx={{ position: 'relative' }}>
<Box as="section" sx={{ textAlign: 'center', pt: '4em', overflow: 'hidden' }}>
<ExpiresAt expirationDate={new Date(2024, 3, 13)}>
<Box sx={{ mt: 3 }}>
<Announcement
copy="Please pardon our dust!"
caption="You found us a little early! We're still building this page, but you can RSVP early."
iconLeft="welcome"
/>
</Box>
</ExpiresAt>
<Box sx={{
'@media (prefers-reduced-motion: no-preference)': {
animation: `${wobble} 0.5s ease-in-out infinite alternate`
// animation: `${spin} 2.5s linear infinite`
},
}}>
<Image
src="https://cloud-mt5wqf6f5-hack-club-bot.vercel.app/0rummaging.png"
onClick={(e) => { fireConfetti(); crunch(); spinIt(e.target) }}
@ -210,23 +218,6 @@ export default function Bin() {
}
}}
/>
{/* <Heading
as="h1"
variant="ultratitle"
py={3}
onClick={() => fireConfetti()}
sx={{
fontSize: '6em',
display: 'inline-block',
cursor: 'pointer',
':active': {
animation: `${bounce} 0.125s`
},
}}
>
🗑
</Heading> */}
</Box>
<br />
<RsvpCount />
@ -235,24 +226,47 @@ export default function Bin() {
<Image src="https://cloud-rdlz8he4l-hack-club-bot.vercel.app/0thebin.svg" sx={{ maxWidth: '250px' }} />
</Sparkles>
</Box>
{/* <Heading as="h1" variant="ultratitle" py={3}>
<Sparkles size={10}>
The Bin
</Sparkles>
</Heading> */}
<Text sx={{ fontWeight: 'bold' }}>
An electronics starter kit, customized for <em>your</em>&nbsp;project
Build{' '}
<em>
<TypeAnimation
cursor={false}
sequence={[
// Same substring at the start will only be typed out once, initially
'a laser guided nerf gun',
1000, // wait 1s before replacing "Mice" with "Hamsters"
'a clap activated lamp',
1000,
'a temperature activated Febreze can',
1000,
'a flame actuated speaker',
1000,
'a light dependant door',
1000
]}
repeat={Infinity}
/>
</em>
{' '}
with parts you pick out.
<br />
Free for high schoolers.
{/* with all the parts bought for you */}
{/* An electronics starter kit, customized for <em>your</em>&nbsp;project */}
</Text>
</Box>
<Box as="section" sx={{ textAlign: 'center' }}>
<Fade up delay={100}>
<Card sx={{ p: 3, mt: 4, mx: 'auto', maxWidth: '50ch' }}>
<Text as="p" sx={{ mb: 1, mt: 0, textWrap: 'balance', fontSize: 2 }}>
High schoolers can get a kit of electronics parts for free to
build their first project.
<Text as="p" sx={{ mb: 1, mt: 0, textWrap: 'pretty', fontSize: 2 }}>
Running for only 2 months.
{/* High schoolers can RSVP now! */}
{/* High schoolers can get a kit of electronics parts for free to
build their first project. */}
</Text>
<Text as="p" sx={{ color: 'muted', mb: 2, fontSize: 2, fontWeight: 800 }}>
RSVP to get notified when applications open.
RSVP to get notified when orders&nbsp;open.
</Text>
<RsvpForm />
</Card>

View file

@ -117,6 +117,33 @@ export default function Apply() {
})
}
>
<Box
sx={{
borderLeft: '3px solid',
borderLeftColor: 'blue',
paddingLeft: 2,
color: 'blue',
fontSize: [1, 2],
textWrap: 'pretty',
lineHeight: 1.375
}}
>
<Text as="p" sx={{ fontSize: [2, 3], fontWeight: 'bold' }}>
Join our waitlist
</Text>
<Text as="p" sx={{ mt: 1, textWrap: 'balance' }}>
HCB has been experiencing some exciting growth and subsequent
capacity constraints. We are prioritizing organizations ran by Hack
Clubbers, teens, FIRST teams, as well as groups with an annual
budget greater than $50k. Please expect to hear back by May 1st,
2024.
</Text>
<Text as="p" sx={{ mt: 1, textWrap: 'balance' }}>
We currently do not work with new organizations outside of STEM,
Education, and Climate.
</Text>
</Box>
<Heading as="h2" variant="headline" sx={{ mb: -2 }}>
Your organization
</Heading>

View file

@ -51,24 +51,13 @@ export default function ApplicationSuccess() {
</Text>
<Text as="p" variant="lead">
<Balancer>
Well review your application and get back to you within two
business days.
We are prioritizing organizations ran by Hack Clubbers, teens, FIRST
teams, as well as groups with an annual budget greater than $50k. If
you fall outside of these categories, you will hear back from us by
May 1st, 2024.
</Balancer>
</Text>
</header>
<footer>
<Text as="h2" variant="subheadline">
Questions about your application?
</Text>
<Text as="p" fontSize={2} color="muted">
You can always email us at{' '}
<Link href="mailto:hcb@hackclub.com" color="blue">
hcb@hackclub.com
</Link>
.
</Text>
</footer>
</Container>
)
}

View file

@ -241,10 +241,11 @@ export default function Page() {
sx={{
bg: 'blue',
backgroundImage: theme => theme.util.gx('cyan', 'blue'),
fontSize: [16, 16, 32],
lineHeight: 0.9
}}
>
Apply now
Join the waitlist
</Button>
</Link>
<Button
@ -603,15 +604,15 @@ export default function Page() {
bg: 'white',
mixBlendMode: 'screen',
color: 'black !important',
fontSize: [58, 96],
fontSize: [36, 64],
width: ['100%', 'auto'],
py: 4,
px: [4, null, 6],
px: [4, null, 5],
lineHeight: 0.9,
textTransform: 'none'
}}
>
Apply now
Join the waitlist
</Button>
</Link>
<Text as="p" variant="lead" sx={{ color: 'white', mb: [0, 0] }}>

View file

@ -40,6 +40,7 @@ import Photo from '../components/photo'
import Comma from '../components/comma'
import Haxidraw from '../components/index/cards/haxidraw'
import Onboard from '../components/index/cards/onboard'
import Apocalypse from '../components/index/cards/apocalypse'
/** @jsxImportSource theme-ui */
@ -203,10 +204,10 @@ function Page({
gradient="linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.45))"
/>
<Announcement
copy="Hop OnBoard and create your first PCB"
caption="Join 1,000 others to create your first circuit board."
href="https://hackclub.com/onboard/"
iconLeft="idea"
copy="Get free boba for making your first website! 🍵"
caption="Follow the tutorial to build your own space on the web."
href="https://workshops.hackclub.com/personal_website"
iconLeft="web"
/>
<Box
sx={{
@ -675,6 +676,7 @@ function Page({
</Text>
</Box>
<Pizza />
<Apocalypse />
<Slack slackKey={slackKey} data={slackData} events={events} />
</Box>
</Box>

View file

@ -141,7 +141,7 @@ const SlackPage = () => {
person="JC"
img="https://ca.slack-edge.com/T0266FRGM-U03MNFDRSGJ-e6fb939acfd8-512"
age={17}
location="CT"
location="MA"
/>
<Quote
text="Finally, I found my people!"

View file

@ -301,6 +301,13 @@ export default function Team({ team }) {
img="/team/ced.png"
pronouns="he/him"
/>
<Bio
name="Kara Massie"
teamRole="Production Lead"
text="Before joining Hack Club, Kara was a lead producer at Activision, shipping Crash Bandicoot N. Sane Trilogy and Bungie's Destiny 2 expansions. Shes deeply committed to inclusivity in gaming and tech spaces, and is beyond thrilled to be part of an org with kindness at its core. She has lived in 3 countries and names her pets after vegetables."
img="/team/kara.png"
pronouns="she/her"
/>
<Bio
name="Sam Poder"
teamRole="Engineering & Operations"

View file

@ -15,10 +15,10 @@
"@jridgewell/gen-mapping" "^0.3.0"
"@jridgewell/trace-mapping" "^0.3.9"
"@apollo/client@^3.9.9":
version "3.9.9"
resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.9.9.tgz#38f983a1ad24e2687abfced0a9c1c3bef8d32616"
integrity sha512-/sMecU/M0WK9knrguts1lSLV8xFKzIgOMVb4mi6MOxgJXjliDB8PvOtmXhTqh2cVMMR4TzXgOnb+af/690zlQw==
"@apollo/client@^3.9.11":
version "3.9.11"
resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.9.11.tgz#737e5c35c21d6f3b78423033ad81837a8a6992e0"
integrity sha512-H7e9m7cRcFO93tokwzqrsbnfKorkpV24xU30hFH5u2g6B+c1DMo/ouyF/YrBPdrTzqxQCjTUmds/FLmJ7626GA==
dependencies:
"@graphql-typed-document-node/core" "^3.1.1"
"@wry/caches" "^1.0.0"
@ -3216,6 +3216,11 @@ camelcase@^5.3.1:
resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
camelcase@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-8.0.0.tgz#c0d36d418753fb6ad9c5e0437579745c1c14a534"
integrity sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==
camelize@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3"
@ -7497,10 +7502,15 @@ react-tsparticles@^2.12.2:
dependencies:
tsparticles-engine "^2.12.0"
react-use-websocket@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/react-use-websocket/-/react-use-websocket-4.7.0.tgz#e45545ed48eb60171bf6401d1884cc80c700a0ea"
integrity sha512-YjR62jB7vB94IZy5UPBGZSR3c0hxu796q9IuJ0vbNg7InJ7Z84NHOd/LHzVI5nAKtaGy1oqvf8EmjKxX+cNz4A==
react-type-animation@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/react-type-animation/-/react-type-animation-3.2.0.tgz#6863d5d60e3beb237f2bd690cceb585402c47e6a"
integrity sha512-WXTe0i3rRNKjmggPvT5ntye1QBt0ATGbijeW6V3cQe2W0jaMABXXlPPEdtofnS9tM7wSRHchEvI9SUw+0kUohw==
react-use-websocket@^4.8.1:
version "4.8.1"
resolved "https://registry.yarnpkg.com/react-use-websocket/-/react-use-websocket-4.8.1.tgz#be06a0bc956c6d56391a29cbe2caa6ae8edb5615"
integrity sha512-FTXuG5O+LFozmu1BRfrzl7UIQngECvGJmL7BHsK4TYXuVt+mCizVA8lT0hGSIF0Z0TedF7bOo1nRzOUdginhDw==
react-wrap-balancer@^1.1.0:
version "1.1.0"
@ -8234,8 +8244,16 @@ string-hash@1.1.3:
resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
integrity sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
name string-width-cjs
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string-width@^4.1.0:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==