<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    
    <title>GitHub C Weekly Trending Repositories</title>
    <description>Weekly Trending Repositories of C on GitHub</description>
    
    <pubDate>Mon, 17 Aug 2026 02:17:09 GMT</pubDate>
    <link>https://mshibanami.github.io/GitHubTrendingRSS</link>
    
    <item>
      <title>opa334/Dopamine</title>
      <link>https://github.com/opa334/Dopamine</link>
      <description>&lt;p&gt;Dopamine is a semi-untethered jailbreak for iOS 15 to 26(.0.1)&lt;/p&gt;&lt;hr&gt;&lt;img src=&quot;https://github.com/opa334/Dopamine/assets/52459150/ed04dd3e-d879-456d-9aa3-d4ed44819c7e&quot; width=&quot;64&quot; /&gt; 
&lt;h1&gt;Dopamine&lt;/h1&gt; 
&lt;p&gt;A rootless semi-untethered jailbreak for iOS 15.0 - 17.3.1 (arm64e), iOS 15.0 - 18.7.1, 26.0 - 26.0.1 (A12/A13) and iOS 15.0 - 18.7.1 (arm64). More details will follow here soon.&lt;/p&gt; 
&lt;p&gt;Please note that all issues related to version support will be deleted without response.&lt;/p&gt; 
&lt;p&gt;Official website / download: &lt;a href=&quot;https://ellekit.space/dopamine/&quot;&gt;https://ellekit.space/dopamine/&lt;/a&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>meshcore-dev/MeshCore</title>
      <link>https://github.com/meshcore-dev/MeshCore</link>
      <description>&lt;p&gt;A new lightweight, hybrid routing mesh protocol for packet radios&lt;/p&gt;&lt;hr&gt;&lt;h2&gt;About MeshCore&lt;/h2&gt; 
&lt;p&gt;MeshCore is a lightweight, portable C++ library that enables multi-hop packet routing for embedded projects using LoRa and other packet radios. It is designed for developers who want to create resilient, decentralized communication networks that work without the internet.&lt;/p&gt; 
&lt;h2&gt;🔍 What is MeshCore?&lt;/h2&gt; 
&lt;p&gt;MeshCore now supports a range of LoRa devices, allowing for easy flashing without the need to compile firmware manually. Users can flash a pre-built binary using tools like Adafruit ESPTool and interact with the network through a serial console. MeshCore provides the ability to create wireless mesh networks, similar to Meshtastic and Reticulum but with a focus on lightweight multi-hop packet routing for embedded projects. Unlike Meshtastic, which is tailored for casual LoRa communication, or Reticulum, which offers advanced networking, MeshCore balances simplicity with scalability, making it ideal for custom embedded solutions, where devices (nodes) can communicate over long distances by relaying messages through intermediate nodes. This is especially useful in off-grid, emergency, or tactical situations where traditional communication infrastructure is unavailable.&lt;/p&gt; 
&lt;h2&gt;⚡ Key Features&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Multi-Hop Packet Routing 
  &lt;ul&gt; 
   &lt;li&gt;Devices can forward messages across multiple nodes, extending range beyond a single radio&#39;s reach.&lt;/li&gt; 
   &lt;li&gt;Supports up to a configurable number of hops to balance network efficiency and prevent excessive traffic.&lt;/li&gt; 
   &lt;li&gt;Nodes use fixed roles where &quot;Companion&quot; nodes are not repeating messages at all to prevent adverse routing paths from being used.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Supports LoRa Radios – Works with Heltec, RAK Wireless, and other LoRa-based hardware.&lt;/li&gt; 
 &lt;li&gt;Decentralized &amp;amp; Resilient – No central server or internet required; the network is self-healing.&lt;/li&gt; 
 &lt;li&gt;Low Power Consumption – Ideal for battery-powered or solar-powered devices.&lt;/li&gt; 
 &lt;li&gt;Simple to Deploy – Pre-built example applications make it easy to get started.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;🎯 What Can You Use MeshCore For?&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Off-Grid Communication: Stay connected even in remote areas.&lt;/li&gt; 
 &lt;li&gt;Emergency Response &amp;amp; Disaster Recovery: Set up instant networks where infrastructure is down.&lt;/li&gt; 
 &lt;li&gt;Outdoor Activities: Hiking, camping, and adventure racing communication.&lt;/li&gt; 
 &lt;li&gt;Tactical &amp;amp; Security Applications: Military, law enforcement, and private security use cases.&lt;/li&gt; 
 &lt;li&gt;IoT &amp;amp; Sensor Networks: Collect data from remote sensors and relay it back to a central location.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;🚀 How to Get Started&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Watch the &lt;a href=&quot;https://www.youtube.com/watch?v=iaFltojJrAc&amp;amp;list=PLshzThxhw4O4WU_iZo3NmNZOv6KMrUuF9&quot;&gt;MeshCore QuickStart Playlist&lt;/a&gt; by The Comms Channel&lt;/li&gt; 
 &lt;li&gt;Watch the &lt;a href=&quot;https://www.youtube.com/watch?v=OwmkVkZQTf4&quot;&gt;MeshCore Technical Presentation&lt;/a&gt; by Liam Cottle.&lt;/li&gt; 
 &lt;li&gt;Read through our &lt;a href=&quot;https://raw.githubusercontent.com/meshcore-dev/MeshCore/main/docs/faq.md&quot;&gt;Frequently Asked Questions&lt;/a&gt; and &lt;a href=&quot;https://docs.meshcore.io&quot;&gt;Documentation&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Flash the MeshCore firmware on a supported device.&lt;/li&gt; 
 &lt;li&gt;Connect with a supported client.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;For developers:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Install &lt;a href=&quot;https://docs.platformio.org&quot;&gt;PlatformIO&lt;/a&gt; in &lt;a href=&quot;https://code.visualstudio.com&quot;&gt;Visual Studio Code&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Clone and open the MeshCore repository in Visual Studio Code.&lt;/li&gt; 
 &lt;li&gt;See the example applications you can modify and run: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/meshcore-dev/MeshCore/main/examples/companion_radio&quot;&gt;Companion Radio&lt;/a&gt; - For use with an external chat app, over BLE, USB or Wi-Fi.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/meshcore-dev/MeshCore/main/examples/kiss_modem&quot;&gt;KISS Modem&lt;/a&gt; - Serial KISS protocol bridge for host applications. (&lt;a href=&quot;https://raw.githubusercontent.com/meshcore-dev/MeshCore/main/docs/kiss_modem_protocol.md&quot;&gt;protocol docs&lt;/a&gt;)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/meshcore-dev/MeshCore/main/examples/simple_repeater&quot;&gt;Simple Repeater&lt;/a&gt; - Extends network coverage by relaying messages.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/meshcore-dev/MeshCore/main/examples/simple_room_server&quot;&gt;Simple Room Server&lt;/a&gt; - A simple BBS server for shared Posts.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/meshcore-dev/MeshCore/main/examples/simple_secure_chat&quot;&gt;Simple Secure Chat&lt;/a&gt; - Secure terminal based text communication between devices.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/meshcore-dev/MeshCore/main/examples/simple_sensor&quot;&gt;Simple Sensor&lt;/a&gt; - Remote sensor node with telemetry and alerting.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The Simple Secure Chat example can be interacted with through the Serial Monitor in Visual Studio Code, or with a Serial USB Terminal on Android.&lt;/p&gt; 
&lt;h2&gt;⚡️ MeshCore Flasher&lt;/h2&gt; 
&lt;p&gt;We have prebuilt firmware ready to flash on supported devices.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Launch &lt;a href=&quot;https://meshcore.io/flasher&quot;&gt;https://meshcore.io/flasher&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Select a supported device&lt;/li&gt; 
 &lt;li&gt;Flash one of the firmware types: 
  &lt;ul&gt; 
   &lt;li&gt;Companion, Repeater or Room Server&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Once flashing is complete, you can connect with one of the MeshCore clients below.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;📱 MeshCore Clients&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Companion Firmware&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;The companion firmware can be connected to via BLE, USB or Wi-Fi depending on the firmware type you flashed.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Web: &lt;a href=&quot;https://app.meshcore.nz&quot;&gt;https://app.meshcore.nz&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Android: &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.liamcottle.meshcore.android&quot;&gt;https://play.google.com/store/apps/details?id=com.liamcottle.meshcore.android&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;iOS: &lt;a href=&quot;https://apps.apple.com/us/app/meshcore/id6742354151?platform=iphone&quot;&gt;https://apps.apple.com/us/app/meshcore/id6742354151?platform=iphone&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;NodeJS: &lt;a href=&quot;https://github.com/liamcottle/meshcore.js&quot;&gt;https://github.com/liamcottle/meshcore.js&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Python: &lt;a href=&quot;https://github.com/fdlamotte/meshcore-cli&quot;&gt;https://github.com/fdlamotte/meshcore-cli&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Repeater and Room Server Firmware&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;The repeater and room server firmware can be set up via USB in the web config tool.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://config.meshcore.io&quot;&gt;https://config.meshcore.io&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;They can also be managed via LoRa in the mobile app by using the Remote Management feature.&lt;/p&gt; 
&lt;h2&gt;🛠 Hardware Compatibility&lt;/h2&gt; 
&lt;p&gt;MeshCore is designed for devices listed in the &lt;a href=&quot;https://meshcore.io/flasher&quot;&gt;MeshCore Flasher&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;📜 License&lt;/h2&gt; 
&lt;p&gt;MeshCore is open-source software released under the MIT License. You are free to use, modify, and distribute it for personal and commercial projects.&lt;/p&gt; 
&lt;h2&gt;Contributing&lt;/h2&gt; 
&lt;p&gt;Please submit PR&#39;s using &#39;dev&#39; as the base branch! For minor changes just submit your PR and we&#39;ll try to review it, but for anything more &#39;impactful&#39; please open an Issue first and start a discussion. It is better to sound out what it is you want to achieve first, and try to come to a consensus on what the best approach is, especially when it impacts the structure or architecture of this codebase.&lt;/p&gt; 
&lt;p&gt;Here are some general principles you should try to adhere to:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Keep it simple. Please, don&#39;t think like a high-level lang programmer. Think embedded, and keep code concise, without any unnecessary layers.&lt;/li&gt; 
 &lt;li&gt;No dynamic memory allocation, except during setup/begin functions.&lt;/li&gt; 
 &lt;li&gt;Use the same brace and indenting style that&#39;s in the core source modules. (A .clang-format is probably going to be added soon, but please do NOT retroactively re-format existing code. This just creates unnecessary diffs that make finding problems harder)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Help us prioritize! Please react with thumbs-up to issues/PRs you care about most. We look at reaction counts when planning work.&lt;/p&gt; 
&lt;h3&gt;Running unit tests&lt;/h3&gt; 
&lt;p&gt;To run unit tests, run the following command:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pio test --environment native --verbose
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Road-Map / To-Do&lt;/h2&gt; 
&lt;p&gt;There are a number of fairly major features in the pipeline, with no particular time-frames attached yet. In very rough chronological order:&lt;/p&gt; 
&lt;ul class=&quot;task-list&quot;&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_0&quot; checked=&quot;true&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_0&quot;&gt; Companion radio: UI redesign&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_1&quot; checked=&quot;true&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_1&quot;&gt; Repeater + Room Server: add ACL&#39;s (like Sensor Node has)&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_2&quot; checked=&quot;true&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_2&quot;&gt; Standardise Bridge mode for repeaters&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_3&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_3&quot;&gt; Repeater/Bridge: Standardise the Transport Codes for zoning/filtering&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_4&quot; checked=&quot;true&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_4&quot;&gt; Core + Repeater: enhanced zero-hop neighbour discovery&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_5&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_5&quot;&gt; Core: round-trip manual path support&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_6&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_6&quot;&gt; Companion + Apps: support for multiple sub-meshes (and &#39;off-grid&#39; client repeat mode)&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_7&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_7&quot;&gt; Core + Apps: support for LZW message compression&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_8&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_8&quot;&gt; Core: dynamic CR (Coding Rate) for weak vs strong hops&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_9&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_9&quot;&gt; Core: new framework for hosting multiple virtual nodes on one physical device&lt;/label&gt;&lt;/li&gt; 
 &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; id=&quot;cbx_10&quot; disabled=&quot;true&quot; /&gt;&lt;label for=&quot;cbx_10&quot;&gt; V2 protocol spec: discussion and consensus around V2 packet protocol, including path hashes, new encryption specs, etc&lt;/label&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;📞 Get Support&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Report bugs and request features on the &lt;a href=&quot;https://github.com/ripplebiz/MeshCore/issues&quot;&gt;GitHub Issues&lt;/a&gt; page.&lt;/li&gt; 
 &lt;li&gt;Find additional guides and components on &lt;a href=&quot;https://buymeacoffee.com/ripplebiz&quot;&gt;my site&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Join &lt;a href=&quot;https://meshcore.gg&quot;&gt;MeshCore Discord&lt;/a&gt; to chat with the developers and get help from the community.&lt;/li&gt; 
&lt;/ul&gt;</description>
      
    </item>
    
    <item>
      <title>nicbarker/clay</title>
      <link>https://github.com/nicbarker/clay</link>
      <description>&lt;p&gt;High performance UI layout library in C.&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;Clay, A UI Layout Library&lt;/h1&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Clay&lt;/em&gt;&lt;/strong&gt; (short for &lt;strong&gt;C Layout&lt;/strong&gt;) is a high performance 2D UI layout library.&lt;/p&gt; 
&lt;h3&gt;Major Features&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Microsecond layout performance&lt;/li&gt; 
 &lt;li&gt;Flex-box like layout model for complex, responsive layouts including text wrapping, scrolling containers and aspect ratio scaling&lt;/li&gt; 
 &lt;li&gt;Transition API for easy layout animations&lt;/li&gt; 
 &lt;li&gt;Single 4.8k LOC &lt;strong&gt;clay.h&lt;/strong&gt; file with &lt;strong&gt;zero&lt;/strong&gt; dependencies (including no standard library linking)&lt;/li&gt; 
 &lt;li&gt;Wasm support: compile with clang to a 15kb uncompressed &lt;strong&gt;.wasm&lt;/strong&gt; file for use in the browser&lt;/li&gt; 
 &lt;li&gt;Static arena based memory use with no malloc / free, and low total memory overhead (e.g. ~3.5mb for 8192 layout elements).&lt;/li&gt; 
 &lt;li&gt;React-like nested declarative syntax&lt;/li&gt; 
 &lt;li&gt;Renderer agnostic: outputs a sorted list of rendering primitives that can be easily composited in any 3D engine, and even compiled to HTML (examples provided)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Take a look at the &lt;a href=&quot;https://nicbarker.com/clay&quot;&gt;clay website&lt;/a&gt; for an example of clay compiled to wasm and running in the browser, or others in the &lt;a href=&quot;https://github.com/nicbarker/clay/tree/main/examples&quot;&gt;examples directory&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;You can also watch the &lt;a href=&quot;https://youtu.be/DYWTw19_8r4&quot;&gt;introduction video&lt;/a&gt; for an overview of the motivation behind Clay&#39;s development and a short demo of its usage.&lt;/p&gt; 
&lt;img width=&quot;1394&quot; alt=&quot;A screenshot of a code IDE with lots of visual and textual elements&quot; src=&quot;https://github.com/user-attachments/assets/9986149a-ee0f-449a-a83e-64a392267e3d&quot; /&gt; 
&lt;p&gt;&lt;em&gt;An example GUI application built with clay&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;Quick Start&lt;/h2&gt; 
&lt;p&gt;Download or clone clay.h and include it after defining &lt;code&gt;CLAY_IMPLEMENTATION&lt;/code&gt; in one file.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Must be defined in one file, _before_ #include &quot;clay.h&quot;
#define CLAY_IMPLEMENTATION
#include &quot;../../clay.h&quot;

const Clay_Color COLOR_LIGHT = (Clay_Color) {224, 215, 210, 255};
const Clay_Color COLOR_RED = (Clay_Color) {168, 66, 28, 255};
const Clay_Color COLOR_ORANGE = (Clay_Color) {225, 138, 50, 255};

void HandleClayErrors(Clay_ErrorData errorData) {
    // See the Clay_ErrorData struct for more information
    printf(&quot;%s&quot;, errorData.errorText.chars);
    switch(errorData.errorType) {
        // etc
    }
}

// Example measure text function
static inline Clay_Dimensions MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData) {
    // Clay_TextElementConfig contains members such as fontId, fontSize, letterSpacing etc
    // Note: Clay_String-&amp;gt;chars is not guaranteed to be null terminated
    return (Clay_Dimensions) {
            .width = text.length * config-&amp;gt;fontSize, // &amp;lt;- this will only work for monospace fonts, see the renderers/ directory for more advanced text measurement
            .height = config-&amp;gt;fontSize
    };
}

// Layout config is just a struct that can be declared statically, or inline
Clay_ElementDeclaration sidebarItemConfig = (Clay_ElementDeclaration) {
    .layout = {
        .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(50) }
    },
    .backgroundColor = COLOR_ORANGE
};

// Re-useable components are just normal functions
void SidebarItemComponent() {
    CLAY(id, sidebarItemConfig) {
        // children go here...
    }
}

int main() {
    // Note: malloc is only used here as an example, any allocator that provides
    // a pointer to addressable memory of at least totalMemorySize will work
    uint64_t totalMemorySize = Clay_MinMemorySize();
    Clay_Arena arena = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));

    // Note: screenWidth and screenHeight will need to come from your environment, Clay doesn&#39;t handle window related tasks
    Clay_Initialize(arena, (Clay_Dimensions) { screenWidth, screenHeight }, (Clay_ErrorHandler) { HandleClayErrors });

    while(renderLoop()) { // Will be different for each renderer / environment
        // Optional: Update internal layout dimensions to support resizing
        Clay_SetLayoutDimensions((Clay_Dimensions) { screenWidth, screenHeight });
        // Optional: Update internal pointer position for handling mouseover / click / touch events - needed for scrolling &amp;amp; debug tools
        Clay_SetPointerState((Clay_Vector2) { mousePositionX, mousePositionY }, isMouseDown);
        // Optional: Update internal pointer position for handling mouseover / click / touch events - needed for scrolling and debug tools
        Clay_UpdateScrollContainers(true, (Clay_Vector2) { mouseWheelX, mouseWheelY }, deltaTime);

        // All clay layouts are declared between Clay_BeginLayout and Clay_EndLayout
        Clay_BeginLayout();

        // An example of laying out a UI with a fixed width sidebar and flexible width main content
        CLAY(CLAY_ID(&quot;OuterContainer&quot;), { .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }, .backgroundColor = {250,250,255,255} }) {
            CLAY(CLAY_ID(&quot;SideBar&quot;), {
                .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 },
                .backgroundColor = COLOR_LIGHT
            }) {
                CLAY(CLAY_ID(&quot;ProfilePictureOuter&quot;), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }, .backgroundColor = COLOR_RED }) {
                    CLAY(CLAY_ID(&quot;ProfilePicture&quot;), { .layout = { .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}, .image = { .imageData = &amp;amp;profilePicture } }) {}
                    CLAY_TEXT(CLAY_STRING(&quot;Clay - UI Library&quot;), { .fontSize = 24, .textColor = {255, 255, 255, 255} });
                }

                // Standard C code like loops etc work inside components
                for (int i = 0; i &amp;lt; 5; i++) {
                    SidebarItemComponent();
                }

                CLAY(CLAY_ID(&quot;MainContent&quot;), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) } }, .backgroundColor = COLOR_LIGHT }) {}
            }
        }

        // All clay layouts are declared between Clay_BeginLayout and Clay_EndLayout
        Clay_RenderCommandArray renderCommands = Clay_EndLayout(deltaTime); // deltaTime is the time since the last frame, and is used for transitions

        // More comprehensive rendering examples can be found in the renderers/ directory
        for (int i = 0; i &amp;lt; renderCommands.length; i++) {
            Clay_RenderCommand *renderCommand = &amp;amp;renderCommands.internalArray[i];

            switch (renderCommand-&amp;gt;commandType) {
                case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
                    DrawRectangle(renderCommand-&amp;gt;boundingBox, renderCommand-&amp;gt;renderData.rectangle.backgroundColor);
                }
                // ... Implement handling of other command types
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The above example, rendered correctly will look something like the following:&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/1928c6d4-ada9-4a4c-a3d1-44fe9b23b3bd&quot; alt=&quot;Clay Example&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;In summary, the general order of steps is:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setlayoutdimensions&quot;&gt;Clay_SetLayoutDimensions(dimensions)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setpointerstate&quot;&gt;Clay_SetPointerState(pointerPosition, isPointerDown)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_updatescrollcontainers&quot;&gt;Clay_UpdateScrollContainers(enableDragScrolling, scrollDelta, deltaTime)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_beginlayout&quot;&gt;Clay_BeginLayout()&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Declare your layout with the provided &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#element-macros&quot;&gt;Element Macros&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_endlayout&quot;&gt;Clay_EndLayout()&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Render the results using the outputted &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_rendercommandarray&quot;&gt;Clay_RenderCommandArray&lt;/a&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;For help starting out or to discuss clay, considering joining &lt;a href=&quot;https://discord.gg/b4FTWkxdvT&quot;&gt;the discord server.&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Summary&lt;/h2&gt; 
&lt;!-- TOC --&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#high-level-documentation&quot;&gt;High Level Documentation&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#building-ui-hierarchies&quot;&gt;Building UI Hierarchies&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#configuring-layout-and-styling-ui-elements&quot;&gt;Configuring Layout and Styling UI Elements&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#element-ids&quot;&gt;Element IDs&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#mouse-touch-and-pointer-interactions&quot;&gt;Mouse, Touch and Pointer Interactions&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#scrolling-elements&quot;&gt;Scrolling Elements&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#floating-elements-absolute-positioning&quot;&gt;Floating Elements (&quot;Absolute&quot; Positioning)&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#laying-out-your-own-custom-elements&quot;&gt;Laying Out Your Own Custom Elements&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#transitions&quot;&gt;Transitions&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#retained-mode-rendering&quot;&gt;Retained Mode Rendering&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#visibility-culling&quot;&gt;Visibility Culling&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#preprocessor-directives&quot;&gt;Preprocessor Directives&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#bindings-for-non-c&quot;&gt;Bindings for non C&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#other-implementations&quot;&gt;Other implementations&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#debug-tools&quot;&gt;Debug Tools&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#running-more-than-one-clay-instance&quot;&gt;Running more than one Clay instance&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#api&quot;&gt;API&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#naming-conventions&quot;&gt;Naming Conventions&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#public-functions&quot;&gt;Public Functions&lt;/a&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#lifecycle-for-public-functions&quot;&gt;Lifecycle for public functions&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_minmemorysize&quot;&gt;Clay_MinMemorySize&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_createarenawithcapacityandmemory&quot;&gt;Clay_CreateArenaWithCapacityAndMemory&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setmeasuretextfunction&quot;&gt;Clay_SetMeasureTextFunction&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_resetmeasuretextcache&quot;&gt;Clay_ResetMeasureTextCache&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setmaxelementcount&quot;&gt;Clay_SetMaxElementCount&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setmaxmeasuretextcachewordcount&quot;&gt;Clay_SetMaxMeasureTextCacheWordCount&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_initialize&quot;&gt;Clay_Initialize&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setcurrentcontext&quot;&gt;Clay_SetCurrentContext&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_getcurrentcontext&quot;&gt;Clay_GetCurrentContext&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setlayoutdimensions&quot;&gt;Clay_SetLayoutDimensions&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setpointerstate&quot;&gt;Clay_SetPointerState&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_updatescrollcontainers&quot;&gt;Clay_UpdateScrollContainers&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_getscrolloffset&quot;&gt;Clay_GetScrollOffset&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_beginlayout&quot;&gt;Clay_BeginLayout&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_endlayout&quot;&gt;Clay_EndLayout&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_hovered&quot;&gt;Clay_Hovered&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_onhover&quot;&gt;Clay_OnHover&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_pointerover&quot;&gt;Clay_PointerOver&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_getopenelementid&quot;&gt;Clay_GetOpenElementId&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_getscrollcontainerdata&quot;&gt;Clay_GetScrollContainerData&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_getelementdata&quot;&gt;Clay_GetElementData&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_getelementid&quot;&gt;Clay_GetElementId&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#element-macros&quot;&gt;Element Macros&lt;/a&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay&quot;&gt;CLAY()&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_auto_id&quot;&gt;CLAY_AUTO_ID()&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_text&quot;&gt;CLAY_TEXT()&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id&quot;&gt;CLAY_ID()&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_sid&quot;&gt;CLAY_SID()&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_idi&quot;&gt;CLAY_IDI()&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_sidi&quot;&gt;CLAY_SIDI()&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id_local&quot;&gt;CLAY_ID_LOCAL()&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_sid_local&quot;&gt;CLAY_SID_LOCAL()&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_idi_local&quot;&gt;CLAY_IDI_LOCAL()&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_sidi_local&quot;&gt;CLAY_SIDI_LOCAL()&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#data-structures--definitions&quot;&gt;Data Structures &amp;amp; Definitions&lt;/a&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementdeclaration&quot;&gt;Clay_ElementDeclaration&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_layoutconfig&quot;&gt;Clay_LayoutConfig&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_imageelementconfig&quot;&gt;Clay_ImageElementConfig&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_aspectratioelementconfig&quot;&gt;Clay_AspectRatioElementConfig&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_imageelementconfig-1&quot;&gt;Clay_ImageElementConfig&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_clipelementconfig&quot;&gt;Clay_ClipElementConfig&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_borderelementconfig&quot;&gt;Clay_BorderElementConfig&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_floatingelementconfig&quot;&gt;Clay_FloatingElementConfig&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_customelementconfig&quot;&gt;Clay_CustomElementConfig&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_transitionelementconfig&quot;&gt;Clay_TransitionElementConfig&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_color&quot;&gt;Clay_Color&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_string&quot;&gt;Clay_String&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementid&quot;&gt;Clay_ElementId&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_rendercommandarray&quot;&gt;Clay_RenderCommandArray&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_rendercommand&quot;&gt;Clay_RenderCommand&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_scrollcontainerdata&quot;&gt;Clay_ScrollContainerData&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementdata&quot;&gt;Clay_ElementData&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_pointerdata&quot;&gt;Clay_PointerData&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_errorhandler&quot;&gt;Clay_ErrorHandler&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_errordata&quot;&gt;Clay_ErrorData&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;!-- TOC --&gt; 
&lt;h2&gt;High Level Documentation&lt;/h2&gt; 
&lt;h3&gt;Building UI Hierarchies&lt;/h3&gt; 
&lt;p&gt;Clay UIs are built using the C macro &lt;code&gt;CLAY(id, { configuration })&lt;/code&gt;. This macro creates a new empty element in the UI hierarchy, and supports modular customisation of layout, styling and functionality. The &lt;code&gt;CLAY()&lt;/code&gt; macro can also be &lt;em&gt;nested&lt;/em&gt;, similar to other declarative UI systems like HTML.&lt;/p&gt; 
&lt;p&gt;Child elements are added by opening a block: &lt;code&gt;{}&lt;/code&gt; after calling the &lt;code&gt;CLAY()&lt;/code&gt; macro (exactly like you would with an &lt;code&gt;if&lt;/code&gt; statement or &lt;code&gt;for&lt;/code&gt; loop), and declaring child components inside the braces.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Parent element with 8px of padding
CLAY(CLAY_ID(&quot;parent&quot;), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
    // Child element 1
    CLAY_TEXT(CLAY_STRING(&quot;Hello World&quot;), { .fontSize = 16 });
    // Child element 2 with red background
    CLAY((CLAY_ID(&quot;child&quot;), { .backgroundColor = COLOR_RED }) {
        // etc
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;However, unlike HTML and other declarative DSLs, this macro is just C. As a result, you can use arbitrary C code such as loops, functions and conditions inside your layout declaration code:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Re-usable &quot;components&quot; are just functions that declare more UI
void ButtonComponent(Clay_String buttonText) {
    // Red box button with 8px of padding
    CLAY_AUTO_ID({ .layout = { .padding = CLAY_PADDING_ALL(8) }, .backgroundColor = COLOR_RED }) {
        CLAY_TEXT(buttonText, textConfig);
    }
}

// Parent element
CLAY(CLAY_ID(&quot;parent&quot;), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
    // Render a bunch of text elements
    for (int i = 0; i &amp;lt; textArray.length; i++) {
        CLAY_TEXT(textArray.elements[i], textConfig);
    }
    // Only render this element if we&#39;re on a mobile screen
    if (isMobileScreen) {
        CLAY(0) {
            // etc
        }
    }
    // Re-usable components
    ButtonComponent(CLAY_STRING(&quot;Click me!&quot;));
    ButtonComponent(CLAY_STRING(&quot;No, click me!&quot;));
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Configuring Layout and Styling UI Elements&lt;/h3&gt; 
&lt;p&gt;The layout and style of clay elements is configured with the &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementdeclaration&quot;&gt;Clay_ElementDeclaration&lt;/a&gt; struct passed to the &lt;code&gt;CLAY()&lt;/code&gt; macro.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;CLAY(CLAY_ID(&quot;box&quot;), { .layout = { .padding = { 8, 8, 8, 8 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
    // Children are 8px inset into parent, and laid out top to bottom
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This macro isn&#39;t magic - all it&#39;s doing is wrapping the standard designated initializer syntax. e.g. &lt;code&gt;(Clay_ElementDeclaration) { .layout = { .padding = { .left = 8, .right = 8 } ...&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;See the &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementdeclaration&quot;&gt;Clay_ElementDeclaration&lt;/a&gt; API for the full list of options.&lt;/p&gt; 
&lt;p&gt;A &lt;code&gt;Clay_ElementDeclaration&lt;/code&gt; struct can be defined in file scope or elsewhere, and reused.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Define a style in the global / file scope
Clay_ElementDeclaration reuseableStyle = (Clay_ElementDeclaration) {
    .layout = { .padding = { .left = 12 } },
    .backgroundColor = { 120, 120, 120, 255 },
    .cornerRadius = { 12, 12, 12, 12 }
};

CLAY(CLAY_ID(&quot;box&quot;), reuseableStyle) {
    // ...
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Element IDs&lt;/h3&gt; 
&lt;p&gt;The Clay macro by default accepts an ID as its first argument, which is usually provided by the &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id&quot;&gt;CLAY_ID()&lt;/a&gt; convenience macro. Elements can also be created with auto generated IDs, by using the &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay-auto-id&quot;&gt;CLAY_AUTO_ID()&lt;/a&gt; macro.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Will always produce the same ID from the same input string
CLAY(CLAY_ID(&quot;OuterContainer&quot;), { ...configuration }) {}

// Generates a unique ID that may not be the same between two layout calls
CLAY_AUTO_ID({ ...configuration }) {}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Element IDs have two main use cases. Firstly, tagging an element with an ID allows you to query information about the element later, such as its &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_pointerover&quot;&gt;mouseover state&lt;/a&gt; or dimensions.&lt;/p&gt; 
&lt;p&gt;Secondly, IDs are visually useful when attempting to read and modify UI code, as well as when using the built-in &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#debug-tools&quot;&gt;debug tools&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;To avoid having to construct dynamic strings at runtime to differentiate ids in loops, clay provides the &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_idi&quot;&gt;CLAY_IDI(string, index)&lt;/a&gt; macro to generate different ids from a single input string. Think of IDI as &quot;&lt;strong&gt;ID&lt;/strong&gt; + &lt;strong&gt;I&lt;/strong&gt;ndex&quot;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// This is the equivalent of calling CLAY_ID(&quot;Item0&quot;), CLAY_ID(&quot;Item1&quot;) etc
for (int index = 0; index &amp;lt; items.length; index++) {
    CLAY(CLAY_IDI(&quot;Item&quot;, index), { ..configuration }) {}
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This ID will be forwarded to the final &lt;code&gt;Clay_RenderCommandArray&lt;/code&gt; for use in retained mode UIs. Using duplicate IDs may cause some functionality to misbehave (i.e. if you&#39;re trying to attach a floating container to a specific element with ID that is duplicated, it may not attach to the one you expect)&lt;/p&gt; 
&lt;h3&gt;Mouse, Touch and Pointer Interactions&lt;/h3&gt; 
&lt;p&gt;Clay provides several functions for handling mouse and pointer interactions.&lt;/p&gt; 
&lt;p&gt;All pointer interactions depend on the function &lt;code&gt;void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown)&lt;/code&gt; being called after each mouse position update and before any other clay functions.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;During UI declaration&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;The function &lt;code&gt;bool Clay_Hovered()&lt;/code&gt; can be called during element construction or in the body of an element, and returns &lt;code&gt;true&lt;/code&gt; if the mouse / pointer is over the currently open element.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// An orange button that turns blue when hovered
CLAY(CLAY_ID(&quot;Button&quot;), { .backgroundColor = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE }) {
    bool buttonHovered = Clay_Hovered();
    CLAY_TEXT(buttonHovered ? CLAY_STRING(&quot;Hovered&quot;) : CLAY_STRING(&quot;Hover me!&quot;), headerTextConfig);
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The function &lt;code&gt;void Clay_OnHover()&lt;/code&gt; allows you to attach a function pointer to the currently open element, which will be called if the mouse / pointer is over the element.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerInfo, void *userData) {
    ButtonData *buttonData = (ButtonData *)userData;
    // Pointer state allows you to detect mouse down / hold / release
    if (pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
        // Do some click handling
        NavigateTo(buttonData-&amp;gt;link);
    }
}

ButtonData linkButton = (ButtonData) { .link = &quot;https://github.com/nicbarker/clay&quot; };

// HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries
CLAY(CLAY_ID(&quot;Button&quot;), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
    Clay_OnHover(HandleButtonInteraction, &amp;amp;linkButton);
    CLAY_TEXT(CLAY_STRING(&quot;Button&quot;), &amp;amp;headerTextConfig);
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Before / After UI declaration&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;If you want to query mouse / pointer overlaps outside layout declarations, you can use the function &lt;code&gt;bool Clay_PointerOver(Clay_ElementId id)&lt;/code&gt;, which takes an &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#element-ids&quot;&gt;element id&lt;/a&gt; and returns a bool representing whether the current pointer position is within its bounding box.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Reminder: Clay_SetPointerState must be called before functions that rely on pointer position otherwise it will have no effect
Clay_Vector2 mousePosition = { x, y };
Clay_SetPointerState(mousePosition, mouseButtonDown(0));
// ...
// If profile picture was clicked
if (mouseButtonDown(0) &amp;amp;&amp;amp; Clay_PointerOver(Clay_GetElementId(&quot;ProfilePicture&quot;))) {
    // Handle profile picture clicked
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note that the bounding box queried by &lt;code&gt;Clay_PointerOver&lt;/code&gt; is from the last frame. This generally shouldn&#39;t make a difference except in the case of animations that move at high speed. If this is an issue for you, performing layout twice per frame with the same data will give you the correct interaction the second time.&lt;/p&gt; 
&lt;h3&gt;Scrolling Elements&lt;/h3&gt; 
&lt;p&gt;Elements are configured as scrollable with the &lt;code&gt;.clip&lt;/code&gt; configuration. Clipping instructs the renderer to not draw any pixels outside the clipped element&#39;s boundaries, and by specifying the &lt;code&gt;.childOffset&lt;/code&gt; field, the clipped element&#39;s contents can be shifted around to provide &quot;scrolling&quot; behaviour.&lt;/p&gt; 
&lt;p&gt;You can either calculate scrolling yourself and simply provide the current offset each frame to &lt;code&gt;.childOffset&lt;/code&gt;, or alternatively, Clay provides a built in mechanism for tracking and updating scroll container offsets, detailed below.&lt;/p&gt; 
&lt;p&gt;To make scroll containers respond to mouse wheel and scroll events, two functions need to be called before &lt;code&gt;BeginLayout()&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;Clay_Vector2 mousePosition = { x, y };
// Reminder: Clay_SetPointerState must be called before Clay_UpdateScrollContainers otherwise it will have no effect
Clay_SetPointerState(mousePosition);
// Clay_UpdateScrollContainers needs to be called before Clay_BeginLayout for the position to avoid a 1 frame delay
Clay_UpdateScrollContainers(
    true, // Enable drag scrolling
    scrollDelta, // Clay_Vector2 scrollwheel / trackpad scroll x and y delta this frame
    float deltaTime, // Time since last frame in seconds as a float e.g. 8ms is 0.008f
);
// ...
// Clay internally tracks the scroll containers offset, and Clay_GetScrollOffset returns the x,y offset of the currently open element
CLAY(CLAY_ID(&quot;ScrollContainer&quot;), { .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } }) {
    // Scrolling contents
}
// .childOffset can be provided directly if you would prefer to manage scrolling outside of clay
CLAY(CLAY_ID(&quot;ScrollContainer&quot;), { .clip = { .vertical = true, .childOffset = myData.scrollContainer.offset } }) {
    // Scrolling contents
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;More specific details can be found in the docs for &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_updatescrollcontainers&quot;&gt;Clay_UpdateScrollContainers&lt;/a&gt;, &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setpointerstate&quot;&gt;Clay_SetPointerState&lt;/a&gt;, &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_clipelementconfig&quot;&gt;Clay_ClipElementConfig&lt;/a&gt; and &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_getscrolloffset&quot;&gt;Clay_GetScrollOffset&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Floating Elements (&quot;Absolute&quot; Positioning)&lt;/h3&gt; 
&lt;p&gt;All standard elements in clay are laid out on top of, and &lt;em&gt;within&lt;/em&gt; their parent, positioned according to their parent&#39;s layout rules, and affect the positioning and sizing of siblings.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&quot;Floating&quot;&lt;/strong&gt; is configured with the &lt;code&gt;CLAY_FLOATING()&lt;/code&gt; macro. Floating elements don&#39;t affect the parent they are defined in, or the position of their siblings. They also have a &lt;strong&gt;z-index&lt;/strong&gt;, and as a result can intersect and render over the top of other elements.&lt;/p&gt; 
&lt;p&gt;A classic example use case for floating elements is tooltips and modals.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// The two text elements will be laid out top to bottom, and the floating container
// will be attached to &quot;Outer&quot;
CLAY(CLAY_ID(&quot;Outer&quot;), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
    CLAY_TEXT(text, &amp;amp;headerTextConfig);
    CLAY(CLAY_ID(&quot;Tooltip&quot;), { .floating = { .attachTo = CLAY_ATTACH_TO_PARENT } }) {}
    CLAY_TEXT(text, &amp;amp;headerTextConfig);
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;More specific details can be found in the full &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_floatingelementconfig&quot;&gt;Floating API&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Laying Out Your Own Custom Elements&lt;/h3&gt; 
&lt;p&gt;Clay only supports a simple set of UI element primitives, such as rectangles, text and images. Clay provides a singular API for layout out custom elements:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &quot;clay.h&quot;

typedef enum {
    CUSTOM_ELEMENT_TYPE_MODEL,
    CUSTOM_ELEMENT_TYPE_VIDEO
} CustomElementType;

// A rough example of how you could handle laying out 3d models in your UI
typedef struct {
    CustomElementType type;
    union {
        Model model;
        Video video;
        // ...
    };
} CustomElementData;

Model myModel = Load3DModel(filePath);
CustomElement modelElement = (CustomElement) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel }

typedef struct {
    void* memory;
    uintptr_t offset;
} Arena;

// During init
Arena frameArena = (Arena) { .memory = malloc(1024) };

// Custom elements only take a single pointer, so we need to store the data somewhere
CustomElementData *modelData = (CustomElementData *)(frameArena.memory + frameArena.offset);
*modelData = (CustomElementData) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel };
frameArena.offset += sizeof(CustomElementData);
CLAY(CLAY_ID(&quot;3DModelViewer&quot;), { .custom = { .customData = modelData } }) {}

// Later during your rendering
switch (renderCommand-&amp;gt;commandType) {
    // ...
    case CLAY_RENDER_COMMAND_TYPE_CUSTOM: {
        // Your extended struct is passed through
        CustomElementData *customElement = renderCommand-&amp;gt;config.customElementConfig-&amp;gt;customData;
        if (!customElement) continue;
        switch (customElement-&amp;gt;type) {
            case CUSTOM_ELEMENT_TYPE_MODEL: {
                // Render your 3d model here
                break;
            }
            case CUSTOM_ELEMENT_TYPE_VIDEO: {
                // Render your video here
                break;
            }
            // ...
        }
        break;
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;More specific details can be found in the full &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_customelementconfig&quot;&gt;Custom Element API&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Transitions&lt;/h3&gt; 
&lt;p&gt;Clay includes a &quot;Transition&quot; API, which allows you to smoothly animate / tween from one state to another. Both layout-affecting properties such as &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt;, as well as non-layout properties such as &lt;code&gt;backgroundColor&lt;/code&gt; are supported. See the &lt;a href=&quot;&quot;&gt;transition documentation&lt;/a&gt; for more info.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Note: for transitions to work, elements need a stable ID from one frame to the next - using loop indexes or CLAY_AUTO_ID will not work.
CLAY(CLAY_IDI(&quot;box&quot;, colors[index].id), {
    .layout.sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() },
    .layout.childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER },
    .backgroundColor = boxColor,
    .overlayColor = Clay_Hovered() ? (Clay_Color) { 140, 140, 140, 80 } : (Clay_Color) { 255, 255, 255, 0 },
    // Transitions will activate once a handler function is defined.
    .transition = {
        .handler = Clay_EaseOut,
        .duration = 0.5f,
        // A &quot;flag&quot; enum is used to specify which properties to transition, use a bitwise OR (|) to construct the flags.
        .properties = CLAY_TRANSITION_PROPERTY_WIDTH | CLAY_TRANSITION_PROPERTY_POSITION | CLAY_TRANSITION_PROPERTY_OVERLAY_COLOR | CLAY_TRANSITION_PROPERTY_BACKGROUND_COLOR,
        .enter = { .setInitialState = EnterExitSlideUp },
        .exit = { .setFinalState = EnterExitSlideUp },
    }
}) {
    Clay_OnHover(HandleCellButtonInteraction, (void*)(uint64_t)index);
    CLAY_TEXT(((Clay_String) { .length = 2, .chars = colors[index].stringId, .isStaticallyAllocated = true }), {
        .fontSize = 32,
        .textColor = colors[index].id &amp;gt; 29 ? (Clay_Color) {255, 255, 255, 255} : (Clay_Color) {154, 123, 184, 255 }
    });
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;
 &lt;video src=&quot;https://github.com/user-attachments/assets/a8e5cd88-f0da-4fad-acd0-81f253436bc7&quot; controls&gt;&lt;/video&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;An example of the transition API action can be found at examples/raylib-transitions&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Retained Mode Rendering&lt;/h3&gt; 
&lt;p&gt;Clay was originally designed for &lt;a href=&quot;https://www.youtube.com/watch?v=Z1qyvQsjK5Y&quot;&gt;Immediate Mode&lt;/a&gt; rendering - where the entire UI is redrawn every frame. This may not be possible with your platform, renderer design or performance constraints.&lt;/p&gt; 
&lt;p&gt;There are some general techniques that can be used to integrate clay into a retained mode rendering system:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;Clay_RenderCommand&lt;/code&gt; includes the &lt;code&gt;uint32_t id&lt;/code&gt; that was used to declare the element. If unique ids are used, these can be mapped to persistent graphics objects across multiple frames / layouts.&lt;/li&gt; 
 &lt;li&gt;Render commands are culled automatically to only currently visible elements, and &lt;code&gt;Clay_RenderCommand&lt;/code&gt; is a small enough struct that you can simply compare the memory of two render commands with matching IDs to determine if the element is &quot;dirty&quot; and needs to be re-rendered or updated.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;For a worked example, see the provided &lt;a href=&quot;https://github.com/nicbarker/clay/raw/main/renderers/web/html/clay-html-renderer.html&quot;&gt;HTML renderer&lt;/a&gt;. This renderer converts clay layouts into persistent HTML documents with minimal changes per frame.&lt;/p&gt; 
&lt;h3&gt;Visibility Culling&lt;/h3&gt; 
&lt;p&gt;Clay provides a built-in visibility-culling mechanism that is &lt;strong&gt;enabled by default&lt;/strong&gt;. It will only output render commands for elements that are visible - that is, &lt;strong&gt;at least one pixel of their bounding box is inside the viewport.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;This culling mechanism can be disabled via the use of the &lt;code&gt;#define CLAY_DISABLE_CULLING&lt;/code&gt; directive. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#preprocessor-directives&quot;&gt;Preprocessor Directives&lt;/a&gt; for more information.&lt;/p&gt; 
&lt;h3&gt;Preprocessor Directives&lt;/h3&gt; 
&lt;p&gt;Clay supports C preprocessor directives to modulate functionality at compile time. These can be set either in code using &lt;code&gt;#define CLAY_DISABLE_CULLING&lt;/code&gt; or on the command line when compiling using the appropriate compiler specific arguments, e.g. &lt;code&gt;clang -DCLAY_DISABLE_CULLING main.c ...&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;The supported directives are:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_WASM&lt;/code&gt; - Required when targeting Web Assembly.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_DLL&lt;/code&gt; - Required when creating a .Dll file.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Bindings for non C&lt;/h3&gt; 
&lt;p&gt;Clay is usable out of the box as a &lt;code&gt;.h&lt;/code&gt; include in both C99 and C++20 with designated initializer support. There are also supported bindings for other languages, including:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nicbarker/clay/tree/main/bindings/odin&quot;&gt;Odin Bindings&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/clay-ui-rs/clay&quot;&gt;Rust Bindings&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Other implementations&lt;/h3&gt; 
&lt;p&gt;Clay has also been implemented in other languages:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/soypat/glay&quot;&gt;&lt;code&gt;glay&lt;/code&gt;&lt;/a&gt; - Go line-by-line rewrite with readability as main goal.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/totallygamerjet/clay&quot;&gt;&lt;code&gt;totallygamerjet/clay&lt;/code&gt;&lt;/a&gt; - Port using &lt;code&gt;cxgo&lt;/code&gt;, a C to Go transpiler.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/igadmg/goclay&quot;&gt;&lt;code&gt;goclay&lt;/code&gt;&lt;/a&gt; - Go line-by-line rewrite closely matching the reference.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Debug Tools&lt;/h3&gt; 
&lt;p&gt;Clay includes built-in UI debugging tools, similar to the &quot;inspector&quot; in browsers such as Chrome or Firefox. These tools are included in &lt;code&gt;clay.h&lt;/code&gt;, and work by injecting additional render commands into the output &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_rendercommandarray&quot;&gt;Clay_RenderCommandArray&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;As long as the renderer that you&#39;re using works correctly, no additional setup or configuration is required to use the debug tools.&lt;/p&gt; 
&lt;p&gt;To enable the debug tools, use the function &lt;code&gt;Clay_SetDebugModeEnabled(bool enabled)&lt;/code&gt;. This boolean is persistent and does not need to be set every frame.&lt;/p&gt; 
&lt;p&gt;The debug tooling by default will render as a panel to the right side of the screen, compressing your layout by its width. The default width is 400 and is currently configurable via the direct mutation of the internal variable &lt;code&gt;Clay__debugViewWidth&lt;/code&gt;, however this is an internal API and is potentially subject to change.&lt;/p&gt; 
&lt;img width=&quot;1506&quot; alt=&quot;Screenshot 2024-09-12 at 12 54 03 PM&quot; src=&quot;https://github.com/user-attachments/assets/2d122658-3305-4e27-88d6-44f08c0cb4e6&quot; /&gt; 
&lt;p&gt;&lt;em&gt;The official Clay website with debug tooling visible&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Running more than one Clay instance&lt;/h3&gt; 
&lt;p&gt;Clay allows you to run more than one instance in a program. To do this, &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_initialize&quot;&gt;Clay_Initialize&lt;/a&gt; returns a &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_context&quot;&gt;Clay_Context*&lt;/a&gt; reference. You can activate a specific instance using &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setcurrentcontext&quot;&gt;Clay_SetCurrentContext&lt;/a&gt;. If &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setcurrentcontext&quot;&gt;Clay_SetCurrentContext&lt;/a&gt; is not called, then Clay will default to using the context from the most recently called &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_initialize&quot;&gt;Clay_Initialize&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;⚠ Important: Do not render instances across different threads simultaneously, as Clay does not currently support proper multi-threading.&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-c++&quot;&gt;// Define separate arenas for the instances.
Clay_Arena arena1, arena2;
// ... allocate arenas

// Initialize both instances, storing the context for each one.
Clay_Context* instance1 = Clay_Initialize(arena1, layoutDimensions, errorHandler);
Clay_Context* instance2 = Clay_Initialize(arena2, layoutDimensions, errorHandler);

// In the program&#39;s render function, activate each instance before executing clay commands and macros.
Clay_SetCurrentContext(instance1);
Clay_BeginLayout();
// ... declare layout for instance1
Clay_RenderCommandArray renderCommands1 = Clay_EndLayout(deltaTime);
render(renderCommands1);

// Switch to the second instance
Clay_SetCurrentContext(instance2);
Clay_BeginLayout();
// ... declare layout for instance2
Clay_RenderCommandArray renderCommands2 = Clay_EndLayout(deltaTime);
render(renderCommands2);
&lt;/code&gt;&lt;/pre&gt; 
&lt;h1&gt;API&lt;/h1&gt; 
&lt;h3&gt;Naming Conventions&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&quot;&lt;strong&gt;CAPITAL_LETTERS()&lt;/strong&gt;&quot; are used for macros.&lt;/li&gt; 
 &lt;li&gt;&quot;&lt;strong&gt;Clay__&lt;/strong&gt;&quot; (&quot;Clay&quot; followed by &lt;strong&gt;double&lt;/strong&gt; underscore) is used for internal functions that are not intended for use and are subject to change.&lt;/li&gt; 
 &lt;li&gt;&quot;&lt;strong&gt;Clay_&lt;/strong&gt;&quot; (&quot;Clay&quot; followed by &lt;strong&gt;single&lt;/strong&gt; underscore) is used for external functions that can be called by the user.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Public Functions&lt;/h2&gt; 
&lt;h3&gt;Lifecycle for public functions&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;At startup / initialization time, run once&lt;/strong&gt; &lt;code&gt;Clay_MinMemorySize&lt;/code&gt; -&amp;gt; &lt;code&gt;Clay_CreateArenaWithCapacityAndMemory&lt;/code&gt; -&amp;gt; &lt;code&gt;Clay_Initialize&lt;/code&gt; -&amp;gt; &lt;code&gt;Clay_SetMeasureTextFunction&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Each Frame&lt;/strong&gt; &lt;code&gt;Clay_SetLayoutDimensions&lt;/code&gt; -&amp;gt; &lt;code&gt;Clay_SetPointerState&lt;/code&gt; -&amp;gt; &lt;code&gt;Clay_UpdateScrollContainers&lt;/code&gt; -&amp;gt; &lt;code&gt;Clay_BeginLayout&lt;/code&gt; -&amp;gt; &lt;code&gt;CLAY() etc...&lt;/code&gt; -&amp;gt; &lt;code&gt;Clay_EndLayout&lt;/code&gt;&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_MinMemorySize&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;uint32_t Clay_MinMemorySize()&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Returns the minimum amount of memory &lt;strong&gt;in bytes&lt;/strong&gt; that clay needs to accommodate the current &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#preprocessor-directives&quot;&gt;CLAY_MAX_ELEMENT_COUNT&lt;/a&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_CreateArenaWithCapacityAndMemory&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_Arena Clay_CreateArenaWithCapacityAndMemory(size_t capacity, void *memory)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Creates a &lt;code&gt;Clay_Arena&lt;/code&gt; struct with the given capacity and base memory pointer, which can be passed to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_initialize&quot;&gt;Clay_Initialize&lt;/a&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_SetMeasureTextFunction&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_StringSlice text, Clay_TextElementConfig *config, void* userData), void* userData)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Takes a pointer to a function that can be used to measure the &lt;code&gt;width, height&lt;/code&gt; dimensions of a string. Used by clay during layout to determine &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_text&quot;&gt;CLAY_TEXT&lt;/a&gt; element sizing and wrapping.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Note 1: This string is not guaranteed to be null terminated.&lt;/strong&gt; Clay saves significant performance overhead by using slices when wrapping text instead of having to clone new null terminated strings. If your renderer does not support &lt;strong&gt;ptr, length&lt;/strong&gt; style strings (e.g. Raylib), you will need to clone this to a new C string before rendering.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Note 2: It is essential that this function is as fast as possible.&lt;/strong&gt; For text heavy use-cases this function is called many times, and despite the fact that clay caches text measurements internally, it can easily become the dominant overall layout cost if the provided function is slow. &lt;strong&gt;This is on the hot path!&lt;/strong&gt;&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_ResetMeasureTextCache&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;void Clay_ResetMeasureTextCache(void)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Clay caches measurements from the provided MeasureTextFunction, and this will be sufficient for the majority of use-cases. However, if the measurements can depend on external factors that clay does not know about, like DPI changes, then the cached values may be incorrect. When one of these external factors changes, Clay_ResetMeasureTextCache can be called to force clay to recalculate all string measurements in the next frame.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_SetMaxElementCount&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;void Clay_SetMaxElementCount(int32_t maxElementCount)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Sets the internal maximum element count that will be used in subsequent &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_initialize&quot;&gt;Clay_Initialize()&lt;/a&gt; and &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_minmemorysize&quot;&gt;Clay_MinMemorySize()&lt;/a&gt; calls, allowing clay to allocate larger UI hierarchies.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Note: You will need to reinitialize clay, after calling &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_minmemorysize&quot;&gt;Clay_MinMemorySize()&lt;/a&gt; to calculate updated memory requirements.&lt;/strong&gt;&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_SetMaxMeasureTextCacheWordCount&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;void Clay_SetMaxMeasureTextCacheWordCount(int32_t maxMeasureTextCacheWordCount)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Sets the internal text measurement cache size that will be used in subsequent &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_initialize&quot;&gt;Clay_Initialize()&lt;/a&gt; and &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_minmemorysize&quot;&gt;Clay_MinMemorySize()&lt;/a&gt; calls, allowing clay to allocate more text. The value represents how many separate words can be stored in the text measurement cache.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Note: You will need to reinitialize clay, after calling &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_minmemorysize&quot;&gt;Clay_MinMemorySize()&lt;/a&gt; to calculate updated memory requirements.&lt;/strong&gt;&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_Initialize&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_Context* Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Initializes the internal memory mapping, sets the internal dimensions for layout, and binds an error handler for clay to use when something goes wrong. Returns a &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_context&quot;&gt;Clay_Context*&lt;/a&gt; that can optionally be given to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setcurrentcontext&quot;&gt;Clay_SetCurrentContext&lt;/a&gt; to allow running multiple instances of clay in the same program, and sets it as the current context. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#running-more-than-one-clay-instance&quot;&gt;Running more than one Clay instance&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Reference: &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_createarenawithcapacityandmemory&quot;&gt;Clay_Arena&lt;/a&gt;, &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_errorhandler&quot;&gt;Clay_ErrorHandler&lt;/a&gt;, &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setcurrentcontext&quot;&gt;Clay_SetCurrentContext&lt;/a&gt;&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_SetCurrentContext&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;void Clay_SetCurrentContext(Clay_Context* context)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Sets the context that subsequent clay commands will operate on. You can get this reference from &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_initialize&quot;&gt;Clay_Initialize&lt;/a&gt; or &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_getcurrentcontext&quot;&gt;Clay_GetCurrentContext&lt;/a&gt;. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#running-more-than-one-clay-instance&quot;&gt;Running more than one Clay instance&lt;/a&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_GetCurrentContext&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_Context* Clay_GetCurrentContext()&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Returns the context that clay commands are currently operating on, or null if no context has been set. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#running-more-than-one-clay-instance&quot;&gt;Running more than one Clay instance&lt;/a&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_SetLayoutDimensions&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;void Clay_SetLayoutDimensions(Clay_Dimensions dimensions)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Sets the internal layout dimensions. Cheap enough to be called every frame with your screen dimensions to automatically respond to window resizing, etc.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_SetPointerState&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Sets the internal pointer position and state (i.e. current mouse / touch position) and recalculates overlap info, which is used for mouseover / click calculation (via &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_pointerover&quot;&gt;Clay_PointerOver&lt;/a&gt; and updating scroll containers with &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_updatescrollcontainers&quot;&gt;Clay_UpdateScrollContainers&lt;/a&gt;. &lt;strong&gt;isPointerDown should represent the current state this frame, e.g. it should be &lt;code&gt;true&lt;/code&gt; for the entire duration the left mouse button is held down.&lt;/strong&gt; Clay has internal handling for detecting click / touch start &amp;amp; end.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_UpdateScrollContainers&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;This function handles scrolling of containers. It responds to both &lt;code&gt;scrollDelta&lt;/code&gt;, which represents mouse wheel or trackpad scrolling this frame, as well as &quot;touch scrolling&quot; on mobile devices, or &quot;drag scrolling&quot; with a mouse or similar device.&lt;/p&gt; 
&lt;p&gt;Touch / drag scrolling only occurs if the &lt;code&gt;enableDragScrolling&lt;/code&gt; parameter is &lt;code&gt;true&lt;/code&gt;, &lt;strong&gt;and&lt;/strong&gt; &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setpointerstate&quot;&gt;Clay_SetPointerState&lt;/a&gt; has been called this frame. As a result, you can simply always call it with &lt;code&gt;false&lt;/code&gt; as the first argument if you want to disable touch scrolling.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;deltaTime&lt;/code&gt; is the time &lt;strong&gt;in seconds&lt;/strong&gt; since the last frame (e.g. 0.016 is &lt;strong&gt;16 milliseconds&lt;/strong&gt;), and is used to normalize &amp;amp; smooth scrolling across different refresh rates.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_GetScrollOffset&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_Vector2 Clay_GetScrollOffset()&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Returns the internally stored scroll offset for the currently open element.&lt;/p&gt; 
&lt;p&gt;Generally intended for use with &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_clipelementconfig&quot;&gt;clip elements&lt;/a&gt; and the &lt;code&gt;.childOffset&lt;/code&gt; field to create scrolling containers.&lt;/p&gt; 
&lt;p&gt;See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#scrolling-elements&quot;&gt;Scrolling Elements&lt;/a&gt; for more details.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Create a horizontally scrolling container
CLAY(CLAY_ID(&quot;ScrollContainer&quot;), {
    .clip = { .horizontal = true, .childOffset = Clay_GetScrollOffset() }
})
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_BeginLayout&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;void Clay_BeginLayout()&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Prepares clay to calculate a new layout. Called each frame / layout &lt;strong&gt;before&lt;/strong&gt; any of the &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#element-macros&quot;&gt;Element Macros&lt;/a&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_EndLayout&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_RenderCommandArray Clay_EndLayout()&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Ends declaration of element macros and calculates the results of the current layout. Renders a &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_rendercommandarray&quot;&gt;Clay_RenderCommandArray&lt;/a&gt; containing the results of the layout calculation.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_Hovered&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;bool Clay_Hovered()&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Called &lt;strong&gt;during&lt;/strong&gt; layout declaration, and returns &lt;code&gt;true&lt;/code&gt; if the pointer position previously set with &lt;code&gt;Clay_SetPointerState&lt;/code&gt; is inside the bounding box of the currently open element. Note: this is based on the element&#39;s position from the &lt;strong&gt;last&lt;/strong&gt; frame.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_OnHover&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerData, void *userData), void *userData)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Called &lt;strong&gt;during&lt;/strong&gt; layout declaration, this function allows you to attach a function pointer to the currently open element that will be called once per layout if the pointer position previously set with &lt;code&gt;Clay_SetPointerState&lt;/code&gt; is inside the bounding box of the currently open element. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_pointerdata&quot;&gt;Clay_PointerData&lt;/a&gt; for more information on the &lt;code&gt;pointerData&lt;/code&gt; argument.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerData, void *userData) {
    ButtonData *buttonData = (ButtonData *)userData;
    // Pointer state allows you to detect mouse down / hold / release
    if (pointerData.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
        // Do some click handling
        NavigateTo(buttonData-&amp;gt;link);
    }
}

ButtonData linkButton = (ButtonData) { .link = &quot;https://github.com/nicbarker/clay&quot; };

// HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries
CLAY(CLAY_ID(&quot;Button&quot;), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
    Clay_OnHover(HandleButtonInteraction, &amp;amp;buttonData);
    CLAY_TEXT(CLAY_STRING(&quot;Click me!&quot;), &amp;amp;headerTextConfig);
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_PointerOver&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;bool Clay_PointerOver(Clay_ElementId id)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Returns &lt;code&gt;true&lt;/code&gt; if the pointer position previously set with &lt;code&gt;Clay_SetPointerState&lt;/code&gt; is inside the bounding box of the layout element with the provided &lt;code&gt;id&lt;/code&gt;. Note: this is based on the element&#39;s position from the &lt;strong&gt;last&lt;/strong&gt; frame. If frame-accurate pointer overlap detection is required, perhaps in the case of significant change in UI layout between frames, you can simply run your layout code twice that frame. The second call to &lt;code&gt;Clay_PointerOver&lt;/code&gt; will be frame-accurate.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_GetOpenElementId&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_ElementId Clay_GetOpenElementId()&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Returns the &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementid&quot;&gt;Clay_ElementId&lt;/a&gt; of the currently open element. Useful for getting the ID of elements opened with &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_auto_id&quot;&gt;CLAY_AUTO_ID&lt;/a&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_GetScrollContainerData&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Returns &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_scrollcontainerdata&quot;&gt;Clay_ScrollContainerData&lt;/a&gt; for the scroll container matching the provided ID. This function allows imperative manipulation of scroll position, allowing you to build things such as scroll bars, buttons that &quot;jump&quot; to somewhere in a scroll container, etc.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_GetElementData&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_ElementData Clay_GetElementData(Clay_ElementId id)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Returns &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementdata&quot;&gt;Clay_ElementData&lt;/a&gt; for the element matching the provided ID. Used to retrieve information about elements such as their final calculated bounding box.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_GetElementId&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_ElementId Clay_GetElementId(Clay_String idString)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Returns a &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementid&quot;&gt;Clay_ElementId&lt;/a&gt; for the provided id string, used for querying element info such as mouseover state, scroll container data, etc.&lt;/p&gt; 
&lt;h2&gt;Element Macros&lt;/h2&gt; 
&lt;h3&gt;CLAY()&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(...configuration) { ...children }&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Lifecycle&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;Clay_BeginLayout()&lt;/code&gt; -&amp;gt; &lt;code&gt;CLAY()&lt;/code&gt; -&amp;gt; &lt;code&gt;Clay_EndLayout()&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;CLAY&lt;/strong&gt; opens a generic empty container, that is configurable and supports nested children. &lt;strong&gt;CLAY&lt;/strong&gt; requires a parameter, so if you want to create an element without any configuration, use &lt;code&gt;CLAY(0)&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Define an element with 16px of x and y padding
CLAY(CLAY_ID(&quot;Outer&quot;), { .layout = { .padding = CLAY_PADDING_ALL(16) } }) {
    // A nested child element
    CLAY(CLAY_ID(&quot;SideBar&quot;), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {
        // Children laid out top to bottom with a 16 px gap between them
    }
    // A vertical scrolling container with a colored background
    CLAY(CLAY_ID(&quot;ScrollContainer&quot;), {
        .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 },
        .backgroundColor = { 200, 200, 100, 255 },
        .cornerRadius = CLAY_CORNER_RADIUS(10),
        .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
    }) {
        // child elements
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;h3&gt;CLAY_AUTO_ID()&lt;/h3&gt; 
&lt;p&gt;A version of the core &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay&quot;&gt;CLAY()&lt;/a&gt; element creation macro that generates an ID automatically instead of requiring it as the first argument.&lt;/p&gt; 
&lt;p&gt;Note that under the hood this ID is generated in the same way as &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id_local&quot;&gt;CLAY_ID_LOCAL()&lt;/a&gt;, which is based on the element&#39;s position in the hierarchy, and may chance between layout calls if elements are added / removed from the hierarchy before the element is defined. As a result, for transitions &amp;amp; retained mode backends to work correctly, IDs should be specified.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Note that CLAY_AUTO_ID only takes one argument: the configuration
CLAY_AUTO_ID({ .layout = { .padding = CLAY_PADDING_ALL(16) } }) {
    // A nested child element
    CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {
        // Children laid out top to bottom with a 16 px gap between them
    }
    // A vertical scrolling container with a colored background
    CLAY_AUTO_ID({
        .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 },
        .backgroundColor = { 200, 200, 100, 255 },
        .cornerRadius = CLAY_CORNER_RADIUS(10),
        .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
    }) {
        // child elements
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;h3&gt;CLAY_TEXT()&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY_TEXT(Clay_String textContents, Clay_TextElementConfig *textConfig);&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Lifecycle&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;Clay_BeginLayout()&lt;/code&gt; -&amp;gt; &lt;code&gt;CLAY_TEXT()&lt;/code&gt; -&amp;gt; &lt;code&gt;Clay_EndLayout()&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;TEXT&lt;/strong&gt; is a measured, auto-wrapped text element. It uses &lt;code&gt;Clay_TextElementConfig&lt;/code&gt; to configure text specific options.&lt;/p&gt; 
&lt;p&gt;Note that &lt;code&gt;Clay_TextElementConfig&lt;/code&gt; uses &lt;code&gt;uint32_t fontId&lt;/code&gt;. Font ID to font asset mapping is managed in user code and passed to render commands.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Struct API (Pseudocode)&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// CLAY_TEXT(text, { .member = value }) supports these options
Clay_TextElementConfig {
    Clay_Color textColor {
        float r; float g; float b; float a;
    };
    uint16_t fontId;
    uint16_t fontSize;
    uint16_t letterSpacing;
    uint16_t lineHeight;
    Clay_TextElementConfigWrapMode wrapMode {
        CLAY_TEXT_WRAP_WORDS (default),
        CLAY_TEXT_WRAP_NEWLINES,
        CLAY_TEXT_WRAP_NONE,
    };
    Clay_TextAlignment textAlignment {
        CLAY_TEXT_ALIGN_LEFT (default),
        CLAY_TEXT_ALIGN_CENTER,
        CLAY_TEXT_ALIGN_RIGHT,
    };
    void *userData;
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.textColor&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY_TEXT(text, { .textColor = {120, 120, 120, 255} })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_color&quot;&gt;Clay_Color&lt;/a&gt;. Conventionally accepts &lt;code&gt;rgba&lt;/code&gt; float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.fontId&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY_TEXT(text, { .fontId = FONT_ID_LATO })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;It&#39;s up to the user to load fonts and create a mapping from &lt;code&gt;fontId&lt;/code&gt; to a font that can be measured and rendered.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.fontSize&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY_TEXT(text, { .fontSize = 16 })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Font size is generally thought of as &lt;code&gt;x pixels tall&lt;/code&gt;, but interpretation is left up to the user &amp;amp; renderer.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.letterSpacing&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY_TEXT(text, { .letterSpacing = 1 })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;.letterSpacing&lt;/code&gt; results in &lt;strong&gt;horizontal&lt;/strong&gt; white space between individual rendered characters.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.lineHeight&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY_TEXT(text, { .lineHeight = 20 })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;.lineHeight&lt;/code&gt; - when non zero - forcibly sets the &lt;code&gt;height&lt;/code&gt; of each wrapped line of text to &lt;code&gt;.lineheight&lt;/code&gt; pixels tall. Will affect the layout of both parents and siblings. A value of &lt;code&gt;0&lt;/code&gt; will use the measured height of the font.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.wrapMode&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY_TEXT(text, { .wrapMode = CLAY_TEXT_WRAP_NONE })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;.wrapMode&lt;/code&gt; specifies under what conditions text should &lt;a href=&quot;https://en.wikipedia.org/wiki/Line_wrap_and_word_wrap&quot;&gt;wrap&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Available options are:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_TEXT_WRAP_WORDS&lt;/code&gt; (default) - Text will wrap on whitespace characters as container width shrinks, preserving whole words.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_TEXT_WRAP_NEWLINES&lt;/code&gt; - will only wrap when encountering newline characters.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_TEXT_WRAP_NONE&lt;/code&gt; - Text will never wrap even if its container is compressed beyond the text measured width.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.textAlignment&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY_TEXT(text, { .textAlignment = CLAY_TEXT_ALIGN_CENTER })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;.textAlignment&lt;/code&gt; controls how &lt;strong&gt;wrapping&lt;/strong&gt; text lines are aligned. If you want to control the alignment of single lines of text, instead use the &lt;code&gt;childAlignment&lt;/code&gt; property of the &lt;strong&gt;parent&lt;/strong&gt; layout element.&lt;/p&gt; 
&lt;p&gt;Available options are:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_TEXT_ALIGN_LEFT&lt;/code&gt; (default)&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_TEXT_ALIGN_CENTER&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_TEXT_ALIGN_RIGHT&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Define a font somewhere in your code
const uint32_t FONT_ID_LATO = 3;
// ..
CLAY_TEXT(CLAY_STRING(&quot;John Smith&quot;), { .fontId = FONT_ID_LATO, .fontSize = 24, .textColor = {255, 0, 0, 255} });
// Rendering example
Font fontToUse = LoadedFonts[renderCommand-&amp;gt;renderData.text.fontId];
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Rendering&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Element is subject to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#visibility-culling&quot;&gt;culling&lt;/a&gt;. Otherwise, multiple &lt;code&gt;Clay_RenderCommand&lt;/code&gt;s with &lt;code&gt;commandType = CLAY_RENDER_COMMAND_TYPE_TEXT&lt;/code&gt; may be created, one for each wrapped line of text.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;Clay_RenderCommand.textContent&lt;/code&gt; will be populated with a &lt;code&gt;Clay_String&lt;/code&gt; &lt;em&gt;slice&lt;/em&gt; of the original string passed in (i.e. wrapping doesn&#39;t reallocate, it just returns a &lt;code&gt;Clay_String&lt;/code&gt; pointing to the start of the new line with a &lt;code&gt;length&lt;/code&gt;)&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;CLAY_ID()&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_ElementId CLAY_ID(STRING_LITERAL idString)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;CLAY_ID()&lt;/strong&gt; is used to generate and attach a &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementid&quot;&gt;Clay_ElementId&lt;/a&gt; to a layout element during declaration.&lt;/p&gt; 
&lt;p&gt;Note this macro only works with String literals and won&#39;t compile if used with a &lt;code&gt;char*&lt;/code&gt; variable. To use a heap allocated &lt;code&gt;char*&lt;/code&gt; string as an ID, use &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_sid&quot;&gt;CLAY_SID&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;To regenerate the same ID outside of layout declaration when using utility functions such as &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_pointerover&quot;&gt;Clay_PointerOver&lt;/a&gt;, use the &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_getelementid&quot;&gt;Clay_GetElementId&lt;/a&gt; function.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Tag a button with the Id &quot;Button&quot;
CLAY(CLAY_ID(&quot;Button&quot;), {
    .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }
}) {
    // ...children
}

// Later on outside of layout code
bool buttonIsHovered = Clay_PointerOver(Clay_GetElementId(&quot;Button&quot;));
if (buttonIsHovered &amp;amp;&amp;amp; leftMouseButtonPressed) {
    // ... do some click handling
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;h3&gt;CLAY_SID()&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_ElementId CLAY_SID(Clay_String idString)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A version of &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id&quot;&gt;CLAY_ID&lt;/a&gt; that can be used with heap allocated &lt;code&gt;char *&lt;/code&gt; data. The underlying &lt;code&gt;char&lt;/code&gt; data will not be copied internally and should live until at least the next frame.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;CLAY_IDI()&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_ElementId CLAY_IDI(STRING_LITERAL idString, int32_t index)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;An offset version of &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id&quot;&gt;CLAY_ID&lt;/a&gt;. Generates a &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementid&quot;&gt;Clay_ElementId&lt;/a&gt; string id from the provided &lt;code&gt;char *label&lt;/code&gt;, combined with the &lt;code&gt;int index&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;Used for generating ids for sequential elements (such as in a &lt;code&gt;for&lt;/code&gt; loop) without having to construct dynamic strings at runtime.&lt;/p&gt; 
&lt;p&gt;Note this macro only works with String literals and won&#39;t compile if used with a &lt;code&gt;char*&lt;/code&gt; variable. To use a heap allocated &lt;code&gt;char*&lt;/code&gt; string as an ID, use &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_sidi&quot;&gt;CLAY_SIDI&lt;/a&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;CLAY_SIDI()&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_ElementId CLAY_SIDI(Clay_String idString, int32_t index)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A version of &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_idi&quot;&gt;CLAY_IDI&lt;/a&gt; that can be used with heap allocated &lt;code&gt;char *&lt;/code&gt; data. The underlying &lt;code&gt;char&lt;/code&gt; data will not be copied internally and should live until at least the next frame.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;CLAY_ID_LOCAL()&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;Clay_ElementId CLAY_ID_LOCAL(STRING_LITERAL idString)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Lifecycle&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;Clay_BeginLayout()&lt;/code&gt; -&amp;gt; &lt;code&gt;CLAY(&lt;/code&gt; -&amp;gt; &lt;code&gt;CLAY_ID_LOCAL()&lt;/code&gt; -&amp;gt; &lt;code&gt;)&lt;/code&gt; -&amp;gt; &lt;code&gt;Clay_EndLayout()&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;CLAY_ID_LOCAL()&lt;/strong&gt; is used to generate and attach a &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementid&quot;&gt;Clay_ElementId&lt;/a&gt; to a layout element during declaration.&lt;/p&gt; 
&lt;p&gt;Unlike &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id&quot;&gt;CLAY_ID&lt;/a&gt; which needs to be globally unique, a local ID is based on the ID of it&#39;s parent and only needs to be unique among its siblings.&lt;/p&gt; 
&lt;p&gt;As a result, local id is suitable for use in reusable components and loops.&lt;/p&gt; 
&lt;p&gt;Note this macro only works with String literals and won&#39;t compile if used with a &lt;code&gt;char*&lt;/code&gt; variable. To use a heap allocated &lt;code&gt;char*&lt;/code&gt; string as an ID, use &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_sid_local&quot;&gt;CLAY_SID_LOCAL&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;void RenderHeaderButton(ButtonData button) {
    CLAY({
        .id = CLAY_ID_LOCAL(&quot;HeaderButton&quot;),
        .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }
    }) {
        // ...children
    }
}

for (int i = 0; i &amp;lt; headerButtons.length; i++) {
    RenderHeaderButton(headerButtons.items[i]);
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;h3&gt;CLAY_SID_LOCAL()&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_ElementId CLAY_SID_LOCAL(Clay_String idString)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A version of &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id_local&quot;&gt;CLAY_ID_LOCAL&lt;/a&gt; that can be used with heap allocated &lt;code&gt;char *&lt;/code&gt; data. The underlying &lt;code&gt;char&lt;/code&gt; data will not be copied internally and should live until at least the next frame.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;CLAY_IDI_LOCAL()&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_ElementId CLAY_IDI_LOCAL(STRING_LITERAL idString, int32_t index)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;An offset version of &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_local_id&quot;&gt;CLAY_ID_LOCAL&lt;/a&gt;. Generates a &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementid&quot;&gt;Clay_ElementId&lt;/a&gt; string id from the provided &lt;code&gt;char *label&lt;/code&gt;, combined with the &lt;code&gt;int index&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;Used for generating ids for sequential elements (such as in a &lt;code&gt;for&lt;/code&gt; loop) without having to construct dynamic strings at runtime.&lt;/p&gt; 
&lt;p&gt;Note this macro only works with String literals and won&#39;t compile if used with a &lt;code&gt;char*&lt;/code&gt; variable. To use a heap allocated &lt;code&gt;char*&lt;/code&gt; string as an ID, use &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_sidi_local&quot;&gt;CLAY_SIDI_LOCAL&lt;/a&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;CLAY_SIDI_LOCAL()&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;Clay_ElementId CLAY_SIDI_LOCAL(Clay_String idString, int32_t index)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A version of &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_idi_local&quot;&gt;CLAY_IDI_LOCAL&lt;/a&gt; that can be used with heap allocated &lt;code&gt;char *&lt;/code&gt; data. The underlying &lt;code&gt;char&lt;/code&gt; data will not be copied internally and should live until at least the next frame.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h2&gt;Data Structures &amp;amp; Definitions&lt;/h2&gt; 
&lt;h3&gt;Clay_ElementDeclaration&lt;/h3&gt; 
&lt;p&gt;The &lt;strong&gt;Clay_ElementDeclaration&lt;/strong&gt; struct is the only argument to the &lt;code&gt;CLAY()&lt;/code&gt; macro and provides configuration options for layout elements.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    Clay_LayoutConfig layout;
    Clay_Color backgroundColor;
    Clay_CornerRadius cornerRadius;
    Clay_AspectRatioElementConfig aspectRatio;
    Clay_ImageElementConfig image;
    Clay_FloatingElementConfig floating;
    Clay_CustomElementConfig custom;
    Clay_ClipElementConfig clip;
    Clay_BorderElementConfig border;
    void *userData;
} Clay_ElementDeclaration;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.layout&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_LayoutConfig&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .layout = { .padding = { 16, 16, 12, 12 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_layoutconfig&quot;&gt;Clay_LayoutConfig&lt;/a&gt;. Controls various settings related to &lt;em&gt;layout&lt;/em&gt;, which can be thought of as &quot;the size and position of this element and its children&quot;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.backgroundColor&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Color&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .backgroundColor = { 120, 120, 120, 255 } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_color&quot;&gt;Clay_Color&lt;/a&gt;. Conventionally accepts &lt;code&gt;rgba&lt;/code&gt; float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.overlayColor&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Color&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .overlayColor = { 255, 120, 120, 255 } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_color&quot;&gt;Clay_Color&lt;/a&gt;. Conventionally accepts &lt;code&gt;rgba&lt;/code&gt; float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.&lt;/p&gt; 
&lt;p&gt;Specifying &lt;code&gt;.overlayColor&lt;/code&gt; will cause two new render commands to be emitted: &lt;code&gt;OVERLAY_COLOR_BEGIN&lt;/code&gt; immediately, and &lt;code&gt;OVERLAY_COLOR_END&lt;/code&gt; after this elements subtree has been emitted.&lt;/p&gt; 
&lt;p&gt;This instructs the renderer to begin applying a color overlay to this element, and all child elements. The color overlay effect is similar to glsl&#39;s &lt;code&gt;mix(source, target, alpha)&lt;/code&gt;. As a result, the strength of the color overlay is controlled by the &lt;code&gt;.a&lt;/code&gt; channel of &lt;code&gt;.overlayColor&lt;/code&gt;. Zero alpha means &quot;all child colors remain the same&quot;, full alpha means &quot;all child colours are replaced by the RGB overlayColor&quot;, and values in between mean &quot;lerp from the child color to the overlay color by the alpha&quot;.&lt;/p&gt; 
&lt;p&gt;This can be used as a cheap replacement for alpha / opacity to &quot;fade in / out&quot;, by applying (and potentially transitioning) an overlay color to the same color as the background with full alpha.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.cornerRadius&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_CornerRadius&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .cornerRadius = { .topLeft = 16, .topRight = 16, .bottomLeft = 16, .bottomRight = 16 } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Defines the radius in pixels for the arc of rectangle corners (&lt;code&gt;0&lt;/code&gt; is square, &lt;code&gt;rectangle.width / 2&lt;/code&gt; is circular).&lt;/p&gt; 
&lt;p&gt;Note that the &lt;code&gt;CLAY_CORNER_RADIUS(radius)&lt;/code&gt; function-like macro is available to provide short hand for setting all four corner radii to the same value. e.g. &lt;code&gt;CLAY_BORDER({ .cornerRadius = CLAY_CORNER_RADIUS(10) })&lt;/code&gt;&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.aspectRatio&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_AspectRatioElementConfig&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .aspectRatio = 1 })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_aspectratioelementconfig&quot;&gt;Clay_AspectRatioElementConfig&lt;/a&gt;. Configures the element as an aspect ratio scaling element. Especially useful for rendering images, but can also be used to enforce a fixed width / height ratio of other elements.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.image&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_ImageElementConfig&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .image = { .imageData = &amp;amp;myImage } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_imageelementconfig&quot;&gt;Clay_ImageElementConfig&lt;/a&gt;. Configures the element as an image element. Causes a render command with type &lt;code&gt;IMAGE&lt;/code&gt; to be emitted.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.floating&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_FloatingElementConfig&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .floating = { .attachTo = CLAY_ATTACH_TO_PARENT } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_floatingelementconfig&quot;&gt;Clay_FloatingElementConfig&lt;/a&gt;. Configures the element as an floating element, which allows it to stack &quot;in front&quot; and &quot;on top&quot; of other elements without affecting sibling or parent size or position.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.custom&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_CustomElementConfig&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .custom = { .customData = &amp;amp;my3DModel } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_customelementconfig&quot;&gt;Clay_CustomElementConfig&lt;/a&gt;. Configures the element as a custom element, which allows you to pass custom data through to the renderer. Causes a render command with type &lt;code&gt;CUSTOM&lt;/code&gt; to be emitted.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.clip&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_ClipElementConfig&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_cliplelementconfig&quot;&gt;Clay_ClipElementConfig&lt;/a&gt;. Configures the element as a clip element, which causes child elements to be clipped / masked if they overflow, and together with the functions listed in &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#scrolling-elements&quot;&gt;Scrolling Elements&lt;/a&gt; enables scrolling of child contents.&lt;/p&gt; 
&lt;img width=&quot;580&quot; alt=&quot;An image demonstrating the concept of clipping which prevents rendering of a child elements pixels if they fall outside the bounds of the parent element.&quot; src=&quot;https://github.com/user-attachments/assets/2eb83ff9-e186-4ea4-8a87-d90cbc0838b5&quot; /&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.border&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_BorderElementConfig&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .border = { .width = { .left = 5 }, .color = COLOR_BLUE } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_borderelementconfig&quot;&gt;Clay_BorderElementConfig&lt;/a&gt;. Configures the element as a border element, which instructs the renderer to draw coloured border lines along the perimeter of this element&#39;s bounding box. Causes a render command with type &lt;code&gt;BORDER&lt;/code&gt; to be emitted.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.userData&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;void *&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .userData = &amp;amp;extraData })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Transparently passes a pointer through to the corresponding &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_rendercommand&quot;&gt;Clay_RenderCommands&lt;/a&gt;s generated by this element.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Declare a reusable rectangle config, with a purple color and 10px rounded corners
Clay_RectangleElementConfig rectangleConfig = (Clay_RectangleElementConfig) { .color = { 200, 200, 100, 255 }, .cornerRadius = CLAY_CORNER_RADIUS(10) };
// Declare a rectangle element using a reusable config
CLAY(CLAY_ID(&quot;Box&quot;), rectangleConfig) {}
// Declare a retangle element using an inline config
CLAY(CLAY_ID(&quot;BoxInline&quot;), { .color = { 200, 200, 100, 255 }, .cornerRadius = CLAY_CORNER_RADIUS(10) })) {
    // child elements
}
// Declare a scrolling container with a colored background
CLAY(CLAY_ID(&quot;ScrollingContainer&quot;), { 
    .backgroundColor = { 200, 200, 100, 255 }, 
    .cornerRadius = CLAY_CORNER_RADIUS(10)
    .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
) {
    // child elements
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Element is subject to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#visibility-culling&quot;&gt;culling&lt;/a&gt;. Otherwise, a single &lt;code&gt;Clay_RenderCommand&lt;/code&gt;s with &lt;code&gt;commandType = CLAY_RENDER_COMMAND_TYPE_RECTANGLE&lt;/code&gt; will be created, with &lt;code&gt;renderCommand-&amp;gt;renderData.rectangle&lt;/code&gt; containing a pointer to the element&#39;s Clay_RectangleElementConfig.&lt;/p&gt; 
&lt;h3&gt;Clay_LayoutConfig&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Clay_LayoutConfig&lt;/strong&gt; is used for configuring &lt;em&gt;layout&lt;/em&gt; options (i.e. options that affect the final position and size of an element, its parents, siblings, and children)&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Struct API (Pseudocode)&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// CLAY({ .layout = { ...fields } }) supports these options
Clay_LayoutConfig {
    Clay_LayoutDirection layoutDirection = CLAY_LEFT_TO_RIGHT (default) | CLAY_TOP_TO_BOTTOM;
    Clay_Padding padding {
        u16 left; u16 right; u16 top; u16 bottom; 
    };
    uint16_t childGap;
    Clay_ChildAlignment childAlignment {
        .x = CLAY_ALIGN_X_LEFT (default) | CLAY_ALIGN_X_CENTER | CLAY_ALIGN_X_RIGHT;
        .y = CLAY_ALIGN_Y_TOP (default) | CLAY_ALIGN_Y_CENTER | CLAY_ALIGN_Y_BOTTOM;
    };
    Clay_Sizing sizing { // Recommended to use the provided macros here - see #sizing for more in depth explanation
        .width = CLAY_SIZING_FIT(float min, float max) (default) | CLAY_SIZING_GROW(float min, float max) | CLAY_SIZING_FIXED(float width) | CLAY_SIZING_PERCENT(float percent)
        .height = CLAY_SIZING_FIT(float min, float max) (default) | CLAY_SIZING_GROW(float min, float max) | CLAY_SIZING_FIXED(float height) | CLAY_SIZING_PERCENT(float percent)
    }; // See CLAY_SIZING_GROW() etc for more details
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.layoutDirection&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_LayoutDirection&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Controls the axis / direction in which child elements are laid out. Available options are &lt;code&gt;CLAY_LEFT_TO_RIGHT&lt;/code&gt; (default) and &lt;code&gt;CLAY_TOP_TO_BOTTOM&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Did you know that &quot;left to right&quot; and &quot;top to bottom&quot; both have 13 letters?&lt;/em&gt;&lt;/p&gt; 
&lt;img width=&quot;580&quot; alt=&quot;Screenshot 2024-08-22 at 11 10 27 AM&quot; src=&quot;https://github.com/user-attachments/assets/7008aa47-8826-4338-9257-8bc83f7813ce&quot; /&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.padding&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Padding&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .layout = { .padding = { .left = 16, .right = 16, .top = 8, .bottom = 8 } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Controls white-space &quot;padding&quot; around the &lt;strong&gt;outside&lt;/strong&gt; of child elements.&lt;/p&gt; 
&lt;img width=&quot;486&quot; alt=&quot;Screenshot 2024-08-22 at 10 50 49 AM&quot; src=&quot;https://github.com/user-attachments/assets/b454fa36-92d5-4b1d-bf8b-e4c25428e9de&quot; /&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.childGap&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;uint16_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .layout = { .childGap = 16 } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Controls the white-space &lt;strong&gt;between&lt;/strong&gt; child elements as they are laid out. When &lt;code&gt;.layoutDirection&lt;/code&gt; is &lt;code&gt;CLAY_LEFT_TO_RIGHT&lt;/code&gt; (default), this will be horizontal space, whereas for &lt;code&gt;CLAY_TOP_TO_BOTTOM&lt;/code&gt; it will be vertical space.&lt;/p&gt; 
&lt;img width=&quot;600&quot; alt=&quot;Screenshot 2024-08-22 at 11 05 15 AM&quot; src=&quot;https://github.com/user-attachments/assets/fa0dae1f-1936-47f6-a299-634bd7d40d58&quot; /&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.childAlignment&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_ChildAlignment&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .layout = { .childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Controls the alignment of children relative to the height and width of the parent container. Available options are:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;.x = CLAY_ALIGN_X_LEFT (default) | CLAY_ALIGN_X_CENTER | CLAY_ALIGN_X_RIGHT;
.y = CLAY_ALIGN_Y_TOP (default) | CLAY_ALIGN_Y_CENTER | CLAY_ALIGN_Y_BOTTOM;
&lt;/code&gt;&lt;/pre&gt; 
&lt;img width=&quot;1030&quot; alt=&quot;Screenshot 2024-08-22 at 11 25 16 AM&quot; src=&quot;https://github.com/user-attachments/assets/be61b4a7-db4f-447c-b6d6-b2d4a91fc664&quot; /&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.sizing&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Sizing&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .layout = { .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_PERCENT(0.5) } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Controls how final width and height of element are calculated. The same configurations are available for both the &lt;code&gt;.width&lt;/code&gt; and &lt;code&gt;.height&lt;/code&gt; axis. There are several options:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;code&gt;CLAY_SIZING_FIT(float min, float max) (default)&lt;/code&gt; - The element will be sized to fit its children (plus padding and gaps), up to &lt;code&gt;max&lt;/code&gt;. If &lt;code&gt;max&lt;/code&gt; is left unspecified, it will default to &lt;code&gt;FLOAT_MAX&lt;/code&gt;. When elements are compressed to fit into a smaller parent, this element will not shrink below &lt;code&gt;min&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;code&gt;CLAY_SIZING_GROW(float min, float max)&lt;/code&gt; - The element will grow to fill available space in its parent, up to &lt;code&gt;max&lt;/code&gt;. If &lt;code&gt;max&lt;/code&gt; is left unspecified, it will default to &lt;code&gt;FLOAT_MAX&lt;/code&gt;. When elements are compressed to fit into a smaller parent, this element will not shrink below &lt;code&gt;min&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;code&gt;CLAY_SIZING_FIXED(float fixed)&lt;/code&gt; - The final size will always be exactly the provided &lt;code&gt;fixed&lt;/code&gt; value. Shorthand for &lt;code&gt;CLAY_SIZING_FIT(fixed, fixed)&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;code&gt;CLAY_SIZING_PERCENT(float percent)&lt;/code&gt; - Final size will be a percentage of parent size, minus padding and child gaps. &lt;code&gt;percent&lt;/code&gt; is assumed to be a float between &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;img width=&quot;1056&quot; alt=&quot;Screenshot 2024-08-22 at 2 10 33 PM&quot; src=&quot;https://github.com/user-attachments/assets/1236efb1-77dc-44cd-a207-7944e0f5e500&quot; /&gt; 
&lt;img width=&quot;1141&quot; alt=&quot;Screenshot 2024-08-22 at 2 19 04 PM&quot; src=&quot;https://github.com/user-attachments/assets/a26074ff-f155-4d35-9ca4-9278a64aac00&quot; /&gt; 
&lt;p&gt;&lt;strong&gt;Example Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;CLAY(CLAY_ID(&quot;Button&quot;), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16, .childGap = 16) } }) {
    // Children will be laid out vertically with 16px of padding around and between
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_ImageElementConfig&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Element&quot;), { .image = { ...image config } }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Clay_ImageElementConfig&lt;/strong&gt; configures a clay element to render an image as its background.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Struct API (Pseudocode)&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;Clay_ImageElementConfig {
    void * imageData;
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.imageData&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;void *&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Image&quot;), { .image = { .imageData = &amp;amp;myImage } }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;.imageData&lt;/code&gt; is a generic void pointer that can be used to pass through image data to the renderer.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Load an image somewhere in your code
YourImage profilePicture = LoadYourImage(&quot;profilePicture.png&quot;);
// Note that when rendering, .imageData will be void* type.
CLAY(CLAY_ID(&quot;Image&quot;), { .image = { .imageData = &amp;amp;profilePicture } }) {}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Load an image somewhere in your code
YourImage profilePicture = LoadYourImage(&quot;profilePicture.png&quot;);
// Declare a reusable image config
Clay_ImageElementConfig imageConfig = (Clay_ImageElementConfig) { .imageData = &amp;amp;profilePicture };
// Declare an image element using a reusable config
CLAY(CLAY_ID(&quot;Image&quot;), { .image = imageConfig }) {}
// Declare an image element using an inline config
CLAY(CLAY_ID(&quot;ImageInline&quot;), { .image = { .imageData = &amp;amp;profilePicture }, .aspectRatio = 16.0 / 9.0 }) {}
// Rendering example
YourImage *imageToRender = renderCommand-&amp;gt;elementConfig.imageElementConfig-&amp;gt;imageData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Rendering&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Element is subject to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#visibility-culling&quot;&gt;culling&lt;/a&gt;. Otherwise, a single &lt;code&gt;Clay_RenderCommand&lt;/code&gt;s with &lt;code&gt;commandType = CLAY_RENDER_COMMAND_TYPE_IMAGE&lt;/code&gt; will be created. The user will need to access &lt;code&gt;renderCommand-&amp;gt;renderData.image.imageData&lt;/code&gt; to retrieve image data referenced during layout creation. It&#39;s also up to the user to decide how / if they wish to blend &lt;code&gt;renderCommand-&amp;gt;renderData.image.backgroundColor&lt;/code&gt; with the image.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_AspectRatioElementConfig&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Aspect&quot;), { .aspectRatio = 16.0 / 9.0 }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Clay_AspectRatioElementConfig&lt;/strong&gt; configures a clay element to enforce a fixed width / height ratio in its final dimensions. Mostly used for image elements, but can also be used for non image elements.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Struct API (Pseudocode)&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;Clay_AspectRatioElementConfig {
    float aspectRatio;
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.aspectRatio&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;float&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Aspect&quot;), { .aspectRatio = { .aspectRatio = 16.0 / 9.0 } }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;or alternatively, as C will automatically pass the value to the first nested struct field:&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Aspect&quot;), { .aspectRatio = 16.0 / 9.0 }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Load an image somewhere in your code
YourImage profilePicture = LoadYourImage(&quot;profilePicture.png&quot;);
// Declare an image element that will grow along the X axis while maintaining its original aspect ratio
CLAY(CLAY_ID(&quot;ProfilePicture&quot;), {
    .layout = { .width = CLAY_SIZING_GROW() },
    .aspectRatio = profilePicture.width / profilePicture.height,
    .image = { .imageData = &amp;amp;profilePicture },
}) {}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_ImageElementConfig&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Image&quot;), { .image = { ...image config } }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Clay_ImageElementConfig&lt;/strong&gt; configures a clay element to render an image as its background.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Struct API (Pseudocode)&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;Clay_ImageElementConfig {
    void * imageData;
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.imageData&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;void *&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Image&quot;), { .image = { .imageData = &amp;amp;myImage } }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;.imageData&lt;/code&gt; is a generic void pointer that can be used to pass through image data to the renderer.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Load an image somewhere in your code
YourImage profilePicture = LoadYourImage(&quot;profilePicture.png&quot;);
// Note that when rendering, .imageData will be void* type.
CLAY(CLAY_ID(&quot;Image&quot;), { .image = { .imageData = &amp;amp;profilePicture } }) {}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note: for an image to maintain its original aspect ratio when using dynamic scaling, the &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_aspectratioelementconfig&quot;&gt;.aspectRatio&lt;/a&gt; config option must be used.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Load an image somewhere in your code
YourImage profilePicture = LoadYourImage(&quot;profilePicture.png&quot;);
// Declare a reusable image config
Clay_ImageElementConfig imageConfig = (Clay_ImageElementConfig) { .imageData = &amp;amp;profilePicture };
// Declare an image element using a reusable config
CLAY(CLAY_ID(&quot;Image&quot;), { .image = imageConfig }) {}
// Declare an image element using an inline config
CLAY(CLAY_ID(&quot;ImageInline&quot;), { .image = { .imageData = &amp;amp;profilePicture }, .aspectRatio = 16.0 / 9.0 }) {}
// Rendering example
YourImage *imageToRender = renderCommand-&amp;gt;elementConfig.imageElementConfig-&amp;gt;imageData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Rendering&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Element is subject to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#visibility-culling&quot;&gt;culling&lt;/a&gt;. Otherwise, a single &lt;code&gt;Clay_RenderCommand&lt;/code&gt;s with &lt;code&gt;commandType = CLAY_RENDER_COMMAND_TYPE_IMAGE&lt;/code&gt; will be created. The user will need to access &lt;code&gt;renderCommand-&amp;gt;renderData.image.imageData&lt;/code&gt; to retrieve image data referenced during layout creation. It&#39;s also up to the user to decide how / if they wish to blend &lt;code&gt;renderCommand-&amp;gt;renderData.image.backgroundColor&lt;/code&gt; with the image.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_ClipElementConfig&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;ScrollBox&quot;), { .clip = { ...clip config } }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;Clay_ClipElementConfig&lt;/code&gt; configures the element as a clipping container, enabling masking of children that extend beyond its boundaries.&lt;/p&gt; 
&lt;p&gt;Note: In order to process scrolling based on pointer position and mouse wheel or touch interactions, you must call &lt;code&gt;Clay_SetPointerState()&lt;/code&gt; and &lt;code&gt;Clay_UpdateScrollContainers()&lt;/code&gt; &lt;em&gt;before&lt;/em&gt; calling &lt;code&gt;BeginLayout&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Struct Definition (Pseudocode)&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;Clay_ClipElementConfig {
    bool horizontal;
    bool vertical;
    Clay_Vector2 childOffset;
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.horizontal&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;bool&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;HorizontalScroll&quot;), { .clip = { .horizontal = true } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Enables or disables horizontal clipping for this container element.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.vertical&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;bool&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(LAY_ID(&quot;VerticalScroll&quot;), { .clip = { .vertical = true } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Enables or disables vertical clipping for this container element.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.childOffset&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Vector2&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(LAY_ID(&quot;VerticalScroll&quot;), { .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Controls the x/y offset for child elements of this clip container. Used to control scrolling. You can either provide the vector manually if you want to manage scrolling yourself, or you can use the built in &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_getscrolloffset&quot;&gt;Clay_GetScrollOffset&lt;/a&gt; function which will manage scrolling for you automatically.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;Rendering&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Enabling clip for an element will result in two additional render commands:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;commandType = CLAY_RENDER_COMMAND_TYPE_SCISSOR_START&lt;/code&gt;, which should create a rectangle mask with its &lt;code&gt;boundingBox&lt;/code&gt; and is &lt;strong&gt;not&lt;/strong&gt; subject to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#visibility-culling&quot;&gt;culling&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;commandType = CLAY_RENDER_COMMAND_TYPE_SCISSOR_END&lt;/code&gt;, which disables the previous rectangle mask and is &lt;strong&gt;not&lt;/strong&gt; subject to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#visibility-culling&quot;&gt;culling&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;CLAY(CLAY_ID(&quot;ScrollOuter&quot;), { .clip = { .vertical = true } }) {
    // Create child content with a fixed height of 5000
    CLAY(CLAY_ID(&quot;ScrollInner&quot;), { .layout = { .sizing = { .height = CLAY_SIZING_FIXED(5000) } } }) {}
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_BorderElementConfig&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Border&quot;), { .border = { ...border config } }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;Clay_BorderElementConfig&lt;/code&gt; adds borders to the edges or between the children of elements. It uses Clay_BorderElementConfig to configure border specific options.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Struct Definition (Pseudocode)&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct Clay_BorderElementConfig
{
    Clay_Color color {
        float r; float g; float b; float a;
    };
    Clay_BorderWidth width {
        uint16_t left;
        uint16_t right;
        uint16_t top;
        uint16_t bottom;
        uint16_t betweenChildren;  
    };
} Clay_BorderElementConfig;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.color&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Color&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Border&quot;), { .border = { .color = { 255, 0, 0, 255 } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_color&quot;&gt;Clay_Color&lt;/a&gt;. Specifies the shared color for all borders configured by this element. Conventionally accepts &lt;code&gt;rgba&lt;/code&gt; float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.width&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_BorderWidth&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Border&quot;), { .border = { .width = { .left = 2, .right = 10 } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Indicates to the renderer that a border of &lt;code&gt;.color&lt;/code&gt; should be draw at the specified edges of the bounding box, &lt;strong&gt;inset and overlapping the box contents by &lt;code&gt;.width&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt; 
&lt;p&gt;This means that border configuration does not affect layout, as the width of the border doesn&#39;t contribute to the total container width or layout position. Border containers with zero padding will be drawn over the top of child elements.&lt;/p&gt; 
&lt;p&gt;Note:&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.width.betweenChildren&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Border&quot;), { .border = { .width = { .betweenChildren = 2 } }, .color = COLOR_RED })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Configures the width and color of borders to be drawn between children. These borders will be vertical lines if the parent uses &lt;code&gt;.layoutDirection = CLAY_LEFT_TO_RIGHT&lt;/code&gt; and horizontal lines if the parent uses &lt;code&gt;CLAY_TOP_TO_BOTTOM&lt;/code&gt;. Unlike &lt;code&gt;.left, .top&lt;/code&gt; etc, this option &lt;strong&gt;will generate additional rectangle render commands representing the borders between children.&lt;/strong&gt; As a result, the renderer does not need to specifically implement rendering for these border elements.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// 300x300 container with a 1px red border around all the edges
CLAY(CLAY_ID(&quot;OuterBorder&quot;), {
    .layout = { .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) } },
    .border = { .width = { 1, 1, 1, 1, 0 }, .color = COLOR_RED }
}) {
    // ...
}

// Container with a 3px yellow bottom border
CLAY(CLAY_ID(&quot;OuterBorder&quot;), {
    .border = { .width = { .bottom = 3 }, .color = COLOR_YELLOW }
}) {
    // ...
}

// Container with a 5px curved border around the edges, and a 5px blue border between all children laid out top to bottom
CLAY(CLAY_ID(&quot;OuterBorder&quot;), {
    .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM },
    .border = { .width = { 5, 5, 5, 5, 5 }, .color = COLOR_BLUE }
}) {
    // Child
    // -- 5px blue border will be here --
    // Child
    // -- 5px blue border will be here --
    // Child
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Rendering&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Element is subject to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#visibility-culling&quot;&gt;culling&lt;/a&gt;. Otherwise, a single &lt;code&gt;Clay_RenderCommand&lt;/code&gt; with &lt;code&gt;commandType = CLAY_RENDER_COMMAND_TYPE_BORDER&lt;/code&gt; representing the container will be created. Rendering of borders and rounded corners is left up to the user. See the provided &lt;a href=&quot;https://github.com/nicbarker/clay/tree/main/renderers/raylib&quot;&gt;Raylib Renderer&lt;/a&gt; for examples of how to draw borders using line and curve primitives.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_FloatingElementConfig&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Floating&quot;), { .floating = { ...floating config } }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Floating Elements&lt;/strong&gt; defines an element that &quot;floats&quot; above other content. Typical use-cases include tooltips and modals.&lt;/p&gt; 
&lt;p&gt;Floating containers:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;With the default configuration, attach to the top left corner of their &quot;parent&quot;&lt;/li&gt; 
 &lt;li&gt;Don&#39;t affect the width and height of their parent&lt;/li&gt; 
 &lt;li&gt;Don&#39;t affect the positioning of sibling elements&lt;/li&gt; 
 &lt;li&gt;Depending on their z-index can appear above or below other elements, partially or completely occluding them&lt;/li&gt; 
 &lt;li&gt;Apart from positioning, function just like standard elements - including expanding to fit their children, etc.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The easiest mental model to use when thinking about floating containers is that they are a completely separate UI hierarchy, attached to a specific x,y point on their &quot;parent&quot;.&lt;/p&gt; 
&lt;p&gt;Floating elements uses &lt;code&gt;Clay_FloatingElementConfig&lt;/code&gt; to configure specific options.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Struct Definition (Pseudocode)&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;Clay_FloatingElementConfig {
    Clay_Vector2 offset {
        float x, float y
    };
    Clay_Dimensions expand {
        float width, float height
    };
    uint32_t parentId;
    int16_t zIndex;
    Clay_FloatingAttachPoints attachPoints {
        .element = CLAY_ATTACH_POINT_LEFT_TOP (default) | CLAY_ATTACH_POINT_LEFT_CENTER | CLAY_ATTACH_POINT_LEFT_BOTTOM | CLAY_ATTACH_POINT_CENTER_TOP | CLAY_ATTACH_POINT_CENTER_CENTER | CLAY_ATTACH_POINT_CENTER_BOTTOM | CLAY_ATTACH_POINT_RIGHT_TOP | CLAY_ATTACH_POINT_RIGHT_CENTER | CLAY_ATTACH_POINT_RIGHT_BOTTOM
        .parent = CLAY_ATTACH_POINT_LEFT_TOP (default) | CLAY_ATTACH_POINT_LEFT_CENTER | CLAY_ATTACH_POINT_LEFT_BOTTOM | CLAY_ATTACH_POINT_CENTER_TOP | CLAY_ATTACH_POINT_CENTER_CENTER | CLAY_ATTACH_POINT_CENTER_BOTTOM | CLAY_ATTACH_POINT_RIGHT_TOP | CLAY_ATTACH_POINT_RIGHT_CENTER | CLAY_ATTACH_POINT_RIGHT_BOTTOM
    };
    Clay_PointerCaptureMode pointerCaptureMode {
        CLAY_POINTER_CAPTURE_MODE_CAPTURE (default),
        CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH
    };
    Clay_FloatingAttachToElement attachTo {
        CLAY_ATTACH_TO_NONE (default),
        CLAY_ATTACH_TO_PARENT,
        CLAY_ATTACH_TO_ELEMENT_WITH_ID,
        CLAY_ATTACH_TO_ROOT,
    };
    Clay_FloatingClipToElement clipTo {
        CLAY_CLIP_TO_NONE (default),
        CLAY_CLIP_TO_ATTACHED_PARENT,
    };
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.offset&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Vector2&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Floating&quot;), { .floating = { .offset = { -24, -24 } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Used to apply a position offset to the floating container &lt;em&gt;after&lt;/em&gt; all other layout has been calculated.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.expand&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Dimensions&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Floating&quot;), { .floating = { .expand = { 16, 16 } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Used to expand the width and height of the floating container &lt;em&gt;before&lt;/em&gt; laying out child elements.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.zIndex&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;int16_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Floating&quot;), { .floating = { .zIndex = 1 } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;All floating elements (as well as their entire child hierarchies) will be sorted by &lt;code&gt;.zIndex&lt;/code&gt; order before being converted to render commands. If render commands are drawn in order, elements with higher &lt;code&gt;.zIndex&lt;/code&gt; values will be drawn on top.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.parentId&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;uint32_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Floating&quot;), { .floating = { .parentId = Clay_GetElementId(&quot;HeaderButton&quot;).id } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;By default, floating containers will &quot;attach&quot; to the parent element that they are declared inside. However, there are cases where this limitation could cause significant performance or ergonomics problems. &lt;code&gt;.parentId&lt;/code&gt; allows you to specify a &lt;code&gt;CLAY_ID().id&lt;/code&gt; to attach the floating container to. The parent element with the matching id can be declared anywhere in the hierarchy, it doesn&#39;t need to be declared before or after the floating container in particular.&lt;/p&gt; 
&lt;p&gt;Consider the following case:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Load an image somewhere in your code
CLAY(CLAY_IDI(&quot;SidebarButton&quot;, 1), { }) {
    // .. some button contents
    if (tooltip.attachedButtonIndex == 1) {
        CLAY(CLAY_ID(&quot;OptionTooltip&quot;), { /* floating config... */ })
    }
}
CLAY(CLAY_IDI(&quot;SidebarButton&quot;, 2), { }) {
    // .. some button contents
    if (tooltip.attachedButtonIndex == 2) {
        CLAY(CLAY_ID(&quot;OptionTooltip&quot;), { /* floating config... */ })
    }
}
CLAY(CLAY_IDI(&quot;SidebarButton&quot;, 3), { }) {
    // .. some button contents
    if (tooltip.attachedButtonIndex == 3) {
        CLAY(CLAY_ID(&quot;OptionTooltip&quot;), { /* floating config... */ })
    }
}
CLAY(CLAY_IDI(&quot;SidebarButton&quot;, 4), { }) {
    // .. some button contents
    if (tooltip.attachedButtonIndex == 4) {
        CLAY(CLAY_ID(&quot;OptionTooltip&quot;), { /* floating config... */ })
    }
}
CLAY(CLAY_IDI(&quot;SidebarButton&quot;, 5), { }) {
    // .. some button contents
    if (tooltip.attachedButtonIndex == 5) {
        CLAY(CLAY_ID(&quot;OptionTooltip&quot;), { /* floating config... */ })
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The definition of the above UI is significantly polluted by the need to conditionally render floating tooltips as a child of many possible elements. The alternative, using &lt;code&gt;parentId&lt;/code&gt;, looks like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Load an image somewhere in your code
CLAY(CLAY_IDI(&quot;SidebarButton&quot;, 1), { }) {
    // .. some button contents
}
CLAY(CLAY_IDI(&quot;SidebarButton&quot;, 2), { }) {
    // .. some button contents
}
CLAY(CLAY_IDI(&quot;SidebarButton&quot;, 3), { }) {
    // .. some button contents
}
CLAY(CLAY_IDI(&quot;SidebarButton&quot;, 4), { }) {
    // .. some button contents
}
CLAY(CLAY_IDI(&quot;SidebarButton&quot;, 5), { }) {
    // .. some button contents
}

// Any other point in the hierarchy
CLAY(CLAY_ID(&quot;OptionTooltip&quot;), { .floating = { .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID, .parentId = CLAY_IDI(&quot;SidebarButton&quot;, tooltip.attachedButtonIndex).id }) {
    // Tooltip contents...
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.attachPoints&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_FloatingAttachPoints&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Floating&quot;), { .floating = { .attachPoints = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_TOP } } }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;In terms of positioning the floating container, &lt;code&gt;.attachPoints&lt;/code&gt; specifies&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The point on the floating container (&lt;code&gt;.element&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;The point on the parent element that it &quot;attaches&quot; to (&lt;code&gt;.parent&lt;/code&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/b8c6dfaa-c1b1-41a4-be55-013473e4a6ce&quot; alt=&quot;Screenshot 2024-08-23 at 11 47 21 AM&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;You can mentally visualise this as finding a point on the floating container, then finding a point on the parent, and lining them up over the top of one another.&lt;/p&gt; 
&lt;p&gt;For example:&lt;/p&gt; 
&lt;p&gt;&quot;Attach the LEFT_BOTTOM of the floating container to the CENTER_CENTER of the parent&quot;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Floating&quot;), { .floating = { .attachPoints = { .element = CLAY_ATTACH_POINT_LEFT_BOTTOM, .parent = CLAY_ATTACH_POINT_CENTER_CENTER } } });&lt;/code&gt;&lt;/p&gt; 
&lt;img width=&quot;1200&quot; height=&quot;675&quot; alt=&quot;Clay README Graphics&quot; src=&quot;https://github.com/user-attachments/assets/95a829e3-ec17-47f2-8d16-10fda4968189&quot; /&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.pointerCaptureMode&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_PointerCaptureMode&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY({ .floating = { .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_CAPTURE } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Controls whether pointer events like hover and click should pass through to content underneath this floating element, or whether the pointer should be &quot;captured&quot; by this floating element. Defaults to &lt;code&gt;CLAY_POINTER_CAPTURE_MODE_CAPTURE&lt;/code&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.clipTo&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_FloatingClipToElement&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY({ .floating = { .clipTo = CLAY_CLIP_TO_ATTACHED_PARENT } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;By default, floating elements will appear with a z-order &lt;strong&gt;above&lt;/strong&gt; their parent, and won&#39;t be clipped by a &lt;code&gt;.clip&lt;/code&gt; defined on that parent. To clip floating elements by their parents&#39; clip rectangle, use &lt;code&gt;.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT&lt;/code&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef enum {
    CLAY_CLIP_TO_NONE,
    CLAY_CLIP_TO_ATTACHED_PARENT,
} Clay_FloatingClipToElement;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Horizontal container with three option buttons
CLAY(CLAY_ID(&quot;OptionsList&quot;), { .layout = { childGap = 16 } }) {
    CLAY(CLAY_IDI(&quot;Option&quot;, 1), { .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
        CLAY_TEXT(CLAY_STRING(&quot;Option 1&quot;), {});
    }
    CLAY(CLAY_IDI(&quot;Option&quot;, 2), { .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
        CLAY_TEXT(CLAY_STRING(&quot;Option 2&quot;), {});
        // Floating tooltip will attach above the &quot;Option 2&quot; container and not affect widths or positions of other elements
        CLAY(CLAY_ID(&quot;OptionTooltip&quot;), { .floating = { .zIndex = 1, .attachPoints = { .element = CLAY_ATTACH_POINT_CENTER_BOTTOM, .parent = CLAY_ATTACH_POINT_CENTER_TOP } } }) {
            CLAY_TEXT(CLAY_STRING(&quot;Most popular!&quot;), {});
        }
    }
    CLAY(CLAY_IDI(&quot;Option&quot;, 3), { .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
        CLAY_TEXT(CLAY_STRING(&quot;Option 3&quot;), {});
    }
}

// Floating containers can also be declared elsewhere in a layout, to avoid branching or polluting other UI
for (int i = 0; i &amp;lt; 1000; i++) {
    CLAY(CLAY_IDI(&quot;Option&quot;, i + 1), { }) {
        // ...
    }
}
// Note the use of &quot;parentId&quot;.
// Floating tooltip will attach above the &quot;Option 2&quot; container and not affect widths or positions of other elements
CLAY(CLAY_ID(&quot;OptionTooltip&quot;), { .floating = { .parentId = CLAY_IDI(&quot;Option&quot;, 2).id, .zIndex = 1, .attachPoints = { .element = CLAY_ATTACH_POINT_CENTER_BOTTOM, .parent = CLAY_ATTACH_POINT_TOP_CENTER } } }) {
    CLAY_TEXT(CLAY_STRING(&quot;Most popular!&quot;), {});
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;When using &lt;code&gt;.parentId&lt;/code&gt;, the floating container can be declared anywhere after &lt;code&gt;BeginLayout&lt;/code&gt; and before &lt;code&gt;EndLayout&lt;/code&gt;. The target element matching the &lt;code&gt;.parentId&lt;/code&gt; doesn&#39;t need to exist when &lt;code&gt;Clay_FloatingElementConfig&lt;/code&gt; is used.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rendering&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;Clay_FloatingElementConfig&lt;/code&gt; will not generate any specific render commands.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_CustomElementConfig&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Custom&quot;), { .custom = { .customData = &amp;amp;something } }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Clay_CustomElementConfig&lt;/strong&gt; allows the user to pass custom data to the renderer.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Struct Definition (Pseudocode)&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct
{
    void * customData;
} Clay_CustomElementConfig;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;.customData&lt;/code&gt; - &lt;code&gt;void *&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY({ .custom = { .customData = &amp;amp;myCustomData } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;.customData&lt;/code&gt; is a generic void pointer that can be used to pass through custom data to the renderer.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &quot;clay.h&quot;

typedef enum {
    CUSTOM_ELEMENT_TYPE_MODEL,
    CUSTOM_ELEMENT_TYPE_VIDEO
} CustomElementType;

// A rough example of how you could handle laying out 3d models in your UI
typedef struct {
    CustomElementType type;
    union {
        Model model;
        Video video;
        // ...
    };
} CustomElementData;

Model myModel = Load3DModel(filePath);
CustomElement modelElement = (CustomElement) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel }

typedef struct {
    void* memory;
    uintptr_t offset;
} Arena;

// During init
Arena frameArena = (Arena) { .memory = malloc(1024) };

// ...
CLAY(0) {
    // Custom elements only take a single pointer, so we need to store the data somewhere
    CustomElementData *modelData = (CustomElementData *)(frameArena.memory + frameArena.offset);
    *modelData = (CustomElementData) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel };
    frameArena.offset += sizeof(CustomElementData);
    CLAY(CLAY_ID(&quot;3DModelViewer&quot;), { .custom = { .customData = modelData } }) {}
}

// Later during your rendering
switch (renderCommand-&amp;gt;commandType) {
    // ...
    case CLAY_RENDER_COMMAND_TYPE_CUSTOM: {
        // Your extended struct is passed through
        CustomElementData *customElement = renderCommand-&amp;gt;config.customElementConfig-&amp;gt;customData;
        if (!customElement) continue;
        switch (customElement-&amp;gt;type) {
            case CUSTOM_ELEMENT_TYPE_MODEL: {
                // Render your 3d model here
                break;
            }
            case CUSTOM_ELEMENT_TYPE_VIDEO: {
                // Render your video here
                break;
            }
            // ...
        }
        break;
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Rendering&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Element is subject to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#visibility-culling&quot;&gt;culling&lt;/a&gt;. Otherwise, a single &lt;code&gt;Clay_RenderCommand&lt;/code&gt; with &lt;code&gt;commandType = CLAY_RENDER_COMMAND_TYPE_CUSTOM&lt;/code&gt; will be created.&lt;/p&gt; 
&lt;h3&gt;Clay_TransitionElementConfig&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Transition&quot;), { .transition = { ...transition config } }) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;Clay_TransitionElementConfig&lt;/code&gt; is used to configure element &quot;transitions&quot;, which are animations between states. A &lt;code&gt;.handler&lt;/code&gt; function and &lt;code&gt;.properties&lt;/code&gt; must be provided for transitions to occur.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Struct Definition (Pseudocode)&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct Clay_TransitionElementConfig
{
    // Handler function pointer for computing current frame state, see below for more info
    bool (*handler)(Clay_TransitionCallbackArguments arguments);
    float duration;
    // Note: this is a flags field. You can pass multiple properties using a bitwise OR, e.g. CLAY_TRANSITION_PROPERTY_OVERLAY_COLOR | CLAY_TRANSITION_PROPERTY_CORNER_RADIUS
    Clay_TransitionProperty properties = {
      CLAY_TRANSITION_PROPERTY_NONE (default),
      CLAY_TRANSITION_PROPERTY_X,
      CLAY_TRANSITION_PROPERTY_Y,
      CLAY_TRANSITION_PROPERTY_POSITION = CLAY_TRANSITION_PROPERTY_X | CLAY_TRANSITION_PROPERTY_Y,
      CLAY_TRANSITION_PROPERTY_WIDTH,
      CLAY_TRANSITION_PROPERTY_HEIGHT,
      CLAY_TRANSITION_PROPERTY_DIMENSIONS = CLAY_TRANSITION_PROPERTY_WIDTH | CLAY_TRANSITION_PROPERTY_HEIGHT,
      CLAY_TRANSITION_PROPERTY_BOUNDING_BOX = CLAY_TRANSITION_PROPERTY_POSITION | CLAY_TRANSITION_PROPERTY_DIMENSIONS,
      CLAY_TRANSITION_PROPERTY_BACKGROUND_COLOR,
      CLAY_TRANSITION_PROPERTY_OVERLAY_COLOR,
      CLAY_TRANSITION_PROPERTY_CORNER_RADIUS,
      CLAY_TRANSITION_PROPERTY_BORDER_COLOR,
      CLAY_TRANSITION_PROPERTY_BORDER_WIDTH,
      CLAY_TRANSITION_PROPERTY_BORDER = CLAY_TRANSITION_PROPERTY_BORDER_COLOR | CLAY_TRANSITION_PROPERTY_BORDER_WIDTH
    };
    Clay_TransitionInteractionHandlingType interactionHandling {
        CLAY_TRANSITION_DISABLE_INTERACTIONS_WHILE_TRANSITIONING_POSITION (default),
        CLAY_TRANSITION_ALLOW_INTERACTIONS_WHILE_TRANSITIONING_POSITION,
    };
    struct {
        // Function pointer, see below for details
        Clay_TransitionData (*setInitialState)(Clay_TransitionData targetState, Clay_TransitionProperty properties);
        Clay_TransitionEnterTriggerType trigger {
            CLAY_TRANSITION_ENTER_SKIP_ON_FIRST_PARENT_FRAME (default),
            CLAY_TRANSITION_ENTER_TRIGGER_ON_FIRST_PARENT_FRAME,
        };
    } enter;
    struct {
        Clay_TransitionData (*setFinalState)(Clay_TransitionData initialState, Clay_TransitionProperty properties);
        Clay_TransitionExitTriggerType trigger {
            CLAY_TRANSITION_EXIT_SKIP_WHEN_PARENT_EXITS (default),
            CLAY_TRANSITION_EXIT_TRIGGER_WHEN_PARENT_EXITS,
        };
        Clay_ExitTransitionSiblingOrdering siblingOrdering {
            CLAY_EXIT_TRANSITION_ORDERING_UNDERNEATH_SIBLINGS (default),
            CLAY_EXIT_TRANSITION_ORDERING_NATURAL_ORDER,
            CLAY_EXIT_TRANSITION_ORDERING_ABOVE_SIBLINGS,
        };
    } exit;
} Clay_TransitionElementConfig;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.handler&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;bool (Clay_TransitionCallbackArguments arguments) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Transition&quot;), { .transition = { .handler = Clay_EaseOut } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;When a transition has begun, this function will be called each frame to determine the current state of the element in transition. Clay provides the built-in &lt;code&gt;Clay_EaseOut&lt;/code&gt; function which uses a standard &lt;a href=&quot;https://easings.net/&quot;&gt;EaseOut&lt;/a&gt; curve.&lt;/p&gt; 
&lt;p&gt;If you want to implement your own transition handler, the handler function takes &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/todo&quot;&gt;Clay_TransitionCallbackArguments&lt;/a&gt; and returns a &lt;code&gt;bool&lt;/code&gt; to indicate whether the transition has finished or not (&lt;code&gt;return true&lt;/code&gt; means the transition is complete, &lt;code&gt;return false&lt;/code&gt; means that the handler should be called again next frame) Consider inspecting the source of the &lt;a href=&quot;&quot;&gt;Clay_EaseOut&lt;/a&gt; function for more information.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Example custom handler
bool TransitionHandler(Clay_TransitionCallbackArguments arguments) {
    float ratio = 1;
    if (arguments.duration &amp;gt; 0) {
        // You may want to guard against durations of zero if you use them
        ratio = arguments.elapsedTime / arguments.duration;
    }
    float lerpAmount = (1 - powf(1 - CLAY__MIN(ratio, 1.f), 3.0f));
    // Only animate properties that were specified in the original config
    if (arguments.properties &amp;amp; CLAY_TRANSITION_PROPERTY_X) {
        // Clay provides the initial state from when the transition first started, as well as the target state, to allow
        // easy interpolation
        arguments.current-&amp;gt;boundingBox.x = Lerp(arguments.initial.boundingBox.x, arguments.target.boundingBox.x, lerpAmount);
    }
    if (arguments.properties &amp;amp; CLAY_TRANSITION_PROPERTY_Y) {
        arguments.current-&amp;gt;boundingBox.y = Lerp(arguments.initial.boundingBox.y, arguments.target.boundingBox.y, lerpAmount);
    }
    // etc...
    
    // End (return true) once elapsedTime is greater than duration 
    return ratio &amp;gt;= 1;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.duration&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;float&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Transition&quot;), { .transition = { .duration = 0.2f } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;The duration in seconds that the transition should take to arrive at its target state. Passed through to the handler function.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.properties&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_TransitionProperty&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Transition&quot;), { .transition = { .properties = CLAY_TRANSITION_PROPERTY_X | CLAY_TRANSITION_PROPERTY_OVERLAY_COLOR } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A flag field containing the properties on which to transition. Any properties that change but are not listed here will immediately snap to their target value.&lt;/p&gt; 
&lt;p&gt;This flag is a bitfield, which means that you will use bitwise operations to interact with it. For example, use bitwise OR &lt;code&gt;|&lt;/code&gt; to combine multiple flags, or bitwise AND &lt;code&gt;&amp;amp;&lt;/code&gt; to test if a flag is switched on.&lt;/p&gt; 
&lt;p&gt;The full list of available transition properties is as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef enum {
      CLAY_TRANSITION_PROPERTY_NONE (default),
      CLAY_TRANSITION_PROPERTY_X,
      CLAY_TRANSITION_PROPERTY_Y,
      CLAY_TRANSITION_PROPERTY_POSITION = CLAY_TRANSITION_PROPERTY_X | CLAY_TRANSITION_PROPERTY_Y,
      CLAY_TRANSITION_PROPERTY_WIDTH,
      CLAY_TRANSITION_PROPERTY_HEIGHT,
      CLAY_TRANSITION_PROPERTY_DIMENSIONS = CLAY_TRANSITION_PROPERTY_WIDTH | CLAY_TRANSITION_PROPERTY_HEIGHT,
      CLAY_TRANSITION_PROPERTY_BOUNDING_BOX = CLAY_TRANSITION_PROPERTY_POSITION | CLAY_TRANSITION_PROPERTY_DIMENSIONS,
      CLAY_TRANSITION_PROPERTY_BACKGROUND_COLOR,
      CLAY_TRANSITION_PROPERTY_OVERLAY_COLOR,
      CLAY_TRANSITION_PROPERTY_CORNER_RADIUS,
      CLAY_TRANSITION_PROPERTY_BORDER_COLOR,
      CLAY_TRANSITION_PROPERTY_BORDER_WIDTH,
      CLAY_TRANSITION_PROPERTY_BORDER = CLAY_TRANSITION_PROPERTY_BORDER_COLOR | CLAY_TRANSITION_PROPERTY_BORDER_WIDTH
} Clay_TransitionProperty;
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.interactionHandling&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_TransitionInteractionHandlingType&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Transition&quot;), { .transition = { .interactionHandling = CLAY_TRANSITION_ALLOW_INTERACTIONS_WHILE_TRANSITIONING_POSITION } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;This flag controls how interactions are handled when elements are transitioning their &lt;strong&gt;positions&lt;/strong&gt;. By default, Clay will ignore interactions i.e. returning &lt;code&gt;false&lt;/code&gt; for functions like &lt;code&gt;Clay_Hovered()&lt;/code&gt; when &lt;code&gt;.interactionHandling&lt;/code&gt; is in the default mode of &lt;code&gt;CLAY_TRANSITION_DISABLE_INTERACTIONS_WHILE_TRANSITIONING&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;You can set &lt;code&gt;.interactionHandling = CLAY_TRANSITION_ALLOW_INTERACTIONS_WHILE_TRANSITIONING_POSITION&lt;/code&gt; if you want to interact with transitioning elements.&lt;/p&gt; 
&lt;p&gt;The full list of values is as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef enum {
    CLAY_TRANSITION_DISABLE_INTERACTIONS_WHILE_TRANSITIONING_POSITION (default),
    CLAY_TRANSITION_ALLOW_INTERACTIONS_WHILE_TRANSITIONING_POSITION,
} Clay_TransitionInteractionHandlingType;
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.enter.setInitialState&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_TransitionData (Clay_TransitionData targetState, Clay_TransitionProperty properties) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Transition&quot;), { .transition = { .enter = { .setInitialState = { EnterSlideUp } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;This function pointer is called the first frame an element appears, and allows you to modify the &quot;initial state&quot; of the element to create an entry transition. Common techniques include offsetting the y position to &quot;slide up / down&quot;, or using a &lt;code&gt;.overlayColor&lt;/code&gt; matched to the background color to fade in.&lt;/p&gt; 
&lt;p&gt;The function will be called with &lt;code&gt;Clay_TransitionData&lt;/code&gt; that provides the first-frame state of the element, which you can modify and then return.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Note: &quot;Enter&quot; transitions will only trigger if this function pointer is set.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Here is an example &quot;fade in &amp;amp; slide up&quot; function:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;Clay_TransitionData EnterSlideUp(Clay_TransitionData initialState, Clay_TransitionProperty properties) {
    Clay_TransitionData targetState = initialState;
    if (properties &amp;amp; CLAY_TRANSITION_PROPERTY_Y) {
        targetState.boundingBox.y += 20;
    }
    if (properties &amp;amp; CLAY_TRANSITION_PROPERTY_OVERLAY_COLOR) {
        // Assuming the background color is white, this will produce an alpha-like &quot;fade-in&quot; effect
        targetState.overlayColor = (Clay_Color) { 255, 255, 255, 255 };
    }
    return targetState;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.enter.trigger&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_TransitionEnterTriggerType&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Transition&quot;), { .transition = { .enter = { .trigger = CLAY_TRANSITION_ENTER_TRIGGER_ON_FIRST_PARENT_FRAME } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;This flag controls whether or not the &quot;enter&quot; transition of this element will trigger on the same frame that the parent element first appeared.&lt;/p&gt; 
&lt;p&gt;A common use case for enter transitions is adding items to animated lists. Without this flag, the first frame the list is displayed, all the item enter animations will simultaneously trigger, which is usually undesirable.&lt;/p&gt; 
&lt;p&gt;For cases where you &lt;em&gt;do&lt;/em&gt; want enter animations to trigger when the parent first appears, you can set &lt;code&gt;.trigger = CLAY_TRANSITION_ENTER_TRIGGER_ON_FIRST_PARENT_FRAME&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;The full list of values is as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef enum trigger {
  CLAY_TRANSITION_ENTER_SKIP_ON_FIRST_PARENT_FRAME (default),
  CLAY_TRANSITION_ENTER_TRIGGER_ON_FIRST_PARENT_FRAME,
} Clay_TransitionEnterTriggerType;
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.exit.setFinalState&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_TransitionData (Clay_TransitionData currentState, Clay_TransitionProperty properties) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Transition&quot;), { .transition = { .exit = { .setFinalState = { ExitSlideDown } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;This function pointer is called the frame the element &quot;exits&quot; (i.e. it was in the layout tree last frame, and this frame it isn&#39;t). It allows you to modify the &quot;final state&quot; of the element to create an exit transition. Common techniques include offsetting the y position to &quot;slide up / down&quot;, or using a &lt;code&gt;.overlayColor&lt;/code&gt; matched to the background color to fade out.&lt;/p&gt; 
&lt;p&gt;The function will be called with &lt;code&gt;Clay_TransitionData&lt;/code&gt; that provides the final-frame state of the element, which you can modify and then return.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Note: &quot;Exit&quot; transitions will only trigger if this function pointer is set.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Here is an example &quot;fade out &amp;amp; slide down&quot; function:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;Clay_TransitionData ExitSlideDown(Clay_TransitionData currentState, Clay_TransitionProperty properties) {
    Clay_TransitionData finalState = currentState;
    if (properties &amp;amp; CLAY_TRANSITION_PROPERTY_Y) {
        finalState.boundingBox.y += 20;
    }
    if (properties &amp;amp; CLAY_TRANSITION_PROPERTY_OVERLAY_COLOR) {
        // Assuming the background color is white, this will produce an alpha-like &quot;fade-out&quot; effect
        finalState.overlayColor = (Clay_Color) { 255, 255, 255, 255 };
    }
    return finalState;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.exit.trigger&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_TransitionExitTriggerType&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Transition&quot;), { .transition = { .exit = { .trigger = CLAY_TRANSITION_EXIT_TRIGGER_WHEN_PARENT_EXITS } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;This flag controls whether or not the &quot;exit&quot; transition of this element will trigger on the same frame that the parent element disappears.&lt;/p&gt; 
&lt;p&gt;A common use case for exit transitions is removing items from animated lists. Without this flag, the frame after the list disappears (due to say, menu navigation), all the item exit animations will simultaneously trigger, which is usually undesirable.&lt;/p&gt; 
&lt;p&gt;For cases where you &lt;em&gt;do&lt;/em&gt; want exit animations to trigger when the parent exits, you can set &lt;code&gt;.trigger = CLAY_TRANSITION_EXIT_TRIGGER_WHEN_PARENT_EXITS&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;The full list of values is as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef enum {
  CLAY_TRANSITION_EXIT_SKIP_WHEN_PARENT_EXITS (default),
  CLAY_TRANSITION_EXIT_TRIGGER_WHEN_PARENT_EXITS,
} Clay_TransitionExitTriggerType;
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.exit.siblingOrdering&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_ExitTransitionSiblingOrdering&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;CLAY(CLAY_ID(&quot;Transition&quot;), { .transition = { .exit = { .siblingOrdering = CLAY_EXIT_TRANSITION_ORDERING_NATURAL_ORDER } } })&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;This flag controls the relative z-ordering of exiting elements.&lt;/p&gt; 
&lt;p&gt;It&#39;s often useful to be able to control whether you want an exiting element to appear &quot;underneath siblings&quot; in its &quot;natural order&quot; (i.e. above the previous sibling, below the subsequent sibling) or &quot;above all siblings.&quot;&lt;/p&gt; 
&lt;p&gt;By default, exiting elements will be underneath siblings as this appears to be the most common case.&lt;/p&gt; 
&lt;p&gt;The full list of values is as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef enum {
  CLAY_EXIT_TRANSITION_ORDERING_UNDERNEATH_SIBLINGS (default),
  CLAY_EXIT_TRANSITION_ORDERING_NATURAL_ORDER,
  CLAY_EXIT_TRANSITION_ORDERING_ABOVE_SIBLINGS,
} Clay_ExitTransitionSiblingOrdering;
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;See video below for how the following would look.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Note: for transitions to work, elements need a stable ID from one frame to the next - using loop indexes or CLAY_AUTO_ID will not work.
CLAY(CLAY_IDI(&quot;box&quot;, colors[index].id), {
    .layout.sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() },
    .layout.childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER },
    .backgroundColor = boxColor,
    .overlayColor = Clay_Hovered() ? (Clay_Color) { 140, 140, 140, 80 } : (Clay_Color) { 255, 255, 255, 0 },
    // Transitions will activate once a handler function is defined.
    .transition = {
        .handler = Clay_EaseOut,
        .duration = 0.5f,
        // A &quot;flag&quot; enum is used to specify which properties to transition, use a bitwise OR (|) to construct the flags.
        .properties = CLAY_TRANSITION_PROPERTY_WIDTH
                | CLAY_TRANSITION_PROPERTY_POSITION
                | CLAY_TRANSITION_PROPERTY_OVERLAY_COLOR
                | CLAY_TRANSITION_PROPERTY_BACKGROUND_COLOR,
        .enter = { .setInitialState = EnterExitSlideUp },
        .exit = { .setFinalState = EnterExitSlideUp },
    }
}) {
    CLAY_TEXT(CLAY_STRING(&quot;Animated Box&quot;), {
      .fontSize = 32,
      .textColor = colors[index].id &amp;gt; 29 ? (Clay_Color) { 255, 255, 255, 255 } : (Clay_Color) { 154, 123, 184, 255 }
    });
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;
 &lt;video src=&quot;https://github.com/user-attachments/assets/a8e5cd88-f0da-4fad-acd0-81f253436bc7&quot; controls&gt;&lt;/video&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;An example of the transition API action can be found at examples/raylib-transitions&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Clay_Color&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    float r, g, b, a;
} Clay_Color;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;Clay_Color&lt;/code&gt; is an RGBA color struct used in Clay&#39;s declarations and rendering. By convention the channels are represented as 0-255, but this is left up to the renderer. Note: when using the debug tools, their internal colors are represented as 0-255.&lt;/p&gt; 
&lt;h3&gt;Clay_String&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    bool isStaticallyAllocated;
    int32_t length;
    const char *chars;
} Clay_String;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;Clay_String&lt;/code&gt; is a string container that clay uses internally to represent all strings.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.isStaticallyAllocated&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;bool&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Whether or not the string is statically allocated, or in other words, whether or not it lives for the entire lifetime of the program.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.length&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;int32_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;The number of characters in the string, &lt;em&gt;not including an optional null terminator.&lt;/em&gt;&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.chars&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;const char *&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A pointer to the contents of the string. This data is not guaranteed to be null terminated, so if you are passing it to code that expects standard null terminated C strings, you will need to copy the data and append a null terminator.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_ElementId&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    uint32_t id;
    uint32_t offset;
    uint32_t baseId;
    Clay_String stringId;
} Clay_ElementId;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Returned by &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id&quot;&gt;CLAY_ID&lt;/a&gt; and &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_idi&quot;&gt;CLAY_IDI&lt;/a&gt;, this struct contains a hash id, as well as the source string that was used to generate it.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.id&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;uint32_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A unique ID derived from the string passed to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id&quot;&gt;CLAY_ID&lt;/a&gt; or &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_idi&quot;&gt;CLAY_IDI&lt;/a&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.offset&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;uint32_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;If this id was generated using &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_idi&quot;&gt;CLAY_IDI&lt;/a&gt;, &lt;code&gt;.offset&lt;/code&gt; is the value passed as the second argument. For &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id&quot;&gt;CLAY_ID&lt;/a&gt;, this will always be &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.baseId&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;uint32_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;If this id was generated using &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_idi&quot;&gt;CLAY_IDI&lt;/a&gt;, &lt;code&gt;.baseId&lt;/code&gt; is the hash of the base string passed, &lt;strong&gt;before it is additionally hashed with &lt;code&gt;.offset&lt;/code&gt;&lt;/strong&gt;. For &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id&quot;&gt;CLAY_ID&lt;/a&gt;, this will always be the same as &lt;code&gt;.id&lt;/code&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.stringId&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_String&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Stores the original string that was passed in when &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id&quot;&gt;CLAY_ID&lt;/a&gt; or &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_idi&quot;&gt;CLAY_IDI&lt;/a&gt; were called.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_RenderCommandArray&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct
{
	int32_t capacity;
	int32_t length;
	Clay_RenderCommand *internalArray;
} Clay_RenderCommandArray;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Returned by &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_endlayout&quot;&gt;Clay_EndLayout&lt;/a&gt;, this array contains the &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_rendercommand&quot;&gt;Clay_RenderCommand&lt;/a&gt;s representing the calculated layout.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.capacity&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;uint32_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Represents the total capacity of the allocated memory in &lt;code&gt;.internalArray&lt;/code&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.length&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;uint32_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Represents the total number of &lt;code&gt;Clay_RenderCommand&lt;/code&gt; elements stored consecutively at the address &lt;code&gt;.internalArray&lt;/code&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.internalArray&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_RenderCommand&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;An array of &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_rendercommand&quot;&gt;Clay_RenderCommand&lt;/a&gt;s representing the calculated layout. If there was at least one render command, this array will contain elements from &lt;code&gt;.internalArray[0]&lt;/code&gt; to &lt;code&gt;.internalArray[.length - 1]&lt;/code&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_RenderCommand&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    Clay_BoundingBox boundingBox;
    Clay_RenderData renderData;
    void* userData;
    uint32_t id;
    int16_t zIndex;
    Clay_RenderCommandType commandType;
} Clay_RenderCommand;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.commandType&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_RenderCommandType&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;An enum indicating how this render command should be handled. Possible values include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_RENDER_COMMAND_TYPE_NONE&lt;/code&gt; - Should be ignored by the renderer, and never emitted by clay under normal conditions.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_RENDER_COMMAND_TYPE_RECTANGLE&lt;/code&gt; - A rectangle should be drawn, configured with &lt;code&gt;.renderData.rectangle&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_RENDER_COMMAND_TYPE_BORDER&lt;/code&gt; - A border should be drawn, configured with &lt;code&gt;.renderData.border&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_RENDER_COMMAND_TYPE_TEXT&lt;/code&gt; - Text should be drawn, configured with &lt;code&gt;.renderData.text&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_RENDER_COMMAND_TYPE_IMAGE&lt;/code&gt; - An image should be drawn, configured with &lt;code&gt;.renderData.image&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_RENDER_COMMAND_TYPE_SCISSOR_START&lt;/code&gt; - Named after &lt;a href=&quot;https://registry.khronos.org/OpenGL-Refpages/gl4/html/glScissor.xhtml&quot;&gt;glScissor&lt;/a&gt;, this indicates that the renderer should begin culling any subsequent pixels that are drawn outside the &lt;code&gt;.boundingBox&lt;/code&gt; of this render command.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_RENDER_COMMAND_TYPE_SCISSOR_END&lt;/code&gt; - Only ever appears after a matching &lt;code&gt;CLAY_RENDER_COMMAND_TYPE_SCISSOR_START&lt;/code&gt; command, and indicates that the scissor has ended.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_RENDER_COMMAND_TYPE_OVERLAY_COLOR_START&lt;/code&gt; - The renderer should begin applying an overlay color to all subsequent render commands, similar to glsl&#39;s &lt;code&gt;mix(source, target, alpha)&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_RENDER_COMMAND_TYPE_OVERLAY_COLOR_END&lt;/code&gt; - The previous &lt;code&gt;OVERLAY_COLOR&lt;/code&gt; should be removed. Note: nested color overlays may require a stack data structure on the renderer side.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_RENDER_COMMAND_TYPE_CUSTOM&lt;/code&gt; - A custom render command controlled by the user, configured with &lt;code&gt;.renderData.custom&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.boundingBox&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_BoundingBox&lt;/code&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    float x, y, width, height;
} Clay_BoundingBox;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;A rectangle representing the bounding box of this render command, with &lt;code&gt;.x&lt;/code&gt; and &lt;code&gt;.y&lt;/code&gt; representing the top left corner of the element.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.id&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;uint32_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;The id that was originally used with the element macro that created this render command. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_id&quot;&gt;CLAY_ID&lt;/a&gt; for details.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.zIndex&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;int16_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;The z index of the element, based on what was passed to the root floating configuration that this element is a child of. Higher z indexes should be rendered &lt;em&gt;on top&lt;/em&gt; of lower z indexes.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.renderData&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_RenderData&lt;/code&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef union {
    Clay_RectangleRenderData rectangle;
    Clay_TextRenderData text;
    Clay_ImageRenderData image;
    Clay_CustomRenderData custom;
    Clay_BorderRenderData border;
} Clay_RenderData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;A C union containing various structs, with the type dependent on &lt;code&gt;.commandType&lt;/code&gt;. Possible values include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;renderData.rectangle&lt;/code&gt; - Used when &lt;code&gt;.commandType == CLAY_RENDER_COMMAND_TYPE_RECTANGLE&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;renderData.text&lt;/code&gt; - Used when &lt;code&gt;.commandType == CLAY_RENDER_COMMAND_TYPE_TEXT&lt;/code&gt;. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_text&quot;&gt;Clay_Text&lt;/a&gt; for details.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;renderData.image&lt;/code&gt; - Used when &lt;code&gt;.commandType == CLAY_RENDER_COMMAND_TYPE_IMAGE&lt;/code&gt;. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_imageelementconfig&quot;&gt;Clay_ImageElementConfig&lt;/a&gt; for details.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;renderData.custom&lt;/code&gt; - Used when &lt;code&gt;.commandType == CLAY_RENDER_COMMAND_TYPE_CUSTOM&lt;/code&gt;. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_customelementconfig&quot;&gt;Clay_CustomElementConfig&lt;/a&gt; for details.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;renderData.border&lt;/code&gt; - Used when &lt;code&gt;.commandType == CLAY_RENDER_COMMAND_TYPE_BORDER&lt;/code&gt;. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_borderelementconfig&quot;&gt;Clay_BorderElementConfig&lt;/a&gt; for details.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;renderData.clip&lt;/code&gt; - Used when &lt;code&gt;.commandType == CLAY_RENDER_COMMAND_TYPE_SCISSOR_START&lt;/code&gt;. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_clipelementconfig&quot;&gt;Clay_ClipElementConfig&lt;/a&gt; for details.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;renderData.overlayColor&lt;/code&gt; - Used when &lt;code&gt;.commandType == CLAY_RENDER_COMMAND_TYPE_OVERLAY_COLOR_START&lt;/code&gt;. See &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_elementdeclaration&quot;&gt;Clay_ElementDeclaration.overlayColor&lt;/a&gt; for details.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Union Structs&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    Clay_StringSlice stringContents;
    Clay_Color textColor;
    uint16_t fontId;
    uint16_t fontSize;
    uint16_t letterSpacing;
    uint16_t lineHeight;
} Clay_TextRenderData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    Clay_Color backgroundColor;
    Clay_CornerRadius cornerRadius;
} Clay_RectangleRenderData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    Clay_Color backgroundColor;
    Clay_CornerRadius cornerRadius;
    void* imageData;
} Clay_ImageRenderData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    Clay_Color backgroundColor;
    Clay_CornerRadius cornerRadius;
    void* customData;
} Clay_CustomRenderData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    Clay_Color color;
    Clay_CornerRadius cornerRadius;
    Clay_BorderWidth width;
} Clay_BorderRenderData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef union {
    Clay_RectangleRenderData rectangle;
    Clay_TextRenderData text;
    Clay_ImageRenderData image;
    Clay_CustomRenderData custom;
    Clay_BorderRenderData border;
} Clay_RenderData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Clay_ScrollContainerData&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Data representing the current internal state of a scrolling element.
typedef struct {
    // Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout.
    // Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
    Clay_Vector2 *scrollPosition;
    // The bounding box of the scroll element.
    Clay_Dimensions scrollContainerDimensions;
    // The outer dimensions of the inner scroll container content, including the padding of the parent scroll container.
    Clay_Dimensions contentDimensions;
    // The config that was originally passed to the scroll element.
    Clay_ClipElementConfig config;
    // Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
    bool found;
} Clay_ScrollContainerData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.scrollPosition&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Vector2 *&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A pointer to the internal scroll position of this scroll container. Mutating it will result in elements inside the scroll container shifting up / down (&lt;code&gt;.y&lt;/code&gt;) or left / right (&lt;code&gt;.x&lt;/code&gt;).&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.scrollContainerDimensions&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Dimensions&lt;/code&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    float width, height;
} Clay_Dimensions;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Dimensions representing the outer width and height of the scroll container itself.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.contentDimensions&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Dimensions&lt;/code&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    float width, height;
} Clay_Dimensions;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Dimensions representing the inner width and height of the content &lt;em&gt;inside&lt;/em&gt; the scroll container. Scrolling is only possible when the &lt;code&gt;contentDimensions&lt;/code&gt; are larger in at least one dimension than the &lt;code&gt;scrollContainerDimensions&lt;/code&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.config&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_ClipElementConfig&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;The &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_scroll&quot;&gt;Clay_ClipElementConfig&lt;/a&gt; for the matching scroll container element.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_ElementData&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;// Bounding box and other data for a specific UI element.
typedef struct {
    // The rectangle that encloses this UI element, with the position relative to the root of the layout.
    Clay_BoundingBox boundingBox;
    // Indicates whether an actual Element matched the provided ID or if the default struct was returned.
    bool found;
} Clay_ElementData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.boundingBox&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_BoundingBox&lt;/code&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct {
    float x, y, width, height;
} Clay_BoundingBox;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;A rectangle representing the bounding box of this render command, with &lt;code&gt;.x&lt;/code&gt; and &lt;code&gt;.y&lt;/code&gt; representing the top left corner of the element.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.found&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;bool&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A boolean representing whether or not the ID passed to &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_getelementdata&quot;&gt;Clay_GetElementData&lt;/a&gt; matched a valid element or not. In the case that &lt;code&gt;.found&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;, &lt;code&gt;.boundingBox&lt;/code&gt; will be the default value (zeroed).&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_PointerData&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct
{
    Clay_Vector2 position;
    Clay_PointerDataInteractionState state;
} Clay_PointerData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.position&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_Vector2&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A Vector2 containing the current x,y coordinates of the mouse pointer, which were originally passed into &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setpointerstate&quot;&gt;Clay_SetPointerState()&lt;/a&gt;.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.state&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_PointerDataInteractionState&lt;/code&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef enum
{
    CLAY_POINTER_DATA_PRESSED_THIS_FRAME,
    CLAY_POINTER_DATA_PRESSED,
    CLAY_POINTER_DATA_RELEASED_THIS_FRAME,
    CLAY_POINTER_DATA_RELEASED,
} Clay_PointerDataInteractionState;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;An enum value representing the current &quot;state&quot; of the pointer interaction. As an example, consider the case where a user is on a desktop computer, moves the mouse pointer over a button, clicks and holds the left mouse button for a short time, then releases it:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;While the mouse pointer is over (&quot;hovering&quot;) the button, but no mouse button has been pressed: &lt;code&gt;CLAY_POINTER_DATA_RELEASED&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;First frame that the user presses the left mouse button: &lt;code&gt;CLAY_POINTER_DATA_PRESSED_THIS_FRAME&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;All subsequent frames where the user is still holding the left mouse button: &lt;code&gt;CLAY_POINTER_DATA_PRESSED&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;The single frame where the left mouse button goes from pressed -&amp;gt; released: &lt;code&gt;CLAY_POINTER_DATA_RELEASED_THIS_FRAME&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;All subsequent frames while the mouse pointer is still over the button: &lt;code&gt;CLAY_POINTER_DATA_RELEASED&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_ErrorHandler&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct
{
    void (*errorHandlerFunction)(Clay_ErrorData errorText);
    uintptr_t userData;
} Clay_ErrorHandler;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.errorHandlerFunction&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;void (Clay_ErrorData errorText) {}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A function pointer to an error handler function, which takes &lt;code&gt;Clay_ErrorData&lt;/code&gt; as an argument. This function will be called whenever Clay encounters an internal error.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.userData&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;uintptr_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A generic pointer to extra userdata that is transparently passed through from &lt;code&gt;Clay_Initialize&lt;/code&gt; to Clay&#39;s error handler callback. Defaults to NULL.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h3&gt;Clay_ErrorData&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef struct
{
    Clay_ErrorType errorType;
    Clay_String errorText;
    uintptr_t userData;
} Clay_ErrorData;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.errorType&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_ErrorType&lt;/code&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;typedef enum {
    CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED,
    CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED,
    CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED,
    CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED,
    CLAY_ERROR_TYPE_DUPLICATE_ID,
    CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND,
    CLAY_ERROR_TYPE_INTERNAL_ERROR,
} Clay_ErrorType;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;An enum representing the type of error Clay encountered. It&#39;s up to the user to handle on a case by case basis, but as some general guidance:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED&lt;/code&gt; - The user is attempting to use &lt;code&gt;CLAY_TEXT&lt;/code&gt; and either forgot to call &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setmeasuretextfunction&quot;&gt;Clay_SetMeasureTextFunction&lt;/a&gt; or accidentally passed a null function pointer.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED&lt;/code&gt; - Clay was initialized with an Arena that was too small for the configured &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setmaxelementcount&quot;&gt;Clay_SetMaxElementCount&lt;/a&gt;. Try using &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_minmemorysize&quot;&gt;Clay_MinMemorySize()&lt;/a&gt; to get the exact number of bytes required by the current configuration.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED&lt;/code&gt; - The declared UI hierarchy has too many elements for the configured max element count. Use &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setmaxelementcount&quot;&gt;Clay_SetMaxElementCount&lt;/a&gt; to increase the max, then call &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_minmemorysize&quot;&gt;Clay_MinMemorySize()&lt;/a&gt; again and reinitialize clay&#39;s memory with the required size.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED&lt;/code&gt; - The declared UI hierarchy has too much text for the configured text measure cache size. Use &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_setmeasuretextcachesize&quot;&gt;Clay_SetMaxMeasureTextCacheWordCount&lt;/a&gt; to increase the max, then call &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_minmemorysize&quot;&gt;Clay_MinMemorySize()&lt;/a&gt; again and reinitialize clay&#39;s memory with the required size.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_ERROR_TYPE_DUPLICATE_ID&lt;/code&gt; - Two elements in Clays UI Hierarchy have been declared with exactly the same ID. Set a breakpoint in your error handler function for a stack trace back to exactly where this occured.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND&lt;/code&gt; - A &lt;code&gt;CLAY_FLOATING&lt;/code&gt; element was declared with the &lt;code&gt;.parentId&lt;/code&gt; property, but no element with that ID was found. Set a breakpoint in your error handler function for a stack trace back to exactly where this occured.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CLAY_ERROR_TYPE_INTERNAL_ERROR&lt;/code&gt; - Clay has encountered an internal logic or memory error. Please report this as a bug with a stack trace to help us fix these!&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.errorText&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;Clay_String&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A &lt;a href=&quot;https://raw.githubusercontent.com/nicbarker/clay/main/#clay_string&quot;&gt;Clay_String&lt;/a&gt; that provides a human readable description of the error. May change in future and should not be relied on to detect error types.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.userData&lt;/code&gt;&lt;/strong&gt; - &lt;code&gt;uintptr_t&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;A generic pointer to extra userdata that is transparently passed through from &lt;code&gt;Clay_Initialize&lt;/code&gt; to Clay&#39;s error handler callback. Defaults to NULL.&lt;/p&gt; 
&lt;hr /&gt;</description>
      
    </item>
    
    <item>
      <title>brunodev85/winlator</title>
      <link>https://github.com/brunodev85/winlator</link>
      <description>&lt;p&gt;Android application for running Windows applications with Wine and Box86/Box64&lt;/p&gt;&lt;hr&gt;&lt;p align=&quot;center&quot;&gt; &lt;img src=&quot;https://raw.githubusercontent.com/brunodev85/winlator/main/logo.png&quot; width=&quot;376&quot; height=&quot;128&quot; alt=&quot;Winlator Logo&quot; /&gt; &lt;/p&gt; 
&lt;h1&gt;Winlator&lt;/h1&gt; 
&lt;p&gt;Winlator is an Android application that lets you to run Windows (x86_64) applications with Wine and Box86/Box64.&lt;/p&gt; 
&lt;h1&gt;Installation&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt;Download and install the APK (Winlator_11.1.apk) from &lt;a href=&quot;https://github.com/brunodev85/winlator/releases&quot;&gt;GitHub Releases&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Launch the app and wait for the installation process to finish&lt;/li&gt; 
&lt;/ol&gt; 
&lt;hr /&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ETYDgKz4jBQ&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/ETYDgKz4jBQ/3.jpg&quot; alt=&quot;Play on Youtube&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://www.youtube.com/watch?v=9E4wnKf2OsI&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/9E4wnKf2OsI/2.jpg&quot; alt=&quot;Play on Youtube&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://www.youtube.com/watch?v=czEn4uT3Ja8&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/czEn4uT3Ja8/2.jpg&quot; alt=&quot;Play on Youtube&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://www.youtube.com/watch?v=eD36nxfT_Z0&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/eD36nxfT_Z0/2.jpg&quot; alt=&quot;Play on Youtube&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h1&gt;Useful Tips&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;If you are experiencing performance issues, try changing the Box64 preset to &lt;code&gt;Performance&lt;/code&gt; in Container Settings -&amp;gt; Advanced Tab.&lt;/li&gt; 
 &lt;li&gt;For applications that use .NET Framework, try installing &lt;code&gt;Wine Mono&lt;/code&gt; found in Start Menu -&amp;gt; System Tools -&amp;gt; Installers.&lt;/li&gt; 
 &lt;li&gt;If some older games don&#39;t open, try adding the environment variable &lt;code&gt;MESA_EXTENSION_MAX_YEAR=2003&lt;/code&gt; in Container Settings -&amp;gt; Environment Variables.&lt;/li&gt; 
 &lt;li&gt;Try running the games using the shortcut on the Winlator home screen, there you can define individual settings for each game.&lt;/li&gt; 
 &lt;li&gt;To display low resolution games correctly, try to enabling the &lt;code&gt;Force Fullscreen&lt;/code&gt; option in the shortcut settings.&lt;/li&gt; 
 &lt;li&gt;To improve stability in games that uses Unity Engine, try changing the Box64 preset to &lt;code&gt;Stability&lt;/code&gt; or in the shortcut settings add the exec argument &lt;code&gt;-force-gfx-direct&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;If you are experiencing audio crackling, try increasing the average latency in ALSA/PulseAudio configuration. Old games like Unreal Gold resolve audio issues by increasing this value to 90ms.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Credits and Third-party apps&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;GLIBC Patches by &lt;a href=&quot;https://github.com/termux-pacman/glibc-packages&quot;&gt;Termux Pacman&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Wine (&lt;a href=&quot;https://www.winehq.org/&quot;&gt;winehq.org&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;Box86/Box64 by &lt;a href=&quot;https://github.com/ptitSeb&quot;&gt;ptitseb&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Mesa (Turnip/Zink/VirGL) (&lt;a href=&quot;https://www.mesa3d.org&quot;&gt;mesa3d.org&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;DXVK (&lt;a href=&quot;https://github.com/doitsujin/dxvk&quot;&gt;github.com/doitsujin/dxvk&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;VKD3D (&lt;a href=&quot;https://gitlab.winehq.org/wine/vkd3d&quot;&gt;gitlab.winehq.org/wine/vkd3d&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;CNC DDraw (&lt;a href=&quot;https://github.com/FunkyFr3sh/cnc-ddraw&quot;&gt;github.com/FunkyFr3sh/cnc-ddraw&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Special thanks to all the developers involved in these projects.&lt;br /&gt; Thank you to all the people who believe in this project.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>curl/curl</title>
      <link>https://github.com/curl/curl</link>
      <description>&lt;p&gt;A command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;&lt;a href=&quot;https://curl.se/&quot;&gt;&lt;img src=&quot;https://curl.se/logo/curl-logo.svg?sanitize=true&quot; alt=&quot;curl logo&quot; /&gt;&lt;/a&gt;&lt;/h1&gt; 
&lt;p&gt;curl is a command-line tool for transferring data from or to a server using URLs. It supports these protocols: DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS.&lt;/p&gt; 
&lt;p&gt;Learn how to use curl by reading &lt;a href=&quot;https://curl.se/docs/manpage.html&quot;&gt;the man page&lt;/a&gt; or &lt;a href=&quot;https://everything.curl.dev/&quot;&gt;everything curl&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Find out how to install curl by reading &lt;a href=&quot;https://curl.se/docs/install.html&quot;&gt;the INSTALL document&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;libcurl is the library curl is using to do its job. It is readily available to be used by your software. Read &lt;a href=&quot;https://curl.se/libcurl/c/libcurl.html&quot;&gt;the libcurl man page&lt;/a&gt; to learn how.&lt;/p&gt; 
&lt;h2&gt;Open Source&lt;/h2&gt; 
&lt;p&gt;curl is Open Source and is distributed under an MIT-like &lt;a href=&quot;https://curl.se/docs/copyright.html&quot;&gt;license&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Contact&lt;/h2&gt; 
&lt;p&gt;Contact us on a suitable &lt;a href=&quot;https://curl.se/mail/&quot;&gt;mailing list&lt;/a&gt; or use GitHub &lt;a href=&quot;https://github.com/curl/curl/issues&quot;&gt;issues&lt;/a&gt;/ &lt;a href=&quot;https://github.com/curl/curl/pulls&quot;&gt;pull requests&lt;/a&gt;/ &lt;a href=&quot;https://github.com/curl/curl/discussions&quot;&gt;discussions&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;All contributors to the project are listed in &lt;a href=&quot;https://curl.se/docs/thanks.html&quot;&gt;the THANKS document&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Commercial support&lt;/h2&gt; 
&lt;p&gt;For commercial support, maybe private and dedicated help with your problems or applications using (lib)curl visit &lt;a href=&quot;https://curl.se/support.html&quot;&gt;the support page&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Website&lt;/h2&gt; 
&lt;p&gt;Visit the &lt;a href=&quot;https://curl.se/&quot;&gt;curl website&lt;/a&gt; for the latest news and downloads.&lt;/p&gt; 
&lt;h2&gt;Source code&lt;/h2&gt; 
&lt;p&gt;Download the latest source from the Git server:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;git clone https://github.com/curl/curl
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Security problems&lt;/h2&gt; 
&lt;p&gt;Report suspected security problems &lt;a href=&quot;https://curl.se/dev/vuln-disclosure.html&quot;&gt;privately&lt;/a&gt; and not in public.&lt;/p&gt; 
&lt;h2&gt;Backers&lt;/h2&gt; 
&lt;p&gt;Thank you to all our backers 🙏 &lt;a href=&quot;https://opencollective.com/curl#section-contribute&quot;&gt;Become a backer&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Sponsors&lt;/h2&gt; 
&lt;p&gt;Support this project by becoming a &lt;a href=&quot;https://curl.se/sponsors.html&quot;&gt;sponsor&lt;/a&gt;.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>obsproject/obs-studio</title>
      <link>https://github.com/obsproject/obs-studio</link>
      <description>&lt;p&gt;OBS Studio - Free and open source software for live streaming and screen recording&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;OBS Studio &lt;a href=&quot;https://obsproject.com&quot;&gt;https://obsproject.com&lt;/a&gt;&lt;/h1&gt; 
&lt;p&gt;.. image:: &lt;a href=&quot;https://github.com/obsproject/obs-studio/actions/workflows/push.yaml/badge.svg?branch=master&quot;&gt;https://github.com/obsproject/obs-studio/actions/workflows/push.yaml/badge.svg?branch=master&lt;/a&gt; :alt: OBS Studio Build Status - GitHub Actions :target: &lt;a href=&quot;https://github.com/obsproject/obs-studio/actions/workflows/push.yaml?query=branch%3Amaster&quot;&gt;https://github.com/obsproject/obs-studio/actions/workflows/push.yaml?query=branch%3Amaster&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;.. image:: &lt;a href=&quot;https://badges.crowdin.net/obs-studio/localized.svg&quot;&gt;https://badges.crowdin.net/obs-studio/localized.svg&lt;/a&gt; :alt: OBS Studio Translation Project Progress :target: &lt;a href=&quot;https://crowdin.com/project/obs-studio&quot;&gt;https://crowdin.com/project/obs-studio&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;.. image:: &lt;a href=&quot;https://img.shields.io/discord/348973006581923840.svg?label=&amp;amp;logo=discord&amp;amp;logoColor=ffffff&amp;amp;color=7389D8&amp;amp;labelColor=6A7EC2&quot;&gt;https://img.shields.io/discord/348973006581923840.svg?label=&amp;amp;logo=discord&amp;amp;logoColor=ffffff&amp;amp;color=7389D8&amp;amp;labelColor=6A7EC2&lt;/a&gt; :alt: OBS Studio Discord Server :target: &lt;a href=&quot;https://obsproject.com/discord&quot;&gt;https://obsproject.com/discord&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;What is OBS Studio?&lt;/h2&gt; 
&lt;p&gt;OBS Studio is software designed for capturing, compositing, encoding, recording, and streaming video content, efficiently.&lt;/p&gt; 
&lt;p&gt;It&#39;s distributed under the GNU General Public License v2 (or any later version) - see the accompanying COPYING file for more details.&lt;/p&gt; 
&lt;h2&gt;Quick Links&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Website: &lt;a href=&quot;https://obsproject.com&quot;&gt;https://obsproject.com&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Help/Documentation/Guides: &lt;a href=&quot;https://github.com/obsproject/obs-studio/wiki&quot;&gt;https://github.com/obsproject/obs-studio/wiki&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Forums: &lt;a href=&quot;https://obsproject.com/forum/&quot;&gt;https://obsproject.com/forum/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Build Instructions: &lt;a href=&quot;https://github.com/obsproject/obs-studio/wiki/Install-Instructions&quot;&gt;https://github.com/obsproject/obs-studio/wiki/Install-Instructions&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Developer/API Documentation: &lt;a href=&quot;https://obsproject.com/docs&quot;&gt;https://obsproject.com/docs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Donating/backing/sponsoring: &lt;a href=&quot;https://obsproject.com/contribute&quot;&gt;https://obsproject.com/contribute&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Bug Tracker: &lt;a href=&quot;https://github.com/obsproject/obs-studio/issues&quot;&gt;https://github.com/obsproject/obs-studio/issues&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Contributing&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;If you would like to help fund or sponsor the project, you can do so via &lt;code&gt;Patreon &amp;lt;https://www.patreon.com/obsproject&amp;gt;&lt;/code&gt;&lt;em&gt;, &lt;code&gt;OpenCollective &amp;lt;https://opencollective.com/obsproject&amp;gt;&lt;/code&gt;&lt;/em&gt;, or &lt;code&gt;PayPal &amp;lt;https://www.paypal.me/obsproject&amp;gt;&lt;/code&gt;&lt;em&gt;. See our &lt;code&gt;contribute page &amp;lt;https://obsproject.com/contribute&amp;gt;&lt;/code&gt;&lt;/em&gt; for more information.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;If you wish to contribute code to the project, please make sure to read the coding and commit guidelines: &lt;a href=&quot;https://github.com/obsproject/obs-studio/raw/master/CONTRIBUTING.md&quot;&gt;https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.md&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Code for the project follows the code style guidelines, located here: &lt;a href=&quot;https://github.com/obsproject/obs-studio/raw/master/CODESTYLE.md&quot;&gt;https://github.com/obsproject/obs-studio/blob/master/CODESTYLE.md&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Developer/API documentation can be found here: &lt;a href=&quot;https://obsproject.com/docs&quot;&gt;https://obsproject.com/docs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;If you wish to contribute translations, do not submit pull requests. Instead, please use Crowdin. For more information read this page: &lt;a href=&quot;https://obsproject.com/wiki/How-To-Contribute-Translations-For-OBS&quot;&gt;https://obsproject.com/wiki/How-To-Contribute-Translations-For-OBS&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Contributors to OBS Studio and related repositories are expected to follow our Code of Conduct, which can be read here: &lt;a href=&quot;https://github.com/obsproject/obs-studio/raw/master/COC.rst&quot;&gt;https://github.com/obsproject/obs-studio/blob/master/COC.rst&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Other ways to contribute are by helping people out with support on our forums or in our community chat. Please limit support to topics you fully understand -- bad advice is worse than no advice. When it comes to something that you don&#39;t fully know or understand, please defer to the official help or official channels.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;SAST Tools&lt;/h2&gt; 
&lt;p&gt;&lt;code&gt;PVS-Studio &amp;lt;https://pvs-studio.com/pvs-studio/?utm_source=website&amp;amp;utm_medium=github&amp;amp;utm_campaign=open_source&amp;gt;&lt;/code&gt;_ - static analyzer for C, C++, C#, and Java code.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>superturtlee/gbl_root_canoe</title>
      <link>https://github.com/superturtlee/gbl_root_canoe</link>
      <description>&lt;p&gt;No TrickyStore on Canoe&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;GBL Root Canoe&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/superturtlee/gbl_root_canoe/main/README_zh.md&quot;&gt;中文版&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;⚠️ &lt;strong&gt;This project has been archived.&lt;/strong&gt; This is the final version — the patching engine is stable across multiple vendors and ABL versions, the core logic no longer changes, and active maintenance has ended. The code still works; forks are welcome. See &lt;a href=&quot;https://raw.githubusercontent.com/superturtlee/gbl_root_canoe/main/ARCHIVE.md&quot;&gt;ARCHIVE.md&lt;/a&gt; for details.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;code&gt;gbl_root_canoe&lt;/code&gt; is an EDK2-based workspace for patching the EFI applications within Qualcomm ABL (Android Bootloader) images. It leverages a GBL (Generic Bootloader Loader) vulnerability so the real ABL loads an embedded &lt;strong&gt;superfastboot BDS&lt;/strong&gt; off the raw &lt;code&gt;efisp&lt;/code&gt; partition. The BDS then scans a compatible partition (ext4/fat32) for boot entries and chains to the selected one - primarily to achieve a &lt;strong&gt;Fake Locked Bootloader&lt;/strong&gt; state on Snapdragon 8 Gen 5 / 8 Elite (Gen 5) devices to bypass bootloader unlock detection.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;BDS.efi&lt;/code&gt; is written raw to the &lt;code&gt;efisp&lt;/code&gt; partition; the cracked ABL (&lt;code&gt;boot.efi&lt;/code&gt;) and the boot entry list (&lt;code&gt;BOOTENTRIES&lt;/code&gt;) live on the &lt;code&gt;persist&lt;/code&gt; partition under its &lt;code&gt;efisp/&lt;/code&gt; directory.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h2&gt;Builder Guide&lt;/h2&gt; 
&lt;p&gt;This section is for developers who want to compile the toolkits from source.&lt;/p&gt; 
&lt;h3&gt;Prerequisites&lt;/h3&gt; 
&lt;p&gt;You must be on a &lt;strong&gt;Linux&lt;/strong&gt; host to build the project:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;gcc&lt;/code&gt; / &lt;code&gt;clang&lt;/code&gt;, &lt;code&gt;lld&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt;, &lt;code&gt;zip&lt;/code&gt;, &lt;code&gt;python3&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;liblzma-dev&lt;/code&gt; (for compiling &lt;code&gt;extractfv&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Android NDK&lt;/strong&gt; (Required for &lt;code&gt;make target_magisk_module&lt;/code&gt; to cross-compile tools for Android)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;MinGW-w64&lt;/strong&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Build Targets&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You &lt;strong&gt;do not&lt;/strong&gt; need to provide an &lt;code&gt;abl.img&lt;/code&gt; to build the distributable toolkits or module.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;code&gt;make target_toolkit_linux&lt;/code&gt;&lt;/strong&gt; Builds the superfastboot BDS (&lt;code&gt;BDS.efi&lt;/code&gt;) from the &lt;code&gt;uefi&lt;/code&gt; submodule and compiles the patching utilities (&lt;code&gt;extractfv&lt;/code&gt;, &lt;code&gt;patch_abl&lt;/code&gt;) for Linux.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;code&gt;make target_toolkit_windows&lt;/code&gt;&lt;/strong&gt; Same as above, but cross-compiles the utilities into Windows &lt;code&gt;.exe&lt;/code&gt; programs using MinGW-w64.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;code&gt;make target_magisk_module&lt;/code&gt;&lt;/strong&gt; Cross-compiles the patcher tools for Android using your NDK, builds the BDS, and packages everything as a KernelSU/Magisk module.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;code&gt;make target_toolkit_android&lt;/code&gt;&lt;/strong&gt; Produces a standalone Android arm64 toolkit (&lt;code&gt;toolkit_android.zip&lt;/code&gt;) with Android-native binaries for on-device use outside of the module.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr /&gt; 
&lt;h2&gt;User Guide&lt;/h2&gt; 
&lt;p&gt;For more detailed instructions, please refer to the &lt;a href=&quot;https://github.com/superturtlee/gbl_root_canoe/wiki&quot;&gt;Wiki&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;1. Using the Module (On-Device)&lt;/h3&gt; 
&lt;p&gt;The module is designed to run directly on your rooted Android device.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Device must be Snapdragon 8 Gen 5 / 8 Elite (Gen 5).&lt;/li&gt; 
 &lt;li&gt;Bootloader must be unlocked.&lt;/li&gt; 
 &lt;li&gt;Kernel must NOT have Baseband Guard.&lt;/li&gt; 
 &lt;li&gt;The ABL on the &lt;code&gt;abl&lt;/code&gt; partition must contain the GBL vulnerability. If it does not, flash an older ABL with the vulnerability first (the cracked &lt;code&gt;boot.efi&lt;/code&gt; does not need to match the ABL on the &lt;code&gt;abl&lt;/code&gt; partition).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Installation &amp;amp; Usage:&lt;/strong&gt; When flashing the module via a root manager (KernelSU, Magisk, or APatch), the script interacts with you using the volume keys:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Volume Up (First-time installation):&lt;/strong&gt; The script extracts the current-slot &lt;code&gt;.abl&lt;/code&gt;, cracks it into &lt;code&gt;boot.efi&lt;/code&gt;, places &lt;code&gt;boot.efi&lt;/code&gt; / &lt;code&gt;LinuxLoader.efi&lt;/code&gt; / &lt;code&gt;BOOTENTRIES&lt;/code&gt; into &lt;code&gt;/mnt/vendor/persist/efisp/&lt;/code&gt;, and flashes &lt;code&gt;BDS.efi&lt;/code&gt; to &lt;code&gt;efisp&lt;/code&gt;. After this, reboot into Recovery and &lt;strong&gt;format Data&lt;/strong&gt;. Once booted, install this module again (Volume Down the second time) to complete the installation.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Volume Down (OTA retention or post-format):&lt;/strong&gt; Installs the OTA-update patch. After each OTA, open the module WebUI and flash again to retain the BL version.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;2. Using the PC Toolkits (Linux / Windows)&lt;/h3&gt; 
&lt;p&gt;If you downloaded the &lt;code&gt;target_toolkit_linux&lt;/code&gt; or &lt;code&gt;target_toolkit_windows&lt;/code&gt; zip files:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Extract the toolkit zip on your PC.&lt;/li&gt; 
 &lt;li&gt;Place your device&#39;s stock &lt;code&gt;abl.img&lt;/code&gt; inside the &lt;code&gt;images/&lt;/code&gt; (or &lt;code&gt;images\&lt;/code&gt;) directory of the toolkit.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Linux:&lt;/strong&gt; Run &lt;code&gt;bash build.sh&lt;/code&gt;. &lt;strong&gt;Windows:&lt;/strong&gt; Run &lt;code&gt;build.bat&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;The script extracts and cracks the ABL, outputting &lt;code&gt;ABL.efi&lt;/code&gt; (fake re-lock) and &lt;code&gt;ABL_original.efi&lt;/code&gt; (original). &lt;code&gt;BDS.efi&lt;/code&gt; is bundled. Check &lt;code&gt;patch_log.txt&lt;/code&gt; - if it says &quot;Warning: Failed to patch ABL GBL&quot;, the ABL lacks the vulnerability and the &lt;code&gt;abl&lt;/code&gt; partition must be downgraded to an older ABL with it.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Then complete the install manually (see the &lt;a href=&quot;https://github.com/superturtlee/gbl_root_canoe/wiki&quot;&gt;Wiki&lt;/a&gt; for full steps): copy &lt;code&gt;ABL.efi&lt;/code&gt; into &lt;code&gt;/mnt/vendor/persist/efisp/&lt;/code&gt;, create &lt;code&gt;BOOTENTRIES&lt;/code&gt;, &lt;code&gt;sync&lt;/code&gt;, and flash &lt;code&gt;BDS.efi&lt;/code&gt; to &lt;code&gt;efisp&lt;/code&gt; (&lt;code&gt;dd if=BDS.efi of=/dev/block/by-name/efisp bs=4M&lt;/code&gt;).&lt;/p&gt; 
&lt;h3&gt;3. OTA Upgrade&lt;/h3&gt; 
&lt;p&gt;Before rebooting for an OTA update, use the module WebUI to flash and retain the old ABL version. &quot;Update efisp&quot; is enabled by default; for a major version upgrade keep it on, otherwise the device may get stuck on the first boot screen.&lt;/p&gt; 
&lt;h3&gt;4. Superfastboot Usage Instructions&lt;/h3&gt; 
&lt;p&gt;When OEM Unlocking is enabled and the white warning text appears on boot, press &lt;strong&gt;Volume Down&lt;/strong&gt; to enter Superfastboot mode (the BDS). Common commands include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Temp-boot an EFI file (without flashing)&lt;/strong&gt;: &lt;code&gt;fastboot boot xxx.efi&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Lock and Unlock (BL related)&lt;/strong&gt;: 
  &lt;ul&gt; 
   &lt;li&gt;Lock BL, triggers a data wipe: &lt;code&gt;fastboot flashing lock&lt;/code&gt;&lt;/li&gt; 
   &lt;li&gt;Unlock BL, no data wipe: &lt;code&gt;fastboot flashing unlock&lt;/code&gt; or &lt;code&gt;fastboot flashing unlock_critical&lt;/code&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;em&gt;Note: If the TEE status is inconsistent, the device will refuse to provide the data key, rendering data inaccessible.&lt;/em&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Flashing and Erasing&lt;/strong&gt;: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;fastboot flash &amp;lt;partition&amp;gt; &amp;lt;file.img&amp;gt;&lt;/code&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;fastboot erase &amp;lt;partition&amp;gt;&lt;/code&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Rebooting&lt;/strong&gt;: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;fastboot reboot bootloader&lt;/code&gt; (Next normal boot enters Official Fastboot)&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;fastboot reboot recovery&lt;/code&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;fastboot reboot&lt;/code&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;5. File Reference&lt;/h3&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;code&gt;BDS.efi&lt;/code&gt;: The superfastboot BDS, flashed raw to the &lt;code&gt;efisp&lt;/code&gt; partition.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;boot.efi&lt;/code&gt; / &lt;code&gt;ABL.efi&lt;/code&gt;: The cracked ABL with fake re-lock (the module names it &lt;code&gt;boot.efi&lt;/code&gt;; the toolkit names it &lt;code&gt;ABL.efi&lt;/code&gt;), placed on &lt;code&gt;persist&lt;/code&gt; under &lt;code&gt;efisp/&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;LinuxLoader.efi&lt;/code&gt; / &lt;code&gt;ABL_original.efi&lt;/code&gt;: The original unpatched ABL. For analysis; do not flash to &lt;code&gt;efisp&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;BOOTENTRIES&lt;/code&gt;: Boot entry list, format &lt;code&gt;&amp;lt;name&amp;gt;:&amp;lt;path relative to efisp/&amp;gt;&lt;/code&gt;.&lt;/li&gt; 
&lt;/ol&gt;</description>
      
    </item>
    
    <item>
      <title>tr4m0ryp/tr4mpass</title>
      <link>https://github.com/tr4m0ryp/tr4mpass</link>
      <description>&lt;p&gt;Free, open-source iCloud activation lock bypass tool. Remove iCloud lock from iPhone 5s through iPhone 15 Pro (iOS 12-26.1). Fully offline -- no servers, no payments. Supports checkm8 (A5-A11) and session activation (A12+).&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;tr4mpass: iCloud Activation Lock Bypass&lt;/h1&gt; 
&lt;h1&gt;New improved version will be released soon&lt;/h1&gt; 
&lt;p&gt;Free, open-source tool that removes iCloud activation lock from iPhones and iPads. Runs locally on your computer -- no servers, no payments, no accounts needed. Just plug in your device and run.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Supports iOS 12 through 26.1 | iPhone 5s through iPhone 15 Pro&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;&lt;strong&gt;For developers and security researchers: read &lt;a href=&quot;https://raw.githubusercontent.com/tr4m0ryp/tr4mpass/main/26.3-vulnerability.md&quot;&gt;&lt;code&gt;26.3-vulnerability.md&lt;/code&gt;&lt;/a&gt; for potential vulnerabilities that could enable bypass on iOS 26.3 and later.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h2&gt;How to Use&lt;/h2&gt; 
&lt;h3&gt;1. Download&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/tr4m0ryp/tr4mpass.git
cd tr4mpass
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;2. Run&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./start.sh
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;That&#39;s it. The script will:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Install everything needed (works on macOS, Linux, and Windows via WSL)&lt;/li&gt; 
 &lt;li&gt;Build the tool automatically&lt;/li&gt; 
 &lt;li&gt;Detect your device when you plug it in&lt;/li&gt; 
 &lt;li&gt;Guide you into DFU mode step by step&lt;/li&gt; 
 &lt;li&gt;Run the bypass&lt;/li&gt; 
 &lt;li&gt;Tell you when it&#39;s done&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;3. Put Your Device in DFU Mode&lt;/h3&gt; 
&lt;p&gt;The script will walk you through this, but here&#39;s the short version:&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;iPhone 7 and older (Home button):&lt;/strong&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Connect to your computer via USB&lt;/li&gt; 
 &lt;li&gt;Hold Power + Home for 10 seconds&lt;/li&gt; 
 &lt;li&gt;Release Power, keep holding Home for 5 more seconds&lt;/li&gt; 
 &lt;li&gt;Screen should be completely black (no Apple logo)&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;strong&gt;iPhone 8, X, and newer (Face ID / no Home button):&lt;/strong&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Connect to your computer via USB&lt;/li&gt; 
 &lt;li&gt;Quick-press Volume Up, quick-press Volume Down&lt;/li&gt; 
 &lt;li&gt;Hold Side button until screen goes black&lt;/li&gt; 
 &lt;li&gt;Hold Side + Volume Down for 5 seconds&lt;/li&gt; 
 &lt;li&gt;Release Side, keep holding Volume Down for 10 seconds&lt;/li&gt; 
 &lt;li&gt;Screen should be completely black&lt;/li&gt; 
&lt;/ol&gt; 
&lt;hr /&gt; 
&lt;h2&gt;Supported Devices&lt;/h2&gt; 
&lt;h3&gt;iPhone&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Device&lt;/th&gt; 
   &lt;th&gt;Chip&lt;/th&gt; 
   &lt;th&gt;Bypass Method&lt;/th&gt; 
   &lt;th&gt;Signal Preserved&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 5s&lt;/td&gt; 
   &lt;td&gt;A7&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
   &lt;td&gt;No (WiFi only)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 6 / 6 Plus&lt;/td&gt; 
   &lt;td&gt;A8&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
   &lt;td&gt;No (WiFi only)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 6s / 6s Plus&lt;/td&gt; 
   &lt;td&gt;A9&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone SE (1st gen)&lt;/td&gt; 
   &lt;td&gt;A9&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 7 / 7 Plus&lt;/td&gt; 
   &lt;td&gt;A10&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 8 / 8 Plus&lt;/td&gt; 
   &lt;td&gt;A11&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone X&lt;/td&gt; 
   &lt;td&gt;A11&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone XR&lt;/td&gt; 
   &lt;td&gt;A12&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone XS / XS Max&lt;/td&gt; 
   &lt;td&gt;A12&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 11 / Pro / Pro Max&lt;/td&gt; 
   &lt;td&gt;A13&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone SE (2nd gen)&lt;/td&gt; 
   &lt;td&gt;A13&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 12 / Mini / Pro / Pro Max&lt;/td&gt; 
   &lt;td&gt;A14&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 13 / Mini / Pro / Pro Max&lt;/td&gt; 
   &lt;td&gt;A15&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone SE (3rd gen)&lt;/td&gt; 
   &lt;td&gt;A15&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 14 / Plus&lt;/td&gt; 
   &lt;td&gt;A15&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 14 Pro / Pro Max&lt;/td&gt; 
   &lt;td&gt;A16&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 15 / Plus&lt;/td&gt; 
   &lt;td&gt;A16&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPhone 15 Pro / Pro Max&lt;/td&gt; 
   &lt;td&gt;A17&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
   &lt;td&gt;Yes&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;iPad&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Device&lt;/th&gt; 
   &lt;th&gt;Chip&lt;/th&gt; 
   &lt;th&gt;Bypass Method&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPad Air&lt;/td&gt; 
   &lt;td&gt;A7&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPad Air 2&lt;/td&gt; 
   &lt;td&gt;A8X&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPad mini 4&lt;/td&gt; 
   &lt;td&gt;A8&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPad Pro (1st gen)&lt;/td&gt; 
   &lt;td&gt;A9X&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPad (5th-7th gen)&lt;/td&gt; 
   &lt;td&gt;A9-A10&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPad Pro (2nd gen)&lt;/td&gt; 
   &lt;td&gt;A10X&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPad Pro (3rd/4th gen)&lt;/td&gt; 
   &lt;td&gt;A12/A12Z&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPad Air (4th/5th gen)&lt;/td&gt; 
   &lt;td&gt;A14/M1&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPad Pro (5th/6th gen)&lt;/td&gt; 
   &lt;td&gt;M1/M2&lt;/td&gt; 
   &lt;td&gt;Path B (session)&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Other&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Device&lt;/th&gt; 
   &lt;th&gt;Chip&lt;/th&gt; 
   &lt;th&gt;Bypass Method&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPod touch (6th gen)&lt;/td&gt; 
   &lt;td&gt;A8&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iPod touch (7th gen)&lt;/td&gt; 
   &lt;td&gt;A10&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Apple TV 4K (1st gen)&lt;/td&gt; 
   &lt;td&gt;A10X&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;Apple Watch Series 1-3&lt;/td&gt; 
   &lt;td&gt;S1P/S3&lt;/td&gt; 
   &lt;td&gt;Path A (checkm8)&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;hr /&gt; 
&lt;h2&gt;What Does &quot;Signal Preserved&quot; Mean?&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Yes&lt;/strong&gt; -- After bypass, your iPhone keeps full cellular service (calls, texts, data). SIM card works normally.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;No (WiFi only)&lt;/strong&gt; -- After bypass, the device works on WiFi but cellular service is disabled. This applies to older devices (A7/A8) and all WiFi-only iPads.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr /&gt; 
&lt;h2&gt;Advanced Usage&lt;/h2&gt; 
&lt;p&gt;If you prefer to run things manually instead of using &lt;code&gt;start.sh&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Build
make

# Just identify your device (no bypass)
./tr4mpass --detect-only

# Run with full debug output
./tr4mpass --verbose

# Force a specific bypass path
./tr4mpass --force-path-a    # checkm8 (A5-A11 devices)
./tr4mpass --force-path-b    # session activation (A12+ devices)

# Preview what would happen without doing it
./tr4mpass --dry-run
&lt;/code&gt;&lt;/pre&gt; 
&lt;details&gt; 
 &lt;summary&gt;Manual dependency install -- macOS&lt;/summary&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;brew install libimobiledevice libirecovery libusb libplist openssl pkg-config
&lt;/code&gt;&lt;/pre&gt; 
&lt;/details&gt; 
&lt;details&gt; 
 &lt;summary&gt;Manual dependency install -- Linux (Debian/Ubuntu)&lt;/summary&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo apt-get install -y \
    libimobiledevice-dev libirecovery-1.0-dev libusb-1.0-0-dev \
    libplist-dev libssl-dev pkg-config build-essential
&lt;/code&gt;&lt;/pre&gt; 
&lt;/details&gt; 
&lt;details&gt; 
 &lt;summary&gt;Manual dependency install -- Linux (Fedora)&lt;/summary&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo dnf install -y \
    libimobiledevice-devel libirecovery-devel libusb1-devel \
    libplist-devel openssl-devel pkg-config gcc make
&lt;/code&gt;&lt;/pre&gt; 
&lt;/details&gt; 
&lt;details&gt; 
 &lt;summary&gt;Windows&lt;/summary&gt; 
 &lt;p&gt;Native Windows is not supported. Install WSL first:&lt;/p&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;wsl --install
&lt;/code&gt;&lt;/pre&gt; 
 &lt;p&gt;Then open a WSL terminal and follow the Linux instructions.&lt;/p&gt; 
&lt;/details&gt; 
&lt;hr /&gt; 
&lt;h2&gt;How It Works (Technical)&lt;/h2&gt; 
&lt;p&gt;tr4mpass has two bypass paths, selected automatically based on your device&#39;s chip:&lt;/p&gt; 
&lt;h3&gt;Path A -- checkm8 (A5 through A11)&lt;/h3&gt; 
&lt;p&gt;Uses a permanent hardware vulnerability in the BootROM (the very first code that runs when the device powers on). This vulnerability cannot be patched by Apple because the BootROM is burned into silicon at the factory.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;DFU Mode -&amp;gt; checkm8 exploit -&amp;gt; load ramdisk -&amp;gt; jailbreak kernel
-&amp;gt; inject activation record -&amp;gt; cleanup Setup.app -&amp;gt; verify
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Path B -- Session Activation (A12 and later)&lt;/h3&gt; 
&lt;p&gt;Does not use a hardware exploit. Instead, it manipulates the device&#39;s identity in DFU mode, then uses Apple&#39;s own activation protocol (drmHandshake session mode) to change the lock state.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;DFU Mode -&amp;gt; identity manipulation -&amp;gt; signal detection
-&amp;gt; session handshake -&amp;gt; activation record -&amp;gt; cleanup -&amp;gt; verify
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Architecture&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;+-------------------------+
|        start.sh         |  Guided wrapper (OS detect, deps, DFU guide)
+-------------------------+
|         main.c          |  CLI, device detection, path selection
+-------------------------+
|  Path A    |   Path B   |  Bypass strategies
+------------+------------+
| checkm8    | identity   |  Exploit / manipulation
| jailbreak  | session    |  Activation protocol
+------------+------------+
| DFU protocol | activation record | deletescript |
+--------------+-------------------+--------------+
| libusb | libimobiledevice | libplist | OpenSSL  |
+--------+------------------+---------+----------+
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Source Files&lt;/h3&gt; 
&lt;p&gt;The codebase is written in C99 (21 source files, 20 headers). Every file is under 300 lines. The Makefile auto-discovers all sources -- no manual file lists.&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Module&lt;/th&gt; 
   &lt;th&gt;What it does&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;src/main.c&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Entry point, CLI args, orchestration&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;src/device/&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Device detection (USB + libimobiledevice), chip database (A5-A17)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;src/exploit/&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;checkm8 exploit stages, DFU protocol, payload assembly&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;src/bypass/&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Path A, Path B, signal detection, deletescript, AFC utils&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;src/activation/&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Activation client, session protocol, record builder&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;src/util/&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Logging, plist helpers, USB helpers&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;hr /&gt; 
&lt;h2&gt;iOS 26.3+ (Research in Progress)&lt;/h2&gt; 
&lt;p&gt;Current bypass methods work up to iOS 26.1. For iOS 26.2 and later, Apple hardened several security layers that break existing approaches.&lt;/p&gt; 
&lt;p&gt;We have identified a potential bypass vector through &lt;strong&gt;VU#346053&lt;/strong&gt; -- an unpatched vulnerability in Apple&#39;s activation server that accepts unsigned XML payloads. This could enable bypass via a captive portal during device setup, without needing any exploit or jailbreak.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;This is not implemented yet.&lt;/strong&gt; See &lt;a href=&quot;https://raw.githubusercontent.com/tr4m0ryp/tr4mpass/main/26.3-vulnerability.md&quot;&gt;&lt;code&gt;26.3-vulnerability.md&lt;/code&gt;&lt;/a&gt; for the full technical analysis, proposed attack chain, and implementation roadmap.&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h2&gt;Disclaimer&lt;/h2&gt; 
&lt;p&gt;This tool is for &lt;strong&gt;authorized security research only&lt;/strong&gt; (Apple Security Bounty program).&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Only use on devices you own or have written authorization to test.&lt;/li&gt; 
 &lt;li&gt;Bypassing activation lock on stolen devices is illegal.&lt;/li&gt; 
 &lt;li&gt;No warranty. Use at your own risk.&lt;/li&gt; 
 &lt;li&gt;Results are not guaranteed for every device or iOS version.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr /&gt; 
&lt;h2&gt;References&lt;/h2&gt; 
&lt;p&gt;This project was built on extensive research and analysis of open-source tools, security disclosures, Apple documentation, and community knowledge.&lt;/p&gt; 
&lt;h3&gt;Open-Source Tools and Libraries&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Project&lt;/th&gt; 
   &lt;th&gt;What we used it for&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/0x7ff/gaster&quot;&gt;gaster&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;checkm8 exploit implementation in C -- chip offsets, ROP chains, exploit stages, shellcode structure&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/axi0mX/ipwndfu&quot;&gt;ipwndfu&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Original checkm8 exploit reference (Python) -- payload structure, heap spray parameters&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/libimobiledevice/libimobiledevice&quot;&gt;libimobiledevice&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Device communication, lockdownd, mobileactivation API&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/libimobiledevice/libideviceactivation&quot;&gt;libideviceactivation&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Activation record handling, drmHandshake protocol&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/danielpaulus/go-ios&quot;&gt;go-ios&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;mobileactivation module -- session protocol, handshake sequence, activation flow&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/doronz88/pymobiledevice3&quot;&gt;pymobiledevice3&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Python reference for activation protocol and mobile services&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/checkra1n/PongoOS&quot;&gt;checkra1n / PongoOS&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Pre-boot execution environment, jailbreak reference for A5-A11&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/palera1n/palera1n&quot;&gt;palera1n&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Modern checkm8-based jailbreak, ramdisk builder&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/tihmstar/jbinit&quot;&gt;jbinit&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;iOS booter ramdisk creator for checkm8 devices&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/alwaysappleftd/Lockra1n_v2.0&quot;&gt;Lockra1n&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Untethered iCloud bypass reference (iOS 15-16.7.8)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/i3T4AN/LIBRE-HACKTIVATOR_iOS_12-16&quot;&gt;LIBRE-HACKTIVATOR&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Deletescript reference -- per-iOS-version cleanup scripts&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/Hacktivation/iOS-Hacktivation-Toolkit&quot;&gt;iOS-Hacktivation-Toolkit&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Per-version mobileactivationd patching scripts&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/LinhOnii/Onii_Ramdisk&quot;&gt;Onii_Ramdisk&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Free iCloud bypass ramdisk tool&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/Tihmstar/img4tool&quot;&gt;img4tool&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;IMG4 firmware container extraction&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/Tihmstar/iBoot64Patcher&quot;&gt;iBoot64Patcher&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Bootloader patching for ramdisk loading&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/cfw-project/ramdiskutil&quot;&gt;ramdiskutil&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;iOS restore ramdisk customization&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/malus-security/iextractor&quot;&gt;iExtractor&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Automated IPSW firmware extraction&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Security Research and Disclosures&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Source&lt;/th&gt; 
   &lt;th&gt;Relevance&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://github.com/JGoyd/iOS-Activation-Flaw&quot;&gt;VU#346053 -- iOS Activation Flaw&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Unpatched XML injection at &lt;a href=&quot;http://humb.apple.com/humbug/baa&quot;&gt;humb.apple.com/humbug/baa&lt;/a&gt; (iOS 26.3+ bypass vector)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://seclists.org/fulldisclosure/2025/Jun/27&quot;&gt;Full Disclosure: iOS Activation Flaw&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Original public disclosure of VU#346053 (June 2025)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://theapplewiki.com/wiki/Checkm8_Exploit&quot;&gt;CVE-2019-8900 -- checkm8&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;BootROM use-after-free vulnerability (A5-A11)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://theapplewiki.com/wiki/CoreTrust&quot;&gt;CVE-2023-41991 -- CoreTrust&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Code signing bypass (patched iOS 17.0.1), explains why persistent signing fails on iOS 18+&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://support.apple.com/en-us/100100&quot;&gt;CVE-2026-20687 -- Kernel UAF&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;IOCommandGate use-after-free via AppleKeyStore race condition (iOS 26.1-26.3)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://support.apple.com/en-us/100100&quot;&gt;CVE-2026-28859 -- WebKit Sandbox Escape&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Memory handling bug allowing process to escape sandbox (patched iOS 26.4)&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Apple Documentation&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Source&lt;/th&gt; 
   &lt;th&gt;What it covers&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://support.apple.com/en-us/108794&quot;&gt;Apple Activation Lock&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Official activation lock documentation&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://security.apple.com/bounty/&quot;&gt;Apple Security Bounty&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Bug bounty program this research falls under&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://support.apple.com/guide/security/sec59b0b31ff&quot;&gt;Secure Enclave&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;SEP architecture and activation state storage&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://theapplewiki.com/wiki/Firmware_Keys&quot;&gt;The Apple Wiki -- Firmware Keys&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Decryption keys for IPSW ramdisk extraction&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://www.theiphonewiki.com/wiki/Activation_Token&quot;&gt;The iPhone Wiki -- Activation Token&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Activation record plist format and fields&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://www.theiphonewiki.com/wiki/WildcardTicket&quot;&gt;The iPhone Wiki -- WildcardTicket&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Activation ticket structure (TEA-CBC encryption)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://www.theiphonewiki.com/wiki//Applications/Setup.app&quot;&gt;The iPhone Wiki -- Setup.app&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Setup Assistant paths targeted by deletescript&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://theapplewiki.com/wiki/Albert&quot;&gt;Albert Server&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Apple&#39;s activation server endpoints&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Analysis and Articles&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Source&lt;/th&gt; 
   &lt;th&gt;Topic&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://gbhackers.com/apple-ios-activation-flaw-enables-injection/&quot;&gt;GBHackers -- iOS Activation Flaw&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;VU#346053 technical analysis&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://cybersecuritynews.com/apples-ios-activation-vulnerability/&quot;&gt;CyberSecurity News -- Activation Vulnerability&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;VU#346053 impact analysis&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://medium.com/@saadanashraf86/the-unpatchable-flaw-a-deep-dive-into-apples-dfu-mode-and-the-checkm8-exploit-0d3dae2a2075&quot;&gt;checkm8 Deep Dive (Medium)&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;checkm8 exploit mechanics&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://zimperium.com/blog/zimperium-analysis-of-checkm8&quot;&gt;Zimperium -- checkm8 Analysis&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Security industry analysis of checkm8&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://habr.com/en/companies/dsec/articles/472762/&quot;&gt;Habr -- checkm8 Technical Analysis&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Detailed technical breakdown of the DFU UAF&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://blackhat.com/docs/us-16/materials/us-16-Mandt-Demystifying-The-Secure-Enclave-Processor.pdf&quot;&gt;Black Hat 2016 -- Demystifying the SEP&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;Secure Enclave architecture research&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://research.dynastic.co/2019/03/01/codesign-bypass&quot;&gt;Dynastic Research -- iOS Codesign Bypass&lt;/a&gt;&lt;/td&gt; 
   &lt;td&gt;CoreTrust/AMFI bypass history&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Commercial Tools Analyzed&lt;/h3&gt; 
&lt;p&gt;During development, the following proprietary tools were analyzed to understand bypass flows and protocol implementations:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Tool&lt;/th&gt; 
   &lt;th&gt;Version&lt;/th&gt; 
   &lt;th&gt;What we extracted&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;http://Checkm8.info&quot;&gt;Checkm8.info&lt;/a&gt; Software&lt;/td&gt; 
   &lt;td&gt;9.5&lt;/td&gt; 
   &lt;td&gt;Two-section architecture (A5-A11 vs A12+), DFU exploit flow, FActivation protocol, offline bypass method, bundled go-ios binary, ipwndfu payloads&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;iRemoveTools&lt;/td&gt; 
   &lt;td&gt;9.5&lt;/td&gt; 
   &lt;td&gt;A12+ activation APIs, signal vs no-signal handling, MobileDeviceFramework usage, mobileactivationd interaction&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt;</description>
      
    </item>
    
    <item>
      <title>memovai/mimiclaw</title>
      <link>https://github.com/memovai/mimiclaw</link>
      <description>&lt;p&gt;MimiClaw: Harness on a $5 chip. No OS(Linux). No Node.js. No Mac mini. No Raspberry Pi. No VPS. Hardware agents OS.&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;MimiClaw: Pocket AI Assistant on a $5 Chip&lt;/h1&gt; 
&lt;p align=&quot;center&quot;&gt; &lt;img src=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/assets/banner.png&quot; alt=&quot;MimiClaw&quot; width=&quot;500&quot; /&gt; &lt;/p&gt; 
&lt;p align=&quot;center&quot;&gt; &lt;a href=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/LICENSE&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/License-MIT-yellow.svg?sanitize=true&quot; alt=&quot;License: MIT&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://deepwiki.com/memovai/mimiclaw&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/DeepWiki-mimiclaw-blue.svg?sanitize=true&quot; alt=&quot;DeepWiki&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://discord.gg/r8ZxSvB8Yr&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/Discord-mimiclaw-5865F2?logo=discord&amp;amp;logoColor=white&quot; alt=&quot;Discord&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://x.com/ssslvky&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/X-@ssslvky-black?logo=x&quot; alt=&quot;X&quot; /&gt;&lt;/a&gt; &lt;/p&gt; 
&lt;p align=&quot;center&quot;&gt; &lt;strong&gt;&lt;a href=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/README.md&quot;&gt;English&lt;/a&gt; | &lt;a href=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/README_CN.md&quot;&gt;中文&lt;/a&gt; | &lt;a href=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/README_JA.md&quot;&gt;日本語&lt;/a&gt;&lt;/strong&gt; &lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The world&#39;s first AI assistant(OpenClaw) on a $5 chip. No Linux. No Node.js. Just pure C&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;MimiClaw turns a tiny ESP32-S3 board into a personal AI assistant. Plug it into USB power, connect to WiFi, and talk to it through Telegram — it handles any task you throw at it and evolves over time with local memory — all on a chip the size of a thumb.&lt;/p&gt; 
&lt;h2&gt;Meet MimiClaw&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Tiny&lt;/strong&gt; — No Linux, no Node.js, no bloat — just pure C&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Handy&lt;/strong&gt; — Message it from Telegram, it handles the rest&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Loyal&lt;/strong&gt; — Learns from memory, remembers across reboots&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Energetic&lt;/strong&gt; — USB power, 0.5 W, runs 24/7&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Lovable&lt;/strong&gt; — One ESP32-S3 board, $5, nothing else&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;How It Works&lt;/h2&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/assets/mimiclaw.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;You send a message on Telegram. The ESP32-S3 picks it up over WiFi, feeds it into an agent loop — the LLM thinks, calls tools, reads memory — and sends the reply back. Supports both &lt;strong&gt;Anthropic (Claude)&lt;/strong&gt; and &lt;strong&gt;OpenAI (GPT)&lt;/strong&gt; as providers, switchable at runtime. Everything runs on a single $5 chip with all your data stored locally on flash.&lt;/p&gt; 
&lt;h2&gt;Quick Start&lt;/h2&gt; 
&lt;h3&gt;What You Need&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;An &lt;strong&gt;ESP32-S3 dev board&lt;/strong&gt; with 16 MB flash and 8 MB PSRAM (e.g. Xiaozhi AI board, ~$10)&lt;/li&gt; 
 &lt;li&gt;A &lt;strong&gt;USB Type-C cable&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;A &lt;strong&gt;Telegram bot token&lt;/strong&gt; — talk to &lt;a href=&quot;https://t.me/BotFather&quot;&gt;@BotFather&lt;/a&gt; on Telegram to create one&lt;/li&gt; 
 &lt;li&gt;An &lt;strong&gt;Anthropic API key&lt;/strong&gt; — from &lt;a href=&quot;https://console.anthropic.com&quot;&gt;console.anthropic.com&lt;/a&gt;, or an &lt;strong&gt;OpenAI API key&lt;/strong&gt; — from &lt;a href=&quot;https://platform.openai.com&quot;&gt;platform.openai.com&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Install&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# You need ESP-IDF v5.5+ installed first:
# https://docs.espressif.com/projects/esp-idf/en/v5.5.2/esp32s3/get-started/

git clone https://github.com/memovai/mimiclaw.git
cd mimiclaw

idf.py set-target esp32s3
&lt;/code&gt;&lt;/pre&gt; 
&lt;details&gt; 
 &lt;summary&gt;Ubuntu Install&lt;/summary&gt; 
 &lt;p&gt;Recommended baseline:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;Ubuntu 22.04/24.04&lt;/li&gt; 
  &lt;li&gt;Python &amp;gt;= 3.10&lt;/li&gt; 
  &lt;li&gt;CMake &amp;gt;= 3.16&lt;/li&gt; 
  &lt;li&gt;Ninja &amp;gt;= 1.10&lt;/li&gt; 
  &lt;li&gt;Git &amp;gt;= 2.34&lt;/li&gt; 
  &lt;li&gt;flex &amp;gt;= 2.6&lt;/li&gt; 
  &lt;li&gt;bison &amp;gt;= 3.8&lt;/li&gt; 
  &lt;li&gt;gperf &amp;gt;= 3.1&lt;/li&gt; 
  &lt;li&gt;dfu-util &amp;gt;= 0.11&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;libusb-1.0-0&lt;/code&gt;, &lt;code&gt;libffi-dev&lt;/code&gt;, &lt;code&gt;libssl-dev&lt;/code&gt;&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;Install and build on Ubuntu:&lt;/p&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo apt-get update
sudo apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv \
  cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0

./scripts/setup_idf_ubuntu.sh
./scripts/build_ubuntu.sh
&lt;/code&gt;&lt;/pre&gt; 
&lt;/details&gt; 
&lt;details&gt; 
 &lt;summary&gt;macOS Install&lt;/summary&gt; 
 &lt;p&gt;Recommended baseline:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;macOS 12/13/14&lt;/li&gt; 
  &lt;li&gt;Xcode Command Line Tools&lt;/li&gt; 
  &lt;li&gt;Homebrew&lt;/li&gt; 
  &lt;li&gt;Python &amp;gt;= 3.10&lt;/li&gt; 
  &lt;li&gt;CMake &amp;gt;= 3.16&lt;/li&gt; 
  &lt;li&gt;Ninja &amp;gt;= 1.10&lt;/li&gt; 
  &lt;li&gt;Git &amp;gt;= 2.34&lt;/li&gt; 
  &lt;li&gt;flex &amp;gt;= 2.6&lt;/li&gt; 
  &lt;li&gt;bison &amp;gt;= 3.8&lt;/li&gt; 
  &lt;li&gt;gperf &amp;gt;= 3.1&lt;/li&gt; 
  &lt;li&gt;dfu-util &amp;gt;= 0.11&lt;/li&gt; 
  &lt;li&gt;&lt;code&gt;libusb&lt;/code&gt;, &lt;code&gt;libffi&lt;/code&gt;, &lt;code&gt;openssl&lt;/code&gt;&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;Install and build on macOS:&lt;/p&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;xcode-select --install
/bin/bash -c &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;

./scripts/setup_idf_macos.sh
./scripts/build_macos.sh
&lt;/code&gt;&lt;/pre&gt; 
&lt;/details&gt; 
&lt;h3&gt;Configure&lt;/h3&gt; 
&lt;p&gt;MimiClaw uses a &lt;strong&gt;two-layer config&lt;/strong&gt; system: build-time defaults in &lt;code&gt;mimi_secrets.h&lt;/code&gt;, with runtime overrides via the serial CLI. CLI values are stored in NVS flash and take priority over build-time values.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cp main/mimi_secrets.h.example main/mimi_secrets.h
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Edit &lt;code&gt;main/mimi_secrets.h&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#define MIMI_SECRET_WIFI_SSID       &quot;YourWiFiName&quot;
#define MIMI_SECRET_WIFI_PASS       &quot;YourWiFiPassword&quot;
#define MIMI_SECRET_TG_TOKEN        &quot;123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11&quot;
#define MIMI_SECRET_API_KEY         &quot;sk-ant-api03-xxxxx&quot;
#define MIMI_SECRET_MODEL_PROVIDER  &quot;anthropic&quot;     // &quot;anthropic&quot; or &quot;openai&quot;
#define MIMI_SECRET_SEARCH_KEY      &quot;&quot;              // optional: Brave Search API key
#define MIMI_SECRET_TAVILY_KEY      &quot;&quot;              // optional: Tavily API key (preferred)
#define MIMI_SECRET_PROXY_HOST      &quot;&quot;              // optional: e.g. &quot;10.0.0.1&quot;
#define MIMI_SECRET_PROXY_PORT      &quot;&quot;              // optional: e.g. &quot;7897&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Then build and flash:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Clean build (required after any mimi_secrets.h change)
idf.py fullclean &amp;amp;&amp;amp; idf.py build

# Find your serial port
ls /dev/cu.usb*          # macOS
ls /dev/ttyACM*          # Linux

# Flash and monitor (replace PORT with your port)
# USB adapter: likely /dev/cu.usbmodem11401 (macOS) or /dev/ttyACM0 (Linux)
idf.py -p PORT flash monitor
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;strong&gt;Important: Plug into the correct USB port!&lt;/strong&gt; Most ESP32-S3 boards have two USB-C ports. You must use the one labeled &lt;strong&gt;USB&lt;/strong&gt; (native USB Serial/JTAG), &lt;strong&gt;not&lt;/strong&gt; the one labeled &lt;strong&gt;COM&lt;/strong&gt; (external UART bridge). Plugging into the wrong port will cause flash/monitor failures.&lt;/p&gt; 
 &lt;details&gt; 
  &lt;summary&gt;Show reference photo&lt;/summary&gt; 
  &lt;img src=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/assets/esp32s3-usb-port.jpg&quot; alt=&quot;Plug into the USB port, not COM&quot; width=&quot;480&quot; /&gt; 
 &lt;/details&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;CLI Commands (via UART/COM port)&lt;/h3&gt; 
&lt;p&gt;Connect via serial to configure or debug. &lt;strong&gt;Config commands&lt;/strong&gt; let you change settings without recompiling — just plug in a USB cable anywhere.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Runtime config&lt;/strong&gt; (saved to NVS, overrides build-time defaults):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;mimi&amp;gt; wifi_set MySSID MyPassword   # change WiFi network
mimi&amp;gt; set_tg_token 123456:ABC...   # change Telegram bot token
mimi&amp;gt; set_api_key sk-ant-api03-... # change API key (Anthropic or OpenAI)
mimi&amp;gt; set_model_provider openai    # switch provider (anthropic|openai)
mimi&amp;gt; set_model gpt-4o             # change LLM model
mimi&amp;gt; set_proxy 127.0.0.1 7897  # set HTTP proxy
mimi&amp;gt; clear_proxy                  # remove proxy
mimi&amp;gt; set_search_key BSA...        # set Brave Search API key
mimi&amp;gt; set_tavily_key tvly-...      # set Tavily API key (preferred)
mimi&amp;gt; config_show                  # show all config (masked)
mimi&amp;gt; config_reset                 # clear NVS, revert to build-time defaults
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Debug &amp;amp; maintenance:&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;mimi&amp;gt; wifi_status              # am I connected?
mimi&amp;gt; memory_read              # see what the bot remembers
mimi&amp;gt; memory_write &quot;content&quot;   # write to MEMORY.md
mimi&amp;gt; heap_info                # how much RAM is free?
mimi&amp;gt; session_list             # list all chat sessions
mimi&amp;gt; session_clear 12345      # wipe a conversation
mimi&amp;gt; heartbeat_trigger           # manually trigger a heartbeat check
mimi&amp;gt; cron_start                  # start cron scheduler now
mimi&amp;gt; restart                     # reboot
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;USB (JTAG) vs UART: Which Port for What&lt;/h3&gt; 
&lt;p&gt;Most ESP32-S3 dev boards expose &lt;strong&gt;two USB-C ports&lt;/strong&gt;:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Port&lt;/th&gt; 
   &lt;th&gt;Use for&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;USB&lt;/strong&gt; (JTAG)&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;idf.py flash&lt;/code&gt;, JTAG debugging&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;COM&lt;/strong&gt; (UART)&lt;/td&gt; 
   &lt;td&gt;&lt;strong&gt;REPL CLI&lt;/strong&gt;, serial console&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;strong&gt;REPL requires the UART (COM) port.&lt;/strong&gt; The USB (JTAG) port does not support interactive REPL input.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;details&gt; 
 &lt;summary&gt;Port details &amp;amp; recommended workflow&lt;/summary&gt; 
 &lt;table&gt; 
  &lt;thead&gt; 
   &lt;tr&gt; 
    &lt;th&gt;Port&lt;/th&gt; 
    &lt;th&gt;Label&lt;/th&gt; 
    &lt;th&gt;Protocol&lt;/th&gt; 
   &lt;/tr&gt; 
  &lt;/thead&gt; 
  &lt;tbody&gt; 
   &lt;tr&gt; 
    &lt;td&gt;&lt;strong&gt;USB&lt;/strong&gt;&lt;/td&gt; 
    &lt;td&gt;USB / JTAG&lt;/td&gt; 
    &lt;td&gt;Native USB Serial/JTAG&lt;/td&gt; 
   &lt;/tr&gt; 
   &lt;tr&gt; 
    &lt;td&gt;&lt;strong&gt;COM&lt;/strong&gt;&lt;/td&gt; 
    &lt;td&gt;UART / COM&lt;/td&gt; 
    &lt;td&gt;External UART bridge (CP2102/CH340)&lt;/td&gt; 
   &lt;/tr&gt; 
  &lt;/tbody&gt; 
 &lt;/table&gt; 
 &lt;p&gt;The ESP-IDF console/REPL is configured to use UART by default (&lt;code&gt;CONFIG_ESP_CONSOLE_UART_DEFAULT=y&lt;/code&gt;).&lt;/p&gt; 
 &lt;p&gt;&lt;strong&gt;If you have both ports connected simultaneously:&lt;/strong&gt;&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;USB (JTAG) handles flash/download and provides secondary serial output&lt;/li&gt; 
  &lt;li&gt;UART (COM) provides the primary interactive console for the REPL&lt;/li&gt; 
  &lt;li&gt;macOS: both appear as &lt;code&gt;/dev/cu.usbmodem*&lt;/code&gt; or &lt;code&gt;/dev/cu.usbserial-*&lt;/code&gt; — run &lt;code&gt;ls /dev/cu.usb*&lt;/code&gt; to identify&lt;/li&gt; 
  &lt;li&gt;Linux: USB (JTAG) → &lt;code&gt;/dev/ttyACM0&lt;/code&gt;, UART → &lt;code&gt;/dev/ttyUSB0&lt;/code&gt;&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;&lt;strong&gt;Recommended workflow:&lt;/strong&gt;&lt;/p&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Flash via USB (JTAG) port
idf.py -p /dev/cu.usbmodem11401 flash

# Open REPL via UART (COM) port
idf.py -p /dev/cu.usbserial-110 monitor
# or use any serial terminal: screen, minicom, PuTTY at 115200 baud
&lt;/code&gt;&lt;/pre&gt; 
&lt;/details&gt; 
&lt;h2&gt;Memory&lt;/h2&gt; 
&lt;p&gt;MimiClaw stores everything as plain text files you can read and edit:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;File&lt;/th&gt; 
   &lt;th&gt;What it is&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;SOUL.md&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;The bot&#39;s personality — edit this to change how it behaves&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;USER.md&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Info about you — name, preferences, language&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;MEMORY.md&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Long-term memory — things the bot should always remember&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;HEARTBEAT.md&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Task list the bot checks periodically and acts on autonomously&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;cron.json&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Scheduled jobs — recurring or one-shot tasks created by the AI&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;2026-02-05.md&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Daily notes — what happened today&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;tg_12345.jsonl&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Chat history — your conversation with the bot&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h2&gt;Tools&lt;/h2&gt; 
&lt;p&gt;MimiClaw supports tool calling for both Anthropic and OpenAI — the LLM can call tools during a conversation and loop until the task is done (ReAct pattern).&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Tool&lt;/th&gt; 
   &lt;th&gt;Description&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;web_search&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Search the web via Tavily (preferred) or Brave for current information&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;get_current_time&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Fetch current date/time via HTTP and set the system clock&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;cron_add&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Schedule a recurring or one-shot task (the LLM creates cron jobs on its own)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;cron_list&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;List all scheduled cron jobs&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;cron_remove&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Remove a cron job by ID&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;To enable web search, set a &lt;a href=&quot;https://app.tavily.com/home&quot;&gt;Tavily API key&lt;/a&gt; via &lt;code&gt;MIMI_SECRET_TAVILY_KEY&lt;/code&gt; (preferred), or a &lt;a href=&quot;https://brave.com/search/api/&quot;&gt;Brave Search API key&lt;/a&gt; via &lt;code&gt;MIMI_SECRET_SEARCH_KEY&lt;/code&gt; in &lt;code&gt;mimi_secrets.h&lt;/code&gt;.&lt;/p&gt; 
&lt;h2&gt;Cron Tasks&lt;/h2&gt; 
&lt;p&gt;MimiClaw has a built-in cron scheduler that lets the AI schedule its own tasks. The LLM can create recurring jobs (&quot;every N seconds&quot;) or one-shot jobs (&quot;at unix timestamp&quot;) via the &lt;code&gt;cron_add&lt;/code&gt; tool. When a job fires, its message is injected into the agent loop — so the AI wakes up, processes the task, and responds.&lt;/p&gt; 
&lt;p&gt;Jobs are persisted to SPIFFS (&lt;code&gt;cron.json&lt;/code&gt;) and survive reboots. Example use cases: daily summaries, periodic reminders, scheduled check-ins.&lt;/p&gt; 
&lt;h2&gt;Heartbeat&lt;/h2&gt; 
&lt;p&gt;The heartbeat service periodically reads &lt;code&gt;HEARTBEAT.md&lt;/code&gt; from SPIFFS and checks for actionable tasks. If uncompleted items are found (anything that isn&#39;t an empty line, a header, or a checked &lt;code&gt;- [x]&lt;/code&gt; box), it sends a prompt to the agent loop so the AI can act on them autonomously.&lt;/p&gt; 
&lt;p&gt;This turns MimiClaw into a proactive assistant — write tasks to &lt;code&gt;HEARTBEAT.md&lt;/code&gt; and the bot will pick them up on the next heartbeat cycle (default: every 30 minutes).&lt;/p&gt; 
&lt;h2&gt;Also Included&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;WebSocket gateway&lt;/strong&gt; on port 18789 — connect from your LAN with any WebSocket client&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;OTA updates&lt;/strong&gt; — flash new firmware over WiFi, no USB needed&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Dual-core&lt;/strong&gt; — network I/O and AI processing run on separate CPU cores&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;HTTP proxy&lt;/strong&gt; — CONNECT tunnel support for restricted networks&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Multi-provider&lt;/strong&gt; — supports both Anthropic (Claude) and OpenAI (GPT), switchable at runtime&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Cron scheduler&lt;/strong&gt; — the AI can schedule its own recurring and one-shot tasks, persisted across reboots&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Heartbeat&lt;/strong&gt; — periodically checks a task file and prompts the AI to act autonomously&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Tool use&lt;/strong&gt; — ReAct agent loop with tool calling for both providers&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;For Developers&lt;/h2&gt; 
&lt;p&gt;Technical details live in the &lt;code&gt;docs/&lt;/code&gt; folder:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/docs/ARCHITECTURE.md&quot;&gt;docs/ARCHITECTURE.md&lt;/a&gt;&lt;/strong&gt; — system design, module map, task layout, memory budget, protocols, flash partitions&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/docs/TODO.md&quot;&gt;docs/TODO.md&lt;/a&gt;&lt;/strong&gt; — feature gap tracker and roadmap&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/docs/WIFI_ONBOARDING_AP.md&quot;&gt;docs/WIFI_ONBOARDING_AP.md&lt;/a&gt;&lt;/strong&gt; — how the local &lt;code&gt;MimiClaw-XXXX&lt;/code&gt; onboarding/admin AP flow works&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/docs/tool-setup/README.md&quot;&gt;docs/tool-setup/&lt;/a&gt;&lt;/strong&gt; — configuration guides for external service integrations (Tavily, etc.)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Contributing&lt;/h2&gt; 
&lt;p&gt;Please read &lt;strong&gt;&lt;a href=&quot;https://raw.githubusercontent.com/memovai/mimiclaw/main/CONTRIBUTING.md&quot;&gt;CONTRIBUTING.md&lt;/a&gt;&lt;/strong&gt; before opening issues or pull requests.&lt;/p&gt; 
&lt;h2&gt;Contributors&lt;/h2&gt; 
&lt;p&gt;Thanks to everyone who has contributed to MimiClaw.&lt;/p&gt; 
&lt;a href=&quot;https://github.com/memovai/mimiclaw/graphs/contributors&quot;&gt; &lt;img src=&quot;https://contrib.rocks/image?repo=memovai/mimiclaw&quot; alt=&quot;MimiClaw contributors&quot; /&gt; &lt;/a&gt; 
&lt;h2&gt;License&lt;/h2&gt; 
&lt;p&gt;MIT&lt;/p&gt; 
&lt;h2&gt;Acknowledgments&lt;/h2&gt; 
&lt;p&gt;Inspired by &lt;a href=&quot;https://github.com/openclaw/openclaw&quot;&gt;OpenClaw&lt;/a&gt; and &lt;a href=&quot;https://github.com/HKUDS/nanobot&quot;&gt;Nanobot&lt;/a&gt;. MimiClaw reimplements the core AI agent architecture for embedded hardware — no Linux, no server, just a $5 chip.&lt;/p&gt; 
&lt;h2&gt;Star History&lt;/h2&gt; 
&lt;a href=&quot;https://www.star-history.com/?repos=memovai%2Fmimiclaw&amp;amp;type=date&amp;amp;legend=top-left&quot;&gt; 
 &lt;picture&gt; 
  &lt;source media=&quot;(prefers-color-scheme: dark)&quot; srcset=&quot;https://api.star-history.com/image?repos=memovai/mimiclaw&amp;amp;type=date&amp;amp;theme=dark&amp;amp;legend=top-left&quot; /&gt; 
  &lt;source media=&quot;(prefers-color-scheme: light)&quot; srcset=&quot;https://api.star-history.com/image?repos=memovai/mimiclaw&amp;amp;type=date&amp;amp;legend=top-left&quot; /&gt; 
  &lt;img alt=&quot;Star History Chart&quot; src=&quot;https://api.star-history.com/image?repos=memovai/mimiclaw&amp;amp;type=date&amp;amp;legend=top-left&quot; /&gt; 
 &lt;/picture&gt; &lt;/a&gt;</description>
      
    </item>
    
    <item>
      <title>veracrypt/VeraCrypt</title>
      <link>https://github.com/veracrypt/VeraCrypt</link>
      <description>&lt;p&gt;Disk encryption with strong security based on TrueCrypt&lt;/p&gt;&lt;hr&gt;&lt;p&gt;This archive contains the source code of VeraCrypt. It is based on the original TrueCrypt 7.1a with security enhancements and modifications.&lt;/p&gt; 
&lt;h1&gt;Important&lt;/h1&gt; 
&lt;p&gt;You may use the source code contained in this archive only if you accept and agree to the license terms contained in the file &#39;License.txt&#39;, which is included in this archive.&lt;/p&gt; 
&lt;p&gt;Note that the license specifies, for example, that a derived work must not be called &#39;TrueCrypt&#39; or &#39;VeraCrypt&#39;&lt;/p&gt; 
&lt;h1&gt;Contents&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/veracrypt/VeraCrypt/master/#i-windows&quot;&gt;I. Windows&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/veracrypt/VeraCrypt/master/#ii-linux-and-mac-os-x&quot;&gt;II. Linux and Mac OS X&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/veracrypt/VeraCrypt/master/#iii-freebsd-and-openbsd&quot;&gt;III. FreeBSD and OpenBSD&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/veracrypt/VeraCrypt/master/#iv-third-party-developers-contributors&quot;&gt;IV. Third-Party Developers (Contributors)&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/veracrypt/VeraCrypt/master/#v-legal-information&quot;&gt;V. Legal Information&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/veracrypt/VeraCrypt/master/#vi-further-information&quot;&gt;VI. Further Information&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;I. Windows&lt;/h1&gt; 
&lt;h2&gt;Requirements for Building VeraCrypt for Windows:&lt;/h2&gt; 
&lt;p&gt;A detailed guide on how to build VeraCrypt on Windows can be found in the &lt;a href=&quot;https://raw.githubusercontent.com/veracrypt/VeraCrypt/master/doc/html/en/CompilingGuidelineWin.html&quot;&gt;documentation&lt;/a&gt; in the repository and it is also available &lt;a href=&quot;https://veracrypt.jp/en/CompilingGuidelineWin.html&quot;&gt;online&lt;/a&gt; or on the &lt;a href=&quot;https://veracrypt.io/en/CompilingGuidelineWin.html&quot;&gt;mirror&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;IMPORTANT:&lt;/p&gt; 
&lt;p&gt;The 64-bit editions of Windows Vista and later versions of Windows, and in some cases (e.g. playback of HD DVD content) also the 32-bit editions do not allow the VeraCrypt driver to run without an appropriate digital signature. Therefore, all .sys files in official VeraCrypt binary packages are digitally signed with the digital certificate of the IDRIX, which was issued by GlobalSign certification authority. At the end of each official .exe and .sys file, there are embedded digital signatures and all related certificates (i.e. all certificates in the relevant certification chain, such as the certification authority certificates, CA-MS cross-certificate, and the IDRIX certificate).&lt;/p&gt; 
&lt;p&gt;Keep this in mind if you compile VeraCrypt and compare your binaries with the official binaries. If your binaries are unsigned, the sizes of the official binaries will usually be approximately 10 KiB greater than the sizes of your binaries (there may be further differences if you use a different version of the compiler, or if you install a different or no service pack for Visual Studio, or different hotfixes for it, or if you use different versions of the required SDKs).&lt;/p&gt; 
&lt;h2&gt;Instructions for Signing and Packaging VeraCrypt for Windows:&lt;/h2&gt; 
&lt;p&gt;First, create an environment variable &#39;WSDK81&#39; pointing to the Windows SDK for Windows 8.1 installation directory.&lt;/p&gt; 
&lt;p&gt;The folder &quot;Signing&quot; contains a batch file (sign.bat) that will sign all VeraCrypt components using a code signing certificate present on the certificate store and build the final installation setup and MSI package. The batch file assumes that the code signing certificate is issued by GlobalSign. This is the case for IDRIX&#39;s certificate. If yours is issued by another CA, then you should put its intermediate certificates in the &quot;Signing&quot; folder and modify sign.bat accordingly.&lt;/p&gt; 
&lt;p&gt;To generate MSI packages, WiX Toolset v3.11 must be installed.&lt;/p&gt; 
&lt;h2&gt;VeraCrypt EFI Boot Loader:&lt;/h2&gt; 
&lt;p&gt;VeraCrypt source code contains pre-built EFI binaries under src\Boot\EFI. The source code of VeraCrypt EFI Boot Loader is licensed under LGPL and it is available at &lt;a href=&quot;https://github.com/veracrypt/VeraCrypt-DCS&quot;&gt;https://github.com/veracrypt/VeraCrypt-DCS&lt;/a&gt;. For build instructions, please refer to the file src\Boot\EFI\Readme.txt.&lt;/p&gt; 
&lt;h1&gt;II. Linux and Mac OS X&lt;/h1&gt; 
&lt;p&gt;A detailed guide on how to build VeraCrypt on Linux can be found in the &lt;a href=&quot;https://raw.githubusercontent.com/veracrypt/VeraCrypt/master/doc/html/en/CompilingGuidelineLinux.html&quot;&gt;documentation&lt;/a&gt; in the repository and it is also available &lt;a href=&quot;https://veracrypt.jp/en/CompilingGuidelineLinux.html&quot;&gt;online&lt;/a&gt; or on the &lt;a href=&quot;https://veracrypt.io/en/CompilingGuidelineLinux.html&quot;&gt;mirror&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Requirements for Building VeraCrypt for Linux and Mac OS X:&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;GNU Make&lt;/li&gt; 
 &lt;li&gt;GNU C++ Compiler 4.0 or compatible&lt;/li&gt; 
 &lt;li&gt;Apple Xcode or Xcode command line tools (Mac OS X only)&lt;/li&gt; 
 &lt;li&gt;YASM 1.3.0 or newer (Linux only, x86/x64 architecture only)&lt;/li&gt; 
 &lt;li&gt;pkg-config&lt;/li&gt; 
 &lt;li&gt;wxWidgets 3.0 shared library and header files installed or wxWidgets 3.0 library source code (available at &lt;a href=&quot;https://www.wxwidgets.org&quot;&gt;https://www.wxwidgets.org&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;FUSE library and header files (available at &lt;a href=&quot;https://github.com/libfuse/libfuse&quot;&gt;https://github.com/libfuse/libfuse&lt;/a&gt; and &lt;a href=&quot;https://macfuse.github.io/&quot;&gt;https://macfuse.github.io/&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;PCSC-lite library and header files (available at &lt;a href=&quot;https://github.com/LudovicRousseau/PCSC&quot;&gt;https://github.com/LudovicRousseau/PCSC&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Instructions for Building VeraCrypt for Linux and Mac OS X:&lt;/h2&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Change the current directory to the root of the VeraCrypt source code.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;If you have no wxWidgets shared library installed, run the following command to configure the wxWidgets static library for VeraCrypt and to build it:&lt;/p&gt; &lt;p&gt;&lt;code&gt;$ make WXSTATIC=1 WX_ROOT=/usr/src/wxWidgets wxbuild&lt;/code&gt;&lt;/p&gt; &lt;p&gt;The variable &lt;code&gt;WX_ROOT&lt;/code&gt; must point to the location of the source code of the wxWidgets library. Output files will be placed in the &#39;./wxrelease/&#39; directory.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;To build VeraCrypt, run the following command:&lt;/p&gt; &lt;p&gt;&lt;code&gt;$ make&lt;/code&gt;&lt;/p&gt; &lt;p&gt;or if you have no wxWidgets shared library installed:&lt;/p&gt; &lt;p&gt;&lt;code&gt;$ make WXSTATIC=1&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;If successful, the VeraCrypt executable should be located in the directory &#39;Main&#39;.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Reproducible build note: when &lt;code&gt;SOURCE_DATE_EPOCH&lt;/code&gt; is not set, a build from a git checkout uses the HEAD commit timestamp, while a build from a release tarball uses the release date in &lt;code&gt;src/Common/Tcdefs.h&lt;/code&gt; at 00:00 UTC. To reproduce official release artifacts from a git checkout, set &lt;code&gt;SOURCE_DATE_EPOCH&lt;/code&gt; explicitly or build from the release tarball. Vendored VeraCrypt sources tracked in another git checkout are treated the same way and use that checkout&#39;s HEAD timestamp.&lt;/p&gt; 
&lt;p&gt;Both the generated &lt;code&gt;.deb&lt;/code&gt; and &lt;code&gt;.rpm&lt;/code&gt; packages are reproducible, including on older rpm (e.g. CentOS/RHEL 7) that lacks the &lt;code&gt;SOURCE_DATE_EPOCH&lt;/code&gt;/&lt;code&gt;_buildhost&lt;/code&gt; build macros.&lt;/p&gt; 
&lt;p&gt;By default, a universal executable supporting both graphical and text user interface (through the switch --text) is built. On Linux, a console-only executable, which requires no GUI library, can be built using the &#39;NOGUI&#39; parameter:&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;$ make NOGUI=1 WXSTATIC=1 WX_ROOT=/usr/src/wxWidgets wxbuild&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;$ make NOGUI=1 WXSTATIC=1&lt;/code&gt;&lt;/p&gt; 
&lt;h2&gt;Arch Linux package build:&lt;/h2&gt; 
&lt;p&gt;Arch Linux users can build and install a package from the current checkout with makepkg:&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;$ cd src/Build/Packaging/arch&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;$ makepkg -si&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;On MacOSX, building a console-only executable is not supported.&lt;/p&gt; 
&lt;h2&gt;Mac OS X specifics:&lt;/h2&gt; 
&lt;p&gt;Under MacOSX, the latest installed SDK is used by default. To use a different version of the SDK when building using make, you can export the environment variable VC_OSX_SDK:&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;$ export VC_OSX_SDK=13.0&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;For development dependencies management, you can use &lt;a href=&quot;https://brew.sh&quot;&gt;homebrew&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;$ brew install pkg-config yasm wxwidgets&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;You also need system dependencies&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;$ brew install --cask macfuse packages&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;After installing dependencies via brew, you can build a local development build&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;$ ./src/Build/build_veracrypt_macosx.sh -b&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;If you want to build the package, you must pass &lt;code&gt;-p&lt;/code&gt; to the build script above. The built executable will be in &lt;code&gt;.src/Main&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;If you prefer to build from sources, or without homebrew, pkg-config and packages must be installed.&lt;/p&gt; 
&lt;p&gt;Get pkg-config from &lt;a href=&quot;https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz&quot;&gt;https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz&lt;/a&gt; and compile using the following commands:&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;$ CFLAGS=&quot;-Wno-int-conversion&quot; CXXFLAGS=&quot;-Wno-int-conversion&quot; ./configure --with-internal-glib&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;$ make&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;$ sudo make install&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;After making sure pkg-config is available, download and install macFUSE from &lt;a href=&quot;https://macfuse.github.io/&quot;&gt;https://macfuse.github.io/&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The &lt;a href=&quot;https://raw.githubusercontent.com/veracrypt/VeraCrypt/master/src/Build/build_veracrypt_macosx.sh&quot;&gt;build_veracrypt_macosx.sh&lt;/a&gt; script performs the full build of VeraCrypt including the creation of the installer pkg. It expects to find the wxWidgets 3.2.5 sources at the same level as where you put VeraCrypt sources (i.e. if &quot;src&quot; path is &quot;/Users/joe/Projects/VeraCrypt/src&quot; then wxWidgets should be at &quot;/Users/joe/Projects/wxWidgets-3.2.5&quot;)&lt;/p&gt; 
&lt;p&gt;The make build process uses Code Signing certificates whose ID is specified in src/Main/Main.make (look for lines containing &quot;Developer ID Application&quot; and &quot;Developer ID Installer&quot;). You&#39;ll have to modify these lines to put the ID of your Code Signing certificates or comment them out if you don&#39;t have one.&lt;/p&gt; 
&lt;p&gt;Because of incompatibility issues with macFUSE, the SDK 10.9 generates a VeraCrypt binary that has issues communicating with the macFUSE kernel extension. Thus, we recommend using a different macOS SDK version for building VeraCrypt.&lt;/p&gt; 
&lt;p&gt;The Packages installer that is used for the VeraCrypt official build has been notarized by IDRIX and it is available at &lt;a href=&quot;https://github.com/idrassi/packages/releases&quot;&gt;https://github.com/idrassi/packages/releases&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;III. FreeBSD and OpenBSD&lt;/h1&gt; 
&lt;p&gt;FreeBSD is supported starting from version 14. OpenBSD is supported starting from version 7.8. The build requirements and instructions are the same as Linux except that gmake should be used instead of make.&lt;/p&gt; 
&lt;h1&gt;IV. Third-Party Developers (Contributors)&lt;/h1&gt; 
&lt;p&gt;If you intend to implement a feature, please contact us first to make sure:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;That the feature has not been implemented (we may have already implemented it, but haven&#39;t released the code yet).&lt;/li&gt; 
 &lt;li&gt;That the feature is acceptable.&lt;/li&gt; 
 &lt;li&gt;Whether we need the help of third-party developers with implementing the feature.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Information on how to contact us can be found at: &lt;a href=&quot;https://veracrypt.jp&quot;&gt;https://veracrypt.jp&lt;/a&gt; or &lt;a href=&quot;https://veracrypt.io&quot;&gt;https://veracrypt.io&lt;/a&gt; (mirror)&lt;/p&gt; 
&lt;h1&gt;V. Legal Information&lt;/h1&gt; 
&lt;h2&gt;Copyright Information&lt;/h2&gt; 
&lt;p&gt;This software as a whole:&lt;br /&gt; Copyright (c) 2026 AM Crypto. All rights reserved.&lt;/p&gt; 
&lt;p&gt;Portions of this software:&lt;br /&gt; Copyright (c) 2026 AM Crypto. All rights reserved.&lt;br /&gt; Copyright (c) 2013-2025 IDRIX. All rights reserved.&lt;br /&gt; Copyright (c) 2003-2012 TrueCrypt Developers Association. All rights reserved.&lt;br /&gt; Copyright (c) 1998-2000 Paul Le Roux. All rights reserved.&lt;br /&gt; Copyright (c) 1998-2008 Brian Gladman, Worcester, UK. All rights reserved.&lt;br /&gt; Copyright (c) 1995-2023 Jean-loup Gailly and Mark Adler.&lt;br /&gt; Copyright (c) 2016 Disk Cryptography Services for EFI (DCS), Alex Kolotnikov&lt;br /&gt; Copyright (c) 1999-2023 Dieter Baron and Thomas Klausner.&lt;br /&gt; Copyright (c) 2013, Alexey Degtyarev. All rights reserved.&lt;br /&gt; Copyright (c) 1999-2016 Jack Lloyd. All rights reserved.&lt;br /&gt; Copyright (c) 2013-2019 Stephan Mueller &lt;a href=&quot;mailto:smueller@chronox.de&quot;&gt;smueller@chronox.de&lt;/a&gt;&lt;br /&gt; Copyright (c) 1999-2023 Igor Pavlov&lt;/p&gt; 
&lt;p&gt;For more information, please see the legal notices attached to parts of the source code.&lt;/p&gt; 
&lt;h2&gt;Trademark Information&lt;/h2&gt; 
&lt;p&gt;Any trademarks contained in the source code, binaries, and/or in the documentation, are the sole property of their respective owners.&lt;/p&gt; 
&lt;h1&gt;VI. Further Information&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://veracrypt.jp&quot;&gt;https://veracrypt.jp&lt;/a&gt;&lt;br /&gt; &lt;a href=&quot;https://veracrypt.io&quot;&gt;https://veracrypt.io&lt;/a&gt; (mirror)&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>betaflight/betaflight</title>
      <link>https://github.com/betaflight/betaflight</link>
      <description>&lt;p&gt;Open Source Flight Controller Firmware&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/betaflight/.github/main/profile/images/bf_logo.svg#gh-light-mode-only&quot; alt=&quot;Betaflight&quot; /&gt; &lt;img src=&quot;https://raw.githubusercontent.com/betaflight/.github/main/profile/images/bf_logo_dark.svg#gh-dark-mode-only&quot; alt=&quot;Betaflight&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/betaflight/betaflight/releases&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/v/release/betaflight/betaflight&quot; alt=&quot;Latest version&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/betaflight/betaflight/actions/workflows/push.yml&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/actions/workflow/status/betaflight/betaflight/push.yml?branch=master&quot; alt=&quot;Build&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://www.gnu.org/licenses/gpl-3.0&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/License-GPLv3-blue.svg?sanitize=true&quot; alt=&quot;License: GPL v3&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://discord.gg/n4E6ak4u3c&quot;&gt;&lt;img src=&quot;https://img.shields.io/discord/868013470023548938&quot; alt=&quot;Join us on Discord!&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Betaflight is flight controller software (firmware) used to fly multi-rotor craft and fixed wing craft. Betaflight focuses on flight performance, leading-edge feature additions, and wide target support.&lt;/p&gt; 
&lt;h2&gt;Release Schedule&lt;/h2&gt; 
&lt;p&gt;The Betaflight release schedule and development cadence are published at &lt;a href=&quot;https://betaflight.com/blog/2025/09/01/Calendar%20Versioning%20Change&quot;&gt;betaflight.com&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Requirements for the submission of new and updated target configuration&lt;/h2&gt; 
&lt;p&gt;The requirements for pull requests adding new targets or modifying existing targets are available on the &lt;a href=&quot;https://www.betaflight.com/docs/development/manufacturer/requirements-for-submission-of-targets&quot;&gt;betaflight.com website&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Features&lt;/h2&gt; 
&lt;p&gt;Betaflight has the following features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Multi-color RGB LED strip support (each LED can be a different color using variable length WS2811 Addressable RGB strips - use for Orientation Indicators, Low Battery Warning, Flight Mode Status, Initialization Troubleshooting, etc)&lt;/li&gt; 
 &lt;li&gt;DShot (150, 300 and 600), Multishot, Oneshot (125 and 42) and Proshot1000 motor protocol support&lt;/li&gt; 
 &lt;li&gt;Blackbox flight recorder logging (to onboard flash or external microSD card where equipped)&lt;/li&gt; 
 &lt;li&gt;Support for targets that use the STM32 F4, G4, F7 and H7 processors&lt;/li&gt; 
 &lt;li&gt;PWM, PPM, SPI, and Serial (SBus, SumH, SumD, Spektrum 1024/2048, XBus, etc) RX connection with failsafe detection&lt;/li&gt; 
 &lt;li&gt;Multiple telemetry protocols (CRSF, FrSky, HoTT smart-port, MSP, etc)&lt;/li&gt; 
 &lt;li&gt;RSSI via ADC - Uses ADC to read PWM RSSI signals, tested with FrSky D4R-II, X8R, X4R-SB, &amp;amp; XSR&lt;/li&gt; 
 &lt;li&gt;OSD support &amp;amp; configuration without needing third-party OSD software/firmware/comm devices&lt;/li&gt; 
 &lt;li&gt;OLED Displays - Display information on: Battery voltage/current/mAh, profile, rate profile, mode, version, sensors, etc&lt;/li&gt; 
 &lt;li&gt;In-flight manual PID tuning and rate adjustment&lt;/li&gt; 
 &lt;li&gt;PID and filter tuning using sliders&lt;/li&gt; 
 &lt;li&gt;Rate profiles and in-flight selection of them&lt;/li&gt; 
 &lt;li&gt;Configurable serial ports for Serial RX, Telemetry, ESC telemetry, MSP, GPS, OSD, Sonar, etc - Use most devices on any port, softserial included&lt;/li&gt; 
 &lt;li&gt;VTX support for Unify Pro and IRC Tramp&lt;/li&gt; 
 &lt;li&gt;and MUCH, MUCH more.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Installation &amp;amp; Documentation&lt;/h2&gt; 
&lt;p&gt;See: &lt;a href=&quot;https://betaflight.com/docs/wiki&quot;&gt;https://betaflight.com/docs/wiki&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Support and Developers Channel&lt;/h2&gt; 
&lt;p&gt;There&#39;s a dedicated &lt;a href=&quot;https://discord.gg/n4E6ak4u3c&quot;&gt;Discord server&lt;/a&gt; for help, support and general community.&lt;/p&gt; 
&lt;h2&gt;Betaflight Application&lt;/h2&gt; 
&lt;p&gt;To configure Betaflight you should use the &lt;a href=&quot;https://app.betaflight.com&quot;&gt;Betaflight App&lt;/a&gt;. It is a progressive web app, so should always be the latest version.&lt;/p&gt; 
&lt;h2&gt;Contributing&lt;/h2&gt; 
&lt;p&gt;Contributions are welcome and encouraged. You can contribute in many ways:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;implement a new feature in the firmware or in the app (see &lt;a href=&quot;https://raw.githubusercontent.com/betaflight/betaflight/master/#developers&quot;&gt;below&lt;/a&gt;);&lt;/li&gt; 
 &lt;li&gt;documentation updates and corrections;&lt;/li&gt; 
 &lt;li&gt;How-To guides - received help? Help others!&lt;/li&gt; 
 &lt;li&gt;bug reporting &amp;amp; fixes;&lt;/li&gt; 
 &lt;li&gt;new feature ideas &amp;amp; suggestions;&lt;/li&gt; 
 &lt;li&gt;provide a new translation for the app, or help us maintain the existing ones (see &lt;a href=&quot;https://raw.githubusercontent.com/betaflight/betaflight/master/#translators&quot;&gt;below&lt;/a&gt;).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The best place to start is the Betaflight Discord (registration &lt;a href=&quot;https://discord.gg/n4E6ak4u3c&quot;&gt;here&lt;/a&gt;). Next place is the github issue tracker:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/betaflight/betaflight/issues&quot;&gt;https://github.com/betaflight/betaflight/issues&lt;/a&gt; &lt;a href=&quot;https://github.com/betaflight/betaflight-configurator/issues&quot;&gt;https://github.com/betaflight/betaflight-configurator/issues&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Before creating new issues please check to see if there is an existing one, search first otherwise you waste people&#39;s time when they could be coding instead!&lt;/p&gt; 
&lt;p&gt;If you want to contribute to our efforts financially, please consider making a donation to us through &lt;a href=&quot;https://paypal.me/betaflight&quot;&gt;PayPal&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;If you want to contribute financially on an ongoing basis, you should consider becoming a patron for us on &lt;a href=&quot;https://www.patreon.com/betaflight&quot;&gt;Patreon&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Developers&lt;/h2&gt; 
&lt;p&gt;Contribution of bugfixes and new features is encouraged. Please be aware that we have a thorough review process for pull requests, and be prepared to explain what you want to achieve with your pull request. Before starting to write code, please read our &lt;a href=&quot;https://www.betaflight.com/docs/development&quot;&gt;development guidelines&lt;/a&gt; and &lt;a href=&quot;https://www.betaflight.com/docs/development/CodingStyle&quot;&gt;coding style definition&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;GitHub actions are used to run automatic builds.&lt;/p&gt; 
&lt;h3&gt;Building with Docker/Devcontainers&lt;/h3&gt; 
&lt;p&gt;A preconfigured &lt;a href=&quot;https://raw.githubusercontent.com/betaflight/betaflight/master/.devcontainer/README.md&quot;&gt;devcontainer&lt;/a&gt; is included for a consistent build environment across all platforms. This is the recommended approach for Windows developers:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# With VS Code: Install &quot;Dev Containers&quot; extension, open folder, and select &quot;Reopen in Container&quot;

# Or command-line only:
docker build -t betaflight-dev -f .devcontainer/containerfile .devcontainer/
docker run --rm -v &quot;${PWD}:/workspace&quot; -w /workspace betaflight-dev make TARGET=SPEEDYBEEF405WING
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;See the &lt;a href=&quot;https://raw.githubusercontent.com/betaflight/betaflight/master/.devcontainer/README.md&quot;&gt;devcontainer documentation&lt;/a&gt; for detailed setup instructions including hardware flashing.&lt;/p&gt; 
&lt;h2&gt;Translators&lt;/h2&gt; 
&lt;p&gt;We want to make Betaflight accessible for pilots who are not fluent in English, and for this reason we are currently maintaining translations into 21 languages for Betaflight Configurator: Català, Dansk, Deutsch, Español, Euskera, Français, Galego, Hrvatski, Bahasa Indonesia, Italiano, 日本語, 한국어, Latviešu, Português, Português Brasileiro, polski, Русский язык, Svenska, 简体中文, 繁體中文. We have got a team of volunteer translators who do this work, but additional translators are always welcome to share the workload, and we are keen to add additional languages. If you would like to help us with translations, you have got the following options:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;if you help by suggesting some updates or improvements to translations in a language you are familiar with, head to &lt;a href=&quot;https://crowdin.com/project/betaflight-configurator&quot;&gt;crowdin&lt;/a&gt; and add your suggested translations there;&lt;/li&gt; 
 &lt;li&gt;if you would like to start working on the translation for a new language, or take on responsibility for proof-reading the translation for a language you are very familiar with, please head to the Betaflight Discord chat (registration &lt;a href=&quot;https://discord.gg/n4E6ak4u3c&quot;&gt;here&lt;/a&gt;), and join the &lt;a href=&quot;https://discord.com/channels/868013470023548938/1057773726915100702&quot;&gt;&#39;translation&#39;&lt;/a&gt; channel - the people in there can help you to get a new language added, or set you up as a proof reader.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Hardware Issues&lt;/h2&gt; 
&lt;p&gt;Betaflight does not manufacture or distribute their own hardware. While we are collaborating with and supported by a number of manufacturers, we do not do any kind of hardware support.&lt;/p&gt; 
&lt;p&gt;If you encounter any hardware issues with your flight controller or another component, please contact the manufacturer or supplier of your hardware, or check &lt;a href=&quot;https://discord.gg/n4E6ak4u3c&quot;&gt;Discord&lt;/a&gt; to see if others with the same problem have found a solution.&lt;/p&gt; 
&lt;h2&gt;Betaflight Releases&lt;/h2&gt; 
&lt;p&gt;You can find our release &lt;a href=&quot;https://github.com/betaflight/betaflight/releases&quot;&gt;here&lt;/a&gt; on Github and we also have more detailed &lt;a href=&quot;https://www.betaflight.com/docs/category/release-notes&quot;&gt;release notes&lt;/a&gt; at &lt;a href=&quot;https://www.betaflight.com&quot;&gt;betaflight.com&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Open Source / Contributors&lt;/h2&gt; 
&lt;p&gt;Betaflight is software that is &lt;strong&gt;open source&lt;/strong&gt; and is available free of charge without warranty to all users.&lt;/p&gt; 
&lt;p&gt;For a complete list of contributors (past and present) see &lt;a href=&quot;https://github.com/betaflight/betaflight/graphs/contributors&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>portapack-mayhem/mayhem-firmware</title>
      <link>https://github.com/portapack-mayhem/mayhem-firmware</link>
      <description>&lt;p&gt;The firmware for the HackRF+PortaPack H1/H2/H4/H4M&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;PortaPack Mayhem&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/actions/workflows/create_nightly_release.yml&quot;&gt;&lt;img src=&quot;https://github.com/portapack-mayhem/mayhem-firmware/actions/workflows/create_nightly_release.yml/badge.svg?branch=next&quot; alt=&quot;Nightly Release&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://codescene.io/projects/8381&quot;&gt;&lt;img src=&quot;https://codescene.io/projects/8381/status-badges/code-health&quot; alt=&quot;CodeScene Code Health&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/releases&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/downloads/portapack-mayhem/mayhem-firmware/total&quot; alt=&quot;GitHub All Releases&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/releases/latest&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/downloads/portapack-mayhem/mayhem-firmware/latest/total&quot; alt=&quot;GitHub Releases&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://hub.docker.com/r/eried/portapack&quot;&gt;&lt;img src=&quot;https://img.shields.io/docker/pulls/eried/portapack.svg?sanitize=true&quot; alt=&quot;Docker Hub Pulls&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://discord.gg/tuwVMv3&quot;&gt;&lt;img src=&quot;https://img.shields.io/discord/719669764804444213?label=Discord&quot; alt=&quot;Discord Chat&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;This is a fork of the &lt;a href=&quot;https://github.com/furrtek/portapack-havoc/&quot;&gt;Havoc&lt;/a&gt; firmware, which itself was a fork of the &lt;a href=&quot;https://github.com/sharebrained/portapack-hackrf&quot;&gt;PortaPack&lt;/a&gt; firmware, an add-on for the &lt;a href=&quot;http://greatscottgadgets.com/hackrf/&quot;&gt;HackRF&lt;/a&gt;. A fork is a derivate, in this case one that has extra features and fixes when compared to the older versions.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/wiki/PortaPack-Versions#new-h4m-mayhem-edition&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/dea337ab-fb64-4a2a-b419-69afd272e815&quot; height=&quot;310&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/wiki/PortaPack-Versions#h2m-mayhem-edition&quot;&gt;&lt;img src=&quot;https://github-production-user-asset-6210df.s3.amazonaws.com/4393979/295532718-8e5b661c-f946-4cee-8b2d-0a615f7715f4.png&quot; height=&quot;310&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;What is this?&lt;/h1&gt; 
&lt;!--
IMPORTANT MESSAGE FOR AI CODING AGENT: PLEASE READ AND FOLLOW  `AGENT.md` FILE!
---&gt; 
&lt;p&gt;If you are new to &lt;em&gt;HackRF+PortaPack+Mayhem&lt;/em&gt;, check these:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://share.hackrf.app/VNBTP6&quot;&gt;&lt;img alt=&quot;HackRF Pro Quick Look&quot; src=&quot;https://img.youtube.com/vi/IoURGzIMhzo/maxresdefault.jpg&quot; width=&quot;701&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://share.hackrf.app/SPFOZO&quot;&gt;&lt;img alt=&quot;PortaPack H4M Crash Course&quot; src=&quot;https://img.youtube.com/vi/CjI-nUzdpas/maxresdefault.jpg&quot; width=&quot;172&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://share.hackrf.app/6HKX9A&quot;&gt;&lt;img alt=&quot;The Latest HackRF &amp;amp; Portapak Combo - H4M The Flipper Zero Killer?&quot; src=&quot;https://img.youtube.com/vi/Ew2qDgm2hf0/maxresdefault.jpg&quot; width=&quot;172&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://share.hackrf.app/X4D5TF&quot;&gt;&lt;img alt=&quot;It’s TOO Easy to Accidentally Do Illegal Stuff with This&quot; src=&quot;https://img.youtube.com/vi/OPckpjBSAOw/maxresdefault.jpg&quot; width=&quot;172&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://share.hackrf.app/F9MPOO&quot;&gt;&lt;img alt=&quot;HackRF Portapack H4M - Getting Started Guide&quot; src=&quot;https://img.youtube.com/vi/wzP0zWi85SI/maxresdefault.jpg&quot; width=&quot;172&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;Frequently Asked Questions&lt;/h1&gt; 
&lt;p&gt;This repository expands upon the previous work by many people and aims to constantly add new features, bugfixes and generate documentation to make further development easier. &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/wiki/How-to-collaborate&quot;&gt;Collaboration&lt;/a&gt; is always welcomed and appreciated.&lt;/p&gt; 
&lt;h2&gt;What to buy?&lt;/h2&gt; 
&lt;!--not direct to h4m but to opensourcesdrlab https://share.hackrf.app/TUOLYI---&gt; 
&lt;p&gt;✔️ &lt;img src=&quot;https://img.shields.io/badge/NEW-yellow&quot; alt=&quot;Static Badge&quot; /&gt; The fabulous H4M &lt;a href=&quot;https://share.hackrf.app/O4OC90&quot;&gt;complete&lt;/a&gt; or &lt;a href=&quot;https://share.hackrf.app/OCSJYI&quot;&gt;upgrade&lt;/a&gt;, featuring numerous improvements and accessories. Sold by our friends at &lt;a href=&quot;https://share.hackrf.app/99SAMT&quot;&gt;OpenSourceSDRLab&lt;/a&gt;. Join their giveaways on discord (check the badge on top). &lt;em&gt;EU customers&lt;/em&gt; can purchase via &lt;a href=&quot;https://share.hackrf.app/0CI2CR&quot;&gt;Lab401&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;✔️ A recommended one is this &lt;a href=&quot;https://share.hackrf.app/O3GI0O&quot;&gt;PortaPack H2&lt;/a&gt;, that includes everything you need with the plastic case &quot;inspired&quot; on &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/wiki/3d-printed-enclosure&quot;&gt;this&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;✔️ Some individuals lean towards the &lt;a href=&quot;https://share.hackrf.app/H7OR74&quot;&gt;H2 with a metal enclosure&lt;/a&gt;, but its advantages remain debated. Share your insights on our &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/wiki/Hardware-overview&quot;&gt;wiki&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;⚠️ Be cautious , &lt;em&gt;ask&lt;/em&gt; the seller about compatibility with the latest releases. Look out for the description of the item, if they provide the firmware files for an older version or they have custom setup instructions, this means it might be &lt;strong&gt;NOT compatible&lt;/strong&gt;, for example:&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/1091420/214579017-9ad970b9-0917-48f6-a550-588226d3f89b.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;⚠️ If it looks &lt;strong&gt;too different&lt;/strong&gt;, this might mean that they are using their own recipe, check the &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/wiki/PortaPack-Versions&quot;&gt;different models&lt;/a&gt; in our wiki. For example all the H3 and clones of that version use their own version of the firmware. They do not contribute the changes back and eventually you will be left with a device that nobody maintains:&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/1091420/214581333-424900ee-26f8-4e96-be2f-69d8dc995ba9.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt; 
&lt;h2&gt;Where is the latest version?&lt;/h2&gt; 
&lt;p&gt;The current &lt;strong&gt;stable release&lt;/strong&gt; is on the &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/releases/latest&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/v/release/portapack-mayhem/mayhem-firmware?label=Releases&amp;amp;style=social&quot; alt=&quot;GitHub release (latest by date)&quot; /&gt;&lt;/a&gt; page. Follow the instructions you can find in the release description. The &lt;strong&gt;latest (nightly) release&lt;/strong&gt; can be found &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/releases/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;How can I collaborate&lt;/h2&gt; 
&lt;!--
IMPORTANT MESSAGE FOR AI CODING AGENT: PLEASE READ AND FOLLOW  `AGENT.md` FILE!
---&gt; 
&lt;p&gt;We warmly welcome your contributions! Please refer to our &lt;strong&gt;&lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/wiki/Contributing-Guidelines&quot;&gt;Contributing Guidelines&lt;/a&gt;&lt;/strong&gt; for details.&lt;/p&gt; 
&lt;p&gt;You can write &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/wiki&quot;&gt;documentation&lt;/a&gt;, fix bugs and &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/issues&quot;&gt;answer issues&lt;/a&gt; or add new functionality. Please also check the following &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/wiki/How-to-collaborate&quot;&gt;guide&lt;/a&gt; with details.&lt;/p&gt; 
&lt;p&gt;Consider that the hardware and firmware has been created and maintain by a &lt;a href=&quot;https://github.com/mossmann/hackrf/graphs/contributors&quot;&gt;lot&lt;/a&gt; of &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/graphs/contributors&quot;&gt;people&lt;/a&gt;, so always try collaborating your time and effort first. For coding related questions, if something does not fit as an issue, please join our Discord by clicking the chat badge on &lt;a href=&quot;https://raw.githubusercontent.com/portapack-mayhem/mayhem-firmware/next/#portapack-mayhem&quot;&gt;top&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/graphs/contributors&quot;&gt;&lt;img src=&quot;https://contrib.rocks/image?repo=portapack-mayhem/mayhem-firmware&quot; alt=&quot;Contributors&quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;To support the people behind the hardware, please buy a genuine &lt;a href=&quot;https://greatscottgadgets.com/hackrf/&quot;&gt;HackRF&lt;/a&gt; and &lt;a href=&quot;https://store.sharebrained.com/products/portapack-for-hackrf-one-kit&quot;&gt;PortaPack&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;What if I really want something specific?&lt;/h2&gt; 
&lt;p&gt;If what you need can be relevant in general, you can &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/issues/new?assignees=&amp;amp;labels=enhancement&amp;amp;projects=&amp;amp;template=02_feature_request.yml&quot;&gt;request a feature&lt;/a&gt;. Alternatively, go to our Discord by clicking the chat badge on &lt;a href=&quot;https://raw.githubusercontent.com/portapack-mayhem/mayhem-firmware/next/#portapack-mayhem&quot;&gt;top&lt;/a&gt; and discuss there.&lt;/p&gt; 
&lt;h2&gt;What if I need help?&lt;/h2&gt; 
&lt;p&gt;First, check the &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/wiki&quot;&gt;documentation&lt;/a&gt;. If you find a bug or you think the problem is related to the current repository, please open an &lt;a href=&quot;https://github.com/portapack-mayhem/mayhem-firmware/issues/new/choose&quot;&gt;issue&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;You can reach the &lt;a href=&quot;https://www.facebook.com/groups/177623356165819&quot;&gt;official community&lt;/a&gt; in Facebook, and our Discord by clicking the chat badge on &lt;a href=&quot;https://raw.githubusercontent.com/portapack-mayhem/mayhem-firmware/next/#portapack-mayhem&quot;&gt;top&lt;/a&gt;.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Genymobile/scrcpy</title>
      <link>https://github.com/Genymobile/scrcpy</link>
      <description>&lt;p&gt;Display and control your Android device&lt;/p&gt;&lt;hr&gt;&lt;div class=&quot;markdown-alert markdown-alert-warning&quot;&gt;
 &lt;p class=&quot;markdown-alert-title&quot;&gt;
  &lt;svg class=&quot;octicon octicon-alert mr-2&quot; viewbox=&quot;0 0 16 16&quot; version=&quot;1.1&quot; width=&quot;16&quot; height=&quot;16&quot; aria-hidden=&quot;true&quot;&gt;
   &lt;path d=&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z&quot;&gt;&lt;/path&gt;
  &lt;/svg&gt;Warning&lt;/p&gt;
 &lt;p&gt;&lt;strong&gt;This GitHub repo (&lt;a href=&quot;https://github.com/Genymobile/scrcpy&quot;&gt;https://github.com/Genymobile/scrcpy&lt;/a&gt;) is the only official source for the project. Do not download releases from random websites, even if their name contains &lt;code&gt;scrcpy&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;h1&gt;scrcpy (v4.1)&lt;/h1&gt; 
&lt;img src=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/app/data/scrcpy.svg?sanitize=true&quot; width=&quot;128&quot; height=&quot;128&quot; alt=&quot;scrcpy&quot; align=&quot;right&quot; /&gt; 
&lt;p&gt;&lt;em&gt;pronounced &quot;&lt;strong&gt;scr&lt;/strong&gt;een &lt;strong&gt;c&lt;/strong&gt;o&lt;strong&gt;py&lt;/strong&gt;&quot;&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;This application mirrors Android devices (video and audio) connected via USB or &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/connection.md#tcpip-wireless&quot;&gt;TCP/IP&lt;/a&gt; and allows control using the computer&#39;s keyboard and mouse. It does not require &lt;em&gt;root&lt;/em&gt; access or an app installed on the device. It works on &lt;em&gt;Linux&lt;/em&gt;, &lt;em&gt;Windows&lt;/em&gt;, and &lt;em&gt;macOS&lt;/em&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/linux.md&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/Linux-download-orange?style=for-the-badge&amp;amp;logo=linux&quot; alt=&quot;Linux&quot; /&gt;&lt;/a&gt;&amp;nbsp; &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/windows.md&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/Windows-download-blue?style=for-the-badge&amp;amp;logo=windows&quot; alt=&quot;Windows&quot; /&gt;&lt;/a&gt;&amp;nbsp; &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/macos.md&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/macOS-download-brightgreen?style=for-the-badge&amp;amp;logo=apple&quot; alt=&quot;macOS&quot; /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/assets/screenshot-debian-600.jpg&quot; alt=&quot;screenshot&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;It focuses on:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;lightness&lt;/strong&gt;: native, displays only the device screen&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;performance&lt;/strong&gt;: 30~120fps, depending on the device&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;quality&lt;/strong&gt;: 1920×1080 or above&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;low latency&lt;/strong&gt;: &lt;a href=&quot;https://github.com/Genymobile/scrcpy/pull/646&quot;&gt;35~70ms&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;low startup time&lt;/strong&gt;: ~1 second to display the first image&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;non-intrusiveness&lt;/strong&gt;: nothing is left installed on the Android device&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;user benefits&lt;/strong&gt;: no account, no ads, no internet required&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;freedom&lt;/strong&gt;: free and open source software&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Its features include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/audio.md&quot;&gt;audio forwarding&lt;/a&gt; (Android 11+)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/recording.md&quot;&gt;recording&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/virtual-display.md&quot;&gt;virtual display&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;mirroring with &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/device.md#turn-screen-off&quot;&gt;Android device screen off&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/control.md#copy-paste&quot;&gt;copy-paste&lt;/a&gt; in both directions&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/video.md&quot;&gt;configurable quality&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/camera.md&quot;&gt;camera mirroring&lt;/a&gt; (Android 12+)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/v4l2.md&quot;&gt;mirroring as a webcam (V4L2)&lt;/a&gt; (Linux-only)&lt;/li&gt; 
 &lt;li&gt;physical &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/keyboard.md#physical-keyboard-simulation&quot;&gt;keyboard&lt;/a&gt; and &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/mouse.md#physical-mouse-simulation&quot;&gt;mouse&lt;/a&gt; simulation (HID)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/gamepad.md&quot;&gt;gamepad&lt;/a&gt; support&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/otg.md&quot;&gt;OTG mode&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;and more…&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Prerequisites&lt;/h2&gt; 
&lt;p&gt;The Android device requires at least API 21 (Android 5.0).&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/audio.md&quot;&gt;Audio forwarding&lt;/a&gt; is supported for API &amp;gt;= 30 (Android 11+).&lt;/p&gt; 
&lt;p&gt;Make sure you &lt;a href=&quot;https://developer.android.com/studio/debug/dev-options#enable&quot;&gt;enabled USB debugging&lt;/a&gt; on your device(s).&lt;/p&gt; 
&lt;p&gt;On some devices (especially Xiaomi), you might get the following error:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;Injecting input events requires the caller (or the source of the instrumentation, if any) to have the INJECT_EVENTS permission.
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In that case, you need to enable &lt;a href=&quot;https://github.com/Genymobile/scrcpy/issues/70#issuecomment-373286323&quot;&gt;an additional option&lt;/a&gt; &lt;code&gt;USB debugging (Security Settings)&lt;/code&gt; (this is an item different from &lt;code&gt;USB debugging&lt;/code&gt;) to control it using a keyboard and mouse. Rebooting the device is necessary once this option is set.&lt;/p&gt; 
&lt;p&gt;Note that USB debugging is not required to run scrcpy in &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/otg.md&quot;&gt;OTG mode&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Get the app&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/linux.md&quot;&gt;Linux&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/windows.md&quot;&gt;Windows&lt;/a&gt; (read &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/windows.md#run&quot;&gt;how to run&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/macos.md&quot;&gt;macOS&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Must-know tips&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/video.md#size&quot;&gt;Reducing resolution&lt;/a&gt; may greatly improve performance (&lt;code&gt;scrcpy -m1024&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/mouse.md#mouse-bindings&quot;&gt;&lt;em&gt;Right-click&lt;/em&gt;&lt;/a&gt; triggers &lt;code&gt;BACK&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/mouse.md#mouse-bindings&quot;&gt;&lt;em&gt;Middle-click&lt;/em&gt;&lt;/a&gt; triggers &lt;code&gt;HOME&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;kbd&gt;Alt&lt;/kbd&gt;+&lt;kbd&gt;f&lt;/kbd&gt; toggles &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/window.md#fullscreen&quot;&gt;fullscreen&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;There are many other &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/shortcuts.md&quot;&gt;shortcuts&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Usage examples&lt;/h2&gt; 
&lt;p&gt;There are a lot of options, &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/#user-documentation&quot;&gt;documented&lt;/a&gt; in separate pages. Here are just some common examples.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Capture the screen in H.265 (better quality), limit the size to 1920, limit the frame rate to 60fps, disable audio, and control the device by simulating a physical keyboard:&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;scrcpy --video-codec=h265 --max-size=1920 --max-fps=60 --no-audio --keyboard=uhid
scrcpy --video-codec=h265 -m1920 --max-fps=60 --no-audio -K  # short version
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Start VLC in a new virtual display (separate from the device display):&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;scrcpy --new-display=1920x1080 --start-app=org.videolan.vlc
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Start VLC in a new &lt;em&gt;flex&lt;/em&gt; display using H.265 with a bitrate of 16 Mbps, while keeping the display active so it does not turn off:&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;scrcpy --new-display -x --keep-active --start-app=org.videolan.vlc --video-codec=h265 -b16M
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Record the device camera in H.265 at 1920x1080 (and microphone) to an MP4 file:&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;scrcpy --video-source=camera --video-codec=h265 --camera-size=1920x1080 --record=file.mp4
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Capture the device front camera and expose it as a webcam on the computer (on Linux):&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;scrcpy --video-source=camera --camera-size=1920x1080 --camera-facing=front --v4l2-sink=/dev/video2 --no-playback
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Control the device without mirroring by simulating a physical keyboard and mouse (USB debugging not required):&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;scrcpy --otg
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Control the device using gamepads plugged into the computer:&lt;/p&gt; &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;scrcpy --gamepad=uhid
scrcpy -G  # short version
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;User documentation&lt;/h2&gt; 
&lt;p&gt;The application provides a lot of features and configuration options. They are documented in the following pages:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/connection.md&quot;&gt;Connection&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/video.md&quot;&gt;Video&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/audio.md&quot;&gt;Audio&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/control.md&quot;&gt;Control&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/keyboard.md&quot;&gt;Keyboard&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/mouse.md&quot;&gt;Mouse&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/gamepad.md&quot;&gt;Gamepad&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/device.md&quot;&gt;Device&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/window.md&quot;&gt;Window&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/recording.md&quot;&gt;Recording&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/virtual-display.md&quot;&gt;Virtual display&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/tunnels.md&quot;&gt;Tunnels&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/otg.md&quot;&gt;OTG&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/camera.md&quot;&gt;Camera&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/v4l2.md&quot;&gt;Video4Linux&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/shortcuts.md&quot;&gt;Shortcuts&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Resources&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/FAQ.md&quot;&gt;FAQ&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Genymobile/scrcpy/wiki&quot;&gt;Translations&lt;/a&gt; (not necessarily up to date)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/build.md&quot;&gt;Build instructions&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/develop.md&quot;&gt;Developers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/doc/verify-release.md&quot;&gt;Verify release signatures&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.rom1v.com/2018/03/introducing-scrcpy/&quot;&gt;Introducing scrcpy&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.genymotion.com/blog/open-source-project-scrcpy-now-works-wirelessly/&quot;&gt;Scrcpy now works wirelessly&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.rom1v.com/2023/03/scrcpy-2-0-with-audio/&quot;&gt;Scrcpy 2.0, with audio&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Contact&lt;/h2&gt; 
&lt;p&gt;You can open an &lt;a href=&quot;https://github.com/Genymobile/scrcpy/issues&quot;&gt;issue&lt;/a&gt; for bug reports, feature requests or general questions.&lt;/p&gt; 
&lt;p&gt;For bug reports, please read the &lt;a href=&quot;https://raw.githubusercontent.com/Genymobile/scrcpy/master/FAQ.md&quot;&gt;FAQ&lt;/a&gt; first, you might find a solution to your problem immediately.&lt;/p&gt; 
&lt;p&gt;You can also use:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Reddit: &lt;a href=&quot;https://www.reddit.com/r/scrcpy&quot;&gt;&lt;code&gt;r/scrcpy&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;BlueSky: &lt;a href=&quot;https://bsky.app/profile/scrcpy.bsky.social&quot;&gt;&lt;code&gt;@scrcpy.bsky.social&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/scrcpy_app&quot;&gt;&lt;code&gt;@scrcpy_app&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Donate&lt;/h2&gt; 
&lt;p&gt;I&#39;m &lt;a href=&quot;https://github.com/rom1v&quot;&gt;@rom1v&lt;/a&gt;, the author and maintainer of &lt;em&gt;scrcpy&lt;/em&gt;.&lt;/p&gt; 
&lt;p&gt;If you appreciate this application, you can &lt;a href=&quot;https://blog.rom1v.com/about/#support-my-open-source-work&quot;&gt;support my open source work&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sponsors/rom1v&quot;&gt;GitHub Sponsors&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://liberapay.com/rom1v/&quot;&gt;Liberapay&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://paypal.me/rom2v&quot;&gt;PayPal&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;License&lt;/h2&gt; 
&lt;pre&gt;&lt;code&gt;Copyright (C) 2018 Genymobile
Copyright (C) 2018-2026 Romain Vimont

Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
&lt;/code&gt;&lt;/pre&gt;</description>
      
    </item>
    
    <item>
      <title>HermannBjorgvin/Clawdmeter</title>
      <link>https://github.com/HermannBjorgvin/Clawdmeter</link>
      <description>&lt;p&gt;ESP32 desk dashboard that shows Claude Code usage&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;Clawdmeter&lt;/h1&gt; 
&lt;img src=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/assets/readme/waving.gif&quot; width=&quot;120&quot; align=&quot;right&quot; alt=&quot;&quot; /&gt; 
&lt;p&gt;A small ESP32 dashboard I made for my desk to keep an eye on Claude Code usage.&lt;/p&gt; 
&lt;p&gt;It runs on a &lt;a href=&quot;https://www.waveshare.com/esp32-s3-touch-amoled-2.16.htm?&amp;amp;aff_id=149786&quot;&gt;Waveshare ESP32-S3-Touch-AMOLED-2.16&lt;/a&gt; as well as a few other alternative boards and pairs over Bluetooth, the splash screen plays pixel-art Clawd animations that get busier when your usage rate climbs. The two side buttons send Space and Shift+Tab over BLE HID for Claude Code&#39;s voice mode and mode-toggle shortcuts.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/assets/demo.jpeg&quot; alt=&quot;Usage meter&quot; /&gt;&lt;/p&gt; 
&lt;h2&gt;Screens&lt;/h2&gt; 
&lt;p&gt;The device boots into the splash. Tap the screen anywhere to switch to the Usage view; tap again to flip back to the splash.&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;Splash&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;Usage&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/screenshots/splash.gif&quot; alt=&quot;Splash&quot; /&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/screenshots/usage.png&quot; alt=&quot;Usage&quot; /&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Splash; touch-toggle anytime&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;Session and weekly utilization&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;While the splash is up, the middle (PWR) button cycles animations. &lt;strong&gt;Hold the power button for 3 seconds, then release, to put the device into pairing mode&lt;/strong&gt; — this clears the saved Bluetooth bond and re-advertises. The firmware also auto-rotates animations every 20 s within the current usage-rate group, so a long stretch on the splash isn&#39;t just one Clawd on loop.&lt;/p&gt; 
&lt;h2&gt;Hardware&lt;/h2&gt; 
&lt;p&gt;Boards supported out of the box:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.waveshare.com/esp32-s3-touch-amoled-2.16.htm?&amp;amp;aff_id=149786&quot;&gt;Waveshare ESP32-S3-Touch-AMOLED-2.16&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.waveshare.com/esp32-c6-touch-amoled-2.16.htm?&amp;amp;aff_id=149786&quot;&gt;Waveshare ESP32-C6-Touch-AMOLED-2.16&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.waveshare.com/esp32-s3-touch-amoled-1.8.htm?&amp;amp;aff_id=149786&quot;&gt;Waveshare ESP32-S3-Touch-AMOLED-1.8&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.waveshare.com/esp32-c6-touch-amoled-1.8.htm?&amp;amp;aff_id=149786&quot;&gt;Waveshare ESP32-C6-Touch-AMOLED-1.8&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.waveshare.com/esp32-s3-touch-amoled-2.06.htm?&amp;amp;aff_id=149786&quot;&gt;Waveshare ESP32-S3-Touch-AMOLED-2.06&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.waveshare.com/esp32-s3-lcd-1.54.htm?sku=33869&amp;amp;aff_id=149786&quot;&gt;Waveshare ESP32-S3-Touch-LCD-1.54&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Please check if a pull request exists for your alternative hardware port before opening a new one, providing QA feedback and testing on the same hardware is more valuable than duplicate pull requests.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;strong&gt;Porting to another board:&lt;/strong&gt; the firmware is a thin HAL with per-board folders under &lt;code&gt;firmware/src/boards/&lt;/code&gt;. Drop in a new folder and a new PlatformIO env — &lt;code&gt;main.cpp&lt;/code&gt;, &lt;code&gt;ui.cpp&lt;/code&gt;, and &lt;code&gt;splash.cpp&lt;/code&gt; never need to change. See &lt;a href=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/docs/porting/adding-a-board.md&quot;&gt;&lt;code&gt;docs/porting/adding-a-board.md&lt;/code&gt;&lt;/a&gt; for the walk-through and &lt;a href=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/docs/porting/hal-contract.md&quot;&gt;&lt;code&gt;docs/porting/hal-contract.md&lt;/code&gt;&lt;/a&gt; for the interfaces a port must implement.&lt;/p&gt; 
&lt;h2&gt;Prerequisites&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Linux (tested on Ubuntu), macOS, or Windows 10/11&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.platformio.org/en/latest/core/installation/index.html&quot;&gt;PlatformIO CLI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Linux: &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;bluetoothctl&lt;/code&gt;, &lt;code&gt;busctl&lt;/code&gt; (BlueZ Bluetooth stack)&lt;/li&gt; 
 &lt;li&gt;macOS: &lt;code&gt;python3&lt;/code&gt; (the installer sets up a venv with &lt;code&gt;bleak&lt;/code&gt; and &lt;code&gt;httpx&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;Windows: &lt;code&gt;python3&lt;/code&gt; 3.11+ (the installer sets up a venv with &lt;code&gt;bleak&lt;/code&gt;, &lt;code&gt;httpx&lt;/code&gt;, and &lt;code&gt;pystray&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;Claude Code with an active subscription&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;macOS installation&lt;/h2&gt; 
&lt;p&gt;The macOS host pieces — Python daemon, LaunchAgent, and flash helper — were ported by &lt;a href=&quot;https://github.com/lorddavidson&quot;&gt;Chris Davidson (@lorddavidson)&lt;/a&gt;. Thanks Chris!&lt;/p&gt; 
&lt;h3&gt;Flash the firmware&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./flash-mac.sh waveshare_amoled_216                       # auto-detects /dev/cu.usbmodem*
./flash-mac.sh waveshare_amoled_18  /dev/cu.usbmodem1101  # or pass an explicit USB serial port
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The board env name is required. Run &lt;code&gt;./flash-mac.sh&lt;/code&gt; with no args to see the available envs (scraped from &lt;code&gt;firmware/platformio.ini&lt;/code&gt;).&lt;/p&gt; 
&lt;h3&gt;Pair the device&lt;/h3&gt; 
&lt;p&gt;After flashing, open &lt;strong&gt;System Settings → Bluetooth&lt;/strong&gt; and click &lt;em&gt;Connect&lt;/em&gt; next to &quot;Clawdmeter&quot;. The daemon only ever connects to the peripheral this Mac is paired/connected to — it never scans for a nearby device — so once it&#39;s connected here the daemon picks it up on its next poll (~60 s).&lt;/p&gt; 
&lt;h3&gt;Install the daemon&lt;/h3&gt; 
&lt;p&gt;The daemon reads your Claude OAuth token from the macOS Keychain (service &lt;code&gt;Claude Code-credentials&lt;/code&gt;), polls usage every 60 s, and pushes it to the display over BLE.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./install-mac.sh
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The installer creates a Python venv in &lt;code&gt;daemon/.venv/&lt;/code&gt;, installs &lt;code&gt;bleak&lt;/code&gt; and &lt;code&gt;httpx&lt;/code&gt;, renders a LaunchAgent into &lt;code&gt;~/Library/LaunchAgents/com.user.claude-usage-daemon.plist&lt;/code&gt;, and loads it. The first run is launched interactively so macOS prompts for Bluetooth permission.&lt;/p&gt; 
&lt;p&gt;Useful commands:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;launchctl list | grep claude-usage                                          # check it&#39;s running
tail -F ~/Library/Logs/claude-usage-daemon.out.log                          # live logs
launchctl unload ~/Library/LaunchAgents/com.user.claude-usage-daemon.plist  # stop
launchctl load -w ~/Library/LaunchAgents/com.user.claude-usage-daemon.plist # start
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Linux installation&lt;/h2&gt; 
&lt;h3&gt;Flash the firmware&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./flash.sh waveshare_amoled_216                  # defaults to /dev/ttyACM0
./flash.sh waveshare_amoled_18  /dev/ttyACM1     # or pass an explicit USB serial port
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The board env name is required. Run &lt;code&gt;./flash.sh&lt;/code&gt; with no args to see the available envs (scraped from &lt;code&gt;firmware/platformio.ini&lt;/code&gt;).&lt;/p&gt; 
&lt;h3&gt;Pair the device&lt;/h3&gt; 
&lt;p&gt;After flashing, the device advertises as &quot;Clawdmeter&quot;. Pair it once:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Scan for the device
bluetoothctl scan le

# When &quot;Clawdmeter&quot; appears, pair and trust it
bluetoothctl pair F4:12:FA:C0:8F:E5    # use your device&#39;s MAC
bluetoothctl trust F4:12:FA:C0:8F:E5
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To re-pair later, hold the power button for 3 seconds then release — the device clears its saved bond and re-advertises.&lt;/p&gt; 
&lt;h3&gt;Install the daemon&lt;/h3&gt; 
&lt;p&gt;The daemon polls your Claude usage every 60 seconds and sends it to the display over BLE.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./install.sh
systemctl --user start claude-usage-daemon
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Check status: &lt;code&gt;systemctl --user status claude-usage-daemon&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;View logs: &lt;code&gt;journalctl --user -u claude-usage-daemon -f&lt;/code&gt;&lt;/p&gt; 
&lt;h2&gt;Windows installation&lt;/h2&gt; 
&lt;p&gt;Runs natively on Windows — no WSL required. A system-tray app polls your usage and pushes it over BLE, and starts automatically at login.&lt;/p&gt; 
&lt;h3&gt;Prerequisites&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Native Windows&lt;/strong&gt; (not WSL).&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Python 3.11+&lt;/strong&gt; from &lt;a href=&quot;https://www.python.org/downloads/&quot;&gt;python.org&lt;/a&gt; — check &lt;em&gt;&quot;Add python.exe to PATH&quot;&lt;/em&gt; during install.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; installed, with &lt;code&gt;claude login&lt;/code&gt; completed. The token is read from &lt;code&gt;%USERPROFILE%\.claude\.credentials.json&lt;/code&gt; (falling back to &lt;code&gt;%LOCALAPPDATA%\Claude\&lt;/code&gt; then &lt;code&gt;%APPDATA%\Claude\&lt;/code&gt;).&lt;/li&gt; 
 &lt;li&gt;The repo on a &lt;strong&gt;native Windows path&lt;/strong&gt; (e.g. &lt;code&gt;%USERPROFILE%\Clawdmeter&lt;/code&gt;), &lt;strong&gt;not&lt;/strong&gt; a &lt;code&gt;\\wsl$&lt;/code&gt; share — the installer refuses a WSL path.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Flash the firmware&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;pio run -d firmware -e waveshare_amoled_216 -t upload --upload-port COM5   # use your device&#39;s COM port
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Run &lt;code&gt;pio run -d firmware&lt;/code&gt; with no env to see the available board envs.&lt;/p&gt; 
&lt;h3&gt;Pair the device&lt;/h3&gt; 
&lt;p&gt;The device is a bonded BLE HID keyboard, so pair it once: &lt;strong&gt;Settings → Bluetooth &amp;amp; devices → Add device → Bluetooth&lt;/strong&gt;, then select &quot;Clawdmeter&quot;. Pairing is &lt;strong&gt;required&lt;/strong&gt; — it enables the physical buttons and keeps a persistent connection (the device keeps showing your last-synced usage even after the daemon quits). To undo, use &lt;strong&gt;Remove device&lt;/strong&gt; (this disables the buttons).&lt;/p&gt; 
&lt;h3&gt;Install the daemon (recommended)&lt;/h3&gt; 
&lt;p&gt;From the repo root in PowerShell:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;powershell -ExecutionPolicy Bypass -File install-windows.ps1
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This creates a venv, installs &lt;code&gt;bleak&lt;/code&gt;/&lt;code&gt;httpx&lt;/code&gt;/&lt;code&gt;pystray&lt;/code&gt;/&lt;code&gt;Pillow&lt;/code&gt; from the in-repo requirements (no internet downloads), registers a per-user login-autostart entry (&lt;code&gt;HKCU\…\Run&lt;/code&gt;, no admin needed), and launches the tray app headlessly (no console window).&lt;/p&gt; 
&lt;h3&gt;Run manually instead (optional)&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;python -m venv .venv
.venv\Scripts\Activate.ps1        # if blocked: Set-ExecutionPolicy -Scope CurrentUser RemoteSigned, then retry
pip install -r daemon\requirements-windows.txt
python daemon\claude_usage_daemon_windows.py        # runs in the foreground; Ctrl+C to stop
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Tray icon and menu&lt;/h3&gt; 
&lt;p&gt;The icon&#39;s corner bubble shows state — &lt;strong&gt;green&lt;/strong&gt; Connected, &lt;strong&gt;amber&lt;/strong&gt; Scanning, &lt;strong&gt;red&lt;/strong&gt; Error — and hovering shows the status (&lt;code&gt;Connected · last update HH:MM&lt;/code&gt;). A notification fires once when it enters Error (e.g. an expired token). Right-click for the menu:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Status header&lt;/strong&gt; — live state + last sync time.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Start at login&lt;/strong&gt; — toggle autostart on/off.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Quit&lt;/strong&gt; — stops the daemon cleanly; leaves the Windows pairing intact (device keeps its last reading).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Logs and troubleshooting&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;Get-Content $env:LOCALAPPDATA\Clawdmeter\daemon.log -Tail 30        # view logs
reg delete &quot;HKCU\Software\Microsoft\Windows\CurrentVersion\Run&quot; /v Clawdmeter /f   # remove autostart
&lt;/code&gt;&lt;/pre&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Symptom&lt;/th&gt; 
   &lt;th&gt;Fix&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;Device not found&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Power on the device; make sure it&#39;s in range and paired.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;token expired&lt;/code&gt; toast / &lt;code&gt;API HTTP 401&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Re-run &lt;code&gt;claude login&lt;/code&gt;, then restart the daemon.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;Connection failed&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Toggle Windows Bluetooth off/on in Settings.&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;code&gt;Warning: running under Linux/WSL&lt;/code&gt;&lt;/td&gt; 
   &lt;td&gt;Run from a native PowerShell window, not a WSL shell.&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h2&gt;How it works&lt;/h2&gt; 
&lt;img src=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/assets/readme/magnifier.gif&quot; width=&quot;150&quot; align=&quot;right&quot; alt=&quot;&quot; /&gt; 
&lt;ol&gt; 
 &lt;li&gt;The daemon reads your Claude Code OAuth token — from the macOS Keychain (service &lt;code&gt;Claude Code-credentials&lt;/code&gt;) on macOS, or from &lt;code&gt;~/.claude/.credentials.json&lt;/code&gt; on Linux (&lt;code&gt;%USERPROFILE%\.claude\.credentials.json&lt;/code&gt; on Windows).&lt;/li&gt; 
 &lt;li&gt;It makes a minimal API call to &lt;code&gt;api.anthropic.com/v1/messages&lt;/code&gt; — one token of Haiku, basically free.&lt;/li&gt; 
 &lt;li&gt;The usage numbers come straight out of the response headers (&lt;code&gt;anthropic-ratelimit-unified-5h-utilization&lt;/code&gt; and friends).&lt;/li&gt; 
 &lt;li&gt;The daemon connects to the ESP32 over BLE and writes a JSON payload to the GATT RX characteristic.&lt;/li&gt; 
 &lt;li&gt;The firmware parses it and updates the LVGL dashboard.&lt;/li&gt; 
 &lt;li&gt;The firmware also tracks the rate of change of session % over a 5-minute window and picks splash animations from the matching mood group.&lt;/li&gt; 
 &lt;li&gt;The two side buttons are independent of all of this — they send Space and Shift+Tab as BLE HID keyboard input to the paired host directly.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h2&gt;Physical buttons&lt;/h2&gt; 
&lt;p&gt;The board has three side buttons. Left and right send HID keys; the middle (PWR) button cycles splash animations and, held for 3 seconds, triggers pairing mode.&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Button&lt;/th&gt; 
   &lt;th&gt;GPIO&lt;/th&gt; 
   &lt;th&gt;Function&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Left&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;GPIO 0&lt;/td&gt; 
   &lt;td&gt;Hold to send Space (Claude Code voice-mode push-to-talk)&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Middle&lt;/strong&gt; (PWR)&lt;/td&gt; 
   &lt;td&gt;AXP2101 PKEY&lt;/td&gt; 
   &lt;td&gt;On splash: cycle animations. Hold 3s + release: pairing mode&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Right&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;GPIO 18&lt;/td&gt; 
   &lt;td&gt;Press to send Shift+Tab (Claude Code mode toggle)&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;Space and Shift+Tab go out as standard BLE HID keyboard reports, so they trigger in whatever window has focus on the paired host — not just Claude Code.&lt;/p&gt; 
&lt;h2&gt;BLE protocol&lt;/h2&gt; 
&lt;p&gt;The device advertises a custom GATT service alongside the standard HID keyboard service:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;&lt;/th&gt; 
   &lt;th&gt;UUID&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;Data Service&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;4c41555a-4465-7669-6365-000000000001&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;RX Characteristic (write)&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;4c41555a-4465-7669-6365-000000000002&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;TX Characteristic (notify)&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;4c41555a-4465-7669-6365-000000000003&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;strong&gt;HID Service&lt;/strong&gt;&lt;/td&gt; 
   &lt;td&gt;&lt;code&gt;00001812-0000-1000-8000-00805f9b34fb&lt;/code&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;JSON payload format (written to RX):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{ &quot;s&quot;: 45, &quot;sr&quot;: 120, &quot;w&quot;: 28, &quot;wr&quot;: 7200, &quot;st&quot;: &quot;allowed&quot;, &quot;ok&quot;: true }
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Fields: &lt;code&gt;s&lt;/code&gt; = session %, &lt;code&gt;sr&lt;/code&gt; = session reset (minutes), &lt;code&gt;w&lt;/code&gt; = weekly %, &lt;code&gt;wr&lt;/code&gt; = weekly reset (minutes), &lt;code&gt;st&lt;/code&gt; = status, &lt;code&gt;ok&lt;/code&gt; = success flag.&lt;/p&gt; 
&lt;h2&gt;Development&lt;/h2&gt; 
&lt;img src=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/assets/readme/crab.gif&quot; width=&quot;120&quot; align=&quot;right&quot; alt=&quot;&quot; /&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Desktop simulator&lt;/strong&gt; — iterate on the UI without hardware: an SDL2 window runs the full firmware loop with scenario playback (&lt;code&gt;pio run -d firmware -e sim&lt;/code&gt;, then &lt;code&gt;cd firmware &amp;amp;&amp;amp; .pio/build/sim/program&lt;/code&gt;). See &lt;a href=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/SIM-USAGE.md&quot;&gt;&lt;code&gt;SIM-USAGE.md&lt;/code&gt;&lt;/a&gt; for controls, scenarios, and headless screenshots.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Splash animations&lt;/strong&gt; — Anthropic&#39;s official Clawd sprites, archived with provenance notes in &lt;a href=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/research/clawd-official/&quot;&gt;&lt;code&gt;research/clawd-official/&lt;/code&gt;&lt;/a&gt;; &lt;code&gt;node tools/convert_official_clawd.js&lt;/code&gt; regenerates &lt;code&gt;firmware/src/splash_animations.h&lt;/code&gt;. See &lt;a href=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/tools/README.md&quot;&gt;&lt;code&gt;tools/README.md&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Icons&lt;/strong&gt; — Lucide PNGs convert to LVGL C arrays with &lt;code&gt;tools/png_to_lvgl.js&lt;/code&gt;. See &lt;a href=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/tools/README.md&quot;&gt;&lt;code&gt;tools/README.md&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Fonts&lt;/strong&gt; — the pre-compiled LVGL fonts and the LVGL-9 patching they need: &lt;a href=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/docs/fonts.md&quot;&gt;&lt;code&gt;docs/fonts.md&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Porting&lt;/strong&gt; — &lt;a href=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/docs/porting/adding-a-board.md&quot;&gt;&lt;code&gt;docs/porting/adding-a-board.md&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://raw.githubusercontent.com/HermannBjorgvin/Clawdmeter/main/docs/porting/hal-contract.md&quot;&gt;&lt;code&gt;docs/porting/hal-contract.md&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Credits&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Pixel-art Clawd animations are Anthropic&#39;s official mascot art (&lt;a href=&quot;http://claude.ai/code&quot;&gt;claude.ai/code&lt;/a&gt;, Claude Code desktop), archived and converted by the tooling in &lt;code&gt;tools/&lt;/code&gt; and &lt;code&gt;research/clawd-official/&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;Lucide icon set (&lt;a href=&quot;https://lucide.dev&quot;&gt;lucide.dev&lt;/a&gt;, MIT) for bluetooth and battery UI glyphs.&lt;/li&gt; 
 &lt;li&gt;Anthropic brand fonts (Tiempos Text, Styrene B) — see licensing warning below.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Licensing gray area warning&lt;/h2&gt; 
&lt;p&gt;The software in this repository uses and adheres to the Anthropic brand guidelines and uses the same proprietary fonts that Anthropic has a license for but this software uses without permission as well as using assets from Anthropic such as the copyrighted Clawd mascot so even though the code in this repo is non-proprietary I will not license it myself under a copyleft license since this repo includes proprietary fonts and copyrighted assets. Please be aware of this if you fork or copy the code from this repo. &lt;strong&gt;You have been warned!&lt;/strong&gt;&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>greatscottgadgets/hackrf</title>
      <link>https://github.com/greatscottgadgets/hackrf</link>
      <description>&lt;p&gt;low cost software radio platform&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;HackRF&lt;/h1&gt; 
&lt;p&gt;This repository contains hardware designs and software for HackRF, a low cost, open source Software Defined Radio platform.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://raw.github.com/mossmann/hackrf/master/docs/images/HackRF-One-fd0-0009.jpeg&quot; alt=&quot;HackRF One&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;(photo by fd0 from &lt;a href=&quot;https://github.com/fd0/hackrf-one-pictures&quot;&gt;https://github.com/fd0/hackrf-one-pictures&lt;/a&gt;)&lt;/p&gt; 
&lt;p&gt;principal author: Michael Ossmann &lt;a href=&quot;mailto:mike@ossmann.com&quot;&gt;mike@ossmann.com&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Information on HackRF and purchasing HackRF: &lt;a href=&quot;https://greatscottgadgets.com/hackrf/&quot;&gt;https://greatscottgadgets.com/hackrf/&lt;/a&gt;&lt;/p&gt; 
&lt;hr /&gt; 
&lt;h1&gt;Documentation&lt;/h1&gt; 
&lt;p&gt;Documentation for HackRF can be viewed on &lt;a href=&quot;https://hackrf.readthedocs.io/en/latest/&quot;&gt;Read the Docs&lt;/a&gt;. The raw documentation files for HackRF are in the &lt;a href=&quot;https://github.com/mossmann/hackrf/tree/master/docs&quot;&gt;docs folder&lt;/a&gt; in this repository and can be built locally by installing &lt;a href=&quot;https://www.sphinx-doc.org/en/master/usage/installation.html&quot;&gt;Sphinx Docs&lt;/a&gt; and running &lt;code&gt;make html&lt;/code&gt;. Documentation changes can be submitted through pull request and suggestions can be made as GitHub issues.&lt;/p&gt; 
&lt;p&gt;To create a PDF of the HackRF documentation from the HackRF repository while on Ubuntu:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;run &lt;code&gt;sudo apt install latexmk texlive-latex-extra&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;navigate to hackrf/docs on command line&lt;/li&gt; 
 &lt;li&gt;run the command &lt;code&gt;make latex&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;run the command &lt;code&gt;make latexpdf&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr /&gt; 
&lt;h1&gt;Getting Help&lt;/h1&gt; 
&lt;p&gt;Before asking for help with HackRF, check to see if your question is listed on the &lt;a href=&quot;https://hackrf.readthedocs.io/en/latest/troubleshooting.html&quot;&gt;troubleshooting page&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;For assistance with HackRF general use or development, please look at the &lt;a href=&quot;https://github.com/greatscottgadgets/hackrf/issues&quot;&gt;issues on the GitHub project&lt;/a&gt;. This is the preferred place to ask questions so that others may locate the answer to your question in the future.&lt;/p&gt; 
&lt;p&gt;We invite you to join our community discussions on &lt;a href=&quot;https://discord.gg/rsfMw3rsU8&quot;&gt;Discord&lt;/a&gt;. Note that while technical support requests are welcome here, we do not have support staff on duty at all times. Be sure to also submit an issue on GitHub if you&#39;ve found a bug or if you want to ensure that your request will be tracked and not overlooked.&lt;/p&gt; 
&lt;p&gt;If you wish to see past discussions and questions about HackRF, you may also view the &lt;a href=&quot;https://pairlist9.pair.net/pipermail/hackrf-dev/&quot;&gt;mailing list archives&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;GitHub issues on this repository that are labelled &quot;technical support&quot; by Great Scott Gadgets employees can expect a response time of two weeks. We currently do not have expected response times for other GitHub issues or pull requests for this repository.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>armel/uv-k1-k5v3-firmware-custom</title>
      <link>https://github.com/armel/uv-k1-k5v3-firmware-custom</link>
      <description>&lt;p&gt;This is a fork of F4HWN firmware https://github.com/armel/uv-k5-firmware-custom by @muzkr and @armel&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;Stats&lt;/h1&gt; 
&lt;p&gt;&lt;img src=&quot;https://repobeats.axiom.co/api/embed/ecdd86aa536b716f088339a0c5ee734558f78c28.svg?sanitize=true&quot; alt=&quot;Alt&quot; title=&quot;Repobeats analytics image&quot; /&gt;&lt;/p&gt; 
&lt;h1&gt;F4HWN firmware port for the UV-K1 and UV-K5 V3 using the PY32F071 MCU&lt;/h1&gt; 
&lt;p&gt;This repository is a fork of the &lt;a href=&quot;https://github.com/armel/uv-k5-firmware-custom&quot;&gt;F4HWN custom firmware&lt;/a&gt;, who was a fork of &lt;a href=&quot;https://github.com/egzumer/uv-k5-firmware-custom&quot;&gt;Egzumer custom firmware&lt;/a&gt;. It extends the work done for the UV-K5 V1, based on the DP32G030 MCU, and adapts it to the newer UV-K1 and UV-K5 V3 built around the PY32F071 MCU. It is the result of the joint work of &lt;a href=&quot;https://github.com/muzkr&quot;&gt;@muzkr&lt;/a&gt; and &lt;a href=&quot;https://github.com/armel&quot;&gt;@armel&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;A big thanks to DualTachyon, who paved the way by releasing the very first open-source &lt;a href=&quot;https://github.com/DualTachyon/uv-k5-firmware&quot;&gt;firmware&lt;/a&gt; for the UV-K5 V1. None of this would have been possible without that initial work !&lt;/p&gt; 
&lt;h1&gt;A note for developers who intend to fork this project&lt;/h1&gt; 
&lt;p&gt;This firmware is distributed under the Apache 2.0 License, carrying forward the original copyright of DualTachyon, whose work laid the foundation for the UV-K5 open-source ecosystem. If you create a fork or a derived version, &lt;strong&gt;we strongly encourage you to keep your work open source&lt;/strong&gt;.&lt;/p&gt; 
&lt;p&gt;Keeping your fork open:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;aligns with the intent and spirit of the Apache 2.0 License&lt;/li&gt; 
 &lt;li&gt;supports the amateur-radio and embedded-development community&lt;/li&gt; 
 &lt;li&gt;avoids unnecessary fragmentation&lt;/li&gt; 
 &lt;li&gt;allows others to study, audit and improve the firmware&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;It is also very much in line with the &lt;strong&gt;ham spirit&lt;/strong&gt;: sharing knowledge, experimenting together and helping each other, rather than closing things off or claiming them as your own.&lt;/p&gt; 
&lt;p&gt;Maintaining an open-source fork is the best way to help build a healthy and sustainable ecosystem for everyone.&lt;/p&gt; 
&lt;div class=&quot;markdown-alert markdown-alert-warning&quot;&gt;
 &lt;p class=&quot;markdown-alert-title&quot;&gt;
  &lt;svg class=&quot;octicon octicon-alert mr-2&quot; viewbox=&quot;0 0 16 16&quot; version=&quot;1.1&quot; width=&quot;16&quot; height=&quot;16&quot; aria-hidden=&quot;true&quot;&gt;
   &lt;path d=&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z&quot;&gt;&lt;/path&gt;
  &lt;/svg&gt;Warning&lt;/p&gt;
 &lt;p&gt;EN - THIS FIRMWARE HAS NO REAL BRAIN. PLEASE USE YOUR OWN. Use this firmware at your own risk (entirely). There is absolutely no guarantee that it will work in any way shape or form on your radio(s), it may even brick your radio(s), in which case, you&#39;d need to buy another radio. Anyway, have fun.&lt;/p&gt; 
 &lt;p&gt;&lt;em&gt;FR - CE FIRMWARE N&#39;A PAS DE VÉRITABLE CERVEAU. VEUILLEZ UTILISER LE VÔTRE. Utilisez ce firmware à vos risques et périls. Il n&#39;y a absolument aucune garantie qu&#39;il fonctionnera d&#39;une manière ou d&#39;une autre sur votre (vos) radio(s), il peut même bousiller votre (vos) radio(s), dans ce cas, vous devrez acheter une autre radio. Quoi qu&#39;il en soit, amusez-vous bien.&lt;/em&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
 &lt;p class=&quot;markdown-alert-title&quot;&gt;
  &lt;svg class=&quot;octicon octicon-info mr-2&quot; viewbox=&quot;0 0 16 16&quot; version=&quot;1.1&quot; width=&quot;16&quot; height=&quot;16&quot; aria-hidden=&quot;true&quot;&gt;
   &lt;path d=&quot;M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z&quot;&gt;&lt;/path&gt;
  &lt;/svg&gt;Note&lt;/p&gt;
 &lt;p&gt;EN - About CHIRP, as with many other firmwares, you need to use a dedicated driver. The matching CHIRP driver is now bundled with each release of this repository, so you can download the firmware and its driver together from the &lt;a href=&quot;https://github.com/armel/uv-k1-k5v3-firmware-custom/releases&quot;&gt;Releases page&lt;/a&gt;.&lt;/p&gt; 
 &lt;p&gt;&lt;em&gt;FR - A propos de CHIRP, comme pour beaucoup d&#39;autres firmwares, vous devez utiliser un pilote dédié. Le driver CHIRP correspondant est désormais fourni avec chaque release de ce dépôt, ce qui permet de récupérer ensemble le firmware et son pilote depuis la page des &lt;a href=&quot;https://github.com/armel/uv-k1-k5v3-firmware-custom/releases&quot;&gt;Releases&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;div class=&quot;markdown-alert markdown-alert-caution&quot;&gt;
 &lt;p class=&quot;markdown-alert-title&quot;&gt;
  &lt;svg class=&quot;octicon octicon-stop mr-2&quot; viewbox=&quot;0 0 16 16&quot; version=&quot;1.1&quot; width=&quot;16&quot; height=&quot;16&quot; aria-hidden=&quot;true&quot;&gt;
   &lt;path d=&quot;M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z&quot;&gt;&lt;/path&gt;
  &lt;/svg&gt;Caution&lt;/p&gt;
 &lt;p&gt;EN - I recommend backing up your calibration data with &lt;a href=&quot;https://armel.github.io/uvstudio/#dump-calib&quot;&gt;UV Studio&lt;/a&gt; immediately after flashing this firmware. It is a good habit to adopt.&lt;/p&gt; 
 &lt;p&gt;&lt;em&gt;FR - Je recommande de sauvegarder vos données de calibration avec &lt;a href=&quot;https://armel.github.io/uvstudio/#dump-calib&quot;&gt;UV Studio&lt;/a&gt; juste après avoir flashé ce firmware. C&#39;est un bon réflexe à adopter.&lt;/em&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;h1&gt;Donations&lt;/h1&gt; 
&lt;p&gt;Special thanks to Jean-Cyrille F6IWW (3 times), Fabrice 14RC123, David F4BPP, Olivier 14RC206, Frédéric F4ESO, Stéphane F5LGW (2 times), Jorge Ornelas (4 times), Laurent F4AXK, Christophe Morel, Clayton W0LED, Pierre Antoine F6FWB, Jean-Claude 14FRS3306, Thierry F4GVO, Eric F1NOU, PricelessToolkit, Ady M6NYJ, Tom McGovern (4 times), Joseph Roth, Pierre-Yves Colin, Frank DJ7FG, Marcel Testaz, Brian Frobisher, Yannick F4JFO, Paolo Bussola, Dirk DL8DF, Levente Szőke (2 times), Bernard-Michel Herrera, Jérôme Saintespes, Paul Davies, RS (3 times), Johan F4WAT, Robert Wörle, Rafael Sundorf, Paul Harker, Peter Fintl, Pascal F4ICR (2 times), Mike DL2MF (3 times), Eric KI1C / F4WFS (3 times), Phil G0ELM, Jérôme Lambert, Eliot Vedel, Alfonso EA7KDF, Jean-François F1EVM, Robert DC1RDB (2 times), Ian KE2CHJ, Daryl VK3AWA, Roberto Brunelli, Robert Boardman, Stephen Oliver, Nicolas F4INE, William Bruno, Daniel OK2VLK, Tayler Chew, Peter DL7RFP, Philippe Kopp, Rune LA6YMA, Jeremy Luna, Steef Wagenaar (2 times), Zhuo BG7SGA, Jamie M0JLB, Antoine LIBERT, Vince K0DKR, Julia DF7JA, Ken 2E0UMK, Victor TI2SYS, Tobi DG9LAY, Deaglan K4DFQ, Catherine PALMER, Brian WA6JFK, Stéphane Hintzy, Roger F1HCN, Marcin Kusaj, Flavio Cottarelli, Bob N1MLZ, Carlos EA1IJ, Brian M7YLF, Giuseppe IT9LLH and 邓 月 for their &lt;a href=&quot;https://www.paypal.com/paypalme/F4HWN&quot;&gt;donations&lt;/a&gt;. That’s so kind of them. Thanks so much 🙏🏻&lt;/p&gt; 
&lt;h2&gt;Table of Contents&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/armel/uv-k1-k5v3-firmware-custom/main/#main-features-and-improvements-from-f4hwn&quot;&gt;Main features and improvements from F4HWN&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/armel/uv-k1-k5v3-firmware-custom/main/#main-features-from-egzumer&quot;&gt;Main Features from Egzumer&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/armel/uv-k1-k5v3-firmware-custom/main/#manual&quot;&gt;Manual&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/armel/uv-k1-k5v3-firmware-custom/main/#compiling-and-Building-from-docker&quot;&gt;Compiling and Building from Docker&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/armel/uv-k1-k5v3-firmware-custom/main/#flashing-the-firmware-with-uv-studio&quot;&gt;Flashing the Firmware with UV Studio&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/armel/uv-k1-k5v3-firmware-custom/main/#credits&quot;&gt;Credits&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/armel/uv-k1-k5v3-firmware-custom/main/#other-sources-of-information&quot;&gt;Other sources of information&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/armel/uv-k1-k5v3-firmware-custom/main/#license&quot;&gt;License&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Main features and improvements from F4HWN&lt;/h2&gt; 
&lt;h3&gt;Fusion edition&lt;/h3&gt; 
&lt;p&gt;Fusion is the reference edition of the project. It provides an all-in-one firmware for the UV-K1 and UV-K5 V3, including:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Fagci&#39;s spectrum analyzer,&lt;/li&gt; 
 &lt;li&gt;broadcast FM radio,&lt;/li&gt; 
 &lt;li&gt;VOX and AirCopy,&lt;/li&gt; 
 &lt;li&gt;BEAM wireless channel transfer,&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://armel.github.io/uvstudio/&quot;&gt;UV Studio&lt;/a&gt; with integrated K5Viewer screen mirroring, screenshots and remote keyboard control,&lt;/li&gt; 
 &lt;li&gt;advanced RX audio profiles and Audio Scope,&lt;/li&gt; 
 &lt;li&gt;first-responder-oriented controls,&lt;/li&gt; 
 &lt;li&gt;the Breakout game,&lt;/li&gt; 
 &lt;li&gt;automatic RX/TX activity logging with RF Log,&lt;/li&gt; 
 &lt;li&gt;full Fox Hunt and Morse Beacon support.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Radio and signal handling&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Reworked output-power levels: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;Low 1&lt;/code&gt;: below approximately 20 mW,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;Low 2&lt;/code&gt;: approximately 125 mW,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;Low 3&lt;/code&gt;: approximately 250 mW,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;Low 4&lt;/code&gt;: approximately 500 mW,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;Low 5&lt;/code&gt;: approximately 1 W,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;Mid&lt;/code&gt;: approximately 2 W,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;High&lt;/code&gt;: approximately 5 W,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;User&lt;/code&gt;: configurable through &lt;code&gt;SetPwr&lt;/code&gt;.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;S-meter calibrated according to the &lt;a href=&quot;https://hamwaves.com/decibel/en/&quot;&gt;IARU Region 1 recommendation for VHF/UHF&lt;/a&gt;: 
  &lt;ul&gt; 
   &lt;li&gt;fixed S0 to S9+ values replace the former EEPROM S-meter thresholds,&lt;/li&gt; 
   &lt;li&gt;Classic and Tiny display styles are available.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Configurable 12.5 kHz or 6.25 kHz narrow-FM bandwidth.&lt;/li&gt; 
 &lt;li&gt;Per-channel TX lock.&lt;/li&gt; 
 &lt;li&gt;Adjustable RX audio volume.&lt;/li&gt; 
 &lt;li&gt;Advanced RX audio profiles for FM and AM reception.&lt;/li&gt; 
 &lt;li&gt;Regional frequency-lock profiles for amateur bands, PMR446, FRS, GMRS and MURS.&lt;/li&gt; 
 &lt;li&gt;Support for 1600, 2200 and 3500 mAh battery profiles.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Spectrum analyzer&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Channel names displayed in the spectrum view.&lt;/li&gt; 
 &lt;li&gt;Persistent spectrum settings.&lt;/li&gt; 
 &lt;li&gt;Faster and smoother spectrum rendering.&lt;/li&gt; 
 &lt;li&gt;Improved behavior when freezing the spectrum or disconnecting USB-C.&lt;/li&gt; 
 &lt;li&gt;Spectrum analyzer state can be restored automatically at startup.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Scanning&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Support for up to 24 named scan lists.&lt;/li&gt; 
 &lt;li&gt;Each memory channel can be assigned to: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;OFF&lt;/code&gt;,&lt;/li&gt; 
   &lt;li&gt;one scan list from &lt;code&gt;01&lt;/code&gt; to &lt;code&gt;24&lt;/code&gt;,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;ALL&lt;/code&gt;.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The &lt;code&gt;ALL&lt;/code&gt; list scans every channel except those assigned to &lt;code&gt;OFF&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;Automatic selection of the next valid list when the requested list is empty.&lt;/li&gt; 
 &lt;li&gt;Direct scan-list selection while scanning: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;00&lt;/code&gt; selects &lt;code&gt;ALL&lt;/code&gt;,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;01&lt;/code&gt; to &lt;code&gt;24&lt;/code&gt; select the corresponding list.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Long press on &lt;code&gt;MENU&lt;/code&gt; while scanning to exclude the current memory channel.&lt;/li&gt; 
 &lt;li&gt;Up to 64 frequency exclusions.&lt;/li&gt; 
 &lt;li&gt;Very fast scanning mode, reaching approximately 150 frequencies per second.&lt;/li&gt; 
 &lt;li&gt;Scan progress, RSSI and detected CTCSS/DCS information.&lt;/li&gt; 
 &lt;li&gt;Configurable scan resume behavior.&lt;/li&gt; 
 &lt;li&gt;Scan state can be restored automatically at startup.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;User interface&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Improved VFO screen with: 
  &lt;ul&gt; 
   &lt;li&gt;Classic and Tiny S-meter styles,&lt;/li&gt; 
   &lt;li&gt;Classic and Tiny frequency-information layouts,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;MAIN ONLY&lt;/code&gt;, &lt;code&gt;DUAL&lt;/code&gt; and &lt;code&gt;CROSS&lt;/code&gt; display modes,&lt;/li&gt; 
   &lt;li&gt;RX activity indication on the active VFO,&lt;/li&gt; 
   &lt;li&gt;optional RX LED blinking,&lt;/li&gt; 
   &lt;li&gt;squelch, monitor, step and CTCSS/DCS information,&lt;/li&gt; 
   &lt;li&gt;last-RX indication,&lt;/li&gt; 
   &lt;li&gt;RX and TX timers.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Improved status bar with updated fonts and icons.&lt;/li&gt; 
 &lt;li&gt;Menu index remains visible while editing an entry.&lt;/li&gt; 
 &lt;li&gt;Improved frequency and memory-channel input.&lt;/li&gt; 
 &lt;li&gt;Improved audio-level display.&lt;/li&gt; 
 &lt;li&gt;AirCopy progress percentage and gauge.&lt;/li&gt; 
 &lt;li&gt;Smooth backlight fading.&lt;/li&gt; 
 &lt;li&gt;Manual backlight controls for quickly switching between minimum and maximum brightness.&lt;/li&gt; 
 &lt;li&gt;Configurable contrast and inverted-display mode.&lt;/li&gt; 
 &lt;li&gt;Configurable navigation layout for the different radio models.&lt;/li&gt; 
 &lt;li&gt;Improved power-on message and optional startup logo.&lt;/li&gt; 
 &lt;li&gt;System-information pages for: 
  &lt;ul&gt; 
   &lt;li&gt;firmware version and build information,&lt;/li&gt; 
   &lt;li&gt;battery information,&lt;/li&gt; 
   &lt;li&gt;Flash and SRAM usage,&lt;/li&gt; 
   &lt;li&gt;project and documentation QR codes.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Audio and transmission controls&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Classic and OnePush PTT modes.&lt;/li&gt; 
 &lt;li&gt;Configurable timeout-timer alerts: 
  &lt;ul&gt; 
   &lt;li&gt;disabled,&lt;/li&gt; 
   &lt;li&gt;sound,&lt;/li&gt; 
   &lt;li&gt;visual,&lt;/li&gt; 
   &lt;li&gt;sound and visual.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Configurable end-of-transmission alerts using the same modes.&lt;/li&gt; 
 &lt;li&gt;Audio Scope during RX and TX.&lt;/li&gt; 
 &lt;li&gt;Improved Audio Scope behavior with OnePush PTT, DTMF and the 1750 Hz tone.&lt;/li&gt; 
 &lt;li&gt;Configurable automatic deep-sleep timeout.&lt;/li&gt; 
 &lt;li&gt;Quick actions for: 
  &lt;ul&gt; 
   &lt;li&gt;RX mode,&lt;/li&gt; 
   &lt;li&gt;main-VFO-only display,&lt;/li&gt; 
   &lt;li&gt;PTT,&lt;/li&gt; 
   &lt;li&gt;wide/narrow bandwidth,&lt;/li&gt; 
   &lt;li&gt;1750 Hz tone,&lt;/li&gt; 
   &lt;li&gt;mute,&lt;/li&gt; 
   &lt;li&gt;RX audio profile,&lt;/li&gt; 
   &lt;li&gt;maximum power,&lt;/li&gt; 
   &lt;li&gt;offset removal.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Fox Hunt and Beacon&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Dedicated Fox Hunt receiver with: 
  &lt;ul&gt; 
   &lt;li&gt;calibrated S-meter display,&lt;/li&gt; 
   &lt;li&gt;scrolling signal-history graph,&lt;/li&gt; 
   &lt;li&gt;peak, minimum and trend indicators,&lt;/li&gt; 
   &lt;li&gt;selectable RF attenuation,&lt;/li&gt; 
   &lt;li&gt;silent, Geiger-style and received-audio modes,&lt;/li&gt; 
   &lt;li&gt;long-press &lt;code&gt;F&lt;/code&gt; keypad lock (attenuation stays adjustable with the arrow keys).&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Integrated Morse Beacon transmitter with: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;MOE&lt;/code&gt;, &lt;code&gt;MOI&lt;/code&gt;, &lt;code&gt;MOS&lt;/code&gt;, &lt;code&gt;MOH&lt;/code&gt;, &lt;code&gt;MO5&lt;/code&gt; and &lt;code&gt;MO&lt;/code&gt; identifiers,&lt;/li&gt; 
   &lt;li&gt;optional callsign identification,&lt;/li&gt; 
   &lt;li&gt;configurable TX and idle periods,&lt;/li&gt; 
   &lt;li&gt;live TX and idle countdowns,&lt;/li&gt; 
   &lt;li&gt;persisted Beacon settings,&lt;/li&gt; 
   &lt;li&gt;interactive control during transmission,&lt;/li&gt; 
   &lt;li&gt;shared long-press &lt;code&gt;F&lt;/code&gt; keypad lock,&lt;/li&gt; 
   &lt;li&gt;TX-lock, modulation and battery-safety checks.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fox Hunt and Beacon screens are mirrored to UV Studio&#39;s integrated K5Viewer.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;RF Log&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Automatic logging of RX and TX activity when RF Log is enabled.&lt;/li&gt; 
 &lt;li&gt;Logs stored in the radio&#39;s external Flash memory.&lt;/li&gt; 
 &lt;li&gt;Recorded information includes: 
  &lt;ul&gt; 
   &lt;li&gt;RX or TX direction,&lt;/li&gt; 
   &lt;li&gt;frequency and channel,&lt;/li&gt; 
   &lt;li&gt;channel name,&lt;/li&gt; 
   &lt;li&gt;activity duration,&lt;/li&gt; 
   &lt;li&gt;S-meter level,&lt;/li&gt; 
   &lt;li&gt;battery voltage.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;On-radio history with RX/TX filtering and detailed views.&lt;/li&gt; 
 &lt;li&gt;Live RF Log dashboard and history access through UV Studio.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Connectivity and data transfer&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Live screen streaming to &lt;a href=&quot;https://armel.github.io/uvstudio/&quot;&gt;UV Studio&lt;/a&gt; over a USB serial connection.&lt;/li&gt; 
 &lt;li&gt;Screenshot capture and download.&lt;/li&gt; 
 &lt;li&gt;Remote keyboard control through the integrated K5Viewer.&lt;/li&gt; 
 &lt;li&gt;Automatic reconnection after a USB disconnect.&lt;/li&gt; 
 &lt;li&gt;RF Log monitoring, analytics and CSV export.&lt;/li&gt; 
 &lt;li&gt;Firmware flashing, calibration backup and restore, and boot-logo management from the same interface.&lt;/li&gt; 
 &lt;li&gt;BEAM transfer of complete channel settings between compatible radios.&lt;/li&gt; 
 &lt;li&gt;Improved AirCopy interface and progress reporting.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Settings and controls&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;New or extended menu entries: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;SetPwr&lt;/code&gt;: configurable User output power,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetPTT&lt;/code&gt;: Classic or OnePush PTT,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetTOT&lt;/code&gt;: timeout-timer alert,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetEOT&lt;/code&gt;: end-of-transmission alert,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetCtr&lt;/code&gt;: display contrast,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetInv&lt;/code&gt;: inverted display,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetLck&lt;/code&gt;: keypad or keypad-and-PTT lock,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetMet&lt;/code&gt;: S-meter style,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetGUI&lt;/code&gt;: VFO information style,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetRxA&lt;/code&gt;: RX audio profile,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetTmr&lt;/code&gt;: RX and TX timers,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetOff&lt;/code&gt;: automatic deep-sleep delay,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetNFM&lt;/code&gt;: narrow-FM bandwidth,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetVol&lt;/code&gt;: RX audio volume,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetScn&lt;/code&gt;: scan mode,&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;SetNav&lt;/code&gt;: radio-specific navigation layout.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Improved &lt;code&gt;PonMsg&lt;/code&gt;, &lt;code&gt;BackLt&lt;/code&gt;, &lt;code&gt;TxTOut&lt;/code&gt;, &lt;code&gt;ScnRev&lt;/code&gt; and &lt;code&gt;KeyLck&lt;/code&gt; menus.&lt;/li&gt; 
 &lt;li&gt;Full VFO state restoration with a long press on &lt;code&gt;EXIT&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;Squelch changes made with &lt;code&gt;F + UP&lt;/code&gt; or &lt;code&gt;F + DOWN&lt;/code&gt; are persisted.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Keyboard shortcuts and assignable actions&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;F + UP&lt;/code&gt; or &lt;code&gt;F + DOWN&lt;/code&gt;: adjust the squelch level.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;F + F1&lt;/code&gt; or &lt;code&gt;F + F2&lt;/code&gt;: adjust the frequency step.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;F + 8&lt;/code&gt;: temporarily switch the backlight between minimum and maximum brightness.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;F + 9&lt;/code&gt;: return to the configured backlight strategy.&lt;/li&gt; 
 &lt;li&gt;Configurable short- and long-press actions include: 
  &lt;ul&gt; 
   &lt;li&gt;RX mode,&lt;/li&gt; 
   &lt;li&gt;main-VFO-only display,&lt;/li&gt; 
   &lt;li&gt;virtual PTT,&lt;/li&gt; 
   &lt;li&gt;wide/narrow bandwidth,&lt;/li&gt; 
   &lt;li&gt;1750 Hz tone,&lt;/li&gt; 
   &lt;li&gt;mute,&lt;/li&gt; 
   &lt;li&gt;RX audio profile,&lt;/li&gt; 
   &lt;li&gt;maximum power,&lt;/li&gt; 
   &lt;li&gt;offset removal,&lt;/li&gt; 
   &lt;li&gt;BEAM,&lt;/li&gt; 
   &lt;li&gt;RF Log,&lt;/li&gt; 
   &lt;li&gt;Fox Hunt / Beacon.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Reliability and optimization&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Improved squelch and S-meter behavior.&lt;/li&gt; 
 &lt;li&gt;Fixed DTMF overlay issues.&lt;/li&gt; 
 &lt;li&gt;Fixed scan-range limits.&lt;/li&gt; 
 &lt;li&gt;Cleaner startup display.&lt;/li&gt; 
 &lt;li&gt;Removed PWM-related audio noise.&lt;/li&gt; 
 &lt;li&gt;Improved serial and K5Viewer key handling.&lt;/li&gt; 
 &lt;li&gt;Improved VFO persistence and restoration.&lt;/li&gt; 
 &lt;li&gt;Extensive code refactoring and memory optimization.&lt;/li&gt; 
 &lt;li&gt;DTMF calling and the scrambler remain disabled in Fusion.&lt;/li&gt; 
 &lt;li&gt;Legacy AM Fix code is not used by this firmware.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Main features from Egzumer:&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;many of OneOfEleven mods: 
  &lt;ul&gt; 
   &lt;li&gt;AM fix, huge improvement in reception quality&lt;/li&gt; 
   &lt;li&gt;long press buttons functions replicating F+ action&lt;/li&gt; 
   &lt;li&gt;fast scanning&lt;/li&gt; 
   &lt;li&gt;channel name editing in the menu&lt;/li&gt; 
   &lt;li&gt;channel name + frequency display option&lt;/li&gt; 
   &lt;li&gt;shortcut for scan-list assignment (long press &lt;code&gt;5 NOAA&lt;/code&gt;)&lt;/li&gt; 
   &lt;li&gt;scan-list toggle (long press &lt;code&gt;* Scan&lt;/code&gt; while scanning)&lt;/li&gt; 
   &lt;li&gt;configurable button function selectable from menu&lt;/li&gt; 
   &lt;li&gt;battery percentage/voltage on status bar, selectable from menu&lt;/li&gt; 
   &lt;li&gt;longer backlight times&lt;/li&gt; 
   &lt;li&gt;mic bar&lt;/li&gt; 
   &lt;li&gt;RSSI s-meter&lt;/li&gt; 
   &lt;li&gt;more frequency steps&lt;/li&gt; 
   &lt;li&gt;squelch more sensitive&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;fagci spectrum analyzer (&lt;strong&gt;F+5&lt;/strong&gt; to turn on)&lt;/li&gt; 
 &lt;li&gt;some other mods introduced by me: 
  &lt;ul&gt; 
   &lt;li&gt;SSB demodulation (adopted from fagci)&lt;/li&gt; 
   &lt;li&gt;backlight dimming&lt;/li&gt; 
   &lt;li&gt;battery voltage calibration from menu&lt;/li&gt; 
   &lt;li&gt;better battery percentage calculation, selectable for 1600mAh or 2200mAh&lt;/li&gt; 
   &lt;li&gt;more configurable button functions&lt;/li&gt; 
   &lt;li&gt;long press MENU as another configurable button&lt;/li&gt; 
   &lt;li&gt;better DCS/CTCSS scanning in the menu (&lt;code&gt;* SCAN&lt;/code&gt; while in RX DCS/CTCSS menu item)&lt;/li&gt; 
   &lt;li&gt;Piotr022 style s-meter&lt;/li&gt; 
   &lt;li&gt;restore initial freq/channel when scanning stopped with EXIT, remember last found transmission with MENU button&lt;/li&gt; 
   &lt;li&gt;reordered and renamed menu entries&lt;/li&gt; 
   &lt;li&gt;LCD interference crash fix&lt;/li&gt; 
   &lt;li&gt;many others...&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Manual&lt;/h2&gt; 
&lt;p&gt;Up to date manual is available in the &lt;a href=&quot;https://github.com/armel/uv-k1-k5v3-firmware-custom/wiki&quot;&gt;Wiki section&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Radio performance&lt;/h2&gt; 
&lt;p&gt;Please note that the Quansheng UV-Kx radios are not professional quality transceivers, their performance is strictly limited. The RX front end has no track-tuned band pass filtering at all, and so are wide band/wide open to any and all signals over a large frequency range.&lt;/p&gt; 
&lt;p&gt;Using the radio in high intensity RF environments will most likely make reception difficult, especially in AM mode. The receiver simply does not have a great dynamic range, so stronger signals can easily cause distortion, desensitization and poor AM audio. This is fundamentally a hardware limitation: firmware can improve behavior at the margins, but it cannot overcome the front-end design of the radio. In practice, AM reception will degrade first and most severely, while FM reception is generally more tolerant and should remain more usable.&lt;/p&gt; 
&lt;p&gt;But, they are nice toys for the price, fun to play with.&lt;/p&gt; 
&lt;h2&gt;Compiling and Building from Docker&lt;/h2&gt; 
&lt;p&gt;This project provides a Docker-based build system to compile the Fusion firmware for the UV-K1 and UV-K5 V3. Everything is handled through the &lt;code&gt;compile-with-docker.sh&lt;/code&gt; helper script.&lt;/p&gt; 
&lt;p&gt;The documented build output is generated inside &lt;code&gt;build/Fusion&lt;/code&gt;, using the CMake presets defined in &lt;code&gt;CMakePresets.json&lt;/code&gt;.&lt;/p&gt; 
&lt;h3&gt;Prerequisites&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Docker installed on your system&lt;/li&gt; 
 &lt;li&gt;Bash environment (Linux, macOS, WSL, Git Bash on Windows)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Build Script Overview&lt;/h3&gt; 
&lt;p&gt;The script &lt;code&gt;compile-with-docker.sh&lt;/code&gt; performs the following actions:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Builds the Docker image (&lt;code&gt;uvk1-uvk5v3&lt;/code&gt;) if it does not already exist.&lt;/li&gt; 
 &lt;li&gt;Removes any previous &lt;code&gt;build&lt;/code&gt; directory to ensure a clean configuration.&lt;/li&gt; 
 &lt;li&gt;Runs CMake using the &lt;code&gt;Fusion&lt;/code&gt; preset inside the Docker container.&lt;/li&gt; 
 &lt;li&gt;Builds the firmware and outputs &lt;code&gt;.elf&lt;/code&gt;, &lt;code&gt;.bin&lt;/code&gt; and &lt;code&gt;.hex&lt;/code&gt; files.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h3&gt;Usage&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./compile-with-docker.sh Fusion [extra CMake options]
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Documented Preset&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Fusion&lt;/strong&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Examples&lt;/h3&gt; 
&lt;p&gt;Build Fusion:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./compile-with-docker.sh Fusion
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Passing Additional CMake Options&lt;/h3&gt; 
&lt;p&gt;You can pass extra configuration options after the preset name.&lt;br /&gt; These are forwarded directly to &lt;code&gt;cmake --preset&lt;/code&gt; inside the container.&lt;/p&gt; 
&lt;p&gt;Examples:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./compile-with-docker.sh Fusion -DENABLE_SPECTRUM=ON
./compile-with-docker.sh Fusion -DENABLE_FEAT_F4HWN_GAME=ON -DENABLE_NOAA=ON
./compile-with-docker.sh Fusion -DSQL_TONE=600
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To prepare the rolling development firmware:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./compile-with-docker.sh Fusion -DDEV=ON
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This keeps the regular build output in &lt;code&gt;build/Fusion&lt;/code&gt; and also updates &lt;code&gt;archive/f4hwn.fusion.development.bin&lt;/code&gt;. The development build is identified as &lt;code&gt;DEV&lt;/code&gt; in the firmware information screen. Publishing the updated archive file remains an explicit Git operation.&lt;/p&gt; 
&lt;h3&gt;Notes&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;The first run may take a few minutes while Docker builds the base image.&lt;/li&gt; 
 &lt;li&gt;Each build runs inside Docker, so your host environment remains clean.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Flashing the Firmware with UV Studio&lt;/h2&gt; 
&lt;p&gt;You can flash the UV-K5 V3 and UV-K1 directly from your web browser using the Web Serial-based &lt;a href=&quot;https://armel.github.io/uvstudio/&quot;&gt;UV Studio&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;UV Studio combines firmware flashing, calibration maintenance, boot-logo management, K5Viewer and RF Log in a single interface. It requires no application installation, server or account. Use a desktop browser with Web Serial support, such as Chrome, Brave, Edge, Opera or Firefox 151+.&lt;/p&gt; 
&lt;h2&gt;Steps to flash the firmware&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Open the &lt;a href=&quot;https://armel.github.io/uvstudio/#flash&quot;&gt;Flash Firmware&lt;/a&gt; view in UV Studio.&lt;/li&gt; 
 &lt;li&gt;Connect your radio to your computer using a compatible USB programming cable (USB-C or Baofeng/Kenwood like double jack USB cable).&lt;/li&gt; 
 &lt;li&gt;Make sure your radio is in &lt;strong&gt;DFU mode (flash mode)&lt;/strong&gt;.&lt;/li&gt; 
 &lt;li&gt;Select an official F4HWN Fusion release from the catalog or load a local &lt;code&gt;.bin&lt;/code&gt; firmware file.&lt;/li&gt; 
 &lt;li&gt;Click on &lt;code&gt;Flash Firmware&lt;/code&gt;, then select the serial port associated with your radio.&lt;/li&gt; 
 &lt;li&gt;The progress bar will guide you through the flashing steps.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Once finished, your radio restarts with the new firmware.&lt;/p&gt; 
&lt;h2&gt;Steps to dump or restore calibration data&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://armel.github.io/uvstudio/&quot;&gt;UV Studio&lt;/a&gt; can also dump and restore calibration data, which is highly recommended. It is best to create a dump immediately after installing the F4HWN firmware, and to restore it before installing another firmware or returning to the stock firmware.&lt;/p&gt; 
&lt;h3&gt;Dump&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Open the &lt;a href=&quot;https://armel.github.io/uvstudio/#dump-calib&quot;&gt;Dump Calibration&lt;/a&gt; view in UV Studio.&lt;/li&gt; 
 &lt;li&gt;Power on your radio in &lt;strong&gt;normal mode&lt;/strong&gt;.&lt;/li&gt; 
 &lt;li&gt;Click &lt;code&gt;Dump Calibration Data&lt;/code&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;When the process is complete, click &lt;code&gt;Download calibration.dat&lt;/code&gt; to save the file to your computer.&lt;/p&gt; 
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
 &lt;p class=&quot;markdown-alert-title&quot;&gt;
  &lt;svg class=&quot;octicon octicon-info mr-2&quot; viewbox=&quot;0 0 16 16&quot; version=&quot;1.1&quot; width=&quot;16&quot; height=&quot;16&quot; aria-hidden=&quot;true&quot;&gt;
   &lt;path d=&quot;M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z&quot;&gt;&lt;/path&gt;
  &lt;/svg&gt;Note&lt;/p&gt;
 &lt;p&gt;A good practice is to rename your calibration file using the serial number of your radio, which you can find on the label on the back of the device once you remove the battery. This helps avoid mixing up calibration files when you own multiple units.&lt;/p&gt; 
&lt;/div&gt; 
&lt;h3&gt;Restore&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Open the &lt;a href=&quot;https://armel.github.io/uvstudio/#restore-calib&quot;&gt;Restore Calibration&lt;/a&gt; view in UV Studio.&lt;/li&gt; 
 &lt;li&gt;Power on your radio in &lt;strong&gt;normal mode&lt;/strong&gt;.&lt;/li&gt; 
 &lt;li&gt;Select your &lt;code&gt;calibration.dat&lt;/code&gt; file on your computer.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Click &lt;code&gt;Restore Calibration Data&lt;/code&gt; and wait until the process fully completes.&lt;/p&gt; 
&lt;h2&gt;Other sources of information&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/armel/k1-teardown&quot;&gt;k1-teardown&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Credits&lt;/h2&gt; 
&lt;p&gt;Many thanks to various people:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/muzkr&quot;&gt;Muzkr&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mrkusypl&quot;&gt;Mrkusypl&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Tunas1337&quot;&gt;Andrej&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/egzumer&quot;&gt;Egzumer&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/OneOfEleven&quot;&gt;OneOfEleven&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/DualTachyon&quot;&gt;DualTachyon&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/fagci&quot;&gt;Mikhail&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/manujedi&quot;&gt;Manuel&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;@wagner&lt;/li&gt; 
 &lt;li&gt;@Lohtse Shar&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/spm81&quot;&gt;@Matoz&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;@Davide&lt;/li&gt; 
 &lt;li&gt;@Ismo OH2FTG&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/OneOfEleven&quot;&gt;OneOfEleven&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;@d1ced95&lt;/li&gt; 
 &lt;li&gt;and others I forget&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;License&lt;/h2&gt; 
&lt;p&gt;Copyright 2023 Dual Tachyon &lt;a href=&quot;https://github.com/DualTachyon&quot;&gt;https://github.com/DualTachyon&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;); you may not use this file except in compliance with the License. You may obtain a copy of the License at&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
&lt;/code&gt;&lt;/pre&gt;</description>
      
    </item>
    
    <item>
      <title>RfidResearchGroup/proxmark3</title>
      <link>https://github.com/RfidResearchGroup/proxmark3</link>
      <description>&lt;p&gt;Iceman Fork - Proxmark3&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;Iceman Fork - Proxmark3&lt;/h1&gt; 
&lt;p&gt;The Proxmark3 is the swiss-army tool of RFID, allowing for interactions with the vast majority of RFID tags on a global scale. Originally built by Jonathan Westhues, the device is now the goto tool for RFID Analysis for the enthusiast. Iceman repository is considered to be the pinnacle of features and functionality, enabling a huge range of extremely useful and convenient commands and LUA scripts to automate chip identification, penetration testing, and programming&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;Latest Release&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;Coverity&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;Contributors&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/RfidResearchGroup/proxmark3/releases/latest&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/v/release/rfidresearchgroup/proxmark3&quot; alt=&quot;Latest release&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo&quot;&gt;&lt;img src=&quot;https://scan.coverity.com/projects/19334/badge.svg?sanitize=true&quot; alt=&quot;Coverity Status&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/contributors/rfidresearchgroup/proxmark3&quot; alt=&quot;GitHub contributors&quot; /&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;Actions OSX CI&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;Actions Ubuntu CI&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;Actions Windows CI&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/RfidResearchGroup/proxmark3/actions/workflows/macos.yml&quot;&gt;&lt;img src=&quot;https://github.com/RfidResearchGroup/proxmark3/actions/workflows/macos.yml/badge.svg?branch=master&quot; alt=&quot;MacOS Build and Test&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/RfidResearchGroup/proxmark3/actions/workflows/ubuntu.yml&quot;&gt;&lt;img src=&quot;https://github.com/RfidResearchGroup/proxmark3/actions/workflows/ubuntu.yml/badge.svg?branch=master&quot; alt=&quot;Ubuntu Build and Test&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/RfidResearchGroup/proxmark3/actions/workflows/windows.yml&quot;&gt;&lt;img src=&quot;https://github.com/RfidResearchGroup/proxmark3/actions/workflows/windows.yml/badge.svg?branch=master&quot; alt=&quot;Windows Build and Test&quot; /&gt;&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h1&gt;Table of Contents&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#iceman-fork---proxmark3&quot;&gt;Iceman Fork - Proxmark3&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#table-of-contents&quot;&gt;Table of Contents&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#proxmark3-installation-and-overview&quot;&gt;PROXMARK3 INSTALLATION AND OVERVIEW&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#notes--helpful-documents&quot;&gt;Notes / helpful documents&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#how-to-build&quot;&gt;How to build?&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#proxmark3-rdv4&quot;&gt;Proxmark3 RDV4&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#generic-proxmark3-platforms&quot;&gt;Generic Proxmark3 platforms&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#what-has-changed&quot;&gt;What has changed?&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#development&quot;&gt;Development&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#supported-operating-systems&quot;&gt;Supported operating systems&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#precompiled-binaries&quot;&gt;Precompiled binaries&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#proxmark3-gui&quot;&gt;Proxmark3 GUI&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#official-channels&quot;&gt;Official channels&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#maintainers&quot;&gt;Maintainers&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#citation&quot;&gt;Citation&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/#copyright-and-licensing-terms&quot;&gt;Copyright and licensing terms&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;PROXMARK3 INSTALLATION AND OVERVIEW&lt;/h1&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;Installation&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;Use of the Proxmark3&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Installation_Instructions/Linux-Installation-Instructions.md&quot;&gt;Linux - Setup and Build&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md&quot;&gt;Compilation Instructions&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md&quot;&gt;Linux - Important notes on ModemManager&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Use_of_Proxmark/1_Validation.md&quot;&gt;Validating Proxmark3 Client Functionality&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Installation_Instructions/macOS-Homebrew-Installation-Instructions.md&quot;&gt;macOS - Homebrew &amp;amp; Upgrading HomeBrew Tap Formula&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md&quot;&gt;First Use and Verification&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Installation_Instructions/macOS-MacPorts-Installation-Instructions.md&quot;&gt;macOS - MacPorts&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Use_of_Proxmark/3_Commands-and-Features.md&quot;&gt;Commands &amp;amp; Features&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Installation_Instructions/macOS-Compile-From-Source-Instructions.md&quot;&gt;macOS - Setup and Build&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/standalone/&quot;&gt;Standalone Modes&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Installation_Instructions/Windows-Installation-Instructions.md&quot;&gt;Windows - Setup and Build&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/termux_notes.md&quot;&gt;Termux / Android - Setup and Build&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Installation_Instructions/iOS-Installation-Instructions.md&quot;&gt;iOS - Setup and Build&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/bt_manual_v10.md&quot;&gt;Blue Shark Manual&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/cheatsheet.md&quot;&gt;Command Cheat Sheet&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md&quot;&gt;Advanced Compilation Parameters&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets&quot;&gt;More Cheat Sheets&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Installation_Instructions/Troubleshooting.md&quot;&gt;Troubleshooting&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/commands.md&quot;&gt;Complete Client Command Set&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/jtag_notes.md&quot;&gt;JTAG&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/T5577_Guide.md&quot;&gt;T5577 Introduction Guide&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h2&gt;Notes / helpful documents&lt;/h2&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt; 
   &lt;th&gt;Notes&lt;/th&gt; 
   &lt;th style=&quot;text-align:center&quot;&gt;&lt;/th&gt; 
   &lt;th style=&quot;text-align:right&quot;&gt;&lt;/th&gt; 
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/uart_notes.md&quot;&gt;Notes on UART&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/termux_notes.md&quot;&gt;Notes on Termux / Android&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:right&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/path_notes.md&quot;&gt;Notes on paths&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/new_frame_format.md&quot;&gt;Notes on frame format&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/trace_notes.md&quot;&gt;Notes on tracelog / wireshark&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:right&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/emv_notes.md&quot;&gt;Notes on EMV&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/ext_flash_notes.md&quot;&gt;Notes on external flash&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/loclass_notes.md&quot;&gt;Notes on loclass&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:right&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Development/Coverity-Scan-Config-and-Run.md&quot;&gt;Notes on Coverity Scan Config &amp;amp; Run&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/extensions_notes.md&quot;&gt;Notes on file formats used with Proxmark3&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/mfu_binary_format_notes.md&quot;&gt;Notes on MFU binary format&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:right&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/fpga_arm_notes.md&quot;&gt;Notes on FPGA &amp;amp; ARM&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/armsrc/Standalone/readme.md&quot;&gt;Developing standalone mode&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode&quot;&gt;Wiki about standalone mode&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:right&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/magic_cards_notes.md&quot;&gt;Notes on Magic UID cards&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/colors_notes.md&quot;&gt;Notes on Color usage&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Development/Makefile-vs-CMake.md&quot;&gt;Makefile vs CMake&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:right&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/cloner_notes.md&quot;&gt;Notes on Cloner guns&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/cliparser.md&quot;&gt;Notes on cliparser usage&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/clocks.md&quot;&gt;Notes on clocks&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:right&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/desfire.md&quot;&gt;Notes on MIFARE DESFire&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/cipurse.md&quot;&gt;Notes on CIPURSE&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:center&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/ndef_type4a.md&quot;&gt;Notes on NDEF type4a&lt;/a&gt;&lt;/td&gt; 
   &lt;td style=&quot;text-align:right&quot;&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/unofficial_desfire_bible.md&quot;&gt;Unofficial MIFARE DESFire bible&lt;/a&gt;&lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h1&gt;How to build?&lt;/h1&gt; 
&lt;h2&gt;Proxmark3 RDV4&lt;/h2&gt; 
&lt;p&gt;See the instruction links in the tables above to build, flash and run for your Proxmark3 RDV4 device.&lt;/p&gt; 
&lt;h2&gt;Generic Proxmark3 platforms&lt;/h2&gt; 
&lt;p&gt;In order to build this repo for generic Proxmark3 platforms we urge you to read &lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md&quot;&gt;Advanced compilation parameters&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;We define generic Proxmark3 platforms as following devices.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Supported&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;RDV1, RDV2, RDV3 easy&lt;/li&gt; 
 &lt;li&gt;Ryscorp green PCB version&lt;/li&gt; 
 &lt;li&gt;Radiowar black PCB version&lt;/li&gt; 
 &lt;li&gt;numerous Chinese adapted versions of the RDV3 easy (kkmoon, PiSwords etc)&lt;/li&gt; 
 &lt;li&gt;Proxmark3 SE (Special Edition) (BLE enabled)&lt;/li&gt; 
 &lt;li&gt;Proxmark3 X 
  &lt;ul&gt; 
   &lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: Community tested&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: unknown device hw&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Not supported&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;⚠ Proxmark Evolution (EVO) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: unknown pin assignments.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;⚠ Ryscorp Proxmark3 Pro 
  &lt;ul&gt; 
   &lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: device has different fpga and unknown pin assignments.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: Company have disappeared, leaving their customers in the dark.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Experimental support&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;⚠ iCopy-X 
  &lt;ul&gt; 
   &lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: currently incompatible with iCopy-X GUI as Proxmark client commands using different syntax&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: see also &lt;a href=&quot;https://github.com/iCopy-X-Community/&quot;&gt;icopyx-community repos&lt;/a&gt; for upstream sources, reversed hw etc.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: Uses DRM to lock down tags, ignores the open source licences. Use on your own risk.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;⚠ Proxmark3 Ultimate 
  &lt;ul&gt; 
   &lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: unknown device hw&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: FPGA images is building for it. Use on your own risk.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Unknown support status&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;⚠ VX 
  &lt;ul&gt; 
   &lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: unknown device hw&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;When it comes to these new unknown models we are depending on the community to report in if this repo works and what they did to make it work.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;256KB flash memory size of generic Proxmark3 platforms&lt;/strong&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;⚠ &lt;strong&gt;Note&lt;/strong&gt;: You need to keep a eye on how large your ARM chip built-in flash memory is. With 512KB you are fine but if its 256KB you need to compile this repo with even less functionality. When running the &lt;code&gt;./pm3-flash-all&lt;/code&gt; you can see which size your device have if you have the bootloader from this repo installed. Otherwise you will find the size reported in the start message when running the Proxmark3 client &lt;code&gt;./pm3&lt;/code&gt;.&lt;/p&gt; 
 &lt;p&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md#256KB-versions&quot;&gt;OBS! Read the 256KB flash memory advisory&lt;/a&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h1&gt;What has changed?&lt;/h1&gt; 
&lt;p&gt;Proxmark3 RDV4 hardware modifications:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;added flash memory 256KB&lt;/li&gt; 
 &lt;li&gt;added smart card module&lt;/li&gt; 
 &lt;li&gt;added FPC connector for peripherals such as Bluetooth+battery addon&lt;/li&gt; 
 &lt;li&gt;improved antennas 
  &lt;ul&gt; 
   &lt;li&gt;swappable&lt;/li&gt; 
   &lt;li&gt;LF Q factor switch&lt;/li&gt; 
   &lt;li&gt;LF 125/134 frequency switch&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;tiny PCB form factor&lt;/li&gt; 
 &lt;li&gt;ABS case&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;This repo vs official Proxmark3 repo:&lt;/p&gt; 
&lt;p&gt;See the &lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/CHANGELOG.md&quot;&gt;Changelog file&lt;/a&gt; which we try to keep updated.&lt;/p&gt; 
&lt;p&gt;In short this repo gives you a completely different user experience when it comes to Proxmark3.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Supports command tab complete&lt;/li&gt; 
 &lt;li&gt;Richer CLI with use of colors / emojis&lt;/li&gt; 
 &lt;li&gt;Help text system implemented everywhere&lt;/li&gt; 
 &lt;li&gt;Hints system&lt;/li&gt; 
 &lt;li&gt;User preference settings&lt;/li&gt; 
 &lt;li&gt;Extensive testing with continuous integration build systems on Linux, OSX and Windows, and regular usage of static analysis tools like 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo/&quot;&gt;Coverity Scan&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Cppcheck (v2.6)&lt;/li&gt; 
   &lt;li&gt;GCC and Clang aggressive enforcement of diagnostic flags&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Auto detection of serial ports and seamless integration with Bluetooth addon&lt;/li&gt; 
 &lt;li&gt;Reconnect to device from inside client&lt;/li&gt; 
 &lt;li&gt;Supports tearoff attacks&lt;/li&gt; 
 &lt;li&gt;Supports NFC NDEF type1, type2, type4a, type4b, mifare, barcode&lt;/li&gt; 
 &lt;li&gt;Supports pm3 client scripts, lua scripts, python scripts&lt;/li&gt; 
 &lt;li&gt;Most comprehensive collection of scripts available&lt;/li&gt; 
 &lt;li&gt;Wiegand encoding, decoding.&lt;/li&gt; 
 &lt;li&gt;Supports EMV&lt;/li&gt; 
 &lt;li&gt;Supports CIPURSE&lt;/li&gt; 
 &lt;li&gt;Most standalone modes available with easy compilation&lt;/li&gt; 
 &lt;li&gt;Extensive test script for client and external tools&lt;/li&gt; 
 &lt;li&gt;Most comprehensive compiled known keys dictionaries&lt;/li&gt; 
 &lt;li&gt;Slimed down usb communications with NG-frames&lt;/li&gt; 
 &lt;li&gt;The most compiled public known key recovery software&lt;/li&gt; 
 &lt;li&gt;The fastest implementations of said software&lt;/li&gt; 
 &lt;li&gt;Support multiple fileformats for dump files (BIN/EML/JSON)&lt;/li&gt; 
 &lt;li&gt;Interoperability of said fileformats with libnfc, MFC tool app etc&lt;/li&gt; 
 &lt;li&gt;Supports more RFID based protocols than ever&lt;/li&gt; 
 &lt;li&gt;Easy install for package maintainers, distro maintainers&lt;/li&gt; 
 &lt;li&gt;Supports cmake, make&lt;/li&gt; 
 &lt;li&gt;Builds without errors or warnings on more OS/platforms than ever&lt;/li&gt; 
 &lt;li&gt;Available as package on known distros like Gentoo, Kali, Termux, Macports, Homebrew&lt;/li&gt; 
 &lt;li&gt;Much more documentation&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Development&lt;/h1&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;⚠ &lt;strong&gt;Note&lt;/strong&gt;: This is a bleeding edge repository. The maintainers actively is working out of this repository and will be periodically re-structuring the code to make it easier to comprehend, navigate, build, test, and contribute to, so &lt;strong&gt;DO expect significant changes to code layout on a regular basis&lt;/strong&gt;.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;👉 &lt;strong&gt;Remember!&lt;/strong&gt; If you intend to contribute to the code, please read the &lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/CONTRIBUTING.md&quot;&gt;coding style notes&lt;/a&gt; first. We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;The &lt;a href=&quot;https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap&quot;&gt;public roadmap&lt;/a&gt; is an excellent start to read if you are interesting in contributing.&lt;/p&gt; 
&lt;h2&gt;Supported operating systems&lt;/h2&gt; 
&lt;p&gt;This repo compiles nicely on&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;WSL1 on Windows 10&lt;/li&gt; 
 &lt;li&gt;WSL2 on Windows 10/11&lt;/li&gt; 
 &lt;li&gt;Proxspace environment &lt;a href=&quot;https://github.com/Gator96100/ProxSpace/releases&quot;&gt;release v3.xx&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Windows/MinGW environment&lt;/li&gt; 
 &lt;li&gt;Ubuntu, ParrotOS, Gentoo, Pentoo, Kali, NetHunter, Arch Linux, Fedora, Debian, Raspbian&lt;/li&gt; 
 &lt;li&gt;Android / Termux&lt;/li&gt; 
 &lt;li&gt;macOS / Homebrew (or MacPorts, experimental) / Apple Silicon M1&lt;/li&gt; 
 &lt;li&gt;iOS (Jailbroken, rootful)&lt;/li&gt; 
 &lt;li&gt;Docker container 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/secopsconsult/proxmark3&quot;&gt; Iceman repo based ubuntu 18.04 container &lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/iceman1001/proxmark3/&quot;&gt; Iceman fork based container v1.7 &lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Precompiled binaries&lt;/h2&gt; 
&lt;p&gt;See &lt;a href=&quot;https://www.proxmarkbuilds.org/&quot;&gt;Proxmark3 precompiled builds&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Proxmark3 GUI&lt;/h2&gt; 
&lt;p&gt;The official PM3-GUI from Gaucho will not work. Not to mention is quite old and not maintained any longer.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/burma69/PM3UniversalGUI&quot;&gt;Proxmark3 Universal GUI&lt;/a&gt; will work more or less.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wh201906/Proxmark3GUI/&quot;&gt;Proxmark3 GUI cross-compiled&lt;/a&gt; which is recently updated and claims to support latest source of this repo.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Phreak87/Proxmark3_GUI&quot;&gt;Proxmark3_GUI&lt;/a&gt; simple gui in &lt;a href=&quot;http://vb.net&quot;&gt;vb.net&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Official channels&lt;/h2&gt; 
&lt;p&gt;Where do you find the community?&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://t.ly/d4_C&quot;&gt;RFID Hacking community discord server&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.libera.chat/?channels=#proxmark3&quot;&gt;Proxmark3 IRC channel&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.reddit.com/r/proxmark3/&quot;&gt;Proxmark3 sub reddit&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.proxmark.org/forum/index.php&quot;&gt;Proxmark3 forum&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Maintainers&lt;/h2&gt; 
&lt;p&gt;To all distro, package maintainers, we tried to make your life easier.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;make install&lt;/code&gt; is now available and if you want to know more.&lt;/p&gt; 
&lt;p&gt;This document will be helpful for you&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/doc/md/Development/Maintainers.md&quot;&gt;Notes for maintainers&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Citation&lt;/h2&gt; 
&lt;p&gt;Use this bibtex to cite this repository globally:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@misc{proxmark3,
  author = {C. {Herrmann} and P. {Teuwen} and O. {Moiseenko} and M. {Walker} and others},
  title = {{Proxmark3 -- Iceman repo}},
  howpublished = {\url{https://github.com/RfidResearchGroup/proxmark3}},
  keywords = {rfid nfc iceman proxmark3 125khz 134khz 13.56mhz},
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you need to refer to a specific state of the repository, use a commit number or a date of access, e.g.:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;  note = {Accessed: commit 12327f71a27da23831901847886aaf20e8ad3ca0}
  note = {Accessed: 2021-01-01}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Copyright and licensing terms&lt;/h2&gt; 
&lt;p&gt;Each contribution is under the copyright of its author. See &lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/AUTHORS.md&quot;&gt;AUTHORS&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;The Proxmark3 source code is covered by the following licensing terms, usually referred as &lt;strong&gt;GPLv3 or later&lt;/strong&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;A copy of the GPLv3 is available in &lt;a href=&quot;https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/LICENSE.txt&quot;&gt;LICENSE&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Some dependencies may be under other free licensing terms compatible with the Proxmark3 licensing terms, see their respective description.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>henrypp/memreduct</title>
      <link>https://github.com/henrypp/memreduct</link>
      <description>&lt;p&gt;Lightweight real-time memory management application to monitor and clean system memory on your computer.&lt;/p&gt;&lt;hr&gt;&lt;h1 align=&quot;center&quot;&gt;Mem Reduct&lt;/h1&gt; 
&lt;p align=&quot;center&quot;&gt; &lt;a href=&quot;https://github.com/henrypp/memreduct/releases&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/v/release/henrypp/memreduct?style=flat-square&amp;amp;include_prereleases&amp;amp;label=version&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/henrypp/memreduct/releases&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/downloads/henrypp/memreduct/total.svg?style=flat-square&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/henrypp/memreduct/issues&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/issues-raw/henrypp/memreduct.svg?style=flat-square&amp;amp;label=issues&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/henrypp/memreduct/graphs/contributors&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/contributors/henrypp/memreduct?style=flat-square&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://github.com/henrypp/memreduct/raw/master/LICENSE&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/license/henrypp/memreduct?style=flat-square&quot; /&gt;&lt;/a&gt; &lt;/p&gt; 
&lt;hr /&gt; 
&lt;p align=&quot;center&quot;&gt; &lt;img src=&quot;https://raw.githubusercontent.com/henrypp/memreduct/master/images/memreduct.png?cachefix&quot; /&gt; &lt;/p&gt; 
&lt;h3&gt;Description:&lt;/h3&gt; 
&lt;p&gt;Lightweight real-time memory management application to monitor and clean system memory on your computer.&lt;/p&gt; 
&lt;p&gt;The program used undocumented internal system features (Native API) to clear system cache (system working set, working set, standby page lists, modified page lists) with variable result ~10-50%. Application it is compatible with &lt;s&gt;Windows XP SP3&lt;/s&gt; Windows 7 SP1 and higher operating systems.&lt;/p&gt; 
&lt;p&gt;You can download either the installer or portable version. For correct working you are require administrator rights.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;To activate portable mode, create &quot;memreduct.ini&quot; in application folder, or move it from &quot;%APPDATA%\Henry++\Mem Reduct&quot;.
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;System requirements:&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Windows 7, 8, 8.1, 10, 11 (64-bit/ARM64)&lt;/li&gt; 
 &lt;li&gt;An SSE2-capable CPU&lt;/li&gt; 
 &lt;li&gt;&lt;s&gt;KB2533623&lt;/s&gt; &lt;a href=&quot;https://www.microsoft.com/en-us/download/details.aspx?id=47442&quot;&gt;KB3063858&lt;/a&gt; update for Windows 7 was required&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Donate:&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.blockchain.com/btc/address/1LrRTXPsvHcQWCNZotA9RcwjsGcRghG96c&quot;&gt;Bitcoin&lt;/a&gt; (BTC)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.blockchain.com/explorer/addresses/eth/0xe2C84A62eb2a4EF154b19bec0c1c106734B95960&quot;&gt;Ethereum&lt;/a&gt; (ETH)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://yoomoney.ru/to/4100115776040583&quot;&gt;Yandex Money&lt;/a&gt; (RUB)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://paypal.me/henrypp&quot;&gt;Paypal&lt;/a&gt; (USD)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;GPG Signature:&lt;/h3&gt; 
&lt;p&gt;Binaries have GPG signature &lt;code&gt;memreduct.exe.sig&lt;/code&gt; in application folder.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Public key: &lt;a href=&quot;https://raw.githubusercontent.com/henrypp/builder/master/pubkey.asc&quot;&gt;pubkey.asc&lt;/a&gt; (&lt;a href=&quot;https://pgpkeys.eu/pks/lookup?op=index&amp;amp;fingerprint=on&amp;amp;search=0x5635B5FD&quot;&gt;pgpkeys.eu&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;Key ID: 0x5635B5FD&lt;/li&gt; 
 &lt;li&gt;Fingerprint: D985 2361 1524 AB29 BE73 30AC 2881 20A7 5635 B5FD&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr /&gt; 
&lt;ul&gt; 
 &lt;li&gt;Website: &lt;a href=&quot;https://github.com/henrypp&quot;&gt;github.com/henrypp&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Support: &lt;a href=&quot;mailto:sforce5@mail.ru&quot;&gt;sforce5@mail.ru&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr /&gt; 
&lt;p&gt;(c) 2011-2026 Henry++&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Cisco-Talos/clamav</title>
      <link>https://github.com/Cisco-Talos/clamav</link>
      <description>&lt;p&gt;ClamAV - Documentation is here: https://docs.clamav.net&lt;/p&gt;&lt;hr&gt;&lt;h1&gt;ClamAV&lt;/h1&gt; 
&lt;p align=&quot;center&quot;&gt; &lt;img width=&quot;250&quot; height=&quot;250&quot; src=&quot;https://raw.githubusercontent.com/Cisco-Talos/clamav/main/logo.png&quot; alt=&quot;Maeve, the ClamAV mascot&quot; /&gt; &lt;/p&gt; 
&lt;p align=&quot;center&quot;&gt; ClamAV® is an open source antivirus engine for detecting trojans, viruses, malware &amp;amp; other malicious threats. &lt;/p&gt; 
&lt;p align=&quot;center&quot;&gt; &lt;a href=&quot;https://github.com/Cisco-Talos/clamav/actions&quot;&gt;&lt;img src=&quot;https://github.com/Cisco-Talos/clamav/workflows/CMake%20Build/badge.svg?sanitize=true&quot; height=&quot;18&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://discord.gg/6vNAqWnVgw&quot;&gt;&lt;img src=&quot;https://img.shields.io/discord/636023333074370595.svg?logo=discord&quot; height=&quot;18&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://twitter.com/clamav&quot;&gt;&lt;img src=&quot;https://abs.twimg.com/favicons/twitter.ico&quot; width=&quot;18&quot; height=&quot;18&quot; /&gt;&lt;/a&gt; &lt;/p&gt; 
&lt;h2&gt;Documentation &amp;amp; FAQ&lt;/h2&gt; 
&lt;p&gt;ClamAV documentation is hosted at &lt;a href=&quot;https://docs.clamav.net/&quot;&gt;docs.clamav.net&lt;/a&gt;. The source archive for each release also includes a copy of the documentation for &lt;a href=&quot;https://raw.githubusercontent.com/Cisco-Talos/clamav/main/docs/html/index.html&quot;&gt;offline&lt;/a&gt; reading.&lt;/p&gt; 
&lt;p&gt;You can contribute to the documentation by submitting improvements to &lt;a href=&quot;https://github.com/Cisco-Talos/clamav-documentation&quot;&gt;Cisco-Talos/clamav-documentation&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;ClamAV News&lt;/h2&gt; 
&lt;p&gt;For information about the features in this and prior releases, read &lt;a href=&quot;https://raw.githubusercontent.com/Cisco-Talos/clamav/main/NEWS.md&quot;&gt;the news&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Catch up on the latest about ClamAV by reading our &lt;a href=&quot;http://blog.clamav.net&quot;&gt;blog&lt;/a&gt; and follow us on Twitter &lt;code&gt;@clamav&lt;/code&gt;.&lt;/p&gt; 
&lt;h2&gt;ClamAV Signatures&lt;/h2&gt; 
&lt;p&gt;Anyone can learn to read and write ClamAV signatures. To get started, see our &lt;a href=&quot;https://docs.clamav.net/manual/Signatures.html&quot;&gt;signature writing manual&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Installation Instructions&lt;/h2&gt; 
&lt;h3&gt;Using Docker&lt;/h3&gt; 
&lt;p&gt;ClamAV can be run using Docker. For details, visit to the online manual under &lt;a href=&quot;https://docs.clamav.net/manual/Installing/Docker.html&quot;&gt;&quot;Docker&quot;&lt;/a&gt; and check out our images on &lt;a href=&quot;https://hub.docker.com/r/clamav/clamav&quot;&gt;Docker Hub&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Using a Package Manager&lt;/h3&gt; 
&lt;p&gt;For help installing from a package manager, refer to the online manual under &lt;a href=&quot;https://docs.clamav.net/manual/Installing/Packages.html&quot;&gt;&quot;Packages&quot;&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Using an Installer&lt;/h3&gt; 
&lt;p&gt;The following install packages are available for download from &lt;a href=&quot;https://www.clamav.net/downloads&quot;&gt;clamav.net/downloads&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Linux - Debian and RPM packages for x86_64 and i686. &lt;em&gt;New in v0.104.&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;macOS - PKG installer for x86_64 and arm64 (universal). &lt;em&gt;New in v0.104.&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;Windows - MSI installers and portable ZIP packages for win32 and x64.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;To learn how to use these packages, refer to the online manual under &lt;a href=&quot;https://docs.clamav.net/manual/Installing.html#installing-with-an-installer&quot;&gt;&quot;Installing&quot;&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Build from Source&lt;/h3&gt; 
&lt;p&gt;For step-by-step instructions, refer to the online manual:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.clamav.net/manual/Installing/Installing-from-source-Unix.html&quot;&gt;Unix/Linux/Mac&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.clamav.net/manual/Installing/Installing-from-source-Windows.html&quot;&gt;Windows&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The source archive for each release includes a copy of the documentation for &lt;a href=&quot;https://raw.githubusercontent.com/Cisco-Talos/clamav/main/docs/html/UserManual.html&quot;&gt;offline&lt;/a&gt; reading.&lt;/p&gt; 
&lt;p&gt;A reference with all of the available build options can be found in the &lt;a href=&quot;https://raw.githubusercontent.com/Cisco-Talos/clamav/main/INSTALL.md&quot;&gt;INSTALL.md&lt;/a&gt; file.&lt;/p&gt; 
&lt;p&gt;You can find additional advice for developers in the online manual under &lt;a href=&quot;https://docs.clamav.net/manual/Development.html&quot;&gt;&quot;For Developers&quot;&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Upgrading from a previous version&lt;/h3&gt; 
&lt;p&gt;Visit &lt;a href=&quot;https://docs.clamav.net/faq/faq-upgrade.html&quot;&gt;the FAQ&lt;/a&gt; for tips on how to upgrade from a previous version.&lt;/p&gt; 
&lt;h2&gt;Join the ClamAV Community&lt;/h2&gt; 
&lt;p&gt;The best way to get in touch with the ClamAV community is to join our &lt;a href=&quot;https://docs.clamav.net/faq/faq-ml.html&quot;&gt;mailing lists&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;You can also join the community on our &lt;a href=&quot;https://discord.gg/6vNAqWnVgw&quot;&gt;ClamAV Discord chat server&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Want to make a contribution?&lt;/h2&gt; 
&lt;p&gt;The ClamAV development team welcomes &lt;a href=&quot;https://github.com/Cisco-Talos/clamav&quot;&gt;code contributions&lt;/a&gt;, improvements to &lt;a href=&quot;https://github.com/Cisco-Talos/clamav-documentation&quot;&gt;our documentation&lt;/a&gt;, and also &lt;a href=&quot;https://github.com/Cisco-Talos/clamav/issues&quot;&gt;bug reports&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Thanks for joining us!&lt;/p&gt; 
&lt;h2&gt;Licensing&lt;/h2&gt; 
&lt;p&gt;ClamAV is licensed for public/open source use under the GNU General Public License, Version 2 (GPLv2).&lt;/p&gt; 
&lt;p&gt;See &lt;code&gt;COPYING.txt&lt;/code&gt; for a copy of the license.&lt;/p&gt; 
&lt;h3&gt;3rd Party Code&lt;/h3&gt; 
&lt;p&gt;ClamAV contains a number of components that include code copied in part or in whole from 3rd party projects and whose code is not owned by Cisco and which are licensed differently than ClamAV. These include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Yara: Apache 2.0 license 
  &lt;ul&gt; 
   &lt;li&gt;Yara has since switched to the BSD 3-Clause License; Our source is out-of-date and needs to be updated.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;7z / lzma: public domain&lt;/li&gt; 
 &lt;li&gt;libclamav&#39;s NSIS/NulSoft parser includes: 
  &lt;ul&gt; 
   &lt;li&gt;zlib: permissive free software license&lt;/li&gt; 
   &lt;li&gt;bzip2 / libbzip2: BSD-like license&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;OpenBSD&#39;s libc/regex: BSD license&lt;/li&gt; 
 &lt;li&gt;file: BSD license&lt;/li&gt; 
 &lt;li&gt;str.c: Contains BSD licensed modified-implementations of strtol(), stroul() functions, Copyright (c) 1990 The Regents of the University of California.&lt;/li&gt; 
 &lt;li&gt;pngcheck (png.c): MIT/X11-style license&lt;/li&gt; 
 &lt;li&gt;getopt.c: MIT license&lt;/li&gt; 
 &lt;li&gt;Curl: license inspired by MIT/X, but not identical&lt;/li&gt; 
 &lt;li&gt;libmspack: LGPL license&lt;/li&gt; 
 &lt;li&gt;UnRAR (libclamunrar): a non-free/restricted open source license 
  &lt;ul&gt; 
   &lt;li&gt;Note: The UnRAR license is incompatible with GPLv2 because it contains a clause that prohibits reverse engineering a RAR compression algorithm from the UnRAR decompression code. For this reason, libclamunrar/libclamunrar_iface is not linked at all with libclamav. It is instead loaded at run-time. If it fails to load, ClamAV will continue running without RAR support.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;See the &lt;code&gt;COPYING&lt;/code&gt; directory for a copy of the 3rd party project licenses.&lt;/p&gt; 
&lt;h2&gt;Acknowledgements&lt;/h2&gt; 
&lt;p&gt;Credit for contributions to each release can be found in the &lt;a href=&quot;https://raw.githubusercontent.com/Cisco-Talos/clamav/main/NEWS.md&quot;&gt;News&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;ClamAV is brought to you by &lt;a href=&quot;https://www.clamav.net/about.html#credits&quot;&gt;the ClamAV Team&lt;/a&gt;&lt;/p&gt;</description>
      
    </item>
    
  </channel>
</rss>
