- 종단 보기 구독이 배수유역도 관 마커 · 유역 · 마름모까지 알림 없이 칠함 · 재계산 뒤 다시 얹음 - 지도 고름 · 목록 관 고름 · 목록 다시 누름도 고름 한 칸에 적고 칠하기는 구독 몫 - 목록 관 줄 폭 PIPE_MATCH_M · 조금 옮겨진 관도 고름 따라감 · 저장 뒤 목록 주입이 관 폼 안 닫음 - design_pick_escape — Esc = 고름 한 칸 비움 → 종단 · 3D · 지도 · 폼 · 횡단 카드 · 범위 · 형상 모두 풂 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STqEqztUthVFBmEP18wBSz
121 lines
4.1 KiB
JavaScript
121 lines
4.1 KiB
JavaScript
/* 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_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));
|