prefab 1.1.3__py3-none-any.whl → 1.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.
- prefab/__init__.py +1 -1
- prefab/compare.py +2 -2
- prefab/device.py +44 -19
- prefab/predict.py +87 -40
- {prefab-1.1.3.dist-info → prefab-1.1.5.dist-info}/METADATA +1 -1
- prefab-1.1.5.dist-info/RECORD +13 -0
- prefab-1.1.3.dist-info/RECORD +0 -13
- {prefab-1.1.3.dist-info → prefab-1.1.5.dist-info}/WHEEL +0 -0
- {prefab-1.1.3.dist-info → prefab-1.1.5.dist-info}/licenses/LICENSE +0 -0
prefab/__init__.py
CHANGED
prefab/compare.py
CHANGED
|
@@ -24,7 +24,7 @@ def mean_squared_error(device_a: Device, device_b: Device) -> float:
|
|
|
24
24
|
float
|
|
25
25
|
The mean squared error between two devices.
|
|
26
26
|
"""
|
|
27
|
-
return np.mean((device_a.device_array - device_b.device_array) ** 2)
|
|
27
|
+
return float(np.mean((device_a.device_array - device_b.device_array) ** 2))
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
def intersection_over_union(device_a: Device, device_b: Device) -> float:
|
|
@@ -77,7 +77,7 @@ def hamming_distance(device_a: Device, device_b: Device) -> int:
|
|
|
77
77
|
"One or both devices are not binarized.", UserWarning, stacklevel=2
|
|
78
78
|
)
|
|
79
79
|
|
|
80
|
-
return np.sum(device_a.device_array != device_b.device_array)
|
|
80
|
+
return int(np.sum(device_a.device_array != device_b.device_array))
|
|
81
81
|
|
|
82
82
|
|
|
83
83
|
def dice_coefficient(device_a: Device, device_b: Device) -> float:
|
prefab/device.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Provides the Device class for representing photonic devices."""
|
|
2
2
|
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
4
|
|
|
5
5
|
import cv2
|
|
6
6
|
import gdstk
|
|
@@ -9,7 +9,7 @@ import numpy as np
|
|
|
9
9
|
from matplotlib.axes import Axes
|
|
10
10
|
from matplotlib.patches import Rectangle
|
|
11
11
|
from PIL import Image
|
|
12
|
-
from pydantic import BaseModel, Field,
|
|
12
|
+
from pydantic import BaseModel, Field, root_validator, validator
|
|
13
13
|
from scipy.ndimage import distance_transform_edt
|
|
14
14
|
from skimage import measure
|
|
15
15
|
|
|
@@ -17,6 +17,10 @@ from . import compare, geometry
|
|
|
17
17
|
from .models import Model
|
|
18
18
|
from .predict import predict_array
|
|
19
19
|
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
import gdsfactory as gf
|
|
22
|
+
import tidy3d as td
|
|
23
|
+
|
|
20
24
|
Image.MAX_IMAGE_PIXELS = None
|
|
21
25
|
|
|
22
26
|
|
|
@@ -36,7 +40,7 @@ class BufferSpec(BaseModel):
|
|
|
36
40
|
('top', 'bottom', 'left', 'right'), where 'constant' is used for isolated
|
|
37
41
|
structures and 'edge' is utilized for preserving the edge, such as for waveguide
|
|
38
42
|
connections.
|
|
39
|
-
thickness : dict[str,
|
|
43
|
+
thickness : dict[str, int]
|
|
40
44
|
A dictionary that defines the thickness of the buffer zone for each side of the
|
|
41
45
|
device ('top', 'bottom', 'left', 'right'). Each value must be greater than 0.
|
|
42
46
|
|
|
@@ -75,7 +79,7 @@ class BufferSpec(BaseModel):
|
|
|
75
79
|
"right": "constant",
|
|
76
80
|
}
|
|
77
81
|
)
|
|
78
|
-
thickness: dict[str,
|
|
82
|
+
thickness: dict[str, int] = Field(
|
|
79
83
|
default_factory=lambda: {
|
|
80
84
|
"top": 128,
|
|
81
85
|
"bottom": 128,
|
|
@@ -91,6 +95,12 @@ class BufferSpec(BaseModel):
|
|
|
91
95
|
raise ValueError(f"Buffer mode must be one of {allowed_modes}, got '{v}'")
|
|
92
96
|
return v
|
|
93
97
|
|
|
98
|
+
@validator("thickness")
|
|
99
|
+
def check_thickness(cls, v):
|
|
100
|
+
if not all(t > 0 for t in v.values()):
|
|
101
|
+
raise ValueError("All thickness values must be greater than 0")
|
|
102
|
+
return v
|
|
103
|
+
|
|
94
104
|
|
|
95
105
|
class Device(BaseModel):
|
|
96
106
|
device_array: np.ndarray = Field(...)
|
|
@@ -100,8 +110,8 @@ class Device(BaseModel):
|
|
|
100
110
|
arbitrary_types_allowed = True
|
|
101
111
|
|
|
102
112
|
@property
|
|
103
|
-
def shape(self) -> tuple[int,
|
|
104
|
-
return self.device_array.shape
|
|
113
|
+
def shape(self) -> tuple[int, ...]:
|
|
114
|
+
return tuple(self.device_array.shape)
|
|
105
115
|
|
|
106
116
|
def __init__(
|
|
107
117
|
self, device_array: np.ndarray, buffer_spec: Optional[BufferSpec] = None
|
|
@@ -370,12 +380,14 @@ class Device(BaseModel):
|
|
|
370
380
|
buffer_thickness = self.buffer_spec.thickness
|
|
371
381
|
buffer_mode = self.buffer_spec.mode
|
|
372
382
|
|
|
373
|
-
crop_top = buffer_thickness["top"] if buffer_mode["top"] == "
|
|
383
|
+
crop_top = buffer_thickness["top"] if buffer_mode["top"] == "constant" else 0
|
|
374
384
|
crop_bottom = (
|
|
375
|
-
buffer_thickness["bottom"] if buffer_mode["bottom"] == "
|
|
385
|
+
buffer_thickness["bottom"] if buffer_mode["bottom"] == "constant" else 0
|
|
386
|
+
)
|
|
387
|
+
crop_left = buffer_thickness["left"] if buffer_mode["left"] == "constant" else 0
|
|
388
|
+
crop_right = (
|
|
389
|
+
buffer_thickness["right"] if buffer_mode["right"] == "constant" else 0
|
|
376
390
|
)
|
|
377
|
-
crop_left = buffer_thickness["left"] if buffer_mode["left"] == "edge" else 0
|
|
378
|
-
crop_right = buffer_thickness["right"] if buffer_mode["right"] == "edge" else 0
|
|
379
391
|
|
|
380
392
|
ndarray = device_array[
|
|
381
393
|
crop_top : device_array.shape[0] - crop_bottom,
|
|
@@ -529,8 +541,18 @@ class Device(BaseModel):
|
|
|
529
541
|
polygons_to_process = hierarchy_polygons[level]
|
|
530
542
|
|
|
531
543
|
if polygons_to_process:
|
|
532
|
-
|
|
533
|
-
|
|
544
|
+
buffer_thickness = self.buffer_spec.thickness
|
|
545
|
+
|
|
546
|
+
center_x_nm = (
|
|
547
|
+
self.device_array.shape[1]
|
|
548
|
+
- buffer_thickness["left"]
|
|
549
|
+
- buffer_thickness["right"]
|
|
550
|
+
) / 2
|
|
551
|
+
center_y_nm = (
|
|
552
|
+
self.device_array.shape[0]
|
|
553
|
+
- buffer_thickness["top"]
|
|
554
|
+
- buffer_thickness["bottom"]
|
|
555
|
+
) / 2
|
|
534
556
|
|
|
535
557
|
center_x_um = center_x_nm / 1000
|
|
536
558
|
center_y_um = center_y_nm / 1000
|
|
@@ -583,7 +605,7 @@ class Device(BaseModel):
|
|
|
583
605
|
self,
|
|
584
606
|
eps0: float,
|
|
585
607
|
thickness: float,
|
|
586
|
-
) -> "td.Structure":
|
|
608
|
+
) -> "td.Structure":
|
|
587
609
|
"""
|
|
588
610
|
Convert the device geometry to a Tidy3D Structure.
|
|
589
611
|
|
|
@@ -622,7 +644,10 @@ class Device(BaseModel):
|
|
|
622
644
|
eps_dataset = SpatialDataArray(eps_array, coords=dict(x=X, y=Y, z=Z))
|
|
623
645
|
medium = CustomMedium.from_eps_raw(eps_dataset)
|
|
624
646
|
return Structure(
|
|
625
|
-
geometry=Box(center=(0, 0, 0), size=(inf, inf, thickness)
|
|
647
|
+
geometry=Box(center=(0, 0, 0), size=(inf, inf, thickness), attrs={}),
|
|
648
|
+
medium=medium,
|
|
649
|
+
name="device",
|
|
650
|
+
attrs={},
|
|
626
651
|
)
|
|
627
652
|
|
|
628
653
|
def to_3d(self, thickness_nm: int) -> np.ndarray:
|
|
@@ -678,7 +703,7 @@ class Device(BaseModel):
|
|
|
678
703
|
If the numpy-stl package is not installed.
|
|
679
704
|
"""
|
|
680
705
|
try:
|
|
681
|
-
from stl import mesh
|
|
706
|
+
from stl import mesh # type: ignore
|
|
682
707
|
except ImportError:
|
|
683
708
|
raise ImportError(
|
|
684
709
|
"The stl package is required to use this function; "
|
|
@@ -764,7 +789,7 @@ class Device(BaseModel):
|
|
|
764
789
|
self,
|
|
765
790
|
show_buffer: bool = True,
|
|
766
791
|
bounds: Optional[tuple[tuple[int, int], tuple[int, int]]] = None,
|
|
767
|
-
level: int = None,
|
|
792
|
+
level: Optional[int] = None,
|
|
768
793
|
ax: Optional[Axes] = None,
|
|
769
794
|
**kwargs,
|
|
770
795
|
) -> Axes:
|
|
@@ -819,7 +844,7 @@ class Device(BaseModel):
|
|
|
819
844
|
# label: Optional[str] = "Device contour",
|
|
820
845
|
show_buffer: bool = True,
|
|
821
846
|
bounds: Optional[tuple[tuple[int, int], tuple[int, int]]] = None,
|
|
822
|
-
level: int = None,
|
|
847
|
+
level: Optional[int] = None,
|
|
823
848
|
ax: Optional[Axes] = None,
|
|
824
849
|
**kwargs,
|
|
825
850
|
):
|
|
@@ -893,7 +918,7 @@ class Device(BaseModel):
|
|
|
893
918
|
self,
|
|
894
919
|
show_buffer: bool = True,
|
|
895
920
|
bounds: Optional[tuple[tuple[int, int], tuple[int, int]]] = None,
|
|
896
|
-
level: int = None,
|
|
921
|
+
level: Optional[int] = None,
|
|
897
922
|
ax: Optional[Axes] = None,
|
|
898
923
|
**kwargs,
|
|
899
924
|
):
|
|
@@ -956,7 +981,7 @@ class Device(BaseModel):
|
|
|
956
981
|
ref_device: "Device",
|
|
957
982
|
show_buffer: bool = True,
|
|
958
983
|
bounds: Optional[tuple[tuple[int, int], tuple[int, int]]] = None,
|
|
959
|
-
level: int = None,
|
|
984
|
+
level: Optional[int] = None,
|
|
960
985
|
ax: Optional[Axes] = None,
|
|
961
986
|
**kwargs,
|
|
962
987
|
) -> Axes:
|
prefab/predict.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Provides prediction functions for ndarrays of device geometries."""
|
|
2
|
+
|
|
1
3
|
import base64
|
|
2
4
|
import io
|
|
3
5
|
import json
|
|
@@ -6,6 +8,8 @@ import os
|
|
|
6
8
|
import numpy as np
|
|
7
9
|
import requests
|
|
8
10
|
import toml
|
|
11
|
+
from autograd import primitive
|
|
12
|
+
from autograd.extend import defvjp
|
|
9
13
|
from PIL import Image
|
|
10
14
|
from tqdm import tqdm
|
|
11
15
|
|
|
@@ -23,24 +27,34 @@ def predict_array(
|
|
|
23
27
|
gpu: bool = False,
|
|
24
28
|
) -> np.ndarray:
|
|
25
29
|
"""
|
|
26
|
-
|
|
30
|
+
Predict the nanofabrication outcome of a device array using a specified model.
|
|
27
31
|
|
|
28
|
-
This function sends the device array to a prediction service, which uses
|
|
29
|
-
learning model to predict the outcome of the nanofabrication
|
|
30
|
-
can be performed on a GPU if specified.
|
|
32
|
+
This function sends the device array to a serverless prediction service, which uses
|
|
33
|
+
a specified machine learning model to predict the outcome of the nanofabrication
|
|
34
|
+
process. The prediction can be performed on a GPU if specified.
|
|
31
35
|
|
|
32
36
|
Parameters
|
|
33
37
|
----------
|
|
34
38
|
device_array : np.ndarray
|
|
35
|
-
|
|
39
|
+
A 2D array representing the planar geometry of the device. This array undergoes
|
|
40
|
+
various transformations to predict the nanofabrication process.
|
|
36
41
|
model : Model
|
|
37
|
-
The model to use for prediction
|
|
42
|
+
The model to use for prediction, representing a specific fabrication process and
|
|
43
|
+
dataset. This model encapsulates details about the fabrication foundry, process,
|
|
44
|
+
material, technology, thickness, and sidewall presence, as defined in
|
|
45
|
+
`models.py`. Each model is associated with a version and dataset that detail its
|
|
46
|
+
creation and the data it was trained on, ensuring the prediction is tailored to
|
|
47
|
+
specific fabrication parameters.
|
|
38
48
|
model_type : str
|
|
39
49
|
The type of model to use (e.g., 'p', 'c', 's').
|
|
40
50
|
binarize : bool
|
|
41
|
-
|
|
51
|
+
If True, the predicted device geometry will be binarized using a threshold
|
|
52
|
+
method. This is useful for converting probabilistic predictions into binary
|
|
53
|
+
geometries.
|
|
42
54
|
gpu : bool, optional
|
|
43
|
-
|
|
55
|
+
If True, the prediction will be performed on a GPU. Defaults to False. Note: The
|
|
56
|
+
GPU option has more overhead and will take longer for small devices, but will be
|
|
57
|
+
faster for larger devices.
|
|
44
58
|
|
|
45
59
|
Returns
|
|
46
60
|
-------
|
|
@@ -69,38 +83,11 @@ def predict_array(
|
|
|
69
83
|
raise RuntimeError(f"Request failed: {e}") from e
|
|
70
84
|
|
|
71
85
|
|
|
72
|
-
def
|
|
73
|
-
device_array: np.ndarray, model: Model
|
|
86
|
+
def _predict_array_with_grad(
|
|
87
|
+
device_array: np.ndarray, model: Model
|
|
74
88
|
) -> tuple[np.ndarray, np.ndarray]:
|
|
75
|
-
"""
|
|
76
|
-
Predicts the output array and its gradient for a given device array using a
|
|
77
|
-
specified model.
|
|
78
|
-
|
|
79
|
-
This function sends the device array to a prediction service, which uses a machine
|
|
80
|
-
learning model to predict both the outcome and the gradient of the nanofabrication
|
|
81
|
-
process.
|
|
82
|
-
|
|
83
|
-
Parameters
|
|
84
|
-
----------
|
|
85
|
-
device_array : np.ndarray
|
|
86
|
-
The input device array to be predicted.
|
|
87
|
-
model : Model
|
|
88
|
-
The model to use for prediction.
|
|
89
|
-
model_type : str
|
|
90
|
-
The type of model to use (e.g., 'p', 'c', 's').
|
|
91
|
-
|
|
92
|
-
Returns
|
|
93
|
-
-------
|
|
94
|
-
tuple[np.ndarray, np.ndarray]
|
|
95
|
-
A tuple containing the predicted output array and its gradient.
|
|
96
|
-
|
|
97
|
-
Raises
|
|
98
|
-
------
|
|
99
|
-
RuntimeError
|
|
100
|
-
If the request to the prediction service fails.
|
|
101
|
-
"""
|
|
102
89
|
headers = _prepare_headers()
|
|
103
|
-
predict_data = _prepare_predict_data(device_array, model,
|
|
90
|
+
predict_data = _prepare_predict_data(device_array, model, "p", False)
|
|
104
91
|
endpoint_url = f"{BASE_URL}-with-grad-v1.modal.run"
|
|
105
92
|
|
|
106
93
|
response = requests.post(
|
|
@@ -116,8 +103,68 @@ def predict_array_with_grad(
|
|
|
116
103
|
return (prediction_array, gradient_array)
|
|
117
104
|
|
|
118
105
|
|
|
106
|
+
@primitive
|
|
107
|
+
def predict_array_with_grad(device_array: np.ndarray, model: Model) -> np.ndarray:
|
|
108
|
+
"""
|
|
109
|
+
Predict the nanofabrication outcome of a device array and compute its gradient.
|
|
110
|
+
|
|
111
|
+
This function predicts the outcome of the nanofabrication process for a given
|
|
112
|
+
device array using a specified model. It also computes the gradient of the
|
|
113
|
+
prediction with respect to the input device array.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
device_array : np.ndarray
|
|
118
|
+
A 2D array representing the planar geometry of the device.
|
|
119
|
+
model : Model
|
|
120
|
+
The model to use for prediction, representing a specific fabrication process.
|
|
121
|
+
|
|
122
|
+
Returns
|
|
123
|
+
-------
|
|
124
|
+
np.ndarray
|
|
125
|
+
The predicted output array.
|
|
126
|
+
"""
|
|
127
|
+
prediction_array, gradient_array = _predict_array_with_grad(
|
|
128
|
+
device_array=device_array, model=model
|
|
129
|
+
)
|
|
130
|
+
predict_array_with_grad.gradient_array = gradient_array
|
|
131
|
+
return prediction_array
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def predict_array_with_grad_vjp(ans: np.ndarray, x: np.ndarray, model: Model):
|
|
135
|
+
"""
|
|
136
|
+
Define the vector-Jacobian product (VJP) for the prediction function.
|
|
137
|
+
|
|
138
|
+
This function provides the VJP for the `predict_array_with_grad` function,
|
|
139
|
+
which is used in reverse-mode automatic differentiation to compute gradients.
|
|
140
|
+
|
|
141
|
+
Parameters
|
|
142
|
+
----------
|
|
143
|
+
ans : np.ndarray
|
|
144
|
+
The output of the `predict_array_with_grad` function.
|
|
145
|
+
x : np.ndarray
|
|
146
|
+
The input device array for which the gradient is computed.
|
|
147
|
+
model : Model
|
|
148
|
+
The model used for prediction.
|
|
149
|
+
|
|
150
|
+
Returns
|
|
151
|
+
-------
|
|
152
|
+
function
|
|
153
|
+
A function that computes the VJP given an upstream gradient `g`.
|
|
154
|
+
"""
|
|
155
|
+
grad_x = predict_array_with_grad.gradient_array
|
|
156
|
+
|
|
157
|
+
def vjp(g: np.ndarray) -> np.ndarray:
|
|
158
|
+
return g * grad_x
|
|
159
|
+
|
|
160
|
+
return vjp
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
defvjp(predict_array_with_grad, predict_array_with_grad_vjp)
|
|
164
|
+
|
|
165
|
+
|
|
119
166
|
def _encode_array(array):
|
|
120
|
-
"""Encode
|
|
167
|
+
"""Encode an ndarray as a base64 encoded image for transmission."""
|
|
121
168
|
image = Image.fromarray(np.uint8(array * 255))
|
|
122
169
|
buffered = io.BytesIO()
|
|
123
170
|
image.save(buffered, format="PNG")
|
|
@@ -126,7 +173,7 @@ def _encode_array(array):
|
|
|
126
173
|
|
|
127
174
|
|
|
128
175
|
def _decode_array(encoded_png):
|
|
129
|
-
"""Decode a base64 encoded
|
|
176
|
+
"""Decode a base64 encoded image and return an ndarray."""
|
|
130
177
|
binary_data = base64.b64decode(encoded_png)
|
|
131
178
|
image = Image.open(io.BytesIO(binary_data))
|
|
132
179
|
return np.array(image) / 255
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: prefab
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.5
|
|
4
4
|
Summary: Artificial nanofabrication of integrated photonic circuits using deep learning
|
|
5
5
|
Project-URL: Homepage, https://prefabphotonics.com
|
|
6
6
|
Project-URL: Repository, https://github.com/PreFab-Photonics/PreFab
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
prefab/__init__.py,sha256=0QHTuxxeHo3xJIUq20iQCLiC2nk-rgf2C374l-Aby-g,425
|
|
2
|
+
prefab/__main__.py,sha256=aAgt1WXa44k1nJqsiSD3uAfNeGpwtjWqMUYCHN5_Qrw,2759
|
|
3
|
+
prefab/compare.py,sha256=iz0H5EvZFZ5O-N2QOQ6wFe-Hftkfyd6oMYpjfjnrMIw,3251
|
|
4
|
+
prefab/device.py,sha256=kKmud8QxfSBvadeZw56W_MNXqjRIyTA16jNTQ8v69U0,53048
|
|
5
|
+
prefab/geometry.py,sha256=0sa6ietUWZGkxOnUPUzD3q2QpFuOpWkSANoopGpPd6s,11035
|
|
6
|
+
prefab/models.py,sha256=JpBqNFIqbo1ymKEl0NWWF4ZkhvK23rEVVBEFl05TXCI,3671
|
|
7
|
+
prefab/predict.py,sha256=upGTeNC6vY9Tdko6JEM0gKQH1PGUVYXACpep1OT8EVs,10593
|
|
8
|
+
prefab/read.py,sha256=MuF-cugFQ7MWBJ8DOvQuwktIk0fJ8PXBeLye0ydrB8o,14734
|
|
9
|
+
prefab/shapes.py,sha256=2qaqyNzu5WG3wVdk4oQzeNXmhwXRHcPnRZlgRrM4MoA,25576
|
|
10
|
+
prefab-1.1.5.dist-info/METADATA,sha256=tk_MMU6lQcjqt4FBDgjx87ziII0ulouu2zCj2Ayr-g8,34824
|
|
11
|
+
prefab-1.1.5.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
12
|
+
prefab-1.1.5.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
|
|
13
|
+
prefab-1.1.5.dist-info/RECORD,,
|
prefab-1.1.3.dist-info/RECORD
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
prefab/__init__.py,sha256=DuARo1QC4MGMw-yzCBLEoRlOU3MsKZTbWDCAqUpQjWM,425
|
|
2
|
-
prefab/__main__.py,sha256=aAgt1WXa44k1nJqsiSD3uAfNeGpwtjWqMUYCHN5_Qrw,2759
|
|
3
|
-
prefab/compare.py,sha256=2MKUT7N2A639tUGCnJHpfF9MmS-v3oARDkTqHbWJ9OM,3239
|
|
4
|
-
prefab/device.py,sha256=l0etqB0559xa9Frb0IKl5N3kU56vWHlwHc-qehINTlw,52292
|
|
5
|
-
prefab/geometry.py,sha256=0sa6ietUWZGkxOnUPUzD3q2QpFuOpWkSANoopGpPd6s,11035
|
|
6
|
-
prefab/models.py,sha256=JpBqNFIqbo1ymKEl0NWWF4ZkhvK23rEVVBEFl05TXCI,3671
|
|
7
|
-
prefab/predict.py,sha256=AuCh_vOMP0dD68u75WQaOTog6TMi1FG3nLQxv6UgIkA,8579
|
|
8
|
-
prefab/read.py,sha256=MuF-cugFQ7MWBJ8DOvQuwktIk0fJ8PXBeLye0ydrB8o,14734
|
|
9
|
-
prefab/shapes.py,sha256=2qaqyNzu5WG3wVdk4oQzeNXmhwXRHcPnRZlgRrM4MoA,25576
|
|
10
|
-
prefab-1.1.3.dist-info/METADATA,sha256=TGbeM7u0kktbeGeOwGIFS43dwp8rWvLSwHDYlXEcsfI,34824
|
|
11
|
-
prefab-1.1.3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
12
|
-
prefab-1.1.3.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
|
|
13
|
-
prefab-1.1.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|