diff --git a/B06_Section/B06_Section_UI_Section_View.ts b/B06_Section/B06_Section_UI_Section_View.ts index 0d6a90505..9434bb10d 100644 --- a/B06_Section/B06_Section_UI_Section_View.ts +++ b/B06_Section/B06_Section_UI_Section_View.ts @@ -285,6 +285,16 @@ export function createSectionView( /** 같은 측점을 다시 고르면 선택을 푼다(2026-08-02 사용자 지시) — 카드·측점선 어느 쪽이든. */ const selectStation = (stationId: string, scroll: boolean): void => { + // 고른 노면공 범위 안 카드는 다시 눌러도 그대로 — 풂은 빈 자리 · 목록 · 알약(167-3) + const section = currentDetail?.cross_sections.find((entry) => entry.station_id === stationId); + const held = + section && isPavement(spanMarkId) + ? inSpan( + section, + spanMarks.find((entry) => entry.structure_id === spanMarkId), + ) + : false; + if (selectedStationId === stationId && held) return; const previous = selectedStationId; const deselect = selectedStationId === stationId; selectedStationId = deselect ? null : stationId; diff --git a/resources/tester/helper_165_pavement_flow.cjs b/resources/tester/helper_165_pavement_flow.cjs index b7d3a565e..407a783ef 100644 --- a/resources/tester/helper_165_pavement_flow.cjs +++ b/resources/tester/helper_165_pavement_flow.cjs @@ -189,6 +189,14 @@ const view = { return !!mark && markTypes.find((type) => type.type_id === mark.type_id)?.group === "G"; }, selectStation(id) { + // 고른 노면공 범위 안 카드 재누름 = 그대로(167-3 · Section_View `selectStation`) + const card = CARDS.find((entry) => entry.station_id === id); + const mark = marks.find((entry) => entry.structure_id === this.spanMarkId); + const held = + this.isPavement(this.spanMarkId) && + card.chainage_m >= Math.min(mark.start_m, mark.end_m) - 0.01 && + card.chainage_m <= Math.max(mark.start_m, mark.end_m) + 0.01; + if (this.selected === id && held) return; const previous = this.selected; this.selected = this.selected === id ? null : id; profile.showCard(CARDS.find((card) => card.station_id === this.selected) ?? null); @@ -300,6 +308,8 @@ const wallPick = (cardAtM, ownerM) => { await build([PAVE, { structure_id: "sign", type_id: "hazard_sign", chainage_m: 127.86 }]); listPick("pave"); out.step1 = snap(); + cardPick(40); // 고름이 이미 연 범위 첫 카드 재누름(브레인 ORCA ②) + out.step2re = snap(); cardPick(140); out.step2 = snap(); cardPick(100); @@ -313,6 +323,8 @@ const wallPick = (cardAtM, ownerM) => { pillPick("pave"); cardPick(280); // 범위 밖 = 모두 풂 out.outside = snap(); + cardPick(280); // 범위 밖 카드 재누름 = 카드 풂(옛 규칙 그대로) + out.outsideRe = snap(); // 5. B05 알약 → B06 복귀 — 넘김값 {범위 첫 카드 · sid} · `restoreStructurePick` 의 focusStation 차례 await build([PAVE]); diff --git a/resources/tester/test_165_pavement_flow.py b/resources/tester/test_165_pavement_flow.py index 5ab8f210d..7ab3b105e 100644 --- a/resources/tester/test_165_pavement_flow.py +++ b/resources/tester/test_165_pavement_flow.py @@ -59,6 +59,7 @@ def test_1_목록_노면공(out): def test_2_범위_안_빈_카드는_노면공_그대로(out): + assert out["step2re"] == _pave(40) # 이미 고른 카드 재누름도 그대로(167-3) assert out["step2"] == _pave(140) assert out["step2b"] == _pave(100) @@ -78,6 +79,7 @@ def test_4_알약_다시_관_카드_범위_밖(out): "card": 280, "sid": None, } + assert out["outsideRe"]["card"] is None def test_5_B05_복귀(out): @@ -98,3 +100,4 @@ def test_배선(): assert at < panel.index("deps.markStructure?.(`pipe-${hit.pipeChainageM.toFixed(2)}`);", at) view = _read("B06_Section", "B06_Section_UI_Section_View.ts") assert "spanMarkId = span || isPavement(structureId) ? structureId : null;" in view + assert "if (selectedStationId === stationId && held) return;" in view