- `design_pipe_ids.ts` — 장부(세션 pipe-ids) · pipe-s{차례} · 자리 → id(찾는 거리 안 가장 가까운 것) · followMovedPipe 가 id 를 새 자리로(고름 id 그대로 · 순환 import 없게 design_selection 에서 옮김) · 설계 페이지가 프로젝트를 정함(usePipeIds) · 자리 이름 만들기 열 곳 · 되읽기 둘 걷음 · 측점 계획 주인 = 세션 id(withPipeIds)
- `design_pick_match.ts` — pickLights(① id ② 같은 자리 ③ 고른 부분) · paintPicked(카드 통째 형상 · 부분 · 관 계열 · 포장층은 제 손잡이) · tagShape — 관 세트 벽 · 집수정 · 관 · 세월교 측벽 · 몸체 · BOX 끝 · C군 벽 · 물넘이 콘크리트에 신원표 · 형상 판정면은 통째 형상 · 콘크리트만
- 3D — 부재 맞춤 = pickLights(옛 0.01 걷음) · C군 벽 솔리드 = 구조물 id(덮는 측점 어디서 골라도 한 번 스윕한 벽이 켜짐)
- 322-0 이 깬 것 고침 — 노면공 흐름 도움 파일(165 · 231-1) 정의 판 확인 흉내 · design_view_profile 700줄(322-0 이 704)
- 시험: test_323_5_pick(세션 id · 옮김 · 강조 규칙 · 칠하기) · 옛 시험 도움 파일 흉내 · 기대 글 고침
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
95 lines
4.2 KiB
JavaScript
95 lines
4.2 KiB
JavaScript
/* PLAN 323-5 고름 한 칸 헬퍼 — 진짜 `design_pipe_ids.ts`(관 세션 id) · `design_selection.ts`(고름 · 관 옮김 따라가기) ·
|
|
* `design_pick_match.ts`(고름 강조 한 규칙)를 그 자리에서 트랜스파일해 Node 로 돌림(세션만 흉내) · 결과 = 표준출력 JSON.
|
|
* 짝 = `test_323_5_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"));
|
|
|
|
const memory = new Map();
|
|
const store = {
|
|
getItem: (k) => (memory.has(k) ? memory.get(k) : null),
|
|
setItem: (k, v) => memory.set(k, String(v)),
|
|
removeItem: (k) => memory.delete(k),
|
|
key: (i) => [...memory.keys()][i] ?? null,
|
|
get length() {
|
|
return memory.size;
|
|
},
|
|
};
|
|
globalThis.window = { sessionStorage: store, localStorage: store, addEventListener: () => {} };
|
|
globalThis.sessionStorage = store;
|
|
globalThis.localStorage = store;
|
|
|
|
const cache = new Map();
|
|
function load(file) {
|
|
const full = path.resolve(file);
|
|
if (cache.has(full)) return cache.get(full);
|
|
const js = ts.transpileModule(fs.readFileSync(full, "utf8"), {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
|
|
}).outputText;
|
|
const box = { exports: {} };
|
|
cache.set(full, box.exports);
|
|
const need = (spec) => load(path.join(path.dirname(full), `${spec}.ts`));
|
|
new Function("exports", "module", "require", js)(box.exports, box, need);
|
|
return box.exports;
|
|
}
|
|
const D = (name) => path.join(ROOT, "A00_Common", "design", `${name}.ts`);
|
|
const ids = load(D("design_pipe_ids"));
|
|
const sel = load(D("design_selection"));
|
|
const match = load(D("design_pick_match"));
|
|
|
|
const out = {};
|
|
// ① 관 세션 id — 자리마다 차례 · 같은 자리(0.51 안)면 같은 id · 프로젝트 없으면 옛 자리 이름
|
|
ids.usePipeIds("P");
|
|
const a = ids.pipeIdAt(85.05);
|
|
out.ids = [a, ids.pipeIdAt(85), ids.pipeIdAt(173), ids.pipeChainageOf(a)];
|
|
ids.usePipeIds(null);
|
|
out.legacy = [ids.pipeIdAt(85), ids.pipeChainageOf("pipe-85.00"), ids.pipeChainageOf("w1")];
|
|
ids.usePipeIds("P");
|
|
// ② 옮겨도 id 그대로 — 고름도 자리만 새로(부재키 그대로) · 새 자리 id = 그 id
|
|
sel.selectDesign("P", { chainageM: 85.05, structureId: a }, { partKey: "inlet" });
|
|
ids.followMovedPipe("P", 85.05, 90);
|
|
out.moved = [sel.readSelection("P"), ids.pipeIdAt(90), ids.pipeChainageOf(a)];
|
|
// 다른 것을 골랐으면 고름 그대로 · 관 id 는 따라감
|
|
const b = ids.pipeIdAt(173);
|
|
sel.selectDesign("P", { chainageM: 300, structureId: "w1" });
|
|
ids.followMovedPipe("P", 173, 180);
|
|
out.other = [sel.readSelection("P"), ids.pipeIdAt(180) === b];
|
|
// ③ 강조 한 규칙
|
|
const L = match.pickLights;
|
|
out.lights = {
|
|
idOverPlace: L({ chainageM: 93, structureId: "w1" }, { chainageM: 101, structureId: "w1" }),
|
|
idDiffers: L({ chainageM: 101, structureId: "w2" }, { chainageM: 101, structureId: "w1" }),
|
|
placeNear: L({ chainageM: 85, structureId: null }, { chainageM: 85.4 }),
|
|
placeFar: L({ chainageM: 85, structureId: null }, { chainageM: 85.6 }),
|
|
partOnly: L({ chainageM: 85, partKey: "inlet" }, { chainageM: 85, part: "outlet" }),
|
|
partSame: L({ chainageM: 85, partKey: "inlet" }, { chainageM: 85, part: "inlet" }),
|
|
partNoTag: L({ chainageM: 85, partKey: "inlet" }, { chainageM: 85 }),
|
|
wholePick: L({ chainageM: 85 }, { chainageM: 85, part: "outlet" }),
|
|
none: L(null, { chainageM: 85 }),
|
|
};
|
|
// ④ 카드 통째 형상 칠하기 — 부분 · 관 계열 · 포장층은 제 손잡이 몫
|
|
class Shape {
|
|
constructor(attrs) {
|
|
this.attrs = attrs;
|
|
this.on = false;
|
|
this.classList = { toggle: (_c, v) => (this.on = v) };
|
|
}
|
|
getAttribute(k) {
|
|
return this.attrs[k] ?? null;
|
|
}
|
|
}
|
|
const shapes = [
|
|
new Shape({ "data-structure-id": "ud-1" }),
|
|
new Shape({ "data-structure-id": "w1", "data-part": "own" }),
|
|
new Shape({ "data-structure-id": a, "data-part": "concrete" }),
|
|
new Shape({ "data-structure-id": "pave-1", "data-pave-type": "pavement_concrete" }),
|
|
];
|
|
const root = { querySelectorAll: () => shapes };
|
|
match.paintPicked(root, { structureId: "ud-1" });
|
|
const lit1 = shapes.map((s) => s.on);
|
|
match.paintPicked(root, { structureId: "w1" });
|
|
out.paint = [lit1, shapes.map((s) => s.on)];
|
|
process.stdout.write(JSON.stringify(out));
|