data-updater
npx skills add https://github.com/orientpine/honeypot --skill data-updater
Agent 安装分布
Skill 文档
Fund Data Updater
Overview
ê³¼í기ì ê³µì í í´ì§ì°ê¸ CSV íì¼ì ì½ì´ Python ì¤í¬ë¦½í¸ë¥¼ íµí´ íë ë°ì´í° JSON íì¼ì ìë ìì±íë ì¤í¬ì´ë¤.
íµì¬ 기ë¥:
- CSV íì¼ íì± ë° ê²ì¦
- fund_data.json ìì± (íë 기본 ì ë³´ ë° ììµë¥ )
- fund_fees.json ìì± (íë ììë£ ì ë³´)
- fund_classification.json ìë ìì± (íë ë¶ë¥)
- í¬ì ê°ë¥ íë íí°ë§ (investable_codes.json 기ë°)
- funds/all/ í´ëì ì ì²´ íë ë°ì´í° ì ì¥ (2015ê°)
- deposit_rates.json ì ë°ì´í¸ (ìê¸ê¸ë¦¬ – ì¬ì©ì ì ë ¥ íì)
- 기존 íì¼ ìë ë°±ì (archive/ ëë í 리)
â ï¸ ì¤ì: ìê¸ê¸ë¦¬ ë°ì´í°ë ì¹ ê²ìì¼ë¡ ì»ì ì ììµëë¤. ê³¼í기ì ì¸ê³µì í ë´ë¶ ê¸ë¦¬ì´ë¯ë¡ ë°ëì ì¬ì©ììê² ì§ì íì¸í´ì¼ í©ëë¤.
ì¬ì©ì ì ë ¥ ì¤í¤ë§
íì ì ë ¥
| í목 | ì¤ëª | ìì |
|---|---|---|
| CSV íì¼ ê²½ë¡ | ê³¼í기ì ê³µì í í´ì§ì°ê¸ CSV íì¼ | resource/26ë
01ì_ìíì ìì_í´ì§ì°ê¸(DCIRP).csv |
ì í ì ë ¥
| í목 | ì¤ëª | ê¸°ë³¸ê° |
|---|---|---|
| ì¶ë ¥ ëë í 리 | JSON íì¼ ì ì¥ ìì¹ | ìë ê°ì§ (investments/funds/) |
| dry-run 모ë | 미리보기 (íì¼ ìì± ìì´ ê²°ê³¼ë§ ì¶ë ¥) | false |
Workflow
[Phase 0: ì
ë ¥ ê²ì¦]
|
+-- Step 0-1. CSV íì¼ íì¸
| +-- ì¬ì©ì ì ê³µ ê²½ë¡ ì¡´ì¬ ì¬ë¶ íì¸
| +-- íì¼ íì¥ì (.csv) íì¸
| +-- ì¸ì½ë© ê²ì¦ (UTF-8 íì)
|
+-- Step 0-2. ì¶ë ¥ í´ë ì¤ì
| +-- funds/ í´ë ì¡´ì¬ íì¸ (ìì¼ë©´ ìì±)
| +-- archive/ í´ë ì¡´ì¬ íì¸ (ìì¼ë©´ ìì±)
| +-- 기존 JSON íì¼ ë°±ì
ì¤ë¹
|
+-- Step 0-3. Python íê²½ íì¸
+-- Python 3.10+ ì¤ì¹ ì¬ë¶ íì¸
+-- íì í¨í¤ì§: íì¤ ë¼ì´ë¸ë¬ë¦¬ë§ (ì¸ë¶ í¨í¤ì§ ë¶íì)
[Phase 1: Dry-run ì¤í (ê¶ì¥)]
|
+-- Step 1-1. 미리보기 ì¤í
| +-- --dry-run ìµì
ì¼ë¡ ì¤í¬ë¦½í¸ ì¤í
| +-- CSV ë©íë°ì´í° íì¸ (ì¬ì
ìëª
, 기ì¤ì¼ ë±)
| +-- íë ê°ì íì¸
|
+-- Step 1-2. ìí ë°ì´í° ê²í
+-- ì²ì 3ê° íë ë°ì´í° 미리보기
+-- ì¬ì©ììê² íì¸ ìì² (ì§í ì¬ë¶)
[Phase 2: ë°ì´í° ë³í]
|
+-- Step 2-1. Python ì¤í¬ë¦½í¸ 찾기 ë° ì¤í
| +-- ìëê²½ë¡ ì°¸ì¡°: scripts/update_fund_data.py (ì¤í¬ ë£¨í¸ ê¸°ì¤)
| +-- ì¤í¨ ì Glob í´ë°±: **/investments-portfolio/skills/data-updater/scripts/update_fund_data.py
| +-- Globë ì¤í¨ ì: Glob: **/update_fund_data.py
| +-- ì°¾ì ê²½ë¡ë¡ ì¤í: python {ê²½ë¡} --file [csv_file_path]
| +-- ì¤í¬ë¦½í¸ë¥¼ ì°¾ì§ ëª»íë©´: ì¦ì ì¤ë¨, ì¬ì©ììê² ê²½ë¡ íì¸ ìì²
| +-- ì ë ê¸ì§: ì¤í¬ë¦½í¸ë¥¼ 못 ì°¾ìì ë ìì²´ Python ì½ë를 ìì±íì¬ ëì²´íì§ ìì
|
+-- Step 2-2. ìë ë¶ë¥ ì¤í
| +-- update_fund_data.pyê° ìëì¼ë¡ classify_funds.py í¸ì¶
| +-- fund_classification.json ìë ìì±
|
+-- Step 2-3. ê²°ê³¼ íì¸
+-- ìì±ë JSON íì¼ ëª©ë¡ íì¸
+-- íë ê°ì ë° ë¶ë¥ íµê³ íì¸
[Phase 3: ê²ì¦]
|
+-- Step 3-1. íì¼ ê²ì¦
| +-- fund_data.json ì¡´ì¬ ë° JSON ì í¨ì± íì¸
| +-- fund_fees.json ì¡´ì¬ ë° JSON ì í¨ì± íì¸
| +-- fund_classification.json ì¡´ì¬ íì¸
|
+-- Step 3-2. ë©íë°ì´í° ê²ì¦
+-- _meta.version íì¸ (CSV 기ì¤ì¼ê³¼ ì¼ì¹)
+-- _meta.recordCount íì¸ (íë ê°ì)
+-- _meta.updatedAt íì¸ (íì¬ ìê°)
[Phase 4: ìë£ ë³´ê³ ]
|
+-- Step 4-1. ì¤í ë³´ê³ ì ìì±
| +-- í¬í¨ ë´ì©:
| - ì
ë ¥ CSV íì¼ëª
ë° ê¸°ì¤ì¼
| - ìì±ë JSON íì¼ ëª©ë¡
| - íë ê°ì ë° ë¶ë¥ íµê³
| - ìì¹´ì´ë¸ë íì¼ ëª©ë¡
|
+-- Step 4-2. ì¬ì©ì ìë´
+-- ìì± ìë£ ì림
+-- funds/ í´ë ìì¹ ìë´
+-- ë¤ì ë¨ê³ ìë´ (í¬í¸í´ë¦¬ì¤ ë¶ì ë±)
[Phase 5: ìê¸ê¸ë¦¬ ì
ë°ì´í¸ (ì í)]
|
+-- Step 5-0. ìê¸ê¸ë¦¬ ì
ë°ì´í¸ íì ì¬ë¶ íì¸
| +-- deposit_rates.json ì¡´ì¬ íì¸
| +-- _meta.version ê¸°ì¤ ê²½ê³¼ì¼ ê³ì°
| +-- 30ì¼ ì´ì 경과 ì ì
ë°ì´í¸ ê¶ì¥
|
+-- Step 5-1. ì¬ì©ììê² ìê¸ê¸ë¦¬ íì¸ ìì² (mcp_question ì¬ì©)
| +-- â ï¸ ì¹ ê²ì ë¶ê° - ì¬ì©ì ì§ì ì
ë ¥ íì
| +-- ì§ë¬¸: "ê³¼í기ì ì¸ê³µì í í´ì§ì°ê¸ ìê¸ê¸ë¦¬ë¥¼ ì
ë ¥í´ì£¼ì¸ì"
| +-- íì ì
ë ¥ í목:
| - ê³¼í기ì ì¸ê³µì í 1ë
ì 기ìê¸ ê¸ë¦¬ (%)
| - ì°ë¦¬ìí 1ë
ì 기ìê¸ ê¸ë¦¬ (%) - ì í
|
+-- Step 5-2. deposit_rates.json ì
ë°ì´í¸
| +-- _meta.version: íì¬ ë ì§ (YYYY-MM-DD)
| +-- _meta.updatedAt: íì¬ ISO 8601 íìì¤í¬í
| +-- rates ë°°ì´ ì
ë°ì´í¸
|
+-- Step 5-3. ì
ë°ì´í¸ ìë£ íì¸
+-- JSON ì í¨ì± ê²ì¬
+-- ì
ë°ì´í¸ ë´ì ë³´ê³
ì¤í¬ë¦½í¸ ì¤í ë°©ì
ì¤í¬ë¦½í¸ 참조 ë° ì¤í (CRITICAL)
ì¤í¬ë¦½í¸ë ì´ ì¤í¬ì ìëê²½ë¡ì ìì¹í©ëë¤:
scripts/update_fund_data.py scripts/classify_funds.py
ì¤í ìì:
Step 1. ìëê²½ë¡ë¡ ì¤í (ìµì°ì )
python scripts/update_fund_data.py --file [csv_file_path]
python scripts/classify_funds.py --fund-data "funds/fund_data.json"
Step 2. ìëê²½ë¡ ì¤í¨ ì Glob í´ë°±
Glob: **/investments-portfolio/skills/data-updater/scripts/update_fund_data.py
Glob: **/investments-portfolio/skills/data-updater/scripts/classify_funds.py
Step 3. Globë ì¤í¨ ì íì¥ íì
Glob: **/update_fund_data.py
Glob: **/classify_funds.py
ì ë ê¸ì§: ì¤í¬ë¦½í¸ë¥¼ ì°¾ì§ ëª»íì ë ìì²´ì ì¼ë¡ Python ì½ë를 ìì±íì§ ë§ì¸ì. ë°ëì ìë¬ë¥¼ ë³´ê³ íê³ ì¬ì©ììê² ê²½ë¡ íì¸ì ìì²íì¸ì.
ì¤í ëª ë ¹ì´
# Dry-run (미리보기) - ê¶ì¥
python scripts/update_fund_data.py \
--file [csv_file_path] \
--dry-run
# ì¤ì ì¤í (ìë ê²½ë¡ ê°ì§)
python scripts/update_fund_data.py \
--file [csv_file_path]
# ì¤ì ì¤í (ì¶ë ¥ ê²½ë¡ ì§ì )
python scripts/update_fund_data.py \
--file [csv_file_path] \
--output-dir [output_directory]
ë¶ë¥ë§ ì¬ì¤í (ì í)
python scripts/classify_funds.py \
--fund-data "funds/fund_data.json"
ì¤í¬ë¦½í¸ ìµì
| ì¤í¬ë¦½í¸ | ìµì | íì | ì¤ëª |
|---|---|---|---|
| update_fund_data.py | --file |
O | CSV íì¼ ê²½ë¡ |
| update_fund_data.py | --output-dir |
X | ì¶ë ¥ ëë í 리 (기본: ìë ê°ì§) |
| update_fund_data.py | --dry-run |
X | 미리보기 모ë |
| classify_funds.py | --fund-data |
O | fund_data.json íì¼ ê²½ë¡ |
| classify_funds.py | --output |
X | ì¶ë ¥ íì¼ ê²½ë¡ |
ìì¡´ì±
- Python 3.10+
- íì¤ ë¼ì´ë¸ë¬ë¦¬ë§ ì¬ì© (ì¸ë¶ í¨í¤ì§ ë¶íì)
Output Structure
ì¶ë ¥ ëë í 리 구조
funds/
âââ fund_data.json # íí°ë§ë íë (206ê°)
âââ fund_fees.json # íí°ë§ë ììë£ ì ë³´
âââ fund_classification.json # íí°ë§ë íë ë¶ë¥
âââ investable_codes.json # í¬ì ê°ë¥ íë ì½ë 목ë¡
âââ deposit_rates.json # ìê¸ê¸ë¦¬ ì ë³´
âââ all/ # ì ì²´ íë ë°ì´í°
â âââ all_fund_data.json # ì ì²´ íë (2015ê°)
â âââ all_fund_fees.json # ì ì²´ ììë£ ì ë³´
â âââ all_fund_classification.json # ì ì²´ íë ë¶ë¥
âââ archive/ # ì´ì ë²ì ë°±ì
âââ fund_data_2026-01-01.json
âââ fund_fees_2026-01-01.json
fund_data.json 구조
{
"_meta": {
"version": "2026-01-01",
"sourceFile": "26ë
01ì_ìíì ìì_í´ì§ì°ê¸(DCIRP).csv",
"updatedAt": "2026-01-21T21:00:00+09:00",
"recordCount": 206,
"missing": []
},
"funds": [
{
"fundCode": "K55105EC1749",
"name": "íëëª
",
"company": "ì´ì©ì¬ëª
",
"riskLevel": 2,
"riskName": "ëììí",
"return10y": "",
"return7y": "",
"return5y": "",
"return3y": "70.34",
"return1y": "178.03",
"return6m": "30.03",
"netAssets": "50840000",
"inceptionDate": "20220627",
"isAffiliate": false,
"fundType": "ETF"
}
]
}
fund_classification.json 구조
{
"íëëª
": {
"category": "í´ì¸ì£¼ìí",
"riskAsset": true,
"assetClass": "equity",
"region": "global",
"themes": ["semiconductor", "ai"],
"hedged": false,
"riskLevel": 2,
"source": "fund_data.json + keyword classification",
"generatedAt": "2026-01-21"
}
}
deposit_rates.json 구조
{
"_meta": {
"version": "2026-01-31",
"source": "ê³¼í기ì ì¸ê³µì í í´ì§ì°ê¸ ì리ê¸ë³´ì¥í ì´ì©ë°©ë² ìë´",
"updatedAt": "2026-01-31T12:00:00+09:00",
"recordCount": 4,
"freshnessThresholdDays": 30,
"note": "30ì¼ ê²½ê³¼ ì ë°ì´í° ì
ë°ì´í¸ íì"
},
"rates": [
{
"id": "sema-1y",
"institution": "ê³¼í기ì ì¸ê³µì í",
"productName": "ê³¼í기ì ì¸ê³µì í í´ì§ì°ê¸ ì´ì©ë°©ë² (1ë
)",
"type": "ì리ê¸ë³´ì¥íì´ì©ë°©ë²",
"term": "1ë
",
"termMonths": 12,
"rate": 4.9,
"unit": "%"
},
{
"id": "woori-1y",
"institution": "ì°ë¦¬ìí",
"productName": "ì°ë¦¬ìí ì 기ìê¸ 1ë
",
"type": "ì리ê¸ë³´ì¥íì´ì©ë°©ë²",
"term": "1ë
",
"termMonths": 12,
"rate": 2.75,
"unit": "%"
}
],
"summary": {
"highestRate": {
"institution": "ê³¼í기ì ì¸ê³µì í",
"rate": 4.9,
"term": "1ë
"
},
"institutions": ["ê³¼í기ì ì¸ê³µì í", "ì°ë¦¬ìí"]
}
}
ìê¸ê¸ë¦¬ ì ë°ì´í¸ (Phase 5)
â ï¸ ì¤ì: ì¹ ê²ì ë¶ê°
ìê¸ê¸ë¦¬ ë°ì´í°ë ì¹ ê²ìì¼ë¡ ì»ì ì ììµëë¤.
- ê³¼í기ì ì¸ê³µì í ë´ë¶ ê¸ë¦¬ë ê³µê° ì¹ì ê²ìëì§ ìì
- íì ì ì© í¬í¸ ëë ê³ ê°ì¼í°ììë§ íì¸ ê°ë¥
- ë°ë¼ì ì¬ì©ììê² ì§ì íì¸ ìì²ì´ íì
ì¬ì©ì ì§ë¬¸ ìì (mcp_question ì¬ì©)
{
"questions": [
{
"header": "ìê¸ê¸ë¦¬ ì
ë°ì´í¸",
"question": "ê³¼í기ì ì¸ê³µì í í´ì§ì°ê¸ 1ë
ì 기ìê¸ ê¸ë¦¬(%)를 ì
ë ¥í´ì£¼ì¸ì. (ì: 4.9)",
"options": [
{"label": "4.9%", "description": "íì¬ ì ì¥ë ê¸ë¦¬"},
{"label": "5.0%", "description": ""},
{"label": "4.8%", "description": ""},
{"label": "4.7%", "description": ""}
]
}
]
}
ëë ì§ì ì ë ¥ì ë°ë ê²½ì°:
ì¬ì©ììê² ìê¸ê¸ë¦¬ íì¸ì ìì²í©ëë¤.
ê³¼í기ì ì¸ê³µì í í´ì§ì°ê¸ í¬í¸ìì íì¬ ìê¸ê¸ë¦¬ë¥¼ íì¸í´ì£¼ì¸ì:
- ê³¼í기ì ì¸ê³µì í 1ë
ì 기ìê¸ ê¸ë¦¬: _____ %
- (ì í) ì°ë¦¬ìí 1ë
ì 기ìê¸ ê¸ë¦¬: _____ %
íì¸ ë°©ë²:
1. ê³¼í기ì ì¸ê³µì í í´ì§ì°ê¸ í¬í¸ ë¡ê·¸ì¸
2. ì리ê¸ë³´ì¥í ì´ì©ë°©ë² ìë´ íì´ì§ íì¸
3. íì¬ ê¸ë¦¬ ì
ë ¥
ì ë°ì´í¸ ìí ë°©ë²
ì¬ì©ìë¡ë¶í° ê¸ë¦¬ ì 보를 ë°ì í:
# deposit_rates.json ì
ë°ì´í¸
import json
from datetime import datetime
# íì¬ íì¼ ì½ê¸°
with open('funds/deposit_rates.json', 'r', encoding='utf-8') as f:
data = json.load(f)
# ë©íë°ì´í° ì
ë°ì´í¸
data['_meta']['version'] = datetime.now().strftime('%Y-%m-%d')
data['_meta']['updatedAt'] = datetime.now().isoformat()
# ê¸ë¦¬ ì
ë°ì´í¸ (ì¬ì©ì ì
ë ¥ê° ì¬ì©)
for rate in data['rates']:
if rate['id'] == 'sema-1y':
rate['rate'] = 4.9 # ì¬ì©ì ì
ë ¥ê°
elif rate['id'] == 'woori-1y':
rate['rate'] = 2.75 # ì¬ì©ì ì
ë ¥ê°
# ìì½ ì
ë°ì´í¸
data['summary']['highestRate']['rate'] = max(r['rate'] for r in data['rates'])
# ì ì¥
with open('funds/deposit_rates.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
Usage Example
ì ë ¥ ìì 1: íë ë°ì´í° ì ë°ì´í¸
data-updater ì¤í¬ì ì¬ì©í´ì íë ë°ì´í°ë¥¼ ì
ë°ì´í¸í´ì¤.
CSV íì¼: resource/26ë
01ì_ìíì ìì_í´ì§ì°ê¸(DCIRP).csv
ëë ê°ë¨í:
íë ë°ì´í° ì
ë°ì´í¸í´ì¤
ì ë ¥ ìì 2: ìê¸ê¸ë¦¬ ì ë°ì´í¸
ìê¸ê¸ë¦¬ ë°ì´í°ë ì
ë°ì´í¸í´ì¤
ëë:
data-updater ì¤í¬ë¡ ìê¸ê¸ë¦¬ ì
ë°ì´í¸ í´ì¤.
ê³¼í기ì ì¸ê³µì í 1ë
: 4.9%
ì°ë¦¬ìí 1ë
: 2.75%
ìí ì ì°¨
íë ë°ì´í° ì ë°ì´í¸ (Phase 0-4):
- Phase 0: CSV íì¼ íì¸, UTF-8 ì¸ì½ë© ê²ì¦
- Phase 1: Dry-runì¼ë¡ 미리보기, 2015ê° íë ë°ê²¬
- Phase 2: Python ì¤í¬ë¦½í¸ ì¤í, JSON íì¼ ìì±
- Phase 3: ìì±ë íì¼ ê²ì¦
- Phase 4: ìë£ ë³´ê³ ì ìì±
ìê¸ê¸ë¦¬ ì ë°ì´í¸ (Phase 5, ì í): 6. Phase 5: ì¬ì©ììê² ìê¸ê¸ë¦¬ íì¸ ìì² â deposit_rates.json ì ë°ì´í¸
ì¶ë ¥ íì¼
funds/fund_data.json: íë ë§ì¤í° ë°ì´í° (2015ê°)funds/fund_fees.json: íë ììë£ ì ë³´funds/fund_classification.json: íë ë¶ë¥ ì ë³´funds/deposit_rates.json: ìê¸ê¸ë¦¬ ì ë³´ (Phase 5 ì¤í ì)
ìë¬ ì²ë¦¬
| ìë¬ | ìì¸ | í´ê²° |
|---|---|---|
File not found |
CSV íì¼ ê²½ë¡ ì¤ë¥ | ê²½ë¡ íì¸, ì ë ê²½ë¡ ì¬ì© |
UnicodeDecodeError |
ì¸ì½ë© ì¤ë¥ | CSV íì¼ì UTF-8ë¡ ì¬ì ì¥ |
Header not found |
CSV íì ì¤ë¥ | “íëì½ë” í¬í¨ í¤ë íì¸ |
Output directory not found |
ê²½ë¡ ê°ì§ ì¤í¨ | --output-dir ìµì
ì¬ì© |
ìì¸í ìë¬ ì²ë¦¬ ë° ëë²ê¹
ë°©ë²ì ./scripts/README.md 참조.
CSV íì¼ íì
ìì 구조
Row 1: ì¬ì
ìëª
| 미ëìì
ì¦ê¶
Row 2: ì ëì í | DC/IRP
Row 3: ìíì í | ì¤ì ë°°ë¹í ìí(íë/ETF)
Row 4: 기ì¤ì¼ | 2026-01-01, ì ë¡ì¸
Row 5-7: (ë¹ í ëë 기í)
Row 8: í¤ë | íëì½ë | íëëª
| ì´ì©íì¬ëª
| ìíë±ê¸ | ...
Row 9+: ë°ì´í° | K55105EC1749 | íëëª
| ì´ì©ì¬ | 2ë±ê¸(ëììí) | ...
íì 컬ë¼
| 컬ë¼ëª | ì©ë |
|---|---|
| íëì½ë | ê³ ì ìë³ì |
| íëëª | íë ì´ë¦ |
| ì´ì©íì¬ëª | ì´ì©ì¬ |
| ìíë±ê¸ | “Në±ê¸(ìíëª )” íì |
| ììì°ì´ì¡(ìµì) | ììì° (ìµì ë¨ì) |
| ììµë¥ (6M), (1Y), (3Y), (5Y), (7Y), (10Y) | 기ê°ë³ ììµë¥ |
| ì¤ì ì¼ | íë ì¤ì ì¼ |
| ë¹ì¨(%) | ì´ë³´ì |
| 1ë í¬ìë¹ì©(ì) | ì°ê° ë¹ì© |
ê´ë ¨ íë¬ê·¸ì¸
| íë¬ê·¸ì¸/ìì´ì í¸ | ìí | ì°ê³ |
|---|---|---|
| portfolio-orchestrator | í¬í¸í´ë¦¬ì¤ ë¶ì ì¤ì¼ì¤í¸ë ì´ì ì¤í¬ | fund_data.json, deposit_rates.json ì ì ë ê²ì¬ |
| fund-portfolio | íë ì¶ì² | fund_data.json, fund_classification.json, deposit_rates.json ì¬ì© |
| compliance-checker | DC ê·ì ê²ì¦ | fund_classification.json, deposit_rates.json ì¬ì© |
| fund-selection-criteria | íë ì í ê¸°ì¤ | deposit_rates.jsonì¼ë¡ ìê¸ vs ì±ê¶ ë¹êµ |
| data-updater | ë°ì´í° ë³í | íì¬ ì¤í¬ |
Resources
ì¤í¬ë¦½í¸ ìì¹
- ë©ì¸ ì¤í¬ë¦½í¸:
scripts/update_fund_data.py(Globì¼ë¡ ì ëê²½ë¡ íë³´ í ì¤í) - ë¶ë¥ ì¤í¬ë¦½í¸:
scripts/classify_funds.py(Globì¼ë¡ ì ëê²½ë¡ íë³´ í ì¤í) - ìì¸ ë¬¸ì:
scripts/README.md
ì±ë¥
- 2,015ê° íë ì²ë¦¬ ìê°: ì½ 1-2ì´
- ë©ëª¨ë¦¬ ì¬ì©ë: ì½ 50MB