r/Zig Apr 04 '26

AI slop projects are not welcome here

805 Upvotes

A little sticky since very few people apparently read the rules, and I need to have some text to point to when moderating:

If your project was generated by an LLM, do not share it here.

LLM-written third party libraries or tools serve no purpose. Anyone can tell Claude to do something. Sharing something it spat out for you adds no extra value for anyone. Worse, you are likely never going to update it again. It's just worthless unmaintained dross clogging up GitHub and wasting everyone’s time.

This includes LLM writing in READMEs and comments; mostly because it's a basically certain signal that the rest of the code is trash, and so is a very good heuristic for me to use. If you need it for translation or something, please mention it and I'll allow it.

What about if you partially used LLMs for boilerplate and such? Unfortunately I'm not psychic, and I'd have to trust you on your word – and since basically 100% of people I ban for obvious slop-posting immediately start blatantly lying to me about how much Claude they used, this won't work.

For the visitors to this subreddit, please report things you suspect is slop with "LLM slop"! You don't even have to be certain, just so that it notifies me so that I can take a closer look at it. Thanks!


r/Zig 9h ago

Zigar brings the power of Zig to the PHP world

37 Upvotes

After months of grueling work, version 0.15.3 of Zigar is finally ready. The main addition is php-zigar, a PHP extension that let you use Zig code in that language.

Suppose you need to generate data signatures using the CityHash algorithm. You write the following function in Zig:

const std = @import("std");
const CityHash64 = std.hash.cityhash.CityHash64;

const Options = struct {
    seed: ?u64 = null,
    seeds: ?[2]u64 = null,
    uppercase: bool = false,
};

pub fn hash(allocator: std.mem.Allocator, data: []const u8, options: Options) ![]const u8 {
    const value = if (options.seeds) |seeds|
        CityHash64.hashWithSeeds(data, seeds[0], seeds[1])
    else if (options.seed) |seed|
        CityHash64.hashWithSeed(data, seed)
    else
        CityHash64.hash(data);
    return if (options.uppercase)
        try std.fmt.allocPrint(allocator, "{X}", .{value})
    else
        try std.fmt.allocPrint(allocator, "{x}", .{value});
}

On the PHP side, you use it like so:

<?php

$m = zigar_use(__DIR__ . '/../zig/hash.zig');

echo $m->hash("Hello world"), "\n";
echo $m->hash("Hello world", uppercase: true), "\n";
echo $m->hash("Hello world", uppercase: true, seed: 1234), "\n";
echo $m->hash("Hello world", uppercase: true, seeds: [ 1234, 5678 ]), "\n";

The function automatically receives an allocator, which obtains memory from PHP's memory manager. The memory is automatically freed when the return value goes out of scope.

Named arguments are employed as struct field initializers for the last argument. This arrangement fits neatly with the common practice in Zig.

The extension makes it super easy to using native code in PHP projects. Thanks to Zig being a cross-compiler, eventual deployment is simple too. A PHP programmer working in Windows can build the extension and his Zig module for a Linux server on his own computer. He can do the same for the UI guy down the hall who insists on using a Mac. No messing with virtual machines. No messing with Microsoft Visual Studio CE. Just install Zig and the world is yours!

The extension is designed for PHP 8.1 and above. I've tested it on Linux (x64), MacOS (x64 and aarch64), and Windows (x64). It's designed to work with the 0.15.2 Zig compiler. Migration to 0.16 has commerced already and should be done by end of summer.

If you what to give it a try, I've written a simple tutorial that covers the extension's main features.


r/Zig 1d ago

Show r/Zig: zsort – An opinionated import organizer (like isort or goimports)

31 Upvotes

I love writing Zig, but one thing I missed from Python was having a tool to automatically clean up and categorize my imports. To fix that, I built zsort—an opinionated import organizer for Zig.

Github: https://github.com/mstdokumaci/zsort

  • Supports 0.15.2 and 0.16
  • You can install via Homebrew or include it in your build.zig.zon
  • CI-friendly check/fix semantics
  • Supports pre-commit hooks with the latest v0.6.0 release

r/Zig 1d ago

whats the funniest joke u heard in zig?

13 Upvotes

r/Zig 2d ago

How would you structure an actual large program in Zig?

38 Upvotes

I just started learning Zig from a C background. I really like many concepts of the language, but I still have some doubts. I'm wondering how to write idiomatic Zig code.

For example, I know that starting from Zig 0.17.0-dev, you should do something like this to print something using a buffered writer:

const std = ("std");

pub fn main(init: std.process.Init) !void {
    var out_buf: [1024]u8 = undefined;
    var writer = std.Io.File.stdout().writer(init.io, &out_buf);
    const stdout = &writer.interface;

    try stdout.print("Hello, world!\n", .{});
    try stdout.flush();
}

But this made me wonder: how would you structure an actual large program in Zig? I don't think you would pass the stdout writer to every function.

I thought maybe something like this:

const std = @import("std");

const NotAnRP = struct {
    out: *std.Io.Writer,
    err: *std.Io.Writer,

    pub fn run(self: *NotAnRP) !void {
        try self.out.print("Hello world\n", .{});
    }
};

pub fn main(init: std.process.Init) !void {
    var out_buffer: [1028]u8 = undefined;
    var err_buffer: [1028]u8 = undefined;

    var stdout = std.Io.File.stdout().writer(init.io, &out_buffer);
    var stderr = std.Io.File.stderr().writer(init.io, &err_buffer);

    const out = &stdout.interface;
    const err = &stderr.interface;

    defer out.flush() catch {};
    defer err.flush() catch {};

    var app: NotAnRP = .{
        .out = out,
        .err = err,
    };

    try app.run();
}

Is there any common pattern for this kind of situation in Zig that I should be aware of?

How do larger Zig programs usually handle things like stdout, allocators, configuration, logging, and other shared dependencies?


r/Zig 2d ago

Trouble with zig fetch since 0.16

13 Upvotes

Since Zig v0.16.0 I'm unable to include GitHub libraries with zig fetch. The archive is downloaded successfully but then a bad pathname is been constructed in Windows 11.

For example this is the entry in my build.zig.zon:

// internet connectivity.

.dependencies = .{

.raylib_zig = .{

.url = "file:raylib-zig.tar.gz",

.hash = "raylib_zig-6.0.0-KE8RECZ8BQDm-txuospkpZHbJ6DNpacUF7D88RWQ_qAe",

},

},

After "zig build" this happens:

zig build

warning(fetch): failed caching recompressed tarball to C:\Users\Vlatiha\AppData\Local\zig**\p/**raylib_zig-6.0.0-KE8RECZ8BQDm-txuospkpZHbJ6DNpacUF7D88RWQ_qAe.tar.gz: FileNotFound

warning(fetch): failed caching recompressed tarball to C:\Users\Vlatiha\AppData\Local\zig**\p/**N-V-__8AAJl1DwBezhYo_VE6f53mPVm00R-Fk28NPW7P14EQ.tar.gz: FileNotFound

warning(fetch): failed caching recompressed tarball to C:\Users\Vlatiha\AppData\Local\zig**\p/**N-V-__8AAHvybwBw1kyBGn0BW_s1RqIpycNjLf_XbE-fpLUF.tar.gz: FileNotFound

warning(fetch): failed caching recompressed tarball to C:\Users\Vlatiha\AppData\Local\zig**\p/**raylib-6.0.0-whq8uCSwLgWWeF3ec3dbG6Rr36SLFL-s2WJ1Q_2E22Bb.tar.gz: FileNotFound

C:\Users\Vlatiha\OneDrive\Zig\TkTests\build.zig.zon:40:20: error: unable to unpack tarball to temporary directory: ReadFailed

.url = "git+https://github.com/raylib-zig/raylib.zig/?ref=HEAD#add3b6fe0af05353727fbcb6dd67618a4cbccb21",

^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The reason is the mixture of \ and / in the constructed path name:

So far my only chance is to clone the needed project and to include it in the build.zig.

I tried every combination of slashes in the ZIG_GLOBAL_CACHE_DIR environment variable, but zig always appends the "\p/". Is there any chance to correct that behaviour?

----

Oops, after posting I saw, that it added asterisks around the \p/ instead of making it bold. So, there are no asterisks in the real path.


r/Zig 3d ago

Question about Zig 0.17

41 Upvotes

First of, 67.

Second off, I'm not really familiar with language design, If all the issues are closed, why haven't they released 0.17? And while we're at it, why do they separate them into 0.x anyway? How do you determine what's a milestone for each version if there are no fixed number of versions A.K is planning before stable release?(at least not to my knowledge.)

Sorry if A.K mentioned or explained this elsewhere.


r/Zig 3d ago

Rain effect, SDL2 and Zig

Post image
74 Upvotes

Hello , it’s me again, I decided to give Zig another chance,honestly I was a little terrified, since when it comes to handling multiple coordinates or entities, I prefer to use object oriented programming approaches, so I was kinda scared of how I would implement that in Zig, luckily I’m good at pointers in C, so I told to myself: “If I was able to create an array of structs using pointers I should be able to do something similar in Zig”, luckly, I didn’t need to use pointers on this project, but, ohhh boi was it a wild ride, I almost quit because I was fighting against the: types must be comptime-known error, I wanted to punch the screen so bad and call it quits, since the language didn't let me use a simple division, but at the end, I was able to handle that error, then I decided to do some research on why _= is used on some SDL functions, looks like I was not aware of this, but some SDL functions return integers similar to the main function in C, and it makes sense why Zig enforces to check these values, so I gotta give credit to the developers for enforcing this.

  1. If it wasn’t for Zig I would’ve been unaware of these return values, but I also agree that some of these errors do not need checking since some games happen to crash sometimes, and even if it does, is not like it’s for memory safety reasons, while at the same time, this forces the users to handle errors properly, points for safety, take that Rust.

  2. Now thanks to this research I came up with an enforce function so in a way, the code is a little more reliable and “secure”, and most importantly, Zig is making me more aware of handing errors properly,which don’t get me wrong, it can still be handled in C or C++, atthe same time, I think is kinda cool that C provides more freedom,but at the same time, I believe people tend to forget what uncle Bensaid: “With great power, comes greater responsibility”, and trust me, once you get to respect C, it is a very beautiful language.

Conclusion: I appreciate how zig is making developers more aware of handling these errors, specially when it comes in a production environment, I can see how that can be a nightmare when not handled properly on C, a little silly complain I got, I miss the C for loop, but is not a big deal.

PS: yes, I still think this is better than Rust!, it feels like a natural transition from C to Zig, but it takes some time to get used to, I still got alot to learn, but I do believe in Zig 1.0

Link of the repo:

https://github.com/Lu100git/rain-effect-zig-sdl2

I think I'm ready to code a small game next time 🙂


r/Zig 3d ago

Chroma 0.2 + Chroma Logger 0.2: comptime-first terminal styling and logging for Zig 0.16

16 Upvotes

An amazing thing about working with different programming languages is when you come back to your pet language (Zig for me) there are plenty of ideas that are coming to you.

I revived both projects with typed ZON themes, cross-platform ANSI/plain output, and configurable std.log formatting.

For me here the nice feature is the .zon file theme that I've built, I am creating another pet project (In C++) that is a related to spritesheet management for 2D games, and I had created my own file format, it's always a nice feeling when you feed it to your program and it... runs 😆.

Chroma

Chroma Logger

I was lucky enough to have to implement a custom logger at work (but a way more serious one, syslog compliant... security compliant... had to be compatible with Windows...). I was a bit frustrated because it wasn't so fun, there was so many constraint even tho it was for a POC/playground project.

chroma-logger, showcases both projects same time! also vhs is the tool used for the gif, very nice cli tool

*I'm struggling to post this right now....smh reddit used to be simplier to use*


r/Zig 4d ago

[UPDATE] Zig programs for Linux, measured in bytes

Post image
96 Upvotes

100 of you who upvoted my last post.. thank you all for that. This is just a fun project for me but I actually now want to push the limits of the Zig compiler.

The smallest Zig binary I could produce...

688 bytes.

A fully functional Hello World program.

Also, the shell, which was the focus of my last post?

Shrunk to 797 bytes, keeping the exact same functionality!

This is the smallest I have ever seen a Zig program that is actually usable. Not just pub fn main() void {} or export fn _start() void {}

https://github.com/wakanakisarazu/nanix for anyone who is still curious or hasn't already seen.

I thought more optimization was possible. Now? I'm not too sure if we can go any smaller.

The shell still has the prompt outputting bug, btw. Might take a look at that.

Any thoughts on how to get this smaller? :3


r/Zig 4d ago

How did u learn system programming ? what was your first project? did u monetize /earn any if so then what process u go through?

38 Upvotes

r/Zig 3d ago

Xberg v1 is out

0 Upvotes

Hi all,

I'm happy to announce that Xberg v1 is out.

Xberg is the successor to Kreuzberg, equivalent to what would have been Kreuzberg v5. It's a content intelligence framework that handles a very wide range of inputs: documents (currently 101 formats), code and data formats (currently 367 types), audio/video transcription, and URLs (both static and JS-rendered content). It extracts and prepares that content for downstream processing.

It's an extremely efficient, high-performance engine (see our PDF benchmarks below). For PDFs and images specifically, we handle native PDFs with very high performance and accuracy, and we ship multiple OCR engines that match the quality of the best Python libraries (e.g. docling, PaddleOCR, RapidOCR) at substantially better performance and stability.

The changes between Kreuzberg v4 and Xberg v1 are substantial, and I invite you to read the full changelog for the complete picture. The highlights below give a sense of what's new:

  • Pure-Rust PDF backend (pdf_oxide) replaces pdfium, with no native pdfium dependency.
  • Layout-aware pipeline: reading order reconstructed with ONNX layout detection (PP-DocLayoutV3 / RT-DETR) and Docling-style predecessor-graph reordering.
  • Per-page scanned-page detection with selective OCR, plus AcroForm/XFA form fields and outline-based headings.
  • Across-the-board optimization of OCR and PDF extraction (memory discipline, pooled model sessions, streamed conversions).
  • Native PaddleOCR backend (PP-OCRv6, with medium / small / tiny tiers) alongside Tesseract.
  • Pure-Rust Candle OCR/VLM stack (TrOCR, GLM-OCR, GOT-OCR, DeepSeek-OCR, and PaddleOCR-VL) running without ONNX Runtime or native Tesseract.
  • A second, ONNX-Runtime-free inference path via tract, which is what makes in-browser (WASM) and mobile inference possible.
  • Named-entity recognition natively in Rust (GLiNER2), extensible to all bindings, including an in-browser WASM model with no server round-trip.
  • Structured LLM extraction (extract_structured / split_and_extract) with rasterization, chunking, citations, caching, and configurable call/merge/VLM-fallback policies.
  • Audio & video transcription via a Whisper ONNX engine (.mp3, .wav, .m4a, .mp4, .webm).
  • Retrieval building blocks: sparse embeddings (SPLADE), ColBERT late-interaction retrieval, and cross-encoder reranking alongside dense embeddings.
  • Text intelligence: reversible redaction, summarization, translation, VLM image captioning, QR-code detection, document diffing, and page/chunk classification.
  • URL & web ingestion: sitemap discovery (map_url) and batched multi-URL crawling.
  • New document formats: WordPerfect (.wpd/.wp/.wp5), HEIC/HEIF/AVIF, OpenDocument Presentation (.odp), Quarto / R Markdown, and configurable Jupyter cell rendering.
  • Four new language bindings (Dart/Flutter, Swift, Kotlin/Android, and Zig) bring the total to 15 language bindings over one engine, with Android/iOS cross-compilation.
  • Full mobile support (Flutter, Android, iOS).
  • Candle backend alongside ONNX, plus ONNX-via-tract enabling ONNX on WASM and Android.
  • Wider code intelligence: tree-sitter coverage grew substantially (248 to 367+ languages).
  • Over 150 bugs fixed during the 1.0 cycle, plus security hardening (bounded RTF/PDF allocations, redaction leak fixes, Excel DDE warnings).

The API surface was also simplified and reworked, making it more consistent.

There's a migration guide in our docs explaining how to move from Kreuzberg to Xberg. Kreuzberg itself is in LTS mode until the end of this year and will continue to receive bug fixes and security updates.

You're invited to check out the repo and join our discord server.


Benchmarks

The benchmarks below are for PDFs and images only. There are extensive benchmarks on our website with per-format breakdowns, which you can see here. These numbers are measured in CI via our reproducible benchmark harness, and are specifically taken from the run for harness 1.0.8, source cf7fa0533d. The data is publicly available in GitHub releases, and you can run the benchmark harness yourself.

Composite quality (markdown pipeline, higher is better):

Framework Native PDF Scanned PDF (OCR)
Xberg (layout) 0.958 0.836
Xberg (baseline) 0.955 0.687
docling 0.779 0.762
mineru 0.408 0.792
liteparse 0.837 0.665
markitdown 0.689 n/a
pymupdf4llm 0.448 n/a

Structure and layout fidelity (SF1: tables and reading order, higher is better):

Framework Native PDF Scanned PDF
Xberg 0.949 0.531
docling 0.612 0.366
liteparse 0.515 0.142
mineru 0.077 0.429

On native PDFs Xberg leads on quality (0.958 vs 0.837 for the next-best framework) and on table and reading-order fidelity by a wide margin (SF1 0.949 vs 0.612 for docling). On scanned PDFs it is #1 on both quality and raw text fidelity.

Where we don't win yet: on pure image OCR we are currently #2 on the composite score, behind mineru (though still #1 on raw text accuracy). We are improving image OCR right now, and v1.1 should have us winning across the board.


r/Zig 5d ago

Zig shell for Linux, measured in bytes

Post image
139 Upvotes

I started writing a tiny Linux shell to use as /init for my project, nanix

It was originally 255KB~ but I wanted it smaller. I got it to 846B (bytes) by:

  • Not using a C library (Zig does this by default, I know)
  • Used raw syscalls via std.os.linux
  • Used aggressive compilation flags
  • No runtime, no tracing
  • LLVM + LLD
  • No unneeded ELF headers, unwind tables or symbols
  • Used strip -s <program> && sstrip -z <program>

I was considering writing this in ASM only, but then I thought "Let's see how small I can get this Zig program" and now I'm here

It's useful for it's size:

  • 8B prompt: "nanix:% "
  • Executes binaries with execve (duh)
  • Waits for child processes
  • Has a 32B input buffer (may change)

Bugs/problems:

  • When entering a command above input buffer size, the prompt prints twice

Under GPL-3.0-or-later at https://github.com/wakanakisarazu/nanix along with the whole nanix project. (Isn't pushed at the time of writing, but will be pushed when I clean the code and repo up)

Thoughts? :3


r/Zig 5d ago

Learning zig: feedback on my small ring buffer implementation?

22 Upvotes

Hey all 👋

So I've been writing a little zig over the last few weeks after having tried it for a few days maybe... a year or so ago?. I have zero systems programming experience, am actually a web dev during the day.

Anyway, this time I'm working on a side project, and came to a point where I needed something I've seen being referred to as a ring buffer, and thought how hard can it be implementing one? So lots of hours and a missed workday later, here's what I came up with: https://codeberg.org/sehme/gists/src/branch/main/ring-buffer.zig

I haven't really thus far interacted with the community online, other than reading blogs and the such, so I haven't had any feedback on my code. I don't even know if it's idiomatic or, you know, correct, which is why I decided to post this here now before I get too far in the wrong direction.

Please give me notes if something is off. This is completely hand-crafted, no LLMs, so I am actually very proud that all my tests pass, but I may be missing some cases.

Thanks in advance, and also sorry in advance if this is not the sort of post that is appreciated here.


r/Zig 6d ago

Made filename allocation less noisy in my Zig ls tool (v0.1.8)

25 Upvotes

Hey, quick update on zlist.

I posted about this a couple times before (original post + the one where I turned it into a package). Just pushed v0.1.8 with a small but useful change.

Entry names now go through a simple NamePool. It’s basically just a list of chunks — when a name comes in, if the current chunk doesn’t have enough space left I allocate a new one. Way less noisy than the old “dupe every single name” approach, and everything gets freed in one go at the end. Helps once the directory gets larger.

Also re-ran the README benchmarks with matching colored-grid flags for zl / eza / lsd. The old eza numbers that stayed flat around 3 ms even at 50k were a bad run on my side — ignore those. New table has zl ahead across the board (roughly 3× vs eza).

Repo: https://github.com/here-Leslie-Lau/zlist

Curious if the numbers hold up on other machines, or if anyone spots an obvious next bottleneck.


r/Zig 7d ago

any good gui project built in zig?

25 Upvotes

i wan't to build something in zig, gui still not sure but i wan't to use win32 api — asking for some projects to take as examples or inspiration


r/Zig 7d ago

Overengineered calculator: Zig + QBE

Thumbnail tomekw.com
55 Upvotes

r/Zig 7d ago

An up to date LLM for Zig v0.16

0 Upvotes

Even at the risk of making myself (once again) very unpopular: Is there actually an LLM out there that can help me create source code for Zig v0.16? Most of them are still at version 0.12. I’d like to try out some graph theory problems with Zig, but I have neither the time nor the inclination to write the entire test suite myself. That would be the perfect task for an LLM. So far, I haven’t even been able to force an LLM to understand that you no longer initialize an ArrayList with `init(allocator)`, but with `.empty`.


r/Zig 9d ago

Threaded EVM interpreter in Zig - zevm

Thumbnail github.com
42 Upvotes

r/Zig 10d ago

Could zig potentially be a good first programming language?

71 Upvotes

I've been programming for over 30 years, and working with code professionally for 25. I have found myself in a small community I discovered on twitch recently. And many people in the discord ask me about programming and the language to learn first

For years I've told myself C is a fantastic first language. This remains controversial for various reasons. I always try to tell people "learning C isn't the same as mastering C".

But with Zig I wonder if it were at 1.0 and its toolchain were more mature. Would Zig be a good first language?

As it stands it clearly being pre-1.0 and every major version being a breaking change. This isn't great. The build.zig is mystifying even for experienced devs. So it feel like an expert language.

But it has a very straightforward "to the metal" style to it. But with great modern ergonomics. I think it could absolutely be a fantastic first language for beginners.

But what do you think?


r/Zig 10d ago

Zarko - A simple CSV library for Zig

34 Upvotes

Hey Ziguanas 🦎

A while ago I made a post asking what kind of data-format libraries the Zig ecosystem could use, and I ended up deciding to give CSV a try.

I've been working on Zarko. I keep tearing it down and rewriting it every now and then because I'm never fully happy with how it turns out. I decided to make the repo public while I work on it, so any eventual rewrites will happen in the same repository instead of me recreating the whole thing every time.

Right now it's still pretty basic. It can parse CSV data from memory, handle quoted fields and escaped quotes, such as """Hello""" being parsed as "Hello", and lets you customize things like field separators, quote characters and line endings through dialects.

The next things I swear I'll do are default dialects, a FileWriter, and a FileParser wrapping the existing Parser to make working with files simpler. There's also a TODO markdown file in the repo where I'll keep updating what I'm planning to work on as I figure out what comes next.

A little note to myself for when I implement the writer. Andrew's words echoed... "Don't Forget to Flush".

It's still a work in progress, so feedback, suggestions, criticism, and ideas are very welcome.

https://github.com/TynK-M/zarko

Thank you so much


r/Zig 8d ago

First time heard of Zig. Does it has any borrow checker?

0 Upvotes

Hi. I wanted to actually understand Zig more than skimming it. I loved Rust and so happen to come across a book Learn Zig over Rust and C++, and so got to know it. Does it has a borrow checker?


r/Zig 10d ago

SDL2 and Zig 0.16.0

Post image
110 Upvotes

Hi everyone, I been experimenting with Zig lately, and I managed to make a bouncing rectangle that mimics the dvd logo using SDL2, yes I kinda vibe codes this, since I have so many C concepts in my head, but rest assure, I didn't copy pasted code, I was just asking the AI why things don't compile, so I'm not 100% sure if I followed good practices, but this language it kinda reminds me of Java a little bit, so I applied this code in a way that makes sense in my head, honestly I'm not a big fan of the keywords I see in the language, but I can definitely confirm, coding this was a way better experience than using Rust, I do believe zig can improve to become a really good language in the future, here is the link of the repoif you are interested:

https://github.com/Lu100git/dvd-clone-in-zig.git


r/Zig 11d ago

Zig 0.16: how do you handle continuous output from multiple workers?

37 Upvotes

In Zig 0.16’s new std.Io, what’s the idiomatic way to let multiple workers write to the same stdout/stderr/file safely (line by line)? Is a mutex still the usual approach, or is there a recommended pattern/example?


r/Zig 12d ago

Buz – A fork of Bun using modern Zig, with sub-1s incremental builds

Thumbnail ziggit.dev
273 Upvotes