From c8f0761c8a1bf4eeddaa4ce15ada90627112124a Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 5 Oct 2026 16:24:59 +0900 Subject: [PATCH 1/3] =?UTF-8?q?chore(sync):=20=EA=B3=B5=EC=9C=A0=20docs=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EB=8B=B4=EC=9D=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/raw/M02_구조물옵션정의/정의_틀.md | 101 +++++++++++++++++++++ docs/raw/사용자요구/2026-10-05_수정요구.md | 24 +++++ 2 files changed, 125 insertions(+) create mode 100644 docs/raw/M02_구조물옵션정의/정의_틀.md diff --git a/docs/raw/M02_구조물옵션정의/정의_틀.md b/docs/raw/M02_구조물옵션정의/정의_틀.md new file mode 100644 index 000000000..c64e03855 --- /dev/null +++ b/docs/raw/M02_구조물옵션정의/정의_틀.md @@ -0,0 +1,101 @@ +# 구조물 정의 틀 (PLAN 48-1) + +정본 = `resources/master_template/구조물정의.json` 한 벌. 서버 · 화면은 이 한 벌만 읽음. + +## 1. 길 + +| 길 | 누가 | 하는 것 | +| --- | --- | --- | +| `GET /api/m02/structure-definition` | 로그인 누구나 | 정의 한 벌 그대로 | +| `PUT /api/m02/structure-definition` `{판, 정의}` | 시스템 관리자만(아니면 403) | 통째로 고쳐 씀 · 낡은 판 409 · 검사 틀림 422 | +| `GET /api/projects/structure-types` | 로그인 | 정의의 `types` + `표시` · `그룹` 을 옛 꼴 그대로(`visible` · `groups`) | +| `PUT /api/m02/structure-options` · `structure-option-groups` | 시스템 관리자 | 정의의 `표시` · `그룹` 칸만 고쳐 씀(같은 판 · 같은 이력) | + +- 서버 읽기 = `B05_Profile_Structures_Schema.load_definition()` · `load_structure_types()` · 쓰기 = `M02_SO_Definition.save()` · `save_sections()`. + +## 2. 담는 것 + +| 칸 | 꼴 | 뜻 | +| --- | --- | --- | +| `판` | 정수 | 저장마다 +1 · 앞 판은 `구조물정의_이력/판_N.json` | +| `schema_version` · `comment` | 수 · 글 | 옛 레지스트리 머리 그대로 | +| `구조물군` | `{군 키: 이름}` | 구조물군 이름(A 횡단배수 …) | +| `동작` | `{동작 이름: 뜻}` | 손코딩 특수 동작 목록(5장) | +| `types` | 종류 목록 | 종류 · 옵션 · 선택지 · 기본값 · placement 등(옛 `B05_Profile_Structure_Types.json` 꼴 그대로) | +| `종류` | `{종류 키: {기준측점?, 동작?}}` | 종류마다 덧칸 — 없으면 기본 | +| `표시` | `{종류 키: {옵션 키: false}}` | 끈 옵션만(옛 `구조물옵션표시.json`) | +| `그룹` | `{종류 키: [그룹]}` | 옵션 그룹(옛 `구조물옵션그룹.json` · 46장) + 형상 칸 | +| `배치` | `{종류 키: {옵션 키: {줄, 칸, 너비}}}` | B05 · B06 좌측 「구조물 배치」 칸 자리 — 없으면 지금 차례 | +| `규칙` | 규칙 목록 | 상위 옵션 값 → 하위 옵션(4장) | + +## 3. 키 규칙 + +- 키 = 만들 때 자동 · 안 바뀜 · 영문 소문자 · 숫자 · `_`. 이름(`name` · `label` · 선택지 글 · 그룹 `이름`)은 자유. +- 종류 키(`type_id`) 는 정의 안에서 하나 · 옵션 키(`key`) 는 종류 안에서 하나 · 그룹 id 는 `g` + 소문자 · 숫자. +- 지움 = 「안 씀」(`enabled: false`) — 종류 · 옵션을 목록에서 빼지 않음. +- 저장된 값의 키가 지금 정의에 없으면 = 지난 정의 값 — 버리지 않고 남김(오류 없음 · 계산은 없는 값으로). +- 프로젝트 `structures.json` 에 저장 때 정의 판(`definition_version`). + +## 4. 옵션 + +### 꼴 + +| `input` | 이름 | 값 | +| --- | --- | --- | +| `select` | 고르기 | `choices` 중 하나(선택지 있어야 함) | +| `number` | 숫자 | 0 이상 수 · `unit` | +| `text` | 글 | 글 | +| `bool` | 예/아니오 | 참 · 거짓 | + +- 옵션 덧칸(옛 그대로) = `label` · `choices` · `unit` · `default` · `required` · `phase`(b05 · detail) · `enabled` · `empty_means` · `default_basis` · `warn_above` · `warn_message` · `not_in_table`. + +### 배치 칸 + +- `줄` = 몇째 줄(1부터) · `칸` = 그 줄 몇째 칸(1부터) · `너비` = 칸 몇 개 차지(1부터). 셋 다 1 이상 정수. + +### 그룹 + +``` +{"id": "g1a2b3c", "이름": "유입구 기슭막이", "옵션": ["옵션 키", …], + "형상": {"길이": {"받기": true, "뜻": "유입구 기슭막이 연장"}, "높이": {…}, "전": {…}, "후": {…}}} +``` + +- 옵션 하나는 한 종류 안에서 그룹 하나에만 · 빈 그룹(옵션 0)도 그룹 · 그룹에 안 넣은 옵션 = 본체 칸. +- `형상` = 그룹이 받을 형상 칸(길이 · 높이 · 기준 측점 전 · 후) — 칸마다 `받기`(켬끔) + `뜻`(무엇을 정하는지). 없는 칸 = 안 받음. + +### 종류 덧칸 + +- `기준측점` = 종류 맨 위 기준 측점 칸 보이기(없으면 보임). +- `동작` = 이 종류에 붙인 특수 동작 이름들(`동작` 목록 안에서). + +## 5. 규칙 꼴 + +``` +{"종류": "종류 키", + "만약": {"옵션": "상위 옵션 키", "값들": ["값", …]}, + "그러면": {"옵션": "하위 옵션 키", "선택지": ["값", …], "보이기": false, "기본값": "값"}} +``` + +- 만약 상위 옵션 = 값들 중 하나 → 그러면 하위 옵션의 선택지 / 보이기 / 기본값(셋 중 하나 이상). +- 상위 · 하위는 같은 종류 안 · 서로 다른 옵션 · 고르기 꼴이면 값들은 선택지 안 · 하위 `선택지` 는 고르기 꼴의 선택지 안 · `기본값` 은 (좁힌) 선택지 안. +- 계산 · 연동 제어는 넣지 않음(48-5). + +## 6. 동작 이름(손코딩 특수 동작) + +| 이름 | 붙은 종류 | 하는 것 | +| --- | --- | --- | +| `계곡통과시설` | pipe · box_culvert · ford_pavement · ford_bridge · revetment | 관 지점 정본 시설 — 부속 옵션 서브폼 · 저장은 폼이 아는 칸만 | +| `유입유출_묶음` | pipe | 유입구(집수정 · 기슭막이 택일) · 유출구(기슭막이) 소그룹 | +| `기슭막이_한벌` | pipe · revetment | 형태 · 길이 · 높이 · 바닥 보호공 한 벌 | +| `BOX_본체규격` | box_culvert | 본체 규격 프리셋(폭 × 높이) | +| `날개벽` | box_culvert · ford_bridge | 날개벽 유입 · 유출 · 짧은쪽 높이 · 길이 · 각도 | +| `월류단면` | ford_pavement · ford_bridge | 월류 폭 · 높이 · 바닥 경사 · 포장 두께 + 개략 단면 · 필요 수심 미만 되돌림 | +| `포장_물넘이_겹침` | pavement_concrete | 포장 구간이 물넘이를 품으면 나눔 · 끝만 걸치면 저장 멈춤 | + +- 정의에서 붙이고 뗌 = `종류.{키}.동작` · 새 동작은 코딩 뒤 목록에 이름을 더함. + +## 7. 판 · 이력 + +- 저장 = 읽어 간 `판` 을 같이 보냄 → 같으면 앞 판을 `구조물정의_이력/판_N.json` 으로 남기고 새 판 = N + 1. +- 검사(틀리면 422 · 안 씀) = 칸 꼴 · 종류 키 · 옵션 키 겹침 · 고르기 선택지 있음 · 구조물군 있음 · 표시 · 그룹 · 배치 · 종류 덧칸 · 규칙 대상 있음. +- 판 1 = 옛 `B05_Profile_Structure_Types.json`(37종 · 옵션 235) + `구조물옵션표시.json` + `구조물옵션그룹.json` 을 키 그대로 옮김. diff --git a/docs/raw/사용자요구/2026-10-05_수정요구.md b/docs/raw/사용자요구/2026-10-05_수정요구.md index eeadef7f7..023a682e3 100644 --- a/docs/raw/사용자요구/2026-10-05_수정요구.md +++ b/docs/raw/사용자요구/2026-10-05_수정요구.md @@ -48,3 +48,27 @@ 4. 구조물 조합의 단가산출 상세화면에도 원문보기 우측 패널이 있어야함. 우측 패널은 단가산출 로직을 선택할 경우에 원문을 보여주는 기능이며 패널을 접었다 펼수 있어야함. 5. 원문 패널 추가에 따라 현재 단가산출 로직 항목을 선택하면 옵션창이 보이나 선택하면 하이라이트를 하고 원문을 보일수 있게 함. 그리고 옵션설정에 대한 조정은 올리기, 내리기, 빼기 버튼의 이름을 위로, 아래로, 삭제로 변경하고 아래로 와 삭제 사이에 신규 버튼(이름 : 옵션)을 추가하여 선택할 수 있게 변경. 버튼 사이간격에 대해 템플릿화하여 적용. 6. 구조물 조합의 면적산출 우측패널에 별도의 도면 패널 추가(기능은 4번 요청 확인) + +## 구조물 옵션 정의 페이지 (10-5 · 원문 그대로) + +이제부터 다시 계획서를 세울 예정임. +1. 목표 : 현재 구조물 옵션 보이기의 컨테이너 항목을 기준으로 프로젝트 내부에 사용하는 구조물의 옵션 항목 및 제어를 설정하는 페이지를 궁성 +2. 상세 내용 + - 현재 M02의 구조물 옵션보이기 항목으로 구조물군과 구조물 종류를 설정하고 이름을 변경할 수 있게 반영 + - 구조물 종류를 선택시 우측에 해당항목의 일위대가 그룹을 지정하고 변수를 편입할수 있게 반영(기반영), 추가로 배치 순서를 조절할 수 있게, 행열의 크기 제어도 같이 + - 구조물 종류의 특정 옵션의 옵션 값 항목을 지정할 수 있게 반영 + - 구조물 종류의 최상위에 기본값인 기준 측점을 표현할건지에 대한 기능 + - 구조물의 길이, 높이, 기준측점 전/후 값에 대한 옵션 사용여부 및 어떤걸 제어하는지에 대한 결정 + - 구조물 옵션과 값들의 이름 변경기능 + - 옵션들은 상위에 따라 하위 옵션을 변경할 수 있게 반영 +3. 현재 B05와 B06의 방대한 변경이 필요하니 순차적으로 진행, 가자먼저 작업할 내용은 B05와 B06에 좌측 패널의 구조물 배치 컨테이너에 보일 항목을 반만들수 있게 반영하고 선택에 따라 변경되는 변수 값과 제어는 별도로 작업 할 예정. 일단 방향성에 대해 검토해보고 대화부터 하자. 내가 원하는 방향은 결국 내가 프로그래머가 아니라서 나중에 항목을 추가하거나 옵션을 변경하였을때 프론트엔드에 기능을 구현하고 변경하고 싶은것임. + +## 원문 보기 패널 (10-5 · 원문 그대로) + +계획서는 작성해주고 빠르게 작업해줄 내용이 M01과 M02에서 원문보기가 패널 양식을 사용하지 않고 있음. 추가로 M01페이지의 원문보기에서 md파일을 보기가 깨짐이 있음. M02는 정상. M01의 경우 흐름도와 원분은 우측 패널로 구현되어있음. 좌측 패널과 동일하게 접었다 펴는 양식 제대로 확인할 ㄱ서. + +그리고 우측 패널의 내용은 메인 화면의 스크롤과 별개로 동작하게 반영 + +추가로 원문에서 표는 스크롤로 매우 낮은 공간만 보이고 스크롤 표현되어서 보기가 힘듬. 그냥 표가 길더라도 보여줄것. 어차피 상세페이지와 원문의 우측 패널의 영역은 별도의 스크롤 영역이라 무관함. + +원문은 M01과 M02에 표현되고 있는데 일원화 할것. M02가 더 가독성이 좋음. From 25cc82ef86c1fa937d5176736f196c06420dc2c2 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 5 Oct 2026 16:28:06 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=EF=BB=BFchore(sync):=20=EA=B3=B5=EC=9C=A0?= =?UTF-8?q?=20docs=20=ED=8C=8C=EC=9D=BC=20=EB=8B=B4=EC=9D=8C=20=E2=80=94?= =?UTF-8?q?=20=EA=B8=B0=EC=A4=80=20=EC=BB=A4=EB=B0=8B=EA=B3=BC=20=EA=B0=99?= =?UTF-8?q?=EC=9D=80=20=EB=82=B4=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/raw/사용자요구/2026-10-05_수정요구.md | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/raw/사용자요구/2026-10-05_수정요구.md b/docs/raw/사용자요구/2026-10-05_수정요구.md index eeadef7f7..023a682e3 100644 --- a/docs/raw/사용자요구/2026-10-05_수정요구.md +++ b/docs/raw/사용자요구/2026-10-05_수정요구.md @@ -48,3 +48,27 @@ 4. 구조물 조합의 단가산출 상세화면에도 원문보기 우측 패널이 있어야함. 우측 패널은 단가산출 로직을 선택할 경우에 원문을 보여주는 기능이며 패널을 접었다 펼수 있어야함. 5. 원문 패널 추가에 따라 현재 단가산출 로직 항목을 선택하면 옵션창이 보이나 선택하면 하이라이트를 하고 원문을 보일수 있게 함. 그리고 옵션설정에 대한 조정은 올리기, 내리기, 빼기 버튼의 이름을 위로, 아래로, 삭제로 변경하고 아래로 와 삭제 사이에 신규 버튼(이름 : 옵션)을 추가하여 선택할 수 있게 변경. 버튼 사이간격에 대해 템플릿화하여 적용. 6. 구조물 조합의 면적산출 우측패널에 별도의 도면 패널 추가(기능은 4번 요청 확인) + +## 구조물 옵션 정의 페이지 (10-5 · 원문 그대로) + +이제부터 다시 계획서를 세울 예정임. +1. 목표 : 현재 구조물 옵션 보이기의 컨테이너 항목을 기준으로 프로젝트 내부에 사용하는 구조물의 옵션 항목 및 제어를 설정하는 페이지를 궁성 +2. 상세 내용 + - 현재 M02의 구조물 옵션보이기 항목으로 구조물군과 구조물 종류를 설정하고 이름을 변경할 수 있게 반영 + - 구조물 종류를 선택시 우측에 해당항목의 일위대가 그룹을 지정하고 변수를 편입할수 있게 반영(기반영), 추가로 배치 순서를 조절할 수 있게, 행열의 크기 제어도 같이 + - 구조물 종류의 특정 옵션의 옵션 값 항목을 지정할 수 있게 반영 + - 구조물 종류의 최상위에 기본값인 기준 측점을 표현할건지에 대한 기능 + - 구조물의 길이, 높이, 기준측점 전/후 값에 대한 옵션 사용여부 및 어떤걸 제어하는지에 대한 결정 + - 구조물 옵션과 값들의 이름 변경기능 + - 옵션들은 상위에 따라 하위 옵션을 변경할 수 있게 반영 +3. 현재 B05와 B06의 방대한 변경이 필요하니 순차적으로 진행, 가자먼저 작업할 내용은 B05와 B06에 좌측 패널의 구조물 배치 컨테이너에 보일 항목을 반만들수 있게 반영하고 선택에 따라 변경되는 변수 값과 제어는 별도로 작업 할 예정. 일단 방향성에 대해 검토해보고 대화부터 하자. 내가 원하는 방향은 결국 내가 프로그래머가 아니라서 나중에 항목을 추가하거나 옵션을 변경하였을때 프론트엔드에 기능을 구현하고 변경하고 싶은것임. + +## 원문 보기 패널 (10-5 · 원문 그대로) + +계획서는 작성해주고 빠르게 작업해줄 내용이 M01과 M02에서 원문보기가 패널 양식을 사용하지 않고 있음. 추가로 M01페이지의 원문보기에서 md파일을 보기가 깨짐이 있음. M02는 정상. M01의 경우 흐름도와 원분은 우측 패널로 구현되어있음. 좌측 패널과 동일하게 접었다 펴는 양식 제대로 확인할 ㄱ서. + +그리고 우측 패널의 내용은 메인 화면의 스크롤과 별개로 동작하게 반영 + +추가로 원문에서 표는 스크롤로 매우 낮은 공간만 보이고 스크롤 표현되어서 보기가 힘듬. 그냥 표가 길더라도 보여줄것. 어차피 상세페이지와 원문의 우측 패널의 영역은 별도의 스크롤 영역이라 무관함. + +원문은 M01과 M02에 표현되고 있는데 일원화 할것. M02가 더 가독성이 좋음. From ff85704a05c4ffbc5ec981d274f2b9fec5331ed0 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 5 Oct 2026 16:32:02 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat(M02):=2049-6=20=EA=B5=AC=EC=A1=B0?= =?UTF-8?q?=EB=AC=BC=20=EC=A1=B0=ED=95=A9=20=EC=9D=BC=EC=9C=84=EB=8C=80?= =?UTF-8?q?=EA=B0=80=20=EC=B9=B4=EB=93=9C=20=EC=9E=90=EC=9E=AC=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20[=EC=9E=90=EC=9E=AC=20=EC=B6=94=EA=B0=80]=20?= =?UTF-8?q?=EC=88=A8=EA=B9=80=20=E2=80=94=20=EC=83=81=EC=84=B8=EB=8A=94=20?= =?UTF-8?q?=EA=B7=B8=EB=8C=80=EB=A1=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7 --- .../M02_MasterTemplete_Labor_Detail.ts | 4 +- resources/tester/test_m02_card_shell.py | 1 + .../tester/ui_checks/43-4_일위대가_카드.js | 2 +- .../ui_checks/49-6_카드_자재추가_숨김.js | 46 +++++++++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 resources/tester/ui_checks/49-6_카드_자재추가_숨김.js diff --git a/M02_MasterTemplete/M02_MasterTemplete_Labor_Detail.ts b/M02_MasterTemplete/M02_MasterTemplete_Labor_Detail.ts index 24b45bd61..0e34d21ee 100644 --- a/M02_MasterTemplete/M02_MasterTemplete_Labor_Detail.ts +++ b/M02_MasterTemplete/M02_MasterTemplete_Labor_Detail.ts @@ -62,7 +62,7 @@ export interface LaborDetailOptions { /** 「면적산출에서 잇기」 — 그 열 면적산출 상세로(옮겨 가면 참 · 취소 = 거짓 · 없으면 단추 없음) */ goArea: GoArea | null; /** 구조물 조합 카드 갈래(43-4) — 단가산출 로직 표 + 자재목록만 · 위로 · 아래로 · 로직 추가 · - * 정보(단위 · 본뜬) · 다이어그램 없음 · 옵션 · 삭제 · 자재 추가 · 줄 · 수량 모달은 상세와 같음 */ + * 자재 추가 · 정보(단위 · 본뜬) · 다이어그램 없음 · 옵션 · 삭제 · 줄 · 수량 모달은 상세와 같음 */ card?: boolean; } @@ -434,7 +434,7 @@ export function mountLaborDetail( }), ]), section(tc("Logics_Title"), opt.card ? null : addLogic, logicHost), - section(tc("Labor_Mats"), addMat, matHost), + section(tc("Labor_Mats"), opt.card ? null : addMat, matHost), ...(opt.card ? [] : [dgBox]), ], }), diff --git a/resources/tester/test_m02_card_shell.py b/resources/tester/test_m02_card_shell.py index 7431f9b31..0cd36812d 100644 --- a/resources/tester/test_m02_card_shell.py +++ b/resources/tester/test_m02_card_shell.py @@ -80,6 +80,7 @@ def test_일위대가_카드는_상세_카드_갈래(): detail = _text("M02_MasterTemplete_Labor_Detail.ts") assert "...(opt.card ? {} : { move })" in detail # 순서 단추 없음 · 빼기는 그대로 assert "opt.card ? null : addLogic" in detail and "...(opt.card ? [] : [dgBox])," in detail + assert "opt.card ? null : addMat" in detail # 49-6 — 카드엔 [자재 추가] 없음 · 상세는 그대로 rows = _text("M02_MasterTemplete_Labor_Rows.ts") assert "const tools = !!(move || remove || option);" in rows and "compactTable" not in rows assert "compact" not in _text("M02_MasterTemplete_Labor_View.ts").split("*/", 1)[1] diff --git a/resources/tester/ui_checks/43-4_일위대가_카드.js b/resources/tester/ui_checks/43-4_일위대가_카드.js index bc992ab31..10c6db239 100644 --- a/resources/tester/ui_checks/43-4_일위대가_카드.js +++ b/resources/tester/ui_checks/43-4_일위대가_카드.js @@ -4,7 +4,7 @@ * 부르는 법: orca eval --expression "$(cat 이 파일)" (async 식 · JSON 글을 돌려줌 · 20초 안 — 길면 ORCA 가 끊음) * 기대 수치: * - sections = ["단가산출 로직", "자재목록"] · diagram = 0 · info = 0(단위 · 본뜬 칸 없음) - * - addLogic = 0 · up = down = 0 · remove = 로직 줄 수 · addMat = 1 · rows = 담은 로직 수(item1 = 14) + * - addLogic = 0 · up = down = 0 · remove = 로직 줄 수 · addMat = 0(49-6) · rows = 담은 로직 수(item1 = 14) * - money2 = true(금액 칸이 두 줄 — 위 기준 · 아래 반영) * - scroll.overflowX = "auto" · scroll.wide = 참(item1 표 ≈ 870px > 카드 ≈ 310px · 표 감싸개 안 가로 스크롤) * - rowModal = 「넣을 값 — …」 · qtyModal = 모달 뜸(수량 · 43-1) · 둘 다 닫기 뒤 dirty = false diff --git a/resources/tester/ui_checks/49-6_카드_자재추가_숨김.js b/resources/tester/ui_checks/49-6_카드_자재추가_숨김.js new file mode 100644 index 000000000..5cd5c7167 --- /dev/null +++ b/resources/tester/ui_checks/49-6_카드_자재추가_숨김.js @@ -0,0 +1,46 @@ +/* 49-6 — 구조물 조합 일위대가 카드엔 [자재 추가] 없음 · 일위대가 상세엔 그대로 + * 시작 화면: M02 마스터 템플릿 · 마스터 층(#/m02-master-template?open=구조물조합&root=master) · 시스템 관리자 · + * 나무에 item1(일위대가 담은 로직 있는 열)이 있음 + * 부르는 법: orca eval --expression "$(cat 이 파일)" (async 식 · JSON 글을 돌려줌) + * 기대 수치: card.addMat = 0 · card.addLogic = 0 · card.mats = 1(자재목록 구역은 있음) · detail.addMat = 1 + * 하는 일: 카드 읽기 → 카드 [수정] 상세 읽기(저장 안 함 · item1 다시 눌러 상세에서 나옴) + */ +(async () => { + const w = (ms) => new Promise((r) => setTimeout(r, ms)); + const until = async (fn, ms = 6000) => { + for (let t = 0; t < ms; t += 150) { + const v = fn(); + if (v) return v; + await w(150); + } + return null; + }; + const vis = (b) => b && !b.hidden && b.offsetParent !== null; + const count = (root, t) => + [...root.querySelectorAll("button")].filter((b) => vis(b) && b.textContent.trim() === t).length; + document.querySelector('[data-node="i|item1"]').click(); + const ed = await until(() => { + const e = document.querySelector(".m02-struct__labor .m02-labor__edit"); + return e && e.querySelector("tbody tr[data-labor-logic]") ? e : null; + }); + if (!ed) return JSON.stringify({ error: "카드 몸 없음" }); + const card = ed.closest(".m02-struct > *"); + const out = { + card: { + addMat: count(card, "자재 추가"), + addLogic: count(card, "로직 추가"), + mats: [...ed.querySelectorAll(".m01-logic__section-head h3")].filter( + (h) => h.textContent === "자재목록", + ).length, + }, + }; + // 일위대가 상세 = 카드 [수정] + [...card.querySelectorAll(".m02-struct__card-tools button")] + .find((b) => b.innerText.trim() === "수정") + ?.click(); + await until(() => document.querySelector(".ui-side-panels-row .m02-labor__edit")); + await w(300); + out.detail = { addMat: count(document, "자재 추가") }; + document.querySelector('[data-node="i|item1"]')?.click(); + return JSON.stringify(out); +})();