- 올림 칸 accept .estx · .stc · 올림 안내 「원파일 · EST/STmate — 호표 N · 같은 공사 엑셀 HP 에 붙음」 - 줄 쌓기 위 옵션 가로 — 가져온 식 값으로 드러난 수 하나 변수(q · K · E · Cm · Q …) = 값 칸 + 꼬리표 「원파일」 · 「엑셀」(`sourceOf` · 공식 묶음 밖) · 규격 칸(원파일) · 품셈 조건 글 = 「추정」 칸(읽기만 · 기초에 안 묶음) - 합 밖 · 비목 없는 소계 줄 = 종류 「소계」 · 비목 칸 빈칸(편집 · 산출근거 표 칸 모두) - 원문 카드 — 「원파일 · EST 산근 D… · 행 …」 한 줄 + 원파일 확정(확정 · 표지 · 추정 · 확정률) - 서버 — 원파일 원본에 원코드 · 규격(EST) · 문서 머리 가져온에 원코드 · 규격 · 확정 · 추정 글줄(금액 · 길 그대로) - 화면 계산기 큰나머지 끝전 — 나머지 비교 소수 흔들림 반올림(파이썬 Decimal 과 같은 갈래 · 동부청영월 블록 1810 재료비 1 원 어긋남 고침) - 시험 test_810_3_native_screen(EST 1,849 · STC 371 블록 화면 셈 = 서버 셈 · 옵션 칸 · 추정 칸 수 = 확정 추정 · 소계 · 카드) · 헬퍼 helper_810_3_screen.cjs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
66 lines
2.8 KiB
JavaScript
66 lines
2.8 KiB
JavaScript
/* 810-3 화면 셈 거울 헬퍼 — 가져온 식 문서를 화면과 같은 길(importView → calcDoc)로 셈 + 줄 쌓기 옵션 칸 꼴.
|
|
* stdin = {문서들: {키: 문서}, 대상: [키], 기록: {열쇠: {값 | 빈 | 끊김}}, 기준: "엑셀" | "우리"}
|
|
* stdout = {답: {키: calcDoc 답}, 꼴: {키: {옵션: [기호], 숨김: [기호], 공식: [기호]}}}
|
|
* 짝 = test_810_3_native_screen.py · 기록 열쇠 = helper_802_1_formula_doc.cjs 와 같음. */
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
|
|
|
|
const cache = new Map();
|
|
function load(at) {
|
|
if (cache.has(at)) return cache.get(at);
|
|
const js = ts.transpileModule(fs.readFileSync(at, "utf8"), {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
|
|
}).outputText;
|
|
const box = { exports: {} };
|
|
cache.set(at, box.exports);
|
|
const need = (p) =>
|
|
p.startsWith(".") ? load(path.resolve(path.dirname(at), `${p}.ts`)) : require(p);
|
|
new Function("exports", "module", "require", js)(box.exports, box, need);
|
|
return box.exports;
|
|
}
|
|
const root = path.join(__dirname, "..", "..", "common_util");
|
|
const calc = load(path.join(root, "common_util_formula_doc_calc.ts"));
|
|
const imp = load(path.join(root, "common_util_formula_doc_import.ts"));
|
|
const stack = load(path.join(root, "common_util_line_stack.ts"));
|
|
const { varId } = load(path.join(root, "common_util_formula_doc.ts"));
|
|
|
|
function canon(v) {
|
|
if (typeof v === "number") return calc.plainText(v);
|
|
if (Array.isArray(v)) return v.map(canon);
|
|
if (v && typeof v === "object") {
|
|
const out = {};
|
|
for (const k of Object.keys(v).sort()) out[k] = canon(v[k]);
|
|
return out;
|
|
}
|
|
return v;
|
|
}
|
|
const input = JSON.parse(fs.readFileSync(0, "utf8"));
|
|
const record = input.기록 || {};
|
|
function answer(kind, p) {
|
|
const k = `${kind}|${JSON.stringify(canon(p))}`;
|
|
if (!(k in record)) throw new calc.Broken(`기록 없음 ${k}`);
|
|
const got = record[k];
|
|
if ("빈" in got) throw new calc.Gap(got.빈);
|
|
if ("끊김" in got) throw new calc.Broken(got.끊김);
|
|
return got.값;
|
|
}
|
|
const docs = input.문서들 || {};
|
|
const links = {
|
|
element: (p) => answer("요소", p),
|
|
table: (p) => answer("표", p),
|
|
doc: (key) => (docs[key] ? imp.importView(docs[key], input.기준 || "엑셀") : null),
|
|
};
|
|
const out = { 답: {}, 꼴: {} };
|
|
for (const key of input.대상 || []) {
|
|
const doc = docs[key];
|
|
out.답[key] = calc.calcDoc(imp.importView(doc, input.기준 || "엑셀"), links);
|
|
const hidden = stack.hiddenOf(doc);
|
|
out.꼴[key] = {
|
|
옵션: (doc.변수 || []).filter((v) => stack.sourceOf(doc, v)).map(varId),
|
|
숨김: [...hidden],
|
|
공식: stack.stackOf(doc).flatMap((it) => it.줄.flatMap((l) => (l.꼴 === "공식" ? l.기호 : []))),
|
|
};
|
|
}
|
|
process.stdout.write(JSON.stringify(out));
|