@kaydash9999/banker-plugins 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +41 -0
  4. package/PRIVACY.md +1 -0
  5. package/README.md +39 -13
  6. package/bin/banker.js +118 -22
  7. package/bin/lib/codex-hooks.mjs +116 -18
  8. package/bin/lib/codex-names.mjs +4 -0
  9. package/bin/lib/codex-routes.mjs +93 -1
  10. package/bin/lib/command-skill.cjs +37 -6
  11. package/codex/command-skills/front-qa/SKILL.md +1 -1
  12. package/codex/command-skills/setup/SKILL.md +4 -4
  13. package/codex/hooks.json +5 -5
  14. package/codex/manifest.json +18 -15
  15. package/codex/skills/progress/scripts/progress.mjs +44 -14
  16. package/codex/skills/teamwork/SKILL.md +137 -0
  17. package/codex/skills/teamwork/scripts/teamwork.mjs +957 -0
  18. package/codex/transform-matrix.md +5 -3
  19. package/hooks/obsidize-hook.mjs +75 -32
  20. package/hooks/telemetry-count-codex.mjs +238 -57
  21. package/hooks/update-fetch.mjs +2 -1
  22. package/hooks/update-notify.mjs +82 -20
  23. package/package.json +3 -1
  24. package/skills/3d-intro-build/SKILL.md +101 -20
  25. package/skills/3d-intro-build/references/NOTICE.md +9 -2
  26. package/skills/3d-intro-build/references/assemble.mjs +113 -22
  27. package/skills/3d-intro-build/references/azure-adapter.mjs +110 -24
  28. package/skills/3d-intro-build/references/clip-post.mjs +443 -0
  29. package/skills/3d-intro-build/references/dive-mode.mjs +299 -0
  30. package/skills/3d-intro-build/references/intro-fixes.css +11 -0
  31. package/skills/3d-intro-build/references/prompts.md +51 -4
  32. package/skills/3d-intro-build/references/scrub-engine.js +1 -0
  33. package/skills/3d-intro-build/references/step-nav.css +29 -0
  34. package/skills/3d-intro-build/references/step-nav.js +277 -106
  35. package/skills/3d-intro-build/references/verify-intro.mjs +373 -32
  36. package/skills/3d-intro-build/references/verify.md +6 -0
  37. package/skills/3d-intro-build/references/video-pool.mjs +142 -12
  38. package/skills/3d-intro-setup/SKILL.md +20 -7
  39. package/skills/3d-intro-setup/references/azure-adapter.mjs +110 -24
  40. package/skills/3d-intro-setup/references/video-pool.mjs +142 -12
  41. package/skills/all-in-one/SKILL.md +125 -86
  42. package/skills/omc-patch/SKILL.md +1 -1
  43. package/skills/payload-mon/SKILL.md +1 -1
  44. package/skills/play-qa/SKILL.md +6 -4
  45. package/skills/progress-mon/README.md +162 -0
  46. package/skills/progress-mon/SKILL.md +165 -0
  47. package/skills/progress-mon/assets/fixture/README.md +1 -0
  48. package/skills/progress-mon/assets/fixture/arch.json +33 -0
  49. package/skills/progress-mon/assets/fixture/commits.json +7 -0
  50. package/skills/progress-mon/assets/fixture/config.json +30 -0
  51. package/skills/progress-mon/assets/fixture/events.jsonl +7 -0
  52. package/skills/progress-mon/assets/fixture/flow.json +44 -0
  53. package/skills/progress-mon/assets/fixture/items.json +14 -0
  54. package/skills/progress-mon/assets/fixture/req-spec.json +31 -0
  55. package/skills/progress-mon/assets/fixture/reqs.json +11 -0
  56. package/skills/progress-mon/assets/fixture/variants/arch-auto/arch.json +58 -0
  57. package/skills/progress-mon/assets/fixture/variants/check-auto/arch.json +15 -0
  58. package/skills/progress-mon/assets/fixture/variants/check-overlap/arch.json +14 -0
  59. package/skills/progress-mon/assets/fixture/variants/history-manual/config.json +13 -0
  60. package/skills/progress-mon/assets/fixture/variants/history-manual/items.json +7 -0
  61. package/skills/progress-mon/assets/fixture/variants/workflow-wide/flow.json +35 -0
  62. package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a01.jsonl +1 -0
  63. package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a02.jsonl +1 -0
  64. package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a03.jsonl +1 -0
  65. package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a04.jsonl +1 -0
  66. package/skills/progress-mon/assets/fixture/workflows/wf_ex1/journal.jsonl +7 -0
  67. package/skills/progress-mon/references/arch.md +280 -0
  68. package/skills/progress-mon/references/authoring.md +199 -0
  69. package/skills/progress-mon/references/config.md +115 -0
  70. package/skills/progress-mon/references/flow.md +75 -0
  71. package/skills/progress-mon/references/inventory.md +58 -0
  72. package/skills/progress-mon/references/items.md +74 -0
  73. package/skills/progress-mon/references/req-spec.md +74 -0
  74. package/skills/progress-mon/references/reqs.md +30 -0
  75. package/skills/progress-mon/scripts/index.js +31 -0
  76. package/skills/progress-mon/scripts/pm-check.mjs +526 -0
  77. package/skills/progress-mon/scripts/pm-config.mjs +341 -0
  78. package/skills/progress-mon/scripts/pm-data.mjs +394 -0
  79. package/skills/progress-mon/scripts/pm-html.mjs +77 -0
  80. package/skills/progress-mon/scripts/pm-memory.mjs +308 -0
  81. package/skills/progress-mon/scripts/pm-render.mjs +1644 -0
  82. package/skills/progress-mon/scripts/pm-server.mjs +735 -0
  83. package/skills/progress-mon/scripts/pm-sources.mjs +501 -0
  84. package/skills/progress-mon/scripts/progress-mon.mjs +167 -0
  85. package/skills/ralph-qa/SKILL.md +104 -15
  86. package/skills/ralph-qa/references/gate-evidence.mjs +457 -0
  87. package/skills/ralph-qa/references/payload-scan.mjs +19 -2
  88. package/skills/ralph-qa/references/run-folder.mjs +299 -0
  89. package/skills/ralph-qa/references/seat-payload.mjs +60 -13
  90. package/skills/ralph-qa/references/seat-run.mjs +159 -155
  91. package/skills/remains/SKILL.md +1 -0
  92. package/skills/remains/scripts/boxes.mjs +6 -2
  93. package/skills/setup-bypass-permissions/scripts/codex-config.mjs +19 -8
  94. package/skills/setup-mcp/SKILL.md +1 -1
  95. package/skills/setup-omc-hud/SKILL.md +2 -1
  96. package/skills/setup-omc-hud/assets/codex-config.mjs +19 -8
  97. package/skills/ultra-chain/SKILL.md +32 -14
  98. package/skills/ultra-chain/references/chain-ledger.mjs +111 -3
  99. package/skills/ultra-init/SKILL.md +30 -22
  100. package/skills/ultraqa/NOTICE.md +34 -0
  101. package/skills/ultraqa/SKILL.md +196 -0
  102. package/skills/ultraqa/references/gate-evidence.mjs +457 -0
  103. package/skills/ultraqa/references/run-folder.mjs +299 -0
  104. package/skills/ultraqa/references/tmux-drive.md +52 -0
  105. package/skills/ultraqa/references/uqa-run.mjs +339 -0
  106. package/skills/update-banker/SKILL.md +1 -1
@@ -0,0 +1,58 @@
1
+ {
2
+ "note": "좌표 키 하나(zones[1].h)가 빠진 변형. 그림 전체 자동 배치.",
3
+ "width": 1000,
4
+ "height": 380,
5
+ "legend": [
6
+ "주황 굵은 선: 요청 길",
7
+ "점선: 파일 읽기와 쓰기"
8
+ ],
9
+ "main": [
10
+ "browser",
11
+ "server",
12
+ "render"
13
+ ],
14
+ "zones": [
15
+ { "id": "user", "label": "사용자 쪽", "x": 20, "y": 40, "w": 200, "h": 320, "color": "#1565c0" },
16
+ { "id": "app", "label": "앱", "x": 320, "y": 40, "w": 360, "color": "#2e7d32" },
17
+ { "id": "store", "label": "저장", "x": 780, "y": 40, "w": 200, "h": 320, "color": "#6a1b9a", "dashed": true }
18
+ ],
19
+ "nodes": [
20
+ { "id": "browser", "zone": "user", "label": "브라우저", "x": 40, "y": 90, "w": 160, "h": 64, "kind": "사람", "detail": "탭을 고름" },
21
+ { "id": "cli", "zone": "user", "label": "CLI", "x": 40, "y": 250, "w": 160, "h": 64, "kind": "명령", "detail": "시작, 정지, 기록" },
22
+ { "id": "server", "zone": "app", "label": "서버", "x": 340, "y": 90, "w": 130, "h": 64, "kind": "프로세스", "detail": "Host 검사" },
23
+ { "id": "render", "zone": "app", "label": "렌더", "x": 530, "y": 90, "w": 130, "h": 64, "kind": "모듈", "detail": "네 탭 HTML" },
24
+ { "id": "files", "zone": "store", "label": "자료 파일", "x": 800, "y": 90, "w": 160, "h": 64, "kind": "파일", "detail": "JSON 네 개" },
25
+ { "id": "git", "zone": "store", "label": "git 저장소", "x": 800, "y": 250, "w": 160, "h": 64, "kind": "저장소", "detail": "커밋 제목" }
26
+ ],
27
+ "edges": [
28
+ { "id": "e-req", "from": "browser", "to": "server", "kind": "api", "label": "요청", "off": -12 },
29
+ { "id": "e-render", "from": "server", "to": "render", "kind": "control", "label": "" },
30
+ { "id": "e-read", "from": "render", "to": "files", "kind": "data", "label": "자료 읽기" },
31
+ { "id": "e-log", "from": "render", "to": "git", "kind": "data", "label": "" },
32
+ { "id": "e-ctl", "from": "cli", "to": "server", "kind": "control", "label": "시작, 정지" },
33
+ { "id": "e-write", "from": "cli", "to": "store", "kind": "data", "label": "자료 쓰기" },
34
+ { "id": "e-res", "from": "server", "to": "browser", "kind": "control", "label": "응답", "off": 12 }
35
+ ],
36
+ "scenes": [
37
+ {
38
+ "n": 1,
39
+ "sec": 2,
40
+ "focus": [
41
+ "browser",
42
+ "server",
43
+ "e-req"
44
+ ],
45
+ "caption": "브라우저가 서버에 요청"
46
+ },
47
+ {
48
+ "n": 2,
49
+ "sec": 3,
50
+ "focus": [
51
+ "render",
52
+ "files",
53
+ "git"
54
+ ],
55
+ "caption": "렌더가 자료와 git 을 읽음"
56
+ }
57
+ ]
58
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "note": "check 사례: 좌표 없는 구성도. 같은 행의 가운데 상자를 건너뛰는 연결.",
3
+ "zones": [
4
+ { "id": "z1", "label": "영역", "color": "#1565c0" }
5
+ ],
6
+ "nodes": [
7
+ { "id": "n1", "zone": "z1", "label": "하나" },
8
+ { "id": "n2", "zone": "z1", "label": "둘" },
9
+ { "id": "n3", "zone": "z1", "label": "셋" }
10
+ ],
11
+ "edges": [
12
+ { "id": "e1", "from": "n1", "to": "n3", "kind": "control", "label": "" }
13
+ ],
14
+ "scenes": []
15
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "note": "check 사례: 좌표가 겹친 구성도.",
3
+ "width": 460,
4
+ "height": 240,
5
+ "zones": [
6
+ { "id": "z1", "label": "영역", "x": 20, "y": 20, "w": 420, "h": 200, "color": "#1565c0" }
7
+ ],
8
+ "nodes": [
9
+ { "id": "n1", "zone": "z1", "label": "상자 하나", "x": 40, "y": 60, "w": 160, "h": 64 },
10
+ { "id": "n2", "zone": "z1", "label": "상자 둘", "x": 150, "y": 90, "w": 160, "h": 64 }
11
+ ],
12
+ "edges": [],
13
+ "scenes": []
14
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "schema": 1,
3
+ "title": "수동 기록 예시",
4
+ "shortName": "manual-app",
5
+ "refreshSec": 30,
6
+ "stages": "auto",
7
+ "stories": [],
8
+ "sources": {
9
+ "events": "auto",
10
+ "git": true,
11
+ "workflowDirs": []
12
+ }
13
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "notes": {},
3
+ "items": [],
4
+ "storyCommits": {},
5
+ "storyStates": {},
6
+ "stageEvents": []
7
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "note": "긴 흐름 변형. 분기 5개 단계 바로 아래 칸 상자에 외부 표가 있음.",
3
+ "lanes": [
4
+ {
5
+ "id": "wide",
6
+ "title": "긴 흐름 예시",
7
+ "color": "#6a1b9a",
8
+ "steps": [
9
+ { "id": "w1", "label": "시작", "detail": "인자 확인", "actor": "cli.mjs", "refs": [], "planned": false },
10
+ { "id": "w2", "label": "권한 확인", "detail": "자료 폴더 쓰기 권한", "actor": "cli.mjs", "refs": [], "planned": false },
11
+ { "id": "w3", "label": "자료 읽기", "detail": "네 자료 파일 읽기", "actor": "sources.mjs", "refs": [], "planned": false },
12
+ { "id": "w4", "label": "판정", "detail": "단계와 스토리 상태", "actor": "sources.mjs", "refs": [], "planned": false },
13
+ { "id": "w5", "label": "설정 파일 형식 검사와 보정", "detail": "틀린 키를 기본값으로 바꾸고 경고 줄을 남김. 바꾼 키는 기록에 적음", "actor": "config.mjs", "refs": [], "planned": false },
14
+ { "id": "w6", "label": "렌더", "detail": "탭 HTML", "actor": "render.mjs", "refs": [], "planned": false },
15
+ { "id": "w7", "label": "응답", "detail": "브라우저로 보냄", "actor": "server.mjs", "refs": [], "planned": false },
16
+ { "id": "w8", "label": "알림", "detail": "완료 알림 보냄", "actor": "notify.mjs", "refs": [], "planned": false },
17
+ { "id": "w9", "label": "결과 알림 보내기", "detail": "알림 결과를 모아 한 번에 보냄. 실패하면 다시 보냄", "actor": "notify.mjs", "refs": [], "planned": true },
18
+ { "id": "w10", "label": "정리", "detail": "임시 파일 지움", "actor": "cli.mjs", "refs": [], "planned": false }
19
+ ],
20
+ "branches": [
21
+ { "from": "w3", "to": "w1", "when": "형식 오류", "note": "JSON 이 깨짐" },
22
+ { "from": "w3", "to": "w2", "when": "권한 없음", "note": "읽기 권한 없음" },
23
+ { "from": "w3", "to": "", "when": "시간 초과", "note": "5초 넘음" },
24
+ { "from": "w3", "to": "w10", "when": "중복 실행", "note": "다른 쓰기가 진행 중" },
25
+ { "from": "w3", "to": "", "when": "취소됨", "note": "사용자가 멈춤" }
26
+ ],
27
+ "externals": [
28
+ { "id": "x1", "label": "알림 서버", "linkTo": "w8", "note": "외부 알림 서비스" }
29
+ ]
30
+ }
31
+ ],
32
+ "scenes": [
33
+ { "n": 1, "sec": 3, "lane": "wide", "focus": ["w3"], "caption": "분기가 많은 단계" }
34
+ ]
35
+ }
@@ -0,0 +1 @@
1
+ {"type":"user","message":{"role":"user","content":"예시 작업 a01"}}
@@ -0,0 +1 @@
1
+ {"type":"user","message":{"role":"user","content":"예시 작업 a02"}}
@@ -0,0 +1 @@
1
+ {"type":"user","message":{"role":"user","content":"예시 작업 a03"}}
@@ -0,0 +1 @@
1
+ {"type":"user","message":{"role":"user","content":"예시 작업 a04"}}
@@ -0,0 +1,7 @@
1
+ {"type":"launched"}
2
+ {"type":"started","key":"k1","agentId":"a01","label":"impl-A1-r1","phase":"impl"}
3
+ {"type":"result","key":"k1","agentId":"a01","result":{"done":true}}
4
+ {"type":"started","key":"k2","agentId":"a02","label":"impl-A2-r1","phase":"impl"}
5
+ {"type":"result","key":"k2","agentId":"a02","result":{"done":true}}
6
+ {"type":"started","key":"k3","agentId":"a03","label":"impl-A3-r1","phase":"impl"}
7
+ {"type":"started","key":"k4","agentId":"a04","label":"check-docs","phase":"review"}
@@ -0,0 +1,280 @@
1
+ # arch.json
2
+
3
+ 구성도 탭의 영역(zones), 구성요소(nodes), 연결(edges). init 은 좌표 없이 쓴다(자동 배치).
4
+
5
+ ## 스키마
6
+
7
+ ```json
8
+ {
9
+ "note": "구성요소와 연결을 그린 화면. 실행 순서는 workflow 탭. 근거는 저장소 루트 기준 파일:줄.",
10
+ "legend": ["요청 길(주황 굵은 선): 브라우저, API 서버, DB 차례", "점선은 파일과 설정 읽기"],
11
+ "main": ["web", "api", "db"],
12
+ "zones": [
13
+ { "id": "client", "label": "사용자 쪽", "color": "#1565c0" },
14
+ { "id": "server", "label": "서버", "color": "#2e7d32" },
15
+ { "id": "ext", "label": "외부", "color": "#757575", "dashed": true }
16
+ ],
17
+ "nodes": [
18
+ { "id": "web", "zone": "client", "label": "웹 화면", "kind": "프런트엔드", "detail": "목록과 상세 화면을 그리고 /api 로 요청을 보냄", "items": ["React 18", "라우터"], "refs": ["web/src/App.tsx:1-40"], "lines": 2 },
19
+ { "id": "api", "zone": "server", "label": "API 서버", "kind": "서비스", "detail": "요청을 검증하고 저장소 계층을 불러 JSON 으로 답함", "refs": ["server/app.js:12-60"] },
20
+ { "id": "db", "zone": "ext", "label": "PostgreSQL", "kind": "외부", "detail": "주문과 사용자 표를 저장. 연결 문자열은 환경 변수", "refs": ["server/db.js:5"] }
21
+ ],
22
+ "edges": [
23
+ { "id": "e-req", "from": "web", "to": "api", "kind": "api", "label": "HTTP /api", "detail": "fetch 로 JSON 요청", "refs": ["web/src/api.ts:8"] },
24
+ { "id": "e-sql", "from": "api", "to": "db", "kind": "data", "label": "SQL", "refs": ["server/db.js:20-34"] }
25
+ ],
26
+ "scenes": [
27
+ { "n": 1, "sec": 1.2, "focus": ["web", "e-req"], "caption": "사용자가 화면에서 요청을 보냄" }
28
+ ]
29
+ }
30
+ ```
31
+
32
+ | 키 | 형식 | 필수 | 뜻 |
33
+ |---|---|---|---|
34
+ | `note` | 문자열 | 아니오 | 탭 머리 설명 |
35
+ | `legend` | 문자열 배열 | 밀도 | "읽는 법" 목록 |
36
+ | `main` | 구성요소 id 배열 | 밀도 | 주 흐름. 이 차례로 상자가 빛남 |
37
+ | `zones[]` | `{id, label, color?, dashed?}` | 예 | 영역. `dashed` 면 점선 테두리 |
38
+ | `nodes[]` | `{id, zone, label, kind?, detail, lines?, items?, refs?, path?, planned?, color?}` | 예 | 구성요소. `zone` 은 영역 id |
39
+ | `nodes[].detail` | 문자열 | 예 | 상자 안 설명. 상자 폭으로 줄바꿈, 기본 2줄만 그림. 3줄이면 `"lines": 3`(`references/authoring.md` 의 "설명 줄 수") |
40
+ | `nodes[].items` | 문자열 배열 | 아니오 | 칩. `config.json` 의 `text.plannedPrefix`(기본 `예정`)로 시작하면 주황 |
41
+ | `nodes[].refs`, `path`, `kind` | 문자열 | 아니오 | 마우스를 올리면 보이는 근거 |
42
+ | `edges[]` | `{id?, from, to, kind?, label?, detail?, refs?, both?, color?}` | 예 | 연결. id 가 없으면 `<from>-<to>` |
43
+ | `edges[].from`, `to` | 문자열 | 예 | 구성요소 id 를 먼저 찾고 없으면 영역 id |
44
+ | `edges[].kind` | `api`, `control`, `data` | 아니오 | `api` 주황 굵은 선(요청 길), `control` 회색 실선(실행, 호출), `data` 점선(파일, 설정) |
45
+ | `edges[].refs` | 문자열 배열 | 밀도 | 근거 `파일:줄` |
46
+ | `edges[].both` | 참, 거짓 | 아니오 | 양쪽 화살표 |
47
+ | `scenes[]` | `{n, sec, focus, caption}` | 밀도 | 장면 대본. `focus` 는 구성요소 id 나 연결 id |
48
+
49
+ - 색은 `#rrggbb` 만. 그 밖은 FAIL, 화면은 기본 색
50
+ - 연결에 마우스를 올리면 `detail`, 없으면 `label` 이 보이고 뒤에 `refs`. 둘 다 없으면 `refs` 만
51
+ - `from` 과 `to` 가 같은 연결(자기 연결)은 그릴 길이 없다. `check` 가 `자기 연결` WARN
52
+
53
+ ## 좌표 키
54
+
55
+ 좌표는 선택이다. 아래 키가 모두 있고 유한 수일 때만 좌표를 쓴다.
56
+
57
+ | 대상 | 키 |
58
+ |---|---|
59
+ | 그림 | `width`, `height` |
60
+ | 영역 | `x`, `y`, `w`, `h` |
61
+ | 상자 | `x`, `y`, `w`, `h` |
62
+ | 연결(있을 때만 쓰는 선택 키) | `via`(`[[x, y], ...]`), `lx`, `ly`, `off`, `offTo` |
63
+
64
+ - 하나라도 빠지거나 틀리면 그 그림 전체를 자동 배치하고, 연결 선택 키는 무시한다. 좌표를 일부만 썼으면 `check` 가 WARN
65
+ - 자동 배치는 화면에 따로 알리지 않는다. 좌표를 일부만 쓴 경우는 `check` 의 WARN 으로 안다
66
+ - 영역을 끝으로 쓰는 연결은 영역 사각형 가장자리에서 나간다
67
+
68
+ ## 자동 배치
69
+
70
+ 목표는 가로로 넓은 그림이다(옛 운영 화면 1600 x 1000 과 비슷한 비). 영역을 띠(가로 줄)에 옆으로 놓고, 띠가 차면 다음 띠로 내려간다.
71
+
72
+ - 영역: 영역 순서대로 띠에 왼쪽부터 채운다. 띠 폭이 상한을 넘으면 다음 띠
73
+ - 영역 순서 후보는 둘. `zones` 배열 순서, 그리고 연결이 많은 영역끼리 이웃하게 이은 순서(첫 영역에서 시작해 마지막에 놓은 영역과 연결이 가장 많은 영역을 다음에. 같으면 이미 놓은 영역 전체와 연결 수, 다음에 배열 순서)
74
+ - 지그재그 후보: 둘째, 넷째 띠를 오른쪽부터 채운다. 앞 띠의 끝 영역 바로 아래에 다음 영역이 온다
75
+ - 같은 띠 옆 영역 사이 틈은 48 px. 두 영역을 잇는 이름표 있는 연결이 있으면 가장 넓은 이름표 폭 + 16 px 까지 넓힌다. 이름표가 영역 테두리를 덮지 않고 틈에 들어간다
76
+ - 띠마다 영역 폭을 똑같이 늘려 모든 띠를 가장 넓은 띠 폭에 맞춘다. 영역 높이는 그 띠에서 가장 높은 영역에 맞춘다
77
+ - 상자: 영역마다 그 영역 상자를 아래 순서대로 행 우선. 칸 수는 줄 수가 상한 이하가 되는 가장 적은 수. 상자 묶음은 영역 가운데
78
+ - 상자 순서 후보는 둘. `nodes` 배열에서 나온 순서, 그리고 다른 영역과 잇는 연결이 4개 이상 몰린 상자만 옮긴 순서
79
+ - 옮기는 값: 영역 순서에서 뒤 영역(영역 없는 상자 포함)과 잇는 연결 수 - 앞 영역과 잇는 연결 수. 4 이상이면 맨 뒤 칸(아래 행), -4 이하면 맨 앞 칸. 나머지 상자는 배열 순서 그대로
80
+ - 영역 폭이 띠 폭 상한을 넘으면 칸 수를 줄이고 줄을 늘린다. 그래서 그림 폭은 띠 폭 상한 + 40 px 이하(1600 px, 넓은 후보는 1800 px)
81
+ - 영역 없는 상자(`zone` 이 영역 id 가 아님)는 맨 아래 띠에 혼자 놓는다. 테두리 없음
82
+ - 상자 크기: 영역마다 모든 상자가 같은 폭과 높이. 그 영역에서 가장 크게 필요한 상자에 맞춤
83
+ - 연결: 장애물을 피하는 가로세로 길 찾기. 모든 선분이 가로나 세로(옛 운영 화면과 같음). 대각선은 없다
84
+ - 두 끝이 아닌 상자와 영역 제목 띠는 지나지 않는다. 같은 영역 안 연결도 같다(같은 행에서 사이 상자를 건너뛰는 연결은 그 상자를 돌아감)
85
+ - 영역 제목 띠: 영역 이름을 쓰는 자리. 영역 왼쪽 위에서 (12, 5), 폭은 영역 이름 글 폭 x 1.3, 높이 18 px
86
+ - 격자: 통로 가운데 선(상자 옆 틈, 같은 행 이웃 상자 사이 틈, 상자 아래 틈, 영역 사이 틈, 영역 안 상자 묶음 둘레의 넓은 빈 곳, 그림 가장자리 여백)과 상자 가운데 선. 6 px 보다 가까운 선은 하나만 둔다(상자 가운데 선이 먼저)
87
+ - 통로 가운데 선이 그림 가장자리 여백 가운데(가장자리에서 10 px)보다 바깥이면 버린다. 영역 테두리에 가까운 선은 남긴다(다른 띠 영역 테두리에 가까워 상자 사이 틈 가운데 선이 사라지지 않게). 그 테두리를 따라 가지 못하는 것은 아래 규칙
88
+ - 영역 제목 띠를 지나는 가로선과 세로선이 없으면 띠 가운데에 하나씩 더한다
89
+ - 같은 띠 옆 영역 사이 틈 가운데에도 세로선을 둔다(넓힌 틈에 이름표가 들어가는 자리)
90
+ - 격자점은 상자와 영역 제목 띠에서 8 px 넘게 떨어진 곳만 쓴다
91
+ - 영역 테두리에서 6 px 보다 가까운 격자선(다른 띠의 상자 가운데 선 등)은 그 테두리를 따라 가지 않는다. 가로지르기만 한다
92
+ - 끝 자리: 상자는 네 옆면에서, 옆면을 지나는 격자선마다(모서리에서 10 px 안쪽). 옆면 가운데에서 떨어진 px 마다 0.5 를 더한다. 영역 끝은 영역 테두리를 지나는 격자선마다
93
+ - 끝 선분(옆면에서 첫 격자점까지)은 10 px 이상(화살표 길이). 끝 자리 쪽에서 되돌아 들어오는 길(제 선과 겹치고 끝 선분이 짧아짐)은 쓰지 않는다
94
+ - 짧은 연결부터 하나씩, 값이 가장 작은 길을 고른다(A*). 값이 같으면 먼저 찾은 길. 같은 자료면 늘 같은 선
95
+ - 값: 길이 + 꺾기 x 40 + 다른 선과 엇갈림 x 30 + 이미 다른 선이 지나는 통로 길이 x 0.5 x 그 선 수 + 같은 옆면을 쓰는 연결 수 x 12(같은 자리면 30 더)
96
+ + 두 끝이 속하지 않는 영역 안을 지나는 길이 x 1 + 그림 가장자리 여백(가장자리에서 20 px 안)과 영역 머리 줄(영역 위 테두리에서 32 px 안)을 따라 가는 길이 x 0.5
97
+ - 두 끝이 속한 영역은 상자 끝이면 그 상자가 든 영역, 영역 끝이면 그 영역. 관계없는 영역을 가로지르는 선은 돌아갈 길이 영역 안 길이보다 짧을 때 돌아간다
98
+ - 통로마다 나란한 선이 들어갈 수(폭에서 20 을 뺀 폭 / 12 + 1)를 넘기면 그 통로 길이 x 4 를 더한다. 통로 폭은 양옆에서 가장 가까운 상자, 영역 제목 띠, 영역 테두리 사이
99
+ - 이름표가 있는 연결은 이름표가 상자와 겹치지 않고(격자점에서 선분과 수직으로 6 px, 선분 방향으로 1 px 여유) 영역 테두리에서 4 px 떨어지는 곧은 구간을 지나는 길만 고른다. 그런 길이 없으면 조건 없이 고른다
100
+ - 길을 찾지 못하면(끝 자리가 모두 막힘) 한 번 꺾은 선. 이때만 선이 상자를 지날 수 있고 `check` 가 `선이 상자 지남` WARN
101
+ - 나란한 선: 같은 방향 선분이 구간이 겹치거나 12 px 안으로 이어지면 나란한 자리로 벌린다. 관계없는 연결이 한 선분을 같이 쓰지 않는다. 혼자인 선분도 아래 범위 안으로 옮긴다
102
+ - 간격과 상자 거리(영역 제목 띠도 같음)는 아래 차례로 처음 맞는 것. 끝내 못 맞추면 원래 줄에 둔다. 나란한 영역 테두리와 그림 가장자리에서는 늘 6 px 이상
103
+ 1. 이름표 있는 연결의 가로 선분끼리 이웃이면 20 px(이름표 높이 16 + 4), 나머지 12 px, 상자에서 10 px. 이름표 있는 가로 선분이 이웃할 때만
104
+ 2. 간격 12 px, 상자에서 10 px
105
+ 3. 간격 11 에서 6 px 까지, 상자에서 10 px
106
+ 4. 간격 12 에서 6 px 까지, 상자에서 6 px
107
+ 5. 간격 5, 4 px, 상자에서 10 px, 다음에 6 px
108
+ 6. 간격 12 에서 3 px 까지, 상자에서 3 px
109
+ - 단계마다 먼저 이름표 있는 선과 100 px 넘는 선분은 나란한 영역 테두리에서 12 px, 이름표 있는 가로 선분은 상자에서 13 px(이름표 반 높이 8 + 5) 떨어뜨려 보고, 안 되면 6 px 과 위 상자 거리로
110
+ - 끝 선분에 이어지는 선분은 끝 상자에서 10 px 이상(끝 선분이 화살표 길이 이상). 끝 자리는 옆면 모서리에서 10 px 안쪽
111
+ - 차례: 원래 줄 좌표, 다음에 먼저 끝나는 쪽 끝에서 꺾는 방향(위, 왼쪽으로 꺾으면 앞 자리). 엇갈림이 덜 생긴다
112
+ - 벌린 뒤 다른 묶음 선과 12 px 보다 가까우면 두 묶음을 합쳐 다시 벌린다
113
+ - 이름표: 선을 모두 그은 뒤 놓는다. 후보 자리는 그 연결의 선분을 긴 차례로, 선분마다 17곳. 0.5 에서 시작 쪽으로 0.1 까지, 다음에 끝 쪽으로 0.55 에서 0.9 까지(0.05 간격)
114
+ - 상자와 겹치지 않는 후보가 없으면 선분마다 가운데부터 4 px 간격으로 더 본다
115
+ - 그림 밖으로 나가는 후보는 그림 안(가장자리에서 1 px 안쪽, 테두리 선 굵기 포함)으로 민다
116
+ - 상자와 겹치지 않는 후보가 적은 이름표부터 놓는다(같으면 연결 차례)
117
+ - 상자와 겹치지 않고 상자에서 5 px 이상, 앞서 놓은 이름표와 4 px 이상 떨어지고, 영역 이름과 영역 테두리를 가리지 않고, 다른 연결의 선과 4 px 이상 떨어진 첫 곳에 놓는다. 영역 테두리는 4 px 안에 들어와도 가린 것으로 센다
118
+ - 그런 곳이 없으면 (덮는 상자 수, 5 px 안 상자 수, 가까운 이름표 수, 가리는 영역 이름과 영역 테두리 수, 4 px 안의 다른 선 수)가 가장 작은 첫 곳에 놓는다. 상자를 덮으면 `check` 가 `이름표 덮음` WARN
119
+ - 배치 고르기: 아래 후보를 놓아 보고, 그 가운데 몇 개만 선을 그어 하나를 고른다
120
+ - 후보: 순서(영역 순서 2 x 상자 순서 2, 같은 것은 하나) x 띠 폭 상한(1200, 1400, 1560 px) x 영역 안 줄 수 상한(1 부터 가장 많은 영역의 상자 수까지) x 띠 방향(왼쪽부터, 지그재그)
121
+ - 값: 높이 + (`선이 상자 지남`, `이름표 덮음`, `이름표가 그림 밖` 수) x 60 + 선 길이 합 x 0.1 + 엇갈림 수 x 10 + 붐비는 이름표 수 x 30
122
+ + 다른 영역 안 길이 x 0.3 + (좁은 나란한 선 쌍 수 + 테두리 붙은 긴 선분 수) x 20
123
+ - 엇갈림은 다른 연결의 가로 선분과 세로 선분이 두 선분 안쪽에서 만나는 곳
124
+ - 붐비는 이름표는 놓은 자리에서 상자에서 5 px 안이거나 영역 이름이나 영역 테두리를 가리거나 다른 선이 4 px 안에 있는 이름표
125
+ - 다른 영역 안 길이는 선분이 두 끝이 속하지 않는 영역 사각형 안을 지나는 길이 합
126
+ - 좁은 나란한 선 쌍은 다른 연결의 같은 방향 선분이 20 px 넘게 함께 달리며 12 px 보다 가까운 쌍. 테두리 붙은 긴 선분은 영역 테두리와 100 px 넘게 나란히 12 px 안을 달리는 선분
127
+ - 가중치 근거: 다른 영역 1 px 의 0.3 은 선 길이 1 px 의 3배(관계없는 영역을 지나는 선은 길이보다 읽기를 크게 해침. 0.5 로 하면 영역을 피하려고 그림이 세로로 길어짐). 좁은 쌍 하나의 20 은 엇갈림 둘, 높이 20 px 과 같음
128
+ - 상자 20개 이상이고 가로세로 비가 1.2 아래면 모자란 폭(1.2 x 높이 - 폭)을 높이에 더한다
129
+ - 선을 긋기 전에 아래 한계(높이 + 두 끝 사각형 사이 가로세로 거리 합 x 0.1, 비가 모자라면 위와 같이 더함)를 잰다. 선은 두 끝 사이 거리보다 짧을 수 없다
130
+ - 비 하한을 맞춘 후보를 앞에, 다음에 아래 한계가 작은 차례(같으면 먼저 만든 후보)로 줄 세워 앞 3개만 선을 긋는다. 그 가운데 앞서 고른 후보 값보다 아래 한계가 큰 후보는 긋지 않는다
131
+ - 고르는 기준(앞 기준이 같을 때만 다음 기준)
132
+
133
+ | 순서 | 기준 |
134
+ |---|---|
135
+ | 1 | 상자 20개 이상이면 가로세로 비(폭 / 높이) 1.2 이상 |
136
+ | 2 | 위 값이 가장 작음 |
137
+ | 3 | 먼저 만든 후보(배열 순서, 띠 폭 상한이 작은 것, 줄 수 상한이 작은 것, 왼쪽부터 채우기 차례) |
138
+
139
+ - 고른 후보에서 아래 틈을 넓혀 한 번 더 놓고 그어 본다. 값이 더 작고 기준 1 을 지키면 바꾼다
140
+ - 같은 띠 옆 영역 사이 틈: 그 틈을 지나는 세로 선분을 구간이 이어지는 묶음으로 나눠 가장 큰 묶음의 선 수가 n 이면 (n - 1) x 12 + 24 px. 지금 틈보다 넓을 때만
141
+ - 띠 사이 틈: 가로 선분으로 같은 방법
142
+ - 영역 안 상자 사이 가로 간격: 같은 행 이웃 상자를 곧게 잇는 이름표 있는 선의 이름표가 상자에서 5 px 안이면 이름표 폭 + 12 px(76 px 이하일 때만)
143
+ - 1560 px 후보로 기준 1 을 못 맞추면 띠 폭 상한 1760 px 후보도 같은 방법으로 보고, 위 기준으로 더 나은 쪽을 고른다
144
+ - 같은 그림이 되는 후보는 한 번만 본다. 같은 자료면 늘 같은 배치
145
+
146
+ ### 자동 배치 치수
147
+
148
+ | 항목 | 값 |
149
+ |---|---|
150
+ | 바깥 여백 | 20 px |
151
+ | 영역 머리(영역 이름 줄) | 32 px |
152
+ | 영역 안 여백(좌우, 아래) | 16 px |
153
+ | 상자 사이 가로 간격 | 60 px. 같은 행 이웃 상자를 곧게 잇는 선의 이름표가 상자에서 5 px 안이면 그 영역만 이름표 폭 + 12 px(76 px 이하) |
154
+ | 상자 사이 세로 간격(영역 안 행 사이) | 40 px |
155
+ | 띠 사이 간격(위아래 영역 사이) | 72 px. 나란한 가로 선이 들어가지 않으면 (선 수 - 1) x 12 + 24 px |
156
+ | 같은 띠 영역 사이 간격(옆) | 48 px. 두 영역을 잇는 이름표 있는 연결이 있으면 가장 넓은 이름표 폭 + 16 px 과 48 px 가운데 큰 값. 나란한 세로 선이 들어가지 않으면 (선 수 - 1) x 12 + 24 px |
157
+ | 띠 폭 상한 후보 | 1200, 1400, 1560 px. 비를 못 맞추면 1760 px |
158
+ | 그림 폭 상한 | 띠 폭 상한 + 40 px(1600 px, 넓은 후보 1800 px) |
159
+ | 가로세로 비 하한 | 1.2(상자 20개 이상일 때만) |
160
+ | WARN 하나의 값(배치 고르기) | 60 px |
161
+ | 길 찾기 격자점과 상자 테두리 사이 | 8 px 초과 |
162
+ | 나란한 선 간격 | 12 px(모자라면 3 px 까지). 이름표 있는 연결의 가로 선분끼리는 먼저 20 px |
163
+ | 이름표와 다른 선, 영역 테두리 사이 | 4 px 이상(자리가 없으면 가장 덜 가리는 곳) |
164
+ | 이름표와 상자 사이 | 5 px 이상(자리가 없으면 가장 덜 가리는 곳) |
165
+ | 길 찾기 값(영역, 가장자리) | 두 끝이 속하지 않는 영역 안 1 px 에 1, 그림 가장자리 여백(20 px 안)과 영역 머리 줄(32 px 안)을 따라 1 px 에 0.5 |
166
+ | 배치 고르기 값 | 선 길이 1 px 에 0.1, 엇갈림 하나에 10, 붐비는 이름표 하나에 30, 다른 영역 안 1 px 에 0.3, 좁은 나란한 선 쌍과 테두리 붙은 긴 선분 하나에 20 |
167
+ | 선을 그어 보는 후보 수 | 3(비 하한, 아래 한계 차례) |
168
+ | 상자 순서를 옮기는 연결 수 | 4 이상 |
169
+ | 나란한 선과 상자 사이 | 10 px(모자라면 3 px 까지) |
170
+ | 선과 나란한 영역 테두리, 그림 가장자리 사이 | 6 px 이상. 이름표 있는 선과 100 px 넘는 선분은 영역 테두리에서 먼저 12 px |
171
+ | 끝 선분 최소 길이 | 10 px |
172
+ | 상자 최소 크기 | 폭 160 px, 높이 64 px |
173
+ | 상자 폭 | 160, 이름 글 폭 x 1.3 + 16(`planned` 면 표시 폭 더함), 가장 넓은 칩 + 14, 설명의 가장 긴 낱말 글 폭 x 1.1 + 16 가운데 큰 값. 영역마다 가장 넓은 폭에 맞춤 |
174
+ | 상자 높이 | 64 와 내용 아래 끝 + 10 가운데 큰 값. 영역마다 가장 큰 높이에 맞춤 |
175
+ | 내용 아래 끝 | 칩 없음: 24 + 14 x 설명 줄. 칩 있음: 46 + 14 x 설명 줄 + 19 x (칩 줄 - 1) |
176
+ | 행 높이(영역 안) | 상자 높이 + 40 px |
177
+ | 영역 높이 | 32 + 행 수 x 상자 높이 + (행 수 - 1) x 40 + 16 px. 띠 안에서는 가장 높은 영역에 맞춤 |
178
+ | 이름표 크기 | 높이 16 px, 폭 = 글 폭 + 10 px |
179
+ | 글 폭 추정 | 한글 등 넓은 글자 10.5 px, 영문, 숫자, 공백 6 px |
180
+
181
+ - 위아래 띠의 상자 사이 세로 거리: 16 + 72 + 32 = 120 px 이상. 이름표(높이 16)가 넉넉히 들어감
182
+ - 같은 띠 옆 영역의 상자 사이 가로 거리: 16 + 48 + 16 = 80 px 이상(영역을 늘리거나 이름표로 틈을 넓히면 더 넓음)
183
+ - 같은 행 이웃 상자 사이 가로 선은 60 px. 이름표 글 폭이 48 px 를 넘으면(한글 5자 이상) 선이 이름표가 들어가는 통로(행 사이, 영역 사이)로 돌아간다. 이름표가 상자에서 5 px 안이면 위 표대로 그 영역 간격을 넓혀 본다
184
+
185
+ ### 결과 예
186
+
187
+ 좌표를 모두 지운 자료를 자동 배치한 크기와 WARN 수(이 스킬을 만들 때 잰 값. 내 자료는 `check` 의 WARN 과 화면으로 확인).
188
+ 겹친 선분은 다른 연결의 같은 방향 선분이 6 px 보다 가깝고 구간이 겹치는 쌍. 이름표 겹침은 이름표가 상자나 다른 이름표와 겹치는 수.
189
+ 제목 띠 통과는 영역 제목 띠를 지나는 선분 수. 테두리 붙음은 영역 테두리와 나란히 6 px 안을 달리는 선분 길이 합(px). 가장자리 붙음은 그림 가장자리 6 px 안을 달리는 선분 수.
190
+ 엇갈림은 다른 연결의 가로 선분과 세로 선분이 만나는 수. 선 길이는 px. 긴 선은 700 px 넘는 선 수. 테두리 위 이름표는 영역 테두리가 지나는 이름표 수.
191
+ 이름표와 선 간격은 이름표와 다른 연결 선 사이 최소 거리(px, 괄호는 4 px 안에 다른 선이 있는 이름표 수). 나란한 선 간격은 다른 연결의 나란한 선 사이 최소 거리(px).
192
+ 다른 영역은 두 끝이 속하지 않는 영역 안을 지나는 선 수(괄호는 그 길이 합 px). 이름표와 상자 간격은 이름표와 상자 사이 최소 거리(px).
193
+
194
+ | 자료 | 영역 | 상자 | 연결 | 크기(비) | 대각 선분 | WARN(선이 상자 지남, 이름표 덮음, 이름표가 그림 밖) | 겹친 선분 | 이름표 겹침 | 제목 띠 통과 | 테두리 붙음 | 가장자리 붙음 | 엇갈림 | 선 길이 | 긴 선 | 테두리 위 이름표 | 이름표와 선 간격 | 나란한 선 간격 | 다른 영역 | 이름표와 상자 간격 |
195
+ |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
196
+ | 견본(banker 플러그인) | 7 | 46 | 43 | 1657 x 1308(1.27) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 28 | 19235 | 9 | 0 | 0(5) | 12 | 8(3018) | 1 |
197
+ | 빌드와 런처 | 11 | 38 | 33 | 1528 x 1109(1.38) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 13 | 12088 | 5 | 1 | 0(6) | 6 | 4(792) | 5 |
198
+ | 이 저장소 운영 자료(좌표 지움) | 8 | 46 | 27 | 1699 x 1676(1.01) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 38 | 19634 | 14 | 0 | 4(0) | 7 | 2(940) | 5.5 |
199
+ | 작은 CLI | 6 | 10 | 10 | 1491 x 324(4.60) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2411 | 2 | 0 | 12(0) | 20 | 0(0) | 12 |
200
+
201
+ - 한계: 상자가 많고 큰 영역(칩이 많아 상자가 높은 영역 등)은 폭 상한 안에서 줄을 늘리므로 그림이 세로로 길어질 수 있다. 위 셋째 줄은 12상자 영역의 상자 높이가 198 px 이라 가로세로 비 1.2 를 맞추지 못하고 비 1.01 로 물러남
202
+ - 한계: 좁은 통로에 선이 몰리면 나란한 선 간격이 6 px 까지 줄고, 이름표 자리가 모자라면 이름표가 다른 선에 4 px 보다 가깝거나 영역 테두리에 걸친다(위 둘째 줄 1개)
203
+ - 한계: 연결이 10개 넘게 몰린 상자는 옆면 하나에서 선 5개 안팎이 나란히 나간다. 그 상자 옆면과 아래 영역 상자 사이 틈이 겹치는 폭이 좁으면 간격이 11 px 안팎으로 준다
204
+ - 한계: 다른 영역을 피해 돌아갈 길이 영역 안 길이보다 길면 그대로 지난다(위 다른 영역 열). 이웃 상자 사이 틈을 넓히면 선이 바뀌어 값이 커지는 자료는 넓히지 않아 이름표가 상자에 1 px 까지 붙는다(위 첫째 줄)
205
+ - 이런 자료는 영역을 나누거나(아래 표 3) 좌표를 모두 쓴다
206
+
207
+ ## 자동 배치 WARN 줄이기
208
+
209
+ - 자동 배치는 선이 상자를 지나지 않게 돌아간다. 남는 WARN 은 이름표가 들어갈 곳이 없을 때의 `이름표 덮음`, `이름표가 그림 밖` 이다. 배치 조언이고 실패가 아니다
210
+ - 아래 할 일은 WARN 이 없어도 선을 짧게 하고 꺾기와 엇갈림을 줄인다
211
+ - 밀도 하한(연결 15 등)을 지키는 것이 먼저다. WARN 을 없애려고 실제 연결을 지우지 않는다
212
+ - 아래 순서로 줄인다
213
+
214
+ | 순서 | 할 일 | 효과 |
215
+ |---|---|---|
216
+ | 1 | `zones` 를 주 흐름 차례로 놓는다. 연결이 많은 두 영역을 배열에서 이웃하게(자동 배치도 연결이 많은 영역끼리 이은 순서를 후보로 보지만 배열 순서가 출발점) | 이웃 영역은 같은 띠 옆이나 바로 아래 띠에 놓여 선이 짧아짐 |
217
+ | 2 | 영역 안 `nodes` 순서를 바꾼다. 같은 영역 안에서 서로 잇는 상자를 이웃 칸(같은 행 옆, 같은 칸 위아래)에 | 같은 영역 안 연결이 사이 상자를 돌아가지 않아 직선이 됨 |
218
+ | 3 | 상자가 많은 영역을 둘로 나눈다(영역 하한 5 에도 도움) | 영역 사이 연결이 되어 꺾은선으로 돌아갈 수 있음 |
219
+ | 4 | 한 영역의 여러 상자로 가는 같은 뜻의 연결은 끝을 영역 id 로 한 줄에 | 선 수가 줄어 통로가 덜 붐빔. 연결 하한 아래로는 묶지 않음 |
220
+ | 5 | 그래도 많으면 좌표를 모두 쓴다(위 "좌표 키") | 좌표 사용에서는 같은 검사가 FAIL 이 되므로 모두 고쳐야 함 |
221
+
222
+ - 남은 WARN 수는 사용자에게 보고한다
223
+
224
+ ### 연결 방향으로 영역 나누기
225
+
226
+ - 영역은 영역 순서(배열 순서, 또는 연결이 많은 영역끼리 이은 순서)대로 띠에 옆으로 놓이고, 띠가 차면 다음 띠로 내려간다. 불리는 쪽 영역을 부르는 쪽 영역 바로 뒤에 둔다
227
+ - 외부 구성요소를 맨 끝 "외부" 영역 하나에 모으지 않는다. 부르는 쪽마다 나눠 그 바로 뒤에 둔다
228
+ - 예: 화면이 부르는 외부 API 는 "외부(화면이 부름)" 영역을 화면 영역 바로 뒤에
229
+ - 예: 서버가 부르는 DB 는 "외부(서버가 부름)" 영역을 서버 영역 바로 뒤에
230
+ - 효과: 선이 먼 영역을 건너지 않아 꺾은선이 짧고 꺾기와 엇갈림이 줄어듦. 영역 하한 5 에도 도움
231
+
232
+ ### 여러 상자가 한 상자로 모일 때
233
+
234
+ - 여러 상자에서 한 상자로 가는 연결(예: 네 모듈이 모두 같은 설정 파일을 읽음)은 끝이 한 점에 모인다
235
+ - 받는 상자를 보내는 상자들의 영역 바로 뒤 영역에 따로 둔다. 같은 영역에 두면 선이 이웃 상자를 돌아가 길어진다
236
+ - 같은 뜻의 연결이면 보내는 쪽 끝을 영역 id 로 한 줄에 묶는다(위 표 4). 연결 하한 아래로는 묶지 않는다
237
+ - 묶지 못하면 이름표는 한 연결에만 달고 나머지는 이름표 없이 `detail` 에 뜻을 쓴다. 이름표가 모이는 곳에서 서로 밀어내기 때문이다
238
+
239
+ ### `이름표 덮음` 줄이기
240
+
241
+ - 원인: 이름표가 상자와 겹치지 않는 곧은 구간을 지나는 길이 없을 때. 이름표가 아주 길거나 상자가 빽빽할 때
242
+ - 같은 행 이웃 상자 사이 연결의 이름표 글 폭이 48 px 를 넘으면 선이 행 사이나 영역 사이로 돌아가 길어진다
243
+ - 아래 순서로 줄인다
244
+ 1. 같은 행 이웃 상자 사이 연결의 이름표는 글 폭 48 px 이하로 쓴다(한글 4자, 또는 영문 8자). 예: `SQL 읽기`(45 px). 선이 곧게 이웃 상자로 간다
245
+ 2. 그 연결을 다른 영역 사이 연결로 바꾼다(위 "연결 방향으로 영역 나누기"). 영역 사이 거리 80~120 px 에서는 이름표가 들어간다
246
+ 3. 같은 두 끝을 잇는 연결이 여럿이면 하나로 합치고 `detail` 에 나머지 뜻을 쓴다
247
+ 4. 이름표가 꼭 필요하지 않은 연결은 `label` 을 빼고 `detail` 만 쓴다. `label` 은 밀도 항목이 아니다
248
+ - 이름표를 줄이려고 연결을 지우지 않는다
249
+
250
+ ### 배치 후보 비교
251
+
252
+ - 배치 후보는 최대 3개 만든다. 후보마다 위 표 1~4 가운데 다른 조합을 쓴다(예: 영역 순서만, 영역 순서와 상자 순서, 영역 나누기까지)
253
+ - 자료 폴더를 임시 폴더에 복사하고 후보마다 사본의 `arch.json` 만 바꿔 검사한다
254
+ - `node "<S>/scripts/progress-mon.mjs" check --runtime <rt> --data <사본 폴더>`
255
+ - 고르는 기준(앞 기준이 같을 때만 다음 기준을 본다)
256
+
257
+ | 순서 | 기준 |
258
+ |---|---|
259
+ | 1 | FAIL 0 |
260
+ | 2 | `선이 상자 지남`, `이름표 덮음`, `이름표가 그림 밖` WARN 합이 가장 적음 |
261
+ | 3 | `이름표 덮음` 이 더 적음 |
262
+ | 4 | `zones` 순서가 `main` 차례에 더 가까움 |
263
+
264
+ - 고른 후보의 `arch.json` 만 실제 자료 폴더에 쓴다. 사본 폴더는 지운다
265
+ - 3개로도 WARN 이 남으면 남은 수를 사용자에게 보고하고 멈춘다. 좌표를 모두 쓸지는 사용자가 정한다
266
+
267
+ ## check 항목
268
+
269
+ | 검사 | 좌표 사용 | 자동 배치 |
270
+ |---|---|---|
271
+ | 형식, 필수 키, id 겹침, 연결 끝, 영역, 장면 대상, `main`, 색 | FAIL | FAIL |
272
+ | 상자 겹침, 영역 겹침 | FAIL | FAIL(배치가 막음) |
273
+ | 영역 밖, 그림 밖 | FAIL | FAIL(배치가 막음) |
274
+ | 글 넘침(이름, 설명, 칩, 내용이 상자 아래로) | FAIL | FAIL |
275
+ | 선이 상자 지남 | FAIL | WARN(길 찾기가 돌아가므로 길을 찾지 못한 연결만) |
276
+ | 이름표 덮음, 이름표가 그림 밖 | FAIL | WARN |
277
+ | 설명이 `lines` 보다 김(잘림) | WARN | WARN |
278
+ | 상자 60개, 연결 60개 초과 | WARN(크기 지침) | WARN |
279
+
280
+ - 자동 배치의 WARN 은 실패가 아니다. 줄이는 법은 위 "자동 배치 WARN 줄이기"