- 관 벽 높이 · 형태(조정 h · m) · 흙막이 n 단(h · m · 구간)을 layPipeOptions 가 얹음(관 초안 ?? 저장 관) - 상세 가게 읽기 · 다시 셈 창구(관 옵션을 고친 뒤 묶음 cross)에서 부름 — 예전에는 B06 보기가 열릴 때만 - 새 test_387_4b_pipe_options(상세 가게 얹기 = B06 폼 되보내기 · 면적 같음 · 옵션 바꿔도) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014utrjfoW831Vc5wJUd13kL
145 lines
5.7 KiB
JavaScript
145 lines
5.7 KiB
JavaScript
/* 387-4b 헬퍼 — 관 옵션 → 횡단 조정값: 상세 가게 얹기(`layPipeOptions` · B05 만 연 페이지) = B06 폼 되보내기
|
|
* (`applyPipeOptionsToCache` · 조정창 흉내 = 캐시에 같은 칸으로 씀)인지 · 옵션을 바꿔도 같은지 · 면적으로 견줌.
|
|
* 짝 = `test_387_4b_pipe_options.py`.
|
|
*/
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
|
|
const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1)
|
|
|
|
const ROOT = path.join(__dirname, "..", "..");
|
|
const cache = new Map();
|
|
const STUBS = { "@ui/ui_template_toast": { showToast: () => undefined } };
|
|
|
|
function loadTs(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,
|
|
esModuleInterop: true,
|
|
},
|
|
}).outputText;
|
|
const box = { exports: {} };
|
|
cache.set(full, box.exports);
|
|
const localRequire = (request) => {
|
|
if (CATALOG.isCatalogRequest(request)) return CATALOG;
|
|
if (STUBS[request]) return STUBS[request];
|
|
const alias = { "@util/": "common_util", "@ui/": "ui_template", "@config/": "config" };
|
|
for (const [prefix, dir] of Object.entries(alias))
|
|
if (request.startsWith(prefix))
|
|
return loadTs(resolve(path.join(ROOT, dir, request.slice(prefix.length))));
|
|
return loadTs(resolve(path.join(path.dirname(full), request)));
|
|
};
|
|
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
|
|
cache.set(full, box.exports);
|
|
return box.exports;
|
|
}
|
|
const resolve = (base) =>
|
|
[base, `${base}.ts`, path.join(base, "index.ts")].find(
|
|
(p) => fs.existsSync(p) && fs.statSync(p).isFile(),
|
|
) ?? `${base}.ts`;
|
|
|
|
function memoryStorage() {
|
|
const map = new Map();
|
|
return {
|
|
getItem: (k) => (map.has(k) ? map.get(k) : null),
|
|
setItem: (k, v) => map.set(k, String(v)),
|
|
removeItem: (k) => map.delete(k),
|
|
key: (i) => [...map.keys()][i] ?? null,
|
|
get length() {
|
|
return map.size;
|
|
},
|
|
};
|
|
}
|
|
globalThis.window = { sessionStorage: memoryStorage(), localStorage: memoryStorage() };
|
|
|
|
const B06 = (f) => path.join(ROOT, "B06_Section", `${f}.ts`);
|
|
const { structureAreaRows, computeStoredLayouts } = loadTs(B06("B06_Section_Structure_Layouts"));
|
|
const { layPipeOptions } = loadTs(B06("B06_Section_Section_Adjusts"));
|
|
const { applyPipeOptionsToCache } = loadTs(B06("B06_Section_UI_Page_Pipe_Options"));
|
|
const { ZERO_ADJUST } = loadTs(B06("B06_Section_UI_Cross_Culvert_Types"));
|
|
|
|
const fresh = () =>
|
|
JSON.parse(fs.readFileSync(path.join(__dirname, "fixtures", "b06_186_1_pipe_292.json"), "utf8"))
|
|
.cross_sections;
|
|
const areaOf = (sections) => {
|
|
const s = sections.find((x) => x.culvert);
|
|
const row = structureAreaRows(sections).find((r) => r.chainage_m === s.chainage_m);
|
|
return [row?.cut_area_m2 ?? null, row?.fill_area_m2 ?? null, s.design.revet_adjust ?? null];
|
|
};
|
|
|
|
/** B06 길 — 조정창 흉내(세션 없음 · 캐시 칸에 같은 꼴로 씀 · `storeAdjust` 규칙). */
|
|
function b06(sections, options, extra = 0) {
|
|
const owner = sections.find((x) => x.culvert);
|
|
owner.design.extra_wall_counts = { outlet: extra, basin: 0 };
|
|
const adjustFor = (section, role) => ({
|
|
...ZERO_ADJUST,
|
|
...(section.design.revet_adjust?.[role] ?? {}),
|
|
});
|
|
const round1 = (v) => Math.round(v * 10) / 10;
|
|
const ctx = {
|
|
detail: () => ({ cross_sections: sections }),
|
|
ford: {},
|
|
box: {},
|
|
revetOffset: {
|
|
adjustFor,
|
|
update: (at, role, patch) => {
|
|
const section = sections.find((x) => Math.abs(x.chainage_m - at) < 0.01);
|
|
const cur = adjustFor(section, role);
|
|
const next = {
|
|
...cur,
|
|
h: patch.h === undefined ? cur.h : patch.h === null ? null : round1(patch.h),
|
|
m: patch.m === undefined ? cur.m : patch.m,
|
|
};
|
|
const bucket = { ...(section.design.revet_adjust ?? {}) };
|
|
const dflt = Math.abs(next.x) < 1e-9 && next.d == null && next.h == null && next.m == null;
|
|
if (dflt) delete bucket[role];
|
|
else bucket[role] = next;
|
|
section.design.revet_adjust = bucket;
|
|
},
|
|
},
|
|
soilTiers: () => {
|
|
const probe = { ...owner, design: { ...owner.design } };
|
|
return extra
|
|
? (computeStoredLayouts(probe, sections)?.culvert?.extraWalls.length ?? extra)
|
|
: 0;
|
|
},
|
|
overrideOptions: () => undefined,
|
|
refreshCard: () => undefined,
|
|
};
|
|
applyPipeOptionsToCache(ctx, owner.chainage_m, options, true);
|
|
return areaOf(sections);
|
|
}
|
|
|
|
/** 상세 가게 길(B05 만 연 페이지) — 관 초안 · 저장 관의 폼 칸 그대로. */
|
|
function store(sections, options, extra = 0) {
|
|
const owner = sections.find((x) => x.culvert);
|
|
owner.design.extra_wall_counts = { outlet: extra, basin: 0 };
|
|
layPipeOptions({ cross_sections: sections }, [{ chainage_m: owner.chainage_m, options }]);
|
|
return areaOf(sections);
|
|
}
|
|
|
|
const at = fresh().find((x) => x.culvert).chainage_m;
|
|
const first = {
|
|
inlet_revet_height_m: 1.5,
|
|
inlet_revet_form: "돌쌓기(찰)",
|
|
outlet_revet_height_m: 1.5,
|
|
outlet_revet_form: "돌쌓기(찰)",
|
|
};
|
|
const changed = { ...first, outlet_revet_height_m: 2.4, outlet_revet_form: "옹벽" };
|
|
const out = { at, none: areaOf(fresh()) };
|
|
for (const [name, options] of Object.entries({ first, changed })) {
|
|
out[name] = { b06: b06(fresh(), options), store: store(fresh(), options) };
|
|
}
|
|
// 흙막이 단(soil_add) — 유출 다단 두 단 · 높이 · 형태
|
|
const tiers = {
|
|
...first,
|
|
soil_add_1_height: 1.2,
|
|
soil_add_1_form: "돌쌓기(찰)",
|
|
soil_add_2_height: 0.05,
|
|
};
|
|
out.tiers = { b06: b06(fresh(), tiers, 2), store: store(fresh(), tiers, 2) };
|
|
process.stdout.write(JSON.stringify(out));
|