contracts-hj3415 0.1.1__py3-none-any.whl → 0.2.0__py3-none-any.whl
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.
- contracts/.DS_Store +0 -0
- contracts/nfs/c101.py +52 -0
- contracts/nfs/c103.py +19 -0
- contracts/nfs/c104.py +24 -0
- contracts/nfs/c106.py +37 -0
- contracts/nfs/c108.py +61 -0
- {contracts_hj3415-0.1.1.dist-info → contracts_hj3415-0.2.0.dist-info}/METADATA +2 -7
- contracts_hj3415-0.2.0.dist-info/RECORD +12 -0
- contracts_hj3415/common/base.py +0 -1
- contracts_hj3415/common/types.py +0 -1
- contracts_hj3415/common.py +0 -25
- contracts_hj3415/events.py +0 -10
- contracts_hj3415/items.py +0 -14
- contracts_hj3415/nfs/__init__.py +0 -0
- contracts_hj3415/nfs/delta.py +0 -0
- contracts_hj3415/nfs/dim_account.py +0 -13
- contracts_hj3415/nfs/dim_period.py +0 -0
- contracts_hj3415/nfs/fact.py +0 -22
- contracts_hj3415/users.py +0 -20
- contracts_hj3415-0.1.1.dist-info/RECORD +0 -17
- {contracts_hj3415 → contracts}/__init__.py +0 -0
- {contracts_hj3415/common → contracts/nfs}/__init__.py +0 -0
- {contracts_hj3415-0.1.1.dist-info → contracts_hj3415-0.2.0.dist-info}/WHEEL +0 -0
- {contracts_hj3415-0.1.1.dist-info → contracts_hj3415-0.2.0.dist-info}/licenses/LICENSE +0 -0
contracts/.DS_Store
ADDED
|
Binary file
|
contracts/nfs/c101.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# contracts/nfs/c101.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class C101DTO(BaseModel):
|
|
9
|
+
# 기본 식별 정보
|
|
10
|
+
종목명: str
|
|
11
|
+
코드: str
|
|
12
|
+
날짜: str
|
|
13
|
+
업종: str
|
|
14
|
+
|
|
15
|
+
# 재무 지표
|
|
16
|
+
eps: Optional[int] = None
|
|
17
|
+
bps: Optional[int] = None
|
|
18
|
+
per: Optional[float] = None
|
|
19
|
+
업종per: Optional[float] = None
|
|
20
|
+
pbr: Optional[float] = None
|
|
21
|
+
배당수익률: Optional[float] = None
|
|
22
|
+
|
|
23
|
+
# 주가 정보
|
|
24
|
+
주가: Optional[int] = None
|
|
25
|
+
전일대비: Optional[int] = None
|
|
26
|
+
수익률: Optional[float] = None
|
|
27
|
+
|
|
28
|
+
최고52: Optional[int] = None
|
|
29
|
+
최저52: Optional[int] = None
|
|
30
|
+
|
|
31
|
+
거래량: Optional[int] = None
|
|
32
|
+
거래대금: Optional[int] = None
|
|
33
|
+
시가총액: Optional[int] = None
|
|
34
|
+
|
|
35
|
+
베타52주: Optional[float] = None
|
|
36
|
+
|
|
37
|
+
발행주식: Optional[int] = None
|
|
38
|
+
유동비율: Optional[float] = None
|
|
39
|
+
외국인지분율: Optional[float] = None
|
|
40
|
+
|
|
41
|
+
# 기간 수익률
|
|
42
|
+
수익률1M: Optional[float] = None
|
|
43
|
+
수익률3M: Optional[float] = None
|
|
44
|
+
수익률6M: Optional[float] = None
|
|
45
|
+
수익률1Y: Optional[float] = None
|
|
46
|
+
|
|
47
|
+
# 텍스트 정보
|
|
48
|
+
개요: str = ""
|
|
49
|
+
|
|
50
|
+
class Config:
|
|
51
|
+
# 한글 필드명을 그대로 쓰기 위한 옵션
|
|
52
|
+
populate_by_name = True
|
contracts/nfs/c103.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# contracts/nfs/c103.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
5
|
+
|
|
6
|
+
Num = float | int | None
|
|
7
|
+
Row = dict[str, Num] # 예: {"2020/12": 1.0, "전년대비": 2.0, ...}
|
|
8
|
+
ItemsMap = dict[str, Row] # 예: {"매출액(수익)": {...}, ...}
|
|
9
|
+
|
|
10
|
+
class C103DTO(BaseModel):
|
|
11
|
+
코드: str
|
|
12
|
+
손익계산서y: ItemsMap = Field(default_factory=dict)
|
|
13
|
+
손익계산서q: ItemsMap = Field(default_factory=dict)
|
|
14
|
+
재무상태표y: ItemsMap = Field(default_factory=dict)
|
|
15
|
+
재무상태표q: ItemsMap = Field(default_factory=dict)
|
|
16
|
+
현금흐름표y: ItemsMap = Field(default_factory=dict)
|
|
17
|
+
현금흐름표q: ItemsMap = Field(default_factory=dict)
|
|
18
|
+
|
|
19
|
+
model_config = ConfigDict(extra="ignore")
|
contracts/nfs/c104.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# contracts/nfs/c104.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
5
|
+
|
|
6
|
+
Num = float | int | None
|
|
7
|
+
Row = dict[str, Num] # 예: {"2020/12": 1.0, "전년대비": 2.0, ...}
|
|
8
|
+
ItemsMap = dict[str, Row] # 예: {"ROE": {...}, ...}
|
|
9
|
+
|
|
10
|
+
class C104DTO(BaseModel):
|
|
11
|
+
코드: str
|
|
12
|
+
수익성y: ItemsMap = Field(default_factory=dict)
|
|
13
|
+
수익성q: ItemsMap = Field(default_factory=dict)
|
|
14
|
+
성장성y: ItemsMap = Field(default_factory=dict)
|
|
15
|
+
성장성q: ItemsMap = Field(default_factory=dict)
|
|
16
|
+
안정성y: ItemsMap = Field(default_factory=dict)
|
|
17
|
+
안정성q: ItemsMap = Field(default_factory=dict)
|
|
18
|
+
활동성y: ItemsMap = Field(default_factory=dict)
|
|
19
|
+
활동성q: ItemsMap = Field(default_factory=dict)
|
|
20
|
+
가치분석y: ItemsMap = Field(default_factory=dict)
|
|
21
|
+
가치분석q: ItemsMap = Field(default_factory=dict)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
model_config = ConfigDict(extra="ignore")
|
contracts/nfs/c106.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# contracts/nfs/c106.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, Field, ConfigDict
|
|
5
|
+
|
|
6
|
+
NumMap = dict[str, float | None]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class C106Block(BaseModel):
|
|
10
|
+
전일종가: NumMap = Field(default_factory=dict)
|
|
11
|
+
시가총액: NumMap = Field(default_factory=dict)
|
|
12
|
+
자산총계: NumMap = Field(default_factory=dict)
|
|
13
|
+
부채총계: NumMap = Field(default_factory=dict)
|
|
14
|
+
|
|
15
|
+
매출액: NumMap = Field(default_factory=dict)
|
|
16
|
+
영업이익: NumMap = Field(default_factory=dict)
|
|
17
|
+
당기순이익: NumMap = Field(default_factory=dict)
|
|
18
|
+
당기순이익_지배: NumMap = Field(default_factory=dict)
|
|
19
|
+
|
|
20
|
+
영업이익률: NumMap = Field(default_factory=dict)
|
|
21
|
+
순이익률: NumMap = Field(default_factory=dict)
|
|
22
|
+
ROE: NumMap = Field(default_factory=dict)
|
|
23
|
+
부채비율: NumMap = Field(default_factory=dict)
|
|
24
|
+
|
|
25
|
+
PER: NumMap = Field(default_factory=dict)
|
|
26
|
+
PBR: NumMap = Field(default_factory=dict)
|
|
27
|
+
|
|
28
|
+
투자의견: NumMap = Field(default_factory=dict)
|
|
29
|
+
목표주가: NumMap = Field(default_factory=dict)
|
|
30
|
+
|
|
31
|
+
model_config = ConfigDict(extra="ignore")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class C106DTO(BaseModel):
|
|
35
|
+
코드: str
|
|
36
|
+
q: C106Block
|
|
37
|
+
y: C106Block
|
contracts/nfs/c108.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import math
|
|
2
|
+
from pydantic import BaseModel, field_validator
|
|
3
|
+
from typing import List, Optional, Any
|
|
4
|
+
import re
|
|
5
|
+
|
|
6
|
+
class C108DTO(BaseModel):
|
|
7
|
+
코드: str
|
|
8
|
+
날짜: Optional[str]
|
|
9
|
+
제목: str
|
|
10
|
+
작성자: Optional[str]
|
|
11
|
+
제공처: Optional[str]
|
|
12
|
+
투자의견: Optional[str]
|
|
13
|
+
목표가: Optional[float]
|
|
14
|
+
분량: Optional[str]
|
|
15
|
+
내용: List[str]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@field_validator("투자의견", mode="before")
|
|
19
|
+
@classmethod
|
|
20
|
+
def _coerce_opinion(cls, v):
|
|
21
|
+
# pandas/bs4 parsing sometimes yields float('nan') for empty cells
|
|
22
|
+
if v is None:
|
|
23
|
+
return None
|
|
24
|
+
if isinstance(v, float) and math.isnan(v):
|
|
25
|
+
return None
|
|
26
|
+
if isinstance(v, str):
|
|
27
|
+
s = v.strip()
|
|
28
|
+
if not s or s.lower() == "nan" or s in {"-", "N/A", "NA"}:
|
|
29
|
+
return None
|
|
30
|
+
return s
|
|
31
|
+
# Any other type -> string fallback (keeps validation tolerant)
|
|
32
|
+
return str(v)
|
|
33
|
+
|
|
34
|
+
@field_validator("목표가", mode="before")
|
|
35
|
+
@classmethod
|
|
36
|
+
def _v_target_price(cls, v: Any):
|
|
37
|
+
if v is None:
|
|
38
|
+
return None
|
|
39
|
+
|
|
40
|
+
# nan 방어
|
|
41
|
+
if isinstance(v, float) and math.isnan(v):
|
|
42
|
+
return None
|
|
43
|
+
|
|
44
|
+
# 안내 문구/결측 문자열 방어
|
|
45
|
+
if isinstance(v, str):
|
|
46
|
+
s = v.strip()
|
|
47
|
+
if not s or s in {"-", "N/A"} or "검색된 데이터가 없습니다" in s:
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
# "123,456원" 같은 케이스에서 숫자만 추출
|
|
51
|
+
m = re.findall(r"\d+(?:,\d+)*", s)
|
|
52
|
+
if not m:
|
|
53
|
+
return None
|
|
54
|
+
return float(m[0].replace(",", ""))
|
|
55
|
+
|
|
56
|
+
# 숫자면 그대로 float로
|
|
57
|
+
if isinstance(v, (int, float)):
|
|
58
|
+
return float(v)
|
|
59
|
+
|
|
60
|
+
# 그 외 타입은 None 처리(또는 raise로 엄격하게)
|
|
61
|
+
return None
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: contracts-hj3415
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: DTO pakages for hj3415
|
|
5
5
|
Keywords: example,demo
|
|
6
6
|
Author-email: Hyungjin Kim <hj3415@gmail.com>
|
|
7
7
|
Requires-Python: >=3.11
|
|
@@ -11,10 +11,5 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
11
11
|
Classifier: Typing :: Typed
|
|
12
12
|
License-File: LICENSE
|
|
13
13
|
Requires-Dist: pydantic>=2.7
|
|
14
|
-
Requires-Dist: pytest>=8 ; extra == "dev"
|
|
15
|
-
Requires-Dist: pytest-cov>=7.0 ; extra == "dev"
|
|
16
|
-
Requires-Dist: ruff>=0.5 ; extra == "dev"
|
|
17
|
-
Requires-Dist: mypy>=1.10 ; extra == "dev"
|
|
18
|
-
Provides-Extra: dev
|
|
19
14
|
|
|
20
15
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
contracts/.DS_Store,sha256=Xf_I-6KjIMtAPAfhql2fkvFbFFnxThECsUIUP4jzjcw,6148
|
|
2
|
+
contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
contracts/nfs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
contracts/nfs/c101.py,sha256=W5i_D7Icve6E_2sqtees-tm6WWC8nLh9-ZsVIlvRrZY,1301
|
|
5
|
+
contracts/nfs/c103.py,sha256=6toVW_FE2xHgajg-6PDzUyaEcJt3T6uxi6Kjjk9Y710,756
|
|
6
|
+
contracts/nfs/c104.py,sha256=y8f133MN0dVreRefMXltk_60CNz1ZFszxuAE02P5wRk,933
|
|
7
|
+
contracts/nfs/c106.py,sha256=s96kPOBB1QiBGkE8jGKki1wsTBgXx7EOvF-1t3_5Q8I,1168
|
|
8
|
+
contracts/nfs/c108.py,sha256=vNjq_TrBTdlJO_L6hgwZ1IUNAzjDSPFVWqO6_pKz7Ds,1816
|
|
9
|
+
contracts_hj3415-0.2.0.dist-info/licenses/LICENSE,sha256=QBiVGQuKAESeCfQE344Ik2ex6g2zfYdu9WqrRWydxIs,1068
|
|
10
|
+
contracts_hj3415-0.2.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
11
|
+
contracts_hj3415-0.2.0.dist-info/METADATA,sha256=m5qPOSW5Gs5vtGnnr4a7PLHxzSyYhbiWa0IZGwOoKE8,405
|
|
12
|
+
contracts_hj3415-0.2.0.dist-info/RECORD,,
|
contracts_hj3415/common/base.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# Base DTO, mixins, timestamp helpers
|
contracts_hj3415/common/types.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# Literal, Enum 정의 등
|
contracts_hj3415/common.py
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
#src/contracts_hj3415/common.py — 공용 타입, 베이스 모델, Enum 등
|
|
2
|
-
|
|
3
|
-
from datetime import datetime
|
|
4
|
-
from uuid import UUID, uuid4
|
|
5
|
-
from enum import Enum
|
|
6
|
-
from pydantic import BaseModel, Field
|
|
7
|
-
|
|
8
|
-
class IDModel(BaseModel):
|
|
9
|
-
id: UUID = Field(default_factory=uuid4)
|
|
10
|
-
|
|
11
|
-
class TimestampMixin(BaseModel):
|
|
12
|
-
created_at: datetime = Field(default_factory=datetime.utcnow)
|
|
13
|
-
updated_at: datetime | None = None
|
|
14
|
-
|
|
15
|
-
class UserRole(str, Enum):
|
|
16
|
-
ADMIN = "admin"
|
|
17
|
-
STAFF = "staff"
|
|
18
|
-
CUSTOMER = "customer"
|
|
19
|
-
|
|
20
|
-
# 공통 BaseModel
|
|
21
|
-
class ContractModel(BaseModel):
|
|
22
|
-
class Config:
|
|
23
|
-
orm_mode = True
|
|
24
|
-
extra = "forbid"
|
|
25
|
-
from_attributes = True
|
contracts_hj3415/events.py
DELETED
contracts_hj3415/items.py
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#src/contracts_hj3415/items.py — 아이템 관련 DTO
|
|
2
|
-
|
|
3
|
-
from datetime import datetime
|
|
4
|
-
from .common import IDModel, ContractModel
|
|
5
|
-
|
|
6
|
-
class ItemBase(ContractModel):
|
|
7
|
-
name: str
|
|
8
|
-
description: str | None = None
|
|
9
|
-
|
|
10
|
-
class ItemCreate(ItemBase):
|
|
11
|
-
pass
|
|
12
|
-
|
|
13
|
-
class ItemRead(IDModel, ItemBase):
|
|
14
|
-
created_at: datetime
|
contracts_hj3415/nfs/__init__.py
DELETED
|
File without changes
|
contracts_hj3415/nfs/delta.py
DELETED
|
File without changes
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# contracts_hj3415/nfs/dim_account.py
|
|
2
|
-
from pydantic import BaseModel
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
|
-
class DimAccountDTO(BaseModel):
|
|
6
|
-
accode: str
|
|
7
|
-
account_name: str
|
|
8
|
-
level: Optional[int] = None
|
|
9
|
-
parent_accode: Optional[str] = None
|
|
10
|
-
group_type: Optional[int] = None
|
|
11
|
-
unit_type: Optional[int] = None
|
|
12
|
-
acc_kind: Optional[str] = None
|
|
13
|
-
precision: Optional[int] = None
|
|
File without changes
|
contracts_hj3415/nfs/fact.py
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# contracts_hj3415/nfs/fact.py
|
|
2
|
-
from pydantic import BaseModel, Field
|
|
3
|
-
from datetime import date
|
|
4
|
-
from typing import Optional
|
|
5
|
-
|
|
6
|
-
class FactFinanceDTO(BaseModel):
|
|
7
|
-
cmp_cd: str
|
|
8
|
-
page: str
|
|
9
|
-
rpt: str
|
|
10
|
-
frq: str
|
|
11
|
-
accode: str
|
|
12
|
-
account_name: str
|
|
13
|
-
period: date
|
|
14
|
-
value: float
|
|
15
|
-
basis: Optional[str] = None
|
|
16
|
-
is_estimate: bool = False
|
|
17
|
-
unit_type: Optional[int] = None
|
|
18
|
-
level: Optional[int] = None
|
|
19
|
-
parent_accode: Optional[str] = None
|
|
20
|
-
group_type: Optional[int] = None
|
|
21
|
-
acc_kind: Optional[str] = None
|
|
22
|
-
precision: Optional[int] = None
|
contracts_hj3415/users.py
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#src/contracts_hj3415/users.py — 사용자 관련 DTO
|
|
2
|
-
|
|
3
|
-
from datetime import datetime
|
|
4
|
-
from pydantic import BaseModel, EmailStr
|
|
5
|
-
from .common import IDModel, ContractModel, UserRole
|
|
6
|
-
|
|
7
|
-
class UserBase(ContractModel):
|
|
8
|
-
email: EmailStr
|
|
9
|
-
nickname: str | None = None
|
|
10
|
-
role: UserRole = UserRole.CUSTOMER
|
|
11
|
-
|
|
12
|
-
class UserCreate(UserBase):
|
|
13
|
-
password: str
|
|
14
|
-
|
|
15
|
-
class UserUpdate(BaseModel):
|
|
16
|
-
nickname: str | None = None
|
|
17
|
-
role: UserRole | None = None
|
|
18
|
-
|
|
19
|
-
class UserRead(IDModel, UserBase):
|
|
20
|
-
created_at: datetime
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
contracts_hj3415/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
contracts_hj3415/common.py,sha256=VDTSWDTYBC2kNX-GsogN3uualTUq5MMJ_rlGI_7RrPM,651
|
|
3
|
-
contracts_hj3415/events.py,sha256=vQ14lksEsINW4Ud9sPbLj9ipDhoatWv4wYNU3E3zt9E,262
|
|
4
|
-
contracts_hj3415/items.py,sha256=5f6KXoENO6iTPvXobZOZM8jjndBf6tXph0-HEgcMzOI,309
|
|
5
|
-
contracts_hj3415/users.py,sha256=PlKWqvJMdjleZRSmvkvZrMpUG_3qmofR791I6i_jFog,506
|
|
6
|
-
contracts_hj3415/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
contracts_hj3415/common/base.py,sha256=Iy0_CapYGG9w2FHOVorOyS0Ju8Kk6Yd5HU6nVZZ7SXw,37
|
|
8
|
-
contracts_hj3415/common/types.py,sha256=jzcc0XiP8Nd9QzBucWswQwOHP0UcV_TQyC2pffFScMs,26
|
|
9
|
-
contracts_hj3415/nfs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
contracts_hj3415/nfs/delta.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
contracts_hj3415/nfs/dim_account.py,sha256=DWjDi5exdcTSVy3r3vIV0jaFIVUOHGUJocXPNHxMnoQ,383
|
|
12
|
-
contracts_hj3415/nfs/dim_period.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
contracts_hj3415/nfs/fact.py,sha256=_Bq7jW-l7eDpcs4gS2BYPlTX9MGKXFn-F7HozfVcgek,562
|
|
14
|
-
contracts_hj3415-0.1.1.dist-info/licenses/LICENSE,sha256=QBiVGQuKAESeCfQE344Ik2ex6g2zfYdu9WqrRWydxIs,1068
|
|
15
|
-
contracts_hj3415-0.1.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
16
|
-
contracts_hj3415-0.1.1.dist-info/METADATA,sha256=EgkvOLZuM0bRdIkDAsvloWh_Sa-M9kUzSzjaPiTaqdA,600
|
|
17
|
-
contracts_hj3415-0.1.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|