feat(771-1·771-2): B05 예정노선 수정 — 중간 노드에서 긋기 · 닿은 노드 사이 갈음 · 지움 뒤 긋기 Esc = 지움 전

- 771-2: 한 선 페이지(B05) 중간 노드 누름 = 그 노드에서 긋기 · 같은 선 다른 노드에 닿으면 그 사이 갈음(rejoinSpan · 거꾸로 됨 · 한 줄) · 같은 노드 · 안 닿고 끝냄 = 꼴 그대로 + 안내 · 되돌리기 한 걸음 · D03 는 중간 꺾임점 = 갈래 그대로
- 771-1: 긋기 Esc = 긋기 직전 꼴 · 지움(노드 · 토막 · 구역 · 전체 · 잇단 지움) 바로 뒤 긋기면 지움 전 꼴(D03 같은 부품)
- 시험: test_771_2_rejoin_span 새로 · test_626_3 의 lineLimitBlock 줄 문자열 대조를 새 꼴(branches 변수)로 고침

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-03 19:48:42 +09:00
co-authored by Claude Opus 5.5
parent b13eb584fb
commit df879ffcb9
6 changed files with 225 additions and 21 deletions
+18 -4
View File
@@ -128,6 +128,8 @@ export interface PlanEdit {
dropRegion: (line: string) => void;
/** 전체 지움 — 선 · 구역 모두(지점 남김) · 되돌리기 한 걸음. */
dropAll: () => void;
/** 지금 꼴이 선 지움(노드 · 토막 · 구역 · 전체 · 잇단 지움 묶음) 바로 뒤면 지움 전 꼴 · 아니면 null(771-1). */
dropBase: () => PlanNetwork | null;
/** 이 자리 선 위에 연도 구역 마커 — 놓음 = 참. */
splitAt: (px: number, py: number, map: ScreenMap) => boolean;
/** 이 자리에 무엇이 있나(우클릭 메뉴). */
@@ -184,6 +186,17 @@ export function createPlanEdit(params: PlanEditParams): PlanEdit {
sel.sync();
}
/** 선 지움 — 지움 전 꼴 기억(잇단 지움 = 첫 지움 전 · 771-1). */
let dropped: { before: PlanNetwork; after: PlanNetwork } | null = null;
const dropBase = (): PlanNetwork | null =>
dropped && dropped.after === params.network() ? dropped.before : null;
function drop(next: PlanNetwork | string): void {
const before = params.network();
const base = dropBase() ?? before;
apply(next);
if (params.network() !== before) dropped = { before: base, after: params.network() };
}
/** 선 끝 — 첫 점(갈래 아님) · 끝 점 · 그 밖 = null. */
function endOf(node: PlanNode): LineEnd | null {
const line = params.network().lines.find((entry) => entry.id === node.line);
@@ -217,19 +230,19 @@ export function createPlanEdit(params: PlanEditParams): PlanEdit {
function dropNode(node: PlanNode): void {
const network = params.network();
const index = lineIndexOf(network, node.line);
if (index >= 0) apply(removeVertex(network, index, node.vertex));
if (index >= 0) drop(removeVertex(network, index, node.vertex));
}
function dropRegion(line: string): void {
const network = params.network();
const index = lineIndexOf(network, line);
if (index >= 0) apply(removeLine(network, index));
if (index >= 0) drop(removeLine(network, index));
}
function dropAll(): void {
const network = params.network();
if (!network.lines.length) return;
apply(removeAll(network));
drop(removeAll(network));
showToast("노선을 모두 지웠습니다 — 되돌리기(Ctrl+Z) · [저장] 때 정본.", "info");
}
@@ -239,7 +252,7 @@ export function createPlanEdit(params: PlanEditParams): PlanEdit {
if (!picked) return;
if (picked.kind === "mark") return dropMark();
if (picked.kind === "node") return dropNode(picked.node!);
if (picked.kind === "segment") return apply(removeSegments(params.network(), picked.segments));
if (picked.kind === "segment") return drop(removeSegments(params.network(), picked.segments));
if (picked.kind === "line") return dropRegion(picked.line!);
if (picked.kind === "all") return dropAll();
showToast("연도 구간은 지우지 않습니다 — 노드 · 선 · 구역으로 고르세요.", "info");
@@ -618,6 +631,7 @@ export function createPlanEdit(params: PlanEditParams): PlanEdit {
dropMark,
dropRegion,
dropAll,
dropBase,
splitAt,
hit,
key(event) {