hipowork-cli 0.3.2__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/PKG-INFO +5 -2
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/README.md +4 -1
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/pyproject.toml +1 -1
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/__init__.py +2 -0
- hipowork_cli-0.3.3/src/hipowork_cli/scripts/hipo_company.py +103 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_mcp_client.py +26 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_publish_job.py +2 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_resume_validate.py +9 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli.egg-info/PKG-INFO +5 -2
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli.egg-info/SOURCES.txt +1 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/setup.cfg +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/__main__.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/examples/job.example.json +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/examples/resume.example.json +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_accounts.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_auth.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_authorize.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_close_job.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_e2e.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_healthcheck.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_market.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_match_candidates.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_match_jobs.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_resume_extract.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_resume_import.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_search_candidates.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_stats.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_token_refresh.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_token_status.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_token_sync.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/templates/success.html +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli.egg-info/dependency_links.txt +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli.egg-info/entry_points.txt +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli.egg-info/requires.txt +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli.egg-info/top_level.txt +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/tests/test_hipo_accounts.py +0 -0
- {hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/tests/test_hipo_resume_import.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hipowork-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: HiPo Work CLI — Agent 友好的招聘平台命令行工具集(OAuth 授权 / 岗位发布 / 候选人匹配 / 简历导入)
|
|
5
5
|
Author-email: Lin Tong <sexylin2010@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -158,7 +158,10 @@ hipo search "成都 5年经验 熟悉Solidity和Go的全栈"
|
|
|
158
158
|
### 招聘方(Employer)
|
|
159
159
|
| 命令 | 说明 |
|
|
160
160
|
|---|---|
|
|
161
|
-
| `hipo
|
|
161
|
+
| `hipo company create --name "公司名" [--desc "简介"] [--default]` | 创建企业主体信息(支持设置默认企业) |
|
|
162
|
+
| `hipo company set-default <company_id>` | 将指定企业主体设为默认企业 |
|
|
163
|
+
| `hipo company list` | 查看当前招聘方名下的所有企业主体列表及默认企业 |
|
|
164
|
+
| `hipo publish-job --title x --text "..." [--salary-currency USDT] [--json file]` | 发布招聘需求(支持多币种 CNY/USDT/USD/EUR/GBP/AUD/SGD、结构化条件与面议设置) |
|
|
162
165
|
| `hipo close-job <job_id>` | 关闭已发布的职位(关闭后不再被候选人检索或参与匹配) |
|
|
163
166
|
| `hipo search "自然语言描述" [--max n]` | 自然语言直接检索候选人人格与经历 |
|
|
164
167
|
| `hipo match-candidates --text "..." / --json cond.json / --job <id>` | 结构化多维度候选人匹配(支持技能硬过滤与向量语义检索) |
|
|
@@ -125,7 +125,10 @@ hipo search "成都 5年经验 熟悉Solidity和Go的全栈"
|
|
|
125
125
|
### 招聘方(Employer)
|
|
126
126
|
| 命令 | 说明 |
|
|
127
127
|
|---|---|
|
|
128
|
-
| `hipo
|
|
128
|
+
| `hipo company create --name "公司名" [--desc "简介"] [--default]` | 创建企业主体信息(支持设置默认企业) |
|
|
129
|
+
| `hipo company set-default <company_id>` | 将指定企业主体设为默认企业 |
|
|
130
|
+
| `hipo company list` | 查看当前招聘方名下的所有企业主体列表及默认企业 |
|
|
131
|
+
| `hipo publish-job --title x --text "..." [--salary-currency USDT] [--json file]` | 发布招聘需求(支持多币种 CNY/USDT/USD/EUR/GBP/AUD/SGD、结构化条件与面议设置) |
|
|
129
132
|
| `hipo close-job <job_id>` | 关闭已发布的职位(关闭后不再被候选人检索或参与匹配) |
|
|
130
133
|
| `hipo search "自然语言描述" [--max n]` | 自然语言直接检索候选人人格与经历 |
|
|
131
134
|
| `hipo match-candidates --text "..." / --json cond.json / --job <id>` | 结构化多维度候选人匹配(支持技能硬过滤与向量语义检索) |
|
|
@@ -28,6 +28,7 @@ COMMANDS = {
|
|
|
28
28
|
"token-sync": "hipo_token_sync",
|
|
29
29
|
"accounts": "hipo_accounts",
|
|
30
30
|
"match-jobs": "hipo_match_jobs",
|
|
31
|
+
"company": "hipo_company",
|
|
31
32
|
"publish-job": "hipo_publish_job",
|
|
32
33
|
"close-job": "hipo_close_job",
|
|
33
34
|
"search": "hipo_search_candidates",
|
|
@@ -50,6 +51,7 @@ HELP = {
|
|
|
50
51
|
"token-sync": "导出 token 到浏览器 localStorage(4 个 base64)",
|
|
51
52
|
"accounts": "多账户管理(list/switch/delete)",
|
|
52
53
|
"match-jobs": "求职者:匹配岗位",
|
|
54
|
+
"company": "招聘方:企业主体管理(创建/设为默认/查询)",
|
|
53
55
|
"publish-job": "招聘方:发布岗位",
|
|
54
56
|
"close-job": "招聘方:关闭已发布的岗位",
|
|
55
57
|
"search": "招聘方:自然语言搜索候选人",
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""招聘方:管理企业主体信息(创建公司、指定默认公司、查询公司列表)。
|
|
2
|
+
|
|
3
|
+
用法:
|
|
4
|
+
hipo company list
|
|
5
|
+
hipo company create --name "成都灵羽科技" --desc "专注 AI Agent 基础设施研发" [--default]
|
|
6
|
+
hipo company set-default <company_id>
|
|
7
|
+
"""
|
|
8
|
+
import argparse
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
from hipo_auth import TokenStore, require_py310
|
|
12
|
+
from hipo_mcp_client import HipiError, check_role, create_company, list_companies, print_json, set_default_company
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def main() -> int:
|
|
16
|
+
require_py310()
|
|
17
|
+
parser = argparse.ArgumentParser(description="招聘方:企业主体信息管理")
|
|
18
|
+
subparsers = parser.add_subparsers(dest="subcommand", help="子命令")
|
|
19
|
+
|
|
20
|
+
# list
|
|
21
|
+
sub_list = subparsers.add_parser("list", help="查看所有企业主体")
|
|
22
|
+
sub_list.add_argument("--account", default=None, help="账户 ID")
|
|
23
|
+
sub_list.add_argument("--file", default=None, help="token 仓库文件路径")
|
|
24
|
+
sub_list.add_argument("--json-out", action="store_true", help="输出原始 JSON 响应")
|
|
25
|
+
|
|
26
|
+
# create
|
|
27
|
+
sub_create = subparsers.add_parser("create", help="创建企业主体")
|
|
28
|
+
sub_create.add_argument("--name", required=True, help="公司名称")
|
|
29
|
+
sub_create.add_argument("--desc", default="", help="公司简介")
|
|
30
|
+
sub_create.add_argument("--default", action="store_true", help="是否设为默认企业主体")
|
|
31
|
+
sub_create.add_argument("--account", default=None, help="账户 ID")
|
|
32
|
+
sub_create.add_argument("--file", default=None, help="token 仓库文件路径")
|
|
33
|
+
sub_create.add_argument("--json-out", action="store_true", help="输出原始 JSON 响应")
|
|
34
|
+
|
|
35
|
+
# set-default
|
|
36
|
+
sub_default = subparsers.add_parser("set-default", help="指定默认企业主体")
|
|
37
|
+
sub_default.add_argument("company_id", help="企业主体 ID")
|
|
38
|
+
sub_default.add_argument("--account", default=None, help="账户 ID")
|
|
39
|
+
sub_default.add_argument("--file", default=None, help="token 仓库文件路径")
|
|
40
|
+
sub_default.add_argument("--json-out", action="store_true", help="输出原始 JSON 响应")
|
|
41
|
+
|
|
42
|
+
args = parser.parse_args()
|
|
43
|
+
if not args.subcommand:
|
|
44
|
+
parser.print_help()
|
|
45
|
+
return 2
|
|
46
|
+
|
|
47
|
+
store = TokenStore(args.file)
|
|
48
|
+
role = check_role(store, args.account)
|
|
49
|
+
if role and role != "employer":
|
|
50
|
+
print(f"⚠️ 当前账户角色是 {role},企业管理是招聘方(employer)功能。", file=sys.stderr)
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
if args.subcommand == "list":
|
|
54
|
+
resp = list_companies(store=store, account_id=args.account)
|
|
55
|
+
if args.json_out:
|
|
56
|
+
print_json(resp)
|
|
57
|
+
else:
|
|
58
|
+
companies = resp.get("companies", [])
|
|
59
|
+
print(f"🏢 名下共 {len(companies)} 个企业主体:\n")
|
|
60
|
+
for c in companies:
|
|
61
|
+
default_tag = "【默认】" if c.get("is_default") else ""
|
|
62
|
+
print(f"- {c.get('company_name')} {default_tag}")
|
|
63
|
+
print(f" ID: {c.get('id')}")
|
|
64
|
+
if c.get("description"):
|
|
65
|
+
print(f" 简介: {c.get('description')}")
|
|
66
|
+
print()
|
|
67
|
+
|
|
68
|
+
elif args.subcommand == "create":
|
|
69
|
+
resp = create_company(
|
|
70
|
+
company_name=args.name,
|
|
71
|
+
description=args.desc,
|
|
72
|
+
is_default=args.default,
|
|
73
|
+
store=store,
|
|
74
|
+
account_id=args.account,
|
|
75
|
+
)
|
|
76
|
+
if args.json_out:
|
|
77
|
+
print_json(resp)
|
|
78
|
+
else:
|
|
79
|
+
c = resp.get("company", {})
|
|
80
|
+
print(f"✅ 公司创建成功: {c.get('company_name')}")
|
|
81
|
+
print(f" ID: {c.get('id')}")
|
|
82
|
+
print(f" 默认: {'是' if c.get('is_default') else '否'}")
|
|
83
|
+
|
|
84
|
+
elif args.subcommand == "set-default":
|
|
85
|
+
resp = set_default_company(
|
|
86
|
+
company_id=args.company_id,
|
|
87
|
+
store=store,
|
|
88
|
+
account_id=args.account,
|
|
89
|
+
)
|
|
90
|
+
if args.json_out:
|
|
91
|
+
print_json(resp)
|
|
92
|
+
else:
|
|
93
|
+
c = resp.get("company", {})
|
|
94
|
+
print(f"✅ 已成功将「{c.get('company_name')}」设为默认企业主体")
|
|
95
|
+
|
|
96
|
+
return 0
|
|
97
|
+
except HipiError as exc:
|
|
98
|
+
print(f"❌ 操作失败: {exc}", file=sys.stderr)
|
|
99
|
+
return 1
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
if __name__ == "__main__":
|
|
103
|
+
sys.exit(main())
|
|
@@ -86,9 +86,34 @@ def match_jobs_for_me(store: TokenStore | None = None, account_id: str | None =
|
|
|
86
86
|
return data if raw else _summarize_job_matches(data)
|
|
87
87
|
|
|
88
88
|
|
|
89
|
+
def create_company(company_name: str, description: str = "", is_default: bool = False,
|
|
90
|
+
store: TokenStore | None = None, account_id: str | None = None) -> dict:
|
|
91
|
+
"""招聘方:创建公司信息(POST /agent/create-company)。"""
|
|
92
|
+
token = get_access_token(store, account_id)
|
|
93
|
+
return _req("POST", "/agent/create-company", token=token, body={
|
|
94
|
+
"company_name": company_name,
|
|
95
|
+
"description": description or "",
|
|
96
|
+
"is_default": bool(is_default),
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def set_default_company(company_id: str,
|
|
101
|
+
store: TokenStore | None = None, account_id: str | None = None) -> dict:
|
|
102
|
+
"""招聘方:指定默认公司(POST /agent/set-default-company)。"""
|
|
103
|
+
token = get_access_token(store, account_id)
|
|
104
|
+
return _req("POST", "/agent/set-default-company", token=token, body={"company_id": company_id})
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def list_companies(store: TokenStore | None = None, account_id: str | None = None) -> dict:
|
|
108
|
+
"""招聘方:查询名下所有公司(GET /agent/list-companies)。"""
|
|
109
|
+
token = get_access_token(store, account_id)
|
|
110
|
+
return _req("GET", "/agent/list-companies", token=token)
|
|
111
|
+
|
|
112
|
+
|
|
89
113
|
def publish_job(title: str, required: list | None = None, preferred: dict | None = None,
|
|
90
114
|
raw_text: str = "", salary_min: int | None = None,
|
|
91
115
|
salary_max: int | None = None, salary_unit: str | None = "monthly",
|
|
116
|
+
salary_currency: str | None = "CNY",
|
|
92
117
|
benefits: list | None = None,
|
|
93
118
|
store: TokenStore | None = None, account_id: str | None = None) -> dict:
|
|
94
119
|
"""招聘方:发布结构化岗位(POST /agent/publish-job)。
|
|
@@ -107,6 +132,7 @@ def publish_job(title: str, required: list | None = None, preferred: dict | None
|
|
|
107
132
|
"salary_min": salary_min,
|
|
108
133
|
"salary_max": salary_max,
|
|
109
134
|
"salary_unit": effective_unit,
|
|
135
|
+
"salary_currency": salary_currency or "CNY",
|
|
110
136
|
"benefits": benefits or [],
|
|
111
137
|
}
|
|
112
138
|
return _req("POST", "/agent/publish-job", token=token, body=body)
|
|
@@ -42,6 +42,7 @@ def main() -> int:
|
|
|
42
42
|
parser.add_argument("--salary-min", type=int, default=None, help="月薪下限(k)")
|
|
43
43
|
parser.add_argument("--salary-max", type=int, default=None, help="月薪上限(k)")
|
|
44
44
|
parser.add_argument("--salary-unit", choices=["monthly", "yearly"], default=None, help="薪资单位(缺省时取 JSON 的 salary_unit,再无则 monthly)")
|
|
45
|
+
parser.add_argument("--salary-currency", choices=["CNY", "USDT", "USD", "EUR", "GBP", "AUD", "SGD"], default=None, help="计价币种(CNY/USDT/USD/EUR/GBP/AUD/SGD,默认CNY)")
|
|
45
46
|
parser.add_argument("--benefit", action="append", default=[], help="福利标签(可重复)")
|
|
46
47
|
parser.add_argument("--account", default=None, help="账户 ID")
|
|
47
48
|
parser.add_argument("--file", default=None, help="token 仓库文件路径")
|
|
@@ -76,6 +77,7 @@ def main() -> int:
|
|
|
76
77
|
# 修复:CLI 未显式传 --salary-unit 时回退到 JSON 的 salary_unit,再无则 monthly。
|
|
77
78
|
# 此前只传 args.salary_unit(默认 monthly),JSON 里的 yearly 被静默丢弃。
|
|
78
79
|
salary_unit=args.salary_unit or job_data.get("salary_unit") or "monthly",
|
|
80
|
+
salary_currency=args.salary_currency or job_data.get("salary_currency") or "CNY",
|
|
79
81
|
benefits=args.benefit or job_data.get("benefits") or None,
|
|
80
82
|
store=store,
|
|
81
83
|
account_id=args.account,
|
|
@@ -200,6 +200,15 @@ def validate(resume: dict, strict: bool = False) -> Report:
|
|
|
200
200
|
f"第 {[i + 1 for i in missing_duration]} 段工作经历缺少 duration_months,"
|
|
201
201
|
"会导致经验年限(experience_years)不累计、岗位匹配经验分(0-30)拿不到",
|
|
202
202
|
)
|
|
203
|
+
# role 缺失提醒(前端显示"未填写职位",后端会自动推断占位但建议显式提供)
|
|
204
|
+
missing_role = [i for i, w in enumerate(works[:WORK_MAX_ITEMS])
|
|
205
|
+
if isinstance(w, dict) and not w.get("role")]
|
|
206
|
+
if missing_role:
|
|
207
|
+
report.warn(
|
|
208
|
+
"work_experiences",
|
|
209
|
+
f"第 {[i + 1 for i in missing_role]} 段工作经历缺少 role(岗位头衔),"
|
|
210
|
+
"前端将显示后端推断的占位头衔(如'工程师'),建议显式填写以保证准确",
|
|
211
|
+
)
|
|
203
212
|
|
|
204
213
|
skills = resume.get("skills") or []
|
|
205
214
|
if isinstance(skills, list) and not skills:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hipowork-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: HiPo Work CLI — Agent 友好的招聘平台命令行工具集(OAuth 授权 / 岗位发布 / 候选人匹配 / 简历导入)
|
|
5
5
|
Author-email: Lin Tong <sexylin2010@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -158,7 +158,10 @@ hipo search "成都 5年经验 熟悉Solidity和Go的全栈"
|
|
|
158
158
|
### 招聘方(Employer)
|
|
159
159
|
| 命令 | 说明 |
|
|
160
160
|
|---|---|
|
|
161
|
-
| `hipo
|
|
161
|
+
| `hipo company create --name "公司名" [--desc "简介"] [--default]` | 创建企业主体信息(支持设置默认企业) |
|
|
162
|
+
| `hipo company set-default <company_id>` | 将指定企业主体设为默认企业 |
|
|
163
|
+
| `hipo company list` | 查看当前招聘方名下的所有企业主体列表及默认企业 |
|
|
164
|
+
| `hipo publish-job --title x --text "..." [--salary-currency USDT] [--json file]` | 发布招聘需求(支持多币种 CNY/USDT/USD/EUR/GBP/AUD/SGD、结构化条件与面议设置) |
|
|
162
165
|
| `hipo close-job <job_id>` | 关闭已发布的职位(关闭后不再被候选人检索或参与匹配) |
|
|
163
166
|
| `hipo search "自然语言描述" [--max n]` | 自然语言直接检索候选人人格与经历 |
|
|
164
167
|
| `hipo match-candidates --text "..." / --json cond.json / --job <id>` | 结构化多维度候选人匹配(支持技能硬过滤与向量语义检索) |
|
|
@@ -14,6 +14,7 @@ src/hipowork_cli/scripts/hipo_accounts.py
|
|
|
14
14
|
src/hipowork_cli/scripts/hipo_auth.py
|
|
15
15
|
src/hipowork_cli/scripts/hipo_authorize.py
|
|
16
16
|
src/hipowork_cli/scripts/hipo_close_job.py
|
|
17
|
+
src/hipowork_cli/scripts/hipo_company.py
|
|
17
18
|
src/hipowork_cli/scripts/hipo_e2e.py
|
|
18
19
|
src/hipowork_cli/scripts/hipo_healthcheck.py
|
|
19
20
|
src/hipowork_cli/scripts/hipo_market.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hipowork_cli-0.3.2 → hipowork_cli-0.3.3}/src/hipowork_cli/scripts/hipo_search_candidates.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|