annofabcli 1.106.4__py3-none-any.whl → 1.106.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.
- annofabcli/stat_visualization/write_performance_rating_csv.py +49 -48
- annofabcli/statistics/visualization/dataframe/project_performance.py +10 -1
- {annofabcli-1.106.4.dist-info → annofabcli-1.106.5.dist-info}/METADATA +1 -1
- {annofabcli-1.106.4.dist-info → annofabcli-1.106.5.dist-info}/RECORD +7 -7
- {annofabcli-1.106.4.dist-info → annofabcli-1.106.5.dist-info}/WHEEL +0 -0
- {annofabcli-1.106.4.dist-info → annofabcli-1.106.5.dist-info}/entry_points.txt +0 -0
- {annofabcli-1.106.4.dist-info → annofabcli-1.106.5.dist-info}/licenses/LICENSE +0 -0
|
@@ -178,10 +178,10 @@ class CollectingPerformanceInfo:
|
|
|
178
178
|
self.productivity_indicator_by_directory = productivity_indicator_by_directory if productivity_indicator_by_directory is not None else {}
|
|
179
179
|
self.quality_indicator_by_directory = quality_indicator_by_directory if quality_indicator_by_directory is not None else {}
|
|
180
180
|
|
|
181
|
-
def get_threshold_info(self,
|
|
181
|
+
def get_threshold_info(self, dirname: str, productivity_type: ProductivityType) -> ThresholdInfo:
|
|
182
182
|
"""指定したプロジェクト名に対応する、閾値情報を取得する。"""
|
|
183
183
|
global_info = self.threshold_info
|
|
184
|
-
local_info = self.threshold_infos_by_directory.get((
|
|
184
|
+
local_info = self.threshold_infos_by_directory.get((dirname, productivity_type))
|
|
185
185
|
if local_info is None:
|
|
186
186
|
return global_info
|
|
187
187
|
|
|
@@ -190,7 +190,7 @@ class CollectingPerformanceInfo:
|
|
|
190
190
|
|
|
191
191
|
return ThresholdInfo(threshold_worktime=worktime, threshold_task_count=task_count)
|
|
192
192
|
|
|
193
|
-
def filter_df_with_threshold(self, df: pandas.DataFrame, phase: TaskPhase,
|
|
193
|
+
def filter_df_with_threshold(self, df: pandas.DataFrame, phase: TaskPhase, dirname: str): # noqa: ANN201
|
|
194
194
|
"""
|
|
195
195
|
引数`df`をインタンスとして持っている閾値情報でフィルタリングする。
|
|
196
196
|
"""
|
|
@@ -201,7 +201,7 @@ class CollectingPerformanceInfo:
|
|
|
201
201
|
else:
|
|
202
202
|
raise RuntimeError(f"未対応のフェーズです。phase={phase}")
|
|
203
203
|
|
|
204
|
-
threshold_info = self.get_threshold_info(
|
|
204
|
+
threshold_info = self.get_threshold_info(dirname, productivity_type)
|
|
205
205
|
if threshold_info.threshold_worktime is not None:
|
|
206
206
|
df = df[df[(self.productivity_indicator.worktime_type.value, phase.value)] > threshold_info.threshold_worktime]
|
|
207
207
|
|
|
@@ -210,42 +210,44 @@ class CollectingPerformanceInfo:
|
|
|
210
210
|
|
|
211
211
|
return df
|
|
212
212
|
|
|
213
|
-
def join_annotation_productivity(self, df: pandas.DataFrame, df_performance: pandas.DataFrame, project_title: str) -> pandas.DataFrame:
|
|
213
|
+
def join_annotation_productivity(self, df: pandas.DataFrame, df_performance: pandas.DataFrame, dirname: str, project_title: str) -> pandas.DataFrame:
|
|
214
214
|
"""
|
|
215
215
|
引数`df_performance`から教師付生産性を抽出して引数`df`にjoinした結果を返す
|
|
216
216
|
|
|
217
217
|
Args:
|
|
218
218
|
df: 教師付生産性が格納されたDataFrame。行方向にユーザー、列方向にプロジェクトが並んでいる。
|
|
219
|
-
|
|
220
|
-
df_performance: 引数`
|
|
219
|
+
dirname: 引数`df`にjoinする対象のプロジェクト名。列名に使用する。
|
|
220
|
+
df_performance: 引数`dirname`のユーザーごとの生産性と品質が格納されたDataFrame。
|
|
221
221
|
"""
|
|
222
222
|
phase = TaskPhase.ANNOTATION
|
|
223
223
|
|
|
224
224
|
df_joined = df_performance
|
|
225
225
|
|
|
226
|
-
df_joined = self.filter_df_with_threshold(df_joined, phase,
|
|
226
|
+
df_joined = self.filter_df_with_threshold(df_joined, phase, dirname=dirname)
|
|
227
227
|
|
|
228
|
-
productivity_indicator = self.productivity_indicator_by_directory.get(
|
|
228
|
+
productivity_indicator = self.productivity_indicator_by_directory.get(dirname, self.productivity_indicator)
|
|
229
229
|
column = (productivity_indicator.column, phase.value)
|
|
230
230
|
if column in df_joined.columns:
|
|
231
231
|
df_tmp = df_joined[[column]]
|
|
232
232
|
else:
|
|
233
|
-
logger.warning(f"'{
|
|
233
|
+
logger.warning(f"'{dirname}'に生産性の指標である'{column}'の列が存在しませんでした。")
|
|
234
234
|
df_tmp = pandas.DataFrame(index=df_joined.index, columns=[column])
|
|
235
|
-
df_tmp.columns = pandas.MultiIndex.from_tuples([(project_title, f"{productivity_indicator.column}__{phase.value}")])
|
|
235
|
+
df_tmp.columns = pandas.MultiIndex.from_tuples([(dirname, project_title, f"{productivity_indicator.column}__{phase.value}")])
|
|
236
|
+
|
|
236
237
|
return df.join(df_tmp)
|
|
237
238
|
|
|
238
|
-
def join_inspection_acceptance_productivity(self, df: pandas.DataFrame, df_performance: pandas.DataFrame, project_title: str) -> pandas.DataFrame:
|
|
239
|
+
def join_inspection_acceptance_productivity(self, df: pandas.DataFrame, df_performance: pandas.DataFrame, dirname: str, project_title: str) -> pandas.DataFrame:
|
|
239
240
|
"""
|
|
240
241
|
引数`df_performance`から検査/受入の生産性を抽出して引数`df`にjoinした結果を返す
|
|
241
242
|
|
|
242
243
|
Args:
|
|
243
244
|
df: 検査/受入の生産性が格納されたDataFrame。行方向にユーザー、列方向にプロジェクトが並んでいる。
|
|
244
|
-
|
|
245
|
-
|
|
245
|
+
dirname: 引数`df`にjoinする対象のプロジェクト名。列名に使用する。
|
|
246
|
+
project_title: プロジェクトのタイトル。列名に使用する。
|
|
247
|
+
df_performance: 引数`dirname`のユーザーごとの生産性と品質が格納されたDataFrame。
|
|
246
248
|
"""
|
|
247
249
|
|
|
248
|
-
productivity_indicator = self.productivity_indicator_by_directory.get(
|
|
250
|
+
productivity_indicator = self.productivity_indicator_by_directory.get(dirname, self.productivity_indicator)
|
|
249
251
|
|
|
250
252
|
def _join_inspection() -> pandas.DataFrame:
|
|
251
253
|
phase = TaskPhase.INSPECTION
|
|
@@ -253,10 +255,10 @@ class CollectingPerformanceInfo:
|
|
|
253
255
|
return df
|
|
254
256
|
|
|
255
257
|
df_joined = df_performance
|
|
256
|
-
df_joined = self.filter_df_with_threshold(df_joined, phase,
|
|
258
|
+
df_joined = self.filter_df_with_threshold(df_joined, phase, dirname=dirname)
|
|
257
259
|
|
|
258
260
|
df_tmp = df_joined[[(productivity_indicator.column, phase.value)]]
|
|
259
|
-
df_tmp.columns = pandas.MultiIndex.from_tuples([(project_title, f"{productivity_indicator.column}__{phase.value}")])
|
|
261
|
+
df_tmp.columns = pandas.MultiIndex.from_tuples([(dirname, project_title, f"{productivity_indicator.column}__{phase.value}")])
|
|
260
262
|
|
|
261
263
|
return df.join(df_tmp)
|
|
262
264
|
|
|
@@ -266,10 +268,10 @@ class CollectingPerformanceInfo:
|
|
|
266
268
|
return df
|
|
267
269
|
|
|
268
270
|
df_joined = df_performance
|
|
269
|
-
df_joined = self.filter_df_with_threshold(df_joined, phase,
|
|
271
|
+
df_joined = self.filter_df_with_threshold(df_joined, phase, dirname=dirname)
|
|
270
272
|
|
|
271
273
|
df_tmp = df_joined[[(productivity_indicator.column, phase.value)]]
|
|
272
|
-
df_tmp.columns = pandas.MultiIndex.from_tuples([(project_title, f"{productivity_indicator.column}__{phase.value}")])
|
|
274
|
+
df_tmp.columns = pandas.MultiIndex.from_tuples([(dirname, project_title, f"{productivity_indicator.column}__{phase.value}")])
|
|
273
275
|
|
|
274
276
|
return df.join(df_tmp)
|
|
275
277
|
|
|
@@ -278,30 +280,31 @@ class CollectingPerformanceInfo:
|
|
|
278
280
|
|
|
279
281
|
return df
|
|
280
282
|
|
|
281
|
-
def join_annotation_quality(self, df: pandas.DataFrame, df_performance: pandas.DataFrame, project_title: str) -> pandas.DataFrame:
|
|
283
|
+
def join_annotation_quality(self, df: pandas.DataFrame, df_performance: pandas.DataFrame, dirname: str, project_title: str) -> pandas.DataFrame:
|
|
282
284
|
"""
|
|
283
285
|
引数`df_performance`から教師付の品質を抽出して引数`df`にjoinした結果を返す
|
|
284
286
|
|
|
285
287
|
Args:
|
|
286
288
|
df: 教師付の品質が格納されたDataFrame。行方向にユーザー、列方向にプロジェクトが並んでいる。
|
|
287
|
-
|
|
288
|
-
|
|
289
|
+
dirname: 引数`df`にjoinする対象のプロジェクト名。列名に使用する。
|
|
290
|
+
project_title: プロジェクトのタイトル。列名に使用する。
|
|
291
|
+
df_performance: 引数`dirname`のユーザーごとの生産性と品質が格納されたDataFrame。
|
|
289
292
|
"""
|
|
290
293
|
phase = TaskPhase.ANNOTATION
|
|
291
294
|
df_joined = df_performance
|
|
292
295
|
|
|
293
|
-
df_joined = self.filter_df_with_threshold(df_joined, phase=TaskPhase.ANNOTATION,
|
|
296
|
+
df_joined = self.filter_df_with_threshold(df_joined, phase=TaskPhase.ANNOTATION, dirname=dirname)
|
|
294
297
|
|
|
295
|
-
quality_indicator = self.quality_indicator_by_directory.get(
|
|
298
|
+
quality_indicator = self.quality_indicator_by_directory.get(dirname, self.quality_indicator)
|
|
296
299
|
|
|
297
300
|
column = (quality_indicator.column, phase.value)
|
|
298
301
|
if column in df_joined.columns:
|
|
299
302
|
df_tmp = df_joined[[column]]
|
|
300
303
|
else:
|
|
301
|
-
logger.warning(f"'{
|
|
304
|
+
logger.warning(f"'{dirname}'に品質の指標である'{column}'の列が存在しませんでした。")
|
|
302
305
|
df_tmp = pandas.DataFrame(index=df_joined.index, columns=[column])
|
|
303
306
|
|
|
304
|
-
df_tmp.columns = pandas.MultiIndex.from_tuples([(project_title, f"{quality_indicator.column}__{phase.value}")])
|
|
307
|
+
df_tmp.columns = pandas.MultiIndex.from_tuples([(dirname, project_title, f"{quality_indicator.column}__{phase.value}")])
|
|
305
308
|
return df.join(df_tmp)
|
|
306
309
|
|
|
307
310
|
def create_rating_df(
|
|
@@ -321,7 +324,7 @@ class CollectingPerformanceInfo:
|
|
|
321
324
|
continue
|
|
322
325
|
|
|
323
326
|
custom_production_volume_list = custom_production_volume_list_by_directory.get(p_project_dir.name) if custom_production_volume_list_by_directory is not None else None
|
|
324
|
-
|
|
327
|
+
dirname = p_project_dir.name
|
|
325
328
|
project_dir = ProjectDir(
|
|
326
329
|
p_project_dir,
|
|
327
330
|
task_completion_criteria=TaskCompletionCriteria.ACCEPTANCE_COMPLETED,
|
|
@@ -329,6 +332,14 @@ class CollectingPerformanceInfo:
|
|
|
329
332
|
)
|
|
330
333
|
project_dir_list.append(project_dir)
|
|
331
334
|
|
|
335
|
+
try:
|
|
336
|
+
project_info = project_dir.read_project_info()
|
|
337
|
+
project_title = project_info.project_title
|
|
338
|
+
except Exception:
|
|
339
|
+
# 複数のプロジェクトをマージして生産性情報を出力した場合は、`project_info.json`は存在しないので、このブロックに入る
|
|
340
|
+
logger.info(f"'{project_dir}'からプロジェクト情報を読み込むのに失敗しました。project_titleは空文字にします。", exc_info=True)
|
|
341
|
+
project_title = ""
|
|
342
|
+
|
|
332
343
|
try:
|
|
333
344
|
user_performance = project_dir.read_user_performance()
|
|
334
345
|
except Exception:
|
|
@@ -341,23 +352,11 @@ class CollectingPerformanceInfo:
|
|
|
341
352
|
df_performance = user_performance.df.copy()
|
|
342
353
|
df_performance.set_index("user_id", inplace=True)
|
|
343
354
|
|
|
344
|
-
df_annotation_productivity = self.join_annotation_productivity(
|
|
345
|
-
df_annotation_productivity,
|
|
346
|
-
df_performance,
|
|
347
|
-
project_title=project_title,
|
|
348
|
-
)
|
|
355
|
+
df_annotation_productivity = self.join_annotation_productivity(df_annotation_productivity, df_performance, dirname=dirname, project_title=project_title)
|
|
349
356
|
|
|
350
|
-
df_annotation_quality = self.join_annotation_quality(
|
|
351
|
-
df_annotation_quality,
|
|
352
|
-
df_performance,
|
|
353
|
-
project_title=project_title,
|
|
354
|
-
)
|
|
357
|
+
df_annotation_quality = self.join_annotation_quality(df_annotation_quality, df_performance, dirname=dirname, project_title=project_title)
|
|
355
358
|
|
|
356
|
-
df_inspection_acceptance_productivity = self.join_inspection_acceptance_productivity(
|
|
357
|
-
df_inspection_acceptance_productivity,
|
|
358
|
-
df_performance,
|
|
359
|
-
project_title=project_title,
|
|
360
|
-
)
|
|
359
|
+
df_inspection_acceptance_productivity = self.join_inspection_acceptance_productivity(df_inspection_acceptance_productivity, df_performance, dirname=dirname, project_title=project_title)
|
|
361
360
|
|
|
362
361
|
# プロジェクトの生産性と品質のDataFrameを生成する
|
|
363
362
|
project_performance = ProjectPerformance.from_project_dirs(project_dir_list)
|
|
@@ -443,9 +442,9 @@ def create_deviation_df(
|
|
|
443
442
|
|
|
444
443
|
df_rank["mean_of_deviation"] = df_rank[project_columns].mean(axis=1)
|
|
445
444
|
df_rank["count_of_project"] = df_rank[project_columns].count(axis=1)
|
|
446
|
-
df = df_rank[[*list(user_columns), ("mean_of_deviation", ""), ("count_of_project", ""), *list(project_columns)]]
|
|
445
|
+
df = df_rank[[*list(user_columns), ("mean_of_deviation", "", ""), ("count_of_project", "", ""), *list(project_columns)]]
|
|
447
446
|
if user_ids is not None:
|
|
448
|
-
return df[df[("user_id", "")].isin(user_ids)]
|
|
447
|
+
return df[df[("user_id", "", "")].isin(user_ids)]
|
|
449
448
|
else:
|
|
450
449
|
return df
|
|
451
450
|
|
|
@@ -463,7 +462,7 @@ def create_user_df(target_dir: Path) -> pandas.DataFrame:
|
|
|
463
462
|
target_dir:
|
|
464
463
|
|
|
465
464
|
Returns:
|
|
466
|
-
ユーザのDataFrame. columnは("username", ""), ("biography", "") , indexが"user_id"
|
|
465
|
+
ユーザのDataFrame. columnは("username", "", ""), ("biography", "", "") , indexが"user_id"
|
|
467
466
|
|
|
468
467
|
"""
|
|
469
468
|
all_user_list: list[dict[str, Any]] = []
|
|
@@ -486,10 +485,12 @@ def create_user_df(target_dir: Path) -> pandas.DataFrame:
|
|
|
486
485
|
tmp_df_user = user_performance.df[[("user_id", ""), ("username", ""), ("biography", "")]].copy()
|
|
487
486
|
all_user_list.extend(tmp_df_user.to_dict("records"))
|
|
488
487
|
|
|
489
|
-
|
|
490
|
-
|
|
488
|
+
df_user = pandas.DataFrame(all_user_list, columns=pandas.MultiIndex.from_tuples([("user_id", ""), ("username", ""), ("biography", "")]))
|
|
489
|
+
|
|
491
490
|
df_user.drop_duplicates(inplace=True)
|
|
492
|
-
|
|
491
|
+
# 出力結果のCSV列に合わせて3行の列名に変更する
|
|
492
|
+
df_user.columns = pandas.MultiIndex.from_tuples([("user_id", "", ""), ("username", "", ""), ("biography", "", "")])
|
|
493
|
+
return df_user.sort_values(("user_id", "", "")).set_index(("user_id", "", ""))
|
|
493
494
|
|
|
494
495
|
|
|
495
496
|
def create_custom_production_volume_by_directory(cli_value: str) -> dict[str, list[ProductionVolumeColumn]]:
|
|
@@ -139,6 +139,15 @@ class ProjectWorktimePerMonth:
|
|
|
139
139
|
new_index = [str(dt)[0:7] for dt in series.index]
|
|
140
140
|
result = pandas.Series(series.values, index=new_index)
|
|
141
141
|
result["dirname"] = project_dir.project_dir.name
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
project_info = project_dir.read_project_info()
|
|
145
|
+
project_title = project_info.project_title
|
|
146
|
+
except Exception:
|
|
147
|
+
# 複数のプロジェクトをマージして生産性情報を出力した場合は、`project_info.json`は存在しないので、このブロックに入る
|
|
148
|
+
logger.info(f"'{project_dir}'からプロジェクト情報を読み込むのに失敗しました。project_titleは空文字にします。", exc_info=True)
|
|
149
|
+
project_title = ""
|
|
150
|
+
result["project_title"] = project_title
|
|
142
151
|
return result
|
|
143
152
|
|
|
144
153
|
@classmethod
|
|
@@ -170,7 +179,7 @@ class ProjectWorktimePerMonth:
|
|
|
170
179
|
if not self._validate_df_for_output(output_file):
|
|
171
180
|
return
|
|
172
181
|
|
|
173
|
-
header_columns = ["dirname"]
|
|
182
|
+
header_columns = ["dirname", "project_title"]
|
|
174
183
|
remain_columns = list(self.df.columns)
|
|
175
184
|
for col in header_columns:
|
|
176
185
|
remain_columns.remove(col)
|
|
@@ -133,7 +133,7 @@ annofabcli/stat_visualization/merge_visualization_dir.py,sha256=7rOluAY7X5rcukWs
|
|
|
133
133
|
annofabcli/stat_visualization/subcommand_stat_visualization.py,sha256=vk-LPAjhfkTaGHC-pDLhwLCc0opF3hMz-0af3yichuA,1484
|
|
134
134
|
annofabcli/stat_visualization/summarize_whole_performance_csv.py,sha256=gPldqPECBqC61IdTw7JPAscUVRz76YluDiF3QOVnSEk,3099
|
|
135
135
|
annofabcli/stat_visualization/write_graph.py,sha256=gRO0LcZ6x7Jgln9ALUUM3BHTMaAt1H15PB4_0bRo8TI,9101
|
|
136
|
-
annofabcli/stat_visualization/write_performance_rating_csv.py,sha256=
|
|
136
|
+
annofabcli/stat_visualization/write_performance_rating_csv.py,sha256=OfKounf4eQW7pzNrFxUtySPX9fdRaFQKRvtL0-v-wE8,31265
|
|
137
137
|
annofabcli/statistics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
138
138
|
annofabcli/statistics/histogram.py,sha256=CvzDxT2cKLSnBGSqkZE6p92PayGxYYja1YyB24M4ALU,3245
|
|
139
139
|
annofabcli/statistics/linegraph.py,sha256=0kr7jVBNMiM2ECYhv3Ry5RitElKerSl9ZKxbKzfiplI,12494
|
|
@@ -166,7 +166,7 @@ annofabcli/statistics/visualization/dataframe/custom_production_volume.py,sha256
|
|
|
166
166
|
annofabcli/statistics/visualization/dataframe/input_data_count.py,sha256=wDRFtoIWw_Gy2bPZ7LBx3eMO3LdUdjbQKS9mncXav6I,1654
|
|
167
167
|
annofabcli/statistics/visualization/dataframe/inspection_comment_count.py,sha256=RxpQzRy4U2hKEpgbksUXotcxH2sKz__NO20mxpMqK1w,4382
|
|
168
168
|
annofabcli/statistics/visualization/dataframe/productivity_per_date.py,sha256=_AibOSwyeGM6KeYqknN40M8vS4Tl6l45tC0ua1AHFFc,27087
|
|
169
|
-
annofabcli/statistics/visualization/dataframe/project_performance.py,sha256=
|
|
169
|
+
annofabcli/statistics/visualization/dataframe/project_performance.py,sha256=YYv_vWjtB9RBPInp-_jCg1fJIFHeKDgk1w5VEhdtlBU,9078
|
|
170
170
|
annofabcli/statistics/visualization/dataframe/task.py,sha256=v5vUbKJAuqqcKeumrAc4t2PKEX7jt86xFqqko0LrI98,25044
|
|
171
171
|
annofabcli/statistics/visualization/dataframe/task_history.py,sha256=FZ3MLqOiM6834fxWZKP0Hy9WDRSSLCYm6kNzdWW7-S8,2744
|
|
172
172
|
annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py,sha256=khXqxQ-v7Q1PBtttQmPCCbVLraeqNCPi2tkhTxxaZPg,13641
|
|
@@ -209,8 +209,8 @@ annofabcli/task_history_event/download_task_history_event_json.py,sha256=hQLVbQ0
|
|
|
209
209
|
annofabcli/task_history_event/list_all_task_history_event.py,sha256=EeKMyPUxGwYCFtWQHHW954ZserGm8lUqrwNnV1iX9X4,6830
|
|
210
210
|
annofabcli/task_history_event/list_worktime.py,sha256=Y7Pu5DP7scPf7HPt6CTiTvB1_5_Nfi1bStUIaCpkhII,15507
|
|
211
211
|
annofabcli/task_history_event/subcommand_task_history_event.py,sha256=mJVJoT4RXk4HWnY7-Nrsl4If-gtaIIEXd2z7eFZwM2I,1260
|
|
212
|
-
annofabcli-1.106.
|
|
213
|
-
annofabcli-1.106.
|
|
214
|
-
annofabcli-1.106.
|
|
215
|
-
annofabcli-1.106.
|
|
216
|
-
annofabcli-1.106.
|
|
212
|
+
annofabcli-1.106.5.dist-info/METADATA,sha256=pyB9yiLXILXx5FOgB9-ovYSkWROiJJOrX1L7bctwmQo,5286
|
|
213
|
+
annofabcli-1.106.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
214
|
+
annofabcli-1.106.5.dist-info/entry_points.txt,sha256=C2uSUc-kkLJpoK_mDL5FEMAdorLEMPfwSf8VBMYnIFM,56
|
|
215
|
+
annofabcli-1.106.5.dist-info/licenses/LICENSE,sha256=pcqWYfxFtxBzhvKp3x9MXNM4xciGb2eFewaRhXUNHlo,1081
|
|
216
|
+
annofabcli-1.106.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|