Files
Aislo/resources/tester/helper_472_5r_rock.mjs
T
eomsangdonandClaude Opus 5.5 cfdcf0aed7 fix(472-5 남음): 암선 · 암 경사 · B05 상단측 메모리 맵 걷음 · 노선 저장 뒤 옛 노선 칸 · hold 비움
- 암 경계 · 암 절토 경사 저장소(`B06_Section_UI_Page_Persist`) = 세션 칸이 주인 — 읽을 때마다 측점 열쇠 칸(`readCells`) · 고칠 때 지금 칸을 읽어 그 측점만 바꿔 씀(`putCell`) · 메모리 맵 · load · 갈아끼움 다시 읽기(keyedStores · reloadKeyedStores) 걷음 · ↶ 뒤 다음 조작이 되돌림을 덮던 흠(N5) 고침
- 저장 재료 = `offsets()` · `ratios()`(새 Map) · ↶ ↷ 가 rockb · cutslope 칸을 바꾸면 조정창과 같은 onRestore 로 카드 · 면적 다시
- B05 상단측 메모리 맵(uphillOverrides · load/saveUphillOverrides) 걷음 — 읽는 곳 없이 저장 뒤 비우기만 하던 사본 · 값 주인 = 세션 칸 `uphill` · 상단측 차례 = 기본 조각 그대로
- 노선 바뀐 [저장] 성공 뒤(페이지 다시 세운 뒤) 옛 노선 번호의 노선 범위 초안(`clearRouteDrafts`) · `route-draft-hold` 비움 · 넘김 규칙 그대로 · 같은 번호면 노선 칸 안 지움 · 실패면 그대로
- 시험 test_472_5r_rock_owner 7(옛 코드 빨강 5) · 옛 단언 고침(176_3 · 271 · 443 상단측 조각 · 344_3 저장소 load)
- 위키 암선 · 암 경사 · ↶ ↷ 규칙 · 노선 저장 뒤 정리 줄

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 15:13:30 +09:00

122 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 472-5 남음 헬퍼 — node helper_472_5r_rock.mjs <묶음.mjs> · 표준출력 JSON.
* ① 암 경계(▲▼ · 되돌림) · 암 절토 경사를 고침 → ↶ → 다른 측점을 고침 → ↶ ↷ — 세션 칸 · 카드 읽기 · 저장 재료가
* 되돌린 값을 따르는가(옛 코드 = 메모리 맵이 옛 값을 쥐고 다음 조작이 칸을 통째로 다시 씀 · N5).
* ② clearRouteDrafts — 그 노선 번호의 노선 범위 초안만 비움(다른 노선 · 프로젝트 칸 그대로). */
import { pathToFileURL } from "node:url";
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(),
};
};
const any = new Proxy(function () {}, {
get: (_t, k) => (k === Symbol.toPrimitive ? () => 0 : any),
apply: () => any,
construct: () => any,
});
globalThis.window = { sessionStorage: storage(), localStorage: storage() }; // 손길 듣기 없음 = 열 때 규칙 꺼짐
globalThis.sessionStorage = window.sessionStorage;
globalThis.localStorage = window.localStorage;
globalThis.document = any;
const m = await import(pathToFileURL(process.argv[2]).href);
const P = "p4725rock";
const R = 7;
localStorage.setItem("frd_current_project_id", P);
const SAVED_ROCK = -0.8; // 저장분 암 경계(측점 100)
const sections = [100, 120, 140].map((chainage_m) => ({
chainage_m,
station_id: `s${chainage_m}`,
design: chainage_m === 100 ? { rock_boundary_offset_m: SAVED_ROCK } : {},
}));
const detail = { cross_sections: sections };
const refreshed = [];
const rock = m.createRockBoundaryStore({
sessionKey: () => m.stateKey("rockb", P, R),
detail: () => detail,
refreshCard: (at) => refreshed.push(at),
recompute: () => undefined,
});
rock.setDefaults(-0.5, 0.1);
const cut = m.createCutSlopeStore({
sessionKey: () => m.stateKey("cutslope", P, R),
standard: () => ({ rock: { cut_slope_ratio: 0.4 }, soil: { cut_slope_ratio: 1.0 } }),
refreshCard: () => undefined,
recompute: () => undefined,
});
const cell = (name) => {
const raw = m.readState(name, P, R) ?? {};
// 측점 열쇠 칸 = 열쇠 → 값 · `@at`(쓴 때 누가거리) · `@seat` — 누가거리 → 값으로 풀어 봄
const at = raw["@at"] ?? {};
return Object.fromEntries(
Object.entries(raw)
.filter(([key]) => !key.startsWith("@"))
.map(([key, value]) => [Number(at[key] ?? key).toFixed(2), value]),
);
};
const cells = () => ({ rockb: cell("rockb"), cutslope: cell("cutslope") });
const reads = () =>
Object.fromEntries(
sections.map((s) => [
s.chainage_m,
{ rock: rock.control.offsetFor(s), cut: cut.control.ratioFor(s) },
]),
);
const out = {};
const history = m.createProfileHistory(() => undefined, 100);
// 조작 A — 100 ▼(저장분 −0.8 → −0.9) · 120 ▲(기본 −0.5 → −0.4) · 140 암 경사 0.7
rock.control.adjust(100, -0.1);
rock.control.adjust(120, 0.1);
cut.control.set(140, 0.7);
history.record();
out.afterA = cells();
out.readsA = reads();
history.undo(); // ↶ = 세션 칸을 조작 전으로 되씀(저장소를 안 거침)
out.afterUndo = cells();
out.readsUndo = reads();
// 조작 B — 다른 측점(옛 코드 = 메모리 맵이 A 값을 쥐고 통째로 다시 씀)
rock.control.adjust(140, -0.1);
cut.control.set(100, 0.5);
out.afterB = cells();
out.payloadB = {
rock: Object.fromEntries(typeof rock.offsets === "function" ? rock.offsets() : rock.offsets), // 옛 꼴 = Map
cut: Object.fromEntries(typeof cut.ratios === "function" ? cut.ratios() : cut.ratios),
};
history.record();
history.undo();
out.afterUndo2 = cells();
history.redo(); // ↷ = B 그대로
out.afterRedo = cells();
out.readsRedo = reads();
// 되돌림(↺) — 암 경계 = 기본값 · 암 경사 = 0(표준 표시)
rock.control.reset(140);
cut.control.set(100, null);
out.afterReset = cells();
out.readsReset = reads();
// ② 노선 저장 뒤 옛 노선 칸만 비움
m.writeState("rockb", { "grid:1": -0.7 }, P, 8);
m.writeState("crossw", { "100.00": 6 }, P, R);
m.writeState("uphill", { "100.000": "left" }, P);
m.writeState("rockb", { "grid:1": -0.6 }, "other", R);
const keys = () =>
Array.from({ length: sessionStorage.length }, (_, i) => sessionStorage.key(i))
.filter((key) => key.startsWith("aislo:draft:"))
.sort();
out.keysBefore = keys();
m.clearRouteDrafts(P, R);
out.keysAfter = keys();
process.stdout.write(JSON.stringify(out));