- 관 계획을 아는 동안(초안 · 관 주인 있음) 계획에 없는 관 같은 측점 = 옮겨 간 옛 자리 — pipeIdAt 대신 pipeIdNear(안 지음) · 장부에 없으면 at: 열쇠 - 초안 없음 = 옛 갈래 그대로(지음) - 화면 관 목록 맞춤 때 지금 관 자리 근처에 없는 기록 정리(prunePipeIds) - 시험 test_411_b 덧붙임(헛 id 0 · 옛 갈래 · 정리) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TteK8mfYZetk5P3bEZkyVZ
184 lines
6.8 KiB
JavaScript
184 lines
6.8 KiB
JavaScript
/* 411-B · 411-D 헬퍼 — vite ssr 로 묶은 진짜 모듈(helper_411_b_entry.ts)을 부르고 결과를 JSON 한 벌로.
|
|
* node helper_411_b_pipe_id_pairing.mjs <묶음.mjs>
|
|
* 사용자 길: 관 p2 를 앞 관 p1 을 지나 옮김(150 → 80) · 노선 따라감이 두 관을 함께 밂.
|
|
*/
|
|
import { pathToFileURL } from "node:url";
|
|
|
|
const store = () => {
|
|
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.window = globalThis;
|
|
globalThis.sessionStorage = store();
|
|
globalThis.localStorage = store();
|
|
const any = new Proxy(function () {}, {
|
|
get: (_t, k) => (k === Symbol.toPrimitive ? () => 0 : any),
|
|
apply: () => any,
|
|
construct: () => any,
|
|
});
|
|
globalThis.document = any;
|
|
globalThis.requestAnimationFrame = (run) => setTimeout(run, 0);
|
|
|
|
const m = await import(pathToFileURL(process.argv[2]).href);
|
|
const out = {};
|
|
const P = "p411";
|
|
m.usePipeIds(P);
|
|
|
|
/* 1. 알림 목록 ↔ 가게 관 초안 짝 = id — 옮겨 차례가 뒤바뀌어도 그 관 */
|
|
const reports = [
|
|
{ id: "p10000", chainage_m: 100, facility: "pipe" },
|
|
{ id: "p15000", chainage_m: 150, facility: "pipe", start_m: 145, end_m: 155 },
|
|
];
|
|
const draft = [
|
|
{ id: "p15000", chainage_m: 80 },
|
|
{ id: "p10000", chainage_m: 100 },
|
|
];
|
|
out.reports = m
|
|
.followPipeReports(reports, draft)
|
|
.map((r) => [r.id, r.chainage_m, r.start_m ?? null]);
|
|
|
|
/* 2. 세션 id 장부 — 끌어 옮김(followMovedPipe 길) · 그 사이 옛 측점 열쇠가 옛 자리에 헛 id 를 지음 →
|
|
* 화면 목록 맞춤(shownPipes = 관 고정 id 가 쥔 세션 id 를 새 자리로 · placePipeIds) */
|
|
const idA = m.pipeIdAt(100, P);
|
|
const idB = m.pipeIdAt(150, P);
|
|
const sessionIds = new Map([
|
|
["p10000", idA],
|
|
["p15000", idB],
|
|
]);
|
|
m.movePipeId(150, 80, P); // 끌기 = 옮긴 관 id 그대로
|
|
const stray = m.pipeIdAt(150, P); // 옛 측점 열쇠가 옛 자리를 물음
|
|
const place = (shown, project) =>
|
|
m.placePipeIds(
|
|
shown.map((r) => [sessionIds.get(r.id), r.chainage_m]),
|
|
project,
|
|
);
|
|
place(m.followPipeReports(reports, draft), P);
|
|
out.ids = { idA, idB, stray, at80: m.pipeIdAt(80, P), at100: m.pipeIdAt(100, P) };
|
|
|
|
/* 2-1. 되돌림 — 관이 옛 자리로 돌아감 · 그 자리에 헛 id 가 먼저 있어도 그 관 id(헛 기록은 뺌) */
|
|
place(
|
|
[
|
|
{ id: "p15000", chainage_m: 150 },
|
|
{ id: "p10000", chainage_m: 100 },
|
|
],
|
|
P,
|
|
);
|
|
out.back = { at150: m.pipeIdAt(150, P), strayAt: m.pipeChainageOf(stray, P) };
|
|
|
|
/* 3. 노선 따라감이 두 관을 함께 밂(앞 관이 뒤 관 옛 자리로) — 기록 안 잃음 · 헛 id 안 생김 */
|
|
const Q = "q411";
|
|
const q1 = m.pipeIdAt(100, Q);
|
|
const q2 = m.pipeIdAt(103, Q);
|
|
m.placePipeIds(
|
|
[
|
|
[q1, 103],
|
|
[q2, 106],
|
|
],
|
|
Q,
|
|
);
|
|
out.batch = {
|
|
q1,
|
|
q2,
|
|
at103: m.pipeIdAt(103, Q),
|
|
at106: m.pipeIdAt(106, Q),
|
|
next: m.pipeIdAt(500, Q),
|
|
};
|
|
|
|
/* 4. 알약 따라감 — 알약이 이미 따라간 자리면 같은 자리 짝(차례 뒤바뀜에도 그 관) */
|
|
const marks = [
|
|
{ structure_id: idB, chainage_m: 80 },
|
|
{ structure_id: idA, chainage_m: 100 },
|
|
{ structure_id: "st-1", chainage_m: 40 },
|
|
];
|
|
out.marks = m
|
|
.followedMarks(marks, [{ structure_id: "st-1", chainage_m: 42 }], draft)
|
|
.map((mk) => [mk.structure_id, mk.chainage_m]);
|
|
|
|
/* 5. 배수 편집기 — 따라간 관 자리(id 짝)를 받음 · 시설 속성 · 고름도 따라감 */
|
|
const editor = m.createPipeEditor(() => {});
|
|
editor.setPipes([
|
|
{ chainage_m: 100, reason: "stream", id: "p10000" },
|
|
{ chainage_m: 150, reason: "confirmed", id: "p15000" },
|
|
]);
|
|
editor.select(1);
|
|
const facilities = m.createFacilityStore();
|
|
facilities.set(150, { facility: "ford", options: { 월류높이: 0.3 } });
|
|
m.followEditorPipes(editor, facilities, [
|
|
{ id: "p10000", chainage_m: 103 },
|
|
{ id: "p15000", chainage_m: 98 },
|
|
]);
|
|
out.editor = {
|
|
pipes: editor.pipes().map((p) => [p.id, p.chainage_m, p.reason]),
|
|
selected: editor.pipes()[editor.selected()]?.id ?? null,
|
|
ford98: facilities.get(98)?.facility ?? null,
|
|
at150: facilities.get(150),
|
|
};
|
|
m.followEditorPipes(editor, facilities, [{ id: "p10000", chainage_m: 103 }]); // 같은 값 = 그대로
|
|
out.editorSame = editor.pipes().map((p) => p.chainage_m);
|
|
|
|
/* 5-1. 막 놓은 관 — 초안엔 id 없음 · 편집기는 서버 id(재계산 응답) → id 없는 것끼리 차례 짝 */
|
|
const fresh = m.createPipeEditor(() => {});
|
|
fresh.setPipes([
|
|
{ chainage_m: 120, reason: "confirmed", id: "p12000" },
|
|
{ chainage_m: 351, reason: "stream", id: "p35100" },
|
|
]);
|
|
m.followEditorPipes(fresh, m.createFacilityStore(), [
|
|
{ chainage_m: 120 },
|
|
{ id: "p35100", chainage_m: 353 },
|
|
]);
|
|
const fresh2 = m.createPipeEditor(() => {});
|
|
fresh2.setPipes([
|
|
{ chainage_m: 200, reason: "confirmed", id: "p20000" },
|
|
{ chainage_m: 351, reason: "stream", id: "p35100" },
|
|
]);
|
|
m.followEditorPipes(fresh2, m.createFacilityStore(), [
|
|
{ chainage_m: 204 },
|
|
{ id: "p35100", chainage_m: 353 },
|
|
]);
|
|
out.fresh = [fresh.pipes(), fresh2.pipes()].map((list) => list.map((p) => [p.id, p.chainage_m]));
|
|
|
|
/* 6. B06 측점 열쇠 — 서버 관 id 도 관(계산 묶음 `pipe:` 와 같음) */
|
|
const planned = [
|
|
{ chainage_m: 80.17, owners: ["p8017"], role: "anchor" },
|
|
{ chainage_m: 52.5, owners: ["st-1"], role: "anchor" },
|
|
];
|
|
const sections = [
|
|
{ chainage_m: 52.5, kind: "irregular" },
|
|
{ chainage_m: 80.17, kind: "irregular" },
|
|
];
|
|
m.useStationOwners(P, planned, [{ id: "p8017", chainage_m: 80.17 }]);
|
|
out.keys = m.stationKeysOf(P, sections, 20).map((k) => k.key);
|
|
m.useStationOwners(P, planned);
|
|
out.keysNoPipes = m.stationKeysOf(P, sections, 20).map((k) => k.key);
|
|
out.pipelineKey = m.pipelineStationKey("pipe", "p8017");
|
|
|
|
/* 7. 411-E — 관 계획을 아는 동안 옛 자리 관 측점(옮겨 간 자리)은 세션 id 를 안 지음 · 헛 id 정리 */
|
|
const E = "e411";
|
|
m.usePipeIds(E);
|
|
const e1 = m.pipeIdAt(80, E); // 옮긴 관(새 자리)
|
|
const bookSize = () => JSON.parse(sessionStorage.getItem(`aislo:draft:pipe-ids:${E}`)).ids.length;
|
|
m.useStationOwners(E, [{ chainage_m: 80, owners: ["p15000"], role: "anchor" }], [{ id: "p15000" }]);
|
|
const staleSections = [
|
|
{ chainage_m: 80, kind: "irregular", structure: "파형강관 D800", culvert: {} },
|
|
{ chainage_m: 150, kind: "irregular", structure: "파형강관 D800", culvert: {} }, // 옛 자리
|
|
];
|
|
out.staleKeys = m.stationKeysOf(E, staleSections, 20).map((k) => k.key);
|
|
out.staleBook = bookSize();
|
|
m.useStationOwners(E, []); // 관 계획 모름(초안 없음) = 옛 갈래 그대로 지음
|
|
out.legacyKey = m.stationKeysOf(E, [staleSections[1]], 20)[0].key;
|
|
out.legacyBook = bookSize();
|
|
m.prunePipeIds([80], E); // 지금 관 자리만 남김
|
|
out.pruned = { size: bookSize(), at80: m.pipeIdAt(80, E), e1 };
|
|
m.usePipeIds(P);
|
|
|
|
process.stdout.write(JSON.stringify(out));
|