From 4ff96a6771582b1da6b5db523c1307eba5434df2 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sat, 14 Nov 2026 15:44:22 +0900 Subject: [PATCH] =?UTF-8?q?feat(stmate-test):=20REA=20MCP(Ghidra)=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EC=97=94=EC=A7=84=20=E2=80=94=20=ED=91=9C?= =?UTF-8?q?=EC=A4=80=EC=8B=9C=EC=9E=A5=EB=8B=A8=EA=B0=80(A=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20COSTA)=20=EB=82=B4=EC=97=AD=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=C2=B7=20EXRNM=20=EC=BC=9C=EC=A7=90=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=C2=B7=20=EC=86=90=EB=A3=8C=20=EB=B0=98=EC=98=AC=EB=A6=BC=20MRO?= =?UTF-8?q?UNDUD=20=C2=B7=20=EC=A0=81=EC=9A=A9=EA=B8=B0=EC=A4=80=20?= =?UTF-8?q?=EC=BD=A4=EB=B3=B4=20=EA=B0=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - A 코드 = COSTA · S_JDA 참 = 저장 단가 · 거짓 = AAMTn 노무비율 나눔 · ACTTYP·ACTOPT = PRJLST · calcBoq·api_load 연결 - EXRNM 참 = S 줄만 단가×율/1000 · ECD 자리 버림 · 천원 · 전각 $ - 손료 계수 반올림 = 첫 버림 자리 5 이상 올림 - 적용기준 국가 2·지방 0·행자부 1 · 행자부 RATE_M 조회 rateMLookup - 지식DB 36번 Co-Authored-By: Claude Opus 5.5 --- .../36_계산엔진_잔여규칙.md | 150 +++ .../REA_MCP/Ghidra_kj_0x47a1bc_요율조회.txt | 1104 +++++++++++++++++ ...dra_main_0x42a828_설정로더_S_JDA_EXRNM.txt | 621 ++++++++++ .../REA_MCP/Ghidra_main_0x43307c_발췌.txt | 526 ++++++++ ...ra_main_0x45c848_PRJLST로더_ACTTYP.asm.txt | 83 ++ .../REA_MCP/evidence_ids.txt | 9 + .../REA_MCP/read_bytes_0x439d28_상수.txt | 2 + resources/tester/helper_stmate_std.cjs | 48 + resources/tester/test_stmate_smt_tools.py | 2 +- resources/tester/test_stmate_std_market.py | 200 +++ resources/tester/test_stmate_xrate_round.py | 34 + tools/stmate-test/calc.js | 46 +- tools/stmate-test/calc_xrate.js | 11 +- tools/stmate-test/kanjub_parts.js | 29 +- tools/stmate-test/server.py | 32 + tools/stmate-test/smt_engine.js | 50 +- tools/stmate-test/smt_eval.js | 12 +- 17 files changed, 2936 insertions(+), 23 deletions(-) create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/36_계산엔진_잔여규칙.md create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_kj_0x47a1bc_요율조회.txt create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x42a828_설정로더_S_JDA_EXRNM.txt create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x43307c_발췌.txt create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x45c848_PRJLST로더_ACTTYP.asm.txt create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/evidence_ids.txt create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/read_bytes_0x439d28_상수.txt create mode 100644 resources/tester/helper_stmate_std.cjs create mode 100644 resources/tester/test_stmate_std_market.py create mode 100644 resources/tester/test_stmate_xrate_round.py diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/36_계산엔진_잔여규칙.md b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/36_계산엔진_잔여규칙.md new file mode 100644 index 000000000..3a381324a --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/36_계산엔진_잔여규칙.md @@ -0,0 +1,150 @@ +# 36 계산 엔진 잔여 규칙 — 표준시장단가 연결 · 환율 EXRNM 두 경로 · 수량 계산기 반올림 · 적용기준 콤보 + +## 0. 범위·방법·한계 + +- 대상 항목: F2-61 표준시장단가 · F2-04 환율 EXRNM · F1-36 손료(수량 계산기) 반올림 · F2-24 적용기준 콤보·행자부 RATE_M. +- 방법: REA MCP(rea-agents 6.7.0 · Ghidra 12.1.4) — STmate.Cpm · ST_KanJub.CPM 디컴파일·어셈블리·xrefs·read_bytes. 원본 실행 없음. +- 근거 파일: `REA_MCP/` (evidence_ids.txt 에 증거 ID). +- 실물 대조: 실무 STC 7건 — COSTA.DBF 행 0 건(A 코드 표본 없음) · 외화 줄은 울진 3건($ · EXRNM 참)만. + +## 1. 표준시장단가(A 코드) 단가 읽기 (F2-61) — 확인 + +### 1.1 자료 자리 + +- A 코드 단가표 = COSTA.DBF(실적단가 표 · 암호 0x06 꼴). + - 칸: AAMT1~4 · RATE_L · RATE_M · RATE_S · LAMT1~4·MAMT1~4·SAMT1~4·TAMT1~4 · LAMT1_R~LAMT4_R(·MAMTn_R·SAMTn_R) · DOLLOR 등. +- 구성(일위대가·중기) 줄 단가 다시 읽기 Main 0x43307c → 0x437a13: + - 계산 종류 1~3 · 6(계열 > 1) · 7·8(계열 3·칸 3)일 때 줄마다 0x430c60 호출. + - 줄 코드 첫 글자 'A' → 자료집합 [[0x5e6090]+0xc](COSTA) · 깃발 1. 그 밖 → [+8](COSTN) · 깃발 0. + +### 1.2 0x430c60 (깃발 1) + +- 설정 +0x7c8 = Start8x.Ini [Start] S_JDA(ReadBool 기본 거짓 · 로더 0x42afd9) 참 → 저장 LAMTn·MAMTn·SAMTn·TAMTn 그대로. +- 거짓 → L·M·S = 0 · T = AAMTn. + - T ≠ 0 · RATE_L = 0 · LAMTn_R ≠ 0 → L = LAMTn_R. + - 0x45a468(T 묶음, R = RATE_L, ACTTYP, ACTOPT) 호출 — 나눔 규칙은 34 §6 그대로. +- 끝(0x4312ad): T = L + M + S + 넷째 칸(+0x1e8 · OPTIMIZ 묶음의 A 칸). + +### 1.3 ACTTYP·ACTOPT 출처 + +- 계산이 읽는 공사 레코드 +0x172c·+0x1730 = PRJLST 행 ACTTYP·ACTOPT (로더 0x45c848 · 0x45c938~0x45c956 · 같은 로더가 PCLASS → +0x1750). +- 34 §6 의 「화면 기본 1·2(PCLASS ≠ 9)」는 화면 0x528ac0 의 콤보 채우기 — 계산값은 PRJLST 저장값. +- 실물: 6건 ACTTYP 1·ACTOPT 2 · 울진 2025 1건 0·0. + +### 1.4 미확인 + +- COSTA 칸 5(변경 4차 · 계열 5) 이름 없음 — 계열 5 의 A 줄 값. +- 넷째 칸 A 가 원가계산서(제잡비) 밑수에 들어가는 자리. +- 내역(ST_Boq) A 줄 금액 끝수 — 같은 몸 0x45d534 · 줄 금액 절사는 다른 비목과 같다고 둠. + +## 2. 환율 적용 범위 EXRNM 두 경로 (F2-04) — 규칙 확인 · 금액은 같지 않음 + +### 2.1 설정 자리 (로더 0x42a828) + +| 키 | 자리 | +|---|---| +| [EQUIPMENT] EXLNMn | +0x718 + n×8 | +| EXHNMn | +0x728 + n×8 | +| EXYENn | +0x738 + n×8 | +| EXEURn | +0x748 + n×8 | +| EXRNM | +0x7c9 (ReadBool) | +| [Start] ECDNM | +8 | +| [Start] S_JDA | +0x7c8 | + +- n = 1·2 · 계산 쪽 첨자 = 단가 칸 번호([in_stack+0x18]). + +### 2.2 경로 A — EXRNM 참 (0x437aa2~0x437e2f) + +- 조건: 계산 종류 3~8·10 · 줄 코드 'S' · 줄 단위 $·$·€·¥. +- 율 r: + - € = EXEUR/1000. + - ¥ = EXYEN/100000. + - $·$ = IIF(줄 T < 100000, EXL, EXH)/1000. +- S = MROUNDUD(S × r, ECD, 0) — 천원 단위 · ECD 자리 아래 버림. +- 단위 → 「천원」 · T = S. +- 상위 B·천원 갈래(2.3 과 같은 자리 0x435600~0x43590d)에서는 수량 칸 = 1.0 · 단위 「천원」. + +### 2.3 경로 B — EXRNM 거짓 (0x435600~0x43590d) + +- 조건: 상위 코드 B · 「천원」 비교 참. +- 줄 단위: + - 「천원」 → 수량 칸(+0x128[계열]) = 1.0. + - $·$·€·¥ → 수량 칸 = r(2.2 와 같은 율) · 단가는 외화 그대로. +- 유효수량 +0x1a0 = 수량 칸(0x43590d). +- 비목 금액 = ADDBJVAL(단가 × 유효수량)(0x437303~). +- 상수: 0x439d2c 「천원」 · 0x439d3c 「$」 · 0x439d48 「$」 · 0x439d70 「€」 · 0x439d80 「¥」 · 0x439d64 100000.0f · 0x439d74 1000.0f. + +### 2.4 두 경로 금액 + +- A = 줄끝수(1.0 × MROUNDUD(S × r, ECD, 0)) · B = 줄끝수(r × S). +- S × r 이 ECD 자리 안에서 끝나면 같음. 아니면 A 가 버린 만큼 작음. + - 예: $123.45 · EXL 1289 · ECD 0 → A 159 · B 159.12705(BPN 1 → 159.1). +- ⇒ 같지 않음(ECD 버림 차이). + +### 2.5 미확인 + +- 경로 B 첫 「천원」 비교 문자열의 출처(상위 단위로 추정되나 SmallString 인자 미복원). +- EXRNM 거짓 · 상위 X 등 그 밖 줄의 금액 단계 환산 0x438130~(율 [in_stack−0x98]) 금액식. + +## 3. 수량 계산기 반올림 (F1-36) — 확인 + +- wM_Edit_XRate 일일수량 Q_11 · 적용수량 Q_p = MROUNDUD(x, d, 선택 1) (REA 30). +- MROUNDUD 선택 1 = 첫 버림 자리 ≥ 5 이면 한 단위 올림 · 0 반대쪽 (REA 32 §1.1 · DP_Common 0x4544f0). +- 예: 1 ÷ 8 = 0.125 · 2자리 → 0.13. + +## 4. 적용기준 콤보 · 행자부 RATE_M (F2-24) — 짝 확인 · 조회 규칙 확인 + +### 4.1 콤보 값 + +- TWM_KANJUB.dfm cmBx_Set_Base(태그 65): + - Items = 일반(국가계약법) · 일반(지방계약법) · 행자부기준. + - Values = 2 · 0 · 1. + - 34 §5.2·§17.5 「DFM 에 Values 없음」 정정. +- 저장 = TwCombo.GetInteger = Values 값. + - 방증: 같은 방식으로 읽는 공사종류를 원본이 8·9 와 비교(0x47fa24) — 8 항목 콤보 순번으로는 나올 수 없는 값. + - 방증: 건설기계 구분 −1 갈래. +- ⇒ I_SET_BASE 1 = 행자부기준 · 0 = 지방계약법 · 2 = 국가계약법. +- 실물 7건 모두 0. + +### 4.2 행자부(SET_BASE 1) 조회 (ST_KanJub 0x47a1bc · 0x47acd8~0x47b100) + +- 규모 b: + - 밑수 < G[2](50억) → 0 · < G[3](300억) → 1 · 그 밖 2. + - 밑수 = 원가 칸 0x4e4260 첫 값 — RATE_R 규모 조회와 같은 칸. +- 간접노무비 RATE_M: + - 공사종류 < 5 · I_ILBAN ≠ 1 → Go(b+11) · 칸 `RATE{기간 + IIF(공사종류 ∈ {1,3}, 5, 0)}`. + - I_ILBAN 1 또는 공사종류 ≥ 5 → Go(b+15) · `RATE{기간+5}`. + - 기간 = [0x504840]. +- 일반관리비 = Go(23) RATE1. +- 이윤 = Go(24) RATE0. +- 그 밖 갈래(SET_BASE ≠ 1): + - 일반관리비 = RATE_R Go(21) RATE_11 · 공사종류 5 = Go(1) RATE_31. + - 이윤 = Go(21) RATE_16. +- 이윤 상한 10: (전역 [0x4d26cc+1] ≠ 0 또는 (S_JDA 거짓 · PCLASS 9)) · 이윤 > 10. +- 실물 RATE_M(25×10): 11~13·15~17 줄 간접노무비 · 23 줄 RATE1 6.0 · 24 줄 RATE0 15.0 → 줄 번호 1부터와 맞음. + +### 4.3 앱과 다른 점(보고만) + +- 앱 RATE_R 조회는 일반관리비·이윤을 규모 묶음 머리 줄에서 읽음 · 전문공사 일반관리비 15열. +- 원본 0x47a1bc 는 21줄 고정 · 전문공사 갈래 없음 → 50억 이상·전문공사에서 갈릴 수 있음. +- 실물 7건은 모두 50억 미만·I_ILBAN 0. + +## 5. 앱 반영 + +- calc.js: + - `stdMarketUnit`(S_JDA · ACTTYP · ACTOPT · 칸 n). + - calcBoq A 줄 → COSTA 나눔 · 넷째 칸 A(aAmt · directA · T 포함). +- smt_engine.js: + - costnLookup 이 COSTA A 줄을 나눔 단가로 돌려줌. + - fxOf 키 없음 = 1000. + - compositionOptions.exrnm. +- smt_eval.js: + - EXRNM 참 → S 줄만 MROUNDUD(·, ECD, 0) · $ 인식 · 고액 환율 0 대체 제거. +- server.py api_load: + - COSTA 풀어 읽기(costa_rows) · sim_state.stdMarketItems · sysConfig.stdMarket. + - A 임시 일위대가 걷기. +- calc_xrate.js: q = MROUNDUD 선택 1(exec_calc 원형). +- kanjub_parts.js NATIVE: `SET_BASE`(Values↔Items) · `rateMLookup`. +- 시험: + - resources/tester/test_stmate_std_market.py. + - resources/tester/test_stmate_xrate_round.py. diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_kj_0x47a1bc_요율조회.txt b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_kj_0x47a1bc_요율조회.txt new file mode 100644 index 000000000..29ee69d6d --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_kj_0x47a1bc_요율조회.txt @@ -0,0 +1,1104 @@ + +/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */ + +void FUN_0047a1bc(undefined4 param_1,int param_2) + +{ + ulonglong uVar1; + undefined1 *puVar2; + undefined4 uVar3; + undefined *puVar4; + int iVar5; + uint extraout_EDX; + uint extraout_EDX_00; + uint extraout_EDX_01; + uint uVar6; + undefined4 unaff_EDI; + undefined4 *in_FS_OFFSET; + float10 in_ST0; + float10 fVar7; + float10 fVar8; + float10 fVar9; + float10 fVar10; + float10 fVar11; + float10 fVar12; + float10 in_ST1; + float10 in_ST2; + float10 fVar13; + float10 in_ST3; + float10 in_ST4; + float10 in_ST5; + float10 in_ST6; + float10 in_ST7; + undefined4 local_1c4; + undefined4 local_1c0; + undefined4 local_1bc; + undefined4 local_1b8; + undefined4 local_1b4; + undefined4 local_1b0; + undefined4 local_1ac; + undefined4 local_1a8; + undefined4 local_1a4; + undefined4 local_1a0; + undefined4 local_19c; + undefined4 local_198; + undefined4 local_194; + undefined4 local_190; + undefined4 local_18c; + undefined4 local_188; + undefined4 local_184; + undefined4 local_180; + undefined4 local_17c; + undefined4 local_178; + int local_174; + undefined4 local_170; + undefined4 local_16c; + undefined4 local_168; + undefined4 local_164; + undefined4 local_160; + undefined4 local_15c; + undefined4 local_158; + undefined4 local_154; + undefined4 local_150 [2]; + int local_148; + undefined4 local_144; + undefined1 local_140 [16]; + undefined1 local_130 [16]; + undefined4 local_120; + undefined4 local_11c; + undefined4 local_118; + undefined4 local_114; + undefined4 local_110 [2]; + int local_108; + undefined4 local_104; + undefined1 local_100 [4]; + undefined4 local_fc; + undefined4 local_f8; + undefined4 local_f4; + undefined1 local_f0 [16]; + undefined4 local_e0; + undefined4 local_dc; + undefined4 local_d8; + int local_d4; + undefined4 local_d0 [2]; + undefined4 local_c8; + undefined4 local_c4; + undefined1 local_c0 [16]; + undefined1 local_b0 [16]; + undefined4 local_a0; + undefined4 local_9c; + undefined4 local_98; + undefined4 local_94; + undefined4 local_90 [2]; + undefined4 local_88; + undefined4 local_84; + undefined1 local_80 [4]; + undefined4 local_7c; + undefined4 local_78; + undefined4 local_74; + undefined1 local_70 [4]; + undefined4 uStack_6c; + undefined1 *puStack_68; + undefined4 uStack_64; + undefined4 local_60; + undefined1 *local_5c; + undefined4 local_58; + undefined4 local_54; + undefined4 local_50; + undefined4 local_4c; + int local_48; + undefined4 local_44; + undefined4 local_40; + undefined4 uStack_3c; + undefined4 uStack_38; + undefined4 uStack_34; + int local_30; + int local_2c; + undefined4 local_28; + undefined4 local_24; + undefined1 *local_20; + undefined1 *local_1c; + uint local_c; + + local_28 = &stack0xfffffffc; + iVar5 = 0x38; + do { + iVar5 = iVar5 + -1; + } while (iVar5 != 0); + _local_1c = (double)CONCAT44(unaff_EDI,&stack0xfffffffc); + local_20 = &LAB_0047b71f; + *in_FS_OFFSET = &local_24; + if (param_2 == 2) { + if ((DAT_004f4818 == 1) && + ((PTR_DAT_004d26cc[1] != '\0' || + ((*(char *)(*(int *)PTR_DAT_004d270c + 0x7c8) == '\0' && (DAT_004f48d0 == '\t')))))) { + local_24 = 0x17c83; + } + else { + local_24 = 0xe8ec458b; + } + DAT_004f483c = 1; + DAT_004f4840 = 0; + DAT_004f48dc = 1; + local_2c = 0x47a259; + FUN_00479ae8(); + local_28._0_2_ = 0xa261; + local_28._2_2_ = 0x47; + FUN_00483254(local_20); + } + else { + if ((PTR_DAT_004d26cc[1] == '\0') && + ((*(char *)(*(int *)PTR_DAT_004d270c + 0x7c8) != '\0' || (DAT_004f48d0 != '\t')))) { + local_24 = 0xe8ec458b; + } + else { + DAT_004f4818 = 1; + DAT_004f481c = 1; + local_24 = 0x17c83; + } + local_28._0_2_ = 0xa2c5; + local_28._2_2_ = 0x47; + _Urcombos_TwCombo_SetValueIndex_qqri(0xe8c0458d,0); + local_28._0_2_ = 0xa2d4; + local_28._2_2_ = 0x47; + _Urcombos_TwCombo_SetValueIndex_qqri(*(undefined4 *)(local_20 + 0xf58),0); + if (0 < DAT_004f4858) { + DAT_004f48b4 = 0; + } + DAT_004f46e8 = 0; + DAT_004f46ec = 0; + local_28._0_2_ = 0xa2ff; + local_28._2_2_ = 0x47; + (**(code **)(**(int **)(local_20 + 0xecc) + 200))(*(int **)(local_20 + 0xecc),0); + if (DAT_004f484c - 8 < 2) { + DAT_004f4894 = 0; + DAT_004f483c = 1; + DAT_004f4840 = 0; + DAT_004f48dc = 1; + DAT_004f46f8 = 0.0; + DAT_004f4884 = 1; + if ((DAT_004f48d0 == '\a') && ('\x01' < DAT_004f48d3)) { + DAT_004f4884 = 2; + } + local_28._0_2_ = 0xa373; + local_28._2_2_ = 0x47; + _Urcombos_TwCombo_SetInteger_qqri(*(undefined4 *)(local_20 + 0xf48),DAT_004f4884); + DAT_004f4868 = (uint)(*PTR_DAT_004d26cc == '\x04'); + local_28._0_2_ = 0xa3a4; + local_28._2_2_ = 0x47; + _Urcombos_TwCombo_SetInteger_qqri(*(undefined4 *)(local_20 + 0xf68),DAT_004f4868); + local_28._0_2_ = 0xa3bc; + local_28._2_2_ = 0x47; + (**(code **)(**(int **)(local_20 + 0xf68) + 100)) + (*(int **)(local_20 + 0xf68),*PTR_DAT_004d26cc != '\x04'); + local_2c = 0x47a3c2; + local_28 = &stack0xfffffffc; + FUN_00479ae8(); + DAT_004f4728 = 0; + DAT_004f472c = 0; + DAT_004f4730 = 0; + DAT_004f4734 = 0; + DAT_004f4738 = 0; + DAT_004f473c = 0; + DAT_004e43d0 = 0; + DAT_004e43d4 = 0; + DAT_004e43d8 = 0; + DAT_004e43dc = 0; + DAT_004e43e0 = 0; + DAT_004e43e4 = 0; + DAT_004f46f0 = 0.0; + DAT_004f4740 = 0.0; + DAT_004f4720 = 0.0; + DAT_004f47a0 = 0.0; + DAT_004e44f8._0_4_ = 0; + DAT_004e44f8._4_4_ = 0; + local_28._0_2_ = 0xa45a; + local_28._2_2_ = 0x47; + _System__VarFromInt_qqrr14System_Variantxixi(&local_50,6,1); + local_28._0_2_ = (undefined2)local_44; + local_28._2_2_ = (undefined2)((uint)local_44 >> 0x10); + local_2c = local_48; + local_30 = CONCAT22(local_4c._2_2_,(undefined2)local_4c); + uStack_34._0_2_ = (undefined2)local_50; + uStack_34._2_2_ = (undefined2)((uint)local_50 >> 0x10); + uStack_38 = 0x47a475; + uVar3 = _System__VarFromInt_qqrr14System_Variantxixi(&local_60,10,1); + uStack_38 = local_54; + uStack_3c = CONCAT22(local_58._2_2_,(undefined2)local_58); + local_40._0_2_ = SUB42(local_5c,0); + local_40._2_2_ = (undefined2)((uint)local_5c >> 0x10); + local_44 = local_60; + local_48 = CONCAT31((int3)((uint)uVar3 >> 8),DAT_004f484c == 8); + local_4c = &local_40; + local_50 = 0x47a495; + IIF(); + local_50 = 0x47a49d; + _System__VarToReal_qqrrx14System_Variant(&local_40); + DAT_004f47c0 = (double)in_ST0; + DAT_004f47c8 = 10.0; + DAT_004e4518._0_4_ = 0; + DAT_004e4518._4_4_ = 0; + DAT_004f4700 = 0.0; + DAT_004f48bc = 0; + DAT_004f48bd = 0; + local_50 = 0x47a4f0; + (**(code **)(**(int **)(local_20 + 0x480) + 200)) + (*(int **)(local_20 + 0x480),extraout_EDX & 0xffffff00); + local_50 = 0x47a506; + (**(code **)(**(int **)(local_20 + 0x484) + 200))(*(int **)(local_20 + 0x484),DAT_004f48bc); + local_50 = 0x47a51c; + (**(code **)(**(int **)(local_20 + 0x4cc) + 200))(*(int **)(local_20 + 0x4cc),DAT_004f48bd); + local_50 = 0x47a532; + (**(code **)(**(int **)(local_20 + 0x4d0) + 200))(*(int **)(local_20 + 0x4d0),DAT_004f48bd); + local_50 = 0x47a548; + (**(code **)(**(int **)(local_20 + 0x770) + 200))(*(int **)(local_20 + 0x770),DAT_004f48bc); + local_50 = 0x47a55e; + (**(code **)(**(int **)(local_20 + 0x774) + 200))(*(int **)(local_20 + 0x774),DAT_004f48bc); + local_50 = 0x47a574; + (**(code **)(**(int **)(local_20 + 0x920) + 200))(*(int **)(local_20 + 0x920),DAT_004f48bd); + local_50 = 0x47a58a; + (**(code **)(**(int **)(local_20 + 0x924) + 200))(*(int **)(local_20 + 0x924),DAT_004f48bd); + DAT_004f4828 = 0; + DAT_004f4708 = 0.0; + DAT_004f4710 = 0.0; + DAT_004f482c = 0; + DAT_004f4718 = 0.0; + DAT_004f4788 = 0.0; + DAT_004e4490 = 0.0; + DAT_004e4498 = 0.0; + DAT_004f4798 = 0.0; + DAT_004f47a8._0_4_ = 0; + DAT_004f47a8._4_4_ = 0; + DAT_004f47b0 = 0.0; + DAT_004f47b8 = 0.0; + DAT_004e4590._0_4_ = 0; + DAT_004e4590._4_4_ = 0; + DAT_004f48a0 = 3; + DAT_004f48a4 = 0; + DAT_004e45d8._0_4_ = DAT_004e45c8; + DAT_004e45d8._4_4_ = DAT_004e45cc; + DAT_004f48a8 = 3; + DAT_004f48ac = 0; + DAT_004e45e0._0_4_ = DAT_004e45d0; + DAT_004e45e0._4_4_ = DAT_004e45d4; + DAT_004f4890 = 0; + local_50 = 0x47a68c; + _Urcombos_TwCombo_SetInteger_qqri(*(undefined4 *)(local_20 + 0xf64),0); + local_28._0_2_ = 0xa697; + local_28._2_2_ = 0x47; + FUN_0047fa24(local_20,0,0); + DAT_004f48be = 0; + } + else { + DAT_004f4894 = 0; + DAT_004f483c = 1; + DAT_004f4840 = 0; + DAT_004f48dc = 1; + local_28._0_2_ = 0xa6d6; + local_28._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),0x2e); + local_28._0_2_ = 0xa6e8; + local_28._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),"RATE_01"); + DAT_004f46f8 = (double)in_ST0; + DAT_004f4884 = 1; + if ((DAT_004f48d0 == '\a') && ('\x01' < DAT_004f48d3)) { + DAT_004f4884 = 2; + } + local_28._0_2_ = 0xa725; + local_28._2_2_ = 0x47; + _Urcombos_TwCombo_SetInteger_qqri(*(undefined4 *)(local_20 + 0xf48),DAT_004f4884); + local_28._0_2_ = 0xa738; + local_28._2_2_ = 0x47; + _Urcombos_TwCombo_SetInteger_qqri(*(undefined4 *)(local_20 + 0x1120),DAT_004f4888); + DAT_004f4868 = (uint)(*PTR_DAT_004d26cc == '\x04'); + local_28._0_2_ = 0xa769; + local_28._2_2_ = 0x47; + _Urcombos_TwCombo_SetInteger_qqri(*(undefined4 *)(local_20 + 0xf68),DAT_004f4868); + local_28._0_2_ = 0xa781; + local_28._2_2_ = 0x47; + (**(code **)(**(int **)(local_20 + 0xf68) + 100)) + (*(int **)(local_20 + 0xf68),*PTR_DAT_004d26cc != '\x04'); + local_2c = 0x47a787; + local_28 = &stack0xfffffffc; + FUN_00479ae8(); + puVar2 = local_28; + if (DAT_004f484c == 5) { + if (*(double *)PTR_DAT_004d241c <= _DAT_004e4260) { + if (*(double *)(PTR_DAT_004d241c + 8) <= _DAT_004e4260) { + if (*(double *)(PTR_DAT_004d241c + 0x10) <= _DAT_004e4260) { + iVar5 = 0x10; + } + else { + iVar5 = 0xb; + } + } + else { + iVar5 = 6; + } + } + else { + iVar5 = 1; + } + local_28._0_2_ = 0xa7f5; + local_28._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),iVar5 + DAT_00504840,puVar2) + ; + } + else { + if (*(double *)(PTR_DAT_004d2700 + 0x40) <= _DAT_004e4260) { + if (*(double *)(PTR_DAT_004d2700 + 0x10) <= _DAT_004e4260) { + if (*(double *)(PTR_DAT_004d2700 + 0x20) <= _DAT_004e4260) { + if (*(double *)(PTR_DAT_004d2700 + 0x38) <= _DAT_004e4260) { + iVar5 = 0x29; + } + else { + iVar5 = 0x24; + } + } + else { + iVar5 = 0x1f; + } + } + else { + iVar5 = 0x15; + } + } + else { + iVar5 = 0xb; + } + local_28._0_2_ = 0xa874; + local_28._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),iVar5 + DAT_00504840,puVar2) + ; + } + switch(DAT_004f484c) { + case 0: + local_30 = 1; + break; + case 1: + local_30 = 4; + local_4c = (undefined4 *)CONCAT22(local_4c._2_2_,(undefined2)local_4c); + break; + case 2: + local_30 = 2; + local_4c = (undefined4 *)CONCAT22(local_4c._2_2_,(undefined2)local_4c); + break; + case 3: + local_30 = 3; + local_4c = (undefined4 *)CONCAT22(local_4c._2_2_,(undefined2)local_4c); + break; + case 4: + local_30 = 5; + local_4c = (undefined4 *)CONCAT22(local_4c._2_2_,(undefined2)local_4c); + break; + case 5: + local_28._0_2_ = 0xa8ed; + local_28._2_2_ = 0x47; + _System__VarFromInt_qqrr14System_Variantxixi(local_80,0x15,1); + local_28._0_2_ = (undefined2)local_74; + local_28._2_2_ = (undefined2)((uint)local_74 >> 0x10); + local_2c = local_78; + local_30 = local_7c; + uStack_34._0_2_ = local_80._0_2_; + uStack_34._2_2_ = local_80._2_2_; + uStack_38 = 0x47a90b; + _System__VarFromInt_qqrr14System_Variantxixi(local_90,1,1); + uStack_38 = local_84; + uStack_3c = local_88; + local_40._0_2_ = (undefined2)local_90[1]; + local_40._2_2_ = (undefined2)((uint)local_90[1] >> 0x10); + local_44 = local_90[0]; + puVar4 = PTR_DAT_004d26cc; + if ((PTR_DAT_004d26cc[1] == '\0') && + ((puVar4 = *(undefined **)PTR_DAT_004d270c, puVar4[0x7c8] != '\0' || + (DAT_004f48d0 != '\t')))) { + local_48 = 0; + } + else { + local_48 = CONCAT31((int3)((uint)puVar4 >> 8),1); + } + local_4c = (undefined4 *)local_70; + local_50 = 0x47a954; + IIF(); + local_50 = 0x47a95c; + local_30 = _System__VarToInt_qqrrx14System_Variant(local_70); + break; + default: + local_30 = 1; + local_4c = (undefined4 *)CONCAT22(local_4c._2_2_,(undefined2)local_4c); + } + fVar7 = (float10)local_30; + local_30 = SUB104(fVar7,0); + local_2c = (int)((unkuint10)fVar7 >> 0x20); + local_28._0_2_ = (undefined2)((unkuint10)fVar7 >> 0x40); + uStack_34._0_2_ = 0xa982; + uStack_34._2_2_ = 0x47; + fVar11 = in_ST7; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_98); + uStack_34._0_2_ = 0xa998; + uStack_34._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_94,"RATE_",local_98); + uStack_34._0_2_ = 0xa9ab; + uStack_34._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),local_94); + DAT_004f46f0 = (double)in_ST1; + fVar7 = in_ST2; + if (((DAT_004f484c != 5) && (iVar5 == 0xb)) && (DAT_004f46f0 == 0.0)) { + uStack_34._0_2_ = 0xa9e2; + uStack_34._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),DAT_00504840 + 0x15); + fVar7 = (float10)local_30; + uStack_3c = SUB104(fVar7,0); + uStack_38 = (undefined4)((unkuint10)fVar7 >> 0x20); + uStack_34._0_2_ = (undefined2)((unkuint10)fVar7 >> 0x40); + local_40._0_2_ = 0xa9fc; + local_40._2_2_ = 0x47; + fVar8 = fVar11; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_a0); + local_40._0_2_ = 0xaa12; + local_40._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_9c,"RATE_",local_a0); + local_40._0_2_ = 0xaa25; + local_40._2_2_ = 0x47; + fVar7 = in_ST3; + in_ST3 = in_ST4; + in_ST4 = in_ST5; + in_ST5 = in_ST6; + in_ST6 = in_ST7; + in_ST7 = fVar11; + fVar11 = fVar8; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),local_9c); + DAT_004f46f0 = (double)in_ST2; + } + if (((PTR_DAT_004d26cc[1] != '\0') || (DAT_004f484c == 5)) || + ((*(char *)(*(int *)PTR_DAT_004d270c + 0x7c8) == '\0' && (DAT_004f48d0 == '\t')))) { + uStack_34._0_2_ = 0xaa6e; + uStack_34._2_2_ = 0x47; + _System__VarFromInt_qqrr14System_Variantxixi(local_b0,iVar5,0xfc); + uStack_34 = local_b0; + uStack_38 = 0x47aa88; + _System__VarFromInt_qqrr14System_Variantxixi(local_d0,DAT_00504840,0xfc); + uStack_38 = local_c4; + uStack_3c = local_c8; + local_40._0_2_ = (undefined2)local_d0[1]; + local_40._2_2_ = (undefined2)((uint)local_d0[1] >> 0x10); + local_44 = local_d0[0]; + local_48 = 0x47aaaf; + uVar3 = _System__VarFromInt_qqrr14System_Variantxixi(&local_e0,0,1); + local_48 = local_d4; + local_4c._0_2_ = (undefined2)local_d8; + local_4c._2_2_ = (undefined2)((uint)local_d8 >> 0x10); + local_50 = local_dc; + local_54 = local_e0; + local_58._0_2_ = (undefined2)CONCAT31((int3)((uint)uVar3 >> 8),DAT_004f484c == 5); + local_58._2_2_ = (undefined2)((uint)uVar3 >> 0x10); + local_5c = local_c0; + local_60 = 0x47aade; + IIF(); + puVar2 = local_5c; + local_5c = (undefined1 *)0x47aaea; + _System__VarAdd_qqrr14System_Variantrx14System_Variant(puVar2,local_c0); + local_5c = (undefined1 *)0x47aaf5; + uVar3 = _System__VarToInt_qqrrx14System_Variant(local_b0); + local_5c = (undefined1 *)0x47aaff; + _Apodset_TApolloTable_Go_qqri(local_24,uVar3); + } + switch(DAT_004f484c) { + case 0: + local_30 = 6; + break; + case 1: + local_30 = 9; + local_58 = (undefined1 *)CONCAT22(local_58._2_2_,(undefined2)local_58); + break; + case 2: + local_30 = 7; + local_58 = (undefined1 *)CONCAT22(local_58._2_2_,(undefined2)local_58); + break; + case 3: + local_30 = 8; + local_58 = (undefined1 *)CONCAT22(local_58._2_2_,(undefined2)local_58); + break; + case 4: + local_30 = 10; + local_58 = (undefined1 *)CONCAT22(local_58._2_2_,(undefined2)local_58); + break; + case 5: + uStack_34._0_2_ = 0xab7b; + uStack_34._2_2_ = 0x47; + _System__VarFromInt_qqrr14System_Variantxixi(local_100,0x1a,1); + uStack_34._0_2_ = (undefined2)local_f4; + uStack_34._2_2_ = (undefined2)((uint)local_f4 >> 0x10); + uStack_38 = local_f8; + uStack_3c = local_fc; + local_40._0_2_ = local_100._0_2_; + local_40._2_2_ = local_100._2_2_; + local_44 = 0x47aba5; + _System__VarFromInt_qqrr14System_Variantxixi(local_110,6,1); + local_44 = local_104; + local_48 = local_108; + local_4c._0_2_ = (undefined2)local_110[1]; + local_4c._2_2_ = (undefined2)((uint)local_110[1] >> 0x10); + local_50 = local_110[0]; + puVar4 = PTR_DAT_004d26cc; + if ((PTR_DAT_004d26cc[1] == '\0') && + ((puVar4 = *(undefined **)PTR_DAT_004d270c, puVar4[0x7c8] != '\0' || + (DAT_004f48d0 != '\t')))) { + local_54 = 0; + } + else { + local_54 = CONCAT31((int3)((uint)puVar4 >> 8),1); + } + local_58 = local_f0; + local_5c = (undefined1 *)0x47abf4; + IIF(); + local_5c = (undefined1 *)0x47abff; + local_30 = _System__VarToInt_qqrrx14System_Variant(local_f0); + break; + default: + local_30 = 6; + local_58 = (undefined1 *)CONCAT22(local_58._2_2_,(undefined2)local_58); + } + fVar8 = (float10)local_30; + uStack_3c = SUB104(fVar8,0); + uStack_38 = (undefined4)((unkuint10)fVar8 >> 0x20); + uStack_34._0_2_ = (undefined2)((unkuint10)fVar8 >> 0x40); + local_40._0_2_ = 0xac25; + local_40._2_2_ = 0x47; + fVar8 = fVar11; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_118); + local_40._0_2_ = 0xac3b; + local_40._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_114,"RATE_",local_118); + local_40._0_2_ = 0xac49; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString(local_24,local_114); + DAT_004f4740 = (double)fVar7; + fVar7 = in_ST3; + if (((DAT_004f484c != 5) && (iVar5 == 0xb)) && (DAT_004f4740 == 0.0)) { + local_40._0_2_ = 0xac86; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),DAT_00504840 + 0x15); + fVar7 = (float10)local_30; + local_48 = SUB104(fVar7,0); + local_44 = (undefined4)((unkuint10)fVar7 >> 0x20); + local_40._0_2_ = (undefined2)((unkuint10)fVar7 >> 0x40); + local_4c._0_2_ = 0xaca0; + local_4c._2_2_ = 0x47; + fVar9 = fVar8; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_120); + local_4c._0_2_ = 0xacb6; + local_4c._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_11c,"RATE_",local_120); + local_4c._0_2_ = 0xacc4; + local_4c._2_2_ = 0x47; + fVar7 = in_ST4; + in_ST4 = in_ST5; + in_ST5 = in_ST6; + in_ST6 = in_ST7; + in_ST7 = fVar11; + fVar11 = fVar8; + fVar8 = fVar9; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString(local_24,local_11c); + DAT_004f4740 = (double)in_ST3; + } + fVar9 = fVar7; + if (DAT_004f4880 == 1) { + if (*(double *)(PTR_DAT_004d2468 + 0x10) <= _DAT_004e4260) { + if (*(double *)(PTR_DAT_004d2468 + 0x18) <= _DAT_004e4260) { + local_2c = 2; + } + else { + local_2c = 1; + } + } + else { + local_2c = 0; + } + if (DAT_004f484c < 5) { + if (DAT_004f4834 == 1) { + local_40._0_2_ = 0xad38; + local_40._2_2_ = 0x47; + fVar12 = fVar8; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x728),local_2c + 0xf); + local_30 = DAT_00504840 + 5; + fVar9 = in_ST4; + in_ST4 = in_ST5; + in_ST5 = in_ST6; + in_ST6 = in_ST7; + in_ST7 = fVar11; + fVar11 = fVar8; + fVar8 = fVar12; + } + else { + local_40._0_2_ = 0xad5b; + local_40._2_2_ = 0x47; + fVar12 = fVar8; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x728),local_2c + 0xb); + local_40._0_2_ = 0xad6e; + local_40._2_2_ = 0x47; + _System__VarFromInt_qqrr14System_Variantxixi(local_130,DAT_00504840,0xfc); + local_40 = local_130; + local_44 = 0x47ad84; + _System__VarFromInt_qqrr14System_Variantxixi(local_150,0,1); + local_44 = local_144; + local_48 = local_148; + local_4c._0_2_ = (undefined2)local_150[1]; + local_4c._2_2_ = (undefined2)((uint)local_150[1] >> 0x10); + local_50 = local_150[0]; + local_54 = 0x47adae; + _System__VarFromInt_qqrr14System_Variantxixi(&local_160,5,1); + local_54 = local_154; + local_58._0_2_ = (undefined2)local_158; + local_58._2_2_ = (undefined2)((uint)local_158 >> 0x10); + local_5c = (undefined1 *)local_15c; + local_60 = local_160; + if ((DAT_004f484c == 1) || (DAT_004f484c == 3)) { + uStack_64 = 1; + } + else { + uStack_64 = 0; + } + puStack_68 = local_140; + uStack_6c = 0x47ade9; + IIF(); + puVar2 = puStack_68; + puStack_68 = (undefined1 *)0x47adf5; + _System__VarAdd_qqrr14System_Variantrx14System_Variant(puVar2,local_140); + puStack_68 = (undefined1 *)0x47ae00; + local_30 = _System__VarToInt_qqrrx14System_Variant(local_130); + fVar9 = in_ST4; + in_ST4 = in_ST5; + in_ST5 = in_ST6; + in_ST6 = in_ST7; + in_ST7 = fVar11; + fVar11 = fVar8; + fVar8 = fVar12; + } + } + else { + local_40._0_2_ = 0xae18; + local_40._2_2_ = 0x47; + fVar12 = fVar8; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x728),local_2c + 0xf); + local_30 = DAT_00504840 + 5; + fVar9 = in_ST4; + in_ST4 = in_ST5; + in_ST5 = in_ST6; + in_ST6 = in_ST7; + in_ST7 = fVar11; + fVar11 = fVar8; + fVar8 = fVar12; + } + local_40._0_2_ = 0xae31; + local_40._2_2_ = 0x47; + _Sysutils_IntToStr_qqri(local_30,&local_168); + local_40._0_2_ = 0xae47; + local_40._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_164,&DAT_0047b768,local_168); + local_40._0_2_ = 0xae5a; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x728),local_164); + DAT_004f46f0 = (double)fVar7; + } + local_40._0_2_ = 0xae70; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),0x2f); + _local_1c = _DAT_004e4260 + (double)(ulonglong)local_c; + fVar7 = fVar9; + fVar12 = fVar8; + if (DAT_004f4830 < 3) { + local_174 = DAT_004f4830 + 0x10; + fVar7 = (float10)local_174; + local_48 = SUB104(fVar7,0); + local_44 = (undefined4)((unkuint10)fVar7 >> 0x20); + local_40._0_2_ = (undefined2)((unkuint10)fVar7 >> 0x40); + local_4c._0_2_ = 0xaeb0; + local_4c._2_2_ = 0x47; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_170); + local_4c._0_2_ = 0xaec6; + local_4c._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_16c,"RATE_",local_170); + local_4c._0_2_ = 0xaed9; + local_4c._2_2_ = 0x47; + fVar7 = in_ST4; + in_ST4 = in_ST5; + in_ST5 = in_ST6; + in_ST6 = in_ST7; + in_ST7 = fVar11; + fVar11 = fVar8; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),local_16c); + DAT_004f4720 = (double)fVar9; + } + local_40._0_2_ = 0xaeef; + local_40._2_2_ = 0x47; + fVar8 = fVar12; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),0x30); + if (DAT_004f484c == 5) { + DAT_004f47a0 = 0.0; + } + else if (DAT_004f4860 - 1U < 0xe) { + fVar8 = (float10)DAT_004f4860; + local_48 = SUB104(fVar8,0); + local_44 = (undefined4)((unkuint10)fVar8 >> 0x20); + local_40._0_2_ = (undefined2)((unkuint10)fVar8 >> 0x40); + local_4c._0_2_ = 0xaf31; + local_4c._2_2_ = 0x47; + fVar8 = fVar12; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_17c); + local_4c._0_2_ = 0xaf47; + local_4c._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_178,"RATE_",local_17c); + local_4c._0_2_ = 0xaf5a; + local_4c._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),local_178); + DAT_004f47a0 = (double)fVar7; + fVar7 = in_ST4; + in_ST4 = in_ST5; + in_ST5 = in_ST6; + in_ST6 = in_ST7; + in_ST7 = fVar11; + fVar11 = fVar12; + fVar12 = fVar8; + } + else { + DAT_004f47a0 = 0.0; + } + DAT_004e44f8._0_4_ = 0; + DAT_004e44f8._4_4_ = 0; + if (DAT_004f4880 == 1) { + local_40._0_2_ = 0xaf9a; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x728),0x17); + local_2c = 1; + local_40._0_2_ = 0xafaf; + local_40._2_2_ = 0x47; + _Sysutils_IntToStr_qqri(1,&local_184); + local_40._0_2_ = 0xafc5; + local_40._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_180,&DAT_0047b768,local_184); + local_40._0_2_ = 0xafd8; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x728),local_180); + DAT_004f47c0 = (double)fVar7; + } + else if (DAT_004f484c == 5) { + local_40._0_2_ = 0xafff; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x728),1); + local_2c = 0x1f; + local_40._0_2_ = 0xb014; + local_40._2_2_ = 0x47; + _Sysutils_IntToStr_qqri(0x1f,&local_18c); + local_40._0_2_ = 0xb02a; + local_40._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_188,"RATE_",local_18c); + local_40._0_2_ = 0xb03d; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),local_188); + DAT_004f47c0 = (double)fVar7; + } + else { + local_40._0_2_ = 0xb058; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),0x15); + fVar8 = (float10)0xb; + local_48 = SUB104(fVar8,0); + local_44 = (undefined4)((unkuint10)fVar8 >> 0x20); + local_40._0_2_ = (undefined2)((unkuint10)fVar8 >> 0x40); + local_4c._0_2_ = 0xb079; + local_4c._2_2_ = 0x47; + fVar8 = fVar12; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_194); + local_4c._0_2_ = 0xb08f; + local_4c._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_190,"RATE_",local_194); + local_4c._0_2_ = 0xb0a2; + local_4c._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),local_190); + DAT_004f47c0 = (double)fVar7; + } + if (DAT_004f4880 == 1) { + local_40._0_2_ = 0xb0c4; + local_40._2_2_ = 0x47; + fVar7 = fVar8; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x728),0x18); + local_2c = 0; + local_40._0_2_ = 0xb0d7; + local_40._2_2_ = 0x47; + _Sysutils_IntToStr_qqri(0,&local_19c); + local_40._0_2_ = 0xb0ed; + local_40._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_198,&DAT_0047b768,local_19c); + local_40._0_2_ = 0xb100; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x728),local_198); + } + else { + local_40._0_2_ = 0xb11b; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),0x15); + fVar7 = (float10)0x10; + local_48 = SUB104(fVar7,0); + local_44 = (undefined4)((unkuint10)fVar7 >> 0x20); + local_40._0_2_ = (undefined2)((unkuint10)fVar7 >> 0x40); + local_4c._0_2_ = 0xb13c; + local_4c._2_2_ = 0x47; + fVar7 = fVar8; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_1a4); + local_4c._0_2_ = 0xb152; + local_4c._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_1a0,"RATE_",local_1a4); + local_4c._0_2_ = 0xb165; + local_4c._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),local_1a0); + } + DAT_004f47c8 = (double)in_ST4; + if (((PTR_DAT_004d26cc[1] != '\0') || + ((*(char *)(*(int *)PTR_DAT_004d270c + 0x7c8) == '\0' && (DAT_004f48d0 == '\t')))) && + (10.0 < DAT_004f47c8)) { + DAT_004f47c8 = 10.0; + } + DAT_004e4518._0_4_ = 0; + DAT_004e4518._4_4_ = 0; + local_40._0_2_ = 0xb1d3; + local_40._2_2_ = 0x47; + fVar9 = fVar7; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),0x2e); + if (DAT_004f4870 - 1U < 7) { + local_174 = DAT_004f4870 + 10; + fVar9 = (float10)local_174; + local_48 = SUB104(fVar9,0); + local_44 = (undefined4)((unkuint10)fVar9 >> 0x20); + local_40._0_2_ = (undefined2)((unkuint10)fVar9 >> 0x40); + local_4c._0_2_ = 0xb20b; + local_4c._2_2_ = 0x47; + fVar9 = fVar7; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_1ac); + local_4c._0_2_ = 0xb221; + local_4c._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_1a8,"RATE_",local_1ac); + local_4c._0_2_ = 0xb234; + local_4c._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),local_1a8); + DAT_004f4700 = (double)in_ST5; + uVar6 = extraout_EDX_01; + in_ST5 = in_ST6; + in_ST6 = in_ST7; + in_ST7 = fVar11; + fVar11 = fVar12; + fVar12 = fVar8; + fVar8 = fVar7; + fVar7 = fVar9; + } + else { + DAT_004f4700 = 0.0; + uVar6 = extraout_EDX_00; + } + DAT_004f48bc = 0; + DAT_004f48bd = 0; + local_40._0_2_ = 0xb266; + local_40._2_2_ = 0x47; + (**(code **)(**(int **)(local_20 + 0x480) + 200)) + (*(int **)(local_20 + 0x480),uVar6 & 0xffffff00); + local_40._0_2_ = 0xb27c; + local_40._2_2_ = 0x47; + (**(code **)(**(int **)(local_20 + 0x484) + 200))(*(int **)(local_20 + 0x484),DAT_004f48bc); + local_40._0_2_ = 0xb292; + local_40._2_2_ = 0x47; + (**(code **)(**(int **)(local_20 + 0x4cc) + 200))(*(int **)(local_20 + 0x4cc),DAT_004f48bd); + local_40._0_2_ = 0xb2a8; + local_40._2_2_ = 0x47; + (**(code **)(**(int **)(local_20 + 0x4d0) + 200))(*(int **)(local_20 + 0x4d0),DAT_004f48bd); + local_40._0_2_ = 0xb2be; + local_40._2_2_ = 0x47; + (**(code **)(**(int **)(local_20 + 0x770) + 200))(*(int **)(local_20 + 0x770),DAT_004f48bc); + local_40._0_2_ = 0xb2d4; + local_40._2_2_ = 0x47; + (**(code **)(**(int **)(local_20 + 0x774) + 200))(*(int **)(local_20 + 0x774),DAT_004f48bc); + local_40._0_2_ = 0xb2ea; + local_40._2_2_ = 0x47; + (**(code **)(**(int **)(local_20 + 0x920) + 200))(*(int **)(local_20 + 0x920),DAT_004f48bd); + local_40._0_2_ = 0xb300; + local_40._2_2_ = 0x47; + (**(code **)(**(int **)(local_20 + 0x924) + 200))(*(int **)(local_20 + 0x924),DAT_004f48bd); + local_40._0_2_ = 0xb312; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),0x2f); + DAT_004f4828 = 0; + local_40._0_2_ = 0xb32c; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),"RATE_01"); + DAT_004f4708 = (double)in_ST5; + local_40._0_2_ = 0xb342; + local_40._2_2_ = 0x47; + fVar13 = fVar9; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),"RATE_11"); + DAT_004f4710 = (double)in_ST6; + local_40._0_2_ = 0xb358; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),0x2f); + DAT_004f482c = 0; + local_40._0_2_ = 0xb372; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),"RATE_06"); + DAT_004f4718 = (double)in_ST7; + if (*(int *)(*(int *)(local_20 + 0xde4) + 0x288) == 0) { + DAT_004f4708 = 0.0; + DAT_004f4710 = 0.0; + DAT_004f4718 = 0.0; + } + local_40._0_2_ = 0xb3b1; + local_40._2_2_ = 0x47; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),0x31); + if (*(double *)PTR_DAT_004d2738 <= _DAT_004e4260) { + if (*(double *)(PTR_DAT_004d2738 + 8) <= _DAT_004e4260) { + if (*(double *)(PTR_DAT_004d2738 + 0x10) <= _DAT_004e4260) { + if (*(double *)(PTR_DAT_004d2738 + 0x18) <= _DAT_004e4260) { + iVar5 = 10; + } + else { + iVar5 = 5; + } + } + else { + iVar5 = 0; + } + } + else { + iVar5 = 0x19; + } + } + else { + iVar5 = 0x14; + } + local_174 = iVar5 + 1; + fVar10 = (float10)local_174; + local_48 = SUB104(fVar10,0); + local_44 = (undefined4)((unkuint10)fVar10 >> 0x20); + local_40._0_2_ = (undefined2)((unkuint10)fVar10 >> 0x40); + local_4c._0_2_ = 0xb43c; + local_4c._2_2_ = 0x47; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_1b4); + local_4c._0_2_ = 0xb452; + local_4c._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_1b0,"RATE_",local_1b4); + local_4c._0_2_ = 0xb465; + local_4c._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),local_1b0); + DAT_004f4788 = (double)fVar11; + local_174 = iVar5 + 2; + fVar11 = (float10)local_174; + local_54 = SUB104(fVar11,0); + local_50 = (undefined4)((unkuint10)fVar11 >> 0x20); + local_4c._0_2_ = (undefined2)((unkuint10)fVar11 >> 0x40); + local_58._0_2_ = 0xb495; + local_58._2_2_ = 0x47; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_1bc); + local_58._0_2_ = 0xb4ab; + local_58._2_2_ = 0x47; + _System__LStrCat3_qqrv(&local_1b8,"RATE_",local_1bc); + local_58._0_2_ = 0xb4be; + local_58._2_2_ = 0x47; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),local_1b8); + DAT_004e4490 = (double)(fVar12 * (float10)1000.0); + local_174 = iVar5 + 3; + fVar11 = (float10)local_174; + local_60 = SUB104(fVar11,0); + local_5c = (undefined1 *)((unkuint10)fVar11 >> 0x20); + local_58._0_2_ = (undefined2)((unkuint10)fVar11 >> 0x40); + uStack_64 = 0x47b4f4; + _Sysutils_FormatFloat_qqrx17System_AnsiStringg(&DAT_0047b748,&local_1c4); + uStack_64 = 0x47b50a; + _System__LStrCat3_qqrv(&local_1c0,"RATE_",local_1c4); + uStack_64 = 0x47b51d; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),local_1c0); + DAT_004e4498 = (double)(fVar8 * (float10)1e+08); + if (((DAT_004f484c < 2) || (DAT_004f484c - 3 < 2)) && (DAT_004f4834 != 1)) { + uStack_64 = 0x47b556; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),0x15); + uStack_64 = 0x47b568; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),"RATE_19"); + DAT_004f4798 = (double)fVar7; + fVar7 = fVar9; + fVar9 = fVar13; + } + else { + DAT_004f4798 = 0.0; + } + DAT_004f47a8._0_4_ = 0; + DAT_004f47a8._4_4_ = 0; + uStack_64 = 0x47b59f; + _Apodset_TApolloTable_Go_qqri(*(undefined4 *)(local_20 + 0x490),0x32); + uStack_64 = 0x47b5b1; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),"RATE_21"); + DAT_004f47b0 = (double)fVar7; + uStack_64 = 0x47b5ca; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(local_20 + 0x490),"RATE_26"); + DAT_004f47b8 = (double)fVar9; + DAT_004e4590._0_4_ = 0; + DAT_004e4590._4_4_ = 0; + DAT_004f48a0 = 3; + DAT_004f48a4 = 0; + DAT_004e45d8._0_4_ = DAT_004e45c8; + DAT_004e45d8._4_4_ = DAT_004e45cc; + DAT_004f48a8 = 3; + DAT_004f48ac = 0; + DAT_004e45e0._0_4_ = DAT_004e45d0; + DAT_004e45e0._4_4_ = DAT_004e45d4; + DAT_004f4890 = 0; + if (((*(int *)PTR_DAT_004d26a4 == 7) && ('\x01' < DAT_004f48d3)) && + ((DAT_004f4828 != 1 && (DAT_004f482c != 1)))) { + DAT_004f4890 = 1; + } + uStack_64 = 0x47b67d; + _Urcombos_TwCombo_SetInteger_qqri(*(undefined4 *)(local_20 + 0xf64),DAT_004f4890); + local_28._0_2_ = 0xb688; + local_28._2_2_ = 0x47; + FUN_0047fa24(local_20,0,0); + DAT_004f48be = 0; + } + } + puVar2 = local_1c; + *in_FS_OFFSET = local_24; + uVar1 = (ulonglong)_local_1c >> 0x20; + _local_1c = (double)CONCAT44((int)uVar1,&LAB_0047b729); + local_20 = (undefined1 *)0x47b6ac; + _System__LStrArrayClr_qqrpvi(&local_1c4,0x14,puVar2); + local_20 = (undefined1 *)0x47b6bc; + _System__LStrArrayClr_qqrpvi(&local_170,4); + local_20 = (undefined1 *)0x47b6d2; + _System__FinalizeArray_qqrpvt1ui(&local_160,__xp_14System_Variant_exref,4); + local_20 = (undefined1 *)0x47b6e2; + _System__LStrArrayClr_qqrpvi(&local_120,4); + local_20 = (undefined1 *)0x47b6f8; + _System__FinalizeArray_qqrpvt1ui(local_110,__xp_14System_Variant_exref,7); + local_20 = (undefined1 *)0x47b708; + _System__LStrArrayClr_qqrpvi(&local_a0,4); + local_20 = (undefined1 *)0x47b71e; + _System__FinalizeArray_qqrpvt1ui(local_90,__xp_14System_Variant_exref,6); + return; +} + diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x42a828_설정로더_S_JDA_EXRNM.txt b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x42a828_설정로더_S_JDA_EXRNM.txt new file mode 100644 index 000000000..ef17dd156 --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x42a828_설정로더_S_JDA_EXRNM.txt @@ -0,0 +1,621 @@ + +/* WARNING: Removing unreachable block (ram,0x0042a950) */ + +void FUN_0042a828(void) + +{ + undefined1 *puVar1; + char cVar2; + undefined1 uVar3; + short sVar4; + int *piVar5; + undefined4 uVar6; + LPCSTR lpLibFileName; + FARPROC pFVar7; + int iVar8; + undefined4 *in_FS_OFFSET; + float10 in_ST0; + float10 in_ST1; + float10 in_ST2; + float10 in_ST3; + float10 in_ST4; + float10 in_ST5; + float10 in_ST6; + float10 in_ST7; + float10 fVar9; + undefined *puStackY_22c; + undefined4 uStack_21c; + undefined **ppuStack_218; + char *pcStack_1f4; + undefined4 uStack_1ec; + undefined4 ***local_184; + undefined4 local_180; + undefined4 local_17c; + undefined4 local_178; + undefined **local_174; + undefined *local_170; + undefined4 *local_16c; + undefined4 local_168; + undefined4 **local_164; + undefined4 local_160; + undefined **local_15c; + undefined4 local_158; + undefined **local_154; + undefined4 uStack_150; + undefined4 **ppuStack_14c; + undefined4 uStack_148; + undefined **local_144; + char *local_140; + undefined4 local_13c; + undefined ***local_138; + undefined4 ***local_134; + undefined *local_130; + undefined4 ***local_12c; + undefined4 ***local_128; + undefined *local_124; + undefined *local_120; + undefined **local_11c; + undefined *local_118; + undefined **local_114; + undefined ***local_110; + undefined *local_10c; + undefined ***local_108; + undefined4 ***local_104; + undefined *local_100; + undefined *local_fc; + undefined **local_f8; + undefined *local_f4; + undefined ***local_f0; + undefined4 ***local_ec; + undefined *local_e8; + undefined4 local_e4; + undefined4 *local_e0; + undefined *local_dc; + undefined *local_d8; + undefined **local_d4; + undefined *local_d0; + undefined ***local_cc; + undefined4 ***local_c8; + undefined *local_c4; + undefined **local_c0; + undefined ***local_bc; + undefined *local_b8; + undefined ***local_b4; + undefined4 local_b0; + undefined *local_ac; + undefined ***local_a8; + undefined4 ***local_a4; + undefined *local_a0; + undefined ***local_9c; + undefined4 ***local_98; + undefined *local_94; + undefined *local_90; + undefined ***local_8c; + undefined4 ***local_88; + undefined *local_84; + undefined *local_80; + undefined **local_7c; + undefined *puStack_78; + undefined *puStack_74; + undefined **ppuStack_70; + undefined *local_6c; + undefined **local_68; + undefined ***local_64; + undefined *local_60; + undefined *local_5c; + undefined **local_58; + undefined *local_54; + HMODULE local_50; + undefined4 ***local_4c; + HMODULE local_48; + undefined4 ***local_44; + undefined4 *local_40; + HMODULE local_3c; + HMODULE *local_38; + HMODULE local_34; + undefined4 *local_30; + HMODULE local_2c; + int local_28; + undefined4 local_24; + undefined1 *local_20; + undefined1 *local_1c; + undefined4 local_8; + + local_1c = &stack0xfffffffc; + iVar8 = 0x30; + do { + local_8 = 0; + iVar8 = iVar8 + -1; + } while (iVar8 != 0); + local_20 = &LAB_0042b6f3; + local_24 = *in_FS_OFFSET; + *in_FS_OFFSET = &local_24; + puVar1 = &stack0xfffffffc; + if (*(int *)(*(int *)PTR_DAT_005e5f8c + 0x5c) != 0) { + local_28 = 0x42a868; + _Sysutils_FreeAndNil_qqrpv(*(int *)PTR_DAT_005e5f8c + 0x5c); + puVar1 = local_1c; + } + local_1c = puVar1; + local_28 = 0x42a87f; + _System__LStrCat3_qqrv(&local_30,*(undefined4 *)(*(int *)PTR_DAT_005e5f8c + 0x38),"STini.MEM"); + local_28 = 0x42a887; + cVar2 = _Sysutils_FileExists_qqrx17System_AnsiString(local_30); + if (cVar2 == '\0') { + local_28 = 1; + local_2c = (HMODULE)0x42a8a4; + _System__LStrCat3_qqrv(&local_34,*(undefined4 *)(*(int *)PTR_DAT_005e5f8c + 0x38),"STini.MEM"); + local_2c = local_34; + local_30 = (undefined4 *)0x42a8bf; + _System__LStrCat3_qqrv(&local_38,*(undefined4 *)(*(int *)PTR_DAT_005e5f8c + 0x38),"START8X.INI") + ; + local_30 = local_38; + local_34 = (HMODULE)0x42a8c8; + COPY_FILE(); + } + else { + local_28 = 1; + local_2c = (HMODULE)0x42a8e3; + _System__LStrCat3_qqrv(&local_3c,*(undefined4 *)(*(int *)PTR_DAT_005e5f8c + 0x38),"Start8x.Ini") + ; + local_2c = local_3c; + local_30 = (undefined4 *)0x42a8fe; + _System__LStrCat3_qqrv(&local_40,*(undefined4 *)(*(int *)PTR_DAT_005e5f8c + 0x38),"STini.MEM"); + local_30 = local_40; + local_34 = (HMODULE)0x42a907; + COPY_FILE(); + } + local_34 = (HMODULE)0x42a91e; + _System__LStrCat3_qqrv(&local_44,*(undefined4 *)(*(int *)PTR_DAT_005e5f8c + 0x38),"STini.MEM"); + local_34 = (HMODULE)0x42a92d; + piVar5 = (int *)_Inifiles_TCustomIniFile__bctr_qqrx17System_AnsiString + (_Inifiles_TIniFile__exref,1,local_44); + *(int **)(*(int *)PTR_DAT_005e5f8c + 0x5c) = piVar5; + puVar1 = *(undefined1 **)PTR_DAT_005e6148; + puVar1[1] = 1; + local_34 = (HMODULE)&DAT_0042b74c; + local_38 = &local_48; + local_3c = (HMODULE)0x42a96d; + (**(code **)*piVar5)(piVar5,"Start","ACDNM"); + local_3c = local_48; + local_40 = (undefined4 *)0x42a976; + MSTRTODBL(); + local_40 = (undefined4 *)0x42a97b; + uVar3 = _System__ROUND_qqrv(); + puVar1[2] = uVar3; + local_40 = (undefined4 *)&DAT_0042b74c; + local_44 = (undefined4 ***)&local_50; + local_48 = (HMODULE)0x42a997; + (**(code **)*piVar5)(piVar5,"Start","ACDNM"); + local_48 = local_50; + local_4c = &local_4c; + local_50 = (HMODULE)0x42a9af; + (**(code **)*piVar5)(piVar5,"Start","BPNNM"); + local_50 = (HMODULE)local_4c; + local_54 = (undefined *)0x42a9b8; + MSTRTODBL(); + local_54 = (undefined *)0x42a9bd; + uVar3 = _System__ROUND_qqrv(); + puVar1[9] = uVar3; + local_54 = &DAT_0042b788; + local_58 = &local_54; + local_5c = (undefined *)0x42a9d9; + (**(code **)*piVar5)(piVar5,"Start","YCDNM"); + local_5c = local_54; + local_60 = (undefined *)0x42a9e2; + MSTRTODBL(); + local_60 = (undefined *)0x42a9e7; + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7c0) = uVar6; + local_60 = &DAT_0042b788; + local_64 = &local_58; + local_68 = (undefined **)0x42aa06; + (**(code **)*piVar5)(piVar5,"Start","BCDNM"); + local_68 = local_58; + local_6c = (undefined *)0x42aa0f; + MSTRTODBL(); + local_6c = (undefined *)0x42aa14; + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7a0) = uVar6; + local_6c = &DAT_0042b788; + ppuStack_70 = &local_5c; + puStack_74 = (undefined *)0x42aa33; + (**(code **)*piVar5)(piVar5,"Start","DCDNM"); + puStack_74 = local_5c; + puStack_78 = (undefined *)0x42aa3c; + MSTRTODBL(); + puStack_78 = (undefined *)0x42aa41; + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7a4) = uVar6; + puStack_78 = &DAT_0042b788; + local_7c = &local_60; + local_80 = (undefined *)0x42aa60; + (**(code **)*piVar5)(piVar5,"Start","ICDNM"); + local_80 = local_60; + local_84 = (undefined *)0x42aa69; + MSTRTODBL(); + local_84 = (undefined *)0x42aa6e; + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7a8) = uVar6; + local_84 = &DAT_0042b74c; + local_88 = &local_64; + local_8c = (undefined ***)0x42aa8d; + (**(code **)*piVar5)(piVar5,"Start","KCDNM"); + local_8c = local_64; + local_90 = (undefined *)0x42aa96; + MSTRTODBL(); + local_90 = (undefined *)0x42aa9b; + uVar3 = _System__ROUND_qqrv(); + puVar1[5] = uVar3; + local_90 = (undefined *)0x42aabe; + _System__VarFromPStr_qqrr14System_Variantrx28System__SmallString_iuc_255_(&local_8c,&local_90); + local_90 = local_80; + local_94 = local_84; + local_98 = local_88; + local_9c = local_8c; + local_a4 = (undefined4 ***)CONCAT22(local_a4._2_2_,0x3200); + local_a4 = (undefined4 ***)CONCAT31(local_a4._1_3_,1); + local_a0 = (undefined *)0x42aaf0; + uVar6 = _System__VarFromPStr_qqrr14System_Variantrx28System__SmallString_iuc_255_ + (&local_a0,&local_a4); + local_a0 = local_94; + local_a4 = local_98; + local_a8 = local_9c; + local_ac = local_94; + local_b0 = CONCAT31((int3)((uint)uVar6 >> 8),puVar1[5] == '\x02'); + local_b4 = &local_7c; + local_b8 = (undefined *)0x42ab19; + IIF(); + local_b8 = (undefined *)0x42ab24; + _System__VarToLStr_qqrr17System_AnsiStringrx14System_Variant(&local_6c,&local_7c); + local_b8 = local_6c; + local_bc = &local_68; + local_c0 = (undefined **)0x42ab3c; + (**(code **)*piVar5)(piVar5,"Start","JCDNM"); + local_c0 = local_68; + local_c4 = (undefined *)0x42ab45; + MSTRTODBL(); + local_c4 = (undefined *)0x42ab4a; + uVar3 = _System__ROUND_qqrv(); + puVar1[7] = uVar3; + local_c4 = &DAT_0042b788; + local_c8 = &local_a8; + local_cc = (undefined ***)0x42ab69; + (**(code **)*piVar5)(piVar5,"Start","ECDNM"); + local_cc = local_a8; + local_d0 = (undefined *)0x42ab75; + MSTRTODBL(); + local_d0 = (undefined *)0x42ab7a; + uVar3 = _System__ROUND_qqrv(); + puVar1[8] = uVar3; + local_d0 = &DAT_0042b788; + local_d4 = &local_ac; + local_d8 = (undefined *)0x42ab99; + (**(code **)*piVar5)(piVar5,"Start","LCDNM"); + local_d8 = local_ac; + local_dc = (undefined *)0x42aba5; + MSTRTODBL(); + local_dc = (undefined *)0x42abaa; + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7ac) = uVar6; + local_dc = &DAT_0042b788; + local_e0 = &local_b0; + local_e4 = 0x42abcc; + (**(code **)*piVar5)(piVar5,"Start","MCDNM"); + local_e4 = local_b0; + local_e8 = (undefined *)0x42abd8; + MSTRTODBL(); + local_e8 = (undefined *)0x42abdd; + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7b0) = uVar6; + local_e8 = &DAT_0042b824; + local_ec = &local_b4; + local_f0 = (undefined ***)0x42abff; + (**(code **)*piVar5)(piVar5,"Start","PCDNM"); + local_f0 = local_b4; + local_f4 = (undefined *)0x42ac0b; + MSTRTODBL(); + local_f4 = (undefined *)0x42ac10; + uVar3 = _System__ROUND_qqrv(); + *puVar1 = uVar3; + local_f4 = &DAT_0042b788; + local_f8 = &local_b8; + local_fc = (undefined *)0x42ac2e; + (**(code **)*piVar5)(piVar5,"Start","QCDNM"); + local_fc = local_b8; + local_100 = (undefined *)0x42ac3a; + MSTRTODBL(); + local_100 = (undefined *)0x42ac3f; + uVar3 = _System__ROUND_qqrv(); + puVar1[4] = uVar3; + local_100 = &DAT_0042b788; + local_104 = &local_bc; + local_108 = (undefined ***)0x42ac5e; + (**(code **)*piVar5)(piVar5,"Start","SCDNM"); + local_108 = local_bc; + local_10c = (undefined *)0x42ac6a; + MSTRTODBL(); + local_10c = (undefined *)0x42ac6f; + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7b4) = uVar6; + local_10c = &DAT_0042b788; + local_110 = &local_c0; + local_114 = (undefined **)0x42ac91; + (**(code **)*piVar5)(piVar5,"Start","WCDNM"); + local_114 = local_c0; + local_118 = (undefined *)0x42ac9d; + MSTRTODBL(); + local_118 = (undefined *)0x42aca2; + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7bc) = uVar6; + local_118 = &DAT_0042b788; + local_11c = &local_c4; + local_120 = (undefined *)0x42acc4; + (**(code **)*piVar5)(piVar5,"Start","XCDNM"); + local_120 = local_c4; + local_124 = (undefined *)0x42acd0; + MSTRTODBL(); + local_124 = (undefined *)0x42acd5; + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7b8) = uVar6; + local_124 = &DAT_0042b880; + local_128 = &local_c8; + local_12c = (undefined4 ***)0x42acf7; + (**(code **)*piVar5)(piVar5,"Start","ZCDNM"); + local_12c = local_c8; + local_130 = (undefined *)0x42ad03; + MSTRTODBL(); + local_130 = (undefined *)0x42ad08; + uVar3 = _System__ROUND_qqrv(); + puVar1[3] = uVar3; + local_130 = &DAT_0042b89c; + local_134 = &local_cc; + local_138 = (undefined ***)0x42ad27; + (**(code **)*piVar5)(piVar5,"Start","JUKNM"); + local_138 = local_cc; + local_13c = 0x42ad33; + MSTRTODBL(); + local_13c = 0x42ad38; + uVar3 = _System__ROUND_qqrv(); + puVar1[6] = uVar3; + local_13c = 1; + local_140 = (char *)0x42ad4e; + uVar3 = (**(code **)(*piVar5 + 0x10))(piVar5,"Start","USRPG"); + puVar1[0xc] = uVar3; + local_140 = "1/8 * 16/12 * 25/20"; + local_144 = &local_d0; + uStack_148 = 0x42ad6d; + (**(code **)*piVar5)(piVar5,"EQUIPMENT","RXXNM"); + uStack_148 = 0x42ad80; + _System__LStrToString_qqrv(puVar1 + 0x1f,local_d0,0xff); + uStack_148 = 0; + ppuStack_14c = &local_d4; + uStack_150 = 0x42ad99; + (**(code **)*piVar5)(piVar5,"EQUIPMENT","RXTNM"); + uStack_150 = 0x42adaf; + _System__LStrToString_qqrv(puVar1 + 0x11f,local_d4,0xff); + uStack_150 = 0; + local_154 = &local_d8; + local_158 = 0x42adc8; + (**(code **)*piVar5)(piVar5,"EQUIPMENT","RX1NM"); + local_158 = 0x42adde; + _System__LStrToString_qqrv(puVar1 + 0x21f,local_d8,0xff); + local_158 = 0; + local_15c = &local_dc; + local_160 = 0x42adf7; + (**(code **)*piVar5)(piVar5,"EQUIPMENT","RX2NM"); + local_160 = 0x42ae0d; + _System__LStrToString_qqrv(puVar1 + 799,local_dc,0xff); + local_160 = 0; + local_164 = &local_e0; + local_168 = 0x42ae26; + (**(code **)*piVar5)(piVar5,"EQUIPMENT","RX3NM"); + local_168 = 0x42ae3c; + _System__LStrToString_qqrv(puVar1 + 0x41f,local_e0,0xff); + local_168 = 0; + local_16c = &local_e4; + local_170 = (undefined *)0x42ae55; + (**(code **)*piVar5)(piVar5,"EQUIPMENT",&DAT_0042b948); + local_170 = (undefined *)0x42ae6b; + _System__LStrToString_qqrv(puVar1 + 0x51f,local_e4,0xff); + if ((*(char *)(*(int *)PTR_DAT_005e5e7c + 0x19ba) == '\x01') && + (*(char *)(*(int *)PTR_DAT_005e5f8c + 0x57) == '\x05')) { + local_170 = &DAT_0042b958; + local_174 = &local_e8; + local_178 = 0x42aea4; + (**(code **)*piVar5)(piVar5,"EQUIPMENT","RXNNM"); + local_178 = 0x42aeba; + _System__LStrToString_qqrv(puVar1 + 0x61f,local_e8,0xff); + } + local_170 = (undefined *)0x1; + local_174 = (undefined **)0x42aecd; + uVar3 = (**(code **)(*piVar5 + 0x10))(piVar5,"Start","CHGNM"); + puVar1[0x7c4] = uVar3; + local_174 = (undefined **)0x1; + local_178 = 0x42aee6; + local_178 = (**(code **)(*piVar5 + 0x10))(piVar5,"Start","CHGNM"); + local_17c = 0x42aef8; + uVar3 = (**(code **)(*piVar5 + 0x10))(piVar5,"Start","CHBNM"); + puVar1[0x7c6] = uVar3; + local_17c = 1; + local_180 = 0x42af11; + uVar3 = (**(code **)(*piVar5 + 0x10))(piVar5,"Start","CHNNM"); + puVar1[0x7c5] = uVar3; + local_180 = 0; + local_184 = (undefined4 ***)0x42af2a; + uVar3 = (**(code **)(*piVar5 + 0x10))(piVar5,"Start","CUTNM"); + puVar1[0x7ca] = uVar3; + local_184 = &local_ec; + (**(code **)*piVar5)(piVar5,"Start","OPTNM"); + _System__LStrCopy_qqrv(local_f0,1,3); + _System__LStrToString_qqrv(puVar1 + 0x7dc,local_ec,0xff); + local_28 = 1; + do { + _System__LStrFromString_qqrr17System_AnsiStringrx28System__SmallString_iuc_255_ + (&local_f4,puVar1 + 0x7dc); + _System__LStrFromChar_qqrr17System_AnsiStringc + (&local_f8,CONCAT31(0x42b9,(&UNK_0042b9cf)[local_28])); + cVar2 = MPOS(); + if (cVar2 == '\0') { + *(undefined4 *)(puVar1 + 0x7dc) = 0x4c4d5303; + break; + } + local_28 = local_28 + 1; + } while (local_28 != 4); + uVar3 = (**(code **)(*piVar5 + 0x10))(piVar5,"Start","S_JDA"); + puVar1[0x7c8] = uVar3; + local_28 = 1; + do { + _Sysutils_IntToStr_qqri(local_28,&local_104); + _System__LStrCat3_qqrv(&local_100,"EXLNM",local_104); + (**(code **)*piVar5)(piVar5,"EQUIPMENT",local_100); + MSTRTODBL(); + *(double *)(puVar1 + local_28 * 8 + 0x718) = (double)in_ST0; + fVar9 = in_ST7; + _Sysutils_IntToStr_qqri(local_28,&local_110); + _System__LStrCat3_qqrv(&local_10c,"EXHNM",local_110); + (**(code **)*piVar5)(piVar5,"EQUIPMENT",local_10c); + in_ST0 = in_ST4; + in_ST4 = fVar9; + MSTRTODBL(); + *(double *)(puVar1 + local_28 * 8 + 0x728) = (double)in_ST1; + fVar9 = in_ST4; + _Sysutils_IntToStr_qqri(local_28,&local_11c); + _System__LStrCat3_qqrv(&local_118,"EXEUR",local_11c); + (**(code **)*piVar5)(piVar5,"EQUIPMENT",local_118); + in_ST1 = in_ST5; + in_ST5 = fVar9; + MSTRTODBL(); + *(double *)(puVar1 + local_28 * 8 + 0x748) = (double)in_ST2; + fVar9 = in_ST5; + _Sysutils_IntToStr_qqri(local_28,&local_128); + _System__LStrCat3_qqrv(&local_124,"EXYEN",local_128); + (**(code **)*piVar5)(piVar5,"EQUIPMENT",local_124); + in_ST2 = in_ST6; + in_ST6 = fVar9; + MSTRTODBL(); + *(double *)(puVar1 + local_28 * 8 + 0x738) = (double)in_ST3; + local_28 = local_28 + 1; + in_ST3 = in_ST7; + in_ST7 = in_ST6; + } while (local_28 != 3); + uVar3 = (**(code **)(*piVar5 + 0x10))(piVar5,"EQUIPMENT","EXRNM"); + puVar1[0x7c9] = uVar3; + (**(code **)*piVar5)(piVar5,"NAG_HAL","NAGNM"); + MSTRTODBL(); + *(double *)(puVar1 + 0x760) = (double)in_ST0; + (**(code **)*piVar5)(piVar5,"NAG_HAL","ST_MHAL"); + MSTRTODBL(); + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7cc) = uVar6; + (**(code **)*piVar5)(piVar5,"NAG_HAL","EQ_LHAL"); + MSTRTODBL(); + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 2000) = uVar6; + (**(code **)*piVar5)(piVar5,"NAG_HAL","EQ_MHAL"); + MSTRTODBL(); + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7d4) = uVar6; + (**(code **)*piVar5)(piVar5,"NAG_HAL","EQ_SHAL"); + MSTRTODBL(); + uVar6 = _System__ROUND_qqrv(); + *(undefined4 *)(puVar1 + 0x7d8) = uVar6; + _Apodset_TApolloTable_SetTableName_qqr17System_AnsiString + (*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 0x1c),"BDQTY.DBF"); + _Apodset_TApolloTable_SetMasterSource_qqrp14Db_TDataSource + (*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 0x1c),0); + _Apodset_TApolloTable_SetMasterFields_qqrx17System_AnsiString + (*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 0x1c),0); + _Db_TDataSet_Open_qqrv(*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 0x1c)); + _Apodset_TApolloTable_SetIndexName_qqr17System_AnsiString + (*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 0x1c),"BDCODE"); + _Apodset_TApolloTable_GoTop_qqrv(*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 8)); + iVar8 = _Apodset_TApolloTable_ApolloLocate_qqr17System_AnsiStringusus + (*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 8),"CODE=\"X\"",0); + if ((0 < iVar8) && + (cVar2 = FUN_0042a680(*(int *)PTR_DAT_005e5f8c + 4,*(int *)PTR_DAT_005e5f8c + 0xc, + &stack0xfffffff0), cVar2 == '\0')) { + uStack_1ec = 1; + local_144 = (undefined **)&DAT_0042bb20; + local_140 = &DAT_0042bb3c; + pcStack_1f4 = (char *)0x1; + sVar4 = FUN_0044b680(*(undefined4 *)(*(int *)_Forms_Application_exref + 0x30),&DAT_0042bb78, + &DAT_0042bb50); + if (sVar4 != 2) goto LAB_0042b66c; + } + FUN_0042a680(*(int *)PTR_DAT_005e5f8c + 8,*(int *)PTR_DAT_005e5f8c + 0x10,&stack0xffffffec); + uStack_1ec = *(undefined4 *)(*(int *)PTR_DAT_005e6148 + 0x77c); + FUN_0042a680(*(int *)PTR_DAT_005e5f8c + 0x14,*(int *)PTR_DAT_005e5f8c + 0x24,&stack0xffffffe8); + pcStack_1f4 = "CON2D"; + FUN_0042a680(*(int *)PTR_DAT_005e5f8c + 0x18,*(int *)PTR_DAT_005e5f8c + 0x28,&local_1c); + FUN_0042a680(*(int *)PTR_DAT_005e5f8c + 0x1c,*(int *)PTR_DAT_005e5f8c + 0x2c,&local_20); + ppuStack_218 = (undefined **)0x42b497; + FUN_0042a680(*(int *)PTR_DAT_005e5f8c + 0x20,*(int *)PTR_DAT_005e5f8c + 0x30,&local_24); + _Db_TDataSet_Close_qqrv(*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 0x1c)); + if (2 < (byte)puVar1[2]) { + puVar1[2] = 1; + } + if (2 < (byte)puVar1[9]) { + puVar1[9] = 1; + } + if (2 < (byte)puVar1[5]) { + puVar1[5] = 1; + } + if (2 < (byte)puVar1[7]) { + _System__VarFromInt_qqrr14System_Variantxixi(&local_164,0,1); + ppuStack_218 = local_15c; + uStack_21c = local_160; + _System__VarFromInt_qqrr14System_Variantxixi(&local_174,2,1,local_164); + puStackY_22c = local_170; + IIF(); + uVar3 = _System__VarToInt_qqrrx14System_Variant(&local_154); + puVar1[7] = uVar3; + } + if (2 < (byte)puVar1[8]) { + puVar1[8] = 0; + } + if (1 < (byte)(puVar1[3] - 2)) { + puVar1[3] = 2; + } + _System__LStrFromString_qqrr17System_AnsiStringrx28System__SmallString_iuc_255_ + (&local_178,*(int *)PTR_DAT_005e5e7c + 0x106d); + _System__LStrCat_qqrv(&local_178,"ST_PRT.CPM"); + lpLibFileName = (LPCSTR)_System__LStrToPChar_qqrx17System_AnsiString(local_178); + ppuStack_218 = (undefined **)0x42b594; + local_2c = LoadLibraryA(lpLibFileName); + if (local_2c != (HMODULE)0x0) { + ppuStack_218 = (undefined **)&LAB_0042b62d; + uStack_21c = *in_FS_OFFSET; + *in_FS_OFFSET = &uStack_21c; + pFVar7 = GetProcAddress(local_2c,"GS_Prn_Rec"); + if (pFVar7 == (FARPROC)0x0) { + _System__LStrFromString_qqrr17System_AnsiStringrx28System__SmallString_iuc_255_ + (&local_180,*(int *)PTR_DAT_005e5e7c + 0x106d); + puStackY_22c = &DAT_0042bcd4; + _System__LStrCatN_qqrv(&local_17c,4); + FUN_0044a35c(local_17c); + } + else { + (*pFVar7)(); + } + *in_FS_OFFSET = puStackY_22c; + FreeLibrary(local_2c); + return; + } + _System__LStrFromString_qqrr17System_AnsiStringrx28System__SmallString_iuc_255_ + (&local_184,*(int *)PTR_DAT_005e5e7c + 0x106d); + _System__LStrCat_qqrv(&local_184,"ST_PRT.CPM"); + FUN_0044a080(local_184); +LAB_0042b66c: + *in_FS_OFFSET = pcStack_1f4; + _System__LStrArrayClr_qqrpvi(&local_184,4,uStack_1ec); + _System__FinalizeArray_qqrpvt1ui(&local_174,__xp_14System_Variant_exref,3); + _System__LStrArrayClr_qqrpvi(&local_13c,0x26); + _System__VarClr_qqrr14System_Variant(&local_a0); + _System__FinalizeArray_qqrpvt1ui(&local_8c,__xp_14System_Variant_exref,2); + _System__LStrArrayClr_qqrpvi(&local_6c,0x10); + _System__LStrArrayClr_qqrpvi(&local_24,6); + _System__LStrClr_qqrpv(&local_8); + return; +} + diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x43307c_발췌.txt b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x43307c_발췌.txt new file mode 100644 index 000000000..f55a6e51a --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x43307c_발췌.txt @@ -0,0 +1,526 @@ +# Ghidra main 0x43307c 발췌 — 줄 단가 다시 읽기(0x437a13) · 상위 B·천원 환율 칸(0x435600~0x43590d) · EXRNM 참 S 환산(0x437aa2~) +## 1205-1232 (줄 수량 칸 +0x128[계열]) + *(undefined2 *)(iVar15 + 0x1d5 + *puVar16 * 0x550) = 0x2001; + *(undefined2 *)(iVar15 + 0x1d9 + *puVar16 * 0x550) = 0x2001; + } + } +LAB_004353d3: + uVar5 = local_7c._2_2_; + uVar13 = *(int *)(in_stack_00000004 + 0x10) - 3; + local_7c._2_2_ = (undefined2)((uint)puVar16 >> 0x10); + uVar6 = local_7c._2_2_; + if ((uVar13 < 6) || (uVar13 == 7)) { + fVar26 = (float10)*(double *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8); + local_2c = (uint *)0x435407; + _System__VarFromReal_qqrv(local_608); + local_2c = local_5fc; + local_30._0_2_ = SUB42(local_608[2],0); + local_30._2_2_ = (undefined2)((uint)local_608[2] >> 0x10); + local_34._0_2_ = SUB42(local_608[1],0); + local_34._2_2_ = (undefined2)((uint)local_608[1] >> 0x10); + local_38 = local_608[0]; + fVar28 = (float10)*(double *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8) / + (float10)100.0; + local_3c = 0x5442; + uStack_3a = 0x43; + in_ST6 = in_ST4; + _System__VarFromReal_qqrv(local_618); + local_3c = (undefined2)local_60c; + uStack_3a = (undefined2)((uint)local_60c >> 0x10); + local_40 = local_610; +## 1300-1490 + local_7c._0_2_ = 0x5595; + local_7c._2_2_ = 0x43; + IIF(); + local_7c._0_2_ = 0x55a0; + local_7c._2_2_ = 0x43; + _System__VarToReal_qqrrx14System_Variant(local_628); + *(double *)(iVar15 + 0x1a8 + *puVar16 * 0x550) = (double)fVar28; + } + else { + local_7c._2_2_ = uVar5; + if (*(char *)(*(int *)PTR_DAT_005e5f8c + 0x69) == 'B') { + uVar22 = *(int *)PTR_DAT_005e5f8c == -0x179; + local_2c = (uint *)0x4355de; + _System__LStrFromString_qqrr17System_AnsiStringrx28System__SmallString_iuc_255_ + (&local_650); + local_2c = (uint *)0x4355ef; + _Sysutils_Trim_qqrx17System_AnsiString(local_650,&local_64c); + local_2c = (uint *)0x4355ff; + _System__LStrCmp_qqrv(local_64c,&DAT_00439d2c); + if ((bool)uVar22) { + local_2c = (uint *)0x43561f; + _Apodset_TApolloTable_GetString_qqr17System_AnsiString + (*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 8),&DAT_00439c10,&local_654); + local_2c = (uint *)0x43562d; + _Sysutils_Trim_qqrx17System_AnsiString(local_654,&stack0xffffffe4); + local_2c = (uint *)0x43563a; + _System__LStrCmp_qqrv(unaff_EDI,&DAT_00439d2c); + if ((bool)uVar22) { + iVar12 = iVar15 + *puVar16 * 0x550; + uVar13 = *puVar19; + *(undefined4 *)(iVar12 + 0x128 + uVar13 * 8) = 0; + *(undefined4 *)(iVar12 + 300 + uVar13 * 8) = 0x3ff00000; + local_a0 = (undefined1 *)CONCAT22(local_a0._2_2_,(short)local_a0); + } + else { + local_7c._0_2_ = 0x566d; + local_7c._2_2_ = 0x43; + _System__LStrCmp_qqrv(unaff_EDI,&DAT_00439d3c); + if (!(bool)uVar22) { + local_7c._0_2_ = 0x567c; + local_7c._2_2_ = 0x43; + _System__LStrCmp_qqrv(unaff_EDI,&DAT_00439d48); + if (!(bool)uVar22) { + local_7c._0_2_ = 0x57ea; + local_7c._2_2_ = 0x43; + _System__LStrCmp_qqrv(unaff_EDI,&DAT_00439d70); + if ((bool)uVar22) { + if ((*(int *)PTR_DAT_005e6148 == 0) || + (*(char *)(*(int *)PTR_DAT_005e6148 + 0x7c9) == '\0')) { + *(double *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8) = + *(double *) + (*(int *)PTR_DAT_005e6148 + 0x748 + + *(int *)(in_stack_00000004 + 0x18) * 8) / 1000.0; + local_a0 = (undefined1 *)CONCAT22(local_a0._2_2_,(short)local_a0); + } + else { + iVar12 = iVar15 + *puVar16 * 0x550; + uVar13 = *puVar19; + *(undefined4 *)(iVar12 + 0x128 + uVar13 * 8) = 0; + *(undefined4 *)(iVar12 + 300 + uVar13 * 8) = 0x3ff00000; + puVar18 = (undefined4 *)(iVar15 + 0x1c6 + *puVar16 * 0x550); + *puVar18 = 0xbfb5c304; + *(undefined1 *)(puVar18 + (uint)bVar25 * -2 + 1) = + (&DAT_00439d50)[(uint)bVar25 * -8]; + local_80 = puVar19; + local_7c._2_2_ = uVar6; + local_a0 = (undefined1 *)CONCAT22(local_a0._2_2_,(short)local_a0); + } + } + else { + local_7c._0_2_ = 0x5886; + local_7c._2_2_ = 0x43; + _System__LStrCmp_qqrv(unaff_EDI,&DAT_00439d80); + local_a0 = (undefined1 *)CONCAT22(local_a0._2_2_,(short)local_a0); + if ((bool)uVar22) { + if ((*(int *)PTR_DAT_005e6148 == 0) || + (*(char *)(*(int *)PTR_DAT_005e6148 + 0x7c9) == '\0')) { + *(double *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8) = + *(double *) + (*(int *)PTR_DAT_005e6148 + 0x738 + + *(int *)(in_stack_00000004 + 0x18) * 8) / 100000.0; + local_a0 = (undefined1 *)CONCAT22(local_a0._2_2_,(short)local_a0); + } + else { + iVar12 = iVar15 + *puVar16 * 0x550; + uVar13 = *puVar19; + *(undefined4 *)(iVar12 + 0x128 + uVar13 * 8) = 0; + *(undefined4 *)(iVar12 + 300 + uVar13 * 8) = 0x3ff00000; + puVar18 = (undefined4 *)(iVar15 + 0x1c6 + *puVar16 * 0x550); + *puVar18 = 0xbfb5c304; + *(undefined1 *)(puVar18 + (uint)bVar25 * -2 + 1) = + (&DAT_00439d50)[(uint)bVar25 * -8]; + local_80 = puVar19; + local_7c._2_2_ = uVar6; + local_a0 = (undefined1 *)CONCAT22(local_a0._2_2_,(short)local_a0); + } + } + } + goto LAB_0043590d; + } + } + if ((*(int *)PTR_DAT_005e6148 == 0) || + (*(char *)(*(int *)PTR_DAT_005e6148 + 0x7c9) == '\0')) { + fVar30 = (float10)*(double *) + (*(int *)PTR_DAT_005e6148 + 0x728 + + *(int *)(in_stack_00000004 + 0x18) * 8); + local_7c._0_2_ = 0x56f8; + local_7c._2_2_ = 0x43; + _System__VarFromReal_qqrv(local_674); + local_7c._0_2_ = (undefined2)local_668; + local_7c._2_2_ = (undefined2)((uint)local_668 >> 0x10); + local_80 = local_66c; + local_84._0_2_ = (undefined2)local_674._4_4_; + local_84._2_2_ = SUB42(local_674._4_4_,2); + local_88._0_2_ = (undefined2)local_674._0_4_; + local_88._2_2_ = SUB42(local_674._0_4_,2); + fVar28 = (float10)*(double *) + (*(int *)PTR_DAT_005e6148 + 0x718 + + *(int *)(in_stack_00000004 + 0x18) * 8); + local_8c = 0x435730; + _System__VarFromReal_qqrv(local_684); + local_8c = local_678; + local_90._0_2_ = (undefined2)local_684[2]; + local_90._2_2_ = (undefined2)((uint)local_684[2] >> 0x10); + local_94 = (undefined2)local_684[1]; + uStack_92 = (undefined2)((uint)local_684[1] >> 0x10); + local_98 = local_684[0]; + local_9c = 0x5767; + uStack_9a = 0x43; + _System__LStrCat3_qqrv + (&local_688,&DAT_00439d5c, + *(undefined4 *) + (PTR_PTR_005e5f40 + *(int *)(in_stack_00000004 + 0x18) * 4)); + local_9c = 0x577c; + uStack_9a = 0x43; + _Apodset_TApolloTable_GetDouble_qqr17System_AnsiString + (*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 8),local_688); + fVar26 = (float10)100000.0; + local_9c = (undefined2) + CONCAT31((int3)(CONCAT22(extraout_var, + (ushort)(fVar28 < fVar26) << 8 | + (ushort)(NAN(fVar28) || NAN(fVar26)) << 10 | + (ushort)(fVar28 == fVar26) << 0xe) >> 8), + fVar28 < fVar26 != 0); + local_a0 = local_664; + local_a4._0_2_ = 0x5795; + local_a4._2_2_ = 0x43; + in_ST6 = in_ST5; + uStack_9a = extraout_var; + IIF(); + local_a4 = local_664; + puStack_a8 = (undefined1 *)0x4357ae; + _System__VarFromInt_qqrr14System_Variantxixi(local_698,1000,2); + puVar10 = local_a4; + local_a4._0_2_ = 0x57ba; + local_a4._2_2_ = 0x43; + _System__VarRDiv_qqrr14System_Variantrx14System_Variant(puVar10,local_698); + local_a4._0_2_ = 0x57c5; + local_a4._2_2_ = 0x43; + _System__VarToReal_qqrrx14System_Variant(local_664); + *(double *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8) = (double)fVar30; + } + else { + iVar12 = iVar15 + *puVar16 * 0x550; + uVar13 = *puVar19; + *(undefined4 *)(iVar12 + 0x128 + uVar13 * 8) = 0; + *(undefined4 *)(iVar12 + 300 + uVar13 * 8) = 0x3ff00000; + puVar18 = (undefined4 *)(iVar15 + 0x1c6 + *puVar16 * 0x550); + *puVar18 = 0xbfb5c304; + *(undefined1 *)(puVar18 + (uint)bVar25 * -2 + 1) = + (&DAT_00439d50)[(uint)bVar25 * -8]; + local_80 = puVar19; + local_7c._2_2_ = uVar6; + local_a0 = (undefined1 *)CONCAT22(local_a0._2_2_,(short)local_a0); + } + } +LAB_0043590d: + uVar13 = *puVar16; + puVar18 = (undefined4 *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8); + *(undefined4 *)(iVar15 + 0x1a0 + uVar13 * 0x550) = *puVar18; + *(undefined4 *)(iVar15 + 0x1a4 + uVar13 * 0x550) = puVar18[1]; + uVar13 = *puVar16; + uVar4 = *puVar16; + *(undefined4 *)(iVar15 + 0x1a8 + uVar13 * 0x550) = + *(undefined4 *)(iVar15 + 0x1a0 + uVar4 * 0x550); + *(undefined4 *)(iVar15 + 0x1ac + uVar13 * 0x550) = + *(undefined4 *)(iVar15 + 0x1a4 + uVar4 * 0x550); + goto LAB_00436222; + } + } + local_2c = *(uint **)(*(int *)PTR_DAT_005e5f8c + 4); +## 1770-1800 · 1905-1930 (수량 칸 → 유효수량 +0x1a0) + *(undefined4 *)(iVar15 + 0x1a8 + uVar13 * 0x550) = + *(undefined4 *)(iVar15 + 0x1a0 + uVar4 * 0x550); + *(undefined4 *)(iVar15 + 0x1ac + uVar13 * 0x550) = + *(undefined4 *)(iVar15 + 0x1a4 + uVar4 * 0x550); + } + else { + if (*(double *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8) == 0.0) { + uVar13 = *puVar16; + *(undefined4 *)(iVar15 + 0x1a0 + uVar13 * 0x550) = 0; + *(undefined4 *)(iVar15 + 0x1a4 + uVar13 * 0x550) = 0; + } + else { + *(double *)(iVar15 + 0x1a0 + *puVar16 * 0x550) = + (double)(1.0 / (float)*(double *) + (iVar15 + *puVar16 * 0x550 + 0x128 + + *puVar19 * 8)); + } + uVar13 = *puVar16; + uVar4 = *puVar16; + *(undefined4 *)(iVar15 + 0x1a8 + uVar13 * 0x550) = + *(undefined4 *)(iVar15 + 0x1a0 + uVar4 * 0x550); + *(undefined4 *)(iVar15 + 0x1ac + uVar13 * 0x550) = + *(undefined4 *)(iVar15 + 0x1a4 + uVar4 * 0x550); + } + } + else { +LAB_00435fbd: + iVar12 = *(int *)PTR_DAT_005e6148; + puVar18 = (undefined4 *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8); + *puVar18 = *(undefined4 *)(iVar12 + 0x790); + puVar18[1] = *(undefined4 *)(iVar12 + 0x794); + } + } +LAB_00436222: + fVar26 = in_ST0; + if (*(double *)(iVar15 + 0x428 + *puVar16 * 0x550) != 0.0) { + local_7c._0_2_ = 0; + local_7c._2_2_ = 0; + local_80 = (uint *)0xb; + fVar26 = (float10)*(double *)(iVar15 + 0x1a0 + *puVar16 * 0x550) * + (float10)*(double *)(iVar15 + 0x428 + *puVar16 * 0x550); + local_8c = SUB104(fVar26,0); + local_88._0_2_ = (undefined2)((unkuint10)fVar26 >> 0x20); + local_88._2_2_ = (undefined2)((unkuint10)fVar26 >> 0x30); + local_84._0_2_ = (undefined2)((unkuint10)fVar26 >> 0x40); + local_90._0_2_ = 0x6264; + local_90._2_2_ = 0x43; + fVar26 = in_ST1; + in_ST1 = in_ST2; + in_ST2 = in_ST3; + in_ST3 = in_ST4; + in_ST4 = in_ST5; + in_ST5 = in_ST6; + MROUNDUD(); + *(double *)(iVar15 + 0x1a0 + *puVar16 * 0x550) = (double)in_ST0; + } + if (*(char *)(iVar15 + 0x1bd + *puVar16 * 0x550) == '%') { +## 2640-2725 (비목별 줄 금액 = 단가 × 유효수량 → ADDBJVAL) + _System__VarAdd_qqrr14System_Variantrx14System_Variant(puVar10,local_78c); + uStack_e4._0_2_ = 0x6675; + uStack_e4._2_2_ = 0x43; + _System__VarToReal_qqrrx14System_Variant(local_77c); + *(double *)(*(int *)PTR_DAT_005e5d84 + 200 + *puVar19 * 0x30) = (double)fVar28; + uVar13 = *puVar19; + iVar12 = *(int *)PTR_DAT_005e5d84; + *(undefined4 *)(iVar12 + 0xe8 + uVar13 * 0x30) = 0; + *(undefined4 *)(iVar12 + 0xec + uVar13 * 0x30) = 0; + *(double *)(*(int *)PTR_DAT_005e5d84 + 0xc0 + *puVar19 * 0x30) = + *(double *)(*(int *)PTR_DAT_005e5d84 + 200 + *puVar19 * 0x30) + + *(double *)(*(int *)PTR_DAT_005e5d84 + 0xd0 + *puVar19 * 0x30) + + *(double *)(*(int *)PTR_DAT_005e5d84 + 0xd8 + *puVar19 * 0x30) + + *(double *)(*(int *)PTR_DAT_005e5d84 + 0xe0 + *puVar19 * 0x30); + } + } +LAB_00437303: + fVar28 = (float10)*(double *)(*(int *)PTR_DAT_005e5d84 + 200 + *puVar19 * 0x30) * + (float10)*(double *)(iVar15 + 0x1a0 + *puVar16 * 0x550); + uStack_c4 = SUB104(fVar28,0); + uStack_c0 = (undefined4)((unkuint10)fVar28 >> 0x20); + uStack_bc._0_2_ = (undefined2)((unkuint10)fVar28 >> 0x40); + uStack_c8 = 0x7332; + uStack_c6 = 0x43; + fVar28 = in_ST6; + ADDBJVAL(); + *(double *)(in_stack_00000004 + -0x70) = (double)fVar26; + fVar26 = in_ST1; + if ((*(char *)(*(int *)PTR_DAT_005e5e7c + 0x19ba) == '\x01') && + (*(char *)(*(int *)PTR_DAT_005e5f8c + 0x57) == '\x05')) { + fVar26 = (float10)*(double *)(*(int *)PTR_DAT_005e5d84 + 0xe8 + *puVar19 * 0x30) * + (float10)*(double *)(iVar15 + 0x1a0 + *puVar16 * 0x550); + puStack_d0 = SUB104(fVar26,0); + uStack_cc = (undefined4)((unkuint10)fVar26 >> 0x20); + uStack_c8 = (undefined2)((unkuint10)fVar26 >> 0x40); + uStack_d4._0_2_ = 0x7385; + uStack_d4._2_2_ = 0x43; + fVar26 = in_ST2; + in_ST2 = in_ST3; + in_ST3 = in_ST4; + in_ST4 = in_ST5; + in_ST5 = in_ST6; + in_ST6 = fVar28; + ADDBJVAL(); + *(double *)(in_stack_00000004 + -0x50) = (double)in_ST1; + } + fVar30 = (float10)*(double *)(*(int *)PTR_DAT_005e5d84 + 0xd0 + *puVar19 * 0x30) * + (float10)*(double *)(iVar15 + 0x1a0 + *puVar16 * 0x550); + puStack_d0 = SUB104(fVar30,0); + uStack_cc = (undefined4)((unkuint10)fVar30 >> 0x20); + uStack_c8 = (undefined2)((unkuint10)fVar30 >> 0x40); + uStack_d4._0_2_ = 0x73bb; + uStack_d4._2_2_ = 0x43; + ADDBJVAL(); + *(double *)(in_stack_00000004 + -0x68) = (double)fVar26; + fVar26 = (float10)*(double *)(*(int *)PTR_DAT_005e5d84 + 0xd8 + *puVar19 * 0x30) * + (float10)*(double *)(iVar15 + 0x1a0 + *puVar16 * 0x550); + uStack_dc = SUB104(fVar26,0); + uStack_d8 = (undefined2)((unkuint10)fVar26 >> 0x20); + uStack_d6 = (undefined2)((unkuint10)fVar26 >> 0x30); + uStack_d4._0_2_ = (undefined2)((unkuint10)fVar26 >> 0x40); + uStack_e0._0_2_ = 0x73f1; + uStack_e0._2_2_ = 0x43; + ADDBJVAL(); + *(double *)(in_stack_00000004 + -0x60) = (double)in_ST2; + fVar26 = (float10)*(double *)(*(int *)PTR_DAT_005e5d84 + 0xe0 + *puVar19 * 0x30) * + (float10)*(double *)(iVar15 + 0x1a0 + *puVar16 * 0x550); + uStack_e8 = SUB104(fVar26,0); + uStack_e4._0_2_ = (undefined2)((unkuint10)fVar26 >> 0x20); + uStack_e4._2_2_ = (undefined2)((unkuint10)fVar26 >> 0x30); + uStack_e0._0_2_ = (undefined2)((unkuint10)fVar26 >> 0x40); + uStack_ec = 0x7427; + uStack_ea = 0x43; + ADDBJVAL(); + *(double *)(in_stack_00000004 + -0x58) = (double)in_ST3; + fVar26 = (float10)*(double *)(*(int *)PTR_DAT_005e5d84 + 0xc0 + *puVar19 * 0x30) * + (float10)*(double *)(iVar15 + 0x1a0 + *puVar16 * 0x550); + uStack_f4 = SUB104(fVar26,0); + uStack_f0 = (undefined2)((unkuint10)fVar26 >> 0x20); + uStack_ee = (undefined2)((unkuint10)fVar26 >> 0x30); + uStack_ec = (undefined2)((unkuint10)fVar26 >> 0x40); + uStack_f8 = 0x43745d; + ADDBJVAL(); + *(double *)(in_stack_00000004 + -0x78) = (double)in_ST4; + cVar8 = *(char *)(iVar15 + 0x1d4 + *puVar16 * 0x550); + if (((byte)(cVar8 + 0xb4U) < 2) || (cVar8 == 'S')) { +## 2970-3100 (A 줄 = COSTA · EXRNM 참 환산) + } + } + else { +LAB_00437a13: + if (((*(int *)(in_stack_00000004 + 0x10) - 1U < 3) || + ((*(int *)(in_stack_00000004 + 0x10) == 6 && (1 < (int)*puVar19)))) || + ((*(int *)(in_stack_00000004 + 0x10) - 7U < 2 && + ((*(int *)(in_stack_00000004 + 0x18) == 3 && (*puVar19 == 3)))))) { + if (*(char *)(iVar15 + 0x1b + *puVar16 * 0x550) == 'A') { + local_7c._0_2_ = (undefined2)*puVar19; + local_7c._2_2_ = (undefined2)(*puVar19 >> 0x10); + local_80 = (uint *)0x1; + local_84._0_2_ = 0x7a7c; + local_84._2_2_ = 0x43; + FUN_00430c60(iVar15 + *puVar16 * 0x550,*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 0xc), + *(undefined4 *)(in_stack_00000004 + 0x18)); + } + else { + local_7c._0_2_ = (undefined2)*puVar19; + local_7c._2_2_ = (undefined2)(*puVar19 >> 0x10); + local_80 = (uint *)0x0; + local_84._0_2_ = 0x7aa2; + local_84._2_2_ = 0x43; + FUN_00430c60(iVar15 + *puVar16 * 0x550,*(undefined4 *)(*(int *)PTR_DAT_005e6090 + 8), + *(undefined4 *)(in_stack_00000004 + 0x18)); + } + } + uVar13 = *(int *)(in_stack_00000004 + 0x10) - 3; + if ((uVar13 < 6) || (uVar13 == 7)) { + if ((*(int *)PTR_DAT_005e6148 != 0) && + ((*(char *)(*(int *)PTR_DAT_005e6148 + 0x7c9) != '\0' && + (uVar22 = *(char *)(iVar15 + 0x1b + *puVar16 * 0x550) == 'S', (bool)uVar22)))) { + local_7c._0_2_ = 0x7b04; + local_7c._2_2_ = 0x43; + _System__LStrFromString_qqrr17System_AnsiStringrx28System__SmallString_iuc_255_ + (&local_ad0,iVar15 + 0x1bb + *puVar16 * 0x550); + local_7c._0_2_ = 0x7b15; + local_7c._2_2_ = 0x43; + _Sysutils_Trim_qqrx17System_AnsiString(local_ad0,&local_acc); + local_7c._0_2_ = 0x7b25; + local_7c._2_2_ = 0x43; + _System__LStrCmp_qqrv(local_acc,&DAT_00439d3c); + if (!(bool)uVar22) { + local_7c._0_2_ = 0x7b43; + local_7c._2_2_ = 0x43; + _System__LStrFromString_qqrr17System_AnsiStringrx28System__SmallString_iuc_255_ + (&local_ad8,iVar15 + 0x1bb + *puVar16 * 0x550); + local_7c._0_2_ = 0x7b54; + local_7c._2_2_ = 0x43; + _Sysutils_Trim_qqrx17System_AnsiString(local_ad8,&local_ad4); + local_7c._0_2_ = 0x7b64; + local_7c._2_2_ = 0x43; + _System__LStrCmp_qqrv(local_ad4,&DAT_00439d48); + if (!(bool)uVar22) { + local_7c._0_2_ = 0x7b7e; + local_7c._2_2_ = 0x43; + _System__LStrFromString_qqrr17System_AnsiStringrx28System__SmallString_iuc_255_ + (&local_ae0,iVar15 + 0x1bb + *puVar16 * 0x550); + local_7c._0_2_ = 0x7b8f; + local_7c._2_2_ = 0x43; + _Sysutils_Trim_qqrx17System_AnsiString(local_ae0,&local_adc); + local_7c._0_2_ = 0x7b9f; + local_7c._2_2_ = 0x43; + _System__LStrCmp_qqrv(local_adc,&DAT_00439d70); + if (!(bool)uVar22) { + local_7c._0_2_ = 0x7bb9; + local_7c._2_2_ = 0x43; + _System__LStrFromString_qqrr17System_AnsiStringrx28System__SmallString_iuc_255_ + (&local_ae8,iVar15 + 0x1bb + *puVar16 * 0x550); + local_7c._0_2_ = 0x7bca; + local_7c._2_2_ = 0x43; + _Sysutils_Trim_qqrx17System_AnsiString(local_ae8,&local_ae4); + local_7c._0_2_ = 0x7bda; + local_7c._2_2_ = 0x43; + _System__LStrCmp_qqrv(local_ae4,&DAT_00439d80); + if (!(bool)uVar22) goto LAB_00437e32; + } + } + } + local_7c._0_2_ = 0x7bf8; + local_7c._2_2_ = 0x43; + _System__LStrFromString_qqrr17System_AnsiStringrx28System__SmallString_iuc_255_ + (&local_af0,iVar15 + 0x1bb + *puVar16 * 0x550); + local_7c._0_2_ = 0x7c09; + local_7c._2_2_ = 0x43; + _Sysutils_Trim_qqrx17System_AnsiString(local_af0,&local_aec); + local_7c._0_2_ = 0x7c19; + local_7c._2_2_ = 0x43; + _System__LStrCmp_qqrv(local_aec,&DAT_00439d70); + if ((bool)uVar22) { + *(double *)(in_stack_00000004 + -0x98) = + *(double *) + (*(int *)PTR_DAT_005e6148 + 0x748 + *(int *)(in_stack_00000004 + 0x18) * 8) / + 1000.0; + fVar28 = in_ST1; + in_ST1 = in_ST3; + in_ST3 = in_ST5; + } + else { + local_7c._0_2_ = 0x7c5d; + local_7c._2_2_ = 0x43; + _System__LStrFromString_qqrr17System_AnsiStringrx28System__SmallString_iuc_255_ + (&local_af8,iVar15 + 0x1bb + *puVar16 * 0x550); + local_7c._0_2_ = 0x7c6e; + local_7c._2_2_ = 0x43; + _Sysutils_Trim_qqrx17System_AnsiString(local_af8,&local_af4); + local_7c._0_2_ = 0x7c7e; + local_7c._2_2_ = 0x43; + _System__LStrCmp_qqrv(local_af4,&DAT_00439d80); + if ((bool)uVar22) { + *(double *)(in_stack_00000004 + -0x98) = + *(double *) + (*(int *)PTR_DAT_005e6148 + 0x738 + *(int *)(in_stack_00000004 + 0x18) * 8) / + 100000.0; + fVar28 = in_ST1; + in_ST1 = in_ST3; + in_ST3 = in_ST5; + } + else { + fVar31 = (float10)*(double *) + (*(int *)PTR_DAT_005e6148 + 0x728 + + *(int *)(in_stack_00000004 + 0x18) * 8); + local_7c._0_2_ = 0x7cca; + local_7c._2_2_ = 0x43; + _System__VarFromReal_qqrv(local_b18); + local_7c._0_2_ = (undefined2)local_b0c; + local_7c._2_2_ = (undefined2)((uint)local_b0c >> 0x10); + local_80 = (uint *)local_b10; + local_84._0_2_ = (undefined2)local_b18._4_4_; + local_84._2_2_ = SUB42(local_b18._4_4_,2); + local_88._0_2_ = (undefined2)local_b18._0_4_; +## 4525-4550 + _Sysutils_Trim_qqrx17System_AnsiString(local_1d0,&local_1cc); + local_30._0_2_ = 0x3635; + local_30._2_2_ = 0x43; + _System__LStrCmp_qqrv(local_1cc,&DAT_00439b64); + if ((bool)uVar22) { + uVar13 = *puVar16; + puVar18 = (undefined4 *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8); + *(undefined4 *)(iVar15 + 0x1a0 + uVar13 * 0x550) = *puVar18; + *(undefined4 *)(iVar15 + 0x1a4 + uVar13 * 0x550) = puVar18[1]; + } + else { + *(double *)(iVar15 + 0x1a0 + *puVar16 * 0x550) = + *(double *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8) / 100.0; + } + } + else if (*(double *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8) == 0.0) { + uVar13 = *puVar16; + *(undefined4 *)(iVar15 + 0x1a0 + uVar13 * 0x550) = 0; + *(undefined4 *)(iVar15 + 0x1a4 + uVar13 * 0x550) = 0; + } + else { + *(double *)(iVar15 + 0x1a0 + *puVar16 * 0x550) = + (double)(1.0 / (float)*(double *)(iVar15 + *puVar16 * 0x550 + 0x128 + *puVar19 * 8)); + } + if ((*(char *)(*(int *)PTR_DAT_005e5e7c + 0x19ba) == '\x01') && + (*(char *)(*(int *)PTR_DAT_005e5f8c + 0x57) == '\x05')) { diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x45c848_PRJLST로더_ACTTYP.asm.txt b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x45c848_PRJLST로더_ACTTYP.asm.txt new file mode 100644 index 000000000..baf32974e --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/Ghidra_main_0x45c848_PRJLST로더_ACTTYP.asm.txt @@ -0,0 +1,83 @@ +0x45c848: PUSH EBP +0x45c849: MOV EBP, ESP +0x45c84b: PUSH 0x0 +0x45c84d: PUSH 0x0 +0x45c84f: PUSH 0x0 +0x45c851: PUSH EBX +0x45c852: PUSH ESI +0x45c853: MOV ESI, EAX +0x45c855: XOR EAX, EAX +0x45c857: PUSH EBP +0x45c858: PUSH 0x45c977 +0x45c85d: PUSH dword ptr FS:[EAX] +0x45c860: MOV dword ptr FS:[EAX], ESP +0x45c863: MOV EAX, [0x005e5dfc] +0x45c868: MOV EAX, dword ptr [EAX] +0x45c86a: MOV EBX, EAX +0x45c86c: LEA ECX, [EBP + -0x8] +0x45c86f: MOV EDX, 0x45c98c +0x45c874: MOV EAX, ESI +0x45c876: CALL 0x00404790 +0x45c87b: MOV EAX, dword ptr [EBP + -0x8] +0x45c87e: LEA EDX, [EBP + -0x4] +0x45c881: CALL 0x00401e40 +0x45c886: MOV EDX, dword ptr [EBP + -0x4] +0x45c889: LEA EAX, [EBX + 0x928] +0x45c88f: MOV ECX, 0xff +0x45c894: CALL 0x00401298 +0x45c899: LEA ECX, [EBP + -0xc] +0x45c89c: MOV EDX, 0x45c99c +0x45c8a1: MOV EAX, ESI +0x45c8a3: CALL 0x00404790 +0x45c8a8: MOV EDX, dword ptr [EBP + -0xc] +0x45c8ab: LEA EAX, [EBX + 0x128] +0x45c8b1: MOV ECX, 0xff +0x45c8b6: CALL 0x00401298 +0x45c8bb: MOV EDX, 0x45c9ac +0x45c8c0: MOV EAX, ESI +0x45c8c2: CALL 0x00404778 +0x45c8c7: MOV word ptr [EBX + 0x1750], AX +0x45c8ce: MOV EDX, 0x45c9bc +0x45c8d3: MOV EAX, ESI +0x45c8d5: CALL 0x00404778 +0x45c8da: MOV word ptr [EBX + 0x1752], AX +0x45c8e1: MOV EDX, 0x45c9cc +0x45c8e6: MOV EAX, ESI +0x45c8e8: CALL 0x00404778 +0x45c8ed: MOV word ptr [EBX + 0x1754], AX +0x45c8f4: MOV EDX, 0x45c9dc +0x45c8f9: MOV EAX, ESI +0x45c8fb: CALL 0x00404780 +0x45c900: CMP AX, 0x1 +0x45c904: SBB EAX, EAX +0x45c906: INC EAX +0x45c907: MOV byte ptr [EBX + 0x52bd], AL +0x45c90d: MOV EDX, 0x45c9ec +0x45c912: MOV EAX, ESI +0x45c914: CALL 0x00404780 +0x45c919: CMP AX, 0x1 +0x45c91d: SBB EAX, EAX +0x45c91f: INC EAX +0x45c920: MOV byte ptr [EBX + 0x52be], AL +0x45c926: MOV EDX, 0x45c9fc +0x45c92b: MOV EAX, ESI +0x45c92d: CALL 0x00404778 +0x45c932: MOV dword ptr [EBX + 0x52b8], EAX +0x45c938: MOV EDX, 0x45ca0c +0x45c93d: MOV EAX, ESI +0x45c93f: CALL 0x00404778 +0x45c944: MOV dword ptr [EBX + 0x172c], EAX +0x45c94a: MOV EDX, 0x45ca1c +0x45c94f: MOV EAX, ESI +0x45c951: CALL 0x00404778 +0x45c956: MOV dword ptr [EBX + 0x1730], EAX +0x45c95c: XOR EAX, EAX +0x45c95e: POP EDX +0x45c95f: POP ECX +0x45c960: POP ECX +0x45c961: MOV dword ptr FS:[EAX], EDX +0x45c964: PUSH 0x45c97e +0x45c969: LEA EAX, [EBP + -0xc] +0x45c96c: MOV EDX, 0x3 +0x45c971: CALL 0x00401258 +0x45c976: RET \ No newline at end of file diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/evidence_ids.txt b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/evidence_ids.txt new file mode 100644 index 000000000..6ab9fe8e5 --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/evidence_ids.txt @@ -0,0 +1,9 @@ +kj_47a1bc ev_4ded8d98d2a16037b53d3b40a8e7b733e5cc9b14d52aa0896f6c7fc1c44c596a +loader_42b166 ev_8112ff8e59578982e808a3ccd9a95c381010288faf9fb7ed48ccccfa3f165951 +main_43307c ev_6a03bc19fb86d1f061dd4ccc6c3f9c8347924d406cf81a28294dcb93bef671a2 +open_main +open_kj +as_0x45c938 ev_03492f4e870a253f1a153291962a982e91a70f934d28c231c497117d05de240e +xr_0x45ca0c ev_b47e243fa2378a168088bfb5ca2f687127dc8292fc50c686aab4a35279959d56 +ss_acttyp ev_72931dd7a5ce247a89d29048e5af4bb76eecf82ee7ef88d48ab97c3debc65ed1 +rb_439d28 ev_70b05c0574df5ec386ca25cdd756707ba26c912824f55cf0eeeae24e5f6f5333 diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/read_bytes_0x439d28_상수.txt b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/read_bytes_0x439d28_상수.txt new file mode 100644 index 000000000..b6908caca --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/36_계산엔진_잔여_작업자료_20261114/REA_MCP/read_bytes_0x439d28_상수.txt @@ -0,0 +1,2 @@ +ev_70b05c0574df5ec386ca25cdd756707ba26c912824f55cf0eeeae24e5f6f5333 +04000000c3b5bff800000000ffffffff0100000024000000ffffffff02000000a3a4000004c3b5bff8000000ffffffff0400000054414d54000000000050c347ffffffff02000000a2e6000000007a44ffffffff02000000a1cd0000ffffffff02000000c0ce0000012c000001200000 diff --git a/resources/tester/helper_stmate_std.cjs b/resources/tester/helper_stmate_std.cjs new file mode 100644 index 000000000..a8a70be21 --- /dev/null +++ b/resources/tester/helper_stmate_std.cjs @@ -0,0 +1,48 @@ +// STMATE 재현 앱 — 표준시장단가(A) 내역·구성 · 외화 환산(EXRNM) · 행자부 RATE_M 조회 · stdin {mode, ...} → 결과 +// boq: calc.calculateAll 내역 줄 · comp: smt_engine 단가 읽기(costnLookup) + 구성 조립 · ratem: kanjub_parts.NATIVE.rateMLookup +globalThis.window = globalThis; +const C = require("../../tools/stmate-test/calc.js"); +const Parts = require("../../tools/stmate-test/kanjub_parts.js"); +require("../../tools/stmate-test/smt_eval.js"); +require("../../tools/stmate-test/smt_engine.js"); +const E = window.STMATE_ENGINE; +const V = window.STMATE_SMT_EVAL; + +const MODES = { + boq({ items, rows, std, slot }) { + const st = C.createDefaultState(); + Object.assign(st, { stdMarketItems: items, boqItems: rows }); + st.sysConfig.stdMarket = std; + const res = C.calculateAll(st); + const boq = slot === 2 ? res.boqRev : res.boqOrig; + const pick = (r) => ({ M: r.M, L: r.L, S: r.S, A: r.A, T: r.T, uL: r.lUnit, uM: r.mUnit }); + return { rows: boq.rows.map(pick), directA: boq.directA, directT: boq.directT }; + }, + comp({ cases }) { + return cases.map((c) => { + const ctx = { + dbfData: Object.assign({ start_ini: {}, costn_rows: [], costa_rows: [] }, c.data), + state: { sysConfig: {} }, + }; + const code = c.code || "B00001"; + const opts = E.compositionOptions(ctx, code, {}); + const { lookup } = E.costnLookup(ctx); + const ev = V.evaluateComposition(c.rows, lookup, opts); + return { M: ev.M, L: ev.L, S: ev.S, unit: c.peek ? lookup(c.peek) : null }; + }); + }, + ratem({ rows, cases }) { + return { + setBase: Parts.NATIVE.SET_BASE, + out: cases.map((o) => Parts.NATIVE.rateMLookup(rows, o)), + }; + }, +}; + +let buf = ""; +process.stdin.setEncoding("utf8"); +process.stdin.on("data", (d) => (buf += d)); +process.stdin.on("end", () => { + const req = JSON.parse(buf); + process.stdout.write(JSON.stringify(MODES[req.mode](req))); +}); diff --git a/resources/tester/test_stmate_smt_tools.py b/resources/tester/test_stmate_smt_tools.py index aade8fa56..7aef54f2a 100644 --- a/resources/tester/test_stmate_smt_tools.py +++ b/resources/tester/test_stmate_smt_tools.py @@ -1,7 +1,7 @@ """STMATE 재현 앱 계산 도구 — 노무·장비 수량 계산기(wM_Edit_XRate) · 실적→일식 비목율(wM_Conv_A2W). 근거: REA 30 labor_equipment_quantity_rules.json · REA 27 conversion_component_rate_rules.json — 손셈 대조. -수량 계산기 반올림(MROUNDUD) 방향은 미확정 — 반올림으로 둔 값은 경계가 아닌 수로만 봄. +수량 계산기 반올림 = MROUNDUD 선택 1(사사오입 · REA 32 §1.1) — 경계 값은 test_stmate_xrate_round. """ import json diff --git a/resources/tester/test_stmate_std_market.py b/resources/tester/test_stmate_std_market.py new file mode 100644 index 000000000..9637a08cb --- /dev/null +++ b/resources/tester/test_stmate_std_market.py @@ -0,0 +1,200 @@ +"""STMATE 재현 앱 — 표준시장단가(A 코드) 내역·구성 연결 · 외화 환산 EXRNM · 행자부 RATE_M 조회 · 적용기준 콤보 짝. + +근거(지식DB REA 36 · 34 §6·§11·§17): + 표준시장단가 단가 읽기 Main 0x430c60 — A 줄 = COSTA(0x437a4b) · S_JDA 참 = 저장 단가 · 거짓 = 0x45a468 나눔 + L0 = T×R/100 · X = T×(100−R)/100 · ACTOPT 0 절사 · 1 OPTIMIZ{L0,0,0,X}[0] · 2 OPTIMIZ{X,0,0,L0}[3](동률 = 앞 칸) + R = 0 이고 LAMTn_R 있으면 그 값이 노무 · 나머지 ACTTYP 1 재료 · 2 경비 · 0 넷째 칸(A) · ACTTYP·ACTOPT = PRJLST(0x45c938) + EXRNM 참 — S 줄 단가 = MROUNDUD(단가 × 환율/1000, ECD, 0)(0x437aa2~0x437df2) · $ 10만 미만 EXL · € /1000 · ¥ /100000 + 행자부(SET_BASE 1) — ST_KanJub 0x47a1bc: 줄 b+11 / b+15 · 칸 RATE{기간(+5)} · 일반관리비 줄 23 RATE1 · 이윤 줄 24 RATE0 + 적용기준 콤보 = TWM_KANJUB.dfm cmBx_Set_Base Items/Values +기대값은 위 규칙 손셈 또는 실물 STC(RATE_M 표 · PRJLST 값) · DFM 원자료에서 읽음. +""" + +import json +import subprocess +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +sys.path.insert(0, str(ROOT / "tools/stmate-test")) +import server # noqa: E402 + +HELPER = Path(__file__).with_name("helper_stmate_std.cjs") +DOCS = ROOT / "resources/knowledge/original/실무문서" +STC = DOCS / ( + "25년 산불진화임도(기번8)(울진소광)/2025년 산불진화임도 신설사업(기번8 울진.금강송.소광.산29외).STC" +) +DFM = ( + ROOT / "resources/knowledge/original/경쟁사 프로그램/STmate/REA 분석/" + "21_제경비_입력화면연결_작업자료_20261025/ST_KanJub/resource-TWM_KANJUB.dfm.json" +) + + +def run(req): + out = subprocess.check_output( + ["node", str(HELPER)], + input=json.dumps(req, ensure_ascii=False), + text=True, + encoding="utf-8", + ) + return json.loads(out) + + +def item(aamt, rate_l, lamt_r=(0, 0, 0, 0), stored=None): + st = stored or {"L": [0] * 4, "M": [0] * 4, "S": [0] * 4} + base = {"code": "A00001", "name": "표준", "unit": "m", "aamt": aamt, "rateL": rate_l} + return base | {"lamtR": list(lamt_r), "stored": st} + + +ROW = [{"id": "BOQ_1", "code": "A00001", "refId": "A00001", "qty": 3, "changedQty": 3}] + + +def boq(it, std, slot=1, rows=ROW): + return run({"mode": "boq", "items": [it], "rows": rows, "std": std, "slot": slot}) + + +def test_std_market_boq_actopt_tie(): + # T 10001 · R 50 → L0 = X = 5000.5(동률) — 0 절사 5000 · 1 노무 칸 앞 → 5001 · 2 노무 칸 뒤 → 5000 + it = item([10001, 0, 0, 0], 50) + r0, r1, r2 = (boq(it, {"acttyp": 1, "actopt": op})["rows"][0] for op in (0, 1, 2)) + assert (r0["uL"], r0["uM"]) == (5000, 5001) + assert (r1["uL"], r1["uM"]) == (5001, 5000) + assert (r2["uL"], r2["uM"]) == (5000, 5001) + # 수량 3 — 비목별 원 미만 절사 · 합계 = 단가 합 × 3 + assert (r1["L"], r1["M"], r1["S"], r1["T"]) == (15003, 15000, 0, 30003) + + +def test_std_market_boq_rest_column_and_preset(): + it = item([10001, 0, 0, 0], 50) + s = boq(it, {"acttyp": 2, "actopt": 0})["rows"][0] + assert (s["L"], s["M"], s["S"]) == (15000, 0, 15003) + a = boq(it, {"acttyp": 0, "actopt": 0}) + # ACTTYP 0 — 나머지는 넷째 칸 A(비목 밖) · 줄·내역 합계에는 들어감 + assert (a["rows"][0]["M"], a["rows"][0]["A"], a["rows"][0]["T"]) == (0, 15003, 30003) + assert a["directA"] == 15003 and a["directT"] == 30003 + # R 0 · LAMT1_R 4000 → 노무 4000 그대로 · 나머지 6001 재료 + p = boq(item([10001, 0, 0, 0], 0, (4000, 0, 0, 0)), {"acttyp": 1, "actopt": 2})["rows"][0] + assert (p["uL"], p["uM"]) == (4000, 6001) + + +def test_std_market_boq_stored_and_slot2(): + stored = {"L": [111, 0, 0, 0], "M": [222, 0, 0, 0], "S": [33, 0, 0, 0]} + s = boq(item([10001, 0, 0, 0], 50, stored=stored), {"useStored": True})["rows"][0] + assert (s["uL"], s["uM"], s["T"]) == (111, 222, (111 + 222 + 33) * 3) + # 변경(2칸) = AAMT2 로 다시 나눔 + r = boq(item([10001, 20000, 0, 0], 50), {"acttyp": 1, "actopt": 0}, slot=2)["rows"][0] + assert (r["uL"], r["uM"]) == (10000, 10000) + + +COSTA = {"CODE": "A00001", "NAME": "표준", "UNIT": "m", "AAMT1": "10001", "RATE_L": "50"} + + +def test_std_market_composition_lookup(): + data = {"costa_rows": [COSTA], "prjlst": {"ACTTYP": "1", "ACTOPT": "1"}} + (r,) = run( + { + "mode": "comp", + "cases": [ + {"data": data, "rows": [{"CODE": "A00001", "QTY1": 2}], "peek": "A00001"}, + ], + } + ) + assert (r["unit"]["L"], r["unit"]["M"], r["unit"]["S"]) == (5001, 5000, 0) + assert (r["L"], r["M"], r["S"]) == (10002, 10000, 0) + + +def test_exrnm_unit_price_rounds_to_ecd(): + # $123.45 × 1289/1000 = 159.12705 천원 · 수량 10 + costn = [{"CODE": "S00001", "UNIT": "$", "SAMT1": "123.45", "TAMT1": "123.45"}] + ini = {"EXLNM1": "1289", "EXHNM1": "1300"} + rows = [{"CODE": "S00001", "QTY1": 10}] + cases = [ + {"data": {"costn_rows": costn, "start_ini": ini | {"EXRNM": "1"}}, "rows": rows}, + { + "data": {"costn_rows": costn, "start_ini": ini | {"EXRNM": "1", "ECDNM": "2"}}, + "rows": rows, + }, + # 키 없음 = 로더 기본 1000.00 → 123.45 × 1 → ECD 0 절사 123 + {"data": {"costn_rows": costn, "start_ini": {"EXRNM": "1"}}, "rows": rows}, + ] + a, b, c = run({"mode": "comp", "cases": cases}) + assert a["S"] == 1590 # 159(ECD 0 버림) × 10 + assert b["S"] == 1591 # 159.12 × 10 = 1591.2 + assert c["S"] == 1230 + + +def test_exrnm_only_s_lines_and_fullwidth_dollar(): + ini = {"EXRNM": "1", "EXLNM1": "1500", "EXHNM1": "1500"} + costn = [ + {"CODE": "M00009", "UNIT": "$", "MAMT1": "100", "TAMT1": "100"}, + {"CODE": "S00002", "UNIT": "$", "SAMT1": "10", "TAMT1": "10"}, + ] + data = {"costn_rows": costn, "start_ini": ini} + m, s = run( + { + "mode": "comp", + "cases": [ + {"data": data, "rows": [{"CODE": "M00009", "QTY1": 1}]}, + {"data": data, "rows": [{"CODE": "S00002", "QTY1": 1}]}, + ], + } + ) + # 원본 환산 조건 = 줄 코드 S(0x437adb) — 재료 $ 줄은 그대로 · 전각 $ 도 $ 와 같음 + assert m["M"] == 100 and s["S"] == 15 + + +def _rate_m_rows(): + files = server.read_project_files(str(STC)) + return server.parse_dbf_bytes(files["RATE_M.DBF"])[1] + + +def test_rate_m_lookup_against_stc_table(): + rows = _rate_m_rows() + cases = [ + {"scale": 40e8, "kongType": 0, "ilban": 0, "kikan": 1}, + {"scale": 100e8, "kongType": 3, "ilban": 0, "kikan": 2}, + {"scale": 500e8, "kongType": 0, "ilban": 1, "kikan": 0}, + {"scale": 10e8, "kongType": 5, "ilban": 0, "kikan": -1}, + ] + res = run({"mode": "ratem", "rows": rows, "cases": cases})["out"] + want = [(11, 1), (12, 7), (17, 5), (15, 5)] # (줄, 칸) = 규칙 손셈 + for got, (line, col) in zip(res, want): + assert got["cells"]["KANNO"] == [line, col] + assert got["rates"]["KANNO"] == server.fnum(rows[line - 1][f"RATE{col}"]) + assert got["rates"]["ILBAN"] == server.fnum(rows[22]["RATE1"]) + assert got["rates"]["IYUN"] == server.fnum(rows[23]["RATE0"]) + assert [g["band"] for g in res] == [0, 1, 2, 0] + + +def test_set_base_combo_pairs_from_dfm(): + nodes = json.loads(DFM.read_text(encoding="utf-8"))["nodes"] + combo = next(o for o in _walk(nodes) if o.get("name") == "cmBx_Set_Base") + p = combo["properties"] + want = [[int(v), t] for v, t in zip(p["Values.Strings"], p["Items.Strings"])] + got = run({"mode": "ratem", "rows": [], "cases": []})["setBase"] + assert got == want + + +def _walk(x): + if isinstance(x, dict): + if "name" in x and "properties" in x: + yield x + for v in x.values(): + yield from _walk(v) + elif isinstance(x, list): + for v in x: + yield from _walk(v) + + +def test_api_load_passes_std_market_settings(): + loaded = server.api_load(server.LoadReq(source_path=str(STC))) + files = server.read_project_files(str(STC)) + prj = server.parse_dbf_bytes(files["PRJLST.DBF"])[1][0] + ini = server.parse_ini_bytes(files.get("START8X.INI") or b"") + std = loaded["sim_state"]["sysConfig"]["stdMarket"] + assert std["acttyp"] == int(server.fnum(prj["ACTTYP"])) + assert std["actopt"] == int(server.fnum(prj["ACTOPT"])) + assert std["useStored"] == (ini.get("S_JDA", "").strip() == "1") + costa = server.parse_dbf_bytes(files["COSTA.DBF"])[1] + assert len(loaded["sim_state"]["stdMarketItems"]) == len(costa) + assert len(loaded["costa_rows"]) == len(costa) diff --git a/resources/tester/test_stmate_xrate_round.py b/resources/tester/test_stmate_xrate_round.py new file mode 100644 index 000000000..6c9103061 --- /dev/null +++ b/resources/tester/test_stmate_xrate_round.py @@ -0,0 +1,34 @@ +"""STMATE 재현 앱 수량 계산기(wM_Edit_XRate) 반올림 방향 — Q_d = MROUNDUD(x, d, 선택 1). + +근거: REA 30 labor_equipment_quantity_rules.json(0x442f97 일일수량 Q_11 · 0x442fec 적용수량 Q_p · 선택 1) + REA 32 §1.1 MROUNDUD(DP_Common 0x454044) — 선택 1 = 첫 버림 자리 ≥ 5 이면 한 단위 올림(0 반대쪽) +기대값은 이 규칙의 손셈 — 경계(첫 버림 자리 5)에서 절사·은행가 반올림과 갈림. +""" + +import json +import subprocess +from pathlib import Path + +HELPER = Path(__file__).with_name("helper_stmate_smt_tools.cjs") + + +def call(*calls): + payload = [{"fn": f, "args": list(a)} for f, *a in calls] + out = subprocess.check_output( + ["node", str(HELPER)], input=json.dumps(payload), text=True, encoding="utf-8" + ) + return json.loads(out) + + +def test_applied_quantity_half_rounds_away_from_zero(): + lab, eq, mid = call( + ("compute", {"qty1": 8, "cond": "", "hrat": 100, "lqty": 1, "labor": True, "point": 2}), + ("compute", {"qty1": 64, "cond": "", "hrat": 100, "lqty": 1, "labor": False, "point": 2}), + ("compute", {"qty1": 16, "cond": "", "hrat": 100, "lqty": 1, "labor": True, "point": 3}), + ) + # 1 ÷ 8 = 0.125 → 2자리 첫 버림 자리 5 → 0.13(절사 0.12 · 은행가 0.12) + assert lab["qday"] == 8 and lab["cqty"] == 0.13 + # 장비 1 × 8 ÷ 64 = 0.125 → 0.13 + assert eq["cqty"] == 0.13 + # 1 ÷ 16 = 0.0625 → 3자리 첫 버림 자리 5 → 0.063 + assert mid["cqty"] == 0.063 diff --git a/tools/stmate-test/calc.js b/tools/stmate-test/calc.js index 5283f7e43..4df0472eb 100644 --- a/tools/stmate-test/calc.js +++ b/tools/stmate-test/calc.js @@ -333,7 +333,13 @@ const StmateCalc = (() => { const sys = data.sysConfig || {}, chnMode = sys.chnMode || "bimok", optOrder = (sys.optOrder || "SML").toUpperCase(); + const stdMap = Object.fromEntries((data.stdMarketItems || []).map((x) => [x.code, x])); const lookupUnit = (refId) => { + const sm = stdMap[refId]; + if (sm) { + const meta = { name: sm.name, code: sm.code, spec: sm.spec || "", unit: sm.unit || "" }; + return Object.assign(stdMarketUnit(sm, slot, sys.stdMarket || {}), meta); + } const r = ilwiMap[refId] || sanMap[refId] || machMap[refId] || resMap[refId]; if (!r) return { M: 0, L: 0, S: 0, T: 0, name: "미연결", code: "-", spec: "", unit: "" }; const pick = (k, iProp, prop) => @@ -354,6 +360,7 @@ const StmateCalc = (() => { let directM = 0, directL = 0, directS = 0, + directA = 0, govRawTotal = 0, govFeeTotal = 0; // 내역 비율 줄(PR) 밑수 — 표시(PRPT) 줄 금액 누적 · PR 줄을 지나면 비움(영월 조달수수료 4줄 대조) @@ -370,7 +377,7 @@ const StmateCalc = (() => { } const su = slot > 1 && row.units && row.units[slot]; const u = su - ? Object.assign({}, lookupUnit(row.refId), { M: su[0], L: su[1], S: su[2] }) + ? Object.assign({}, lookupUnit(row.refId), { M: su[0], L: su[1], S: su[2], A: 0 }) : lookupUnit(row.refId); // 행 고정 단가(fixedUnit) · 내역 할증율(wBoqRate RATE/RM·RL·RS = 비목별 단가 가산, 원 단위 절사) // — 금액 가산(BDQTY X_QTY·X_HAL 은 손료계수 칸 · REA 정정)(07번 §4 · 34번 wBoqRate) · 저장 차수 단가는 이미 반영된 값이라 건너뜀 @@ -384,7 +391,8 @@ const StmateCalc = (() => { (c) => pct(c) && (u[c] = Math.trunc(u[c] * Math.fround((100 + pct(c)) / 100))), ); } - u.T = u.M + u.L + u.S; + u.A = num(u.A); + u.T = u.M + u.L + u.S + u.A; const qty = Number( slot > 1 && row.qtys @@ -397,16 +405,18 @@ const StmateCalc = (() => { rawL = u.L * qty, rawS = u.S * qty, rawT = u.T * qty; + // 넷째 칸 A(표준시장단가 비목 밖 금액) — 다른 비목과 같은 줄 금액 절사 · 합계 T 에 넣음(0x4312ad) let M = roundDown(rawM, 0), L = roundDown(rawL, 0), S = roundDown(rawS, 0), - T = M + L + S; + A = roundDown(u.A * qty, 0), + T = M + L + S + A; // 코드 붙은 % 줄(조달수수료 M%·T%) = 같은 상위 공종 안 앞 말단 줄 비목 합 × 율 → 제 비목(server pct_row_base) if (row.pctBase) { const k = row.pctComp, base = row.pctBase.reduce((a, id) => a + ((doneById[id] || {})[k] || 0), 0); const own = /^L/.test(row.code) ? "L" : /^S/.test(row.code) ? "S" : "M"; - ((M = 0), (L = 0), (S = 0)); + ((M = 0), (L = 0), (S = 0), (A = 0)); const amt = roundDown((base * num((row.prQtys || [])[slot - 1])) / 100, 0); if (own === "L") L = amt; else if (own === "S") S = amt; @@ -426,7 +436,7 @@ const StmateCalc = (() => { .filter((k) => got[k] !== { M, L, S }[k]) .map((k) => `${k}(+${got[k] - { M, L, S }[k]})`) .join(""); - ((M = got.M), (L = got.L), (S = got.S), (T = M + L + S)); + ((M = got.M), (L = got.L), (S = got.S), (T = M + L + S + A)); } } doneById[row.id] = { M, L, S, T }; @@ -437,7 +447,7 @@ const StmateCalc = (() => { ((prBase.M += M), (prBase.L += L), (prBase.S += S)); if (row.rowType === "gov_mat") govRawTotal += T; else if (row.rowType === "gov_fee") govFeeTotal += T; - else ((directM += M), (directL += L), (directS += S)); + else ((directM += M), (directL += L), (directS += S), (directA += A)); const out = Object.assign({}, row, { spec: row.spec || u.spec || "", unit: row.unit || u.unit || "", @@ -451,13 +461,14 @@ const StmateCalc = (() => { sUnit: u.S, tUnit: u.T, }; - const u2 = { mAmt: M, lAmt: L, sAmt: S, tAmt: T, M, L, S, T, optimizDiff, optimizTarget }; + const u2 = { mAmt: M, lAmt: L, sAmt: S, aAmt: A, tAmt: T, M, L, S, A, T }; + Object.assign(u2, { aUnit: u.A, optimizDiff, optimizTarget }); return Object.assign(out, u1, u2, { aggM, aggL, aggS, aggT: aggM + aggL + aggS }); }); - const directT = directM + directL + directS, + const directT = directM + directL + directS + directA, govCombinedRaw = govRawTotal + govFeeTotal; const totals = Object.assign( - { directM, directL, directS, directT }, + { directM, directL, directS, directA, directT }, { govRawTotal, govMatTotal: govRawTotal, govFeeTotal, govCombinedRaw }, ); return Object.assign({ rows, directTotal: directT, totals }, totals); @@ -508,6 +519,21 @@ const StmateCalc = (() => { return Object.assign(out, { T: out.L + out.M + out.S + out.N }); } + // 표준시장단가 코드(A · COSTA) 한 칸 단가 — 단가 읽기 Main 0x430c60(A 줄 = COSTA 자료집합 · 0x437a4b) + // S_JDA(Start8x.Ini · 설정 +0x7c8) 참 = 저장 LAMTn·MAMTn·SAMTn 그대로 · 거짓 = AAMTn 을 RATE_L 로 나눔(splitStdMarket) + // ACTTYP·ACTOPT = PRJLST 값(로더 0x45c938 → 공사 레코드 +0x172c·+0x1730) · 넷째 칸 A = 비목 밖 금액(합계엔 포함) + // item: { aamt[1..4], rateL, lamtR[1..4], stored: { L, M, S }[1..4] } · cfg: { acttyp, actopt, useStored } + function stdMarketUnit(item, slot = 1, cfg = {}) { + const at = (arr) => num((arr || [])[slot - 1]); + const st = (item && item.stored) || {}; + if (cfg.useStored) { + const [L, M, S] = ["L", "M", "S"].map((k) => at(st[k])); + return { L, M, S, A: 0, T: L + M + S }; + } + const sp = splitStdMarket(at(item.aamt), item.rateL, at(item.lamtR), cfg.acttyp, cfg.actopt); + return { L: sp.L, M: sp.M, S: sp.S, A: sp.N, T: sp.T }; + } + function evalKOrdTransition(pclass, regMode, flag, currentK) { const K = Number(currentK) || 1; const nextK = @@ -620,7 +646,7 @@ const StmateCalc = (() => { const api = { KINDS, KIND_KEYS, num, fmt, evalFormula, evalLeftToRight }; Object.assign(api, { roundDown, roundUp, roundHalfUp, roundBanker }); Object.assign(api, { evalWageFormulaLeftToRight, evalQFormula, evalKOrdTransition }); - Object.assign(api, { optimizParts, splitStdMarket }); + Object.assign(api, { optimizParts, splitStdMarket, stdMarketUnit }); return Object.assign(api, { createDefaultState, calculateAll, computeAll: calculateAll }); })(); diff --git a/tools/stmate-test/calc_xrate.js b/tools/stmate-test/calc_xrate.js index cb9f175e4..41f6d89e8 100644 --- a/tools/stmate-test/calc_xrate.js +++ b/tools/stmate-test/calc_xrate.js @@ -6,15 +6,22 @@ * 적용수량 = 일일수량 0 이면 0 · 아니면 Qp(조수량 × (노무 1 · 장비 8) ÷ 일일수량) * 자동 자리 = 기준수량 정수부 자릿수 + 1 (2~6 사이로 묶음) · 일일수량이 아니라 기준수량을 봄 * 조건식 = 빈칸 걷은 뒤 * + - . / 0~9 ^ 만 허용(괄호 없음) · 빈 식 = 1 - * Q_d = DP_Common.MROUNDUD(x, d, 1) — 반올림 방향 미확정(REA 15 · 14) · 여기서는 반올림으로 둠(가정) + * Q_d = DP_Common.MROUNDUD(x, d, 1) — 선택 1 = 첫 버림 자리 ≥ 5 이면 한 단위 올림(0 반대쪽 · 사사오입) + * 근거: REA 32 §1.1(DP_Common 0x454044 · 0x4544f0 올림 판정) · 원형 = exec_calc.js mroundud(한 벌) */ const StmateXRate = (() => { const EV = () => (typeof window !== "undefined" && window.STMATE_SMT_EVAL) || (typeof require !== "undefined" ? require("./smt_eval.js") : null); - // 반올림(가정) — 이진 오차를 십진 자리로 맞춤 + const EX = () => + (typeof window !== "undefined" && window.STMATE_EXEC) || + (typeof require !== "undefined" ? require("./exec_calc.js") : null); + + // Q_d = MROUNDUD(v, d, 1) — 원형(exec_calc) 이 안 실렸으면 같은 방향(사사오입 · 0 반대쪽)으로 function q(v, d) { + const ex = EX(); + if (ex && ex.mroundud) return ex.mroundud(v, d, 1); const f = 10 ** d, r = Math.floor(Math.abs(Number(v) || 0) * f + 0.5 + 1e-9) / f; return v < 0 ? -r : r; diff --git a/tools/stmate-test/kanjub_parts.js b/tools/stmate-test/kanjub_parts.js index 7d274ad6e..ffe8a03c5 100644 --- a/tools/stmate-test/kanjub_parts.js +++ b/tools/stmate-test/kanjub_parts.js @@ -63,7 +63,34 @@ const STMATE_KANJUB_NATIVE = (() => { const bf = on && Number(keys.I_KUNBO) !== 1 && Number(keys.I_YUNBO) !== 1 ? 1 : 0; return { I_ANJUNAUTO: on ? 2 : 1, I_BF_CH_BO: bf }; } - return { chasuList, firstSeries, chgGate, CHG_ITEMS, changeDefaults }; + // 적용기준 I_SET_BASE — cmBx_Set_Base(TWM_KANJUB.dfm) Items 순번 ↔ Values · 저장 = TwCombo.GetInteger = Values 값 + // (같은 GetInteger 로 읽는 공사종류·건설기계 구분을 원본이 8·9·−1 값으로 비교 — 순번이면 나올 수 없는 값) + const SET_BASE = [ + [2, "일반(국가계약법)"], + [0, "일반(지방계약법)"], + [1, "행자부기준"], + ]; + // 행자부기준(SET_BASE 1) 요율 조회 — ST_KanJub 0x47a1bc(0x47acd8~0x47b100) · RATE_M(JB_M) 줄 = Go 번호(1부터) + // 규모 b = 밑수 < 50억 → 0 · < 300억 → 1 · 그 밖 2(G[2]·G[3] · 밑수 = RATE_R 조회와 같은 원가 칸 0x4e4260) + // 간접노무비 = 공사종류 < 5 · I_ILBAN ≠ 1 → 줄 b+11 · 칸 RATE{기간 + (공사종류 1·3 이면 5)} + // I_ILBAN 1 또는 공사종류 ≥ 5 → 줄 b+15 · 칸 RATE{기간+5} (기간 = max(0, 화면순번−1)) + // 일반관리비 = 줄 23 RATE1 · 이윤 = 줄 24 RATE0 · 그 밖 요율은 RATE_R 그대로 + // rows: RATE_M 행(1번 줄 = rows[0]) · o: { scale, kongType, ilban, kikan } + function rateMLookup(rows, o = {}) { + const n = (v) => Number(v) || 0; + const at = (line, col) => n(((rows || [])[line - 1] || {})[`RATE${col}`]); + const b = n(o.scale) < 50e8 ? 0 : n(o.scale) < 300e8 ? 1 : 2; + const kt = n(o.kongType), + kik = Math.max(0, n(o.kikan)); + const wide = n(o.ilban) === 1 || kt >= 5; + const line = b + (wide ? 15 : 11), + col = kik + (wide || kt === 1 || kt === 3 ? 5 : 0); + const cells = { KANNO: [line, col], ILBAN: [23, 1], IYUN: [24, 0] }; + const rates = Object.fromEntries(Object.entries(cells).map(([k, [r, c]]) => [k, at(r, c)])); + return { band: b, rates, cells }; + } + const out = { chasuList, firstSeries, chgGate, CHG_ITEMS, changeDefaults }; + return Object.assign(out, { SET_BASE, rateMLookup }); })(); const StmateKanjubParts = ({ num, fmt, roundDown, roundUp, roundBanker }) => { diff --git a/tools/stmate-test/server.py b/tools/stmate-test/server.py index 212a0757a..d8bee2d28 100644 --- a/tools/stmate-test/server.py +++ b/tools/stmate-test/server.py @@ -491,6 +491,37 @@ def api_load(req: LoadReq): c for c in (conld[i : i + 6].strip() for i in range(0, len(conld), 6)) if c ) sim_state["sysConfig"]["rxFormula"] = ini.get("RXXNM") or sim_state["sysConfig"]["rxFormula"] + # 표준시장단가(A 코드 · COSTA.DBF) — 노무비율 나눔 설정 = PRJLST ACTTYP·ACTOPT(Main 0x45c938) · + # S_JDA 참 = 저장 단가 그대로(설정 +0x7c8 · 기본 거짓) — calc.stdMarketUnit + costa_rows = parse_dbf_bytes(files["COSTA.DBF"])[1] if "COSTA.DBF" in files else [] + prj0 = prj_rows[0] if prj_rows else {} + sim_state["sysConfig"]["stdMarket"] = { + "acttyp": int(fnum(prj0.get("ACTTYP"))), + "actopt": int(fnum(prj0.get("ACTOPT"))), + "useStored": str(ini.get("S_JDA", "")).strip().upper() in ("1", "T", "TRUE", "Y"), + } + std_items = [ + { + "id": (r.get("CODE") or "").strip(), + "code": (r.get("CODE") or "").strip(), + "name": r.get("NAME") or "", + "spec": r.get("SIZE") or "", + "unit": r.get("UNIT") or "", + "aamt": [fnum(r.get(f"AAMT{n}")) for n in range(1, 5)], + "rateL": fnum(r.get("RATE_L")), + "lamtR": [fnum(r.get(f"LAMT{n}_R")) for n in range(1, 5)], + "stored": {c: [fnum(r.get(f"{c}AMT{n}")) for n in range(1, 5)] for c in "LMS"}, + } + for r in costa_rows + if (r.get("CODE") or "").strip() + ] + sim_state["stdMarketItems"] = std_items + # 내역의 A 줄은 COSTA 로 계산 — 저장 단가로 만든 임시 일위대가·자원은 걷음 + std_codes = {x["code"] for x in std_items} + sim_state["ilwiItems"] = [x for x in sim_state["ilwiItems"] if x["id"] not in std_codes] + sim_state["resources"] = [ + x for x in sim_state["resources"] if str(x["id"]).rsplit("_", 1)[0] not in std_codes + ] return { "source_path": req.source_path, "boq_table_name": boq_name, @@ -510,6 +541,7 @@ def api_load(req: LoadReq): "start_ini": ini, "sim_state": sim_state, **extra_tables(files), + "costa_rows": costa_rows, # 암호 표도 풀어 읽은 행(smt_engine A 줄 단가) } diff --git a/tools/stmate-test/smt_engine.js b/tools/stmate-test/smt_engine.js index 5ad03cfa4..fa511cb5c 100644 --- a/tools/stmate-test/smt_engine.js +++ b/tools/stmate-test/smt_engine.js @@ -13,17 +13,51 @@ // 낙찰률(NAGCD) 단가는 2칸 원단가로 산근을 셈 — 1칸은 원단가 × 낙찰률 const costSlot = (r) => (num(r.NAGCD) > 0 ? 2 : 1); + // 표준시장단가(A) 줄 단가 설정 — PRJLST ACTTYP·ACTOPT(로더 0x45c938) · Start8x.Ini S_JDA(설정 +0x7c8, 기본 거짓) + const iniBool = (v) => + ["1", "T", "TRUE", "Y"].includes( + String(v ?? "") + .trim() + .toUpperCase(), + ); + function stdMarketCfg(ctx) { + const d = ctx.dbfData || {}, + prj = d.prjlst || {}; + const useStored = iniBool((d.start_ini || {}).S_JDA); + return { acttyp: num(prj.ACTTYP), actopt: num(prj.ACTOPT), useStored }; + } + // COSTA 행 → calc.stdMarketUnit 꼴(AAMTn · RATE_L · LAMTn_R · 저장 LAMTn·MAMTn·SAMTn) + const ns = [1, 2, 3, 4]; + const stdItem = (r) => ({ + aamt: ns.map((n) => num(r[`AAMT${n}`])), + rateL: num(r.RATE_L), + lamtR: ns.map((n) => num(r[`LAMT${n}_R`])), + stored: Object.fromEntries( + "LMS".split("").map((k) => [k, ns.map((n) => num(r[`${k}AMT${n}`]))]), + ), + }); + function costnLookup(ctx) { - const byCode = {}; + const byCode = {}, + byA = {}; ((ctx.dbfData && ctx.dbfData.costn_rows) || []).forEach((r) => (byCode[rowCode(r)] = r)); + ((ctx.dbfData && ctx.dbfData.costa_rows) || []).forEach((r) => (byA[rowCode(r)] = r)); + const smCfg = stdMarketCfg(ctx); const lookup = (code) => { + // A 줄 = COSTA 에서 읽어 노무비율로 나눔(Main 0x437a4b → 0x430c60 → 0x45a468) · 넷째 칸 A 는 구성 합계 밖 + const a = code && code[0] === "A" && !byCode[code] ? byA[code] : null; + if (a) { + const u = Calc.stdMarketUnit(stdItem(a), 1, smCfg); + const meta = { unit: String(a.UNIT || "").trim(), name: String(a.NAME || "") }; + return Object.assign({ M: u.M, L: u.L, S: u.S, A: u.A }, meta); + } const r = byCode[code]; if (!r) return null; const s = costSlot(r); const out = { M: num(r[`MAMT${s}`]), L: num(r[`LAMT${s}`]), S: num(r[`SAMT${s}`]) }; return Object.assign(out, { unit: String(r.UNIT || "").trim(), name: String(r.NAME || "") }); }; - return { byCode, lookup }; + return { byCode, byA, lookup }; } // 결과금액조정(COSTN S_ADJ · ADJ_M/L/S) — 표시된 것만 @@ -61,13 +95,15 @@ const digitOf = (v, def = 1) => (/^[0-2]$/.test(String(v ?? "").trim()) ? Number(v) : def); // 외산장비 환율 — 단가의 조사시점(ARENM 1 당초 · 2 변경)의 EXLNM·EXHNM·EXEUR·EXYEN(REA 14 cmBx_ARE) + // 키가 없으면 로더 기본 "1000.00"(Main 0x42b0xx [EQUIPMENT]) function fxOf(ini) { const n = String(ini.ARENM || "1").trim() === "2" ? 2 : 1; + const v = (k) => (ini[k] == null || String(ini[k]).trim() === "" ? 1000 : num(ini[k])); return { - usd: num(ini[`EXLNM${n}`]), - usdHigh: num(ini[`EXHNM${n}`]), - eur: num(ini[`EXEUR${n}`]), - yen: num(ini[`EXYEN${n}`]), + usd: v(`EXLNM${n}`), + usdHigh: v(`EXHNM${n}`), + eur: v(`EXEUR${n}`), + yen: v(`EXYEN${n}`), }; } @@ -163,6 +199,8 @@ rx: ini.RXXNM || sys.rxFormula, usdRate: num(ini.EXLNM1), fx: fxOf(ini), + // 환율 적용 범위 EXRNM([EQUIPMENT] · 설정 +0x7c9 · 기본 거짓) — 참이면 S 줄 단가를 천원으로 미리 환산(0x437aa2) + exrnm: iniBool(ini.EXRNM), // 줄 금액 자리 = 중기 KCD · 일위대가 BPN · 중기 노임 단가 JCD · $장비 단가 ECD(22 §3.4 · REA 14 안내문) lineDigits: digitOf(code[0] === "X" ? ini.KCDNM : ini.BPNNM), // JCD 빈칸 기본 = KCD 2 이면 2 · 아니면 0(Main 0x42ab08) diff --git a/tools/stmate-test/smt_eval.js b/tools/stmate-test/smt_eval.js index 853a23aa5..ef7e565ce 100644 --- a/tools/stmate-test/smt_eval.js +++ b/tools/stmate-test/smt_eval.js @@ -397,9 +397,10 @@ const StmateSmtEval = (() => { // opts.fx = { usd, usdHigh, eur, yen } · 옛 opts.usdRate 는 usd 로 봄 function foreignUnit(unit, price, opts) { const fx = opts.fx || { usd: opts.usdRate }; + // $·$ = 단가 10만 미만 EXL · 그 밖 EXH(Main 0x437caa~0x437d45 · 고액 환율이 안 주어진 옛 호출만 EXL) const rate = - unit === "$" - ? Number(price) >= 100000 && Number(fx.usdHigh) > 0 + unit === "$" || unit === "$" + ? Number(price) >= 100000 && fx.usdHigh != null ? fx.usdHigh : fx.usd : unit === "€" @@ -467,7 +468,12 @@ const StmateSmtEval = (() => { p = { M: 0, L: hourlyWage(r.L, rx, Number(opts.wageDigits) || 0), S: 0 }; } const fxRate = foreignUnit(unit, r.M + r.L + r.S, opts); - if (fxRate !== null) + // EXRNM 참 — S 줄만 단가 = MROUNDUD(단가 × 환율/1000, ECD, 0)(천원 · ECD 자리 버림 · Main 0x437aa2~0x437df2) + // 거짓 — 원본은 상위 B·천원 줄 수량 칸에 환율/1000 을 넣는 다른 경로(0x435660) · 여기는 옛 환산 유지(미확인) + if (fxRate !== null && opts.exrnm) { + if (code[0] === "S") + p = Object.assign({}, p, { S: trunc((p.S * fxRate) / 1000, Number(opts.fxDigits) || 0) }); + } else if (fxRate !== null) for (const k of "MLS") p[k] = opts.fxDigits == null