Merge remote-tracking branch 'origin/dev' into main_laptop_1

This commit is contained in:
2026-10-21 20:18:37 +09:00
64 changed files with 419 additions and 869 deletions
+29 -5
View File
@@ -22,13 +22,20 @@ import {
effectiveStandardCross,
readRockBoundaryDefault,
} from "../../B06_Section/B06_Section_UI_Standard_Panel";
import type {
CrossInput,
SeatedFields,
SectionSpecs,
import {
crossAtSeat,
type CrossInput,
type SeatedFields,
type SectionSpecs,
} from "../../B05_Profile/logic/B05_Profile_Pipeline_Detail";
import { SEAT_HINT } from "../../B06_Section/logic/B06_Section_Route_Carry";
import type { PipelineStation } from "./logic/design_pipeline_types";
import {
SOURCE_INPUT,
type ChangeSource,
type PipelineInputs,
type PipelineStation,
} from "./logic/design_pipeline_types";
import type { DesignPipeline } from "./logic/design_pipeline";
import type { StationSeat } from "../../common_util/common_util_station_key";
export interface PipelineCrossSource {
@@ -252,3 +259,20 @@ export function pipelineCrossSource(
specs,
};
}
/** 맞춤이 다시 먹일 입력 — 지금 입력이 묶음 입력 · 넘긴 입력(follow 전) 둘 다와 다른 것. cross 는 지금 측점 자리로
* 자리 칸을 가른 뒤 견줌(`crossAtSeat` — 노선 초안 넘김이 새 자리 자리 칸만 걷은 것 = 같은 값 · 508-1c). */
export function staleInputs(
now: PipelineInputs,
given: Partial<PipelineInputs>,
pipe: DesignPipeline,
): Array<[ChangeSource, unknown]> {
const stations = pipe.output("ground")?.stations ?? [];
const seen = (key: keyof PipelineInputs, value: unknown): string =>
JSON.stringify(key === "cross" ? crossAtSeat(value as CrossInput | null, stations) : value);
return (Object.entries(SOURCE_INPUT) as Array<[ChangeSource, keyof PipelineInputs]>)
.filter(([, key]) =>
[pipe.input(key), given[key]].every((was) => seen(key, was) !== seen(key, now[key])),
)
.map(([source, key]) => [source, now[key]]);
}
+2 -4
View File
@@ -70,6 +70,7 @@ import { fetchStructureTypes } from "../../B05_Profile/B05_Profile_Api_Structure
import { forgetPageData, pagePipes, pageStructures, trackPageBusy } from "./design_page_data";
import type { PagePipelineOptions, ProfileLink } from "./design_pipeline_page_types";
import { createPageSaved } from "./design_pipeline_page_saved";
import { staleInputs } from "./design_pipeline_cross";
import {
draftDetailOf,
heldSectionDetail,
@@ -563,10 +564,7 @@ function createPagePipeline(
await pipe.settled();
if (disposed || pageSaved.canonRouteId() !== savedSource().routeId) return round; // 정본 바뀜 = restart 몫
if (facilities.saving()) return (facilities.afterSave(), round); // 저장 도중 = 옛 저장분 · 끝나면 다시
const now = inputsNow();
const stale = (Object.entries(SOURCE_INPUT) as Array<[ChangeSource, keyof PipelineInputs]>)
.filter(([, key]) => !same(now[key], pipe.input(key)) && !same(now[key], given[key]))
.map(([source, key]): [ChangeSource, unknown] => [source, now[key]]);
const stale = staleInputs(inputsNow(), given, pipe); // cross = 지금 측점 자리로 견줌(508-1c)
if (!stale.length) return round;
if (round >= RECONCILE_ROUNDS) {
options.onUnstable?.();
+8 -13
View File
@@ -2,9 +2,8 @@
* 트랜스파일해 가짜 DOM 위에서 ① 주소마다 줄 차례 ② [<] [>] = 이웃 단계 단추 누름(꺼진 단계 = 알림만)을
* 돌려 JSON 한 벌로 냄. 확장자 `.cjs` 까닭은 `helper_design_view_parity.cjs` 머리와 같음.
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
@@ -148,20 +147,16 @@ const STUBS = {
};
globalThis.__DEV = false;
function loadTs(file) {
const src = fs.readFileSync(file, "utf8").replace(/import\.meta\.env\.DEV/g, "globalThis.__DEV");
const js = ts.transpileModule(src, {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
cache: false,
rewrite: (js) => js.replace(/import\.meta\.env\.DEV/g, "globalThis.__DEV"),
requireFor: () => (request) => {
if (request.endsWith(".css")) return {};
if (STUBS[request]) return STUBS[request];
throw new Error(`대역 없음: ${request}`);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
},
});
help = loadTs(path.join(ROOT, "ui_template", "ui_template_help.ts"));
const layout = loadTs(path.join(ROOT, "ui_template", "ui_template_workflow_layout.ts"));
@@ -4,7 +4,7 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const B07 = path.join(__dirname, "..", "..", "B07_DesignDetail");
const calls = [];
@@ -36,14 +36,13 @@ global.localStorage = {
global.location = { reload: () => calls.push(["reload"]) };
global.document = { querySelectorAll: () => [] };
function loadTs(file) {
const js = ts.transpileModule(fs.readFileSync(file, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
new Function("exports", "module", "require", js)(box.exports, box, (r) => STUBS[r] ?? {});
return box.exports;
}
const { loadTs } = makeLoader({
root: path.join(__dirname, "..", ".."),
cache: false,
requireFor: (full) => {
return (r) => STUBS[r] ?? {};
},
});
const Save = loadTs(path.join(B07, "B07_DesignDetail_UI_Save.ts"));
+9 -25
View File
@@ -2,22 +2,13 @@
* `design_leave` 를 그 자리에서 트랜스파일 · 페이지를 다섯 번 다시 세운 뒤 창 듣개 수 · 옛 노드 풀림.
* `node --expose-gc` 로 부름 · 결과 JSON 을 stdout 으로.
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader, memoryStorage } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const session = new Map();
const storage = {
getItem: (key) => (session.has(key) ? session.get(key) : null),
setItem: (key, value) => session.set(key, String(value)),
removeItem: (key) => session.delete(key),
key: (index) => [...session.keys()][index] ?? null,
get length() {
return session.size;
},
};
const storage = memoryStorage();
const win = new EventTarget();
const doc = new EventTarget();
const counts = { window: 0, document: 0 };
@@ -54,24 +45,17 @@ const STUBS = {
"../router": { currentRoute: () => "/b05-profile", setLeaveGuard: (fn) => (guard = fn) },
};
const loaded = new Map();
function loadTs(file) {
if (loaded.has(file)) return loaded.get(file);
const js = ts.transpileModule(fs.readFileSync(file, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 },
}).outputText;
const box = { exports: {} };
loaded.set(file, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
target: ts.ScriptTarget.ES2022,
requireFor: (full) => (request) => {
if (request in STUBS) return STUBS[request];
if (request.startsWith("@ui/"))
return loadTs(path.join(ROOT, "ui_template", `${request.slice(4)}.ts`));
if (request.startsWith(".")) return loadTs(path.join(path.dirname(file), `${request}.ts`));
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
},
});
const drag = loadTs(path.join(ROOT, "ui_template", "ui_template_overlay_drag.ts"));
const leave = loadTs(path.join(ROOT, "A00_Common", "design", "design_leave.ts"));
+8 -26
View File
@@ -7,7 +7,7 @@
const fs = require("fs");
const path = require("path");
const ROOT = path.join(__dirname, "..", "..");
const ts = require(path.join(ROOT, "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const input = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
const clone = (v) => JSON.parse(JSON.stringify(v));
@@ -137,27 +137,11 @@ const resolveFile = (base) =>
[base, `${base}.ts`, base.replace(/\.js$/, ".ts"), path.join(base, "index.ts")].find(
(p) => fs.existsSync(p) && fs.statSync(p).isFile(),
) ?? `${base}.ts`;
const cache = new Map();
function loadTs(target) {
const full = path.resolve(target);
if (STUBS.has(full)) return STUBS.get(full);
if (cache.has(full)) return cache.get(full);
if (full.endsWith(".css")) return {}; // 화면 꼴(vite 몫)
if (full.endsWith(".json")) {
const data = JSON.parse(fs.readFileSync(full, "utf8"));
cache.set(full, data);
return data;
}
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 need = (spec) => {
const { loadTs } = makeLoader({
root: ROOT,
interop: true,
fileStub: (full) => STUBS.get(full) ?? (full.endsWith(".css") ? {} : undefined), // .css = 화면 꼴(vite 몫)
requireFor: (full) => (spec) => {
if (spec === "three") return require(path.join(ROOT, "config", "node_modules", "three"));
const alias = { "@util/": "common_util", "@ui/": "ui_template", "@config/": "config" };
for (const [prefix, dir] of Object.entries(alias))
@@ -165,10 +149,8 @@ function loadTs(target) {
return loadTs(resolveFile(path.join(ROOT, dir, spec.slice(prefix.length))));
if (spec.startsWith(".")) return loadTs(resolveFile(path.join(path.dirname(full), spec)));
return require(spec);
};
new Function("exports", "module", "require", js)(box.exports, box, need);
return box.exports;
}
},
});
/* ── 견본 횡단 ───────────────────────────────────────────────────────────── */
const plainAt = (at) => ({ ...clone(input.plain_section), chainage_m: at, kind: "regular" });
+17 -32
View File
@@ -2,25 +2,12 @@
* `B06_Section_UI_Page_Persist.ts`(횡단 뒤처리) · `B06_Section_Section_Store.ts`(상세 캐시)를 Node 로 돌림.
* 서버 창구만 가짜 — 상세는 저장 전(옛 자리) · 저장 뒤(새 자리) 두 벌.
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader, memoryStorage } = require("./helper_ts_stub_loader.cjs");
const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1)
const ROOT = path.join(__dirname, "..", "..");
const memory = () => {
const map = new Map();
return {
getItem: (key) => (map.has(key) ? map.get(key) : null),
setItem: (key, value) => map.set(key, String(value)),
removeItem: (key) => map.delete(key),
key: (index) => [...map.keys()][index] ?? null,
get length() {
return map.size;
},
};
};
globalThis.window = { sessionStorage: memory(), localStorage: memory() };
globalThis.window = { sessionStorage: memoryStorage(), localStorage: memoryStorage() };
globalThis.sessionStorage = globalThis.window.sessionStorage;
const calls = [];
@@ -66,29 +53,27 @@ STUBS[path.join(ROOT, "A00_Common", "design", "design_save_api.ts")] = {
},
};
const cache = new Map();
function loadTs(file) {
const full = path.resolve(file);
if (STUBS[full]) return STUBS[full];
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
// 라우터(302-1 draft 길 `import.meta.glob`) — 이 로더로 못 읽음 · 저장 차례는 지금 길만 봄
STUBS[path.join(ROOT, "A00_Common", "router.ts")] = {
currentRoute: () => "",
remountRoute: () => undefined,
navigateTo: () => undefined,
setLeaveGuard: () => undefined,
};
const anyModule = () => new Proxy({}, { get: () => () => undefined });
const { loadTs } = makeLoader({
root: ROOT,
fileStub: (full) => STUBS[full],
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (CATALOG.isCatalogRequest(request)) return CATALOG;
if (request.endsWith(".json")) return require(path.join(path.dirname(full), request));
if (request.endsWith(".css")) return {};
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
if (request.startsWith("@")) return new Proxy({}, { get: () => () => undefined });
if (request.startsWith("@")) return anyModule();
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
// 측점 열쇠 한 벌(344-3 · 346-2)은 진짜로 — 빈 대역은 열쇠 목록을 못 냄
STUBS["@util/common_util_station_key"] = loadTs(
@@ -5,20 +5,12 @@
const fs = require("fs");
const path = require("path");
const ROOT = path.join(__dirname, "..", "..");
const ts = require(path.join(ROOT, "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const cache = new Map();
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 },
})
.outputText.replace(/import\.meta\.url/g, '"file:///x.js"');
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
rewrite: (js) => js.replace(/import\.meta\.url/g, '"file:///x.js"'),
requireFor: (full) => (request) => {
if (request.startsWith("@ui/") || request.startsWith("@config/"))
return new Proxy({}, { get: () => () => undefined });
const target = request.startsWith("@util/")
@@ -26,10 +18,8 @@ function loadTs(file) {
: path.join(path.dirname(full), request);
if (request.endsWith(".json")) return JSON.parse(fs.readFileSync(target, "utf8"));
return loadTs(fs.existsSync(`${target}.ts`) ? `${target}.ts` : path.join(target, "index.ts"));
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
},
});
const B05 = (name) => path.join(ROOT, "B05_Profile", `${name}.ts`);
const { buildCorridor } = loadTs(B05("B05_Profile_UI_Corridor_Build"));
@@ -1,30 +1,25 @@
/* 347 덧 관 고정 id — `reconcilePipes`(되돌리기 · 구조물 폼으로 관 목록이 바뀔 때)가 id 를 따라 옮기는지.
* `B05_Profile_UI_Drainage_Parts.ts` 를 그 자리에서 트랜스파일 · 그 밖 import 는 빈 껍데기(틀 = helper_281_1).
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const stub = new Proxy(function () {}, { get: () => stub, apply: () => stub });
function loadTs(file, real) {
const js = ts.transpileModule(fs.readFileSync(file, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
const localRequire = (request) =>
real.some((name) => request.endsWith(name))
? loadTs(path.join(path.dirname(file), `${request}.ts`), ["common_util_pipe_match"]) // 472-6
: stub;
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
const TOP = path.join(ROOT, "B05_Profile", "B05_Profile_UI_Drainage_Parts.ts");
// 진짜로 부를 import — 맨 위 = 고름 · 그 밑 = 관 짝 맞춤(472-6) · 그 밖 = 빈 껍데기
const realOf = (full) => (full === TOP ? ["design_selection"] : ["common_util_pipe_match"]);
const { loadTs } = makeLoader({
root: ROOT,
cache: false,
requireFor: (full) => (request) =>
realOf(full).some((name) => request.endsWith(name))
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: stub,
});
const { adoptDraftPipes, reconcilePipes } = loadTs(
path.join(ROOT, "B05_Profile", "B05_Profile_UI_Drainage_Parts.ts"),
["design_selection"],
);
const { adoptDraftPipes, reconcilePipes } = loadTs(TOP);
const before = [
{ chainage_m: 100, reason: "stream", id: "a1" },
{ chainage_m: 200, reason: "user", id: "b2" },
@@ -3,27 +3,18 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const B05 = path.join(__dirname, "..", "..", "B05_Profile");
const STUBS = { "./B05_Profile_UI_RouteEdit_Input": { pickHover: () => null } };
const cache = new Map();
function loadTs(full) {
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: path.join(__dirname, "..", ".."),
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
/** 그린 것만 적는 가짜 캔버스 — 선 = moveTo/lineTo 점 · 점 = arc 가운데 · 획 색. */
function fakeContext() {
+14 -21
View File
@@ -3,13 +3,11 @@
* 같은 길(스냅 켬 = `fitCurveStations` → 길이 고정 R · 하한 → `buildEditedPolyline`)로 흉내.
* node helper_398_2_curve_input.cjs
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const B05 = path.join(ROOT, "B05_Profile");
const cache = new Map();
let handlers = null;
const shows = [];
const STUBS = {
@@ -23,23 +21,13 @@ const STUBS = {
"@ui/ui_template_elements": { showToast: () => {} }, // 곡선 삭제 경고(430)
};
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) =>
STUBS[request] ??
(request.startsWith(".")
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: require(request));
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
// 곡선 판 가둠(505-3) — 판 크기 감시 · 가짜 그릇엔 판이 없어 빈 감시
globalThis.ResizeObserver = class {
observe() {}
disconnect() {}
};
const { loadTs } = makeLoader({ root: ROOT, stubs: STUBS });
const curve = loadTs(path.join(B05, "logic", "B05_Profile_UI_RouteEdit_Curve.ts"));
const edits = loadTs(path.join(B05, "logic", "B05_Profile_UI_RouteEdit_Edits.ts"));
@@ -101,7 +89,12 @@ function editor(snap) {
status.textContent = `예상노선 — ${message} 꼬리`;
};
made = bar.createCurveBar({
canvas: { getBoundingClientRect: () => ({ left: 0, top: 0, right: 800, bottom: 600 }) },
canvas: {
getBoundingClientRect: () => ({ left: 0, top: 0, right: 800, bottom: 600 }),
closest: () => null,
parentElement: null,
isConnected: true,
},
container: { querySelector: (sel) => (sel === ".b05-routeedit__status" ? status : null) },
state: () => state,
toScreen: (v) => [v[0], v[1]],
@@ -5,7 +5,7 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const B05 = path.join(__dirname, "..", "..", "B05_Profile");
const out = {};
@@ -94,25 +94,16 @@ const STUBS = {
],
},
};
const cache = new Map();
function loadTs(full) {
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: path.join(__dirname, "..", ".."),
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith("@ui/"))
return loadTs(path.join(B05, "..", "ui_template", `${request.slice(4)}.ts`));
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
/** 그린 것만 적는 가짜 캔버스 — 획 = 색 · 굵기 · 그때 옮긴 자리(translate) · 선 점. */
function fakeContext(canvas) {
+7 -11
View File
@@ -1,26 +1,22 @@
/* 403 곡선 창 하단 글 헬퍼 — `_Label.curveInfoText` 를 트랜스파일해 경우별 글을 JSON 으로 낸다. */
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const B05 = path.join(__dirname, "..", "..", "B05_Profile");
const STUBS = {
"@ui/ui_template_elements": { createButton: () => null },
"./B05_Profile_UI_Panel_Fields": { numberField: () => null, toggleButton: () => null },
};
function loadTs(full) {
const js = ts.transpileModule(fs.readFileSync(full, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: path.join(__dirname, "..", ".."),
cache: false,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
},
});
const { curveInfoText } = loadTs(path.join(B05, "B05_Profile_UI_RouteEdit_Label.ts"));
process.stdout.write(
@@ -3,13 +3,11 @@
* 같은 길(스냅 켬 = `fitStart` → `fitCurveStations` → 길이 고정 R · 하한 → `buildEditedPolyline`)로 흉내.
* node helper_408_radius_downstream.cjs
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const B05 = path.join(ROOT, "B05_Profile");
const cache = new Map();
let handlers = null;
const STUBS = {
"./B05_Profile_UI_RouteEdit_Label": {
@@ -22,23 +20,13 @@ const STUBS = {
"@ui/ui_template_elements": { showToast: () => {} }, // 곡선 삭제 경고(430)
};
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) =>
STUBS[request] ??
(request.startsWith(".")
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: require(request));
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
// 곡선 판 가둠(505-3) — 판 크기 감시 · 가짜 그릇엔 판이 없어 빈 감시
globalThis.ResizeObserver = class {
observe() {}
disconnect() {}
};
const { loadTs } = makeLoader({ root: ROOT, stubs: STUBS });
const curve = loadTs(path.join(B05, "logic", "B05_Profile_UI_RouteEdit_Curve.ts"));
const edits = loadTs(path.join(B05, "logic", "B05_Profile_UI_RouteEdit_Edits.ts"));
@@ -108,7 +96,12 @@ function editor(snap, apexLock = []) {
committed = copy(state);
};
bar.createCurveBar({
canvas: { getBoundingClientRect: () => ({ left: 0, top: 0, right: 800, bottom: 600 }) },
canvas: {
getBoundingClientRect: () => ({ left: 0, top: 0, right: 800, bottom: 600 }),
closest: () => null,
parentElement: null,
isConnected: true,
},
container: { querySelector: (sel) => (sel === ".b05-routeedit__status" ? status : null) },
state: () => state,
toScreen: (v) => [v[0], v[1]],
@@ -5,7 +5,7 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const B05 = path.join(__dirname, "..", "..", "B05_Profile");
const out = {};
@@ -84,23 +84,14 @@ const STUBS = {
routeCrossSource: () => null,
},
};
const cache = new Map();
function loadTs(full) {
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: path.join(__dirname, "..", ".."),
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const cross = loadTs(path.join(B05, "B05_Profile_UI_RouteEdit_Cross.ts"));
const station = (key, chainageM, kind, id = null) => ({ key, chainageM, kind, id });
+10 -13
View File
@@ -4,24 +4,21 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const CATALOG = require("./helper_322_catalog_module.cjs");
const ROOT = path.join(__dirname, "..", "..");
function loadTs(file) {
const js = ts.transpileModule(fs.readFileSync(path.join(ROOT, file), "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
const localRequire = (request) => {
const { loadTs: loadFull, load } = makeLoader({
root: ROOT,
cache: false,
requireFor: (full) => (request) => {
if (CATALOG.isCatalogRequest(request)) return CATALOG;
if (request.startsWith(".")) return loadTs(path.join(path.dirname(file), `${request}.ts`));
throw new Error(`stub 없음: ${request} (${file})`);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
if (request.startsWith(".")) return loadFull(path.join(path.dirname(full), `${request}.ts`));
throw new Error(`stub 없음: ${request} (${path.relative(ROOT, full)})`);
},
});
const loadTs = (file) => load(file); // 뿌리 기준 상대 경로
const cases = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
const station = loadTs("common_util/common_util_structure_station.ts");
+4 -17
View File
@@ -4,24 +4,11 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
const { loadTs } = makeLoader({
root: path.join(__dirname, "..", ".."),
});
const ground = loadTs(
path.join(__dirname, "..", "..", "B05_Profile", "logic", "B05_Profile_Grade_Ground.ts"),
+9 -17
View File
@@ -4,30 +4,22 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const CATALOG = require("./helper_322_catalog_module.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
function loadTs(file) {
const full = path.join(ROOT, 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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs: loadFull, load } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (CATALOG.isCatalogRequest(request)) return CATALOG;
if (request.endsWith(".json"))
return JSON.parse(fs.readFileSync(path.join(path.dirname(full), request), "utf8"));
if (request.startsWith(".")) return loadTs(path.join(path.dirname(file), `${request}.ts`));
throw new Error(`stub 없음: ${request} (${file})`);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
if (request.startsWith(".")) return loadFull(path.join(path.dirname(full), `${request}.ts`));
throw new Error(`stub 없음: ${request} (${path.relative(ROOT, full)})`);
},
});
const loadTs = (file) => load(file); // 뿌리 기준 상대 경로
const grade = loadTs("B05_Profile/logic/B05_Profile_Pipeline_Grade.ts");
const carry = loadTs("B05_Profile/logic/B05_Profile_Grade_Carry.ts");
+6 -15
View File
@@ -3,24 +3,15 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) =>
const { loadTs } = makeLoader({
root: path.join(__dirname, "..", ".."),
requireFor: (full) => (request) =>
request.startsWith(".")
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: require(request);
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
: require(request),
});
const align = loadTs(
path.join(__dirname, "..", "..", "B05_Profile", "logic", "B05_Profile_UI_Profile_Alignment.ts"),
+8 -9
View File
@@ -3,7 +3,7 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const B07 = path.join(__dirname, "..", "..", "B07_DesignDetail");
const calls = [];
@@ -39,14 +39,13 @@ global.localStorage = { removeItem: (key) => calls.push(["drop", key]) };
global.location = { reload: () => calls.push(["reload"]) };
global.document = { querySelectorAll: () => [] };
function loadTs(file) {
const js = ts.transpileModule(fs.readFileSync(file, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
new Function("exports", "module", "require", js)(box.exports, box, (r) => STUBS[r] ?? {});
return box.exports;
}
const { loadTs } = makeLoader({
root: path.join(__dirname, "..", ".."),
cache: false,
requireFor: (full) => {
return (r) => STUBS[r] ?? {};
},
});
Save = loadTs(path.join(B07, "B07_DesignDetail_UI_Save.ts"));
@@ -6,28 +6,18 @@
const fs = require("fs");
const path = require("path");
const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1)
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (CATALOG.isCatalogRequest(request)) return CATALOG; // 구조물 표(본보기 · 323-7)
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const { balloonLines } = loadTs(
path.join(ROOT, "B05_Profile", "logic", "B05_Profile_UI_Structures_Balloon.ts"),
@@ -4,11 +4,10 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1)
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
// ── 화면 그릇 흉내 — 태그 · 클래스 · data · 이벤트만 ─────────────────────────
class FakeNode {
@@ -144,25 +143,16 @@ const STUBS = {
},
};
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (CATALOG.isCatalogRequest(request)) return CATALOG;
if (STUBS[request]) return STUBS[request];
if (request.startsWith("@util/"))
return loadTs(path.join(ROOT, "common_util", `${request.slice(6)}.ts`));
return loadTs(path.join(path.dirname(full), `${request}.ts`));
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const { createFacilityOptionsForm } = loadTs(
path.join(ROOT, "B05_Profile", "B05_Profile_UI_Drainage_Facility.ts"),
+3 -28
View File
@@ -3,19 +3,12 @@
*
* ⚠ 확장자가 `.cjs` 인 까닭은 `helper_b05_structures_form_summary.cjs` 머리와 같다.
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader, memoryStorage } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
const session = new Map();
const fakeStorage = {
getItem: (k) => session.get(k) ?? null,
setItem: (k, v) => session.set(k, String(v)),
removeItem: (k) => session.delete(k),
};
const fakeStorage = memoryStorage();
globalThis.window = { sessionStorage: fakeStorage, localStorage: fakeStorage };
globalThis.sessionStorage = fakeStorage;
globalThis.localStorage = fakeStorage;
@@ -24,25 +17,7 @@ const STUBS = {
"@config/config_frontend": { API_BASE_URL: "/api", API_TIMEOUT_MS: 1000 },
};
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
if (STUBS[request]) return STUBS[request];
if (request.endsWith(".json")) return require(path.join(path.dirname(full), request));
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
if (request.startsWith("@")) return new Proxy({}, { get: () => () => {} });
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
const { loadTs } = makeLoader({ root: ROOT, stubs: STUBS });
const marks = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Structures_Marks.ts"));
+7 -25
View File
@@ -4,44 +4,26 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
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);
if (full.endsWith(".json")) {
const data = JSON.parse(fs.readFileSync(full, "utf8"));
cache.set(full, data);
return data;
}
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) => {
const { loadTs } = makeLoader({
root: ROOT,
interop: true,
requireFor: (full) => (request) => {
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(),
+7 -25
View File
@@ -3,44 +3,26 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
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);
if (full.endsWith(".json")) {
const data = JSON.parse(fs.readFileSync(full, "utf8"));
cache.set(full, data);
return data;
}
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) => {
const { loadTs } = makeLoader({
root: ROOT,
interop: true,
requireFor: (full) => (request) => {
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(),
+7 -25
View File
@@ -3,44 +3,26 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
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);
if (full.endsWith(".json")) {
const data = JSON.parse(fs.readFileSync(full, "utf8"));
cache.set(full, data);
return data;
}
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) => {
const { loadTs } = makeLoader({
root: ROOT,
interop: true,
requireFor: (full) => (request) => {
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(),
+5 -14
View File
@@ -3,22 +3,13 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => loadTs(path.join(path.dirname(full), `${request}.ts`));
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => loadTs(path.join(path.dirname(full), `${request}.ts`)),
});
class Node {
constructor(tag) {
+7 -25
View File
@@ -3,44 +3,26 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
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);
if (full.endsWith(".json")) {
const data = JSON.parse(fs.readFileSync(full, "utf8"));
cache.set(full, data);
return data;
}
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) => {
const { loadTs } = makeLoader({
root: ROOT,
interop: true,
requireFor: (full) => (request) => {
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(),
+6 -16
View File
@@ -5,10 +5,9 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
const session = new Map();
const fakeStorage = {
@@ -21,22 +20,13 @@ globalThis.sessionStorage = fakeStorage;
globalThis.localStorage = fakeStorage;
globalThis.requestAnimationFrame = (fn) => fn();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) =>
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) =>
request.startsWith(".")
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: require(request);
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
: require(request),
});
const sel = loadTs(path.join(ROOT, "A00_Common", "design", "design_selection.ts"));
const pickPage = loadTs(path.join(ROOT, "B06_Section", "B06_Section_UI_Page_Structure_Pick.ts"));
@@ -6,28 +6,18 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
/** TS 한 장을 CommonJS 로 옮겨 실행한다. 상대 import 는 같은 길로 다시 들어온다. */
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) =>
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) =>
request.startsWith(".")
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: require(request);
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
: require(request),
});
const edits = loadTs(path.join(ROOT, "B05_Profile", "logic", "B05_Profile_UI_RouteEdit_Edits.ts"));
const { applyCurveLimits, curveShortfalls, radiusFloorM } = edits;
@@ -5,7 +5,7 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
function memoryStorage() {
@@ -115,24 +115,14 @@ const STUBS = {
},
};
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const { createCrossPreview } = loadTs(
path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Cross.ts"),
@@ -6,10 +6,9 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
function memoryStorage() {
const map = new Map();
@@ -30,26 +29,17 @@ globalThis.fetch = () => Promise.resolve({ ok: false });
const STUBS = { "@ui/ui_template_palette": { themeColor: (_name, fallback) => fallback } };
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.endsWith(".css")) return {};
if (request.startsWith("@ui/"))
return loadTs(path.join(ROOT, "ui_template", `${request.slice(4)}.ts`));
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const model = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Initial_Model.ts"));
const { DEFAULT_WEIGHTS } = model;
@@ -11,10 +11,9 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
function memoryStorage() {
const map = new Map();
@@ -33,23 +32,14 @@ globalThis.fetch = () => Promise.resolve({ ok: false });
const STUBS = { "@ui/ui_template_palette": { themeColor: (_name, fallback) => fallback } };
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const model = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Initial_Model.ts"));
const edits = loadTs(path.join(ROOT, "B05_Profile", "logic", "B05_Profile_UI_RouteEdit_Edits.ts"));
+7 -17
View File
@@ -6,10 +6,9 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
// 브라우저 저장소 흉내 — `b_page_state` 가 읽고 쓰는 자리.
function memoryStorage() {
@@ -31,23 +30,14 @@ globalThis.fetch = () => Promise.resolve({ ok: false });
const STUBS = { "@ui/ui_template_palette": { themeColor: (_name, fallback) => fallback } };
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const lock = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Lock.ts"));
@@ -86,7 +76,7 @@ const arcAll = [1, 2].map((index) => lock.arcLocked([true, true, true, true], in
// ⑤ 노선을 못 읽은(노드 1개 이하) 채 닫으면 적어 둔 고정을 안 지운다 · 깨진 값은 기본값.
lock.writeRouteLocks("p-1", [], []);
const keptAfterEmpty = lock.readRouteLocks("p-1");
local.setItem("aislo:pref:routeedit-locks:p-3", "{\"start\":false,\"apex\":[[1,\"x\"],[2,3]]}");
local.setItem("aislo:pref:routeedit-locks:p-3", '{"start":false,"apex":[[1,"x"],[2,3]]}');
const broken = lock.readRouteLocks("p-3");
process.stdout.write(
+6 -16
View File
@@ -4,10 +4,9 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
const STUBS = {
"@ui/ui_template_palette": { themeColor: (_name, fallback) => fallback },
"@util/common_util_svg": {
@@ -15,23 +14,14 @@ const STUBS = {
},
};
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const input = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Input.ts"));
const curve = loadTs(path.join(ROOT, "B05_Profile", "logic", "B05_Profile_UI_RouteEdit_Curve.ts"));
+6 -16
View File
@@ -6,10 +6,9 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
// 브라우저 저장소 흉내 — `b_page_state` 가 읽고 쓰는 자리.
function memoryStorage() {
@@ -31,23 +30,14 @@ globalThis.fetch = () => Promise.resolve({ ok: false });
const STUBS = { "@ui/ui_template_palette": { themeColor: (_name, fallback) => fallback } };
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const viewMod = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_View.ts"));
const render = loadTs(path.join(ROOT, "B04_PreProcess", "B04_PreProcess_UI_MapRender.ts"));
@@ -4,30 +4,20 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1)
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) =>
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) =>
CATALOG.isCatalogRequest(request)
? CATALOG
: request.startsWith(".")
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: require(request);
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
: require(request),
});
// 측점 칸이 쓰는 만큼만 흉내 낸 DOM
function fakeElement() {
@@ -5,11 +5,10 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1)
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
// ── 화면 그릇 흉내 — 요소 · 클래스 · 이벤트 · 글자만 ─────────────────────────
class FakeNode {
@@ -115,15 +114,9 @@ const STUBS = {
"@config/config_frontend": { API_BASE_URL: "/api", API_TIMEOUT_MS: 1000 },
};
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (CATALOG.isCatalogRequest(request)) return CATALOG;
if (STUBS[request]) return STUBS[request];
// 화면 공용 부품(@ui/…) — 이 시험이 안 쓰는 것이라 뭘 불러도 아무 일 안 하는 함수로 막아 둠
@@ -138,11 +131,8 @@ function loadTs(file) {
return request.startsWith(".")
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const B05 = (name) => loadTs(path.join(ROOT, "B05_Profile", `${name}.ts`));
const item = loadTs(path.join(ROOT, "common_util", "common_util_summary_item.ts"));
@@ -5,7 +5,7 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1)
const ROOT = path.join(__dirname, "..", "..");
@@ -93,25 +93,16 @@ const STUBS = {
},
};
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (CATALOG.isCatalogRequest(request)) return CATALOG;
if (STUBS[request]) return STUBS[request];
if (request.startsWith("@util/"))
return loadTs(path.join(ROOT, "common_util", `${request.slice(6)}.ts`));
return loadTs(path.join(path.dirname(full), `${request}.ts`));
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const B06 = (name) => loadTs(path.join(ROOT, "B06_Section", `${name}.ts`));
const { buildStructurePanel } = B06("B06_Section_UI_Cross_Structure_Panel");
@@ -7,11 +7,10 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1)
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
const session = new Map();
const fakeStorage = {
@@ -23,15 +22,9 @@ globalThis.window = { sessionStorage: fakeStorage, localStorage: fakeStorage };
globalThis.sessionStorage = fakeStorage;
globalThis.localStorage = fakeStorage;
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (CATALOG.isCatalogRequest(request)) return CATALOG;
// 화면 공용 부품(@ui/…)은 이 시험이 안 쓰는 것이라 아무 일 안 하는 함수로 막아 둠
if (request.startsWith("@ui/")) return new Proxy({}, { get: () => () => {} });
@@ -42,11 +35,8 @@ function loadTs(file) {
return request.startsWith(".")
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const DEF = JSON.parse(
fs.readFileSync(path.join(ROOT, "resources", "master_template", "구조물정의.json"), "utf8"),
@@ -5,7 +5,7 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
@@ -27,23 +27,9 @@ const local = memoryStorage();
globalThis.window = { sessionStorage: session, localStorage: local };
globalThis.sessionStorage = session;
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
const { loadTs } = makeLoader({
root: ROOT,
});
const { useDesignStore } = loadTs(path.join(ROOT, "A00_Common", "design", "design_store.ts"));
const history = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Profile_History.ts"));
+6 -16
View File
@@ -4,7 +4,7 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
@@ -121,24 +121,14 @@ const STUBS = {
"./design_leave": { designSignature: () => "", markDesignClean: () => undefined },
};
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const { useDesignStore } = loadTs(path.join(ROOT, "A00_Common", "design", "design_store.ts"));
const edit = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Profile_Edit.ts"));
+6 -16
View File
@@ -6,10 +6,9 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
// ── 화면 그릇 흉내 — 요소 · 클래스 · 속성 · 글자 · 자식 ──────────────────────────
class FakeNode {
@@ -147,24 +146,15 @@ const STUBS = {
},
};
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.endsWith(".css")) return {};
if (request.startsWith(".")) return loadTs(`${path.resolve(path.dirname(full), request)}.ts`);
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const panel = loadTs(path.join(ROOT, "A00_Common", "design", "design_panel.ts"));
loadTs(path.join(ROOT, "A00_Common", "design", "design_sections.ts"));
@@ -9,31 +9,21 @@
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
const STUBS = { "@config/config_frontend": { API_BASE_URL: "/api" } };
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.endsWith(".css")) return {};
if (request.startsWith(".")) return loadTs(`${path.resolve(path.dirname(full), request)}.ts`);
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
const reply = (status, body) => ({
status,
+6 -15
View File
@@ -3,7 +3,7 @@
* stdin = {lines, rows, ledger} · stdout = {check, choose, ledger, sheet, calls, pick} JSON. */
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const STUBS = { "@config/config_frontend": { API_BASE_URL: "/api" } };
@@ -28,25 +28,16 @@ const stub = new Proxy(
: () => {},
},
);
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (STUB_FILES.some((name) => request.endsWith(name))) return stub;
if (request.startsWith(".") && !request.endsWith(".css"))
return loadTs(`${path.resolve(path.dirname(full), request)}.ts`);
return stub;
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
},
});
const store = new Map();
global.sessionStorage = {
+6 -15
View File
@@ -4,7 +4,7 @@
* stdin = {rows, built} · stdout = {calls, kinds, rows, picked, project, view, sheet} JSON. */
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const STUBS = { "@config/config_frontend": { API_BASE_URL: "/api" } };
@@ -17,25 +17,16 @@ const STUB_FILES = [
"M01_MasterData_UI_LogicLab_Source",
];
const stub = new Proxy({}, { get: (_t, k) => (k === "currentLanguageIndex" ? () => 0 : () => {}) });
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (STUB_FILES.some((name) => request.endsWith(name))) return stub;
if (request.startsWith(".") && !request.endsWith(".css"))
return loadTs(`${path.resolve(path.dirname(full), request)}.ts`);
return stub;
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
},
});
(async () => {
const input = JSON.parse(fs.readFileSync(0, "utf8"));
+6 -15
View File
@@ -5,7 +5,7 @@
* count: {top}} JSON — count = 「후보」 줄 1순위 근거 맞음. */
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const STUBS = { "@config/config_frontend": { API_BASE_URL: "/api" } };
@@ -17,25 +17,16 @@ const STUB_FILES = [
"M01_MasterData_UI_LogicLab_Source",
];
const stub = new Proxy({}, { get: (_t, k) => (k === "currentLanguageIndex" ? () => 0 : () => {}) });
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (STUB_FILES.some((name) => request.endsWith(name))) return stub;
if (request.startsWith(".") && !request.endsWith(".css"))
return loadTs(`${path.resolve(path.dirname(full), request)}.ts`);
return stub;
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
},
});
const input = JSON.parse(fs.readFileSync(0, "utf8"));
const M02 = path.join(ROOT, "M02_MasterTemplete");
+6 -15
View File
@@ -2,7 +2,7 @@
* `el` 대역 = 나무 꼴 {tag, className, text, attrs, children} · stdin = {origin} · stdout = 나무 JSON. */
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const el = (tag, o = {}) => ({ tag, ...o, children: o.children ?? [] });
@@ -11,24 +11,15 @@ const STUBS = {
"@ui/ui_template_locale": { currentLanguageIndex: 0 },
"@config/config_frontend": { API_BASE_URL: "/api" },
};
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".") && !request.endsWith(".css"))
return loadTs(`${path.resolve(path.dirname(full), request)}.ts`);
return new Proxy({}, { get: () => () => ({}) });
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
},
});
const input = JSON.parse(fs.readFileSync(0, "utf8"));
const national = loadTs(
+6 -15
View File
@@ -4,29 +4,20 @@
* stdin = {rows, def?, view?} · stdout = {urls, tree, classes} JSON. */
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const STUBS = { "@config/config_frontend": { API_BASE_URL: "/api" } };
const stub = new Proxy({}, { get: (_t, k) => (k === "currentLanguageIndex" ? () => 0 : () => {}) });
const cache = new Map();
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 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".") && !request.endsWith(".css"))
return loadTs(`${path.resolve(path.dirname(full), request)}.ts`);
return stub;
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
return box.exports;
}
},
});
const urls = [];
global.fetch = async (url) => {
+9 -3
View File
@@ -32,7 +32,9 @@ function memoryStorage() {
* requireFor(full, file) 풀이 함수를 헬퍼가 직접 지음(기본 풀이 대신) · 인자 없으면 진짜 require
* interop esModuleInterop 로 트랜스파일
* cache:false 같은 파일을 부를 때마다 새로 읽음(기본은 한 번만)
* fileStub(full) 파일 경로로 통째 대신할 값(없으면 undefined) */
* fileStub(full) 파일 경로로 통째 대신할 값(없으면 undefined)
* target 트랜스파일 대상(기본 ES2020)
* rewrite(js) 트랜스파일한 글 손봄(`import.meta` 처럼 CommonJS 가 못 읽는 것) */
function makeLoader({
root,
stubs = {},
@@ -41,6 +43,8 @@ function makeLoader({
interop = false,
cache: useCache = true,
fileStub,
target = ts.ScriptTarget.ES2020,
rewrite = (js) => js,
}) {
const cache = new Map();
function defaultRequire(full) {
@@ -68,9 +72,11 @@ function makeLoader({
if (useCache) cache.set(full, data);
return data;
}
const compilerOptions = { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 };
const compilerOptions = { module: ts.ModuleKind.CommonJS, target };
if (interop) compilerOptions.esModuleInterop = true;
const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { compilerOptions }).outputText;
const js = rewrite(
ts.transpileModule(fs.readFileSync(full, "utf8"), { compilerOptions }).outputText,
);
const box = { exports: {} };
if (useCache) cache.set(full, box.exports);
const localRequire = requireFor ? requireFor(full, file) : defaultRequire(full);
+10 -7
View File
@@ -9,8 +9,6 @@ from __future__ import annotations
import os
import re
import pytest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
@@ -57,8 +55,13 @@ def find_project(*rels: str) -> Path:
return min(found, key=lambda project: _touched(project, rels), default=NONE)
#: 제품 흠으로 보고한 시험만(508-1a) — 고치면 그 시험에서 걷음
DRIFT = pytest.mark.xfail(
strict=False,
reason="508-1a 제품 흠: 노선 초안 자리 칸 넘김이 cross 입력을 바꿔 cross 군더더기 차례(a02367e61)",
)
def own_ports() -> tuple[str, str]:
"""OWNERS.md 표에서 이 폴더 줄의 (API, vite) 주소 — 줄이 없으면 빈 글 둘(시험이 안 돎 · 508-1a)."""
owners = ROOT / "OWNERS.md"
for line in owners.read_text(encoding="utf-8-sig").splitlines() if owners.is_file() else []:
cells = [cell.strip().strip("`") for cell in line.strip().strip("|").split("|")]
if len(cells) >= 5 and Path(cells[2]).resolve() == ROOT.resolve():
ports = re.findall(r"\d{4,5}", cells[4])
if len(ports) == 2:
return f"http://localhost:{ports[0]}", f"http://localhost:{ports[1]}"
return "", ""
@@ -19,7 +19,9 @@ from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[2]
BASE = os.environ.get("AISLO_UI_BASE", "http://localhost:5177") # sub2 화면 서버(OWNERS 자기 줄)
from helper_verify_project import own_ports # noqa: E402
BASE = os.environ.get("AISLO_UI_BASE", own_ports()[1]) # 화면 서버 = OWNERS.md 이 폴더 줄
LAYOUT = ROOT / "ui_template" / "ui_template_workflow_layout.ts"
NAV = ROOT / "A00_Common" / "m_settings_nav.ts"
STEPS = ["파일입력", "전처리", "종단설계"]
@@ -13,7 +13,6 @@ from __future__ import annotations
import asyncio
import json
import re
import subprocess
import urllib.request
from pathlib import Path
@@ -22,20 +21,9 @@ import pytest
ROOT = Path(__file__).resolve().parents[2]
from helper_verify_project import own_ports # noqa: E402
def _own_ports() -> list[str]:
"""OWNERS.md 표에서 이 폴더 줄의 (API, vite) 포트(508-1a)."""
for line in (ROOT / "OWNERS.md").read_text(encoding="utf-8-sig").splitlines():
cells = [cell.strip().strip("`") for cell in line.strip().strip("|").split("|")]
if len(cells) >= 5 and Path(cells[2]).resolve() == ROOT.resolve():
return re.findall(r"\d{4,5}", cells[4])
return []
_PORTS = _own_ports()
API, BASE = (
[f"http://localhost:{port}" for port in _PORTS] if len(_PORTS) == 2 else ["", ""]
) # 이 폴더 백엔드 · 그 백엔드를 프록시하는 vite
API, BASE = own_ports() # 이 폴더 백엔드 · 그 백엔드를 프록시하는 vite(OWNERS.md 이 폴더 줄)
BOARD = ROOT / "resources" / "master_template" / "calc_sites.json"
PROJECT = "cb15892a-5788-4a26-9316-20a15421f68b" # 검증_sub2(OWNERS.md)
SHOTS = ROOT / "tmp" / "shots_504_2"
+1 -3
View File
@@ -42,13 +42,11 @@ def test_after_save_cards_show_server_new_detail(out: dict) -> None:
def test_no_redraw_from_stale_cache_while_saving(out: dict) -> None:
assert out["savingSeen"] == [True, False] and out["savingIdle"] is False
# 저장 도중 신호는 건너뜀 · 뒤처리가 새로 한 번 받음(오버레이 안)
# 저장 도중 신호는 건너뜀 · 뒤처리가 새로 한 번 받음 · 노선 그대로 [저장] = 가림막 없음(498-3 D1)
assert out["calls"] == [
"overlay:on",
"refresh:skip",
"cross:save",
"fetch:새 자리 4+8 · 47+0",
"overlay:off",
]
@@ -87,6 +87,7 @@ def _server(ts: dict, sampler) -> list[dict]:
"cut": design["cut_area_m2"],
"fill": design["fill_area_m2"],
"lineEnds": [line[0]["offset_m"], line[-1]["offset_m"]],
"unclosed": wide is not None,
}
)
return out
@@ -172,9 +173,8 @@ def test_격자_없으면_넓힘_없음(r):
def test_초안_상세_표본은_넓힌_표본(r):
widened = [
s for s in r["wide"]["stations"] if s["lineEnds"] and max(map(abs, s["lineEnds"])) > 20.01
]
# 넓힘 표본 = 서버 `extend_unclosed` 가 표본을 낸 미교차 측점(지표면 끝에 막혀 못 넓혀도 · 508-1c)
widened = [s for s in r["server"] if s["unclosed"]]
assert r["wide"]["shownWide"] == len(widened) # 349-0n — 서버도 넓힌 표본을 상세에 남김
assert r["plain"]["shownWide"] == 0
+1 -3
View File
@@ -25,7 +25,7 @@ ROOT = HERE.parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from helper_verify_project import DRIFT, ROUTE_SET, SKIP_REASON, find_project # noqa: E402
from helper_verify_project import ROUTE_SET, SKIP_REASON, find_project # noqa: E402
from B05_Profile.B05_Profile_Structures_Schema import structure_type_map # noqa: E402
from common_util.common_util_surface_sampler import dtm_grid_bytes # noqa: E402
@@ -149,7 +149,6 @@ def test_열기(r):
assert o["final"] is not None
@DRIFT
def test_끌기_새_노선(r):
d = r["first"]
assert [x["sources"] for x in d["runs"]] == [["route"]], d["runs"]
@@ -188,7 +187,6 @@ def test_다시_하기_첫_끌기_값(r):
assert d["stations"] == f["stations"]
@DRIFT
def test_횡단_보기_다녀와도_열기_값(r):
o = r["open"]
for step in (r["cross"], r["back"]):
@@ -19,7 +19,9 @@ import pytest
ROOT = Path(__file__).resolve().parents[2]
# 기본 = sub4 환경 · 다른 창은 AISLO_505_3_BASE · AISLO_505_3_PROJECT 로 바꿔 test_0 만 돌림(test_1 · 2 는 sub4 자료)
BASE = os.environ.get("AISLO_505_3_BASE", "http://localhost:5179")
from helper_verify_project import own_ports # noqa: E402
BASE = os.environ.get("AISLO_505_3_BASE", own_ports()[1]) # 화면 서버 = OWNERS.md 이 폴더 줄
PROJECT = os.environ.get("AISLO_505_3_PROJECT", "c725d747-50ae-46b0-87ce-4d4e56a53cf3") # 검증_sub4
SHOTS = ROOT / "tmp" / "shots_505_3"
PIPE_M = 388 # 검증_sub4 배관 하나(관경 빈칸 · 19+8)
@@ -14,7 +14,9 @@ from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[2]
BASE = "http://localhost:5179"
from helper_verify_project import own_ports # noqa: E402
BASE = own_ports()[1] # 화면 서버 = OWNERS.md 이 폴더 줄
PROJECT = "c725d747-50ae-46b0-87ce-4d4e56a53cf3" # 검증_sub4(OWNERS.md)
LIST_URL = f"{BASE}/api/projects/{PROJECT}/route/structures"
+3 -1
View File
@@ -26,7 +26,9 @@ import pytest
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT))
BASE = "http://localhost:5177"
from helper_verify_project import own_ports # noqa: E402
BASE = own_ports()[1] # 화면 서버 = OWNERS.md 이 폴더 줄
PROJECT = "cb15892a-5788-4a26-9316-20a15421f68b" # 검증_sub2(OWNERS.md)
SHOTS = ROOT / "tmp" / "shots_506_3"
COLS = (
+5 -3
View File
@@ -18,7 +18,9 @@ import pytest
HERE = os.path.dirname(__file__)
ROOT = os.path.join(HERE, "..", "..")
# 화면 서버(OWNERS 자기 줄) — 돌리는 창 포트로 바꿈
BASE = os.environ.get("AISLO_UI_BASE", "http://localhost:5177")
from helper_verify_project import own_ports # noqa: E402
BASE = os.environ.get("AISLO_UI_BASE", own_ports()[1])
KEY = "aislo:pref:input-prefs"
# 앱 스크립트보다 먼저 — 설정 키에 쓰는 횟수를 셈
@@ -51,7 +53,7 @@ def node() -> dict:
def test_별칭_검사(node):
assert node["commands"] == 153
assert node["commands"] == 154 # 488-3 IMPORT 더함
assert node["parse"] == [["LL", "CC", "X1"], [], []]
assert node["ok"] == {} # 남의 기본 별칭(C = CIRCLE)을 내 것으로 덮는 건 됨(acad.pgp 식)
assert node["chars"] == {"LINE": "chars", "CIRCLE": "chars"}
@@ -138,7 +140,7 @@ def test_설정_창_탭_저장_물음():
page.click("[data-settings-tab=cad]")
assert _visible_panel_has(page, "input[data-cad-command]")
assert not _visible_panel_has(page, "input[type=radio]")
assert page.locator(".app-settings input[data-cad-command]").count() == 153
assert page.locator(".app-settings input[data-cad-command]").count() == 154
page.click("[data-settings-tab=keys]")
assert (
page.evaluate(
+3 -1
View File
@@ -10,7 +10,9 @@ import urllib.request
import pytest
URL = os.environ.get("CAD_TOUCH_URL", "http://localhost:5174/b07-cad/")
from helper_verify_project import own_ports # noqa: E402
URL = os.environ.get("CAD_TOUCH_URL", f"{own_ports()[1]}/b07-cad/") # OWNERS.md 이 폴더 줄
def _up() -> bool:
+3 -1
View File
@@ -20,7 +20,9 @@ import pytest
ROOT = Path(__file__).resolve().parents[2]
# 다른 창 서버로 돌릴 때 — AISLO_UI_BASE · AISLO_UI_PROJECT(OWNERS 자기 줄)
BASE = os.environ.get("AISLO_UI_BASE", "http://localhost:5174")
from helper_verify_project import own_ports # noqa: E402
BASE = os.environ.get("AISLO_UI_BASE", own_ports()[1])
PROJECT_NAME = os.environ.get("AISLO_UI_PROJECT", "검증_sub1")
PAGES = [
"a01-home",
+3 -1
View File
@@ -10,7 +10,9 @@ import urllib.request
import pytest
BASE = "http://localhost:5174"
from helper_verify_project import own_ports # noqa: E402
BASE = own_ports()[1] # 화면 서버 = OWNERS.md 이 폴더 줄
MOUNT = """
async () => {
+3 -1
View File
@@ -13,7 +13,9 @@ import urllib.request
import pytest
BASE = os.environ.get("AISLO_UI_BASE", "http://localhost:5174") # 다른 창 서버 = 환경값
from helper_verify_project import own_ports # noqa: E402
BASE = os.environ.get("AISLO_UI_BASE", own_ports()[1]) # 다른 창 서버 = 환경값
def _up() -> bool: