bizydraft 0.2.82.dev20251209023307__py3-none-any.whl → 0.2.83.dev20251203095346__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.
bizydraft/oss_utils.py CHANGED
@@ -312,17 +312,9 @@ async def upload_mask(request):
312
312
  if "http" in original_subfolder:
313
313
  # subfolder 中包含 URL 基础路径
314
314
  original_subfolder = original_subfolder[original_subfolder.find("http") :]
315
- original_subfolder = unquote(original_subfolder)
316
- if "https:/" in original_subfolder and not original_subfolder.startswith(
317
- "https://"
318
- ):
319
- original_subfolder = original_subfolder.replace(
320
- "https:/", "https://", 1
321
- )
322
- if "http:/" in original_subfolder and not original_subfolder.startswith(
323
- "http://"
324
- ):
325
- original_subfolder = original_subfolder.replace("http:/", "http://", 1)
315
+ original_subfolder = unquote(original_subfolder).replace(
316
+ "https:/", "https://"
317
+ )
326
318
  original_url = f"{original_subfolder}/{original_filename}"
327
319
  elif original_filename.startswith(http_prefix_options):
328
320
  # filename 本身就是完整 URL
@@ -229,7 +229,6 @@ def human_readable_size(size_bytes):
229
229
 
230
230
 
231
231
  async def view_video(request):
232
- """处理VHS插件的viewvideo接口,支持从OSS URL加载视频"""
233
232
  logger.debug(
234
233
  f"Received request for /vhs/viewvideo with query: {request.rel_url.query}"
235
234
  )
@@ -238,23 +237,39 @@ async def view_video(request):
238
237
  logger.warning("'filename' not provided in query string, returning 404")
239
238
  return web.Response(status=404, text="'filename' not provided in query string")
240
239
 
241
- # VHS插件的filename参数本身就是完整的URL(可能是URL编码的)
242
240
  filename = unquote(request.rel_url.query["filename"])
241
+ subfolder = request.rel_url.query.get("subfolder", "")
243
242
 
244
243
  http_prefix_options = ("http:", "https:")
245
244
 
246
- if not filename.startswith(http_prefix_options):
247
- logger.warning(f"Invalid filename format: {filename=}, only URLs are supported")
245
+ if not filename.startswith(http_prefix_options) and "http" not in subfolder:
246
+ logger.warning(
247
+ f"Invalid filename format: {filename=}, {subfolder=} only URLs are supported"
248
+ )
248
249
  return web.Response(
249
250
  status=400, text="Invalid filename format(only url supported)"
250
251
  )
251
252
 
252
253
  try:
253
- content_type, _ = mimetypes.guess_type(filename)
254
+ if "http" in subfolder:
255
+ subfolder = subfolder[subfolder.find("http") :]
256
+ subfolder = unquote(subfolder)
257
+ if "https:/" in subfolder and not subfolder.startswith("https://"):
258
+ subfolder = subfolder.replace("https:/", "https://", 1)
259
+ if "http:/" in subfolder and not subfolder.startswith("http://"):
260
+ subfolder = subfolder.replace("http:/", "http://", 1)
261
+
262
+ full_url = (
263
+ f"{subfolder}/{filename}"
264
+ if not filename.startswith(http_prefix_options)
265
+ else filename
266
+ )
267
+
268
+ content_type, _ = mimetypes.guess_type(full_url)
254
269
 
255
270
  timeout = ClientTimeout(total=BIZYDRAFT_REQUEST_TIMEOUT)
256
271
  async with ClientSession(timeout=timeout) as session:
257
- async with session.get(filename) as resp:
272
+ async with session.get(full_url) as resp:
258
273
  resp.raise_for_status()
259
274
 
260
275
  # 优先使用服务器返回的Content-Type
@@ -17,6 +17,19 @@ function stripTypeSuffix(value) {
17
17
  if (!value || typeof value !== 'string') return value;
18
18
  return value.replace(/\s\[(input|output)\]$/i, '');
19
19
  }
20
+
21
+ function stripClipspacePrefix(subfolder) {
22
+ return typeof subfolder === 'string' ? subfolder.replace(/^clipspace\//, '') : subfolder;
23
+ }
24
+
25
+ function normalizeProtocolBase(base) {
26
+ return typeof base === 'string' ? base.replace(/^(https?:)\/+/, '$1//') : base;
27
+ }
28
+
29
+ function joinBaseAndFile(base, file) {
30
+ const sep = base.endsWith('/') ? '' : '/';
31
+ return `${base}${sep}${file}`;
32
+ }
20
33
  // ═══════════════════════════════════════════════════════════════════════════
21
34
  // 工具函数:替换 clipspace URL 为 OSS URL
22
35
  // ═══════════════════════════════════════════════════════════════════════════
@@ -29,6 +42,7 @@ function replaceClipspaceUrl(urlString) {
29
42
  const filename = url.searchParams.get('filename');
30
43
  const subfolder = url.searchParams.get('subfolder');
31
44
 
45
+ // subfolder 为 "clipspace",尝试映射为 OSS URL
32
46
  if (subfolder === 'clipspace' && filename) {
33
47
  const ossUrl = findOssUrl(filename);
34
48
  if (ossUrl) {
@@ -37,6 +51,15 @@ function replaceClipspaceUrl(urlString) {
37
51
  return url.pathname + url.search;
38
52
  }
39
53
  }
54
+ // 2) subfolder 形如 "clipspace/https:/..." 或 "clipspace/http:/..."
55
+ if (typeof subfolder === 'string' && subfolder.startsWith('clipspace/')) {
56
+ const fixedBase = normalizeProtocolBase(stripClipspacePrefix(subfolder));
57
+ if (filename) {
58
+ url.searchParams.set('filename', joinBaseAndFile(fixedBase, filename));
59
+ url.searchParams.set('subfolder', '');
60
+ return url.pathname + url.search;
61
+ }
62
+ }
40
63
  } catch (e) {
41
64
  console.error('[BizyDraft] Error replacing clipspace URL:', e);
42
65
  }
@@ -62,7 +85,7 @@ function replaceClipspaceUrl(urlString) {
62
85
  });
63
86
 
64
87
  const originalSetAttribute = HTMLImageElement.prototype.setAttribute;
65
- HTMLImageElement.prototype.setAttribute = function (name, value) {
88
+ HTMLImageElement.prototype.setAttribute = function(name, value) {
66
89
  if (name === 'src') {
67
90
  const modifiedValue = replaceClipspaceUrl(value);
68
91
  return originalSetAttribute.call(this, name, modifiedValue);
@@ -75,11 +98,10 @@ function replaceClipspaceUrl(urlString) {
75
98
  // 拦截上传响应,保存映射并篡改返回值
76
99
  // ═══════════════════════════════════════════════════════════════════════════
77
100
  const originalFetchApi = api.fetchApi;
78
- api.fetchApi = async function (url, options) {
101
+ api.fetchApi = async function(url, options) {
79
102
  const response = await originalFetchApi.call(this, url, options);
80
103
 
81
- const isUploadApi = url === '/upload/image' || url === '/upload/mask'
82
- || url === '/api/upload/image' || url === '/api/upload/mask';
104
+ const isUploadApi = url.includes('/upload/image') || url.includes('/upload/mask');
83
105
 
84
106
  if (!isUploadApi || !response.ok) {
85
107
  return response;
@@ -89,7 +111,7 @@ api.fetchApi = async function (url, options) {
89
111
 
90
112
  // 检查是否是 OSS 上传响应
91
113
  const isOssUpload = data.subfolder?.includes('http://') || data.subfolder?.includes('https://')
92
- || data.name?.startsWith('http://') || data.name?.startsWith('https://');
114
+ || data.name?.startsWith('http://') || data.name?.startsWith('https://');
93
115
 
94
116
  if (!isOssUpload) return response;
95
117
 
@@ -118,7 +140,7 @@ api.fetchApi = async function (url, options) {
118
140
  finalUrl = ossUrl;
119
141
 
120
142
  [`clipspace-mask-${baseId}.png`, `clipspace-paint-${baseId}.png`,
121
- `clipspace-painted-${baseId}.png`, `clipspace-painted-masked-${baseId}.png`
143
+ `clipspace-painted-${baseId}.png`, `clipspace-painted-masked-${baseId}.png`
122
144
  ].forEach(v => window.CLIPSPACE_TO_OSS_MAP[v] = ossUrl);
123
145
 
124
146
  } else {
@@ -156,11 +178,20 @@ api.fetchApi = async function (url, options) {
156
178
  // 修改 clipspace.images
157
179
  if (clipspace.images && clipspace.images.length > 0) {
158
180
  const clipImage = clipspace.images[clipspace.selectedIndex || 0];
159
- if (clipImage && clipImage.subfolder === 'clipspace') {
160
- clipspace.images[clipspace.selectedIndex || 0] = {
161
- filename: finalUrl,
162
- subfolder: ''
163
- };
181
+ if (clipImage) {
182
+ if (clipImage.subfolder === 'clipspace') {
183
+ clipspace.images[clipspace.selectedIndex || 0] = {
184
+ filename: finalUrl,
185
+ subfolder: ''
186
+ };
187
+ } else if (typeof clipImage.subfolder === 'string' && clipImage.subfolder.startsWith('clipspace/')) {
188
+ const fixedBase = normalizeProtocolBase(stripClipspacePrefix(clipImage.subfolder));
189
+ const file = clipImage.filename || data.name;
190
+ clipspace.images[clipspace.selectedIndex || 0] = {
191
+ filename: joinBaseAndFile(fixedBase, file),
192
+ subfolder: ''
193
+ };
194
+ }
164
195
  }
165
196
  }
166
197
 
@@ -169,17 +200,30 @@ api.fetchApi = async function (url, options) {
169
200
  const imageWidgetIndex = clipspace.widgets.findIndex(w => w.name === 'image');
170
201
  if (imageWidgetIndex >= 0) {
171
202
  const widgetValue = clipspace.widgets[imageWidgetIndex].value;
172
- if (widgetValue && typeof widgetValue === 'object' && widgetValue.subfolder === 'clipspace') {
173
- clipspace.widgets[imageWidgetIndex].value = {
174
- filename: finalUrl,
175
- subfolder: ''
176
- };
203
+ if (widgetValue && typeof widgetValue === 'object') {
204
+ if (widgetValue.subfolder === 'clipspace') {
205
+ clipspace.widgets[imageWidgetIndex].value = {
206
+ filename: finalUrl,
207
+ subfolder: ''
208
+ };
209
+ } else if (typeof widgetValue.subfolder === 'string' && widgetValue.subfolder.startsWith('clipspace/')) {
210
+ const fixedBase = normalizeProtocolBase(stripClipspacePrefix(widgetValue.subfolder));
211
+ const file = (typeof widgetValue.filename === 'string' && widgetValue.filename) ? widgetValue.filename : data.name;
212
+ clipspace.widgets[imageWidgetIndex].value = {
213
+ filename: joinBaseAndFile(fixedBase, file),
214
+ subfolder: ''
215
+ };
216
+ }
217
+ } else if (typeof widgetValue === 'string' && widgetValue.startsWith('clipspace/')) {
218
+ // 处理 value 为字符串且包含 clipspace/ 前缀的情况
219
+ const fixedUrl = normalizeProtocolBase(stripClipspacePrefix(widgetValue));
220
+ clipspace.widgets[imageWidgetIndex].value = fixedUrl;
177
221
  }
178
222
  }
179
223
  }
180
224
  }
181
225
 
182
- // 篡改响应,让 ComfyUI 使用完整的 OSS URL
226
+ // 非视频类型:篡改响应,让 ComfyUI 使用完整的 OSS URL
183
227
  const modifiedData = { ...data, name: finalUrl, subfolder: '' };
184
228
  return new Response(JSON.stringify(modifiedData), {
185
229
  status: response.status,
@@ -204,29 +248,16 @@ function convertClipspacePathsInPrompt(prompt) {
204
248
 
205
249
  for (const [inputKey, inputValue] of Object.entries(node.inputs)) {
206
250
  if (typeof inputValue === 'string' && inputValue.includes('clipspace')) {
207
- // 1) 特殊情况:clipspace/https://... 或 clipspace/http://...
208
- const ossUrlMatch = inputValue.match(/clipspace\/(https?:\/\/[^\s]+)/i);
209
- if (ossUrlMatch) {
210
- // 移除可能的 [input] 或 [output] 后缀
211
- let cleanUrl = ossUrlMatch[1].replace(/\s*\[(input|output)\]$/i, '');
212
- node.inputs[inputKey] = cleanUrl;
213
-
214
- if (inputKey === 'image' && node.inputs['image_name']) {
215
- node.inputs['image_name'] = cleanUrl.split('/').pop();
216
- }
217
- } else {
218
- // 2) 常规情况:clipspace/xxx.png
219
- const match = inputValue.match(/clipspace\/([\w-]+\.(?:png|jpg|jpeg|webp|gif))/i);
220
- if (match) {
221
- const filename = match[1];
222
- const ossUrl = findOssUrl(filename);
251
+ const match = inputValue.match(/clipspace\/([\w-]+\.(?:png|jpg|jpeg|webp|gif))/i);
252
+ if (match) {
253
+ const filename = match[1];
254
+ const ossUrl = findOssUrl(filename);
223
255
 
224
- if (ossUrl) {
225
- node.inputs[inputKey] = ossUrl;
256
+ if (ossUrl) {
257
+ node.inputs[inputKey] = ossUrl;
226
258
 
227
- if (inputKey === 'image' && node.inputs['image_name']) {
228
- node.inputs['image_name'] = ossUrl.split('/').pop();
229
- }
259
+ if (inputKey === 'image' && node.inputs['image_name']) {
260
+ node.inputs['image_name'] = ossUrl.split('/').pop();
230
261
  }
231
262
  }
232
263
  }
@@ -245,7 +276,7 @@ function interceptPasteFromClipspace() {
245
276
  if (!ComfyApp || !ComfyApp.pasteFromClipspace) return;
246
277
 
247
278
  const originalPasteFromClipspace = ComfyApp.pasteFromClipspace;
248
- ComfyApp.pasteFromClipspace = function (node) {
279
+ ComfyApp.pasteFromClipspace = function(node) {
249
280
  // 调用原始函数
250
281
  originalPasteFromClipspace.call(this, node);
251
282
 
@@ -257,23 +288,14 @@ function interceptPasteFromClipspace() {
257
288
 
258
289
  // 1) 如果是 clipspace 路径格式,替换为 OSS URL
259
290
  if (value.includes('clipspace/')) {
260
- // 1.1) 特殊情况:clipspace/https://... 或 clipspace/http://...
261
- // 这种情况是 OSS URL 被错误地加了 clipspace/ 前缀,直接移除前缀
262
- const ossUrlMatch = value.match(/clipspace\/(https?:\/\/[^\s]+)/i);
263
- if (ossUrlMatch) {
264
- // 移除可能的 [input] 或 [output] 后缀
265
- let cleanUrl = ossUrlMatch[1].replace(/\s*\[(input|output)\]$/i, '');
266
- imageWidget.value = cleanUrl;
267
- } else {
268
- // 1.2) 常规情况:clipspace/xxx.png,提取文件名并查找映射
269
- const match = value.match(/clipspace\/([\w-]+\.(?:png|jpg|jpeg|webp|gif))(\s\[(input|output)\])?/i);
270
- if (match) {
271
- const filename = match[1];
272
- const ossUrl = findOssUrl(filename);
273
-
274
- if (ossUrl) {
275
- imageWidget.value = ossUrl;
276
- }
291
+ // 提取文件名
292
+ const match = value.match(/clipspace\/([\w-]+\.(?:png|jpg|jpeg|webp|gif))(\s\[(input|output)\])?/i);
293
+ if (match) {
294
+ const filename = match[1];
295
+ const ossUrl = findOssUrl(filename);
296
+
297
+ if (ossUrl) {
298
+ imageWidget.value = ossUrl;
277
299
  }
278
300
  }
279
301
  }
@@ -295,31 +317,22 @@ app.registerExtension({
295
317
  async setup() {
296
318
  const originalGraphToPrompt = app.graphToPrompt;
297
319
 
298
- // 在构建 Prompt 之前,先清理所有 widget 的值,去掉多余的后缀和错误的 clipspace 前缀
320
+ // 在构建 Prompt 之前,先清理所有 widget 的值,去掉多余的后缀
299
321
  function sanitizeGraphWidgets(graph) {
300
322
  const nodes = graph?._nodes || [];
301
323
  for (const node of nodes) {
302
324
  if (!node?.widgets) continue;
303
325
  for (const widget of node.widgets) {
304
326
  if (typeof widget?.value === 'string') {
305
- let value = widget.value;
306
- // 先处理 clipspace/https://... 格式
307
- if (value.includes('clipspace/')) {
308
- const ossUrlMatch = value.match(/clipspace\/(https?:\/\/[^\s]+)/i);
309
- if (ossUrlMatch) {
310
- value = ossUrlMatch[1];
311
- }
312
- }
313
- // 再移除类型后缀
314
- widget.value = stripTypeSuffix(value);
327
+ widget.value = stripTypeSuffix(widget.value);
315
328
  }
316
329
  }
317
330
  }
318
331
  }
319
332
 
320
- app.graphToPrompt = async function (...args) {
333
+ app.graphToPrompt = async function(...args) {
321
334
  // 预清理,避免 workflow.widgets_values 和 prompt 输入里包含 [input]/[output]
322
- try { sanitizeGraphWidgets(app.graph); } catch (e) { }
335
+ try { sanitizeGraphWidgets(app.graph); } catch (e) {}
323
336
 
324
337
  const result = await originalGraphToPrompt.apply(this, args);
325
338
 
@@ -1,9 +1,6 @@
1
1
  // 主入口文件,导入所有模块
2
2
  import "./disableComfyWebSocket.js";
3
- import "./hookLoadImage.js";
3
+ import "./hookLoadMedia.js";
4
4
  import "./postEvent.js";
5
5
  import "./handleStyle.js";
6
6
  import "./clipspaceToOss.js";
7
- import "./aspectRatio.js";
8
- import "./imageUpload.js";
9
- import "./limitTimeRange.js";
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bizydraft
3
- Version: 0.2.82.dev20251209023307
3
+ Version: 0.2.83.dev20251203095346
4
4
  Summary: bizydraft
5
5
  Requires-Dist: loguru
6
6
  Requires-Dist: aiohttp
@@ -3,24 +3,21 @@ bizydraft/block_nodes.py,sha256=Lqn3oSCaGDHR2OICc8a2iRoRCVVK9v1-9MM3r-qIZgA,1092
3
3
  bizydraft/env.py,sha256=VFmGopVL2TGWA6hwxyFhIglCEcQxy6iVvL_raMNd6u4,407
4
4
  bizydraft/hijack_nodes.py,sha256=riHsp4DhU60E60bfXUl8kVqjs1QvQWmx_FsgQAdWTa4,4197
5
5
  bizydraft/hijack_routes.py,sha256=j7i9xAfaWvcu-mSoDISQyEwdERd0y-GFhvY2To7MRTU,5015
6
- bizydraft/oss_utils.py,sha256=_UzbS4e_MW5UynkQd2JI6edfdWxStm-Kbt6k7CvJJGA,16663
7
- bizydraft/patch_handlers.py,sha256=cP6gIYBYghWXI72hBbz3BbQHP1O5IvslS8iNK29MEbI,14159
6
+ bizydraft/oss_utils.py,sha256=IjWKFZ98KNvLw7bmFuqux5mEG36B8c9eQbQmL_gZo0M,16254
7
+ bizydraft/patch_handlers.py,sha256=l9bNRttr2RjZJIKboZ3noYdeXLIDkXepoNrGLVFrhTk,14694
8
8
  bizydraft/postload.py,sha256=XFElKcmCajT_oO7SVJJBaN04XcWro54N5HB5cSCxfvI,1308
9
9
  bizydraft/prestartup_patch.py,sha256=4FGjmRcDHELjtlQOrfTfk2Un5OS89QIqfq-gEcB9WDs,998
10
10
  bizydraft/resp.py,sha256=8INvKOe5Dgai3peKfqKjrhUoYeuXWXn358w30-_cY-A,369
11
11
  bizydraft/server.py,sha256=L2zoJgOisr65IRphOyko74AdsLel59gh55peyMaUrO8,2102
12
12
  bizydraft/workflow_io.py,sha256=MYhJbpgkv8hrA5k_aolijOTrWpTtu62nzRznA4hv8JE,4298
13
13
  bizydraft/static/js/aiAppHandler.js,sha256=OQRhhoqvc8iZeCvHTtdaD2VTYBGzkeAGdCk1UMO2RZs,17525
14
- bizydraft/static/js/aspectRatio.js,sha256=p--C62sTd2QLywa0KpB4T0QI-n7FXv8dO_6Tkl8vtdk,27943
15
- bizydraft/static/js/clipspaceToOss.js,sha256=zTXYzop4Gx0k0NA1MiWUA_J4RKq75tA_wQSroBASCyg,16177
14
+ bizydraft/static/js/clipspaceToOss.js,sha256=He9FbiS5CzsQHxGcUeeAUDNJBHXM6D6uNCYRK6KCAJA,16795
16
15
  bizydraft/static/js/disableComfyWebSocket.js,sha256=ZDOVlU3v3EvWpMRkD8s_AnO43vuWojVLLjkF2pNEVrA,1957
17
16
  bizydraft/static/js/freezeModeHandler.js,sha256=SjpHD2nYymR-E13B0YcqkA6e4WycZOVI3c48Ts9qvWE,18027
18
17
  bizydraft/static/js/handleStyle.js,sha256=GPshFVoa70UxLwFQB-kXZldVREE0cEF-BxxIM44ngkc,5436
19
18
  bizydraft/static/js/hookLoadMedia.js,sha256=EYDuitzOFvlNzM_e4IdE0-wXHQfnyCx7KrwzoxVTdr0,6363
20
19
  bizydraft/static/js/hookLoadModel.js,sha256=gY4D77DqVDzpuQZlqgqcUrL0Yho3koyR_lOHLyiqGfc,8204
21
- bizydraft/static/js/imageUpload.js,sha256=S7YY4jaaZq83epWyT5_s4GOCa2vC_-4MwWMg3HVHyCU,4178
22
- bizydraft/static/js/limitTimeRange.js,sha256=Bz-qHOfqUZk0zr8HYfuR3AzCYjUJHUvp8CdYLu0o6Ic,4619
23
- bizydraft/static/js/main.js,sha256=LaIbmXPOsKrXzwsQRaXE7HXXyw_q0FcXX492ik-f0F0,272
20
+ bizydraft/static/js/main.js,sha256=-pMeAG8vkKO6yq9zXCeHI78KezGn0r9AhYm65DuZrVI,188
24
21
  bizydraft/static/js/nodeFocusHandler.js,sha256=24xXbS4Q-GjJdRqf11i-1pBo8MkOJ24F7MHFV44EG6Q,4683
25
22
  bizydraft/static/js/nodeParamsFilter.js,sha256=H7lBB0G8HNqoGhOCH1hNXqPU-rPlrFyTxg_f_JgLEMk,4168
26
23
  bizydraft/static/js/postEvent.js,sha256=_EyA71m5DwGbhHsuf1amKhpLUBxfBWZaMMxViNhuYzU,43481
@@ -31,7 +28,7 @@ bizydraft/static/js/workflow_io.js,sha256=FWAjncvWhvy-3nN_legD2fpRwgnIncpRLHU5X0
31
28
  bizydraft/static/js/hookLoad/configLoader.js,sha256=R1k0GKdEmv4IIxdT2F-oOI9X9I19ECe77P_1tO3XxgY,2525
32
29
  bizydraft/static/js/hookLoad/media.js,sha256=iX_zoZ0OzLAdYZ3bn5GpzpnwU-YjcBuEozQt-MwNuwk,17936
33
30
  bizydraft/static/js/hookLoad/model.js,sha256=aHvEPt9k3CcrawHSYnQYcvbtTRwIztk-XDRA3lvgXvA,9890
34
- bizydraft-0.2.82.dev20251209023307.dist-info/METADATA,sha256=aD-Dv6wd_rBGaWBYs62q5ts7qtZad8PV0I9dh1k_tik,180
35
- bizydraft-0.2.82.dev20251209023307.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
- bizydraft-0.2.82.dev20251209023307.dist-info/top_level.txt,sha256=XtoBq6hjZhXIM7aas4GtPDtAiKo8FdLzMABXW8qqQ8M,10
37
- bizydraft-0.2.82.dev20251209023307.dist-info/RECORD,,
31
+ bizydraft-0.2.83.dev20251203095346.dist-info/METADATA,sha256=-rRdMygQkxyvbTl256yZrDzxVT_lAAkqhCRKydworNU,180
32
+ bizydraft-0.2.83.dev20251203095346.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
33
+ bizydraft-0.2.83.dev20251203095346.dist-info/top_level.txt,sha256=XtoBq6hjZhXIM7aas4GtPDtAiKo8FdLzMABXW8qqQ8M,10
34
+ bizydraft-0.2.83.dev20251203095346.dist-info/RECORD,,