- 헬퍼 동작 그대로(풀이 함수 본문은 옮겨 담음) · 제품 코드 안 고침 - 확인: 이 묶음 헬퍼를 쓰는 시험 233 개 전 233 통과 → 후 233 통과 (시험별 junit 대조 · 어긋남 0) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
102 lines
3.8 KiB
JavaScript
102 lines
3.8 KiB
JavaScript
/* 409-2 평면 마커 고름 풂(b05-plan · 값 없음) = 좌측 폼 · 목록 강조도 풂 — 진짜 `design_selection` ·
|
|
* `design_pick_escape` · `design_pick_profile` 을 Node 로 돌림. 종단도 · 폼 · 오른쪽 횡단 판은 흉내.
|
|
* 표준출력 JSON 한 벌 · 짝 = test_409_mark_top_deselect.py.
|
|
*/
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const ROOT = path.join(__dirname, "..", "..");
|
|
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
|
|
|
|
function loadTs(file, stubs = {}) {
|
|
return makeLoader({
|
|
root: ROOT,
|
|
cache: false,
|
|
requireFor: (full) => (request) => {
|
|
if (stubs[request]) return stubs[request];
|
|
throw new Error(`stub 없음: ${request}`);
|
|
},
|
|
}).loadTs(path.join(ROOT, file));
|
|
}
|
|
|
|
globalThis.window = { addEventListener() {}, removeEventListener() {} };
|
|
globalThis.document = { querySelector: () => null };
|
|
|
|
const store = new Map();
|
|
const DSel = loadTs("A00_Common/design/design_selection.ts", {
|
|
"../../common_util/common_util_pipe_match": { PIPE_MATCH_M: 0.51 }, // 찾는 거리 정의 자리(472-6)
|
|
"../b_page_state": {
|
|
readState: (key, pid) => store.get(`${key}:${pid}`) ?? null,
|
|
writeState: (key, value, pid) => store.set(`${key}:${pid}`, value),
|
|
},
|
|
});
|
|
const ESC = loadTs("A00_Common/design/design_pick_escape.ts", { "./design_selection": DSel });
|
|
const IRR = { irregularStationId: (id) => `irregular:${id}`, isPipeStation: () => true };
|
|
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)}` },
|
|
"./design_pick_escape": ESC,
|
|
"../../B05_Profile/B05_Profile_UI_Selection": SY,
|
|
"../../B05_Profile/B05_Profile_UI_IrregularStations": IRR,
|
|
});
|
|
|
|
const PID = "p409";
|
|
const sel = (chainageM, structureId, from) =>
|
|
DSel.selectDesign(PID, chainageM === null ? DSel.NO_SELECTION : { chainageM, structureId }, {
|
|
from,
|
|
});
|
|
|
|
/* 폼 — 관 폼을 닫으면 진짜 폼처럼 관 고름도 비움(`resetForm` → onPipeSelect(null) → b05 풂) */
|
|
const form = { open: null, resets: 0 };
|
|
const profile = { structure: null };
|
|
PP.bindProfilePick(
|
|
PID,
|
|
{
|
|
profile: {
|
|
setSelectedStation: () => (profile.structure = null),
|
|
setSelectedStructure: (id) => (profile.structure = id),
|
|
},
|
|
form: {
|
|
hasSelection: () => form.open !== null,
|
|
selectById: () => {
|
|
const wasPipe = form.open === "pipe";
|
|
form.open = null;
|
|
form.resets += 1;
|
|
if (wasPipe) sel(null, null, "b05");
|
|
},
|
|
},
|
|
},
|
|
{ visible: () => true, onDispose() {} },
|
|
{ irregular: () => [], pipes: () => [{ chainage_m: 80.17 }], sections: () => [] },
|
|
);
|
|
/* 오른쪽 횡단 판 흉내 — 받은 알림(낸 쪽) */
|
|
const crossSaw = [];
|
|
DSel.subscribeSelection(PID, (selection, from) => crossSaw.push([selection.chainageM, from]));
|
|
|
|
const out = {};
|
|
// 관 마커 고름 → 폼 열림 → 평면 마커 고름 풂
|
|
sel(80.17, null, "b05");
|
|
form.open = "pipe";
|
|
crossSaw.length = 0;
|
|
sel(null, null, ESC.PLAN_PICK_FROM);
|
|
out.pipeRelease = { form: { ...form }, crossSaw: [...crossSaw], session: DSel.readSelection(PID) };
|
|
// 구조물 고름 → 폼 → 풂
|
|
sel(40, "A", "b05");
|
|
form.open = "A";
|
|
sel(null, null, ESC.PLAN_PICK_FROM);
|
|
out.structureRelease = { form: { ...form }, pill: profile.structure };
|
|
// 평면 눈금 클릭(값 있음 · b05-plan) = 폼 안 닫음(옛 그대로)
|
|
form.open = "A";
|
|
sel(20, null, ESC.PLAN_PICK_FROM);
|
|
out.tickKeepsForm = form.open;
|
|
// 폼 없음 = 안 부름
|
|
form.open = null;
|
|
const resets = form.resets;
|
|
sel(null, null, ESC.PLAN_PICK_FROM);
|
|
out.noFormNoReset = form.resets - resets;
|
|
out.planName = ESC.PLAN_PICK_FROM;
|
|
process.stdout.write(JSON.stringify(out));
|