From 0ef19098ce2f718e8fb3f8df1fc6782f184ca008 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 5 May 2026 21:14:29 +0900 Subject: [PATCH] Initial commit: agent-status dashboard (agent.pinksky.kr) --- __pycache__/health_check.cpython-311.pyc | Bin 0 -> 21827 bytes health.json | 394 +++++ health_check.log | 1781 ++++++++++++++++++++++ health_check.py | 432 ++++++ health_check.py.backup.20260429_2057 | 338 ++++ health_check.py.v4.20260430_0923 | 231 +++ health_check_backup.py | 302 ++++ index.html | 403 +++++ index.html.backup.20260429_2057 | 280 ++++ index.html.v4.20260430_0923 | 241 +++ v0.5_plan_for_pink.md | 41 + 11 files changed, 4443 insertions(+) create mode 100644 __pycache__/health_check.cpython-311.pyc create mode 100644 health.json create mode 100644 health_check.log create mode 100644 health_check.py create mode 100755 health_check.py.backup.20260429_2057 create mode 100755 health_check.py.v4.20260430_0923 create mode 100644 health_check_backup.py create mode 100644 index.html create mode 100644 index.html.backup.20260429_2057 create mode 100644 index.html.v4.20260430_0923 create mode 100644 v0.5_plan_for_pink.md diff --git a/__pycache__/health_check.cpython-311.pyc b/__pycache__/health_check.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..68eb9ec19e021797977d40563d6f20b3b931059d GIT binary patch literal 21827 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 z z`rWskk(?4(z?YxqbDn|s&JO;C3BKEjZ}xd$B^H><2=t7lmT&93b0U&c70Jnq{j+Q??!S8nB>w5_X<$&}oj?JXRp7O~d(lvuB8*n1XVl39>9kR-tOglefVZyO37E6X9Ao6fWDfn*tP^XB>|j#>;8yo%hI`sv4(HygGLyz5dfeO zrAxUHV^zeIA5t!NMc_ZLXcT6MMPOvIwk>OK_wl2rdG#51K_dNwe!vWzuF!(D0RXkB u>61x*0OXMN8CEiK{k;FKtdN%#M&!o1{VyN9dT@^Zt;ra95d>3K^?w0DE?o5h literal 0 HcmV?d00001 diff --git a/health.json b/health.json new file mode 100644 index 0000000..864fdd3 --- /dev/null +++ b/health.json @@ -0,0 +1,394 @@ +{ + "subdomains": [ + { + "name": "wiki.pinksky.kr", + "group": "pinksky.kr", + "desc": "MiniCITY 지식정원", + "status": "online", + "detail": "HTTP 200", + "latency_ms": 21.0 + }, + { + "name": "openclaw.pinksky.kr", + "group": "pinksky.kr", + "desc": "OpenClaw 대시보드", + "status": "online", + "detail": "HTTP 200", + "latency_ms": 18.0 + }, + { + "name": "agent.pinksky.kr", + "group": "pinksky.kr", + "desc": "인프라 현황판", + "status": "online", + "detail": "HTTP 200", + "latency_ms": 13.0 + }, + { + "name": "search.pinksky.kr", + "group": "pinksky.kr", + "desc": "SearXNG 메타서치", + "status": "online", + "detail": "HTTP 200", + "latency_ms": 824.0 + }, + { + "name": "erp.pinksky.kr", + "group": "pinksky.kr", + "desc": "공사관리 ERP", + "status": "online", + "detail": "HTTP 200", + "latency_ms": 20.0 + }, + { + "name": "dify.pinksky.kr", + "group": "pinksky.kr", + "desc": "Dify 워크플로우", + "status": "online", + "detail": "HTTP 307", + "latency_ms": 17.0 + }, + { + "name": "photo.pinksky.kr", + "group": "pinksky.kr", + "desc": "PhotoVault 자료정리", + "status": "online", + "detail": "HTTP 200", + "latency_ms": 46.0 + }, + { + "name": "git.pinksky.kr", + "group": "pinksky.kr", + "desc": "Gitea Git 서버", + "status": "online", + "detail": "HTTP 200", + "latency_ms": 18.0 + }, + { + "name": "find.pinksky.kr", + "group": "pinksky.kr", + "desc": "Everything 검색", + "status": "online", + "detail": "HTTP 401", + "latency_ms": 23.0 + }, + { + "name": "gwenc.kr", + "group": "gwenc.kr", + "desc": "회사 메인 사이트", + "status": "online", + "detail": "HTTP 200", + "latency_ms": 28.0 + }, + { + "name": "minicity.kr", + "group": "minicity.kr", + "desc": "집 NAS 웹 UI", + "status": "online", + "detail": "HTTP 200", + "latency_ms": 65.0 + } + ], + "domains": { + "pinksky.kr": { + "domain": { + "status": "online", + "detail": "100.70.47.91" + }, + "pcs": { + "macmini": { + "name": "맥미니 M4 Pro", + "emoji": "🖥️", + "spec": "Apple M4 Pro · 64GB · 통합 GPU", + "dns": "pinksky.kr", + "tailscale_ip": "100.70.47.91", + "status": "online", + "detail": "", + "agents": { + "mimi": { + "status": "online", + "version": "2026.5.2", + "uptime": "02-05:04:59", + "proc_count": 1, + "engine": "openclaw", + "detail": "02-05:04:59 · 1프로세스", + "name": "미미", + "emoji": "🦞" + }, + "ruki": { + "status": "online", + "version": "v0.11.0", + "uptime": "01-17:52:56", + "proc_count": 2, + "engine": "hermes", + "detail": "01-17:52:56 · 2프로세스", + "name": "루키", + "emoji": "🌱" + } + } + }, + "mainpc": { + "name": "메인컴 (PS-i14700K)", + "emoji": "🖥️", + "spec": "Intel Core i7-14700K · 96GB · RTX 3090 24GB", + "dns": "mainpc-wsl.pinksky.kr", + "tailscale_ip": "100.105.122.120", + "status": "online", + "detail": "alive", + "agents": { + "pink": { + "status": "online", + "version": "v0.11.0", + "uptime": "?", + "proc_count": 2, + "engine": "hermes", + "detail": "2프로세스", + "name": "분홍", + "emoji": "🤖" + } + } + }, + "subpc": { + "name": "보조컴 (MH-3900x)", + "emoji": "🖥️", + "spec": "AMD Ryzen 9 3900X · 32GB · RTX 3080 12GB", + "dns": "subpc-wsl.pinksky.kr", + "tailscale_ip": "100.124.61.85", + "status": "online", + "detail": "alive", + "agents": { + "sky": { + "status": "online", + "version": "v0.11.0", + "uptime": "?", + "proc_count": 1, + "engine": "hermes", + "detail": "1프로세스", + "name": "하늘", + "emoji": "🤖" + } + } + } + } + }, + "minicity.kr": { + "domain": { + "status": "online", + "detail": "집 NAS/공유기" + }, + "pcs": { + "nas_home": { + "name": "집 NAS (mh-nas)", + "emoji": "🗄️", + "spec": "Synology DS418+", + "dns": "minicity.kr", + "tailscale_ip": "100.69.107.65", + "status": "online", + "detail": "alive", + "agents": {} + }, + "router_home": { + "name": "집 공유기", + "emoji": "📡", + "spec": "아이피타임 AX8004BCM", + "dns": "pinksky.iptime.org", + "tailscale_ip": "", + "status": "online", + "detail": "DDNS · 원격관리 9090", + "agents": {} + } + } + }, + "gwenc.kr": { + "domain": { + "status": "online", + "detail": "tcp open" + }, + "pcs": { + "officepc": { + "name": "서버컴 (gw-ps-5600)", + "emoji": "🖥️", + "spec": "Intel Core i7-14700K · 96GB · RTX 3090", + "dns": "gwenc.kr", + "tailscale_ip": "", + "status": "online", + "detail": "tcp open", + "agents": {} + }, + "nas_office": { + "name": "회사 NAS (gwenc-nas2)", + "emoji": "🗄️", + "spec": "Synology", + "dns": "", + "tailscale_ip": "100.105.95.19", + "status": "online", + "detail": "", + "agents": {} + }, + "nas_backup": { + "name": "백업 NAS (ps-bk-nas)", + "emoji": "🗄️", + "spec": "14TB HDD", + "dns": "", + "tailscale_ip": "100.83.176.55", + "status": "online", + "detail": "", + "agents": {} + }, + "router_office": { + "name": "회사 공유기", + "emoji": "📡", + "spec": "TP-LINK AX18000", + "dns": "gwenc.kr", + "tailscale_ip": "", + "status": "online", + "detail": "원격관리 9000/9443", + "agents": {} + } + } + } + }, + "nas_storage": { + "nas_home": { + "name": "집 NAS (mh-nas)", + "model": "Synology DS418+", + "os": "DSM 7.2", + "status": "online", + "volumes": [ + { + "mount": "/volume1", + "label": "데이터", + "total": "1.8T", + "used": "833G", + "free": "952G", + "pct": "47%" + }, + { + "mount": "/volume2", + "label": "백업", + "total": "7.0T", + "used": "6.0T", + "free": "1020G", + "pct": "86%" + } + ], + "detail": "alive" + }, + "nas_office": { + "name": "회사 NAS (gwenc-nas2)", + "model": "Synology DS923+", + "os": "DSM 7.2", + "status": "online", + "volumes": [ + { + "mount": "/volume1", + "label": "메인", + "total": "21G", + "used": "2.2G", + "free": "19G", + "pct": "11%" + }, + { + "mount": "/volume3", + "label": "SSD캐시", + "total": "493G", + "used": "211G", + "free": "283G", + "pct": "43%" + }, + { + "mount": "/volume2", + "label": "대용량스토리지", + "total": "7.3T", + "used": "250G", + "free": "7.0T", + "pct": "4%" + } + ], + "detail": "alive" + }, + "nas_backup": { + "name": "백업 NAS (ps-bk-nas)", + "model": "Synology", + "os": "DSM 7.x", + "status": "online", + "volumes": [ + { + "mount": "/volume1", + "label": "메인백업", + "total": "52G", + "used": "1.4G", + "free": "51G", + "pct": "3%" + }, + { + "mount": "/volume2", + "label": "대용량백업", + "total": "15T", + "used": "5.3T", + "free": "9.2T", + "pct": "37%" + } + ], + "detail": "alive" + } + }, + "proxmox": { + "host": { + "name": "서버컴 (gw-ps-5600)", + "model": "ASRock Z790M-ITX WiFi", + "cpu": "Intel Core i7-14700K", + "ram": "96GB", + "os": "Windows 11 Pro + Hyper-V", + "role": "Hyper-V 호스트", + "status": "online", + "detail": "tcp open" + }, + "proxmox": { + "name": "Proxmox VE", + "version": "8.x", + "os": "Debian 12 + Proxmox", + "cpu": "8 vCPU", + "ram": "32GB", + "storage": "1TB SSD", + "role": "Hyper-V 가상머신 · VM 호스팅", + "status": "online", + "detail": "tcp open" + }, + "vms": [ + { + "name": "정환용 업무컴", + "host": "gwenc.kr", + "port": 13389, + "emoji": "🖥️", + "status": "online", + "detail": "tcp open" + }, + { + "name": "주영용 업무컴", + "host": "gwenc.kr", + "port": 23389, + "emoji": "🖥️", + "status": "online", + "detail": "tcp open" + }, + { + "name": "임시용 업무컴", + "host": "gwenc.kr", + "port": 43348, + "emoji": "🖥️", + "status": "offline", + "detail": "timeout" + } + ] + }, + "summary": { + "total": 27, + "online": 26, + "offline": 1, + "domain_total": 3, + "domain_online": 3 + }, + "timestamp": "2026-05-05T21:13:48.223557+09:00", + "timestamp_epoch": 1777983228 +} \ No newline at end of file diff --git a/health_check.log b/health_check.log new file mode 100644 index 0000000..fc527cb --- /dev/null +++ b/health_check.log @@ -0,0 +1,1781 @@ +[18:18:32] 온라인 7/15 | 도메인 2/3 +[18:19:05] 온라인 8/15 | 도메인 2/3 +[18:19:39] 온라인 8/15 | 도메인 2/3 +[18:20:12] 온라인 8/15 | 도메인 2/3 +[18:20:45] 온라인 7/15 | 도메인 2/3 +[18:21:18] 온라인 7/15 | 도메인 2/3 +[18:21:51] 온라인 7/15 | 도메인 2/3 +[18:22:25] 온라인 7/15 | 도메인 2/3 +[18:22:58] 온라인 7/15 | 도메인 2/3 +[18:23:31] 온라인 7/15 | 도메인 2/3 +[18:24:04] 온라인 7/15 | 도메인 2/3 +[18:24:37] 온라인 7/15 | 도메인 2/3 +[18:25:10] 온라인 7/15 | 도메인 2/3 +[18:25:44] 온라인 7/15 | 도메인 2/3 +[18:26:17] 온라인 7/15 | 도메인 2/3 +[18:26:50] 온라인 7/15 | 도메인 2/3 +[18:27:23] 온라인 7/15 | 도메인 2/3 +[18:27:57] 온라인 7/15 | 도메인 2/3 +[18:28:30] 온라인 7/15 | 도메인 2/3 +[18:29:03] 온라인 7/15 | 도메인 2/3 +[18:29:36] 온라인 7/15 | 도메인 2/3 +[18:30:10] 온라인 7/15 | 도메인 2/3 +[18:30:43] 온라인 7/15 | 도메인 2/3 +[18:31:16] 온라인 7/15 | 도메인 2/3 +[18:31:49] 온라인 7/15 | 도메인 2/3 +[18:32:23] 온라인 7/15 | 도메인 2/3 +[18:32:56] 온라인 7/15 | 도메인 2/3 +[18:33:29] 온라인 7/15 | 도메인 2/3 +[18:34:02] 온라인 7/15 | 도메인 2/3 +[18:34:35] 온라인 7/15 | 도메인 2/3 +[18:35:09] 온라인 7/15 | 도메인 2/3 +[18:35:42] 온라인 7/15 | 도메인 2/3 +[18:36:15] 온라인 7/15 | 도메인 2/3 +[18:36:48] 온라인 7/15 | 도메인 2/3 +[18:37:21] 온라인 7/15 | 도메인 2/3 +[18:37:55] 온라인 7/15 | 도메인 2/3 +[18:38:28] 온라인 7/15 | 도메인 2/3 +[18:39:01] 온라인 7/15 | 도메인 2/3 +[18:39:35] 온라인 7/15 | 도메인 2/3 +[18:40:08] 온라인 7/15 | 도메인 2/3 +[18:40:41] 온라인 7/15 | 도메인 2/3 +[18:41:14] 온라인 7/15 | 도메인 2/3 +[18:41:48] 온라인 7/15 | 도메인 2/3 +[18:42:21] 온라인 7/15 | 도메인 2/3 +[18:42:54] 온라인 7/15 | 도메인 2/3 +[18:43:27] 온라인 7/15 | 도메인 2/3 +[18:44:01] 온라인 7/15 | 도메인 2/3 +[18:44:34] 온라인 7/15 | 도메인 2/3 +[18:45:07] 온라인 7/15 | 도메인 2/3 +[18:45:41] 온라인 7/15 | 도메인 2/3 +[18:46:14] 온라인 7/15 | 도메인 2/3 +[18:46:47] 온라인 7/15 | 도메인 2/3 +[18:47:20] 온라인 7/15 | 도메인 2/3 +[18:47:54] 온라인 7/15 | 도메인 2/3 +[18:48:27] 온라인 7/15 | 도메인 2/3 +[18:49:00] 온라인 7/15 | 도메인 2/3 +[18:49:33] 온라인 7/15 | 도메인 2/3 +[18:50:07] 온라인 7/15 | 도메인 2/3 +[18:50:40] 온라인 7/15 | 도메인 2/3 +[18:51:14] 온라인 7/15 | 도메인 2/3 +[18:51:47] 온라인 7/15 | 도메인 2/3 +[18:52:20] 온라인 7/15 | 도메인 2/3 +[18:52:54] 온라인 7/15 | 도메인 2/3 +[18:53:27] 온라인 7/15 | 도메인 2/3 +[18:54:00] 온라인 7/15 | 도메인 2/3 +[18:54:33] 온라인 7/15 | 도메인 2/3 +[18:55:07] 온라인 7/15 | 도메인 2/3 +[18:55:40] 온라인 7/15 | 도메인 2/3 +[18:56:13] 온라인 7/15 | 도메인 2/3 +[18:56:46] 온라인 7/15 | 도메인 2/3 +[18:57:20] 온라인 7/15 | 도메인 2/3 +[18:57:53] 온라인 7/15 | 도메인 2/3 +[18:58:26] 온라인 7/15 | 도메인 2/3 +[18:58:59] 온라인 7/15 | 도메인 2/3 +[18:59:32] 온라인 7/15 | 도메인 2/3 +[19:00:06] 온라인 7/15 | 도메인 2/3 +[19:00:39] 온라인 7/15 | 도메인 2/3 +[19:01:12] 온라인 7/15 | 도메인 2/3 +[19:01:45] 온라인 7/15 | 도메인 2/3 +[19:02:18] 온라인 7/15 | 도메인 2/3 +[19:02:52] 온라인 7/15 | 도메인 2/3 +[19:03:25] 온라인 7/15 | 도메인 2/3 +[19:03:59] 온라인 7/15 | 도메인 2/3 +[19:04:32] 온라인 7/15 | 도메인 2/3 +[19:05:05] 온라인 7/15 | 도메인 2/3 +[19:05:38] 온라인 7/15 | 도메인 2/3 +[19:06:11] 온라인 7/15 | 도메인 2/3 +[19:06:45] 온라인 7/15 | 도메인 2/3 +[19:07:18] 온라인 7/15 | 도메인 2/3 +[19:07:51] 온라인 7/15 | 도메인 2/3 +[19:08:24] 온라인 7/15 | 도메인 2/3 +[19:08:57] 온라인 7/15 | 도메인 2/3 +[19:09:31] 온라인 7/15 | 도메인 2/3 +[19:10:04] 온라인 7/15 | 도메인 2/3 +[19:10:37] 온라인 8/15 | 도메인 2/3 +[19:11:10] 온라인 8/15 | 도메인 2/3 +[19:11:45] 온라인 8/15 | 도메인 2/3 +[19:12:18] 온라인 8/15 | 도메인 2/3 + File "/Users/pinksky/agent-status/health_check.py", line 82 + return m.group(0) if m else "?" + ^ +SyntaxError: default 'except:' must be last +[19:13:22] 온라인 8/15 | 도메인 2/3 +[19:13:56] 온라인 8/15 | 도메인 2/3 +[19:14:29] 온라인 8/15 | 도메인 2/3 +[19:15:03] 온라인 8/15 | 도메인 2/3 +[19:15:37] 온라인 8/15 | 도메인 2/3 +[19:16:10] 온라인 8/15 | 도메인 2/3 +[19:16:44] 온라인 8/15 | 도메인 2/3 +[19:17:17] 온라인 8/15 | 도메인 2/3 +[19:17:51] 온라인 8/15 | 도메인 2/3 +[19:18:24] 온라인 8/15 | 도메인 2/3 +[19:18:58] 온라인 8/15 | 도메인 2/3 +[19:19:32] 온라인 8/15 | 도메인 2/3 +[19:20:09] 온라인 8/15 | 도메인 2/3 +[19:20:42] 온라인 8/15 | 도메인 2/3 +[19:21:16] 온라인 8/15 | 도메인 2/3 +[19:21:50] 온라인 8/15 | 도메인 2/3 +[19:22:23] 온라인 8/15 | 도메인 2/3 +[19:22:57] 온라인 8/15 | 도메인 2/3 +[19:23:30] 온라인 8/15 | 도메인 2/3 +[19:24:04] 온라인 8/15 | 도메인 2/3 +[19:24:38] 온라인 8/15 | 도메인 2/3 +[19:25:11] 온라인 8/15 | 도메인 2/3 +[19:25:46] 온라인 7/14 | 도메인 3/4 +[19:26:19] 온라인 7/14 | 도메인 3/4 +[19:26:52] 온라인 7/14 | 도메인 3/4 +[19:27:25] 온라인 7/14 | 도메인 3/4 +[19:27:58] 온라인 7/14 | 도메인 3/4 +[19:28:32] 온라인 7/14 | 도메인 3/4 +[19:29:05] 온라인 7/14 | 도메인 3/4 +[19:29:38] 온라인 7/14 | 도메인 3/4 +[19:30:11] 온라인 7/14 | 도메인 3/4 +[19:30:44] 온라인 7/14 | 도메인 3/4 +[19:31:18] 온라인 7/14 | 도메인 3/4 +[19:31:51] 온라인 7/14 | 도메인 3/4 +[19:32:24] 온라인 7/14 | 도메인 3/4 +[19:32:57] 온라인 7/14 | 도메인 3/4 +[19:33:30] 온라인 7/14 | 도메인 3/4 +[19:34:04] 온라인 7/14 | 도메인 3/4 +[19:34:37] 온라인 7/14 | 도메인 3/4 +[19:35:10] 온라인 7/14 | 도메인 3/4 +[19:35:43] 온라인 7/14 | 도메인 3/4 +[19:36:17] 온라인 7/14 | 도메인 3/4 +[19:36:50] 온라인 7/14 | 도메인 3/4 +[19:37:23] 온라인 7/14 | 도메인 3/4 +[19:37:56] 온라인 7/14 | 도메인 3/4 +[19:38:29] 온라인 7/14 | 도메인 3/4 +[19:39:03] 온라인 7/14 | 도메인 3/4 +[19:39:36] 온라인 7/14 | 도메인 3/4 +[19:40:09] 온라인 7/14 | 도메인 3/4 +[19:40:42] 온라인 7/14 | 도메인 3/4 +[19:41:15] 온라인 7/14 | 도메인 3/4 +[19:41:48] 온라인 7/14 | 도메인 3/4 +[19:42:21] 온라인 7/14 | 도메인 3/4 +[19:42:54] 온라인 7/14 | 도메인 3/4 +[19:43:28] 온라인 7/14 | 도메인 3/4 +[19:44:01] 온라인 7/14 | 도메인 3/4 +[19:44:34] 온라인 7/14 | 도메인 3/4 +[19:45:10] 온라인 7/14 | 도메인 3/4 +[19:45:46] 온라인 7/14 | 도메인 3/4 +[19:46:20] 온라인 7/14 | 도메인 3/4 +[19:46:53] 온라인 7/14 | 도메인 3/4 +[19:47:27] 온라인 7/14 | 도메인 3/4 +[19:48:01] 온라인 7/14 | 도메인 3/4 +[19:48:34] 온라인 7/14 | 도메인 3/4 +[19:49:07] 온라인 7/14 | 도메인 3/4 +[19:49:41] 온라인 7/14 | 도메인 3/4 +[19:50:14] 온라인 7/14 | 도메인 3/4 +[19:50:48] 온라인 7/14 | 도메인 3/4 +[19:51:21] 온라인 7/14 | 도메인 3/4 +[19:51:54] 온라인 7/14 | 도메인 3/4 +[19:52:28] 온라인 7/14 | 도메인 3/4 +[19:53:01] 온라인 7/14 | 도메인 3/4 +[19:53:35] 온라인 7/14 | 도메인 3/4 +[19:54:08] 온라인 7/14 | 도메인 3/4 +[19:54:42] 온라인 7/14 | 도메인 3/4 +[19:55:15] 온라인 7/14 | 도메인 3/4 +[19:55:48] 온라인 7/14 | 도메인 3/4 +[19:56:22] 온라인 7/14 | 도메인 3/4 +[19:56:56] 온라인 7/14 | 도메인 3/4 +[19:57:29] 온라인 7/14 | 도메인 3/4 +[19:58:03] 온라인 7/14 | 도메인 3/4 +[19:58:36] 온라인 7/14 | 도메인 3/4 +[19:59:10] 온라인 7/14 | 도메인 3/4 +[19:59:43] 온라인 7/14 | 도메인 3/4 +[20:00:17] 온라인 7/14 | 도메인 3/4 +[20:00:50] 온라인 7/14 | 도메인 3/4 +[20:01:24] 온라인 7/14 | 도메인 3/4 +[20:01:57] 온라인 7/14 | 도메인 3/4 +[20:02:31] 온라인 7/14 | 도메인 3/4 +[20:03:06] 온라인 7/14 | 도메인 3/4 +[20:03:40] 온라인 7/14 | 도메인 3/4 +[20:04:13] 온라인 7/14 | 도메인 3/4 +[20:04:47] 온라인 7/14 | 도메인 3/4 +[20:05:20] 온라인 7/14 | 도메인 3/4 +[20:05:54] 온라인 7/14 | 도메인 3/4 +[20:06:27] 온라인 7/14 | 도메인 3/4 +[20:07:01] 온라인 7/14 | 도메인 3/4 +[20:07:34] 온라인 7/14 | 도메인 3/4 +[20:08:08] 온라인 7/14 | 도메인 3/4 +[20:08:41] 온라인 7/14 | 도메인 3/4 +[20:09:14] 온라인 7/14 | 도메인 3/4 +[20:09:47] 온라인 7/14 | 도메인 3/4 +[20:10:21] 온라인 7/14 | 도메인 3/4 +[20:10:54] 온라인 7/14 | 도메인 3/4 +[20:11:28] 온라인 7/14 | 도메인 3/4 +[20:12:01] 온라인 7/14 | 도메인 3/4 +[20:12:34] 온라인 7/14 | 도메인 3/4 +[20:13:08] 온라인 7/14 | 도메인 3/4 +[20:13:42] 온라인 7/14 | 도메인 3/4 +[20:14:15] 온라인 7/14 | 도메인 3/4 +[20:14:48] 온라인 7/14 | 도메인 3/4 +[20:15:22] 온라인 7/14 | 도메인 3/4 +[20:15:55] 온라인 7/14 | 도메인 3/4 +[20:16:29] 온라인 7/14 | 도메인 3/4 +[20:17:02] 온라인 7/14 | 도메인 3/4 +[20:17:35] 온라인 7/14 | 도메인 3/4 +[20:18:08] 온라인 7/14 | 도메인 3/4 +[20:18:42] 온라인 7/14 | 도메인 3/4 +[20:19:15] 온라인 7/14 | 도메인 3/4 +[20:19:48] 온라인 7/14 | 도메인 3/4 +[20:20:22] 온라인 7/14 | 도메인 3/4 +[20:20:55] 온라인 7/14 | 도메인 3/4 +[20:21:28] 온라인 7/14 | 도메인 3/4 +[20:22:02] 온라인 7/14 | 도메인 3/4 +[20:22:35] 온라인 7/14 | 도메인 3/4 +[20:23:08] 온라인 7/14 | 도메인 3/4 +[20:23:42] 온라인 7/14 | 도메인 3/4 +[20:24:15] 온라인 7/14 | 도메인 3/4 +[20:24:49] 온라인 7/14 | 도메인 3/4 +[20:25:23] 온라인 7/14 | 도메인 3/4 +[20:25:56] 온라인 7/14 | 도메인 3/4 +[20:26:30] 온라인 7/14 | 도메인 3/4 +[20:27:06] 온라인 7/14 | 도메인 3/4 +[20:27:40] 온라인 7/14 | 도메인 3/4 +[20:28:14] 온라인 7/14 | 도메인 3/4 +[20:28:47] 온라인 7/14 | 도메인 3/4 +[20:29:20] 온라인 7/14 | 도메인 3/4 +[20:29:53] 온라인 7/14 | 도메인 3/4 +[20:30:27] 온라인 7/14 | 도메인 3/4 +[20:31:00] 온라인 7/14 | 도메인 3/4 +[20:31:33] 온라인 7/14 | 도메인 3/4 +[20:32:07] 온라인 7/14 | 도메인 3/4 +[20:32:40] 온라인 7/14 | 도메인 3/4 +[20:33:14] 온라인 7/14 | 도메인 3/4 +[20:33:47] 온라인 7/14 | 도메인 3/4 +[20:34:21] 온라인 7/14 | 도메인 3/4 +[20:34:54] 온라인 7/14 | 도메인 3/4 +[20:35:28] 온라인 7/14 | 도메인 3/4 +[20:36:01] 온라인 7/14 | 도메인 3/4 +[20:36:34] 온라인 7/14 | 도메인 3/4 +[20:37:12] 온라인 7/14 | 도메인 3/4 +[20:37:46] 온라인 7/14 | 도메인 3/4 +[20:38:19] 온라인 7/14 | 도메인 3/4 +[20:38:52] 온라인 7/14 | 도메인 3/4 +[20:39:26] 온라인 7/14 | 도메인 3/4 +[20:39:59] 온라인 7/14 | 도메인 3/4 +[20:40:33] 온라인 7/14 | 도메인 3/4 +[20:41:06] 온라인 7/14 | 도메인 3/4 +[20:41:40] 온라인 7/14 | 도메인 3/4 +[20:42:13] 온라인 7/14 | 도메인 3/4 +[20:42:47] 온라인 7/14 | 도메인 3/4 +[20:43:20] 온라인 7/14 | 도메인 3/4 +[20:43:54] 온라인 7/14 | 도메인 3/4 +[20:44:28] 온라인 7/14 | 도메인 3/4 +[20:45:01] 온라인 7/14 | 도메인 3/4 +[20:45:35] 온라인 7/14 | 도메인 3/4 +[20:46:08] 온라인 7/14 | 도메인 3/4 +[20:46:42] 온라인 7/14 | 도메인 3/4 +[20:47:18] 온라인 7/14 | 도메인 3/4 +[20:47:52] 온라인 7/14 | 도메인 3/4 +[20:48:31] 온라인 7/14 | 도메인 3/4 +[20:49:04] 온라인 7/14 | 도메인 3/4 +[20:49:37] 온라인 7/14 | 도메인 3/4 +[20:50:11] 온라인 7/14 | 도메인 3/4 +[20:50:14] 온라인 7/14 | 도메인 3/4 +[20:50:47] 온라인 7/14 | 도메인 3/4 +[20:50:51] 온라인 7/14 | 도메인 3/4 +[20:51:24] 온라인 7/14 | 도메인 3/4 +[20:51:27] 온라인 7/14 | 도메인 3/4 +[20:52:00] 온라인 7/14 | 도메인 3/4 +[20:52:03] 온라인 7/14 | 도메인 3/4 +[20:52:36] 온라인 7/14 | 도메인 3/4 +[20:52:39] 온라인 7/14 | 도메인 3/4 +[20:53:12] 온라인 7/14 | 도메인 3/4 +[20:53:15] 온라인 7/14 | 도메인 3/4 +[20:53:49] 온라인 7/14 | 도메인 3/4 +[20:53:52] 온라인 7/14 | 도메인 3/4 +[20:54:25] 온라인 7/14 | 도메인 3/4 +[20:54:28] 온라인 7/14 | 도메인 3/4 +[20:55:02] 온라인 7/14 | 도메인 3/4 +[20:55:05] 온라인 7/14 | 도메인 3/4 +[20:55:38] 온라인 8/14 | 도메인 3/4 +[20:56:17] 온라인 8/14 | 도메인 3/4 +[20:56:56] 온라인 8/14 | 도메인 3/4 +[20:57:35] 온라인 8/14 | 도메인 3/4 +[20:58:14] 온라인 8/14 | 도메인 3/4 +[20:58:53] 온라인 8/14 | 도메인 3/4 +[20:59:31] 온라인 8/14 | 도메인 3/4 +[21:00:10] 온라인 8/14 | 도메인 3/4 +[21:00:49] 온라인 8/14 | 도메인 3/4 +[21:01:29] 온라인 8/14 | 도메인 3/4 +[21:02:08] 온라인 8/14 | 도메인 3/4 +[21:02:51] 온라인 8/14 | 도메인 3/4 +[21:03:30] 온라인 8/14 | 도메인 3/4 +[21:04:09] 온라인 8/14 | 도메인 3/4 +[21:04:48] 온라인 8/14 | 도메인 3/4 +[21:05:27] 온라인 8/14 | 도메인 3/4 +[21:06:10] 온라인 8/14 | 도메인 3/4 +[21:06:49] 온라인 8/14 | 도메인 3/4 +[21:07:13] 온라인 8/14 | 도메인 3/4 +[21:07:28] 온라인 8/14 | 도메인 3/4 +[21:08:07] 온라인 8/14 | 도메인 3/4 +[21:08:21] 온라인 8/14 | 도메인 3/4 +[21:08:45] 온라인 8/14 | 도메인 3/4 +[21:09:24] 온라인 8/14 | 도메인 3/4 +[21:09:30] 온라인 8/14 | 도메인 3/4 +[21:10:03] 온라인 8/14 | 도메인 3/4 +[21:10:38] 온라인 8/14 | 도메인 3/4 +[21:10:41] 온라인 8/14 | 도메인 3/4 +[21:11:20] 온라인 8/14 | 도메인 3/4 +[21:11:46] 온라인 8/14 | 도메인 3/4 +[21:11:59] 온라인 8/14 | 도메인 3/4 +[21:12:38] 온라인 8/14 | 도메인 3/4 +[21:12:55] 온라인 8/14 | 도메인 3/4 +[21:13:16] 온라인 8/14 | 도메인 3/4 +[21:13:55] 온라인 8/14 | 도메인 3/4 +[21:14:04] 온라인 8/14 | 도메인 3/4 +[21:14:34] 온라인 8/14 | 도메인 3/4 +[21:15:13] 온라인 8/14 | 도메인 3/4 +[21:15:12] 온라인 8/14 | 도메인 3/4 +[21:15:52] 온라인 8/14 | 도메인 3/4 +[21:16:22] 온라인 8/14 | 도메인 3/4 +[21:16:31] 온라인 8/14 | 도메인 3/4 +[21:17:10] 온라인 8/14 | 도메인 3/4 +[21:17:31] 온라인 8/14 | 도메인 3/4 +[21:17:49] 온라인 8/14 | 도메인 3/4 +[21:18:27] 온라인 8/14 | 도메인 3/4 +[21:18:40] 온라인 8/14 | 도메인 3/4 +[21:19:05] 온라인 8/14 | 도메인 3/4 +[21:19:47] 온라인 8/14 | 도메인 3/4 +[21:19:48] 온라인 8/14 | 도메인 3/4 +[21:20:26] 온라인 8/14 | 도메인 3/4 +[21:20:57] 온라인 8/14 | 도메인 3/4 +[21:21:05] 온라인 8/14 | 도메인 3/4 +[21:21:44] 온라인 8/14 | 도메인 3/4 +[21:22:06] 온라인 8/14 | 도메인 3/4 +[21:22:23] 온라인 8/14 | 도메인 3/4 +[21:23:01] 온라인 8/14 | 도메인 3/4 +[21:23:15] 온라인 8/14 | 도메인 3/4 +[21:23:39] 온라인 8/14 | 도메인 3/4 +[21:24:18] 온라인 8/14 | 도메인 3/4 +[21:24:23] 온라인 8/14 | 도메인 3/4 +[21:24:57] 온라인 8/14 | 도메인 3/4 +[21:25:32] 온라인 8/14 | 도메인 3/4 +[21:25:36] 온라인 8/14 | 도메인 3/4 +[21:26:14] 온라인 8/14 | 도메인 3/4 +[21:26:40] 온라인 8/14 | 도메인 3/4 +[21:26:53] 온라인 8/14 | 도메인 3/4 +[21:27:31] 온라인 8/14 | 도메인 3/4 +[21:27:49] 온라인 8/14 | 도메인 3/4 +[21:28:10] 온라인 8/14 | 도메인 3/4 +[21:28:48] 온라인 8/14 | 도메인 3/4 +[21:28:58] 온라인 8/14 | 도메인 3/4 +[21:29:27] 온라인 8/14 | 도메인 3/4 +[21:30:06] 온라인 8/14 | 도메인 3/4 +[21:30:06] 온라인 8/14 | 도메인 3/4 +[21:30:45] 온라인 8/14 | 도메인 3/4 +[21:31:16] 온라인 8/14 | 도메인 3/4 +[21:31:24] 온라인 8/14 | 도메인 3/4 +[21:32:02] 온라인 8/14 | 도메인 3/4 +[21:32:24] 온라인 8/14 | 도메인 3/4 +[21:32:41] 온라인 8/14 | 도메인 3/4 +[21:33:19] 온라인 8/14 | 도메인 3/4 +[21:33:33] 온라인 8/14 | 도메인 3/4 +[21:33:57] 온라인 8/14 | 도메인 3/4 +[21:34:36] 온라인 8/14 | 도메인 3/4 +[21:34:42] 온라인 8/14 | 도메인 3/4 +[21:35:15] 온라인 8/14 | 도메인 3/4 +[21:35:50] 온라인 8/14 | 도메인 3/4 +[21:35:53] 온라인 8/14 | 도메인 3/4 +[21:36:32] 온라인 8/14 | 도메인 3/4 +[21:36:58] 온라인 8/14 | 도메인 3/4 +[21:37:10] 온라인 8/14 | 도메인 3/4 +[21:37:49] 온라인 8/14 | 도메인 3/4 +[21:38:07] 온라인 8/14 | 도메인 3/4 +[21:38:27] 온라인 8/14 | 도메인 3/4 +[21:39:06] 온라인 8/14 | 도메인 3/4 +[21:39:16] 온라인 8/14 | 도메인 3/4 +[21:39:45] 온라인 8/14 | 도메인 3/4 +[21:40:23] 온라인 8/14 | 도메인 3/4 +[21:40:24] 온라인 8/14 | 도메인 3/4 +[21:41:03] 온라인 8/14 | 도메인 3/4 +[21:41:33] 온라인 8/14 | 도메인 3/4 +[21:41:42] 온라인 8/14 | 도메인 3/4 +[21:42:20] 온라인 8/14 | 도메인 3/4 +[21:42:42] 온라인 8/14 | 도메인 3/4 +[21:42:59] 온라인 8/14 | 도메인 3/4 +[21:43:37] 온라인 8/14 | 도메인 3/4 +[21:43:50] 온라인 8/14 | 도메인 3/4 +[21:44:15] 온라인 8/14 | 도메인 3/4 +[21:44:54] 온라인 8/14 | 도메인 3/4 +[21:44:59] 온라인 8/14 | 도메인 3/4 +[21:45:33] 온라인 8/14 | 도메인 3/4 +[21:46:07] 온라인 8/14 | 도메인 3/4 +[21:46:12] 온라인 8/14 | 도메인 3/4 +[21:46:51] 온라인 8/14 | 도메인 3/4 +[21:47:16] 온라인 8/14 | 도메인 3/4 +[21:47:29] 온라인 8/14 | 도메인 3/4 +[21:48:08] 온라인 8/14 | 도메인 3/4 +[21:48:24] 온라인 8/14 | 도메인 3/4 +[21:48:46] 온라인 8/14 | 도메인 3/4 +[21:49:33] 온라인 8/14 | 도메인 3/4 +[21:49:43] 온라인 8/14 | 도메인 3/4 +[21:50:33] 온라인 8/14 | 도메인 3/4 +[21:50:52] 온라인 8/14 | 도메인 3/4 +[21:51:23] 온라인 8/14 | 도메인 3/4 +[21:52:07] 온라인 8/14 | 도메인 3/4 +[21:52:12] 온라인 8/14 | 도메인 3/4 +[21:52:45] 온라인 8/14 | 도메인 3/4 +[21:53:20] 온라인 8/14 | 도메인 3/4 +[21:53:24] 온라인 8/14 | 도메인 3/4 +[21:54:02] 온라인 8/14 | 도메인 3/4 +[21:54:28] 온라인 8/14 | 도메인 3/4 +[21:54:40] 온라인 8/14 | 도메인 3/4 +[21:55:18] 온라인 8/14 | 도메인 3/4 +[21:55:37] 온라인 8/14 | 도메인 3/4 +[21:55:57] 온라인 8/14 | 도메인 3/4 +[21:56:35] 온라인 8/14 | 도메인 3/4 +[21:56:45] 온라인 8/14 | 도메인 3/4 +[21:57:13] 온라인 8/14 | 도메인 3/4 +[21:57:51] 온라인 8/14 | 도메인 3/4 +[21:57:53] 온라인 8/14 | 도메인 3/4 +[21:58:30] 온라인 8/14 | 도메인 3/4 +[21:59:01] 온라인 8/14 | 도메인 3/4 +[21:59:09] 온라인 8/14 | 도메인 3/4 +[21:59:47] 온라인 8/14 | 도메인 3/4 +[22:00:10] 온라인 8/14 | 도메인 3/4 +[22:00:25] 온라인 8/14 | 도메인 3/4 +[22:01:04] 온라인 8/14 | 도메인 3/4 +[22:01:18] 온라인 6/14 | 도메인 1/4 +[22:01:42] 온라인 8/14 | 도메인 3/4 +[22:02:40] 온라인 8/14 | 도메인 3/4 +[22:03:01] 온라인 8/14 | 도메인 3/4 +[22:03:19] 온라인 8/14 | 도메인 3/4 +[22:03:57] 온라인 8/14 | 도메인 3/4 +[22:04:10] 온라인 8/14 | 도메인 3/4 +[22:04:35] 온라인 8/14 | 도메인 3/4 +[22:05:13] 온라인 8/14 | 도메인 3/4 +[22:05:18] 온라인 8/14 | 도메인 3/4 +[22:05:52] 온라인 8/14 | 도메인 3/4 +[22:06:26] 온라인 8/14 | 도메인 3/4 +[22:06:30] 온라인 8/14 | 도메인 3/4 +[22:07:08] 온라인 8/14 | 도메인 3/4 +[22:07:34] 온라인 8/14 | 도메인 3/4 +[22:07:46] 온라인 8/14 | 도메인 3/4 +[22:08:25] 온라인 8/14 | 도메인 3/4 +[22:08:43] 온라인 8/14 | 도메인 3/4 +[22:09:03] 온라인 8/14 | 도메인 3/4 +[22:09:41] 온라인 8/14 | 도메인 3/4 +[22:09:51] 온라인 8/14 | 도메인 3/4 +[22:10:20] 온라인 8/14 | 도메인 3/4 +[22:10:59] 온라인 8/14 | 도메인 3/4 +[22:11:00] 온라인 8/14 | 도메인 3/4 +[22:11:37] 온라인 8/14 | 도메인 3/4 +[22:12:08] 온라인 8/14 | 도메인 3/4 +[22:12:15] 온라인 8/14 | 도메인 3/4 +[22:12:54] 온라인 8/14 | 도메인 3/4 +[22:13:16] 온라인 8/14 | 도메인 3/4 +[22:13:33] 온라인 8/14 | 도메인 3/4 +[22:14:11] 온라인 8/14 | 도메인 3/4 +[22:14:25] 온라인 8/14 | 도메인 3/4 +[22:14:49] 온라인 8/14 | 도메인 3/4 +[22:15:27] 온라인 8/14 | 도메인 3/4 +[22:15:36] 온라인 8/14 | 도메인 3/4 +[22:16:06] 온라인 8/14 | 도메인 3/4 +[22:16:44] 온라인 8/14 | 도메인 3/4 +[22:16:44] 온라인 8/14 | 도메인 3/4 +[22:17:22] 온라인 8/14 | 도메인 3/4 +[22:17:53] 온라인 8/14 | 도메인 3/4 +[22:18:01] 온라인 8/14 | 도메인 3/4 +[22:18:39] 온라인 8/14 | 도메인 3/4 +[22:19:01] 온라인 8/14 | 도메인 3/4 +[22:19:18] 온라인 8/14 | 도메인 3/4 +[22:19:56] 온라인 8/14 | 도메인 3/4 +[22:20:10] 온라인 8/14 | 도메인 3/4 +[22:20:35] 온라인 8/14 | 도메인 3/4 +[22:21:15] 온라인 8/14 | 도메인 3/4 +[22:21:19] 온라인 8/14 | 도메인 3/4 +[22:21:54] 온라인 8/14 | 도메인 3/4 +[22:22:27] 온라인 8/14 | 도메인 3/4 +[22:22:32] 온라인 8/14 | 도메인 3/4 +[22:23:11] 온라인 8/14 | 도메인 3/4 +[22:23:35] 온라인 8/14 | 도메인 3/4 +[22:23:49] 온라인 8/14 | 도메인 3/4 +[22:24:28] 온라인 8/14 | 도메인 3/4 +[22:24:44] 온라인 8/14 | 도메인 3/4 +[22:25:06] 온라인 8/14 | 도메인 3/4 +[22:25:44] 온라인 8/14 | 도메인 3/4 +[22:25:52] 온라인 8/14 | 도메인 3/4 +[22:26:28] 온라인 8/14 | 도메인 3/4 +[22:27:01] 온라인 8/14 | 도메인 3/4 +[22:27:06] 온라인 8/14 | 도메인 3/4 +[22:27:45] 온라인 8/14 | 도메인 3/4 +[22:28:09] 온라인 8/14 | 도메인 3/4 +[22:28:24] 온라인 8/14 | 도메인 3/4 +[22:29:02] 온라인 8/14 | 도메인 3/4 +[22:29:17] 온라인 8/14 | 도메인 3/4 +[22:29:41] 온라인 8/14 | 도메인 3/4 +[22:30:20] 온라인 8/14 | 도메인 3/4 +[22:30:25] 온라인 8/14 | 도메인 3/4 +[22:30:59] 온라인 8/14 | 도메인 3/4 +[22:31:33] 온라인 8/14 | 도메인 3/4 +[22:31:38] 온라인 8/14 | 도메인 3/4 +[22:32:16] 온라인 8/14 | 도메인 3/4 +[22:32:42] 온라인 8/14 | 도메인 3/4 +[22:32:55] 온라인 8/14 | 도메인 3/4 +[22:33:33] 온라인 8/14 | 도메인 3/4 +[22:33:51] 온라인 8/14 | 도메인 3/4 +[22:34:12] 온라인 8/14 | 도메인 3/4 +[22:34:51] 온라인 8/14 | 도메인 3/4 +[22:35:00] 온라인 8/14 | 도메인 3/4 +[22:35:30] 온라인 8/14 | 도메인 3/4 +[22:36:08] 온라인 8/14 | 도메인 3/4 +[22:36:08] 온라인 8/14 | 도메인 3/4 +[22:36:47] 온라인 8/14 | 도메인 3/4 +[22:37:18] 온라인 8/14 | 도메인 3/4 +[22:37:27] 온라인 8/14 | 도메인 3/4 +[22:38:06] 온라인 8/14 | 도메인 3/4 +[22:38:30] 온라인 8/14 | 도메인 3/4 +[22:38:46] 온라인 8/14 | 도메인 3/4 +[22:39:25] 온라인 8/14 | 도메인 3/4 +[22:39:39] 온라인 8/14 | 도메인 3/4 +[22:40:05] 온라인 8/14 | 도메인 3/4 +[22:40:44] 온라인 8/14 | 도메인 3/4 +[22:40:49] 온라인 8/14 | 도메인 3/4 +[22:41:25] 온라인 8/14 | 도메인 3/4 +[22:41:58] 온라인 8/14 | 도메인 3/4 +[22:42:04] 온라인 8/14 | 도메인 3/4 +[22:42:43] 온라인 8/14 | 도메인 3/4 +[22:43:08] 온라인 8/14 | 도메인 3/4 +[22:43:22] 온라인 8/14 | 도메인 3/4 +[22:44:02] 온라인 8/14 | 도메인 3/4 +[22:44:17] 온라인 8/14 | 도메인 3/4 +[22:44:41] 온라인 8/14 | 도메인 3/4 +[22:45:20] 온라인 8/14 | 도메인 3/4 +[22:45:26] 온라인 8/14 | 도메인 3/4 +[22:46:01] 온라인 8/14 | 도메인 3/4 +[22:46:36] 온라인 8/14 | 도메인 3/4 +[22:46:40] 온라인 8/14 | 도메인 3/4 +[22:47:20] 온라인 8/14 | 도메인 3/4 +[22:47:45] 온라인 8/14 | 도메인 3/4 +[22:48:00] 온라인 8/14 | 도메인 3/4 +[22:48:39] 온라인 8/14 | 도메인 3/4 +[22:48:55] 온라인 8/14 | 도메인 3/4 +[22:49:18] 온라인 8/14 | 도메인 3/4 +[22:49:58] 온라인 8/14 | 도메인 3/4 +[22:50:04] 온라인 8/14 | 도메인 3/4 +[22:50:38] 온라인 8/14 | 도메인 3/4 +[22:51:13] 온라인 8/14 | 도메인 3/4 +[22:51:18] 온라인 8/14 | 도메인 3/4 +[22:51:57] 온라인 8/14 | 도메인 3/4 +[22:52:23] 온라인 8/14 | 도메인 3/4 +[22:52:37] 온라인 8/14 | 도메인 3/4 +[22:53:16] 온라인 8/14 | 도메인 3/4 +[22:53:32] 온라인 8/14 | 도메인 3/4 +[22:53:55] 온라인 8/14 | 도메인 3/4 +[22:54:35] 온라인 8/14 | 도메인 3/4 +[22:54:42] 온라인 8/14 | 도메인 3/4 +[22:55:15] 온라인 8/14 | 도메인 3/4 +[22:55:51] 온라인 8/14 | 도메인 3/4 +[22:55:54] 온라인 8/14 | 도메인 3/4 +[22:56:33] 온라인 8/14 | 도메인 3/4 +[22:57:01] 온라인 8/14 | 도메인 3/4 +[22:57:13] 온라인 8/14 | 도메인 3/4 +[22:57:52] 온라인 8/14 | 도메인 3/4 +[22:58:10] 온라인 8/14 | 도메인 3/4 +[22:58:31] 온라인 8/14 | 도메인 3/4 +[22:59:11] 온라인 8/14 | 도메인 3/4 +[22:59:20] 온라인 8/14 | 도메인 3/4 +[22:59:51] 온라인 8/14 | 도메인 3/4 +[23:00:29] 온라인 8/14 | 도메인 3/4 +[23:00:33] 온라인 8/14 | 도메인 3/4 +[23:01:12] 온라인 8/14 | 도메인 3/4 +[23:01:38] 온라인 8/14 | 도메인 3/4 +[23:01:52] 온라인 8/14 | 도메인 3/4 +[23:02:31] 온라인 8/14 | 도메인 3/4 +[23:02:48] 온라인 8/14 | 도메인 3/4 +[23:03:11] 온라인 8/14 | 도메인 3/4 +[23:03:50] 온라인 8/14 | 도메인 3/4 +[23:03:58] 온라인 8/14 | 도메인 3/4 +[23:04:31] 온라인 8/14 | 도메인 3/4 +[23:05:07] 온라인 8/14 | 도메인 3/4 +[23:05:10] 온라인 8/14 | 도메인 3/4 +[23:05:50] 온라인 8/14 | 도메인 3/4 +[23:06:17] 온라인 8/14 | 도메인 3/4 +[23:06:29] 온라인 8/14 | 도메인 3/4 +[23:07:09] 온라인 8/14 | 도메인 3/4 +[23:07:27] 온라인 8/14 | 도메인 3/4 +[23:07:49] 온라인 8/14 | 도메인 3/4 +[23:08:30] 온라인 8/14 | 도메인 3/4 +[23:08:37] 온라인 8/14 | 도메인 3/4 +[23:09:11] 온라인 8/14 | 도메인 3/4 +[23:09:47] 온라인 8/14 | 도메인 3/4 +[23:09:51] 온라인 8/14 | 도메인 3/4 +[23:10:31] 온라인 8/14 | 도메인 3/4 +[23:10:58] 온라인 8/14 | 도메인 3/4 +[23:11:11] 온라인 8/14 | 도메인 3/4 +[23:11:52] 온라인 8/14 | 도메인 3/4 +[23:12:08] 온라인 8/14 | 도메인 3/4 +[23:12:32] 온라인 8/14 | 도메인 3/4 +[23:13:13] 온라인 8/14 | 도메인 3/4 +[23:13:18] 온라인 8/14 | 도메인 3/4 +[23:13:54] 온라인 8/14 | 도메인 3/4 +[23:14:28] 온라인 8/14 | 도메인 3/4 +[23:14:35] 온라인 8/14 | 도메인 3/4 +[23:15:15] 온라인 8/14 | 도메인 3/4 +[23:15:39] 온라인 8/14 | 도메인 3/4 +[23:15:55] 온라인 8/14 | 도메인 3/4 +[23:16:36] 온라인 8/14 | 도메인 3/4 +[23:16:50] 온라인 8/14 | 도메인 3/4 +[23:17:16] 온라인 8/14 | 도메인 3/4 +[23:17:57] 온라인 8/14 | 도메인 3/4 +[23:18:00] 온라인 8/14 | 도메인 3/4 +[23:18:38] 온라인 7/14 | 도메인 3/4 +[23:19:10] 온라인 7/14 | 도메인 3/4 +[23:19:18] 온라인 7/14 | 도메인 3/4 +[23:19:58] 온라인 7/14 | 도메인 3/4 +[23:20:20] 온라인 7/14 | 도메인 3/4 +[23:20:39] 온라인 7/14 | 도메인 3/4 +[23:21:20] 온라인 7/14 | 도메인 3/4 +[23:21:31] 온라인 7/14 | 도메인 3/4 +[23:22:01] 온라인 8/14 | 도메인 3/4 +[23:22:41] 온라인 8/14 | 도메인 3/4 +[23:22:46] 온라인 8/14 | 도메인 3/4 +[23:23:30] 온라인 8/14 | 도메인 3/4 +[23:23:56] 온라인 8/14 | 도메인 3/4 +[23:24:14] 온라인 8/14 | 도메인 3/4 +[23:24:55] 온라인 8/14 | 도메인 3/4 +[23:25:10] 온라인 8/14 | 도메인 3/4 +[23:25:36] 온라인 8/14 | 도메인 3/4 +[23:26:17] 온라인 8/14 | 도메인 3/4 +[23:26:20] 온라인 8/14 | 도메인 3/4 +[23:26:58] 온라인 8/14 | 도메인 3/4 +[23:27:30] 온라인 8/14 | 도메인 3/4 +[23:27:39] 온라인 8/14 | 도메인 3/4 +[23:28:20] 온라인 8/14 | 도메인 3/4 +[23:28:41] 온라인 8/14 | 도메인 3/4 +[23:29:03] 온라인 8/14 | 도메인 3/4 +[23:29:44] 온라인 8/14 | 도메인 3/4 +[23:29:51] 온라인 8/14 | 도메인 3/4 +[23:30:26] 온라인 8/14 | 도메인 3/4 +[23:31:01] 온라인 8/14 | 도메인 3/4 +[23:31:06] 온라인 8/14 | 도메인 3/4 +[23:31:46] 온라인 8/14 | 도메인 3/4 +[23:32:12] 온라인 8/14 | 도메인 3/4 +[23:32:26] 온라인 8/14 | 도메인 3/4 +[23:33:06] 온라인 8/14 | 도메인 3/4 +[23:33:22] 온라인 8/14 | 도메인 3/4 +[23:33:47] 온라인 8/14 | 도메인 3/4 +[23:34:27] 온라인 8/14 | 도메인 3/4 +[23:34:33] 온라인 8/14 | 도메인 3/4 +[23:35:12] 온라인 8/14 | 도메인 3/4 +[23:35:47] 온라인 8/14 | 도메인 3/4 +[23:35:52] 온라인 8/14 | 도메인 3/4 +[23:36:33] 온라인 8/14 | 도메인 3/4 +[23:37:01] 온라인 8/14 | 도메인 3/4 +[23:37:18] 온라인 8/14 | 도메인 3/4 +[23:37:59] 온라인 8/14 | 도메인 3/4 +[23:38:16] 온라인 8/14 | 도메인 3/4 +[23:38:40] 온라인 8/14 | 도메인 3/4 +[23:39:20] 온라인 8/14 | 도메인 3/4 +[23:39:26] 온라인 8/14 | 도메인 3/4 +[23:40:01] 온라인 8/14 | 도메인 3/4 +[23:40:36] 온라인 8/14 | 도메인 3/4 +[23:40:41] 온라인 8/14 | 도메인 3/4 +[23:41:21] 온라인 8/14 | 도메인 3/4 +[23:41:47] 온라인 8/14 | 도메인 3/4 +[23:42:02] 온라인 8/14 | 도메인 3/4 +[23:42:43] 온라인 8/14 | 도메인 3/4 +[23:42:57] 온라인 8/14 | 도메인 3/4 +[23:43:23] 온라인 8/14 | 도메인 3/4 +[23:44:04] 온라인 8/14 | 도메인 3/4 +[23:44:08] 온라인 8/14 | 도메인 3/4 +[23:44:45] 온라인 8/14 | 도메인 3/4 +[23:45:18] 온라인 8/14 | 도메인 3/4 +[23:45:25] 온라인 8/14 | 도메인 3/4 +[23:46:06] 온라인 8/14 | 도메인 3/4 +[23:46:28] 온라인 8/14 | 도메인 3/4 +[23:46:46] 온라인 8/14 | 도메인 3/4 +[23:47:26] 온라인 8/14 | 도메인 3/4 +[23:47:38] 온라인 8/14 | 도메인 3/4 +[23:48:06] 온라인 8/14 | 도메인 3/4 +[23:48:46] 온라인 8/14 | 도메인 3/4 +[23:48:49] 온라인 8/14 | 도메인 3/4 +[23:49:27] 온라인 8/14 | 도메인 3/4 +[23:49:58] 온라인 8/14 | 도메인 3/4 +[23:50:07] 온라인 8/14 | 도메인 3/4 +[23:50:47] 온라인 8/14 | 도메인 3/4 +[23:51:09] 온라인 8/14 | 도메인 3/4 +[23:51:27] 온라인 8/14 | 도메인 3/4 +[23:52:07] 온라인 8/14 | 도메인 3/4 +[23:52:19] 온라인 8/14 | 도메인 3/4 +[23:52:48] 온라인 8/14 | 도메인 3/4 +[23:53:29] 온라인 8/14 | 도메인 3/4 +[23:53:29] 온라인 8/14 | 도메인 3/4 +[23:54:10] 온라인 8/14 | 도메인 3/4 +[23:54:40] 온라인 8/14 | 도메인 3/4 +[23:54:51] 온라인 8/14 | 도메인 3/4 +[23:55:31] 온라인 8/14 | 도메인 3/4 +[23:55:51] 온라인 8/14 | 도메인 3/4 +[23:56:11] 온라인 8/14 | 도메인 3/4 +[23:56:51] 온라인 8/14 | 도메인 3/4 +[23:57:01] 온라인 8/14 | 도메인 3/4 +[23:57:32] 온라인 8/14 | 도메인 3/4 +[23:58:10] 온라인 8/14 | 도메인 3/4 +[23:58:12] 온라인 8/14 | 도메인 3/4 +[23:58:52] 온라인 8/14 | 도메인 3/4 +[23:59:21] 온라인 8/14 | 도메인 3/4 +[23:59:33] 온라인 8/14 | 도메인 3/4 +[00:00:13] 온라인 8/14 | 도메인 3/4 +[00:00:31] 온라인 8/14 | 도메인 3/4 +[00:00:53] 온라인 8/14 | 도메인 3/4 +[00:01:33] 온라인 8/14 | 도메인 3/4 +[00:01:42] 온라인 8/14 | 도메인 3/4 +[00:02:14] 온라인 8/14 | 도메인 3/4 +[00:02:52] 온라인 8/14 | 도메인 3/4 +[00:02:54] 온라인 8/14 | 도메인 3/4 +[00:03:34] 온라인 8/14 | 도메인 3/4 +[00:04:02] 온라인 8/14 | 도메인 3/4 +[00:04:18] 온라인 8/14 | 도메인 3/4 +[00:04:58] 온라인 8/14 | 도메인 3/4 +[00:05:13] 온라인 8/14 | 도메인 3/4 +[00:05:39] 온라인 8/14 | 도메인 3/4 +[00:06:20] 온라인 8/14 | 도메인 3/4 +[00:06:23] 온라인 8/14 | 도메인 3/4 +[00:07:00] 온라인 8/14 | 도메인 3/4 +[00:07:33] 온라인 8/14 | 도메인 3/4 +[00:07:41] 온라인 8/14 | 도메인 3/4 +[00:08:21] 온라인 8/14 | 도메인 3/4 +[00:08:43] 온라인 8/14 | 도메인 3/4 +[00:09:01] 온라인 8/14 | 도메인 3/4 +[00:09:42] 온라인 8/14 | 도메인 3/4 +[00:09:54] 온라인 8/14 | 도메인 3/4 +[00:10:23] 온라인 8/14 | 도메인 3/4 +[00:11:04] 온라인 8/14 | 도메인 3/4 +[00:11:04] 온라인 8/14 | 도메인 3/4 +[00:11:45] 온라인 8/14 | 도메인 3/4 +[00:12:15] 온라인 8/14 | 도메인 3/4 +[00:12:31] 온라인 8/14 | 도메인 3/4 +[00:13:12] 온라인 8/14 | 도메인 3/4 +[00:13:27] 온라인 8/14 | 도메인 3/4 +[00:13:53] 온라인 8/14 | 도메인 3/4 +[00:14:33] 온라인 8/14 | 도메인 3/4 +[00:14:37] 온라인 8/14 | 도메인 3/4 +[00:15:18] 온라인 7/14 | 도메인 3/4 +[00:15:49] 온라인 8/14 | 도메인 3/4 +[00:16:17] 온라인 7/14 | 도메인 3/4 +[00:17:24] 온라인 8/14 | 도메인 3/4 +[00:17:11] 온라인 8/14 | 도메인 3/4 +[00:18:12] 온라인 8/14 | 도메인 3/4 +[00:18:42] 온라인 8/14 | 도메인 3/4 +[00:18:52] 온라인 8/14 | 도메인 3/4 +[00:19:32] 온라인 8/14 | 도메인 3/4 +[00:19:53] 온라인 8/14 | 도메인 3/4 +[00:20:12] 온라인 8/14 | 도메인 3/4 +[00:20:52] 온라인 8/14 | 도메인 3/4 +[00:21:03] 온라인 8/14 | 도메인 3/4 +[00:21:33] 온라인 8/14 | 도메인 3/4 +[00:22:13] 온라인 8/14 | 도메인 3/4 +[00:22:14] 온라인 8/14 | 도메인 3/4 +[00:22:54] 온라인 8/14 | 도메인 3/4 +[00:23:24] 온라인 8/14 | 도메인 3/4 +[00:23:34] 온라인 8/14 | 도메인 3/4 +[00:24:14] 온라인 8/14 | 도메인 3/4 +[00:24:34] 온라인 8/14 | 도메인 3/4 +[00:24:54] 온라인 8/14 | 도메인 3/4 +[00:25:33] 온라인 8/14 | 도메인 3/4 +[00:25:44] 온라인 8/14 | 도메인 3/4 +[00:26:14] 온라인 8/14 | 도메인 3/4 +[00:26:54] 온라인 8/14 | 도메인 3/4 +[00:26:55] 온라인 8/14 | 도메인 3/4 +[00:27:35] 온라인 8/14 | 도메인 3/4 +[00:28:05] 온라인 8/14 | 도메인 3/4 +[00:28:16] 온라인 8/14 | 도메인 3/4 +[00:28:56] 온라인 8/14 | 도메인 3/4 +[00:29:16] 온라인 8/14 | 도메인 3/4 +[00:29:36] 온라인 8/14 | 도메인 3/4 +[00:30:16] 온라인 8/14 | 도메인 3/4 +[00:30:26] 온라인 8/14 | 도메인 3/4 +[00:30:57] 온라인 8/14 | 도메인 3/4 +[00:31:36] 온라인 8/14 | 도메인 3/4 +[00:31:38] 온라인 8/14 | 도메인 3/4 +[00:32:17] 온라인 8/14 | 도메인 3/4 +[00:32:46] 온라인 8/14 | 도메인 3/4 +[00:32:57] 온라인 8/14 | 도메인 3/4 +[00:33:37] 온라인 8/14 | 도메인 3/4 +[00:33:57] 온라인 8/14 | 도메인 3/4 +[00:34:17] 온라인 8/14 | 도메인 3/4 +[00:34:57] 온라인 8/14 | 도메인 3/4 +[00:35:07] 온라인 8/14 | 도메인 3/4 +[00:35:38] 온라인 8/14 | 도메인 3/4 +[00:36:17] 온라인 8/14 | 도메인 3/4 +[00:36:17] 온라인 8/14 | 도메인 3/4 +[00:36:59] 온라인 8/14 | 도메인 3/4 +[00:37:28] 온라인 8/14 | 도메인 3/4 +[00:37:39] 온라인 8/14 | 도메인 3/4 +[00:38:19] 온라인 8/14 | 도메인 3/4 +[00:38:39] 온라인 8/14 | 도메인 3/4 +[00:38:59] 온라인 8/14 | 도메인 3/4 +[00:39:40] 온라인 8/14 | 도메인 3/4 +[00:39:49] 온라인 8/14 | 도메인 3/4 +[00:40:21] 온라인 8/14 | 도메인 3/4 +[00:40:59] 온라인 8/14 | 도메인 3/4 +[00:41:01] 온라인 8/14 | 도메인 3/4 +[00:41:42] 온라인 8/14 | 도메인 3/4 +[00:42:10] 온라인 8/14 | 도메인 3/4 +[00:42:23] 온라인 8/14 | 도메인 3/4 +[00:43:02] 온라인 8/14 | 도메인 3/4 +[00:43:20] 온라인 8/14 | 도메인 3/4 +[00:43:42] 온라인 8/14 | 도메인 3/4 +[00:44:23] 온라인 8/14 | 도메인 3/4 +[00:44:30] 온라인 8/14 | 도메인 3/4 +[00:45:05] 온라인 8/14 | 도메인 3/4 +[00:45:40] 온라인 8/14 | 도메인 3/4 +[00:45:45] 온라인 8/14 | 도메인 3/4 +[00:46:25] 온라인 8/14 | 도메인 3/4 +[00:46:50] 온라인 8/14 | 도메인 3/4 +[00:47:05] 온라인 8/14 | 도메인 3/4 +[00:47:45] 온라인 8/14 | 도메인 3/4 +[00:48:01] 온라인 8/14 | 도메인 3/4 +[00:48:25] 온라인 8/14 | 도메인 3/4 +[00:49:05] 온라인 8/14 | 도메인 3/4 +[00:49:11] 온라인 8/14 | 도메인 3/4 +[00:49:46] 온라인 8/14 | 도메인 3/4 +[00:50:20] 온라인 8/14 | 도메인 3/4 +[00:50:26] 온라인 8/14 | 도메인 3/4 +[00:51:06] 온라인 8/14 | 도메인 3/4 +[00:51:31] 온라인 8/14 | 도메인 3/4 +[00:51:46] 온라인 8/14 | 도메인 3/4 +[00:52:27] 온라인 8/14 | 도메인 3/4 +[00:52:41] 온라인 8/14 | 도메인 3/4 +[00:53:07] 온라인 8/14 | 도메인 3/4 +[00:53:47] 온라인 8/14 | 도메인 3/4 +[00:53:52] 온라인 8/14 | 도메인 3/4 +[00:54:28] 온라인 8/14 | 도메인 3/4 +[00:55:02] 온라인 8/14 | 도메인 3/4 +[00:55:08] 온라인 8/14 | 도메인 3/4 +[00:55:49] 온라인 8/14 | 도메인 3/4 +[00:56:13] 온라인 8/14 | 도메인 3/4 +[00:56:29] 온라인 8/14 | 도메인 3/4 +[00:57:09] 온라인 8/14 | 도메인 3/4 +[00:57:23] 온라인 8/14 | 도메인 3/4 +[00:57:50] 온라인 8/14 | 도메인 3/4 +[00:58:30] 온라인 8/14 | 도메인 3/4 +[00:58:33] 온라인 8/14 | 도메인 3/4 +[00:59:10] 온라인 8/14 | 도메인 3/4 +[00:59:43] 온라인 8/14 | 도메인 3/4 +[00:59:50] 온라인 8/14 | 도메인 3/4 +[01:00:31] 온라인 8/14 | 도메인 3/4 +[01:00:53] 온라인 8/14 | 도메인 3/4 +[01:01:11] 온라인 8/14 | 도메인 3/4 +[01:01:51] 온라인 8/14 | 도메인 3/4 +[01:02:04] 온라인 8/14 | 도메인 3/4 +[01:02:32] 온라인 8/14 | 도메인 3/4 +[01:03:12] 온라인 8/14 | 도메인 3/4 +[01:03:13] 온라인 8/14 | 도메인 3/4 +[01:03:53] 온라인 8/14 | 도메인 3/4 +[01:04:24] 온라인 8/14 | 도메인 3/4 +[01:04:33] 온라인 8/14 | 도메인 3/4 +[01:05:14] 온라인 8/14 | 도메인 3/4 +[01:05:34] 온라인 8/14 | 도메인 3/4 +[01:05:54] 온라인 8/14 | 도메인 3/4 +[01:06:34] 온라인 8/14 | 도메인 3/4 +[01:06:45] 온라인 8/14 | 도메인 3/4 +[01:07:15] 온라인 8/14 | 도메인 3/4 +[01:07:55] 온라인 8/14 | 도메인 3/4 +[01:07:55] 온라인 8/14 | 도메인 3/4 +[01:08:35] 온라인 8/14 | 도메인 3/4 +[01:09:05] 온라인 8/14 | 도메인 3/4 +[01:09:15] 온라인 8/14 | 도메인 3/4 +[01:09:55] 온라인 8/14 | 도메인 3/4 +[01:10:15] 온라인 8/14 | 도메인 3/4 +[01:10:34] 온라인 8/14 | 도메인 3/4 +[01:11:14] 온라인 8/14 | 도메인 3/4 +[01:11:26] 온라인 8/14 | 도메인 3/4 +[01:11:54] 온라인 8/14 | 도메인 3/4 +[01:12:34] 온라인 8/14 | 도메인 3/4 +[01:12:35] 온라인 8/14 | 도메인 3/4 +[01:13:15] 온라인 8/14 | 도메인 3/4 +[01:13:45] 온라인 8/14 | 도메인 3/4 +[01:13:55] 온라인 8/14 | 도메인 3/4 +[01:14:35] 온라인 8/14 | 도메인 3/4 +[01:14:56] 온라인 8/14 | 도메인 3/4 +[01:15:15] 온라인 8/14 | 도메인 3/4 +[01:15:56] 온라인 8/14 | 도메인 3/4 +[01:16:07] 온라인 8/14 | 도메인 3/4 +[01:16:38] 온라인 8/14 | 도메인 3/4 +[01:17:17] 온라인 8/14 | 도메인 3/4 +[01:17:18] 온라인 8/14 | 도메인 3/4 +[01:17:59] 온라인 8/14 | 도메인 3/4 +[01:18:28] 온라인 8/14 | 도메인 3/4 +[01:18:39] 온라인 8/14 | 도메인 3/4 +[01:19:19] 온라인 8/14 | 도메인 3/4 +[01:19:38] 온라인 8/14 | 도메인 3/4 +[01:19:59] 온라인 8/14 | 도메인 3/4 +[01:20:40] 온라인 8/14 | 도메인 3/4 +[01:20:49] 온라인 8/14 | 도메인 3/4 +[01:21:21] 온라인 8/14 | 도메인 3/4 +[01:21:58] 온라인 8/14 | 도메인 3/4 +[01:22:01] 온라인 8/14 | 도메인 3/4 +[01:22:41] 온라인 8/14 | 도메인 3/4 +[01:23:09] 온라인 8/14 | 도메인 3/4 +[01:23:23] 온라인 8/14 | 도메인 3/4 +[01:24:03] 온라인 8/14 | 도메인 3/4 +[01:24:19] 온라인 8/14 | 도메인 3/4 +[01:24:43] 온라인 8/14 | 도메인 3/4 +[01:25:24] 온라인 8/14 | 도메인 3/4 +[01:25:30] 온라인 8/14 | 도메인 3/4 +[01:26:04] 온라인 8/14 | 도메인 3/4 +[01:26:40] 온라인 8/14 | 도메인 3/4 +[01:26:45] 온라인 8/14 | 도메인 3/4 +[01:27:25] 온라인 8/14 | 도메인 3/4 +[01:27:51] 온라인 8/14 | 도메인 3/4 +[01:28:05] 온라인 8/14 | 도메인 3/4 +[01:28:45] 온라인 8/14 | 도메인 3/4 +[01:29:01] 온라인 8/14 | 도메인 3/4 +[01:29:25] 온라인 8/14 | 도메인 3/4 +[01:30:05] 온라인 8/14 | 도메인 3/4 +[01:30:12] 온라인 8/14 | 도메인 3/4 +[01:30:47] 온라인 8/14 | 도메인 3/4 +[01:31:22] 온라인 8/14 | 도메인 3/4 +[01:31:27] 온라인 8/14 | 도메인 3/4 +[01:32:07] 온라인 8/14 | 도메인 3/4 +[01:32:32] 온라인 8/14 | 도메인 3/4 +[01:32:47] 온라인 8/14 | 도메인 3/4 +[01:33:27] 온라인 8/14 | 도메인 3/4 +[01:33:43] 온라인 8/14 | 도메인 3/4 +[01:34:07] 온라인 8/14 | 도메인 3/4 +[01:34:47] 온라인 8/14 | 도메인 3/4 +[01:34:53] 온라인 8/14 | 도메인 3/4 +[01:35:27] 온라인 8/14 | 도메인 3/4 +[01:36:03] 온라인 8/14 | 도메인 3/4 +[01:36:07] 온라인 8/14 | 도메인 3/4 +[01:36:47] 온라인 8/14 | 도메인 3/4 +[01:37:14] 온라인 8/14 | 도메인 3/4 +[01:37:28] 온라인 8/14 | 도메인 3/4 +[01:38:07] 온라인 8/14 | 도메인 3/4 +[01:38:24] 온라인 8/14 | 도메인 3/4 +[01:38:47] 온라인 8/14 | 도메인 3/4 +[01:39:27] 온라인 8/14 | 도메인 3/4 +[01:39:35] 온라인 8/14 | 도메인 3/4 +[01:40:07] 온라인 8/14 | 도메인 3/4 +[01:40:45] 온라인 8/14 | 도메인 3/4 +[01:40:47] 온라인 8/14 | 도메인 3/4 +[01:41:27] 온라인 8/14 | 도메인 3/4 +[01:41:56] 온라인 8/14 | 도메인 3/4 +[01:42:07] 온라인 8/14 | 도메인 3/4 +[01:42:47] 온라인 8/14 | 도메인 3/4 +[01:43:06] 온라인 8/14 | 도메인 3/4 +[01:43:27] 온라인 8/14 | 도메인 3/4 +[01:44:07] 온라인 8/14 | 도메인 3/4 +[01:44:17] 온라인 8/14 | 도메인 3/4 +[01:44:48] 온라인 8/14 | 도메인 3/4 +[01:45:27] 온라인 8/14 | 도메인 3/4 +[01:45:30] 온라인 8/14 | 도메인 3/4 +[01:46:11] 온라인 8/14 | 도메인 3/4 +[01:46:38] 온라인 8/14 | 도메인 3/4 +[01:46:51] 온라인 8/14 | 도메인 3/4 +[01:47:30] 온라인 8/14 | 도메인 3/4 +[01:47:48] 온라인 8/14 | 도메인 3/4 +[01:48:11] 온라인 8/14 | 도메인 3/4 +[01:48:51] 온라인 8/14 | 도메인 3/4 +[01:48:59] 온라인 8/14 | 도메인 3/4 +[01:49:31] 온라인 8/14 | 도메인 3/4 +[01:50:09] 온라인 8/14 | 도메인 3/4 +[01:50:11] 온라인 8/14 | 도메인 3/4 +[01:50:51] 온라인 8/14 | 도메인 3/4 +[01:51:19] 온라인 8/14 | 도메인 3/4 +[01:51:31] 온라인 8/14 | 도메인 3/4 +[01:52:12] 온라인 8/14 | 도메인 3/4 +[01:52:30] 온라인 8/14 | 도메인 3/4 +[01:52:52] 온라인 8/14 | 도메인 3/4 +[01:53:32] 온라인 8/14 | 도메인 3/4 +[01:53:41] 온라인 8/14 | 도메인 3/4 +[01:54:13] 온라인 8/14 | 도메인 3/4 +[01:54:51] 온라인 8/14 | 도메인 3/4 +[01:54:53] 온라인 8/14 | 도메인 3/4 +[01:55:34] 온라인 8/14 | 도메인 3/4 +[01:56:02] 온라인 8/14 | 도메인 3/4 +[01:56:14] 온라인 8/14 | 도메인 3/4 +[01:56:54] 온라인 8/14 | 도메인 3/4 +[01:57:12] 온라인 8/14 | 도메인 3/4 +[01:57:35] 온라인 8/14 | 도메인 3/4 +[01:58:15] 온라인 8/14 | 도메인 3/4 +[01:58:23] 온라인 8/14 | 도메인 3/4 +[01:58:56] 온라인 8/14 | 도메인 3/4 +[01:59:33] 온라인 8/14 | 도메인 3/4 +[01:59:37] 온라인 8/14 | 도메인 3/4 +[02:00:17] 온라인 8/14 | 도메인 3/4 +[02:00:44] 온라인 8/14 | 도메인 3/4 +[02:00:57] 온라인 8/14 | 도메인 3/4 +[02:01:38] 온라인 8/14 | 도메인 3/4 +[02:01:54] 온라인 8/14 | 도메인 3/4 +[02:02:18] 온라인 8/14 | 도메인 3/4 +[02:02:58] 온라인 8/14 | 도메인 3/4 +[02:03:05] 온라인 8/14 | 도메인 3/4 +[02:03:39] 온라인 8/14 | 도메인 3/4 +[02:04:15] 온라인 8/14 | 도메인 3/4 +[02:04:20] 온라인 8/14 | 도메인 3/4 +[02:05:00] 온라인 8/14 | 도메인 3/4 +[02:05:25] 온라인 8/14 | 도메인 3/4 +[02:05:40] 온라인 8/14 | 도메인 3/4 +[02:06:21] 온라인 8/14 | 도메인 3/4 +[02:06:36] 온라인 8/14 | 도메인 3/4 +[02:07:01] 온라인 8/14 | 도메인 3/4 +[02:07:42] 온라인 8/14 | 도메인 3/4 +[02:07:46] 온라인 8/14 | 도메인 3/4 +[02:08:22] 온라인 8/14 | 도메인 3/4 +[02:08:56] 온라인 8/14 | 도메인 3/4 +[02:09:03] 온라인 8/14 | 도메인 3/4 +[02:09:43] 온라인 8/14 | 도메인 3/4 +[02:10:07] 온라인 8/14 | 도메인 3/4 +[02:10:24] 온라인 8/14 | 도메인 3/4 +[02:11:04] 온라인 8/14 | 도메인 3/4 +[02:11:17] 온라인 8/14 | 도메인 3/4 +[02:11:44] 온라인 8/14 | 도메인 3/4 +[02:12:24] 온라인 8/14 | 도메인 3/4 +[02:12:27] 온라인 8/14 | 도메인 3/4 +[02:13:05] 온라인 8/14 | 도메인 3/4 +[02:13:37] 온라인 8/14 | 도메인 3/4 +[02:13:45] 온라인 8/14 | 도메인 3/4 +[02:14:25] 온라인 8/14 | 도메인 3/4 +[02:14:48] 온라인 8/14 | 도메인 3/4 +[02:15:06] 온라인 8/14 | 도메인 3/4 +[02:15:46] 온라인 8/14 | 도메인 3/4 +[02:15:59] 온라인 8/14 | 도메인 3/4 +[02:16:26] 온라인 8/14 | 도메인 3/4 +[02:17:07] 온라인 8/14 | 도메인 3/4 +[02:17:09] 온라인 8/14 | 도메인 3/4 +[02:17:48] 온라인 8/14 | 도메인 3/4 +[02:18:19] 온라인 8/14 | 도메인 3/4 +[02:18:29] 온라인 8/14 | 도메인 3/4 +[02:19:09] 온라인 8/14 | 도메인 3/4 +[02:19:30] 온라인 8/14 | 도메인 3/4 +[02:19:50] 온라인 8/14 | 도메인 3/4 +[02:20:31] 온라인 8/14 | 도메인 3/4 +[02:20:40] 온라인 8/14 | 도메인 3/4 +[02:21:12] 온라인 8/14 | 도메인 3/4 +[02:21:51] 온라인 8/14 | 도메인 3/4 +[02:21:53] 온라인 8/14 | 도메인 3/4 +[02:22:33] 온라인 8/14 | 도메인 3/4 +[02:23:01] 온라인 8/14 | 도메인 3/4 +[02:23:14] 온라인 8/14 | 도메인 3/4 +[02:23:54] 온라인 8/14 | 도메인 3/4 +[02:24:11] 온라인 8/14 | 도메인 3/4 +[02:24:35] 온라인 8/14 | 도메인 3/4 +[02:25:15] 온라인 8/14 | 도메인 3/4 +[02:25:22] 온라인 8/14 | 도메인 3/4 +[02:25:55] 온라인 8/14 | 도메인 3/4 +[02:26:32] 온라인 8/14 | 도메인 3/4 +[02:26:36] 온라인 8/14 | 도메인 3/4 +[02:27:16] 온라인 8/14 | 도메인 3/4 +[02:27:43] 온라인 8/14 | 도메인 3/4 +[02:27:56] 온라인 8/14 | 도메인 3/4 +[02:28:37] 온라인 8/14 | 도메인 3/4 +[02:28:54] 온라인 8/14 | 도메인 3/4 +[02:29:17] 온라인 8/14 | 도메인 3/4 +[02:29:57] 온라인 8/14 | 도메인 3/4 +[02:30:04] 온라인 8/14 | 도메인 3/4 +[02:30:39] 온라인 8/14 | 도메인 3/4 +[02:31:14] 온라인 8/14 | 도메인 3/4 +[02:31:19] 온라인 8/14 | 도메인 3/4 +[02:31:59] 온라인 8/14 | 도메인 3/4 +[02:32:25] 온라인 8/14 | 도메인 3/4 +[02:32:40] 온라인 8/14 | 도메인 3/4 +[02:33:19] 온라인 8/14 | 도메인 3/4 +[02:33:35] 온라인 8/14 | 도메인 3/4 +[02:34:00] 온라인 8/14 | 도메인 3/4 +[02:34:40] 온라인 8/14 | 도메인 3/4 +[02:34:45] 온라인 8/14 | 도메인 3/4 +[02:35:20] 온라인 8/14 | 도메인 3/4 +[02:35:55] 온라인 8/14 | 도메인 3/4 +[02:36:00] 온라인 8/14 | 도메인 3/4 +[02:36:41] 온라인 8/14 | 도메인 3/4 +[02:37:05] 온라인 8/14 | 도메인 3/4 +[02:37:21] 온라인 8/14 | 도메인 3/4 +[02:38:01] 온라인 8/14 | 도메인 3/4 +[02:38:16] 온라인 8/14 | 도메인 3/4 +[02:38:41] 온라인 8/14 | 도메인 3/4 +[02:39:21] 온라인 8/14 | 도메인 3/4 +[02:39:26] 온라인 8/14 | 도메인 3/4 +[02:40:01] 온라인 8/14 | 도메인 3/4 +[02:40:36] 온라인 8/14 | 도메인 3/4 +[02:40:42] 온라인 8/14 | 도메인 3/4 +[02:41:22] 온라인 8/14 | 도메인 3/4 +[02:41:47] 온라인 8/14 | 도메인 3/4 +[02:42:02] 온라인 8/14 | 도메인 3/4 +[02:42:42] 온라인 8/14 | 도메인 3/4 +[02:42:57] 온라인 8/14 | 도메인 3/4 +[02:43:21] 온라인 8/14 | 도메인 3/4 +[02:44:02] 온라인 8/14 | 도메인 3/4 +[02:44:08] 온라인 8/14 | 도메인 3/4 +[02:44:42] 온라인 8/14 | 도메인 3/4 +[02:45:18] 온라인 8/14 | 도메인 3/4 +[02:45:23] 온라인 8/14 | 도메인 3/4 +[02:46:03] 온라인 8/14 | 도메인 3/4 +[02:46:29] 온라인 8/14 | 도메인 3/4 +[02:46:43] 온라인 8/14 | 도메인 3/4 +[02:47:23] 온라인 8/14 | 도메인 3/4 +[02:47:40] 온라인 8/14 | 도메인 3/4 +[02:48:04] 온라인 8/14 | 도메인 3/4 +[02:48:44] 온라인 8/14 | 도메인 3/4 +[02:48:50] 온라인 8/14 | 도메인 3/4 +[02:49:25] 온라인 8/14 | 도메인 3/4 +[02:50:00] 온라인 8/14 | 도메인 3/4 +[02:50:05] 온라인 8/14 | 도메인 3/4 +[02:50:46] 온라인 8/14 | 도메인 3/4 +[02:51:10] 온라인 8/14 | 도메인 3/4 +[02:51:27] 온라인 8/14 | 도메인 3/4 +[02:52:07] 온라인 8/14 | 도메인 3/4 +[02:52:21] 온라인 8/14 | 도메인 3/4 +[02:52:47] 온라인 8/14 | 도메인 3/4 +[02:53:28] 온라인 8/14 | 도메인 3/4 +[02:53:31] 온라인 8/14 | 도메인 3/4 +[02:54:08] 온라인 8/14 | 도메인 3/4 +[02:54:41] 온라인 8/14 | 도메인 3/4 +[02:54:48] 온라인 8/14 | 도메인 3/4 +[02:55:28] 온라인 8/14 | 도메인 3/4 +[02:55:52] 온라인 8/14 | 도메인 3/4 +[02:56:09] 온라인 8/14 | 도메인 3/4 +[02:56:49] 온라인 8/14 | 도메인 3/4 +[02:57:02] 온라인 8/14 | 도메인 3/4 +[02:57:29] 온라인 8/14 | 도메인 3/4 +[02:58:09] 온라인 8/14 | 도메인 3/4 +[02:58:12] 온라인 8/14 | 도메인 3/4 +[02:58:50] 온라인 8/14 | 도메인 3/4 +[02:59:22] 온라인 8/14 | 도메인 3/4 +[02:59:31] 온라인 8/14 | 도메인 3/4 +[03:00:11] 온라인 8/14 | 도메인 3/4 +[03:00:33] 온라인 8/14 | 도메인 3/4 +[03:00:51] 온라인 8/14 | 도메인 3/4 +[03:01:31] 온라인 8/14 | 도메인 3/4 +[03:01:43] 온라인 8/14 | 도메인 3/4 +[03:02:11] 온라인 8/14 | 도메인 3/4 +[03:02:51] 온라인 8/14 | 도메인 3/4 +[03:02:54] 온라인 8/14 | 도메인 3/4 +[03:03:32] 온라인 8/14 | 도메인 3/4 +[03:04:04] 온라인 8/14 | 도메인 3/4 +[03:04:12] 온라인 8/14 | 도메인 3/4 +[03:04:53] 온라인 8/14 | 도메인 3/4 +[03:05:14] 온라인 8/14 | 도메인 3/4 +[03:05:33] 온라인 8/14 | 도메인 3/4 +[03:06:13] 온라인 8/14 | 도메인 3/4 +[03:06:25] 온라인 8/14 | 도메인 3/4 +[03:06:56] 온라인 8/14 | 도메인 3/4 +[03:07:36] 온라인 8/14 | 도메인 3/4 +[03:07:35] 온라인 8/14 | 도메인 3/4 +[03:08:16] 온라인 8/14 | 도메인 3/4 +[03:08:46] 온라인 8/14 | 도메인 3/4 +[03:08:56] 온라인 8/14 | 도메인 3/4 +[03:09:36] 온라인 8/14 | 도메인 3/4 +[03:09:56] 온라인 8/14 | 도메인 3/4 +[03:10:17] 온라인 8/14 | 도메인 3/4 +[03:10:57] 온라인 8/14 | 도메인 3/4 +[03:11:07] 온라인 8/14 | 도메인 3/4 +[03:11:37] 온라인 8/14 | 도메인 3/4 +[03:12:17] 온라인 8/14 | 도메인 3/4 +[03:12:17] 온라인 8/14 | 도메인 3/4 +[03:12:58] 온라인 8/14 | 도메인 3/4 +[03:13:28] 온라인 8/14 | 도메인 3/4 +[03:13:39] 온라인 8/14 | 도메인 3/4 +[03:14:19] 온라인 8/14 | 도메인 3/4 +[03:14:39] 온라인 8/14 | 도메인 3/4 +[03:14:59] 온라인 8/14 | 도메인 3/4 +[03:15:40] 온라인 8/14 | 도메인 3/4 +[03:15:49] 온라인 8/14 | 도메인 3/4 +[03:16:21] 온라인 8/14 | 도메인 3/4 +[03:16:59] 온라인 8/14 | 도메인 3/4 +[03:17:02] 온라인 8/14 | 도메인 3/4 +[03:17:42] 온라인 8/14 | 도메인 3/4 +[03:18:10] 온라인 8/14 | 도메인 3/4 +[03:18:23] 온라인 8/14 | 도메인 3/4 +[03:19:03] 온라인 8/14 | 도메인 3/4 +[03:19:20] 온라인 8/14 | 도메인 3/4 +[03:19:44] 온라인 8/14 | 도메인 3/4 +[03:20:24] 온라인 8/14 | 도메인 3/4 +[03:20:31] 온라인 8/14 | 도메인 3/4 +[03:21:04] 온라인 8/14 | 도메인 3/4 +[03:21:40] 온라인 8/14 | 도메인 3/4 +[03:21:45] 온라인 8/14 | 도메인 3/4 +[03:22:25] 온라인 8/14 | 도메인 3/4 +[03:22:51] 온라인 8/14 | 도메인 3/4 +[03:23:05] 온라인 8/14 | 도메인 3/4 +[03:23:45] 온라인 8/14 | 도메인 3/4 +[03:24:01] 온라인 8/14 | 도메인 3/4 +[03:24:25] 온라인 8/14 | 도메인 3/4 +[03:25:05] 온라인 8/14 | 도메인 3/4 +[03:25:12] 온라인 8/14 | 도메인 3/4 +[03:25:45] 온라인 8/14 | 도메인 3/4 +[03:26:22] 온라인 8/14 | 도메인 3/4 +[03:26:26] 온라인 8/14 | 도메인 3/4 +[03:27:06] 온라인 8/14 | 도메인 3/4 +[03:27:32] 온라인 8/14 | 도메인 3/4 +[03:27:46] 온라인 8/14 | 도메인 3/4 +[03:28:27] 온라인 8/14 | 도메인 3/4 +[03:28:43] 온라인 8/14 | 도메인 3/4 +[03:29:08] 온라인 8/14 | 도메인 3/4 +[03:29:49] 온라인 8/14 | 도메인 3/4 +[03:29:54] 온라인 8/14 | 도메인 3/4 +[03:30:30] 온라인 8/14 | 도메인 3/4 +[03:31:04] 온라인 8/14 | 도메인 3/4 +[03:31:10] 온라인 8/14 | 도메인 3/4 +[03:31:51] 온라인 8/14 | 도메인 3/4 +[03:32:14] 온라인 8/14 | 도메인 3/4 +[03:32:31] 온라인 8/14 | 도메인 3/4 +[03:33:11] 온라인 8/14 | 도메인 3/4 +[03:33:25] 온라인 8/14 | 도메인 3/4 +[03:33:51] 온라인 8/14 | 도메인 3/4 +[03:34:31] 온라인 8/14 | 도메인 3/4 +[03:34:35] 온라인 8/14 | 도메인 3/4 +[03:35:11] 온라인 8/14 | 도메인 3/4 +[03:35:45] 온라인 8/14 | 도메인 3/4 +[03:35:52] 온라인 8/14 | 도메인 3/4 +[03:36:32] 온라인 8/14 | 도메인 3/4 +[03:36:55] 온라인 8/14 | 도메인 3/4 +[03:37:13] 온라인 8/14 | 도메인 3/4 +[03:37:53] 온라인 8/14 | 도메인 3/4 +[03:38:06] 온라인 8/14 | 도메인 3/4 +[03:38:34] 온라인 8/14 | 도메인 3/4 +[03:39:14] 온라인 8/14 | 도메인 3/4 +[03:39:16] 온라인 8/14 | 도메인 3/4 +[03:39:54] 온라인 8/14 | 도메인 3/4 +[03:40:26] 온라인 8/14 | 도메인 3/4 +[03:40:34] 온라인 8/14 | 도메인 3/4 +[03:41:15] 온라인 8/14 | 도메인 3/4 +[03:41:36] 온라인 8/14 | 도메인 3/4 +[03:41:56] 온라인 8/14 | 도메인 3/4 +[03:42:37] 온라인 8/14 | 도메인 3/4 +[03:42:47] 온라인 8/14 | 도메인 3/4 +[03:43:17] 온라인 8/14 | 도메인 3/4 +[03:43:57] 온라인 8/14 | 도메인 3/4 +[03:43:58] 온라인 8/14 | 도메인 3/4 +[03:44:38] 온라인 8/14 | 도메인 3/4 +[03:45:08] 온라인 8/14 | 도메인 3/4 +[03:45:19] 온라인 8/14 | 도메인 3/4 +[03:45:59] 온라인 8/14 | 도메인 3/4 +[03:46:18] 온라인 8/14 | 도메인 3/4 +[03:46:41] 온라인 8/14 | 도메인 3/4 +[03:47:21] 온라인 8/14 | 도메인 3/4 +[03:47:29] 온라인 8/14 | 도메인 3/4 +[03:48:02] 온라인 8/14 | 도메인 3/4 +[03:48:39] 온라인 8/14 | 도메인 3/4 +[03:48:42] 온라인 8/14 | 도메인 3/4 +[03:49:22] 온라인 8/14 | 도메인 3/4 +[03:49:49] 온라인 8/14 | 도메인 3/4 +[03:50:02] 온라인 8/14 | 도메인 3/4 +[03:50:42] 온라인 8/14 | 도메인 3/4 +[03:51:00] 온라인 8/14 | 도메인 3/4 +[03:51:22] 온라인 8/14 | 도메인 3/4 +[03:52:02] 온라인 8/14 | 도메인 3/4 +[03:52:10] 온라인 8/14 | 도메인 3/4 +[03:52:43] 온라인 8/14 | 도메인 3/4 +[03:53:20] 온라인 8/14 | 도메인 3/4 +[03:53:22] 온라인 8/14 | 도메인 3/4 +[03:54:01] 온라인 8/14 | 도메인 3/4 +[03:54:28] 온라인 8/14 | 도메인 3/4 +[03:54:39] 온라인 8/14 | 도메인 3/4 +[03:55:17] 온라인 8/14 | 도메인 3/4 +[03:55:37] 온라인 8/14 | 도메인 3/4 +[03:55:55] 온라인 8/14 | 도메인 3/4 +[03:56:33] 온라인 8/14 | 도메인 3/4 +[03:56:45] 온라인 8/14 | 도메인 3/4 +[03:57:12] 온라인 8/14 | 도메인 3/4 +[03:57:50] 온라인 8/14 | 도메인 3/4 +[03:57:53] 온라인 8/14 | 도메인 3/4 +[03:58:28] 온라인 8/14 | 도메인 3/4 +[03:59:00] 온라인 8/14 | 도메인 3/4 +[03:59:06] 온라인 8/14 | 도메인 3/4 +[03:59:44] 온라인 8/14 | 도메인 3/4 +[04:00:09] 온라인 8/14 | 도메인 3/4 +[04:00:23] 온라인 8/14 | 도메인 3/4 +[04:01:01] 온라인 8/14 | 도메인 3/4 +[04:01:17] 온라인 8/14 | 도메인 3/4 +[04:01:39] 온라인 8/14 | 도메인 3/4 +[04:02:17] 온라인 8/14 | 도메인 3/4 +[04:02:25] 온라인 8/14 | 도메인 3/4 +[04:02:56] 온라인 8/14 | 도메인 3/4 +[04:03:33] 온라인 8/14 | 도메인 3/4 +[04:03:34] 온라인 8/14 | 도메인 3/4 +[04:04:12] 온라인 8/14 | 도메인 3/4 +[04:04:41] 온라인 8/14 | 도메인 3/4 +[04:04:50] 온라인 8/14 | 도메인 3/4 +[04:05:28] 온라인 8/14 | 도메인 3/4 +[04:05:50] 온라인 8/14 | 도메인 3/4 +[04:06:06] 온라인 8/14 | 도메인 3/4 +[04:06:44] 온라인 8/14 | 도메인 3/4 +[04:06:58] 온라인 8/14 | 도메인 3/4 +[04:07:23] 온라인 8/14 | 도메인 3/4 +[04:08:00] 온라인 8/14 | 도메인 3/4 +[04:08:06] 온라인 8/14 | 도메인 3/4 +[04:08:39] 온라인 8/14 | 도메인 3/4 +[04:09:14] 온라인 8/14 | 도메인 3/4 +[04:09:18] 온라인 8/14 | 도메인 3/4 +[04:09:56] 온라인 8/14 | 도메인 3/4 +[04:10:22] 온라인 8/14 | 도메인 3/4 +[04:10:34] 온라인 8/14 | 도메인 3/4 +[04:11:12] 온라인 8/14 | 도메인 3/4 +[04:11:30] 온라인 8/14 | 도메인 3/4 +[04:11:50] 온라인 8/14 | 도메인 3/4 +[04:12:29] 온라인 8/14 | 도메인 3/4 +[04:12:39] 온라인 8/14 | 도메인 3/4 +[04:13:07] 온라인 8/14 | 도메인 3/4 +[04:13:45] 온라인 8/14 | 도메인 3/4 +[04:13:47] 온라인 8/14 | 도메인 3/4 +[04:14:23] 온라인 8/14 | 도메인 3/4 +[04:14:55] 온라인 8/14 | 도메인 3/4 +[04:15:02] 온라인 8/14 | 도메인 3/4 +[04:15:40] 온라인 8/14 | 도메인 3/4 +[04:16:03] 온라인 8/14 | 도메인 3/4 +[04:16:18] 온라인 8/14 | 도메인 3/4 +[04:16:56] 온라인 8/14 | 도메인 3/4 +[04:17:11] 온라인 8/14 | 도메인 3/4 +[04:17:34] 온라인 8/14 | 도메인 3/4 +[04:18:12] 온라인 8/14 | 도메인 3/4 +[04:18:19] 온라인 8/14 | 도메인 3/4 +[04:18:50] 온라인 8/14 | 도메인 3/4 +[04:19:27] 온라인 8/14 | 도메인 3/4 +[04:19:29] 온라인 8/14 | 도메인 3/4 +[04:20:07] 온라인 8/14 | 도메인 3/4 +[04:20:35] 온라인 8/14 | 도메인 3/4 +[04:20:45] 온라인 8/14 | 도메인 3/4 +[04:21:23] 온라인 8/14 | 도메인 3/4 +[04:21:44] 온라인 8/14 | 도메인 3/4 +[04:22:01] 온라인 8/14 | 도메인 3/4 +[04:22:39] 온라인 8/14 | 도메인 3/4 +[04:22:52] 온라인 8/14 | 도메인 3/4 +[04:23:22] 온라인 8/14 | 도메인 3/4 +[04:24:00] 온라인 8/14 | 도메인 3/4 +[04:24:00] 온라인 8/14 | 도메인 3/4 +[04:24:40] 온라인 8/14 | 도메인 3/4 +[04:25:09] 온라인 8/14 | 도메인 3/4 +[04:25:17] 온라인 8/14 | 도메인 3/4 +[04:25:55] 온라인 8/14 | 도메인 3/4 +[04:26:17] 온라인 8/14 | 도메인 3/4 +[04:26:33] 온라인 8/14 | 도메인 3/4 +[04:27:11] 온라인 8/14 | 도메인 3/4 +[04:27:26] 온라인 8/14 | 도메인 3/4 +[04:27:49] 온라인 8/14 | 도메인 3/4 +[04:28:27] 온라인 8/14 | 도메인 3/4 +[04:28:34] 온라인 8/14 | 도메인 3/4 +[04:29:06] 온라인 8/14 | 도메인 3/4 +[04:29:42] 온라인 8/14 | 도메인 3/4 +[04:29:45] 온라인 8/14 | 도메인 3/4 +[04:30:23] 온라인 8/14 | 도메인 3/4 +[04:30:50] 온라인 8/14 | 도메인 3/4 +[04:31:01] 온라인 8/14 | 도메인 3/4 +[04:31:40] 온라인 8/14 | 도메인 3/4 +[04:31:58] 온라인 8/14 | 도메인 3/4 +[04:32:18] 온라인 8/14 | 도메인 3/4 +[04:32:57] 온라인 8/14 | 도메인 3/4 +[04:33:07] 온라인 8/14 | 도메인 3/4 +[04:33:36] 온라인 8/14 | 도메인 3/4 +[04:34:15] 온라인 8/14 | 도메인 3/4 +[04:34:14] 온라인 8/14 | 도메인 3/4 +[04:34:53] 온라인 8/14 | 도메인 3/4 +[04:35:23] 온라인 8/14 | 도메인 3/4 +[04:35:31] 온라인 8/14 | 도메인 3/4 +[04:36:09] 온라인 8/14 | 도메인 3/4 +[04:36:31] 온라인 8/14 | 도메인 3/4 +[04:36:47] 온라인 8/14 | 도메인 3/4 +[04:37:25] 온라인 8/14 | 도메인 3/4 +[04:37:40] 온라인 8/14 | 도메인 3/4 +[04:38:03] 온라인 8/14 | 도메인 3/4 +[04:38:41] 온라인 8/14 | 도메인 3/4 +[04:38:48] 온라인 8/14 | 도메인 3/4 +[04:39:19] 온라인 8/14 | 도메인 3/4 +[04:39:56] 온라인 8/14 | 도메인 3/4 +[04:39:58] 온라인 8/14 | 도메인 3/4 +[04:40:35] 온라인 8/14 | 도메인 3/4 +[04:41:04] 온라인 8/14 | 도메인 3/4 +[04:41:13] 온라인 8/14 | 도메인 3/4 +[04:41:51] 온라인 8/14 | 도메인 3/4 +[04:42:13] 온라인 8/14 | 도메인 3/4 +[04:42:29] 온라인 8/14 | 도메인 3/4 +[04:43:07] 온라인 8/14 | 도메인 3/4 +[04:43:21] 온라인 8/14 | 도메인 3/4 +[04:43:45] 온라인 8/14 | 도메인 3/4 +[04:44:22] 온라인 8/14 | 도메인 3/4 +[04:44:29] 온라인 8/14 | 도메인 3/4 +[04:45:00] 온라인 8/14 | 도메인 3/4 +[04:45:37] 온라인 8/14 | 도메인 3/4 +[04:45:38] 온라인 8/14 | 도메인 3/4 +[04:46:16] 온라인 8/14 | 도메인 3/4 +[04:46:46] 온라인 8/14 | 도메인 3/4 +[04:46:56] 온라인 8/14 | 도메인 3/4 +[04:47:34] 온라인 8/14 | 도메인 3/4 +[04:47:54] 온라인 8/14 | 도메인 3/4 +[04:48:12] 온라인 8/14 | 도메인 3/4 +[04:48:49] 온라인 8/14 | 도메인 3/4 +[04:49:02] 온라인 8/14 | 도메인 3/4 +[04:49:27] 온라인 8/14 | 도메인 3/4 +[04:50:05] 온라인 8/14 | 도메인 3/4 +[04:50:11] 온라인 8/14 | 도메인 3/4 +[04:50:43] 온라인 8/14 | 도메인 3/4 +[04:51:18] 온라인 8/14 | 도메인 3/4 +[04:51:21] 온라인 8/14 | 도메인 3/4 +[04:52:00] 온라인 8/14 | 도메인 3/4 +[04:52:26] 온라인 8/14 | 도메인 3/4 +[04:52:38] 온라인 8/14 | 도메인 3/4 +[04:53:21] 온라인 8/14 | 도메인 3/4 +[04:53:35] 온라인 8/14 | 도메인 3/4 +[04:53:59] 온라인 8/14 | 도메인 3/4 +[04:54:37] 온라인 8/14 | 도메인 3/4 +[04:54:43] 온라인 8/14 | 도메인 3/4 +[04:55:15] 온라인 8/14 | 도메인 3/4 +[04:55:51] 온라인 8/14 | 도메인 3/4 +[04:55:54] 온라인 8/14 | 도메인 3/4 +[04:56:32] 온라인 8/14 | 도메인 3/4 +[04:56:59] 온라인 8/14 | 도메인 3/4 +[04:57:10] 온라인 8/14 | 도메인 3/4 +[04:57:48] 온라인 8/14 | 도메인 3/4 +[04:58:08] 온라인 8/14 | 도메인 3/4 +[04:58:26] 온라인 8/14 | 도메인 3/4 +[04:59:04] 온라인 8/14 | 도메인 3/4 +[04:59:16] 온라인 8/14 | 도메인 3/4 +[04:59:42] 온라인 8/14 | 도메인 3/4 +[05:00:20] 온라인 8/14 | 도메인 3/4 +[05:00:24] 온라인 8/14 | 도메인 3/4 +[05:00:59] 온라인 8/14 | 도메인 3/4 +[05:01:32] 온라인 8/14 | 도메인 3/4 +[05:01:37] 온라인 8/14 | 도메인 3/4 +[05:02:15] 온라인 8/14 | 도메인 3/4 +[05:02:40] 온라인 8/14 | 도메인 3/4 +[05:02:53] 온라인 8/14 | 도메인 3/4 +[05:03:31] 온라인 8/14 | 도메인 3/4 +[05:03:49] 온라인 8/14 | 도메인 3/4 +[05:04:09] 온라인 8/14 | 도메인 3/4 +[05:04:48] 온라인 8/14 | 도메인 3/4 +[05:04:57] 온라인 8/14 | 도메인 3/4 +[05:05:26] 온라인 8/14 | 도메인 3/4 +[05:06:04] 온라인 8/14 | 도메인 3/4 +[05:06:05] 온라인 8/14 | 도메인 3/4 +[05:06:44] 온라인 8/14 | 도메인 3/4 +[05:07:14] 온라인 8/14 | 도메인 3/4 +[05:07:22] 온라인 8/14 | 도메인 3/4 +[05:08:00] 온라인 8/14 | 도메인 3/4 +[05:08:23] 온라인 8/14 | 도메인 3/4 +[05:08:38] 온라인 8/14 | 도메인 3/4 +[05:09:16] 온라인 8/14 | 도메인 3/4 +[05:09:31] 온라인 8/14 | 도메인 3/4 +[05:09:54] 온라인 8/14 | 도메인 3/4 +[05:10:32] 온라인 8/14 | 도메인 3/4 +[05:10:39] 온라인 8/14 | 도메인 3/4 +[05:11:10] 온라인 8/14 | 도메인 3/4 +[05:11:47] 온라인 8/14 | 도메인 3/4 +[05:11:48] 온라인 8/14 | 도메인 3/4 +[05:12:27] 온라인 8/14 | 도메인 3/4 +[05:12:55] 온라인 8/14 | 도메인 3/4 +[05:13:05] 온라인 8/14 | 도메인 3/4 +[05:13:43] 온라인 8/14 | 도메인 3/4 +[05:14:04] 온라인 8/14 | 도메인 3/4 +[05:14:21] 온라인 8/14 | 도메인 3/4 +[05:14:59] 온라인 8/14 | 도메인 3/4 +[05:15:12] 온라인 8/14 | 도메인 3/4 +[05:15:38] 온라인 8/14 | 도메인 3/4 +[05:16:16] 온라인 8/14 | 도메인 3/4 +[05:16:20] 온라인 8/14 | 도메인 3/4 +[05:16:54] 온라인 8/14 | 도메인 3/4 +[05:17:28] 온라인 8/14 | 도메인 3/4 +[05:17:32] 온라인 8/14 | 도메인 3/4 +[05:18:11] 온라인 8/14 | 도메인 3/4 +[05:18:37] 온라인 8/14 | 도메인 3/4 +[05:18:49] 온라인 8/14 | 도메인 3/4 +[05:19:27] 온라인 8/14 | 도메인 3/4 +[05:19:45] 온라인 8/14 | 도메인 3/4 +[05:20:06] 온라인 8/14 | 도메인 3/4 +[05:20:44] 온라인 8/14 | 도메인 3/4 +[05:20:54] 온라인 8/14 | 도메인 3/4 +[05:21:22] 온라인 8/14 | 도메인 3/4 +[05:22:00] 온라인 8/14 | 도메인 3/4 +[05:22:01] 온라인 8/14 | 도메인 3/4 +[05:22:39] 온라인 8/14 | 도메인 3/4 +[05:23:10] 온라인 8/14 | 도메인 3/4 +[05:23:21] 온라인 8/14 | 도메인 3/4 +[05:23:59] 온라인 8/14 | 도메인 3/4 +[05:24:18] 온라인 8/14 | 도메인 3/4 +[05:24:38] 온라인 8/14 | 도메인 3/4 +[05:25:15] 온라인 8/14 | 도메인 3/4 +[05:25:27] 온라인 8/14 | 도메인 3/4 +[05:25:54] 온라인 8/14 | 도메인 3/4 +[05:26:31] 온라인 8/14 | 도메인 3/4 +[05:26:35] 온라인 8/14 | 도메인 3/4 +[05:27:10] 온라인 8/14 | 도메인 3/4 +[05:27:42] 온라인 8/14 | 도메인 3/4 +[05:27:48] 온라인 8/14 | 도메인 3/4 +[05:28:27] 온라인 8/14 | 도메인 3/4 +[05:28:51] 온라인 8/14 | 도메인 3/4 +[05:29:05] 온라인 8/14 | 도메인 3/4 +[05:29:42] 온라인 8/14 | 도메인 3/4 +[05:29:59] 온라인 8/14 | 도메인 3/4 +[05:30:21] 온라인 8/14 | 도메인 3/4 +[05:30:59] 온라인 8/14 | 도메인 3/4 +[05:31:08] 온라인 8/14 | 도메인 3/4 +[05:31:37] 온라인 8/14 | 도메인 3/4 +[05:32:15] 온라인 8/14 | 도메인 3/4 +[05:32:15] 온라인 8/14 | 도메인 3/4 +[05:32:54] 온라인 8/14 | 도메인 3/4 +[05:33:24] 온라인 8/14 | 도메인 3/4 +[05:33:32] 온라인 8/14 | 도메인 3/4 +[05:34:11] 온라인 8/14 | 도메인 3/4 +[05:34:33] 온라인 8/14 | 도메인 3/4 +[05:34:49] 온라인 8/14 | 도메인 3/4 +[05:35:27] 온라인 8/14 | 도메인 3/4 +[05:35:41] 온라인 8/14 | 도메인 3/4 +[05:36:05] 온라인 8/14 | 도메인 3/4 +[05:36:43] 온라인 8/14 | 도메인 3/4 +[05:36:49] 온라인 8/14 | 도메인 3/4 +[05:37:22] 온라인 8/14 | 도메인 3/4 +[05:37:57] 온라인 8/14 | 도메인 3/4 +[05:38:01] 온라인 8/14 | 도메인 3/4 +[05:38:39] 온라인 8/14 | 도메인 3/4 +[05:39:06] 온라인 8/14 | 도메인 3/4 +[05:39:18] 온라인 8/14 | 도메인 3/4 +[05:39:56] 온라인 8/14 | 도메인 3/4 +[05:40:14] 온라인 8/14 | 도메인 3/4 +[05:40:34] 온라인 8/14 | 도메인 3/4 +[05:41:13] 온라인 8/14 | 도메인 3/4 +[05:41:23] 온라인 8/14 | 도메인 3/4 +[05:41:52] 온라인 8/14 | 도메인 3/4 +[05:42:30] 온라인 8/14 | 도메인 3/4 +[05:42:31] 온라인 8/14 | 도메인 3/4 +[05:43:09] 온라인 8/14 | 도메인 3/4 +[05:43:39] 온라인 8/14 | 도메인 3/4 +[05:43:48] 온라인 8/14 | 도메인 3/4 +[05:44:26] 온라인 8/14 | 도메인 3/4 +[05:44:47] 온라인 8/14 | 도메인 3/4 +[05:45:04] 온라인 8/14 | 도메인 3/4 +[05:45:43] 온라인 8/14 | 도메인 3/4 +[05:45:56] 온라인 8/14 | 도메인 3/4 +[05:46:21] 온라인 8/14 | 도메인 3/4 +[05:47:00] 온라인 8/14 | 도메인 3/4 +[05:47:04] 온라인 8/14 | 도메인 3/4 +[05:47:38] 온라인 8/14 | 도메인 3/4 +[05:48:12] 온라인 8/14 | 도메인 3/4 +[05:48:17] 온라인 8/14 | 도메인 3/4 +[05:48:55] 온라인 8/14 | 도메인 3/4 +[05:49:20] 온라인 8/14 | 도메인 3/4 +[05:49:33] 온라인 8/14 | 도메인 3/4 +[05:50:11] 온라인 8/14 | 도메인 3/4 +[05:50:28] 온라인 8/14 | 도메인 3/4 +[05:50:48] 온라인 8/14 | 도메인 3/4 +[05:51:26] 온라인 8/14 | 도메인 3/4 +[05:51:36] 온라인 8/14 | 도메인 3/4 +[05:52:04] 온라인 8/14 | 도메인 3/4 +[05:52:44] 온라인 8/14 | 도메인 3/4 +[05:52:42] 온라인 8/14 | 도메인 3/4 +[05:53:22] 온라인 8/14 | 도메인 3/4 +[05:53:52] 온라인 8/14 | 도메인 3/4 +[05:54:00] 온라인 8/14 | 도메인 3/4 +[05:54:38] 온라인 8/14 | 도메인 3/4 +[05:55:00] 온라인 8/14 | 도메인 3/4 +[05:55:17] 온라인 8/14 | 도메인 3/4 +[05:55:54] 온라인 8/14 | 도메인 3/4 +[05:56:08] 온라인 8/14 | 도메인 3/4 +[05:56:32] 온라인 8/14 | 도메인 3/4 +[05:57:10] 온라인 8/14 | 도메인 3/4 +[05:57:17] 온라인 8/14 | 도메인 3/4 +[05:57:49] 온라인 8/14 | 도메인 3/4 +[05:58:24] 온라인 8/14 | 도메인 3/4 +[05:58:27] 온라인 8/14 | 도메인 3/4 +[05:59:05] 온라인 8/14 | 도메인 3/4 +[05:59:32] 온라인 8/14 | 도메인 3/4 +[05:59:43] 온라인 8/14 | 도메인 3/4 +[06:00:22] 온라인 8/14 | 도메인 3/4 +[06:00:41] 온라인 8/14 | 도메인 3/4 +[06:01:00] 온라인 8/14 | 도메인 3/4 +[06:01:38] 온라인 8/14 | 도메인 3/4 +[06:01:49] 온라인 8/14 | 도메인 3/4 +[06:02:16] 온라인 8/14 | 도메인 3/4 +[06:02:55] 온라인 8/14 | 도메인 3/4 +[06:02:57] 온라인 8/14 | 도메인 3/4 +[06:03:34] 온라인 8/14 | 도메인 3/4 +[06:04:05] 온라인 8/14 | 도메인 3/4 +[06:04:12] 온라인 8/14 | 도메인 3/4 +[06:04:51] 온라인 8/14 | 도메인 3/4 +[06:05:13] 온라인 8/14 | 도메인 3/4 +[06:05:28] 온라인 8/14 | 도메인 3/4 +[06:06:07] 온라인 8/14 | 도메인 3/4 +[06:06:22] 온라인 8/14 | 도메인 3/4 +[06:06:45] 온라인 8/14 | 도메인 3/4 +[06:07:23] 온라인 8/14 | 도메인 3/4 +[06:07:30] 온라인 8/14 | 도메인 3/4 +[06:08:02] 온라인 8/14 | 도메인 3/4 +[06:08:37] 온라인 8/14 | 도메인 3/4 +[06:08:40] 온라인 8/14 | 도메인 3/4 +[06:09:19] 온라인 8/14 | 도메인 3/4 +[06:09:46] 온라인 8/14 | 도메인 3/4 +[06:09:56] 온라인 8/14 | 도메인 3/4 +[06:10:35] 온라인 8/14 | 도메인 3/4 +[06:10:54] 온라인 8/14 | 도메인 3/4 +[06:11:12] 온라인 8/14 | 도메인 3/4 +[06:11:50] 온라인 8/14 | 도메인 3/4 +[06:12:03] 온라인 8/14 | 도메인 3/4 +[06:12:29] 온라인 8/14 | 도메인 3/4 +[06:13:07] 온라인 8/14 | 도메인 3/4 +[06:13:11] 온라인 8/14 | 도메인 3/4 +[06:13:46] 온라인 8/14 | 도메인 3/4 +[06:14:18] 온라인 8/14 | 도메인 3/4 +[06:14:24] 온라인 8/14 | 도메인 3/4 +[06:15:02] 온라인 8/14 | 도메인 3/4 +[06:15:27] 온라인 8/14 | 도메인 3/4 +[06:15:40] 온라인 8/14 | 도메인 3/4 +[06:16:17] 온라인 8/14 | 도메인 3/4 +[06:16:35] 온라인 8/14 | 도메인 3/4 +[06:16:55] 온라인 8/14 | 도메인 3/4 +[06:17:33] 온라인 8/14 | 도메인 3/4 +[06:17:44] 온라인 8/14 | 도메인 3/4 +[06:18:11] 온라인 8/14 | 도메인 3/4 +[06:18:49] 온라인 8/14 | 도메인 3/4 +[06:18:52] 온라인 8/14 | 도메인 3/4 +[06:19:27] 온라인 8/14 | 도메인 3/4 +[06:19:59] 온라인 8/14 | 도메인 3/4 +[06:20:05] 온라인 8/14 | 도메인 3/4 +[06:20:43] 온라인 8/14 | 도메인 3/4 +[06:21:08] 온라인 8/14 | 도메인 3/4 +[06:21:21] 온라인 8/14 | 도메인 3/4 +[06:21:59] 온라인 8/14 | 도메인 3/4 +[06:22:16] 온라인 8/14 | 도메인 3/4 +[06:22:38] 온라인 8/14 | 도메인 3/4 +[06:23:16] 온라인 8/14 | 도메인 3/4 +[06:23:24] 온라인 8/14 | 도메인 3/4 +[06:23:55] 온라인 8/14 | 도메인 3/4 +[06:24:32] 온라인 8/14 | 도메인 3/4 +[06:24:34] 온라인 8/14 | 도메인 3/4 +[06:25:12] 온라인 8/14 | 도메인 3/4 +[06:25:40] 온라인 8/14 | 도메인 3/4 +[06:25:49] 온라인 8/14 | 도메인 3/4 +[06:26:28] 온라인 8/14 | 도메인 3/4 +[06:26:49] 온라인 8/14 | 도메인 3/4 +[06:27:06] 온라인 8/14 | 도메인 3/4 +[06:27:44] 온라인 8/14 | 도메인 3/4 +[06:27:57] 온라인 8/14 | 도메인 3/4 +[06:28:22] 온라인 8/14 | 도메인 3/4 +[06:29:00] 온라인 8/14 | 도메인 3/4 +[06:29:05] 온라인 8/14 | 도메인 3/4 +[06:29:39] 온라인 8/14 | 도메인 3/4 +[06:30:12] 온라인 8/14 | 도메인 3/4 +[06:30:17] 온라인 8/14 | 도메인 3/4 +[06:30:55] 온라인 8/14 | 도메인 3/4 +[06:31:21] 온라인 8/14 | 도메인 3/4 +[06:31:33] 온라인 8/14 | 도메인 3/4 +[06:32:11] 온라인 8/14 | 도메인 3/4 +[06:32:29] 온라인 8/14 | 도메인 3/4 +[06:32:49] 온라인 8/14 | 도메인 3/4 +[06:33:27] 온라인 8/14 | 도메인 3/4 +[06:33:41] 온라인 8/14 | 도메인 3/4 +[06:34:06] 온라인 8/14 | 도메인 3/4 +[06:34:45] 온라인 8/14 | 도메인 3/4 +[06:34:48] 온라인 8/14 | 도메인 3/4 +[06:35:28] 온라인 8/14 | 도메인 3/4 +[06:36:00] 온라인 8/14 | 도메인 3/4 +[06:36:06] 온라인 8/14 | 도메인 3/4 +[06:36:44] 온라인 8/14 | 도메인 3/4 +[06:37:08] 온라인 8/14 | 도메인 3/4 +[06:37:21] 온라인 8/14 | 도메인 3/4 +[06:37:59] 온라인 8/14 | 도메인 3/4 +[06:38:16] 온라인 8/14 | 도메인 3/4 +[06:38:38] 온라인 8/14 | 도메인 3/4 +[06:39:16] 온라인 8/14 | 도메인 3/4 +[06:39:24] 온라인 8/14 | 도메인 3/4 +[06:39:54] 온라인 8/14 | 도메인 3/4 +[06:40:32] 온라인 8/14 | 도메인 3/4 +[06:40:32] 온라인 8/14 | 도메인 3/4 +[06:41:11] 온라인 8/14 | 도메인 3/4 +[06:41:41] 온라인 8/14 | 도메인 3/4 +[06:41:49] 온라인 8/14 | 도메인 3/4 +[06:42:27] 온라인 8/14 | 도메인 3/4 +[06:42:54] 온라인 8/14 | 도메인 3/4 +[06:43:06] 온라인 8/14 | 도메인 3/4 +[06:43:45] 온라인 8/14 | 도메인 3/4 +[06:44:02] 온라인 8/14 | 도메인 3/4 +[06:44:28] 온라인 8/14 | 도메인 3/4 +[06:45:06] 온라인 8/14 | 도메인 3/4 +[06:45:11] 온라인 8/14 | 도메인 3/4 +[06:45:45] 온라인 8/14 | 도메인 3/4 +[06:46:18] 온라인 8/14 | 도메인 3/4 +[06:46:23] 온라인 8/14 | 도메인 3/4 +[06:47:02] 온라인 8/14 | 도메인 3/4 +[06:47:26] 온라인 8/14 | 도메인 3/4 +[06:47:40] 온라인 8/14 | 도메인 3/4 +[06:48:18] 온라인 8/14 | 도메인 3/4 +[06:48:35] 온라인 8/14 | 도메인 3/4 +[06:48:55] 온라인 8/14 | 도메인 3/4 +[06:49:33] 온라인 8/14 | 도메인 3/4 +[06:49:43] 온라인 8/14 | 도메인 3/4 +[06:50:12] 온라인 8/14 | 도메인 3/4 +[06:50:51] 온라인 8/14 | 도메인 3/4 +[06:50:51] 온라인 8/14 | 도메인 3/4 +[06:51:30] 온라인 8/14 | 도메인 3/4 +[06:52:00] 온라인 8/14 | 도메인 3/4 +[06:52:08] 온라인 8/14 | 도메인 3/4 +[06:52:47] 온라인 8/14 | 도메인 3/4 +[06:53:08] 온라인 8/14 | 도메인 3/4 +[06:53:25] 온라인 8/14 | 도메인 3/4 +[06:54:03] 온라인 8/14 | 도메인 3/4 +[06:54:17] 온라인 8/14 | 도메인 3/4 +[06:54:41] 온라인 8/14 | 도메인 3/4 +[06:55:19] 온라인 8/14 | 도메인 3/4 +[06:55:25] 온라인 8/14 | 도메인 3/4 +[06:55:58] 온라인 8/14 | 도메인 3/4 +[06:56:33] 온라인 8/14 | 도메인 3/4 +[06:56:36] 온라인 8/14 | 도메인 3/4 +[06:57:15] 온라인 8/14 | 도메인 3/4 +[06:57:41] 온라인 8/14 | 도메인 3/4 +[06:57:52] 온라인 8/14 | 도메인 3/4 +[06:58:31] 온라인 8/14 | 도메인 3/4 +[06:58:49] 온라인 8/14 | 도메인 3/4 +[06:59:09] 온라인 8/14 | 도메인 3/4 +[06:59:47] 온라인 8/14 | 도메인 3/4 +[06:59:57] 온라인 8/14 | 도메인 3/4 +[07:00:30] 온라인 8/14 | 도메인 3/4 +[07:01:07] 온라인 8/14 | 도메인 3/4 +[07:01:09] 온라인 8/14 | 도메인 3/4 +[07:01:45] 온라인 8/14 | 도메인 3/4 +[07:02:16] 온라인 8/14 | 도메인 3/4 +[07:02:23] 온라인 8/14 | 도메인 3/4 +[07:03:01] 온라인 8/14 | 도메인 3/4 +[07:03:28] 온라인 8/14 | 도메인 3/4 +[07:03:43] 온라인 8/14 | 도메인 3/4 +[07:04:20] 온라인 8/14 | 도메인 3/4 +[07:04:40] 온라인 8/14 | 도메인 3/4 +[07:04:58] 온라인 8/14 | 도메인 3/4 +[07:05:36] 온라인 8/14 | 도메인 3/4 +[07:05:49] 온라인 8/14 | 도메인 3/4 +[07:06:14] 온라인 8/14 | 도메인 3/4 +[07:06:52] 온라인 8/14 | 도메인 3/4 +[07:07:00] 온라인 8/14 | 도메인 3/4 +[07:07:29] 온라인 8/14 | 도메인 3/4 +[07:08:07] 온라인 8/14 | 도메인 3/4 +[07:08:08] 온라인 8/14 | 도메인 3/4 +[07:08:45] 온라인 8/14 | 도메인 3/4 +[07:09:16] 온라인 8/14 | 도메인 3/4 +[07:09:23] 온라인 8/14 | 도메인 3/4 +[07:10:02] 온라인 8/14 | 도메인 3/4 +[07:10:24] 온라인 8/14 | 도메인 3/4 +[07:10:39] 온라인 8/14 | 도메인 3/4 +[07:11:17] 온라인 8/14 | 도메인 3/4 +[07:11:32] 온라인 8/14 | 도메인 3/4 +[07:11:56] 온라인 8/14 | 도메인 3/4 +[07:12:34] 온라인 8/14 | 도메인 3/4 +[07:12:41] 온라인 8/14 | 도메인 3/4 +[07:13:12] 온라인 8/14 | 도메인 3/4 +[07:13:48] 온라인 8/14 | 도메인 3/4 +[07:13:51] 온라인 8/14 | 도메인 3/4 +[07:14:28] 온라인 8/14 | 도메인 3/4 +[07:14:57] 온라인 8/14 | 도메인 3/4 +[07:15:06] 온라인 8/14 | 도메인 3/4 +[07:15:43] 온라인 8/14 | 도메인 3/4 +[07:16:05] 온라인 8/14 | 도메인 3/4 +[07:16:21] 온라인 8/14 | 도메인 3/4 +[07:16:59] 온라인 8/14 | 도메인 3/4 +[07:17:13] 온라인 8/14 | 도메인 3/4 +[07:17:37] 온라인 8/14 | 도메인 3/4 +[07:18:15] 온라인 8/14 | 도메인 3/4 +[07:18:22] 온라인 8/14 | 도메인 3/4 +[07:18:53] 온라인 8/14 | 도메인 3/4 +[07:19:29] 온라인 8/14 | 도메인 3/4 +[07:19:30] 온라인 8/14 | 도메인 3/4 +[07:20:12] 온라인 8/14 | 도메인 3/4 +[07:20:41] 온라인 8/14 | 도메인 3/4 +[07:20:54] 온라인 8/14 | 도메인 3/4 +[07:21:32] 온라인 8/14 | 도메인 3/4 +[07:21:50] 온라인 8/14 | 도메인 3/4 +[07:22:09] 온라인 8/14 | 도메인 3/4 +[07:22:47] 온라인 8/14 | 도메인 3/4 +[07:22:58] 온라인 8/14 | 도메인 3/4 +[07:23:26] 온라인 8/14 | 도메인 3/4 +[07:24:44] 온라인 8/14 | 도메인 3/4 +[07:25:14] 온라인 8/14 | 도메인 3/4 diff --git a/health_check.py b/health_check.py new file mode 100644 index 0000000..de1d241 --- /dev/null +++ b/health_check.py @@ -0,0 +1,432 @@ +#!/usr/bin/env python3 +"""작은도시 인프라 현황 v5 — 도메인 계층 + 에이전트/서브도메인 2탭""" +import json, subprocess, re +from pathlib import Path +from datetime import datetime, timezone, timedelta + +KST = timezone(timedelta(hours=9)) +STATUS_FILE = Path(__file__).parent / "health.json" + +PC_SPECS = { + "macmini": {"name": "맥미니 M4 Pro", "emoji": "🖥️", "spec": "Apple M4 Pro · 64GB · 통합 GPU", "dns": "pinksky.kr"}, + "mainpc": {"name": "메인컴 (PS-i14700K)", "emoji": "🖥️", "spec": "Intel Core i7-14700K · 96GB · RTX 3090 24GB", "dns": "mainpc-wsl.pinksky.kr"}, + "subpc": {"name": "보조컴 (MH-3900x)", "emoji": "🖥️", "spec": "AMD Ryzen 9 3900X · 32GB · RTX 3080 12GB", "dns": "subpc-wsl.pinksky.kr"}, + "officepc": {"name": "서버컴 (gw-ps-5600)", "emoji": "🖥️", "spec": "Intel Core i7-14700K · 96GB · RTX 3090", "dns": "gwenc.kr"}, + "nas_home": {"name": "집 NAS (mh-nas)", "emoji": "🗄️", "spec": "Synology DS418+", "dns": "minicity.kr"}, + "nas_office": {"name": "회사 NAS (gwenc-nas2)", "emoji": "🗄️", "spec": "Synology", "dns": ""}, + "nas_backup": {"name": "백업 NAS (ps-bk-nas)", "emoji": "🗄️", "spec": "14TB HDD", "dns": ""}, + "router_home": {"name": "집 공유기", "emoji": "📡", "spec": "아이피타임 AX8004BCM", "dns": "pinksky.iptime.org"}, + "router_apt": {"name": "아지트 공유기", "emoji": "📡", "spec": "TP-LINK Archer BE550", "dns": "pinksky.kr"}, + "router_office": {"name": "회사 공유기", "emoji": "📡", "spec": "TP-LINK AX18000", "dns": "gwenc.kr"}, +} + +# ===== 기본 체크 함수 ===== +def http_check(url, timeout=5): + try: + r = subprocess.run( + ["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}:%{time_total}", + url, "--max-time", str(timeout)], + capture_output=True, text=True, timeout=timeout+2) + parts = r.stdout.strip().split(":") + code = parts[0] if parts else "000" + latency = round(float(parts[1])*1000, 0) if len(parts) > 1 and parts[1] else None + return {"status": "online" if code.startswith(("1","2","3","4")) else "error", + "detail": f"HTTP {code}", "latency_ms": latency} + except: return {"status": "offline", "detail": "timeout", "latency_ms": None} + +def ssh_check(host, timeout=8): + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", + host, "echo alive"], + capture_output=True, text=True, timeout=timeout) + alive = r.returncode == 0 and "alive" in r.stdout + return {"status": "online" if alive else "offline", + "detail": "alive" if alive else r.stderr.strip()[:80]} + except: return {"status": "offline", "detail": "timeout"} + +def tailscale_ping(host, timeout=8): + try: + r = subprocess.run( + ["tailscale", "ping", "--c", "3", host], + capture_output=True, text=True, timeout=timeout) + out = r.stdout + r.stderr + alive = "pong" in out or "is local" in out + return {"status": "online" if alive else "offline", + "detail": "" if alive else "no pong"} + except: return {"status": "offline", "detail": "timeout"} + +def tcp_port_check(host, port, timeout=5): + try: + r = subprocess.run( + ["nc", "-z", "-w", str(timeout), host, str(port)], + capture_output=True, text=True, timeout=timeout+2) + alive = r.returncode == 0 + return {"status": "online" if alive else "offline", + "detail": "tcp open" if alive else "no response"} + except: return {"status": "offline", "detail": "timeout"} + +def get_local_ts_ip(): + try: + r = subprocess.run(["tailscale", "ip", "-4"], capture_output=True, text=True, timeout=5) + return r.stdout.strip() + except: return "?" + +def get_remote_ts(via): + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", via, "tailscale ip -4"], + capture_output=True, text=True, timeout=8) + return r.stdout.strip() if r.returncode == 0 else "?" + except: return "?" + +def get_version(label): + try: + if label == "openclaw": + r = subprocess.run(["openclaw", "--version"], capture_output=True, text=True, timeout=5) + v = r.stdout.strip().replace("OpenClaw ", "") + v = re.sub(r'\s+\([^)]+\)', '', v).strip() + return v if v else "?" + elif label == "hermes": + r = subprocess.run([ + "/Users/pinksky/.hermes/hermes-agent/venv/bin/python", + "-m", "hermes_cli.main", "--version"], + capture_output=True, text=True, timeout=5) + m = re.search(r'v[\d.]+', r.stdout.strip()) + return m.group(0) if m else "?" + except: return "?" + +def get_remote_hermes_version(via): + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", via, + "export PATH=\"$HOME/.local/bin:$PATH\"; hermes --version"], + capture_output=True, text=True, timeout=8) + m = re.search(r'v[\d.]+', r.stdout.strip()) + return m.group(0) if m else "?" + except: return "?" + +def proc_detail(pattern, engine_name="?"): + result = {"status": "offline", "version": "?", "uptime": "?", "proc_count": 0, + "engine": engine_name, "detail": "not running"} + try: + r = subprocess.run(["pgrep", "-f", pattern], capture_output=True, text=True, timeout=5) + pids = [p.strip() for p in r.stdout.strip().split("\n") if p.strip()] + if pids: + result["status"] = "online" + result["proc_count"] = len(pids) + try: + u = subprocess.run(["ps", "-p", pids[0], "-o", "etime="], + capture_output=True, text=True, timeout=5) + result["uptime"] = u.stdout.strip() + except: pass + result["detail"] = f"{result['uptime']} · {result['proc_count']}프로세스" + except: pass + return result + +def remote_proc(via, pattern, engine_name="?"): + result = {"status": "offline", "version": "?", "uptime": "?", "proc_count": 0, + "engine": engine_name, "detail": "not running"} + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", + via, f"ps aux | grep '{pattern}' | grep -v grep || true"], + capture_output=True, text=True, timeout=8) + lines = [l for l in r.stdout.strip().split("\n") if l.strip()] + if lines: + result["status"] = "online" + result["proc_count"] = len(lines) + result["detail"] = f"{result['proc_count']}프로세스" + except: pass + return result + +# --- NAS storage info --- +NAS_CONFIGS = { + "nas_home": { + "name": "집 NAS (mh-nas)", "model": "Synology DS418+", "os": "DSM 7.2", + "ssh_host": "mh-nas", + "volumes": [{"mount": "/volume1", "label": "데이터"}, {"mount": "/volume2", "label": "백업"}] + }, + "nas_office": { + "name": "회사 NAS (gwenc-nas2)", "model": "Synology DS923+", "os": "DSM 7.2", + "ssh_host": "100.105.95.19", + "ssh_port": 55, + "ssh_user": "psbot", + "ssh_pass": "@@Mini3388", + "volumes": [{"mount": "/volume1", "label": "메인"}, {"mount": "/volume3", "label": "SSD캐시"}, {"mount": "/volume2", "label": "대용량스토리지"}] + }, + "nas_backup": { + "name": "백업 NAS (ps-bk-nas)", "model": "Synology", "os": "DSM 7.x", + "ssh_host": "100.83.176.55", + "ssh_port": 55, + "ssh_user": "psbot", + "ssh_pass": "@@Mini3388", + "volumes": [{"mount": "/volume1", "label": "메인백업"}, {"mount": "/volume2", "label": "대용량백업"}] + } +} + +def get_nas_storage(nas_key): + cfg = NAS_CONFIGS[nas_key] + result = {"name": cfg["name"], "model": cfg["model"], "os": cfg["os"], + "status": "offline", "volumes": [], "detail": "not checked"} + host = cfg.get("ssh_host") + if not host: + return result + port = cfg.get("ssh_port", 55) + user = cfg.get("ssh_user", "psbot") + passwd = cfg.get("ssh_pass", "") + try: + mounts = " ".join(v["mount"] for v in cfg["volumes"]) + ssh_cmd = f"ssh -p {port} -o ConnectTimeout=5 -o StrictHostKeyChecking=no {user}@{host} 'df -h {mounts}'" + if passwd: + full_cmd = f"sshpass -p {passwd!r} {ssh_cmd}" + else: + full_cmd = ssh_cmd + r = subprocess.run(full_cmd, shell=True, capture_output=True, text=True, timeout=10) + if r.returncode != 0: + result["detail"] = r.stderr.strip()[:80] + return result + result["status"] = "online" + result["detail"] = "alive" + volumes = [] + for line in r.stdout.strip().split("\n")[1:]: + parts = line.split() + if len(parts) >= 6: + mount = parts[5] + label = mount + for v in cfg["volumes"]: + if v["mount"] == mount: + label = v["label"] + break + volumes.append({ + "mount": mount, "label": label, + "total": parts[1], "used": parts[2], + "free": parts[3], "pct": parts[4] + }) + result["volumes"] = volumes + except Exception as e: + result["detail"] = str(e)[:80] + return result + +# --- Proxmox VM info (서버컴 Hyper-V 위) --- +PROXMOX_CFG = { + "host": { + "name": "서버컴 (gw-ps-5600)", "model": "ASRock Z790M-ITX WiFi", + "cpu": "Intel Core i7-14700K", "ram": "96GB", + "os": "Windows 11 Pro + Hyper-V", "role": "Hyper-V 호스트" + }, + "proxmox": { + "name": "Proxmox VE", "version": "8.x", + "os": "Debian 12 + Proxmox", + "cpu": "8 vCPU", "ram": "32GB", "storage": "1TB SSD", + "role": "Hyper-V 가상머신 · VM 호스팅" + }, + "vms": [ + {"name": "정환용 업무컴", "host": "gwenc.kr", "port": 13389, "emoji": "🖥️"}, + {"name": "주영용 업무컴", "host": "gwenc.kr", "port": 23389, "emoji": "🖥️"}, + {"name": "임시용 업무컴", "host": "gwenc.kr", "port": 43348, "emoji": "🖥️"}, + ] +} + +# ===== 메인 ===== +def run_checks(): + ts = datetime.now(KST) + ts_ip = get_local_ts_ip() + + # --- PC checks --- + mainpc_ssh = ssh_check("mainpc-win", 6) + mainpc_ts = get_remote_ts("mainpc-wsl") + subpc_ssh = ssh_check("subpc-wsl", 6) + subpc_ts = get_remote_ts("subpc-wsl") + office_pc = tcp_port_check("gwenc.kr", 33389, 5) + + # --- NAS checks --- + nas_mh = ssh_check("mh-nas", 6) + nas_gwenc2 = tailscale_ping("gwenc-nas2", 6) + nas_bk = tailscale_ping("ps-bk-nas", 6) + + # --- NAS storage info --- + nas_storage = {} + for nk in NAS_CONFIGS: + nas_storage[nk] = get_nas_storage(nk) + + # --- Proxmox host check (TCP RDP 포트) --- + proxmox_host = tcp_port_check("gwenc.kr", 33389, 5) + # --- Proxmox VE Web UI check --- + proxmox_ve = tcp_port_check("gwenc.kr", 18006, 5) + # --- VM RDP checks --- + vm_results = [] + for vm in PROXMOX_CFG.get("vms", []): + vm_results.append({**vm, **tcp_port_check(vm["host"], vm["port"], 5)}) + + # --- Agent checks --- + mimi = proc_detail("openclaw", "openclaw") + mimi["name"] = "미미" + mimi["emoji"] = "🦞" + mimi["version"] = get_version("openclaw") + + ruki = proc_detail("hermes", "hermes") + ruki["name"] = "루키" + ruki["emoji"] = "🌱" + ruki["version"] = get_version("hermes") + + pink = remote_proc("mainpc-wsl", "hermes", "hermes") + pink["name"] = "분홍" + pink["emoji"] = "🤖" + pink["version"] = get_remote_hermes_version("mainpc-wsl") + + sky = remote_proc("subpc-wsl", "hermes", "hermes") + sky["name"] = "하늘" + sky["emoji"] = "🤖" + sky["version"] = get_remote_hermes_version("subpc-wsl") + + # --- Subdomains --- + subdomains = [ + {"name": "wiki.pinksky.kr", "url": "https://wiki.pinksky.kr/", "group": "pinksky.kr", "desc": "MiniCITY 지식정원"}, + {"name": "openclaw.pinksky.kr", "url": "https://openclaw.pinksky.kr/", "group": "pinksky.kr", "desc": "OpenClaw 대시보드"}, + {"name": "agent.pinksky.kr", "url": "https://agent.pinksky.kr/", "group": "pinksky.kr", "desc": "인프라 현황판"}, + {"name": "search.pinksky.kr", "url": "https://search.pinksky.kr/search?q=test", "group": "pinksky.kr", "desc": "SearXNG 메타서치"}, + {"name": "erp.pinksky.kr", "url": "https://erp.pinksky.kr/", "group": "pinksky.kr", "desc": "공사관리 ERP"}, + {"name": "dify.pinksky.kr", "url": "https://dify.pinksky.kr/", "group": "pinksky.kr", "desc": "Dify 워크플로우"}, + {"name": "photo.pinksky.kr", "url": "https://photo.pinksky.kr/", "group": "pinksky.kr", "desc": "PhotoVault 자료정리"}, + {"name": "git.pinksky.kr", "url": "https://git.pinksky.kr/", "group": "pinksky.kr", "desc": "Gitea Git 서버"}, + {"name": "find.pinksky.kr", "url": "https://find.pinksky.kr/", "group": "pinksky.kr", "desc": "Everything 검색"}, + {"name": "gwenc.kr", "url": "https://gwenc.kr/", "group": "gwenc.kr", "desc": "회사 메인 사이트"}, + {"name": "minicity.kr", "url": "https://minicity.kr/", "group": "minicity.kr", "desc": "집 NAS 웹 UI"}, + ] + sub_results = [] + for s in subdomains: + chk = http_check(s["url"], 4) + sub_results.append({ + "name": s["name"], "group": s["group"], "desc": s["desc"], + "status": chk["status"], "detail": chk["detail"], "latency_ms": chk.get("latency_ms") + }) + + # --- Domain hierarchy --- + domains = { + "pinksky.kr": { + "domain": {"status": "online", "detail": f"{ts_ip}"}, + "pcs": { + "macmini": { + **PC_SPECS["macmini"], + "tailscale_ip": ts_ip, + "status": "online", "detail": "", + "agents": { + "mimi": {**mimi}, + "ruki": {**ruki}, + } + }, + "mainpc": { + **PC_SPECS["mainpc"], + "tailscale_ip": mainpc_ts, + "status": mainpc_ssh["status"], "detail": mainpc_ssh["detail"], + "agents": { + "pink": {**pink}, + } + }, + "subpc": { + **PC_SPECS["subpc"], + "tailscale_ip": subpc_ts, + "status": subpc_ssh["status"], "detail": subpc_ssh["detail"], + "agents": { + "sky": {**sky}, + } + } + } + }, + "minicity.kr": { + "domain": {"status": "online", "detail": "집 NAS/공유기"}, + "pcs": { + "nas_home": { + **PC_SPECS["nas_home"], + "tailscale_ip": "100.69.107.65", + "status": nas_mh["status"], "detail": nas_mh["detail"], + "agents": {} + }, + "router_home": { + **PC_SPECS["router_home"], + "tailscale_ip": "", + "status": "online", "detail": "DDNS · 원격관리 9090", + "agents": {} + } + } + }, + "gwenc.kr": { + "domain": {"status": office_pc["status"], "detail": office_pc["detail"]}, + "pcs": { + "officepc": { + **PC_SPECS["officepc"], + "tailscale_ip": "", + "status": office_pc["status"], "detail": office_pc["detail"], + "agents": {} + }, + "nas_office": { + **PC_SPECS["nas_office"], + "tailscale_ip": "100.105.95.19", + "status": nas_gwenc2["status"], "detail": nas_gwenc2["detail"], + "agents": {} + }, + "nas_backup": { + **PC_SPECS["nas_backup"], + "tailscale_ip": "100.83.176.55", + "status": nas_bk["status"], "detail": nas_bk["detail"], + "agents": {} + }, + "router_office": { + **PC_SPECS["router_office"], + "tailscale_ip": "", + "status": "online", "detail": "원격관리 9000/9443", + "agents": {} + } + } + } + } + + # --- Summary --- + all_items = [] + for d in domains.values(): + for pc in d["pcs"].values(): + all_items.append(pc) + for a in pc.get("agents", {}).values(): + all_items.append(a) + for s in sub_results: + all_items.append(s) + for vm in vm_results: + all_items.append(vm) + + online = sum(1 for x in all_items if x["status"] == "online") + offline = sum(1 for x in all_items if x["status"] == "offline") + + data = { + "subdomains": sub_results, + "domains": domains, + "nas_storage": nas_storage, + "proxmox": { + "host": { + **PROXMOX_CFG["host"], + "status": proxmox_host["status"], + "detail": proxmox_host["detail"] + }, + "proxmox": { + **PROXMOX_CFG["proxmox"], + "status": proxmox_ve["status"], + "detail": proxmox_ve["detail"] + }, + "vms": vm_results + }, + "summary": { + "total": len(all_items), + "online": online, + "offline": offline, + "domain_total": 3, + "domain_online": sum(1 for d in domains.values() if d["domain"]["status"] == "online") + }, + "timestamp": ts.isoformat(), + "timestamp_epoch": int(ts.timestamp()) + } + + STATUS_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False)) + print(f"[{ts.strftime('%H:%M:%S')}] Online {online}/{len(all_items)} · Domains {data['summary']['domain_online']}/3") + +if __name__ == "__main__": + run_checks() diff --git a/health_check.py.backup.20260429_2057 b/health_check.py.backup.20260429_2057 new file mode 100755 index 0000000..bda4543 --- /dev/null +++ b/health_check.py.backup.20260429_2057 @@ -0,0 +1,338 @@ +#!/usr/bin/env python3 +"""Agent Status Health Checker v6 — 메모리/VRAM 실시간 수집 + 사양/박스 구조""" +import json, subprocess, time, re +from pathlib import Path +from datetime import datetime, timezone, timedelta + +KST = timezone(timedelta(hours=9)) +STATUS_FILE = Path(__file__).parent / "health.json" + +# ===== 정적 사양 정보 ===== +PC_SPECS = { + "macmini": "M4 Pro · 64GB · 통합 GPU", + "mainpc": "Intel Core i7-14700K · 96GB · RTX 3090 24GB", + "subpc": "AMD Ryzen 9 3900X · 32GB · RTX 3080 12GB", +} + +# ===== 기본 체크 함수 ===== +def http_check(url, timeout=5): + try: + r = subprocess.run( + ["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}:%{time_total}", + url, "--max-time", str(timeout)], + capture_output=True, text=True, timeout=timeout+2) + parts = r.stdout.strip().split(":") + code = parts[0] if parts else "000" + return {"status": "online" if code.startswith(("2","3")) else "error", + "detail": f"HTTP {code}"} + except: return {"status": "offline", "detail": "timeout"} + +def ssh_check(host, timeout=8): + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", + host, "echo alive"], + capture_output=True, text=True, timeout=timeout) + alive = r.returncode == 0 and "alive" in r.stdout + return {"status": "online" if alive else "offline", + "detail": "alive" if alive else r.stderr.strip()[:80]} + except: return {"status": "offline", "detail": "timeout"} + +def tailscale_ping(host, timeout=8): + try: + r = subprocess.run( + ["tailscale", "ping", "--until", "3s", "--c", "1", host], + capture_output=True, text=True, timeout=timeout) + alive = "pong" in r.stdout or "is local" in r.stdout + return {"status": "online" if alive else "offline", + "detail": "" if alive else "no pong"} + except: return {"status": "offline", "detail": "timeout"} + +def proc_check(process, via=None): + try: + if via: + cmd = ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", + via, f"pgrep -f '{process}' || echo NOT_FOUND"] + else: + cmd = ["pgrep", "-f", process] + r = subprocess.run(cmd, capture_output=True, text=True, timeout=8) + out = r.stdout.strip() + alive = out not in ["NOT_FOUND", ""] and r.returncode == 0 + return {"status": "online" if alive else "offline", + "detail": f"PID {out[:20]}" if alive else "not running"} + except: return {"status": "offline", "detail": "error"} + +# ===== 상태 수집 ===== +def get_local_tailscale_ip(): + try: + r = subprocess.run(["tailscale", "ip", "-4"], capture_output=True, text=True, timeout=5) + return r.stdout.strip() + except: return "?" + +def get_remote_tailscale_ip(via): + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", + via, "tailscale ip -4"], + capture_output=True, text=True, timeout=8) + return r.stdout.strip() if r.returncode == 0 else "?" + except: return "?" + +def get_version(label): + try: + if label == "openclaw": + r = subprocess.run(["openclaw", "--version"], capture_output=True, text=True, timeout=5) + v = r.stdout.strip().replace("OpenClaw ", "") + v = re.sub(r'\s+\([^)]+\)', '', v).strip() + return v if v else "?" + elif label == "hermes": + r = subprocess.run([ + "/Users/pinksky/.hermes/hermes-agent/venv/bin/python", + "-m", "hermes_cli.main", "--version" + ], capture_output=True, text=True, timeout=5) + m = re.search(r'v[\d.]+', r.stdout.strip()) + return m.group(0) if m else "?" + except: return "?" + +def get_uptime(pid_str): + try: + r = subprocess.run(["ps", "-p", pid_str, "-o", "etime="], capture_output=True, text=True, timeout=5) + return r.stdout.strip() + except: return "?" + +def get_local_macos_memory(): + try: + r = subprocess.run(["sysctl", "-n", "hw.memsize"], capture_output=True, text=True, timeout=5) + total_gb = round(int(r.stdout.strip()) / (1024**3), 1) + r = subprocess.run(["vm_stat"], capture_output=True, text=True, timeout=5) + lines = r.stdout.strip().split("\n") + page_size = 16384 + total_pages = 0 + for line in lines: + m = re.search(r'Pages (\w+):\s+([0-9,]+)', line) + if m: + key, val = m.group(1).lower(), int(m.group(2).replace(",","")) + if key in ("active","inactive","wired","compressed"): + total_pages += val + used_gb = round(total_pages * page_size / (1024**3), 1) + return f"{used_gb}GB/{total_gb}GB" + except: return "?.?" + +def get_remote_memory(via): + result = {"sys": "?", "gpu": None} + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", + via, "free -m | awk '/Mem:/ {printf \"%.1f/%.1f\", ($2-$7)/1024, \$2/1024}'"], + capture_output=True, text=True, timeout=8) + out = r.stdout.strip() + if out and r.returncode == 0: + result["sys"] = f"{out}GB" + except: pass + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", + via, "nvidia-smi --query-gpu=memory.used,memory.total --format=csv,noheader,nounits"], + capture_output=True, text=True, timeout=8) + out = r.stdout.strip() + if out and r.returncode == 0: + parts = [x.strip() for x in out.split(",")] + if len(parts) >= 2: + u, t = float(parts[0]), float(parts[1]) + result["gpu"] = f"VRAM {round(u/1024,1)}GB/{round(t/1024,1)}GB" + except: pass + return result + +def proc_details(name_pattern, version_label=None, engine_name="?", via=None): + result = {"status": "offline", "version": "?", "uptime": "?", "proc_count": 0, + "engine": engine_name, "detail": "not running", "mem": None, "gpu": None} + try: + if via: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", + via, f"ps aux | grep '{name_pattern}' | grep -v grep | grep -v health_check || true"], + capture_output=True, text=True, timeout=8) + lines = [l for l in r.stdout.strip().split("\n") if l.strip()] + if lines: + result["status"] = "online" + result["proc_count"] = len(lines) + if version_label: + result["version"] = "?" # 원격 버전 체크는 복잡하므로 여기서는 생략 + mem_data = get_remote_memory(via) + result["mem"] = mem_data["sys"] + result["gpu"] = mem_data["gpu"] + result["detail"] = f"{result['proc_count']}프로세스" + else: + r = subprocess.run(["ps", "aux"], capture_output=True, text=True, timeout=5) + lines = [l for l in r.stdout.strip().split("\n") if name_pattern in l and "grep" not in l and "health_check" not in l] + if lines: + result["status"] = "online" + result["proc_count"] = len(lines) + first = lines[0].strip().split(None, 2) + if len(first) >= 2: + result["uptime"] = get_uptime(first[1]) + if version_label: + result["version"] = get_version(version_label) + result["mem"] = get_local_macos_memory() + result["detail"] = f"{result['uptime']} · {result['proc_count']}프로세스" + except: pass + return result + +# ===== 메인 ===== +def run_checks(): + ts = datetime.now(KST) + ts_ip = get_local_tailscale_ip() + + # ===== pinksky.kr (아지트) ===== + pinksky_domain = http_check("https://pinksky.kr/") + macmini_detail = f"{ts_ip} · pinksky.kr" + mainpc_ts = get_remote_tailscale_ip("mainpc-wsl") + + mimi = proc_details("openclaw-gateway", "openclaw", "openclaw") + ruki = proc_details("hermes", "hermes", "hermes") + mainpc = ssh_check("mainpc-win", 6) + pink_hermes = proc_details("hermes", engine_name="hermes", via="mainpc-wsl") + + pinksky = { + "domain": pinksky_domain, + "pcs": { + "macmini": { + "name": "맥미니 M4 Pro", "emoji": "🖥️", + "tailscale_ip": ts_ip, "dns": "pinksky.kr", + "status": "online", "detail": macmini_detail, + "spec": PC_SPECS["macmini"], + "agents": { + "mimi": { + "name": "미미", "emoji": "🦞", + **{k:v for k,v in mimi.items() if k not in ("status","detail")}, + "status": mimi["status"], "detail": mimi["detail"] + }, + "ruki": { + "name": "루키", "emoji": "🌱", + **{k:v for k,v in ruki.items() if k not in ("status","detail")}, + "status": ruki["status"], "detail": ruki["detail"] + } + } + }, + "mainpc": { + "name": "메인컴", "emoji": "🖥️", + "tailscale_ip": mainpc_ts, "dns": "mainpc-wsl.pinksky.kr", + **mainpc, + "spec": PC_SPECS["mainpc"], + "agents": { + "pink_hermes": { + "name": "분홍", "emoji": "🤖", + **{k:v for k,v in pink_hermes.items() if k not in ("status","detail")}, + "status": pink_hermes["status"], "detail": pink_hermes["detail"] + } + } + } + } + } + + # ===== minicity.kr (집 NAS) ===== + minicity_domain = http_check("https://minicity.kr/") + nas_pc = ssh_check("mh-nas", 6) + + minicity = { + "domain": minicity_domain, + "pcs": { + "nas": { + "name": "NAS (minicity)", "emoji": "🗄️", + **nas_pc, "agents": {} + } + } + } + + # ===== pinksky.iptime.org (집 DDNS / 보조컴) ===== + subpc_ts = get_remote_tailscale_ip("subpc-wsl") + subpc = ssh_check("subpc-wsl", 6) + sky_hermes = proc_details("hermes", engine_name="hermes", via="subpc-wsl") + + iptime = { + "domain": {"status": "online" if subpc["status"] == "online" else "error", "detail": "DDNS"}, + "pcs": { + "subpc": { + "name": "보조컴", "emoji": "🖥️", + "tailscale_ip": subpc_ts, "dns": "subpc-wsl.pinksky.kr", + **subpc, + "spec": PC_SPECS["subpc"], + "agents": { + "sky_hermes": { + "name": "하늘", "emoji": "🤖", + **{k:v for k,v in sky_hermes.items() if k not in ("status","detail")}, + "status": sky_hermes["status"], "detail": sky_hermes["detail"] + } + } + } + } + } + + # ===== gwenc.kr (회사) ===== + gwenc_domain = http_check("https://gwenc.kr/") + server5600 = tailscale_ping("gw-ps-5600", 6) + proxmox = tailscale_ping("proxmox-minicity", 6) + office_nas = tailscale_ping("gwenc-nas2", 6) + backup_nas = tailscale_ping("ps-bk-nas", 6) + office_pc = tailscale_ping("ps-i14700k-win", 6) + office_pc_wsl = tailscale_ping("ps-i14700k-wsl", 6) + + gwenc = { + "domain": gwenc_domain, + "pcs": { + "server5600": {"name": "서버컴 5600", "emoji": "🖥️", **server5600, "agents": {}}, + "proxmox": {"name": "Proxmox", "emoji": "🔶", **proxmox, "agents": {}}, + "office_nas": {"name": "회사 NAS", "emoji": "🗄️", **office_nas, "agents": {}}, + "backup_nas": {"name": "백업 NAS", "emoji": "🗄️", **backup_nas, "agents": {}}, + "office_pc": { + "name": "회사 메인PC", "emoji": "🖥️", **office_pc, + "agents": { + "office_pc_wsl": {"name": "회사 메인PC WSL", "emoji": "🖥️", **office_pc_wsl} + } + } + } + } + + # ===== 서브도메인 ===== + subdomains = [ + {"name": "wiki.pinksky.kr", "url": "https://wiki.pinksky.kr/", "group": "pinksky.kr", "desc": "MiniCITY 지식정원"}, + {"name": "openclaw.pinksky.kr", "url": "https://openclaw.pinksky.kr/", "group": "pinksky.kr", "desc": "OpenClaw 대시보드"}, + {"name": "agent.pinksky.kr", "url": "https://agent.pinksky.kr/", "group": "pinksky.kr", "desc": "에이전트 현황판"}, + {"name": "search.pinksky.kr", "url": "https://search.pinksky.kr/search?q=test", "group": "pinksky.kr", "desc": "SearXNG 메타서치"}, + {"name": "erp.pinksky.kr", "url": "https://erp.pinksky.kr/", "group": "pinksky.kr", "desc": "공사관리 ERP"}, + {"name": "dify.pinksky.kr", "url": "https://dify.pinksky.kr:8443/", "group": "pinksky.kr", "desc": "Dify 워크플로우"}, + {"name": "gwenc.kr", "url": "https://gwenc.kr/", "group": "gwenc.kr", "desc": "회사 메인 사이트"}, + {"name": "minicity.kr", "url": "https://minicity.kr/", "group": "minicity.kr", "desc": "집 NAS 웹 UI"}, + ] + subdomain_results = [{"name": sd["name"], **http_check(sd["url"], 4), "group": sd["group"], "desc": sd["desc"]} + for sd in subdomains] + + # ===== 요약 ===== + all_domains = {"pinksky.kr": pinksky, "minicity.kr": minicity, + "pinksky.iptime.org": iptime, "gwenc.kr": gwenc} + all_pcs = [] + for d in all_domains.values(): + for pc in d["pcs"].values(): + all_pcs.append(pc) + all_pcs.extend(pc["agents"].values()) + + online = sum(1 for p in all_pcs if p["status"] == "online") + total = len(all_pcs) + domain_online = sum(1 for d in all_domains.values() if d["domain"]["status"] == "online") + + data = { + "subdomains": subdomain_results, + "domains": all_domains, + "summary": { + "total": total, "online": online, "offline": total - online, + "domain_total": len(all_domains), "domain_online": domain_online + }, + "timestamp": ts.isoformat(), + "timestamp_epoch": int(ts.timestamp()) + } + + STATUS_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False)) + print(f"[{ts.strftime('%H:%M:%S')}] 온라인 {online}/{total} | 도메인 {domain_online}/{len(all_domains)}") + +if __name__ == "__main__": + run_checks() diff --git a/health_check.py.v4.20260430_0923 b/health_check.py.v4.20260430_0923 new file mode 100755 index 0000000..96583a8 --- /dev/null +++ b/health_check.py.v4.20260430_0923 @@ -0,0 +1,231 @@ +#!/usr/bin/env python3 +"""작은도시 인프라 현황 — PC / NAS / 공유기 / 에이전트 / 도메인 5탭""" +import json, subprocess, re +from pathlib import Path +from datetime import datetime, timezone, timedelta + +KST = timezone(timedelta(hours=9)) +STATUS_FILE = Path(__file__).parent / "health.json" + +# ===== 기본 체크 함수 ===== +def http_check(url, timeout=5): + try: + r = subprocess.run( + ["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}:%{time_total}", + url, "--max-time", str(timeout)], + capture_output=True, text=True, timeout=timeout+2) + parts = r.stdout.strip().split(":") + code = parts[0] if parts else "000" + return {"status": "online" if code.startswith(("2","3")) else "error", + "detail": f"HTTP {code}", + "latency_ms": round(float(parts[1])*1000,0) if len(parts)>1 and parts[1] else None} + except: return {"status": "offline", "detail": "timeout", "latency_ms": None} + +def ssh_check(host, timeout=8): + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", + host, "echo alive"], + capture_output=True, text=True, timeout=timeout) + alive = r.returncode == 0 and "alive" in r.stdout + return {"status": "online" if alive else "offline", + "detail": "alive" if alive else r.stderr.strip()[:80]} + except: return {"status": "offline", "detail": "timeout"} + +def tailscale_ping(host, timeout=8): + try: + r = subprocess.run( + ["tailscale", "ping", "--c", "3", host], + capture_output=True, text=True, timeout=timeout) + out = r.stdout + r.stderr + alive = "pong" in out or "is local" in out + return {"status": "online" if alive else "offline", + "detail": "" if alive else "no pong"} + except: return {"status": "offline", "detail": "timeout"} + +def proc_check(name_pattern, engine_name="?"): + result = {"status": "offline", "version": "?", "uptime": "?", "proc_count": 0, + "engine": engine_name, "detail": "not running", "mem": None} + try: + r = subprocess.run(["pgrep", "-f", name_pattern], capture_output=True, text=True, timeout=5) + pids = [p.strip() for p in r.stdout.strip().split("\n") if p.strip()] + if pids: + result["status"] = "online" + result["proc_count"] = len(pids) + try: + u = subprocess.run(["ps", "-p", pids[0], "-o", "etime="], capture_output=True, text=True, timeout=5) + result["uptime"] = u.stdout.strip() + except: pass + result["detail"] = f"{result['uptime']} · {result['proc_count']}프로세스" + except: pass + return result + +def remote_proc(via, name_pattern, engine_name="?"): + result = {"status": "offline", "version": "?", "uptime": "?", "proc_count": 0, + "engine": engine_name, "detail": "not running", "mem": None} + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", via, + f"ps aux | grep '{name_pattern}' | grep -v grep || true"], + capture_output=True, text=True, timeout=8) + lines = [l for l in r.stdout.strip().split("\n") if l.strip()] + if lines: + result["status"] = "online" + result["proc_count"] = len(lines) + result["detail"] = f"{result['proc_count']}프로세스" + except: pass + return result + +# ===== 버전/TS IP ===== +def get_local_ts_ip(): + try: + r = subprocess.run(["tailscale", "ip", "-4"], capture_output=True, text=True, timeout=5) + return r.stdout.strip() + except: return "?" + +def get_remote_ts(via): + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", via, "tailscale ip -4"], + capture_output=True, text=True, timeout=8) + return r.stdout.strip() if r.returncode == 0 else "?" + except: return "?" + +def get_local_version(label): + try: + if label == "openclaw": + r = subprocess.run(["openclaw", "--version"], capture_output=True, text=True, timeout=5) + v = r.stdout.strip().replace("OpenClaw ", "") + v = re.sub(r'\s+\([^)]+\)', '', v).strip() + return v if v else "?" + elif label == "hermes": + r = subprocess.run(["/Users/pinksky/.hermes/hermes-agent/venv/bin/python","-m","hermes_cli.main","--version"], + capture_output=True, text=True, timeout=5) + m = re.search(r'v[\d.]+', r.stdout.strip()) + return m.group(0) if m else "?" + except: return "?" + +def get_remote_hermes_version(via): + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", via, + "export PATH=\"$HOME/.local/bin:$PATH\"; hermes --version"], + capture_output=True, text=True, timeout=8) + m = re.search(r'v[\d.]+', r.stdout.strip()) + return m.group(0) if m else "?" + except: return "?" + +# ===== 메인 ===== +def run_checks(): + ts = datetime.now(KST) + ts_ip = get_local_ts_ip() + + # --- PC --- + mainpc_ssh = ssh_check("mainpc-win", 6) + mainpc_ts = get_remote_ts("mainpc-wsl") + subpc_ssh = ssh_check("subpc-wsl", 6) + subpc_ts = get_remote_ts("subpc-wsl") + office_pc = tailscale_ping("office-pc", 6) + + pcs = [ + {"name": "맥미니 M4 Pro", "emoji": "🖥️", "spec": "Apple M4 Pro · 64GB · 통합 GPU", + "net": f"{ts_ip} · pinksky.kr", "status": "online", "detail": ""}, + {"name": "메인컴 (PS-i14700K)", "emoji": "🖥️", "spec": "Intel Core i7-14700K · 96GB · RTX 3090 24GB", + "net": f"{mainpc_ts} · mainpc-wsl.pinksky.kr", **mainpc_ssh}, + {"name": "보조컴 (MH-3900x)", "emoji": "🖥️", "spec": "AMD Ryzen 9 3900X · 32GB · RTX 3080 12GB", + "net": f"{subpc_ts} · subpc-wsl.pinksky.kr", **subpc_ssh}, + {"name": "회사 메인PC (PS-i14700K)", "emoji": "🖥️", "spec": "Intel Core i7-14700K · 96GB · RTX 3090", + "net": "", **office_pc}, + ] + + # --- NAS --- + nas_mh = ssh_check("mh-nas", 6) + nas_gwenc2 = tailscale_ping("gwenc-nas2", 6) + nas_bk = tailscale_ping("ps-bk-nas", 6) + + nas = [ + {"name": "집 NAS (mh-nas)", "emoji": "🗄️", "spec": "Synology DS418+", + "net": "100.69.107.65 · minicity.kr", **nas_mh}, + {"name": "회사 NAS (gwenc-nas2)", "emoji": "🗄️", "spec": "Synology", + "net": "100.105.95.19", **nas_gwenc2}, + {"name": "백업 NAS (ps-bk-nas)", "emoji": "🗄️", "spec": "14TB HDD", + "net": "100.83.176.55", **nas_bk}, + ] + + # --- 공유기 --- + routers = [ + {"name": "집 공유기", "emoji": "📡", "spec": "아이피타임 AX8004BCM", + "net": "pinksky.iptime.org", "status": "online", "detail": "DDNS · 원격관리 9090"}, + {"name": "아지트 공유기", "emoji": "📡", "spec": "TP-LINK Archer BE550", + "net": "pinksky.kr", "status": "online", "detail": "헬로비전 · TP-Link 앱"}, + {"name": "회사 공유기", "emoji": "📡", "spec": "TP-LINK AX18000", + "net": "gwenc.kr", "status": "online", "detail": "회사 자산 · 원격관리 9000/9443"}, + ] + + # --- 에이전트 --- + mimi = proc_check("openclaw-gateway", "openclaw") + mimi["name"] = "미미" + mimi["emoji"] = "🦞" + mimi["host"] = "맥미니 (openclaw)" + mimi["version"] = get_local_version("openclaw") + + ruki = proc_check("hermes", "hermes") + ruki["name"] = "루키" + ruki["emoji"] = "🌱" + ruki["host"] = "맥미니 (hermes)" + ruki["version"] = get_local_version("hermes") + + pink = remote_proc("mainpc-wsl", "hermes", "hermes") + pink["name"] = "분홍" + pink["emoji"] = "🤖" + pink["host"] = "메인컴 WSL" + pink["version"] = get_remote_hermes_version("mainpc-wsl") + + sky = remote_proc("subpc-wsl", "hermes", "hermes") + sky["name"] = "하늘" + sky["emoji"] = "🤖" + sky["host"] = "보조컴 WSL" + sky["version"] = get_remote_hermes_version("subpc-wsl") + + agents = [a for a in [mimi, ruki, pink, sky]] + + # --- 도메인 --- + domains = [ + {"name": "wiki.pinksky.kr", "url": "https://wiki.pinksky.kr/", "group": "pinksky.kr", "desc": "MiniCITY 지식정원"}, + {"name": "openclaw.pinksky.kr", "url": "https://openclaw.pinksky.kr/", "group": "pinksky.kr", "desc": "OpenClaw 대시보드"}, + {"name": "agent.pinksky.kr", "url": "https://agent.pinksky.kr/", "group": "pinksky.kr", "desc": "인프라 현황판"}, + {"name": "search.pinksky.kr", "url": "https://search.pinksky.kr/search?q=test", "group": "pinksky.kr", "desc": "SearXNG 메타서치"}, + {"name": "erp.pinksky.kr", "url": "https://erp.pinksky.kr/", "group": "pinksky.kr", "desc": "공사관리 ERP"}, + {"name": "dify.pinksky.kr:8443", "url": "https://dify.pinksky.kr:8443/", "group": "pinksky.kr", "desc": "Dify 워크플로우"}, + {"name": "gwenc.kr", "url": "https://gwenc.kr/", "group": "gwenc.kr", "desc": "회사 메인 사이트"}, + {"name": "minicity.kr", "url": "https://minicity.kr/", "group": "minicity.kr", "desc": "집 NAS 웹 UI"}, + ] + domain_results = [] + for d in domains: + chk = http_check(d["url"], 4) + domain_results.append({ + "name": d["name"], "group": d["group"], "desc": d["desc"], + "status": chk["status"], "detail": chk["detail"], + "latency_ms": chk.get("latency_ms") + }) + + # --- 요약 --- + all_items = pcs + nas + routers + agents + domain_results + online = sum(1 for x in all_items if x["status"] == "online") + + data = { + "pcs": pcs, + "nas": nas, + "routers": routers, + "agents": agents, + "domains": domain_results, + "timestamp": ts.isoformat(), + "timestamp_epoch": int(ts.timestamp()), + "summary": {"online": online, "total": len(all_items)} + } + + STATUS_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False)) + print(f"[{ts.strftime('%H:%M:%S')}] 온라인 {online}/{len(all_items)}") + +if __name__ == "__main__": + run_checks() diff --git a/health_check_backup.py b/health_check_backup.py new file mode 100644 index 0000000..86968ac --- /dev/null +++ b/health_check_backup.py @@ -0,0 +1,302 @@ +#!/usr/bin/env python3 +"""작은도시 인프라 현황 v5 — 도메인 계층 + 에이전트/서브도메인 2탭""" +import json, subprocess, re +from pathlib import Path +from datetime import datetime, timezone, timedelta + +KST = timezone(timedelta(hours=9)) +STATUS_FILE = Path(__file__).parent / "health.json" + +PC_SPECS = { + "macmini": {"name": "맥미니 M4 Pro", "emoji": "🖥️", "spec": "Apple M4 Pro · 64GB · 통합 GPU", "dns": "pinksky.kr"}, + "mainpc": {"name": "메인컴 (PS-i14700K)", "emoji": "🖥️", "spec": "Intel Core i7-14700K · 96GB · RTX 3090 24GB", "dns": "mainpc-wsl.pinksky.kr"}, + "subpc": {"name": "보조컴 (MH-3900x)", "emoji": "🖥️", "spec": "AMD Ryzen 9 3900X · 32GB · RTX 3080 12GB", "dns": "subpc-wsl.pinksky.kr"}, + "officepc": {"name": "회사 메인PC (PS-i14700K)", "emoji": "🖥️", "spec": "Intel Core i7-14700K · 96GB · RTX 3090", "dns": ""}, + "nas_home": {"name": "집 NAS (mh-nas)", "emoji": "🗄️", "spec": "Synology DS418+", "dns": "minicity.kr"}, + "nas_office": {"name": "회사 NAS (gwenc-nas2)", "emoji": "🗄️", "spec": "Synology", "dns": ""}, + "nas_backup": {"name": "백업 NAS (ps-bk-nas)", "emoji": "🗄️", "spec": "14TB HDD", "dns": ""}, + "router_home": {"name": "집 공유기", "emoji": "📡", "spec": "아이피타임 AX8004BCM", "dns": "pinksky.iptime.org"}, + "router_apt": {"name": "아지트 공유기", "emoji": "📡", "spec": "TP-LINK Archer BE550", "dns": "pinksky.kr"}, + "router_office": {"name": "회사 공유기", "emoji": "📡", "spec": "TP-LINK AX18000", "dns": "gwenc.kr"}, +} + +# ===== 기본 체크 함수 ===== +def http_check(url, timeout=5): + try: + r = subprocess.run( + ["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}:%{time_total}", + url, "--max-time", str(timeout)], + capture_output=True, text=True, timeout=timeout+2) + parts = r.stdout.strip().split(":") + code = parts[0] if parts else "000" + latency = round(float(parts[1])*1000, 0) if len(parts) > 1 and parts[1] else None + return {"status": "online" if code.startswith(("2","3")) else "error", + "detail": f"HTTP {code}", "latency_ms": latency} + except: return {"status": "offline", "detail": "timeout", "latency_ms": None} + +def ssh_check(host, timeout=8): + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", + host, "echo alive"], + capture_output=True, text=True, timeout=timeout) + alive = r.returncode == 0 and "alive" in r.stdout + return {"status": "online" if alive else "offline", + "detail": "alive" if alive else r.stderr.strip()[:80]} + except: return {"status": "offline", "detail": "timeout"} + +def tailscale_ping(host, timeout=8): + try: + r = subprocess.run( + ["tailscale", "ping", "--c", "3", host], + capture_output=True, text=True, timeout=timeout) + out = r.stdout + r.stderr + alive = "pong" in out or "is local" in out + return {"status": "online" if alive else "offline", + "detail": "" if alive else "no pong"} + except: return {"status": "offline", "detail": "timeout"} + +def get_local_ts_ip(): + try: + r = subprocess.run(["tailscale", "ip", "-4"], capture_output=True, text=True, timeout=5) + return r.stdout.strip() + except: return "?" + +def get_remote_ts(via): + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", via, "tailscale ip -4"], + capture_output=True, text=True, timeout=8) + return r.stdout.strip() if r.returncode == 0 else "?" + except: return "?" + +def get_version(label): + try: + if label == "openclaw": + r = subprocess.run(["openclaw", "--version"], capture_output=True, text=True, timeout=5) + v = r.stdout.strip().replace("OpenClaw ", "") + v = re.sub(r'\s+\([^)]+\)', '', v).strip() + return v if v else "?" + elif label == "hermes": + r = subprocess.run([ + "/Users/pinksky/.hermes/hermes-agent/venv/bin/python", + "-m", "hermes_cli.main", "--version"], + capture_output=True, text=True, timeout=5) + m = re.search(r'v[\d.]+', r.stdout.strip()) + return m.group(0) if m else "?" + except: return "?" + +def get_remote_hermes_version(via): + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", via, + "export PATH=\"$HOME/.local/bin:$PATH\"; hermes --version"], + capture_output=True, text=True, timeout=8) + m = re.search(r'v[\d.]+', r.stdout.strip()) + return m.group(0) if m else "?" + except: return "?" + +def proc_detail(pattern, engine_name="?"): + result = {"status": "offline", "version": "?", "uptime": "?", "proc_count": 0, + "engine": engine_name, "detail": "not running"} + try: + r = subprocess.run(["pgrep", "-f", pattern], capture_output=True, text=True, timeout=5) + pids = [p.strip() for p in r.stdout.strip().split("\n") if p.strip()] + if pids: + result["status"] = "online" + result["proc_count"] = len(pids) + try: + u = subprocess.run(["ps", "-p", pids[0], "-o", "etime="], + capture_output=True, text=True, timeout=5) + result["uptime"] = u.stdout.strip() + except: pass + result["detail"] = f"{result['uptime']} · {result['proc_count']}프로세스" + except: pass + return result + +def remote_proc(via, pattern, engine_name="?"): + result = {"status": "offline", "version": "?", "uptime": "?", "proc_count": 0, + "engine": engine_name, "detail": "not running"} + try: + r = subprocess.run( + ["ssh", "-o", "ConnectTimeout=5", "-o", "StrictHostKeyChecking=no", + via, f"ps aux | grep '{pattern}' | grep -v grep || true"], + capture_output=True, text=True, timeout=8) + lines = [l for l in r.stdout.strip().split("\n") if l.strip()] + if lines: + result["status"] = "online" + result["proc_count"] = len(lines) + result["detail"] = f"{result['proc_count']}프로세스" + except: pass + return result + +# ===== 메인 ===== +def run_checks(): + ts = datetime.now(KST) + ts_ip = get_local_ts_ip() + + # --- PC checks --- + mainpc_ssh = ssh_check("mainpc-win", 6) + mainpc_ts = get_remote_ts("mainpc-wsl") + subpc_ssh = ssh_check("subpc-wsl", 6) + subpc_ts = get_remote_ts("subpc-wsl") + office_pc = tailscale_ping("office-pc", 6) + + # --- NAS checks --- + nas_mh = ssh_check("mh-nas", 6) + nas_gwenc2 = tailscale_ping("gwenc-nas2", 6) + nas_bk = tailscale_ping("ps-bk-nas", 6) + + # --- Agent checks --- + mimi = proc_detail("openclaw", "openclaw") + mimi["name"] = "미미" + mimi["emoji"] = "🦞" + mimi["version"] = get_version("openclaw") + + ruki = proc_detail("hermes", "hermes") + ruki["name"] = "루키" + ruki["emoji"] = "🌱" + ruki["version"] = get_version("hermes") + + pink = remote_proc("mainpc-wsl", "hermes", "hermes") + pink["name"] = "분홍" + pink["emoji"] = "🤖" + pink["version"] = get_remote_hermes_version("mainpc-wsl") + + sky = remote_proc("subpc-wsl", "hermes", "hermes") + sky["name"] = "하늘" + sky["emoji"] = "🤖" + sky["version"] = get_remote_hermes_version("subpc-wsl") + + # --- Subdomains --- + subdomains = [ + {"name": "wiki.pinksky.kr", "url": "https://wiki.pinksky.kr/", "group": "pinksky.kr", "desc": "MiniCITY 지식정원"}, + {"name": "openclaw.pinksky.kr", "url": "https://openclaw.pinksky.kr/", "group": "pinksky.kr", "desc": "OpenClaw 대시보드"}, + {"name": "agent.pinksky.kr", "url": "https://agent.pinksky.kr/", "group": "pinksky.kr", "desc": "인프라 현황판"}, + {"name": "search.pinksky.kr", "url": "https://search.pinksky.kr/search?q=test", "group": "pinksky.kr", "desc": "SearXNG 메타서치"}, + {"name": "erp.pinksky.kr", "url": "https://erp.pinksky.kr/", "group": "pinksky.kr", "desc": "공사관리 ERP"}, + {"name": "dify.pinksky.kr", "url": "https://dify.pinksky.kr/", "group": "pinksky.kr", "desc": "Dify 워크플로우"}, + {"name": "photo.pinksky.kr", "url": "https://photo.pinksky.kr/", "group": "pinksky.kr", "desc": "PhotoVault 자료정리"}, + {"name": "gwenc.kr", "url": "https://gwenc.kr/", "group": "gwenc.kr", "desc": "회사 메인 사이트"}, + {"name": "minicity.kr", "url": "https://minicity.kr/", "group": "minicity.kr", "desc": "집 NAS 웹 UI"}, + ] + sub_results = [] + for s in subdomains: + chk = http_check(s["url"], 4) + sub_results.append({ + "name": s["name"], "group": s["group"], "desc": s["desc"], + "status": chk["status"], "detail": chk["detail"], "latency_ms": chk.get("latency_ms") + }) + + # --- Domain hierarchy --- + domains = { + "pinksky.kr": { + "domain": {"status": "online", "detail": f"{ts_ip}"}, + "pcs": { + "macmini": { + **PC_SPECS["macmini"], + "tailscale_ip": ts_ip, + "status": "online", "detail": "", + "agents": { + "mimi": {**mimi}, + "ruki": {**ruki}, + } + }, + "mainpc": { + **PC_SPECS["mainpc"], + "tailscale_ip": mainpc_ts, + "status": mainpc_ssh["status"], "detail": mainpc_ssh["detail"], + "agents": { + "pink": {**pink}, + } + }, + "subpc": { + **PC_SPECS["subpc"], + "tailscale_ip": subpc_ts, + "status": subpc_ssh["status"], "detail": subpc_ssh["detail"], + "agents": { + "sky": {**sky}, + } + } + } + }, + "minicity.kr": { + "domain": {"status": "online", "detail": "집 NAS/공유기"}, + "pcs": { + "nas_home": { + **PC_SPECS["nas_home"], + "tailscale_ip": "100.69.107.65", + "status": nas_mh["status"], "detail": nas_mh["detail"], + "agents": {} + }, + "router_home": { + **PC_SPECS["router_home"], + "tailscale_ip": "", + "status": "online", "detail": "DDNS · 원격관리 9090", + "agents": {} + } + } + }, + "gwenc.kr": { + "domain": {"status": office_pc["status"], "detail": office_pc["detail"]}, + "pcs": { + "officepc": { + **PC_SPECS["officepc"], + "tailscale_ip": "", + "status": office_pc["status"], "detail": office_pc["detail"], + "agents": {} + }, + "nas_office": { + **PC_SPECS["nas_office"], + "tailscale_ip": "100.105.95.19", + "status": nas_gwenc2["status"], "detail": nas_gwenc2["detail"], + "agents": {} + }, + "nas_backup": { + **PC_SPECS["nas_backup"], + "tailscale_ip": "100.83.176.55", + "status": nas_bk["status"], "detail": nas_bk["detail"], + "agents": {} + }, + "router_office": { + **PC_SPECS["router_office"], + "tailscale_ip": "", + "status": "online", "detail": "원격관리 9000/9443", + "agents": {} + } + } + } + } + + # --- Summary --- + all_items = [] + for d in domains.values(): + for pc in d["pcs"].values(): + all_items.append(pc) + for a in pc.get("agents", {}).values(): + all_items.append(a) + for s in sub_results: + all_items.append(s) + + online = sum(1 for x in all_items if x["status"] == "online") + offline = sum(1 for x in all_items if x["status"] == "offline") + + data = { + "subdomains": sub_results, + "domains": domains, + "summary": { + "total": len(all_items), + "online": online, + "offline": offline, + "domain_total": 3, + "domain_online": sum(1 for d in domains.values() if d["domain"]["status"] == "online") + }, + "timestamp": ts.isoformat(), + "timestamp_epoch": int(ts.timestamp()) + } + + STATUS_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False)) + print(f"[{ts.strftime('%H:%M:%S')}] Online {online}/{len(all_items)} · Domains {data['summary']['domain_online']}/3") + +if __name__ == "__main__": + run_checks() diff --git a/index.html b/index.html new file mode 100644 index 0000000..33d745e --- /dev/null +++ b/index.html @@ -0,0 +1,403 @@ + + + + + +작은도시 인프라 현황 + + + +
+
+

🏙️ 작은도시 인프라 현황

+
+ 0 Online + 0 Offline + 0 Error +
+
갱신 중...
+
+ +
+ + + + +
+ +
+
+
+
+ +
작은도시 인프라 현황 · 60초마다 자동 갱신
+
+ + + + diff --git a/index.html.backup.20260429_2057 b/index.html.backup.20260429_2057 new file mode 100644 index 0000000..be41f85 --- /dev/null +++ b/index.html.backup.20260429_2057 @@ -0,0 +1,280 @@ + + + + + +작은도시 에이전트 현황 + + + +
+
+

🏙️ 작은도시 에이전트 현황

+
+ 0 Online + 0 Offline + 도메인 0/4 +
+
갱신 중...
+
+ +
+ + +
+ +
+
+ +
+ 작은도시 에이전트 현황 · 1분마다 자동 갱신 +
+
+ + + + diff --git a/index.html.v4.20260430_0923 b/index.html.v4.20260430_0923 new file mode 100644 index 0000000..21303fc --- /dev/null +++ b/index.html.v4.20260430_0923 @@ -0,0 +1,241 @@ + + + + + +작은도시 인프라 현황 + + + +
+
+

🏙️ 작은도시 인프라 현황

+
+ 0 Online + 0 Offline +
+
갱신 중...
+
+ +
+ + + + + +
+ +
+
+
+
+
+ +
작은도시 인프라 현황 · 1분마다 자동 갱신
+
+ + + + diff --git a/v0.5_plan_for_pink.md b/v0.5_plan_for_pink.md new file mode 100644 index 0000000..59ef64b --- /dev/null +++ b/v0.5_plan_for_pink.md @@ -0,0 +1,41 @@ +# 🏙️ MiniCITY v0.5 — 의견 요청 (분홍) + +안녕하세요 분홍! 저는 루키입니다. + +아빠(미미아빠)의 요청으로 MiniCITY 옵시디언 볼트를 v0.5로 재구조화하려고 합니다. +현재 문제점: 17,681개 파일 중 11,620개(66%)가 ERP 소스코드 중복입니다. 실제 문서는 5~6천 개 수준. + +## 제안 구조 +``` +MiniCITY(v0.5_PARA_0502-)/ +├── 00_INBOX/ +├── 01_PROJECTS/ +│ ├── A_mini-happy/ +│ ├── B_선번조사툴/ ← 분홍 담당 +│ ├── C_공사관리ERP/ ← 분홍 담당 +│ ├── D_자료관리/ +│ ├── E_공가신청해지/ +│ ├── H_음성알림시스템/ +│ └── AgentStatusDash/ +├── 02_AREAS/ +│ ├── 인프라/ +│ └── 에이전트/ +│ ├── 미미/ +│ ├── 루키/ +│ ├── 분홍/ ← 분홍 개인 작업공간 +│ └── 하늘/ +├── 03_RESOURCES/ +├── 04_ARCHIVE/ +└── 98_HISTORY/ +└── 99_TEMPLATES/ +``` + +## 분홍에게 묻고 싶은 점 +1. B_선번조사툴 / C_공사관리ERP 문서를 v0.x_구상/초안/진행중 3단계로 정리하는 것 괜찮나요? +2. 작업하던 ERP 소스코드가 옵시디언에 11,620개나 중복되어 있는데, 전부 제거해도 되나요? (git 저장소로 이동) +3. 분홍 개인 작업공간(02_AREAS/에이전트/분홍/)이 필요하다면 어떤 내용을 담고 싶나요? +4. 기타 제안이나 우려사항이 있으면 알려주세요. + +회신은 이 파일 아래에 작성해주세요. (파일을 수정해서 답변을 추가해주세요) +--- +의견: