#🪅-progaming

1 messages · Page 88 of 1

deep mulch
#

the kode tode

supple whale
#

is this actually useful?

#

i usually just do if (!('somekey' in value)) return

royal nymph
#

like a discord message

#

if it comes from anywhere, things like msg.guild, msg.channel etc can differ

#

so you have to manually check all those members

#

you can instead do like

isInGuildChannel() this is GuildChannelMessage {
    return this.guild !== null;
}
#
if (msg.isInGuildChannel()) {
    msg.channel // typed correctly
    msg.guild // typed non null
} else if (msg.isInDm()) {
    msg.channel // DMChannel
    msg.guild // null
}
#

nicer alternative to manual casting

ionic lake
#

isVen() this is Ven {
return this.person.kind === 'cute';
}

supple whale
#

does the same tho?

royal nymph
#

way uglier and not as powerful :P

#

you can have way more advanced assertions

valid jetty
#
function isCute(): this is Cute {
    return this.message.reader === 'you';
}
supple whale
#

TS infers that the msg is a GuildChannelMessage, and you dont need and TS specific syntax

cobalt ledge
#

Can you patch the content in /assets?

fleet cedar
#

Yes, that's where the webpack is

valid jetty
#

yeah level 5 devs make a lot of syntax errors

#

nvm its not

#

but why is he casting a nullptr to a function that returns void

hoary sluice
deep mulch
#

@valid jetty I will cast you to a void pointer

valid jetty
#

void(*x)(int) is a function signature in C

#

void(*)() is a signature that takes no args and returns void

#

theyre casting 0 to that, then inline-calling it

deep mulch
#

@valid jetty find my pointers

hoary sluice
valid jetty
#

though the result is the same

valid jetty
#

yeah, a segfault

fleet cedar
#

Casting 0 to a pointer, whether void or void(), is no problem; it doesn't break until you dereference/call it

hoary sluice
fleet cedar
#

Do you?

jade stone
#

afaik thats 100% possible

winged mantle
#

how

hoary sluice
#

@valid jetty lol thats like 80% of the project

valid jetty
#

lmfao

deep mulch
#

@valid jetty hiii

valid jetty
#

@deep mulch minklang

hoary sluice
#

with pedantic clippy

#

altho yea this was a clippy lint

valid jetty
#

LMAO

deep mulch
hoary sluice
valid jetty
#

what

hoary sluice
#

oh i didnt show the commit msg

#

refactor: fix module inception

valid jetty
#

yeah no i do

#

i personally dont mind that pattern

hoary sluice
hoary sluice
valid jetty
#

lmao yeah

hoary sluice
#
lexer/mod.rs
mod lexer;
#

this does not need to be its own file

valid jetty
hoary sluice
#

i think so, but theres no need to put the lexer into lexer.rs and use it in mod.rs when it can go into mod.rs

valid jetty
#

or just

// lexer/mod.rs
mod lexer;
use lexer;
hoary sluice
#

u mean pub use?

valid jetty
#

yeah

hoary sluice
#

this is what i had

#

whats the point

valid jetty
#

organization

hoary sluice
deep mulch
#

@valid jetty rewrite Elle

valid jetty
#

eventually i will

hoary sluice
#

this is why i have stayed on approx the same loc for months

valid jetty
#

i wanna make the lexer return an iterator lmao

#

so i can do what i did in いちご

hoary sluice
#

rewrite lexer and parser in elle

valid jetty
#

oh great my zed broke again because i ran out of storage

#

fuck this stupid 256gb ssd size

hoary sluice
#

macbook:

valid jetty
#

ok well whatever

#
fn Lexer::iter(Lexer self) -> Iterator<Token, Lexer, SingleEnded> {
    return Iterator {
        env = Box::new(self),
        next = Lexer::next_token,
        next_back = nil
    };
}
``` i did this in いちご
#

the lexer is the Env

hoary sluice
#

rewrite lexer and parser in elle

valid jetty
#

then in main you literally do this

tokens := Lexer::new(args[0]).iter().collect();
#

this is it

valid jetty
#

but that means serializing the AST into some form the rust needs to read

#

for codegen

#

im not doing codegen in elle

hoary sluice
#

or maybe a framework

hoary sluice
valid jetty
#

possible but slightly annoying

#

idk what to tell you but this code so clean

use std/prelude;

use lexer/lexer;
use parser/parser;
use compiler/compiler;

fn main(string[] args) {
    program := args.remove(0).expect("プログラム");
    file := args.remove(0).expect("使い方: {} file.igo\n".format(program));

    tokens := Lexer::new(file).iter().collect();
    tree := Parser::new(tokens).parse();
    module := Compiler::new(tree).compile();

    io::write_to_file(file.replace("igo", "ssa"), "{}".format(module));
}
winged mantle
#

it feels scary that unicode works without jumping through hoops

deep mulch
#

I can't even pronounce that

valid jetty
#

it may be able to be put inside strings but you cant manipulate those strings

#

its an array of bytes not an array of utf8 chars

hoary sluice
valid jetty
#

i wrote a custom utf8 lib for working with utf8 here

deep mulch
#

everyone here speaks English so just send the English name

valid jetty
# deep mulch everyone here speaks English so just send the English name
関数 同一(整数 値)『
    返す 値。
』

関数 気持ち()『
    返す 「大好き〜」。
』

関数 メイン()『
    ※これはコメントです
    整数 フウ = 同一(39)。
    文字列 バル = 気持ち()。
    プリント(「%dが%s:3\n」、フウ、バル)。
    プット(「彼女は「にゃ〜」と言ったの」)。
』
deep mulch
#

you are addicted I think

valid jetty
#

no

deep mulch
#

yes

valid jetty
#

the point is that the language is supposed to be fully jp

deep mulch
nimble bone
#

everyone knows what it means

valid jetty
#

yeah smh

lavish cloud
#

I figured out how to notifications blobfoxcomfy

deep mulch
lavish cloud
#

Hihi zoot

#

I made a website in compose the other day

#

wbu

deep mulch
#

hi

#

I am rewriting an app to use compose

lavish cloud
#

Ooo

shrewd canopy
#

I am considering to make site in C++ with Qt

lavish cloud
#

I should make a mobile app for my site but idk how to do webview content stuff

lavish cloud
deep mulch
lavish cloud
#

Oh yeah look at that

#

Qt for WASM

royal nymph
deep mulch
#

there's no ui

royal nymph
deep mulch
frosty obsidian
#

tui dashboard for minkinator

deep mulch
#

guhh

barren nacelle
#

guy

#

guys

#

i joined this server soully to say i added an extra intensity to party mode

#

i fittingly named it lord and boy is it a mess

lavish cloud
fleet cedar
lavish cloud
#

Cursed

pulsar elk
ionic lake
#

I used ink and it was so painful

#

Yoga is just bog slow and huge

#

You're better off using rust and ratatui

formal belfry
#

This looks like garbage lol

dense sand
#

is there anyone who can help me with writing revanced fingerprint?

#

cause like my fingerprint is failing to be found

fleet cedar
#

Look on the nearest polished glass surface

ionic lake
#

probably ask in the revanced server

dense sand
#

ugh...

valid jetty
#

this is just a terrible idea

#

oh my god stop trying to put react in everything 😭

#

bloat central

#

top 3 ink users are ai slop

#

should give an idea of what kind of tool this is

fleet cedar
#

React is probably easier to vibe code, makes sense that vibe coding tools would want to use it

valid jetty
#

true

fleet cedar
#

Rewrite react in react

balmy lintel
#

my internet so bad it showed the message twice but it sent only once

#

now it deleted both messages

pulsar elk
#

how the fuck do i access the battery % and battery life/metrics

#

losing it

fleet cedar
#

On what platform

#

/sys/class/power_supply/BAT0 on linux

royal nymph
fleet cedar
#

But "everything is a file" is like, linux's slogan

hoary sluice
#

@valid jetty never use rust and docker on a raspi

deep mulch
#

/dev/vee

hoary sluice
#

building my voice assistant takes 20 minutes

deep mulch
#

@royal nymph i will make vee file

hoary sluice
#

3k loc 300 deps

deep mulch
#

every time im in my documents folder the prompt has one leading space and its driving me insane

#

its only the documents folder

valid jetty
dense sand
ionic lake
#

every language has a dependency problem tbf

#

only if you're disciplined then you wouldn't have so many deps

fleet cedar
#

Resisting NIH is what takes discipline

#

More deps means more code you didn't have to waste time rewriting a worse copy of

winged mantle
#

you do NOT need 300 deps

shrewd canopy
ionic lake
#

most of the time you could just take the code and fit in your codebase or simplify it

winged mantle
#

I once used a random timestamp formatting library from npm

#

it seemed more complicated to get it to work how i wanted than just writing it myself

ionic lake
#

you can add deps, but to some degree that the dep itself doesn't do beyond what it needs to do for its job

winged mantle
#

I feel like there's nothing inherently wrong with doing things which have been done before

#

i think as a rule of thumb the one time where you mostly should be using a library is when you need something that implements a specification like http or json

nimble bone
#

i should rewrite apprev to only use the node WebSocket

#

and try going zero dependency

#

tbf it sounds easy it already hooks into the gateway for 99% of what it does

#

dependencies": {
"esbuild": "^0.25.3",
"oceanic.js": "^1.12.0",
"sqlite": "^5.1.1",
"sqlite3": "^5.1.7",
"tsx": "^4.19.4",
"typescript": "^5.8.3"
},

winged mantle
#

or I guess a better way to say that is the one time you're mostly foolish for not using a library is when you need something which implements a specification

nimble bone
#

should i try implementing sqlite @winged mantle

#

or i go back to Json database and state object

winged mantle
#

it does io on every call blobcatcozy

nimble bone
#

do i need to have a state in the state

#

to store itself

#

making a class soon

winged mantle
#

why not

  • make writing add to a queue of promises
  • instead of reading on get, make it read when the file changes asyncrounously
serene elk
hoary sluice
#

its the docker and raspi

hoary sluice
hoary sluice
dense sand
#

Its a raspi, what did u expect

hoary sluice
#

exactly this

hoary sluice
#

it takes 3 mins cargo clean & release on my laptop and a few secs normally

#

but it needs to clean build every run in docker

hoary sluice
hoary sluice
#

by 300 im obviously including nested deps, they dont disappear just cause u didnt declare them as deps

winged mantle
#

don't use rust

#

use java

hoary sluice
#

please tell me how to rewrite this in java with less deps

winged mantle
#

copy all of the deps into your source tree

fleet cedar
#

Vendoring doesn't make you have less deps

#

It just makes managing them more painful

hoary sluice
winged mantle
#

at least you can say technically you have no deps if you instead plagiarise all of them

hoary sluice
#

besides being a pain to use

hoary sluice
ionic lake
#

you could narrow down to just the methods you need but doesn't work all rhe time

winged mantle
#

(don't do this)

fleet cedar
hoary sluice
fleet cedar
#

After cargo clean

winged mantle
#

i have worked on a 0 dep java project before

hoary sluice
#

oh

fleet cedar
#

(Nevermind that cargo clean doesn't delete download caches)

winged mantle
#

hand rolled json parsing

hoary sluice
#

idc but in docker its always clean

fleet cedar
#

Unless you configure your docker right, yeah

hoary sluice
hoary sluice
winged mantle
pearl stagBOT
winged mantle
#

this was so much fun

hoary sluice
winged mantle
#

i first tried to write my own base64 implementation

hoary sluice
#

could only get it to run inside debian docker, now i need it on alpine

#

cant imagine how it was like to use a computer before 2010

winged mantle
hoary sluice
#

this raspi wouldve been state of the art in 2010

winged mantle
#

The Unyivewsaw Opewating System

#

for lesbians

ionic lake
#

she worked on a prism?

formal belfry
#

she worked on a prism?

winged mantle
#

i am right now

formal belfry
#

how

#

I will make a launcher in swift one day

winged mantle
#

swiftie launcher

placid cape
#

give me name suggestions for my voice assistant

fleet cedar
#

Jim

placid cape
#

thx

placid cape
#

and i didn't know about porcupine

crimson sparrow
#

I thought the whole point of Rust was to make every project a supply chain attack nightmare

frosty obsidian
#

you're thinking of javascript

crimson sparrow
valid jetty
#

that many projects use

#

wait

crimson sparrow
#

:)

valid jetty
#

yeah rust has almost no downloads on those kinds of crates

#

supply chain attacks cant happen if people arent stupid

#

as well as, the fact that js has so many fucking packages means ai is very likely to hallucinate js deps, unlike rust which has far less

#

supply chain attacks are only a nightmare in js land

placid cape
#

and polyfill hell

#
valid jetty
#

yea literally

placid cape
#

93 milion downloads

royal nymph
#

lol criticising js for its dependencies while the average rust project uses 150 crates

placid cape
#

thats true

valid jetty
#

rust devs love to boast about how low their dep count is, unlike js devs who just pnpm i everything lol

deep mulch
#

@valid jetty will Elle have built in is even

#

@valid jetty elle_modules

#

make it work identically to npm

valid jetty
deep mulch
#

Int.isEven()

valid jetty
deep mulch
#

yop

#

eagley uses massive if else tree

#

up to 1000

valid jetty
#

if i make enough progress elle could genuinely be usable for aoc (i’m not participating anyway)

#

but i have arrays, iterators, gc, i can add deque and a networking library and stuff

#

it would genuinely be kinda usable

royal nymph
#

both use way too many dependencies for random shit

#

js devs using 150 dependencies: loool lazy js devs just pnpm i anything and have huge supply chain attacks

rust devs using 150 dependencies: actually I am very conservative I just like sharing logic with other highly educated rust developers. rust developers aren't stupid (unlike js devs... ugh) so supply chain attacks can't happen

#

you're sounding so pretentious lmao

#

yes those js packages like is-number is-odd etc are laughable and terrible and I wish people would stop using them but

  1. no one is denying this fact
  2. rust is literally no better in this regard
  3. actually most people don't use these packages, it's just that the authors of these libraries have infested the community so much and getting these shitty packages added as indirect dependencies to major packages like express, that's why they're so popular
winged mantle
#

pretentious people write variable names in french

royal nymph
#

it's literally no different in rust lol

#

no one installs 150 crates

you install 5 crates and those 5 crates pull in 10 other crates that themselves pull in 20 other crates and so on

winged mantle
royal nymph
#

without looking at those deps (maybe there's bs deps), torrent is so complex it is probably warranted

supple whale
#

nah

#

most if is BS

#

like node-datachannel which uses prebuild install

#

because it has native code

#

and that has a gazilion deps

royal nymph
#

i looked and yeah there's a lot of bullshit

supple whale
#

execa is quite a bit of bloat too

#

rest is all kinda required

royal nymph
#

sindre is the king of bloat

#

idk why he has as many sponsors as he does

supple whale
#

first 2 depth shit is all 100% required

#

actually even first 3 depth

#

all this is non bloat

#

the stuff after it is bloat

#

i maintain all that shit btw

#

hell, half of it is mine XD

#

wait wtf that doesnt include the entire tree

#

yeah it omitted a bunch of deps

#

bad website

jade stone
winged mantle
#

am I a noob

#

my other more complicated project has even less

#

what the hell... another project i checked which is not mine

placid cape
spark tiger
#

this sounds like an extremely fucking dumb question, but uh how would one learn how to actually build sites? like i don't need to learn html or css basics or hundred tags/styles/etc. but rather how to actually make a good site optimized for small screens, mobile and all that stuff

valid jetty
winged mantle
median root
#

id just pick 1 and stick with it

royal nymph
#

you just gotta learn best practices

spark tiger
winged mantle
spark tiger
royal nymph
#

like using the right units (em/rem is very good)
using the right tools for building layouts (flex and grid, avoid float or magic numbers)

royal nymph
#

media queries are essentially css if statements

spark tiger
royal nymph
winged mantle
#

if you watch all of theo's videos you'll be a webdev genius

royal nymph
#
@media (max-width: 700px) {
}
spark tiger
median root
royal nymph
#

obviously if you use magic numbers (width: 432px) yeah it's a pain

spark tiger
#

i mean for each resolution

royal nymph
#
.my-card-grid {
  --columns: 3;
  display: grid;
  grid-template-columns: repeat(var(--columns), 1fr);
}

@media (max-width: 1000px) {
    .my-card-grid {
        --columns: 2;
    }
}

@media (max-width: 600px) {
    .my-card-grid {
        --columns: 1;
    }
}
#

simple example

spark tiger
winged mantle
#

i was husk farming

#

didn't work

spark tiger
#

lmao

supple whale
spark tiger
#

if it's the easiest way of doing mobile/small screen support

supple whale
#

full async ebml parser btw

winged mantle
#

i wanna see a graph where there is just one thing which depends on itself

spark tiger
#

is tailwind husk or blobcatcozy

supple whale
#

...both

spark tiger
#

also uh remembering the dependencies discussion this chat had half an hour ago would i rather use a dependency for something not-so-hard (like a popup) or just make it yourself

royal nymph
#

this is just one single example how you can make your ui adapt to different screen sizes

spark tiger
royal nymph
#

build your entire around with stuff like this in mind and always use the right tools (grid, flex)

then it's easy to make it good on smaller sizes

royal nymph
# royal nymph

full code

<div class="my-card-grid">
    <div class="card">1</div>
    <div class="card">2</div>
    <div class="card">3</div>
    <div class="card">4</div>
    <div class="card">5</div>
    <div class="card">6</div>
    <div class="card">7</div>
    <div class="card">8</div>
    <div class="card">9</div>
</div>

<style>
.my-card-grid {
  --columns: 3;
  display: grid;
  gap: 1em;
  grid-template-columns: repeat(var(--columns), 1fr);
}

.card {
    height: 2em;
    text-align: center;
    background: black;
    color: white;    
}

@media (max-width: 1000px) {
    .my-card-grid {
        --columns: 2;
    }
}

@media (max-width: 600px) {
    .my-card-grid {
        --columns: 1;
    }
}
</style>
spark tiger
#

tjank you (ik what flexbox is)

royal nymph
#

with flex you can do stuff like change the direction the elements flow on mobile

hoary sluice
#

@valid jetty im listening to ferris explain hrtbs

spark tiger
#

was testing friends' site on my iphone and apparently it didn't work because of something in webkit and my friends have no idea how to fix it blobcatcozy

hoary sluice
#

i had to install raspi os instead of alpine cause one of the cpp deps i had didnt like musl

winged mantle
#

it would be cool though

shrewd canopy
spark tiger
hoary sluice
winged mantle
shrewd canopy
#

Yop

hoary sluice
spark tiger
winged mantle
#

why does this code feel so wrong to me why do I prefer (new Error).stack

hoary sluice
spark tiger
winged mantle
#

vibe coding

#

committing .env

hoary sluice
#

does new just consume until ) then stop

winged mantle
#

javascript parses things weirdly you need parens around lambda body often

winged mantle
spark tiger
#

also tryna use astro for my site but it differs so much than just regular html+css+js isob

valid jetty
#

if there is no ( token after the id then it assumes theres no args

#

which is a fucking weird feature but whatever

fleet cedar
#

It's a really fucking dumb special case, nobody sane would write constructor calls without parens

spark tiger
#

why tf is it still the only way to download a file in web 🥀🥀🥀

hoary sluice
spark tiger
hoary sluice
#

web dev is always stupid so this seems real

spark tiger
#

nah but this one is just extremely fucking dumb idgi at all

hoary sluice
#

like most things in webdev

valid jetty
spark tiger
#

do you not

#

oh

#

you mean the appendchild

#

idk its chatgpt

pearl stagBOT
valid jetty
#

its not ideal but whatever

spark tiger
#

yeah but still the point is you need to do that goofy .click() that looks so weird

valid jetty
#

somewhat

spark tiger
#

i should stop procrastinating and should start building the site ffs

valid jetty
#

@hoary sluice watch reacher

supple whale
valid jetty
#

im downloading a 100kb json file lmao

#

streaming that is a little overkill

supple whale
#

what if it was a 100TB?

#

you never know

valid jetty
#

i dont think it can ever reach even 1mb naturally lol

supple whale
#

ignore the fact that this code is giga old, and i wrote it when i had like a year of experience with JS

#

on the client side

#

simple

valid jetty
#

😭

supple whale
#

its giga great

#

because then you can do

#

<video src='/server/fakeFile.js'>

#

and you can stream a video created in browser

#

and do the same with images, iframes, audio etc

#

and you can ofc create streams to download data generated in the browser too via

if (req.destination === 'document') {
  res.headers['Content-Type'] = 'application/octet-stream'
  res.headers['Content-Disposition'] = 'attachment'
  res.body = 'DOWNLOAD'
}

which then lets u do
<a href='./fakefile' target='_blank'>

#

which will download the file, but as a stream you implement yourself

#

i love making browsers do shit they arent really made to do

valid jetty
royal nymph
#

he just explained that

supple whale
#

sry

#

but it can be any extension u want

valid jetty
deep mulch
#

@valid jetty omg hiii wyd

#

didn't see you there >-<

royal nymph
#

?

deep mulch
#

@royal nymph

winged mantle
supple whale
#

yeah i worte this like 6 years ago?

#

or 5?

#

i was giga nub at js

#

i could write this x10 better now

winged mantle
#

are you a 10x developer

supple whale
#

yes

#

lol

#

XD

valid jetty
#

im a 9x developer how about that

supple whale
#

respectable

#

x4 devs and under arent welcome here

valid jetty
#

@deep mulch

#

/s

supple whale
winged mantle
#

what's a pyw

deep mulch
#

a pyw

winged mantle
#

fear why do i have opera from 2017

supple whale
#

i've learned ()=>{} is actually really bad to use, and function () {} should almost always be preferred

winged mantle
#

this is my code from 2016

supple whale
#

yeah but you wrote it in notepad

#

so like

#

you didnt have a formatter and shit

winged mantle
#

i don't think i wrote it in notepad

supple whale
#

this is my best code so far

#

i re-wrote the entire app a few days ago

winged mantle
#

using opengl in jshusk

supple whale
#

look closer

#

its webgl on a VIDEO

#

XDD

shrewd canopy
winged mantle
#

ah

#

i guess i wanted it to play an annoying tune with no way to stop it

#

I find it hard to find any of my 2016 code for some reason lol idk if i barely did any or lost most of it

supple whale
#

i have a lot

#

i just dont want to admit its mine

#

my old react code

#

MMMMMMMMMM

winged mantle
#

so good

supple whale
#

i started writing decent code almost right away cuz i was forced to, i was taught from the start to use eslint, and fix any errors found by it

#

and boi was it a good way to learn

pearl stagBOT
# winged mantle https://github.com/TheKodeToad/Spade/blob/v1/Spade/src/main/java/me/mcblueparrot...

ServerPropertiesHandlerMixin.java: Lines 23-60

    @Shadow
//    public boolean onlineMode;
//    @Shadow
//    public boolean preventProxyConnections;
//    @Shadow
//    public String serverIp;
//    @Shadow
//    public boolean spawnAnimals;
//    @Shadow
//    public boolean spawnNpcs;
//    @Shadow
//    public boolean pvp;
//    @Shadow
//    public boolean allowFlight;
//    @Shadow
//    public String resourcePack;
//    @Shadow
//    public String resourcePackHash;
//    @Shadow
//    public String resourcePackSha1;
//    @Shadow
//    public String motd;
//    @Shadow
//    public boolean forceGameMode;
//    @Shadow
//    public boolean enforceWhitelist;
//    @Shadow
//    public Difficulty difficulty;
//    @Shadow
//    public GameMode gameMode;
//    @Shadow
//    public String levelName;
//    @Shadow
//    public int serverPort;
//    @Shadow
//    public int maxBuildHeight;
//    @Shadow
//    public Boolean announcePlayerAchievements;
winged mantle
#

horror

#

so large

pearl stagBOT
# supple whale https://github.com/ThaUnknown/miru/blob/master/src/lib/components/ui/player/play...

player.svelte: Lines 2-24

import Captions from 'lucide-svelte/icons/captions'
import Cast from 'lucide-svelte/icons/cast'
import ChevronDown from 'lucide-svelte/icons/chevron-down'
import ChevronUp from 'lucide-svelte/icons/chevron-up'
import Contrast from 'lucide-svelte/icons/contrast'
import FastForward from 'lucide-svelte/icons/fast-forward'
import List from 'lucide-svelte/icons/list'
import Maximize from 'lucide-svelte/icons/maximize'
import Minimize from 'lucide-svelte/icons/minimize'
import Pause from 'lucide-svelte/icons/pause'
import PictureInPicture2 from 'lucide-svelte/icons/picture-in-picture-2'
import Proportions from 'lucide-svelte/icons/proportions'
import RefreshCcw from 'lucide-svelte/icons/refresh-ccw'
import Rewind from 'lucide-svelte/icons/rewind'
import RotateCcw from 'lucide-svelte/icons/rotate-ccw'
import RotateCw from 'lucide-svelte/icons/rotate-cw'
import ScreenShare from 'lucide-svelte/icons/screen-share'
import SkipBack from 'lucide-svelte/icons/skip-back'
import SkipForward from 'lucide-svelte/icons/skip-forward'
import Users from 'lucide-svelte/icons/users'
import Volume1 from 'lucide-svelte/icons/volume-1'
import Volume2 from 'lucide-svelte/icons/volume-2'
import VolumeX from 'lucide-svelte/icons/volume-x'
supple whale
#

:^)

shrewd canopy
supple whale
#

oh that was only icons sir

#

the full imports are way longer

#

ah o7 @pearl stag

pearl stagBOT
# supple whale https://github.com/ThaUnknown/miru/blob/master/src/service-worker/index.ts#L1-L9

index.ts: Lines 1-9

import { clientsClaim, skipWaiting } from 'workbox-core'
import { cleanupOutdatedCaches, precacheAndRoute } from 'workbox-precaching'

import { build, files, prerendered, version } from '$service-worker'

precacheAndRoute([...build, ...files.filter(e => !['/Ameku.webm', '/video.mkv'].includes(e)), ...prerendered, '/'].map(url => ({ url, revision: version })))
cleanupOutdatedCaches()
clientsClaim()
skipWaiting()
supple whale
#

this tho

#

i fucking love sveltekit

#

4 loc for automatic updating offline cache

pearl stagBOT
# winged mantle has support for groovy plugins https://github.com/TheKodeToad/Spade/blob/v1/Spad...

SpadePluginManager.java: Lines 140-175

else if(pluginFile.isDirectory() && pluginFile.getName().endsWith(".plugin")) {
    try {
        File descriptionFile = new File(pluginFile, "plugin." + ConfigurationSystem.getDefault().getExtension());
        Configuration description;
        String scriptName;
        try {
            description = ConfigurationSystem.getDefault().load(descriptionFile);
            scriptName = description.getString("script");
            Objects.requireNonNull(scriptName);
            Objects.requireNonNull(description.getString("name"));
            Objects.requireNonNull(description.getString("version"));
        }
        catch(Throwable e) {
            logger.error("Invalid plugin description");
            throw e;
        }
        if(scriptName.equals("plugin") || scriptName.equals("server") || scriptName.equals("scheduler") || scriptName.equals("pluginManager")) {
            throw new IllegalArgumentException("Script cannot be called plugin, server, scheduler or pluginManager");
        }
        File scriptFile = new File(pluginFile, scriptName + ".groovy");
        if(!scriptFile.exists()) {
            throw new FileNotFoundException("Cannot find script " + scriptFile.getName());
        }
        ScriptPlugin plugin = new ScriptPlugin(scriptFile);
        plugin.setDescription(description);
        Binding binding = new Binding();
        binding.setProperty("plugin", plugin);
        binding.setProperty("server", Spade.getServer());
        binding.setProperty("scheduler", Spade.getScheduler());
        binding.setProperty("pluginManager", this);
        GroovyShell shell = new GroovyShell(Launch.classLoader);
        Script script = shell.parse(scriptFile);
        script.setBinding(binding);
        script.run();
        plugins.add(plugin);
    }
winged mantle
winged mantle
#

what's a recommended way to stop path traversal in node.js 😭

#

when i search i can only find stuff like normalising and checking whether it starts with .. (which isn't the best)

shrewd canopy
winged mantle
#

yeah but how?

shrewd canopy
#

then where you are trying to prevent path traversal

winged mantle
#

i am trying to join a path to a root dir

#

and throw an error if it goes outside the dir

#

I don't want to do something myself because there might be an oversight

supple whale
#

there's a lot of ways

#

like a LOT LOT

#

start with a path.resolve

#

so path.resolve(base, userinput)

#

that gives u a normalized path

#

then you can check that normalized path

winged mantle
#

i noticed that a lib which did something like that had to change it due to a vuln

#

their solution now is regex

#

ig that's fine

supple whale
#

for example if(path.relative(base, normalized).startsWith('..')) throw new Error('Nuh-uh')

#

there are probs better ways of doing it

winged mantle
#

that also matches paths like ..test, no?

supple whale
#

well that checks if some1 tries to exit base

#

if they are, wont let them

winged mantle
#

i would rather use something battle tested but for example the impl that express uses feels quite complex

supple whale
#

yeah

#

that sounds about right

#

UP_PATH_REGEXP is probably a check for ^../

#

so its legit what i sent u

#

path.normalize instead of path.resolve

#

so i got braincells on me after all

winged mantle
#

checking for .. will break for paths like this

supple whale
#

do ^../

winged mantle
#

ohh I now understand that vuln with express's dep

#

it just allowed you to work out the root path name from seeing if you got an error

#

what even is the point though

#

this is just startsWith

#

maybe old js didn't have

#

implementation i ended with

#

you're right resolve does normalize... at least if i understand node source code correctly

winged mantle
#

@valid jetty you love

#

why just have else if when you can have else for

median root
#

ok why are these stupid font files so hard to work with

#

ive just spent 20mins tryna figure out why my icons were in the wrong place just to find out there like 3 diffrent kinds of .ttf file

#

and im meant to know that

fleet cedar
#

It's just else any-statement

#

Yes

#

That's exactly what I just said

#

if is a statement, {} is a statement

winged mantle
#

for some reason it didn't occur to me

hoary sluice
#

@placid cape i got silence detection to work exactly 20 mins before i have to leave to present it

placid cape
#

Lol

hoary sluice
#

it was supposed to be on alpine & kde but one of my deps (whisper-rs) assumes u have glibc and im not smart enough to make it work

#

and alpine uses musl

placid cape
#

oh yea

hoary sluice
#

but i dont think my supervisor knows what a linux distro is so its fine

hoary sluice
#

@valid jetty portal 2 is turing complete

royal nymph
winged mantle
#

value is not even nullable

royal nymph
#

🤫 just an example

hoary sluice
winged mantle
#

for (const value of arg.value)
if (value != null)
yield value;

#

better

abstract sentinel
#

hey are there some docs or relevant info about plugin development? /getting started?

median root
#

thats what taught me most about this

abstract sentinel
median root
median root
#

yo is anyone elses new "stable" flutter version flashing black on the screen every 0.7 seconds?

#

ive had to downgrade back to 3.29.3

median root
hoary sluice
#

@valid jetty these would be builtins

#

but this isnt really maintainable imo

#

if theres more than 1 arg it gets annoying to write

valid jetty
#

make a macro for it

hoary sluice
#

thats my goal

#

but last time i tried i miserably failed

#

i need to watch some kinda macro tutorial

valid jetty
hoary sluice
#

arg.ok_or right

valid jetty
#
let Value::Integer(a) = arg else {
    return err!();
}
hoary sluice
#

oh

#

right yea

#

you taught me that like a week ago

valid jetty
#

lmao

#

also i think rust should be able to infer the types of arg2 and loc2 because its being assigned directly to the function field

#

but dont quote me on that

hoary sluice
#

yes it can

#

i think this is called a tt muncher

valid jetty
#

yes

placid cape
#

@hoary sluice what do you use for mic, speakers for the rpi?

hoary sluice
placid cape
#

which usb mic

hoary sluice
#

some random one from amazon

placid cape
#

but of course it doesnt work

hoary sluice
#

ik raspi is garbage to work with

#

i wrote the software perfectly fine and then took a long time to get the raspi set up

#

and i had no hardware besides a usb headset

deep mulch
#

@hoary sluice

placid cape
#

i hate it

#

so much

#

AAAAAAAAAAAAAAAAAA

median root
#

Oh yes I love how it dont tell me how to get one of these native.ts files

fleet cedar
#

touch native.ts, same as any other file

glacial mirage
#

it says

files you can create
so you have to make it yourself

spark tiger
fleet cedar
#

Yeah but like on sensible OSes I mean

glacial mirage
#

just open a text editor and save to that file location then

median root
glacial mirage
#

its just based on the name i think

median root
#

well what else would I expect from javascript i guess

#

yeah like this thing:

const Native = VencordNative.pluginHelpers.RandomGary as PluginNative<typeof import("./native")>;
#

do I not need to do this?

median root
#
import definePlugin, { PluginNative } from "@utils/types";
const Native = VencordNative.pluginHelpers.${pluginName} as PluginNative<typeof import("./native")>;
Native.method()
#

something like that I think

#

eh ill try it later

fleet cedar
#

Only electron does

median root
fleet cedar
#

Because electron's literal purpose is frankensteining browser and native

median root
#

augh I wish we could like not-sandbox

fleet cedar
#

You won't wish that anymore after your first 0day

lavish frigate
valid jetty
#

lmao no way 😭😭😭

hoary sluice
#

@valid jetty 135 xp from 1 lesson

fleet cedar
#

Well are you?

hoary sluice
#

Nop, I'm a supercomputer, it's time to finally just admit it.

valid jetty
deep mulch
#

it wont play

valid jetty
#

i don’t think you want it to play

hoary sluice
#

every language ever calls it film

valid jetty
placid cape
#

What's your name on Duolingo

hoary sluice
hoary sluice
hoary sluice
placid cape
#

i sent you request

hoary sluice
#

@valid jetty

#

no macro for it yet but it works

valid jetty
#

yay

hoary sluice
#

i spent a solid 10 minutes trying to figure out why it couldnt resolve the identifier

#

turns out i named the function println cause i thought i was smart

#

and then proceeded to call print in the icy code

#

theres only o

#

no i

#

but now i have more or less of a week of free time

#

so maybe i soon

#

oo

#

also

#
print "hi"
``` evaluates to "hi"
valid jetty
hoary sluice
#

so u can do

print 2 + 3

and itll print 2 and evaluate to 5

#

again its println not print

#

i forgot again

valid jetty
hoary sluice
hoary sluice
#

its parsed as Binary(+, Call(print, 2), 3)

valid jetty
hoary sluice
#

function application has the highest precedence

valid jetty
#

if you pass more args the result is a tuple of the args you passed in

hoary sluice
hoary sluice
#

so println 2 + 3 isnt ambiguous at all

valid jetty
valid jetty
hoary sluice
#

nop

#

u shouldnt expect that

valid jetty
#

are you trying to gaslight me or are you trying to gaslight yourself that its better this way

hoary sluice
#

its how haskell does it lol

valid jetty
#

husk

hoary sluice
#

and it makes more sense

#

print 2 + 3 isnt valid in haskell cause print doesnt return (or like world monad stuff) but f x + y is (f x) + y

valid jetty
hoary sluice
#

i mean this is probably real because i got an sms from them when signing up but also i dont have any money in my bitpanda

hoary sluice
#

id 2 + 3 evaluates to 5

valid jetty
#

you cant print 2 + 3 tho lol

hoary sluice
#

yea like i said, print returns the world monad

valid jetty
#

you can do this i guess

main :: IO ()
main = putStr $ show (2 + 3)
hoary sluice
#

for me print is the identity function

#

in haskell it isnt

valid jetty
#

oh i see what you mean

#

i guess you cant really call this language purely functional

hoary sluice
#

well ok how do u make io purely functional

#

you cant

valid jetty
#

thats a solved problem 😭 you return a new state of the World

hoary sluice
#

returning world monad is a stupid workaround based on technicalities

valid jetty
#

lmao

hoary sluice
#

id rather rosie tell me icy isnt purely functional than make it bad

valid jetty
#

day 542 of telling you you couldve just made it procedural and all your problems dissapear

#

but tbf procedural is slower to write

hoary sluice
#

my problems are quickly fading away

#

and i already made a procedural interpreter

#

be it not very featureful

valid jetty
#

purely functional compiler soon

hoary sluice
#

now i just need input, macros for io, make it compiled (husk) and i can rewrite icy in icy

valid jetty
#

(even i dont know how i would approach that)

hoary sluice
#

compile to haskell

valid jetty
#

isnt that cheating

hoary sluice
#

aka print(open(0).read())

valid jetty
#

😭

#

do you have $

hoary sluice
#

yes but not the same as in haskell

#

its the . in lambdas

#

soon itll get usable enough to where i have to make a readme and docs and an lsp and all that stuff husk

valid jetty
#

is the end goal here to have a situation like vlang

#

for vlang the primary compilation target is C

hoary sluice
#

whats vlang

valid jetty
hoary sluice
#

no the goal is an interpreter

#

i wanna try to get this workable before aoc

deep mulch
#

@valid jetty hii

#

v lang is funny

hoary sluice
#

enough for me to be able to solve every aoc day without having to add extra features during aoc

deep mulch
#

I played around with it before

valid jetty
hoary sluice
#

idk if i wanna compile

deep mulch
#

Elle will compile to JS

valid jetty
deep mulch
#

@valid jetty make Elle compile to Java

valid jetty
#

i could genuinely do it

hoary sluice
#

im starting uni in september so there might be some other stuff ill be doing

deep mulch
#

@hoary sluice I thought you were already in uni

hoary sluice
#

i am technically

#

i finished school in april, doing matura exams now (final exams at the end of high school standardized in europe) and im accepted to the uni, in their cis system, and paid a deposit

#

and im starting in 3rd semester

#

so im technically in the 2nd semester rn

#

tho not actually doing any studying

valid jetty
#

@deep mulch

#

its possible

deep mulch
#

insanity

hoary sluice
#

js always longer than elle

#

compile elle to wasm

#

does qbe target wasm

#

prob not right

#

switch to llvm

#

qbe is limited

#

rewrite elle in elle on llvm

valid jetty
#

i dont want my compilation times to quadruple thank you

hoary sluice
#

the earlier you start the better

pseudo sierra
#

make your own compiler backend in elle

hoary sluice
valid jetty
#

compiling the llvm ir to assembly

#

do you know how slow it is

hoary sluice
#

your compilation times are already extremely fast so quadrupling them wont hurt

#

and youre using rust and complaining abt compile times

deep mulch
#

@valid jetty make Elle os

#

that would be fun I bet

hoary sluice
#

this guy is making a compiled functional language to then make an OS in

deep mulch
#

I wanna do that

valid jetty
#

rust isnt related here, the part im talking about is not elle itself but is the process of translating IR to assembly

#

qbe is very fast, llvm is not so much

hoary sluice
#
deep mulch
#

make Elle faster than C@valid jetty

hoary sluice
hoary sluice
#

statically linking everything and duplicating every dependency is extremely based

valid jetty
deep mulch
#

does Elle have tree shaking

#

where you shake a tree

valid jetty
hoary sluice
#

@deep mulch can i shake your tree

valid jetty
valid jetty
#

i think the best way to go is genuinely to make a C compilation target

#

C can compile to almost anything

deep mulch
#

@young flicker

deep mulch
#

guhh just make Elle support npm modules

valid jetty
#

girl im sorry to scare you

hoary sluice
valid jetty
#

but i think its defined

deep mulch
#

add 500 keywords @valid jetty

#

@valid jetty add keyword to use registers directly

valid jetty
#

why

deep mulch
#

funny!!!

#

@young flicker @young flicker @young flicker

hoary sluice
#

@valid jetty write elle using only rust macros

#

easiest way to compile to rust

#

literally built into rust

#

@deep mulch 100 gorillas vs the sun?

nimble bone
#

write elle in elle @valid jetty

hoary sluice
#

@deep mulch 100 humans vs 1 human?

#

who would win

#

@deep mulch 1 rosie vs 1 zooter?

deep mulch
#

Rosie loses

#

I could destroy Rosie easily

valid jetty
#

@hoary sluice i found another edge case to the monomorphization system earlier

hoary sluice
valid jetty
#
use std/prelude;

struct Foo<T> {
    Option<fn(T) -> T> cb
}

fn main() {
    Foo<i32> foo = Foo {
        cb = Option::Some(fn(x) x * 2)
    };

    x := foo.cb.unwrap();
    $dbg(x(34));
}
``` when the callback is wrapped in another function call

during monomorphization, `Option::Some()` accepts a T, not a function type

even though it can be inferred that `x` is `i32` because `cb` accepts a `Option<T>` where T is a function, the compiler doesnt know that when monomorphizing the function call to Option::Some and as such cant infer the type of `x`
valid jetty
#

there are so many edge cases

#

its going through like 3 steps of monomorphization here

hoary sluice
#

im glad i wont have to mormonize

#

why any time i search for anything related to compilers, the first result is almost always from a rust / book / forum / other rust-related source

#

is rust really just used to make compilers and memecoins

valid jetty
#
  • Foo<T> links T to fn(T) -> T
  • Foo<i32> means that cb's type isOption<fn(i32) -> i32>
  • that type is passed to use in Option::Some to infer T (from the return type, Option<T> vs Option<fn(i32) -> i32>)
  • when deducing a type from fn(x) x * 2, we dont yet know what T (from Option::Some<T>) is, so x cant be inferred
  • i need to do like 4 passes for codegen to properly monomorphize this
  • suffering.
valid jetty
#

i could take the lazy way out

#

and make it so that, if the arg is exactly T and we know T then use a different param ty to monomorphize the lambda with

#

but that breaks when it becomes

fn foo<T>(Bar<T> x) -> Foo<T>

struct A<T> {
    Foo<fn(i32) -> i32> cb;
}

fn main() {
    A<i32> a = A {
        cb = foo(bar(fn(x) x * 2))
    };
}
#

because its Bar<T> x not T x

#

omg wait

hoary sluice
#

i dont understand any of this

valid jetty
valid jetty
hoary sluice
valid jetty
#

uhhh you should probably start caring

#

or youll take 2 years to get your solves

hoary sluice
#

aoc is about writing a good algo not having a fast language

#

to get on global lb you have to beat the bruteforcers

#

if you just try bruteforcing you wont win cause thats easy and a lot of ppl do it so theres a lot of competition

valid jetty
#

i mean yeah good point

#

but there are some cases where it just takes a while

hoary sluice
#

well python is also incredibly slow for no reason

valid jetty
#

..there is a good reason

#

its called ✨ an interpreter ✨

hoary sluice
#

but its like

#

slow even for an interpreter

valid jetty
#

i mean from what ive heard its actually way faster these days than it used to be

#

but still doesnt compare to a compiled language

hoary sluice
#

well ofc

valid jetty
#

excuse me

#

oh i see

#

im not actually sure how to deal with that

hoary sluice
#

how are ur errors so awesome

valid jetty
#

spaghetti code

hoary sluice
#

no like the error msgs

valid jetty
#

the key to a good error display is spaghetti code

hoary sluice
#

almost as good as rust

fleet cedar
#

Delicious spaghetti makes the error gremlins happy

valid jetty
#

true

#

beautiful isnt it

hoary sluice
valid jetty
#

already did for the compiler

#

idk about the rest

hoary sluice
#

rewrite it in elle

valid jetty
#

RIIE

valid jetty
#

to make the inference in lambdas work, i deduce generics from the return type before function arguments

#

which means it learns T = Result<T, E> but doesnt know anything else yet

#

then it compiles the Result::Ok(...) and learns that T = Result<...> but it already learnt that T = Result<T, E>

#

idk if i should allow arbitrary conversions from generic to non-generic structs

#

i have an ideaaaaa

hoary sluice
#

do u use zed dbg

valid jetty
#

no lol

#

i just examined the control flow of my program

hoary sluice
#

why not

valid jetty
#

whats zed dbg

hoary sluice
#

the new zed debugger

valid jetty
#

isnt that ai powered or something

hoary sluice
#

no its codelldb in a fancy panel

valid jetty
#

lmao

#

ok ill look at it

hoary sluice
#

and theres ai agents too

#

its invite only beta but they invite everyone but u have to wait

valid jetty
#

the fact that it is able to infer EVERYTHING here is kinda insane

valid jetty
#

i already got my invite

#

nvm

#

its not an invite

#

its just the launch post

hoary sluice
#

rosie my job suddenly decided to require windows with no admin and supervision

valid jetty
#

qemu with gpu passthrough

hoary sluice
#

u cant install apps

valid jetty
hoary sluice
#

only through baramudi

valid jetty
#

i keep them seperate until after args are deduced, then i add them if there are still unknown generics

#

wtf is baramudi

hoary sluice
#

nah its some kinda enterprise confidentiality management software

valid jetty
hoary sluice
#

but wsl is allowed

#

im gonna try nixos-wsl

#

it probably wont work

valid jetty
#

😭

valid jetty
#

whats a neat way to format this 😭

#
server, port := TcpServer::bind_until(
    8080,
    fn(server) server.is_ok_or(fn(err) err != Errno::EADDRINUSE),
    Option::Some(fn(port) { *port += 1; })
).expect("Failed to bind server");
shrewd canopy
valid jetty
#

true

#

ehhh thats not that bad

server := TcpServer::bind(port := 8080);

while server.is_err_and(fn(err) err == Errno::EADDRINUSE) {
    server = TcpServer::bind(port += 1);
}
#

clean overall i think

use std/prelude;
use std/net/tcp;

const BUF_SIZE = 1024;

fn main() {
    server := TcpServer::bind(port := 8080);

    while server.is_err_and(fn(err) err == Errno::EADDRINUSE) {
        server = TcpServer::bind(port += 1);
    }

    server := server.unwrap();
    defer server.close().unwrap();
    $printf("Server is listening on port {}", port);

    buf := Array::bytes(BUF_SIZE);
    connection := server.accept().unwrap();
    defer connection.close().unwrap();

    while (_, received := connection.read(buf)) && received != 0 {
        $printf("Received {} bytes: {}", received, buf.join("").replace("\n", ""));
        connection.write(buf).expect("Failed to send response");
    }
}
#

@hoary sluice is this a clean api

use std/collections/array;
global pub;

pub struct Foo {
    i32 x,
    string y,
    f64 z,
}

fn Foo::to_bytes(Foo self) -> u8[] {
    res := [];

    res.extend([self.x].to_bytes());
    res.extend([self.y.len()].to_bytes());
    res.extend(Array::from_string(self.y).to_bytes());
    res.extend([self.z].to_bytes());

    return res;
}

fn Foo::from_bytes(u8[] res) {
    self := #alloc(Foo);
    offset := 0;

    self.x = res.read<i32>(&offset);
    len := res.read<u64>(&offset);
    self.y = res.slice(offset, offset += len).to_repr<char>().join("");
    self.z = res.read<f64>(&offset);

    return *self;
}
#

so you can go back and forth

foo := Foo { x = 39, y = "Hello from the server", z = 4.2 };
$printf("Sending {}", foo);
connection.write(foo.to_bytes()).unwrap();
buf := Array::bytes(BUF_SIZE);
client.read(buf).unwrap();
foo := Foo::from_bytes(buf);
$printf("Received {}", foo);
valid jetty
#

@hoary sluice 😭

calm wigeon
#

this is horrid

dense sand
#

What a combo

blazing haven
#

"quick start"

#

more like

#

quick bloat

shrewd canopy
deep mulch
#

elle install is_even

deep mulch
#

@valid jetty if you ever need ideas for Elle just ask me blobcatcozy

fleet cedar
#

But what if she needs good ideas

deep mulch
#

I have all goodideas

hoary sluice
hoary sluice
#

rewriting elle in elle is a good idea

hoary sluice
deep mulch
valid jetty
#
# add :: fun (~x: Int, to y: Int) -> Int: x + y

# main :: fun () -> Int: {
  # x :: 4
  # y :: add(x, to: 3)
  # y
# }

x :: {}
#

interesting syntax

#

oh my god he’s writing a borrow checker

hoary sluice
#

one for the function body one for the caller

valid jetty
#

yea i know there’s quite a few languages that do this

#

namely swift and objc

#

there are definitely more

#

i genuinely cannot tell whether this is real or ai

#

like

deep mulch
#

@valid jetty is an ai

#

AI cannot tell AI from real

#

weird

#

page doesn't work through cloudflare

#

404 for one of the required files

hoary sluice
#

never

valid jetty
#

and the knives are magnetic to the wall???

royal nymph
hoary sluice
hoary sluice
warm wyvern
shrewd canopy
valid jetty
#

@hoary sluice thunks come for free

use std/prelude;

namespace Cat;
fn Cat::speak(Cat *self) {
    $println("*mew*");
}

namespace Dog;
fn Dog::speak(Dog *self) {
    $println("*wof*");
}

struct AnythingSpeak @nofmt {
    void *data,
    fn(void *) speak_thunk
}

fn AnythingSpeak::new<T>(T *t) {
    return AnythingSpeak {
        data = #cast(void *, t),
        speak_thunk = fn(data) #cast(T *, data).speak()
    };
}

fn AnythingSpeak::speak(AnythingSpeak self) {
    cb := self.speak_thunk;
    cb(self.data);
}

fn main() {
    a := AnythingSpeak::new(&Cat {});
    a.speak();
    a = AnythingSpeak::new(&Dog {});
    a.speak();
}
hoary sluice
#

how are these thunks

fleet cedar
#

There's a billion definitions of thunk, I'm sure it's one of them

hoary sluice
#

my understanding of thunk is its a wrapper for a value that tells the interpreter not to evaluate that value until its used

valid jetty
#

thunks in compiled languages are type-erased values

#

things like &dyn Speak in rust

#

or a virtual method in C++

hoary sluice
#

oh

hoary sluice
valid jetty
#

well yeah obviously

hoary sluice
#

its free but it also looks free

valid jetty
#

wellll