Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7
148 lines
5.5 KiB
TypeScript
148 lines
5.5 KiB
TypeScript
/* =============================================================================
|
|
* design_structure_guard.ts
|
|
* 흙막이 공통 양식 — 배관(표 01) · 박스암거(표 02) · 세월교(표 04)가 같은 칸을 씀(PLAN 65-2).
|
|
*
|
|
* · 흙막이 = 형태 6 · 길이 · 높이 · 기준측점 전 · 후(길이 = 전 + 후 맞물림)
|
|
* · 필수 보호공(유입 · 유출)은 구조 갈래마다 저장 키(`{side}_revet_*` 옛 키) · 선택 흙막이 · 도수로/돌붙임은
|
|
* 인스턴스 키(`soil_add_{n}_*` · `chute_add_{n}_*`)
|
|
* import = 꼴만 — 시험이 이 폴더 파일만 옮겨 돌림.
|
|
* ========================================================================== */
|
|
|
|
import type { SpecChoice, SpecContainer, SpecItem } from "./design_structure_spec";
|
|
|
|
export const SOIL_FORMS: SpecChoice[] = [
|
|
{ value: "돌쌓기(찰)", label: "돌 쌓기(찰)" },
|
|
{ value: "돌쌓기(메)", label: "돌 쌓기(메)" },
|
|
{ value: "콘크리트", label: "콘크리트" },
|
|
{ value: "돌망태", label: "돌망태" },
|
|
{ value: "통나무·목재틀", label: "통나무/목재틀" },
|
|
{ value: "바자", label: "바자" },
|
|
];
|
|
|
|
/** 흙막이 기본값(54-36 · 사면안정 흙막이 정의 기본값과 같음). */
|
|
const SOIL_DEFAULTS: Record<string, string> = {
|
|
form: "돌쌓기(찰)",
|
|
length: "10",
|
|
height: "1.5",
|
|
before: "5",
|
|
after: "5",
|
|
};
|
|
|
|
/** 형태 · 길이 · 높이 · 전 · 후 — 필수 보호공은 구조 갈래마다 옛 키(`keys`) · 선택 흙막이는 인스턴스 키.
|
|
* `forms` = 갈래별 형태 선택지(배관 집수정 등) · `defaults` = 새 상자 · 흙막이를 고를 때 칸에 실제 값. */
|
|
export function guardItems(
|
|
keys?: Record<string, Record<string, string>>,
|
|
forms?: Record<string, SpecChoice[]>,
|
|
defaults = !keys,
|
|
): SpecItem[] {
|
|
const by = (field: string, choices?: Record<string, SpecChoice[]>) =>
|
|
keys
|
|
? {
|
|
item: "structure",
|
|
map: Object.fromEntries(
|
|
// 키 없는 갈래 = 그 구조에 없는 칸(집수정 길이 · 전 · 후) — 가림
|
|
Object.entries(keys)
|
|
.filter(([, k]) => k[field])
|
|
.map(([structure, k]) => [
|
|
structure,
|
|
{ key: k[field], choices: choices?.[structure] },
|
|
]),
|
|
),
|
|
}
|
|
: undefined;
|
|
const items: SpecItem[] = [
|
|
{ id: "form", label: "형태", kind: "select", choices: SOIL_FORMS, by: by("form", forms) },
|
|
{ id: "length", label: "길이 (m)", kind: "number", split: "length", step: 1, by: by("length") },
|
|
{ id: "height", label: "높이 (m)", kind: "number", step: 0.1, by: by("height") },
|
|
{
|
|
id: "before",
|
|
label: "기준측점 전 (m)",
|
|
kind: "number",
|
|
split: "before",
|
|
step: 0.5,
|
|
by: by("before"),
|
|
},
|
|
{
|
|
id: "after",
|
|
label: "기준측점 후 (m)",
|
|
kind: "number",
|
|
split: "after",
|
|
step: 0.5,
|
|
by: by("after"),
|
|
},
|
|
];
|
|
return defaults ? items.map((item) => ({ ...item, default: SOIL_DEFAULTS[item.id] })) : items;
|
|
}
|
|
|
|
export const revetKeys = (side: "inlet" | "outlet"): Record<string, string> => ({
|
|
form: `${side}_revet_form`,
|
|
length: `${side}_revet_length_m`,
|
|
height: `${side}_revet_height_m`,
|
|
before: `${side}_revet_before_m`,
|
|
after: `${side}_revet_after_m`,
|
|
});
|
|
|
|
/** 세월교 · 박스 유입 · 유출 흙막이 칸(79-7) — 높이 빈 칸 = 자동(`heightHint` · 횡단도가 셈) ·
|
|
* 유입만 절토부 앞 수평공간 칸(`inlet_revet_berm_m` · 유출은 없음 · 89-4)을 더함. */
|
|
export function bodyGuardItems(side: "inlet" | "outlet", heightHint: string): SpecItem[] {
|
|
const items = guardItems({ 흙막이: revetKeys(side) }, undefined, true).map((item) =>
|
|
item.id === "height" ? { ...item, default: undefined, hint: heightHint } : item,
|
|
);
|
|
if (side === "outlet") return items;
|
|
const berm: SpecItem = {
|
|
id: "berm",
|
|
label: "수평공간 (m)",
|
|
kind: "number",
|
|
step: 0.1,
|
|
default: "1",
|
|
by: { item: "structure", map: { 흙막이: { key: `${side}_revet_berm_m` } } },
|
|
};
|
|
return [...items, berm];
|
|
}
|
|
|
|
/** 추가 흙막이(선택 · 여러 개) — 사면안정 흙막이(표 09 · 54-26)와 같은 칸 · 구조 고르기 없음(54-30). */
|
|
export const SOIL_ADD: SpecContainer = {
|
|
id: "soil_add",
|
|
title: "흙막이",
|
|
required: false,
|
|
prefix: "soil_add",
|
|
link: "gsoiladd",
|
|
items: guardItems(),
|
|
};
|
|
|
|
/** 도수로/돌붙임 칸 — 구조 · 두께(cm · 새 상자 30 · 90-2 사용자 확정) · 붙임 형식 · 면적(98-3) · 물넘이 포장(`ford_chute`)도 같은 칸. */
|
|
export const CHUTE_ITEMS: SpecItem[] = [
|
|
{
|
|
id: "structure",
|
|
label: "구조",
|
|
kind: "select",
|
|
choices: [
|
|
{ value: "도수로", label: "도수로" },
|
|
{ value: "돌붙임", label: "돌붙임" },
|
|
],
|
|
},
|
|
{ id: "thickness", label: "두께 (cm)", kind: "number", step: 1, default: "30" },
|
|
// 붙임 형식 · 면적(98-3) — 빈칸이면 B08 구조물 집계표에 안 셈(설계자가 넣음)
|
|
{
|
|
id: "bond",
|
|
label: "붙임 형식",
|
|
kind: "select",
|
|
choices: [
|
|
{ value: "찰붙임", label: "찰붙임" },
|
|
{ value: "메붙임", label: "메붙임" },
|
|
],
|
|
},
|
|
{ id: "area", label: "면적 (㎡)", kind: "number", step: 0.1 },
|
|
];
|
|
|
|
/** 도수로/돌붙임(선택 · 하나만 · 54-48) — 옛 둘 이상은 보이되 [추가]만 숨김. */
|
|
export const CHUTE_ADD: SpecContainer = {
|
|
id: "chute_add",
|
|
title: "도수로/돌붙임",
|
|
required: false,
|
|
prefix: "chute_add",
|
|
link: "gchuteadd",
|
|
max: 1,
|
|
items: CHUTE_ITEMS,
|
|
};
|