Compare commits

..
18 Commits
Author SHA1 Message Date
Dr.Lt.Data 89e24b7529 fixed: LoadImagesFromDirBatch - invalid mask processing
https://github.com/ltdrdata/ComfyUI-Inspire-Pack/issues/151
2024-08-28 20:33:00 +09:00
Dr.Lt.Data 6db6ca54c0 Merge pull request #150 from jesperol/fix_noise_return
fix: return_with_leftover_noise propagation
2024-08-28 10:45:11 +09:00
Jesper Olsson 69b7c486a9 fix: return_with_leftover_noise propagation 2024-08-21 17:22:31 +02:00
Dr.Lt.Data b09b295009 FIXED: mix_noise - device mismatch error 2024-08-21 01:45:10 +09:00
Dr.Lt.Data a15d3362d8 Merge pull request #143 from pixelprotest/feature/load-last-image-batch-from-dir
Add ability to use Load Image Batch from Dir node, to load the last / latest image in a directory
2024-08-20 22:56:12 +09:00
pixelprotest 019713040c Allow min start_index to drop to -1 to make node get last/latest image from dir 2024-08-20 13:30:59 +01:00
Dr.Lt.Data bc075b1a4f version marker 2024-08-18 19:32:37 +09:00
Dr.Lt.Data 452d8cfc00 Merge pull request #142 from anhkhoatranle30/main
Add filepaths as outputs
2024-08-18 19:30:24 +09:00
khoatrn 17716ddb52 feat: Add filepaths as outputs 2024-08-18 16:14:57 +07:00
Dr.Lt.Data 56f4f01f02 fix: LBW - no effect if weight is less than 0 2024-08-17 11:47:18 +09:00
Dr.Lt.Data f64c98714b improve: LBW - efficient patch
fix: LBW - preset patch
2024-08-17 11:28:03 +09:00
Dr.Lt.Data 30974e69c4 feat: LBW for FLUX 2024-08-17 00:36:48 +09:00
Dr.Lt.Data ec29936d16 fix: IPAdapterModelHelper - compatibility patch
- `insightface_model_name` is added.
2024-08-15 21:16:52 +09:00
Dr.Lt.Data 0bd92419de improve: FloatRange - support decrement 2024-08-14 12:43:03 +09:00
Dr.Lt.Data ec6831fd68 version marker 2024-08-07 23:13:40 +09:00
Dr.Lt.Data c876e477e8 Merge pull request #136 from bvhari/main
Add cosine interpolation for Scheduled CFG
2024-08-07 23:13:01 +09:00
BVH 0de0e4232c Change newline to fix diff 2024-08-07 03:14:06 +05:30
BVH 61ba155cf1 Add cosine interpolation for Scheduled CFG 2024-08-04 23:59:46 +05:30
9 changed files with 200 additions and 32 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
import importlib
version_code = [0, 82, 7]
version_code = [0, 86, 2]
version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
print(f"### Loading: ComfyUI-Inspire-Pack ({version_str})")
+9 -6
View File
@@ -18,7 +18,7 @@ class LoadImagesFromDirBatch:
},
"optional": {
"image_load_cap": ("INT", {"default": 0, "min": 0, "step": 1}),
"start_index": ("INT", {"default": 0, "min": 0, "step": 1}),
"start_index": ("INT", {"default": 0, "min": -1, "step": 1}),
"load_always": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
}
}
@@ -94,10 +94,10 @@ class LoadImagesFromDirBatch:
image2 = comfy.utils.common_upscale(image2.movedim(-1, 1), image1.shape[2], image1.shape[1], "bilinear", "center").movedim(1, -1)
image1 = torch.cat((image1, image2), dim=0)
for mask2 in masks[1:]:
for mask2 in masks:
if has_non_empty_mask:
if image1.shape[1:3] != mask2.shape:
mask2 = torch.nn.functional.interpolate(mask2.unsqueeze(0).unsqueeze(0), size=(image1.shape[2], image1.shape[1]), mode='bilinear', align_corners=False)
mask2 = torch.nn.functional.interpolate(mask2.unsqueeze(0).unsqueeze(0), size=(image1.shape[1], image1.shape[2]), mode='bilinear', align_corners=False)
mask2 = mask2.squeeze(0)
else:
mask2 = mask2.unsqueeze(0)
@@ -126,8 +126,9 @@ class LoadImagesFromDirList:
}
}
RETURN_TYPES = ("IMAGE", "MASK")
OUTPUT_IS_LIST = (True, True)
RETURN_TYPES = ("IMAGE", "MASK", "STRING")
RETURN_NAMES = ("IMAGE", "MASK", "FILE PATH")
OUTPUT_IS_LIST = (True, True, True)
FUNCTION = "load_images"
@@ -159,6 +160,7 @@ class LoadImagesFromDirList:
images = []
masks = []
file_paths = []
limit_images = False
if image_load_cap > 0:
@@ -184,9 +186,10 @@ class LoadImagesFromDirList:
images.append(image)
masks.append(mask)
file_paths.append(str(image_path))
image_count += 1
return images, masks
return (images, masks, file_paths)
class LoadImageInspire:
+2
View File
@@ -56,6 +56,8 @@ def slerp(val, low, high):
def mix_noise(from_noise, to_noise, strength, variation_method):
to_noise = to_noise.to(from_noise.device)
if variation_method == 'slerp':
mixed_noise = slerp(strength, from_noise, to_noise)
else:
+9 -1
View File
@@ -18,9 +18,14 @@ class FloatRange:
CATEGORY = "InspirePack/Util"
def doit(self, start, stop, step, limit, ensure_end):
if start >= stop or step == 0:
if start == stop or step == 0:
return ([start], )
reverse = False
if start > stop:
reverse = True
start, stop = stop, start
res = []
x = start
last = x
@@ -36,6 +41,9 @@ class FloatRange:
res.append(stop)
if reverse:
res.reverse()
return (res, )
+86 -17
View File
@@ -165,8 +165,15 @@ class LoraLoaderBlockWeight:
input_blocks = []
middle_blocks = []
output_blocks = []
double_blocks = []
single_blocks = []
others = []
for k, v in loaded.items():
for key, v in loaded.items():
if isinstance(key, tuple):
k = key[0]
else:
k = key
k_unet = k[len("diffusion_model."):]
if k_unet.startswith("input_blocks."):
@@ -178,18 +185,26 @@ class LoraLoaderBlockWeight:
elif k_unet.startswith("output_blocks."):
k_unet_num = k_unet[len("output_blocks."):len("output_blocks.")+2]
output_blocks.append((k, v, parse_unet_num(k_unet_num), k_unet))
elif k_unet.startswith("double_blocks."):
k_unet_num = k_unet[len("double_blocks."):len("double_blocks.")+2]
double_blocks.append((key, v, parse_unet_num(k_unet_num), k_unet))
elif k_unet.startswith("single_blocks."):
k_unet_num = k_unet[len("single_blocks."):len("single_blocks.")+2]
single_blocks.append((key, v, parse_unet_num(k_unet_num), k_unet))
else:
others.append((k, v, k_unet))
input_blocks = sorted(input_blocks, key=lambda x: x[2])
middle_blocks = sorted(middle_blocks, key=lambda x: x[2])
output_blocks = sorted(output_blocks, key=lambda x: x[2])
double_blocks = sorted(double_blocks, key=lambda x: x[2])
single_blocks = sorted(single_blocks, key=lambda x: x[2])
# prepare patch
np.random.seed(seed % (2**31))
populated_vector_list = []
ratios = []
for k, v, k_unet_num, k_unet in (input_blocks + middle_blocks + output_blocks):
for k, v, k_unet_num, k_unet in (input_blocks + middle_blocks + output_blocks + double_blocks + single_blocks):
if last_k_unet_num != k_unet_num and len(vector) > vector_i:
ratios = LoraLoaderBlockWeight.convert_vector_value(A, B, vector[vector_i].strip())
ratio = ratios.pop(0)
@@ -213,7 +228,9 @@ class LoraLoaderBlockWeight:
last_k_unet_num = k_unet_num
new_modelpatcher.add_patches({k: v}, strength_model * populated_ratio)
if populated_ratio != 0:
new_modelpatcher.add_patches({k: v}, strength_model * populated_ratio)
# if inverse:
# print(f"\t{k_unet} -> inv({ratio}) ")
# else:
@@ -485,7 +502,7 @@ class XYInput_LoraBlockWeight:
XY_Capsule_LoraBlockWeight(0, 2, '', 'diff', storage, common_params),
XY_Capsule_LoraBlockWeight(0, 3, '', 'heatmap', storage, common_params)]
return ((xy_type, x_values), (xy_type, y_values), )
return (xy_type, x_values), (xy_type, y_values),
class LoraBlockInfo:
@@ -535,8 +552,21 @@ class LoraBlockInfo:
text_blocks = []
text_blocks_map = {}
double_block_count = set()
double_blocks = []
double_blocks_map = {}
single_block_count = set()
single_blocks = []
single_blocks_map = {}
others = []
for k, v in loaded.items():
for key, v in loaded.items():
if isinstance(key, tuple):
k = key[0]
else:
k = key
k_unet = k[len("diffusion_model."):]
if k_unet.startswith("input_blocks."):
@@ -572,6 +602,28 @@ class LoraBlockInfo:
else:
output_blocks_map[k_unet_int] = [k_unet]
elif k_unet.startswith("double_blocks."):
k_unet_num = k_unet[len("double_blocks."):len("double_blocks.") + 2]
k_unet_int = parse_unet_num(k_unet_num)
double_block_count.add(k_unet_int)
double_blocks.append(k_unet)
if k_unet_int in double_blocks_map:
double_blocks_map[k_unet_int].append(k_unet)
else:
double_blocks_map[k_unet_int] = [k_unet]
elif k_unet.startswith("single_blocks."):
k_unet_num = k_unet[len("single_blocks."):len("single_blocks.") + 2]
k_unet_int = parse_unet_num(k_unet_num)
single_block_count.add(k_unet_int)
single_blocks.append(k_unet)
if k_unet_int in single_blocks_map:
single_blocks_map[k_unet_int].append(k_unet)
else:
single_blocks_map[k_unet_int] = [k_unet]
elif k_unet.startswith("er.text_model.encoder.layers."):
k_unet_num = k_unet[len("er.text_model.encoder.layers."):len("er.text_model.encoder.layers.")+2]
k_unet_int = parse_unet_num(k_unet_num)
@@ -591,22 +643,39 @@ class LoraBlockInfo:
input_blocks = sorted(input_blocks)
middle_blocks = sorted(middle_blocks)
output_blocks = sorted(output_blocks)
double_blocks = sorted(double_blocks)
single_blocks = sorted(single_blocks)
others = sorted(others)
text += f"\n-------[Input blocks] ({len(input_block_count)}, Subs={len(input_blocks)})-------\n"
input_keys = sorted(input_blocks_map.keys())
for x in input_keys:
text += f" IN{x}: {len(input_blocks_map[x])}\n"
if len(input_block_count) > 0:
text += f"\n-------[Input blocks] ({len(input_block_count)}, Subs={len(input_blocks)})-------\n"
input_keys = sorted(input_blocks_map.keys())
for x in input_keys:
text += f" IN{x}: {len(input_blocks_map[x])}\n"
text += f"\n-------[Middle blocks] ({len(middle_block_count)}, Subs={len(middle_blocks)})-------\n"
middle_keys = sorted(middle_blocks_map.keys())
for x in middle_keys:
text += f" MID{x}: {len(middle_blocks_map[x])}\n"
if len(middle_block_count) > 0:
text += f"\n-------[Middle blocks] ({len(middle_block_count)}, Subs={len(middle_blocks)})-------\n"
middle_keys = sorted(middle_blocks_map.keys())
for x in middle_keys:
text += f" MID{x}: {len(middle_blocks_map[x])}\n"
text += f"\n-------[Output blocks] ({len(output_block_count)}, Subs={len(output_blocks)})-------\n"
output_keys = sorted(output_blocks_map.keys())
for x in output_keys:
text += f" OUT{x}: {len(output_blocks_map[x])}\n"
if len(output_block_count) > 0:
text += f"\n-------[Output blocks] ({len(output_block_count)}, Subs={len(output_blocks)})-------\n"
output_keys = sorted(output_blocks_map.keys())
for x in output_keys:
text += f" OUT{x}: {len(output_blocks_map[x])}\n"
if len(double_block_count) > 0:
text += f"\n-------[Double blocks(MMDiT)] ({len(double_block_count)}, Subs={len(double_blocks)})-------\n"
double_keys = sorted(double_blocks_map.keys())
for x in double_keys:
text += f" DOUBLE{x}: {len(double_blocks_map[x])}\n"
if len(single_block_count) > 0:
text += f"\n-------[Single blocks(DiT)] ({len(single_block_count)}, Subs={len(single_blocks)})-------\n"
single_keys = sorted(single_blocks_map.keys())
for x in single_keys:
text += f" SINGLE{x}: {len(single_blocks_map[x])}\n"
text += f"\n-------[Base blocks] ({len(text_block_count) + len(others)}, Subs={len(text_blocks) + len(others)})-------\n"
text_keys = sorted(text_blocks_map.keys())
+5 -2
View File
@@ -63,6 +63,9 @@ class IPAdapterModelHelper:
"insightface_provider": (["CPU", "CUDA", "ROCM"], ),
"cache_mode": (["insightface only", "clip_vision only", "all", "none"], {"default": "insightface only"}),
},
"optional": {
"insightface_model_name": (['buffalo_l', 'antelopev2'],),
},
"hidden": {"unique_id": "UNIQUE_ID"}
}
@@ -72,7 +75,7 @@ class IPAdapterModelHelper:
CATEGORY = "InspirePack/models"
def doit(self, model, clip, preset, lora_strength_model, lora_strength_clip, insightface_provider, cache_mode="none", unique_id=None):
def doit(self, model, clip, preset, lora_strength_model, lora_strength_clip, insightface_provider, cache_mode="none", unique_id=None, insightface_model_name='buffalo_l'):
if 'IPAdapter' not in nodes.NODE_CLASS_MAPPINGS:
utils.try_install_custom_node('https://github.com/cubiq/ComfyUI_IPAdapter_plus',
"To use 'IPAdapterModelHelper' node, 'ComfyUI IPAdapter Plus' extension is required.")
@@ -157,7 +160,7 @@ class IPAdapterModelHelper:
if cache_mode in ["insightface only", "all"]:
icache_key = 'insightface-' + insightface_provider
if icache_key not in backend_support.cache:
backend_support.update_cache(icache_key, "insightface", (False, insight_face_loader(insightface_provider)[0]))
backend_support.update_cache(icache_key, "insightface", (False, insight_face_loader(provider=insightface_provider, model_name=insightface_model_name)[0]))
_, (_, insightface) = backend_support.cache[icache_key]
else:
insightface = insight_face_loader(insightface_provider)[0]
+16 -3
View File
@@ -122,7 +122,7 @@ class KSamplerAdvanced_progress(a1111_compat.KSamplerAdvanced_inspire):
result.append(x)
latent_image, noise = a1111_compat.KSamplerAdvanced_inspire.sample(model, add_noise, noise_seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, start_at_step, end_at_step,
noise_mode, False, callback=progress_callback, scheduler_func_opt=scheduler_func_opt)
noise_mode, return_with_leftover_noise, callback=progress_callback, scheduler_func_opt=scheduler_func_opt)
if not omit_final_latent:
result.append(latent_image['samples'].cpu())
@@ -172,6 +172,15 @@ def logarithmic_interpolation(from_cfg, to_cfg, i, steps):
return from_cfg + (to_cfg - from_cfg) * t
def cosine_interpolation(from_cfg, to_cfg, i, steps):
if (i == 0) or (i == steps-1):
return from_cfg
t = (1.0 + math.cos(math.pi*2*(i/steps))) / 2
return from_cfg + (to_cfg - from_cfg) * t
class Guider_scheduled(CFGGuider):
def __init__(self, model_patcher, sigmas, from_cfg, to_cfg, schedule):
super().__init__(model_patcher)
@@ -201,6 +210,8 @@ class Guider_scheduled(CFGGuider):
self.cfg_sigmas[k] = exponential_interpolation(self.from_cfg, self.to_cfg, i, steps), i
elif self.schedule == 'log':
self.cfg_sigmas[k] = logarithmic_interpolation(self.from_cfg, self.to_cfg, i, steps), i
elif self.schedule == 'cos':
self.cfg_sigmas[k] = cosine_interpolation(self.from_cfg, self.to_cfg, i, steps), i
else:
self.cfg_sigmas[k] = self.from_cfg + delta * i / steps, i
@@ -252,6 +263,8 @@ class Guider_PerpNeg_scheduled(Guider_PerpNeg):
self.cfg_sigmas[k] = exponential_interpolation(self.from_cfg, self.to_cfg, i, steps), i
elif self.schedule == 'log':
self.cfg_sigmas[k] = logarithmic_interpolation(self.from_cfg, self.to_cfg, i, steps), i
elif self.schedule == 'cos':
self.cfg_sigmas[k] = cosine_interpolation(self.from_cfg, self.to_cfg, i, steps), i
else:
self.cfg_sigmas[k] = self.from_cfg + delta * i / steps, i
@@ -283,7 +296,7 @@ class ScheduledCFGGuider:
"sigmas": ("SIGMAS", ),
"from_cfg": ("FLOAT", {"default": 6.5, "min": 0.0, "max": 100.0, "step": 0.1, "round": 0.01}),
"to_cfg": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step": 0.1, "round": 0.01}),
"schedule": (["linear", "log", "exp"], {'default': 'log'})
"schedule": (["linear", "log", "exp", "cos"], {'default': 'log'})
}
}
@@ -310,7 +323,7 @@ class ScheduledPerpNegCFGGuider:
"sigmas": ("SIGMAS", ),
"from_cfg": ("FLOAT", {"default": 6.5, "min": 0.0, "max": 100.0, "step": 0.1, "round": 0.01}),
"to_cfg": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step": 0.1, "round": 0.01}),
"schedule": (["linear", "log", "exp"], {'default': 'log'})
"schedule": (["linear", "log", "exp", "cos"], {'default': 'log'})
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui-inspire-pack"
description = "This extension provides various nodes to support Lora Block Weight and the Impact Pack. Provides many easily applicable regional features and applications for Variation Seed."
version = "0.82.7"
version = "0.86.2"
license = { file = "LICENSE" }
dependencies = ["matplotlib", "cachetools"]
+71 -1
View File
@@ -29,6 +29,16 @@ SDXL-LyC-ALL:1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
SDXL-LyC-INALL:1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
SDXL-LyC-MIDALL:1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0
SDXL-LyC-OUTALL:1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
FLUX-DBL-ALL:1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
FLUX-DBL-FRONT7:1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
FLUX-DBL-MID6:1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0
FLUX-DBL-TAIL6:1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
FLUX-SINGLE-ALL:1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
FLUX-SINGLE-1to10:1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
FLUX-SINGLE-11to20:1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
FLUX-SINGLE-21to30:1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
FLUX-SINGLE-31to37:1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
FLUX-ALL:1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
@SD-FULL-TEST:17
@SD-BLOCK1-TEST:17,12,1
@SD-BLOCK2-TEST:17,12,2
@@ -49,4 +59,64 @@ SDXL-LyC-OUTALL:1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
@SD-BLOCK17-TEST:17,12,17
@SD-LyC-FULL-TEST:27
@SDXL-FULL-TEST:12
@SDXL-LyC-FULL-TEST:21
@SDXL-LyC-FULL-TEST:21
@FLUX-DBL-FULL:19
@FLUX-DBL-SGL-FULL:58
@FLUX-DBL0-TEST:19,14,2
@FLUX-DBL1-TEST:19,14,3
@FLUX-DBL2-TEST:19,14,4
@FLUX-DBL3-TEST:19,14,5
@FLUX-DBL4-TEST:19,14,6
@FLUX-DBL5-TEST:19,14,7
@FLUX-DBL6-TEST:19,14,8
@FLUX-DBL7-TEST:19,14,9
@FLUX-DBL8-TEST:19,14,10
@FLUX-DBL9-TEST:19,14,11
@FLUX-DBL10-TEST:19,14,12
@FLUX-DBL11-TEST:19,14,13
@FLUX-DBL12-TEST:19,14,14
@FLUX-DBL13-TEST:19,14,15
@FLUX-DBL14-TEST:19,14,16
@FLUX-DBL15-TEST:19,14,17
@FLUX-DBL16-TEST:19,14,18
@FLUX-DBL17-TEST:19,14,19
@FLUX-DBL18-TEST:19,14,20
@FLUX-SGL0-TEST:58,6,21
@FLUX-SGL1-TEST:58,6,22
@FLUX-SGL2-TEST:58,6,23
@FLUX-SGL3-TEST:58,6,24
@FLUX-SGL4-TEST:58,6,25
@FLUX-SGL5-TEST:58,6,26
@FLUX-SGL6-TEST:58,6,27
@FLUX-SGL7-TEST:58,6,28
@FLUX-SGL8-TEST:58,6,29
@FLUX-SGL9-TEST:58,6,30
@FLUX-SGL10-TEST:58,6,31
@FLUX-SGL11-TEST:58,6,32
@FLUX-SGL12-TEST:58,6,33
@FLUX-SGL13-TEST:58,6,34
@FLUX-SGL14-TEST:58,6,35
@FLUX-SGL15-TEST:58,6,36
@FLUX-SGL16-TEST:58,6,37
@FLUX-SGL17-TEST:58,6,38
@FLUX-SGL18-TEST:58,6,39
@FLUX-SGL19-TEST:58,6,40
@FLUX-SGL20-TEST:58,6,41
@FLUX-SGL21-TEST:58,6,42
@FLUX-SGL22-TEST:58,6,43
@FLUX-SGL23-TEST:58,6,44
@FLUX-SGL24-TEST:58,6,45
@FLUX-SGL25-TEST:58,6,46
@FLUX-SGL26-TEST:58,6,47
@FLUX-SGL27-TEST:58,6,48
@FLUX-SGL28-TEST:58,6,49
@FLUX-SGL29-TEST:58,6,50
@FLUX-SGL30-TEST:58,6,51
@FLUX-SGL31-TEST:58,6,52
@FLUX-SGL32-TEST:58,6,53
@FLUX-SGL33-TEST:58,6,54
@FLUX-SGL34-TEST:58,6,55
@FLUX-SGL35-TEST:58,6,56
@FLUX-SGL36-TEST:58,6,57
@FLUX-SGL37-TEST:58,6,58
@FLUX-SGL38-TEST:58,6,59