/* 472-5 5-D 헬퍼 — node helper_472_5d_adjust.mjs <묶음.mjs> · 표준출력 JSON. * 조정창(반폭 · 흙막이 4축 · 유입 형식 · 연동 · 단 수 · 세월교)을 고침 → ↶ → 다른 측점을 고침 → ↶ ↷ — * 세션 칸 · 캐시 설계 칸 · 조정창 읽기 · 저장 묶음이 되돌린 값을 따르는가(옛 코드 = 메모리 맵이 옛 값을 쥠 · N5). */ import { pathToFileURL } from "node:url"; const storage = () => { const m = new Map(); return { getItem: (k) => (m.has(k) ? m.get(k) : null), setItem: (k, v) => m.set(k, String(v)), removeItem: (k) => m.delete(k), key: (i) => [...m.keys()][i] ?? null, get length() { return m.size; }, clear: () => m.clear(), }; }; const any = new Proxy(function () {}, { get: (_t, k) => (k === Symbol.toPrimitive ? () => 0 : any), apply: () => any, construct: () => any, }); globalThis.window = { sessionStorage: storage(), localStorage: storage() }; // 손길 듣기 없음 = 열 때 규칙 꺼짐 globalThis.sessionStorage = window.sessionStorage; globalThis.localStorage = window.localStorage; globalThis.document = any; const m = await import(pathToFileURL(process.argv[2]).href); const P = "p472fived"; const R = 7; localStorage.setItem("frd_current_project_id", P); const NAMES = ["crossw", "revetx", "inletstruct", "revetlink", "extrawall", "fordadjust"]; const SAVED_OUTLET = { x: 2, d: null, h: null, m: null }; const sections = [100, 120, 140].map((chainage_m) => ({ chainage_m, station_id: `s${chainage_m}`, design: chainage_m === 100 ? { revet_adjust: { outlet: { ...SAVED_OUTLET } } } : {}, })); const detail = { cross_sections: sections }; const c = m.createStationControls({ sessionKey: (kind) => m.stateKey(kind, P, R), refreshCard: () => undefined, detail: () => detail, crossHalfWidth: () => undefined, sampledHalfWidth: () => 20, ensureSampledWidth: async () => true, projectId: () => P, }); c.load(); const cells = () => Object.fromEntries(NAMES.map((n) => [n, m.readState(n, P, R)])); const designs = () => sections.map((s) => JSON.parse(JSON.stringify(s.design))); const reads = () => ({ inlet: c.revetOffset.adjustFor(sections[0], "inlet"), outlet: c.revetOffset.adjustFor(sections[0], "outlet"), width100: c.stationWidth.widthFor(sections[0]) ?? null, struct100: c.inletStructure.valueFor(sections[0]), linked120: c.revetLink.linkedFor(sections[1]), extra120: c.extraWalls.countFor(sections[1], "outlet"), ford140: c.ford.adjustFor(140).inlet.lateralM, }); const out = {}; const history = m.createProfileHistory(() => undefined, 100); // 조작 A — 측점 100 · 120 · 140 c.revetOffset.update(100, "inlet", { x: 3 }); c.stationWidth.request(100, 6); c.inletStructure.set(100, "L"); c.revetLink.setLinked(120, false); c.extraWalls.setCount(120, 2, "outlet"); c.ford.update(140, "inlet", { lateralM: 2 }); history.record(); out.afterA = cells(); out.readsA = reads(); history.undo(); // ↶ = 세션 칸을 조작 전으로 되씀(가게 · 조정창을 안 거침) out.afterUndo = cells(); m.withDraftAdjusts(detail, P, R); // 상세 가게가 읽을 때 얹기(↶ 훅 · 보기 전환 · 다시 그림 길) out.designsUndo = designs(); out.readsUndo = reads(); // 조작 B — 다른 측점 · 다른 역할(옛 코드 = 메모리 맵이 A 값을 쥐고 통째로 다시 씀) c.revetOffset.update(100, "outlet", { x: 1 }); c.stationWidth.request(120, 8); c.inletStructure.set(120, "I"); c.revetLink.setLinked(140, false); c.extraWalls.setCount(140, 1, "outlet"); c.ford.update(100, "outlet", { lateralM: 1 }); out.afterB = cells(); out.payloadB = { revet: Object.fromEntries(c.revetAdjustsByChainage()), link: Object.fromEntries(c.linkFlagsByChainage()), extra: Object.fromEntries(c.extraCountsByChainage()), ford: [...c.fordAdjustsByChainage().keys()], }; history.record(); history.undo(); out.afterUndo2 = cells(); history.redo(); // ↷ = B 그대로 out.afterRedo = cells(); m.withDraftAdjusts(detail, P, R); out.designsRedo = designs(); out.readsRedo = reads(); process.stdout.write(JSON.stringify(out));