mdkits 0.1.4__py3-none-any.whl → 0.1.5__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.
Potentially problematic release.
This version of mdkits might be problematic. Click here for more details.
- mdkits/cli/adsorbate.py +9 -0
- mdkits/cli/build_bulk.py +1 -1
- mdkits/cli/build_cli.py +19 -0
- mdkits/cli/build_surface.py +37 -115
- mdkits/mdkits.py +3 -3
- mdkits/util/arg_type.py +11 -0
- {mdkits-0.1.4.dist-info → mdkits-0.1.5.dist-info}/METADATA +19 -3
- {mdkits-0.1.4.dist-info → mdkits-0.1.5.dist-info}/RECORD +11 -10
- {mdkits-0.1.4.dist-info → mdkits-0.1.5.dist-info}/LICENSE +0 -0
- {mdkits-0.1.4.dist-info → mdkits-0.1.5.dist-info}/WHEEL +0 -0
- {mdkits-0.1.4.dist-info → mdkits-0.1.5.dist-info}/entry_points.txt +0 -0
mdkits/cli/adsorbate.py
CHANGED
|
@@ -34,6 +34,10 @@ def parse_argument():
|
|
|
34
34
|
|
|
35
35
|
return parser.parse_args()
|
|
36
36
|
|
|
37
|
+
@click.option('--adsorbate', type=arg_type.Molecule, help='add adsorbate on surface')
|
|
38
|
+
@click.option('--site', type=click.Choice(['ontop', 'hollow','fcc', 'hcp', 'bridge', 'shortbridge', 'longbridge']))
|
|
39
|
+
@click.option('--height', type=float, help='height above the surface')
|
|
40
|
+
@click.option('--rotate', type=click.Tuple([float, float, float]), help='rotate adsorbate molcule around x, y, z axis', default=(0, 0, 0))
|
|
37
41
|
def main():
|
|
38
42
|
args = parse_argument()
|
|
39
43
|
atoms = encapsulated_ase.atoms_read_with_cell(args.filename, cell=args.cell, coord_mode=args.coord)
|
|
@@ -47,6 +51,11 @@ def main():
|
|
|
47
51
|
if atom.index in args.index:
|
|
48
52
|
position_list.append(np.copy(atom.position[0:2])+offset)
|
|
49
53
|
|
|
54
|
+
molecule = build.molecule(adsorbate)
|
|
55
|
+
molecule.rotate(rotate[0], 'x')
|
|
56
|
+
molecule.rotate(rotate[1], 'y')
|
|
57
|
+
molecule.rotate(rotate[2], 'z')
|
|
58
|
+
build.add_adsorbate(atoms, molecule, position=site, height=height)
|
|
50
59
|
if args.m in g2.names:
|
|
51
60
|
molecule = build.molecule(args.m)
|
|
52
61
|
if args.x:
|
mdkits/cli/build_bulk.py
CHANGED
|
@@ -5,7 +5,7 @@ from ase.build import bulk
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
@click.command(name='
|
|
8
|
+
@click.command(name='bulk')
|
|
9
9
|
@click.argument('symbol', type=str)
|
|
10
10
|
@click.argument('cs', type=click.Choice(['sc', 'fcc', 'bcc', 'tetragonal', 'bct', 'hcp', 'rhombohedral', 'orthorhombic', 'mcl', 'diamond', 'zincblende', 'rocksalt', 'cesiumchloride', 'fluorite', 'wurtzite']))
|
|
11
11
|
@click.option('-a', type=float, help='designate lattice constant a')
|
mdkits/cli/build_cli.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from mdkits.cli import (
|
|
3
|
+
build_bulk,
|
|
4
|
+
build_surface,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@click.group(name='build')
|
|
9
|
+
@click.pass_context
|
|
10
|
+
def cli_build(ctx):
|
|
11
|
+
"""kits for building"""
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
cli_build.add_command(build_bulk.main)
|
|
16
|
+
cli_build.add_command(build_surface.main)
|
|
17
|
+
|
|
18
|
+
if __name__ == '__main__':
|
|
19
|
+
cli_build()
|
mdkits/cli/build_surface.py
CHANGED
|
@@ -1,132 +1,54 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import click
|
|
4
4
|
from ase import build
|
|
5
|
-
from ase.geometry import cell_to_cellpar
|
|
6
|
-
from ase.io import write
|
|
7
5
|
import numpy as np
|
|
8
6
|
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
def parse_size(s):
|
|
12
|
-
if s == None:
|
|
13
|
-
return None
|
|
14
|
-
return [int(x) for x in s.replace(',', ' ').split()]
|
|
15
|
-
|
|
16
|
-
|
|
17
8
|
def surface_check(obj, surface_type):
|
|
18
9
|
if hasattr(obj, surface_type):
|
|
19
10
|
return getattr(obj, surface_type)
|
|
20
|
-
else:
|
|
21
|
-
print(f'dont have face named {surface_type}')
|
|
22
|
-
exit()
|
|
23
11
|
|
|
24
12
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
a = args.a * 0.7071 * 2
|
|
51
|
-
else:
|
|
52
|
-
a = args.a
|
|
53
|
-
|
|
54
|
-
vacuum = args.vacuum / 2
|
|
55
|
-
|
|
56
|
-
build_surface = surface_check(build, args.face)
|
|
57
|
-
|
|
58
|
-
if args.orth:
|
|
59
|
-
atoms = build_surface(args.symbol, args.size, a=a, vacuum=vacuum, orthogonal=args.orth)
|
|
60
|
-
else:
|
|
61
|
-
atoms = build_surface(args.symbol, args.size, a=a, vacuum=vacuum)
|
|
62
|
-
|
|
63
|
-
# add adsorbate
|
|
64
|
-
if args.adsorbate != None:
|
|
65
|
-
## add H2Oa and OH
|
|
66
|
-
if args.adsorbate in ['H2Oa', 'OH']:
|
|
67
|
-
if args.adsorbate in ['OH']:
|
|
68
|
-
h2o = build.molecule(args.adsorbate)
|
|
69
|
-
h2o.rotate(90, 'y')
|
|
70
|
-
build.add_adsorbate(atoms, h2o, args.height, position=args.position, offset=args.offset)
|
|
71
|
-
else:
|
|
72
|
-
h2o = build.molecule('H2O')
|
|
73
|
-
h2o.rotate(90, 'y')
|
|
74
|
-
build.add_adsorbate(atoms, h2o, args.height, position=args.position, offset=args.offset)
|
|
75
|
-
## add H2Ob
|
|
76
|
-
elif args.adsorbate in ['H2Ob']:
|
|
77
|
-
h2o = build.molecule('H2O')
|
|
78
|
-
h2o.rotate(90, 'z')
|
|
79
|
-
h2o.rotate(45, 'y')
|
|
80
|
-
build.add_adsorbate(atoms, h2o, args.height, position=args.position, offset=args.offset)
|
|
81
|
-
## add default something
|
|
13
|
+
@click.command(name='surface')
|
|
14
|
+
@click.argument('symbol', type=str)
|
|
15
|
+
@click.argument('surface', type=click.Choice(['fcc100', 'fcc110', 'fcc111', 'fcc211', 'bcc100', 'bcc110', 'bcc111', 'hcp0001', 'hcp10m10', 'diamond100', 'diamond111', 'mx2', 'graphene']))
|
|
16
|
+
@click.argument('size', type=click.Tuple([int, int, int]))
|
|
17
|
+
@click.option('--kind', type=click.Choice(['2H', '1T']), help='designate the kind of MX2 surface')
|
|
18
|
+
@click.option('-a', type=float, help='the lattice constant. if specified, it overrides the expermental lattice constant of the element. must be specified if setting up a crystal structure different from the one found in nature')
|
|
19
|
+
@click.option('-c', type=float, help='extra hcp lattice constant. if specified, it overrides the expermental lattice constant of the element. Default is ideal ratio: sqrt(8/3)', default=np.sqrt(8/3), show_default=True)
|
|
20
|
+
@click.option('--thickness', type=float, help='Thickness of the layer, for mx2 and graphene')
|
|
21
|
+
@click.option('--orth', is_flag=True, help='if specified and true, forces the creation of a unit cell with orthogonal basis vectors. if the default is such a unit cell, this argument is not supported')
|
|
22
|
+
@click.option('--vacuum', type=float, help='designate vacuum of surface, default is None', default=0.0)
|
|
23
|
+
def main(symbol, surface, size, kind, a, c, thickness, orth, vacuum, adsorbate):
|
|
24
|
+
#if args.primitive:
|
|
25
|
+
# a = args.a * 0.7071 * 2
|
|
26
|
+
#else:
|
|
27
|
+
# a = args.a
|
|
28
|
+
|
|
29
|
+
vacuum = vacuum / 2
|
|
30
|
+
build_surface = surface_check(build, surface)
|
|
31
|
+
out_filename = f"{symbol}_{surface}_{size[0]}{size[1]}{size[2]}_{adsorbate}.cif"
|
|
32
|
+
|
|
33
|
+
if surface in ['hcp0001', 'hcp10m10']:
|
|
34
|
+
atoms = build_surface(symbol, size, a=a, c=c, vacuum=vacuum, orthogonal=orth)
|
|
35
|
+
elif surface in ['mx2']:
|
|
36
|
+
if thickness is None:
|
|
37
|
+
atoms = build_surface(symbol, size, kind=kind, a=a, vacuum=vacuum)
|
|
82
38
|
else:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
## get atom position at surface
|
|
88
|
-
surface_positions_dict = {}
|
|
89
|
-
for atom in atoms:
|
|
90
|
-
if atom.tag == 1:
|
|
91
|
-
surface_positions_dict[atom.index] = atom.position
|
|
92
|
-
## error checking
|
|
93
|
-
if site_number := len(surface_positions_dict) < args.coverh:
|
|
94
|
-
print(f"coverh is too big, please less then {site_number}")
|
|
95
|
-
sys.exit()
|
|
96
|
-
## get random site
|
|
97
|
-
random_site_list = np.random.choice(list(surface_positions_dict.keys()), args.coverh, replace=False)
|
|
98
|
-
random_site_list = np.unique(random_site_list)
|
|
99
|
-
## add H atom at hollow site
|
|
100
|
-
for site in random_site_list:
|
|
101
|
-
site_position = surface_positions_dict[site][0:2]
|
|
102
|
-
build.add_adsorbate(atoms, 'H', 2, position=site_position, offset=(0.3, 0.3))
|
|
39
|
+
atoms = build_surface(symbol, size, kind=kind, a=a, vacuum=vacuum, thickness=thickness)
|
|
40
|
+
elif surface in ['graphene']:
|
|
41
|
+
if a is None:
|
|
42
|
+
a = 2.46
|
|
103
43
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
with open('coord.xyz', 'r') as f:
|
|
109
|
-
lines = f.readlines()[2:]
|
|
110
|
-
with open('coord.xyz', 'w') as f:
|
|
111
|
-
f.writelines(lines)
|
|
112
|
-
with open('cell.inc', 'w') as f:
|
|
113
|
-
cell = list(cell_to_cellpar(atoms.cell))
|
|
114
|
-
f.write('ABC [angstrom] ' + str(cell[0]) + ' ' + str(cell[1]) + ' ' + str(cell[2]) + ' ' + '\n')
|
|
115
|
-
f.write('ALPHA_BETA_GAMMA ' + str(cell[3]) + ' ' + str(cell[4]) + ' ' + str(cell[5]) + '\n')
|
|
116
|
-
## output kpoint file with specific number
|
|
117
|
-
if args.k != None:
|
|
118
|
-
if True: #judge M or G
|
|
119
|
-
with open('kpoint.inc', 'w') as f:
|
|
120
|
-
f.write(f"SCHEME MONKHORST-PACK {args.k[0]} {args.k[1]} {args.k[2]}" + "\n")
|
|
121
|
-
## output kpoint file autoly
|
|
122
|
-
if args.autok:
|
|
123
|
-
if True: # judge matel or semi or else
|
|
124
|
-
if True: # judge M or G
|
|
125
|
-
with open('kpoint.inc', 'w') as f:
|
|
126
|
-
f.write(f"SCHEME MONKHORST-PACK {int(round(30/cell[0]))} {int(round(30/cell[1]))} {int(round(30/cell[2]))}" + "\n")
|
|
127
|
-
## output default format or specific xyz file
|
|
44
|
+
if thickness is None:
|
|
45
|
+
atoms = build_surface(formula=symbol, size=size, a=a, vacuum=vacuum)
|
|
46
|
+
else:
|
|
47
|
+
atoms = build_surface(formula=symbol, size=size, thickness=thickness, a=a, vacuum=vacuum)
|
|
128
48
|
else:
|
|
129
|
-
atoms
|
|
49
|
+
atoms = build_surface(symbol, size, a=a, vacuum=vacuum, orthogonal=orth)
|
|
50
|
+
|
|
51
|
+
atoms.write(out_filename)
|
|
130
52
|
|
|
131
53
|
|
|
132
54
|
if __name__ == '__main__':
|
mdkits/mdkits.py
CHANGED
|
@@ -8,7 +8,7 @@ from mdkits.cli import (
|
|
|
8
8
|
density,
|
|
9
9
|
cube,
|
|
10
10
|
pdos,
|
|
11
|
-
|
|
11
|
+
build_cli,
|
|
12
12
|
)
|
|
13
13
|
|
|
14
14
|
|
|
@@ -16,7 +16,7 @@ from mdkits.cli import (
|
|
|
16
16
|
@click.pass_context
|
|
17
17
|
@click.version_option()
|
|
18
18
|
def cli(ctx):
|
|
19
|
-
"""
|
|
19
|
+
"""kits for md or dft"""
|
|
20
20
|
pass
|
|
21
21
|
|
|
22
22
|
|
|
@@ -28,7 +28,7 @@ cli.add_command(plot.main)
|
|
|
28
28
|
cli.add_command(density.main)
|
|
29
29
|
cli.add_command(cube.main)
|
|
30
30
|
cli.add_command(pdos.main)
|
|
31
|
-
cli.add_command(
|
|
31
|
+
cli.add_command(build_cli.cli_build)
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
if __name__ == '__main__':
|
mdkits/util/arg_type.py
CHANGED
|
@@ -37,5 +37,16 @@ class FrameRangeType(click.ParamType):
|
|
|
37
37
|
self.fail(f"{value} is not a valid frame range", param, ctx)
|
|
38
38
|
|
|
39
39
|
|
|
40
|
+
from ase.collections import g2
|
|
41
|
+
class MoleculeType(click.Choice):
|
|
42
|
+
name = "mocular type"
|
|
43
|
+
def __init__(self):
|
|
44
|
+
super().__init__(self)
|
|
45
|
+
g2.names.append(click.Path(exists=True))
|
|
46
|
+
self.choices = tuple(g2.names)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
40
50
|
Cell = CellType()
|
|
41
51
|
FrameRange = FrameRangeType()
|
|
52
|
+
Molecule = MoleculeType()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: mdkits
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.1.5
|
|
4
|
+
Summary: kits for md or dft
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: molecular dynamics,density functional theory
|
|
7
7
|
Author: jxxcr
|
|
@@ -98,8 +98,10 @@ mdkits cube [FILENAME] -b 1 2
|
|
|
98
98
|
会将平均值打印在屏幕上, 同时记录在`cube.out`中的注释行.
|
|
99
99
|
|
|
100
100
|
## 建模
|
|
101
|
+
`build`为界面的工具, 其中包含多个建模工具
|
|
102
|
+
|
|
101
103
|
### 构建体相模型
|
|
102
|
-
`
|
|
104
|
+
`bulk`用于构建体相模型, 如构建`Pt`的`fcc`体相模型:
|
|
103
105
|
```bash
|
|
104
106
|
mdkits build_bulk Pt fcc
|
|
105
107
|
```
|
|
@@ -116,6 +118,20 @@ mdkits build_bulk CsCl cesiumchloride -a 4.123
|
|
|
116
118
|
mdkits build_bulk BaF2 fluorite -a 6.196
|
|
117
119
|
```
|
|
118
120
|
|
|
121
|
+
### 构建表面模型
|
|
122
|
+
`surface`用于构建常见的表面模型, 骑用法为:
|
|
123
|
+
```bash
|
|
124
|
+
mdkits build surface [ELEMENT] [SURFACE_TYPE] [SIZE]
|
|
125
|
+
```
|
|
126
|
+
如构建`Pt`的`fcc111`表面模型:
|
|
127
|
+
```bash
|
|
128
|
+
mdkits build surface Pt fcc111 2 2 3 --vacuum 15
|
|
129
|
+
```
|
|
130
|
+
构建石墨烯表面:
|
|
131
|
+
```bash
|
|
132
|
+
mdkits build surface C2 graphene 3 3 1 --vacuum 15
|
|
133
|
+
```
|
|
134
|
+
|
|
119
135
|
## 其他
|
|
120
136
|
### 轨迹提取
|
|
121
137
|
`extract`用于提取轨迹文件中的特定的帧, 如从`frames.xyz`中提取第 1000 帧到第 2000 帧的轨迹文件, 并输出为`1000-2000.xyz`, `-r`选项的参数与`Python`的切片语法一致:
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
mdkits/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
"mdkits/cli/,hb_distribution_down.py",sha256=i3NguzGebqCgy4uuVBeFajZRZnXtjhsJBPDGDdumlWA,4733
|
|
3
|
-
mdkits/cli/adsorbate.py,sha256=
|
|
4
|
-
mdkits/cli/build_bulk.py,sha256=
|
|
3
|
+
mdkits/cli/adsorbate.py,sha256=yC8YTdAYmt6NhsBR_PsIC14sPswMWcAJccxcDKx5fZY,3778
|
|
4
|
+
mdkits/cli/build_bulk.py,sha256=mOjoHHBui5fTYASabD96l6zBoKlQukT-LOyR2FZNzM4,1549
|
|
5
|
+
mdkits/cli/build_cli.py,sha256=ykxK2-fhOcbcPxQCBw9LKCh-Hkcj4Ke4iYbh3N6BJIk,325
|
|
5
6
|
mdkits/cli/build_interface.py,sha256=i1YE5iwazKVsTdQ_DXalNYeA8oflORWFePgJin1AJM4,3537
|
|
6
|
-
mdkits/cli/build_surface.py,sha256=
|
|
7
|
+
mdkits/cli/build_surface.py,sha256=8-bAstqzPllkd9v-2bUzGlLQOgbOnfGg9MyTVRxFIVU,2641
|
|
7
8
|
mdkits/cli/convert.py,sha256=s2q2Py7IVGNTctHgpHm66YFj_Rr8srnpuJudrMBI0oM,2014
|
|
8
9
|
mdkits/cli/cube.py,sha256=G-QNup8W6J1-LCcEl1EHsV3nstd23byePDOcE_95t18,1176
|
|
9
10
|
mdkits/cli/cut_surface.py,sha256=D1naCWj0QJE3AiInzy3SeGO37butothE3BS1rZsZ5MU,1425
|
|
@@ -21,9 +22,9 @@ mdkits/cli/supercell.py,sha256=r5iddLw1NNzj7NTFlR2j_jpD1AMfrsxhA08bPwQvVvg,2059
|
|
|
21
22
|
mdkits/cli/wrap.py,sha256=AUxGISuiCfEjdMYl-TKc2VMCPHSybWKrMIOTn_6kSp0,1043
|
|
22
23
|
mdkits/config/__init__.py,sha256=ZSwmnPK02LxJLMgcYmNb-tIOk8fEuHf5jpqD3SDHWLg,1039
|
|
23
24
|
mdkits/config/settings.yml,sha256=PY7u0PbFLuxSnd54H5tI9oMjUf-mzyADqSZtm99BwG0,71
|
|
24
|
-
mdkits/mdkits.py,sha256=
|
|
25
|
+
mdkits/mdkits.py,sha256=ASOEhY94G_P902ojOobvqPYu1L3AOFTS_Ooh5LJAjX0,603
|
|
25
26
|
mdkits/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
-
mdkits/util/arg_type.py,sha256=
|
|
27
|
+
mdkits/util/arg_type.py,sha256=ZjP6_PKIEDnHk45ye7by4aKTeZzw1PJq3939jZw57hY,1743
|
|
27
28
|
mdkits/util/cp2k_input_parsing.py,sha256=6BFVsbBYxdauaUPrjr5h8JXk_R0bu7V3cbG2DEWWFlQ,1291
|
|
28
29
|
mdkits/util/encapsulated_ase.py,sha256=rmL80U3M8SsEU2M6QtLyiam2N1FIbrm5dK3P14p1EPg,4093
|
|
29
30
|
mdkits/util/encapsulated_mda.py,sha256=td3H24u3eHOIS2nwPucfIaMxeaVxI77oFI8nnNhw7vo,2217
|
|
@@ -31,8 +32,8 @@ mdkits/util/fig_operation.py,sha256=FwffNUtXorMl6qE04FipgzcVljEQii7wrNJUCJMyY3E,
|
|
|
31
32
|
mdkits/util/numpy_geo.py,sha256=1Op8THoQeyqybSZAi7hVxohYCr4SzY6ndZC8_gAGXDA,3619
|
|
32
33
|
mdkits/util/os_operation.py,sha256=tNRjniDwFqARMy5Rf6MUNmaQGpJlyifCpuN16r8aB2g,828
|
|
33
34
|
mdkits/util/structure_parsing.py,sha256=mRPMJeih3O-ST7HeETDvBEkfV-1psT-XgxyYgDadV0U,4152
|
|
34
|
-
mdkits-0.1.
|
|
35
|
-
mdkits-0.1.
|
|
36
|
-
mdkits-0.1.
|
|
37
|
-
mdkits-0.1.
|
|
38
|
-
mdkits-0.1.
|
|
35
|
+
mdkits-0.1.5.dist-info/entry_points.txt,sha256=xoWWZ_yL87S501AzCO2ZjpnVuYkElC6z-8J3tmuIGXQ,44
|
|
36
|
+
mdkits-0.1.5.dist-info/LICENSE,sha256=VLaqyB0r_H7y3hUntfpPWcE3OATTedHWI983htLftcQ,1081
|
|
37
|
+
mdkits-0.1.5.dist-info/METADATA,sha256=egdGXbw2G_ZVtqF_Wj4Uhnc02wMKPAssXLiyW6-yyNM,6869
|
|
38
|
+
mdkits-0.1.5.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
|
39
|
+
mdkits-0.1.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|