// kalyna.cpp - written and placed in the public domain by Jeffrey Walton
//              This code relied upon three sources. First was Oliynykov, Gorbenko, Kazymyrov, Ruzhentsev,
//              Kuznetsov, Gorbenko, Dyrda, Dolgov, Pushkaryov, Mordvinov and Kaidalov's "A New Encryption
//              Standard of Ukraine: The Kalyna Block Cipher" (http://eprint.iacr.org/2015/650.pdf). Second
//              was Roman Oliynykov and Oleksandr Kazymyrov's GitHub with the reference implementation
//              (http://github.com/Roman-Oliynykov/Kalyna-reference). The third and most utilized resource
//              was Keru Kuro's public domain implementation of Kalyna in CppCrypto
//              (http://sourceforge.net/projects/cppcrypto/). Kuro has an outstanding implementation that
//              performed better than the reference implementation and our initial attempts. The only downside
//              was the missing big endian port.

#include "pch.h"
#include "config.h"

#include "kalyna.h"
#include "argnames.h"
#include "misc.h"
#include "cpu.h"

NAMESPACE_BEGIN(CryptoPP)
NAMESPACE_BEGIN(KalynaTab)

// T can be shared between Kupyna and Kalyna; IT, S and IS are Kalyna specific
extern const word64 T[8][256];  // Columns
extern const word64 IT[8][256]; // Inverse
extern const byte S[4][256];    // Substitution
extern const byte IS[4][256];   // Inverse

NAMESPACE_END
NAMESPACE_END

ANONYMOUS_NAMESPACE_BEGIN

// The typedef here is to sidestep problems with byte in the global namespace
typedef unsigned char byte;

using CryptoPP::word64;
using CryptoPP::KalynaTab::T;
using CryptoPP::KalynaTab::S;
using CryptoPP::KalynaTab::IT;
using CryptoPP::KalynaTab::IS;

template <unsigned int NB>
inline void MakeOddKey(const word64 evenkey[NB], word64 oddkey[NB])
{
#if (CRYPTOPP_BIG_ENDIAN)
    if (NB == 2)
    {
        oddkey[0] = (evenkey[1] << 8) | (evenkey[0] >> 56);
        oddkey[1] = (evenkey[0] << 8) | (evenkey[1] >> 56);
    }
    else if (NB == 4)
    {
        oddkey[0] = (evenkey[2] << 40) | (evenkey[1] >> 24);
        oddkey[1] = (evenkey[3] << 40) | (evenkey[2] >> 24);
        oddkey[2] = (evenkey[0] << 40) | (evenkey[3] >> 24);
        oddkey[3] = (evenkey[1] << 40) | (evenkey[0] >> 24);
    }
    else if (NB == 8)
    {
        oddkey[0] = (evenkey[3] << 40) | (evenkey[2] >> 24);
        oddkey[1] = (evenkey[4] << 40) | (evenkey[3] >> 24);
        oddkey[2] = (evenkey[5] << 40) | (evenkey[4] >> 24);
        oddkey[3] = (evenkey[6] << 40) | (evenkey[5] >> 24);

        oddkey[4] = (evenkey[7] << 40) | (evenkey[6] >> 24);
        oddkey[5] = (evenkey[0] << 40) | (evenkey[7] >> 24);
        oddkey[6] = (evenkey[1] << 40) | (evenkey[0] >> 24);
        oddkey[7] = (evenkey[2] << 40) | (evenkey[1] >> 24);
    }
    else
    {
        CRYPTOPP_ASSERT(0);
    }
#else
    static const unsigned int U = (NB == 2) ? 16 : (NB == 4) ? 32 : (NB == 8) ? 64 : -1;
    static const unsigned int V = (NB == 2) ?  7 : (NB == 4) ? 11 : (NB == 8) ? 19 : -1;

    const byte* even = reinterpret_cast<const byte*>(evenkey);
    byte* odd = reinterpret_cast<byte*>(oddkey);

    std::memcpy(odd, even + V, U - V);
    std::memcpy(odd + U - V, even, V);
#endif
}

template <unsigned int NB>
inline void SwapBlocks(word64 k[NB])
{
    const word64 t = k[0];
    k[0] = k[1];

    if (NB > 2)
    {
        k[1] = k[2];
        k[2] = k[3];
    }

    if (NB > 4)
    {
        k[3] = k[4];
        k[4] = k[5];
        k[5] = k[6];
        k[6] = k[7];
    }

    k[NB - 1] = t;
}

template <unsigned int NB>
inline void AddKey(const word64 x[NB], word64 y[NB], const word64 k[NB])
{
    y[0] = x[0] + k[0];
    y[1] = x[1] + k[1];

    if (NB > 2)
    {
        y[2] = x[2] + k[2];
        y[3] = x[3] + k[3];
    }

    if (NB > 4)
    {
        y[4] = x[4] + k[4];
        y[5] = x[5] + k[5];
        y[6] = x[6] + k[6];
        y[7] = x[7] + k[7];
    }
}

template <unsigned int NB>
inline void SubKey(const word64 x[NB], word64 y[NB], const word64 k[NB])
{
    y[0] = x[0] - k[0];
    y[1] = x[1] - k[1];

    if (NB > 2)
    {
        y[2] = x[2] - k[2];
        y[3] = x[3] - k[3];
    }

    if (NB > 4)
    {
        y[4] = x[4] - k[4];
        y[5] = x[5] - k[5];
        y[6] = x[6] - k[6];
        y[7] = x[7] - k[7];
    }
}

template <unsigned int NB>
static inline void AddConstant(word64 src[NB], word64 dst[NB], word64 constant)
{
    dst[0] = src[0] + constant;
    dst[1] = src[1] + constant;

    if (NB > 2)
    {
        dst[2] = src[2] + constant;
        dst[3] = src[3] + constant;
    }

    if (NB > 4)
    {
        dst[4] = src[4] + constant;
        dst[5] = src[5] + constant;
        dst[6] = src[6] + constant;
        dst[7] = src[7] + constant;
    }
}

inline void G0128(const word64 x[2], word64 y[2])
{
    y[0] = T[0][(byte)x[0]] ^ T[1][(byte)(x[0]


#include <iostream>

// Global dimension variables
const unsigned int ROWS = 3;
const unsigned int COLS = 3;

// Function to print out the board
void printBoard(char** positions) {
  // Clear screen and print header
  std::cout << "\033[H\033[J    A | B | C \n";

  // Print rows
  for (int i = 0; i < ROWS; ++i) {
    std::cout << "   ---|---|---\n";
    std::cout << " " << i << "  " << positions[i][0] << " | " << positions[i][1] << " | " << positions[i][2] << "\n";
  }

  // Add spacing for input text
  std::cout << "\n\n";
}

bool check_for_draw(char** positions) {
  for (int i = 0; i < ROWS; ++i) {
    for (int j = 0; j < COLS; ++j) {
      if (positions[i][j] == ' ') { return false; }
    }
  }
  return true;
}

bool check_for_win(char** positions) {
  // Check for a horizontal win
  char initialChar;
  bool match = true;

  // Scan across each row and check if the initial character matches the next two.
  for (int i = 0; i < ROWS; ++i) {
    initialChar = positions[i][0];
    if (initialChar != ' ') {
      for (int j = 1; j < COLS; ++j) {
	if (initialChar != positions[i][j]) {
	  match = false;
	}
      }
      if (match) { return true; }
    }
  }

  // Scan across each column and check if the initial character matches the next two.
  match = true;
  for (int i = 0; i < COLS; ++i) {
    initialChar = positions[0][i];
    if (initialChar != ' ') {
      for (int j = 0; j < ROWS; ++j) {
	if (initialChar != positions[j][i]) {
	  match = false;
	}
      }
      if (match) { return true; }
    }
  }

  // Scan across each diagonal..
  // Left up to right down (LU-RD)
  match = true;
  initialChar = positions[0][0];
  if (initialChar != ' ') {
    for (int i = 1; i < ROWS; ++i) {
      if (initialChar != positions[i][i]) {
	match = false;
      }
    }
    if (match) { return true; }
  }

  // Right up to left down (RU-LD)
  match = true;
  initialChar = positions[0][2];
  if (initialChar != ' ') {
    for (int i = 1; i < ROWS; ++i) {
      if (initialChar != positions[i][COLS-1-i]) {
	match = false;
      }
    }
    if (match) { return true; }
  }

  return false;
}

int main() {
  char** positions = new char*[ROWS];
  char toPlace[3];

  // Loop variables that infer results
  bool running = true;
  bool hasWon = false;
  bool player1 = true;

  // Variables for converting input to position selection
  unsigned int columnChoice;
  unsigned int rowChoice;

  // Post game result
  unsigned int player1Wins = 0;
  unsigned int player2Wins = 0;
  char playAgain;

  // Allocate memory and assign white space
  for (int i = 0; i < ROWS; ++i) {
    positions[i] = new char[COLS];
    for (int j = 0; j < COLS; ++j) {
      positions[i][j] = ' ';
    }
  }

  while (running) {

    // Each game of tictactoe
    hasWon = false;
    player1 = true;
    while (not hasWon) {
      // Print the board to the user
      printBoard(positions);

      std::cout << "It is " << ((player1) ? "PLAYER 1" : "PLAYER 2") << "\'s turn.\nPlease input the column followed by the row (e.x. a1, b3) > ";
      std::cin >> toPlace;

      // Lowercase the input, then use ascii conversion to check to see if it is within the range
      // Also, convert the row choice to an actual integer
      columnChoice = std::tolower(toPlace[0]) - 'a';
      rowChoice = toPlace[1] - '0';
      if (columnChoice > 2 or rowChoice > 2) {
	std::cout << "\nInvalid column or row choice. Please try again. (press ENTER to continue)\n";
	std::cin.ignore(10000, '\n');
	std::cin.get();
      }
      else {

	// Now, check to see if the space is already taken
	if (positions[rowChoice][columnChoice] != ' ') {
	  std::cout << "\nYour selection is already filled, try another spot. (press ENTER to continue)\n";
	  std::cin.ignore(10000, '\n');
	  std::cin.get();
	}
	else {

	  // The space is open!! Now, assign the player's piece to this spot.
	  positions[rowChoice][columnChoice] = (player1) ? 'X' : 'O';

	  // Check for win or draw
	  if (check_for_win(positions)) {
	    hasWon = true;
	    printBoard(positions);

	    // Add wins to the player
	    if (player1) { ++player1Wins; }
	    else { ++player2Wins; }

	    std::cout << "CONGRATULATIONS TO " << ((player1) ? "PLAYER 1" : "PLAYER 2") << "!!!\n";
	    std::cout << "Player 1 has " << player1Wins << " wins and Player 2 has " << player2Wins << "!\n";
	  }
	  else if (check_for_draw(positions)) {
	    std::cout << "Both players have drawn.\n";
	  }
	  else {
	    player1 = not player1;
	  }
	}
      }
    }

    std::cout << "\nWould you like to play again (y/n) > ";
    std::cin >> playAgain;
    if (playAgain != 'y') {
      running = false;
    }

    for (int i = 0; i < ROWS; ++i) {
      for (int j = 0; j < COLS; ++j) {
	positions[i][j] = ' ';
      }
    }
  }

  // Deallocate memory
  for (int i = 0; i < ROWS; ++i) {
    delete [] positions[i];
  }
  delete [] positions;

  return 0;
}


// multiple virtual

#include<iostream>
using namespace std;
#include<string>

class Vehicle{
    public:
    int tyresize;
    int speed;
    virtual voidcxx


#include<windows.h>
#include<iostream>
#include <GL/glut.h>
#include<math.h>
#include<vector>
#include<utility>
#include<mmsystem.h>
using namespace std;

//Animation parameters
float _moveSun= 0.0f;
float _moveCloud=0.0f;
float _moveBus=0.0f;
float _moveAmbulance=0.0f;
void HeadlightEffect()
{

    glBegin(GL_POLYGON);
    glColor3ub(255, 255, 131);
    glVertex2d(210.3590012512302, 76.5665817179349);
    glVertex2d(269.5623337234856, 95.9958006664856);
    glVertex2d(264.8016436547303, 93.700115596967);
    glVertex2d(261.33058509551, 91.4142965457732);
    glVertex2d(258.2828263605849, 88.112557916271);
    glVertex2d(255.827687379673, 83.3715998841652);
    glVertex2d(254.8117678013646, 78.2920019926234);
    glVertex2d(255.2350676256598, 73.3817240307996);
    glVertex2d(255.9970073093911, 69.9953254364383);
    glVertex2d(257.6055466417126, 67.0322266663722);
    glVertex2d(260.9919452360739, 63.5611681071519);
    glVertex2d(265.9868831627567, 59.6668097236365);
    glVertex2d(268.4420221436686, 58.6508901453281);
    glVertex2d(210.3590012512302, 76.5665817179349);
    glEnd();
}
//Day Scene parameters Predefined
int sky1R=203,sky1G=212,sky1B=137; // Sky color 1st shading
int sky2R=127,sky2G=212,sky2B=239;  // Sky color 2nd shading
int SunMoonR=252,SunMoonG=181,SunMoonB=77;//Sun/Moon color
int windowsR=226,windowsG=219,windowsB=199;//Windows color
int cloudR=255,cloudG=255,cloudB=255;//Cloud Colors
int headlightsBusR=17,headlightsBusG=22,headlightsBusB=56;//Headlight of bus

void handleKeypress(unsigned char key, int x, int y)
{
    switch(key){

case 'd'://Day
    sky1R=203,sky1G=212,sky1B=137; // Sky color 1st shading
    sky2R=127,sky2G=212,sky2B=239;  // Sky color 2nd shading
    SunMoonR=252,SunMoonG=181,SunMoonB=77;//Sun/Moon color
    windowsR=226,windowsG=219,windowsB=199;//Windows color
    cloudR=255,cloudG=255,cloudB=255;//Cloud Colors
    headlightsBusR=17,headlightsBusG=22,headlightsBusB=56;//Headlight of bus
    break;

case 'n'://Night
    sky1R=65,sky1G=65,sky1B=65; // Sky color 1st shading
    sky2R=36,sky2G=36,sky2B=36;  // Sky color 2nd shading
    SunMoonR=255,SunMoonG=205,SunMoonB=136;//SunMoon color
    windowsR=252, windowsG=172, windowsB=11;//Windows color
    cloudR=193,cloudG=204,cloudB=204;//Cloud Colors
    headlightsBusR=252,headlightsBusG=172,headlightsBusB=11;//Headlight of bus

    }
}

//Animations
void Cloud_Move(int value)
{
    _moveCloud+=2.0;
    if(_moveCloud>1366.0)
    {
        _moveCloud=-1000.0;
    }
    glutPostRedisplay();
    glutTimerFunc(20,Cloud_Move, 0);
}

void Bus_Move(int value)
{
    _moveBus+=2.5;
    if(_moveBus>1366.0)
    {
        _moveBus=-100.0;
    }
    glutPostRedisplay();
    glutTimerFunc(20,Bus_Move,0);
}
void Ambulance_Move(int value)
{
    _moveAmbulance-=3.5;
    if(_moveAmbulance<-1366.0)
    {
        _moveAmbulance=450.0;
    }
    glutPostRedisplay();
    glutTimerFunc(20,Ambulance_Move,0);
}

void display()
{
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

        //---------------------------Drawing SKY-------------//

    glBegin(GL_QUADS);
    glColor3ub(sky1R,sky1G,sky1B);
    glVertex2f(0.0,71.0);
    glColor3ub(sky2R,sky2G,sky2B);
    glVertex2f(0.0,800.0);
    glColor3ub(sky2R,sky2G,sky2B);
    glVertex2f(1366.0,800.0);
    glColor3ub(sky1R,sky1G,sky1B);
    glVertex2f(1366.0,71.0);
    glEnd();

    /////////////////////////////////////////////-----Drawing SUN/MOON------\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

    glPushMatrix();
    glBegin(GL_POLYGON);
    glColor3ub(SunMoonR,SunMoonG,SunMoonB);
    for (int i =0;i < 360;i++)
    {
        double theta;
        theta = i * 3.1416 / 180;
        glVertex2d(535+ 30.25* cos(theta),662+ 30.25* sin(theta));
    }
    glEnd();
    glPopMatrix();

    //--------ROADS------------//
    glBegin(GL_QUADS);
    glColor3ub(31, 30, 31);
    glVertex2f(0.0,0.0);
    glVertex2f(0.0,35.0);
    glVertex2f(1366.0,35.0);
    glVertex2f(1366.0,0.0);
    glEnd();

    glBegin(GL_QUADS);
    glColor3ub(31, 30, 31);
    glVertex2f(0.0,35.0);
    glVertex2f(0.0,70.0);
    glVertex2f(1366.0,70.0);
    glVertex2f(1366.0,35.0);
    glEnd();

    glBegin(GL_QUADS);
    glColor3ub(70, 116, 37);
    glVertex2f(0.0,71.0);
    glVertex2f(0.0,90.0);
    glVertex2f(1366.0,90.0);
    glVertex2f(1366.0,71.0);
    glEnd();

        //---------------------------Grass----------------------------------//

        glBegin(GL_QUADS);
    glColor3ub(70, 116, 37);
    glVertex2f(0.0,70.0);
    glVertex2f(0.0,85.0);
    glVertex2f(1366.0,85.0);
    glVertex2f(1366.0,70.0);
    glEnd();

 ///////////////////////////////////////------Triangular big tree---------------\\\\\\\\\\\\\\\\\\\\\\\\\\\

    //-------TRUNK-----//
    glBegin(GL_QUADS);
    glColor3ub(109, 77, 33);
    glVertex2d(1010,85);
    glVertex2d(1010,105);
    glVertex2d(1020,105);
    glVertex2d(1020,85);
    glEnd();
    //---Leaves by triangle----//


#include "components/Executer.hpp"
#include "components/Server.hpp"
#include <cctype>

bool Executer::_requireRegistered(User &user, const std::string &cmdName) {
	if (user.nickOk && user.userOk) return true;
	std::string nick = user.nick.empty() ? "*" : user.nick;
	user.outBuf += Server::serverMessage(ERR_NOTREGISTERED, nick, cmdName, "You must be fully connected to use this command.");
	return false;
}

void Executer::_checkIfLog(User &user) {
	if (user.passOK && user.nickOk && user.userOk && !user.welcome) {
		user.outBuf = Server::serverMessage(RPL_WELCOME, user.nick, "", "Your host is irc.42.fr, running version 1.0");
		user.welcome = true;
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Executer::execute(Command& command, User &user, Server &server) {
	switch (command.type) {
		case PASS:
			_executePass(command, user, server);
			break;
		case NICK:
			_executeNick(command, user, server);
			break;
		case USER:
			_executeUser(command, user);
			break;
		case JOIN:
			_executeJoin(command, user, server);
			break;
		case PRIVMSG:
			_executePrivmsg(command, user, server);
			break;
		case NAMES:
			_executeName(command, user, server);
			break;
		case PART:
			_executePart(command, user, server);
			break;
		case QUIT:
			_executeQuit(command, user, server);
			break;
		case KICK:
			_executeKick(command, user, server);
			break;
		case INVITE:
			_executeInvite(command, user); //todo
			break;
		case TOPIC:
			_executeTopic(command, user); //todo
			break;
		case MODE:
			_executeMode(command, user); //todo
			break;
		case PING:
			_executePing(command, user);
			break;
		case PONG:
			_executePong(command, user);
			break;
		case UNKNOWN:
			_executeUnknown(command, user);
			break;
		default:
			break;
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Executer::_executePass(Command& command, User &user, Server &server) {
	std::cout << "Executing PASS command" << std::endl;
	if (user.passOK) {
		user.outBuf += Server::serverMessage(ERR_ALREADYREGISTRED, user.nick, "PASS", "You are already registered");
		return;
	}
	if (command.args.size() == 1 && command.args[0] == server.getPassword()) {
		user.passOK = true;
		user.outBuf += Server::serverMessage(RPL_YOUREOPER, user.nick, "PASS", "You are now registered");
	} else {
		user.outBuf += Server::serverMessage(ERR_PASSWDMISMATCH, user.nick, "PASS", "Password incorrect");
	}
}

void Executer::_executeNick(Command& command, User &user, Server &server) {
	std::cout << "Executing NICK command" << std::endl;
	if (!user.passOK) {
		user.outBuf += Server::serverMessage(ERR_NOTREGISTERED, user.nick, "NICK", "You must be fully connected to use this command.");
		return ;
	}
	if (command.args.size() < 1) {
		user.outBuf += Server::serverMessage(ERR_NEEDMOREPARAMS, user.nick, "NICK", "Not enough parameters");
		return;
	}
	const std::string &newNick = command.args[0];
	if (newNick.empty() || !std::isalpha(static_cast<unsigned char>(newNick[0]))) {
		user.outBuf += Server::serverMessage(ERR_ERRONEUSNICKNAME, user.nick, "NICK", "Nickname is invalid");
		return;
	}
	for (size_t i = 0; i < newNick.size(); ++i) {
		if (!std::isalnum(static_cast<unsigned char>(newNick[i]))) {
			user.outBuf += Server::serverMessage(ERR_ERRONEUSNICKNAME, user.nick, "NICK", "Nickname is invalid");
			return;
		}
	}
	std::map<int, User> &users = server.getUsers();
	for (std::map<int, User>::iterator it = users.begin(); it != users.end(); it++) {
		if (it->second.nick == newNick) {
			user.outBuf += Server::serverMessage(ERR_NICKNAMEINUSE, user.nick, "NICK", "Nickname is already in use");
			return ;
		}
	}
	user.nick = newNick;
	user.nickOk = true;
	_checkIfLog(user);
}

void Executer::_executeUser(Command& command, User &user) {
	std::cout << "Executing USER command" << std::endl;
	if (!user.passOK) {
		user.outBuf += Server::serverMessage(ERR_NOTREGISTERED, user.nick, "USER", "You must be fully connected to use this command.");
		return ;
	}
	if (user.nickOk && user.userOk) {
		user.outBuf += Server::serverMessage(ERR_ALREADYREGISTRED, user.nick.empty() ? "*" : user.nick, "USER", "You may not reregister");
	}
	if (command.args.size() != 4) {
		user.outBuf += Server::serverMessage(ERR_NEEDMOREPARAMS, user.nick, "USER", "Not enough parameters");
		return;
	}
	user.username = command.args[0];
	user.realname = command.args[3];
	user.userOk = true;
	_checkIfLog(user);
}

void Executer::_executePrivmsg(Command& command, User &user, Server &server) {
	if (!_requireRegistered(user, "PRIVMSG")) return;
	std::cout << "Executing PRIVMSG command" << std::endl;
	if (command.args.size() < 2) {
		user.outBuf += Server::serverMessage(ERR_NEEDMOREPARAMS, user.nick, "PRIVMSG", "Not enough parameters");
		return;
	}
	if (command.args[0].empty() || command.args[1].empty()) {
		user.outBuf += Server::serverMessage(ERR_NEEDMOREPARAMS


#include "pch.h"

// dear imgui, v1.92.2 WIP
// (tables and columns code)

/*

Index of this file:

// [SECTION] Commentary
// [SECTION] Header mess
// [SECTION] Tables: Main code
// [SECTION] Tables: Simple accessors
// [SECTION] Tables: Row changes
// [SECTION] Tables: Columns changes
// [SECTION] Tables: Columns width management
// [SECTION] Tables: Drawing
// [SECTION] Tables: Sorting
// [SECTION] Tables: Headers
// [SECTION] Tables: Context Menu
// [SECTION] Tables: Settings (.ini data)
// [SECTION] Tables: Garbage Collection
// [SECTION] Tables: Debugging
// [SECTION] Columns, BeginColumns, EndColumns, etc.

*/

// Navigating this file:
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.

//-----------------------------------------------------------------------------
// [SECTION] Commentary
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Typical tables call flow: (root level is generally public API):
//-----------------------------------------------------------------------------
// - BeginTable()                               user begin into a table
//    | BeginChild()                            - (if ScrollX/ScrollY is set)
//    | TableBeginInitMemory()                  - first time table is used
//    | TableResetSettings()                    - on settings reset
//    | TableLoadSettings()                     - on settings load
//    | TableBeginApplyRequests()               - apply queued resizing/reordering/hiding requests
//    | - TableSetColumnWidth()                 - apply resizing width (for mouse resize, often requested by previous frame)
//    |    - TableUpdateColumnsWeightFromWidth()- recompute columns weights (of stretch columns) from their respective width
// - TableSetupColumn()                         user submit columns details (optional)
// - TableSetupScrollFreeze()                   user submit scroll freeze information (optional)
//-----------------------------------------------------------------------------
// - TableUpdateLayout() [Internal]             followup to BeginTable(): setup everything: widths, columns positions, clipping rectangles. Automatically called by the FIRST call to TableNextRow() or TableHeadersRow().
//    | TableSetupDrawChannels()                - setup ImDrawList channels
//    | TableUpdateBorders()                    - detect hovering columns for resize, ahead of contents submission
//    | TableBeginContextMenuPopup()
//    | - TableDrawDefaultContextMenu()         - draw right-click context menu contents
//-----------------------------------------------------------------------------
// - TableHeadersRow() or TableHeader()         user submit a headers row (optional)
//    | TableSortSpecsClickColumn()             - when left-clicked: alter sort order and sort direction
//    | TableOpenContextMenu()                  - when right-clicked: trigger opening of the default context menu
// - TableGetSortSpecs()                        user queries updated sort specs (optional, generally after submitting headers)
// - TableNextRow()                             user begin into a new row (also automatically called by TableHeadersRow())
//    | TableEndRow()                           - finish existing row
//    | TableBeginRow()                         - add a new row
// - TableSetColumnIndex() / TableNextColumn()  user begin into a cell
//    | TableEndCell()                          - close existing column/cell
//    | TableBeginCell()                        - enter into current column/cell
// - [...]                                      user emit contents
//-----------------------------------------------------------------------------
// - EndTable()                                 user ends the table
//    | TableDrawBorders()                      - draw outer borders, inner vertical borders
//    | TableMergeDrawChannels()                - merge draw channels if clipping isn't required
//    | EndChild()                              - (if ScrollX/ScrollY is set)
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// TABLE SIZING
//-----------------------------------------------------------------------------
// (Read carefully because this is subtle but it does make sense!)
//-----------------------------------------------------------------------------
// About 'outer_size':
// Its meaning needs to differ slightly depending on if we are using ScrollX/ScrollY flags.
// Default value is ImVec2(0.0f, 0.0f).
//   X
//   - outer_size.x <= 0.0f  ->  Ri


/*
Copyright 2017 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "Gpio.h"

#include <chrono>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <thread>
#include <unistd.h>

constexpr int SET = 7;
constexpr int CLEAR = 10;
constexpr int GET = 13;
constexpr int MAP_SIZE = 0xb4;
constexpr int GPPUD = 37;
constexpr int GPPUDCLK = 38;

Gpio::Gpio(){
	int fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
	if(fd >= 0){
		gpioReg = (uint32_t *)mmap(
				NULL, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

		if(gpioReg == MAP_FAILED){
			gpioReg = nullptr;
		}

		close(fd);
	}
}

Gpio::~Gpio(){
	if(gpioReg){
		munmap(const_cast<uint32_t *>(gpioReg), MAP_SIZE);
	}
}

Gpio::operator bool() const{
	return gpioReg != nullptr;
}

bool Gpio::setInput(int pin, Pull pull){
	if(!gpioReg || pin < 2 || pin > 27){
		return false;
	}

	int reg = pin / 10;
	int shift = (pin % 10) * 3;

	gpioReg[reg] = (gpioReg[reg] & ~(7<<shift));

	gpioReg[GPPUD] = pull & 3;
	std::this_thread::sleep_for(std::chrono::milliseconds(1));
	gpioReg[GPPUDCLK] = 1 << pin;
	std::this_thread::sleep_for(std::chrono::milliseconds(1));

	gpioReg[GPPUD] = 0;
	gpioReg[GPPUDCLK] = 0;

	return true;
}

bool Gpio::setOutput(int pin){
	if(!gpioReg || pin < 2 || pin > 27){
		return false;
	}

	int reg = pin / 10;
	int shift = (pin % 10) * 3;

	gpioReg[reg] = (gpioReg[reg] & ~(7<<shift)) | (1<<shift);

	return true;
}

bool Gpio::write(int pin, bool high){
	if(!gpioReg || pin < 2 || pin > 27){
		return false;
	}

	gpioReg[high ? SET : CLEAR] = 1 << (pin & 0x1f);
	return true;
}

bool Gpio::read(int pin){
	if(!gpioReg || pin < 2 || pin > 27){
		return false;
	}

	return (gpioReg[GET] & (1 << (pin & 0x1f))) != 0;
}

void Gpio::reset(int pin, size_t uSecHold, size_t uSecDelay){
	// Set the pin to an output and drive it low.
	setOutput(pin);
	write(pin, false);
	std::this_thread::sleep_for(std::chrono::microseconds(uSecHold));

	// Restore the pin
	write(pin, 1);
	setInput(pin, PULL_UP);
	std::this_thread::sleep_for(std::chrono::microseconds(uSecDelay));
}


#include <stdio.h>
#include <string.h>
#include <math.h>
#include <esp_log.h>
#include <esp_timer.h>
#include <cJSON.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <driver/uart.h>

#include "../inc/module_handlers.h"
#include "../inc/ugv_config.h"
#include "../inc/servo_controller.h"
#include "../inc/gimbal_controller.h"
#include "../inc/esp_now_controller.h"
#include "../inc/imu_controller.h"
#include "../inc/uart_controller.h"

static const char *TAG = "Module_Handlers";

// UART configuration (matching uart_controller.cpp)
#define UART_NUM UART_NUM_0

// Private function prototypes
static esp_err_t uart_send_feedback(const char *json_string);

// Global variables for module control
static uint32_t prev_time = 0;
static bool steady_mode = false;
static float steady_goal_y = 0.0f;
static float steady_bias = 0.0f;
static uint8_t esp_now_mode = ESP_NOW_MODE_OFF;

// RoArm-M2 constant control variables
static bool const_cmd_base_x = false;
static bool const_cmd_shoulder_y = false;
static bool const_cmd_elbow_z = false;
static bool const_cmd_eoat_t = false;
static double const_goal_base = 0.0;
static double const_goal_shoulder = 0.0;
static double const_goal_elbow = 0.0;
static double const_goal_eoat = 0.0;

// Arm position variables
static double radB = 0.0, radS = 0.0, radE = 0.0, radT = 0.0;
static double lastX = 0.0, lastY = 0.0, lastZ = 0.0, lastT = 0.0;

// Use the gimbal_feedback_t from gimbal_controller.h
static gimbal_feedback_t gimbal_feedback[2]; // [0] = pan, [1] = tilt

// ============================================================================
// MODULE TYPE SPECIFIC FUNCTIONS
// ============================================================================

/**
 * @brief RoArm-M2 module type handler
 */
void module_type_roarm_m2(void) {
    uint32_t curr_time = esp_timer_get_time() / 1000;

    // Constant control every 10ms
    if (curr_time - prev_time >= 10) {
        constant_handle();
        prev_time = curr_time;
    }

    // Get position from servo feedback
    roarm_m2_get_pos_by_servo_feedback();

    // ESP-NOW flow control as flow-leader
    // Note: ESP-NOW flow control functions would be implemented here
    // when ESP-NOW functionality is added to the project

    // Info feedback if enabled
    if (ugv_config.info_print == 2) {
        roarm_m2_info_feedback();
    }
}

/**
 * @brief Gimbal module type handler
 */
void module_type_gimbal(void) {
    // Get gimbal feedback
    get_gimbal_feedback();

    // Apply gimbal stabilization
    gimbal_steady(steady_goal_y);
}

// ============================================================================
// ROARM-M2 SPECIFIC FUNCTIONS
// ============================================================================

/**
 * @brief Constant control handler for RoArm-M2
 */
void constant_handle(void) {
    if (!const_cmd_base_x && !const_cmd_shoulder_y && !const_cmd_elbow_z && !const_cmd_eoat_t) {
        const_goal_base = radB;
        const_goal_shoulder = radS;
        const_goal_elbow = radE;
        const_goal_eoat = radT;
    }

    // Apply constant control to servos
    if (const_cmd_base_x) {
        // Move base servo to constant goal
        scservo_write_pos(ROARM_BASE_SERVO_ID, (uint16_t)(const_goal_base * 180.0 / M_PI), 100, 100);
    }

    if (const_cmd_shoulder_y) {
        // Move shoulder servos to constant goal
        scservo_write_pos(ROARM_SHOULDER_DRIVING_SERVO_ID, (uint16_t)(const_goal_shoulder * 180.0 / M_PI), 100, 100);
        scservo_write_pos(ROARM_SHOULDER_DRIVEN_SERVO_ID, (uint16_t)(const_goal_shoulder * 180.0 / M_PI), 100, 100);
    }

    if (const_cmd_elbow_z) {
        // Move elbow servo to constant goal
        scservo_write_pos(ROARM_ELBOW_SERVO_ID, (uint16_t)(const_goal_elbow * 180.0 / M_PI), 100, 100);
    }

    if (const_cmd_eoat_t) {
        // Move end-effector servo to constant goal
        scservo_write_pos(ROARM_GRIPPER_SERVO_ID, (uint16_t)(const_goal_eoat * 180.0 / M_PI), 100, 100);
    }
}

/**
 * @brief Get RoArm-M2 position from servo feedback
 */
void roarm_m2_get_pos_by_servo_feedback(void) {
    // Get servo positions and convert to radians
    uint16_t base_pos, shoulder_pos, elbow_pos, gripper_pos;

    if (scservo_read_pos(ROARM_BASE_SERVO_ID, &base_pos) == ESP_OK) {
        radB = (double)base_pos * M_PI / 180.0;
    }

    if (scservo_read_pos(ROARM_SHOULDER_DRIVING_SERVO_ID, &shoulder_pos) == ESP_OK) {
        radS = (double)shoulder_pos * M_PI / 180.0;
    }

    if (scservo_read_pos(ROARM_ELBOW_SERVO_ID, &elbow_pos) == ESP_OK) {
        radE = (double)elbow_pos * M_PI / 180.0;
    }

    if (scservo_read_pos(ROARM_GRIPPER_SERVO_ID, &gripper_pos) == ESP_OK) {
        radT = (double)gripper_pos * M_PI / 180.0;
    }

    // Update last position (simplified kinematics)
    lastX = 100.0 + 50.0 * cos(radB) * cos(radS);
    lastY = 50.0 * sin(radB) * cos(radS);
    lastZ = 100.0 + 50.0 * sin(radS);


#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <windows.h>

#include "flutter_window.h"
#include "utils.h"

int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
                      _In_ wchar_t *command_line, _In_ int show_command) {
  // Attach to console when present (e.g., 'flutter run') or create a
  // new console when running with a debugger.
  if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
    CreateAndAttachConsole();
  }

  // Initialize COM, so that it is available for use in the library and/or
  // plugins.
  ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

  flutter::DartProject project(L"data");

  std::vector<std::string> command_line_arguments =
      GetCommandLineArguments();

  project.set_dart_entrypoint_arguments(std::move(command_line_arguments));

  FlutterWindow window(project);
  Win32Window::Point origin(10, 10);
  Win32Window::Size size(1280, 720);
  if (!window.CreateAndShow(L"clima_flutter_app", origin, size)) {
    return EXIT_FAILURE;
  }
  window.SetQuitOnClose(true);

  ::MSG msg;
  while (::GetMessage(&msg, nullptr, 0, 0)) {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
  }

  ::CoUninitialize();
  return EXIT_SUCCESS;
}


#include <iostream>
#include <string>
using namespace std;

struct Cliente { string nombre, cuenta; double saldo; };

int main() {
    Cliente clientes[50];
    int n = 0, op;

    do {
        cout << "\nMENU MI BANCO\n"
             << "1. Agregar cliente\n2. Listar clientes\n3. Consignar\n"
             << "4. Retirar\n5. Transferir\n6. Totales\n0. Salir\n"
             << "Opcion: ";
        cin >> op;

        if (op == 1) {
            if (n < 50) {
                cout << "Nombre(sin espacios): "; cin >> clientes[n].nombre;
                cout << "Cuenta: ";               cin >> clientes[n].cuenta;
                cout << "Saldo inicial: ";        cin >> clientes[n].saldo;
                n++;
                cout << "Agregado.\n";
            } else cout << "Sin espacio.\n";
        }
        else if (op == 2) {
            if (n==0) cout << "No hay.\n";
            for (int i=0;i<n;i++)
                cout << i+1 << ") " << clientes[i].nombre << " | "
                     << clientes[i].cuenta << " | " << clientes[i].saldo << "\n";
        }
        else if (op == 3) {
            string c; double m; cout << "Cuenta: "; cin >> c; cout << "Monto: "; cin >> m;
            for (int i=0;i<n;i++) if (clientes[i].cuenta==c) clientes[i].saldo+=m;
            cout << "Listo.\n";
        }
        else if (op == 4) {
            string c; double m; cout << "Cuenta: "; cin >> c; cout << "Monto: "; cin >> m;
            for (int i=0;i<n;i++) if (clientes[i].cuenta==c && clientes[i].saldo>=m) clientes[i].saldo-=m;
            cout << "Listo.\n";
        }
        else if (op == 5) {
            string a,b; double m;
            cout << "Origen: "; cin >> a; cout << "Destino: "; cin >> b; cout << "Monto: "; cin >> m;
            int iA=-1,iB=-1;
            for (int i=0;i<n;i++){ if(clientes[i].cuenta==a) iA=i; if(clientes[i].cuenta==b) iB=i; }
            if (iA!=-1 && iB!=-1 && clientes[iA].saldo>=m) { clientes[iA].saldo-=m; clientes[iB].saldo+=m; }
            cout << "Listo.\n";
        }
        else if (op == 6) {
            double s=0; for (int i=0;i<n;i++) s+=clientes[i].saldo;
            cout << "Clientes: " << n << "\nSuma saldos: " << s << "\n";
        }
    } while (op != 0);

    cout << "Adios.\n";
    return 0;
}


// g2o - General Graph Optimization
// Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * 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.
//
// 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.

#include "estimate_propagator.h"

#include <queue>
#include <vector>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <fstream>

//#define DEBUG_ESTIMATE_PROPAGATOR

using namespace std;

namespace g2o {

# ifdef DEBUG_ESTIMATE_PROPAGATOR
  struct FrontierLevelCmp {
    bool operator()(EstimatePropagator::AdjacencyMapEntry* e1, EstimatePropagator::AdjacencyMapEntry* e2) const
    {
      return e1->frontierLevel() < e2->frontierLevel();
    }
  };
# endif

  EstimatePropagator::AdjacencyMapEntry::AdjacencyMapEntry()
  {
    reset();
  }

  void EstimatePropagator::AdjacencyMapEntry::reset()
  {
    _child = 0;
    _parent.clear();
    _edge = 0;
    _distance = numeric_limits<double>::max();
    _frontierLevel = -1;
    inQueue = false;
  }

  EstimatePropagator::EstimatePropagator(OptimizableGraph* g): _graph(g)
  {
    for (OptimizableGraph::VertexIDMap::const_iterator it=_graph->vertices().begin(); it!=_graph->vertices().end(); ++it){
      AdjacencyMapEntry entry;
      entry._child = static_cast<OptimizableGraph::Vertex*>(it->second);
      _adjacencyMap.insert(make_pair(entry.child(), entry));
    }
  }

  void EstimatePropagator::reset()
  {
    for (OptimizableGraph::VertexSet::iterator it=_visited.begin(); it!=_visited.end(); ++it){
      OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
      AdjacencyMap::iterator at = _adjacencyMap.find(v);
      assert(at != _adjacencyMap.end());
      at->second.reset();
    }
    _visited.clear();
  }

  void EstimatePropagator::propagate(OptimizableGraph::Vertex* v,
      const EstimatePropagator::PropagateCost& cost,
       const EstimatePropagator::PropagateAction& action,
       double maxDistance,
       double maxEdgeCost)
  {
    OptimizableGraph::VertexSet vset;
    vset.insert(v);
    propagate(vset, cost, action, maxDistance, maxEdgeCost);
  }

  void EstimatePropagator::propagate(OptimizableGraph::VertexSet& vset,
      const EstimatePropagator::PropagateCost& cost,
       const EstimatePropagator::PropagateAction& action,
       double maxDistance,
       double maxEdgeCost)
  {
    reset();

    PriorityQueue frontier;
    for (OptimizableGraph::VertexSet::iterator vit=vset.begin(); vit!=vset.end(); ++vit){
      OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*vit);
      AdjacencyMap::iterator it = _adjacencyMap.find(v);
      assert(it != _adjacencyMap.end());
      it->second._distance = 0.;
      it->second._parent.clear();
      it->second._frontierLevel = 0;
      frontier.push(&it->second);
    }

    while(! frontier.empty()){
      AdjacencyMapEntry* entry = frontier.pop();
      OptimizableGraph::Vertex* u = entry->child();
      double uDistance = entry->distance();
      //cerr << "uDistance " << uDistance << endl;

      // initialize the vertex
      if (entry->_frontierLevel > 0) {
        action(entry->edge(), entry->parent(), u);
      }

      /* std::pair< OptimizableGraph::VertexSet::iterator, bool> insertResult = */ _visited.insert(u);
      OptimizableGraph::EdgeSet::iterator et = u->edges().begin();
      while (et != u->edges().end()){
        OptimizableGraph::Edge* edge = static_cast<OptimizableGraph::Edge*>(*et);
        ++et;

        int maxFrontier = -1;
        OptimizableGraph::VertexSet initializedVertices;
        for (size_t i = 0; i < edge->vertices().size(); ++i) {
          OptimizableGraph::Vertex* z = static_cast<OptimizableGraph::Vertex*>(edge->vertex(i));
          AdjacencyMap::iterator ot = _adjacencyMap.find(z);
          if (ot->seco


// JourneyGenie.cpp
// __define-ocg__: JourneyGenie Trip Planner
#include <bits/stdc++.h>
#include <fstream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <limits>
#include <string>
#include <sstream>

using namespace std;

struct Edge {
    string to;
    int distance;
    int time;
};

struct Node {
    string city;
    int distance;
    int time;
    bool operator>(const Node &other) const {
        return distance > other.distance;
    }
};

class JourneyGenie {
private:
    unordered_map<string, vector<Edge>> graph;

public:
    void loadRoutes(const string &filename) {
    ifstream file(filename);
    if (!file.is_open()) {
        cerr << "⚠ Error: Could not open dataset file: " << filename << endl;
        system("pause"); // keeps console open
        exit(1);
    }
    string from, to;
    int distance, time;
    while (file >> from >> to >> distance >> time) {
        graph[from].push_back({to, distance, time});
        graph[to].push_back({from, distance, time});
    }
    file.close();
}

    void dijkstra(const string &source, const string &destination) {
        unordered_map<string, int> dist;
        unordered_map<string, string> prev;

        for (auto &node : graph) {
            dist[node.first] = numeric_limits<int>::max();
        }
        dist[source] = 0;

        priority_queue<Node, vector<Node>, greater<Node>> pq;
        pq.push({source, 0, 0});

        while (!pq.empty()) {
            Node u = pq.top();
            pq.pop();

            if (u.city == destination) break;

            for (auto &edge : graph[u.city]) {
                int newDist = dist[u.city] + edge.distance;
                if (newDist < dist[edge.to]) {
                    dist[edge.to] = newDist;
                    prev[edge.to] = u.city;
                    pq.push({edge.to, newDist, 0});
                }
            }
        }

        // Print path
        if (dist[destination] == numeric_limits<int>::max()) {
            cout << "No route found.\n";
            return;
        }

        vector<string> path;
        for (string at = destination; at != ""; at = prev[at]) {
            path.push_back(at);
            if (at == source) break;
        }
        reverse(path.begin(), path.end());

        cout << "Shortest Path from " << source << " to " << destination << ":\n";
        for (auto &city : path) cout << city << " ";
        cout << "\nDistance: " << dist[destination] << " km\n";
    }
};

// CLI
int main() {
    JourneyGenie app;
    app.loadRoutes("C:/Users/Keshav/OneDrive/Desktop/c++/JourneyGenie/routes.txt");

    cout << "====== JourneyGenie Trip Planner ======\n";
    string src, dest;
    cout << "Enter source city: ";
    cin >> src;
    cout << "Enter destination city: ";
    cin >> dest;

    app.dijkstra(src, dest);
    return 0;
}


#include <iostream>
#include <string>
#include <unordered_map>
#include "Parser.h"
#include "Tableau.h"

using namespace std;

int main(int argc, char **argv)
{
    if (argc < 2)
    {
        cout << "Usage: ./s5_tableau \"<formula>\"" << endl;
        return 1;
    }

    // Join args into single string (so spaces are allowed)
    // string input;
    // for (int i = 1; i < argc; i++)
    // {
        // if (i > 1)
            // input += " ";
        // input += argv[i];
    // }

    string input = argv[1];
    cout << "Input formula: " << input << endl;

    try
    {
        Parser p(input);
        auto f = p.parse();
        cout << "Parsed formula: " << f->str() << endl;

        // Example evaluation (propositional only, modal nodes throw)
        unordered_map<string, bool> assignment1 = {{"p", true}, {"q", false}};
        unordered_map<string, bool> assignment2 = {{"p", true}, {"q", true}};

        cout << "Eval under {p=true, q=false}: " << f->eval(assignment1) << endl;
        cout << "Eval under {p=true, q=true}: " << f->eval(assignment2) << endl;

        // Put formula into tableau
        TableauNode root({f});
        root.print();
    }
    catch (const exception &e)
    {
        cerr << "Parse error: " << e.what() << endl;
        return 1;
    }

    return 0;
}


#include "SolanaUtils.h"
#include "IoTxChain-lib.h"

// Function implementations

void getSolBalance() {
  Serial.println("\n=== 🔹 getSolBalance() ===");

  const String wallet = PUBLIC_KEY_BASE58;
  uint64_t lamports = 0;

  if (solana.getSolBalance(wallet, lamports)) {
    Serial.print("Wallet address: ");
    Serial.println(wallet);
    Serial.print("SOL Balance (lamports): ");
    Serial.println(lamports);
    Serial.print("SOL Balance (SOL): ");
    Serial.println((float)lamports / 1e9, 9);
  } else {
    Serial.println("❌ Failed to fetch SOL balance.");
  }
}

void confirmTransaction(const String signature) {
  Serial.println("\n=== 🔹 confirmTransaction() ===");

  if (solana.confirmTransaction(signature, 5000)) {
      Serial.println("✅ Transaction confirmed!");
  } else {
    Serial.println("❌ Failed to confirm transaction.");
  }
}

void calculateDiscriminator(const String function_name) {
  Serial.println("\n=== 🔹 calculateDiscriminator() ===");

  std::vector<uint8_t> discriminator = solana.calculateDiscriminator(function_name.c_str());
  Serial.print("Function Name: ");
  Serial.println(function_name);
  Serial.print("Discriminator: ");

  Serial.print("Discriminator for '" + function_name + "': ");
    for (uint8_t b : discriminator) {
        if (b < 16) Serial.print("0");
        Serial.print(b, HEX);
    }
    Serial.println();
}

void sendAnchorInstructionWithPDA(
  const String& functionName,
  const std::vector<std::vector<uint8_t>>& customSeeds,
  const std::vector<uint8_t>& payload
) {
  Serial.println("\n=== 🔹 Anchor Instruction with PDA (Generic) ===");

  uint8_t privateKey[128] = "YOUR_PRIVATE_KEY_64_BYTE_BASE58"; // 64-byte base58 decoded

  Pubkey authority = Pubkey::fromBase58(PUBLIC_KEY_BASE58);
  Keypair signer = Keypair::fromPrivateKey(privateKey);

  std::vector<uint8_t> programId = base58ToPubkey(PROGRAM_ID);
  std::vector<uint8_t> tokenProgramId = base58ToPubkey(TOKEN_PROGRAM_ID);

  String ata;
  solana.findAssociatedTokenAccount(PUBLIC_KEY_BASE58, MINT, ata);
  Pubkey pda = Pubkey::fromBase58(ata);

  Pubkey tempPda = Pubkey::fromBase58(createPDAFromSeeds(customSeeds));

  std::vector<uint8_t> discriminator = solana.calculateDiscriminator(functionName.c_str());
  std::vector<uint8_t> data = discriminator;
  data.insert(data.end(), payload.begin(), payload.end());

  Instruction ix(
      Pubkey{programId},
      functionName == "transfer_to_vault" ? std::vector<AccountMeta>{
          AccountMeta::writable(authority, true),
          AccountMeta::writable(pda, false),
          AccountMeta::writable(Pubkey::fromBase58(VAULT), false),
          AccountMeta{Pubkey::fromBase58(MINT), false, false},
          AccountMeta{Pubkey::fromBase58(TOKEN_PROGRAM_ID), false, false},
      } : std::vector<AccountMeta>{
        AccountMeta::writable(authority, true),
        AccountMeta::writable(tempPda, false),
        AccountMeta{Pubkey::fromBase58("11111111111111111111111111111111"), false, false}
      },
      data
  );

  Transaction tx;
  tx.fee_payer = authority;
  tx.recent_blockhash = solana.getLatestBlockhash();
  if (tx.recent_blockhash.isEmpty()) {
      Serial.println("❌ Failed to get blockhash!");
      return;
  }
  tx.add(ix);
  tx.sign({signer});
  String txBase64 = tx.serializeBase64();

  String txSig;
  if (solana.sendRawTransaction(txBase64, txSig)) {
      Serial.println("✅ Anchor tx sent! Signature: " + txSig);
      confirmTransaction(txSig);
  } else {
      Serial.println("❌ Anchor tx failed.");
  }
}

String createPDAFromSeeds(const std::vector<std::vector<uint8_t>>& customSeeds) {
  Serial.println("\n=== 🔹 Creating PDA from Seeds ===");

  // Program ID for the PDA derivation
  std::vector<uint8_t> programId = base58ToPubkey(PROGRAM_ID);

  // Output variables
  std::vector<uint8_t> pdaBytes;
  uint8_t bump;

  // Generate the PDA
  if (solana.findProgramAddress(customSeeds, programId, pdaBytes, bump)) {
    Serial.println("✅ PDA created successfully!");

    // Convert PDA bytes back to base58 string for display
    // Note: You'd need a proper bytes-to-base58 encoder here
    Serial.print("PDA Bump: ");
    Serial.println(bump);
    Serial.print("PDA Bytes (hex): ");
    for (uint8_t b : pdaBytes) {
      if (b < 16) Serial.print("0");
      Serial.print(b, HEX);
    }
    Serial.println();

    // Convert PDA bytes to base58 string for return
    Serial.print("PDA base 58: ");
    Serial.println(base58Encode(pdaBytes.data(), pdaBytes.size()));
    return base58Encode(pdaBytes.data(), pdaBytes.size());
  }
  else {
    Serial.println("❌ Failed to create PDA");
    return "";
  }
}


#include <Kokkos_Core.hpp>

#include "knn.hpp"
#include "stats.hpp"
#include "xmap.hpp"

namespace edm
{

void lookup(MutableDataset result, Dataset ds, SimplexLUT lut, Targets targets,
            int E)
{
    const auto distances = lut.distances;
    const auto indices = lut.indices;

#ifdef USE_SCRATCH_MEMORY
    size_t scratch_size = ScratchTimeSeries::shmem_size(ds.extent(0));
#endif

    Kokkos::parallel_for(
        "EDM::xmap::lookup",
#ifdef USE_SCRATCH_MEMORY
        Kokkos::TeamPolicy<>(targets.size(), Kokkos::AUTO)
            .set_scratch_size(0, Kokkos::PerTeam(scratch_size)),
#else
        Kokkos::TeamPolicy<>(targets.size(), Kokkos::AUTO),
#endif
        KOKKOS_LAMBDA(const Kokkos::TeamPolicy<>::member_type &member) {
            const int j = targets(member.league_rank());

#ifdef USE_SCRATCH_MEMORY
            ScratchTimeSeries scratch(member.team_scratch(0), ds.extent(0));

            Kokkos::parallel_for(Kokkos::TeamThreadRange(member, ds.extent(0)),
                                 [=](int i) { scratch(i) = ds(i, j); });
#endif

            member.team_barrier();

            Kokkos::parallel_for(
                Kokkos::TeamThreadRange(member, distances.extent(0)),
                [=](int i) {
                    float pred = 0.0f;

#pragma unroll
                    for (int e = 0; e < E + 1; e++) {
#ifdef USE_SCRATCH_MEMORY
                        pred += scratch(indices(i, e)) * distances(i, e);
#else
                        pred += ds(indices(i, e), j) * distances(i, e);
#endif
                    }

                    result(i, j) = pred;
                });
        });
}

void _xmap(CrossMap result, Dataset ds, SimplexLUT lut, Targets targets, int E,
           int tau, int Tp)
{
    const auto distances = lut.distances;
    const auto indices = lut.indices;

#ifdef USE_SCRATCH_MEMORY
    size_t scratch_size = ScratchTimeSeries::shmem_size(ds.extent(0));
#endif

    Kokkos::parallel_for(
        "EDM::xmap::lookup",
#ifdef USE_SCRATCH_MEMORY
        Kokkos::TeamPolicy<>(targets.size(), Kokkos::AUTO)
            .set_scratch_size(0, Kokkos::PerTeam(scratch_size)),
#else
        Kokkos::TeamPolicy<>(targets.size(), Kokkos::AUTO),
#endif
        KOKKOS_LAMBDA(const Kokkos::TeamPolicy<>::member_type &member) {
            int j = targets(member.league_rank());

#ifdef USE_SCRATCH_MEMORY
            ScratchTimeSeries scratch(member.team_scratch(0), ds.extent(0));

            Kokkos::parallel_for(Kokkos::TeamThreadRange(member, ds.extent(0)),
                                 [=](int i) { scratch(i) = ds(i, j); });
#endif

            member.team_barrier();

            CorrcoefState state;

            Kokkos::parallel_reduce(
                Kokkos::TeamThreadRange(member, distances.extent(0)),
                [=](int i, CorrcoefState &upd) {
                    float pred = 0.0f;

                    for (int e = 0; e < E + 1; e++) {
#ifdef USE_SCRATCH_MEMORY
                        pred += scratch(indices(i, e)) * distances(i, e);
#else
                        pred += ds(indices(i, e), j) * distances(i, e);
#endif
                    }

#ifdef USE_SCRATCH_MEMORY
                    float actual = scratch((E - 1) * tau + Tp + i);
#else
                    float actual = ds((E - 1) * tau + Tp + i, j);
#endif

                    upd += CorrcoefState(pred, actual);
                },
                Kokkos::Sum<CorrcoefState>(state));

            Kokkos::single(Kokkos::PerTeam(member),
                           [=]() { result(j) = state.rho(); });
        });
}

// Group time series by their optimal embedding dimensions
void group_ts(std::vector<Targets> &groups, const std::vector<int> &edims,
              int E_max)
{
    std::vector<std::vector<int>> h_groups(E_max);

    groups.resize(E_max);

    for (size_t i = 0; i < edims.size(); i++) {
        h_groups[edims[i] - 1].push_back(i);
    }

    for (int E = 1; E <= E_max; E++) {
        Targets targets("targets", h_groups[E - 1].size());

        auto mirror = Kokkos::create_mirror_view(targets);

        for (size_t j = 0; j < h_groups[E - 1].size(); j++) {
            mirror(j) = h_groups[E - 1][j];
        }

        Kokkos::deep_copy(targets, mirror);
        groups[E - 1] = targets;
    }
}

void xmap(CrossMap result, Dataset ds, TimeSeries library,
          const std::vector<Targets> &groups, std::vector<SimplexLUT> &luts,
          TmpDistances tmp, int E_max, int tau, int Tp)
{
    Kokkos::Profiling::pushRegion("EDM::xmap");

    if (E_max <= 0) {
        throw std::invalid_argument("E_max must be greater than zero");
    } else if (tau <= 0) {
        throw std::invalid_argument("tau must be greater than zero");
    } else if (Tp < 0) {
        throw std::invalid_argument("Tp must be greater or equal to zero");
    }

    // Compute kNN tables for all E
    for (int E = 1; E <= E_max; E++) {
        knn(library, library, luts[E - 1], tmp, E, tau, Tp, E + 1);
        normalize_lut(luts[E - 1]);
    }

    // Perform


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "json.hpp"
#include <boost/multiprecision/cpp_int.hpp>

using BigInt = boost::multiprecision::cpp_int;
using json = nlohmann::json;

// Convert number string in base-n to BigInt
BigInt convertToBase10(const std::string& value, int base) {
    BigInt result = 0;
    BigInt power = 1;
    for (int i = value.length() - 1; i >= 0; i--) {
        int digit;
        if (value[i] >= '0' && value[i] <= '9') {
            digit = value[i] - '0';
        } else {
            digit = toupper(value[i]) - 'A' + 10;
        }
        if (digit >= base) {
            throw std::invalid_argument("Invalid digit for base " + std::to_string(base));
        }
        result += digit * power;
        power *= base;
    }
    return result;
}

// Multiply two polynomials
std::vector<BigInt> multiplyPolynomials(const std::vector<BigInt>& poly1,
                                        const std::vector<BigInt>& poly2) {
    std::vector<BigInt> result(poly1.size() + poly2.size() - 1, 0);
    for (size_t i = 0; i < poly1.size(); ++i) {
        for (size_t j = 0; j < poly2.size(); ++j) {
            result[i + j] += poly1[i] * poly2[j];
        }
    }
    return result;
}

// Solve for coefficients using first k roots
std::vector<BigInt> solveForCoefficients(const json& data) {
    int k = data["keys"]["k"];

    std::vector<BigInt> roots;
    for (int i = 1; i <= k; ++i) {
        std::string key = std::to_string(i);
        if (!data.contains(key)) {
            std::cerr << "Missing root key: " << key << std::endl;
            return {};
        }
        int base = std::stoi(data[key]["base"].get<std::string>());
        std::string value = data[key]["value"];
        roots.push_back(convertToBase10(value, base));
    }

    std::vector<BigInt> poly = {1, -roots[0]}; // (x - r1)
    for (size_t i = 1; i < roots.size(); ++i) {
        std::vector<BigInt> next = {1, -roots[i]};
        poly = multiplyPolynomials(poly, next);
    }
    return poly;
}

void printCoefficients(const std::vector<BigInt>& coeffs, const std::string& label) {
    std::cout << label << " [";
    for (size_t i = 0; i < coeffs.size(); i++) {
        std::cout << coeffs[i] << (i + 1 < coeffs.size() ? ", " : "");
    }
    std::cout << "]\n";
}

int main() {
    // Test Case 1
    json test_case_1 = R"(
    {
        "keys": {"n": 4, "k": 3},
        "1": {"base": "10", "value": "4"},
        "2": {"base": "2", "value": "111"},
        "3": {"base": "10", "value": "12"},
        "6": {"base": "4", "value": "213"}
    })"_json;

    std::vector<BigInt> coeffs1 = solveForCoefficients(test_case_1);
    printCoefficients(coeffs1, "Test Case 1 Coefficients:");

    // Test Case 2
    json test_case_2 = R"(
    {
        "keys": {"n": 10, "k": 7},
        "1": {"base": "6", "value": "13444211440455345511"},
        "2": {"base": "15", "value": "aed7015a346d635"},
        "3": {"base": "15", "value": "6aeeb69631c227c"},
        "4": {"base": "16", "value": "e1b5e05623d881f"},
        "5": {"base": "8", "value": "316034514573652620673"},
        "6": {"base": "3", "value": "2122212201122002221120200210011020220200"},
        "7": {"base": "3", "value": "20120221122211000100210021102001201112121"},
        "8": {"base": "6", "value": "20220554335330240002224253"},
        "9": {"base": "12", "value": "45153788322a1255483"},
        "10": {"base": "7", "value": "1101613130313526312514143"}
    })"_json;

    std::vector<BigInt> coeffs2 = solveForCoefficients(test_case_2);
    printCoefficients(coeffs2, "Test Case 2 Coefficients:");

    return 0;
}


#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <mutex>
#include <iostream>
#include <math.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <cstdint>
#include <cstring>

#define SAMPLERATE 192000
#define BRUH 8192 // 8192 is the largest we can get away with at 192khz without oscilloscope flicker (max hold pot)

#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

std::mutex mu;
std::int16_t *currentFrame;

// Remember to XDestroyImage() the returned pointer
XImage *screenshot() {
	Display* display = XOpenDisplay(nullptr);
	Window root = DefaultRootWindow(display);

	XWindowAttributes attributes = {0};
	XGetWindowAttributes(display, root, &attributes);

	int Width = attributes.width;
	int Height = attributes.height;

	XImage* img = XGetImage(display, root, 0, 0 , Width, Height, AllPlanes, ZPixmap);
	XCloseDisplay(display);
	return img;
}

static unsigned int g_seed;

// Used to seed the generator.
inline void fast_srand(int seed) {
    g_seed = seed;
}

inline int fast_rand(void) {
    g_seed = (214013*g_seed+2531011);
    return (g_seed>>16)&0x7FFF;
}

class MyAudio : public sf::SoundStream {
	bool onGetData(Chunk &data) {
		mu.lock();
		data.samples = currentFrame;
		data.sampleCount = BRUH;
		mu.unlock();
		return true;
	}

	void onSeek(sf::Time timeOffset) {
		return;
	}

	public:
	void load() {
		initialize(2, SAMPLERATE, {sf::SoundChannel::FrontLeft, sf::SoundChannel::FrontRight});
	}
};

float lerp(float a, float b, float t) {
	return a * (1 - t) + b * t;
}

void populate(std::int16_t *samples, std::size_t count, std::int16_t *tallLUT, std::int16_t *shortLUT, float *wallHeights, int numWallHeights) {
	// Zero-out the sample buffer
	for (int i = 0; i < BRUH; i++) {
		samples[i] = 0.0;
	}

	int outputStart = 400;
	int outputEnd = 5000;
	int outputRange = outputEnd - outputStart;

	for (int i = outputStart; i < outputRange; i++) {
		int indexWall = double(i) / double(outputRange) * double(numWallHeights);
		float height = wallHeights[indexWall];
		float output = tallLUT[i] * height;
		samples[i] = 0.15 * output;
	}

	// Negative trigger signal
	const int N = 16;
	for (int i = 0; i < N; i++) {
		samples[i] = -32767;
	}
}

void generate_LUT(std::int16_t *lut, int count, bool tall = false) {
	float amplitude = tall ? 1.0 : 0.05;
	float frequency = tall ? 600.0 : 50.0;

	for (int i = 0; i < count; i++) {
		lut[i] = 8192.0 * amplitude * sin(frequency * double(i) / double(count) * M_PI);
	}
}

int xy_to_index(int x, int y, int width) {
	return x + y * width;
}

// Screenshots and produces the wall heights
void get_wall_heights_from_screenshot(float *wallHeights, int numWallHeights) {
	int offsetX    = 720;
	int offsetY    = 412;
	int gameWidth  = 480;
	int gameHeight = 240;

	int heightStep = 3;

	XImage *img = screenshot();
	int sizeInBytes = img->width * img->height * (img->bits_per_pixel / 8);

	const unsigned int CEILING_COLOR = 56;
	const unsigned int FLOOR_COLOR = 113;
	for (int i = 0; i < numWallHeights; i++) {
		int x = offsetX + i * (gameWidth / numWallHeights);
		const int SCALE = 6;

		// Look for ceiling from the top
		int heightCount = gameHeight / 2 / heightStep - SCALE;
		for (int y = offsetY; y < offsetY + gameHeight/2; y += heightStep) {
			int index = xy_to_index(x, y, img->width);
			unsigned char r = img->data[4 * index + 0];
			unsigned char g = img->data[4 * index + 1];
			unsigned char b = img->data[4 * index + 2];

			// If it isn't grayscale, stop the search
			if (r != g || g != b || r != b) {
				break;
			}

			// If it isn't a ceiling, stop the search
			if (r != CEILING_COLOR) {
				break;
			}

			heightCount -= 1;
		}

		// Look for floor from the bottom
		int heightCount2 = gameHeight / 2 / heightStep - SCALE;
		for (int y = offsetY + gameHeight - 1; y > offsetY + gameHeight / 2; y -= heightStep) {
			int index = xy_to_index(x, y, img->width);
			unsigned char r = img->data[4 * index + 0];
			unsigned char g = img->data[4 * index + 1];
			unsigned char b = img->data[4 * index + 2];

			// If it isn't grayscale, stop the search
			if (r != g || g != b || r != b) {
				break;
			}

			// If it isn't a ceiling, stop the search
			if (r != FLOOR_COLOR) {
				break;
			}

			heightCount2 -= 1;
		}

		// Use the best result
		heightCount = MIN(heightCount, heightCount2);

		wallHeights[i] = double(heightCount) / (double(gameHeight) / 2.0 / double(heightStep));
		//std::cout << "wall height at i=" << i << " is " << wallHeights[i] << '\n';
	}

	XDestroyImage(img);
}

int main() {
	std::srand(std::time(nullptr));

	mu.lock();
	currentFrame = (std::int16_t*)malloc(BRUH * 2);
	mu.unlock();

	auto window = sf::RenderWindow(sf::VideoMode({1920u, 1080u}), "Game");
	window.setFramerateLimit(100);

	// WALL HEIGHTS
	const int NUM_WALL_HEIGHTS = 200;
	float wallHeights[NUM_WALL_HEIGHTS]; // 0.0 to 1.0
	for (int i = 0; i < NUM_WALL_HEIGHTS; i++) {
		wallHeights[i] = 0.0;
	}

	// Tall and short LUTs
	std::int16_t *tallLUT = (std::


#include <iostream>
using namespace std;

class myStack {
    int *arr;
    int capacity;
    int top;

    public:

    myStack(int cap) {
        capacity = cap;
        arr = new int[capacity];
        top = -1;
    }

    void push(int x) {
        if (top >= capacity - 1) {
            cout << "Stack Overflow\n";
            return;
        }
        arr[++top] = x;
    }

    int pop() {
        if (top<0) {
            cout << "Stack Underflow\n";
            return -1;
        }
        return arr[top--];
    }

    int peek() {
        if (top<0) {
            cout << "Stack is Empty\n";
            return -1;
        }
        return arr[top];
    }

    bool isEmpty() {
        return top<0;
    }

    bool isFull() {
        return top == capacity - 1;
    }

    int size(){
        return top+1;
    }
};

int main() {
    myStack st(4);

    st.push(1);
    st.push(2);
    st.push(3);
    st.push(4);

    cout << "Popped: " << st.pop() << "\n";

    cout << "Top element: " << st.peek() << "\n";

    cout << "Is stack empty: " << (st.isEmpty() ? "Yes" : "No") << "\n";

    cout << "Is stack full: " << (st.isFull() ? "Yes" : "No") << "\n";

    return 0;
}


#include <raylib.h>
#include <iostream>
using namespace std;

class Platform {
public:
    bool dead;
    bool ready;
    struct PlatData {
        float height, x;
    };
    Texture2D Pipe;
    Texture2D Extend;
    Texture2D Flipped;
    Texture2D OldTent;
    PlatData arr[6];
    Rectangle piperect[6];

    void updateCollision() {
        for (int i = 0; i < 3; i++) {
            piperect[i * 2]     = { (float)(arr[i].x + 5), (float)(arr[i].height + 230), 60, 320 };
            piperect[i * 2 + 1] = { (float)(arr[i].x + 5), (float)(arr[i].height - 915), 60, 960 };
        }
    }

    void init() {
        for (int i = 0; i < 3; i++) {
            arr[i].height = GetRandomValue(10, 400);
            arr[i].x = i * 250 + 500;
        }
    }

    void draw() {
        for (int i = 0; i < 3; i++) {
            DrawTextureEx(Extend, { arr[i].x + 67, arr[i].height - 320 }, 180.0f, 1.3f, WHITE);
            DrawTextureEx(OldTent, { arr[i].x, 1024 - (800 - arr[i].height - 320) }, 0.0f, 1.3f, WHITE);
            DrawTextureEx(Flipped, { arr[i].x + 67, arr[i].height + 50 }, 180.0f, 1.3f, WHITE);
            DrawTextureEx(Pipe, { arr[i].x, 1024 - (800 - arr[i].height) }, 0.0f, 1.3f, WHITE);
        }
    }

    void update() {
        for (int i = 0; i < 3; i++) {
            if (!dead && !ready) arr[i].x -= 2.5;
            if (arr[i].x < -150) {
                arr[i].x = 576;
                arr[i].height = GetRandomValue(200, 500);
            }
        }
    }
};

class Player {
public:
    Texture2D bird, up, down, play, gameover;
    Sound wing, point, hit, die;
    double x, y, width = 60, height = 60, velocity, gravity, rotation;
    int frame = 0;
    bool dead = false;
    bool ready = true;

    void draw() {
        int speed = 5;
        int count = (frame / speed) % 3;
        Texture2D currentTexture = (dead) ? down : (count == 0 ? up : (count == 1 ? bird : down));
        frame++;

        DrawTexturePro(
            currentTexture,
            { 0, 0, (float)currentTexture.width, (float)currentTexture.height },
            { (float)GetScreenWidth() / 2, (float)y, currentTexture.width * 1.6f, currentTexture.height * 1.6f },
            { currentTexture.width * 1.6f / 2, currentTexture.height * 1.6f / 2 },
            rotation,
            WHITE
        );
    }

    void update() {
        if (ready == false) {
            velocity += gravity;
            y += velocity;
        }

        if (velocity > 0 && velocity < 5) rotation += velocity / 5;
        else if (velocity < 0) rotation += velocity;
        else if (velocity > 0) rotation += velocity / 3;

        if (rotation > 90) rotation = 90;
        if (rotation < -45) rotation = -45;

        if ((IsMouseButtonPressed(MOUSE_BUTTON_LEFT) || IsKeyPressed(KEY_SPACE)) && !ready && !dead) {
            PlaySound(wing);
            velocity = -10;
        }

        if (y >= 780) y = 780;
    }
};

Platform Plat;
Player player;

int main() {
    InitWindow(576, 1024, "Flappy Bird Raylib");
    Image icon = LoadImage("favicon.ico");
    SetWindowIcon(icon);
    SetTargetFPS(60);
    InitAudioDevice();

    int points = 0;
    int high = 0;
    int hightemp = 0;
    double xval = 0;
    int waitval = 0;
    bool finaljump = true;
    bool ready = true;

    double startvel = -10;

    player.bird = LoadTexture("assets/bluebird.png");
    player.up = LoadTexture("assets/blueup.png");
    player.down = LoadTexture("assets/bluedown.png");
    player.play = LoadTexture("assets/playbutton.png");
    player.gameover = LoadTexture("assets/gameover.png");
    player.wing = LoadSound("audios/wing.wav");
    player.point = LoadSound("audios/point.ogg");
    player.hit = LoadSound("audios/hit.wav");
    player.die = LoadSound("audios/die.ogg");

    Plat.Pipe = LoadTexture("assets/pipe.png");
    Plat.Flipped = LoadTexture("assets/flipped.png");
    Plat.OldTent = LoadTexture("assets/oldtend.png");
    Plat.Extend = LoadTexture("assets/extender.png");

    Texture2D bg = LoadTexture("assets/bg.png");
    Texture2D base = LoadTexture("assets/base.png");
    Texture2D Readdy = LoadTexture("assets/GetReady.png");

    Font Flappy = LoadFont("fonts/flappy.ttf");

    Image favicon = LoadImage("favicon.png");
    SetWindowIcon(favicon);

    player.x = GetScreenWidth() / 2 - 107;
    player.y = GetScreenHeight() / 2;
    player.velocity = 10;
    player.gravity = 0.5;
    player.rotation = 90;

    Plat.dead = false;
    Plat.ready = true;

    Plat.init();

    while (!WindowShouldClose()) {
        BeginDrawing();
        ClearBackground(WHITE);

        DrawTextureEx(bg, { 0, 0 }, 0.0f, 2.0f, WHITE);

        player.update();
        Plat.draw();
        Plat.update();
        Plat.updateCollision();

        // collision box DrawRectangle(player.x + 85, player.y - 22, player.width - 15, player.height - 15, WHITE );
        Rectangle birdRect = { (float)player.x + 85, (float)player.y - 22, (float)player.width - 15, (float)player.height - 15 };

        f


// dear imgui, v1.92.1
// (widgets code)

/*

Index of this file:

// [SECTION] Forward Declarations
// [SECTION] Widgets: Text, etc.
// [SECTION] Widgets: Main (Button, Image, Checkbox, RadioButton, ProgressBar, Bullet, etc.)
// [SECTION] Widgets: Low-level Layout helpers (Spacing, Dummy, NewLine, Separator, etc.)
// [SECTION] Widgets: ComboBox
// [SECTION] Data Type and Data Formatting Helpers
// [SECTION] Widgets: DragScalar, DragFloat, DragInt, etc.
// [SECTION] Widgets: SliderScalar, SliderFloat, SliderInt, etc.
// [SECTION] Widgets: InputScalar, InputFloat, InputInt, etc.
// [SECTION] Widgets: InputText, InputTextMultiline
// [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc.
// [SECTION] Widgets: TreeNode, CollapsingHeader, etc.
// [SECTION] Widgets: Selectable
// [SECTION] Widgets: Typing-Select support
// [SECTION] Widgets: Box-Select support
// [SECTION] Widgets: Multi-Select support
// [SECTION] Widgets: Multi-Select helpers
// [SECTION] Widgets: ListBox
// [SECTION] Widgets: PlotLines, PlotHistogram
// [SECTION] Widgets: Value helpers
// [SECTION] Widgets: MenuItem, BeginMenu, EndMenu, etc.
// [SECTION] Widgets: BeginTabBar, EndTabBar, etc.
// [SECTION] Widgets: BeginTabItem, EndTabItem, etc.
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.

*/

#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif

#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
#endif

#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_internal.h"

// System includes
#include <stdint.h>     // intptr_t

//-------------------------------------------------------------------------
// Warnings
//-------------------------------------------------------------------------

// Visual Studio warnings
#ifdef _MSC_VER
#pragma warning (disable: 4127)     // condition expression is constant
#pragma warning (disable: 4996)     // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later
#pragma warning (disable: 5054)     // operator '|': deprecated between enumerations of different types
#endif
#pragma warning (disable: 26451)    // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2).
#pragma warning (disable: 26812)    // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
#endif

// Clang/GCC warnings with -Weverything
#if defined(__clang__)
#if __has_warning("-Wunknown-warning-option")
#pragma clang diagnostic ignored "-Wunknown-warning-option"         // warning: unknown warning group 'xxx'                      // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
#endif
#pragma clang diagnostic ignored "-Wunknown-pragmas"                // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wold-style-cast"                 // warning: use of old-style cast                            // yes, they are more terse.
#pragma clang diagnostic ignored "-Wfloat-equal"                    // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
#pragma clang diagnostic ignored "-Wformat"                         // warning: format specifies type 'int' but the argument has type 'unsigned int'
#pragma clang diagnostic ignored "-Wformat-nonliteral"              // warning: format string is not a string literal            // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
#pragma clang diagnostic ignored "-Wsign-conversion"                // warning: implicit conversion changes signedness
#pragma clang diagnostic ignored "-Wunused-macros"                  // warning: macro is not used                                // we define snprintf/vsnprintf on Windows so they are available, but not always used.
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"  // warning: zero as null pointer constant                    // some standard header variations use #define NULL 0
#pragma clang diagnostic ignored "-Wdouble-promotion"               // warning: implicit conversion from 'float' to 'double' when passing argument to function  // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
#pragma clang diagnostic ignored "-Wenum-enum-conversion"           // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_')
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
#pragma clang diagnostic ignored "-W


#include <iostream>

using namespace std;

int main() {
    string pahlawan;
    string musuh;
    string senjata;

    cout << "\n=== Selamat datang di Petualangan Negeri Konoha ===" << endl;
    cout << "Masukkan nama pahlawan kamu: ";
    getline(cin, pahlawan);

    cout << "Masukkan nama musuh yang akan melawan kamu: ";
    getline(cin, musuh);

    cout << "Masukkan nama senjata rahasia yang akan menjadi andalan kamu: ";
    getline(cin, senjata);

    cout << "\n===== Kisah Legenda =====" << endl;
    cout << "Di sebuah negeri yang jauh, hiduplah seorang pahlawan bernama " << pahlawan << "." << endl;
    cout << pahlawan << " ditugaskan untuk mengalahkan monster jahat " << musuh << " yang meneror desa." << endl;
    cout << "Berbekal " << senjata << " andalannya, " << pahlawan << " pun berangkat menuju markas " << musuh << " untuk pertarungan mempertahankan desa nya." << endl;
    cout << "Dengan keberanian, " << pahlawan << " berhasil mengalahkan " << musuh << " dan membawa kedamaian kembali." << endl;

    return 0;
}


#include "OutputGenerator.hpp"
#include <iostream>
#include <filesystem>
#include <algorithm>

std::string OutputGenerator::GetCurrentTimestamp() {
    auto now = std::chrono::system_clock::now();
    auto time_t = std::chrono::system_clock::to_time_t(now);
    auto tm = *std::gmtime(&time_t);

    std::ostringstream oss;
    oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S UTC");
    return oss.str();
}

void OutputGenerator::GenerateOutput() {
    std::filesystem::create_directories("output");

    GenerateHeaderFile();
    GenerateTextFile();
    GenerateJsonFile();

    std::cout << "\n[+] files dropped:\n";
    std::cout << "    - output/offsets.hpp (c++ header for your cheat)\n";
    std::cout << "    - output/offsets.txt (human readable breakdown)\n";
    std::cout << "    - output/offsets.json (json for whatever)\n";
}

void OutputGenerator::GenerateHeaderFile() {
    std::ofstream file("output/offsets.hpp");

    file << "// offset dumper\n";
    file << "// generated: " << GetCurrentTimestamp() << "\n";
    file << "// roblox version: " << robloxVersion << "\n";
    file << "// byfron version: " << byfronVersion << "\n";
    file << "// generated by: nwesk\n";
    file << "// keep it lowkey fr\n\n";

    file << "#pragma once\n";
    file << "#include <cstdint>\n\n";
    file << "namespace offsets {\n";

    // sort by category
    std::sort(offsets.begin(), offsets.end(), [](const OffsetEntry& a, const OffsetEntry& b) {
        if (a.category != b.category) return a.category < b.category;
        return a.name < b.name;
    });

    std::string currentCategory = "";
    for (const auto& offset : offsets) {
        if (offset.category != currentCategory) {
            if (!currentCategory.empty()) file << "\n";
            file << "    // " << offset.category << " offsets\n";
            currentCategory = offset.category;
        }

        if (offset.found) {
            file << "    inline constexpr uintptr_t " << offset.name
                 << " = 0x" << std::hex << std::uppercase << offset.offset << ";\n";
        } else {
            file << "    // inline constexpr uintptr_t " << offset.name
                 << " = 0x0; // not found - " << offset.description << "\n";
        }
    }

    file << "}\n";
    file.close();
}

void OutputGenerator::GenerateTextFile() {
    std::ofstream file("output/offsets.txt");

    file << "offset dumper\n";
    file << std::string(50, '=') << "\n";
    file << "generated: " << GetCurrentTimestamp() << "\n";
    file << "roblox version: " << robloxVersion << "\n";
    file << "byfron version: " << byfronVersion << "\n";
    file << "generated by: nwesk\n";
    file << std::string(50, '=') << "\n\n";

    std::string currentCategory = "";
    int foundCount = 0;

    for (const auto& offset : offsets) {
        if (offset.category != currentCategory) {
            if (!currentCategory.empty()) file << "\n";
            file << "[" << offset.category << " offsets]\n";
            file << std::string(25, '-') << "\n";
            currentCategory = offset.category;
        }

        if (offset.found) {
            file << "[✓] " << std::setw(25) << std::left << offset.name
                 << " : 0x" << std::hex << std::uppercase << std::setw(8) << std::setfill('0') << offset.offset;
            if (!offset.description.empty()) {
                file << " - " << offset.description;
            }
            file << "\n";
            foundCount++;
        } else {
            file << "[✗] " << std::setw(25) << std::left << offset.name
                 << " : not found";
            if (!offset.description.empty()) {
                file << " - " << offset.description;
            }
            file << "\n";
        }
    }

    file << "\n" << std::string(50, '=') << "\n";
    file << "summary:\n";
    file << "found: " << foundCount << "/" << offsets.size() << " offsets\n";
    file << "success rate: " << (foundCount * 100 / offsets.size()) << "%\n";
    file << "keep it lowkey\n";
    file << std::string(50, '=') << "\n";

    file.close();
}

void OutputGenerator::GenerateJsonFile() {
    std::ofstream file("output/offsets.json");

    file << "{\n";
    file << "  \"metadata\": {\n";
    file << "    \"dumper\": \"offset dumper\",\n";
    file << "    \"generated\": \"" << GetCurrentTimestamp() << "\",\n";
    file << "    \"roblox_version\": \"" << robloxVersion << "\",\n";
    file << "    \"byfron_version\": \"" << byfronVersion << "\",\n";
    file << "    \"generated_by\": \"rgwq\",\n";
    file << "    \"found_count\": " << GetFoundCount() << ",\n";
    file << "    \"total_count\": " << GetTotalCount() << ",\n";
    file << "    \"success_rate\": " << (GetFoundCount() * 100 / GetTotalCount()) << ",\n";
    file << "    \"note\": \"keep it lowkey\"\n"


// Fill out your copyright notice in the Description page of Project Settings.

#include "EnemyFSM.h"

#include "AIController.h"
#include "Enemy.h"
#include "EnemyAnim.h"
#include "NavigationSystem.h"
#include "TPS.h"
#include "TPSPlayer.h"
#include "Components/CapsuleComponent.h"
#include "Components/WidgetComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Kismet/KismetMathLibrary.h"
#include "Navigation/PathFollowingComponent.h"

// Sets default values for this component's properties
UEnemyFSM::UEnemyFSM()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;

	// ...
}

// Called when the game starts
void UEnemyFSM::BeginPlay()
{
	Super::BeginPlay();

	// 소유자 찾기
	me = Cast<AEnemy>(GetOwner());
	// 타겟 찾기
	target = Cast<ATPSPlayer>(UGameplayStatics::GetActorOfClass(GetWorld(), ATPSPlayer::StaticClass()));

	// 애니메이션 블루프린트
	anim = Cast<UEnemyAnim>(me->GetMesh()->GetAnimInstance());

	// ai controller 할당
	ai = Cast<AAIController>(me->GetController());

	hpUIComp = Cast<UWidgetComponent>(me->GetComponentByClass(UWidgetComponent::StaticClass()));
}

// Called every frame
void UEnemyFSM::TickComponent(float DeltaTime, ELevelTick TickType,
                              FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	// 현재 상태 출력
	FString stateStr = UEnum::GetValueAsString(_state);
	// PRINTLOG(TEXT("%s"), *stateStr);
	GEngine->AddOnScreenDebugMessage(0, 1, FColor::Cyan, stateStr);

	switch (_state)
	{
	case EEnemyState::Idle:
		IdleState();
		break;
	case EEnemyState::Move:
		MoveState();
		break;
	case EEnemyState::Attack:
		AttackState();
		break;
	case EEnemyState::Damage:
		DamageState();
		break;
	case EEnemyState::Die:
		DieState();
		break;
	}

	// billboarding 처리
	if (hpUIComp && target)
	{
		FVector direction = target->GetActorLocation() - me->GetActorLocation();
		direction.Z = 0;
		hpUIComp->SetWorldRotation(direction.Rotation());
	}
}

// 일정시간이 지나면 상태를 이동으로 전환하고 싶다.
// 필요속성 : 대기시간, 경과시간
void UEnemyFSM::IdleState()
{
	// 일정시간이 지나면 상태를 이동으로 전환하고 싶다.
	// 1. 시간이 흘러야한다.
	currentTime += GetWorld()->DeltaTimeSeconds;
	// 2. 경과시간이 대기시간을 초과하면
	if (currentTime > idleDelayTime)
	{
		// 3. 상태를 이동으로 전환한다.
		_state = EEnemyState::Move;
		currentTime = 0;
		// 4. 애니메이션 상태도 업데이트
		anim->_state = _state;

		// 랜덤위치 설정
		GetRandomPositionInNavMesh(me->GetActorLocation(), 500, randomPos);
	}
}

// 타겟쪽으로 이동하고 싶다.
// 타겟이 공격범위 안에 들어오면 상태를 공격으로 전환하고 싶다.
void UEnemyFSM::MoveState()
{
	// 플레이어가 없으면??
	if (IsValid(target) == false)
	{
		return;
	}
	// 아무처리하지 않는다.
	// p = p0 + vt
	FVector direction = target->GetActorLocation() - me->GetActorLocation();

	// 1. 타겟과의 거리가 필요하다.
	float distance = direction.Size();
	direction.Normalize();

	//me->AddMovementInput(direction);
	//

	// 목적지(타겟)까지 갈 수 있나?
	auto ns = UNavigationSystemV1::GetNavigationSystem(GetWorld());

	// 길찾기 쿼리 생성
	FAIMoveRequest req;
	FPathFindingQuery query;

	req.SetAcceptanceRadius(3);
	req.SetGoalLocation(target->GetActorLocation());
	ai->BuildPathfindingQuery(req, query);
	// 길을 찾을 수 있다.
	auto r = ns->FindPathSync(query);
	// 갈 수 있다면
	if (r.Result == ENavigationQueryResult::Success)
	{
		ai->MoveToLocation(target->GetActorLocation());
	}
	// 갈 수 없다면?
	else
	{
		// -> 그냥 랜덤위치 패트롤 돌자.
		auto result = ai->MoveToLocation(randomPos);
		// 목적지에 도착하면
		if (result == EPathFollowingRequestResult::Type::AlreadyAtGoal || result == EPathFollowingRequestResult::Failed)
		{
			// -> 랜덤위치 재설정
			GetRandomPositionInNavMesh(me->GetActorLocation(), 500, randomPos);
		}
	}

	// 타겟이 공격범위 안에 들어오면 상태를 공격으로 전환하고 싶다.
	// 2. 타겟과의 거리가 공격범위 안에 들어왔으니까.
	if (distance < attackRange)
	{
		// 3. 상태를 공격으로 전환
		_state = EEnemyState::Attack;
		anim->_state = _state;
		currentTime = attackDelayTime;

		ai->StopMovement();
	}
}

// 네비게이션 영역안에서 랜덤한 위치 가져오기
bool UEnemyFSM::GetRandomPositionInNavMesh(const FVector& centerPos,
	const float radius, FVector& dest)
{
	// 1. 네비게이션 시스템이 필요하다.
	auto ns = UNavigationSystemV1::GetNavigationSystem(GetWorld());
	// 2. 랜덤 위치 가져오기
	FNavLocation loc;
	bool bResult = ns->GetRandomReachablePointInRadius(centerPos, radius, loc);
	dest = loc.Location;
	return bResult;
}

// 일정시간에 한번씩 공격하고 싶다.
// 타겟이 공격범위를 벗어 났다면 상태를 이동으로 전환하고 싶다.
void UEnemyFSM::AttackState()
{
	// 시간이 흘러야한다. -> 공격대기시간 만큼 기다린다.
	currentTime += GetWorld()->DeltaTimeSeconds;

	if (currentTime > attackDelayTime)
	{
		// 공격
		currentTime = 0;

		anim->bAttackPlay = true;
	}

	// 타겟을 바라보게 하자.
	FVector dir = target->GetActorLocation() - me->GetActorLocation();
	FRotator rot = UKismetMathLibrary::MakeRotFromZX(me->GetActorUpVector(), dir);
	me->SetActorRotation(rot);

	// 거리
	float distance = FVector::Dist(target->GetActorLocation(), me->GetActorLocation());
	if (distance > attackRange)
	{
		_state = EEnemyState::Move;
		anim->_state = _state;

		GetRandomPosit


#include "map.hpp"
#include "vector.hpp"
#include <fstream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <dirent.h>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include <bits/stdc++.h>

using namespace std;

// Function declarations for all built-in commands
int shell_cd(vector<string> args);
int shell_ls(vector<string> args);
int shell_mkdir(vector<string> args);
int shell_touch(vector<string> args);
int shell_rm(vector<string> args);
int shell_cp(vector<string> args);
int shell_mv(vector<string> args);
int shell_echo(vector<string> args);
int shell_cat(vector<string> args);
int shell_grep(vector<string> args);
int shell_help(vector<string> args);
int shell_exit(vector<string> args);
int shell_wait(vector<string> args);
int shell_clear(vector<string> args);

// Map to associate command strings with function calls
Map<string, int (*)(vector<string>)> command_Map = {
    {"cd", shell_cd},
    {"ls", shell_ls},
    {"mkdir", shell_mkdir},
    {"touch", shell_touch},
    {"rm", shell_rm},
    {"cp", shell_cp},
    {"mv", shell_mv},
    {"echo", shell_echo},
    {"cat", shell_cat},
    {"grep", shell_grep},
    {"help", shell_help},
    {"exit", shell_exit},
    {"wait", shell_wait},
    {"clear", shell_clear}
};

// Read a line from standard input
string read_line() {
    string input;
    getline(cin, input);
    return input;
}

// Split the input line into tokens
vector<string> split_line(const string& line) {
    vector<string> args;
    size_t start = 0, end = line.find(' ');
    while (end != string::npos) {
        args.push_back(line.substr(start, end - start));
        start = end + 1;
        end = line.find(' ', start);
    }
    args.push_back(line.substr(start));
    return args;
}

// Execute shell built-in or external command
int execute(vector<string> args) {
    if (args.empty()) {
        return 1; // No command entered
    }

    string command = args[0];
    args.erase(args.begin());

    if (command_Map.count(command)) {
        return command_Map[command](args);
    } else {
        pid_t pid = fork();
        if (pid == 0) {
            vector<char*> c_args(args.size() + 2);
            c_args[0] = strdup(command.c_str());
            for (size_t i = 0; i < args.size(); i++) {
                c_args[i + 1] = strdup(args[i].c_str());
            }
            c_args[args.size() + 1] = NULL;

            execvp(c_args[0], c_args.data());
            cerr << "Command not found" << endl;
            exit(EXIT_FAILURE);
        } else if (pid < 0) {
            cerr << "Failed to fork" << endl;
        } else {
            int status;
            waitpid(pid, &status, 0);
        }
    }
    return 1;
}

// Command loop for shell input/output
void shell_loop() {
    string line;
    vector<string> args;
    int status;

    do {
        cout << "> ";
        line = read_line();
        args = split_line(line);
        status = execute(args);
    } while (status);
}

// Main entry point for the shell
int main() {
    shell_loop();
    return EXIT_SUCCESS;
}

// Implementation of built-in shell commands
int shell_cd(vector<string> args) {
    if (args.size() > 1) {
        cerr << "cd: too many arguments" << endl;
        return 1;
    }
    string dir = args.empty() ? getenv("HOME") : args[0];
    if (chdir(dir.c_str()) != 0) {
        perror("cd");
    }
    return 1;
}

int shell_ls(vector<string> args) {
    const char* path = args.empty() ? "." : args[0].c_str();
    DIR* dir = opendir(path);
    if (dir == nullptr) {
        perror("ls");
        return 1;
    }
    dirent* entry;
    while ((entry = readdir(dir)) != nullptr) {
        if (entry->d_name[0] != '.') { // Skip hidden files by default
            cout << entry->d_name << ' ';
        }
    }
    cout << endl;
    closedir(dir);
    return 1;
}

int shell_mkdir(vector<string> args) {
    if (args.empty()) {
        cerr << "mkdir: missing operand" << endl;
        return 1;
    }
    for (const auto& dir : args) {
        if (mkdir(dir.c_str(), 0777) != 0) { // Permission bits are set to allow all actions
            perror("mkdir");
        }
    }
    return 1;
}

int shell_touch(vector<string> args) {
    if (args.empty()) {
        cerr << "touch: missing operand" << endl;
        return 1;
    }
    for (const auto& filename : args) {
        int fd = open(filename.c_str(), O_CREAT | O_WRONLY, 0666);
        if (fd == -1) {
            perror("touch");
        } else {
            close(fd);
        }
    }
    return 1;
}

int shell_rm(vector<string> args) {
    if (args.empty()) {
        cerr << "rm: missing operand" << endl;
        return 1;
    }
    for (const auto& filename : args) {
        if (remove(filename.c_str()) != 0) {
            perror("rm");
        }
    }
    return 1;
}

int shell_cp(vector<string> args) {
    if (args.size() < 2) {
        cerr << "cp: missing source and destination files" << endl;
        return 1;
    }
    ifstre


// ----------------------------------------------------------------------------
// Mod loader of HT's Mod Loader.
// ----------------------------------------------------------------------------
#include <cmath>
#include "cJSON.h"

#include "includes/aliases.h"
#include "includes/htmodloader.h"
#include "utils/logger.h"
#include "utils/globals.h"
#include "utils/texts.h"
#include "htinternal.h"

static std::wstring utf8ToWchar(const char *input) {
  if (!input)
    return std::wstring();
  u64 len = strlen(input);
  std::wstring result;
  i32 size = MultiByteToWideChar(CP_UTF8, 0, input, len, nullptr, 0);
  result.resize(size);
  MultiByteToWideChar(CP_UTF8, 0, input, len, &result[0], size);
  return result;
}

static std::string wcharToUtf8(const wchar_t *input) {
  if (!input)
    return std::string();
  std::string result;
  i32 size = WideCharToMultiByte(CP_UTF8, 0, input, -1, nullptr, 0, nullptr, nullptr);
  result.resize(size);
  WideCharToMultiByte(CP_UTF8, 0, input, -1, &result[0], size, nullptr, nullptr);
  return result;
}

static inline i32 parseVersionNumber(
  const char *str,
  u32 *versions
) {
  u32 result[3];
  if (sscanf(str, "%u.%u.%u", result, result + 1, result + 2) != 3)
    return 0;
  memcpy(versions, result, 3 * sizeof(u32));
  return 1;
}

static inline i32 compareVersion(
  u32 *a1,
  u32 *a2
) {
  for (u08 i = 0; i < 3; i++) {
    if (a1[i] < a2[i])
      return -1;
    if (a1[i] > a2[i])
      return -1;
  }
  return 0;
}

/**
 * Helper function for get string value with cJSON.
 */
static inline std::string getStringValueFrom(
  cJSON *json,
  const char *key
) {
  char *s = cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(json, key));
  if (!s)
    return std::string();
  return std::string(s);
}

/**
 * Deserialize the manifest file.
 */
static i32 deserializeManifestJson(
  const char *buffer,
  ModManifest *manifest
) {
  i32 ret = 0;
  cJSON *json;
  char *parsedStr = nullptr;
  std::string version;
  double editionFlag;

  json = cJSON_Parse(buffer);
  if (!json)
    goto RET;

  // Get dll path.
  parsedStr = cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(json, "main"));
  if (!parsedStr)
    goto RET;
  manifest->paths.dll = manifest->paths.folder + L"\\" + utf8ToWchar(parsedStr);

  // Get package name.
  manifest->meta.packageName = getStringValueFrom(json, "package_name");
  if (manifest->meta.packageName.empty())
    goto RET;

  // Get mod version.
  version = getStringValueFrom(json, "version");
  if (!parseVersionNumber(version.data(), manifest->meta.version))
    goto RET;

  // Get compatible game edition of the mod.
  editionFlag = cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(json, "game_edition"));
  if (std::isnan(editionFlag) || ((u08)editionFlag & 0x03) == 0)
    goto RET;
  manifest->gameEditionFlags = (u08)editionFlag & 0x03;

  // Get display info.
  manifest->modName = getStringValueFrom(json, "mod_name");
  manifest->description = getStringValueFrom(json, "description");
  manifest->author = getStringValueFrom(json, "author");

  ret = 1;
RET:
  cJSON_Delete(json);
  return ret;
}

/**
 * Parse manifest.json to get the basic data of a mod, and check file integrity
 * of the mod.
 */
static i32 parseModManifest(
  const wchar_t *fileName,
  ModManifest *manifest
) {
  i32 ret;
  std::wstring folder(gPathModsWide);
  FILE *fd = nullptr;
  u64 size;
  wchar_t *buffer = nullptr;

  // Get the mod folder.
  folder += L"\\";
  folder += fileName;

  // Check the manifest.json.
  std::wstring jsonPath = folder + L"\\manifest.json";
  if (!fileExists(jsonPath.data()))
    return 0;

  // Open manifest.json.
  fd = _wfopen(jsonPath.data(), L"r, ccs=UTF-8");
  if (!fd)
    return 0;

  // Read file.
  fseek(fd, 0, SEEK_END);
  size = ftell(fd);
  rewind(fd);
  buffer = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
  if (!buffer) {
    fclose(fd);
    return 0;
  }
  fread(buffer, sizeof(wchar_t), size, fd);
  buffer[size] = 0;
  fclose(fd);

  // Save paths.
  manifest->paths.folder = folder;
  manifest->paths.json = jsonPath;

  // Deserialize manifest.
  std::string content = wcharToUtf8(buffer);
  ret = deserializeManifestJson(
    content.data(),
    manifest);

  // Parse and deserialize the file.
  free(buffer);
  return ret;
}

/**
 * Scan all potential mods.
 */
static void scanMods() {
  HANDLE hFindFile;
  WIN32_FIND_DATAW findData;
  ModManifest manifest;
  std::wstring modsFolderPath(gPathModsWide);

  modsFolderPath += L"\\*";
  hFindFile = FindFirstFileW(modsFolderPath.data(), &findData);
  if (!hFindFile)
    return;

  do {
    if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
      continue;
    if (!wcscmp(findData.cFileName, L".") || !wcscmp(findData.cFileName, L".."))
      continue;
    if (!parseModManifest(findData.cFileName, &manifest))
      continue;
    if (!fileExists(manifest.paths.dll.data()))
      continue;

    // When scanning mods, the mod data won't be accessed by multiple threads,


// midiprobe.cpp
//
// Simple program to check MIDI inputs and outputs.
//
// by Gary Scavone, 2003-2012.

#include <iostream>
#include <cstdlib>
#include <map>
#include "RtMidi.h"

int main()
{
  // Create an api map.
  std::map<int, std::string> apiMap;
  apiMap[RtMidi::MACOSX_CORE] = "OS-X CoreMIDI";
  apiMap[RtMidi::WINDOWS_MM] = "Windows MultiMedia";
  apiMap[RtMidi::WINDOWS_UWP] = "Windows UWP";
  apiMap[RtMidi::UNIX_JACK] = "Jack Client";
  apiMap[RtMidi::LINUX_ALSA] = "Linux ALSA";
  apiMap[RtMidi::RTMIDI_DUMMY] = "RtMidi Dummy";

  std::vector< RtMidi::Api > apis;
  RtMidi :: getCompiledApi( apis );

  std::cout << "\nCompiled APIs:\n";
  for ( unsigned int i=0; i<apis.size(); i++ )
    std::cout << "  " << apiMap[ apis[i] ] << std::endl;
  std::cout << std::endl;

  for ( unsigned int i=0; i<apis.size(); i++ ){
    std::cout << "Probing with API " << apiMap[ apis[i] ] << std::endl;

    RtMidiIn  *midiin = 0;
    RtMidiOut *midiout = 0;

    try {

      // RtMidiIn constructor ... exception possible
      midiin = new RtMidiIn(apis[i]);

      std::cout << "\nCurrent input API: " << apiMap[ midiin->getCurrentApi() ] << std::endl;

      // Check inputs.
      unsigned int nPorts = midiin->getPortCount();
      std::cout << "\nThere are " << nPorts << " MIDI input sources available.\n";

      for ( unsigned i=0; i<nPorts; i++ ) {
        std::string portName = midiin->getPortName(i);
        std::cout << "  Input Port #" << i << ": " << portName << '\n';
      }

      // RtMidiOut constructor ... exception possible
      midiout = new RtMidiOut(apis[i]);

      std::cout << "\nCurrent output API: " << apiMap[ midiout->getCurrentApi() ] << std::endl;

      // Check outputs.
      nPorts = midiout->getPortCount();
      std::cout << "\nThere are " << nPorts << " MIDI output ports available.\n";

      for ( unsigned i=0; i<nPorts; i++ ) {
        std::string portName = midiout->getPortName(i);
        std::cout << "  Output Port #" << i << ": " << portName << std::endl;
      }
      std::cout << std::endl;

    } catch ( RtMidiError &error ) {
      error.printMessage();
    }

    delete midiin;
    delete midiout;
  }

  return 0;
}