/*
 * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved.

 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:

 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "../../lv_conf_internal.h"
#if LV_USE_THORVG_INTERNAL

#include <string.h>
#include <math.h>
#include "tvgSwCommon.h"

/************************************************************************/
/* Internal Class Implementation                                        */
/************************************************************************/

static constexpr auto SW_STROKE_TAG_POINT = 1;
static constexpr auto SW_STROKE_TAG_CUBIC = 2;
static constexpr auto SW_STROKE_TAG_BEGIN = 4;
static constexpr auto SW_STROKE_TAG_END = 8;

static inline SwFixed SIDE_TO_ROTATE(const int32_t s)
{
    return (SW_ANGLE_PI2 - static_cast<SwFixed>(s) * SW_ANGLE_PI);
}

static inline void SCALE(const SwStroke& stroke, SwPoint& pt)
{
    pt.x = static_cast<SwCoord>(pt.x * stroke.sx);
    pt.y = static_cast<SwCoord>(pt.y * stroke.sy);
}

static void _growBorder(SwStrokeBorder* border, uint32_t newPts)
{
    auto maxOld = border->maxPts;
    auto maxNew = border->ptsCnt + newPts;

    if (maxNew <= maxOld) return;

    auto maxCur = maxOld;

    while (maxCur < maxNew)
        maxCur += (maxCur >> 1) + 16;
    //OPTIMIZE: use mempool!
    border->pts = static_cast<SwPoint*>(realloc(border->pts, maxCur * sizeof(SwPoint)));
    border->tags = static_cast<uint8_t*>(realloc(border->tags, maxCur * sizeof(uint8_t)));
    border->maxPts = maxCur;
}

static void _borderClose(SwStrokeBorder* border, bool reverse)
{
    auto start = border->start;
    auto count = border->ptsCnt;

    //Don't record empty paths!
    if (count <= start + 1U) {
        border->ptsCnt = start;
    } else {
        /* Copy the last point to the start of this sub-path,
           since it contains the adjusted starting coordinates */
        border->ptsCnt = --count;
        border->pts[start] = border->pts[count];

        if (reverse) {
            //reverse the points
            auto pt1 = border->pts + start + 1;
            auto pt2 = border->pts + count - 1;

            while (pt1 < pt2) {
                auto tmp = *pt1;
                *pt1 = *pt2;
                *pt2 = tmp;
                ++pt1;
                --pt2;
            }

            //reverse the tags
            auto tag1 = border->tags + start + 1;
            auto tag2 = border->tags + count - 1;

            while (tag1 < tag2) {
                auto tmp = *tag1;
                *tag1 = *tag2;
                *tag2 = tmp;
                ++tag1;
                --tag2;
            }
        }

        border->tags[start] |= SW_STROKE_TAG_BEGIN;
        border->tags[count - 1] |=  SW_STROKE_TAG_END;
    }

    border->start = -1;
    border->movable = false;
}

static void _borderCubicTo(SwStrokeBorder* border, const SwPoint& ctrl1, const SwPoint& ctrl2, const SwPoint& to)
{
    _growBorder(border, 3);

    auto pt = border->pts + border->ptsCnt;
    auto tag = border->tags + border->ptsCnt;

    pt[0] = ctrl1;
    pt[1] = ctrl2;
    pt[2] = to;

    tag[0] = SW_STROKE_TAG_CUBIC;
    tag[1] = SW_STROKE_TAG_CUBIC;
    tag[2] = SW_STROKE_TAG_POINT;

    border->ptsCnt += 3;
    border->movable = false;
}

static void _borderArcTo(SwStrokeBorder* border, const SwPoint& center, SwFixed radius, SwFixed angleStart, SwFixed angleDiff, SwStroke& stroke)
{
    constexpr SwFixed ARC_CUBIC_ANGLE = SW_ANGLE_PI / 2;
    SwPoint a = {static_cast<SwCoord>(radius), 0};
    mathRotate(a, angleStart);
    SCALE(stroke, a);
    a += center;

    auto total = angleDiff;
    auto angle = angleStart;
    auto rotate = (angleDiff >= 0) ? SW_ANGLE_PI2 : -SW_ANGLE_PI2;

    while (total != 0) {
        auto step = total;
        if (step > ARC_CUBIC_ANGLE) step = ARC_CUBIC_ANGLE;
        else if (step < -ARC_CUBIC_ANGLE) step = -ARC_CUBIC_ANGLE;

        auto next = angle + step;
        auto theta = step;
        if (theta < 0) theta = -theta;

        theta >>= 1;


/*
* @brief : d3d11로 큐브를 그리는 예제입니다
* @details :
*
		-  큐브를 만듭니다
			//    5________ 6
			//    /|      /|
			//   /_|_____/ |
			//  1|4|_ _ 2|_|7
			//   | /     | /
			//   |/______|/
			//  0       3

		- 인덱스 배열은 다음을 참고하세요
		 DWORD indices[] = {
		// 앞쪽
		0, 1, 2,
		2, 3, 0,
		// 왼쪽
		4, 5, 1,
		1, 0, 4,
		// 맨 위
		1, 5, 6,
		6, 2, 1,
		// 뒤쪽에
		7, 6, 5,
		5, 4, 7,
		// 오른쪽
		3, 2, 6,
		6, 7, 3,
		// 맨 아래
		4, 0, 3,
		3, 7, 4
		};
*/

#include "App.h"
#include "../Common/Helper.h"
#include <d3dcompiler.h>
#include <directxtk/WICTextureLoader.h>
#include <thread>

#pragma comment (lib, "d3d11.lib")
#pragma comment(lib,"d3dcompiler.lib")

bool App::OnInitialize()
{
	if(!InitD3D()) return false;

	if (!InitEffect()) return false;

	if(!InitScene()) return false;

	// ImGui 초기화
	IMGUI_CHECKVERSION();
	ImGui::CreateContext();
	ImGui::StyleColorsDark();
	ImGui_ImplWin32_Init(m_hWnd);
	ImGui_ImplDX11_Init(m_pDevice, m_pDeviceContext);

	// 시스템 정보 수집 (GPU)
	{
		Microsoft::WRL::ComPtr<IDXGIDevice> dxgiDevice;
		if (SUCCEEDED(m_pDevice->QueryInterface(IID_PPV_ARGS(dxgiDevice.GetAddressOf()))))
		{
			Microsoft::WRL::ComPtr<IDXGIAdapter> adapter;
			if (SUCCEEDED(dxgiDevice->GetAdapter(adapter.GetAddressOf())))
			{
				DXGI_ADAPTER_DESC desc{};
				if (SUCCEEDED(adapter->GetDesc(&desc)))
				{
					m_GPUName = desc.Description;
				}
				adapter.As(&m_Adapter3);
				if (m_Adapter3)
				{
					DXGI_QUERY_VIDEO_MEMORY_INFO memInfo{};
					if (SUCCEEDED(m_Adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &memInfo)))
					{
						m_VideoMemoryTotal = memInfo.Budget; // 사용 가능 예산을 총량 근사로 사용
					}
				}
			}
		}
	}

	// 시스템 정보 수집 (CPU)
	{
		wchar_t cpuName[128] = L"";
		DWORD size = sizeof(cpuName);
		HKEY hKey;
		if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
		{
			DWORD type = 0;
			RegQueryValueExW(hKey, L"ProcessorNameString", nullptr, &type, reinterpret_cast<LPBYTE>(cpuName), &size);
			RegCloseKey(hKey);
		}
		m_CPUName = cpuName;
		m_CPUCores = std::thread::hardware_concurrency();
	}

	// 시스템 메모리 총량/가용량 초기화
	{
		MEMORYSTATUSEX ms{ sizeof(MEMORYSTATUSEX) };
		if (GlobalMemoryStatusEx(&ms))
		{
			m_RamTotal = ms.ullTotalPhys;
			m_RamAvail = ms.ullAvailPhys;
		}
	}

	return true;
}

void App::OnUninitialize()
{
	// ImGui 종료
	ImGui_ImplDX11_Shutdown();
	ImGui_ImplWin32_Shutdown();
	ImGui::DestroyContext();

	UninitD3D();
}

void App::OnUpdate(const float& dt)
{
	static float t0 = 0.0f, t1 = 0.0f, t2 = 0.0f;
	t0 += 0.6f * dt;   // 부모(루트) Yaw 속도
	t1 += 1.0f * dt;   // 두번째 메쉬(자식1) Yaw 속도 (루트와 다르게)
	t2 += 1.2f * dt;   // 세번째 메쉬(자식2) 공전 속도

	// 로컬 변환 정의 (간단 Scene Graph)
	XMMATRIX local0 = XMMatrixRotationY(t0) * XMMatrixTranslation(m_RootPos.x, m_RootPos.y, m_RootPos.z); // 루트
	XMMATRIX local1 = XMMatrixRotationY(t1) * XMMatrixTranslation(m_Child1Offset.x, m_Child1Offset.y, m_Child1Offset.z);  // 자식1 (루트 기준 상대)
	XMMATRIX local2 = XMMatrixRotationY(t2) * XMMatrixTranslation(m_Child2Offset.x, m_Child2Offset.y, m_Child2Offset.z);  // 자식2: 자식1을 중심으로 공전

	// 부모-자식 계층 world 계산: world = local * parentWorld
	XMMATRIX world0 = local0;                 // 루트
	XMMATRIX world1 = local1 * world0;        // 자식1
	XMMATRIX world2 = local2 * world1;        // 자식2 (자식1 주변 공전)

	// View/Proj도 UI값 반영 (매 프레임)
	XMMATRIX view = XMMatrixTranspose(XMMatrixLookAtLH(
		XMVectorSet(m_CameraPos.x, m_CameraPos.y, m_CameraPos.z, 0.0f),
		XMVectorSet(m_CameraPos.x + 0.0f, m_CameraPos.y + 0.0f, m_CameraPos.z + 1.0f, 0.0f),
		XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f)));
	float fovRad = XMConvertToRadians(m_CameraFovDeg);
	XMMATRIX proj = XMMatrixTranspose(XMMatrixPerspectiveFovLH(fovRad, AspectRatio(), m_CameraNear, m_CameraFar));

	m_CBuffers[0].world = XMMatrixTranspose(world0);
	m_CBuffers[0].view = view;
	m_CBuffers[0].proj = proj;
	m_CBuffers[1].world = XMMatrixTranspose(world1);
	m_CBuffers[1].view = view;
	m_CBuffers[1].proj = proj;
	m_CBuffers[2].world = XMMatrixTranspose(world2);
	m_CBuffers[2].view = view;
	m_CBuffers[2].proj = proj;

	// FPS 1초 업데이트
	m_FpsTimer += dt;
	if (m_FpsTimer >= 1.0f)
	{
		m_LastFps = 1.0f / dt; // 간단히 최근 프레임의 역수 사용
		m_FpsTimer = 0.0f;
	}

	// 시스템 메모리 가용량 갱신
	{
		MEMORYSTATUSEX ms{ sizeof(MEMORYSTATUSEX) };
		if (GlobalMemoryStatusEx(&ms))
		{
			m_RamTotal = ms.ullTotalPhys;
			m_RamAvail = ms.ullAvailPhys;
		}
	}

	// VRAM 사용량 갱신 (가능한 경우)
	if (m_Adapter3)
	{
		DXGI_QUERY_VIDEO_MEMORY_INFO memInfo{};
		if (SUCCEEDED(m_Adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &memInfo)))
		{
			// Budget은 사용 가능 한도, CurrentUsage는 현재 사용량
			m_VideoMemoryTotal = memInfo.Budget;
			// 사용량은 memInfo.CurrentUsage를 직접 사용, 표시 시 변환
		}
	}
}

// Render() 함수에 중요한 부분이 다 들어있습니다. 여기를 보면 됩니다
void App::OnRender()
{
	float color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
	UINT stride = sizeof(VertexPosTex);	// 바이트 수
	UINT offset = 0;

	m_pDeviceContext->ClearRenderTargetView(m_pRenderTargetView, color);
	m_pDeviceContext->ClearDepthStencilVie


#include <iostream>
#include <vector>
#include <queue>
#include <limits>
#include <algorithm>
#include <utility>
using namespace std;

struct Edge {
    int to;
    long long w;
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, M;
    cout << "Enter number of nodes and edges: ";
    cin >> N >> M;

    vector<vector<Edge>> graph(N);
    cout << "Enter edges (u v weight):\n";
    for (int i = 0; i < M; i++) {
        int u, v;
        long long w;
        cin >> u >> v >> w;
        graph[u].push_back({ v, w });
        graph[v].push_back({ u, w });
    }

    int start;
    cout << "Enter start node: ";
    cin >> start;

    const long long INF = 1e18;
    vector<long long> dist(N, INF);
    dist[start] = 0;

    using P = pair<long long, int>;
    priority_queue<P, vector<P>, greater<P>> pq;
    pq.push({ 0, start });

    while (!pq.empty()) {
        auto [d, u] = pq.top();
        pq.pop();

        if (d != dist[u]) continue;

        for (auto& e : graph[u]) {
            if (dist[e.to] > dist[u] + e.w) {
                dist[e.to] = dist[u] + e.w;
                pq.push({ dist[e.to], e.to });
            }
        }
    }

    cout << "\nShortest distances from node " << start << ":\n";
    for (int i = 0; i < N; i++) {
        if (dist[i] == INF)
            cout << i << ": unreachable\n";
        else
            cout << i << ": " << dist[i] << "\n";
    }
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;

class Name {
   char* m_first{};
   char* m_last{};
   void set(const char* first, const char* last) {
      delete[] m_first;
      delete[] m_last;
      if (first) {
         m_first = new char[strlen(first) + 1];
         strcpy(m_first, first);
      }
      else {
         m_first = nullptr;
      }
      if (last) {
         m_last = new char[strlen(last) + 1];
         strcpy(m_last, last);
      }
      else {
         m_last = nullptr;
      }
   }
public:
   // Constructor
   Name(const char* first = nullptr, const char* last = nullptr) {
      set(first, last);
   }

   // Destructor
   ~Name() {
      delete[] m_first;
      delete[] m_last;
   }

   // Copy Constructor
   Name(const Name& other) {
      set(other.m_first, other.m_last);
   }
   // Move Constructor
   Name(Name&& other) {
      m_first = other.m_first;
      m_last = other.m_last;
      other.m_first = other.m_last = nullptr;
   }

   // Copy Assignment
   Name& operator=(const Name& other) {
      if (this != &other) {
         set(other.m_first, other.m_last);
      }
      return *this;
   }
   // Move Assignment
   Name& operator=(Name&& other) {
      if (this != &other) {
         m_first = other.m_first;
         m_last = other.m_last;
         other.m_first = other.m_last = nullptr;
      }
      return *this;
   }

   void display(ostream& os = cout) const {
      os << (m_first ? m_first : "") << ' ' << (m_last ? m_last : "");
   }
};
ostream& operator<<(ostream& os, const Name& n) {
   n.display(os);
   return os;
}

Name makeName() {
   Name temp("Alice", "Wonderland");
   return temp;
}

void printByValue(Name n) {
   cout << "Inside printByValue: ";
   n.display();
   cout << '\n';
}
int main() {
   // Copy constructor via pass-by-value
   printByValue(Name("John", "Doe"));
   Name n2 = makeName();
   cout << "n2: "; n2.display(); cout << '\n';
   return 0;
}


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

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

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

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

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

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

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

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

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

  ::CoUninitialize();
  return EXIT_SUCCESS;
}


/*
 *      Interactive disassembler (IDA).
 *      Version 2.06
 *      Copyright (c) 1990-93 by Ilfak Guilfanov. (2:5020/209@fidonet)
 *      ALL RIGHTS RESERVED.
 *
 */

#include "i5.hpp"

//----------------------------------------------------------------------
class out_z80_t : public outctx_t
{
  out_z80_t(void) = delete; // not used
  z80_t &pm() { return *static_cast<z80_t *>(procmod); }

public:
  void OutReg(int rgnum);
  bool out_operand(const op_t &x);
  void out_insn(void);
};
CASSERT(sizeof(out_z80_t) == sizeof(outctx_t));

DECLARE_OUT_FUNCS_WITHOUT_OUTMNEM(out_z80_t)

//----------------------------------------------------------------------
static const char *const condNames[] =
{
  "nz",
  "z",
  "nc",
  "c",
  "po",
  "pe",
  "p",
  "m"
};

//----------------------------------------------------------------------
void out_z80_t::OutReg(int rgnum)
{
  if ( (ash.uflag & UAS_NPAIR) != 0 )
  {
    switch ( rgnum )
    {
      case R_bc: out_register(ph.reg_names[R_b]); return;
      case R_de: out_register(ph.reg_names[R_d]); return;
      case R_hl: out_register(ph.reg_names[R_h]); return;
    }
  }
  if ( rgnum == R_af && pm().isZ80() && !pm().isFunny() )
    out_register("af");
  else
    out_register(ph.reg_names[rgnum]);
}

//----------------------------------------------------------------------
bool out_z80_t::out_operand(const op_t &x)
{
  if ( !x.shown() )
    return false;
  switch ( x.type )
  {
    case o_cond:
      if ( x.Cond == oc_not )
        return false;
      {
        char buf[3];
        qstrncpy(buf, condNames[ x.Cond ], sizeof(buf));
        if ( ash.uflag & UAS_CNDUP )
          qstrupr(buf);
        out_keyword(buf);
      }
      break;

    case o_reg:
      OutReg(x.reg);
      break;

    case o_displ:         // Z80 only!!! + GB, one instruction
      if ( ash.uflag & UAS_MKOFF )
        out_value(x, OOF_ADDR|OOFW_16);
      if ( !pm().isGB() )
        out_symbol('(');
      OutReg(x.phrase);
      if ( !(ash.uflag & UAS_MKOFF) )
      {
        qstring buf;
        if ( is_off(F, x.n)
          && get_offset_expression(&buf, insn.ea,x.n,insn.ea+x.offb,x.addr) )
        {
          out_symbol('+');
          out_line(buf.c_str());
        }
        else
        {
          int offbit = (insn.auxpref & aux_off16) ? OOFW_16 : OOFW_8;
          int outf = OOF_ADDR|offbit|OOFS_NEEDSIGN;
          if ( ash.uflag & UAS_TOFF )
            outf |= OOF_SIGNED;
          out_value(x, outf);
        }
      }
      if ( !pm().isGB() )
        out_symbol(')');
      break;

    case o_phrase:
      if ( pm().isZ80() && !pm().isFunny() )
      {
        out_symbol((ash.uflag & UAS_GBASM) ? '[' : '(');
        OutReg(x.phrase);
        out_symbol((ash.uflag & UAS_GBASM) ? ']' : ')');
      }
      else
      {
        if ( x.phrase == R_hl )
          out_register("m");
        else
          OutReg(x.phrase);
      }
      break;

    case o_void:
      return 0;

    case o_imm:
      {
        const char *name = nullptr;
        bool needbrace = false;
        if ( pm().isZ80() )
        {
          switch ( insn.itype )
          {
            case I5_rst:
              if ( pm().isFunny() )
              {
                int radix = get_radix(F, x.n);
                out_long(x.value/8, radix);
                return 1;
              }
            case Z80_im:
            case Z80_bit:
            case Z80_res:
            case Z80_set:
//              name = pm().find_ioport_bit(x.value);
              break;
            case HD_in0:
            case HD_out0:
              name = pm().find_ioport(x.value);
              // fallthrough
            case I5_in:
            case I5_out:
            case Z80_outaw:
            case Z80_inaw:
              if ( !pm().isFunny() )
              {
                out_symbol('(');
                needbrace = true;
              }
              break;
            default:
              if ( ash.uflag & UAS_MKIMM )
                out_symbol('#');
              break;
          }
        }
        if ( name != nullptr )
          out_line(name, COLOR_IMPNAME);
        else
          out_value(x, 0);
        if ( needbrace )
          out_symbol(')');
      }
      break;

    case o_mem:
      if ( pm().isZ80() && !pm().isFunny() )
        out_symbol((ash.uflag & UAS_GBASM) ? '[' : '(');
      // no break
    case o_near:
      {
        ea_t v = map_ea(insn, x, x.type == o_near);
        if ( v == insn.ea && ash.a_curip != nullptr )
        {
          out_line(ash.a_curip);
        }
        else if ( !out_name_expr(x, v, x.addr) )
        {
          out_tagon(COLOR_ERROR);
          out_btoa(x.addr,16);
          out_tagoff(COLOR_ERROR);
          remember_problem(PR_NONAME,insn.ea);
        }
        if ( x.type == o_mem && pm().isZ80() && !pm().isFunny() )
          out_symbol((ash.uflag & UAS_GBASM) ? ']' : ')');
      }
      break;

    default:
      warning("bad optype %x", x.type);
      break;
  }
  return 1;
}

//---------


#include<iostream>
#include<string>
#define MAX 1000
using namespace std;

//涉及联系人结构体
struct Person
{
	string m_Name;
	//性别 1 男 2 女
	int m_Sex;
	//年龄
	int m_Age;
	//电话
	string m_Phone;
	//地址
	string m_Addr;
};

struct Addressbooks
{
	//联系人数组
	struct Person personArray[MAX];
	int m_Size;
};

//1添加联系人
void addPerson(Addressbooks* abs)
{
	//判断通讯录是否满了
	if (abs->m_Size == MAX)
	{
		cout << "通讯录满了，无法添加" << endl;
		return;
	}
	else
	{
		//添加联系人
		//姓名
		string name;
		cout << "请输入姓名： " << endl;
		cin >> name;
		abs->personArray[abs->m_Size].m_Name = name;
		//性别
		cout << "请输入性别: " << endl;
		cout << "1--男" << endl;
		cout << "2--女" << endl;
		int sex = 0;
		while (true)
		{
			cin >> sex;
			if (sex == 1 || sex == 2)
			{
				abs->personArray[abs->m_Size].m_Sex = sex;
				break;
			}
			else
				cout << "输入有误，请重新输入" << endl;
		}
		//年龄
		int age = 0;
		cout << "请输入年龄： " << endl;
		cin >> age;
		abs->personArray[abs->m_Size].m_Age = age;
		//电话
		cout << "请输入联系电话" << endl;
		string phone;
		cin >> phone;
		abs->personArray[abs->m_Size].m_Phone =phone;
		//住址
		cout << "请输入家庭住址" << endl;
		string address;
		cin >> address;
		abs->personArray[abs->m_Size].m_Addr = address;
		//更新通讯录人数
		abs->m_Size++;
		cout << "添加成功！" << endl;
		system("pause");//按任意键继续
		system("cls");//清屏操作
	}
}

//2显示联系人
void showPerson(Addressbooks* abs)
{
	//判断通讯录中人数是否为0
	if (abs->m_Size == 0)
	{
		cout << "当前记录为空" << endl;
	}
	else
	{
		for (int i = 0; i < abs->m_Size; i++)
		{
			cout << "姓名： " << abs->personArray[i].m_Name << "\t";
			cout << "性别： " << (abs->personArray[i].m_Sex==1?"男":"女" )<< "\t";
			cout << "年龄： " << abs->personArray[i].m_Age << "\t";
			cout << "电话: " << abs->personArray[i].m_Phone << "\t";
			cout << "住址: " << abs->personArray[i].m_Addr << endl;
		}
	}
	system("pause");
	system("cls");
}

//检查是否存在,参数1通讯录，参数2联系人姓名
int isExist(Addressbooks* abs, string name)
{
	for(int i =0;i<abs->m_Size;i++)
		if (abs->personArray[i].m_Name == name)
		{
			return i;
		}
	return -1;//如果没有找到，返回-1
}

//3，删除指定联系人
 void deletePerson(Addressbooks * abs)
{
	 cout << "请输入你要删除的联系人" << endl;
	 string name;
	 cin >> name;
	 int ret = isExist(abs, name);
	 if (ret != -1)
	 {
		 for (int i = ret; i < abs->m_Size; i++)
		 {
			 abs->personArray[i] = abs->personArray[i + 1];//数据前移
		 }
		 abs->m_Size--;//更新通讯录的人员数
		 cout << "删除成功" << endl;
	 }
	 else
	 {
		 cout << "查无此人" << endl;

	 }
	 system("pause");
	 system("cls");
}

 //4,查找指定的联系人信息
 void findPerson(Addressbooks* abs)
 {
	 cout << "请输入你要查找的联系人" << endl;
	 string name;
	 cin >> name;
	 //判断指定的联系人是否存在通讯录中
	 int ret=isExist(abs, name);
	 if (ret != -1)
	 {
		 //找到了
		 cout << "姓名: " << abs->personArray[ret].m_Name << "\t";
		 cout << "性别： " << abs->personArray[ret].m_Sex << "\t";
		 cout << "年龄： " << abs->personArray[ret].m_Age << "\t";
		 cout << "电话： " << abs->personArray[ret].m_Phone << "\t";
		 cout << "住址： " << abs->personArray[ret].m_Addr << endl;
	 }
	 else
	 {
		 //未找到联系人
		 cout << "查无此人" << endl;
	 }
	 system("pause");
	 system("cls");
 }

 //5,修改指定联系人信息
 void modifyPerson(Addressbooks* abs)
 {
	 cout << "请输入要修改的联系人" << endl;
	 string name;
	 cin >> name;
	 int ret = isExist(abs, name);

	 if (ret != -1)
	 {
		 //姓名
		 cout << "请输入姓名： " << endl;
		 string name;
		 cin >> name;
		 abs->personArray[ret].m_Name = name;
		 //性别
		 cout << "请输入性别： " << endl;
		 cout << "1--男" << endl;
		 cout << "2--女" << endl;
		 int sex = 0;
		 while (true)
		 {
			 cin >> sex;
			 if (sex == 1 || sex == 2)
			 {
				 abs->personArray[ret].m_Sex = sex;
				 break;
			 }
			 cout << "输入错误" << endl;
		 }
		 //年龄
		 cout << "请输入年龄： " << endl;
		 int age = 0;
		 cin >> age;
		 abs->personArray[ret].m_Age = age;
		 //电话
		 cout << "请输入联系电话： " << endl;
		 string phone;
		 cin >> phone;
		 abs->personArray[ret].m_Phone = phone;
		 //地址
		 cout << "请输入一个家庭地址： " << endl;
		 string address;
		 cin >> address;
		 abs->personArray[ret].m_Addr = address;
		 cout << "修改成功" << endl;
	 }
	 else
	 {
		 cout << "查无此人" << endl;
	 }
	 system("pause");
	 system("cls");
 }

 //6,清空联系人
 void clearPerson(Addressbooks* abs)
 {
	 abs->m_Size = 0;//将当前联系人数置为0
	 cout << "通讯录已清空" << endl;
	 system("pause");
	 system("cls");

 }
//显示菜单界面
void showMenu()
{
	cout << "************************" << endl;
	cout << "***** 1,添加联系人 *****" << endl;
	cout << "***** 2,显示联系人 *****" << endl;
	cout << "***** 3,删除联系人 *****" << endl;
	cout << "***** 4,查找联系人 *****" << endl;
	cout << "***** 5,修改联系人 *****" << endl;
	cout << "***** 6,清空联系人 *****" << endl;
	cout << "***** 0,退出通讯录 *****" << endl;

}

int main()
{
	//创建结构体变量
	Addressbooks abs;
	abs.m_Size = 0;
	int select = 0;//创建用户选择的对象
	while (true) {
		showMenu();
		cin >> select;
		switch (select)
		{
		case 1://添加
			addPerson(&abs);//利用地址传递，可以修饰实参
			break;
		case 2://显示
			showPerson(&abs);
			break;
		case 3://删除
	/*	{
			cout << "请输入删除联系人姓名： " << endl;
			string name;
			cin >> name;
			if (isExist(&abs,name) == -1)
			{
				cout << "查无此人" << endl;
			}
			else
			{
				cout << "找到此人" << endl;
			}


#include<iostream>
#include<stdlib.h>
#include<cmath>

using namespace std;

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

int main(){

    int option=-1;

    do{
        cout<<"=====Taller #1 - IP====="<<endl;
        cout<<"1. Punto uno."<<endl;
        cout<<"2. Punto dos."<<endl;
        cout<<"3. Punto tres."<<endl;
        cout<<"4. Punto cuatro."<<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 0:
            cout<<"Saliendo del programa."<<endl;
            break;

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

    }while(option!=0);

    return 0;
}

void firstPoint(){

    double gradeOne=0.0, gradeTwo=0.0, gradeThree=0.0, finalGrade=0.0;

    cout<<"Digite su primera nota: ";
    cin>>gradeOne;
    cout<<"Digite su segunda nota: ";
    cin>>gradeTwo;
    cout<<"Digite su tercera nota: ";
    cin>>gradeThree;

    if(gradeOne<=5.0 && gradeTwo<=5.0 && gradeThree<=5.0 && 0.0<=gradeOne && 0.0<=gradeTwo && 0.0<=gradeThree){

        finalGrade=(gradeOne+gradeTwo+gradeThree)/3;
        cout<<"\nSu nota final es: "<<finalGrade<<endl;
    }else{

        cout<<"\nLas notas no estan en el rango valido [0.0 - 5.0], digitelas de nuevo."<<endl;
        firstPoint();
    }
}

void secondPoint(){

    string studentName="";
    double practicalGrade=0.0, theoricalGrade=0.0, participationGrade=0.0, finalGrade=0.0;

    cout<<"Digite su nombre: ";
    fflush(stdin);
    getline(cin, studentName);

    cout<<"\nDigite su nota de practica: ";
    cin>>practicalGrade;
    cout<<"Digite su nota teorica: ";
    cin>>theoricalGrade;
    cout<<"Digite su nota de participacion: ";
    cin>>participationGrade;

    if(practicalGrade<=5.0 && theoricalGrade<=5.0 && participationGrade<=5.0 && 0.0<=practicalGrade && 0.0<=theoricalGrade && 0.0<=participationGrade){

        finalGrade=(practicalGrade*0.3)+(theoricalGrade*0.6)+(participationGrade*0.1);
        cout<<"\nNombre del alumno: "<<studentName<<endl;
        cout<<"Nota final: "<<finalGrade<<endl;
    }else{

        cout<<"\nLas notas no estan en el rango valido [0.0 - 5.0], digitelas de nuevo."<<endl;
        secondPoint();
    }
}

void thirdPoint(){

    double firstLeg=0.0, secondLeg=0.0, hypotenuse=0.0;

    cout<<"Digite la medida del primer cateto: ";
    cin>>firstLeg;
    cout<<"Digite la medida del segundo cateto: ";
    cin>>secondLeg;

    if(firstLeg>0 && secondLeg>0){

        hypotenuse=sqrt(pow(firstLeg,2)+pow(secondLeg,2));
        cout<<"\nLa hipotenusa del triangulo mide: "<<hypotenuse<<endl;
    }else{

        cout<<"\nLas medidas de los catetos no son validas, digitelas de nuevo."<<endl;
        thirdPoint();
    }
}

void fourthPoint(){

    int calculatorOption=-1;
    int firstAddend=0, secondAddend=0;
    int minuend=0, subtrahend=0;
    int firstFactor=0, secondFactor=0;
    int dividend=0, divisor=0;
    int base=0, exponent=0;
    int radicand=0;
    int result=0;

    do{
        cout<<"=====Calculadora====="<<endl;
        cout<<"1. Suma."<<endl;
        cout<<"2. Resta."<<endl;
        cout<<"3. Multiplicacion."<<endl;
        cout<<"4. Division."<<endl;
        cout<<"5. Potencia."<<endl;
        cout<<"6. Raiz."<<endl;
        cout<<"0. Salir."<<endl;
        cout<<"\nDigite la opcion a la que desea ingresar: ";
        cin>>calculatorOption;
        cout<<"========================"<<endl;

        switch(calculatorOption){
            case 1:
                cout<<"Digite el primer sumando: ";
                cin>>firstAddend;
                cout<<"Digite el segundo sumando: ";
                cin>>secondAddend;

                result=firstAddend+secondAddend;

                cout<<"\nEl resultado de la suma es: "<<result<<endl;
                break;

            case 2:
                cout<<"Digite el minuendo: ";
                cin>>minuend;
                cout<<"Digite el sustranedo: ";
                cin>>subtrahend;

                result=minuend-subtrahend;

                cout<<"\nEl resultado de la resta es: "<<result<<endl;
                break;

            case 3:
                cout<<"Digite el primer factor: ";
                cin>>firstFactor;
                cout<<"Digite el segundo factor: ";
                cin>>secondFactor;

                result=firstFactor*secondFactor;

                cout<<"\nEl resultado de la multiplicacion es: "<<result<<endl;
                break;

            ca


#include <iostream>
#include <vector>
#include <queue>
#include <limits>
#include <algorithm>
using namespace std;

#define INF 1e9

class Driver {
public:
    int id;
    int location;
    bool available;
    Driver(int _id, int _location) {
        id = _id;
        location = _location;
        available = true;
    }
};

class Rider {
public:
    int id;
    int pickup;
    int drop;
    Rider(int _id, int _pickup, int _drop) {
        id = _id;
        pickup = _pickup;
        drop = _drop;
    }
};

vector<int> dijkstra(int start, vector<vector<pair<int,int>>> &graph) {
    int n = graph.size();
    vector<int> dist(n, INF);
    dist[start] = 0;
    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
    pq.push({0, start});

    while(!pq.empty()) {
        int u = pq.top().second;
        int d = pq.top().first;
        pq.pop();
        if(d > dist[u]) continue;
        for(auto edge : graph[u]) {
            int v = edge.first;
            int w = edge.second;
            if(dist[u] + w < dist[v]) {
                dist[v] = dist[u] + w;
                pq.push({dist[v], v});
            }
        }
    }
    return dist;
}

vector<int> Notes = {1000, 500, 200, 100, 50, 20, 10, 5};

vector<int> minCoinsDP(int amount) {
    vector<int> dp(amount + 1, INF);
    vector<int> coinUsed(amount + 1, -1);
    dp[0] = 0;

    for(int i = 1; i <= amount; i++) {
        for(int note : Notes) {
            if(i - note >= 0 && dp[i - note] + 1 < dp[i]) {
                dp[i] = dp[i - note] + 1;
                coinUsed[i] = note;
            }
        }
    }

    vector<int> coins;
    int amt = amount;
    while(amt > 0 && coinUsed[amt] != -1) {
        coins.push_back(coinUsed[amt]);
        amt -= coinUsed[amt];
    }
    return coins;
}

int main() {
    vector<string> locations = {
        "Gulshan", "Banani", "Dhanmondi", "Mirpur", "Motijheel",
        "Uttara", "Mohakhali", "Rampura" , "Farmgate", "Aftabnagar"
    };

    int n = locations.size();

    vector<vector<pair<int,int>>> graph(n);

    auto addRoad = [&](int u, int v, int w){
        graph[u].push_back({v,w});
        graph[v].push_back({u,w});
    };

    addRoad(0,1,3); // Gulshan to Banani to Gulshan
    addRoad(0,6,4); // Gulshan to Mohakhali to Gulshan
    addRoad(1,6,2); // Banani to Mohakhali to Banani
    addRoad(1,3,7); //Banani to Mirpur to Banani
    addRoad(2,3,5); // Dhanmondi to Mirpur to Dhanmondi
    addRoad(2,4,6); // Dhanmondi to Motijheel to Dhanmondi
    addRoad(3,5,8); // Mirpur to Uttara to Mirpur
    addRoad(4,6,5); // Motijheel to Mohakhali to Motijheel
    addRoad(4,7,4); // Motijheel to Rampura to Motijheel
    addRoad(5,7,10);// Uttara  Rampura to Uttara
    addRoad(2,8,4); // Dhanmondi to Farmgate to Dhanmondi
    addRoad(7,8,2); // Farmgate to Rampura to Farmgate

    int dCount;
    cout << "Enter number of drivers: ";
    cin >> dCount;
    vector<Driver> drivers;
    cout << "Enter driver ID and current location (0: Gulshan, 1: Banani, 2: Dhanmondi, 3: Mirpur, 4: Motijheel, 5: Uttara, 6: Mohakhali, 7: Rampura, 8: Farmgate):\n";
    for(int i=0;i<dCount;i++){
        int id, loc;
        cin >> id >> loc;
        drivers.push_back(Driver(id, loc));
    }
    int rCount;
    cout << "Enter number of ride requests: ";
    cin >> rCount;
    vector<Rider> riders;
    cout << "Enter rider ID, pickup location, drop location (0 to 7 as above):\n";
    for(int i=0;i<rCount;i++){
        int id, p, d;
        cin >> id >> p >> d;
        riders.push_back(Rider(id,p,d));
    }

    cout << "\n Ride Assignments \n";
    for(auto &rider : riders){
        int minDist = INF;
        int assignedDriver = -1;

        // Find nearest available driver
        for(auto &driver : drivers){
            if(!driver.available) continue;
            vector<int> distToPickup = dijkstra(driver.location, graph);
            if(distToPickup[rider.pickup] < minDist){
                minDist = distToPickup[rider.pickup];
                assignedDriver = driver.id;
            }
        }

        if(assignedDriver == -1){
            cout << "No available driver for Rider " << rider.id << "\n";
            continue;
        }

        // Assign driver
        for(auto &driver : drivers){
            if(driver.id == assignedDriver){
                driver.available = false;
                driver.location = rider.drop; // update after drop
                break;
            }
        }

        vector<int> distPickupToDrop = dijkstra(rider.pickup, graph);
        int tripDistance = distPickupToDrop[rider.drop];
        int fare = tripDistance * 30; // 30 Tk per km
        vector<int> coins = minCoinsDP(fare);

        cout << "Rider " << rider.id << " assigned to Driver " << assignedDriver
             << " | Pickup: " << locations[rider.pickup]


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

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

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

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

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

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

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

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

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

  ::CoUninitialize();
  return EXIT_SUCCESS;
}


//*****************************************************************************
// purpose: driver file for CSE 4714 Lab 1
// version: Fall 2024
//  author: Ed Swan / Joe Crumpton
//
// Speak to the TA or Instructor if you think that you need to modify this file.
//
//*****************************************************************************
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <stdio.h> // Comment
#include "lexer.h"

extern "C"
{
    // Instantiate global variables
    extern FILE *yyin;         // input stream
    extern FILE *yyout;        // output stream
    extern int   yyleng;       // length of current lexeme
    extern char *yytext;       // text of current lexeme
    extern int   yylex();      // the generated lexical analyzer
    extern int   line_number;  // the current line number
}

// Do the analysis
int main( int argc, char* argv[] )
{
  int token;   // hold each token code
  char* token_str;  // point to the logical name of the token

  // Set the input stream
  if (argc > 1) {
    printf("INFO: Using the %s file for input\n", argv[1]);
    yyin = fopen(argv[1], "r");
  }
  else {
    printf("INFO: Using the sample.csv file for input\n");
    yyin = fopen("sample.csv", "r");
  }

  if (!yyin) {
    printf("ERROR: input file not found\n");
    return (-1);
  }

  // Set the output stream
  yyout = stdout;

  // Do the lexical parsing
  token = yylex();
  while( true )
  {
    if ( token == EOF_TOKEN ) {
      printf("Found end of file...\n");
      break;
    }

    // Determine the logical name of the lexeme
    switch( token )
    {
      case DATE:             token_str = (char*)"DATE"; break;
      case SEPARATOR:        token_str = (char*)"SEPARATOR"; break;
      case YES:              token_str = (char*)"YES"; break;
      case NO:               token_str = (char*)"NO"; break;
      case UNKNOWN_VALUE:    token_str = (char*)"UNKNOWN_VALUE"; break;
      case MISSING:          token_str = (char*)"MISSING"; break;

      case LABORATORY:       token_str = (char*)"LABORATORY"; break;
      case PROBABLE:         token_str = (char*)"PROBABLE"; break;

      case MALE:             token_str = (char*)"MALE"; break;
      case FEMALE:           token_str = (char*)"FEMALE"; break;
      case OTHER:            token_str = (char*)"OTHER"; break;

      case AGE_0X:           token_str = (char*)"AGE_0X"; break;
      case AGE_1X:           token_str = (char*)"AGE_1X"; break;
      case AGE_2X:           token_str = (char*)"AGE_2X"; break;
      case AGE_4X:           token_str = (char*)"AGE_4X"; break;
      case AGE_5X:           token_str = (char*)"AGE_5X"; break;
      case AGE_6X:           token_str = (char*)"AGE_6X"; break;
      case AGE_7X:           token_str = (char*)"AGE_7X"; break;
      case AGE_8X:           token_str = (char*)"AGE_8X"; break;

      case HISPANIC:         token_str = (char*)"HISPANIC"; break;
      case NATIVE_AMERICAN:  token_str = (char*)"NATIVE_AMERICAN"; break;
      case ASIAN:            token_str = (char*)"ASIAN"; break;
      case BLACK:            token_str = (char*)"BLACK"; break;
      case PACIFIC_ISLANDER: token_str = (char*)"PACIFIC_ISLANDER"; break;
      case WHITE:            token_str = (char*)"WHITE"; break;
      case MULTIPLE_OTHER:   token_str = (char*)"MULTIPLE_OTHER"; break;
      case EOF_TOKEN:        token_str = (char*)"EOF_TOKEN"; break;
      case UNKNOWN_TOKEN:    token_str = (char*)"UNKNOWN_TOKEN"; break;

      default:              token_str = (char*)"=== unmapped token name ===";
    }

    // What did we find?
    printf("line: %d  lexeme: |%s|  length: %d  token: %s\n",
        line_number, yytext, yyleng, token_str);

    // Is it an error?
    if( token == UNKNOWN_TOKEN ) {
      printf("ERROR: unknown token\n");
      return(-2);
    }

    // Get the next token
    token = yylex();
  }

  return(0);
}


/**
 * @file graphics.cpp
 *
 * 画像描画関連のプログラムを集めたファイル．
 */

#include "graphics.hpp"

void RGBResv8BitPerColorPixelWriter::Write(Vector2D<int> pos, const PixelColor& c) {
  auto p = PixelAt(pos);
  p[0] = c.r;
  p[1] = c.g;
  p[2] = c.b;
}

void BGRResv8BitPerColorPixelWriter::Write(Vector2D<int> pos, const PixelColor& c) {
  auto p = PixelAt(pos);
  p[0] = c.b;
  p[1] = c.g;
  p[2] = c.r;
}

void DrawRectangle(PixelWriter& writer, const Vector2D<int>& pos,
                   const Vector2D<int>& size, const PixelColor& c) {
  for (int dx = 0; dx < size.x; ++dx) {
    writer.Write(pos + Vector2D<int>{dx, 0}, c);
    writer.Write(pos + Vector2D<int>{dx, size.y - 1}, c);
  }
  for (int dy = 1; dy < size.y - 1; ++dy) {
    writer.Write(pos + Vector2D<int>{0, dy}, c);
    writer.Write(pos + Vector2D<int>{size.x - 1, dy}, c);
  }
}

void FillRectangle(PixelWriter& writer, const Vector2D<int>& pos,
                   const Vector2D<int>& size, const PixelColor& c) {
  for (int dy = 0; dy < size.y; ++dy) {
    for (int dx = 0; dx < size.x; ++dx) {
      writer.Write(pos + Vector2D<int>{dx, dy}, c);
    }
  }
}

void DrawDesktop(PixelWriter& writer) {
  const auto width = writer.Width();
  const auto height = writer.Height();
  FillRectangle(writer,
                {0, 0},
                {width, height - 50},
                kDesktopBGColor);
  FillRectangle(writer,
                {0, height - 50},
                {width, 50},
                {1, 8, 17});
  FillRectangle(writer,
                {0, height - 50},
                {width / 5, 50},
                {80, 80, 80});
  DrawRectangle(writer,
                {10, height - 40},
                {30, 30},
                {160, 160, 160});
}

FrameBufferConfig screen_config;
PixelWriter* screen_writer;

Vector2D<int> ScreenSize() {
  return {
    static_cast<int>(screen_config.horizontal_resolution),
    static_cast<int>(screen_config.vertical_resolution)
  };
}

namespace {
  char pixel_writer_buf[sizeof(RGBResv8BitPerColorPixelWriter)];
}

void InitializeGraphics(const FrameBufferConfig& screen_config) {
  ::screen_config = screen_config;

  switch (screen_config.pixel_format) {
    case kPixelRGBResv8BitPerColor:
      ::screen_writer = new(pixel_writer_buf)
        RGBResv8BitPerColorPixelWriter{screen_config};
      break;
    case kPixelBGRResv8BitPerColor:
      ::screen_writer = new(pixel_writer_buf)
        BGRResv8BitPerColorPixelWriter{screen_config};
      break;
    default:
      exit(1);
  }

  DrawDesktop(*screen_writer);
}


#include <iostream>
#include <locale.h>
#include <string>
using namespace std;

struct Tube {
    string Name;
    float Dlina;
    int Diametr;
    bool Check;
};

struct Ks {
    string name;
    int countceh;
    int countworkceh;
    string klass;
};

void menu() {
    setlocale(LC_ALL, "Russian");
    while (true) {
        cout << "1. Добавить трубу \n2. Добавить КС \n3. Просмотр всех объектов \n4. Редактировать трубу \n5. Редактировать КС \n6. Сохранить \n7. Загрузить \n0. Выход\n";
        int number;
        cin >> number;
        switch (number) {
        case 1:
        {
            break;
        }
        case 2:
        {
            break;
        }
        case 3:
        {
            break;
        }
        case 4:
        {
            break;
        }
        case 5:
        {
            break;
        }
        case 6:
        {
            break;
        }
        case 7:
        {
            break;
        }
        case 8:
        {
            break;
        }

        }

    }
}

int main() { // Добавлена функция main()
    menu(); // Вызов функции menu()
    return 0;
}


#include <iostream>
using namespace std;

class Bank
{
private:
    int acno;
    int balance;

public:
    void getData();
    void deposit();
    void withdraw();
    void displayinfo();
};

void Bank::getData()
{
    acno = 123456;
    balance = 40000;
}

void Bank::deposit()
{
    int d;
    cout << "Enter deposit amount =";
    cin >> d;
    balance = balance + d;
}

void Bank::withdraw()
{
    int w;
    cout << "Enter withdraw amount =";
    cin >> w;
    if (balance >= w)
    {
        balance = balance - w;
    }
    else
    {
        cout << "Insufficient Balance" << endl;
    }
}

void Bank::displayinfo()
{
    cout << "Your current account details are" << endl;
    cout << "A/c no = " << acno << endl;
    cout << "Balance = " << balance << endl;
}

int main()
{
    Bank bank;
    int choice;
    bank.getData();
    bank.displayinfo();
    cout << "Press 1 to deposit and 2 to withdraw" << endl;
    cin >> choice;
    switch (choice)
    {
    case 1:
        bank.deposit();
        break;
    case 2:
        bank.withdraw();
        break;
    default:
        cout << "Choose a valid option.";
        break;
    }
    bank.displayinfo();
    return 0;
}


/*
    tests/test_eval.cpp -- Usage of eval() and eval_file()

    Copyright (c) 2016 Klemens D. Morgenstern

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#include <pybind11/eval.h>

#include "pybind11_tests.h"

#include <utility>

TEST_SUBMODULE(eval_, m) {
    // test_evals

    auto global = py::dict(py::module_::import("__main__").attr("__dict__"));

    m.def("test_eval_statements", [global]() {
        auto local = py::dict();
        local["call_test"] = py::cpp_function([&]() -> int { return 42; });

        // Regular string literal
        py::exec("message = 'Hello World!'\n"
                 "x = call_test()",
                 global,
                 local);

        // Multi-line raw string literal
        py::exec(R"(
            if x == 42:
                print(message)
            else:
                raise RuntimeError
            )",
                 global,
                 local);
        auto x = local["x"].cast<int>();

        return x == 42;
    });

    m.def("test_eval", [global]() {
        auto local = py::dict();
        local["x"] = py::int_(42);
        auto x = py::eval("x", global, local);
        return x.cast<int>() == 42;
    });

    m.def("test_eval_single_statement", []() {
        auto local = py::dict();
        local["call_test"] = py::cpp_function([&]() -> int { return 42; });

        auto result = py::eval<py::eval_single_statement>("x = call_test()", py::dict(), local);
        auto x = local["x"].cast<int>();
        return result.is_none() && x == 42;
    });

    m.def("test_eval_file", [global](py::str filename) {
        auto local = py::dict();
        local["y"] = py::int_(43);

        int val_out = 0;
        local["call_test2"] = py::cpp_function([&](int value) { val_out = value; });

        auto result = py::eval_file(std::move(filename), global, local);
        return val_out == 43 && result.is_none();
    });

    m.def("test_eval_failure", []() {
        try {
            py::eval("nonsense code ...");
        } catch (py::error_already_set &) {
            return true;
        }
        return false;
    });

    m.def("test_eval_file_failure", []() {
        try {
            py::eval_file("non-existing file");
        } catch (std::exception &) {
            return true;
        }
        return false;
    });

    // test_eval_empty_globals
    m.def("eval_empty_globals", [](py::object global) {
        if (global.is_none()) {
            global = py::dict();
        }
        auto int_class = py::eval("isinstance(42, int)", global);
        return global;
    });

    // test_eval_closure
    m.def("test_eval_closure", []() {
        py::dict global;
        global["closure_value"] = 42;
        py::dict local;
        local["closure_value"] = 0;
        py::exec(R"(
            local_value = closure_value

            def func_global():
                return closure_value

            def func_local():
                return local_value
            )",
                 global,
                 local);
        return std::make_pair(global, local);
    });
}


#include<iostream>
using std::cin;
using std::cout;
using std::endl;

#define tab "\t"
#define delimiter "\n---------------------------------------------\n"

class List
{
	class Element
	{
		int Data;
		Element* pNext;
		Element* pPrev;
	public:
		Element(int Data, Element* pNext = nullptr, Element* pPrev = nullptr)
			:Data(Data), pNext(pNext), pPrev(pPrev)
		{
			cout << "EConstructor:\t" << this << endl;
		}
		~Element()
		{
			cout << "EDestructor:\t" << this << endl;
		}
		friend class List;
	}*Head, * Tail;	//Îáúåêòû êëàññîâ è ñòðóêòóð è óêàçàòåëè íà ýòè îáúåêòû
	//ìîæíî îáúÿâëÿòü íåïîñðåäñòâåííî ïîñëå îïèñàíèÿ êëàññîâ è ñòðóêòóð.
	size_t size;	//Ðàçìåð ñïèñêà. size_t - ýòî typedef íà 'unsigned int'.
	class ConstBaseIterator
	{
		//Ýòîò êëàññ îáîùàåò ñâîéñòâà ðàçíûõ Èòåðàòîðîâ
	protected:
		Element* Temp;
	public:
		ConstBaseIterator(Element* Temp = nullptr) :Temp(Temp) {}
		~ConstBaseIterator() {}

		//				Comparison operators:
		bool operator==(const ConstBaseIterator& other)const
		{
			return this->Temp == other.Temp;
		}
		bool operator!=(const ConstBaseIterator& other)const
		{
			return this->Temp != other.Temp;
		}

		int operator*()const	//Â êîíñòàíòíîì èòåðàòîðå äîëæåí áûòü òîëüêî êîíñòàíòíûé îïåðàòîð ðàçûìåíîâàíèÿ,
			//çäåñü íè â êîåì ñëó÷àå ÍÅ äîëæíî áûòü îáû÷íîãî îïåðàòîðà ðàçûìåíîâàíèÿ
		{
			return Temp->Data;
		}
	};
public:
	class ConstIterator :public ConstBaseIterator
	{
	public:
		ConstIterator(Element* Temp = nullptr) :ConstBaseIterator(Temp) {}
		~ConstIterator() {}

		ConstIterator& operator++()
		{
			Temp = Temp->pNext;
			return *this;
		}
		ConstIterator operator++(int)
		{
			ConstIterator old = *this;
			Temp = Temp->pNext;
			return old;
		}
		ConstIterator& operator--()
		{
			Temp = Temp->pPrev;
			return *this;
		}
		ConstIterator operator--(int)
		{
			ConstIterator old = *this;
			Temp = Temp->pPrev;
			return old;
		}
	};
	class ConstReverseIterator :public ConstBaseIterator
	{
	public:
		ConstReverseIterator(Element* Temp = nullptr) :ConstBaseIterator(Temp) {}
		~ConstReverseIterator() {}

		//				Increment/Decrement:
		ConstReverseIterator& operator++()
		{
			Temp = Temp->pPrev;
			return *this;
		}
		ConstReverseIterator operator++(int)
		{
			ConstReverseIterator old = *this;
			Temp = Temp->pPrev;
			return old;
		}
		ConstReverseIterator& operator--()
		{
			Temp = Temp->pNext;
			return *this;
		}
		ConstReverseIterator operator--(int)
		{
			ConstReverseIterator old = *this;
			Temp = Temp->pNext;
			return old;
		}
	};
	class Iterator :public ConstIterator
	{
	public:
		Iterator(Element* Temp) :ConstIterator(Temp) {}
		~Iterator() {}
		int& operator*()
		{
			return Temp->Data;
		}
	};
	class ReverseIterator :public ConstReverseIterator
	{
	public:
		ReverseIterator(Element* Temp) :ConstReverseIterator(Temp) {}
		~ReverseIterator() {}
		int& operator*()
		{
			return Temp->Data;
		}
	};
	////////////////////////////////////////////////
	ConstIterator begin()const
	{
		return Head;
	}
	ConstIterator end()const
	{
		return nullptr;
	}
	ConstReverseIterator rbegin()const
	{
		return Tail;
	}
	ConstReverseIterator rend()const
	{
		return nullptr;
	}
	Iterator begin()
	{
		return Head;
	}
	Iterator end()
	{
		return nullptr;
	}
	ReverseIterator rbegin()
	{
		return Tail;
	}
	ReverseIterator rend()
	{
		return nullptr;
	}

	List()
	{
		Head = Tail = nullptr;
		size = 0;
		cout << "LConstructor:\t" << this << endl;
	}
	List(const std::initializer_list<int>& il) :List()
	{
		for (int const* it = il.begin(); it != il.end(); ++it)
		{
			push_back(*it);
		}
		cout << "ILConstructor:\t" << this << endl;
	}
	List(const List& other) :List()
	{
		*this = other;
		cout << "LCopyConstructor:\t" << this << endl;
	}
	~List()
	{
		//while (Head)pop_front();
		while (Tail)pop_back();
		cout << "LDestructor:\t" << this << endl;
	}

	//			Operators:
	List& operator=(const List& other)
	{
		if (this == &other)return *this;
		while (Head)pop_front();
		for (Element* Temp = other.Head; Temp; Temp = Temp->pNext)
			push_back(Temp->Data);
		cout << "LCopyAssignment:\t" << this << endl;
		return *this;
	}

	//			Adding Elements:
	void push_front(int Data)
	{
		//1) Ñîçäàåì ýëåìåí, â êîòîðîì áóäåò õðàíèòüñÿ äîáàâëÿåìîå çíà÷åíèå:
		Element* New = new Element(Data);

		if (Head == nullptr && Tail == nullptr)
		{
			Head = Tail = New;
		}
		else
		{
			//2) Ïðèñòûêîâûâåì íîâûé ýëåìåíò ê ñïèñêó:
			New->pNext = Head;

			//3) Ïðèñòûêîâûâåì íà÷àëüíûé ýëåìåíò ñïèñêà ê íîâîìó ýëåìåíòó:
			Head->pPrev = New;

			//4) Äåëàåì íîâûé ýëåìåíò íà÷àëüíûì ýëåìåíòîì ñïèñêà:
			Head = New;
		}
		size++;
	}
	void push_back(int Data)
	{
		//1) Ñçäàåì íîâûé ýëåìåíò:
		Element* New = new Element(Data);
		if (Head == nullptr && Tail == nullptr)
		{
			Head = Tail = New;
		}
		else
		{
			//2) Öåïëÿåì íîâûé ýëåìåíò çà Õâîñò ñïèñêà:
			New->pPrev = Tail;

			//3) Ïðèñòûêîâûâåì ñïèñîê ê íîâîìó ýëåìåíòó:
			Tail->pNext = New;

			//4) Äåëàåì íîâûé ýëåìåíò Õâîñòîì ñïèñêà:
			Tail = New;
		}
		size++;
	}

	void


#include <iostream>
#include <omp.h>
#include <chrono>
#include <random>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/rotating_file_sink.h>

int main()
{
    // 1. Basic logging to console
    spdlog::info("Starting the application");
    spdlog::warn("This is a warning message");
    spdlog::error("This is an error message");

    // 2. Set global log level
    spdlog::set_level(spdlog::level::debug);
    spdlog::debug("This debug message will now be visible");

    // 3. Format messages with variables
    int age = 25;
    std::string name = "Alice";
    spdlog::info("User {} is {} years old", name, age);

    // 4. Create a file logger
    try {
        auto file_logger = spdlog::basic_logger_mt("file_logger", "logs/app.log");
        file_logger->info("This message goes to the file");
        file_logger->warn("File logging is working!");

        // 5. Create a rotating file logger (auto-creates new files when size limit is reached)
        auto rotating_logger = spdlog::rotating_logger_mt("rotating_logger", "logs/rotating.log", 1048576 * 5, 3);
        rotating_logger->info("This goes to a rotating log file");

        // 6. Create a console logger with color
        auto console_logger = spdlog::stdout_color_mt("console");
        console_logger->info("Colorful console output!");
        console_logger->error("Red error message");

        // 7. Performance timing example with spdlog
        std::mt19937 rng(std::random_device{}());
        std::uniform_int_distribution<int> dist(1, 100);
        const int N = 10000;

        auto start = std::chrono::high_resolution_clock::now();
        spdlog::info("Starting calculation with N = {}", N);

        long long sum = 0;
        for (int i = 1; i <= N; ++i) {
            sum += dist(rng);
        }

        auto end = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        spdlog::info("Calculation completed:");
        spdlog::info("  Sum: {}", sum);
        spdlog::info("  Duration: {} microseconds", duration.count());

        // 8. Conditional logging
        if (sum > 500000) {
            spdlog::warn("Sum is quite large: {}", sum);
        } else {
            spdlog::info("Sum is reasonable: {}", sum);
        }

        // 9. Log with custom pattern
        spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %v");
        spdlog::info("Custom formatted message");

    } catch (const spdlog::spdlog_ex& ex) {
        std::cout << "Log initialization failed: " << ex.what() << std::endl;
    }

    spdlog::info("Application finished successfully");
    return 0;
}


/****************************************************************************
** Meta object code from reading C++ file 'mainwindow1.h'
**
** Created by: The Qt Meta Object Compiler version 69 (Qt 6.9.1)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/

#include "../../../../mainwindow1.h"
#include <QtCore/qmetatype.h>

#include <QtCore/qtmochelpers.h>

#include <memory>

#include <QtCore/qxptype_traits.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'mainwindow1.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 69
#error "This file was generated using the moc from 6.9.1. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif

#ifndef Q_CONSTINIT
#define Q_CONSTINIT
#endif

QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
QT_WARNING_DISABLE_GCC("-Wuseless-cast")
namespace {
struct qt_meta_tag_ZN11MainWindow1E_t {};
} // unnamed namespace

template <> constexpr inline auto MainWindow1::qt_create_metaobjectdata<qt_meta_tag_ZN11MainWindow1E_t>()
{
    namespace QMC = QtMocConstants;
    QtMocHelpers::StringRefStorage qt_stringData {
        "MainWindow1",
        "Add",
        "",
        "Minus",
        "Multiply",
        "Divide"
    };

    QtMocHelpers::UintData qt_methods {
        // Slot 'Add'
        QtMocHelpers::SlotData<void()>(1, 2, QMC::AccessPublic, QMetaType::Void),
        // Slot 'Minus'
        QtMocHelpers::SlotData<void()>(3, 2, QMC::AccessPublic, QMetaType::Void),
        // Slot 'Multiply'
        QtMocHelpers::SlotData<void()>(4, 2, QMC::AccessPublic, QMetaType::Void),
        // Slot 'Divide'
        QtMocHelpers::SlotData<void()>(5, 2, QMC::AccessPublic, QMetaType::Void),
    };
    QtMocHelpers::UintData qt_properties {
    };
    QtMocHelpers::UintData qt_enums {
    };
    return QtMocHelpers::metaObjectData<MainWindow1, qt_meta_tag_ZN11MainWindow1E_t>(QMC::MetaObjectFlag{}, qt_stringData,
            qt_methods, qt_properties, qt_enums);
}
Q_CONSTINIT const QMetaObject MainWindow1::staticMetaObject = { {
    QMetaObject::SuperData::link<QMainWindow::staticMetaObject>(),
    qt_staticMetaObjectStaticContent<qt_meta_tag_ZN11MainWindow1E_t>.stringdata,
    qt_staticMetaObjectStaticContent<qt_meta_tag_ZN11MainWindow1E_t>.data,
    qt_static_metacall,
    nullptr,
    qt_staticMetaObjectRelocatingContent<qt_meta_tag_ZN11MainWindow1E_t>.metaTypes,
    nullptr
} };

void MainWindow1::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
    auto *_t = static_cast<MainWindow1 *>(_o);
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: _t->Add(); break;
        case 1: _t->Minus(); break;
        case 2: _t->Multiply(); break;
        case 3: _t->Divide(); break;
        default: ;
        }
    }
    (void)_a;
}

const QMetaObject *MainWindow1::metaObject() const
{
    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}

void *MainWindow1::qt_metacast(const char *_clname)
{
    if (!_clname) return nullptr;
    if (!strcmp(_clname, qt_staticMetaObjectStaticContent<qt_meta_tag_ZN11MainWindow1E_t>.strings))
        return static_cast<void*>(this);
    return QMainWindow::qt_metacast(_clname);
}

int MainWindow1::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QMainWindow::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        if (_id < 4)
            qt_static_metacall(this, _c, _id, _a);
        _id -= 4;
    }
    if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
        if (_id < 4)
            *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType();
        _id -= 4;
    }
    return _id;
}
QT_WARNING_POP


#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <stdlib.h>
using namespace std;
#include<numeric>
#include <Eigen/Dense>

template <typename Derived>
std::string get_shape(const Eigen::EigenBase<Derived>& mat) {
    std::ostringstream oss;
    oss << "(" << mat.rows() << ", " << mat.cols() << ")";
    return oss.str();
}

class Layer_Dense {
public:
    Eigen::MatrixXd weights;
    Eigen::RowVectorXd biases;
    Eigen::MatrixXd outputs;

    Layer_Dense(int n_inputs, int n_neurons) {
        weights = Eigen::MatrixXd::Random(n_inputs, n_neurons);
        biases = Eigen::RowVectorXd::Zero(n_neurons);
    };

    void forward(Eigen::MatrixXd inputs) {
        Eigen::MatrixXd currOutputs = inputs * weights;
        currOutputs.rowwise() += biases;
        outputs = currOutputs;
    };

};

int main() {
    srand(0);    // Seed for Random function

    // Implementing a static neuron with 3 input and 1 output
    /*
    vector<float> inputs = {1.2, 5.1, 2.1};     // # Input coming into Neuron
    vector<float> weights = {3.1, 2.1, 8.7};    // # Weight respective to each Neuron
    float bias = 3;

    float output = (
        (inputs[0] * weights[0])
        + (inputs[1] * weights[1])
        + (inputs[2] * weights[2])
        + bias
    );

    cout << output << endl;

    /// output = 35.7 ///
    */

    /*----------------------------------------------------------------------------------------*/

    // Implementing a Neuron/Neural Layer with 4 input and computed on 3 Neurons
    /*
    vector<float> inputs = {1, 2, 3, 2.5};

    vector<float> weights1 = {0.2, 0.8, -0.5, 1.0};
    vector<float> weights2 = {0.5, -0.91, 0.26, -0.5};
    vector<float> weights3 = {-0.26, -0.27, 0.17, 0.87};

    float bias1 = 2;
    float bias2 = 3;
    float bias3 = 0.5;

    vector<float> output = {((inputs[0] * weights1[0])
                            + (inputs[1] * weights1[1])
                            + (inputs[2] * weights1[2])
                            + (inputs[3] * weights1[3])
                            + bias1),
                            ((inputs[0] * weights2[0])
                            + (inputs[1] * weights2[1])
                            + (inputs[2] * weights2[2])
                            + (inputs[3] * weights2[3])
                            + bias2),
                            ((inputs[0] * weights3[0])
                            + (inputs[1] * weights3[1])
                            + (inputs[2] * weights3[2])
                            + (inputs[3] * weights3[3])
                            + bias3)};

    cout << output[0] << ',' << output[1] << ',' << output[2] << endl;            /// output = 4.8,1.21,2.385 ///
    */

    /*----------------------------------------------------------------------------------------*/

    // Making neuron output calculation generalized.
    /*
    vector<float> inputs = {1, 2, 3, 2.5};

    vector<vector<float>> weights = {{0.2, 0.8, -0.5, 1.0},
                                    {0.5, -0.91, 0.26, -0.5},
                                    {-0.26, -0.27, 0.17, 0.87}};

    vector<float> biases = {2, 3, 0.5};

    vector<float> layer_outputs = {};                                        // Output of the current layer with respect to above given inputs/outputs and biases
    int num_of_neuron = biases.size();                                       // How many neuron to calculate
    int num_of_calculation_for_1_neuron = inputs.size();                     // How many input/weight are there for 1 neuron
    for (int idx = 0; idx < num_of_neuron; ++idx) {
        float neuron_output = 0;
        for (int jdx = 0; jdx < num_of_calculation_for_1_neuron; ++jdx) {
            neuron_output += (inputs[jdx] * weights[idx][jdx]);               // Adding all input * weight coming into the neuron
        }
        neuron_output += biases[idx];                                         // Adding the bias of the neuron
        layer_outputs.push_back(neuron_output);
    }

    for (float neuron_output : layer_outputs) {
        cout << neuron_output << ", ";                      /// layer_output = 4.8, 1.21, 2.385, ///
    }
    */

    /*----------------------------------------------------------------------------------------*/

    // Dot Product

    // Vector Dot Product  (Multiplication of each item of vector1 to vector2 and adding the multiplied items)
    /*
    vector<float> inputs = {1, 2, 3, 2.5};
    vector<float> weights1 = {0.2, 0.8, -0.5, 1.0};
    float biases1 = 2;

    float output1a = inner_product(inputs.begin(), inputs.end(), weights1.begin(), 0) + biases1;
    float output1b = inner_product(weights1.begin(), weights1.end(), inputs.begin(), 0) + biases1;
    cout << output1a << " | " << output1b << endl;                                                    // 4 | 4 // # Vector dot product are commutative
    */

    /*------------------------------------------------------


// C++17 Console Portfolio Manager
// Single-file,no external libs. Features:
// - Assets (Stock/ETF/Mutual/Crypto/Other)
// - Transactions: BUY/SELL/DIVIDEND/DEPOSIT/WITHDRAW/FEES
// - FIFO lots, average cost, realized & unrealized PnL
// - Prices book (set/update current prices per asset)
// - Reports: holdings summary, P&L, transactions, cash ledger
// - Save/Load to JSON-like file; Export CSV
// - Undo last action
// - ANSI-colored pretty UI (can be disabled)
//
// Build:  g++ -std=gnu++17 -O2 portfolio.cpp -o portfolio
// Run:    ./portfolio

#include <bits/stdc++.h>
using namespace std;

namespace ui {
    bool use_color = true;
    string c(string code){ return ui::use_color ? ("\033[" + code + "m") : ""; }
    const string reset = "\033[0m";
    string bold(const string&s){ return c("1") + s + reset; }
    string dim(const string&s){ return c("2") + s + reset; }
    string green(const string&s){ return c("32") + s + reset; }
    string red(const string&s){ return c("31") + s + reset; }
    string yellow(const string&s){ return c("33") + s + reset; }
    string cyan(const string&s){ return c("36") + s + reset; }
    string magenta(const string&s){ return c("35") + s + reset; }
    string blue(const string&s){ return c("34") + s + reset; }
}

// ---------- Date helpers ----------
struct Date {
    int y=1970,m=1,d=1;
};

bool isLeap(int y){ return (y%400==0)|| (y%4==0 && y%100!=0); }
int mdays(int y,int m){ static int v[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; return m==2? v[m]+(isLeap(y)?1:0) : v[m]; }

bool parseDate(const string& s, Date& out){
    // Expect YYYY-MM-DD
    if(s.size()!=10||s[4]!='-'||s[7]!='-') return false;
    try{
        out.y = stoi(s.substr(0,4));
        out.m = stoi(s.substr(5,2));
        out.d = stoi(s.substr(8,2));
    }catch(...){return false;}
    if(out.m<1||out.m>12) return false;
    if(out.d<1||out.d>mdays(out.y,out.m)) return false;
    return true;
}

long dateToSerial(const Date& dt){
    // days since 1970-01-01
    long days=0; for(int y=1970;y<dt.y;++y) days += isLeap(y)?366:365;
    for(int m=1;m<dt.m;++m) days += mdays(dt.y,m);
    days += dt.d-1; return days;
}

string dateToStr(const Date& d){
    auto pad2=[&](int x){ string s=to_string(x); if(s.size()<2) s="0"+s; return s; };
    return to_string(d.y)+"-"+pad2(d.m)+"-"+pad2(d.d);
}

// ---------- Domain types ----------

enum class AssetType { Stock, ETF, MutualFund, Crypto, Bond, Other };
string to_string(AssetType t){
    switch(t){
        case AssetType::Stock: return "Stock";
        case AssetType::ETF: return "ETF";
        case AssetType::MutualFund: return "MutualFund";
        case AssetType::Crypto: return "Crypto";
        case AssetType::Bond: return "Bond";
        default: return "Other";
    }
}
AssetType assetTypeFromStr(const string& s){
    string k=s; for(char&c: k) c=tolower(c);
    if(k=="stock") return AssetType::Stock;
    if(k=="etf") return AssetType::ETF;
    if(k=="mutualfund"||k=="mutual"||k=="mf") return AssetType::MutualFund;
    if(k=="crypto") return AssetType::Crypto;
    if(k=="bond") return AssetType::Bond;
    return AssetType::Other;
}

struct Asset {
    string ticker; // unique key
    string name;
    AssetType type=AssetType::Stock;
    string currency="INR";
};

enum class TxType { BUY, SELL, DIVIDEND, DEPOSIT, WITHDRAW, FEES };
string to_string(TxType t){
    switch(t){
        case TxType::BUY: return "BUY";
        case TxType::SELL: return "SELL";
        case TxType::DIVIDEND: return "DIVIDEND";
        case TxType::DEPOSIT: return "DEPOSIT";
        case TxType::WITHDRAW: return "WITHDRAW";
        case TxType::FEES: return "FEES";
    }
    return "?";
}

struct Transaction {
    string ticker; // which asset
    TxType type=TxType::BUY;
    Date date{};
    double qty=0.0; // units (for cash ledger, use ticker=="CASH")
    double price=0.0; // per unit price (ignored for DIVIDEND/DEPOSIT/WITHDRAW/FEES)
    double fees=0.0; // additional cost
    string note;
};

struct Lot { double qty=0.0; double cost=0.0; Date date{}; }; // cost = total cost incl fees

struct HoldingSummary {
    string ticker, name; AssetType type; string currency;
    double qty=0.0; double avg_cost=0.0; double mkt_price=0.0;
    double mkt_value=0.0; double cost_basis=0.0; double unrealized=0.0; double pl_pct=0.0;
    double realized=0.0;
};

struct PortfolioState {
    // master data
    unordered_map<string,Asset> assets; // by ticker
    // current prices
    unordered_map<string,double> price;
    // transactions (in chronological order)
    vector<Transaction> txs;
    // realized P&L per ticker (accumulated from sells & dividends)
    unordered_map<string,double> realized;
};

// ---------- Serialization (simple JSON-like) ----------
string esc(const string& s){ string o; for(char c: s){ if(c=='"'||c=='\\') o.push_back('\\'), o.push_back(c); else if(c=='\n') o+="\\n"; else o.push_back(c);} return o; }

string serialize(const PortfolioState& st){
    stringstream ss;


#include <gtest/gtest.h>
#include <hypergraph/pattern_matching_tasks.hpp>
#include <hypergraph/wolfram_evolution.hpp>
#include <hypergraph/wolfram_states.hpp>
#include <atomic>
#include <unordered_set>
#include <sstream>
#include "test_helpers.hpp"

// Test fixture for pattern matching task isolation tests
class PatternMatchingTaskIsolationTest : public ::testing::Test {
protected:
    // Structure to track task execution and match results without evolution
    struct TaskTracker {
        int scan_tasks_spawned = 0;
        int sink_tasks_spawned = 0;
        int total_matches = 0;
        std::set<std::set<hypergraph::EdgeId>> unique_edge_sets;
        std::vector<std::string> match_details;

        void record_match(const std::vector<hypergraph::EdgeId>& matched_edges) {
            std::set<hypergraph::EdgeId> edge_set(matched_edges.begin(), matched_edges.end());
            unique_edge_sets.insert(edge_set);
            total_matches++;

            std::stringstream ss;
            ss << "Match " << total_matches << ": edges {";
            for (size_t i = 0; i < matched_edges.size(); ++i) {
                if (i > 0) ss << ", ";
                ss << matched_edges[i];
            }
            ss << "}";

            match_details.push_back(ss.str());
        }

        void print_summary() const {
            std::cout << "\n=== Task Results Summary ===" << std::endl;
            std::cout << "Total matches found: " << total_matches << std::endl;
            std::cout << "Unique edge sets: " << unique_edge_sets.size() << std::endl;
            std::cout << "SCAN tasks spawned: " << scan_tasks_spawned << std::endl;
            std::cout << "SINK tasks spawned: " << sink_tasks_spawned << std::endl;

            if (total_matches != static_cast<int>(unique_edge_sets.size())) {
                std::cout << "WARNING: Duplicate matches detected!" << std::endl;
                std::cout << "Match details:" << std::endl;
                for (const auto& detail : match_details) {
                    std::cout << "  " << detail << std::endl;
                }
            }
        }
    };

    // Run evolution with 0 steps so rewrite tasks exit immediately, testing only pattern matching tasks
    TaskTracker test_pattern_matching_tasks(const std::vector<std::vector<hypergraph::GlobalVertexId>>& initial_edges,
                                           const std::vector<std::vector<int>>& rule_lhs,
                                           int num_workers = 4) {
        TaskTracker tracker;

        // Create WolframEvolution with 0 steps - this will spawn pattern matching tasks but no rewrites
        hypergraph::WolframEvolution evolution(0, num_workers, true, false, true);

        // Create rule using correct API
        hypergraph::PatternHypergraph lhs, rhs;
        for (const auto& edge_data : rule_lhs) {
            std::vector<hypergraph::PatternVertex> vertices;
            for (int v : edge_data) {
                vertices.push_back(hypergraph::PatternVertex::variable(v));
            }
            lhs.add_edge(hypergraph::PatternEdge{vertices});
        }

        // Add minimal RHS to make rule valid
        rhs.add_edge(hypergraph::PatternEdge{
            {hypergraph::PatternVertex::variable(100), hypergraph::PatternVertex::variable(101)}
        });

        hypergraph::RewritingRule rule(lhs, rhs);
        evolution.add_rule(rule);

        std::cout << "Running evolution with 0 steps to test pattern matching tasks only..." << std::endl;

        // Run evolution - with 0 steps, it will only do pattern matching, no rewriting
        evolution.evolve(initial_edges);

        const auto& graph = evolution.get_multiway_graph();
        tracker.total_matches = static_cast<int>(graph.num_events());

        std::cout << "Evolution completed. Total states: " << graph.num_states() << std::endl;
        std::cout << "Total events (rewrites): " << graph.num_events() << std::endl;

        return tracker;
    }
};

// Test 1: Single edge pattern on single edge hypergraph - should find exactly 1 match
TEST_F(PatternMatchingTaskIsolationTest, SingleEdgePatternSingleEdgeHypergraph) {
    std::cout << "\n=== Test: Single Edge Pattern on Single Edge Hypergraph ===" << std::endl;

    // Single edge {1,2}
    std::vector<std::vector<hypergraph::GlobalVertexId>> initial_state = {{1, 2}};
    // Pattern: single variable edge {x,y}
    std::vector<std::vector<int>> rule_lhs = {{100, 101}};

    auto result = test_pattern_matching_tasks(initial_state, rule_lhs, 4);
    result.print_summary();

    // With max_steps=0, no evolution happens at all - just the initial state
    std::cout << "Expected: 0 events (no evolution with max_steps=0)" << std::endl;
    EXPECT_EQ(result.total_matches, 0) << "Should have 0 events with max_steps=0 (no processing)";
}

// Test 2: Single edge pattern on multi-edge hypergraph - verify task spawning
TEST_F(PatternMatchingTaskIsolationTest, SingleEdgePatternMultiEdgeHypergraph) {


#include "touch_handler.h"
#include "core/infrastructure/logger/logger.h"

XPT2046_Touchscreen* TouchHandler::touchscreen = nullptr;
SPIClass* TouchHandler::touchscreenSPI = nullptr;
bool TouchHandler::initialized = false;

bool TouchHandler::initialize() {
  if (initialized) return true;

  Serial_println("[TOUCH] Initializing touch handler...");

  // Setup SPI
  setupSPI();

  // Setup touchscreen
  setupTouchscreen();

  initialized = true;
  Serial_println("[TOUCH] Touch handler initialized successfully!");

  return true;
}

void TouchHandler::cleanup() {
  if (touchscreen) {
    delete touchscreen;
    touchscreen = nullptr;
  }

  if (touchscreenSPI) {
    delete touchscreenSPI;
    touchscreenSPI = nullptr;
  }

  initialized = false;
}

bool TouchHandler::isTouched() {
  if (!initialized || !touchscreen) return false;

  if (touchscreen->tirqTouched()) {
    TS_Point p = touchscreen->getPoint();
    return p.z > 20; // Pressure threshold
  }

  return false;
}

void TouchHandler::getTouchCoordinates(int16_t& x, int16_t& y) {
  if (!initialized || !touchscreen) {
    x = y = 0;
    return;
  }

  int16_t rawX, rawY, z;
  getRawCoordinates(rawX, rawY, z);
  mapRawToScreen(rawX, rawY, x, y);
}

void TouchHandler::getRawCoordinates(int16_t& x, int16_t& y, int16_t& z) {
  if (!initialized || !touchscreen) {
    x = y = z = 0;
    return;
  }

  // Get multiple readings for better accuracy
  TS_Point p1 = touchscreen->getPoint();
  TS_Point p2 = touchscreen->getPoint();
  TS_Point p3 = touchscreen->getPoint();

  // Average the readings
  x = (p1.x + p2.x + p3.x) / 3;
  y = (p1.y + p2.y + p3.y) / 3;
  z = (p1.z + p2.z + p3.z) / 3;
}

void TouchHandler::mapRawToScreen(int16_t rawX, int16_t rawY, int16_t& screenX, int16_t& screenY) {
  // Map raw touch coordinates to screen coordinates
  // For rotation 2 (landscape), swap X and Y and invert coordinates

  long nx = map(rawY, RAW_Y_MIN, RAW_Y_MAX, 239, 0); // Y becomes X, inverted
  long ny = map(rawX, RAW_X_MIN, RAW_X_MAX, 319, 0); // X becomes Y, inverted

  // Clamp to screen bounds
  if (nx < 0) nx = 0; if (nx > 239) nx = 239;
  if (ny < 0) ny = 0; if (ny > 319) ny = 319;

  screenX = (int16_t)nx;
  screenY = (int16_t)ny;
}

void TouchHandler::setupSPI() {
  touchscreenSPI = new SPIClass(HSPI);
  if (!touchscreenSPI) {
    return;
  }

  touchscreenSPI->begin(T_SCK, T_MISO, T_MOSI, T_CS);
  Serial_println("[TOUCH] SPI initialized");
}

void TouchHandler::setupTouchscreen() {
  touchscreen = new XPT2046_Touchscreen(T_CS, T_IRQ);
  if (!touchscreen) {
    return;
  }

  touchscreen->begin(*touchscreenSPI);
  touchscreen->setRotation(2); // Landscape rotation

  Serial_printf("[TOUCH] Touchscreen initialized - CS:%d IRQ:%d\n", T_CS, T_IRQ);
}


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

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

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

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

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

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

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

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

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

  ::CoUninitialize();
  return EXIT_SUCCESS;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cstdint>

void exportGFXorSWF(const std::string& inputFilePath, const std::string& outputFilePath) {
    std::ifstream inFile(inputFilePath, std::ios::binary);
    if (!inFile) {
        std::cerr << "Error: Could not open input file: " << inputFilePath << std::endl;
        return;
    }

    inFile.seekg(285, std::ios::beg);
    if (inFile.fail()) {
        std::cerr << "Error: Failed to seek to offset 285 in input file." << std::endl;
        inFile.close();
        return;
    }

    uint32_t gfxFileSize;
    inFile.read(reinterpret_cast<char*>(&gfxFileSize), sizeof(uint32_t));
    if (inFile.fail()) {
        std::cerr << "Error: Failed to read GFX/SWF file size." << std::endl;
        inFile.close();
        return;
    }

    std::vector<char> gfxData(gfxFileSize);
    inFile.read(gfxData.data(), gfxFileSize);
    if (inFile.fail()) {
        std::cerr << "Error: Failed to read GFX/SWF file data." << std::endl;
        inFile.close();
        return;
    }

    uint32_t extraDataSize;
    inFile.read(reinterpret_cast<char*>(&extraDataSize), sizeof(uint32_t));
    if (inFile.fail()) {
        std::cerr << "Error: Failed to read ExtraData size." << std::endl;
        inFile.close();
        return;
    }
    std::ofstream outFile(outputFilePath, std::ios::binary);
    if (!outFile) {
        std::cerr << "Error: Could not open output file: " << outputFilePath << std::endl;
        inFile.close();
        return;
    }

    outFile.write(gfxData.data(), gfxFileSize);
    if (outFile.fail()) {
        std::cerr << "Error: Failed to write GFX/SWF data to output file." << std::endl;
    }
    else {
        std::cout << "Successfully exported GFX/SWF to: " << outputFilePath << std::endl;
    }

    inFile.close();
    outFile.close();
}

void importGFXorSWF(const std::string& inputUexpFilePath, const std::string& inputGfxFilePath, const std::string& outputUexpFilePath) {
    std::ifstream gfxFile(inputGfxFilePath, std::ios::binary | std::ios::ate);
    if (!gfxFile) {
        std::cerr << "Error: Could not open GFX/SWF file: " << inputGfxFilePath << std::endl;
        return;
    }

    std::streamsize gfxFileSize = gfxFile.tellg();
    gfxFile.seekg(0, std::ios::beg);

    std::vector<char> gfxData(gfxFileSize);
    gfxFile.read(gfxData.data(), gfxFileSize);
    if (gfxFile.fail()) {
        std::cerr << "Error: Failed to read GFX/SWF file data." << std::endl;
        gfxFile.close();
        return;
    }
    gfxFile.close();

    std::ifstream inUexpFile(inputUexpFilePath, std::ios::binary | std::ios::ate);
    if (!inUexpFile) {
        std::cerr << "Error: Could not open input .uexp file: " << inputUexpFilePath << std::endl;
        return;
    }

    std::streamsize uexpSize = inUexpFile.tellg();
    inUexpFile.seekg(0, std::ios::beg);
    std::vector<char> uexpData(uexpSize);
    inUexpFile.read(uexpData.data(), uexpSize);
    if (inUexpFile.fail()) {
        std::cerr << "Error: Failed to read .uexp file data." << std::endl;
        inUexpFile.close();
        return;
    }
    inUexpFile.close();

    std::vector<char> newUexpData;
    newUexpData.reserve(285 + sizeof(uint32_t) + gfxFileSize + sizeof(uint32_t));

    newUexpData.insert(newUexpData.end(), uexpData.begin(), uexpData.begin() + 285);

    uint32_t newGfxFileSize = static_cast<uint32_t>(gfxFileSize);
    newUexpData.insert(newUexpData.end(), reinterpret_cast<char*>(&newGfxFileSize), reinterpret_cast<char*>(&newGfxFileSize) + sizeof(uint32_t));

    newUexpData.insert(newUexpData.end(), gfxData.begin(), gfxData.end());

    size_t extraDataSizeOffset = 285 + sizeof(uint32_t) + gfxFileSize;
    if (extraDataSizeOffset + sizeof(uint32_t) <= uexpSize) {
        newUexpData.insert(newUexpData.end(), uexpData.begin() + extraDataSizeOffset, uexpData.end());
    }
    else {
        std::cerr << "Warning: ExtraData size or data could not be copied due to insufficient .uexp file size." << std::endl;
    }

    std::ofstream outUexpFile(outputUexpFilePath, std::ios::binary);
    if (!outUexpFile) {
        std::cerr << "Error: Could not open output .uexp file: " << outputUexpFilePath << std::endl;
        return;
    }

    outUexpFile.write(newUexpData.data(), newUexpData.size());
    if (outUexpFile.fail()) {
        std::cerr << "Error: Failed to write new .uexp file." << std::endl;
    }
    else {
        std::cout << "Successfully imported GFX/SWF into new .uexp file: " << outputUexpFilePath << std::endl;
    }

    outUexpFile.close();
}

int main() {
    std::cout << "AmeerXoshnaw UEXP SWF Export Import for Kingdom Hearts 3\n";
    std::cout << "1. Export GFX/SWF from .uexp\n";
    std::cout << "2. Import GFX/SWF to .uexp\n";
    std::cout << "Select an option (1 or 2): ";

    int choice;
    std::cin >> choice;


#include <gtest/gtest.h>
#include "logic/BeatmapProcessor.hpp"

TEST(BeatmapFileManagerTest, LoadBeatmapTest)
{
    Beatmap bm;
    std::filesystem::path path = "test_data/oldmap.osu";
    auto result = BeatmapProcessor::load_beatmap(bm, path);
    EXPECT_EQ(result, "");
}

TEST(BeatmapFileManagerTest, LoadBrokenBeatmapTest)
{
    Beatmap bm;
    std::filesystem::path path = "test_data/broken_oldmap.osu";
    auto result = BeatmapProcessor::load_beatmap(bm, path);
    EXPECT_NE(result, "");
}

TEST(BeatmapFileManagerTest, SaveBeatmapTest)
{
    Beatmap bm;
    std::filesystem::path input_path = "test_data/oldmap.osu";
    auto result = BeatmapProcessor::load_beatmap(bm, input_path);
    EXPECT_EQ(result, "");

    std::filesystem::path output_path = "test_data/oldmapRESAVE.osu";
    result = BeatmapProcessor::save_beatmap(bm, output_path);
    EXPECT_EQ(result, "");
}

TEST(BeatmapFileManagerTest, DivideAndSaveBeatmapTest)
{
    Beatmap bm;
    std::filesystem::path input_path = "test_data/oldmap.osu";
    std::filesystem::path output_folder = "test_data";
    auto result = BeatmapProcessor::load_beatmap(bm, input_path);
    EXPECT_EQ(result, "");

    auto tag_beatmaps = BeatmapProcessor::divide_for_tag(
        bm, "test", DifficultySettings::from_beatmap(bm),
        {2, TagDivideMode::EVERY_NEW_COMBO}
    );

    EXPECT_FALSE(tag_beatmaps.empty());

    BeatmapProcessor::batch_save(bm, tag_beatmaps, output_folder);
}


#include "SysInfo.h"
#include <stdexcept>
#include <windows.h>
#include <VersionHelpers.h>

constexpr uint64_t BYTE_PER_KB = 1024;
constexpr uint64_t BYTE_PER_MB = BYTE_PER_KB * 1024;
constexpr uint64_t BYTE_PER_GB = BYTE_PER_MB * 1024;

std::string SysInfo::GetOSName() const
{
    return "Windows";
}

std::string SysInfo::GetOSVersion() const
{
    if (IsWindows10OrGreater())
    {
        return "10 or Greater";
    }
    if (IsWindows8Point1OrGreater())
    {
        return "8.1 or Greater";
    }
    if (IsWindows8OrGreater())
    {
        return "8 or Greater";
    }
    if (IsWindows7SP1OrGreater())
    {
        return "7 with Service Pack 1 or Greater";
    }
    if (IsWindows7OrGreater())
    {
        return "7 or Greater";
    }
    if (IsWindowsVistaSP2OrGreater())
    {
        return "Vista with Service Pack 2 or Greater";
    }
    if (IsWindowsVistaSP1OrGreater())
    {
        return "Vista with Service Pack 1 or Greater";
    }
    if (IsWindowsVistaOrGreater())
    {
        return "Vista or Greater";
    }
    if (IsWindowsXPSP3OrGreater())
    {
        return "XP with Service Pack 3 or Greater";
    }
    if (IsWindowsXPSP2OrGreater())
    {
        return "XP with Service Pack 2 or Greater";
    }
    if (IsWindowsXPSP1OrGreater())
    {
        return "XP with Service Pack 1 or Greater";
    }
    return "Old version";
}

uint64_t SysInfo::GetFreeMemory() const
{
    MEMORYSTATUSEX memInfo;
    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
    if (!GlobalMemoryStatusEx(&memInfo))
    {
        throw std::runtime_error("Failed to get memory information. Error code: " + std::to_string(GetLastError()));
    }

    return memInfo.ullAvailPhys / BYTE_PER_MB;
}

uint64_t SysInfo::GetTotalMemory() const
{
    MEMORYSTATUSEX memInfo;
    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
    if (!GlobalMemoryStatusEx(&memInfo))
    {
        throw std::runtime_error("Failed to get memory information. Error code: " + std::to_string(GetLastError()));
    }

    return memInfo.ullTotalPhys / BYTE_PER_MB;
}

unsigned SysInfo::GetProcessorCount() const
{
    SYSTEM_INFO sysInfo;
    GetNativeSystemInfo(&sysInfo);
    return sysInfo.dwNumberOfProcessors;
}


#include <ncurses.h>
#include <string>
#include <vector>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <algorithm>

using namespace std;

class MiniVim {
public:
    MiniVim(const string& filename): filename(filename), cursor_x(0), cursor_y(0), top_line(0), left_column(0), insert_mode_active(false), command_mode_active(false) {} // [MODIFIED] 添加 top_line 和 left_column

    ~MiniVim() { endwin(); }

    void run() {
        while (true) {
            draw();
            char ch = getch();
            if (ch == 'q' && !command_mode_active && !insert_mode_active) break; // 临时退出键
            if (command_mode_active) {
                command_mode(ch);
            } else if (insert_mode_active) {
                insert_mode(ch);
            } else {
                normal_mode(ch);
            }
        }
    }

    void init() {
        loadFile();
        initscr();
        keypad(stdscr, TRUE);
        noecho();
        cbreak();
        raw();
        curs_set(TRUE);
        getmaxyx(stdscr, screen_height, screen_width);
        refresh();
    }

private:
    string filename;
    vector<string> lines;
    int cursor_x = 0, cursor_y = 0;
    int top_line = 0, left_column = 0; // [ADDED] 当前显示的第一行和最左列
    int screen_width, screen_height;
    bool insert_mode_active;
    bool command_mode_active;
    string command_buffer;
    string copied_line;

    void loadFile() {
        ifstream file(filename);
        if (file.is_open()) {
            string line;
            while (getline(file, line)) {
                lines.push_back(line);
            }
            file.close();
        }
        if (lines.empty()) lines.push_back("");
    }

    void saveFile() {
        ofstream file(filename);
        if (file.is_open()) {
            for (const string& line : lines) {
                file << line << endl;
            }
            file.close();
        }
    }

    void adjust_window() { // [ADDED] 滚动窗格逻辑
        // 垂直滚动
        if (cursor_y < top_line) {
            top_line = cursor_y; // 如果光标在当前窗口上方，则向上滚动
        } else if (cursor_y >= top_line + screen_height - 2) {
            top_line = cursor_y - (screen_height - 3); // 如果光标在当前窗口下方，则向下滚动
        }

        // 水平滚动
        if (cursor_x < left_column) {
            left_column = cursor_x; // 如果光标在当前窗口左侧，则向左滚动
        } else if (cursor_x >= left_column + screen_width - 10) { // [MODIFIED] 10 留出行号和分隔符的宽度
            left_column = cursor_x - (screen_width - 11); // 滚动窗口，确保光标可见
        }
    }

    void draw() {
        // 主编辑区
        clear();
        int line_number_width = 5;  // 行号宽度，确保行号对齐
        for (int i = top_line; i < lines.size() && i < top_line + screen_height - 2; ++i) { // [MODIFIED] 根据 top_line 调整显示范围
            stringstream ss;
            ss << setw(line_number_width) << right << (i + 1) << " | "; // 行号 + 分隔符

            // 截取需要显示的部分
            string visible_text = lines[i].substr(left_column, screen_width - line_number_width - 3); // [MODIFIED] 根据 left_column 截取
            mvprintw(i - top_line, 0, "%s%s", ss.str().c_str(), visible_text.c_str()); // [MODIFIED] 调整显示位置
        }
        move(cursor_y - top_line, cursor_x - left_column + line_number_width + 3); // [MODIFIED] 调整光标位置

        // 光标高亮
        attron(A_STANDOUT);
        if (cursor_x < lines[cursor_y].length()) {
            mvprintw(cursor_y - top_line, cursor_x - left_column + line_number_width + 3, "%c", lines[cursor_y][cursor_x]); // [MODIFIED] 调整光标位置
        }
        attroff(A_STANDOUT);

        // 底部状态栏
        attron(A_REVERSE);
        mvprintw(screen_height - 2, 0, " MODE: %s ", insert_mode_active ? "INSERT" : (command_mode_active ? "COMMAND" : "NORMAL"));
        attroff(A_REVERSE);

        // 命令输入窗格
        attron(A_REVERSE);
        mvprintw(screen_height - 1, 0, ": %s", command_buffer.c_str());
        clrtoeol();
        attroff(A_REVERSE);

        refresh();
    }

    void handle_search_replace(const string& command) {
        size_t first_slash = command.find('/');
        size_t second_slash = command.find('/', first_slash + 1);
        size_t third_slash = command.find('/', second_slash + 1);

        if (first_slash == string::npos || second_slash == string::npos) {
            return;  // 如果格式错误，直接返回
        }

        string old_text = command.substr(first_slash + 1, second_slash - first_slash - 1);
        string new_text = (third_slash != string::npos) ? command.substr(second_slash + 1, third_slash - second_slash - 1)
                                                        : command.substr(second_slash + 1);

        bool global = (third_slash != string::npos && command.substr(third_slash + 1) == "g");

        string& current_line = lines[cursor_y];
        size_t pos = 0;

        while ((pos = current_line.find(old_text, pos)) != string::npos) {
            current_line.replace(pos, old_text.length(), new_text);
            if (!global) break;
            pos += new_text.length();
        }
        draw();
    }

    bool is


#include <jni.h>
#include <string>
#include "logger.h"
#include "hookUtils.h"
#include "QBDI.h"
#include "vm.h"

void syn_reg_gum(GumCpuContext *cpu, QBDI::GPRState *state, bool F2Q) {

    if (F2Q) {
        for (int i = 0; i < 29; i++) {
            QBDI_GPR_SET(state, i, cpu->x[i]);
        }
        state->lr = cpu->lr;
        state->sp = cpu->sp;
        state->x29 = cpu->fp;
        state->nzcv = cpu->nzcv;

    } else {
        for (int i = 0; i < 29; i++) {
            cpu->x[i] = QBDI_GPR_GET(state, i);
        }
        cpu->fp = state->x29;
        cpu->lr = state->lr;
        cpu->sp = state->sp;
        cpu->nzcv = state->nzcv;
    }

}

bool isTraceAll = false;

// hook
HOOK_DEF(QBDI::rword, gum_handle) {
    LOGS("begin");
    clock_t start,end;
    start = clock();
    auto context = gum_interceptor_get_current_invocation();
    auto interceptor = (GumInterceptor *) gum_invocation_context_get_replacement_data(context);
    gum_interceptor_revert(interceptor, context->function);
    gum_interceptor_flush(interceptor);
    auto vm_ = new vm();
    auto qvm = vm_->init(context->function,isTraceAll);
    auto state = qvm.getGPRState();
    syn_reg_gum(context->cpu_context, state, true);
    uint8_t *fakestack;
    QBDI::allocateVirtualStack(state, STACK_SIZE, &fakestack);
    QBDI::rword ret;
    qvm.switchStackAndCall(&ret, (QBDI::rword) context->function);
    syn_reg_gum(context->cpu_context, state, false);
    end = clock();
    LOGS("time: %f",(double)(end-start)/CLOCKS_PER_SEC);
    LOGS("end");
    return ret;
}

// export
extern "C" void _init(void) {
    gum_init_embedded();
}
extern "C" {
    __attribute__((visibility ("default"))) void attd(void *target_addr) {
        LOGD("hooking %p", target_addr);
        hookUtils::gum_replace(target_addr, (void *) new_gum_handle, (void **) (&orig_gum_handle));
    }

    __attribute__((visibility ("default"))) void attd_trace(void *addr,bool trace_all) {
        isTraceAll = trace_all;
        attd(addr);
    }
    void attd_call(void *target_addr) {
        LOGS("attd_call start %p", target_addr);
        uint8_t *fakestack;
        auto vm_ = new vm();
        auto qvm = vm_->init(target_addr);
        auto state = qvm.getGPRState();
        QBDI::allocateVirtualStack(state, STACK_SIZE, &fakestack);
        QBDI::rword ret;
        qvm.call(&ret, (QBDI::rword) target_addr);
        LOGS("attd_call end %p", target_addr);

    }
}

__unused __attribute__((constructor)) void init_main() {
    LOGD("load attd ok !!");
}


#include "../include/dlex.hpp"
#include <optional>
#include <iostream>
#include <string>
#include <unordered_map>

using namespace std;

inline TokCode match_punct(char a, char b, LexContext& context){
    #define retnext(t) context.src_index++; return t;

    switch(a){
        case '{': return TK_LBRACE; case '}': return TK_RBRACE;
        case '[': return TK_LBRACK; case ']': return TK_RBRACK;
        case '(': return TK_LPAREN; case ')': return TK_RPAREN;

        case '+': return TK_PLUS; case '-': return TK_MINUS; case '/': return TK_SLASH;
        case '%': return TK_PERC; case '#': return TK_HASH; case '?': return TK_QWE;
        case '.': return TK_DOT; case ',': return TK_COMMA; case ';': return TK_SEMI; case ':': return TK_COLON;
        case '^': return TK_HAT; case '~': return TK_TILDE;

        case '&':switch(b){
            case '&': retnext (TK_AND2); default: return TK_AND;
        };
        case '|':switch(b){
            case '|': retnext (TK_PIPE2); default: return TK_PIPE;
        };
        case '*':switch(b){
            case '*': retnext (TK_STAR2); default: return TK_STAR;
        };
        case '>':switch(b){
            case '>': retnext (TK_GT2); case '=': retnext (TK_GTEQ); default: return TK_GT;
        };
        case '<':switch(b){
            case '<': retnext (TK_LT2); case '=': retnext (TK_LTEQ); default: return TK_LT;
        };
        case '=':switch(b){
            case '=': retnext (TK_EQ2); default: return TK_EQ;
        };
        case '!':switch(b){
            case '=': retnext (TK_NEQ); default: return TK_EXC;
        };
        default: return TK_EMPTY;
    };
};

static inline optional<float> interp_flt(string lexm){
    char* end; const char* cstr = lexm.c_str();

    float val = strtof(cstr, &end);

    if (end == cstr || *end != '\0'){
        return nullopt;
    }; return val;
};

static inline optional<double> interp_dub(string lexm){
    char* end; const char* cstr = lexm.c_str();

    double val = strtod(cstr, &end);

    if (end == cstr || *end != '\0'){
        return nullopt;
    }; return val;
};

static inline optional<long long> interp_llong(string lexm){
    char* end; const char* cstr = lexm.c_str();

    long long val = strtoll(cstr, &end, 0);

    if (end == cstr || *end != '\0'){
        return nullopt;
    }; return val;
};

static string vischar(char _c){
    switch(_c){
        case ' ': return "<space>";
        case '\n': return "<newline>";
        case '\t': return "<tab>";
        default: return string(1, _c);
    };
};

void token_lctx(LexContext& lctx, int debug_flags){
    // debug flags: 0b[][][][show_msg]

    size_t char_maxext = 0;
    lctx.src_index = 0;

    bool dmsg = (debug_flags & 0b0001) != 0;

    #define next c0 = lctx.cnext(); if(dmsg) {cout<<"\nOn Character " + vischar(c0);}

    unordered_map<string_view, string*> lexeme_map;
    lexeme_map.reserve(512);

    while (1){
        auto [c0, c1] = lctx.cpeek2();

        if (dmsg){cerr << "\nConstructing from " << vischar(c0) << " at " << to_string(lctx.src_index);}
        if (c0 == '\0'){lctx.emitfc(TK_EOF); break;};

        if (lctx.src_index + 1 <= char_maxext){
            // Tokenizer not designed to roll back on characters.
            lctx.throw_err("Reached source index " + to_string(lctx.src_index) + " multiple times!");
        }

        char_maxext = lctx.src_index + 1;

        if (isspace(c0)){
            int skiplen = 0;
            while (isspace(c0)){skiplen++; c0 = lctx.cnext();}
            if (dmsg){cout << "\nSkipped " + to_string(skiplen) + " whitespaces.";}
            continue;
        }

        // Comment handling // or //()
        if (c0 == '/' && c1 == '/'){
            char term = lctx.cpeek(2) == '(' ? ')' : '\n';
            lctx.src_index+=2; // consumes / and /

            while (c0 != term && c0 != '\0'){c0 = lctx.cnext();}
            if (c0 == term){next;}
            continue;
        }

        // Number Literals
        if (isdigit(c0) || (c0 == '.' && isdigit(c1))){
            string lexm;
            char prev = '\0';
            while (isalnum(c0) || c0 == '.' || c0 == '_' || (c0 == '-' && (prev == 'e' || prev == 'E'))){
                if (c0 != '_'){lexm.push_back(c0); prev = c0;}
                next;
            }
            if (lexm.size() < 1){
                lctx.throw_err("Empty literal number lexeme!");
            }

            int dtype = 0; // 0: undesignated, 1: int, 2: float, 3: double
            switch(lexm.back()){
                case 'i': lexm.pop_back(); dtype = 1; break;
                case 'f': lexm.pop_back(); dtype = 2; break;
                case 'd': lexm.pop_back(); dtype = 3; break;
            }

            switch(dtype){
                case 0:{
                    auto val_ll = interp_llong(lexm);
                    if (val_ll.has_value()){
                        auto lltok = Token{TK_LIT_INT, lctx.line}; lltok.pl.t_lng = val_ll.value();