/* 233-1 종단도 강조 = 고름 한 칸에서 파생 — 진짜 `design_pick_profile` · `design_selection` · * `graphTargetAt`(B05_Profile_UI_Selection) 를 Node 로 돌림. 종단도는 고른 측점 · 알약 두 칸만 흉내. * 표준출력 JSON 한 벌 · 짝 = test_233_1_profile_pick.py. */ const fs = require("fs"); const path = require("path"); const ROOT = path.join(__dirname, "..", ".."); const ts = require(path.join(ROOT, "config", "node_modules", "typescript")); function loadTs(file, stubs = {}) { const js = ts.transpileModule(fs.readFileSync(path.join(ROOT, file), "utf8"), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, }).outputText; const box = { exports: {} }; const localRequire = (request) => { if (stubs[request]) return stubs[request]; throw new Error(`stub 없음: ${request}`); }; new Function("exports", "module", "require", js)(box.exports, box, localRequire); return box.exports; } const store = new Map(); const DSel = loadTs("A00_Common/design/design_selection.ts", { "../b_page_state": { readState: (key, pid) => store.get(`${key}:${pid}`) ?? null, writeState: (key, value, pid) => store.set(`${key}:${pid}`, value), }, }); globalThis.window = { addEventListener() {}, removeEventListener() {} }; const ESC = loadTs("A00_Common/design/design_pick_escape.ts", { "./design_selection": DSel }); const IRR = { irregularStationId: (id) => `irregular:${id}`, isPipeStation: (s) => s.origin === "pipe", }; const SY = loadTs("B05_Profile/B05_Profile_UI_Selection.ts", { "../A00_Common/design/design_selection": DSel, "./B05_Profile_UI_IrregularStations": IRR, }); const PP = loadTs("A00_Common/design/design_pick_profile.ts", { "./design_selection": DSel, "./design_pipe_ids": { pipeIdAt: (at) => `pipe-${at.toFixed(2)}` }, // 프로젝트 없음 = 옛 자리 이름(323-5) "./design_pick_escape": ESC, "../../B05_Profile/B05_Profile_UI_Selection": SY, "../../B05_Profile/B05_Profile_UI_IrregularStations": IRR, }); const PID = "p233"; const sections = [80, 100, 120, 140, 300].map((at) => ({ station_id: `s${at}`, chainage_m: at })); let pipes = [{ chainage_m: 80.17 }, { chainage_m: 300.4 }]; const irregular = [ { id: "p80", chainage_m: 80.17, origin: "pipe" }, { id: "sign", chainage_m: 127.86, origin: "user" }, ]; /* 종단도 흉내 — 고른 측점 · 알약 */ const profile = { station: null, structure: null, paints: 0 }; const target = { setSelectedStation: (id) => { profile.station = id; profile.structure = null; profile.paints += 1; }, setSelectedStructure: (id) => { profile.structure = id; profile.station = null; profile.paints += 1; }, }; let visible = true; const disposers = []; const pick = PP.bindProfilePick( PID, { profile: target }, { visible: () => visible, onDispose: (fn) => disposers.push(fn) }, { irregular: () => irregular, pipes: () => pipes, sections: () => sections }, ); const snap = () => ({ station: profile.station, structure: profile.structure }); const sel = (chainageM, structureId = null) => DSel.selectDesign(PID, chainageM === null ? DSel.NO_SELECTION : { chainageM, structureId }); const out = {}; sel(120); out.card = snap(); sel(127.86); out.irregularSign = snap(); sel(80); out.card80 = snap(); // 관 80.17 옆 카드 80 = 카드 선(관 아님) sel(80.17); out.pipe80 = snap(); sel(300.2); out.pipePill = snap(); pipes = [{ chainage_m: 80.17 }, { chainage_m: 300.45 }]; // 관이 옮겨짐 pick.paint(); out.pipeMoved = snap(); sel(100, "wall"); out.structure = snap(); // 다른 길이 강조를 끔(저장 뒤 관 폼 닫힘 · 목록 다시 세움) → 값은 그대로 → 다시 얹음 target.setSelectedStructure(null); out.clearedByOther = snap(); pick.paint(); out.repainted = snap(); // 숨은 보기는 안 그림 · 보이면 다시 얹음 visible = false; sel(140); out.hidden = snap(); visible = true; pick.paint(); out.shownAgain = snap(); // 풂(값 비움) = 선 · 알약 모두 끔 sel(null); out.released = snap(); // 보기를 떠나면 구독 끊음 disposers.forEach((fn) => fn()); const before = profile.paints; sel(120); out.paintsAfterDispose = profile.paints - before; out.disposers = disposers.length; process.stdout.write(JSON.stringify(out));