/* ============================================================================= * M02_SO_Def_Add.ts * 종류 더하기(PLAN 323-7) — 본보기(구조물 정본 원본 종류)를 그대로 복사한 새 종류. * * 키 자동(`{본보기}_xxxxxx` · 만든 뒤 안 바뀜) · 이름 「{본보기} 2」(겹치면 3 …) · 군 · 자리꼴 · 옵션 · 표시 · 그룹 · * 배치 · 규칙 · 종류 덧칸(동작 · 이름 표) · 반영 그대로 · `종류.{새}.본보기 = 원본` — 구조물 표가 본보기 처음값을 * 이어받고(`resolveCatalog` · 일곱 갈래 = 목록 · 횡단도 · 카드이름 · 형상 · 형상칸 · 3D · 자리꼴), 손코딩 동작 · * 명세도 본보기 키로 고름(`baseType`). 관 지점 정본 종류는 본보기에서 뺌(관 시설 폼 · 정본 목록이 따로). * ========================================================================== */ import { clone, newKey, type StructDef } from "./M02_SO_Def_Model"; /** 본보기로 고를 수 있는 종류 — 구조물 정본 · 원본(본보기 아님) · [키, 이름] (정의 차례). */ export const templates = (def: StructDef): Array<[string, string]> => def.types .filter((t) => !t.managed_by && !def.종류[t.type_id]?.본보기) .map((t) => [t.type_id, t.name] as [string, string]); /** 본보기를 복사해 그 뒤에 새 종류를 끼움 — 새 키(못 하면 null). */ export function addFromTemplate(def: StructDef, sourceId: string): string | null { const index = def.types.findIndex((t) => t.type_id === sourceId); const src = def.types[index]; if (!src || src.managed_by || def.종류[sourceId]?.본보기) return null; const key = newKey( `${sourceId}_`, def.types.map((t) => t.type_id), ); const names = new Set(def.types.map((t) => t.name)); let n = 2; while (names.has(`${src.name} ${n}`)) n += 1; const copy = clone(src); copy.type_id = key; copy.name = `${src.name} ${n}`; delete copy.drawing_views; // 안 읽는 칸(323-7) def.types.splice(index + 1, 0, copy); def.종류[key] = { ...clone(def.종류[sourceId] ?? {}), 본보기: sourceId }; for (const table of [def.표시, def.그룹, def.배치] as Array>) if (table[sourceId] !== undefined) table[key] = clone(table[sourceId]); def.규칙.push( ...def.규칙.filter((r) => r.종류 === sourceId).map((r) => ({ ...clone(r), 종류: key })), ); const reflect = (def as { 반영?: Record }).반영; if (reflect?.[sourceId] !== undefined) reflect[key] = clone(reflect[sourceId]); return key; }