Files
Aislo/resources/tester/helper_475_3_seat_carry.mjs
T
eomsangdonandClaude Opus 5.5 a02367e615 feat(475-3 요구 275-3): 노선이 바뀌면 자리 칸(암 경계 · 2단 경사 · 손 상단측)은 같은 자리 측점만 넘김 — 새 자리 = 기본값
- 자리 칸 목록 한 벌 = TS `SEAT_KEYS`(Station_Swap · 파이썬 Router_Design 이 그 글을 읽음) — two_stage_slope · rock_boundary_offset_m · cut_slope_ratio_user · section_mode · ditch_side
- 자리 판정 한 벌 = `sameSeat` ↔ 파이썬 `same_seat`(중심 0.01 m · 왼쪽 축 1e-3 · 모르면 같은 자리 = 옛 동작)
- 끌기 세션 넘김 · Node stations.carry = `carryKeyedStates`(목록 측점 자리 · 값마다 쓴 때 자리 `@seat` — 되돌리기로 되살린 값도 제 자리로)
- 미리보기 = `pipelineCrossSource` 가 저장분 · 세션 자리 칸에 자리째 실음 → `crossAtSeat` 가 새 자리면 뺌
- B06 갈아끼움(노선 초안) = 자리 바뀐 측점 설계의 자리 칸 걷고 기본값(`unseated` · 브레인 덧)
- 서버 노선 저장 = `carry_cross_inputs` 자리 칸 같은 자리만 · 손 단면 유형 · 측구 방향 = `compute_default_designs` 입력
- 옛 단언 시험 고침(자리 모름 목록 = 같은 자리 = 손 상단측도 넘김 · 「@seat」 칸 거름) · 새 시험 test_475_3_seat_carry
- 위키 rules 넘김 규칙 줄

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:29:38 +09:00

136 lines
4.2 KiB
JavaScript

/* 475-3 헬퍼 — vite ssr 로 묶은 진짜 모듈(helper_475_3_entry.ts)을 부르고 결과를 JSON 한 벌로.
* node helper_475_3_seat_carry.mjs <묶음.mjs> <입력.json>
* 입력 = { seats: [[a, b], …] }(자리 판정 거울 사례).
*/
import { readFileSync } from "node:fs";
import { pathToFileURL } from "node:url";
const [bundle, inputPath] = process.argv.slice(2);
const m = await import(pathToFileURL(bundle).href);
const input = JSON.parse(readFileSync(inputPath, "utf-8"));
const out = {};
out.sameSeat = input.seats.map(([a, b]) => m.sameSeat(a, b));
/* 노선 바뀜 넘김 — grid:1 같은 자리 · grid:2 옮김 · grid:3 옮겼지만 값은 새 자리에서 씀(되돌리기로 되살린 값) */
const A = { x: 0, y: 20, left: [-1, 0] };
const B = { x: 0, y: 40, left: [-1, 0] };
const C = { x: 0, y: 60, left: [-1, 0] };
const C2 = { x: 3, y: 60, left: [-1, 0] };
const from = [
{ key: "grid:1", chainageM: 20, seat: A },
{ key: "grid:2", chainageM: 40, seat: B },
{ key: "grid:3", chainageM: 60, seat: C },
];
const to = [
{ key: "grid:1", chainageM: 20, seat: A },
{ key: "grid:2", chainageM: 40.5, seat: { x: 5, y: 40, left: [-1, 0] } },
{ key: "grid:3", chainageM: 61, seat: C2 },
];
const choice = {
ground_type: "soil",
ditch_type: "l_type",
two_stage_slope: true,
section_mode: "right_cut",
ditch_side: "left",
paved: true,
};
const raw = {
rockb: { "grid:1": 1.2, "grid:2": 1.5, "grid:3": 0.9, "@seat": { "grid:3": C2 } },
cutslope: { "grid:1": 0.8, "grid:2": 0.7 },
crossdesign: { "grid:1": choice, "grid:2": choice },
shoulderext: { "grid:2": { left: 0.5 } },
bermdepth: {},
};
const strip = (states) =>
Object.fromEntries(
Object.entries(states).map(([name, cells]) => [
name,
Object.fromEntries(Object.entries(cells).filter(([key]) => !key.startsWith("@"))),
]),
);
const carried = m.carryKeyedStates((name) => raw[name] ?? {}, from, to);
out.carried = strip(carried.states);
out.carriedSeats = carried.states.rockb["@seat"];
out.outside = carried.outside.size;
/* 자리 모름(옛 목록) = 옛 동작 그대로 */
const bare = (list) => list.map(({ key, chainageM }) => ({ key, chainageM }));
out.unknown = strip(m.carryKeyedStates((name) => raw[name] ?? {}, bare(from), bare(to)).states);
/* 미리보기 입력 — 저장분 · 세션 자리 칸 묶음(`seats`) */
const station = (key, x, y) => ({ key, chainageM: y, x, y, left: [-1, 0] });
const input2 = {
standard: {},
byKey: {
"grid:1": {
groundType: "soil",
rockBoundaryOffsetM: 1,
sectionMode: "right_cut",
seats: [{ ...A, fields: ["rockBoundaryOffsetM", "sectionMode"] }],
},
"grid:2": {
groundType: "soil",
twoStageSlope: true,
cutSlopeRatio: 0.7,
seats: [
{ ...B, fields: ["twoStageSlope"] },
{ x: 5, y: 40, left: [-1, 0], fields: ["cutSlopeRatio"] },
],
},
},
};
out.atSeat = m.crossAtSeat(input2, [station("grid:1", 0, 20), station("grid:2", 5, 40)]).byKey;
/* B06 갈아끼움(노선 초안) — 앞 횡단 설계를 이어 받되 자리가 바뀐 측점은 자리 칸 기본값 */
const hand = {
ground_type: "soil",
section_mode: "both_cut",
ditch_side: "right",
two_stage_slope: true,
rock_boundary_offset_m: -1.2,
cut_slope_ratio_user: 0.8,
shoulder_extend_left_m: 0.5,
};
const section = (chainage, x) => ({
station_id: `s${chainage}`,
chainage_m: chainage,
kind: "regular",
center_x: x,
center_y: chainage,
frame: { left_xy: [-1, 0] },
samples: [],
uphill_side: "left",
design: { ...hand },
});
const pipelineStation = (key, chainage, x) => ({
key,
kind: "grid",
chainageM: chainage,
x,
y: chainage,
left: [-1, 0],
azimuthDeg: 0,
planRadiusM: null,
curveOuterSide: null,
curveWideningM: 0,
ground: null,
});
const detail = {
longitudinal: { stations: [], length_m: 40 },
cross_sections: [section(20, 0), section(40, 0)],
};
const swapped = (draft) =>
m
.swapCrossSections(
detail,
[pipelineStation("grid:1", 20, 0), pipelineStation("grid:2", 40, 5)],
["grid:1", "grid:2"],
20,
draft,
)
.detail.cross_sections.map((s) => s.design);
out.swapDraft = swapped(true);
out.swapNoDraft = swapped(false);
process.stdout.write(JSON.stringify(out));