/* 472 덧 헬퍼 — B05 보기 관 지움 ↶ 가 반쪽만 돌아오던 흠 · 종단 ↶ 단추가 다시 그리기 전까지 꺼져 있던 흠. * 실제 TS(`B05_Profile_UI_Profile_Panel_Tools` · `B05_Profile_UI_Profile_History` · 가게)를 그 자리에서 * 트랜스파일해 Node 로 돌림 · 배수 판은 흉내(받은 관 목록만 적음) · 결과 = 표준출력 JSON. 짝 = `test_472_d_b05_pipe_undo.py`. */ const fs = require("fs"); const path = require("path"); const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const CATALOG = require("./helper_322_catalog_module.cjs"); const ROOT = path.join(__dirname, "..", ".."); const listeners = {}; 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(), }; }; globalThis.sessionStorage = storage(); globalThis.localStorage = storage(); globalThis.window = { sessionStorage: globalThis.sessionStorage, localStorage: globalThis.localStorage, addEventListener: (type, fn) => (listeners[type] ??= new Set()).add(fn), removeEventListener: (type, fn) => listeners[type]?.delete(fn), setTimeout: () => 0, clearTimeout: () => undefined, }; globalThis.document = { addEventListener: () => undefined, querySelector: () => null }; // 도구줄 · 자유지정 그림은 흉내 — ↶ ↷ 켜짐 맞춤 부름 수만 셈 let synced = 0; const STUBS = { "./B05_Profile_UI_Profile_Tools": { createProfileTools: () => ({ mode: () => "none", clear: () => undefined, syncHistory: () => void (synced += 1), }), }, "../A00_Common/design/logic/design_profile_free": { createFreeDraw: () => ({ key: () => false, hint: () => "" }), }, "../A00_Common/design/design_profile_free_view": { createFreeView: () => ({ mount: () => undefined, redraw: () => undefined }), }, // 계산 자리 「서버」 길(511-A) — 판 both 그대로 "../A00_Common/design/design_calc_sites": { calcOnServerNow: () => false }, "../A00_Common/design/design_calc_server": { calcChecked: (_key, _id, fn, args) => fn(...args), calcOnServerOnly: async () => undefined, trialRequest: () => ({}), }, }; const { loadTs } = makeLoader({ root: ROOT, requireFor: (full) => (request) => (CATALOG.isCatalogRequest(request) ? CATALOG : null) ?? STUBS[request] ?? (request.startsWith(".") ? loadTs(path.join(path.dirname(full), `${request}.ts`)) : require(request)), }); const store = loadTs(path.join(ROOT, "A00_Common", "design", "design_store.ts")); const tools = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Profile_Panel_Tools.ts")); const P = "p472d"; localStorage.setItem("frd_current_project_id", P); store.pinDraftProject(P); const shop = store.useDesignStore(P, null); // 배수 판 흉내 — 판이 저장분을 읽기 전(빈 목록)에 사진첩이 섬 · 관 하나(351) 프로젝트 let shown = []; const given = []; const panel = tools.createPanelTools({ root: { isConnected: true }, base: () => ({}), alignment: () => null, edits: () => ({}), savedRadii: () => ({}), applyEdits: () => undefined, selectedStationId: () => null, irregularStations: () => [], stationIdOf: (s) => s.id, moveStation: () => undefined, drainage: { pipeChainages: () => shown, // 옛 「처음 본 목록」 길이 부름 setPipeChainages: (chainages) => given.push(chainages), }, restore: () => undefined, restoreSaved: () => undefined, canRestoreSaved: () => false, refresh: () => undefined, }); shown = [351]; // 판이 저장분을 읽음 const touch = () => listeners.keydown?.forEach((fn) => fn({ key: "a", target: null })); // 종단 우클릭 [배관 삭제] — 판이 관을 빼고 가게 관 초안을 빈 목록으로 씀 touch(); const syncedBefore = synced; shown = []; shop.set("pipes", []); panel.history.record(); const afterDelete = { canUndo: panel.history.canUndo(), synced: synced - syncedBefore }; panel.history.undo(); const undo = { given: given.at(-1), draft: shop.get("pipes") ?? null }; panel.history.redo(); const redo = { given: given.at(-1), draft: shop.get("pipes") ?? null }; panel.history.undo(); const undo2 = { given: given.at(-1) }; process.stdout.write(JSON.stringify({ afterDelete, undo, redo, undo2 }));