zlgcan 0.1.16__tar.gz → 0.2.0__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.
- {zlgcan-0.1.16 → zlgcan-0.2.0}/.github/workflows/CI.yml +2 -2
- {zlgcan-0.1.16 → zlgcan-0.2.0}/Cargo.lock +19 -26
- {zlgcan-0.1.16 → zlgcan-0.2.0}/Cargo.toml +3 -3
- {zlgcan-0.1.16 → zlgcan-0.2.0}/PKG-INFO +20 -28
- {zlgcan-0.1.16 → zlgcan-0.2.0}/README.md +19 -27
- {zlgcan-0.1.16 → zlgcan-0.2.0}/src/lib.rs +9 -11
- {zlgcan-0.1.16 → zlgcan-0.2.0}/zlgcan/zlgcan.py +6 -2
- {zlgcan-0.1.16 → zlgcan-0.2.0}/.editorconfig +0 -0
- {zlgcan-0.1.16 → zlgcan-0.2.0}/.github/workflows/label-check.yml +0 -0
- {zlgcan-0.1.16 → zlgcan-0.2.0}/.gitignore +0 -0
- {zlgcan-0.1.16 → zlgcan-0.2.0}/LICENSE.txt +0 -0
- {zlgcan-0.1.16 → zlgcan-0.2.0}/pyproject.toml +0 -0
- {zlgcan-0.1.16 → zlgcan-0.2.0}/requirements.txt +0 -0
- {zlgcan-0.1.16 → zlgcan-0.2.0}/src/wrappers/constants.rs +0 -0
- {zlgcan-0.1.16 → zlgcan-0.2.0}/src/wrappers/mod.rs +0 -0
- {zlgcan-0.1.16 → zlgcan-0.2.0}/zlgcan/__init__.py +0 -0
@@ -93,8 +93,8 @@ jobs:
|
|
93
93
|
- name: Publish to PyPI
|
94
94
|
uses: PyO3/maturin-action@v1
|
95
95
|
env:
|
96
|
-
MATURIN_PYPI_TOKEN: ${{ secrets.
|
96
|
+
MATURIN_PYPI_TOKEN: ${{ secrets.ZLGCAN_TOKEN }}
|
97
97
|
with:
|
98
|
-
token: ${{ secrets.
|
98
|
+
token: ${{ secrets.ZLGCAN_TOKEN }}
|
99
99
|
command: upload
|
100
100
|
args: --non-interactive --skip-existing wheels-*/*
|
@@ -60,12 +60,6 @@ dependencies = [
|
|
60
60
|
"syn",
|
61
61
|
]
|
62
62
|
|
63
|
-
[[package]]
|
64
|
-
name = "dotenvy"
|
65
|
-
version = "0.15.7"
|
66
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
67
|
-
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
68
|
-
|
69
63
|
[[package]]
|
70
64
|
name = "equivalent"
|
71
65
|
version = "1.0.2"
|
@@ -86,9 +80,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
86
80
|
|
87
81
|
[[package]]
|
88
82
|
name = "indexmap"
|
89
|
-
version = "2.
|
83
|
+
version = "2.9.0"
|
90
84
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
91
|
-
checksum = "
|
85
|
+
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
92
86
|
dependencies = [
|
93
87
|
"equivalent",
|
94
88
|
"hashbrown",
|
@@ -129,9 +123,9 @@ dependencies = [
|
|
129
123
|
|
130
124
|
[[package]]
|
131
125
|
name = "once_cell"
|
132
|
-
version = "1.21.
|
126
|
+
version = "1.21.3"
|
133
127
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
134
|
-
checksum = "
|
128
|
+
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
135
129
|
|
136
130
|
[[package]]
|
137
131
|
name = "portable-atomic"
|
@@ -150,9 +144,9 @@ dependencies = [
|
|
150
144
|
|
151
145
|
[[package]]
|
152
146
|
name = "pyo3"
|
153
|
-
version = "0.24.
|
147
|
+
version = "0.24.1"
|
154
148
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
155
|
-
checksum = "
|
149
|
+
checksum = "17da310086b068fbdcefbba30aeb3721d5bb9af8db4987d6735b2183ca567229"
|
156
150
|
dependencies = [
|
157
151
|
"cfg-if",
|
158
152
|
"indoc",
|
@@ -168,9 +162,9 @@ dependencies = [
|
|
168
162
|
|
169
163
|
[[package]]
|
170
164
|
name = "pyo3-build-config"
|
171
|
-
version = "0.24.
|
165
|
+
version = "0.24.1"
|
172
166
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
173
|
-
checksum = "
|
167
|
+
checksum = "e27165889bd793000a098bb966adc4300c312497ea25cf7a690a9f0ac5aa5fc1"
|
174
168
|
dependencies = [
|
175
169
|
"once_cell",
|
176
170
|
"target-lexicon",
|
@@ -178,9 +172,9 @@ dependencies = [
|
|
178
172
|
|
179
173
|
[[package]]
|
180
174
|
name = "pyo3-ffi"
|
181
|
-
version = "0.24.
|
175
|
+
version = "0.24.1"
|
182
176
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
183
|
-
checksum = "
|
177
|
+
checksum = "05280526e1dbf6b420062f3ef228b78c0c54ba94e157f5cb724a609d0f2faabc"
|
184
178
|
dependencies = [
|
185
179
|
"libc",
|
186
180
|
"pyo3-build-config",
|
@@ -188,9 +182,9 @@ dependencies = [
|
|
188
182
|
|
189
183
|
[[package]]
|
190
184
|
name = "pyo3-macros"
|
191
|
-
version = "0.24.
|
185
|
+
version = "0.24.1"
|
192
186
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
193
|
-
checksum = "
|
187
|
+
checksum = "5c3ce5686aa4d3f63359a5100c62a127c9f15e8398e5fdeb5deef1fed5cd5f44"
|
194
188
|
dependencies = [
|
195
189
|
"proc-macro2",
|
196
190
|
"pyo3-macros-backend",
|
@@ -200,9 +194,9 @@ dependencies = [
|
|
200
194
|
|
201
195
|
[[package]]
|
202
196
|
name = "pyo3-macros-backend"
|
203
|
-
version = "0.24.
|
197
|
+
version = "0.24.1"
|
204
198
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
205
|
-
checksum = "
|
199
|
+
checksum = "f4cf6faa0cbfb0ed08e89beb8103ae9724eb4750e3a78084ba4017cbe94f3855"
|
206
200
|
dependencies = [
|
207
201
|
"heck",
|
208
202
|
"proc-macro2",
|
@@ -222,9 +216,9 @@ dependencies = [
|
|
222
216
|
|
223
217
|
[[package]]
|
224
218
|
name = "rs-can"
|
225
|
-
version = "0.2.
|
219
|
+
version = "0.2.2"
|
226
220
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
227
|
-
checksum = "
|
221
|
+
checksum = "7deea04551200cab94e5f3faf27be4ad02f84138db280630aa8f3b0b6bcb29ed"
|
228
222
|
dependencies = [
|
229
223
|
"bitflags",
|
230
224
|
"derive-getters",
|
@@ -351,12 +345,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
351
345
|
|
352
346
|
[[package]]
|
353
347
|
name = "zlgcan"
|
354
|
-
version = "0.2.
|
348
|
+
version = "0.2.2"
|
355
349
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
356
|
-
checksum = "
|
350
|
+
checksum = "2c4aa30b676bf4cb84f707cba8a8336585d8028bdcf4daaf87ca30bfaf233589"
|
357
351
|
dependencies = [
|
358
352
|
"dlopen2",
|
359
|
-
"dotenvy",
|
360
353
|
"log",
|
361
354
|
"rs-can",
|
362
355
|
"serde",
|
@@ -365,7 +358,7 @@ dependencies = [
|
|
365
358
|
|
366
359
|
[[package]]
|
367
360
|
name = "zlgcan-driver"
|
368
|
-
version = "0.
|
361
|
+
version = "0.2.0"
|
369
362
|
dependencies = [
|
370
363
|
"anyhow",
|
371
364
|
"pyo3",
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[package]
|
2
2
|
name = "zlgcan-driver"
|
3
|
-
version = "0.
|
3
|
+
version = "0.2.0"
|
4
4
|
edition = "2021"
|
5
5
|
|
6
6
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
@@ -13,8 +13,8 @@ pyo3 = "0.24"
|
|
13
13
|
#iso15765-2 = { version = "0.1.0-alpha0" }
|
14
14
|
#iso14229-1 = { version = "0.1.0-alpha0" }
|
15
15
|
#docan = { version = "0.1.0-alpha0" }
|
16
|
-
rs-can =
|
17
|
-
zlgcan =
|
16
|
+
rs-can = "0.2.2"
|
17
|
+
zlgcan = "0.2.2"
|
18
18
|
|
19
19
|
[dev-dependencies]
|
20
20
|
anyhow = "1"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: zlgcan
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.2.0
|
4
4
|
Classifier: Programming Language :: Rust
|
5
5
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
6
6
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
@@ -14,45 +14,35 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
14
14
|
Project-URL: homepage, https://github.com/zhuyu4839/zlgcan-driver
|
15
15
|
Project-URL: repository, https://github.com/zhuyu4839/zlgcan-driver
|
16
16
|
|
17
|
+

|
18
|
+

|
19
|
+
|
17
20
|
# ZLGCAN驱动及集成到python-can(因内存模型不同,目前Windows下32位python会报内存非法访问的错误)
|
18
21
|
|
19
22
|
1. 准备
|
20
23
|
* 确保安装相关驱动(USBCAN-I/II驱动得额外安装)
|
21
24
|
* 确保安装相[VC++运行环境](https://manual.zlg.cn/web/#/152?page_id=5332)
|
22
25
|
* 下载[library](https://github.com/zhuyu4839/rust-can/tree/master/zlgcan/library)文件夹(里面包含[bitrate.cfg.yaml](https://github.com/zhuyu4839/rust-can/tree/master/zlgcan/library/bitrate.cfg.yaml))
|
23
|
-
*
|
24
|
-
* 默认(相对运行脚本)路径文件夹内容示例:
|
25
|
-
```shell
|
26
|
-
├─main.py
|
27
|
-
├─library
|
28
|
-
│ ├──linux
|
29
|
-
│ │ └─x86_64
|
30
|
-
│ └─windows
|
31
|
-
│ ├─x86
|
32
|
-
│ └─x86_64
|
33
|
-
└─ bitrate.cfg.yaml
|
34
|
-
```
|
35
|
-
* (相对运行脚本)`zcan.env`文件指定`library`示例:
|
26
|
+
* 库文件示例:
|
36
27
|
```shell
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
├─linux
|
41
|
-
│ └─x86_64
|
42
|
-
├─windows
|
43
|
-
│ ├─x86
|
28
|
+
library
|
29
|
+
├──bitrate.cfg.yaml
|
30
|
+
├──linux
|
44
31
|
│ └─x86_64
|
45
|
-
└─
|
32
|
+
└─windows
|
33
|
+
├─x86
|
34
|
+
└─x86_64
|
35
|
+
```
|
36
|
+
* 在初始化can.Bus的时候指定zlgcan库路径(从0.2.0开始移除`zcan.env`配置), 默认为相对工程运行文件同级目录下`library`
|
37
|
+
```python
|
38
|
+
libpath=r"C:\your\library\path"
|
46
39
|
```
|
47
|
-
* 以下为`zcan.env`文件内容示例
|
48
|
-
```shell
|
49
|
-
ZCAN_LIBRARY="C:/your_library_path"
|
50
|
-
```
|
51
40
|
|
52
|
-
2. 安装zlgcan
|
41
|
+
2. 安装zlgcan(不建议使用低于0.2.0版本)
|
53
42
|
|
54
43
|
```shell
|
55
|
-
pip install zlgcan >= 0.
|
44
|
+
pip install zlgcan >= 0.2.0
|
45
|
+
```
|
56
46
|
|
57
47
|
3. 使用:
|
58
48
|
```python
|
@@ -60,6 +50,7 @@ Project-URL: repository, https://github.com/zhuyu4839/zlgcan-driver
|
|
60
50
|
from zlgcan.zlgcan import ZCanTxMode, ZCANDeviceType
|
61
51
|
|
62
52
|
with can.Bus(interface="zlgcan", device_type=ZCANDeviceType.ZCAN_USBCANFD_200U,
|
53
|
+
libpath="library/",
|
63
54
|
configs=[{'bitrate': 500000, 'resistance': 1}, {'bitrate': 500000, 'resistance': 1}]) as bus:
|
64
55
|
bus.send(can.Message(
|
65
56
|
arbitration_id=0x123,
|
@@ -72,6 +63,7 @@ Project-URL: repository, https://github.com/zhuyu4839/zlgcan-driver
|
|
72
63
|
# time.sleep(0.1)
|
73
64
|
_msg = bus.recv()
|
74
65
|
print(_msg)
|
66
|
+
```
|
75
67
|
|
76
68
|
4. CAN测试列表:
|
77
69
|
* USBCAN-I-mini - ZCAN_USBCAN1, ZCAN_USBCAN2
|
@@ -1,42 +1,32 @@
|
|
1
|
+

|
2
|
+

|
3
|
+
|
1
4
|
# ZLGCAN驱动及集成到python-can(因内存模型不同,目前Windows下32位python会报内存非法访问的错误)
|
2
5
|
|
3
6
|
1. 准备
|
4
7
|
* 确保安装相关驱动(USBCAN-I/II驱动得额外安装)
|
5
8
|
* 确保安装相[VC++运行环境](https://manual.zlg.cn/web/#/152?page_id=5332)
|
6
9
|
* 下载[library](https://github.com/zhuyu4839/rust-can/tree/master/zlgcan/library)文件夹(里面包含[bitrate.cfg.yaml](https://github.com/zhuyu4839/rust-can/tree/master/zlgcan/library/bitrate.cfg.yaml))
|
7
|
-
*
|
8
|
-
* 默认(相对运行脚本)路径文件夹内容示例:
|
9
|
-
```shell
|
10
|
-
├─main.py
|
11
|
-
├─library
|
12
|
-
│ ├──linux
|
13
|
-
│ │ └─x86_64
|
14
|
-
│ └─windows
|
15
|
-
│ ├─x86
|
16
|
-
│ └─x86_64
|
17
|
-
└─ bitrate.cfg.yaml
|
18
|
-
```
|
19
|
-
* (相对运行脚本)`zcan.env`文件指定`library`示例:
|
10
|
+
* 库文件示例:
|
20
11
|
```shell
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
├─linux
|
25
|
-
│ └─x86_64
|
26
|
-
├─windows
|
27
|
-
│ ├─x86
|
12
|
+
library
|
13
|
+
├──bitrate.cfg.yaml
|
14
|
+
├──linux
|
28
15
|
│ └─x86_64
|
29
|
-
└─
|
16
|
+
└─windows
|
17
|
+
├─x86
|
18
|
+
└─x86_64
|
19
|
+
```
|
20
|
+
* 在初始化can.Bus的时候指定zlgcan库路径(从0.2.0开始移除`zcan.env`配置), 默认为相对工程运行文件同级目录下`library`
|
21
|
+
```python
|
22
|
+
libpath=r"C:\your\library\path"
|
30
23
|
```
|
31
|
-
* 以下为`zcan.env`文件内容示例
|
32
|
-
```shell
|
33
|
-
ZCAN_LIBRARY="C:/your_library_path"
|
34
|
-
```
|
35
24
|
|
36
|
-
2. 安装zlgcan
|
25
|
+
2. 安装zlgcan(不建议使用低于0.2.0版本)
|
37
26
|
|
38
27
|
```shell
|
39
|
-
pip install zlgcan >= 0.
|
28
|
+
pip install zlgcan >= 0.2.0
|
29
|
+
```
|
40
30
|
|
41
31
|
3. 使用:
|
42
32
|
```python
|
@@ -44,6 +34,7 @@
|
|
44
34
|
from zlgcan.zlgcan import ZCanTxMode, ZCANDeviceType
|
45
35
|
|
46
36
|
with can.Bus(interface="zlgcan", device_type=ZCANDeviceType.ZCAN_USBCANFD_200U,
|
37
|
+
libpath="library/",
|
47
38
|
configs=[{'bitrate': 500000, 'resistance': 1}, {'bitrate': 500000, 'resistance': 1}]) as bus:
|
48
39
|
bus.send(can.Message(
|
49
40
|
arbitration_id=0x123,
|
@@ -56,6 +47,7 @@
|
|
56
47
|
# time.sleep(0.1)
|
57
48
|
_msg = bus.recv()
|
58
49
|
print(_msg)
|
50
|
+
```
|
59
51
|
|
60
52
|
4. CAN测试列表:
|
61
53
|
* USBCAN-I-mini - ZCAN_USBCAN1, ZCAN_USBCAN2
|
@@ -2,13 +2,8 @@ pub(crate) mod wrappers;
|
|
2
2
|
|
3
3
|
use std::sync::{Arc, Mutex};
|
4
4
|
use pyo3::{exceptions, prelude::*};
|
5
|
-
use rs_can::{CanError, CanFrame, CanType, ChannelConfig, DeviceBuilder
|
6
|
-
use zlgcan_rs::{
|
7
|
-
can::{CanMessage, ZCanFrameType},
|
8
|
-
device::DeriveInfo,
|
9
|
-
driver::{ZCanDriver, ZDevice},
|
10
|
-
ACC_CODE, ACC_MASK, BRP, CHANNEL_MODE, CHANNEL_TYPE, DERIVE_INFO, DEVICE_INDEX, DEVICE_TYPE, FILTER_TYPE
|
11
|
-
};
|
5
|
+
use rs_can::{CanError, CanFrame, CanType, ChannelConfig, DeviceBuilder};
|
6
|
+
use zlgcan_rs::{can::{CanMessage, ZCanFrameType}, device::DeriveInfo, driver::{ZCanDriver, ZDevice}, ACC_CODE, ACC_MASK, BRP, CHANNEL_MODE, CHANNEL_TYPE, DERIVE_INFO, DEVICE_INDEX, DEVICE_TYPE, FILTER_TYPE, LIBPATH};
|
12
7
|
use crate::wrappers::{ZCanChlCfgPy, ZCanDriverWrap, ZCanMessagePy, ZDeriveInfoPy};
|
13
8
|
|
14
9
|
#[pyfunction]
|
@@ -24,13 +19,16 @@ fn convert_from_python<'py>(py: Python<'py>, py_message: &Bound<'py, PyAny>) ->
|
|
24
19
|
|
25
20
|
#[pyfunction]
|
26
21
|
fn zlgcan_init_can(
|
22
|
+
libpath: String,
|
27
23
|
dev_type: u32,
|
28
24
|
dev_idx: u32,
|
29
25
|
cfgs: Vec<ZCanChlCfgPy>,
|
30
26
|
derive_info: Option<ZDeriveInfoPy>,
|
31
27
|
) -> PyResult<ZCanDriverWrap> {
|
32
|
-
let mut builder = DeviceBuilder::new(
|
33
|
-
builder
|
28
|
+
let mut builder = DeviceBuilder::new();
|
29
|
+
builder
|
30
|
+
.add_other(LIBPATH, Box::new(libpath))
|
31
|
+
.add_other(DEVICE_TYPE, Box::new(dev_type))
|
34
32
|
.add_other(DEVICE_INDEX, Box::new(dev_idx));
|
35
33
|
derive_info.map(
|
36
34
|
|info| builder.add_other(DERIVE_INFO, Box::<DeriveInfo>::new(info.into()))
|
@@ -192,7 +190,7 @@ mod tests {
|
|
192
190
|
None,
|
193
191
|
);
|
194
192
|
|
195
|
-
let device = zlgcan_init_can(dev_type, dev_idx, vec![cfg, ], None)?;
|
193
|
+
let device = zlgcan_init_can("../../RustProjects/rust-can/zlgcan/library".into(), dev_type, dev_idx, vec![cfg, ], None)?;
|
196
194
|
let dev_info = zlgcan_device_info(&device)?;
|
197
195
|
println!("{}", dev_info);
|
198
196
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
@@ -201,8 +199,8 @@ mod tests {
|
|
201
199
|
let mut flag = false;
|
202
200
|
while start.elapsed().as_secs() < 15 {
|
203
201
|
let msgs = zlgcan_recv(&device, 0, None)?;
|
204
|
-
println!("{:?}", msgs);
|
205
202
|
if !msgs.is_empty() {
|
203
|
+
println!("{:?}", msgs);
|
206
204
|
flag = true;
|
207
205
|
}
|
208
206
|
drop(msgs);
|
@@ -131,6 +131,7 @@ class ZCanBus(can.BusABC):
|
|
131
131
|
|
132
132
|
def __init__(self,
|
133
133
|
channel: Union[int, Sequence[int], str] = None, *,
|
134
|
+
libpath: str = "library/",
|
134
135
|
device_type: int,
|
135
136
|
device_index: int = 0,
|
136
137
|
derive: ZDeriveInfoPy = None,
|
@@ -142,6 +143,7 @@ class ZCanBus(can.BusABC):
|
|
142
143
|
Constructor
|
143
144
|
|
144
145
|
:param channel: Not used(from super).
|
146
|
+
:param libpath: The library root path.
|
145
147
|
:param device_type: The device type that your device belongs, see `ZCANDeviceType`.
|
146
148
|
:param device_index: The device index.
|
147
149
|
:param derive: The deriver info for specifying the channels and canfd supported if your device is not official.
|
@@ -180,7 +182,7 @@ class ZCanBus(can.BusABC):
|
|
180
182
|
cfg_list.append(_cfg)
|
181
183
|
self.channels.append(idx)
|
182
184
|
|
183
|
-
self.device = zlgcan_init_can(device_type, device_index, cfg_list, derive)
|
185
|
+
self.device = zlgcan_init_can(libpath, device_type, device_index, cfg_list, derive)
|
184
186
|
|
185
187
|
self.dev_info = zlgcan_device_info(self.device)
|
186
188
|
if self.dev_info is not None:
|
@@ -235,7 +237,9 @@ class ZCanBus(can.BusABC):
|
|
235
237
|
|
236
238
|
|
237
239
|
if __name__ == '__main__':
|
238
|
-
with ZCanBus(interface="zlgcan",
|
240
|
+
with ZCanBus(interface="zlgcan",
|
241
|
+
libpath="../../../RustProjects/rust-can/zlgcan/library",
|
242
|
+
device_type=ZCANDeviceType.ZCAN_USBCANFD_200U,
|
239
243
|
configs=[{'bitrate': 500000, 'dbitrate': 1_000_000, 'resistance': 1}]) as bus:
|
240
244
|
# bus.send(can.Message(
|
241
245
|
# arbitration_id=0x7DF,
|
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
|