File hyprutils-0.2.3.obscpio of Package hyprutils

070701101BE2E1000081A400000000000000000000000166F344120000070E000000080000000100000000000000000000001E00000000hyprutils-0.2.3/.clang-format---
Language: Cpp
BasedOnStyle: LLVM

AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignConsecutiveAssignments: true
AlignEscapedNewlines: Right
AlignOperands: false
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: AfterColon
ColumnLimit: 180
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
IncludeBlocks: Preserve
IndentCaseLabels: true
IndentWidth: 4
PointerAlignment: Left
ReflowComments: false
SortIncludes: false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 4
UseTab: Never

AllowShortEnumsOnASingleLine: false

BraceWrapping:
  AfterEnum: false

AlignConsecutiveDeclarations: AcrossEmptyLines

NamespaceIndentation: All
070701410ADF31000041ED00000000000000000000000366F3441200000000000000080000000100000000000000000000001800000000hyprutils-0.2.3/.github0707010007F933000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000002200000000hyprutils-0.2.3/.github/workflows07070100087BFE000081A400000000000000000000000166F3441200000880000000080000000100000000000000000000002B00000000hyprutils-0.2.3/.github/workflows/arch.ymlname: Build & Test (Arch)

on: [push, pull_request, workflow_dispatch]
jobs:
  gcc:
    name: "Arch: Build and Test (gcc)"
    runs-on: ubuntu-latest
    container:
      image: archlinux
    steps:
      - name: Checkout repository actions
        uses: actions/checkout@v4
        with:
          sparse-checkout: .github/actions

      - name: Get required pkgs
        run: |
          sed -i 's/SigLevel    = Required DatabaseOptional/SigLevel    = Optional TrustAll/' /etc/pacman.conf
          pacman --noconfirm --noprogressbar -Syyu
          pacman --noconfirm --noprogressbar -Sy gcc base-devel cmake clang libc++ pixman

      - name: Build hyprutils with gcc
        run: |
          CC="/usr/bin/gcc" CXX="/usr/bin/g++" cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
          CC="/usr/bin/gcc" CXX="/usr/bin/g++" cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
          cmake --install ./build

      - name: Run tests
        run: |
          cd ./build && ctest --output-on-failure

  clang:
    name: "Arch: Build and Test (clang)"
    runs-on: ubuntu-latest
    container:
      image: archlinux
    steps:
      - name: Checkout repository actions
        uses: actions/checkout@v4
        with:
          sparse-checkout: .github/actions

      - name: Get required pkgs
        run: |
          sed -i 's/SigLevel    = Required DatabaseOptional/SigLevel    = Optional TrustAll/' /etc/pacman.conf
          pacman --noconfirm --noprogressbar -Syyu
          pacman --noconfirm --noprogressbar -Sy gcc base-devel cmake clang libc++ pixman

      - name: Build hyprutils with clang
        run: |
          CC="/usr/bin/clang" CXX="/usr/bin/clang++" cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
          CC="/usr/bin/clang" CXX="/usr/bin/clang++" cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
          cmake --install ./build

      - name: Run tests
        run: |
          cd ./build && ctest --output-on-failure
07070100098968000081A400000000000000000000000166F3441200000257000000080000000100000000000000000000002A00000000hyprutils-0.2.3/.github/workflows/nix.ymlname: Build & Test

on: [push, pull_request, workflow_dispatch]
jobs:
  nix:
    strategy:
      matrix:
        package:
          - hyprutils
          - hyprutils-with-tests

    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - uses: cachix/install-nix-action@v26
    - uses: DeterminateSystems/magic-nix-cache-action@main

    # not needed (yet)
    # - uses: cachix/cachix-action@v12
    #   with:
    #     name: hyprland
    #     authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'

    - name: Build & Test
      run: nix build .#${{ matrix.package }} --print-build-logs

070701101C0087000081A400000000000000000000000166F34412000001B5000000080000000100000000000000000000001B00000000hyprutils-0.2.3/.gitignore# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

build/
.vscode/
.cache/

.cmake/
CMakeCache.txt
CMakeFiles/
CTestTestfile.cmake
DartConfiguration.tcl
Makefile
cmake_install.cmake
compile_commands.json
hyprutils.pc
070701101C19C7000081A400000000000000000000000166F3441200000A9F000000080000000100000000000000000000001F00000000hyprutils-0.2.3/CMakeLists.txtcmake_minimum_required(VERSION 3.19)

file(READ "${CMAKE_SOURCE_DIR}/VERSION" VER_RAW)
string(STRIP ${VER_RAW} HYPRUTILS_VERSION)
add_compile_definitions(HYPRUTILS_VERSION="${HYPRUTILS_VERSION}")

project(
  hyprutils
  VERSION ${HYPRUTILS_VERSION}
  DESCRIPTION "Small C++ library for utilities used across the Hypr* ecosystem")

include(CTest)
include(GNUInstallDirs)

set(PREFIX ${CMAKE_INSTALL_PREFIX})
set(INCLUDE ${CMAKE_INSTALL_FULL_INCLUDEDIR})
set(LIBDIR ${CMAKE_INSTALL_FULL_LIBDIR})

configure_file(hyprutils.pc.in hyprutils.pc @ONLY)

set(CMAKE_CXX_STANDARD 23)

if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
  message(STATUS "Configuring hyprutils in Debug")
  add_compile_definitions(HYPRLAND_DEBUG)
else()
  add_compile_options(-O3)
  message(STATUS "Configuring hyprutils in Release")
endif()

file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp" "include/*.hpp")
file(GLOB_RECURSE PUBLIC_HEADERS CONFIGURE_DEPENDS "include/*.hpp")

find_package(PkgConfig REQUIRED)
pkg_check_modules(deps REQUIRED IMPORTED_TARGET pixman-1)

add_library(hyprutils SHARED ${SRCFILES})
target_include_directories(
  hyprutils
  PUBLIC "./include"
  PRIVATE "./src")
set_target_properties(hyprutils PROPERTIES VERSION ${hyprutils_VERSION}
                                           SOVERSION 1)
target_link_libraries(hyprutils PkgConfig::deps)

# tests
add_custom_target(tests)

add_executable(hyprutils_memory "tests/memory.cpp")
target_link_libraries(hyprutils_memory PRIVATE hyprutils PkgConfig::deps)
add_test(
  NAME "Memory"
  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
  COMMAND hyprutils_memory "memory")
add_dependencies(tests hyprutils_memory)

add_executable(hyprutils_string "tests/string.cpp")
target_link_libraries(hyprutils_string PRIVATE hyprutils PkgConfig::deps)
add_test(
  NAME "String"
  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
  COMMAND hyprutils_string "string")
add_dependencies(tests hyprutils_string)

add_executable(hyprutils_signal "tests/signal.cpp")
target_link_libraries(hyprutils_signal PRIVATE hyprutils PkgConfig::deps)
add_test(
  NAME "Signal"
  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
  COMMAND hyprutils_signal "signal")
add_dependencies(tests hyprutils_signal)

add_executable(hyprutils_math "tests/math.cpp")
target_link_libraries(hyprutils_math PRIVATE hyprutils PkgConfig::deps)
add_test(
  NAME "Math"
  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
  COMMAND hyprutils_math "math")
add_dependencies(tests hyprutils_math)

# Installation
install(TARGETS hyprutils)
install(DIRECTORY "include/hyprutils" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES ${CMAKE_BINARY_DIR}/hyprutils.pc
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
070701101C19D0000081A400000000000000000000000166F34412000005DF000000080000000100000000000000000000001800000000hyprutils-0.2.3/LICENSEBSD 3-Clause License

Copyright (c) 2024, Hypr Development

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
070701101C3777000081A400000000000000000000000166F344120000024E000000080000000100000000000000000000001A00000000hyprutils-0.2.3/README.md# hyprutils

Hyprutils is a small C++ library for utilities used across the Hypr* ecosystem.

## Stability

Hyprutils depends on the ABI stability of the stdlib implementation of your compiler. Sover bumps will be done only for hyprutils ABI breaks, not stdlib.

## Building

```sh
git clone https://github.com/hyprwm/hyprutils.git
cd hyprutils/
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf _NPROCESSORS_CONF`
sudo cmake --install build
```
070701101C4913000081A400000000000000000000000166F3441200000006000000080000000100000000000000000000001800000000hyprutils-0.2.3/VERSION0.2.3
070701101C491B000081A400000000000000000000000166F3441200000401000000080000000100000000000000000000001B00000000hyprutils-0.2.3/flake.lock{
  "nodes": {
    "nixpkgs": {
      "locked": {
        "lastModified": 1721138476,
        "narHash": "sha256-+W5eZOhhemLQxelojLxETfbFbc19NWawsXBlapYpqIA=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "ad0b5eed1b6031efaed382844806550c3dcb4206",
        "type": "github"
      },
      "original": {
        "owner": "NixOS",
        "ref": "nixos-unstable",
        "repo": "nixpkgs",
        "type": "github"
      }
    },
    "root": {
      "inputs": {
        "nixpkgs": "nixpkgs",
        "systems": "systems"
      }
    },
    "systems": {
      "locked": {
        "lastModified": 1689347949,
        "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
        "owner": "nix-systems",
        "repo": "default-linux",
        "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
        "type": "github"
      },
      "original": {
        "owner": "nix-systems",
        "repo": "default-linux",
        "type": "github"
      }
    }
  },
  "root": "root",
  "version": 7
}
070701101C4AC8000081A400000000000000000000000166F3441200000582000000080000000100000000000000000000001A00000000hyprutils-0.2.3/flake.nix{
  description = "Small C++ library for utilities used across the Hypr* ecosystem";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    systems.url = "github:nix-systems/default-linux";
  };

  outputs = {
    self,
    nixpkgs,
    systems,
  }: let
    inherit (nixpkgs) lib;
    eachSystem = lib.genAttrs (import systems);
    pkgsFor = eachSystem (system:
      import nixpkgs {
        localSystem.system = system;
        overlays = with self.overlays; [hyprutils];
      });
    mkDate = longDate: (lib.concatStringsSep "-" [
      (builtins.substring 0 4 longDate)
      (builtins.substring 4 2 longDate)
      (builtins.substring 6 2 longDate)
    ]);

    version = lib.removeSuffix "\n" (builtins.readFile ./VERSION);
  in {
    overlays = {
      default = self.overlays.hyprutils;
      hyprutils = final: prev: {
        hyprutils = final.callPackage ./nix/default.nix {
          stdenv = final.gcc13Stdenv;
          version = version + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
        };
        hyprutils-with-tests = final.hyprutils.override {doCheck = true;};
      };
    };

    packages = eachSystem (system: {
      default = self.packages.${system}.hyprutils;
      inherit (pkgsFor.${system}) hyprutils hyprutils-with-tests;
    });

    formatter = eachSystem (system: pkgsFor.${system}.alejandra);
  };
}
070701101C4AC9000081A400000000000000000000000166F3441200000105000000080000000100000000000000000000002000000000hyprutils-0.2.3/hyprutils.pc.inprefix=@PREFIX@
includedir=@INCLUDE@
libdir=@LIBDIR@

Name: hyprutils
URL: https://github.com/hyprwm/hyprutils
Description: Hyprland utilities library used across the ecosystem 
Version: @HYPRUTILS_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lhyprutils
070701101C4AD2000041ED00000000000000000000000366F3441200000000000000080000000100000000000000000000001800000000hyprutils-0.2.3/include070701200DEE83000041ED00000000000000000000000866F3441200000000000000080000000100000000000000000000002200000000hyprutils-0.2.3/include/hyprutils070701300C33FC000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000002700000000hyprutils-0.2.3/include/hyprutils/math070701300DB33F000081A400000000000000000000000166F344120000185E000000080000000100000000000000000000002F00000000hyprutils-0.2.3/include/hyprutils/math/Box.hpp#pragma once

#include "./Vector2D.hpp"
#include "./Misc.hpp"

namespace Hyprutils::Math {

    /**
        * @brief Represents the extents of a bounding box.
        */
    struct SBoxExtents {
        Vector2D topLeft;
        Vector2D bottomRight;

        /**
            * @brief Scales the extents by a given factor.
            * @param scale The scaling factor.
            * @return Scaled SBoxExtents.
            */
        SBoxExtents operator*(const double& scale) const {
            return SBoxExtents{topLeft * scale, bottomRight * scale};
        }
        /**
            * @brief Rounds the coordinates of the extents.
            * @return Rounded SBoxExtents.
            */
        SBoxExtents round() {
            return {topLeft.round(), bottomRight.round()};
        }
        /**
            * @brief Checks equality between two SBoxExtents objects.
            * @param other Another SBoxExtents object to compare.
            * @return True if both SBoxExtents are equal, false otherwise.
            */
        bool operator==(const SBoxExtents& other) const {
            return topLeft == other.topLeft && bottomRight == other.bottomRight;
        }

        /**
            * @brief Adjusts the extents to encompass another SBoxExtents.
            * @param other Another SBoxExtents to add to this one.
            */
        void addExtents(const SBoxExtents& other) {
            topLeft     = topLeft.getComponentMax(other.topLeft);
            bottomRight = bottomRight.getComponentMax(other.bottomRight);
        }
    };

    /**
        * @brief Represents a 2D bounding box.
        */
    class CBox {
      public:
        /**
            * @brief Constructs a CBox with specified position and dimensions.
            * @param x_ X-coordinate of the top-left corner.
            * @param y_ Y-coordinate of the top-left corner.
            * @param w_ Width of the box.
            * @param h_ Height of the box.
            */
        CBox(double x_, double y_, double w_, double h_) {
            x = x_;
            y = y_;
            w = w_;
            h = h_;
        }
        /**
            * @brief Default constructor. Initializes an empty box (0 width, 0 height).
            */
        CBox() {
            w = 0;
            h = 0;
        }
        /**
            * @brief Constructs a CBox with uniform dimensions.
            * @param d Dimensions to apply uniformly (x, y, width, height).
            */
        CBox(const double d) {
            x = d;
            y = d;
            w = d;
            h = d;
        }
        /**
            * @brief Constructs a CBox from a position and size vector.
            * @param pos Position vector representing the top-left corner.
            * @param size Size vector representing width and height.
            */
        CBox(const Vector2D& pos, const Vector2D& size) {
            x = pos.x;
            y = pos.y;
            w = size.x;
            h = size.y;
        }

        // Geometric operations
        CBox& applyFromWlr();
        CBox& scale(double scale);
        CBox& scaleFromCenter(double scale);
        CBox& scale(const Vector2D& scale);
        CBox& translate(const Vector2D& vec);
        CBox& round();
        CBox& transform(const eTransform t, double w, double h);
        CBox& addExtents(const SBoxExtents& e);
        CBox& expand(const double& value);
        CBox& noNegativeSize();

        CBox  copy() const;
        CBox  intersection(const CBox& other) const;
        bool  overlaps(const CBox& other) const;
        bool  inside(const CBox& bound) const;

        /**
            * @brief Computes the extents of the box relative to another box.
            * @param small Another CBox to compare against.
            * @return SBoxExtents representing the extents of the box relative to 'small'.
            */
        SBoxExtents extentsFrom(const CBox&); // this is the big box

        /**
            * @brief Calculates the middle point of the box.
            * @return Vector2D representing the middle point.
            */
        Vector2D middle() const;

        /**
            * @brief Retrieves the position of the top-left corner of the box.
            * @return Vector2D representing the position.
            */
        Vector2D pos() const;

        /**
            * @brief Retrieves the size (width and height) of the box.
            * @return Vector2D representing the size.
            */
        Vector2D size() const;

        /**
            * @brief Retrieves the size of the box offset by its position.
            * @return Vector2D representing the bottom right extent of the box.
            */
        Vector2D extent() const;

        /**
            * @brief Finds the closest point within the box to a given vector.
            * @param vec Vector from which to find the closest point.
            * @return Vector2D representing the closest point within the box.
            */
        Vector2D closestPoint(const Vector2D& vec) const;

        /**
            * @brief Checks if a given point is inside the box.
            * @param vec Vector representing the point to check.
            * @return True if the point is inside the box, false otherwise.
            */
        bool containsPoint(const Vector2D& vec) const;

        /**
            * @brief Checks if the box is empty (zero width or height).
            * @return True if the box is empty, false otherwise.
            */
        bool   empty() const;

        double x = 0, y = 0; // Position of the top-left corner of the box.
        union {
            double w;
            double width;
        };
        union {
            double h;
            double height;
        };

        double rot = 0; //< Rotation angle of the box in radians (counterclockwise).

        /**
            * @brief Checks equality between two CBox objects.
            * @param rhs Another CBox object to compare.
            * @return True if both CBox objects are equal, false otherwise.
            */
        bool operator==(const CBox& rhs) const {
            return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
        }

      private:
        CBox roundInternal();
    };
}
07070130106AFE000081A400000000000000000000000166F3441200000AC2000000080000000100000000000000000000003100000000hyprutils-0.2.3/include/hyprutils/math/Edges.hpp#pragma once
#include <cstdint>

namespace Hyprutils::Math {

    /**
        * @brief Flag set of box edges
        */
    class CEdges {
      public:
        enum eEdges : uint8_t {
            NONE   = 0,
            TOP    = 1,
            LEFT   = 2,
            BOTTOM = 4,
            RIGHT  = 8,
        };

        CEdges() = default;
        CEdges(eEdges edges) : m_edges(edges) {}
        CEdges(uint8_t edges) : m_edges(static_cast<eEdges>(edges)) {}

        bool operator==(const CEdges& other) {
            return m_edges == other.m_edges;
        }

        CEdges operator|(const CEdges& other) {
            return m_edges | other.m_edges;
        }

        CEdges operator&(const CEdges& other) {
            return m_edges & other.m_edges;
        }

        CEdges operator^(const CEdges& other) {
            return m_edges ^ other.m_edges;
        }

        void operator|=(const CEdges& other) {
            m_edges = (*this | other).m_edges;
        }

        void operator&=(const CEdges& other) {
            m_edges = (*this & other).m_edges;
        }

        void operator^=(const CEdges& other) {
            m_edges = (*this ^ other).m_edges;
        }

        /**
            * @return if the edge set contains the top edge.
            */
        bool top() {
            return m_edges & TOP;
        }

        /**
            * @return if the edge set contains the left edge.
            */
        bool left() {
            return m_edges & LEFT;
        }

        /**
            * @return if the edge set contains the bottom edge.
            */
        bool bottom() {
            return m_edges & BOTTOM;
        }

        /**
            * @return if the edge set contains the right edge.
            */
        bool right() {
            return m_edges & RIGHT;
        }

        /**
            * @param top The state the top edge should be set to.
            */
        void setTop(bool top) {
            m_edges = static_cast<eEdges>((m_edges & ~TOP) | (TOP * top));
        }

        /**
            * @param left The state the left edge should be set to.
            */
        void setLeft(bool left) {
            m_edges = static_cast<eEdges>((m_edges & ~LEFT) | (LEFT * left));
        }

        /**
            * @param bottom The state the bottom edge should be set to.
            */
        void setBottom(bool bottom) {
            m_edges = static_cast<eEdges>((m_edges & ~BOTTOM) | (BOTTOM * bottom));
        }

        /**
            * @param right The state the right edge should be set to.
            */
        void setRight(bool right) {
            m_edges = static_cast<eEdges>((m_edges & ~RIGHT) | (RIGHT * right));
        }

        eEdges m_edges = NONE;
    };

}
0707013014AD8F000081A400000000000000000000000166F34412000006AB000000080000000100000000000000000000003200000000hyprutils-0.2.3/include/hyprutils/math/Mat3x3.hpp#pragma once

#include <array>
#include <vector>
#include <string>
#include <ostream>

#include "./Misc.hpp"

namespace Hyprutils {
    namespace Math {
        class CBox;
        class Vector2D;

        class Mat3x3 {
          public:
            Mat3x3();
            Mat3x3(std::array<float, 9>);
            Mat3x3(std::vector<float>);

            /* create an identity 3x3 matrix */
            static Mat3x3 identity();

            /* create an output projection matrix */
            static Mat3x3 outputProjection(const Vector2D& size, eTransform transform);

            /* get the matrix as an array, in a RTL TTB order. */
            std::array<float, 9> getMatrix() const;

            /* create a box projection matrix */
            Mat3x3 projectBox(const CBox& box, eTransform transform, float rot = 0.F /* rad, CCW */) const;

            /* in-place functions */
            Mat3x3& transform(eTransform transform);
            Mat3x3& rotate(float rot /* rad, CCW */);
            Mat3x3& scale(const Vector2D& scale);
            Mat3x3& scale(const float scale);
            Mat3x3& translate(const Vector2D& offset);
            Mat3x3& transpose();
            Mat3x3& multiply(const Mat3x3& other);

            /* misc utils */
            Mat3x3      copy() const;
            std::string toString() const;

            bool        operator==(const Mat3x3& other) const {
                return other.matrix == matrix;
            }

            friend std::ostream& operator<<(std::ostream& os, const Mat3x3& mat) {
                os << mat.toString();
                return os;
            }

          private:
            std::array<float, 9> matrix;
        };
    }
}0707013010FF20000081A400000000000000000000000166F34412000001ED000000080000000100000000000000000000003000000000hyprutils-0.2.3/include/hyprutils/math/Misc.hpp#pragma once

namespace Hyprutils {
    namespace Math {
        enum eTransform {
            HYPRUTILS_TRANSFORM_NORMAL      = 0,
            HYPRUTILS_TRANSFORM_90          = 1,
            HYPRUTILS_TRANSFORM_180         = 2,
            HYPRUTILS_TRANSFORM_270         = 3,
            HYPRUTILS_TRANSFORM_FLIPPED     = 4,
            HYPRUTILS_TRANSFORM_FLIPPED_90  = 5,
            HYPRUTILS_TRANSFORM_FLIPPED_180 = 6,
            HYPRUTILS_TRANSFORM_FLIPPED_270 = 7,
        };
    }
}0707013014752A000081A400000000000000000000000166F3441200000AA9000000080000000100000000000000000000003200000000hyprutils-0.2.3/include/hyprutils/math/Region.hpp#pragma once

#include <pixman.h>
#include <vector>
#include "Vector2D.hpp"
#include "Box.hpp"

namespace Hyprutils {
    namespace Math {
        class CRegion {
          public:
            /* Create an empty region */
            CRegion();
            /* Create from a reference. Copies, does not own. */
            CRegion(const pixman_region32_t* const ref);
            /* Create from a box */
            CRegion(double x, double y, double w, double h);
            /* Create from a CBox */
            CRegion(const CBox& box);
            /* Create from a pixman_box32_t */
            CRegion(pixman_box32_t* box);

            CRegion(const CRegion&);
            CRegion(CRegion&&);

            ~CRegion();

            CRegion& operator=(CRegion&& other) {
                pixman_region32_copy(&m_rRegion, other.pixman());
                return *this;
            }

            CRegion& operator=(CRegion& other) {
                pixman_region32_copy(&m_rRegion, other.pixman());
                return *this;
            }

            CRegion&                    clear();
            CRegion&                    set(const CRegion& other);
            CRegion&                    add(const CRegion& other);
            CRegion&                    add(double x, double y, double w, double h);
            CRegion&                    add(const CBox& other);
            CRegion&                    subtract(const CRegion& other);
            CRegion&                    intersect(const CRegion& other);
            CRegion&                    intersect(double x, double y, double w, double h);
            CRegion&                    translate(const Vector2D& vec);
            CRegion&                    transform(const eTransform t, double w, double h);
            CRegion&                    invert(pixman_box32_t* box);
            CRegion&                    invert(const CBox& box);
            CRegion&                    scale(float scale);
            CRegion&                    scale(const Vector2D& scale);
            CRegion&                    expand(double units);
            CRegion&                    rationalize();
            CBox                        getExtents();
            bool                        containsPoint(const Vector2D& vec) const;
            bool                        empty() const;
            Vector2D                    closestPoint(const Vector2D& vec) const;
            CRegion                     copy() const;

            std::vector<pixman_box32_t> getRects() const;

            //
            pixman_region32_t* pixman() {
                return &m_rRegion;
            }

          private:
            pixman_region32_t m_rRegion;
        };
    }
}
0707013014AD88000081A400000000000000000000000166F3441200001F9D000000080000000100000000000000000000003400000000hyprutils-0.2.3/include/hyprutils/math/Vector2D.hpp#pragma once

#include <format>
#include <string>

namespace Hyprutils {
    namespace Math {
        class Vector2D {
          public:
            Vector2D(double, double);
            Vector2D(int, int);
            Vector2D();
            ~Vector2D();

            double x = 0;
            double y = 0;

            // returns the scale
            double   normalize();

            Vector2D operator+(const Vector2D& a) const {
                return Vector2D(this->x + a.x, this->y + a.y);
            }
            Vector2D operator-(const Vector2D& a) const {
                return Vector2D(this->x - a.x, this->y - a.y);
            }
            Vector2D operator-() const {
                return Vector2D(-this->x, -this->y);
            }
            Vector2D operator*(const double& a) const {
                return Vector2D(this->x * a, this->y * a);
            }
            Vector2D operator/(const double& a) const {
                return Vector2D(this->x / a, this->y / a);
            }

            bool operator==(const Vector2D& a) const {
                return a.x == x && a.y == y;
            }

            bool operator!=(const Vector2D& a) const {
                return a.x != x || a.y != y;
            }

            Vector2D operator*(const Vector2D& a) const {
                return Vector2D(this->x * a.x, this->y * a.y);
            }

            Vector2D operator/(const Vector2D& a) const {
                return Vector2D(this->x / a.x, this->y / a.y);
            }

            bool operator>(const Vector2D& a) const {
                return this->x > a.x && this->y > a.y;
            }

            bool operator<(const Vector2D& a) const {
                return this->x < a.x && this->y < a.y;
            }
            Vector2D& operator+=(const Vector2D& a) {
                this->x += a.x;
                this->y += a.y;
                return *this;
            }
            Vector2D& operator-=(const Vector2D& a) {
                this->x -= a.x;
                this->y -= a.y;
                return *this;
            }
            Vector2D& operator*=(const Vector2D& a) {
                this->x *= a.x;
                this->y *= a.y;
                return *this;
            }
            Vector2D& operator/=(const Vector2D& a) {
                this->x /= a.x;
                this->y /= a.y;
                return *this;
            }
            Vector2D& operator*=(const double& a) {
                this->x *= a;
                this->y *= a;
                return *this;
            }
            Vector2D& operator/=(const double& a) {
                this->x /= a;
                this->y /= a;
                return *this;
            }

            double   distance(const Vector2D& other) const;
            double   distanceSq(const Vector2D& other) const;
            double   size() const;
            Vector2D clamp(const Vector2D& min, const Vector2D& max = Vector2D{-1, -1}) const;

            Vector2D floor() const;
            Vector2D round() const;

            Vector2D getComponentMax(const Vector2D& other) const;
        };
    }
}

// absolutely ridiculous formatter spec parsing
#define AQ_FORMAT_PARSE(specs__, type__)                                                                                                                                              \
    template <typename FormatContext>                                                                                                                                              \
    constexpr auto parse(FormatContext& ctx) {                                                                                                                                     \
        auto it = ctx.begin();                                                                                                                                                     \
        for (; it != ctx.end() && *it != '}'; it++) {                                                                                                                              \
            switch (*it) { specs__ default : throw std::format_error("invalid format specification"); }                                                                            \
        }                                                                                                                                                                          \
        return it;                                                                                                                                                                 \
    }

#define AQ_FORMAT_FLAG(spec__, flag__)                                                                                                                                                \
    case spec__: (flag__) = true; break;

#define AQ_FORMAT_NUMBER(buf__)                                                                                                                                                       \
    case '0':                                                                                                                                                                      \
    case '1':                                                                                                                                                                      \
    case '2':                                                                                                                                                                      \
    case '3':                                                                                                                                                                      \
    case '4':                                                                                                                                                                      \
    case '5':                                                                                                                                                                      \
    case '6':                                                                                                                                                                      \
    case '7':                                                                                                                                                                      \
    case '8':                                                                                                                                                                      \
    case '9': (buf__).push_back(*it); break;

/**
    format specification
    - 'j', as json array
    - 'X', same as std::format("{}x{}", vec.x, vec.y)
    - number, floating point precision, use `0` to format as integer
*/
template <typename CharT>
struct std::formatter<Hyprutils::Math::Vector2D, CharT> : std::formatter<CharT> {
    bool        formatJson = false;
    bool        formatX    = false;
    std::string precision  = "";
    AQ_FORMAT_PARSE(AQ_FORMAT_FLAG('j', formatJson) //
                 AQ_FORMAT_FLAG('X', formatX)    //
                 AQ_FORMAT_NUMBER(precision),
                 Hyprutils::Math::Vector2D)

    template <typename FormatContext>
    auto format(const Hyprutils::Math::Vector2D& vec, FormatContext& ctx) const {
        std::string formatString = precision.empty() ? "{}" : std::format("{{:.{}f}}", precision);

        if (formatJson)
            formatString = std::format("[{0}, {0}]", formatString);
        else if (formatX)
            formatString = std::format("{0}x{0}", formatString);
        else
            formatString = std::format("[Vector2D: x: {0}, y: {0}]", formatString);
        try {
            string buf = std::vformat(formatString, std::make_format_args(vec.x, vec.y));
            return std::format_to(ctx.out(), "{}", buf);
        } catch (std::format_error& e) { return std::format_to(ctx.out(), "[{}, {}]", vec.x, vec.y); }
    }
};
070701410ADF32000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000002900000000hyprutils-0.2.3/include/hyprutils/memory070701410ADF34000081A400000000000000000000000166F344120000252A000000080000000100000000000000000000003700000000hyprutils-0.2.3/include/hyprutils/memory/SharedPtr.hpp#pragma once

#include <cstddef>
#include <cstdint>
#include <memory>

/*
    This is a custom impl of std::shared_ptr.
    It is not thread-safe like the STL one,
    but Hyprland is single-threaded anyways.

    It differs a bit from how the STL one works,
    namely in the fact that it keeps the T* inside the
    control block, and that you can still make a CWeakPtr
    or deref an existing one inside the destructor.
*/

namespace Hyprutils {
    namespace Memory {
        namespace CSharedPointer_ {
            class impl_base {
              public:
                virtual ~impl_base() {};

                virtual void         inc() noexcept         = 0;
                virtual void         dec() noexcept         = 0;
                virtual void         incWeak() noexcept     = 0;
                virtual void         decWeak() noexcept     = 0;
                virtual unsigned int ref() noexcept         = 0;
                virtual unsigned int wref() noexcept        = 0;
                virtual void         destroy() noexcept     = 0;
                virtual bool         destroying() noexcept  = 0;
                virtual bool         dataNonNull() noexcept = 0;
                virtual void*        getData() noexcept     = 0;
            };

            template <typename T>
            class impl : public impl_base {
              public:
                impl(T* data) noexcept : _data(data) {
                    ;
                }

                /* strong refcount */
                unsigned int _ref = 0;
                /* weak refcount */
                unsigned int _weak = 0;

                T*           _data = nullptr;

                friend void  swap(impl*& a, impl*& b) {
                    impl* tmp = a;
                    a         = b;
                    b         = tmp;
                }

                /* if the destructor was called, 
                   creating shared_ptrs is no longer valid */
                bool _destroying = false;

                void _destroy() {
                    if (!_data || _destroying)
                        return;

                    // first, we destroy the data, but keep the pointer.
                    // this way, weak pointers will still be able to
                    // reference and use, but no longer create shared ones.
                    _destroying = true;
                    __deleter(_data);
                    // now, we can reset the data and call it a day.
                    _data       = nullptr;
                    _destroying = false;
                }

                std::default_delete<T> __deleter{};

                //
                virtual void inc() noexcept {
                    _ref++;
                }

                virtual void dec() noexcept {
                    _ref--;
                }

                virtual void incWeak() noexcept {
                    _weak++;
                }

                virtual void decWeak() noexcept {
                    _weak--;
                }

                virtual unsigned int ref() noexcept {
                    return _ref;
                }

                virtual unsigned int wref() noexcept {
                    return _weak;
                }

                virtual void destroy() noexcept {
                    _destroy();
                }

                virtual bool destroying() noexcept {
                    return _destroying;
                }

                virtual bool dataNonNull() noexcept {
                    return _data != nullptr;
                }

                virtual void* getData() noexcept {
                    return _data;
                }

                virtual ~impl() {
                    destroy();
                }
            };
        };

        template <typename T>
        class CSharedPointer {
          public:
            template <typename X>
            using validHierarchy = typename std::enable_if<std::is_assignable<CSharedPointer<T>&, X>::value, CSharedPointer&>::type;
            template <typename X>
            using isConstructible = typename std::enable_if<std::is_constructible<T&, X&>::value>::type;

            /* creates a new shared pointer managing a resource
               avoid calling. Could duplicate ownership. Prefer makeShared */
            explicit CSharedPointer(T* object) noexcept {
                impl_ = new CSharedPointer_::impl<T>(object);
                increment();
            }

            /* creates a shared pointer from a reference */
            template <typename U, typename = isConstructible<U>>
            CSharedPointer(const CSharedPointer<U>& ref) noexcept {
                impl_ = ref.impl_;
                increment();
            }

            CSharedPointer(const CSharedPointer& ref) noexcept {
                impl_ = ref.impl_;
                increment();
            }

            template <typename U, typename = isConstructible<U>>
            CSharedPointer(CSharedPointer<U>&& ref) noexcept {
                std::swap(impl_, ref.impl_);
            }

            CSharedPointer(CSharedPointer&& ref) noexcept {
                std::swap(impl_, ref.impl_);
            }

            /* allows weakPointer to create from an impl */
            CSharedPointer(CSharedPointer_::impl_base* implementation) noexcept {
                impl_ = implementation;
                increment();
            }

            /* creates an empty shared pointer with no implementation */
            CSharedPointer() noexcept {
                ; // empty
            }

            /* creates an empty shared pointer with no implementation */
            CSharedPointer(std::nullptr_t) noexcept {
                ; // empty
            }

            ~CSharedPointer() {
                decrement();
            }

            template <typename U>
            validHierarchy<const CSharedPointer<U>&> operator=(const CSharedPointer<U>& rhs) {
                if (impl_ == rhs.impl_)
                    return *this;

                decrement();
                impl_ = rhs.impl_;
                increment();
                return *this;
            }

            CSharedPointer& operator=(const CSharedPointer& rhs) {
                if (impl_ == rhs.impl_)
                    return *this;

                decrement();
                impl_ = rhs.impl_;
                increment();
                return *this;
            }

            template <typename U>
            validHierarchy<const CSharedPointer<U>&> operator=(CSharedPointer<U>&& rhs) {
                std::swap(impl_, rhs.impl_);
                return *this;
            }

            CSharedPointer& operator=(CSharedPointer&& rhs) {
                std::swap(impl_, rhs.impl_);
                return *this;
            }

            operator bool() const {
                return impl_ && impl_->dataNonNull();
            }

            bool operator==(const CSharedPointer& rhs) const {
                return impl_ == rhs.impl_;
            }

            bool operator()(const CSharedPointer& lhs, const CSharedPointer& rhs) const {
                return reinterpret_cast<uintptr_t>(lhs.impl_) < reinterpret_cast<uintptr_t>(rhs.impl_);
            }

            bool operator<(const CSharedPointer& rhs) const {
                return reinterpret_cast<uintptr_t>(impl_) < reinterpret_cast<uintptr_t>(rhs.impl_);
            }

            T* operator->() const {
                return get();
            }

            T& operator*() const {
                return *get();
            }

            void reset() {
                decrement();
                impl_ = nullptr;
            }

            T* get() const {
                return impl_ ? static_cast<T*>(impl_->getData()) : nullptr;
            }

            unsigned int strongRef() const {
                return impl_ ? impl_->ref() : 0;
            }

            CSharedPointer_::impl_base* impl_ = nullptr;

          private:
            /* 
                no-op if there is no impl_
                may delete the stored object if ref == 0
                may delete and reset impl_ if ref == 0 and weak == 0
            */
            void decrement() {
                if (!impl_)
                    return;

                impl_->dec();

                // if ref == 0, we can destroy impl
                if (impl_->ref() == 0)
                    destroyImpl();
            }
            /* no-op if there is no impl_ */
            void increment() {
                if (!impl_)
                    return;

                impl_->inc();
            }

            /* destroy the pointed-to object 
               if able, will also destroy impl */
            void destroyImpl() {
                // destroy the impl contents
                impl_->destroy();

                // check for weak refs, if zero, we can also delete impl_
                if (impl_->wref() == 0) {
                    delete impl_;
                    impl_ = nullptr;
                }
            }
        };

        template <typename U, typename... Args>
        static CSharedPointer<U> makeShared(Args&&... args) {
            return CSharedPointer<U>(new U(std::forward<Args>(args)...));
        }
    }
}

template <typename T>
struct std::hash<Hyprutils::Memory::CSharedPointer<T>> {
    std::size_t operator()(const Hyprutils::Memory::CSharedPointer<T>& p) const noexcept {
        return std::hash<void*>{}(p.impl_);
    }
};070701410ADF35000081A400000000000000000000000166F3441200001853000000080000000100000000000000000000003500000000hyprutils-0.2.3/include/hyprutils/memory/WeakPtr.hpp#pragma once

#include "./SharedPtr.hpp"

/*
    This is a Hyprland implementation of std::weak_ptr.

    See SharedPtr.hpp for more info on how it's different.
*/

namespace Hyprutils {
    namespace Memory {
        template <typename T>
        class CWeakPointer {
          public:
            template <typename X>
            using validHierarchy = typename std::enable_if<std::is_assignable<CWeakPointer<T>&, X>::value, CWeakPointer&>::type;
            template <typename X>
            using isConstructible = typename std::enable_if<std::is_constructible<T&, X&>::value>::type;

            /* create a weak ptr from a reference */
            template <typename U, typename = isConstructible<U>>
            CWeakPointer(const CSharedPointer<U>& ref) noexcept {
                if (!ref.impl_)
                    return;

                impl_ = ref.impl_;
                incrementWeak();
            }

            /* create a weak ptr from another weak ptr */
            template <typename U, typename = isConstructible<U>>
            CWeakPointer(const CWeakPointer<U>& ref) noexcept {
                if (!ref.impl_)
                    return;

                impl_ = ref.impl_;
                incrementWeak();
            }

            CWeakPointer(const CWeakPointer& ref) noexcept {
                if (!ref.impl_)
                    return;

                impl_ = ref.impl_;
                incrementWeak();
            }

            template <typename U, typename = isConstructible<U>>
            CWeakPointer(CWeakPointer<U>&& ref) noexcept {
                std::swap(impl_, ref.impl_);
            }

            CWeakPointer(CWeakPointer&& ref) noexcept {
                std::swap(impl_, ref.impl_);
            }

            /* create a weak ptr from another weak ptr with assignment */
            template <typename U>
            validHierarchy<const CWeakPointer<U>&> operator=(const CWeakPointer<U>& rhs) {
                if (impl_ == rhs.impl_)
                    return *this;

                decrementWeak();
                impl_ = rhs.impl_;
                incrementWeak();
                return *this;
            }

            CWeakPointer<T>& operator=(const CWeakPointer& rhs) {
                if (impl_ == rhs.impl_)
                    return *this;

                decrementWeak();
                impl_ = rhs.impl_;
                incrementWeak();
                return *this;
            }

            /* create a weak ptr from a shared ptr with assignment */
            template <typename U>
            validHierarchy<const CWeakPointer<U>&> operator=(const CSharedPointer<U>& rhs) {
                if (reinterpret_cast<uintptr_t>(impl_) == reinterpret_cast<uintptr_t>(rhs.impl_))
                    return *this;

                decrementWeak();
                impl_ = rhs.impl_;
                incrementWeak();
                return *this;
            }

            /* create an empty weak ptr */
            CWeakPointer() {
                ;
            }

            ~CWeakPointer() {
                decrementWeak();
            }

            /*  expired MAY return true even if the pointer is still stored.
                the situation would be e.g. self-weak pointer in a destructor.
                for pointer validity, use valid() */
            bool expired() const {
                return !impl_ || !impl_->dataNonNull() || impl_->destroying();
            }

            /*  this means the pointed-to object is not yet deleted and can still be
                referenced, but it might be in the process of being deleted. 
                check !expired() if you want to check whether it's valid and
                assignable to a SP. */
            bool valid() const {
                return impl_ && impl_->dataNonNull();
            }

            void reset() {
                decrementWeak();
                impl_ = nullptr;
            }

            CSharedPointer<T> lock() const {
                if (!impl_ || !impl_->dataNonNull() || impl_->destroying())
                    return {};

                return CSharedPointer<T>(impl_);
            }

            /* this returns valid() */
            operator bool() const {
                return valid();
            }

            bool operator==(const CWeakPointer<T>& rhs) const {
                return impl_ == rhs.impl_;
            }

            bool operator==(const CSharedPointer<T>& rhs) const {
                return impl_ == rhs.impl_;
            }

            bool operator()(const CWeakPointer& lhs, const CWeakPointer& rhs) const {
                return reinterpret_cast<uintptr_t>(lhs.impl_) < reinterpret_cast<uintptr_t>(rhs.impl_);
            }

            bool operator<(const CWeakPointer& rhs) const {
                return reinterpret_cast<uintptr_t>(impl_) < reinterpret_cast<uintptr_t>(rhs.impl_);
            }

            T* get() const {
                return impl_ ? static_cast<T*>(impl_->getData()) : nullptr;
            }

            T* operator->() const {
                return get();
            }

            CSharedPointer_::impl_base* impl_ = nullptr;

          private:
            /* no-op if there is no impl_ */
            void decrementWeak() {
                if (!impl_)
                    return;

                impl_->decWeak();

                // we need to check for ->destroying,
                // because otherwise we could destroy here
                // and have a shared_ptr destroy the same thing
                // later (in situations where we have a weak_ptr to self)
                if (impl_->wref() == 0 && impl_->ref() == 0 && !impl_->destroying()) {
                    delete impl_;
                    impl_ = nullptr;
                }
            }
            /* no-op if there is no impl_ */
            void incrementWeak() {
                if (!impl_)
                    return;

                impl_->incWeak();
            }
        };
    }
}

template <typename T>
struct std::hash<Hyprutils::Memory::CWeakPointer<T>> {
    std::size_t operator()(const Hyprutils::Memory::CWeakPointer<T>& p) const noexcept {
        return std::hash<void*>{}(p.impl_);
    }
};
070701000F4E24000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000002700000000hyprutils-0.2.3/include/hyprutils/path07070100113934000081A400000000000000000000000166F3441200000693000000080000000100000000000000000000003000000000hyprutils-0.2.3/include/hyprutils/path/Path.hpp#pragma once
#include "../string/VarList.hpp"
#include <string>
#include <optional>
#include <utility>

namespace Hyprutils {
    namespace Path {
        /** Check whether a config in the form basePath/hypr/programName.conf exists.
            @param basePath the path where the config will be searched
            @param programName name of the program (and config file) to search for
        */
        bool checkConfigExists(const std::string basePath, const std::string programName);

        /** Constructs a full config path given the basePath and programName.
            @param basePath the path where the config hypr/programName.conf is located
            @param programName name of the program (and config file)
        */
        std::string fullConfigPath(const std::string basePath, const std::string programName);

        /** Retrieves the absolute path of the $HOME env variable.
        */
        std::optional<std::string> getHome();

        /** Retrieves a CVarList of paths from the $XDG_CONFIG_DIRS env variable.
        */
        std::optional<String::CVarList> getXdgConfigDirs();

        /** Retrieves the absolute path of the $XDG_CONFIG_HOME env variable.
        */
        std::optional<std::string> getXdgConfigHome();

        /** Searches for a config according to the XDG Base Directory specification.
            Returns a pair of the full path to a config and the base path.
            Returns std::nullopt in case of a non-existent value.
            @param programName name of the program (and config file)
        */

        using T = std::optional<std::string>;
        std::pair<T, T> findConfig(const std::string programName);
    }
}
070701101C584F000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000002900000000hyprutils-0.2.3/include/hyprutils/signal070701101C5860000081A400000000000000000000000166F344120000057F000000080000000100000000000000000000003600000000hyprutils-0.2.3/include/hyprutils/signal/Listener.hpp#pragma once

#include <any>
#include <functional>
#include <hyprutils/memory/SharedPtr.hpp>

namespace Hyprutils {
    namespace Signal {
        class CSignal;

        class CSignalListener {
          public:
            CSignalListener(std::function<void(std::any)> handler);

            CSignalListener(CSignalListener&&)       = delete;
            CSignalListener(CSignalListener&)        = delete;
            CSignalListener(const CSignalListener&)  = delete;
            CSignalListener(const CSignalListener&&) = delete;

            void emit(std::any data);

          private:
            std::function<void(std::any)> m_fHandler;
        };

        typedef Hyprutils::Memory::CSharedPointer<CSignalListener> CHyprSignalListener;

        class CStaticSignalListener {
          public:
            CStaticSignalListener(std::function<void(void*, std::any)> handler, void* owner);

            CStaticSignalListener(CStaticSignalListener&&)       = delete;
            CStaticSignalListener(CStaticSignalListener&)        = delete;
            CStaticSignalListener(const CStaticSignalListener&)  = delete;
            CStaticSignalListener(const CStaticSignalListener&&) = delete;

            void emit(std::any data);

          private:
            void*                                m_pOwner = nullptr;
            std::function<void(void*, std::any)> m_fHandler;
        };
    }
}
070701101C5B21000081A400000000000000000000000166F34412000003A2000000080000000100000000000000000000003400000000hyprutils-0.2.3/include/hyprutils/signal/Signal.hpp#pragma once

#include <functional>
#include <any>
#include <vector>
#include <memory>
#include <hyprutils/memory/WeakPtr.hpp>
#include "./Listener.hpp"

namespace Hyprutils {
    namespace Signal {
        class CSignal {
          public:
            void emit(std::any data = {});

            //
            [[nodiscard("Listener is unregistered when the ptr is lost")]] CHyprSignalListener registerListener(std::function<void(std::any)> handler);

            // this is for static listeners. They die with this signal.
            // TODO: can we somehow rid of the void* data and make it a custom this?
            void registerStaticListener(std::function<void(void*, std::any)> handler, void* owner);

          private:
            std::vector<Hyprutils::Memory::CWeakPointer<CSignalListener>> m_vListeners;
            std::vector<std::unique_ptr<CStaticSignalListener>>           m_vStaticListeners;
        };
    }
}070701200DEE85000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000002900000000hyprutils-0.2.3/include/hyprutils/string070701200DEE86000081A400000000000000000000000166F344120000016E000000080000000100000000000000000000003400000000hyprutils-0.2.3/include/hyprutils/string/String.hpp#pragma once
#include <string>

namespace Hyprutils {
    namespace String {
        // trims beginning and end of whitespace characters
        std::string trim(const std::string& in);
        bool isNumber(const std::string& str, bool allowfloat = false);
        void replaceInString(std::string& string, const std::string& what, const std::string& to);
    };
};070701200DEE87000081A400000000000000000000000166F3441200000820000000080000000100000000000000000000003500000000hyprutils-0.2.3/include/hyprutils/string/VarList.hpp#pragma once
#include <functional>
#include <vector>
#include <string>

namespace Hyprutils {
    namespace String {
        class CVarList {
          public:
            /** Split string into arg list
                @param lastArgNo stop splitting after argv reaches maximum size, last arg will contain rest of unsplit args
                @param delim if delimiter is 's', use std::isspace
                @param removeEmpty remove empty args from argv
            */
            CVarList(const std::string& in, const size_t lastArgNo = 0, const char delim = ',', const bool removeEmpty = false);

            ~CVarList() = default;

            size_t size() const {
                return m_vArgs.size();
            }

            std::string join(const std::string& joiner, size_t from = 0, size_t to = 0) const;

            void        map(std::function<void(std::string&)> func) {
                for (auto& s : m_vArgs)
                    func(s);
            }

            void append(const std::string arg) {
                m_vArgs.emplace_back(arg);
            }

            std::string operator[](const size_t& idx) const {
                if (idx >= m_vArgs.size())
                    return "";
                return m_vArgs[idx];
            }

            // for range-based loops
            std::vector<std::string>::iterator begin() {
                return m_vArgs.begin();
            }
            std::vector<std::string>::const_iterator begin() const {
                return m_vArgs.begin();
            }
            std::vector<std::string>::iterator end() {
                return m_vArgs.end();
            }
            std::vector<std::string>::const_iterator end() const {
                return m_vArgs.end();
            }

            bool contains(const std::string& el) {
                for (auto& a : m_vArgs) {
                    if (a == el)
                        return true;
                }

                return false;
            }

          private:
            std::vector<std::string> m_vArgs;
        };
    }
}
0707013014AD95000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000002800000000hyprutils-0.2.3/include/hyprutils/utils0707013014ECB5000081A400000000000000000000000166F344120000015B000000080000000100000000000000000000003700000000hyprutils-0.2.3/include/hyprutils/utils/ScopeGuard.hpp#pragma once

#include <functional>

namespace Hyprutils {
    namespace Utils {
        // calls a function when it goes out of scope
        class CScopeGuard {
          public:
            CScopeGuard(const std::function<void()>& fn_);
            ~CScopeGuard();

          private:
            std::function<void()> fn;
        };
    };
};
070701410ADF37000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000001400000000hyprutils-0.2.3/nix0707014107C5AF000081A400000000000000000000000166F344120000024A000000080000000100000000000000000000002000000000hyprutils-0.2.3/nix/default.nix{
  lib,
  stdenv,
  cmake,
  pkg-config,
  pixman,
  version ? "git",
  doCheck ? false,
}:
stdenv.mkDerivation {
  pname = "hyprutils";
  inherit version doCheck;
  src = ../.;

  nativeBuildInputs = [
    cmake
    pkg-config
  ];

  buildInputs = [
    pixman
  ];

  outputs = ["out" "dev"];

  cmakeBuildType = "RelWithDebInfo";

  dontStrip = true;

  meta = with lib; {
    homepage = "https://github.com/hyprwm/hyprutils";
    description = "Small C++ library for utilities used across the Hypr* ecosystem";
    license = licenses.bsd3;
    platforms = platforms.linux;
  };
}
07070100115220000041ED00000000000000000000000766F3441200000000000000080000000100000000000000000000001400000000hyprutils-0.2.3/src070701101C5B3E000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000001900000000hyprutils-0.2.3/src/math070701101C68EB000081A400000000000000000000000166F34412000016F1000000080000000100000000000000000000002100000000hyprutils-0.2.3/src/math/Box.cpp#include <hyprutils/math/Box.hpp>
#include <limits>
#include <algorithm>
#include <cmath>

#define VECINRECT(vec, x1, y1, x2, y2) ((vec).x >= (x1) && (vec).x < (x2) && (vec).y >= (y1) && (vec).y < (y2))

using namespace Hyprutils::Math;

constexpr double HALF    = 0.5;
constexpr double DOUBLE  = 2.0;
constexpr double EPSILON = 1e-9;

CBox&            Hyprutils::Math::CBox::scale(double scale) {
    x *= scale;
    y *= scale;
    w *= scale;
    h *= scale;

    return *this;
}

CBox& Hyprutils::Math::CBox::scale(const Vector2D& scale) {
    x *= scale.x;
    y *= scale.y;
    w *= scale.x;
    h *= scale.y;

    return *this;
}

CBox& Hyprutils::Math::CBox::translate(const Vector2D& vec) {
    x += vec.x;
    y += vec.y;

    return *this;
}

Vector2D Hyprutils::Math::CBox::middle() const {
    return Vector2D{x + w * HALF, y + h * HALF};
}

bool Hyprutils::Math::CBox::containsPoint(const Vector2D& vec) const {
    return VECINRECT(vec, x, y, x + w, y + h);
}

bool Hyprutils::Math::CBox::empty() const {
    return std::fabs(w) < EPSILON || std::fabs(h) < EPSILON;
}

CBox& Hyprutils::Math::CBox::round() {
    double roundedX = std::round(x);
    double roundedY = std::round(y);
    double newW     = x + w - roundedX;
    double newH     = y + h - roundedY;

    x = roundedX;
    y = roundedY;
    w = std::round(newW);
    h = std::round(newH);

    return *this;
}

CBox& Hyprutils::Math::CBox::transform(const eTransform t, double w, double h) {

    CBox temp = *this;

    if (t % 2 == 0) {
        width  = temp.width;
        height = temp.height;
    } else {
        width  = temp.height;
        height = temp.width;
    }

    switch (t) {
        case HYPRUTILS_TRANSFORM_NORMAL:
            x = temp.x;
            y = temp.y;
            break;
        case HYPRUTILS_TRANSFORM_90:
            x = h - temp.y - temp.height;
            y = temp.x;
            break;
        case HYPRUTILS_TRANSFORM_180:
            x = w - temp.x - temp.width;
            y = h - temp.y - temp.height;
            break;
        case HYPRUTILS_TRANSFORM_270:
            x = temp.y;
            y = w - temp.x - temp.width;
            break;
        case HYPRUTILS_TRANSFORM_FLIPPED:
            x = w - temp.x - temp.width;
            y = temp.y;
            break;
        case HYPRUTILS_TRANSFORM_FLIPPED_90:
            x = temp.y;
            y = temp.x;
            break;
        case HYPRUTILS_TRANSFORM_FLIPPED_180:
            x = temp.x;
            y = h - temp.y - temp.height;
            break;
        case HYPRUTILS_TRANSFORM_FLIPPED_270:
            x = h - temp.y - temp.height;
            y = w - temp.x - temp.width;
            break;
    }

    return *this;
}

CBox& Hyprutils::Math::CBox::addExtents(const SBoxExtents& e) {
    x -= e.topLeft.x;
    y -= e.topLeft.y;
    w += e.topLeft.x + e.bottomRight.x;
    h += e.topLeft.y + e.bottomRight.y;

    return *this;
}

CBox& Hyprutils::Math::CBox::scaleFromCenter(double scale) {
    double oldW = w, oldH = h;

    w *= scale;
    h *= scale;

    x -= (w - oldW) * HALF;
    y -= (h - oldH) * HALF;

    return *this;
}

CBox& Hyprutils::Math::CBox::expand(const double& value) {
    x -= value;
    y -= value;
    w += value * DOUBLE;
    h += value * DOUBLE;

    if (w <= EPSILON || h <= EPSILON) {
        w = 0;
        h = 0;
    }

    return *this;
}

CBox& Hyprutils::Math::CBox::noNegativeSize() {
    w = std::clamp(w, 0.0, std::numeric_limits<double>::infinity());
    h = std::clamp(h, 0.0, std::numeric_limits<double>::infinity());

    return *this;
}

CBox Hyprutils::Math::CBox::intersection(const CBox& other) const {
    const double newX      = std::max(x, other.x);
    const double newY      = std::max(y, other.y);
    const double newBottom = std::min(y + h, other.y + other.h);
    const double newRight  = std::min(x + w, other.x + other.w);
    double       newW      = newRight - newX;
    double       newH      = newBottom - newY;

    if (newW <= EPSILON || newH <= EPSILON) {
        newW = 0;
        newH = 0;
    }

    return {newX, newY, newW, newH};
}

bool Hyprutils::Math::CBox::overlaps(const CBox& other) const {
    return (other.x + other.w >= x) && (x + w >= other.x) && (other.y + other.h >= y) && (y + h >= other.y);
}

bool Hyprutils::Math::CBox::inside(const CBox& bound) const {
    return bound.x < x && bound.y < y && x + w < bound.x + bound.w && y + h < bound.y + bound.h;
}

CBox Hyprutils::Math::CBox::roundInternal() {
    double flooredX = std::floor(x);
    double flooredY = std::floor(y);
    double newW     = x + w - flooredX;
    double newH     = y + h - flooredY;

    return CBox{flooredX, flooredY, std::floor(newW), std::floor(newH)};
}

CBox Hyprutils::Math::CBox::copy() const {
    return CBox{*this};
}

Vector2D Hyprutils::Math::CBox::pos() const {
    return {x, y};
}

Vector2D Hyprutils::Math::CBox::size() const {
    return {w, h};
}

Vector2D Hyprutils::Math::CBox::extent() const {
  return pos() + size();
}

Vector2D Hyprutils::Math::CBox::closestPoint(const Vector2D& vec) const {
    if (containsPoint(vec))
        return vec;

    Vector2D nv       = vec;
    Vector2D maxPoint = {x + w - EPSILON, y + h - EPSILON};

    if (x < maxPoint.x)
        nv.x = std::clamp(nv.x, x, maxPoint.x);
    else
        nv.x = x;
    if (y < maxPoint.y)
        nv.y = std::clamp(nv.y, y, maxPoint.y);
    else
        nv.y = y;

    if (std::fabs(nv.x - x) < EPSILON)
        nv.x = x;
    else if (std::fabs(nv.x - (maxPoint.x)) < EPSILON)
        nv.x = maxPoint.x;

    if (std::fabs(nv.y - y) < EPSILON)
        nv.y = y;
    else if (std::fabs(nv.y - (maxPoint.y)) < EPSILON)
        nv.y = maxPoint.y;

    return nv;
}

SBoxExtents Hyprutils::Math::CBox::extentsFrom(const CBox& small) {
    return {{small.x - x, small.y - y}, {w - small.w - (small.x - x), h - small.h - (small.y - y)}};
}
070701101C6E80000081A400000000000000000000000166F3441200001402000000080000000100000000000000000000002400000000hyprutils-0.2.3/src/math/Mat3x3.cpp#include <hyprutils/math/Mat3x3.hpp>
#include <hyprutils/math/Vector2D.hpp>
#include <hyprutils/math/Box.hpp>
#include <cmath>
#include <unordered_map>
#include <format>

using namespace Hyprutils::Math;

static std::unordered_map<eTransform, Mat3x3> transforms = {
    {HYPRUTILS_TRANSFORM_NORMAL, std::array<float, 9>{1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}},
    {HYPRUTILS_TRANSFORM_90, std::array<float, 9>{0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}},
    {HYPRUTILS_TRANSFORM_180, std::array<float, 9>{-1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f}},
    {HYPRUTILS_TRANSFORM_270, std::array<float, 9>{0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}},
    {HYPRUTILS_TRANSFORM_FLIPPED, std::array<float, 9>{-1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}},
    {HYPRUTILS_TRANSFORM_FLIPPED_90, std::array<float, 9>{0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}},
    {HYPRUTILS_TRANSFORM_FLIPPED_180, std::array<float, 9>{1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f}},
    {HYPRUTILS_TRANSFORM_FLIPPED_270, std::array<float, 9>{0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}},
};

Mat3x3::Mat3x3() {
    matrix = {0};
}

Mat3x3::Mat3x3(std::array<float, 9> mat) : matrix(mat) {
    ;
}

Mat3x3::Mat3x3(std::vector<float> mat) {
    for (size_t i = 0; i < 9; ++i) {
        matrix.at(i) = mat.size() < i ? mat.at(i) : 0.F;
    }
}

Mat3x3 Mat3x3::identity() {
    return Mat3x3(std::array<float, 9>{1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f});
}

Mat3x3 Mat3x3::outputProjection(const Vector2D& size, eTransform transform) {
    Mat3x3      mat;

    const auto& t = transforms.at(transform);
    float       x = 2.0f / size.x;
    float       y = 2.0f / size.y;

    // Rotation + reflection
    mat.matrix[0] = x * t.matrix[0];
    mat.matrix[1] = x * t.matrix[1];
    mat.matrix[3] = y * t.matrix[3];
    mat.matrix[4] = y * t.matrix[4];

    // Translation
    mat.matrix[2] = -copysign(1.0f, mat.matrix[0] + mat.matrix[1]);
    mat.matrix[5] = -copysign(1.0f, mat.matrix[3] + mat.matrix[4]);

    // Identity
    mat.matrix[8] = 1.0f;

    return mat;
}

std::array<float, 9> Mat3x3::getMatrix() const {
    return matrix;
}

Mat3x3 Mat3x3::projectBox(const CBox& box, eTransform transform, float rot /* rad, CCW */) const {
    Mat3x3     mat = Mat3x3::identity();

    const auto boxSize = box.size();

    mat.translate(box.pos());

    if (rot != 0) {
        mat.translate(boxSize / 2);
        mat.rotate(rot);
        mat.translate(-boxSize / 2);
    }

    mat.scale(boxSize);

    if (transform != HYPRUTILS_TRANSFORM_NORMAL) {
        mat.translate({0.5, 0.5});
        mat.transform(transform);
        mat.translate({-0.5, -0.5});
    }

    return this->copy().multiply(mat);
}

Mat3x3& Mat3x3::transform(eTransform transform) {
    multiply(transforms.at(transform));
    return *this;
}

Mat3x3& Mat3x3::rotate(float rot) {
    multiply(std::array<float, 9>{(float)cos(rot), (float)-sin(rot), 0.0f, (float)sin(rot), (float)cos(rot), 0.0f, 0.0f, 0.0f, 1.0f});
    return *this;
}

Mat3x3& Mat3x3::scale(const Vector2D& scale_) {
    multiply(std::array<float, 9>{(float)scale_.x, 0.0f, 0.0f, 0.0f, (float)scale_.y, 0.0f, 0.0f, 0.0f, 1.0f});
    return *this;
}

Mat3x3& Mat3x3::scale(const float scale_) {
    return scale({scale_, scale_});
}

Mat3x3& Mat3x3::translate(const Vector2D& offset) {
    multiply(std::array<float, 9>{1.0f, 0.0f, (float)offset.x, 0.0f, 1.0f, (float)offset.y, 0.0f, 0.0f, 1.0f});
    return *this;
}

Mat3x3& Mat3x3::transpose() {
    matrix = std::array<float, 9>{matrix[0], matrix[3], matrix[6], matrix[1], matrix[4], matrix[7], matrix[2], matrix[5], matrix[8]};
    return *this;
}

Mat3x3& Mat3x3::multiply(const Mat3x3& other) {
    std::array<float, 9> product;

    product[0] = matrix[0] * other.matrix[0] + matrix[1] * other.matrix[3] + matrix[2] * other.matrix[6];
    product[1] = matrix[0] * other.matrix[1] + matrix[1] * other.matrix[4] + matrix[2] * other.matrix[7];
    product[2] = matrix[0] * other.matrix[2] + matrix[1] * other.matrix[5] + matrix[2] * other.matrix[8];

    product[3] = matrix[3] * other.matrix[0] + matrix[4] * other.matrix[3] + matrix[5] * other.matrix[6];
    product[4] = matrix[3] * other.matrix[1] + matrix[4] * other.matrix[4] + matrix[5] * other.matrix[7];
    product[5] = matrix[3] * other.matrix[2] + matrix[4] * other.matrix[5] + matrix[5] * other.matrix[8];

    product[6] = matrix[6] * other.matrix[0] + matrix[7] * other.matrix[3] + matrix[8] * other.matrix[6];
    product[7] = matrix[6] * other.matrix[1] + matrix[7] * other.matrix[4] + matrix[8] * other.matrix[7];
    product[8] = matrix[6] * other.matrix[2] + matrix[7] * other.matrix[5] + matrix[8] * other.matrix[8];

    matrix = product;
    return *this;
}

Mat3x3 Mat3x3::copy() const {
    return *this;
}

std::string Mat3x3::toString() const {
    return std::format("[mat3x3: {}, {}, {}, {}, {}, {}, {}, {}, {}]", matrix.at(0), matrix.at(1), matrix.at(2), matrix.at(3), matrix.at(4), matrix.at(5), matrix.at(6),
                       matrix.at(7), matrix.at(8));
}
070701101CA1A0000081A400000000000000000000000166F34412000017A7000000080000000100000000000000000000002400000000hyprutils-0.2.3/src/math/Region.cpp#include <hyprutils/math/Region.hpp>
#include <cmath>

using namespace Hyprutils::Math;

constexpr const int64_t MAX_REGION_SIDE = 10000000;

Hyprutils::Math::CRegion::CRegion() {
    pixman_region32_init(&m_rRegion);
}

Hyprutils::Math::CRegion::CRegion(const pixman_region32_t* const ref) {
    pixman_region32_init(&m_rRegion);
    pixman_region32_copy(&m_rRegion, ref);
}

Hyprutils::Math::CRegion::CRegion(double x, double y, double w, double h) {
    pixman_region32_init_rect(&m_rRegion, x, y, w, h);
}

Hyprutils::Math::CRegion::CRegion(const CBox& box) {
    pixman_region32_init_rect(&m_rRegion, box.x, box.y, box.w, box.h);
}

Hyprutils::Math::CRegion::CRegion(pixman_box32_t* box) {
    pixman_region32_init_rect(&m_rRegion, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1);
}

Hyprutils::Math::CRegion::CRegion(const CRegion& other) {
    pixman_region32_init(&m_rRegion);
    pixman_region32_copy(&m_rRegion, const_cast<CRegion*>(&other)->pixman());
}

Hyprutils::Math::CRegion::CRegion(CRegion&& other) {
    pixman_region32_init(&m_rRegion);
    pixman_region32_copy(&m_rRegion, other.pixman());
}

Hyprutils::Math::CRegion::~CRegion() {
    pixman_region32_fini(&m_rRegion);
}

CRegion& Hyprutils::Math::CRegion::clear() {
    pixman_region32_clear(&m_rRegion);
    return *this;
}

CRegion& Hyprutils::Math::CRegion::set(const CRegion& other) {
    pixman_region32_copy(&m_rRegion, const_cast<CRegion*>(&other)->pixman());
    return *this;
}

CRegion& Hyprutils::Math::CRegion::add(const CRegion& other) {
    pixman_region32_union(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman());
    return *this;
}

CRegion& Hyprutils::Math::CRegion::add(double x, double y, double w, double h) {
    pixman_region32_union_rect(&m_rRegion, &m_rRegion, x, y, w, h);
    return *this;
}

CRegion& Hyprutils::Math::CRegion::add(const CBox& other) {
    pixman_region32_union_rect(&m_rRegion, &m_rRegion, other.x, other.y, other.w, other.h);
    return *this;
}

CRegion& Hyprutils::Math::CRegion::subtract(const CRegion& other) {
    pixman_region32_subtract(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman());
    return *this;
}

CRegion& Hyprutils::Math::CRegion::intersect(const CRegion& other) {
    pixman_region32_intersect(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman());
    return *this;
}

CRegion& Hyprutils::Math::CRegion::intersect(double x, double y, double w, double h) {
    pixman_region32_intersect_rect(&m_rRegion, &m_rRegion, x, y, w, h);
    return *this;
}

CRegion& Hyprutils::Math::CRegion::invert(pixman_box32_t* box) {
    pixman_region32_inverse(&m_rRegion, &m_rRegion, box);
    return *this;
}

CRegion& Hyprutils::Math::CRegion::invert(const CBox& box) {
    pixman_box32 pixmanBox = {(int32_t)box.x, (int32_t)box.y, (int32_t)box.w + (int32_t)box.x, (int32_t)box.h + (int32_t)box.y};
    return this->invert(&pixmanBox);
}

CRegion& Hyprutils::Math::CRegion::translate(const Vector2D& vec) {
    pixman_region32_translate(&m_rRegion, vec.x, vec.y);
    return *this;
}

CRegion& Hyprutils::Math::CRegion::transform(const eTransform t, double w, double h) {
    if (t == HYPRUTILS_TRANSFORM_NORMAL)
        return *this;

    auto rects = getRects();

    clear();

    for (auto& r : rects) {
        CBox xfmd{(double)r.x1, (double)r.y1, (double)r.x2 - r.x1, (double)r.y2 - r.y1};
        xfmd.transform(t, w, h);
        add(xfmd);
    }

    return *this;
}

CRegion& Hyprutils::Math::CRegion::expand(double units) {
    auto rects = getRects();

    clear();

    for (auto& r : rects) {
        CBox b{(double)r.x1 - units, (double)r.y1 - units, (double)r.x2 - r.x1 + units * 2, (double)r.y2 - r.y1 + units * 2};
        add(b);
    }

    return *this;
}

CRegion& Hyprutils::Math::CRegion::rationalize() {
    intersect(CBox{-MAX_REGION_SIDE, -MAX_REGION_SIDE, MAX_REGION_SIDE * 2, MAX_REGION_SIDE * 2});
    return *this;
}

CRegion Hyprutils::Math::CRegion::copy() const {
    return CRegion(*this);
}

CRegion& Hyprutils::Math::CRegion::scale(float scale_) {
    scale({scale_, scale_});
    return *this;
}

CRegion& Hyprutils::Math::CRegion::scale(const Vector2D& scale) {
    if (scale == Vector2D{1, 1})
        return *this;

    auto rects = getRects();

    clear();

    for (auto& r : rects) {
        r.x1 = std::floor(r.x1 * scale.x);
        r.y1 = std::floor(r.y1 * scale.x);
        r.x2 = std::ceil(r.x2 * scale.x);
        r.y2 = std::ceil(r.y2 * scale.x);
        add(&r);
    }

    return *this;
}

std::vector<pixman_box32_t> Hyprutils::Math::CRegion::getRects() const {
    std::vector<pixman_box32_t> result;

    int                         rectsNum = 0;
    const auto                  RECTSARR = pixman_region32_rectangles(&m_rRegion, &rectsNum);

    result.assign(RECTSARR, RECTSARR + rectsNum);

    return result;
}

CBox Hyprutils::Math::CRegion::getExtents() {
    pixman_box32_t* box = pixman_region32_extents(&m_rRegion);
    return {(double)box->x1, (double)box->y1, (double)box->x2 - box->x1, (double)box->y2 - box->y1};
}

bool Hyprutils::Math::CRegion::containsPoint(const Vector2D& vec) const {
    return pixman_region32_contains_point(&m_rRegion, vec.x, vec.y, nullptr);
}

bool Hyprutils::Math::CRegion::empty() const {
    return !pixman_region32_not_empty(&m_rRegion);
}

Vector2D Hyprutils::Math::CRegion::closestPoint(const Vector2D& vec) const {
    if (containsPoint(vec))
        return vec;

    double   bestDist = __FLT_MAX__;
    Vector2D leader   = vec;

    for (auto& box : getRects()) {
        double x = 0, y = 0;

        if (vec.x >= box.x2)
            x = box.x2 - 1;
        else if (vec.x < box.x1)
            x = box.x1;
        else
            x = vec.x;

        if (vec.y >= box.y2)
            y = box.y2 - 1;
        else if (vec.y < box.y1)
            y = box.y1;
        else
            y = vec.y;

        double distance = pow(x, 2) + pow(y, 2);
        if (distance < bestDist) {
            bestDist = distance;
            leader   = {x, y};
        }
    }

    return leader;
}070701101D594F000081A400000000000000000000000166F3441200000622000000080000000100000000000000000000002600000000hyprutils-0.2.3/src/math/Vector2D.cpp#include <hyprutils/math/Vector2D.hpp>
#include <algorithm>
#include <cmath>

using namespace Hyprutils::Math;

Hyprutils::Math::Vector2D::Vector2D(double xx, double yy) {
    x = xx;
    y = yy;
}

Hyprutils::Math::Vector2D::Vector2D(int xx, int yy) {
    x = (double)xx;
    y = (double)yy;
}

Hyprutils::Math::Vector2D::Vector2D() {
    x = 0;
    y = 0;
}

Hyprutils::Math::Vector2D::~Vector2D() {}

double Hyprutils::Math::Vector2D::normalize() {
    // get max abs
    const auto max = std::abs(x) > std::abs(y) ? std::abs(x) : std::abs(y);

    x /= max;
    y /= max;

    return max;
}

Vector2D Hyprutils::Math::Vector2D::floor() const {
    return Vector2D(std::floor(x), std::floor(y));
}

Vector2D Hyprutils::Math::Vector2D::round() const {
    return Vector2D(std::round(x), std::round(y));
}

Vector2D Hyprutils::Math::Vector2D::clamp(const Vector2D& min, const Vector2D& max) const {
    return Vector2D(std::clamp(this->x, min.x, max.x < min.x ? INFINITY : max.x), std::clamp(this->y, min.y, max.y < min.y ? INFINITY : max.y));
}

double Hyprutils::Math::Vector2D::distance(const Vector2D& other) const {
    return std::sqrt(distanceSq(other));
}

double Hyprutils::Math::Vector2D::distanceSq(const Vector2D& other) const {
    return (x - other.x) * (x - other.x) + (y - other.y) * (y - other.y);
}

double Hyprutils::Math::Vector2D::size() const {
    return std::sqrt(x * x + y * y);
}

Vector2D Hyprutils::Math::Vector2D::getComponentMax(const Vector2D& other) const {
    return Vector2D(std::max(this->x, other.x), std::max(this->y, other.y));
}
070701200DEE88000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000001900000000hyprutils-0.2.3/src/path070701200DEE89000081A400000000000000000000000166F3441200000B2A000000080000000100000000000000000000002200000000hyprutils-0.2.3/src/path/Path.cpp#include <hyprutils/path/Path.hpp>
#include <hyprutils/string/VarList.hpp>
#include <filesystem>

using namespace Hyprutils;

namespace Hyprutils::Path {
    std::string fullConfigPath(std::string basePath, std::string programName) {
        return basePath + "/hypr/" + programName + ".conf";
    }

    bool checkConfigExists(std::string basePath, std::string programName) {
        return std::filesystem::exists(fullConfigPath(basePath, programName));
    }

    std::optional<std::string> getHome() {
        static const auto homeDir = getenv("HOME");

        if (!homeDir || !std::filesystem::path(homeDir).is_absolute())
            return std::nullopt;

        return std::string(homeDir).append("/.config");
    }

    std::optional<String::CVarList> getXdgConfigDirs() {
        static const auto xdgConfigDirs = getenv("XDG_CONFIG_DIRS");

        if (!xdgConfigDirs)
            return std::nullopt;

        static const auto xdgConfigDirsList = String::CVarList(xdgConfigDirs, 0, ':');

        return xdgConfigDirsList;
    }

    std::optional<std::string> getXdgConfigHome() {
        static const auto xdgConfigHome = getenv("XDG_CONFIG_HOME");

        if (!xdgConfigHome || !std::filesystem::path(xdgConfigHome).is_absolute())
            return std::nullopt;

        return xdgConfigHome;
    }

    using T = std::optional<std::string>;
    std::pair<T, T> findConfig(std::string programName) {
        bool              xdgConfigHomeExists = false;
        static const auto xdgConfigHome       = getXdgConfigHome();
        if (xdgConfigHome.has_value()) {
            xdgConfigHomeExists = true;
            if (checkConfigExists(xdgConfigHome.value(), programName))
                return std::make_pair(fullConfigPath(xdgConfigHome.value(), programName), xdgConfigHome);
        }

        bool              homeExists = false;
        static const auto home       = getHome();
        if (home.has_value()) {
            homeExists = true;
            if (checkConfigExists(home.value(), programName))
                return std::make_pair(fullConfigPath(home.value(), programName), home);
        }

        static const auto xdgConfigDirs = getXdgConfigDirs();
        if (xdgConfigDirs.has_value()) {
            for (auto dir : xdgConfigDirs.value()) {
                if (checkConfigExists(dir, programName))
                    return std::make_pair(fullConfigPath(dir, programName), std::nullopt);
            }
        }

        if (checkConfigExists("/etc/xdg", programName))
            return std::make_pair(fullConfigPath("/etc/xdg", programName), std::nullopt);

        if (xdgConfigHomeExists)
            return std::make_pair(std::nullopt, xdgConfigHome);
        else if (homeExists)
            return std::make_pair(std::nullopt, home);

        return std::make_pair(std::nullopt, std::nullopt);
    }
}
0707013019D3EF000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000001B00000000hyprutils-0.2.3/src/signal07070130272B20000081A400000000000000000000000166F344120000025C000000080000000100000000000000000000002800000000hyprutils-0.2.3/src/signal/Listener.cpp#include <hyprutils/signal/Listener.hpp>

using namespace Hyprutils::Signal;

Hyprutils::Signal::CSignalListener::CSignalListener(std::function<void(std::any)> handler) : m_fHandler(handler) {
    ;
}

void Hyprutils::Signal::CSignalListener::emit(std::any data) {
    if (!m_fHandler)
        return;

    m_fHandler(data);
}

Hyprutils::Signal::CStaticSignalListener::CStaticSignalListener(std::function<void(void*, std::any)> handler, void* owner) : m_pOwner(owner), m_fHandler(handler) {
    ;
}

void Hyprutils::Signal::CStaticSignalListener::emit(std::any data) {
    m_fHandler(m_pOwner, data);
}
07070130282CBA000081A400000000000000000000000166F34412000006A5000000080000000100000000000000000000002600000000hyprutils-0.2.3/src/signal/Signal.cpp#include <hyprutils/signal/Signal.hpp>
#include <hyprutils/memory/WeakPtr.hpp>
#include <algorithm>

using namespace Hyprutils::Signal;
using namespace Hyprutils::Memory;

#define SP CSharedPointer
#define WP CWeakPointer

void Hyprutils::Signal::CSignal::emit(std::any data) {
    std::vector<SP<CSignalListener>> listeners;
    for (auto& l : m_vListeners) {
        if (l.expired())
            continue;

        listeners.emplace_back(l.lock());
    }

    std::vector<CStaticSignalListener*> statics;
    for (auto& l : m_vStaticListeners) {
        statics.emplace_back(l.get());
    }

    for (auto& l : listeners) {
        // if there is only one lock, it means the event is only held by the listeners
        // vector and was removed during our iteration
        if (l.strongRef() == 1)
            continue;
        
        l->emit(data);
    }

    for (auto& l : statics) {
        l->emit(data);
    }

    // release SPs
    listeners.clear();

    // we cannot release any expired refs here as one of the listeners could've removed this object and 
    // as such we'd be doing a UAF
}

CHyprSignalListener Hyprutils::Signal::CSignal::registerListener(std::function<void(std::any)> handler) {
    CHyprSignalListener listener = makeShared<CSignalListener>(handler);
    m_vListeners.emplace_back(listener);

    // housekeeping: remove any stale listeners
    std::erase_if(m_vListeners, [](const auto& other) { return other.expired(); });
    
    return listener;
}

void Hyprutils::Signal::CSignal::registerStaticListener(std::function<void(void*, std::any)> handler, void* owner) {
    m_vStaticListeners.emplace_back(std::make_unique<CStaticSignalListener>(handler, owner));
}0707014005C2C6000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000001B00000000hyprutils-0.2.3/src/string0707014005C2D2000081A400000000000000000000000166F3441200000694000000080000000100000000000000000000002600000000hyprutils-0.2.3/src/string/String.cpp#include <algorithm>
#include <hyprutils/string/String.hpp>

using namespace Hyprutils::String;

std::string Hyprutils::String::trim(const std::string& in) {
    if (in.empty())
        return in;

    int countBefore = 0;
    while (countBefore < in.length() && std::isspace(in.at(countBefore))) {
        countBefore++;
    }

    int countAfter = 0;
    while (countAfter < in.length() - countBefore && std::isspace(in.at(in.length() - countAfter - 1))) {
        countAfter++;
    }

    std::string result = in.substr(countBefore, in.length() - countBefore - countAfter);

    return result;
}

bool Hyprutils::String::isNumber(const std::string& str, bool allowfloat) {
    if (str.empty())
        return false;

    bool decimalParsed = false;

    for (size_t i = 0; i < str.length(); ++i) {
        const char& c = str.at(i);

        if (i == 0 && str.at(i) == '-') {
            // only place where we allow -
            continue;
        }

        if (!isdigit(c)) {
            if (!allowfloat)
                return false;

            if (c != '.')
                return false;

            if (i == 0)
                return false;

            if (decimalParsed)
                return false;

            decimalParsed = true;

            continue;
        }
    }

    if (!isdigit(str.back()))
        return false;

    return true;
}

void Hyprutils::String::replaceInString(std::string& string, const std::string& what, const std::string& to) {
    if (string.empty())
        return;
    size_t pos = 0;
    while ((pos = string.find(what, pos)) != std::string::npos) {
        string.replace(pos, what.length(), to);
        pos += to.length();
    }
}
0707014005C2D5000081A400000000000000000000000166F34412000004B2000000080000000100000000000000000000002700000000hyprutils-0.2.3/src/string/VarList.cpp#include <ranges>
#include <algorithm>
#include <hyprutils/string/VarList.hpp>
#include <hyprutils/string/String.hpp>

using namespace Hyprutils::String;

Hyprutils::String::CVarList::CVarList(const std::string& in, const size_t lastArgNo, const char delim, const bool removeEmpty) {
    if (!removeEmpty && in.empty())
        m_vArgs.emplace_back("");

    std::string args{in};
    size_t      idx = 0;
    size_t      pos = 0;
    std::ranges::replace_if(
        args, [&](const char& c) { return delim == 's' ? std::isspace(c) : c == delim; }, 0);

    for (const auto& s : args | std::views::split(0)) {
        if (removeEmpty && s.empty())
            continue;
        if (++idx == lastArgNo) {
            m_vArgs.emplace_back(trim(in.substr(pos)));
            break;
        }
        pos += s.size() + 1;
        m_vArgs.emplace_back(trim(std::string_view{s}.data()));
    }
}

std::string Hyprutils::String::CVarList::join(const std::string& joiner, size_t from, size_t to) const {
    size_t      last = to == 0 ? size() : to;

    std::string rolling;
    for (size_t i = from; i < last; ++i) {
        rolling += m_vArgs[i] + (i + 1 < last ? joiner : "");
    }

    return rolling;
}0707010011C7E5000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000001A00000000hyprutils-0.2.3/src/utils0707010011C7EB000081A400000000000000000000000166F34412000000FC000000080000000100000000000000000000002900000000hyprutils-0.2.3/src/utils/ScopeGuard.cpp#include <hyprutils/utils/ScopeGuard.hpp>

using namespace Hyprutils::Utils;

Hyprutils::Utils::CScopeGuard::CScopeGuard(const std::function<void()>& fn_) : fn(fn_) {
    ;
}

Hyprutils::Utils::CScopeGuard::~CScopeGuard() {
    if (fn)
        fn();
}
070701101D5951000041ED00000000000000000000000266F3441200000000000000080000000100000000000000000000001600000000hyprutils-0.2.3/tests070701101D8DF0000081A400000000000000000000000166F3441200000B8F000000080000000100000000000000000000001F00000000hyprutils-0.2.3/tests/math.cpp#include <hyprutils/math/Region.hpp>
#include <hyprutils/math/Mat3x3.hpp>
#include "shared.hpp"

using namespace Hyprutils::Math;

int main(int argc, char** argv, char** envp) {
    CRegion rg = {0, 0, 100, 100};
    rg.add(CBox{{}, {20, 200}});

    int ret = 0;

    EXPECT(rg.getExtents().height, 200);
    EXPECT(rg.getExtents().width, 100);

    rg.intersect(CBox{10, 10, 300, 300});

    EXPECT(rg.getExtents().width, 90);
    EXPECT(rg.getExtents().height, 190);

    /*Box.cpp test cases*/
    // Test default constructor and accessors
    {
        CBox box1;
        EXPECT(box1.x, 0);
        EXPECT(box1.y, 0);
        EXPECT(box1.width, 0);
        EXPECT(box1.height, 0);

        // Test parameterized constructor and accessors
        CBox box2(10, 20, 30, 40);
        EXPECT(box2.x, 10);
        EXPECT(box2.y, 20);
        EXPECT(box2.width, 30);
        EXPECT(box2.height, 40);

        // Test setters and getters
        box2.translate(Vector2D(5, -5));
        EXPECT_VECTOR2D(box2.pos(), Vector2D(15, 15));
    }

    //Test Scaling and Transformation
    {
        CBox box(10, 10, 20, 30);

        // Test scaling
        box.scale(2.0);
        EXPECT_VECTOR2D(box.size(), Vector2D(40, 60));
        EXPECT_VECTOR2D(box.pos(), Vector2D(20, 20));

        // Test scaling from center
        box.scaleFromCenter(0.5);
        EXPECT_VECTOR2D(box.size(), Vector2D(20, 30));
        EXPECT_VECTOR2D(box.pos(), Vector2D(30, 35));

        // Test transformation
        box.transform(HYPRUTILS_TRANSFORM_90, 100, 200);
        EXPECT_VECTOR2D(box.pos(), Vector2D(135, 30));
        EXPECT_VECTOR2D(box.size(), Vector2D(30, 20));

        // Test Intersection and Extents
    }

    {
        CBox box1(0, 0, 100, 100);
        CBox box2(50, 50, 100, 100);

        CBox intersection = box1.intersection(box2);
        EXPECT_VECTOR2D(intersection.pos(), Vector2D(50, 50));
        EXPECT_VECTOR2D(intersection.size(), Vector2D(50, 50));

        SBoxExtents extents = box1.extentsFrom(box2);
        EXPECT_VECTOR2D(extents.topLeft, Vector2D(50, 50));
        EXPECT_VECTOR2D(extents.bottomRight, Vector2D(-50, -50));
    }

    // Test Boundary Conditions and Special Cases
    {
        CBox box(0, 0, 50, 50);

        EXPECT(box.empty(), false);

        EXPECT(box.containsPoint(Vector2D(25, 25)), true);
        EXPECT(box.containsPoint(Vector2D(60, 60)), false);
        EXPECT(box.overlaps(CBox(25, 25, 50, 50)), true);
        EXPECT(box.inside(CBox(0, 0, 100, 100)), false);
    }

    // Test matrices
    {
        Mat3x3 jeremy = Mat3x3::outputProjection({1920, 1080}, HYPRUTILS_TRANSFORM_FLIPPED_90);
        Mat3x3 matrixBox = jeremy.projectBox(CBox{10, 10, 200, 200}, HYPRUTILS_TRANSFORM_NORMAL).translate({100, 100}).scale({1.25F, 1.5F}).transpose();

        Mat3x3 expected = std::array<float, 9>{0, 0.46296296, 0, 0.3125, 0, 0, 19.84375, 36.055557, 1};
        EXPECT(matrixBox, expected);
    }

    return ret;
}070701101DE04D000081A400000000000000000000000166F344120000021E000000080000000100000000000000000000002100000000hyprutils-0.2.3/tests/memory.cpp#include <hyprutils/memory/WeakPtr.hpp>
#include "shared.hpp"

using namespace Hyprutils::Memory;

#define SP CSharedPointer
#define WP CWeakPointer

int main(int argc, char** argv, char** envp) {
    SP<int> intPtr = makeShared<int>(10);

    int ret = 0;

    EXPECT(*intPtr, 10);
    EXPECT(intPtr.strongRef(), 1);

    WP<int> weak = intPtr;

    EXPECT(*intPtr, 10);
    EXPECT(intPtr.strongRef(), 1);
    EXPECT(*weak.get(), 10);
    EXPECT(weak.expired(), false);

    intPtr = {};

    EXPECT(weak.expired(), true);

    return ret;
}070701101DE04E000081A400000000000000000000000166F3441200000DA2000000080000000100000000000000000000002100000000hyprutils-0.2.3/tests/shared.hpp#pragma once
#include <iostream>

namespace Colors {
    constexpr const char* RED     = "\x1b[31m";
    constexpr const char* GREEN   = "\x1b[32m";
    constexpr const char* YELLOW  = "\x1b[33m";
    constexpr const char* BLUE    = "\x1b[34m";
    constexpr const char* MAGENTA = "\x1b[35m";
    constexpr const char* CYAN    = "\x1b[36m";
    constexpr const char* RESET   = "\x1b[0m";
};

#define EXPECT(expr, val)                                                                                                                                                          \
    if (const auto RESULT = expr; RESULT != (val)) {                                                                                                                               \
        std::cout << Colors::RED << "Failed: " << Colors::RESET << #expr << ", expected " << val << " but got " << RESULT << "\n";                                                \
        ret = 1;                                                                                                                                                                   \
    } else {                                                                                                                                                                       \
        std::cout << Colors::GREEN << "Passed " << Colors::RESET << #expr << ". Got " << val << "\n";                                                                              \
    }
#define EXPECT_VECTOR2D(expr, val)                                                                                                                                                 \
    do {                                                                                                                                                                           \
        const auto& RESULT   = expr;                                                                                                                                               \
        const auto& EXPECTED = val;                                                                                                                                                \
        if (!(std::abs(RESULT.x - EXPECTED.x) < 1e-6 && std::abs(RESULT.y - EXPECTED.y) < 1e-6)) {                                                                                 \
            std::cout << Colors::RED << "Failed: " << Colors::RESET << #expr << ", expected (" << EXPECTED.x << ", " << EXPECTED.y << ") but got (" << RESULT.x << ", "            \
                      << RESULT.y << ")\n";                                                                                                                                        \
            ret = 1;                                                                                                                                                               \
        } else {                                                                                                                                                                   \
            std::cout << Colors::GREEN << "Passed " << Colors::RESET << #expr << ". Got (" << RESULT.x << ", " << RESULT.y << ")\n";                                               \
        }                                                                                                                                                                          \
    } while (0)
070701101DE071000081A400000000000000000000000166F34412000001F9000000080000000100000000000000000000002100000000hyprutils-0.2.3/tests/signal.cpp#include <hyprutils/signal/Signal.hpp>
#include <hyprutils/memory/WeakPtr.hpp>
#include "shared.hpp"

using namespace Hyprutils::Signal;
using namespace Hyprutils::Memory;

int main(int argc, char** argv, char** envp) {
    int ret = 0;

    CSignal signal;
    int data = 0;
    auto listener = signal.registerListener([&] (std::any d) {
        data = 1;
    });

    signal.emit();

    EXPECT(data, 1);

    data = 0;

    listener.reset();

    signal.emit();

    EXPECT(data, 0);

    return ret;
}070701101D5961000081A400000000000000000000000166F34412000005E9000000080000000100000000000000000000002100000000hyprutils-0.2.3/tests/string.cpp#include <hyprutils/string/String.hpp>
#include <hyprutils/string/VarList.hpp>
#include "shared.hpp"

using namespace Hyprutils::String;

int main(int argc, char** argv, char** envp) {
    int ret = 0;

    EXPECT(trim("               a             "), "a");
    EXPECT(trim("   a   a           "), "a   a");
    EXPECT(trim("a"), "a");
    EXPECT(trim("                           "), "");

    EXPECT(isNumber("99214123434"), true);
    EXPECT(isNumber("-35252345234"), true);
    EXPECT(isNumber("---3423--432"), false);
    EXPECT(isNumber("s---3423--432"), false);
    EXPECT(isNumber("---3423--432s"), false);
    EXPECT(isNumber("1s"), false);
    EXPECT(isNumber(""), false);
    EXPECT(isNumber("-"), false);
    EXPECT(isNumber("--0"), false);
    EXPECT(isNumber("abc"), false);
    EXPECT(isNumber("0.0", true), true);
    EXPECT(isNumber("0.2", true), true);
    EXPECT(isNumber("0.", true), false);
    EXPECT(isNumber(".0", true), false);
    EXPECT(isNumber("", true), false);
    EXPECT(isNumber("vvss", true), false);
    EXPECT(isNumber("0.9999s", true), false);
    EXPECT(isNumber("s0.9999", true), false);
    EXPECT(isNumber("-1.0", true), true);
    EXPECT(isNumber("-1..0", true), false);
    EXPECT(isNumber("-10.0000000001", true), true);

    CVarList list("hello    world!", 0, 's', true);
    EXPECT(list[0], "hello");
    EXPECT(list[1], "world!");

    std::string hello = "hello world!";
    replaceInString(hello, "hello", "hi");
    EXPECT(hello, "hi world!");

    return ret;
}07070100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!
openSUSE Build Service is sponsored by