Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

s #13

Open
wants to merge 3,422 commits into
base: master
Choose a base branch
from
Open

s #13

wants to merge 3,422 commits into from

Conversation

AdamOswald
Copy link
Member

@AdamOswald AdamOswald commented May 17, 2023

Please read the contributing wiki page before submitting a pull request!

If you have a large change, pay special attention to this paragraph:

Before making changes, if you think that your feature will result in more than 100 lines changing, find me and talk to me about the feature you are proposing. It pains me to reject the hard work someone else did, but I won't add everything to the repo, and it's better if the rejection happens before you have to waste time working on the feature.

Otherwise, after making sure you're following the rules described in wiki page, remove this section and continue on.

Describe what this pull request is trying to achieve.

A clear and concise description of what you're trying to accomplish with this, so your intent doesn't have to be extracted from your code.

Additional notes and description of your changes

More technical discussion about your changes go here, plus anything that a maintainer might have to specifically take a look at, or be wary of.

Environment this was tested in

List the environment you have developed / tested this on. As per the contributing page, changes should be able to work on Windows out of the box.

  • OS: [e.g. Windows, Linux]
  • Browser: [e.g. chrome, safari]
  • Graphics card: [e.g. NVIDIA RTX 2080 8GB, AMD RX 6600 8GB]

Screenshots or videos of your changes

If applicable, screenshots or a video showing off your changes. If it edits an existing UI, it should ideally contain a comparison of what used to be there, before your changes were made.

This is required for anything that touches the user interface.

Summary by CodeRabbit

  • New Features

    • Introduced zooming and panning functionality for canvas images.
    • Added configurable hotkeys for canvas interactions.
    • Launched new mobile layout detection and adjustment.
    • Implemented soft inpainting with adjustable parameters.
    • Added extra options section for txt2img and img2img tabs.
    • Introduced post-processing scripts for cropping, captioning, and image flipping.
    • Enhanced functionality for managing neural networks and Lora modules.
    • Added support for Stable Diffusion 3 with new schedulers and samplers.
  • Improvements

    • Enhanced error handling and logging across multiple modules.
    • Improved memory management and network loading logic.
    • Refined API responses and added new endpoints for better integration.
    • Updated configurations for stable diffusion models.
    • Performance optimizations to reduce resource usage and increase efficiency.
  • UI Enhancements

    • Introduced new styling for canvas tooltips.
    • Enhanced user interface for managing extra networks with sorting, filtering, and metadata display.
  • Bug Fixes

    • Corrected bracket checking in prompts to handle different types of brackets accurately.
    • Resolved issues with grids lacking comprehensive infotexts and improved file handling.
  • Performance Optimizations

    • Optimized self-attention layers in U-Net and VAE models using Hypertile for better computational efficiency.

@sourcery-ai sourcery-ai bot mentioned this pull request May 17, 2023
Copy link

coderabbitai bot commented Dec 16, 2023

Walkthrough

The recent updates bring a substantial overhaul to the stable diffusion web UI, focusing on enhanced functionality, performance improvements, and bug fixes. Key features include support for Stable Diffusion 3, new sampling methods, and refined memory management. The updates streamline operations in neural network models, introduce features like zooming and panning for better user experience, and improve error handling throughout the system, ensuring a smoother workflow for users.

Changes

File(s) Change Summary
.extensions-builtin/LDSR/ldsr_model_arch.py Improved memory management, enhanced exception handling, and removed unnecessary variables.
.extensions-builtin/LDSR/scripts/ldsr_model.py Switched to load_file_from_url, enhanced error handling.
.extensions-builtin/LDSR/sd_hijack_autoencoder.py, .extensions-builtin/LDSR/sd_hijack_ddpm_v1.py Adjusted initialization and logging, modified key handling for better flexibility.
.extensions-builtin/LDSR/vqvae_quantize.py Introduced VectorQuantizer2 for enhanced quantization capabilities.
.extensions-builtin/Lora/... Refactored for improved network management and logging, added new classes and methods for network operations across multiple files.
.extensions-builtin/ScuNET/scripts/scunet_model.py, .extensions-builtin/SwinIR/scripts/swinir_model.py Significant structural and functional updates.
.extensions-builtin/canvas-zoom-and-pan/... Introduced zoom and pan functionality, hotkey configuration, and styling for canvas tooltips.
.extensions-builtin/extra-options-section/scripts/extra_options_section.py Added extra options section for txt2img and img2img tabs.
.extensions-builtin/hypertile/... Introduced Hypertile for optimizing self-attention layers with related functionalities.
.extensions-builtin/mobile/javascript/mobile.js Added layout adjustments for mobile devices.
.extensions-builtin/postprocessing-for-training/scripts/postprocessing_autosized_crop.py Introduced various post-processing functionalities for image cropping and captioning.
.extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js Updated bracket checking functionality for prompts.
.extensions-builtin/soft-inpainting/scripts/soft_inpainting.py Introduced soft inpainting functionalities and UI components.
modules/api/... Enhanced API with new routes, improved error handling, and added functions for image processing and model management.
javascript/extraNetworks.js Restructured and expanded functionality for managing extra network cards.

In the code where changes bloom,
A rabbit hops from room to room.
With memory managed and errors tamed,
New features crafted, none unnamed.
Networks dance, images refine,
In this garden, all align.
🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Comment on lines +33 to +44
const modalImage = gradioApp().getElementById("modalImage");
if (modalImage && modalImage.offsetParent) {
let currentButton = selected_gallery_button();

if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) {
let preview = gradioApp().querySelectorAll('.livePreview > img');
if (opts.js_live_preview_in_modal_lightbox && preview.length > 0) {
// show preview image if available
modalImage.src = preview[preview.length - 1].src;
} else if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) {
modalImage.src = currentButton.children[0].src;
if (modalImage.style.display === 'none') {
modal.style.setProperty('background-image', `url(${modalImage.src})`)
const modal = gradioApp().getElementById("lightboxModal");
modal.style.setProperty('background-image', `url(${modalImage.src})`);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic for updating the background image based on the presence of a preview image or the selected gallery button's child image is sound. However, consider extracting this logic into a separate function for clarity and reusability, especially since similar patterns appear in other parts of the code.

function updateModalBackgroundImage(modalImage, sourceImage) {
    if (modalImage.style.display === 'none') {
        const modal = gradioApp().getElementById("lightboxModal");
        modal.style.setProperty('background-image', `url(${sourceImage.src})`);
    }
}

Comment on lines 56 to 74
var result = -1;
galleryButtons.forEach(function(v, i) {
if (v == currentButton) {
result = i
result = i;
}
})
});

if (result != -1) {
nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)]
nextButton.click()
var nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)];
nextButton.click();
const modalImage = gradioApp().getElementById("modalImage");
const modal = gradioApp().getElementById("lightboxModal");
modalImage.src = nextButton.children[0].src;
if (modalImage.style.display === 'none') {
modal.style.setProperty('background-image', `url(${modalImage.src})`)
modal.style.setProperty('background-image', `url(${modalImage.src})`);
}
setTimeout(function() {
modal.focus()
}, 10)
modal.focus();
}, 10);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The modalImageSwitch function correctly implements the logic for switching images in the modal. However, the use of var for variable declarations is outdated. Consider using let or const for block-scoped variables to improve code maintainability and prevent potential issues with variable hoisting.

- var galleryButtons = all_gallery_buttons();
+ let galleryButtons = all_gallery_buttons();

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
var result = -1;
galleryButtons.forEach(function(v, i) {
if (v == currentButton) {
result = i
result = i;
}
})
});
if (result != -1) {
nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)]
nextButton.click()
var nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)];
nextButton.click();
const modalImage = gradioApp().getElementById("modalImage");
const modal = gradioApp().getElementById("lightboxModal");
modalImage.src = nextButton.children[0].src;
if (modalImage.style.display === 'none') {
modal.style.setProperty('background-image', `url(${modalImage.src})`)
modal.style.setProperty('background-image', `url(${modalImage.src})`);
}
setTimeout(function() {
modal.focus()
}, 10)
modal.focus();
}, 10);
let result = -1;
galleryButtons.forEach(function(v, i) {
if (v == currentButton) {
result = i;
}
});
if (result != -1) {
var nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)];
nextButton.click();
const modalImage = gradioApp().getElementById("modalImage");
const modal = gradioApp().getElementById("lightboxModal");
modalImage.src = nextButton.children[0].src;
if (modalImage.style.display === 'none') {
modal.style.setProperty('background-image', `url(${modalImage.src})`);
}
setTimeout(function() {
modal.focus();
}, 10);

Comment on lines +116 to +144
function updateTooltip(element) {
if (element.title) return; // already has a title

let text = element.textContent;
let tooltip = localization[titles[text]] || titles[text];

if (!tooltip) {
let value = element.value;
if (value) tooltip = localization[titles[value]] || titles[value];
}

if (!tooltip) {
// Gradio dropdown options have `data-value`.
let dataValue = element.dataset.value;
if (dataValue) tooltip = localization[titles[dataValue]] || titles[dataValue];
}

if (!tooltip) {
for (const c of element.classList) {
if (c in titles) {
tooltip = localization[titles[c]] || titles[c];
break;
}
}
}

if (tooltip) {
element.title = tooltip;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updateTooltip function logic appears sound, efficiently updating element titles with tooltips from the titles object. It correctly handles different scenarios, such as elements with existing titles, content-based tooltips, value-based tooltips, and class-based tooltips. However, consider adding comments to explain the logic behind handling different types of elements (e.g., Gradio dropdown options) for future maintainability.

+ // Explain the logic behind handling different types of elements for tooltips

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
function updateTooltip(element) {
if (element.title) return; // already has a title
let text = element.textContent;
let tooltip = localization[titles[text]] || titles[text];
if (!tooltip) {
let value = element.value;
if (value) tooltip = localization[titles[value]] || titles[value];
}
if (!tooltip) {
// Gradio dropdown options have `data-value`.
let dataValue = element.dataset.value;
if (dataValue) tooltip = localization[titles[dataValue]] || titles[dataValue];
}
if (!tooltip) {
for (const c of element.classList) {
if (c in titles) {
tooltip = localization[titles[c]] || titles[c];
break;
}
}
}
if (tooltip) {
element.title = tooltip;
}
function updateTooltip(element) {
// Explain the logic behind handling different types of elements for tooltips
if (element.title) return; // already has a title
let text = element.textContent;
let tooltip = localization[titles[text]] || titles[text];
if (!tooltip) {
let value = element.value;
if (value) tooltip = localization[titles[value]] || titles[value];
}
if (!tooltip) {
// Gradio dropdown options have `data-value`.
let dataValue = element.dataset.value;
if (dataValue) tooltip = localization[titles[dataValue]] || titles[dataValue];
}
if (!tooltip) {
for (const c of element.classList) {
if (c in titles) {
tooltip = localization[titles[c]] || titles[c];
break;
}
}
}
if (tooltip) {
element.title = tooltip;
}
}

Comment on lines 49 to 102
def latent_blend(settings, a, b, t):
"""
Interpolates two latent image representations according to the parameter t,
where the interpolated vectors' magnitudes are also interpolated separately.
The "detail_preservation" factor biases the magnitude interpolation towards
the larger of the two magnitudes.
"""
import torch

# NOTE: We use inplace operations wherever possible.

# [4][w][h] to [1][4][w][h]
t2 = t.unsqueeze(0)
# [4][w][h] to [1][1][w][h] - the [4] seem redundant.
t3 = t[0].unsqueeze(0).unsqueeze(0)

one_minus_t2 = 1 - t2
one_minus_t3 = 1 - t3

# Linearly interpolate the image vectors.
a_scaled = a * one_minus_t2
b_scaled = b * t2
image_interp = a_scaled
image_interp.add_(b_scaled)
result_type = image_interp.dtype
del a_scaled, b_scaled, t2, one_minus_t2

# Calculate the magnitude of the interpolated vectors. (We will remove this magnitude.)
# 64-bit operations are used here to allow large exponents.
current_magnitude = torch.norm(image_interp, p=2, dim=1, keepdim=True).to(torch.float64).add_(0.00001)

# Interpolate the powered magnitudes, then un-power them (bring them back to a power of 1).
a_magnitude = torch.norm(a, p=2, dim=1, keepdim=True).to(torch.float64).pow_(
settings.inpaint_detail_preservation) * one_minus_t3
b_magnitude = torch.norm(b, p=2, dim=1, keepdim=True).to(torch.float64).pow_(
settings.inpaint_detail_preservation) * t3
desired_magnitude = a_magnitude
desired_magnitude.add_(b_magnitude).pow_(1 / settings.inpaint_detail_preservation)
del a_magnitude, b_magnitude, t3, one_minus_t3

# Change the linearly interpolated image vectors' magnitudes to the value we want.
# This is the last 64-bit operation.
image_interp_scaling_factor = desired_magnitude
image_interp_scaling_factor.div_(current_magnitude)
image_interp_scaling_factor = image_interp_scaling_factor.to(result_type)
image_interp_scaled = image_interp
image_interp_scaled.mul_(image_interp_scaling_factor)
del current_magnitude
del desired_magnitude
del image_interp
del image_interp_scaling_factor
del result_type

return image_interp_scaled
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function latent_blend performs complex tensor operations for blending latent image representations. While the logic appears sound, there are several areas where performance could be improved, such as minimizing the use of inplace operations and ensuring tensor operations are efficiently combined. Additionally, adding comments to explain the rationale behind complex operations would greatly enhance maintainability.

Consider reviewing the tensor operations for potential optimizations and adding more detailed comments to explain the steps involved in the blending process.

Comment on lines 105 to 121
def get_modified_nmask(settings, nmask, sigma):
"""
Converts a negative mask representing the transparency of the original latent vectors being overlayed
to a mask that is scaled according to the denoising strength for this step.

Where:
0 = fully opaque, infinite density, fully masked
1 = fully transparent, zero density, fully unmasked

We bring this transparency to a power, as this allows one to simulate N number of blending operations
where N can be any positive real value. Using this one can control the balance of influence between
the denoiser and the original latents according to the sigma value.

NOTE: "mask" is not used
"""
import torch
return torch.pow(nmask, (sigma ** settings.mask_blend_power) * settings.mask_blend_scale)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function get_modified_nmask is concise and uses a power operation to adjust the mask based on the settings. However, it's important to ensure that the sigma and mask_blend_power values are within expected ranges to avoid unexpected behavior. Adding input validation or comments to specify the expected range could improve code robustness.

Consider adding input validation or documentation comments to clarify the expected range of sigma and mask_blend_power.

Comment on lines 124 to 231
import torch
import modules.processing as proc
import modules.images as images
from PIL import Image, ImageOps, ImageFilter

# TODO: Bias the blending according to the latent mask, add adjustable parameter for bias control.
latent_mask = nmask[0].float()
# convert the original mask into a form we use to scale distances for thresholding
mask_scalar = 1 - (torch.clamp(latent_mask, min=0, max=1) ** (settings.mask_blend_scale / 2))
mask_scalar = (0.5 * (1 - settings.composite_mask_influence)
+ mask_scalar * settings.composite_mask_influence)
mask_scalar = mask_scalar / (1.00001 - mask_scalar)
mask_scalar = mask_scalar.cpu().numpy()

latent_distance = torch.norm(latent_processed - latent_orig, p=2, dim=1)

kernel, kernel_center = get_gaussian_kernel(stddev_radius=1.5, max_radius=2)

masks_for_overlay = []

for i, (distance_map, overlay_image) in enumerate(zip(latent_distance, overlay_images)):
converted_mask = distance_map.float().cpu().numpy()
converted_mask = weighted_histogram_filter(converted_mask, kernel, kernel_center,
percentile_min=0.9, percentile_max=1, min_width=1)
converted_mask = weighted_histogram_filter(converted_mask, kernel, kernel_center,
percentile_min=0.25, percentile_max=0.75, min_width=1)

# The distance at which opacity of original decreases to 50%
half_weighted_distance = settings.composite_difference_threshold * mask_scalar
converted_mask = converted_mask / half_weighted_distance

converted_mask = 1 / (1 + converted_mask ** settings.composite_difference_contrast)
converted_mask = smootherstep(converted_mask)
converted_mask = 1 - converted_mask
converted_mask = 255. * converted_mask
converted_mask = converted_mask.astype(np.uint8)
converted_mask = Image.fromarray(converted_mask)
converted_mask = images.resize_image(2, converted_mask, width, height)
converted_mask = proc.create_binary_mask(converted_mask, round=False)

# Remove aliasing artifacts using a gaussian blur.
converted_mask = converted_mask.filter(ImageFilter.GaussianBlur(radius=4))

# Expand the mask to fit the whole image if needed.
if paste_to is not None:
converted_mask = proc.uncrop(converted_mask,
(overlay_image.width, overlay_image.height),
paste_to)

masks_for_overlay.append(converted_mask)

image_masked = Image.new('RGBa', (overlay_image.width, overlay_image.height))
image_masked.paste(overlay_image.convert("RGBA").convert("RGBa"),
mask=ImageOps.invert(converted_mask.convert('L')))

overlay_images[i] = image_masked.convert('RGBA')

return masks_for_overlay


def apply_masks(
settings,
nmask,
overlay_images,
width, height,
paste_to):
import torch
import modules.processing as proc
import modules.images as images
from PIL import Image, ImageOps, ImageFilter

converted_mask = nmask[0].float()
converted_mask = torch.clamp(converted_mask, min=0, max=1).pow_(settings.mask_blend_scale / 2)
converted_mask = 255. * converted_mask
converted_mask = converted_mask.cpu().numpy().astype(np.uint8)
converted_mask = Image.fromarray(converted_mask)
converted_mask = images.resize_image(2, converted_mask, width, height)
converted_mask = proc.create_binary_mask(converted_mask, round=False)

# Remove aliasing artifacts using a gaussian blur.
converted_mask = converted_mask.filter(ImageFilter.GaussianBlur(radius=4))

# Expand the mask to fit the whole image if needed.
if paste_to is not None:
converted_mask = proc.uncrop(converted_mask,
(width, height),
paste_to)

masks_for_overlay = []

for i, overlay_image in enumerate(overlay_images):
masks_for_overlay[i] = converted_mask

image_masked = Image.new('RGBa', (overlay_image.width, overlay_image.height))
image_masked.paste(overlay_image.convert("RGBA").convert("RGBa"),
mask=ImageOps.invert(converted_mask.convert('L')))

overlay_images[i] = image_masked.convert('RGBA')

return masks_for_overlay
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function apply_masks and apply_adaptive_masks perform complex image processing operations. These functions are well-structured but could benefit from further optimization, especially in terms of reducing the number of operations performed on tensors and images. Additionally, ensuring that all image and tensor operations are batched where possible could improve performance.

Review the image and tensor operations for potential optimizations, especially focusing on reducing the computational overhead by batching operations where possible.

Comment on lines +234 to +357
(nparray): A filtered copy of the input image "img", a 2-D array of floats.
"""

# Converts an index tuple into a vector.
def vec(x):
return np.array(x)

kernel_min = -kernel_center
kernel_max = vec(kernel.shape) - kernel_center

def weighted_histogram_filter_single(idx):
idx = vec(idx)
min_index = np.maximum(0, idx + kernel_min)
max_index = np.minimum(vec(img.shape), idx + kernel_max)
window_shape = max_index - min_index

class WeightedElement:
"""
An element of the histogram, its weight
and bounds.
"""

def __init__(self, value, weight):
self.value: float = value
self.weight: float = weight
self.window_min: float = 0.0
self.window_max: float = 1.0

# Collect the values in the image as WeightedElements,
# weighted by their corresponding kernel values.
values = []
for window_tup in np.ndindex(tuple(window_shape)):
window_index = vec(window_tup)
image_index = window_index + min_index
centered_kernel_index = image_index - idx
kernel_index = centered_kernel_index + kernel_center
element = WeightedElement(img[tuple(image_index)], kernel[tuple(kernel_index)])
values.append(element)

def sort_key(x: WeightedElement):
return x.value

values.sort(key=sort_key)

# Calculate the height of the stack (sum)
# and each sample's range they occupy in the stack
sum = 0
for i in range(len(values)):
values[i].window_min = sum
sum += values[i].weight
values[i].window_max = sum

# Calculate what range of this stack ("window")
# we want to get the weighted average across.
window_min = sum * percentile_min
window_max = sum * percentile_max
window_width = window_max - window_min

# Ensure the window is within the stack and at least a certain size.
if window_width < min_width:
window_center = (window_min + window_max) / 2
window_min = window_center - min_width / 2
window_max = window_center + min_width / 2

if window_max > sum:
window_max = sum
window_min = sum - min_width

if window_min < 0:
window_min = 0
window_max = min_width

value = 0
value_weight = 0

# Get the weighted average of all the samples
# that overlap with the window, weighted
# by the size of their overlap.
for i in range(len(values)):
if window_min >= values[i].window_max:
continue
if window_max <= values[i].window_min:
break

s = max(window_min, values[i].window_min)
e = min(window_max, values[i].window_max)
w = e - s

value += values[i].value * w
value_weight += w

return value / value_weight if value_weight != 0 else 0

img_out = img.copy()

# Apply the kernel operation over each pixel.
for index in np.ndindex(img.shape):
img_out[index] = weighted_histogram_filter_single(index)

return img_out
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function weighted_histogram_filter is a complex and innovative approach to applying a generalized convolution filter. While the implementation is correct, the complexity of the function could be reduced by refactoring into smaller, more manageable functions. Additionally, adding more detailed comments explaining the algorithm's steps and its purpose would greatly aid in understanding and maintaining the code.

Consider refactoring the function into smaller parts and adding detailed comments to improve readability and maintainability.

Comment on lines +431 to +467
default = SoftInpaintingSettings(1, 0.5, 4, 0, 0.5, 2)

enabled_ui_label = "Soft inpainting"
enabled_gen_param_label = "Soft inpainting enabled"
enabled_el_id = "soft_inpainting_enabled"

ui_labels = SoftInpaintingSettings(
"Schedule bias",
"Preservation strength",
"Transition contrast boost",
"Mask influence",
"Difference threshold",
"Difference contrast")

ui_info = SoftInpaintingSettings(
"Shifts when preservation of original content occurs during denoising.",
"How strongly partially masked content should be preserved.",
"Amplifies the contrast that may be lost in partially masked regions.",
"How strongly the original mask should bias the difference threshold.",
"How much an image region can change before the original pixels are not blended in anymore.",
"How sharp the transition should be between blended and not blended.")

gen_param_labels = SoftInpaintingSettings(
"Soft inpainting schedule bias",
"Soft inpainting preservation strength",
"Soft inpainting transition contrast boost",
"Soft inpainting mask influence",
"Soft inpainting difference threshold",
"Soft inpainting difference contrast")

el_ids = SoftInpaintingSettings(
"mask_blend_power",
"mask_blend_scale",
"inpaint_detail_preservation",
"composite_mask_influence",
"composite_difference_threshold",
"composite_difference_contrast")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constants and labels defined towards the end of the file are clear and well-organized. However, it's recommended to group these constants in a more structured way, possibly using a class or a module-level dictionary, to improve modularity and maintainability.

Consider organizing these constants into a class or dictionary for better structure and maintainability.

Comment on lines +473 to +747
def process(self, p, enabled, power, scale, detail_preservation, mask_inf, dif_thresh, dif_contr):
if not enabled:
return

if not processing_uses_inpainting(p):
return

# Shut off the rounding it normally does.
p.mask_round = False

settings = SoftInpaintingSettings(power, scale, detail_preservation, mask_inf, dif_thresh, dif_contr)

# p.extra_generation_params["Mask rounding"] = False
settings.add_generation_params(p.extra_generation_params)

def on_mask_blend(self, p, mba: scripts.MaskBlendArgs, enabled, power, scale, detail_preservation, mask_inf,
dif_thresh, dif_contr):
if not enabled:
return

if not processing_uses_inpainting(p):
return

if mba.is_final_blend:
mba.blended_latent = mba.current_latent
return

settings = SoftInpaintingSettings(power, scale, detail_preservation, mask_inf, dif_thresh, dif_contr)

# todo: Why is sigma 2D? Both values are the same.
mba.blended_latent = latent_blend(settings,
mba.init_latent,
mba.current_latent,
get_modified_nmask(settings, mba.nmask, mba.sigma[0]))

def post_sample(self, p, ps: scripts.PostSampleArgs, enabled, power, scale, detail_preservation, mask_inf,
dif_thresh, dif_contr):
if not enabled:
return

if not processing_uses_inpainting(p):
return

nmask = getattr(p, "nmask", None)
if nmask is None:
return

from modules import images
from modules.shared import opts

settings = SoftInpaintingSettings(power, scale, detail_preservation, mask_inf, dif_thresh, dif_contr)

# since the original code puts holes in the existing overlay images,
# we have to rebuild them.
self.overlay_images = []
for img in p.init_images:

image = images.flatten(img, opts.img2img_background_color)

if p.paste_to is None and p.resize_mode != 3:
image = images.resize_image(p.resize_mode, image, p.width, p.height)

self.overlay_images.append(image.convert('RGBA'))

if len(p.init_images) == 1:
self.overlay_images = self.overlay_images * p.batch_size

if getattr(ps.samples, 'already_decoded', False):
self.masks_for_overlay = apply_masks(settings=settings,
nmask=nmask,
overlay_images=self.overlay_images,
width=p.width,
height=p.height,
paste_to=p.paste_to)
else:
self.masks_for_overlay = apply_adaptive_masks(settings=settings,
nmask=nmask,
latent_orig=p.init_latent,
latent_processed=ps.samples,
overlay_images=self.overlay_images,
width=p.width,
height=p.height,
paste_to=p.paste_to)

def postprocess_maskoverlay(self, p, ppmo: scripts.PostProcessMaskOverlayArgs, enabled, power, scale,
detail_preservation, mask_inf, dif_thresh, dif_contr):
if not enabled:
return

if not processing_uses_inpainting(p):
return

if self.masks_for_overlay is None:
return

if self.overlay_images is None:
return

ppmo.mask_for_overlay = self.masks_for_overlay[ppmo.index]
ppmo.overlay_image = self.overlay_images[ppmo.index]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Script class integrates the soft inpainting functionality with the rest of the application. The methods are well-structured and logically sound. However, there are opportunities to improve code readability and maintainability, such as adding type hints and refactoring large methods into smaller, more focused functions. Additionally, ensuring consistent documentation across all methods would aid in understanding the class's purpose and usage.

Consider adding type hints to method parameters and return types, refactoring large methods, and ensuring consistent documentation.

Comment on lines 126 to 152
if (e.dataset.modded) {
return;
}

e.dataset.modded = true;
e.style.cursor='pointer'
e.style.userSelect='none'
e.dataset.modded = true;
e.style.cursor = 'pointer';
e.style.userSelect = 'none';

var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;

// For Firefox, listening on click first switched to next image then shows the lightbox.
// If you know how to fix this without switching to mousedown event, please.
// For other browsers the event is click to make it possiblr to drag picture.
var event = isFirefox ? 'mousedown' : 'click'
// For Firefox, listening on click first switched to next image then shows the lightbox.
// If you know how to fix this without switching to mousedown event, please.
// For other browsers the event is click to make it possiblr to drag picture.
var event = isFirefox ? 'mousedown' : 'click';

e.addEventListener(event, function (evt) {
if(!opts.js_modal_lightbox || evt.button != 0) return;
e.addEventListener(event, function(evt) {
if (evt.button == 1) {
open(evt.target.src);
evt.preventDefault();
return;
}
if (!opts.js_modal_lightbox || evt.button != 0) return;

modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed)
evt.preventDefault()
showModal(evt)
}, true);
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed);
evt.preventDefault();
showModal(evt);
}, true);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setupImageForLightbox function correctly marks images for lightbox functionality and handles different events based on the browser. However, the use of var for isFirefox is outdated. Consider using let or const for better scoping and readability.

- var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
+ const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
if (e.dataset.modded) {
return;
}
e.dataset.modded = true;
e.style.cursor='pointer'
e.style.userSelect='none'
e.dataset.modded = true;
e.style.cursor = 'pointer';
e.style.userSelect = 'none';
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
// For Firefox, listening on click first switched to next image then shows the lightbox.
// If you know how to fix this without switching to mousedown event, please.
// For other browsers the event is click to make it possiblr to drag picture.
var event = isFirefox ? 'mousedown' : 'click'
// For Firefox, listening on click first switched to next image then shows the lightbox.
// If you know how to fix this without switching to mousedown event, please.
// For other browsers the event is click to make it possiblr to drag picture.
var event = isFirefox ? 'mousedown' : 'click';
e.addEventListener(event, function (evt) {
if(!opts.js_modal_lightbox || evt.button != 0) return;
e.addEventListener(event, function(evt) {
if (evt.button == 1) {
open(evt.target.src);
evt.preventDefault();
return;
}
if (!opts.js_modal_lightbox || evt.button != 0) return;
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed)
evt.preventDefault()
showModal(evt)
}, true);
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed);
evt.preventDefault();
showModal(evt);
}, true);
if (e.dataset.modded) {
return;
}
e.dataset.modded = true;
e.style.cursor = 'pointer';
e.style.userSelect = 'none';
const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
// For Firefox, listening on click first switched to next image then shows the lightbox.
// If you know how to fix this without switching to mousedown event, please.
// For other browsers the event is click to make it possiblr to drag picture.
var event = isFirefox ? 'mousedown' : 'click';
e.addEventListener(event, function(evt) {
if (evt.button == 1) {
open(evt.target.src);
evt.preventDefault();
return;
}
if (!opts.js_modal_lightbox || evt.button != 0) return;
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed);
evt.preventDefault();
showModal(evt);
}, true);

Comment on lines +172 to +175
modal.style.setProperty('background-image', 'none');
} else {
modalImage.style.display = 'none';
modal.style.setProperty('background-image', `url(${modalImage.src})`)
modal.style.setProperty('background-image', `url(${modalImage.src})`);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The modalTileImageToggle function's logic for toggling the tiling preview is clear and functional. However, consider abstracting the repeated pattern of changing the display style and background image property into a helper function for DRY (Don't Repeat Yourself) compliance.

function toggleDisplayStyle(element, displayStyle, backgroundImageUrl = null) {
    element.style.display = displayStyle;
    if (backgroundImageUrl !== null) {
        element.style.setProperty('background-image', `url(${backgroundImageUrl})`);
    }
}

Comment on lines 191 to 258

const modalControls = document.createElement('div')
const modalControls = document.createElement('div');
modalControls.className = 'modalControls gradio-container';
modal.append(modalControls);

const modalZoom = document.createElement('span')
const modalZoom = document.createElement('span');
modalZoom.className = 'modalZoom cursor';
modalZoom.innerHTML = '&#10529;'
modalZoom.addEventListener('click', modalZoomToggle, true)
modalZoom.innerHTML = '&#10529;';
modalZoom.addEventListener('click', modalZoomToggle, true);
modalZoom.title = "Toggle zoomed view";
modalControls.appendChild(modalZoom)
modalControls.appendChild(modalZoom);

const modalTileImage = document.createElement('span')
const modalTileImage = document.createElement('span');
modalTileImage.className = 'modalTileImage cursor';
modalTileImage.innerHTML = '&#8862;'
modalTileImage.addEventListener('click', modalTileImageToggle, true)
modalTileImage.innerHTML = '&#8862;';
modalTileImage.addEventListener('click', modalTileImageToggle, true);
modalTileImage.title = "Preview tiling";
modalControls.appendChild(modalTileImage)
modalControls.appendChild(modalTileImage);

const modalSave = document.createElement("span")
modalSave.className = "modalSave cursor"
modalSave.id = "modal_save"
modalSave.innerHTML = "&#x1F5AB;"
modalSave.addEventListener("click", modalSaveImage, true)
modalSave.title = "Save Image(s)"
modalControls.appendChild(modalSave)
const modalSave = document.createElement("span");
modalSave.className = "modalSave cursor";
modalSave.id = "modal_save";
modalSave.innerHTML = "&#x1F5AB;";
modalSave.addEventListener("click", modalSaveImage, true);
modalSave.title = "Save Image(s)";
modalControls.appendChild(modalSave);

const modalClose = document.createElement('span')
const modalClose = document.createElement('span');
modalClose.className = 'modalClose cursor';
modalClose.innerHTML = '&times;'
modalClose.innerHTML = '&times;';
modalClose.onclick = closeModal;
modalClose.title = "Close image viewer";
modalControls.appendChild(modalClose)
modalControls.appendChild(modalClose);

const modalImage = document.createElement('img')
const modalImage = document.createElement('img');
modalImage.id = 'modalImage';
modalImage.onclick = closeModal;
modalImage.tabIndex = 0
modalImage.addEventListener('keydown', modalKeyHandler, true)
modal.appendChild(modalImage)
modalImage.tabIndex = 0;
modalImage.addEventListener('keydown', modalKeyHandler, true);
modal.appendChild(modalImage);

const modalPrev = document.createElement('a')
const modalPrev = document.createElement('a');
modalPrev.className = 'modalPrev';
modalPrev.innerHTML = '&#10094;'
modalPrev.tabIndex = 0
modalPrev.innerHTML = '&#10094;';
modalPrev.tabIndex = 0;
modalPrev.addEventListener('click', modalPrevImage, true);
modalPrev.addEventListener('keydown', modalKeyHandler, true)
modal.appendChild(modalPrev)
modalPrev.addEventListener('keydown', modalKeyHandler, true);
modal.appendChild(modalPrev);

const modalNext = document.createElement('a')
const modalNext = document.createElement('a');
modalNext.className = 'modalNext';
modalNext.innerHTML = '&#10095;'
modalNext.tabIndex = 0
modalNext.innerHTML = '&#10095;';
modalNext.tabIndex = 0;
modalNext.addEventListener('click', modalNextImage, true);
modalNext.addEventListener('keydown', modalKeyHandler, true)
modalNext.addEventListener('keydown', modalKeyHandler, true);

modal.appendChild(modalNext)
modal.appendChild(modalNext);

try {
gradioApp().appendChild(modal);
} catch (e) {
gradioApp().body.appendChild(modal);
}
gradioApp().appendChild(modal);
} catch (e) {
gradioApp().body.appendChild(modal);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dynamic creation and configuration of modal elements (e.g., modalZoom, modalTileImage, modalSave, modalClose, modalImage, modalPrev, modalNext) are correctly implemented. However, consider grouping related element creation and configuration code into functions or a class to improve modularity and readability.

function createModalElement(tagName, className, innerHTML, title, eventListener) {
    const element = document.createElement(tagName);
    element.className = className;
    element.innerHTML = innerHTML;
    element.title = title;
    if (eventListener) {
        element.addEventListener('click', eventListener, true);
    }
    return element;
}

Comment on lines +75 to +85
def read_metadata(primary_model_name, secondary_model_name, tertiary_model_name):
metadata = {}

for checkpoint_name in [primary_model_name, secondary_model_name, tertiary_model_name]:
checkpoint_info = sd_models.checkpoints_list.get(checkpoint_name, None)
if checkpoint_info is None:
continue

metadata.update(checkpoint_info.metadata)

return json.dumps(metadata, indent=4, ensure_ascii=False)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The read_metadata function is a new addition that aggregates metadata from multiple model checkpoints. It's important to ensure that the metadata structure is consistent across different models to avoid potential issues when merging or updating metadata. Additionally, consider handling the case where metadata might be missing or malformed in some checkpoints to prevent runtime errors.

+        if 'metadata' not in checkpoint_info:
+            print(f"Warning: No metadata found for checkpoint {checkpoint_name}")
+            continue

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
def read_metadata(primary_model_name, secondary_model_name, tertiary_model_name):
metadata = {}
for checkpoint_name in [primary_model_name, secondary_model_name, tertiary_model_name]:
checkpoint_info = sd_models.checkpoints_list.get(checkpoint_name, None)
if checkpoint_info is None:
continue
metadata.update(checkpoint_info.metadata)
return json.dumps(metadata, indent=4, ensure_ascii=False)
def read_metadata(primary_model_name, secondary_model_name, tertiary_model_name):
metadata = {}
for checkpoint_name in [primary_model_name, secondary_model_name, tertiary_model_name]:
checkpoint_info = sd_models.checkpoints_list.get(checkpoint_name, None)
if checkpoint_info is None:
continue
if 'metadata' not in checkpoint_info:
print(f"Warning: No metadata found for checkpoint {checkpoint_name}")
continue
metadata.update(checkpoint_info.metadata)
return json.dumps(metadata, indent=4, ensure_ascii=False)

return json.dumps(metadata, indent=4, ensure_ascii=False)


def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_model_name, interp_method, multiplier, save_as_half, custom_name, checkpoint_format, config_source, bake_in_vae, discard_weights, save_metadata, add_merge_recipe, copy_metadata_fields, metadata_json):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The run_modelmerger function has been significantly modified to include additional parameters and logic. It's crucial to ensure that all new parameters are well-documented and validated at the beginning of the function to prevent misuse or errors during the model merging process. Additionally, consider breaking down this large function into smaller, more manageable functions to improve readability and maintainability.

Comment on lines 288 to 318
"is_inpainting": result_is_inpainting_model,
"is_instruct_pix2pix": result_is_instruct_pix2pix_model
}
metadata["sd_merge_recipe"] = json.dumps(merge_recipe)

sd_merge_models = {}

def add_model_metadata(checkpoint_info):
checkpoint_info.calculate_shorthash()
metadata["sd_merge_models"][checkpoint_info.sha256] = {
sd_merge_models[checkpoint_info.sha256] = {
"name": checkpoint_info.name,
"legacy_hash": checkpoint_info.hash,
"sd_merge_recipe": checkpoint_info.metadata.get("sd_merge_recipe", None)
}

metadata["sd_merge_models"].update(checkpoint_info.metadata.get("sd_merge_models", {}))
sd_merge_models.update(checkpoint_info.metadata.get("sd_merge_models", {}))

add_model_metadata(primary_model_info)
if secondary_model_info:
add_model_metadata(secondary_model_info)
if tertiary_model_info:
add_model_metadata(tertiary_model_info)

metadata["sd_merge_models"] = json.dumps(metadata["sd_merge_models"])
metadata["sd_merge_recipe"] = json.dumps(merge_recipe)
metadata["sd_merge_models"] = json.dumps(sd_merge_models)

_, extension = os.path.splitext(output_modelname)
if extension.lower() == ".safetensors":
safetensors.torch.save_file(theta_0, output_modelname, metadata=metadata)
safetensors.torch.save_file(theta_0, output_modelname, metadata=metadata if len(metadata)>0 else None)
else:
torch.save(theta_0, output_modelname)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 NOTE
This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [257-311]

The metadata handling logic within the model merging process has been updated to include more comprehensive metadata aggregation and customization. Ensure that the metadata structure is consistent and that all fields are properly validated before merging. Additionally, consider extracting the metadata handling logic into a separate function to improve modularity and readability.


_, extension = os.path.splitext(output_modelname)
if extension.lower() == ".safetensors":
safetensors.torch.save_file(theta_0, output_modelname, metadata=metadata)
safetensors.torch.save_file(theta_0, output_modelname, metadata=metadata if len(metadata)>0 else None)
else:
torch.save(theta_0, output_modelname)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The static analysis tool warns about potential security risks associated with using functions that rely on pickle for serialization. Consider following the recommendation to switch to a safer serialization method like ONNX, especially for operations involving loading or saving model checkpoints, to mitigate the risk of arbitrary code execution.

Comment on lines +29 to +39
function extract_image_from_gallery(gallery) {
if (gallery.length == 0) {
return [null];
}
if (gallery.length == 1){
if (gallery.length == 1) {
return [gallery[0]];
}

index = selected_gallery_index()
var index = selected_gallery_index();

if (index < 0 || index >= gallery.length){
if (index < 0 || index >= gallery.length) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extract_image_from_gallery function has been introduced to extract a selected image from the gallery. Ensure that the logic correctly handles edge cases, such as when the gallery is empty or when no image is selected. Consider adding error handling or default behavior for these scenarios.

Comment on lines +95 to +98
function create_tab_index_args(tabId, args) {
var res = Array.from(args);
res[0] = get_tab_index(tabId);
return res;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The create_tab_index_args function introduces a way to create arguments for tab switching with the index included. Ensure that the arguments manipulation is robust and does not inadvertently modify the original arguments array passed to the function.

Comment on lines +280 to +286
function confirm_clear_prompt(prompt, negative_prompt) {
if (confirm("Delete prompt?")) {
prompt = "";
negative_prompt = "";
}
}

function recalculate_prompts_txt2img(){
recalculatePromptTokens('txt2img_prompt')
recalculatePromptTokens('txt2img_neg_prompt')
return args_to_array(arguments);
return [prompt, negative_prompt];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The confirm_clear_prompt function introduces a confirmation dialog for clearing prompts. Ensure that the confirmation dialog is user-friendly and provides clear options for confirmation or cancellation. Additionally, consider the user experience and whether there are scenarios where this confirmation might become intrusive or annoying.

javascript/ui.js Outdated
Comment on lines 338 to 351
function restart_reload() {
document.body.innerHTML = '<h1 style="font-family:monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>';

function update_img2img_tokens(...args) {
update_token_counter("img2img_token_button")
if (args.length == 2)
return args[0]
return args;
}
var requestPing = function() {
requestGet("./internal/ping", {}, function(data) {
location.reload();
}, function() {
setTimeout(requestPing, 500);
});
};

function update_token_counter(button_id) {
if (token_timeouts[button_id])
clearTimeout(token_timeouts[button_id]);
token_timeouts[button_id] = setTimeout(() => gradioApp().getElementById(button_id)?.click(), wait_time);
}

function restart_reload(){
document.body.innerHTML='<h1 style="font-family:monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>';
setTimeout(function(){location.reload()},2000)
setTimeout(requestPing, 2000);

return []
return [];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The restart_reload function introduces a mechanism for reloading the application. Ensure that the reload process is smooth and does not lead to data loss or state inconsistencies. Additionally, consider providing feedback to the user during the reload process to improve the user experience.

Comment on lines +397 to +408
function switchWidthHeight(tabname) {
var width = gradioApp().querySelector("#" + tabname + "_width input[type=number]");
var height = gradioApp().querySelector("#" + tabname + "_height input[type=number]");
if (!width || !height) return [];

var tmp = width.value;
width.value = height.value;
height.value = tmp;

updateInput(width);
updateInput(height);
return [];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The switchWidthHeight function swaps the width and height values in the UI. Ensure that this function correctly updates the input fields and that the changes are immediately reflected in the UI. Additionally, consider adding validation to ensure that the input values are within acceptable ranges before swapping.

modules/cache.py Outdated
Comment on lines 17 to 46
def dump_cache():
"""
Marks cache for writing to disk. 5 seconds after no one else flags the cache for writing, it is written.
"""

global dump_cache_after
global dump_cache_thread

def thread_func():
global dump_cache_after
global dump_cache_thread

while dump_cache_after is not None and time.time() < dump_cache_after:
time.sleep(1)

with cache_lock:
cache_filename_tmp = cache_filename + "-"
with open(cache_filename_tmp, "w", encoding="utf8") as file:
json.dump(cache_data, file, indent=4, ensure_ascii=False)

os.replace(cache_filename_tmp, cache_filename)

dump_cache_after = None
dump_cache_thread = None

with cache_lock:
dump_cache_after = time.time() + 5
if dump_cache_thread is None:
dump_cache_thread = threading.Thread(name='cache-writer', target=thread_func)
dump_cache_thread.start()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dump_cache function correctly implements a delayed cache writing mechanism, which is a good practice to reduce disk I/O operations. However, consider adding error handling around the file operations (open, json.dump, os.replace) to catch and log potential I/O errors or issues with file permissions.

try:
    with open(cache_filename_tmp, "w", encoding="utf8") as file:
        json.dump(cache_data, file, indent=4, ensure_ascii=False)
    os.replace(cache_filename_tmp, cache_filename)
except Exception as e:
    print(f'[ERROR] Failed to dump cache: {e}')

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
def dump_cache():
"""
Marks cache for writing to disk. 5 seconds after no one else flags the cache for writing, it is written.
"""
global dump_cache_after
global dump_cache_thread
def thread_func():
global dump_cache_after
global dump_cache_thread
while dump_cache_after is not None and time.time() < dump_cache_after:
time.sleep(1)
with cache_lock:
cache_filename_tmp = cache_filename + "-"
with open(cache_filename_tmp, "w", encoding="utf8") as file:
json.dump(cache_data, file, indent=4, ensure_ascii=False)
os.replace(cache_filename_tmp, cache_filename)
dump_cache_after = None
dump_cache_thread = None
with cache_lock:
dump_cache_after = time.time() + 5
if dump_cache_thread is None:
dump_cache_thread = threading.Thread(name='cache-writer', target=thread_func)
dump_cache_thread.start()
def dump_cache():
"""
Marks cache for writing to disk. 5 seconds after no one else flags the cache for writing, it is written.
"""
global dump_cache_after
global dump_cache_thread
def thread_func():
global dump_cache_after
global dump_cache_thread
while dump_cache_after is not None and time.time() < dump_cache_after:
time.sleep(1)
with cache_lock:
cache_filename_tmp = cache_filename + "-"
try:
with open(cache_filename_tmp, "w", encoding="utf8") as file:
json.dump(cache_data, file, indent=4, ensure_ascii=False)
os.replace(cache_filename_tmp, cache_filename)
except Exception as e:
print(f'[ERROR] Failed to dump cache: {e}')
dump_cache_after = None
dump_cache_thread = None
with cache_lock:
dump_cache_after = time.time() + 5
if dump_cache_thread is None:
dump_cache_thread = threading.Thread(name='cache-writer', target=thread_func)
dump_cache_thread.start()

if (commentBefore) {
var comment = document.createElement('DIV');
comment.className = 'settings-comment';
comment.innerHTML = commentBefore;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using innerHTML to insert user-controlled data can lead to Cross-Site Scripting (XSS) vulnerabilities. Ensure that the content assigned to innerHTML is properly sanitized or consider using safer alternatives like textContent or DOM methods to create and append elements.

- comment.innerHTML = commentBefore;
+ comment.textContent = commentBefore;

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
comment.innerHTML = commentBefore;
comment.textContent = commentBefore;

if (commentAfter) {
comment = document.createElement('DIV');
comment.className = 'settings-comment';
comment.innerHTML = commentAfter;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the previous comment, using innerHTML with user-controlled data poses a security risk. Replace innerHTML with textContent or use DOM manipulation methods to safely create and append content.

- comment.innerHTML = commentAfter;
+ comment.textContent = commentAfter;

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
comment.innerHTML = commentAfter;
comment.textContent = commentAfter;

modules/cache.py Outdated
Comment on lines 49 to 78
def cache(subsection):
"""
Retrieves or initializes a cache for a specific subsection.

Parameters:
subsection (str): The subsection identifier for the cache.

Returns:
dict: The cache data for the specified subsection.
"""

global cache_data

if cache_data is None:
with cache_lock:
if cache_data is None:
try:
with open(cache_filename, "r", encoding="utf8") as file:
cache_data = json.load(file)
except FileNotFoundError:
cache_data = {}
except Exception:
os.replace(cache_filename, os.path.join(script_path, "tmp", "cache.json"))
print('[ERROR] issue occurred while trying to read cache.json, move current cache to tmp/cache.json and create new cache')
cache_data = {}

s = cache_data.get(subsection, {})
cache_data[subsection] = s

return s
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cache function's implementation for retrieving or initializing cache subsections is clear and follows best practices. However, when handling exceptions for file operations, it's recommended to log the error or notify the user instead of silently failing and creating a new cache. This can help in diagnosing issues with file access or corruption.

except FileNotFoundError:
    cache_data = {}
except Exception as e:
-   os.replace(cache_filename, os.path.join(script_path, "tmp", "cache.json"))
-   print('[ERROR] issue occurred while trying to read cache.json, move current cache to tmp/cache.json and create new cache')
+   print(f'[ERROR] Failed to read cache file: {e}')
    cache_data = {}

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
def cache(subsection):
"""
Retrieves or initializes a cache for a specific subsection.
Parameters:
subsection (str): The subsection identifier for the cache.
Returns:
dict: The cache data for the specified subsection.
"""
global cache_data
if cache_data is None:
with cache_lock:
if cache_data is None:
try:
with open(cache_filename, "r", encoding="utf8") as file:
cache_data = json.load(file)
except FileNotFoundError:
cache_data = {}
except Exception:
os.replace(cache_filename, os.path.join(script_path, "tmp", "cache.json"))
print('[ERROR] issue occurred while trying to read cache.json, move current cache to tmp/cache.json and create new cache')
cache_data = {}
s = cache_data.get(subsection, {})
cache_data[subsection] = s
return s
def cache(subsection):
"""
Retrieves or initializes a cache for a specific subsection.
Parameters:
subsection (str): The subsection identifier for the cache.
Returns:
dict: The cache data for the specified subsection.
"""
global cache_data
if cache_data is None:
with cache_lock:
if cache_data is None:
try:
with open(cache_filename, "r", encoding="utf8") as file:
cache_data = json.load(file)
except FileNotFoundError:
cache_data = {}
except Exception as e:
print(f'[ERROR] Failed to read cache file: {e}')
cache_data = {}
s = cache_data.get(subsection, {})
cache_data[subsection] = s
return s

Comment on lines +34 to +86
DEPTH_LAYERS = {
0: [
# SD 1.5 U-Net (diffusers)
"down_blocks.0.attentions.0.transformer_blocks.0.attn1",
"down_blocks.0.attentions.1.transformer_blocks.0.attn1",
"up_blocks.3.attentions.0.transformer_blocks.0.attn1",
"up_blocks.3.attentions.1.transformer_blocks.0.attn1",
"up_blocks.3.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.1.1.transformer_blocks.0.attn1",
"input_blocks.2.1.transformer_blocks.0.attn1",
"output_blocks.9.1.transformer_blocks.0.attn1",
"output_blocks.10.1.transformer_blocks.0.attn1",
"output_blocks.11.1.transformer_blocks.0.attn1",
# SD 1.5 VAE
"decoder.mid_block.attentions.0",
"decoder.mid.attn_1",
],
1: [
# SD 1.5 U-Net (diffusers)
"down_blocks.1.attentions.0.transformer_blocks.0.attn1",
"down_blocks.1.attentions.1.transformer_blocks.0.attn1",
"up_blocks.2.attentions.0.transformer_blocks.0.attn1",
"up_blocks.2.attentions.1.transformer_blocks.0.attn1",
"up_blocks.2.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.4.1.transformer_blocks.0.attn1",
"input_blocks.5.1.transformer_blocks.0.attn1",
"output_blocks.6.1.transformer_blocks.0.attn1",
"output_blocks.7.1.transformer_blocks.0.attn1",
"output_blocks.8.1.transformer_blocks.0.attn1",
],
2: [
# SD 1.5 U-Net (diffusers)
"down_blocks.2.attentions.0.transformer_blocks.0.attn1",
"down_blocks.2.attentions.1.transformer_blocks.0.attn1",
"up_blocks.1.attentions.0.transformer_blocks.0.attn1",
"up_blocks.1.attentions.1.transformer_blocks.0.attn1",
"up_blocks.1.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.7.1.transformer_blocks.0.attn1",
"input_blocks.8.1.transformer_blocks.0.attn1",
"output_blocks.3.1.transformer_blocks.0.attn1",
"output_blocks.4.1.transformer_blocks.0.attn1",
"output_blocks.5.1.transformer_blocks.0.attn1",
],
3: [
# SD 1.5 U-Net (diffusers)
"mid_block.attentions.0.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"middle_block.1.transformer_blocks.0.attn1",
],
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DEPTH_LAYERS and DEPTH_LAYERS_XL dictionaries are crucial for defining the layers to which hypertiling will be applied. It's important to ensure that all layer names are accurate and correspond to the actual model architecture. Additionally, consider adding comments to explain the rationale behind the selection of these specific layers for hypertiling.

+ // Add comments explaining the selection of layers for hypertiling

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
DEPTH_LAYERS = {
0: [
# SD 1.5 U-Net (diffusers)
"down_blocks.0.attentions.0.transformer_blocks.0.attn1",
"down_blocks.0.attentions.1.transformer_blocks.0.attn1",
"up_blocks.3.attentions.0.transformer_blocks.0.attn1",
"up_blocks.3.attentions.1.transformer_blocks.0.attn1",
"up_blocks.3.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.1.1.transformer_blocks.0.attn1",
"input_blocks.2.1.transformer_blocks.0.attn1",
"output_blocks.9.1.transformer_blocks.0.attn1",
"output_blocks.10.1.transformer_blocks.0.attn1",
"output_blocks.11.1.transformer_blocks.0.attn1",
# SD 1.5 VAE
"decoder.mid_block.attentions.0",
"decoder.mid.attn_1",
],
1: [
# SD 1.5 U-Net (diffusers)
"down_blocks.1.attentions.0.transformer_blocks.0.attn1",
"down_blocks.1.attentions.1.transformer_blocks.0.attn1",
"up_blocks.2.attentions.0.transformer_blocks.0.attn1",
"up_blocks.2.attentions.1.transformer_blocks.0.attn1",
"up_blocks.2.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.4.1.transformer_blocks.0.attn1",
"input_blocks.5.1.transformer_blocks.0.attn1",
"output_blocks.6.1.transformer_blocks.0.attn1",
"output_blocks.7.1.transformer_blocks.0.attn1",
"output_blocks.8.1.transformer_blocks.0.attn1",
],
2: [
# SD 1.5 U-Net (diffusers)
"down_blocks.2.attentions.0.transformer_blocks.0.attn1",
"down_blocks.2.attentions.1.transformer_blocks.0.attn1",
"up_blocks.1.attentions.0.transformer_blocks.0.attn1",
"up_blocks.1.attentions.1.transformer_blocks.0.attn1",
"up_blocks.1.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.7.1.transformer_blocks.0.attn1",
"input_blocks.8.1.transformer_blocks.0.attn1",
"output_blocks.3.1.transformer_blocks.0.attn1",
"output_blocks.4.1.transformer_blocks.0.attn1",
"output_blocks.5.1.transformer_blocks.0.attn1",
],
3: [
# SD 1.5 U-Net (diffusers)
"mid_block.attentions.0.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"middle_block.1.transformer_blocks.0.attn1",
],
}
DEPTH_LAYERS = {
// Add comments explaining the selection of layers for hypertiling
# SD 1.5 U-Net (diffusers)
"down_blocks.0.attentions.0.transformer_blocks.0.attn1",
"down_blocks.0.attentions.1.transformer_blocks.0.attn1",
"up_blocks.3.attentions.0.transformer_blocks.0.attn1",
"up_blocks.3.attentions.1.transformer_blocks.0.attn1",
"up_blocks.3.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.1.1.transformer_blocks.0.attn1",
"input_blocks.2.1.transformer_blocks.0.attn1",
"output_blocks.9.1.transformer_blocks.0.attn1",
"output_blocks.10.1.transformer_blocks.0.attn1",
"output_blocks.11.1.transformer_blocks.0.attn1",
# SD 1.5 VAE
"decoder.mid_block.attentions.0",
"decoder.mid.attn_1",
],
// Add comments explaining the selection of layers for hypertiling
# SD 1.5 U-Net (diffusers)
"down_blocks.1.attentions.0.transformer_blocks.0.attn1",
"down_blocks.1.attentions.1.transformer_blocks.0.attn1",
"up_blocks.2.attentions.0.transformer_blocks.0.attn1",
"up_blocks.2.attentions.1.transformer_blocks.0.attn1",
"up_blocks.2.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.4.1.transformer_blocks.0.attn1",
"input_blocks.5.1.transformer_blocks.0.attn1",
"output_blocks.6.1.transformer_blocks.0.attn1",
"output_blocks.7.1.transformer_blocks.0.attn1",
"output_blocks.8.1.transformer_blocks.0.attn1",
],
// Add comments explaining the selection of layers for hypertiling
# SD 1.5 U-Net (diffusers)
"down_blocks.2.attentions.0.transformer_blocks.0.attn1",
"down_blocks.2.attentions.1.transformer_blocks.0.attn1",
"up_blocks.1.attentions.0.transformer_blocks.0.attn1",
"up_blocks.1.attentions.1.transformer_blocks.0.attn1",
"up_blocks.1.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.7.1.transformer_blocks.0.attn1",
"input_blocks.8.1.transformer_blocks.0.attn1",
"output_blocks.3.1.transformer_blocks.0.attn1",
"output_blocks.4.1.transformer_blocks.0.attn1",
"output_blocks.5.1.transformer_blocks.0.attn1",
],
// Add comments explaining the selection of layers for hypertiling
# SD 1.5 U-Net (diffusers)
"mid_block.attentions.0.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"middle_block.1.transformer_blocks.0.attn1",
],
}

Comment on lines +81 to +123
def cached_data_for_file(subsection, title, filename, func):
"""
Retrieves or generates data for a specific file, using a caching mechanism.

Parameters:
subsection (str): The subsection of the cache to use.
title (str): The title of the data entry in the subsection of the cache.
filename (str): The path to the file to be checked for modifications.
func (callable): A function that generates the data if it is not available in the cache.

Returns:
dict or None: The cached or generated data, or None if data generation fails.

The `cached_data_for_file` function implements a caching mechanism for data stored in files.
It checks if the data associated with the given `title` is present in the cache and compares the
modification time of the file with the cached modification time. If the file has been modified,
the cache is considered invalid and the data is regenerated using the provided `func`.
Otherwise, the cached data is returned.

If the data generation fails, None is returned to indicate the failure. Otherwise, the generated
or cached data is returned as a dictionary.
"""

existing_cache = cache(subsection)
ondisk_mtime = os.path.getmtime(filename)

entry = existing_cache.get(title)
if entry:
cached_mtime = entry.get("mtime", 0)
if ondisk_mtime > cached_mtime:
entry = None

if not entry or 'value' not in entry:
value = func()
if value is None:
return None

entry = {'mtime': ondisk_mtime, 'value': value}
existing_cache[title] = entry

dump_cache()

return entry['value']
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cached_data_for_file function correctly implements a caching mechanism that checks for file modifications. However, consider adding error handling for the func() call to catch exceptions that might occur during data generation. This would improve the robustness of the caching mechanism by ensuring that transient errors in data generation do not cause the entire operation to fail.

try:
    value = func()
    if value is None:
        return None
except Exception as e:
    print(f'[ERROR] Failed to generate data for cache: {e}')
    return None

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
def cached_data_for_file(subsection, title, filename, func):
"""
Retrieves or generates data for a specific file, using a caching mechanism.
Parameters:
subsection (str): The subsection of the cache to use.
title (str): The title of the data entry in the subsection of the cache.
filename (str): The path to the file to be checked for modifications.
func (callable): A function that generates the data if it is not available in the cache.
Returns:
dict or None: The cached or generated data, or None if data generation fails.
The `cached_data_for_file` function implements a caching mechanism for data stored in files.
It checks if the data associated with the given `title` is present in the cache and compares the
modification time of the file with the cached modification time. If the file has been modified,
the cache is considered invalid and the data is regenerated using the provided `func`.
Otherwise, the cached data is returned.
If the data generation fails, None is returned to indicate the failure. Otherwise, the generated
or cached data is returned as a dictionary.
"""
existing_cache = cache(subsection)
ondisk_mtime = os.path.getmtime(filename)
entry = existing_cache.get(title)
if entry:
cached_mtime = entry.get("mtime", 0)
if ondisk_mtime > cached_mtime:
entry = None
if not entry or 'value' not in entry:
value = func()
if value is None:
return None
entry = {'mtime': ondisk_mtime, 'value': value}
existing_cache[title] = entry
dump_cache()
return entry['value']
def cached_data_for_file(subsection, title, filename, func):
"""
Retrieves or generates data for a specific file, using a caching mechanism.
Parameters:
subsection (str): The subsection of the cache to use.
title (str): The title of the data entry in the subsection of the cache.
filename (str): The path to the file to be checked for modifications.
func (callable): A function that generates the data if it is not available in the cache.
Returns:
dict or None: The cached or generated data, or None if data generation fails.
The `cached_data_for_file` function implements a caching mechanism for data stored in files.
It checks if the data associated with the given `title` is present in the cache and compares the
modification time of the file with the cached modification time. If the file has been modified,
the cache is considered invalid and the data is regenerated using the provided `func`.
Otherwise, the cached data is returned.
If the data generation fails, None is returned to indicate the failure. Otherwise, the generated
or cached data is returned as a dictionary.
"""
existing_cache = cache(subsection)
ondisk_mtime = os.path.getmtime(filename)
entry = existing_cache.get(title)
if entry:
cached_mtime = entry.get("mtime", 0)
if ondisk_mtime > cached_mtime:
entry = None
if not entry or 'value' not in entry:
try:
value = func()
if value is None:
return None
except Exception as e:
print(f'[ERROR] Failed to generate data for cache: {e}')
return None
entry = {'mtime': ondisk_mtime, 'value': value}
existing_cache[title] = entry
dump_cache()
return entry['value']

Comment on lines +64 to +72
def display(e: Exception, task, *, full_traceback=False):
record_exception()

print(f"{task or 'error'}: {type(e).__name__}", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
te = traceback.TracebackException.from_exception(e)
if full_traceback:
# include frames leading up to the try-catch block
te.stack = traceback.StackSummary(traceback.extract_stack()[:-2] + te.stack)
print(*te.format(), sep="", file=sys.stderr)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The display function's ability to handle full tracebacks and specific error messages is useful. However, the hardcoded error message related to model shape mismatch suggests a specific use case. Consider abstracting this to allow for more generic error handling or moving it to a more appropriate location related to model loading.

- if "copying a param with shape torch.Size([640, 1024]) from checkpoint, the shape in current model is torch.Size([640, 768])" in message:
+ if specific_condition_related_to_model_loading_error(message):

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
def display(e: Exception, task, *, full_traceback=False):
record_exception()
print(f"{task or 'error'}: {type(e).__name__}", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
te = traceback.TracebackException.from_exception(e)
if full_traceback:
# include frames leading up to the try-catch block
te.stack = traceback.StackSummary(traceback.extract_stack()[:-2] + te.stack)
print(*te.format(), sep="", file=sys.stderr)
def display(e: Exception, task, *, full_traceback=False):
record_exception()
print(f"{task or 'error'}: {type(e).__name__}", file=sys.stderr)
te = traceback.TracebackException.from_exception(e)
if full_traceback:
# include frames leading up to the try-catch block
te.stack = traceback.StackSummary(traceback.extract_stack()[:-2] + te.stack)
print(*te.format(), sep="", file=sys.stderr)

w-e-w and others added 26 commits July 18, 2024 23:51
…utton-log.csv-

option to disable save button log.csv
add ids to the resize tabs in img2img
…_on_non-job_actions

[bug] do not break progressbar on non-job actions (add wrap_gradio_call_no_job)
…as_jpeg

fix OSError: cannot write mode P as JPEG
…n_paste_inpaint

do not send image size on paste inpaint
Fix noisy DS_Store files for MacOS
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 52

Outside diff range, codebase verification and nitpick comments (25)
configs/alt-diffusion-m18-inference.yaml (5)

2-2: Specify the learning rate unit.

It's good practice to specify the unit for the learning rate to avoid confusion.

base_learning_rate: 1.0e-04 # learning rate per sample

14-14: Clarify the comment.

The comment should provide more context about why this parameter is different from the one trained before.

cond_stage_trainable: false   # Note: different from the one we trained before because we are using a pre-trained model

24-24: Avoid using extremely large numbers.

Using extremely large numbers can lead to unexpected behavior. Consider using a more reasonable value or explaining why such a large number is necessary.

cycle_lengths: [ 1000000 ] # large number to prevent corner cases

32-32: Remove unused parameter.

The image_size parameter is marked as unused and should be removed to avoid confusion.

# image_size: 32 # unused

53-53: Ensure boolean values are consistent.

Ensure that boolean values are consistently lowercase to avoid potential issues.

double_z: true # should be lowercase
extensions-builtin/Lora/extra_networks_lora.py (3)

9-10: Ensure proper documentation for self.errors.

The self.errors dictionary should be properly documented to explain its purpose and usage.

self.errors = {}
"""mapping of network names to the number of errors the network had during operation"""

24-27: Consider initializing lists outside the loop.

Initializing lists outside the loop can improve readability and maintainability.

names = []
te_multipliers = []
unet_multipliers = []
dyn_dims = []

for params in params_list:
    assert params.items
    names.append(params.positional[0])
    te_multiplier = float(params.positional[1]) if len(params.positional) > 1 else 1.0
    te_multiplier = float(params.named.get("te", te_multiplier))
    unet_multiplier = float(params.positional[2]) if len(params.positional) > 2 else te_multiplier
    unet_multiplier = float(params.named.get("unet", unet_multiplier))
    dyn_dim = int(params.positional[3]) if len(params.positional) > 3 else None
    dyn_dim = int(params.named["dyn"]) if "dyn" in params.named else dyn_dim
    te_multipliers.append(te_multiplier)
    unet_multipliers.append(unet_multiplier)
    dyn_dims.append(dyn_dim)

47-56: Ensure conditional logic is clear and concise.

The conditional logic for adding Lora hashes should be clear and concise.

if shared.opts.lora_add_hashes_to_infotext:
    if not getattr(p, "is_hr_pass", False) or not hasattr(p, "lora_hashes"):
        p.lora_hashes = {}

    for item in networks.loaded_networks:
        if item.network_on_disk.shorthash and item.mentioned_name:
            p.lora_hashes[item.mentioned_name.translate(self.remove_symbols)] = item.network_on_disk.shorthash

    if p.lora_hashes:
        p.extra_generation_params["Lora hashes"] = ', '.join(f'{k}: {v}' for k, v in p.lora_hashes.items())
modules/devices.py (2)

15-16: Missing definition for xpu_specific.has_xpu.

The function xpu_specific.has_xpu is not defined anywhere in the codebase. This will result in a runtime error when has_xpu is called.

  • Ensure that xpu_specific.has_xpu is defined within the xpu_specific module or imported correctly.
Analysis chain

Verify the definition and import of xpu_specific.has_xpu.

Ensure that xpu_specific.has_xpu is correctly defined and imported to avoid runtime errors.


Verify the definition and import of xpu_specific.has_xpu.

Ensure that xpu_specific.has_xpu is correctly defined and imported to avoid runtime errors.


Verify the definition of xpu_specific.has_xpu.

Ensure that xpu_specific.has_xpu is correctly defined to avoid runtime errors.


Verify the definition of xpu_specific.has_xpu.

Ensure that xpu_specific.has_xpu is correctly defined to avoid runtime errors.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the definition and import of `xpu_specific.has_xpu`.

# Test: Search for the definition of `has_xpu` in `xpu_specific`.
rg --type python -A 5 $'def has_xpu' | grep -B 5 'xpu_specific'

Length of output: 93


Script:

#!/bin/bash
# Description: Verify the definition and import of `xpu_specific.has_xpu`.

# Test: Search for the definition of `has_xpu` in the codebase.
rg 'def has_xpu' -A 5

# Test: Search for the import of `xpu_specific`.
rg 'import xpu_specific' -A 5

Length of output: 549


Script:

#!/bin/bash
# Description: Verify the definition of `xpu_specific.has_xpu`.

# Test: Search for the definition of `has_xpu` in the `xpu_specific` module.
rg 'def has_xpu' -A 5 --glob 'modules/xpu_specific.py'

Length of output: 54


Script:

#!/bin/bash
# Description: Verify the definition of `xpu_specific.has_xpu`.

# Test: Search for the definition of `has_xpu` across the entire codebase.
rg 'def has_xpu' -A 5

Length of output: 279


78-93: Missing import for npu_specific in modules/devices.py

The device-specific garbage collection functions torch_mps_gc, torch_xpu_gc, and torch_npu_gc are correctly defined in their respective modules. The imports for mac_specific and xpu_specific are present in modules/devices.py. However, the import for npu_specific is missing.

  • Ensure to add the missing import for npu_specific in modules/devices.py.
Analysis chain

Verify the definition and import of device-specific garbage collection functions.

Ensure that the device-specific garbage collection functions (torch.cuda.empty_cache, mac_specific.torch_mps_gc, xpu_specific.torch_xpu_gc, npu_specific.torch_npu_gc) are correctly defined and imported to avoid runtime errors.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the definition and import of device-specific garbage collection functions.

# Test: Search for the definition of device-specific garbage collection functions.
rg --type python -A 5 $'torch.cuda.empty_cache' | grep -B 5 'mac_specific.torch_mps_gc' | grep -B 5 'xpu_specific.torch_xpu_gc' | grep -B 5 'npu_specific.torch_npu_gc'

Length of output: 191


Script:

#!/bin/bash
# Description: Verify the definition and import of device-specific garbage collection functions.

# Test: Search for the definition and import of torch.cuda.empty_cache
rg 'torch.cuda.empty_cache' --type py -A 5

# Test: Search for the definition and import of mac_specific.torch_mps_gc
rg 'mac_specific.torch_mps_gc' --type py -A 5

# Test: Search for the definition and import of xpu_specific.torch_xpu_gc
rg 'xpu_specific.torch_xpu_gc' --type py -A 5

# Test: Search for the definition and import of npu_specific.torch_npu_gc
rg 'npu_specific.torch_npu_gc' --type py -A 5

Length of output: 1253


Script:

#!/bin/bash
# Description: Verify the definition and import of device-specific garbage collection functions.

# Test: Search for the definition of mac_specific.torch_mps_gc
rg 'def torch_mps_gc' --type py -A 5

# Test: Search for the definition of xpu_specific.torch_xpu_gc
rg 'def torch_xpu_gc' --type py -A 5

# Test: Search for the definition of npu_specific.torch_npu_gc
rg 'def torch_npu_gc' --type py -A 5

# Test: Search for the imports of mac_specific, xpu_specific, and npu_specific
rg 'import mac_specific' --type py -A 5
rg 'import xpu_specific' --type py -A 5
rg 'import npu_specific' --type py -A 5

Length of output: 1628

extensions-builtin/Lora/ui_edit_user_metadata.py (1)

59-69: Input validation missing in save_lora_user_metadata and related methods

The save_lora_user_metadata function and its related methods (get_user_metadata and write_user_metadata) do not perform input validation. This could lead to incorrect or malicious data being stored.

  • extensions-builtin/Lora/ui_edit_user_metadata.py: save_lora_user_metadata
  • modules/ui_extra_networks_user_metadata.py: get_user_metadata
  • modules/ui_extra_networks_user_metadata.py: write_user_metadata

Please ensure that input validation is added to these methods to prevent incorrect data storage.

Analysis chain

Verify the accuracy of input validation and metadata writing.

Ensure that the input validation and metadata writing are performed accurately to avoid incorrect data storage.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the accuracy of input validation and metadata writing.

# Test: Search for the usage of `save_lora_user_metadata`.
rg --type python -A 5 $'save_lora_user_metadata'

Length of output: 78


Script:

#!/bin/bash
# Description: Verify the accuracy of input validation and metadata writing.

# Test: Search for the usage of `save_lora_user_metadata`.
rg -A 5 $'save_lora_user_metadata'

Length of output: 870


Script:

#!/bin/bash
# Description: Verify the input validation for `save_lora_user_metadata`.

# Test: Search for the definition and usage of `setup_save_handler`.
rg -A 10 $'setup_save_handler'

Length of output: 2590


Script:

#!/bin/bash
# Description: Verify the handling and validation of data in `get_user_metadata` and `write_user_metadata`.

# Test: Search for the definition of `get_user_metadata`.
rg -A 10 $'def get_user_metadata'

# Test: Search for the definition of `write_user_metadata`.
rg -A 10 $'def write_user_metadata'

Length of output: 2527

README.md (2)

18-18: Approved: Improved usability for Mac users.

The instructions now include MacOS-specific key combinations, enhancing usability.

Correct the grammar issue.

Change "MacOS" to "macOS" for proper capitalization.

-    - select text and press `Ctrl+Up` or `Ctrl+Down` (or `Command+Up` or `Command+Down` if you're on a MacOS) to automatically adjust attention to selected text (code contributed by anonymous user)
+    - select text and press `Ctrl+Up` or `Ctrl+Down` (or `Command+Up` or `Command+Down` if you're on a macOS) to automatically adjust attention to selected text (code contributed by anonymous user)
Tools
LanguageTool

[grammar] ~18-~18: The operating system from Apple is written “macOS”.
Context: ...nd+UporCommand+Down` if you're on a MacOS) to automatically adjust attention to s...

(MAC_OS)

Markdownlint

18-18: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


107-112: Approved: Comprehensive installation steps for Windows 10/11 with NVidia GPUs.

The addition provides a more comprehensive guide for users on that platform.

Ensure a blank line above the heading.

For better readability and adherence to Markdown standards, ensure there is a blank line above the heading.

+ 
### Installation on Windows 10/11 with NVidia-GPUs using release package
Tools
LanguageTool

[uncategorized] ~111-~111: Possible missing comma found.
Context: ...te.bat. 3. Run run.bat`.

For more details see [Install-and-Run-on-NVidia-GPUs](ht...

(AI_HYDRA_LEO_MISSING_COMMA)

extensions-builtin/Lora/networks.py (6)

150-155: Consider adding type hints to the BundledTIHash class.

Adding type hints can improve code readability and help with static type checking.

- def __init__(self, hash_str):
+ def __init__(self, hash_str: str):

273-278: Consider adding a log message when purging networks from memory.

Adding a log message can help in debugging and understanding the memory management process.

-    while len(networks_in_memory) > shared.opts.lora_in_memory_limit and len(networks_in_memory) > 0:
+    while len(networks_in_memory) > shared.opts.lora_in_memory_limit and len(networks_in_memory) > 0:
+        logging.info(f"Purging network {name} from memory.")

369-373: Consider adding type hints to the allowed_layer_without_weight function.

Adding type hints can improve code readability and help with static type checking.

- def allowed_layer_without_weight(layer):
+ def allowed_layer_without_weight(layer: torch.nn.Module) -> bool:

376-380: Consider adding type hints to the store_weights_backup function.

Adding type hints can improve code readability and help with static type checking.

- def store_weights_backup(weight):
+ def store_weights_backup(weight: torch.Tensor) -> torch.Tensor:

383-388: Consider adding type hints to the restore_weights_backup function.

Adding type hints can improve code readability and help with static type checking.

- def restore_weights_backup(obj, field, weight):
+ def restore_weights_backup(obj: torch.nn.Module, field: str, weight: torch.Tensor) -> None:

391-408: Consider adding type hints to the network_restore_weights_from_backup function.

Adding type hints can improve code readability and help with static type checking.

- def network_restore_weights_from_backup(self):
+ def network_restore_weights_from_backup(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.GroupNorm, torch.nn.LayerNorm, torch.nn.MultiheadAttention]) -> None:
extensions-builtin/soft-inpainting/scripts/soft_inpainting.py (1)

9-32: Consider adding type hints to the SoftInpaintingSettings class methods.

Adding type hints can improve code readability and help with static type checking.

- def __init__(self,
-              mask_blend_power,
-              mask_blend_scale,
-              inpaint_detail_preservation,
-              composite_mask_influence,
-              composite_difference_threshold,
-              composite_difference_contrast):
+ def __init__(self,
+              mask_blend_power: float,
+              mask_blend_scale: float,
+              inpaint_detail_preservation: float,
+              composite_mask_influence: float,
+              composite_difference_threshold: float,
+              composite_difference_contrast: float):
- def add_generation_params(self, dest):
+ def add_generation_params(self, dest: dict) -> None:
modules/api/api.py (5)

58-73: Move import statements to the top of the file.

For better readability and maintainability, move the import statements for socket and urlparse to the top of the file.

-    import socket
-    from urllib.parse import urlparse

Line range hint 492-565:
Improve error handling and add detailed logging.

Enhance error handling around the process_images call and add more detailed logging to help with debugging.

-                    processed = process_images(p)
+                    try:
+                        processed = process_images(p)
+                    except Exception as e:
+                        shared.state.end()
+                        shared.total_tqdm.clear()
+                        raise HTTPException(status_code=500, detail=str(e))

Line range hint 602-628:
Improve progress calculation.

Ensure that the calculation of progress handles edge cases where shared.state.job_count or shared.state.sampling_steps might be zero.

-        if shared.state.job_count > 0:
-            progress += shared.state.job_no / shared.state.job_count
-        if shared.state.sampling_steps > 0:
-            progress += 1 / shared.state.job_count * shared.state.sampling_step / shared.state.sampling_steps
+        if shared.state.job_count > 0:
+            progress += shared.state.job_no / max(shared.state.job_count, 1)
+        if shared.state.sampling_steps > 0:
+            progress += 1 / max(shared.state.job_count, 1) * shared.state.sampling_step / max(shared.state.sampling_steps, 1)

Line range hint 630-647:
Improve error handling.

Enhance error handling around the decode_base64_to_image call to ensure robustness.

-        img = decode_base64_to_image(image_b64)
+        try:
+            img = decode_base64_to_image(image_b64)
+        except Exception as e:
+            raise HTTPException(status_code=500, detail=str(e))

Line range hint 807-823:
Improve error handling.

Enhance error handling around the train_embedding call to ensure robustness.

-            try:
-                embedding, filename = train_embedding(**args) # can take a long time to complete
-            except Exception as e:
-                error = e
+            try:
+                embedding, filename = train_embedding(**args) # can take a long time to complete
+            except Exception as e:
+                error = e
+                raise HTTPException(status_code=500, detail=f"Failed to train embedding: {e}")
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between feee37d and c19d044.

Files selected for processing (31)
  • .github/ISSUE_TEMPLATE/bug_report.yml (2 hunks)
  • .gitignore (2 hunks)
  • CHANGELOG.md (3 hunks)
  • README.md (7 hunks)
  • configs/alt-diffusion-inference.yaml (1 hunks)
  • configs/alt-diffusion-m18-inference.yaml (1 hunks)
  • configs/instruct-pix2pix.yaml (1 hunks)
  • configs/sd3-inference.yaml (1 hunks)
  • configs/sd_xl_inpaint.yaml (1 hunks)
  • configs/v1-inference.yaml (1 hunks)
  • configs/v1-inpainting-inference.yaml (1 hunks)
  • extensions-builtin/LDSR/sd_hijack_ddpm_v1.py (22 hunks)
  • extensions-builtin/Lora/extra_networks_lora.py (1 hunks)
  • extensions-builtin/Lora/network.py (1 hunks)
  • extensions-builtin/Lora/network_lora.py (1 hunks)
  • extensions-builtin/Lora/networks.py (1 hunks)
  • extensions-builtin/Lora/scripts/lora_script.py (1 hunks)
  • extensions-builtin/Lora/ui_edit_user_metadata.py (1 hunks)
  • extensions-builtin/Lora/ui_extra_networks_lora.py (1 hunks)
  • extensions-builtin/hypertile/scripts/hypertile_script.py (1 hunks)
  • extensions-builtin/soft-inpainting/scripts/soft_inpainting.py (1 hunks)
  • javascript/contextMenus.js (1 hunks)
  • javascript/dragdrop.js (2 hunks)
  • javascript/imageviewer.js (3 hunks)
  • javascript/progressbar.js (1 hunks)
  • javascript/ui.js (4 hunks)
  • modules/api/api.py (21 hunks)
  • modules/call_queue.py (4 hunks)
  • modules/cmd_args.py (3 hunks)
  • modules/deepbooru.py (3 hunks)
  • modules/devices.py (4 hunks)
Files skipped from review due to trivial changes (2)
  • .gitignore
  • configs/sd3-inference.yaml
Additional context used
Biome
javascript/imageviewer.js

[error] 36-36: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

LanguageTool
README.md

[uncategorized] ~2-~2: You might be missing the article “the” here.
Context: ...for Stable Diffusion, implemented using Gradio library.

F...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[grammar] ~18-~18: The operating system from Apple is written “macOS”.
Context: ...nd+UporCommand+Down` if you're on a MacOS) to automatically adjust attention to s...

(MAC_OS)


[uncategorized] ~111-~111: Possible missing comma found.
Context: ...te.bat. 3. Run run.bat`.

For more details see [Install-and-Run-on-NVidia-GPUs](ht...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~173-~173: You might be missing the article “the” here.
Context: ...ttings -> Licensesscreen, and also inhtml/licenses.html` file.

  • Stable Di...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

Markdownlint
README.md

18-18: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


175-175: null
Bare URL used

(MD034, no-bare-urls)


175-175: null
Bare URL used

(MD034, no-bare-urls)


175-175: null
Bare URL used

(MD034, no-bare-urls)


176-176: null
Bare URL used

(MD034, no-bare-urls)


177-177: null
Bare URL used

(MD034, no-bare-urls)


178-178: null
Bare URL used

(MD034, no-bare-urls)


179-179: null
Bare URL used

(MD034, no-bare-urls)


180-180: null
Bare URL used

(MD034, no-bare-urls)


181-181: null
Bare URL used

(MD034, no-bare-urls)


182-182: null
Bare URL used

(MD034, no-bare-urls)


200-200: null
Bare URL used

(MD034, no-bare-urls)


202-202: null
Bare URL used

(MD034, no-bare-urls)


203-203: null
Bare URL used

(MD034, no-bare-urls)

CHANGELOG.md

571-571: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


576-576: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


577-577: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


578-578: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


579-579: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


580-580: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


581-581: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


582-582: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


583-583: Expected: 2; Actual: 3
Unordered list indentation

(MD007, ul-indent)


584-584: Expected: 2; Actual: 3
Unordered list indentation

(MD007, ul-indent)


585-585: Expected: 2; Actual: 3
Unordered list indentation

(MD007, ul-indent)


586-586: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


587-587: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


588-588: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


589-589: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


590-590: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


591-591: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


592-592: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


593-593: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


594-594: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


595-595: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


596-596: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


597-597: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


598-598: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


599-599: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


602-602: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


603-603: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


604-604: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


605-605: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


606-606: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


607-607: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


608-608: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


609-609: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


610-610: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


611-611: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


612-612: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


613-613: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


614-614: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


615-615: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


616-616: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


617-617: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


618-618: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


619-619: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


620-620: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


621-621: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


622-622: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


623-623: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


624-624: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


625-625: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


626-626: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


627-627: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


628-628: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


629-629: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


630-630: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


631-631: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


632-632: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


633-633: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


634-634: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


635-635: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


636-636: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


637-637: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


638-638: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


639-639: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


640-640: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


641-641: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


642-642: Expected: 2; Actual: 3
Unordered list indentation

(MD007, ul-indent)


645-645: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


646-646: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


647-647: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


648-648: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


649-649: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


650-650: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


651-651: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


652-652: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


653-653: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


654-654: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


655-655: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


656-656: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


657-657: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


658-658: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


659-659: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


660-660: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


661-661: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


662-662: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


663-663: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


666-666: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


667-667: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


668-668: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


669-669: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


670-670: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


671-671: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


672-672: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


673-673: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


674-674: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


675-675: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


676-676: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


677-677: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


678-678: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


679-679: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


680-680: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


681-681: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


682-682: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


683-683: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


684-684: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


685-685: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


686-686: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


687-687: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


688-688: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


689-689: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


690-690: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


691-691: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


692-692: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


693-693: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


694-694: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


695-695: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


696-696: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


697-697: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


698-698: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


699-699: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


700-700: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


701-701: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


702-702: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


703-703: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


704-704: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


705-705: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


706-706: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


707-707: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


708-708: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


709-709: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


710-710: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


711-711: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


712-712: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


713-713: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


714-714: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


715-715: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


716-716: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


717-717: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


718-718: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


724-724: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


725-725: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


731-731: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


732-732: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


735-735: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


738-738: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


739-739: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


740-740: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


741-741: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


742-742: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


743-743: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


744-744: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


745-745: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


746-746: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


747-747: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


748-748: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


749-749: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


750-750: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


756-756: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


757-757: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


758-758: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


759-759: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


760-760: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


761-761: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


762-762: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


763-763: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


764-764: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


765-765: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


766-766: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


767-767: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


768-768: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


769-769: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


772-772: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


773-773: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


774-774: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


775-775: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


776-776: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


777-777: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


778-778: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


779-779: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


780-780: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


781-781: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


782-782: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


783-783: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


784-784: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


785-785: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


788-788: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


789-789: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


790-790: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


791-791: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


792-792: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


793-793: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


794-794: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


795-795: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


796-796: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


799-799: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


800-800: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


801-801: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


802-802: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


803-803: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


804-804: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


805-805: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


806-806: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


807-807: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


808-808: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


809-809: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


810-810: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


811-811: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


812-812: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


813-813: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


814-814: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


815-815: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


821-821: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


826-826: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


827-827: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


828-828: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


829-829: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


830-830: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


831-831: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


832-832: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


833-833: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


834-834: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


837-837: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


838-838: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


839-839: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


840-840: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


841-841: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


842-842: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


843-843: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


844-844: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


845-845: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


846-846: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


847-847: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


850-850: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


851-851: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


852-852: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


853-853: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


854-854: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


855-855: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


856-856: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


859-859: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


860-860: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


861-861: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


862-862: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


863-863: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


864-864: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


865-865: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


866-866: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


867-867: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


868-868: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


869-869: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


870-870: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


871-871: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


872-872: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


873-873: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


874-874: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


875-875: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


876-876: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


877-877: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


883-883: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


884-884: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


889-889: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


892-892: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


893-893: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


894-894: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


895-895: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


896-896: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


897-897: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


898-898: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


903-903: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


904-904: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


905-905: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


906-906: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


907-907: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


908-908: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


909-909: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


910-910: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


911-911: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


912-912: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


913-913: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


916-916: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


917-917: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


918-918: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


919-919: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


920-920: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


921-921: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


922-922: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


923-923: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


924-924: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


925-925: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


926-926: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


927-927: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


928-928: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


929-929: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


930-930: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


931-931: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


932-932: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


933-933: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


936-936: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


937-937: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


938-938: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


939-939: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


940-940: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


941-941: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


942-942: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


943-943: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


944-944: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


947-947: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


948-948: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


949-949: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


950-950: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


951-951: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


952-952: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


953-953: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


954-954: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


955-955: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


956-956: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


957-957: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


963-963: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


966-966: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


967-967: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


968-968: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


969-969: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


970-970: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


971-971: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


976-976: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


977-977: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


978-978: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


979-979: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


980-980: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


981-981: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


982-982: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


983-983: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


984-984: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


985-985: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


988-988: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


989-989: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


990-990: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


991-991: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


992-992: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


993-993: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


994-994: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


995-995: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


996-996: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


997-997: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


998-998: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1001-1001: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1002-1002: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1005-1005: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1006-1006: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1007-1007: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1008-1008: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1009-1009: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1010-1010: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1011-1011: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1012-1012: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1013-1013: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1014-1014: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1015-1015: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1020-1020: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1024-1024: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1025-1025: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1026-1026: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1027-1027: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1028-1028: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1029-1029: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1030-1030: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1031-1031: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1032-1032: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1033-1033: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


3-3: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


17-17: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


32-32: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


36-36: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


47-47: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


84-84: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


114-114: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


119-119: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


124-124: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


129-129: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


133-133: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


138-138: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


145-145: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


155-155: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


162-162: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


182-182: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


192-192: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


197-197: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


240-240: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


246-246: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


276-276: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


292-292: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


319-319: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


337-337: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


342-342: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


382-382: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


407-407: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


421-421: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


450-450: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


473-473: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


521-521: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


570-570: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


575-575: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


601-601: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


644-644: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


665-665: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


723-723: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


730-730: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


734-734: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


737-737: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


755-755: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


771-771: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


787-787: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


798-798: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


820-820: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


825-825: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


836-836: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


849-849: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


858-858: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


882-882: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


888-888: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


891-891: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


902-902: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


915-915: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


935-935: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


946-946: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


962-962: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


965-965: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


975-975: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


987-987: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


1000-1000: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


1004-1004: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


1019-1019: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


1023-1023: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


283-283: Expected: underscore; Actual: asterisk
Strong style

(MD050, strong-style)


283-283: Expected: underscore; Actual: asterisk
Strong style

(MD050, strong-style)


1042-1042: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1043-1043: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1044-1044: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1045-1045: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1046-1046: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1047-1047: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1048-1048: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1049-1049: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1050-1050: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1051-1051: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1052-1052: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1053-1053: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1056-1056: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1057-1057: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1055-1055: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


1073-1073: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1074-1074: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1075-1075: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1076-1076: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)

Additional comments not posted (113)
configs/v1-inference.yaml (1)

43-43: Review the implications of disabling checkpointing.

The use_checkpoint parameter has been set to False. This change can reduce memory overhead during inference but might affect the ability to recover from certain states or utilize optimization strategies that rely on checkpoints. Ensure that this change aligns with the overall performance and resource management goals.

configs/alt-diffusion-inference.yaml (1)

43-43: Review the implications of disabling checkpointing.

The use_checkpoint parameter has been set to False. This change can reduce memory overhead during inference but might affect the ability to recover from certain states or utilize optimization strategies that rely on checkpoints. Ensure that this change aligns with the overall performance and resource management goals.

configs/v1-inpainting-inference.yaml (1)

43-43: Review the implications of disabling checkpointing.

The use_checkpoint parameter has been set to False. This change can reduce memory overhead during inference but might affect the ability to recover from certain states or utilize optimization strategies that rely on checkpoints. Ensure that this change aligns with the overall performance and resource management goals.

configs/instruct-pix2pix.yaml (1)

48-48: Verify the impact of disabling checkpointing.

Disabling checkpointing may affect the model's ability to save intermediate states. Ensure this change is intentional and does not impact training efficiency.

Verification successful

Verify the impact of disabling checkpointing.

Disabling checkpointing is a consistent change across multiple configuration files and is mentioned in the changelog as a performance improvement. This change appears intentional and aligns with the intended behavior for inference.

  • CHANGELOG.md: Mentions performance improvement with use_checkpoint = False
  • modules/sub_quadratic_attention.py: Indicates checkpointing is recommended for training, not inference
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the impact of disabling checkpointing.

# Test: Search for the usage of `use_checkpoint` in the codebase. Expect: Ensure that the change does not impact critical functionality.
rg --type yaml -A 5 $'use_checkpoint:'

Length of output: 2119


Script:

#!/bin/bash
# Description: Search for the usage of `use_checkpoint` in the codebase to understand its impact.

# Test: Search for the term `use_checkpoint` in all files to see how it is used and if there are any comments or documentation about it.
rg 'use_checkpoint'

Length of output: 1933

extensions-builtin/Lora/extra_networks_lora.py (2)

17-17: Clear errors at the start of the method.

Clearing errors at the start of the method is a good practice to ensure a fresh state.


59-62: Ensure errors are properly reported and cleared.

The method correctly reports and clears errors. Ensure this behavior is consistent with the rest of the application.

modules/deepbooru.py (2)

60-60: Ensure proper data typing for tensor creation.

The addition of devices.dtype in the tensor creation ensures that the tensor is explicitly cast to a specific data type, which can improve compatibility and performance.


81-81: Improved efficiency with set comprehension.

Using a set comprehension directly for filtertags enhances readability and performance by avoiding the intermediate list creation.

configs/sd_xl_inpaint.yaml (5)

1-5: Model configuration looks good.

The model section correctly specifies the target and parameters for the diffusion engine.


7-17: Denoiser configuration looks good.

The denoiser_config section correctly specifies the target and parameters for the denoiser.


19-37: Network configuration looks good.

The network_config section correctly specifies the target and parameters for the UNet model.


39-78: Conditioner configuration looks good.

The conditioner_config section correctly specifies the target and parameters for the general conditioner.


80-98: First stage configuration looks good.

The first_stage_config section correctly specifies the target and parameters for the autoencoder.

extensions-builtin/Lora/ui_extra_networks_lora.py (5)

16-16: Generalized network handling in refresh method.

The refresh method now calls networks.list_available_networks(), indicating a shift from handling Lora-specific networks to a more generalized approach.


18-76: Item creation logic looks good.

The create_item method correctly constructs an item representation for a network with comprehensive metadata, including user metadata, activation text, preferred weight, and negative prompts.


79-84: Improved iteration in list_items method.

The list_items method now instantiates a list of names to prevent concurrent modification issues during iteration and correctly creates items through the create_item method.


87-87: Expanded directories for previews.

The allowed_directories_for_previews method now returns an additional directory path (shared.cmd_opts.lyco_dir_backcompat), correctly expanding the directories from which previews can be generated.


89-90: Enhanced user interaction with metadata.

The create_user_metadata_editor method correctly enhances user interaction with metadata by initializing a LoraUserMetadataEditor.

extensions-builtin/Lora/network_lora.py (5)

25-33: LGTM!

The __init__ method correctly initializes the class and creates the necessary modules.


34-69: LGTM!

The create_module method correctly handles the creation of different types of layers and ensures weights are properly reshaped and assigned.


71-86: LGTM!

The calc_updown method correctly calculates the up and down weights and handles the mid-model if present.


88-92: LGTM!

The forward method correctly moves the models to the device and performs the forward pass.


9-21: LGTM! But verify the class usage in the codebase.

The class definition and method implementation look good.

However, ensure that the ModuleTypeLora class is correctly integrated and used in the codebase.

Verification successful

The ModuleTypeLora class is correctly integrated and used in the codebase.

  • extensions-builtin/Lora/networks.py: The class is included in a list of module types.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of `ModuleTypeLora` class in the codebase.

# Test: Search for the class usage. Expect: Occurrences of `ModuleTypeLora`.
rg --type python -A 5 $'ModuleTypeLora'

Length of output: 69


Script:

#!/bin/bash
# Description: Verify the usage of `ModuleTypeLora` class in the codebase.

# Test: Search for the class usage. Expect: Occurrences of `ModuleTypeLora`.
rg --type py -A 5 $'ModuleTypeLora'

Length of output: 1046

extensions-builtin/Lora/scripts/lora_script.py (7)

15-16: LGTM!

The unload function correctly calls the undo method on networks.originals.


18-24: LGTM!

The before_ui function correctly registers the Lora page and extra network with aliases.


53-59: LGTM!

The create_lora_json function correctly creates a JSON representation of the object.


62-69: LGTM!

The api_networks function correctly defines the API endpoints and their respective handlers.


77-97: LGTM!

The infotext_pasted function correctly processes the infotext and replaces Lora hashes with network aliases.


29-29: LGTM!

The on_model_loaded callback correctly assigns network names to modules.


72-72: LGTM!

The on_app_started callback correctly registers the api_networks function.

.github/ISSUE_TEMPLATE/bug_report.yml (8)

2-2: LGTM!

The updated description is clear and concise.


7-12: LGTM!

The instructions for the bug report title are clear and provide useful guidance.


15-31: LGTM!

The updated checklist provides comprehensive steps for basic debugging and ensures that users perform necessary checks before submitting a bug report.


35-42: LGTM!

The placeholder for the What happened? section is clear and provides useful guidance.


49-52: LGTM!

The placeholder for the Steps to reproduce the problem section is clear and provides useful guidance.


60-62: LGTM!

The placeholder for the What should have happened? section is clear and provides useful guidance.


80-87: LGTM!

The instructions for the Sysinfo section are clear and ensure that users include essential system context in their bug reports.


94-105: LGTM!

The instructions for the Console logs section and the placeholder for the Additional information section are clear and provide useful guidance.

modules/call_queue.py (3)

50-62: LGTM! The state management improvements are crucial.

The changes ensure that the state is consistently reset after the function call.


Line range hint 22-48:
LGTM! But verify the function usage in the codebase.

The code changes are approved.

However, ensure that all function calls to wrap_gradio_gpu_call are correctly implemented.

Verification successful

Function usage verified.

The wrap_gradio_gpu_call function is correctly implemented and used across multiple modules:

  • modules/ui_postprocessing.py
  • modules/ui.py
  • modules/ui_checkpoint_merger.py
  • modules/ui_extensions.py
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `wrap_gradio_gpu_call` are correctly implemented.

# Test: Search for the function usage. Expect: Correct implementation of function calls.
rg --type python -A 5 $'wrap_gradio_gpu_call'

Length of output: 75


Script:

#!/bin/bash
# Description: Verify all function calls to `wrap_gradio_gpu_call` are correctly implemented.

# Test: Search for the function usage. Expect: Correct implementation of function calls.
rg --type py -A 5 $'wrap_gradio_gpu_call'

Length of output: 4782


Line range hint 65-159:
LGTM! The enhancements improve error handling and profiling.

The changes improve error reporting, memory monitoring, and profiling capabilities.

However, ensure that all function calls to wrap_gradio_call_no_job are correctly implemented.

javascript/dragdrop.js (5)

3-5: LGTM! The function correctly validates the image file list.

The function checks if the file list contains exactly one image of the specified types.


Line range hint 7-49:
LGTM! The function handles image replacement robustly.

The changes ensure that the callback is executed correctly after the fetch completes, improving the robustness of the function.


51-57: LGTM! The function encapsulates file presence checks.

The function improves code clarity by encapsulating the logic for file presence checks.


59-64: LGTM! The function correctly validates URLs.

The function uses a try-catch block to validate URLs, ensuring that only valid URLs are accepted.


68-72: LGTM! The function correctly identifies prompt targets.

The function checks the target's placeholder and class name to determine if it is a prompt.

javascript/contextMenus.js (6)

2-114: LGTM! The function restructuring enhances readability and maintainability.

The changes improve scoping clarity and maintainability.


116-120: LGTM! The variable assignments improve scoping clarity.

The changes ensure better scoping clarity by using var.


123-136: LGTM! The function restructuring promotes code reuse and clarity.

The changes ensure better code reuse and clarity.


138-140: LGTM! The function restructuring promotes code reuse and clarity.

The changes ensure better code reuse and clarity.


142-144: LGTM! The function restructuring promotes code reuse and clarity.

The changes ensure better code reuse and clarity.


151-153: LGTM! The function restructuring promotes code reuse and clarity.

The changes ensure better code reuse and clarity.

javascript/progressbar.js (11)

3-4: Empty function detected.

The rememberGallerySelection function is currently empty. Verify if this is intentional or if the implementation is missing.


7-8: Empty function detected.

The getGallerySelectedIndex function is currently empty. Verify if this is intentional or if the implementation is missing.


34-35: LGTM!

The pad2 function is simple and correct.


38-44: LGTM!

The formatTime function is well-structured and correctly handles different time ranges.


55-63: LGTM!

The setTitle function correctly updates the document title based on the provided progress.


68-69: LGTM!

The randomId function is simple and correct.


81-88: LGTM!

The requestWakeLock function is well-structured and correctly handles wake lock requests.


90-98: LGTM!

The releaseWakeLock function is well-structured and correctly handles wake lock release.


111-121: LGTM!

The removeProgressBar function correctly handles the cleanup of progress bar elements and wake lock release.


123-212: LGTM!

The funProgress and funLivePreview functions are well-structured and correctly handle progress updates and live previews.


75-212: LGTM! But verify the function usage in the codebase.

The code changes are approved.

However, ensure that all function calls to requestProgress match the new signature.

extensions-builtin/hypertile/scripts/hypertile_script.py (8)

8-9: LGTM!

The title method is simple and correct.


11-12: LGTM!

The show method is simple and correct.


14-19: LGTM!

The process method is well-structured and correctly handles the hypertile configuration and infotext addition.


21-34: LGTM!

The before_hr method is well-structured and correctly handles the hypertile configuration for the second pass.


36-54: LGTM!

The add_infotext method is well-structured and correctly handles the addition of hypertile configuration details.


57-77: LGTM!

The configure_hypertile function is well-structured and correctly handles the hypertile model configuration.


80-104: LGTM!

The on_ui_settings function is well-structured and correctly handles the addition of hypertile options to the UI settings.


106-118: LGTM!

The add_axis_options function is well-structured and correctly handles the addition of hypertile options to the axis options.

extensions-builtin/Lora/network.py (3)

61-69: LGTM!

The detect_version method is well-structured and correctly handles version detection.


71-77: LGTM!

The set_hash method is well-structured and correctly handles hash setting.


79-82: LGTM!

The read_hash method is well-structured and correctly handles hash reading.

modules/devices.py (7)

Line range hint 43-48:
Verify command-line options parsing.

Ensure that the command-line options are correctly parsed to avoid incorrect device string retrieval.

Verification successful

Command-line options parsing verified successfully.

The usage of shared.cmd_opts.device_id across multiple files (modules/xpu_specific.py, modules/npu_specific.py, and modules/devices.py) confirms that the command-line options are correctly parsed and used for retrieving device strings.

  • modules/xpu_specific.py
  • modules/npu_specific.py
  • modules/devices.py
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify command-line options parsing.

# Test: Search for the usage of `shared.cmd_opts.device_id`.
rg --type python -A 5 $'shared.cmd_opts.device_id'

Length of output: 80


Script:

#!/bin/bash
# Description: Verify command-line options parsing.

# Test: Search for the usage of `shared.cmd_opts.device_id`.
rg --type py -A 5 'shared.cmd_opts.device_id'

Length of output: 1390


187-207: Verify the accuracy of dtype casting application and reversion.

Ensure that the dtype casting is applied and reverted accurately to avoid precision loss or incorrect results.

Verification successful

Verify the accuracy of dtype casting application and reversion.

The dtype casting is applied and reverted accurately within the manual_cast function. The original forward method is restored in the finally block, ensuring no precision loss or incorrect results.

  • modules/devices.py: The manual_cast function is used to apply and revert dtype casting correctly.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the accuracy of dtype casting application and reversion.

# Test: Search for the usage of `manual_cast`.
rg --type python -A 5 $'manual_cast'

Length of output: 66


Script:

#!/bin/bash
# Description: Verify the accuracy of dtype casting application and reversion.

# Test: Search for the usage of `manual_cast`.
rg --type py -A 5 $'manual_cast'

Length of output: 1609


26-32: Verify the accuracy of device ID retrieval and capability check.

Ensure that the device ID retrieval and capability check are accurate to avoid incorrect autocasting behavior.

Verification successful

Verification successful.

The device ID retrieval and capability check in the cuda_no_autocast function are accurate.

  • The get_cuda_device_id function correctly retrieves the device ID.
  • The torch.cuda.get_device_capability function is used appropriately to check the device's capabilities.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the accuracy of device ID retrieval and capability check.

# Test: Search for the usage of `get_cuda_device_id` and `torch.cuda.get_device_capability`.
rg --type python -A 5 $'get_cuda_device_id' | grep -B 5 'torch.cuda.get_device_capability'

Length of output: 118


Script:

#!/bin/bash
# Description: Verify the accuracy of device ID retrieval and capability check.

# Test: Search for the usage of `get_cuda_device_id` and `torch.cuda.get_device_capability`.
rg --glob '*.py' -A 5 'get_cuda_device_id' | grep -B 5 'torch.cuda.get_device_capability'

Length of output: 260


Script:

#!/bin/bash
# Description: Locate the implementation of `get_cuda_device_id` and verify its correctness.

# Search for the implementation of `get_cuda_device_id`.
rg 'def get_cuda_device_id' -A 5 --glob '*.py'

Length of output: 381


284-295: Verify the accuracy of casting prevention.

Ensure that the casting prevention is performed accurately to avoid precision loss or incorrect results.

Verification successful

Verify the accuracy of casting prevention.

Ensure that the casting prevention is performed accurately to avoid precision loss or incorrect results.


Verify the accuracy of casting prevention.

Ensure that the casting prevention is performed accurately to avoid precision loss or incorrect results.


Casting prevention is correctly implemented.

The force_model_fp16 function is invoked correctly when cmd_opts.precision is set to "half", ensuring that the casting prevention is performed accurately.

  • modules/shared_init.py: Lines around the usage of force_model_fp16 confirm the correct implementation.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the accuracy of casting prevention.

# Test: Search for the usage of `force_model_fp16`.
rg --type python -A 5 $'force_model_fp16'

Length of output: 71


Script:

#!/bin/bash
# Description: Verify the accuracy of casting prevention.

# Test: Search for the usage of `force_model_fp16`.
rg -t py -A 5 $'force_model_fp16'

Length of output: 693


Script:

#!/bin/bash
# Description: Retrieve more context around the usage of `force_model_fp16` in `modules/shared_init.py`.

# Test: Search for the usage of `force_model_fp16` in `modules/shared_init.py` with more context lines.
rg -A 10 -B 10 'force_model_fp16' modules/shared_init.py

Length of output: 982


152-184: Verify the accuracy of dtype casting and restoration of original dtype.

Ensure that the dtype casting is performed accurately and that the original dtype is restored after inference to avoid precision loss or incorrect results.

Verification successful

The dtype casting and restoration of the original dtype are handled correctly in the manual_cast_forward function.

  • The manual_cast_forward function is applied to the forward method of module_type.
  • The original forward method is stored in module_type.org_forward.
  • The original dtype is restored after inference in the finally block.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the accuracy of dtype casting and restoration of original dtype.

# Test: Search for the usage of `manual_cast_forward`.
rg --type python -A 5 $'manual_cast_forward'

Length of output: 74


Script:

#!/bin/bash
# Description: Verify the accuracy of dtype casting and restoration of original dtype.

# Test: Search for the usage of `manual_cast_forward`.
rg --type py -A 5 $'manual_cast_forward'

Length of output: 780


Script:

#!/bin/bash
# Description: Verify the accuracy of dtype casting and restoration of original dtype.

# Test: Search for the definition and usage of `module_type`.
rg --type py -A 10 $'module_type'

Length of output: 3642


268-281: Verify the accuracy of memory allocation and layer initialization.

Ensure that the memory allocation and layer initialization are performed accurately to avoid unexpected latency or memory issues.

Verification successful

Verification successful: Memory allocation and layer initialization are performed accurately.

  • The first_time_calculation function is correctly invoked during the initialization process in modules/initialize.py.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the accuracy of memory allocation and layer initialization.

# Test: Search for the usage of `first_time_calculation`.
rg --type python -A 5 $'first_time_calculation'

Length of output: 77


Script:

#!/bin/bash
# Description: Verify the accuracy of memory allocation and layer initialization.

# Find all Python files and search for the usage of `first_time_calculation`.
fd -e py -x rg 'first_time_calculation' {}

Length of output: 116


Script:

#!/bin/bash
# Description: Verify the accuracy of memory allocation and layer initialization.

# Find all Python files and search for the usage of `first_time_calculation`.
fd -e py | xargs rg 'first_time_calculation'

Length of output: 157


Script:

#!/bin/bash
# Description: Verify the accuracy of memory allocation and layer initialization.

# Extract relevant lines from modules/initialize.py where first_time_calculation is used.
rg -A 10 'first_time_calculation' modules/initialize.py

Length of output: 453


35-40: Verify command-line options parsing and torch.cuda.current_device() return value.

Ensure that the command-line options are correctly parsed and that torch.cuda.current_device() returns the expected value.

extensions-builtin/Lora/ui_edit_user_metadata.py (6)

117-136: Verify the accuracy of metadata retrieval and component population.

Ensure that the metadata retrieval and component population are accurate to avoid incorrect display of metadata in UI components.


11-14: Verify the input type and average length calculation.

Ensure that the input tags is a dictionary and that the average length calculation is accurate to avoid incorrect results.

Verification successful

The input type and average length calculation are correct.

The function is_non_comma_tagset correctly expects a dictionary as input and accurately calculates the average length of the keys. The usage context confirms this.

  • File: extensions-builtin/Lora/ui_edit_user_metadata.py
  • Lines: 11-14
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the input type and average length calculation.

# Test: Search for the usage of `is_non_comma_tagset`.
rg --type python -A 5 $'is_non_comma_tagset'

Length of output: 74


Script:

#!/bin/bash
# Description: Verify the input type and average length calculation for the function `is_non_comma_tagset`.

# Search for the function definition and its usage in the codebase.
rg 'def is_non_comma_tagset' -A 10
rg 'is_non_comma_tagset' -A 5

Length of output: 1789


70-115: Verify the accuracy of metadata retrieval and table construction.

Ensure that the metadata retrieval and table construction are accurate to avoid incorrect display of metadata.

Verification successful

The metadata retrieval and table construction logic in the get_metadata_table function appears to be accurate.

The function correctly retrieves metadata, formats it, and constructs an HTML table for display. The usage of this function in the put_values_into_components method further confirms its correctness.

  • modules/ui_extra_networks_user_metadata.py: get_metadata_table is used to generate metadata parameters which are then used to construct an HTML table.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the accuracy of metadata retrieval and table construction.

# Test: Search for the usage of `get_metadata_table`.
rg --type python -A 5 $'get_metadata_table'

Length of output: 73


Script:

#!/bin/bash
# Description: Verify the accuracy of metadata retrieval and table construction.

# Test: Search for the usage of `get_metadata_table`.
rg --type py -A 5 $'get_metadata_table'

Length of output: 1693


Script:

#!/bin/bash
# Description: Verify the accuracy of metadata retrieval and table construction.

# Test: Search for all occurrences of `get_metadata_table` in `modules/ui_extra_networks_user_metadata.py`.
rg 'get_metadata_table' modules/ui_extra_networks_user_metadata.py

Length of output: 158


Script:

#!/bin/bash
# Description: Verify the accuracy of metadata retrieval and table construction.

# Test: Search for the surrounding lines of code where `get_metadata_table` is called in `modules/ui_extra_networks_user_metadata.py`.
rg -A 10 -B 10 'get_metadata_table' modules/ui_extra_networks_user_metadata.py

Length of output: 1669


21-45: Verify the accuracy of metadata parsing and tag frequency calculation.

Ensure that the metadata parsing and tag frequency calculation are accurate to avoid incorrect tag construction.


138-144: Verify the accuracy of metadata retrieval and prompt generation.

Ensure that the metadata retrieval and prompt generation are accurate to avoid incorrect prompt generation.

Verification successful

Verify the accuracy of metadata retrieval and prompt generation.

The metadata retrieval and prompt generation processes appear to be correctly implemented. The build_tags function extracts tag frequencies from the metadata, and the generate_random_prompt_from_tags function uses these tags to generate a random prompt.

  • build_tags(metadata): Extracts tag frequencies from the metadata.
  • generate_random_prompt_from_tags(tags): Generates a random prompt based on the tags.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the accuracy of metadata retrieval and prompt generation.

# Test: Search for the usage of `generate_random_prompt`.
rg --type python -A 5 $'generate_random_prompt'

Length of output: 77


Script:

#!/bin/bash
# Description: Verify the accuracy of metadata retrieval and prompt generation.

# Test: Search for the usage of `generate_random_prompt`.
rg --type py -A 5 $'generate_random_prompt'

Length of output: 2329


Script:

#!/bin/bash
# Description: Verify the accuracy of metadata retrieval and prompt generation by reviewing related functions.

# Search for the definition of the `build_tags` function.
rg --type py -A 5 $'def build_tags'

# Search for the definition of the `generate_random_prompt_from_tags` function.
rg --type py -A 10 $'def generate_random_prompt_from_tags'

Length of output: 1525


145-158: Verify the accuracy of tag processing and prompt generation.

Ensure that the tag processing and prompt generation are accurate to avoid incorrect prompt generation.

javascript/imageviewer.js (1)

8-27: Verify the accuracy of modal element updates and display.

Ensure that the modal elements are correctly updated and displayed to avoid incorrect modal behavior.

README.md (4)

2-2: Approved: Improved clarity in the description.

The updated description provides a clearer understanding of the technology used.

Tools
LanguageTool

[uncategorized] ~2-~2: You might be missing the article “the” here.
Context: ...for Stable Diffusion, implemented using Gradio library.

F...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


81-81: Approved: Enhanced user experience.

The addition of a separate UI for choosing embeddings, hypernetworks, or Loras with preview improves the user experience.


94-94: Approved: Added support for Segmind Stable Diffusion.

This change enhances functionality and compatibility with different models.


97-101: Approved: Improved installation instructions.

The reorganization of installation instructions aids users in quickly locating relevant information based on their hardware.

javascript/ui.js (2)

22-22: Approved: Simplified code using find method.

The refactored function improves readability and simplifies the code.


116-128: Approved: Prevents unnecessary delays.

The function ensures that the image gallery is not sent, preventing unnecessary delays.

modules/cmd_args.py (5)

14-14: Approved: Corrected help text.

The corrected help text improves user understanding.


22-28: Approved: Enhanced robustness with normalized_filepath.

The change ensures that file paths are validated and normalized, enhancing robustness.


45-45: Approved: Enhanced precision options.

The inclusion of "half" as a choice for the --precision argument reflects an enhancement in the precision options available for model evaluation.


82-82: Approved: Clarified help text.

The updated help text improves user understanding by clarifying the functionality.


88-88: Approved: Enhanced robustness with normalized_filepath.

The change ensures that the file path is validated and normalized, enhancing robustness.

modules/api/api.py (8)

567-575: LGTM!

The code changes are approved.


Line range hint 577-586:
LGTM!

The code changes are approved.


771-774: LGTM!

The code changes are approved.


776-778: LGTM!

The code changes are approved.


779-781: LGTM!

The code changes are approved.


917-919: LGTM!

The code changes are approved.


920-923: LGTM!

The code changes are approved.


925-928: LGTM!

The code changes are approved.

extensions-builtin/LDSR/sd_hijack_ddpm_v1.py (6)

51-51: Correct default value for ignore_keys parameter.

Using None as the default value for ignore_keys is appropriate for optional parameters.


103-103: Ensure ignore_keys is correctly handled.

The ignore_keys parameter is conditionally replaced with an empty list. This ensures that the method can handle cases where no keys are provided.


185-191: Handle ignore_keys parameter correctly in init_from_ckpt.

The iteration over ignore_keys is modified to handle the case where it might be None, preventing potential runtime errors.


447-447: Correct default value for ignore_keys parameter.

Using None as the default value for ignore_keys is appropriate for optional parameters.


1424-1424: Ensure correct parameter passing in log_images.

The log_images method correctly passes parameters to the superclass method.


1440-1443: Simplify setting attributes directly.

Using direct attribute setting instead of setattr simplifies the code and improves readability.

Comment on lines +11 to 32
function request(url, data, handler, errorHandler) {
var xhr = new XMLHttpRequest();
var url = url;
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
var js = JSON.parse(xhr.responseText);
handler(js)
handler(js);
} catch (error) {
console.error(error);
errorHandler()
errorHandler();
}
} else{
errorHandler()
} else {
errorHandler();
}
}
};
var js = JSON.stringify(data);
xhr.send(js);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using the fetch API for better readability and maintainability.

The request function can be refactored to use the fetch API, which provides a more concise and promise-based approach to handling HTTP requests.

async function request(url, data, handler, errorHandler) {
    try {
        const response = await fetch(url, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(data),
        });
        if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
        const js = await response.json();
        handler(js);
    } catch (error) {
        console.error('Request failed:', error);
        errorHandler();
    }
}

Comment on lines +407 to +419
function switchWidthHeight(tabname) {
var width = gradioApp().querySelector("#" + tabname + "_width input[type=number]");
var height = gradioApp().querySelector("#" + tabname + "_height input[type=number]");
if (!width || !height) return [];

var tmp = width.value;
width.value = height.value;
height.value = tmp;

updateInput(width);
updateInput(height);
return [];
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add validation for input values.

Ensure that the input values are within acceptable ranges before swapping.

function switchWidthHeight(tabname) {
    var width = gradioApp().querySelector("#" + tabname + "_width input[type=number]");
    var height = gradioApp().querySelector("#" + tabname + "_height input[type=number]");
    if (!width || !height) return [];

    var tmp = width.value;
    width.value = height.value;
    height.value = tmp;

    updateInput(width);
    updateInput(height);
    return [];
}

Committable suggestion was skipped due to low confidence.

* Added pption to run torch profiler for image generation

### Bug Fixes:
* Fix for grids without comprehensive infotexts ([#15958](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15958))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a blank line after the 'Bug Fixes' section heading for consistency.

Ensure there is a blank line after the heading for clarity and consistency.

### Bug Fixes

Committable suggestion was skipped due to low confidence.

* Add process_before_every_sampling hook ([#15984](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15984))
* Return HTTP 400 instead of 404 on invalid sampler error ([#16140](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16140))

### Performance:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove trailing punctuation from the heading.

The heading should not have trailing punctuation.

### Performance:
### Performance
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Performance:
### Performance
Tools
Markdownlint

36-36: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)

* Check for nans in unet only once, after all steps have been completed
* Added pption to run torch profiler for image generation

### Bug Fixes:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove trailing punctuation from the heading.

The heading should not have trailing punctuation.

### Bug Fixes:
### Bug Fixes
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Bug Fixes:
### Bug Fixes
Tools
Markdownlint

47-47: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)

Comment on lines +36 to +47
def processing_uses_inpainting(p):
# TODO: Figure out a better way to determine if inpainting is being used by p
if getattr(p, "image_mask", None) is not None:
return True

if getattr(p, "mask", None) is not None:
return True

if getattr(p, "nmask", None) is not None:
return True

return False
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplify the processing_uses_inpainting function.

The function uses multiple getattr calls to check for the presence of attributes. This approach is correct but could be simplified using a loop over the attribute names.

-    if getattr(p, "image_mask", None) is not None:
-        return True
-    if getattr(p, "mask", None) is not None:
-        return True
-    if getattr(p, "nmask", None) is not None:
-        return True
+    for attr in ["image_mask", "mask", "nmask"]:
+        if getattr(p, attr, None) is not None:
+            return True
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def processing_uses_inpainting(p):
# TODO: Figure out a better way to determine if inpainting is being used by p
if getattr(p, "image_mask", None) is not None:
return True
if getattr(p, "mask", None) is not None:
return True
if getattr(p, "nmask", None) is not None:
return True
return False
def processing_uses_inpainting(p):
# TODO: Figure out a better way to determine if inpainting is being used by p
for attr in ["image_mask", "mask", "nmask"]:
if getattr(p, attr, None) is not None:
return True
return False

Comment on lines +50 to +105
def latent_blend(settings, a, b, t):
"""
Interpolates two latent image representations according to the parameter t,
where the interpolated vectors' magnitudes are also interpolated separately.
The "detail_preservation" factor biases the magnitude interpolation towards
the larger of the two magnitudes.
"""
import torch

# NOTE: We use inplace operations wherever possible.

if len(t.shape) == 3:
# [4][w][h] to [1][4][w][h]
t2 = t.unsqueeze(0)
# [4][w][h] to [1][1][w][h] - the [4] seem redundant.
t3 = t[0].unsqueeze(0).unsqueeze(0)
else:
t2 = t
t3 = t[:, 0][:, None]

one_minus_t2 = 1 - t2
one_minus_t3 = 1 - t3

# Linearly interpolate the image vectors.
a_scaled = a * one_minus_t2
b_scaled = b * t2
image_interp = a_scaled
image_interp.add_(b_scaled)
result_type = image_interp.dtype
del a_scaled, b_scaled, t2, one_minus_t2

# Calculate the magnitude of the interpolated vectors. (We will remove this magnitude.)
# 64-bit operations are used here to allow large exponents.
current_magnitude = torch.norm(image_interp, p=2, dim=1, keepdim=True).to(float64(image_interp)).add_(0.00001)

# Interpolate the powered magnitudes, then un-power them (bring them back to a power of 1).
a_magnitude = torch.norm(a, p=2, dim=1, keepdim=True).to(float64(a)).pow_(settings.inpaint_detail_preservation) * one_minus_t3
b_magnitude = torch.norm(b, p=2, dim=1, keepdim=True).to(float64(b)).pow_(settings.inpaint_detail_preservation) * t3
desired_magnitude = a_magnitude
desired_magnitude.add_(b_magnitude).pow_(1 / settings.inpaint_detail_preservation)
del a_magnitude, b_magnitude, t3, one_minus_t3

# Change the linearly interpolated image vectors' magnitudes to the value we want.
# This is the last 64-bit operation.
image_interp_scaling_factor = desired_magnitude
image_interp_scaling_factor.div_(current_magnitude)
image_interp_scaling_factor = image_interp_scaling_factor.to(result_type)
image_interp_scaled = image_interp
image_interp_scaled.mul_(image_interp_scaling_factor)
del current_magnitude
del desired_magnitude
del image_interp
del image_interp_scaling_factor
del result_type

return image_interp_scaled
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review tensor operations for potential optimizations and add detailed comments.

The function performs complex tensor operations for blending latent image representations. While the logic appears sound, there are several areas where performance could be improved, such as minimizing the use of inplace operations and ensuring tensor operations are efficiently combined. Additionally, adding comments to explain the rationale behind complex operations would greatly enhance maintainability.

-    # NOTE: We use inplace operations wherever possible.
+    # NOTE: We use inplace operations wherever possible to save memory.

Committable suggestion was skipped due to low confidence.

Comment on lines +108 to +124
def get_modified_nmask(settings, nmask, sigma):
"""
Converts a negative mask representing the transparency of the original latent vectors being overlaid
to a mask that is scaled according to the denoising strength for this step.

Where:
0 = fully opaque, infinite density, fully masked
1 = fully transparent, zero density, fully unmasked

We bring this transparency to a power, as this allows one to simulate N number of blending operations
where N can be any positive real value. Using this one can control the balance of influence between
the denoiser and the original latents according to the sigma value.

NOTE: "mask" is not used
"""
import torch
return torch.pow(nmask, (sigma ** settings.mask_blend_power) * settings.mask_blend_scale)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add input validation or documentation comments to get_modified_nmask.

The function uses a power operation to adjust the mask based on the settings. It's important to ensure that the sigma and mask_blend_power values are within expected ranges to avoid unexpected behavior. Adding input validation or comments to specify the expected range could improve code robustness.

-    return torch.pow(nmask, (sigma ** settings.mask_blend_power) * settings.mask_blend_scale)
+    # Ensure sigma and mask_blend_power are within expected ranges.
+    assert sigma > 0, "sigma must be positive"
+    assert settings.mask_blend_power > 0, "mask_blend_power must be positive"
+    return torch.pow(nmask, (sigma ** settings.mask_blend_power) * settings.mask_blend_scale)
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def get_modified_nmask(settings, nmask, sigma):
"""
Converts a negative mask representing the transparency of the original latent vectors being overlaid
to a mask that is scaled according to the denoising strength for this step.
Where:
0 = fully opaque, infinite density, fully masked
1 = fully transparent, zero density, fully unmasked
We bring this transparency to a power, as this allows one to simulate N number of blending operations
where N can be any positive real value. Using this one can control the balance of influence between
the denoiser and the original latents according to the sigma value.
NOTE: "mask" is not used
"""
import torch
return torch.pow(nmask, (sigma ** settings.mask_blend_power) * settings.mask_blend_scale)
def get_modified_nmask(settings, nmask, sigma):
"""
Converts a negative mask representing the transparency of the original latent vectors being overlaid
to a mask that is scaled according to the denoising strength for this step.
Where:
0 = fully opaque, infinite density, fully masked
1 = fully transparent, zero density, fully unmasked
We bring this transparency to a power, as this allows one to simulate N number of blending operations
where N can be any positive real value. Using this one can control the balance of influence between
the denoiser and the original latents according to the sigma value.
NOTE: "mask" is not used
"""
import torch
# Ensure sigma and mask_blend_power are within expected ranges.
assert sigma > 0, "sigma must be positive"
assert settings.mask_blend_power > 0, "mask_blend_power must be positive"
return torch.pow(nmask, (sigma ** settings.mask_blend_power) * settings.mask_blend_scale)

Comment on lines +205 to +244
def apply_masks(
settings,
nmask,
overlay_images,
width, height,
paste_to):
import torch
import modules.processing as proc
import modules.images as images
from PIL import Image, ImageOps, ImageFilter

converted_mask = nmask[0].float()
converted_mask = torch.clamp(converted_mask, min=0, max=1).pow_(settings.mask_blend_scale / 2)
converted_mask = 255. * converted_mask
converted_mask = converted_mask.cpu().numpy().astype(np.uint8)
converted_mask = Image.fromarray(converted_mask)
converted_mask = images.resize_image(2, converted_mask, width, height)
converted_mask = proc.create_binary_mask(converted_mask, round=False)

# Remove aliasing artifacts using a gaussian blur.
converted_mask = converted_mask.filter(ImageFilter.GaussianBlur(radius=4))

# Expand the mask to fit the whole image if needed.
if paste_to is not None:
converted_mask = proc.uncrop(converted_mask,
(width, height),
paste_to)

masks_for_overlay = []

for i, overlay_image in enumerate(overlay_images):
masks_for_overlay[i] = converted_mask

image_masked = Image.new('RGBa', (overlay_image.width, overlay_image.height))
image_masked.paste(overlay_image.convert("RGBA").convert("RGBa"),
mask=ImageOps.invert(converted_mask.convert('L')))

overlay_images[i] = image_masked.convert('RGBA')

return masks_for_overlay
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review image and tensor operations for potential optimizations.

The function performs complex image processing operations. While the structure is clear, there are opportunities to optimize the operations, especially in terms of reducing the number of operations performed on tensors and images. Ensuring that all image and tensor operations are batched where possible could improve performance.

-    converted_mask = nmask[0].float()
+    converted_mask = nmask[0].float().clone()
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def apply_masks(
settings,
nmask,
overlay_images,
width, height,
paste_to):
import torch
import modules.processing as proc
import modules.images as images
from PIL import Image, ImageOps, ImageFilter
converted_mask = nmask[0].float()
converted_mask = torch.clamp(converted_mask, min=0, max=1).pow_(settings.mask_blend_scale / 2)
converted_mask = 255. * converted_mask
converted_mask = converted_mask.cpu().numpy().astype(np.uint8)
converted_mask = Image.fromarray(converted_mask)
converted_mask = images.resize_image(2, converted_mask, width, height)
converted_mask = proc.create_binary_mask(converted_mask, round=False)
# Remove aliasing artifacts using a gaussian blur.
converted_mask = converted_mask.filter(ImageFilter.GaussianBlur(radius=4))
# Expand the mask to fit the whole image if needed.
if paste_to is not None:
converted_mask = proc.uncrop(converted_mask,
(width, height),
paste_to)
masks_for_overlay = []
for i, overlay_image in enumerate(overlay_images):
masks_for_overlay[i] = converted_mask
image_masked = Image.new('RGBa', (overlay_image.width, overlay_image.height))
image_masked.paste(overlay_image.convert("RGBA").convert("RGBa"),
mask=ImageOps.invert(converted_mask.convert('L')))
overlay_images[i] = image_masked.convert('RGBA')
return masks_for_overlay
def apply_masks(
settings,
nmask,
overlay_images,
width, height,
paste_to):
import torch
import modules.processing as proc
import modules.images as images
from PIL import Image, ImageOps, ImageFilter
converted_mask = nmask[0].float().clone()
converted_mask = torch.clamp(converted_mask, min=0, max=1).pow_(settings.mask_blend_scale / 2)
converted_mask = 255. * converted_mask
converted_mask = converted_mask.cpu().numpy().astype(np.uint8)
converted_mask = Image.fromarray(converted_mask)
converted_mask = images.resize_image(2, converted_mask, width, height)
converted_mask = proc.create_binary_mask(converted_mask, round=False)
# Remove aliasing artifacts using a gaussian blur.
converted_mask = converted_mask.filter(ImageFilter.GaussianBlur(radius=4))
# Expand the mask to fit the whole image if needed.
if paste_to is not None:
converted_mask = proc.uncrop(converted_mask,
(width, height),
paste_to)
masks_for_overlay = []
for i, overlay_image in enumerate(overlay_images):
masks_for_overlay[i] = converted_mask
image_masked = Image.new('RGBa', (overlay_image.width, overlay_image.height))
image_masked.paste(overlay_image.convert("RGBA").convert("RGBa"),
mask=ImageOps.invert(converted_mask.convert('L')))
overlay_images[i] = image_masked.convert('RGBA')
return masks_for_overlay

Comment on lines +127 to +202
def apply_adaptive_masks(
settings: SoftInpaintingSettings,
nmask,
latent_orig,
latent_processed,
overlay_images,
width, height,
paste_to):
import torch
import modules.processing as proc
import modules.images as images
from PIL import Image, ImageOps, ImageFilter

# TODO: Bias the blending according to the latent mask, add adjustable parameter for bias control.
if len(nmask.shape) == 3:
latent_mask = nmask[0].float()
else:
latent_mask = nmask[:, 0].float()
# convert the original mask into a form we use to scale distances for thresholding
mask_scalar = 1 - (torch.clamp(latent_mask, min=0, max=1) ** (settings.mask_blend_scale / 2))
mask_scalar = (0.5 * (1 - settings.composite_mask_influence)
+ mask_scalar * settings.composite_mask_influence)
mask_scalar = mask_scalar / (1.00001 - mask_scalar)
mask_scalar = mask_scalar.cpu().numpy()

latent_distance = torch.norm(latent_processed - latent_orig, p=2, dim=1)

kernel, kernel_center = get_gaussian_kernel(stddev_radius=1.5, max_radius=2)

masks_for_overlay = []

for i, (distance_map, overlay_image) in enumerate(zip(latent_distance, overlay_images)):
converted_mask = distance_map.float().cpu().numpy()
converted_mask = weighted_histogram_filter(converted_mask, kernel, kernel_center,
percentile_min=0.9, percentile_max=1, min_width=1)
converted_mask = weighted_histogram_filter(converted_mask, kernel, kernel_center,
percentile_min=0.25, percentile_max=0.75, min_width=1)

# The distance at which opacity of original decreases to 50%
if len(mask_scalar.shape) == 3:
if mask_scalar.shape[0] > i:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar[i]
else:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar[0]
else:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar

converted_mask = converted_mask / half_weighted_distance

converted_mask = 1 / (1 + converted_mask ** settings.composite_difference_contrast)
converted_mask = smootherstep(converted_mask)
converted_mask = 1 - converted_mask
converted_mask = 255. * converted_mask
converted_mask = converted_mask.astype(np.uint8)
converted_mask = Image.fromarray(converted_mask)
converted_mask = images.resize_image(2, converted_mask, width, height)
converted_mask = proc.create_binary_mask(converted_mask, round=False)

# Remove aliasing artifacts using a gaussian blur.
converted_mask = converted_mask.filter(ImageFilter.GaussianBlur(radius=4))

# Expand the mask to fit the whole image if needed.
if paste_to is not None:
converted_mask = proc.uncrop(converted_mask,
(overlay_image.width, overlay_image.height),
paste_to)

masks_for_overlay.append(converted_mask)

image_masked = Image.new('RGBa', (overlay_image.width, overlay_image.height))
image_masked.paste(overlay_image.convert("RGBA").convert("RGBa"),
mask=ImageOps.invert(converted_mask.convert('L')))

overlay_images[i] = image_masked.convert('RGBA')

return masks_for_overlay
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review image and tensor operations for potential optimizations.

The function performs complex image processing operations. While the structure is clear, there are opportunities to optimize the operations, especially in terms of reducing the number of operations performed on tensors and images. Ensuring that all image and tensor operations are batched where possible could improve performance.

-    latent_distance = torch.norm(latent_processed - latent_orig, p=2, dim=1)
+    latent_distance = torch.norm(latent_processed - latent_orig, p=2, dim=1, keepdim=True)
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def apply_adaptive_masks(
settings: SoftInpaintingSettings,
nmask,
latent_orig,
latent_processed,
overlay_images,
width, height,
paste_to):
import torch
import modules.processing as proc
import modules.images as images
from PIL import Image, ImageOps, ImageFilter
# TODO: Bias the blending according to the latent mask, add adjustable parameter for bias control.
if len(nmask.shape) == 3:
latent_mask = nmask[0].float()
else:
latent_mask = nmask[:, 0].float()
# convert the original mask into a form we use to scale distances for thresholding
mask_scalar = 1 - (torch.clamp(latent_mask, min=0, max=1) ** (settings.mask_blend_scale / 2))
mask_scalar = (0.5 * (1 - settings.composite_mask_influence)
+ mask_scalar * settings.composite_mask_influence)
mask_scalar = mask_scalar / (1.00001 - mask_scalar)
mask_scalar = mask_scalar.cpu().numpy()
latent_distance = torch.norm(latent_processed - latent_orig, p=2, dim=1)
kernel, kernel_center = get_gaussian_kernel(stddev_radius=1.5, max_radius=2)
masks_for_overlay = []
for i, (distance_map, overlay_image) in enumerate(zip(latent_distance, overlay_images)):
converted_mask = distance_map.float().cpu().numpy()
converted_mask = weighted_histogram_filter(converted_mask, kernel, kernel_center,
percentile_min=0.9, percentile_max=1, min_width=1)
converted_mask = weighted_histogram_filter(converted_mask, kernel, kernel_center,
percentile_min=0.25, percentile_max=0.75, min_width=1)
# The distance at which opacity of original decreases to 50%
if len(mask_scalar.shape) == 3:
if mask_scalar.shape[0] > i:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar[i]
else:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar[0]
else:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar
converted_mask = converted_mask / half_weighted_distance
converted_mask = 1 / (1 + converted_mask ** settings.composite_difference_contrast)
converted_mask = smootherstep(converted_mask)
converted_mask = 1 - converted_mask
converted_mask = 255. * converted_mask
converted_mask = converted_mask.astype(np.uint8)
converted_mask = Image.fromarray(converted_mask)
converted_mask = images.resize_image(2, converted_mask, width, height)
converted_mask = proc.create_binary_mask(converted_mask, round=False)
# Remove aliasing artifacts using a gaussian blur.
converted_mask = converted_mask.filter(ImageFilter.GaussianBlur(radius=4))
# Expand the mask to fit the whole image if needed.
if paste_to is not None:
converted_mask = proc.uncrop(converted_mask,
(overlay_image.width, overlay_image.height),
paste_to)
masks_for_overlay.append(converted_mask)
image_masked = Image.new('RGBa', (overlay_image.width, overlay_image.height))
image_masked.paste(overlay_image.convert("RGBA").convert("RGBa"),
mask=ImageOps.invert(converted_mask.convert('L')))
overlay_images[i] = image_masked.convert('RGBA')
return masks_for_overlay
def apply_adaptive_masks(
settings: SoftInpaintingSettings,
nmask,
latent_orig,
latent_processed,
overlay_images,
width, height,
paste_to):
import torch
import modules.processing as proc
import modules.images as images
from PIL import Image, ImageOps, ImageFilter
# TODO: Bias the blending according to the latent mask, add adjustable parameter for bias control.
if len(nmask.shape) == 3:
latent_mask = nmask[0].float()
else:
latent_mask = nmask[:, 0].float()
# convert the original mask into a form we use to scale distances for thresholding
mask_scalar = 1 - (torch.clamp(latent_mask, min=0, max=1) ** (settings.mask_blend_scale / 2))
mask_scalar = (0.5 * (1 - settings.composite_mask_influence)
+ mask_scalar * settings.composite_mask_influence)
mask_scalar = mask_scalar / (1.00001 - mask_scalar)
mask_scalar = mask_scalar.cpu().numpy()
latent_distance = torch.norm(latent_processed - latent_orig, p=2, dim=1, keepdim=True)
kernel, kernel_center = get_gaussian_kernel(stddev_radius=1.5, max_radius=2)
masks_for_overlay = []
for i, (distance_map, overlay_image) in enumerate(zip(latent_distance, overlay_images)):
converted_mask = distance_map.float().cpu().numpy()
converted_mask = weighted_histogram_filter(converted_mask, kernel, kernel_center,
percentile_min=0.9, percentile_max=1, min_width=1)
converted_mask = weighted_histogram_filter(converted_mask, kernel, kernel_center,
percentile_min=0.25, percentile_max=0.75, min_width=1)
# The distance at which opacity of original decreases to 50%
if len(mask_scalar.shape) == 3:
if mask_scalar.shape[0] > i:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar[i]
else:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar[0]
else:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar
converted_mask = converted_mask / half_weighted_distance
converted_mask = 1 / (1 + converted_mask ** settings.composite_difference_contrast)
converted_mask = smootherstep(converted_mask)
converted_mask = 1 - converted_mask
converted_mask = 255. * converted_mask
converted_mask = converted_mask.astype(np.uint8)
converted_mask = Image.fromarray(converted_mask)
converted_mask = images.resize_image(2, converted_mask, width, height)
converted_mask = proc.create_binary_mask(converted_mask, round=False)
# Remove aliasing artifacts using a gaussian blur.
converted_mask = converted_mask.filter(ImageFilter.GaussianBlur(radius=4))
# Expand the mask to fit the whole image if needed.
if paste_to is not None:
converted_mask = proc.uncrop(converted_mask,
(overlay_image.width, overlay_image.height),
paste_to)
masks_for_overlay.append(converted_mask)
image_masked = Image.new('RGBa', (overlay_image.width, overlay_image.height))
image_masked.paste(overlay_image.convert("RGBA").convert("RGBa"),
mask=ImageOps.invert(converted_mask.convert('L')))
overlay_images[i] = image_masked.convert('RGBA')
return masks_for_overlay

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between c19d044 and 82a973c.

Files selected for processing (1)
  • CHANGELOG.md (3 hunks)
Additional context used
Markdownlint
CHANGELOG.md

577-577: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


582-582: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


583-583: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


584-584: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


585-585: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


586-586: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


587-587: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


588-588: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


589-589: Expected: 2; Actual: 3
Unordered list indentation

(MD007, ul-indent)


590-590: Expected: 2; Actual: 3
Unordered list indentation

(MD007, ul-indent)


591-591: Expected: 2; Actual: 3
Unordered list indentation

(MD007, ul-indent)


592-592: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


593-593: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


594-594: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


595-595: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


596-596: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


597-597: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


598-598: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


599-599: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


600-600: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


601-601: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


602-602: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


603-603: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


604-604: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


605-605: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


608-608: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


609-609: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


610-610: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


611-611: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


612-612: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


613-613: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


614-614: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


615-615: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


616-616: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


617-617: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


618-618: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


619-619: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


620-620: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


621-621: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


622-622: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


623-623: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


624-624: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


625-625: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


626-626: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


627-627: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


628-628: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


629-629: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


630-630: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


631-631: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


632-632: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


633-633: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


634-634: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


635-635: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


636-636: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


637-637: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


638-638: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


639-639: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


640-640: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


641-641: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


642-642: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


643-643: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


644-644: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


645-645: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


646-646: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


647-647: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


648-648: Expected: 2; Actual: 3
Unordered list indentation

(MD007, ul-indent)


651-651: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


652-652: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


653-653: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


654-654: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


655-655: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


656-656: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


657-657: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


658-658: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


659-659: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


660-660: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


661-661: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


662-662: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


663-663: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


664-664: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


665-665: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


666-666: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


667-667: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


668-668: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


669-669: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


672-672: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


673-673: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


674-674: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


675-675: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


676-676: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


677-677: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


678-678: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


679-679: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


680-680: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


681-681: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


682-682: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


683-683: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


684-684: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


685-685: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


686-686: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


687-687: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


688-688: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


689-689: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


690-690: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


691-691: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


692-692: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


693-693: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


694-694: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


695-695: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


696-696: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


697-697: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


698-698: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


699-699: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


700-700: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


701-701: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


702-702: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


703-703: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


704-704: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


705-705: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


706-706: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


707-707: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


708-708: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


709-709: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


710-710: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


711-711: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


712-712: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


713-713: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


714-714: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


715-715: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


716-716: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


717-717: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


718-718: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


719-719: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


720-720: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


721-721: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


722-722: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


723-723: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


724-724: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


730-730: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


731-731: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


737-737: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


738-738: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


741-741: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


744-744: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


745-745: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


746-746: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


747-747: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


748-748: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


749-749: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


750-750: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


751-751: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


752-752: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


753-753: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


754-754: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


755-755: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


756-756: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


762-762: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


763-763: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


764-764: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


765-765: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


766-766: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


767-767: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


768-768: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


769-769: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


770-770: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


771-771: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


772-772: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


773-773: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


774-774: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


775-775: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


778-778: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


779-779: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


780-780: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


781-781: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


782-782: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


783-783: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


784-784: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


785-785: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


786-786: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


787-787: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


788-788: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


789-789: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


790-790: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


791-791: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


794-794: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


795-795: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


796-796: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


797-797: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


798-798: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


799-799: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


800-800: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


801-801: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


802-802: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


805-805: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


806-806: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


807-807: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


808-808: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


809-809: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


810-810: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


811-811: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


812-812: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


813-813: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


814-814: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


815-815: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


816-816: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


817-817: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


818-818: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


819-819: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


820-820: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


821-821: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


827-827: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


832-832: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


833-833: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


834-834: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


835-835: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


836-836: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


837-837: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


838-838: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


839-839: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


840-840: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


843-843: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


844-844: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


845-845: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


846-846: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


847-847: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


848-848: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


849-849: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


850-850: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


851-851: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


852-852: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


853-853: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


856-856: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


857-857: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


858-858: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


859-859: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


860-860: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


861-861: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


862-862: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


865-865: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


866-866: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


867-867: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


868-868: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


869-869: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


870-870: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


871-871: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


872-872: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


873-873: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


874-874: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


875-875: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


876-876: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


877-877: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


878-878: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


879-879: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


880-880: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


881-881: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


882-882: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


883-883: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


889-889: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


890-890: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


895-895: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


898-898: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


899-899: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


900-900: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


901-901: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


902-902: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


903-903: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


904-904: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


909-909: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


910-910: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


911-911: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


912-912: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


913-913: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


914-914: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


915-915: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


916-916: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


917-917: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


918-918: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


919-919: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


922-922: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


923-923: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


924-924: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


925-925: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


926-926: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


927-927: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


928-928: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


929-929: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


930-930: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


931-931: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


932-932: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


933-933: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


934-934: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


935-935: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


936-936: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


937-937: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


938-938: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


939-939: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


942-942: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


943-943: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


944-944: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


945-945: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


946-946: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


947-947: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


948-948: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


949-949: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


950-950: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


953-953: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


954-954: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


955-955: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


956-956: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


957-957: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


958-958: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


959-959: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


960-960: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


961-961: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


962-962: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


963-963: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


969-969: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


972-972: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


973-973: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


974-974: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


975-975: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


976-976: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


977-977: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


982-982: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


983-983: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


984-984: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


985-985: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


986-986: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


987-987: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


988-988: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


989-989: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


990-990: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


991-991: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


994-994: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


995-995: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


996-996: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


997-997: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


998-998: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


999-999: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1000-1000: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1001-1001: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1002-1002: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1003-1003: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1004-1004: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1007-1007: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1008-1008: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1011-1011: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1012-1012: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1013-1013: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1014-1014: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1015-1015: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1016-1016: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1017-1017: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1018-1018: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1019-1019: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1020-1020: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1021-1021: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1026-1026: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1030-1030: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1031-1031: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1032-1032: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1033-1033: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1034-1034: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1035-1035: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1036-1036: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1037-1037: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1038-1038: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1039-1039: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


3-3: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


9-9: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


23-23: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


38-38: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


42-42: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


53-53: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


90-90: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


120-120: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


125-125: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


130-130: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


135-135: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


139-139: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


144-144: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


151-151: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


161-161: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


168-168: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


188-188: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


198-198: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


203-203: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


246-246: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


252-252: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


282-282: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


298-298: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


325-325: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


343-343: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


348-348: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


388-388: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


413-413: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


427-427: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


456-456: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


479-479: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


527-527: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


576-576: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


581-581: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


607-607: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


650-650: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


671-671: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


729-729: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


736-736: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


740-740: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


743-743: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


761-761: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


777-777: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


793-793: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


804-804: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


826-826: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


831-831: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


842-842: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


855-855: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


864-864: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


888-888: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


894-894: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


897-897: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


908-908: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


921-921: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


941-941: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


952-952: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


968-968: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


971-971: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


981-981: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


993-993: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


1006-1006: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


1010-1010: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


1025-1025: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


1029-1029: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


289-289: Expected: underscore; Actual: asterisk
Strong style

(MD050, strong-style)


289-289: Expected: underscore; Actual: asterisk
Strong style

(MD050, strong-style)


1048-1048: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1049-1049: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1050-1050: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1051-1051: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1052-1052: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1053-1053: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1054-1054: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1055-1055: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1056-1056: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1057-1057: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1058-1058: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1059-1059: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1062-1062: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1063-1063: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1061-1061: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


1079-1079: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1080-1080: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1081-1081: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)


1082-1082: Expected: 0; Actual: 1
Unordered list indentation

(MD007, ul-indent)

Additional comments not posted (10)
CHANGELOG.md (10)

7-7: Add a blank line after the heading for consistency.

Ensure there is a blank line after the heading for clarity and consistency.

## 1.10.0

9-9: Remove trailing punctuation from the heading.

The heading should not have trailing punctuation.

### Features:
### Features
Tools
Markdownlint

9-9: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


23-23: Remove trailing punctuation from the heading.

The heading should not have trailing punctuation.

### Minor:
### Minor
Tools
Markdownlint

23-23: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


38-38: Remove trailing punctuation from the heading.

The heading should not have trailing punctuation.

### Extensions and API:
### Extensions and API
Tools
Markdownlint

38-38: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


42-42: Remove trailing punctuation from the heading.

The heading should not have trailing punctuation.

### Performance:
### Performance
Tools
Markdownlint

42-42: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


53-53: Remove trailing punctuation from the heading.

The heading should not have trailing punctuation.

### Bug Fixes:
### Bug Fixes
Tools
Markdownlint

53-53: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


90-90: Remove trailing punctuation from the heading.

The heading should not have trailing punctuation.

### Other:
### Other
Tools
Markdownlint

90-90: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


91-91: Add a blank line after the 'Other' section heading for consistency.

Ensure there is a blank line after the heading for clarity and consistency.

### Other

24-36: Fix unordered list indentation.

The unordered list items should be properly indented for consistency.

* Option to skip CFG on early steps ([#15607](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15607))
* Add --models-dir option ([#15742](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15742))
* Allow mobile users to open context menu by using two fingers press ([#15682](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15682))
* Infotext: add Lora name as TI hashes for bundled Textual Inversion ([#15679](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15679))
* Check model's hash after downloading it to prevent corruped downloads ([#15602](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15602))
* More extension tag filtering options ([#15627](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15627))
* When saving AVIF, use JPEG's quality setting ([#15610](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15610))
* Add filename pattern: `[basename]` ([#15978](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15978))
* Add option to enable clip skip for clip L on SDXL ([#15992](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15992))
* Option to prevent screen sleep during generation ([#16001](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16001))
* ToggleLivePriview button in image viewer ([#16065](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16065))
* Remove ui flashing on reloading and fast scrollong ([#16153](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16153))
* option to disable save button log.csv ([#16242](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16242))

Likely invalid or redundant comment.


1-5: Fix unordered list indentation.

The unordered list item should be properly indented for consistency.

## 1.10.1

### Bug Fixes:
* fix image upscale on cpu ([#16275](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16275))

Likely invalid or redundant comment.

Tools
Markdownlint

3-3: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)

Comment on lines +91 to +93
* fix changelog #15883 -> #15882 ([#15907](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15907))
* ReloadUI backgroundColor --background-fill-primary ([#15864](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15864))
* Use different torch versions for Intel and ARM Macs ([#15851](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15851))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix unordered list indentation.

The unordered list items should be properly indented for consistency.

* fix changelog #15883 -> #15882 ([#15907](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15907))
* ReloadUI backgroundColor --background-fill-primary ([#15864](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15864))
* Use different torch versions for Intel and ARM Macs ([#15851](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15851))
* XYZ override rework ([#15836](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15836))
* scroll extensions table on overflow ([#15830](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15830))
* img2img batch upload method ([#15817](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15817))
* chore: sync v1.8.0 packages according to changelog ([#15783](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15783))
* Add AVIF MIME type support to mimetype definitions ([#15739](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15739))
* Update imageviewer.js ([#15730](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15730))
* no-referrer ([#15641](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15641))
* .gitignore trace.json ([#15980](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15980))
* Bump spandrel to 0.3.4 ([#16144](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16144))
* Defunct --max-batch-count ([#16119](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16119))
* docs: update bug_report.yml ([#16102](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16102))
* Maintaining Project Compatibility for Python 3.9 Users Without Upgrade Requirements. ([#16088](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16088), [#16169](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16169), [#16192](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16192))
* Update torch for ARM Macs to 2.3.1 ([#16059](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16059))
* remove deprecated setting dont_fix_second_order_samplers_schedule ([#16061](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16061))
* chore: fix typos ([#16060](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16060))
* shlex.join launch args in console log ([#16170](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16170))
* activate venv .bat ([#16231](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16231))
* add ids to the resize tabs in img2img ([#16218](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16218))
* update installation guide linux ([#16178](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16178))
* Robust sysinfo ([#16173](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16173

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +43 to +47
* [Performance 1/6] use_checkpoint = False ([#15803](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15803))
* [Performance 2/6] Replace einops.rearrange with torch native ops ([#15804](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15804))
* [Performance 4/6] Precompute is_sdxl_inpaint flag ([#15806](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15806))
* [Performance 5/6] Prevent unnecessary extra networks bias backup ([#15816](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15816))
* [Performance 6/6] Add --precision half option to avoid casting during inference ([#15820](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15820))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix unordered list indentation.

The unordered list items should be properly indented for consistency.

* [Performance 1/6] use_checkpoint = False ([#15803](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15803))
* [Performance 2/6] Replace einops.rearrange with torch native ops ([#15804](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15804))
* [Performance 4/6] Precompute is_sdxl_inpaint flag ([#15806](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15806))
* [Performance 5/6] Prevent unnecessary extra networks bias backup ([#15816](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15816))
* [Performance 6/6] Add --precision half option to avoid casting during inference ([#15820](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15820))
* [Performance] LDM optimization patches ([#15824](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15824))
* [Performance] Keep sigmas on CPU ([#15823](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15823))
* Check for nans in unet only once, after all steps have been completed
* Added pption to run torch profiler for image generation

Committable suggestion was skipped due to low confidence.

Comment on lines +54 to +87
* Fix for grids without comprehensive infotexts ([#15958](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15958))
* feat: lora partial update precede full update ([#15943](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15943))
* Fix bug where file extension had an extra '.' under some circumstances ([#15893](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15893))
* Fix corrupt model initial load loop ([#15600](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15600))
* Allow old sampler names in API ([#15656](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15656))
* more old sampler scheduler compatibility ([#15681](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15681))
* Fix Hypertile xyz ([#15831](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15831))
* XYZ CSV skipinitialspace ([#15832](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15832))
* fix soft inpainting on mps and xpu, torch_utils.float64 ([#15815](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15815))
* fix extention update when not on main branch ([#15797](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15797))
* update pickle safe filenames
* use relative path for webui-assets css ([#15757](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15757))
* When creating a virtual environment, upgrade pip in webui.bat/webui.sh ([#15750](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15750))
* Fix AttributeError ([#15738](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15738))
* use script_path for webui root in launch_utils ([#15705](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15705))
* fix extra batch mode P Transparency ([#15664](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15664))
* use gradio theme colors in css ([#15680](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15680))
* Fix dragging text within prompt input ([#15657](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15657))
* Add correct mimetype for .mjs files ([#15654](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15654))
* QOL Items - handle metadata issues more cleanly for SD models, Loras and embeddings ([#15632](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15632))
* replace wsl-open with wslpath and explorer.exe ([#15968](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15968))
* Fix SDXL Inpaint ([#15976](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15976))
* multi size grid ([#15988](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15988))
* fix Replace preview ([#16118](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16118))
* Possible fix of wrong scale in weight decomposition ([#16151](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16151))
* Ensure use of python from venv on Mac and Linux ([#16116](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16116))
* Prioritize python3.10 over python3 if both are available on Linux and Mac (with fallback) ([#16092](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16092))
* stoping generation extras ([#16085](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16085))
* Fix SD2 loading ([#16078](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16078), [#16079](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16079))
* fix infotext Lora hashes for hires fix different lora ([#16062](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16062))
* Fix sampler scheduler autocorrection warning ([#16054](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16054))
* fix ui flashing on reloading and fast scrollong ([#16153](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16153))
* fix upscale logic ([#16239](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16239))
* [bug] do not break progressbar on non-job actions (add wrap_gradio_call_no_job) ([#16202](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16202))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix unordered list indentation.

The unordered list items should be properly indented for consistency.

* Fix for grids without comprehensive infotexts ([#15958](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15958))
* feat: lora partial update precede full update ([#15943](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15943))
* Fix bug where file extension had an extra '.' under some circumstances ([#15893](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15893))
* Fix corrupt model initial load loop ([#15600](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15600))
* Allow old sampler names in API ([#15656](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15656))
* more old sampler scheduler compatibility ([#15681](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15681))
* Fix Hypertile xyz ([#15831](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15831))
* XYZ CSV skipinitialspace ([#15832](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15832))
* fix soft inpainting on mps and xpu, torch_utils.float64 ([#15815](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15815))
* fix extention update when not on main branch ([#15797](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15797))
* update pickle safe filenames
* use relative path for webui-assets css ([#15757](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15757))
* When creating a virtual environment, upgrade pip in webui.bat/webui.sh ([#15750](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15750))
* Fix AttributeError ([#15738](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15738))
* use script_path for webui root in launch_utils ([#15705](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15705))
* fix extra batch mode P Transparency ([#15664](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15664))
* use gradio theme colors in css ([#15680](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15680))
* Fix dragging text within prompt input ([#15657](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15657))
* Add correct mimetype for .mjs files ([#15654](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15654))
* QOL Items - handle metadata issues more cleanly for SD models, Loras and embeddings ([#15632](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15632))
* replace wsl-open with wslpath and explorer.exe ([#15968](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15968))
* Fix SDXL Inpaint ([#15976](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15976))
* multi size grid ([#15988](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15988))
* fix Replace preview ([#16118](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16118))
* Possible fix of wrong scale in weight decomposition ([#16151](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16151))
* Ensure use of python from venv on Mac and Linux ([#16116](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16116))
* Prioritize python3.10 over python3 if both are available on Linux and Mac (with fallback) ([#16092](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16092))
* stoping generation extras ([#16085](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16085))
* Fix SD2 loading ([#16078](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16078), [#16079](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16079))
* fix infotext Lora hashes for hires fix different lora ([#16062](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16062))
* Fix sampler scheduler autocorrection warning ([#16054](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16054))
* fix ui flashing on reloading and fast scrollong ([#16153](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16153))
* fix upscale logic ([#16239](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16239))
* [bug] do not break progressbar on non-job actions (add wrap_gradio_call_no_job) ([#16202](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16202))
* fix OSError: cannot write mode P as JPEG ([#16194](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16194))

Committable suggestion was skipped due to low confidence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.