refactor(B05,B06): B05_wf2_Route -> B05_Profile, B06_wf3_ProfileCross -> B06_Section 동시 개명

- 한몸으로 동작하는 두 페이지라 한 커밋으로 처리 (상호 참조 다수)
- B05 37파일 + B06 20파일 접두사 개명 (git mv, 이력 보존)
- 참조 치환 91파일: import 경로, 라우트 슬러그(b05-profile/b06-section),
  라우트 키(B05_PROFILE/B06_SECTION), B03 자동 체인, storage 상수, pyproject 제외 경로
- 로직 변경 없음. typecheck·백엔드 import 검증 통과

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-08 10:03:11 +09:00
co-authored by Claude Fable 5
parent b59aae3ea3
commit 54954a05e5
77 changed files with 223 additions and 223 deletions
@@ -0,0 +1,127 @@
/* =============================================================================
* B06_Section_UI_Standard_Diagram.ts
* 표준 횡단면 설정 패널의 "변수 위치 안내" 모식도.
*
* 설정 패널의 각 편집값(노폭·노견·측구·절토/성토 경사·횡단경사)이 횡단면의 어느
* 위치를 의미하는지 라벨로 표시하는 스키매틱 SVG다. 실제 비율이 아니라 위치 안내용이며,
* config 값과 무관한 고정 도형이다(값은 패널 입력에서 편집).
* ========================================================================== */
import { currentLanguageIndex, ui_locales } from "@ui/ui_template_locale";
const SVG_NS = "http://www.w3.org/2000/svg";
function L(key: keyof typeof ui_locales): string {
return ui_locales[key][currentLanguageIndex];
}
function node(tag: string, attrs: Record<string, string | number>, cls?: string): SVGElement {
const el = document.createElementNS(SVG_NS, tag);
for (const [k, v] of Object.entries(attrs)) el.setAttribute(k, String(v));
if (cls) el.setAttribute("class", cls);
return el;
}
function text(x: number, y: number, value: string, cls: string, anchor = "middle"): SVGElement {
const t = node("text", { x, y, "text-anchor": anchor }, cls);
t.textContent = value;
return t;
}
/**
* 편절편성(좌 절토·우 성토) 표준 단면 모식도를 만든다. 좌표는 위치 안내 전용 고정값.
* 좌표 규약(+offset=좌)에 맞춰 절토측(측구 방향)을 왼쪽에 둔다.
*/
export function buildStandardDiagram(): HTMLElement {
const wrap = document.createElement("details");
wrap.className = "b06-std__diagram";
wrap.open = true;
const summary = document.createElement("summary");
summary.className = "b06-std__diagram-summary";
summary.textContent = L("B06_Std_Diagram_Title");
summary.title = L("B06_Std_Diagram_Toggle");
wrap.append(summary);
// 세로로 긴 형태(300×260) — 사면·측구·라벨 간 여백을 넉넉히 둔다.
const svg = node("svg", {
viewBox: "0 0 300 260",
role: "img",
"aria-label": L("B06_Std_Diagram_Title"),
}) as SVGSVGElement;
svg.setAttribute("class", "b06-std__diagram-svg");
// 지반선(원지반) — 좌측 높고 우측 낮은 사면. 절토/성토의 배경.
svg.append(
node("polyline", { points: "10,60 95,122 205,138 290,210", fill: "none" }, "b06-diag__ground"),
);
// 노면(노견 포함): 위치 안내 모식도라 횡단경사는 반영하지 않고 수평으로 그린다(D-7).
const roadLeft = 95;
const roadRight = 205;
const shoulderL = 108; // 노견 좌 경계
const shoulderR = 192; // 노견 우 경계
const roadY = 128;
svg.append(
node(
"polyline",
{ points: `${roadLeft},${roadY} ${roadRight},${roadY}`, fill: "none" },
"b06-diag__road",
),
);
// 노견 경계 눈금(좌/우)
svg.append(
node("line", { x1: shoulderL, y1: roadY - 5, x2: shoulderL, y2: roadY + 5 }, "b06-diag__tick"),
node("line", { x1: shoulderR, y1: roadY - 5, x2: shoulderR, y2: roadY + 5 }, "b06-diag__tick"),
);
// 중심선(계획고): 노면 중앙 수직 파선. 라벨 행(y=104)은 비워 노폭 라벨과 겹치지 않게 끊는다.
const centerX = (roadLeft + roadRight) / 2;
svg.append(
node("line", { x1: centerX, y1: 38, x2: centerX, y2: 96 }, "b06-diag__center"),
node("line", { x1: centerX, y1: 112, x2: centerX, y2: 162 }, "b06-diag__center"),
);
// 측구(절토측=좌): 노면 좌끝에서 아래로 파는 사다리꼴.
// 깊이는 기존 16 대비 약 60%(10)로 낮추고, 좌·우 벽 기울기를 4.5로 동일하게 맞춰
// 상단(80~95)과 하단(84.5~90.5)의 중심이 모두 87.5가 되도록 좌우 대칭을 유지한다.
const ditchDepth = 10;
const ditchWallInset = 4.5;
svg.append(
node(
"polygon",
{
points: `${roadLeft},${roadY} ${roadLeft - ditchWallInset},${roadY + ditchDepth} ${roadLeft - 15 + ditchWallInset},${roadY + ditchDepth} ${roadLeft - 15},${roadY}`,
},
"b06-diag__ditch",
),
);
// 절토 사면(좌): 측구 바깥에서 원지반까지 상향.
svg.append(node("line", { x1: roadLeft - 15, y1: roadY, x2: 26, y2: 66 }, "b06-diag__cut"));
// 성토 사면(우): 노면 우끝에서 원지반까지 하향.
svg.append(node("line", { x1: roadRight, y1: roadY, x2: 278, y2: 210 }, "b06-diag__fill"));
// 노견 좌 · 노폭 · 노견 우를 한 행(y=104)에 나란히 둔다. 노견 라벨은 바깥쪽 끝이 아니라
// 중앙 노폭 라벨 옆까지 안쪽으로 당겨 세 라벨이 중심(150) 기준 대칭이 되게 한다.
const labelLineY = 104;
svg.append(
text(centerX - 22, labelLineY, L("B06_Std_Diagram_ShoulderL"), "b06-diag__label-sm", "end"),
text(centerX, labelLineY, L("B06_Std_Diagram_Road"), "b06-diag__label"),
text(centerX + 22, labelLineY, L("B06_Std_Diagram_ShoulderR"), "b06-diag__label-sm", "start"),
);
// 나머지 라벨.
svg.append(
text(centerX, 30, L("B06_Std_Diagram_Center"), "b06-diag__label"),
text(roadLeft - 23, roadY + 24, L("B06_Std_Diagram_Ditch"), "b06-diag__label-sm", "middle"),
text(46, 54, L("B06_Std_Diagram_Cut"), "b06-diag__label-sm", "middle"),
text(252, 196, L("B06_Std_Diagram_Fill"), "b06-diag__label-sm", "middle"),
);
wrap.append(svg);
const caption = document.createElement("p");
caption.className = "b06-std__diagram-caption";
caption.textContent = L("B06_Std_Diagram_Caption");
wrap.append(caption);
return wrap;
}