namespace DB720Flasher; public sealed class ComPortInfo { public required string PortName { get; init; } // "COM4" public required string FriendlyName { get; init; } // Win32 PnP 이름 public required string DeviceId { get; init; } // USB\VID_303A&PID_1001\... public int Number { get; init; } public string? Vid { get; init; } public string? Pid { get; init; } public string Kind { get; init; } = "USB 직렬"; // "USB-JTAG (내장)", "CP210x", "CH340", "FTDI" … public bool IsJtag => Vid == "303A" && Pid == "1001"; public string VidPid => Vid is null || Pid is null ? "" : $"{Vid}:{Pid}"; public bool Matches(string? hint) => !string.IsNullOrEmpty(hint) && string.Equals(VidPid, hint, StringComparison.OrdinalIgnoreCase); public string Display => $"{PortName} · {Kind}"; public override string ToString() => Display; } /// 플래시 모드. public enum FlashMode { AppOnly, // 앱만 (+ 프로파일이 지정하면 otadata erase) — 권장 Standard, // 부트로더 제외 전부 (파티션+ota_data+앱(+www)) Full, // 부트로더까지 전부 (eFuse 위험) } public sealed class FirmwareItem { public required string FileName { get; init; } public required string FullPath { get; init; } public long Size { get; init; } public string? Note { get; init; } public string SizeText => Size >= 1_048_576 ? $"{Size / 1048576.0:0.0}MB" : $"{Size / 1024.0:0}KB"; public string Display => Note is null ? $"{FileName} ({SizeText})" : $"{FileName} · {Note}"; public override string ToString() => Display; }