diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..3a8816a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,32 @@ +# Repository Instructions + +## MSIX publish after user approval + +When the user says a completed change is approved and asks to publish, deploy, +patch, or update the MSIX, use the automated NAS publish script instead of +manually editing package versions or copying files. + +Normal approved publish command: + +```powershell +powershell -ExecutionPolicy Bypass -File .\tools\msix\Publish-MsixToNas.ps1 -Configuration Release -IncrementPackageRevision +``` + +Prerequisites: + +- `NAS_USER` must be set to the NAS account with write access to `/volume1/web/msix`. +- `NAS_SSH_KEY` should point to the SSH private key for that NAS account. +- The signing certificate thumbprint must remain + `E691A33C64DF20A204FFD4F096B9C3EB4B95709C`. + +The script will: + +1. Read `Tornado3_2026Election/Package.appxmanifest`. +2. Increment the fourth package version part. +3. Build and sign the MSIX package. +4. Rewrite App Installer URLs to the public NAS path. +5. Upload the files to the NAS over SSH/SCP. +6. Verify the public URLs after upload. + +Do not run this publish command unless the user has explicitly approved +publishing or deployment. diff --git a/OBJECT_TYPE_QUERY.md b/OBJECT_TYPE_QUERY.md new file mode 100644 index 0000000..724ee90 --- /dev/null +++ b/OBJECT_TYPE_QUERY.md @@ -0,0 +1,9 @@ +# Object Type Query + +- Generated: 2026-05-10 04:13:49 +- Scene: `D:\Elect2026\T3_Cut\Elect2026_Bottom_민방\전후보_광역단체장.tscn` +- Objects Queried: 1 + +| Object | Result | Type | Detail | +| --- | --- | --- | --- | +| 득표율01,득표율02,득표율03 | RESULT_ERROR_NO_VARIABLE_OBJECT | OBJECT_TYPE_UNKNOWN | | diff --git a/SCENE_CAPABILITY_INSPECTION.md b/SCENE_CAPABILITY_INSPECTION.md new file mode 100644 index 0000000..6426a63 --- /dev/null +++ b/SCENE_CAPABILITY_INSPECTION.md @@ -0,0 +1,42 @@ +# Scene Capability Inspection + +- Generated: 2026-05-10 04:24:05 +- Scene: `D:\Elect2026\T3_Cut\Elect2026_Bottom_민방\전후보_광역단체장_loop.tscn` +- Candidate Count: 34 + +| Candidate | Found | Anim | Chart | Counter | Path | QueryType | Type | QueryPos | X | Y | Z | SetPos | SetValueText | SetValueImage | CounterKey | Detail | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| bar | yes | | no | no | no | RESULT_ERROR_NO_VARIABLE_OBJECT | OBJECT_TYPE_UNKNOWN | RESULT_ERROR_NO_VARIABLE_OBJECT | | | | | RESULT_ERROR_NO_VARIABLE_OBJECT | RESULT_ERROR_NO_VARIABLE_OBJECT | | | +| data01 | yes | | no | no | no | RESULT_ERROR_NO_VARIABLE_OBJECT | OBJECT_TYPE_UNKNOWN | RESULT_ERROR_NO_VARIABLE_OBJECT | | | | | RESULT_ERROR_NO_VARIABLE_OBJECT | RESULT_ERROR_NO_VARIABLE_OBJECT | | | +| Root | yes | | no | no | no | RESULT_ERROR_NO_VARIABLE_OBJECT | OBJECT_TYPE_UNKNOWN | RESULT_ERROR_NO_VARIABLE_OBJECT | | | | | RESULT_ERROR_NO_VARIABLE_OBJECT | RESULT_ERROR_NO_VARIABLE_OBJECT | | | +| 개표율01 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_TEXT | RESULT_SUCCESS | -24.198 | 23.054 | 0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | | +| 그룹01 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_UNKNOWN | RESULT_SUCCESS | -752.384 | -1 | 0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 그룹02 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_UNKNOWN | RESULT_SUCCESS | -271.38 | -1 | 0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 그룹03 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_UNKNOWN | RESULT_SUCCESS | 210.62 | -1 | 0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 득표수01 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_TEXT | RESULT_SUCCESS | 185.185 | -47.402 | -0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | | +| 득표수02 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_TEXT | RESULT_SUCCESS | 185.185 | -47.402 | -0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | | +| 득표수03 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_TEXT | RESULT_SUCCESS | 185.185 | -47.402 | -0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | | +| 득표율01 | yes | | no | yes | no | RESULT_SUCCESS | OBJECT_TYPE_COUNTER | RESULT_SUCCESS | 239 | -21 | 0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | +| 득표율02 | yes | | no | yes | no | RESULT_SUCCESS | OBJECT_TYPE_COUNTER | RESULT_SUCCESS | 239 | -21 | 0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | +| 득표율03 | yes | | no | yes | no | RESULT_SUCCESS | OBJECT_TYPE_COUNTER | RESULT_SUCCESS | 239 | -21 | 0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | +| 마스크 | yes | | no | no | no | RESULT_ERROR_NO_VARIABLE_OBJECT | OBJECT_TYPE_UNKNOWN | RESULT_ERROR_NO_VARIABLE_OBJECT | | | | | RESULT_ERROR_NO_VARIABLE_OBJECT | RESULT_ERROR_NO_VARIABLE_OBJECT | | | +| 선거구명01 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_TEXT | RESULT_SUCCESS | -0.73 | -22.031 | 0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | | +| 순위01 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_IMAGE | RESULT_SUCCESS | -182 | 9 | 0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 순위02 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_IMAGE | RESULT_SUCCESS | -182 | 9 | -0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 순위03 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_IMAGE | RESULT_SUCCESS | -182 | 9 | -0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 시도 | yes | | no | no | no | RESULT_ERROR_NO_VARIABLE_OBJECT | OBJECT_TYPE_UNKNOWN | RESULT_ERROR_NO_VARIABLE_OBJECT | | | | | RESULT_ERROR_NO_VARIABLE_OBJECT | RESULT_ERROR_NO_VARIABLE_OBJECT | | | +| 유확당01 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_IMAGE | RESULT_SUCCESS | -181 | 10 | 0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 유확당02 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_IMAGE | RESULT_SUCCESS | -181 | 10 | -0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 유확당03 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_IMAGE | RESULT_SUCCESS | -181 | 10 | -0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 정당명01 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_TEXT | RESULT_SUCCESS | 11.187 | 37.97 | 0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | | +| 정당명02 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_TEXT | RESULT_SUCCESS | 11.187 | 37.97 | 0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | | +| 정당명03 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_TEXT | RESULT_SUCCESS | 11.187 | 37.97 | 0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | | +| 정당바01 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_RECT | RESULT_SUCCESS | 36.258 | 0 | 0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 정당바02 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_RECT | RESULT_SUCCESS | 36.258 | 0 | 0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 정당바03 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_RECT | RESULT_SUCCESS | 36.258 | 0 | 0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 후보명01 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_TEXT | RESULT_SUCCESS | 10.053 | -4.864 | 0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | | +| 후보명02 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_TEXT | RESULT_SUCCESS | 10.053 | -4.864 | 0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | | +| 후보명03 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_TEXT | RESULT_SUCCESS | 10.053 | -4.864 | 0 | RESULT_SUCCESS | RESULT_SUCCESS | RESULT_SUCCESS | | | +| 후보사진01 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_IMAGE | RESULT_SUCCESS | -94.972 | -16 | 0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 후보사진02 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_IMAGE | RESULT_SUCCESS | -94.972 | -16 | 0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | +| 후보사진03 | yes | | no | no | no | RESULT_SUCCESS | OBJECT_TYPE_IMAGE | RESULT_SUCCESS | -94.972 | -16 | 0 | RESULT_SUCCESS | RESULT_FAILURE | RESULT_SUCCESS | | | diff --git a/TSCN_VARIABLE_DISCOVERY_TOP_2P.md b/TSCN_VARIABLE_DISCOVERY_TOP_2P.md new file mode 100644 index 0000000..75730af --- /dev/null +++ b/TSCN_VARIABLE_DISCOVERY_TOP_2P.md @@ -0,0 +1,193 @@ +# TSCN Variable Discovery + +- Generated: 2026-05-09 03:06:16 +- Root: `D:\Elect2026\T3_Cut\Elect2026_Top_민방` +- Scene Count: 8 +- Discovered Variable Count: 112 +- Failure Count: 0 + +## Method + +- Candidate names are extracted from each `.tscn` as UTF-16LE strings. +- Each candidate is verified through Karisma TCP callbacks. +- `SetValue(__TCP_VALIDATE__)`, valid `.png`, valid `.vrv`, and `SetCounterNumberKey(1, 1)` are tried as applicable. +- Only callbacks that returned `RESULT_SUCCESS` are listed as discovered variables. + +## Scenes + +### `광역단체장_2인.tscn` + +- Candidate Count: 20 +- Discovered Variables: 14 + +| Variable | Method | Payload | Result | +| --- | --- | --- | --- | +| 개표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 선거구명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 유확당01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 유확당02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 후보사진01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 후보사진02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | + +### `광역단체장_2인_텍스트.tscn` + +- Candidate Count: 18 +- Discovered Variables: 14 + +| Variable | Method | Payload | Result | +| --- | --- | --- | --- | +| 개표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 선거구명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 유확당01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 유확당02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 후보명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 후보명02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | + +### `기초단체장_2인.tscn` + +- Candidate Count: 20 +- Discovered Variables: 15 + +| Variable | Method | Payload | Result | +| --- | --- | --- | --- | +| 개표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 선거구명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 시도명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 유확당01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 유확당02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 후보사진01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 후보사진02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | + +### `기초단체장_2인_텍스트.tscn` + +- Candidate Count: 19 +- Discovered Variables: 13 + +| Variable | Method | Payload | Result | +| --- | --- | --- | --- | +| 개표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 선거구명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 시도명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 유확당01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 유확당02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | + +### `Elect2026_Top_민방\광역단체장_2인.tscn` + +- Candidate Count: 20 +- Discovered Variables: 14 + +| Variable | Method | Payload | Result | +| --- | --- | --- | --- | +| 개표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 선거구명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 유확당01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 유확당02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 후보사진01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 후보사진02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | + +### `Elect2026_Top_민방\광역단체장_2인_텍스트.tscn` + +- Candidate Count: 18 +- Discovered Variables: 14 + +| Variable | Method | Payload | Result | +| --- | --- | --- | --- | +| 개표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 선거구명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 유확당01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 유확당02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 후보명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 후보명02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | + +### `Elect2026_Top_민방\기초단체장_2인.tscn` + +- Candidate Count: 20 +- Discovered Variables: 15 + +| Variable | Method | Payload | Result | +| --- | --- | --- | --- | +| 개표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 선거구명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 시도명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 유확당01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 유확당02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 후보사진01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 후보사진02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | + +### `Elect2026_Top_민방\기초단체장_2인_텍스트.tscn` + +- Candidate Count: 19 +- Discovered Variables: 13 + +| Variable | Method | Payload | Result | +| --- | --- | --- | --- | +| 개표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 득표율02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 선거구명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 순위02 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 시도명01 | SetValue | __TCP_VALIDATE__ | RESULT_SUCCESS | +| 유확당01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 유확당02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당바02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼01 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | +| 정당심볼02 | SetValue | D:\\Elect2026\\T3_Cut\\Elect2026_Top_민방\\Elect2026_Top_민방\\Images\\Dang\\Dang_Symbol\\개혁신당.png | RESULT_SUCCESS | + diff --git a/Tornado3_2026Election/Assets/Stations/ubc.png b/Tornado3_2026Election/Assets/Stations/ubc.png new file mode 100644 index 0000000..68c14f3 Binary files /dev/null and b/Tornado3_2026Election/Assets/Stations/ubc.png differ diff --git a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/1-2위_기초단체장.png b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/1-2위_기초단체장.png index 5831d59..3d724b8 100644 Binary files a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/1-2위_기초단체장.png and b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/1-2위_기초단체장.png differ diff --git a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/1-3위_보궐선거.png b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/1-3위_보궐선거.png index b78d55d..9b760a1 100644 Binary files a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/1-3위_보궐선거.png and b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/1-3위_보궐선거.png differ diff --git a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/경력_광역단체장_in.png b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/경력_광역단체장_in.png index 0267ae5..92e8787 100644 Binary files a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/경력_광역단체장_in.png and b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/경력_광역단체장_in.png differ diff --git a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/경력_기초단체장_in.png b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/경력_기초단체장_in.png index 572dbb3..2bb10b6 100644 Binary files a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/경력_기초단체장_in.png and b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/경력_기초단체장_in.png differ diff --git a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_광역단체장.png b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_광역단체장.png index e6a7eec..4f62502 100644 Binary files a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_광역단체장.png and b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_광역단체장.png differ diff --git a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_광역단체장_L.png b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_광역단체장_L.png index 9305e23..d47d1c1 100644 Binary files a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_광역단체장_L.png and b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_광역단체장_L.png differ diff --git a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장.png b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장.png index 21ad948..bc13c82 100644 Binary files a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장.png and b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장.png differ diff --git a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장_HD.png b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장_HD.png index b98343e..c88bcfc 100644 Binary files a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장_HD.png and b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장_HD.png differ diff --git a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장_L.png b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장_L.png index 2705228..b49c0ac 100644 Binary files a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장_L.png and b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/이시각1위_기초단체장_L.png differ diff --git a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/판세_기초단체장.png b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/판세_기초단체장.png index b80f838..c164dca 100644 Binary files a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/판세_기초단체장.png and b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/판세_기초단체장.png differ diff --git a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/판세_기초단체장_5760.png b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/판세_기초단체장_5760.png index 21c57ca..162196b 100644 Binary files a/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/판세_기초단체장_5760.png and b/Tornado3_2026Election/Assets/Thumbnail/Elect2026_Normal_민방/판세_기초단체장_5760.png differ diff --git a/Tornado3_2026Election/Controls/ChannelSchedulePanel.xaml b/Tornado3_2026Election/Controls/ChannelSchedulePanel.xaml index 518366c..d0c7baa 100644 --- a/Tornado3_2026Election/Controls/ChannelSchedulePanel.xaml +++ b/Tornado3_2026Election/Controls/ChannelSchedulePanel.xaml @@ -90,37 +90,98 @@ BorderBrush="#25405D" BorderThickness="1" CornerRadius="18"> - - - - - + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + - + @@ -778,7 +839,7 @@ + BroadcastRank > 0 && + BroadcastSeatCount > 0 && + BroadcastRank <= BroadcastSeatCount; + public int VoteCount { get => _voteCount; @@ -217,6 +232,9 @@ public sealed class CandidateEntry : ObservableObject BroadcastElectionDistrictName = BroadcastElectionDistrictName, BroadcastDistrictCode = BroadcastDistrictCode, BroadcastCountedRate = BroadcastCountedRate, + BroadcastRank = BroadcastRank, + BroadcastSeatCount = BroadcastSeatCount, + BroadcastCountingClosed = BroadcastCountingClosed, VoteCount = VoteCount, VoteRate = VoteRate, HasImage = HasImage, diff --git a/Tornado3_2026Election/Domain/ChannelScheduleItem.cs b/Tornado3_2026Election/Domain/ChannelScheduleItem.cs index 4fc0add..de99f72 100644 --- a/Tornado3_2026Election/Domain/ChannelScheduleItem.cs +++ b/Tornado3_2026Election/Domain/ChannelScheduleItem.cs @@ -20,6 +20,13 @@ public sealed class ChannelScheduleItem : ObservableObject private double _thumbnailWidth = 160; private double _thumbnailHeight = 90; private ImageSource? _thumbnailSource; + private string _renderedPreviewPath = string.Empty; + private ImageSource? _renderedPreviewSource; + private string _renderedPreviewStatusLabel = string.Empty; + private string _internalNextPreviewPath = string.Empty; + private ImageSource? _internalNextPreviewSource; + private string _internalNextPreviewStatusLabel = string.Empty; + private string _internalNextPreviewDisplayName = string.Empty; public Guid Id { get; set; } = Guid.NewGuid(); @@ -88,6 +95,9 @@ public sealed class ChannelScheduleItem : ObservableObject { OnPropertyChanged(nameof(StateLabel)); OnPropertyChanged(nameof(StateBrush)); + OnPropertyChanged(nameof(StateCardBackgroundBrush)); + OnPropertyChanged(nameof(StateCardBorderBrush)); + OnPropertyChanged(nameof(StateBadgeBackgroundBrush)); OnPropertyChanged(nameof(CardOpacity)); OnPropertyChanged(nameof(CanDelete)); } @@ -133,11 +143,43 @@ public sealed class ChannelScheduleItem : ObservableObject [JsonIgnore] public SolidColorBrush StateBrush => new(State switch { - ScheduleQueueItemState.Next => ColorHelper.FromArgb(255, 245, 158, 11), + ScheduleQueueItemState.Next => ColorHelper.FromArgb(255, 255, 184, 28), + ScheduleQueueItemState.Sending => ColorHelper.FromArgb(255, 255, 132, 38), ScheduleQueueItemState.OnAir => ColorHelper.FromArgb(255, 239, 68, 68), + ScheduleQueueItemState.Error => ColorHelper.FromArgb(255, 251, 113, 133), _ => ColorHelper.FromArgb(255, 100, 116, 139) }); + [JsonIgnore] + public SolidColorBrush StateCardBackgroundBrush => new(State switch + { + ScheduleQueueItemState.Next => ColorHelper.FromArgb(255, 72, 38, 10), + ScheduleQueueItemState.Sending => ColorHelper.FromArgb(255, 64, 42, 16), + ScheduleQueueItemState.OnAir => ColorHelper.FromArgb(255, 58, 22, 24), + ScheduleQueueItemState.Error => ColorHelper.FromArgb(255, 54, 18, 31), + _ => ColorHelper.FromArgb(255, 18, 32, 51) + }); + + [JsonIgnore] + public SolidColorBrush StateCardBorderBrush => new(State switch + { + ScheduleQueueItemState.Next => ColorHelper.FromArgb(255, 255, 184, 28), + ScheduleQueueItemState.Sending => ColorHelper.FromArgb(255, 255, 132, 38), + ScheduleQueueItemState.OnAir => ColorHelper.FromArgb(255, 255, 90, 84), + ScheduleQueueItemState.Error => ColorHelper.FromArgb(255, 251, 113, 133), + _ => ColorHelper.FromArgb(255, 39, 64, 95) + }); + + [JsonIgnore] + public SolidColorBrush StateBadgeBackgroundBrush => new(State switch + { + ScheduleQueueItemState.Next => ColorHelper.FromArgb(255, 194, 65, 12), + ScheduleQueueItemState.Sending => ColorHelper.FromArgb(255, 180, 83, 9), + ScheduleQueueItemState.OnAir => ColorHelper.FromArgb(255, 220, 38, 38), + ScheduleQueueItemState.Error => ColorHelper.FromArgb(255, 190, 18, 60), + _ => ColorHelper.FromArgb(255, 26, 46, 71) + }); + [JsonIgnore] public double CardOpacity => State == ScheduleQueueItemState.Completed ? 0.45 : 1.0; @@ -179,6 +221,33 @@ public sealed class ChannelScheduleItem : ObservableObject [JsonIgnore] public bool HasThumbnail => CutThumbnailAssetCatalog.HasThumbnail(FormatId); + [JsonIgnore] + public ImageSource? PreviewSource => _renderedPreviewSource; + + [JsonIgnore] + public bool HasRenderedPreview => _renderedPreviewSource is not null; + + [JsonIgnore] + public string PreviewStatusLabel => HasRenderedPreview + ? _renderedPreviewStatusLabel + : "실데이터 프리뷰 준비 중"; + + [JsonIgnore] + public ImageSource? InternalNextPreviewSource => _internalNextPreviewSource; + + [JsonIgnore] + public bool HasInternalNextPreview => _internalNextPreviewSource is not null; + + [JsonIgnore] + public string InternalNextPreviewStatusLabel => HasInternalNextPreview + ? _internalNextPreviewStatusLabel + : "다음 지역 프리뷰 준비 중"; + + [JsonIgnore] + public string InternalNextPreviewDisplayName => string.IsNullOrWhiteSpace(_internalNextPreviewDisplayName) + ? DisplayName + : _internalNextPreviewDisplayName; + [JsonIgnore] public double ThumbnailWidth { @@ -204,6 +273,55 @@ public sealed class ChannelScheduleItem : ObservableObject OnPropertyChanged(nameof(ThumbnailStatusLabel)); } + public void UpdateRenderedPreview(string previewPath, string statusLabel) + { + _renderedPreviewPath = previewPath; + _renderedPreviewSource = CutPreviewAssetCatalog.CreateImageSource(previewPath); + _renderedPreviewStatusLabel = statusLabel; + OnPreviewChanged(); + } + + public void UpdateInternalNextPreview(string previewPath, string displayName, string statusLabel) + { + _internalNextPreviewPath = previewPath; + _internalNextPreviewSource = CutPreviewAssetCatalog.CreateImageSource(previewPath); + _internalNextPreviewDisplayName = displayName; + _internalNextPreviewStatusLabel = statusLabel; + OnInternalNextPreviewChanged(); + } + + public void ClearRenderedPreview() + { + if (string.IsNullOrWhiteSpace(_renderedPreviewPath) && + _renderedPreviewSource is null && + string.IsNullOrWhiteSpace(_renderedPreviewStatusLabel)) + { + return; + } + + _renderedPreviewPath = string.Empty; + _renderedPreviewSource = null; + _renderedPreviewStatusLabel = string.Empty; + OnPreviewChanged(); + } + + public void ClearInternalNextPreview() + { + if (string.IsNullOrWhiteSpace(_internalNextPreviewPath) && + _internalNextPreviewSource is null && + string.IsNullOrWhiteSpace(_internalNextPreviewStatusLabel) && + string.IsNullOrWhiteSpace(_internalNextPreviewDisplayName)) + { + return; + } + + _internalNextPreviewPath = string.Empty; + _internalNextPreviewSource = null; + _internalNextPreviewStatusLabel = string.Empty; + _internalNextPreviewDisplayName = string.Empty; + OnInternalNextPreviewChanged(); + } + public void UpdateThumbnailLayout(ThumbnailDisplayMetrics metrics) { ThumbnailWidth = metrics.Width; @@ -227,6 +345,21 @@ public sealed class ChannelScheduleItem : ObservableObject OnPropertyChanged(nameof(DurationApplyStatusLabel)); } + private void OnPreviewChanged() + { + OnPropertyChanged(nameof(PreviewSource)); + OnPropertyChanged(nameof(HasRenderedPreview)); + OnPropertyChanged(nameof(PreviewStatusLabel)); + } + + private void OnInternalNextPreviewChanged() + { + OnPropertyChanged(nameof(InternalNextPreviewSource)); + OnPropertyChanged(nameof(HasInternalNextPreview)); + OnPropertyChanged(nameof(InternalNextPreviewStatusLabel)); + OnPropertyChanged(nameof(InternalNextPreviewDisplayName)); + } + public static ChannelScheduleItem FromTemplate(FormatTemplateDefinition template, ScheduleRegionOption? regionOption = null) { var selectedRegion = regionOption ?? new ScheduleRegionOption diff --git a/Tornado3_2026Election/Domain/CutCategory.cs b/Tornado3_2026Election/Domain/CutCategory.cs index ac6dabd..fb7387e 100644 --- a/Tornado3_2026Election/Domain/CutCategory.cs +++ b/Tornado3_2026Election/Domain/CutCategory.cs @@ -8,6 +8,15 @@ public enum CutCategory MetropolitanCouncil, LocalCouncil, NationalAssembly, + BottomTopTwo, + BottomTopThree, + BottomCurrentLeader, + BottomWinner, + BottomAllCandidates, + BottomTurnoutSido, + BottomTurnoutDistrict, + BottomEarlyTurnout, + BottomElectionDayTurnout, PreElection, Historical, Turnout, diff --git a/Tornado3_2026Election/Domain/ElectionDataSnapshot.cs b/Tornado3_2026Election/Domain/ElectionDataSnapshot.cs index 8b6d985..8c73327 100644 --- a/Tornado3_2026Election/Domain/ElectionDataSnapshot.cs +++ b/Tornado3_2026Election/Domain/ElectionDataSnapshot.cs @@ -32,6 +32,8 @@ public sealed class ElectionDataSnapshot public required DateTimeOffset ReceivedAt { get; init; } + public string ReferenceTimeLabel { get; init; } = string.Empty; + public IReadOnlyList HistoricalTurnoutHistory { get; init; } = Array.Empty(); diff --git a/Tornado3_2026Election/Domain/VideoWallLayoutPreset.cs b/Tornado3_2026Election/Domain/VideoWallLayoutPreset.cs index 35f96ac..589e282 100644 --- a/Tornado3_2026Election/Domain/VideoWallLayoutPreset.cs +++ b/Tornado3_2026Election/Domain/VideoWallLayoutPreset.cs @@ -3,6 +3,7 @@ namespace Tornado3_2026Election.Domain; public enum VideoWallLayoutPreset { Auto, - Standard5760x1080, - UltraWide11520x1080 + Wall3840x810, + Wall2880x1080, + UltraWide8316x1080 } diff --git a/Tornado3_2026Election/MainWindow.xaml b/Tornado3_2026Election/MainWindow.xaml index 6bc65fe..797c320 100644 --- a/Tornado3_2026Election/MainWindow.xaml +++ b/Tornado3_2026Election/MainWindow.xaml @@ -44,13 +44,14 @@ - - - - + + + + - - + + + @@ -812,23 +813,66 @@ + + + + + + CornerRadius="24"> + + + + + + + + + + + + + + + +