/* 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));