diff --git a/README.md b/README.md index 0ebe093a..cf88a8e5 100644 --- a/README.md +++ b/README.md @@ -6,27 +6,36 @@

-[![Discord Server](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.com/invite/u9yhsFmEkB) (for support, and development discussion) | [Troubleshooting guide for common problems](Troubleshooting.md) +[![Discord Server](https://img.shields.io/discord/1014774730907209781?label=Discord)](https://discord.com/invite/u9yhsFmEkB) (for support, and development discussion) | [Troubleshooting guide for common problems](Troubleshooting.md) -️‍🔥🎉 **New!** Face Correction (GFPGAN) and Upscaling (RealESRGAN) have been added! +️‍🔥🎉 **New!** Live Preview, More Samplers, In-Painting, Face Correction (GFPGAN) and Upscaling (RealESRGAN) have been added! This distribution currently uses Stable Diffusion 1.4. Once the model for 1.5 becomes publicly available, the model in this distribution will be updated. # Features in the new v2 Version: - **No Dependencies or Technical Knowledge Required**: 1-click install for Windows 10/11 and Linux. *No dependencies*, no need for WSL or Docker or Conda or technical setup. Just download and run! - **Face Correction (GFPGAN) and Upscaling (RealESRGAN)** +- **In-Painting** +- **Live Preview**: See the image as the AI is drawing it +- **Lots of Samplers:** ddim, plms, heun, euler, euler_a, dpm2, dpm2_a, lms - **Image Modifiers**: A library of *modifier tags* like *"Realistic"*, *"Pencil Sketch"*, *"ArtStation"* etc. Experiment with various styles quickly. - **New UI**: with cleaner design +- **Waifu Model Support**: Just replace the `stable-diffusion\sd-v1-4.ckpt` file after installation with the Waifu model - Supports "*Text to Image*" and "*Image to Image*" - **NSFW Setting**: A setting in the UI to control *NSFW content* - **Use CPU setting**: If you don't have a compatible graphics card, but still want to run it on your CPU. - **Auto-updater**: Gets you the latest improvements and bug-fixes to a rapidly evolving project. +- **Low Memory Usage**: Creates 512x512 images with less than 4GB of VRAM! + +![Screenshot of advanced settings](media/shot-v9.jpg?raw=true) + +## Live Preview +![live-512](https://user-images.githubusercontent.com/844287/192097249-729a0a1e-a677-485e-9ccc-16a9e848fabe.gif) -![Screenshot](media/shot-v8.jpg?raw=true) # System Requirements 1. Windows 10/11, or Linux. Experimental support for Mac is coming soon. -2. An NVIDIA graphics card, preferably with 6GB or more of VRAM. But if you don't have a compatible graphics card, you can still use it with a "Use CPU" setting. It'll be very slow, but it should still work. +2. An NVIDIA graphics card, preferably with 4GB or more of VRAM. But if you don't have a compatible graphics card, you can still use it with a "Use CPU" setting. It'll be very slow, but it should still work. You do not need anything else. You do not need WSL, Docker or Conda. The installer will take care of it. @@ -73,14 +82,11 @@ You can also set the configuration like `seed`, `width`, `height`, `num_outputs` Use the same `seed` number to get the same image for a certain prompt. This is useful for refining a prompt without losing the basic image design. Enable the `random images` checkbox to get random images. -![Screenshot of advanced settings](media/config-v6.png?raw=true) +![Screenshot of advanced settings](media/config-v6.jpg?raw=true) +![Screenshot of advanced settings](media/system-settings-v2.jpg?raw=true) -# What is this? Why no Docker? -This version is a 1-click installer. You don't need WSL or Docker or anything beyond a working NVIDIA GPU with an updated driver. You don't need to use the command-line at all. Even if you don't have a compatible GPU, you can run it on your CPU (albeit very slowly). - -It'll download the necessary files from the original [Stable Diffusion](https://github.com/CompVis/stable-diffusion) git repository, and set it up. It'll then start the browser-based interface like before. - -The NSFW option is currently off (temporarily), so it'll allow NSFW images, for those people who are unable to run their prompts without hitting the NSFW filter incorrectly. +# Image Modifiers +![Screenshot of advanced settings](media/modifiers-v1.jpg?raw=true) # Bugs reports and code contributions welcome If there are any problems or suggestions, please feel free to ask on the [discord server](https://discord.com/invite/u9yhsFmEkB) or [file an issue](https://github.com/cmdr2/stable-diffusion-ui/issues). diff --git a/media/config-v6.jpg b/media/config-v6.jpg new file mode 100644 index 00000000..b7fa74d1 Binary files /dev/null and b/media/config-v6.jpg differ diff --git a/media/modifiers-v1.jpg b/media/modifiers-v1.jpg new file mode 100644 index 00000000..51e1fd02 Binary files /dev/null and b/media/modifiers-v1.jpg differ diff --git a/media/shot-v9.jpg b/media/shot-v9.jpg new file mode 100644 index 00000000..129a7934 Binary files /dev/null and b/media/shot-v9.jpg differ diff --git a/media/system-settings-v2.jpg b/media/system-settings-v2.jpg new file mode 100644 index 00000000..a3c7ecd8 Binary files /dev/null and b/media/system-settings-v2.jpg differ diff --git a/scripts/on_env_start.bat b/scripts/on_env_start.bat index 068231ff..16312a5a 100644 --- a/scripts/on_env_start.bat +++ b/scripts/on_env_start.bat @@ -2,6 +2,8 @@ @echo. & echo "Stable Diffusion UI - v2" & echo. +set PATH=C:\Windows\System32;%PATH% + @cd .. if exist "scripts\config.bat" ( diff --git a/scripts/on_sd_start.bat b/scripts/on_sd_start.bat index 526793fe..b8ef042b 100644 --- a/scripts/on_sd_start.bat +++ b/scripts/on_sd_start.bat @@ -15,9 +15,10 @@ @call git reset --hard @call git pull - @call git checkout d154155d4c0b43e13ec1f00eb72b7ff9d522fcf9 + @call git checkout f6cfebffa752ee11a7b07497b8529d5971de916c @call git apply ..\ui\sd_internal\ddim_callback.patch + @call git apply ..\ui\sd_internal\env_yaml.patch @cd .. ) else ( @@ -32,9 +33,10 @@ ) @cd stable-diffusion - @call git checkout d154155d4c0b43e13ec1f00eb72b7ff9d522fcf9 + @call git checkout f6cfebffa752ee11a7b07497b8529d5971de916c @call git apply ..\ui\sd_internal\ddim_callback.patch + @call git apply ..\ui\sd_internal\env_yaml.patch @cd .. ) @@ -77,6 +79,8 @@ @echo conda_sd_env_created >> ..\scripts\install_status.txt ) +set PATH=C:\Windows\System32;%PATH% + @>nul grep -c "conda_sd_gfpgan_deps_installed" ..\scripts\install_status.txt @if "%ERRORLEVEL%" EQU "0" ( @echo "Packages necessary for GFPGAN (Face Correction) were already installed" diff --git a/scripts/on_sd_start.sh b/scripts/on_sd_start.sh index 8de85925..2941764f 100755 --- a/scripts/on_sd_start.sh +++ b/scripts/on_sd_start.sh @@ -16,9 +16,10 @@ if [ -e "scripts/install_status.txt" ] && [ `grep -c sd_git_cloned scripts/insta git reset --hard git pull - git checkout d154155d4c0b43e13ec1f00eb72b7ff9d522fcf9 + git checkout f6cfebffa752ee11a7b07497b8529d5971de916c git apply ../ui/sd_internal/ddim_callback.patch + git apply ../ui/sd_internal/env_yaml.patch cd .. else @@ -33,9 +34,10 @@ else fi cd stable-diffusion - git checkout d154155d4c0b43e13ec1f00eb72b7ff9d522fcf9 + git checkout f6cfebffa752ee11a7b07497b8529d5971de916c git apply ../ui/sd_internal/ddim_callback.patch + git apply ../ui/sd_internal/env_yaml.patch cd .. fi diff --git a/ui/index.html b/ui/index.html index 677a856f..e720a335 100644 --- a/ui/index.html +++ b/ui/index.html @@ -1,288 +1,56 @@ + - - + + + + + + + + +
-
-
-
-
-
 
- Stable Diffusion is starting.. +
+ +
    + + +
+
+ +
+
+
+
+ Stable Diffusion is starting..
@@ -291,17 +59,21 @@
-
+
+
- + + +
+ +
- -
-
+ +
@@ -310,22 +82,25 @@
 
-
-

Advanced Settings

+
+

Image Settings

    -
  • -
  • - -
  • +
  • (images at once)
  • +
  • +
  • -
  • -
    -
  • -
  • (images at once)
  • -
  • +
  • -
  • -
  • + +
  • -
  • -
  • -

  • -
  •  
  • -
  • -
  • -
  • -
  • -
  • - +
  • +
  • +

  • +
    -
  • + +
  • Render Settings
  • +
  • +
  • +
  • + + +
  • +
  • +
    +
  • The system-related settings have been moved to the top-right corner.

Image Modifiers (art styles, tags etc)

+ + +   + +
-
-
Type a prompt and press the "Make Image" button.

You can set an "Initial Image" if you want to guide the AI.

You can also add modifiers like "Realistic", "Pencil Sketch", "ArtStation" etc by browsing through the "Image Modifiers" section and selecting the desired modifiers.

Click "Advanced Settings" for additional settings like seed, image size, number of images to generate etc.

Enjoy! :)
+
+
+
+ Type a prompt and press the "Make Image" button.

You can set an "Initial Image" if you want to guide the AI.

You can also add modifiers like "Realistic", "Pencil Sketch", "ArtStation" etc by browsing through the "Image Modifiers" section and selecting the desired modifiers.

Click "Advanced Settings" for additional settings like seed, image size, number of images to generate etc.

Enjoy! :) +
+
+
@@ -416,894 +210,8 @@
+ - - diff --git a/ui/media/drawingboard.min.css b/ui/media/drawingboard.min.css new file mode 100644 index 00000000..7d804787 --- /dev/null +++ b/ui/media/drawingboard.min.css @@ -0,0 +1,5 @@ +/* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js +* Copyright (c) 2015 Emmanuel Pelletier +* Licensed MIT */ + +.drawing-board,.drawing-board *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.drawing-board-controls-hidden,.drawing-board-utils-hidden{display:none!important}.drawing-board{position:relative;display:block}.drawing-board-canvas-wrapper{position:relative;margin:0;border:1px solid #ddd}.drawing-board-canvas{position:absolute;top:0;left:0;width:auto;cursor:crosshair;z-index:20}.drawing-board-cursor{position:absolute;top:0;left:0;pointer-events:none;border-radius:50%;background:#ccc;background:rgba(0,0,0,.2);z-index:30}.drawing-board-control-colors-rainbows,.drawing-board-control-size .drawing-board-control-inner,.drawing-board-control-size-dropdown,.drawing-board-control>button{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;overflow:hidden;background-color:#eee;padding:2px 4px;border:1px solid #ccc;box-shadow:0 1px 3px -2px #121212,inset 0 2px 5px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 3px -2px #121212,inset 0 2px 5px 0 rgba(255,255,255,.3);height:28px}.drawing-board-control>button{cursor:pointer;min-width:28px;line-height:14px}.drawing-board-control>button:focus,.drawing-board-control>button:hover{background-color:#ddd}.drawing-board-control>button.active,.drawing-board-control>button:active{box-shadow:inset 0 1px 2px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 2px 0 rgba(0,0,0,.2);background-color:#ddd}.drawing-board-control>button[disabled]{color:gray}.drawing-board-control>button[disabled].active,.drawing-board-control>button[disabled]:active,.drawing-board-control>button[disabled]:focus,.drawing-board-control>button[disabled]:hover{background-color:#eee;box-shadow:0 1px 3px -2px #121212,inset 0 2px 5px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 3px -2px #121212,inset 0 2px 5px 0 rgba(255,255,255,.3);cursor:default}.drawing-board-controls{margin:0 auto;text-align:center;font-size:0;display:table;border-spacing:9.33px 0;position:relative;min-height:28px}.drawing-board-controls[data-align=left]{margin:0;left:-9.33px}.drawing-board-controls[data-align=right]{margin:0 0 0 auto;right:-9.33px}.drawing-board-canvas-wrapper+.drawing-board-controls,.drawing-board-controls+.drawing-board-canvas-wrapper{margin-top:5px}.drawing-board-controls-hidden{height:0;min-height:0;padding:0;margin:0;border:0}.drawing-board-control{display:table-cell;border-collapse:separate;vertical-align:middle;font-size:16px;height:100%}.drawing-board-control-inner{position:relative;height:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.drawing-board-control>button{margin:0;vertical-align:middle}.drawing-board-control-colors{font-size:0;line-height:0}.drawing-board-control-colors-current{border:1px solid #ccc;cursor:pointer;display:inline-block;width:26px;height:26px}.drawing-board-control-colors-rainbows{display:inline-block;position:absolute;left:0;top:33px;margin-left:0;z-index:100;width:250px;height:auto;padding:4px}.drawing-board-control-colors-rainbow{height:18px}.drawing-board-control-colors-picker:first-child{margin-right:5px}.drawing-board-control-colors-picker{display:inline-block;width:18px;height:18px;cursor:pointer}.drawing-board-control-colors-picker[data-color="rgba(255, 255, 255, 1)"]{width:16px;height:17px;border:1px solid #ccc;border-bottom:none}.drawing-board-control-colors-picker:hover{width:16px;height:16px;border:1px solid #555}.drawing-board-control-drawingmode>button{margin-right:2px}.drawing-board-control-drawingmode>button:last-child{margin-right:0}.drawing-board-control-drawingmode-pencil-button{overflow:hidden;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAe9JREFUeNpiZAACVlFRBhYREQZcQPnbNwa3N28YlL5+ZfgLFfvPwGD9m4FhIgsDHuAO0gTUDNKIBvyBmqt/MTDMY8Gl0f31azD7L6oUIxCnAzWmAPHBfwwM01AMUAV6JfPQIVwOYgVqqPnFyOjz6///O38YGKpAgmAD1OXlGdTk5PD5hgeouZudj8/uy9evP/78/dsFFPsJNiAoKIiBABAHap4oLi9v8fTNm48//v7NBwbgWZgkE7rqt8DY+A8JZRBW+cfIuEDT0NDlzadP3z98/doPFDuCrB7TAGFhBqCNIGwM9OcKUzs7+xdv3355+f79VqDYAiTDwZgJh7ONgYpnOvn4GL949erT7UePdgL5JVCD4fgBLBBxaX74+PG789evnwby0/8jKXgExIeB+CG6Af///1e9Ki9vFSAkZPzoyZPPJy9evA9MB77/sWiEARZkzV+/fvXYtGnTpG3btj28EBT0BqjZ5D8OjXCwPksUhA1Wpggf/PHjx/9169Y9EBERaUlgZmaIAcrLE4rk5sIqBqDmlefnRPzfWGX5EaSZm5ubgRloADGA5QZ3RgK7gESY4PMNn9ZtObPpzZvfU4DiYkiB/RcHG+S7fyxAMH/lFU2GOZd2bLx18/cEUMoD4j9I+DcS/RtJHGTYf4AAAwAxaOMYHjxKFwAAAABJRU5ErkJggg==);background-position:50% 50%;background-repeat:no-repeat}.drawing-board-control-drawingmode-pencil-button:before{content:"";display:block;width:0;height:100%}.drawing-board-control-drawingmode-eraser-button{overflow:hidden;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAkpJREFUeNp0kk+IElEcx39vFBc9+OfQRTAwzFt4CaYOKStj6MoeculStzoIQSB4kCVckmDx4iGCXWYJIqjoVOzO1l4qT1F7WfBWHvxzDPyTB3XUmXn93suRybUffHmP997n9/cRsFgwGARJkiAcDsPlwgEIeEZQAhCRAkgAlOD6SQP4rgMFDWVnYCAQgFgsBqFQCBwOByzZNQOotPHx1RNCCCipu6bfb+zSnslkeOQVILPrBkAirbws9btdTEWAzZPXpfepOzaeGMBXwe/3w3+MwTc3Dl+UeghTiskbBvR6Pbh18mZHB0jjmxvCKhIfR37s3r+Sevf8ca/T4TBF2HTSODuDxP7uNjrZFFbBk8lEzOVyspa4ykGYw2zfbTb/7ilvok1YhlVVFfP5vDydTkHXdXDdlhZOOnPY4/HA0YPtp3h6LFjh8XgsFgoFGTPgsKm1zDr8ajTQh8Fh5eGjZzjGI8yjKlgjF4tFGdd/YKYmRja24hw+zu3sYe2HiH3hYzQjl8tleTQanWtou93G6Qngdrth6+1+9h6hTULJZ/PeziJXKhV5OByeg1ut1gJOp9NZTdNOcQ419ot+ggp1qoLdBFmqVmNpm3A8Huewy+Wq1RH8QH9zmBlJJpMRdCIqiiIPBgN+2MCGsW/r8/kgGo1m0fmpzWarseayHlmNeL1eFiWC0cRqtSr3+/3FpSiKHMZtjU1glbFyfKgLTqfzEka9OJvNeDnzz1JnCaFmqOl8ZdJY1SiDOXCiXKg1NtG5DIt0y6ov3dE/AgwAENFWYYLj4mYAAAAASUVORK5CYII=);background-position:50% 50%;background-repeat:no-repeat}.drawing-board-control-drawingmode-eraser-button:before{content:"";display:block;width:0;height:100%}.drawing-board-control-drawingmode-filler-button{overflow:hidden;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnNJREFUeNp0k0trE1EUx89MJpNJooYYXBgDNtCKdRPwlbqoCKUtaNVNA0Uo7UbMxoVPEARTXEi+QWfnwn6DEAlEkrSLttTGRiULEQlJ8yChmbzI++E50yTUJA78uMy953/u/557LmOz2WDEZ2m1WrckSRJSqdR2tVrdHQyYebwHtVoNuFHqTqczhQnWKaBYLDoKhcIuzgHDMKBSqeD20qd+LNdsNocSoFhRr9ctpVLJigl4xIIJQizLAmG4cAPa7bYcy9Iug5TL5UYikbD6/X7Rbre/IUcYe3WUW5ZsnQQzW9LpNOPz+UQc5aBM5mgdh7vI9FCCAesW2tnr9YqZTAby+bw8f3AQRP6853n+Ph5hemSCntjj8YjZbFYWx2IxeS2RSEMwuA87O79eqdXquVolK+GxnP0EPbHb7RZJSGABIR6PA11zJHKIR2MhHA5DIPDj7eH3j95KpfK60Wg8Yntil8slkqgnpioLghacTidoNDpEC3q9HnheCc3s1jZeLcW943pirPw/4lKpBkqlDubnl/riycnLsLy88EKj0fhzuRyZv8RFo1E6wpBYkiqy7Z54YmIcVlYeyOKC4mYwJ0nHRaQuM5vNT6hB/iceG7sIq6sPnwmC4MerDkby40AOCCoiddie1Wp92W7zQ2KTyQSLizNP8T0EsPLBbxEDnCj0GkM2qIEwyZRCobizsfH5A1ZXFhuN52F29vpz3HkL574mk8lj24Y5wsHkvjjoX0BOIWc5jruHzbK2ufmzEwpFO3jnDhQv4JoROYdoERVyGjEgZ8iBDlF3FzXo4go6utZ9lftY4N/dXisjR0i1G0ublv8KMAA0ZoUlicxrhwAAAABJRU5ErkJggg==);background-position:50% 50%;background-repeat:no-repeat}.drawing-board-control-drawingmode-filler-button:before{content:"";display:block;width:0;height:100%}.drawing-board-control-navigation>button{font-family:Helvetica,Arial,sans-serif;font-size:14px;font-weight:700;margin-right:2px}.drawing-board-control-navigation>button:last-child{margin-right:0}.drawing-board-control-size[data-drawing-board-type=range] .drawing-board-control-inner{width:75px}.drawing-board-control-size[data-drawing-board-type=dropdown] .drawing-board-control-inner{overflow:visible}.drawing-board-control-size-range-input{position:relative;width:100%;z-index:100;margin:0;padding:0;border:0}.drawing-board-control-size-dropdown span,.drawing-board-control-size-dropdown-current span,.drawing-board-control-size-range-current{display:block;background:#333;opacity:.8}.drawing-board-control-size-range-current{display:inline-block;opacity:.15;position:absolute;pointer-events:none;left:50%;top:50%;z-index:50}.drawing-board-control-size-dropdown-current{display:block;height:100%;width:40px;overflow:hidden;position:relative}.drawing-board-control-size-dropdown-current span{position:absolute;left:50%;top:50%}.drawing-board-control-size-dropdown{position:absolute;left:-6px;top:33px;height:auto;list-style-type:none;margin:0;padding:0;z-index:100}.drawing-board-control-size-dropdown li{display:block;padding:4px;margin:3px 0;min-height:16px}.drawing-board-control-size-dropdown li:hover{background:#ccc}.drawing-board-control-size-dropdown span{margin:0 auto}.drawing-board-control-download-button{overflow:hidden;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAoBJREFUeNqMkr9PU1EUx7/vR1tQ3yu10hAmTawtBSYSy2YccFOcnDQm/gewOLnj5GYMg4sdXFxkMca4OBAwdUBe/ZkIGFp+9tHXvh/3/fTcAm01aLzJybnn3nM+95tzrnDl6Tb+sibuTmWUWj3C6/Juk+LySUmyvt0FCKKA02ryOCy6LBiu15ngMbZ5DDCNBqIw6gKM+n4nECUJru3glKry8CpjQaHVYmC2rVH82DIMMMdGGARdwJ+SPNdFS9chx+MXDNMp/NzagWNatk/nQU/hiYAoih6FYTBCBs9zUXMCbAhx2OYOv351lPOJ3EwH4LteL6Dcp/Rfu3FrstDyIizt+agpaYxNDU0M9gl4v7Ck+TYrCYLQqZHUyTtdQBiutPSGUflczSXHs5lVKwZdSOBMvwztxVvN0RtzsiyXBFHsAvL5PBSnCpXV2getILFiE2SjspYbuZzPiDSZ2vOXmlvX5yQqTmMfg9ZXqtls1wnT09OHEyAq0aFLg/gSXsSWq9wWk+p9PrCoYTwcijdLOfE7UsEufN9HGIYnT4EnTGIXe1KqtNNIvuNnGamxfi7SgQD/nIJCTbzOPQ/SQh1pud7T4M6W/8qFIw/5WAr5m7Ozsw9UVc069Fls2yJzSC5/lnc9RhaHZVnfSqUnEgXP2oBqtYqBgYG2+mKxmOVADnAcB4yxHgD1RzehKKns/LyV4gUHBweQy+UyRkdH6UKJ6fQDFxcXoWkaXJeRuTgUGCdLQJ9bx72lGZimGWs2m+083oN+2iiFQiGxvLy8RrDzudyltgrG3N8U2G8CrPz4sGYYRqJSqWR4H/jNWbJhUjAWi8XG8R/L87yPpGCVttVfAgwAVpZR+8tZC08AAAAASUVORK5CYII=);background-position:50% 50%;background-repeat:no-repeat}.drawing-board-control-download-button:before{content:"";display:block;width:0;height:100%} \ No newline at end of file diff --git a/ui/media/drawingboard.min.js b/ui/media/drawingboard.min.js new file mode 100644 index 00000000..289d40ae --- /dev/null +++ b/ui/media/drawingboard.min.js @@ -0,0 +1,4 @@ +/* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js +* Copyright (c) 2015 Emmanuel Pelletier +* Licensed MIT */ +!function(){"use strict";function a(a,b){for(;a.length>b;)a.shift()}var b=function(a){var b=a?a:{},c={provider:function(){throw new Error("No provider!")},maxLength:30,onUpdate:function(){}};this.provider="undefined"!=typeof b.provider?b.provider:c.provider,this.maxLength="undefined"!=typeof b.maxLength?b.maxLength:c.maxLength,this.onUpdate="undefined"!=typeof b.onUpdate?b.onUpdate:c.onUpdate,this.initialItem=null,this.clear()};b.prototype.initialize=function(a){this.stack[0]=a,this.initialItem=a},b.prototype.clear=function(){this.stack=[this.initialItem],this.position=0,this.onUpdate()},b.prototype.save=function(){this.provider(function(b){a(this.stack,this.maxLength),this.position=Math.min(this.position,this.stack.length-1),this.stack=this.stack.slice(0,this.position+1),this.stack.push(b),this.position++,this.onUpdate()}.bind(this))},b.prototype.undo=function(a){if(this.canUndo()){var b=this.stack[--this.position];this.onUpdate(),a&&a(b)}},b.prototype.redo=function(a){if(this.canRedo()){var b=this.stack[++this.position];this.onUpdate(),a&&a(b)}},b.prototype.canUndo=function(){return this.position>0},b.prototype.canRedo=function(){return this.positionh;h++){if(g=g[e[h]],g===a)throw"tim: '"+e[h]+"' not found in "+b;if(h===f-1)return g}})}}(),DrawingBoard.Utils.MicroEvent=function(){},DrawingBoard.Utils.MicroEvent.prototype={bind:function(a,b){this._events=this._events||{},this._events[a]=this._events[a]||[],this._events[a].push(b)},unbind:function(a,b){this._events=this._events||{},a in this._events!=!1&&this._events[a].splice(this._events[a].indexOf(b),1)},trigger:function(a){if(this._events=this._events||{},a in this._events!=!1)for(var b=0;b=0;g--)f+=parseInt(a.css(e[g]).replace("px",""),10);return f},DrawingBoard.Utils.boxBorderWidth=function(a,b,c){return DrawingBoard.Utils._boxBorderSize(a,b,c,"width")},DrawingBoard.Utils.boxBorderHeight=function(a,b,c){return DrawingBoard.Utils._boxBorderSize(a,b,c,"height")},DrawingBoard.Utils.isColor=function(a){return a&&a.length?/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a)||-1!==$.inArray(a.substring(0,3),["rgb","hsl"]):!1},DrawingBoard.Utils.RGBToInt=function(a,b,c){var d=0;return d|=(255&a)<<16,d|=(255&b)<<8,d|=255&c},DrawingBoard.Utils.pixelAt=function(a,b,c){var d=4*(c*a.width+b),e=DrawingBoard.Utils.RGBToInt(a.data[d],a.data[d+1],a.data[d+2]);return[d,b,c,e]},DrawingBoard.Utils.compareColors=function(a,b,c){if(0===c)return a===b;var d=a>>16&255,e=b>>16&255,f=a>>8&255,g=b>>8&255,h=255&a,i=255&b;return Math.abs(d-e)<=c&&Math.abs(f-g)<=c&&Math.abs(h-i)<=c},function(){for(var a=["ms","moz","webkit","o"],b=0;b-1?c+='
':c='
'+c,this.$el.addClass("drawing-board").append(c),this.dom={$canvasWrapper:this.$el.find(".drawing-board-canvas-wrapper"),$canvas:this.$el.find(".drawing-board-canvas"),$cursor:this.$el.find(".drawing-board-cursor"),$controls:this.$el.find(".drawing-board-controls")},$.each(["left","right","center"],$.proxy(function(a,b){return this.opts.controlsPosition.indexOf(b)>-1?(this.dom.$controls.attr("data-align",b),!1):void 0},this)),this.canvas=this.dom.$canvas.get(0),this.ctx=this.canvas&&this.canvas.getContext&&this.canvas.getContext("2d")?this.canvas.getContext("2d"):null,this.color=this.opts.color,this.ctx?(this.storage=this._getStorage(),this.initHistory(),this.reset({webStorage:!1,history:!1,background:!1}),this.initControls(),this.resize(),this.reset({webStorage:!1,history:!1,background:!0}),this.restoreWebStorage(),this.initDropEvents(),void this.initDrawEvents()):(this.opts.errorMessage&&this.$el.html(this.opts.errorMessage),!1)},DrawingBoard.Board.defaultOpts={controls:["Color","DrawingMode","Size","Navigation"],controlsPosition:"top left",color:"#000000",size:1,background:"#fff",eraserColor:"background",fillTolerance:100,fillHack:!0,webStorage:"session",droppable:!1,enlargeYourContainer:!1,errorMessage:'

It seems you use an obsolete browser. Update it to start drawing.

',stretchImg:!1},DrawingBoard.Board.prototype={mergeOptions:function(a){return a=$.extend({},DrawingBoard.Board.defaultOpts,a),a.background||"background"!==a.eraserColor||(a.eraserColor="transparent"),a},reset:function(a){a=$.extend({color:this.opts.color,size:this.opts.size,webStorage:!0,history:!0,background:!1},a),this.setMode("pencil"),a.background&&this.resetBackground(this.opts.background,$.proxy(function(){a.history&&this.saveHistory()},this)),a.color&&this.setColor(a.color),a.size&&(this.ctx.lineWidth=a.size),this.ctx.lineCap="round",this.ctx.lineJoin="round",a.webStorage&&this.saveWebStorage(),a.history&&!a.background&&this.saveHistory(),this.blankCanvas=this.getImg(),this.ev.trigger("board:reset",a)},resetBackground:function(a,b){a=a||this.opts.background;var c=DrawingBoard.Utils.isColor(a),d=this.getMode();this.setMode("pencil"),this.ctx.clearRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height),c?(this.ctx.fillStyle=a,this.ctx.fillRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height),this.history.initialize(this.getImg()),b&&b()):a&&this.setImg(a,{callback:$.proxy(function(){this.history.initialize(this.getImg()),b&&b()},this)}),this.setMode(d)},resize:function(){this.dom.$controls.toggleClass("drawing-board-controls-hidden",!this.controls||!this.controls.length);var a,b,c=[this.$el.width(),DrawingBoard.Utils.boxBorderWidth(this.$el),DrawingBoard.Utils.boxBorderWidth(this.dom.$canvasWrapper,!0,!0)],d=[this.$el.height(),DrawingBoard.Utils.boxBorderHeight(this.$el),this.dom.$controls.height(),DrawingBoard.Utils.boxBorderHeight(this.dom.$controls,!1,!0),DrawingBoard.Utils.boxBorderHeight(this.dom.$canvasWrapper,!0,!0)],e=function(a,b){b=b||1;for(var c=a[0],d=1;d0&&q.push(DrawingBoard.Utils.pixelAt(c,p[e]-1,p[f])),p[e]0&&q.push(DrawingBoard.Utils.pixelAt(c,p[e],p[f]-1)),p[f]10&&this.isMouseHovering){this.dom.$cursor.css({width:this.ctx.lineWidth+"px",height:this.ctx.lineWidth+"px"});var a=DrawingBoard.Utils.tpl("translateX({{x}}px) translateY({{y}}px)",{x:this.coords.current.x-this.ctx.lineWidth/2,y:this.coords.current.y-this.ctx.lineWidth/2});this.dom.$cursor.css({transform:a,"-webkit-transform":a,"-ms-transform":a}),this.dom.$cursor.removeClass("drawing-board-utils-hidden")}else this.dom.$cursor.addClass("drawing-board-utils-hidden");if(this.isDrawing){var b=this._getMidInputCoords(this.coords.current);this.ctx.beginPath(),this.ctx.moveTo(b.x,b.y),this.ctx.quadraticCurveTo(this.coords.old.x,this.coords.old.y,this.coords.oldMid.x,this.coords.oldMid.y),this.ctx.stroke(),this.coords.old=this.coords.current,this.coords.oldMid=b}window.requestAnimationFrame&&requestAnimationFrame($.proxy(function(){this.draw()},this))},_onInputStart:function(a,b){this.coords.current=this.coords.old=b,this.coords.oldMid=this._getMidInputCoords(b),this.isDrawing=!0,window.requestAnimationFrame||this.draw(),this.ev.trigger("board:startDrawing",{e:a,coords:b}),a.stopPropagation(),a.preventDefault()},_onInputMove:function(a,b){this.coords.current=b,this.ev.trigger("board:drawing",{e:a,coords:b}),window.requestAnimationFrame||this.draw(),a.stopPropagation(),a.preventDefault()},_onInputStop:function(a,b){!this.isDrawing||a.touches&&0!==a.touches.length||(this.isDrawing=!1,this.saveWebStorage(),this.saveHistory(),this.ev.trigger("board:stopDrawing",{e:a,coords:b}),this.ev.trigger("board:userAction"),a.stopPropagation(),a.preventDefault())},_onMouseOver:function(a,b){this.isMouseHovering=!0,this.coords.old=this._getInputCoords(a),this.coords.oldMid=this._getMidInputCoords(this.coords.old),this.ev.trigger("board:mouseOver",{e:a,coords:b})},_onMouseOut:function(a,b){this.isMouseHovering=!1,this.ev.trigger("board:mouseOut",{e:a,coords:b})},_getInputCoords:function(a){a=a.originalEvent?a.originalEvent:a;var b,c,d=this.canvas.getBoundingClientRect(),e=this.dom.$canvas.width(),f=this.dom.$canvas.height();return a.touches&&1==a.touches.length?(b=a.touches[0].pageX,c=a.touches[0].pageY):(b=a.pageX,c=a.pageY),b-=this.dom.$canvas.offset().left,c-=this.dom.$canvas.offset().top,b*=e/d.width,c*=f/d.height,{x:b,y:c}},_getMidInputCoords:function(a){return{x:this.coords.old.x+a.x>>1,y:this.coords.old.y+a.y>>1}}},DrawingBoard.Control=function(a,b){return this.board=a,this.opts=$.extend({},this.defaults,b),this.$el=$(document.createElement("div")).addClass("drawing-board-control"),this.name&&this.$el.addClass("drawing-board-control-"+this.name),this.board.ev.bind("board:reset",$.proxy(this.onBoardReset,this)),this.initialize.apply(this,arguments),this},DrawingBoard.Control.prototype={name:"",defaults:{},initialize:function(){},addToBoard:function(){this.board.addControl(this)},onBoardReset:function(){}},DrawingBoard.Control.extend=function(a,b){var c,d=this;c=a&&a.hasOwnProperty("constructor")?a.constructor:function(){return d.apply(this,arguments)},$.extend(c,d,b);var e=function(){this.constructor=c};return e.prototype=d.prototype,c.prototype=new e,a&&$.extend(c.prototype,a),c.__super__=d.prototype,c},DrawingBoard.Control.Color=DrawingBoard.Control.extend({name:"colors",initialize:function(){this.initTemplate();var a=this;this.$el.on("click",".drawing-board-control-colors-picker",function(b){var c=$(this).attr("data-color");a.board.setColor(c),a.$el.find(".drawing-board-control-colors-current").css("background-color",c).attr("data-color",c),a.board.ev.trigger("color:changed",c),a.$el.find(".drawing-board-control-colors-rainbows").addClass("drawing-board-utils-hidden"),b.preventDefault()}),this.$el.on("click",".drawing-board-control-colors-current",function(b){a.$el.find(".drawing-board-control-colors-rainbows").toggleClass("drawing-board-utils-hidden"),b.preventDefault()}),$("body").on("click",function(b){var c=$(b.target),d=c.hasClass("drawing-board-control-colors-current")?c:c.closest(".drawing-board-control-colors-current"),e=a.$el.find(".drawing-board-control-colors-current"),f=a.$el.find(".drawing-board-control-colors-rainbows");d.length&&d.get(0)===e.get(0)||f.hasClass("drawing-board-utils-hidden")||f.addClass("drawing-board-utils-hidden")})},initTemplate:function(){var a='
{{rainbows}}
',b='
',c="";$.each([.75,.5,.25],$.proxy(function(a,d){var e=0,f=null;for(c+='
',.25==d&&(f=this._rgba(0,0,0,1)),.5==d&&(f=this._rgba(150,150,150,1)),.75==d&&(f=this._rgba(255,255,255,1)),c+=DrawingBoard.Utils.tpl(b,{color:f.toString()});330>=e;)c+=DrawingBoard.Utils.tpl(b,{color:this._hsl2Rgba(this._hsl(e-60,1,d)).toString()}),e+=30;c+="
"},this)),this.$el.append($(DrawingBoard.Utils.tpl(a,{color:this.board.color,rainbows:c}))),this.$el.find(".drawing-board-control-colors-rainbows").addClass("drawing-board-utils-hidden")},onBoardReset:function(){this.board.setColor(this.$el.find(".drawing-board-control-colors-current").attr("data-color"))},_rgba:function(a,b,c,d){return{r:a,g:b,b:c,a:d,toString:function(){return"rgba("+a+", "+b+", "+c+", "+d+")"}}},_hsl:function(a,b,c){return{h:a,s:b,l:c,toString:function(){return"hsl("+a+", "+100*b+"%, "+100*c+"%)"}}},_hex2Rgba:function(a){var b=parseInt(a.substring(1),16);return this._rgba(b>>16,b>>8&255,255&b,1)},_hsl2Rgba:function(a){function b(a,b,c){return 0>c&&(c+=1),c>1&&(c-=1),1/6>c?a+6*(b-a)*c:.5>c?b:2/3>c?a+(b-a)*(2/3-c)*6:a}var c,d,e,f=a.h/360,g=a.s,h=a.l;if(0===g)c=d=e=h;else{var i=.5>h?h*(1+g):h+g-h*g,j=2*h-i;c=Math.floor(255*b(j,i,f+1/3)),d=Math.floor(255*b(j,i,f)),e=Math.floor(255*b(j,i,f-1/3))}return this._rgba(c,d,e,1)}}),DrawingBoard.Control.DrawingMode=DrawingBoard.Control.extend({name:"drawingmode",defaults:{pencil:!0,eraser:!0,filler:!0},initialize:function(){this.prevMode=this.board.getMode(),$.each(["pencil","eraser","filler"],$.proxy(function(a,b){this.opts[b]&&this.$el.append('')},this)),this.$el.on("click","button[data-mode]",$.proxy(function(a){var b=$(a.currentTarget).attr("data-mode"),c=this.board.getMode();c!==b&&(this.prevMode=c);var d=c===b?this.prevMode:b;this.board.setMode(d),a.preventDefault()},this)),this.board.ev.bind("board:mode",$.proxy(function(a){this.toggleButtons(a)},this)),this.toggleButtons(this.board.getMode())},toggleButtons:function(a){this.$el.find("button[data-mode]").each(function(b,c){var d=$(c);d.toggleClass("active",a===d.attr("data-mode"))})}}),DrawingBoard.Control.Navigation=DrawingBoard.Control.extend({name:"navigation",defaults:{back:!0,forward:!0,reset:!0},initialize:function(){var a="";if(this.opts.back&&(a+=''),this.opts.forward&&(a+=''),this.opts.reset&&(a+=''),this.$el.append(a),this.opts.back){var b=this.$el.find(".drawing-board-control-navigation-back");this.board.ev.bind("historyNavigation",$.proxy(this.updateBack,this,b)),this.$el.on("click",".drawing-board-control-navigation-back",$.proxy(function(a){this.board.goBackInHistory(),a.preventDefault()},this)),this.updateBack(b)}if(this.opts.forward){var c=this.$el.find(".drawing-board-control-navigation-forward");this.board.ev.bind("historyNavigation",$.proxy(this.updateForward,this,c)),this.$el.on("click",".drawing-board-control-navigation-forward",$.proxy(function(a){this.board.goForthInHistory(),a.preventDefault()},this)),this.updateForward(c)}this.opts.reset&&this.$el.on("click",".drawing-board-control-navigation-reset",$.proxy(function(a){this.board.reset({background:!0}),a.preventDefault()},this))},updateBack:function(a){this.board.history.canUndo()?a.removeAttr("disabled"):a.attr("disabled","disabled")},updateForward:function(a){this.board.history.canRedo()?a.removeAttr("disabled"):a.attr("disabled","disabled")}}),DrawingBoard.Control.Size=DrawingBoard.Control.extend({name:"size",defaults:{type:"auto",dropdownValues:[1,3,6,10,20,30,40,50],min:1,max:50},types:["dropdown","range"],initialize:function(){"auto"==this.opts.type&&(this.opts.type=this._iHasRangeInput()?"range":"dropdown");var a=$.inArray(this.opts.type,this.types)>-1?this["_"+this.opts.type+"Template"]():!1;if(!a)return!1;this.val=this.board.opts.size,this.$el.append($(a)),this.$el.attr("data-drawing-board-type",this.opts.type),this.updateView();var b=this;"range"==this.opts.type&&this.$el.on("change",".drawing-board-control-size-range-input",function(a){b.val=$(this).val(),b.updateView(),b.board.ev.trigger("size:changed",b.val),a.preventDefault()}),"dropdown"==this.opts.type&&(this.$el.on("click",".drawing-board-control-size-dropdown-current",$.proxy(function(){this.$el.find(".drawing-board-control-size-dropdown").toggleClass("drawing-board-utils-hidden")},this)),this.$el.on("click","[data-size]",function(a){b.val=parseInt($(this).attr("data-size"),0),b.updateView(),b.board.ev.trigger("size:changed",b.val),a.preventDefault()}))},_rangeTemplate:function(){var a='
';return DrawingBoard.Utils.tpl(a,{min:this.opts.min,max:this.opts.max,size:this.board.opts.size})},_dropdownTemplate:function(){var a='
    ';return $.each(this.opts.dropdownValues,function(b,c){a+=DrawingBoard.Utils.tpl('
  • ',{size:c})}),a+="
"},onBoardReset:function(){this.updateView()},updateView:function(){var a=this.val;if(this.board.ctx.lineWidth=a,this.$el.find(".drawing-board-control-size-range-current, .drawing-board-control-size-dropdown-current span").css({width:a+"px",height:a+"px",borderRadius:a+"px",marginLeft:-1*a/2+"px",marginTop:-1*a/2+"px"}),this.$el.find(".drawing-board-control-inner").attr("title",a),"dropdown"==this.opts.type){var b=null;$.each(this.opts.dropdownValues,function(c,d){(null===b||Math.abs(d-a)'),this.$el.on("click",".drawing-board-control-download-button",$.proxy(function(a){this.board.downloadImg(),a.preventDefault()},this))}}); \ No newline at end of file diff --git a/ui/media/favicon-16x16.png b/ui/media/favicon-16x16.png new file mode 100644 index 00000000..7a33c0b1 Binary files /dev/null and b/ui/media/favicon-16x16.png differ diff --git a/ui/media/favicon-32x32.png b/ui/media/favicon-32x32.png new file mode 100644 index 00000000..3b21168b Binary files /dev/null and b/ui/media/favicon-32x32.png differ diff --git a/ui/media/jquery-3.6.1.min.js b/ui/media/jquery-3.6.1.min.js new file mode 100644 index 00000000..2c69bc90 --- /dev/null +++ b/ui/media/jquery-3.6.1.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),v={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&v(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!y||!y.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ve(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ye(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],y=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||y.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||y.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||y.push(".#.+[+~]"),e.querySelectorAll("\\\f"),y.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),y=y.length&&new RegExp(y.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),v=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&v(p,e)?-1:t==C||t.ownerDocument==p&&v(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!y||!y.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),v.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",v.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",v.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return B(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=_e(v.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return B(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 button { + background-color: #eee; + border-radius: 3pt; +} +.drawing-board-control-inner { + background-color: #eee; + border-radius: 3pt; +} +#inpaintingEditor canvas { + opacity: 0.6; +} +#enable_mask { + margin-top: 8pt; +} + +#top-nav { + padding-top: 3pt; + padding-bottom: 15pt; +} +#top-nav .icon { + padding-right: 4pt; + font-size: 14pt; + transform: translateY(1pt); +} +#logo { + display: inline; +} +#logo h1 { + display: inline; +} +#top-nav-items { + list-style-type: none; + display: inline; + float: right; +} +#top-nav-items > li { + float: left; + display: inline; + padding-left: 20pt; + cursor: default; +} +#initial-text { + padding-top: 15pt; + padding-left: 4pt; +} +.settings-subheader { + font-size: 10pt; + font-weight: bold; +} +.pl-5 { + padding-left: 5pt; +} +#system-settings { + width: 360pt; + transform: translateX(-100%) translateX(70pt); + + padding-top: 10pt; + padding-bottom: 10pt; +} +#system-settings ul { + margin: 0; + padding: 0; +} +#system-settings li { + padding-left: 5pt; +} +#community-links { + list-style-type: none; + margin: 0; + padding: 12pt; + padding-bottom: 0pt; + transform: translateX(-15%); +} +#community-links li { + padding-bottom: 12pt; + display: block; + font-size: 10pt; +} +#community-links li .fa-fw { + padding-right: 2pt; +} +#community-links li a { + color: white; + text-decoration: none; +} +.dropdown { + overflow: hidden; +} +.dropdown-content { + display: none; + position: absolute; + z-index: 2; + + background: rgb(18, 18, 19); + border: 2px solid rgb(37, 38, 41); + border-radius: 7px; + padding: 5px; + margin-bottom: 15px; + box-shadow: 0 20px 28px 0 rgba(0, 0, 0, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.15); +} +.dropdown:hover .dropdown-content { + display: block; +} \ No newline at end of file diff --git a/ui/media/main.js b/ui/media/main.js new file mode 100644 index 00000000..7633b7ee --- /dev/null +++ b/ui/media/main.js @@ -0,0 +1,1218 @@ +const SOUND_ENABLED_KEY = "soundEnabled" +const SAVE_TO_DISK_KEY = "saveToDisk" +const USE_CPU_KEY = "useCPU" +const USE_FULL_PRECISION_KEY = "useFullPrecision" +const USE_TURBO_MODE_KEY = "useTurboMode" +const DISK_PATH_KEY = "diskPath" +const ADVANCED_PANEL_OPEN_KEY = "advancedPanelOpen" +const MODIFIERS_PANEL_OPEN_KEY = "modifiersPanelOpen" +const USE_FACE_CORRECTION_KEY = "useFaceCorrection" +const USE_UPSCALING_KEY = "useUpscaling" +const SHOW_ONLY_FILTERED_IMAGE_KEY = "showOnlyFilteredImage" +const STREAM_IMAGE_PROGRESS_KEY = "streamImageProgress" +const HEALTH_PING_INTERVAL = 5 // seconds +const MAX_INIT_IMAGE_DIMENSION = 768 + +const IMAGE_REGEX = new RegExp('data:image/[A-Za-z]+;base64') + +let sessionId = new Date().getTime() + +let promptField = document.querySelector('#prompt') +let numOutputsTotalField = document.querySelector('#num_outputs_total') +let numOutputsParallelField = document.querySelector('#num_outputs_parallel') +let numInferenceStepsField = document.querySelector('#num_inference_steps') +let guidanceScaleSlider = document.querySelector('#guidance_scale_slider') +let guidanceScaleField = document.querySelector('#guidance_scale') +let randomSeedField = document.querySelector("#random_seed") +let seedField = document.querySelector('#seed') +let widthField = document.querySelector('#width') +let heightField = document.querySelector('#height') +let initImageSelector = document.querySelector("#init_image") +let initImagePreview = document.querySelector("#init_image_preview") +let maskImageSelector = document.querySelector("#mask") +let maskImagePreview = document.querySelector("#mask_preview") +let turboField = document.querySelector('#turbo') +let useCPUField = document.querySelector('#use_cpu') +let useFullPrecisionField = document.querySelector('#use_full_precision') +let saveToDiskField = document.querySelector('#save_to_disk') +let diskPathField = document.querySelector('#diskPath') +// let allowNSFWField = document.querySelector("#allow_nsfw") +let useBetaChannelField = document.querySelector("#use_beta_channel") +let promptStrengthSlider = document.querySelector('#prompt_strength_slider') +let promptStrengthField = document.querySelector('#prompt_strength') +let samplerField = document.querySelector('#sampler') +let samplerSelectionContainer = document.querySelector("#samplerSelection") +let useFaceCorrectionField = document.querySelector("#use_face_correction") +let useUpscalingField = document.querySelector("#use_upscale") +let upscaleModelField = document.querySelector("#upscale_model") +let showOnlyFilteredImageField = document.querySelector("#show_only_filtered_image") +let updateBranchLabel = document.querySelector("#updateBranchLabel") +let streamImageProgressField = document.querySelector("#stream_image_progress") + +let makeImageBtn = document.querySelector('#makeImage') +let stopImageBtn = document.querySelector('#stopImage') + +let imagesContainer = document.querySelector('#current-images') +let initImagePreviewContainer = document.querySelector('#init_image_preview_container') +let initImageClearBtn = document.querySelector('.init_image_clear') +let promptStrengthContainer = document.querySelector('#prompt_strength_container') + +// let maskSetting = document.querySelector('#editor-inputs-mask_setting') +// let maskImagePreviewContainer = document.querySelector('#mask_preview_container') +// let maskImageClearBtn = document.querySelector('#mask_clear') +let maskSetting = document.querySelector('#enable_mask') + +let editorModifierEntries = document.querySelector('#editor-modifiers-entries') +let editorModifierTagsList = document.querySelector('#editor-inputs-tags-list') +let editorTagsContainer = document.querySelector('#editor-inputs-tags-container') + +let previewImageField = document.querySelector('#preview-image') +previewImageField.onchange = () => changePreviewImages(previewImageField.value); + +let modifierCardSizeSlider = document.querySelector('#modifier-card-size-slider') +modifierCardSizeSlider.onchange = () => resizeModifierCards(modifierCardSizeSlider.value); + +let previewPrompt = document.querySelector('#preview-prompt') + +let showConfigToggle = document.querySelector('#configToggleBtn') +// let configBox = document.querySelector('#config') +let outputMsg = document.querySelector('#outputMsg') +let progressBar = document.querySelector("#progressBar") + +let soundToggle = document.querySelector('#sound_toggle') + +let serverStatusColor = document.querySelector('#server-status-color') +let serverStatusMsg = document.querySelector('#server-status-msg') + +let advancedPanelHandle = document.querySelector("#editor-settings .collapsible") +let modifiersPanelHandle = document.querySelector("#editor-modifiers .collapsible") +let inpaintingEditorContainer = document.querySelector('#inpaintingEditor') +let inpaintingEditor = new DrawingBoard.Board('inpaintingEditor', { + color: "#ffffff", + background: false, + size: 30, + webStorage: false, + controls: [{'DrawingMode': {'filler': false}}, 'Size', 'Navigation'] +}) +let inpaintingEditorCanvasBackground = document.querySelector('.drawing-board-canvas-wrapper') + +document.querySelector('.drawing-board-control-navigation-back').innerHTML = '' +document.querySelector('.drawing-board-control-navigation-forward').innerHTML = '' + +let maskResetButton = document.querySelector('.drawing-board-control-navigation-reset') +maskResetButton.innerHTML = 'Clear' +maskResetButton.style.fontWeight = 'normal' +maskResetButton.style.fontSize = '10pt' + +let serverStatus = 'offline' +let activeTags = [] +let modifiers = [] +let lastPromptUsed = '' +let taskStopped = true +let batchesDone = 0 + +const modifierThumbnailPath = 'media/modifier-thumbnails'; +const activeCardClass = 'modifier-card-active'; + +function getLocalStorageItem(key, fallback) { + let item = localStorage.getItem(key) + if (item === null) { + return fallback + } + + return item +} + +function getLocalStorageBoolItem(key, fallback) { + let item = localStorage.getItem(key) + if (item === null) { + return fallback + } + + return (item === 'true' ? true : false) +} + +function handleBoolSettingChange(key) { + return function(e) { + localStorage.setItem(key, e.target.checked.toString()) + } +} + +function handleStringSettingChange(key) { + return function(e) { + localStorage.setItem(key, e.target.value.toString()) + } +} + +function isSoundEnabled() { + return getLocalStorageBoolItem(SOUND_ENABLED_KEY, true) +} + +function isFaceCorrectionEnabled() { + return getLocalStorageBoolItem(USE_FACE_CORRECTION_KEY, false) +} + +function isUpscalingEnabled() { + return getLocalStorageBoolItem(USE_UPSCALING_KEY, false) +} + +function isShowOnlyFilteredImageEnabled() { + return getLocalStorageBoolItem(SHOW_ONLY_FILTERED_IMAGE_KEY, true) +} + +function isSaveToDiskEnabled() { + return getLocalStorageBoolItem(SAVE_TO_DISK_KEY, false) +} + +function isUseCPUEnabled() { + return getLocalStorageBoolItem(USE_CPU_KEY, false) +} + +function isUseFullPrecisionEnabled() { + return getLocalStorageBoolItem(USE_FULL_PRECISION_KEY, false) +} + +function isUseTurboModeEnabled() { + return getLocalStorageBoolItem(USE_TURBO_MODE_KEY, true) +} + +function getSavedDiskPath() { + return getLocalStorageItem(DISK_PATH_KEY, '') +} + +function isAdvancedPanelOpenEnabled() { + return getLocalStorageBoolItem(ADVANCED_PANEL_OPEN_KEY, false) +} + +function isModifiersPanelOpenEnabled() { + return getLocalStorageBoolItem(MODIFIERS_PANEL_OPEN_KEY, false) +} + +function isStreamImageProgressEnabled() { + return getLocalStorageBoolItem(STREAM_IMAGE_PROGRESS_KEY, false) +} + +function setStatus(statusType, msg, msgType) { + if (statusType !== 'server') { + return; + } + + if (msgType == 'error') { + // msg = '' + msg + '' + serverStatusColor.style.color = 'red' + serverStatusMsg.style.color = 'red' + serverStatusMsg.innerText = 'Stable Diffusion has stopped' + } else if (msgType == 'success') { + // msg = '' + msg + '' + serverStatusColor.style.color = 'green' + serverStatusMsg.style.color = 'green' + serverStatusMsg.innerText = 'Stable Diffusion is ready' + serverStatus = 'online' + } +} + +function logMsg(msg, level) { + if (level === 'error') { + outputMsg.innerHTML = 'Error: ' + msg + '' + } else if (level === 'warn') { + outputMsg.innerHTML = 'Warning: ' + msg + '' + } else { + outputMsg.innerText = msg + } + + console.log(level, msg) +} + +function logError(msg, res) { + logMsg(msg, 'error') + + console.log('request error', res) + setStatus('request', 'error', 'error') +} + +function playSound() { + const audio = new Audio('/media/ding.mp3') + audio.volume = 0.2 + audio.play() +} + +async function healthCheck() { + try { + let res = await fetch('/ping') + res = await res.json() + + if (res[0] == 'OK') { + setStatus('server', 'online', 'success') + } else { + setStatus('server', 'offline', 'error') + } + } catch (e) { + setStatus('server', 'offline', 'error') + } +} + +function makeImageElement(width, height) { + let imgItem = document.createElement('div') + imgItem.className = 'imgItem' + + let img = document.createElement('img') + img.width = parseInt(width) + img.height = parseInt(height) + + imgItem.appendChild(img) + imagesContainer.appendChild(imgItem) + + return imgItem +} + +// makes a single image. don't call this directly, use makeImage() instead +async function doMakeImage(reqBody, batchCount) { + if (taskStopped) { + return + } + + let res = '' + let seed = reqBody['seed'] + let numOutputs = parseInt(reqBody['num_outputs']) + + let images = [] + + function makeImageContainers(numImages) { + for (let i = images.length; i < numImages; i++) { + images.push(makeImageElement(reqBody.width, reqBody.height)) + } + } + + try { + res = await fetch('/image', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(reqBody) + }) + + let reader = res.body.getReader() + let textDecoder = new TextDecoder() + let finalJSON = '' + let prevTime = -1 + while (true) { + try { + let t = new Date().getTime() + + const {value, done} = await reader.read() + if (done) { + break + } + + let timeTaken = (prevTime === -1 ? -1 : t - prevTime) + + let jsonStr = textDecoder.decode(value) + + try { + let stepUpdate = JSON.parse(jsonStr) + + if (stepUpdate.step === undefined) { + finalJSON += jsonStr + } else { + let batchSize = stepUpdate.total_steps + let overallStepCount = stepUpdate.step + batchesDone * batchSize + let totalSteps = batchCount * batchSize + let percent = 100 * (overallStepCount / totalSteps) + percent = (percent > 100 ? 100 : percent) + percent = percent.toFixed(0) + + stepsRemaining = totalSteps - overallStepCount + stepsRemaining = (stepsRemaining < 0 ? 0 : stepsRemaining) + timeRemaining = (timeTaken === -1 ? '' : stepsRemaining * timeTaken) // ms + + outputMsg.innerHTML = `Batch ${batchesDone+1} of ${batchCount}` + progressBar.innerHTML = `Generating image(s): ${percent}%` + + if (timeTaken !== -1) { + progressBar.innerHTML += `
Time remaining (approx): ${millisecondsToStr(timeRemaining)}` + } + progressBar.style.display = 'block' + + if (stepUpdate.output !== undefined) { + makeImageContainers(numOutputs) + + for (idx in stepUpdate.output) { + let imgItem = images[idx] + let img = imgItem.firstChild + let tmpImageData = stepUpdate.output[idx] + img.src = tmpImageData['path'] + '?t=' + new Date().getTime() + } + } + } + } catch (e) { + finalJSON += jsonStr + } + + prevTime = t + } catch (e) { + logError('Stable Diffusion had an error. Please check the logs in the command-line window.', res) + res = undefined + throw e + } + } + + if (res.status != 200) { + if (serverStatus === 'online') { + logError('Stable Diffusion had an error: ' + await res.text(), res) + } else { + logError("Stable Diffusion is still starting up, please wait. If this goes on beyond a few minutes, Stable Diffusion has probably crashed. Please check the error message in the command-line window.", res) + } + res = undefined + progressBar.style.display = 'none' + } else { + if (finalJSON !== undefined && finalJSON.indexOf('}{') !== -1) { + // hack for a middleman buffering all the streaming updates, and unleashing them + // on the poor browser in one shot. + // this results in having to parse JSON like {"step": 1}{"step": 2}...{"status": "succeeded"..} + // which is obviously invalid. + // So we need to just extract the last {} section, starting from "status" to the end of the response + + let lastChunkIdx = finalJSON.lastIndexOf('}{') + if (lastChunkIdx !== -1) { + let remaining = finalJSON.substring(lastChunkIdx) + finalJSON = remaining.substring(1) + } + } + + res = JSON.parse(finalJSON) + progressBar.style.display = 'none' + + if (res.status !== 'succeeded') { + let msg = '' + if (res.detail !== undefined) { + msg = res.detail + + if (msg.toLowerCase().includes('out of memory')) { + msg += `

+ Suggestions: +
+ 1. If you have set an initial image, please try reducing its dimension to ${MAX_INIT_IMAGE_DIMENSION}x${MAX_INIT_IMAGE_DIMENSION} or smaller.
+ 2. Try disabling the 'Turbo mode' under 'Advanced Settings'.
+ 3. Try generating a smaller image.
` + } + } else { + msg = res + } + logError(msg, res) + res = undefined + } + } + } catch (e) { + console.log('request error', e) + logError('Stable Diffusion had an error. Please check the logs in the command-line window.

' + e + '
' + e.stack + '
', res) + setStatus('request', 'error', 'error') + progressBar.style.display = 'none' + res = undefined + } + + if (!res) { + return false + } + + lastPromptUsed = reqBody['prompt'] + + makeImageContainers(res.output.length) + + for (let idx in res.output) { + let imgBody = '' + let seed = 0 + + try { + let imgData = res.output[idx] + imgBody = imgData.data + seed = imgData.seed + } catch (e) { + console.log(imgBody) + setStatus('request', 'invalid image', 'error') + continue + } + + let imgItem = images[idx] + let img = imgItem.firstChild + + img.src = imgBody + + let imgItemInfo = document.createElement('span') + imgItemInfo.className = 'imgItemInfo' + + let imgSeedLabel = document.createElement('span') + imgSeedLabel.className = 'imgSeedLabel' + imgSeedLabel.innerText = 'Seed: ' + seed + + let imgUseBtn = document.createElement('button') + imgUseBtn.className = 'imgUseBtn' + imgUseBtn.innerText = 'Use as Input' + + let imgSaveBtn = document.createElement('button') + imgSaveBtn.className = 'imgSaveBtn' + imgSaveBtn.innerText = 'Download' + + imgItem.appendChild(imgItemInfo) + imgItemInfo.appendChild(imgSeedLabel) + imgItemInfo.appendChild(imgUseBtn) + imgItemInfo.appendChild(imgSaveBtn) + + imgUseBtn.addEventListener('click', function() { + initImageSelector.value = null + initImagePreview.src = imgBody + + initImagePreviewContainer.style.display = 'block' + inpaintingEditorContainer.style.display = 'none' + promptStrengthContainer.style.display = 'block' + maskSetting.checked = false + + // maskSetting.style.display = 'block' + + randomSeedField.checked = false + seedField.value = seed + seedField.disabled = false + }) + + imgSaveBtn.addEventListener('click', function() { + let imgDownload = document.createElement('a') + imgDownload.download = createFileName(); + imgDownload.href = imgBody + imgDownload.click() + }) + + imgItem.addEventListener('mouseenter', function() { + imgItemInfo.style.opacity = 1 + }) + + imgItem.addEventListener('mouseleave', function() { + imgItemInfo.style.opacity = 0.5 + }) + } + + return true +} + +function validateInput() { + let width = parseInt(widthField.value) + let height = parseInt(heightField.value) + + if (IMAGE_REGEX.test(initImagePreview.src)) { + if (initImagePreview.naturalWidth > MAX_INIT_IMAGE_DIMENSION || initImagePreview.naturalHeight > MAX_INIT_IMAGE_DIMENSION) { + return {'isValid': false, 'warning': `The dimensions of your initial image are very large, and can cause 'Out of Memory' errors! Please ensure that its dimensions are equal (or smaller) than the desired output image. +

+ Your initial image size is ${initImagePreview.naturalWidth}x${initImagePreview.naturalHeight} pixels. Please try to keep it smaller than ${MAX_INIT_IMAGE_DIMENSION}x${MAX_INIT_IMAGE_DIMENSION}.`} + } + } + + return {'isValid': true} +} + +async function makeImage() { + if (serverStatus !== 'online') { + logError('The server is still starting up..') + return + } + + let validation = validateInput() + if (validation['isValid']) { + outputMsg.innerHTML = 'Starting..' + } else { + if (validation['error']) { + logError(validation['error']) + return + } else if (validation['warning']) { + logMsg(validation['warning'], 'warn') + } + } + + setStatus('request', 'fetching..') + + makeImageBtn.innerHTML = 'Processing..' + makeImageBtn.disabled = true + makeImageBtn.style.display = 'none' + stopImageBtn.style.display = 'block' + + taskStopped = false + batchesDone = 0 + + let seed = (randomSeedField.checked ? Math.floor(Math.random() * 10000000) : parseInt(seedField.value)) + let numOutputsTotal = parseInt(numOutputsTotalField.value) + let numOutputsParallel = parseInt(numOutputsParallelField.value) + let batchCount = Math.ceil(numOutputsTotal / numOutputsParallel) + let batchSize = numOutputsParallel + + let streamImageProgress = (numOutputsTotal > 50 ? false : streamImageProgressField.checked) + + let prompt = promptField.value + if (activeTags.length > 0) { + let promptTags = activeTags.map(x => x.name).join(", "); + prompt += ", " + promptTags; + } + + previewPrompt.innerText = prompt + + let reqBody = { + session_id: sessionId, + prompt: prompt, + num_outputs: batchSize, + num_inference_steps: numInferenceStepsField.value, + guidance_scale: guidanceScaleField.value, + width: widthField.value, + height: heightField.value, + // allow_nsfw: allowNSFWField.checked, + turbo: turboField.checked, + use_cpu: useCPUField.checked, + use_full_precision: useFullPrecisionField.checked, + stream_progress_updates: true, + stream_image_progress: streamImageProgress, + show_only_filtered_image: showOnlyFilteredImageField.checked + } + + if (IMAGE_REGEX.test(initImagePreview.src)) { + reqBody['init_image'] = initImagePreview.src + reqBody['prompt_strength'] = promptStrengthField.value + + // if (IMAGE_REGEX.test(maskImagePreview.src)) { + // reqBody['mask'] = maskImagePreview.src + // } + if (maskSetting.checked) { + reqBody['mask'] = inpaintingEditor.getImg() + } + + reqBody['sampler'] = 'ddim' + } else { + reqBody['sampler'] = samplerField.value + } + + if (saveToDiskField.checked && diskPathField.value.trim() !== '') { + reqBody['save_to_disk_path'] = diskPathField.value.trim() + } + + if (useFaceCorrectionField.checked) { + reqBody['use_face_correction'] = 'GFPGANv1.3' + } + + if (useUpscalingField.checked) { + reqBody['use_upscale'] = upscaleModelField.value + } + + let time = new Date().getTime() + imagesContainer.innerHTML = '' + + let successCount = 0 + + for (let i = 0; i < batchCount; i++) { + reqBody['seed'] = seed + (i * batchSize) + + let success = await doMakeImage(reqBody, batchCount) + batchesDone++ + + if (success) { + outputMsg.innerText = 'Processed batch ' + (i+1) + '/' + batchCount + successCount++ + } + } + + makeImageBtn.innerText = 'Make Image' + makeImageBtn.disabled = false + makeImageBtn.style.display = 'block' + stopImageBtn.style.display = 'none' + + if (isSoundEnabled()) { + playSound() + } + + time = new Date().getTime() - time + time /= 1000 + + if (successCount === batchCount) { + outputMsg.innerText = 'Processed ' + numOutputsTotal + ' images in ' + time + ' seconds' + + setStatus('request', 'done', 'success') + } + + if (randomSeedField.checked) { + seedField.value = seed + } +} + +// create a file name with embedded prompt and metadata +// for easier cateloging and comparison +function createFileName() { + + // Most important information is the prompt + let underscoreName = lastPromptUsed.replace(/[^a-zA-Z0-9]/g, '_') + underscoreName = underscoreName.substring(0, 100) + const seed = seedField.value + const steps = numInferenceStepsField.value + const guidance = guidanceScaleField.value + + // name and the top level metadata + let fileName = `${underscoreName}_Seed-${seed}_Steps-${steps}_Guidance-${guidance}` + + // add the tags + // let tags = []; + // let tagString = ''; + // document.querySelectorAll(modifyTagsSelector).forEach(function(tag) { + // tags.push(tag.innerHTML); + // }) + + // join the tags with a pipe + // if (activeTags.length > 0) { + // tagString = '_Tags-'; + // tagString += tags.join('|'); + // } + + // // append empty or populated tags + // fileName += `${tagString}`; + + // add the file extension + fileName += `.png` + + return fileName +} + +stopImageBtn.addEventListener('click', async function() { + try { + let res = await fetch('/image/stop') + } catch (e) { + console.log(e) + } + + stopImageBtn.style.display = 'none' + makeImageBtn.style.display = 'block' + + taskStopped = true +}) + +soundToggle.addEventListener('click', handleBoolSettingChange(SOUND_ENABLED_KEY)) +soundToggle.checked = isSoundEnabled() + +saveToDiskField.checked = isSaveToDiskEnabled() +diskPathField.disabled = !saveToDiskField.checked + +useFaceCorrectionField.addEventListener('click', handleBoolSettingChange(USE_FACE_CORRECTION_KEY)) +useFaceCorrectionField.checked = isFaceCorrectionEnabled() + +useUpscalingField.checked = isUpscalingEnabled() +upscaleModelField.disabled = !useUpscalingField.checked + +showOnlyFilteredImageField.addEventListener('click', handleBoolSettingChange(SHOW_ONLY_FILTERED_IMAGE_KEY)) +showOnlyFilteredImageField.checked = isShowOnlyFilteredImageEnabled() + +useCPUField.addEventListener('click', handleBoolSettingChange(USE_CPU_KEY)) +useCPUField.checked = isUseCPUEnabled() + +useFullPrecisionField.addEventListener('click', handleBoolSettingChange(USE_FULL_PRECISION_KEY)) +useFullPrecisionField.checked = isUseFullPrecisionEnabled() + +turboField.addEventListener('click', handleBoolSettingChange(USE_TURBO_MODE_KEY)) +turboField.checked = isUseTurboModeEnabled() + +streamImageProgressField.addEventListener('click', handleBoolSettingChange(STREAM_IMAGE_PROGRESS_KEY)) +streamImageProgressField.checked = isStreamImageProgressEnabled() + +diskPathField.addEventListener('change', handleStringSettingChange(DISK_PATH_KEY)) + +saveToDiskField.addEventListener('click', function(e) { + diskPathField.disabled = !this.checked + handleBoolSettingChange(SAVE_TO_DISK_KEY)(e) +}) + +useUpscalingField.addEventListener('click', function(e) { + upscaleModelField.disabled = !this.checked + handleBoolSettingChange(USE_UPSCALING_KEY)(e) +}) + +function setPanelOpen(panelHandle) { + let panelContents = panelHandle.nextElementSibling + panelHandle.classList.add('active') + panelContents.style.display = 'block' +} + +if (isAdvancedPanelOpenEnabled()) { + setPanelOpen(advancedPanelHandle) +} + +if (isModifiersPanelOpenEnabled()) { + setPanelOpen(modifiersPanelHandle) +} + +makeImageBtn.addEventListener('click', makeImage) + + +function updateGuidanceScale() { + guidanceScaleField.value = guidanceScaleSlider.value / 10 +} + +function updateGuidanceScaleSlider() { + if (guidanceScaleField.value < 0) { + guidanceScaleField.value = 0 + } else if (guidanceScaleField.value > 50) { + guidanceScaleField.value = 50 + } + + guidanceScaleSlider.value = guidanceScaleField.value * 10 +} + +guidanceScaleSlider.addEventListener('input', updateGuidanceScale) +guidanceScaleField.addEventListener('input', updateGuidanceScaleSlider) +updateGuidanceScale() + +function updatePromptStrength() { + promptStrengthField.value = promptStrengthSlider.value / 100 +} + +function updatePromptStrengthSlider() { + if (promptStrengthField.value < 0) { + promptStrengthField.value = 0 + } else if (promptStrengthField.value > 0.99) { + promptStrengthField.value = 0.99 + } + + promptStrengthSlider.value = promptStrengthField.value * 100 +} + +promptStrengthSlider.addEventListener('input', updatePromptStrength) +promptStrengthField.addEventListener('input', updatePromptStrengthSlider) +updatePromptStrength() + +useBetaChannelField.addEventListener('click', async function(e) { + if (serverStatus !== 'online') { + logError('The server is still starting up..') + alert('The server is still starting up..') + e.preventDefault() + return false + } + + let updateBranch = (this.checked ? 'beta' : 'main') + + try { + let res = await fetch('/app_config', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + 'update_branch': updateBranch + }) + }) + res = await res.json() + + console.log('set config status response', res) + } catch (e) { + console.log('set config status error', e) + } +}) + +async function getAppConfig() { + try { + let res = await fetch('/app_config') + config = await res.json() + + if (config.update_branch === 'beta') { + useBetaChannelField.checked = true + updateBranchLabel.innerText = "(beta)" + } + + console.log('get config status response', config) + } catch (e) { + console.log('get config status error', e) + } +} + +function checkRandomSeed() { + if (randomSeedField.checked) { + seedField.disabled = true + seedField.value = "0" + } else { + seedField.disabled = false + } +} +randomSeedField.addEventListener('input', checkRandomSeed) +checkRandomSeed() + +function showInitImagePreview() { + if (initImageSelector.files.length === 0) { + initImagePreviewContainer.style.display = 'none' + // inpaintingEditorContainer.style.display = 'none' + promptStrengthContainer.style.display = 'none' + // maskSetting.style.display = 'none' + return + } + + let reader = new FileReader() + let file = initImageSelector.files[0] + + reader.addEventListener('load', function() { + // console.log(file.name, reader.result) + initImagePreview.src = reader.result + initImagePreviewContainer.style.display = 'block' + inpaintingEditorContainer.style.display = 'none' + promptStrengthContainer.style.display = 'block' + samplerSelectionContainer.style.display = 'none' + // maskSetting.checked = false + }) + + if (file) { + reader.readAsDataURL(file) + } +} +initImageSelector.addEventListener('change', showInitImagePreview) +showInitImagePreview() + +initImagePreview.addEventListener('load', function() { + inpaintingEditorCanvasBackground.style.backgroundImage = "url('" + this.src + "')" + // maskSetting.style.display = 'block' + // inpaintingEditorContainer.style.display = 'block' +}) + +initImageClearBtn.addEventListener('click', function() { + initImageSelector.value = null + // maskImageSelector.value = null + + initImagePreview.src = '' + // maskImagePreview.src = '' + maskSetting.checked = false + + initImagePreviewContainer.style.display = 'none' + // inpaintingEditorContainer.style.display = 'none' + // maskImagePreviewContainer.style.display = 'none' + + // maskSetting.style.display = 'none' + + promptStrengthContainer.style.display = 'none' + samplerSelectionContainer.style.display = 'block' +}) + +maskSetting.addEventListener('click', function() { + inpaintingEditorContainer.style.display = (this.checked ? 'block' : 'none') +}) + +// function showMaskImagePreview() { +// if (maskImageSelector.files.length === 0) { +// // maskImagePreviewContainer.style.display = 'none' +// return +// } + +// let reader = new FileReader() +// let file = maskImageSelector.files[0] + +// reader.addEventListener('load', function() { +// // maskImagePreview.src = reader.result +// // maskImagePreviewContainer.style.display = 'block' +// }) + +// if (file) { +// reader.readAsDataURL(file) +// } +// } +// maskImageSelector.addEventListener('change', showMaskImagePreview) +// showMaskImagePreview() + +// maskImageClearBtn.addEventListener('click', function() { +// maskImageSelector.value = null +// maskImagePreview.src = '' +// // maskImagePreviewContainer.style.display = 'none' +// }) + +// https://stackoverflow.com/a/8212878 +function millisecondsToStr(milliseconds) { + function numberEnding (number) { + return (number > 1) ? 's' : ''; + } + + var temp = Math.floor(milliseconds / 1000); + var hours = Math.floor((temp %= 86400) / 3600); + var s = '' + if (hours) { + s += hours + ' hour' + numberEnding(hours) + ' '; + } + var minutes = Math.floor((temp %= 3600) / 60); + if (minutes) { + s += minutes + ' minute' + numberEnding(minutes) + ' '; + } + var seconds = temp % 60; + if (!hours && minutes < 4 && seconds) { + s += seconds + ' second' + numberEnding(seconds); + } + + return s; +} + +function createCollapsibles(node) { + if (!node) { + node = document + } + + let collapsibles = node.querySelectorAll(".collapsible") + collapsibles.forEach(function(c) { + let handle = document.createElement('span') + handle.className = 'collapsible-handle' + + if (c.className.indexOf('active') !== -1) { + handle.innerHTML = '➖' // minus + } else { + handle.innerHTML = '➕' // plus + } + c.insertBefore(handle, c.firstChild) + + c.addEventListener('click', function() { + this.classList.toggle("active") + let content = this.nextElementSibling + if (content.style.display === "block") { + content.style.display = "none" + handle.innerHTML = '➕' // plus + } else { + content.style.display = "block" + handle.innerHTML = '➖' // minus + } + + if (this == advancedPanelHandle) { + let state = (content.style.display === 'block' ? 'true' : 'false') + localStorage.setItem(ADVANCED_PANEL_OPEN_KEY, state) + } else if (this == modifiersPanelHandle) { + let state = (content.style.display === 'block' ? 'true' : 'false') + localStorage.setItem(MODIFIERS_PANEL_OPEN_KEY, state) + } + }) + }) +} +createCollapsibles() + +function refreshTagsList() { + editorModifierTagsList.innerHTML = ''; + + if (activeTags.length == 0) { + editorTagsContainer.style.display = 'none'; + return; + } else { + editorTagsContainer.style.display = 'block'; + } + + activeTags.forEach((tag, index) => { + tag.element.querySelector('.modifier-card-image-overlay').innerText = '-'; + tag.element.classList.add('modifier-card-tiny'); + + editorModifierTagsList.appendChild(tag.element); + + tag.element.addEventListener('click', () => { + let idx = activeTags.indexOf(tag); + + if (idx !== -1) { + activeTags[idx].originElement.classList.remove(activeCardClass); + activeTags[idx].originElement.querySelector('.modifier-card-image-overlay').innerText = '+'; + + activeTags.splice(idx, 1); + refreshTagsList(); + } + }); + }); + + let brk = document.createElement('br') + brk.style.clear = 'both' + editorModifierTagsList.appendChild(brk) +} + +async function getDiskPath() { + try { + let diskPath = getSavedDiskPath() + + if (diskPath !== '') { + diskPathField.value = diskPath + return + } + + let res = await fetch('/output_dir') + if (res.status === 200) { + res = await res.json() + res = res[0] + + document.querySelector('#diskPath').value = res + } + } catch (e) { + console.log('error fetching output dir path', e) + } +} + +function createModifierCard(name, previews) { + const modifierCard = document.createElement('div'); + modifierCard.className = 'modifier-card'; + modifierCard.innerHTML = ` +
+
+
+
+

+ Modifier Image +
+
+

+
`; + + const image = modifierCard.querySelector('.modifier-card-image'); + const errorText = modifierCard.querySelector('.modifier-card-error-label'); + const label = modifierCard.querySelector('.modifier-card-label'); + + errorText.innerText = 'No Image'; + + if (typeof previews == 'object') { + image.src = previews[0]; // portrait + image.setAttribute('preview-type', 'portrait'); + } else { + image.remove(); + } + + const maxLabelLength = 30; + const nameWithoutBy = name.replace('by ', ''); + + if(nameWithoutBy.length <= maxLabelLength) { + label.querySelector('p').innerText = nameWithoutBy; + } else { + const tooltipText = document.createElement('span'); + tooltipText.className = 'tooltip-text'; + tooltipText.innerText = name; + + label.classList.add('tooltip'); + label.appendChild(tooltipText); + + label.querySelector('p').innerText = nameWithoutBy.substring(0, maxLabelLength) + '...'; + } + + return modifierCard; +} + +function changePreviewImages(val) { + const previewImages = document.querySelectorAll('.modifier-card-image-container img'); + + let previewArr = []; + + modifiers.map(x => x.modifiers).forEach(x => previewArr.push(...x.map(m => m.previews))); + + previewArr = previewArr.map(x => { + let obj = {}; + + x.forEach(preview => { + obj[preview.name] = preview.path; + }); + + return obj; + }); + + previewImages.forEach(previewImage => { + const currentPreviewType = previewImage.getAttribute('preview-type'); + const relativePreviewPath = previewImage.src.split(modifierThumbnailPath + '/').pop(); + + const previews = previewArr.find(preview => relativePreviewPath == preview[currentPreviewType]); + + if(typeof previews == 'object') { + let preview = null; + + if (val == 'portrait') { + preview = previews.portrait; + } + else if (val == 'landscape') { + preview = previews.landscape; + } + + if(preview != null) { + previewImage.src = `${modifierThumbnailPath}/${preview}`; + previewImage.setAttribute('preview-type', val); + } + } + }); +} + +function resizeModifierCards(val) { + const cardSizePrefix = 'modifier-card-size_'; + const modifierCardClass = 'modifier-card'; + + const modifierCards = document.querySelectorAll(`.${modifierCardClass}`); + const cardSize = n => `${cardSizePrefix}${n}`; + + modifierCards.forEach(card => { + // remove existing size classes + const classes = card.className.split(' ').filter(c => !c.startsWith(cardSizePrefix)); + card.className = classes.join(' ').trim(); + + if(val != 0) + card.classList.add(cardSize(val)); + }); +} + +async function loadModifiers() { + try { + let res = await fetch('/modifiers.json?v=2') + if (res.status === 200) { + res = await res.json() + + modifiers = res; // update global variable + + res.forEach((modifierGroup, idx) => { + const title = modifierGroup.category; + const modifiers = modifierGroup.modifiers; + + const titleEl = document.createElement('h5'); + titleEl.className = 'collapsible'; + titleEl.innerText = title; + + const modifiersEl = document.createElement('div'); + modifiersEl.classList.add('collapsible-content', 'editor-modifiers-leaf'); + + if (idx == 0) { + titleEl.className += ' active' + modifiersEl.style.display = 'block' + } + + modifiers.forEach(modObj => { + const modifierName = modObj.modifier; + const modifierPreviews = modObj?.previews?.map(preview => `${modifierThumbnailPath}/${preview.path}`); + + const modifierCard = createModifierCard(modifierName, modifierPreviews); + + if(typeof modifierCard == 'object') { + modifiersEl.appendChild(modifierCard); + + modifierCard.addEventListener('click', () => { + if (activeTags.map(x => x.name).includes(modifierName)) { + // remove modifier from active array + activeTags = activeTags.filter(x => x.name != modifierName); + modifierCard.classList.remove(activeCardClass); + + modifierCard.querySelector('.modifier-card-image-overlay').innerText = '+'; + } else { + // add modifier to active array + activeTags.push({ + 'name': modifierName, + 'element': modifierCard.cloneNode(true), + 'originElement': modifierCard, + 'previews': modifierPreviews + }); + + modifierCard.classList.add(activeCardClass); + + modifierCard.querySelector('.modifier-card-image-overlay').innerText = '-'; + } + + refreshTagsList(); + }); + } + }); + + let brk = document.createElement('br') + brk.style.clear = 'both' + modifiersEl.appendChild(brk) + + let e = document.createElement('div') + e.appendChild(titleEl) + e.appendChild(modifiersEl) + + editorModifierEntries.appendChild(e) + }) + + createCollapsibles(editorModifierEntries) + } + } catch (e) { + console.log('error fetching modifiers', e) + } +} diff --git a/ui/media/modifier-thumbnails.css b/ui/media/modifier-thumbnails.css new file mode 100644 index 00000000..22af3083 --- /dev/null +++ b/ui/media/modifier-thumbnails.css @@ -0,0 +1,216 @@ +.modifier-card { + box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); + transition: 0.1s; + border-radius: 7px; + margin: 3pt 3pt; + float: left; + width: 8em; + height: 11.5em; + display: grid; + grid-template-columns: 1fr; + grid-template-rows: 8em 3.5em; + gap: 0px 0px; + grid-auto-flow: row; + grid-template-areas: + "modifier-card-image-container" + "modifier-card-container"; + border: 2px solid rgba(255, 255, 255, .05); + cursor: pointer; +} +.modifier-card-size_5 { + width: 18em; + grid-template-rows: 18em 3.5em; + height: 21.5em; +} +.modifier-card-size_5 .modifier-card-image-overlay { + font-size: 8em; +} +.modifier-card-size_4 { + width: 14em; + grid-template-rows: 14em 3.5em; + height: 17.5em; +} +.modifier-card-size_4 .modifier-card-image-overlay { + font-size: 7em; +} +.modifier-card-size_3 { + width: 11em; + grid-template-rows: 11em 3.5em; + height: 14.5em; +} +.modifier-card-size_3 .modifier-card-image-overlay { + font-size: 6em; +} +.modifier-card-size_2 { + width: 10em; + grid-template-rows: 10em 3.5em; + height: 13.5em; +} +.modifier-card-size_2 .modifier-card-image-overlay { + font-size: 6em; +} +.modifier-card-size_1 { + width: 9em; + grid-template-rows: 9em 3.5em; + height: 12.5em; +} +.modifier-card-size_1 .modifier-card-image-overlay { + font-size: 5em; +} +.modifier-card-size_-1 { + width: 7em; + grid-template-rows: 7em 3.5em; + height: 10.5em; +} +.modifier-card-size_-1 .modifier-card-image-overlay { + font-size: 4em; +} +.modifier-card-size_-2 { + width: 6em; + grid-template-rows: 6em 3.5em; + height: 9.5em; +} +.modifier-card-size_-2 .modifier-card-image-overlay { + font-size: 3em; +} +.modifier-card-size_-3 { + width: 5em; + grid-template-rows: 5em 3.5em; + height: 8.5em; +} +.modifier-card-size_-3 .modifier-card-image-overlay { + font-size: 3em; +} +.modifier-card-size_-3 .modifier-card-label { + font-size: 0.8em; +} +.modifier-card-tiny { + width: 6em; + height: 9.5em; + grid-template-rows: 6em 3.5em; +} +.modifier-card-tiny .modifier-card-image-overlay { + font-size: 4em; +} +.modifier-card:hover { + transform: scale(1.05); + box-shadow: 0 5px 16px 5px rgba(0, 0, 0, 0.25); +} +.modifier-card-image-container { + border-radius: 5px 5px 0 0; + width: inherit; + height: 100%; + background-color: rgba(0, 0, 0, .2); + grid-area: modifier-card-image-container; + position: relative; + display: flex; + align-items: center; + justify-content: center; + color: rgb(255 255 255 / 8%); +} +.modifier-card-image-container img { + width: inherit; + height: 100%; + border-radius: 5px 5px 0 0; +} +.modifier-card-image-container * { + position: absolute; +} +.modifier-card-container { + text-align: center; + background-color: rgba(0,0,0,0.5); + border-radius: 0 0 5px 5px; + display: flex; + justify-content: center; + align-items: center; + grid-area: modifier-card-container; + font-weight: 100; + font-size: .9em; + width: inherit; +} +.modifier-card-label { + padding: 4px; + word-break: break-word; +} +.modifier-card-image-overlay { + width: inherit; + height: inherit; + background-color: rgb(0 0 0 / 50%); + z-index: 2; + position: absolute; + border-radius: 5px 5px 0 0; + opacity: 0; + font-size: 5em; + font-weight: 900; + color: rgb(255 255 255 / 50%); + display: flex; + align-items: center; + justify-content: center; +} +.modifier-card-overlay { + width: inherit; + height: inherit; + position: absolute; + z-index: 3; +} +.modifier-card:hover > .modifier-card-image-container .modifier-card-image-overlay { + opacity: 1; +} +.modifier-card:hover > .modifier-card-image-container img { + filter: blur(.1em); +} +.modifier-card:active { + transform: scale(0.95); + box-shadow: 0 5px 16px 5px rgba(0, 0, 0, 0.5); +} +#preview-image { + margin-top: 0.5em; + margin-bottom: 0.5em; +} +.modifier-card-active { + border: 2px solid rgb(179 82 255 / 94%); + box-shadow: 0 0px 10px 0 rgb(170 0 229 / 58%); +} +.tooltip { + position: relative; + display: inline-block; +} +.tooltip .tooltip-text { + visibility: hidden; + width: 120px; + background: rgb(101,97,181); + background: linear-gradient(180deg, rgba(101,97,181,1) 0%, rgba(47,45,85,1) 100%); + color: #fff; + text-align: center; + border-radius: 6px; + padding: 5px; + position: absolute; + z-index: 1; + top: 105%; + left: 39%; + margin-left: -60px; + opacity: 0; + transition: opacity 0.3s; + border: 2px solid rgb(90 100 177 / 94%); + box-shadow: 0px 10px 20px 5px rgb(11 0 58 / 55%); + width: 10em; +} +.tooltip .tooltip-text::after { + content: ""; + position: absolute; + top: -0.9em; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: transparent transparent rgb(90 100 177 / 94%) transparent; +} +.tooltip:hover .tooltip-text { + visibility: visible; + opacity: 1; +} +#modifier-card-size-slider { + width: 6em; + margin-bottom: 0.5em; + vertical-align: middle; +} diff --git a/ui/media/modifier-thumbnails/artist/artstation/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/artstation/landscape-0.jpg new file mode 100644 index 00000000..66bb6606 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/artstation/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/artstation/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/artstation/portrait-0.jpg new file mode 100644 index 00000000..ab66239f Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/artstation/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_agnes_lawrence_pelton/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_agnes_lawrence_pelton/landscape-0.jpg new file mode 100644 index 00000000..06ba6e97 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_agnes_lawrence_pelton/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_agnes_lawrence_pelton/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_agnes_lawrence_pelton/portrait-0.jpg new file mode 100644 index 00000000..39a757af Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_agnes_lawrence_pelton/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_akihito_yoshida/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_akihito_yoshida/landscape-0.jpg new file mode 100644 index 00000000..ef89ca57 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_akihito_yoshida/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_akihito_yoshida/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_akihito_yoshida/portrait-0.jpg new file mode 100644 index 00000000..008cba8f Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_akihito_yoshida/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_alex_grey/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_alex_grey/landscape-0.jpg new file mode 100644 index 00000000..50a7b7fa Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_alex_grey/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_alex_grey/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_alex_grey/portrait-0.jpg new file mode 100644 index 00000000..465d892a Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_alex_grey/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_alexander_jansson/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_alexander_jansson/landscape-0.jpg new file mode 100644 index 00000000..b99ed16e Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_alexander_jansson/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_alexander_jansson/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_alexander_jansson/portrait-0.jpg new file mode 100644 index 00000000..c27a25ed Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_alexander_jansson/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_alphonse_mucha/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_alphonse_mucha/landscape-0.jpg new file mode 100644 index 00000000..2d170e1b Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_alphonse_mucha/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_alphonse_mucha/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_alphonse_mucha/portrait-0.jpg new file mode 100644 index 00000000..aa07839b Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_alphonse_mucha/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_andy_warhol/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_andy_warhol/landscape-0.jpg new file mode 100644 index 00000000..480aa3cc Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_andy_warhol/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_andy_warhol/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_andy_warhol/portrait-0.jpg new file mode 100644 index 00000000..a8c1ee6c Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_andy_warhol/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_artgerm/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_artgerm/landscape-0.jpg new file mode 100644 index 00000000..a96a0e69 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_artgerm/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_artgerm/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_artgerm/portrait-0.jpg new file mode 100644 index 00000000..e7f2e2b3 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_artgerm/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_asaf_hanuka/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_asaf_hanuka/landscape-0.jpg new file mode 100644 index 00000000..a8443268 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_asaf_hanuka/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_asaf_hanuka/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_asaf_hanuka/portrait-0.jpg new file mode 100644 index 00000000..3775a2fa Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_asaf_hanuka/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_aubrey_beardsley/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_aubrey_beardsley/landscape-0.jpg new file mode 100644 index 00000000..ae388a25 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_aubrey_beardsley/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_aubrey_beardsley/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_aubrey_beardsley/portrait-0.jpg new file mode 100644 index 00000000..da3fe32d Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_aubrey_beardsley/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_banksy/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_banksy/landscape-0.jpg new file mode 100644 index 00000000..a3b6d562 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_banksy/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_banksy/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_banksy/portrait-0.jpg new file mode 100644 index 00000000..45b5f808 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_banksy/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_beeple/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_beeple/landscape-0.jpg new file mode 100644 index 00000000..984ee5e0 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_beeple/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_beeple/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_beeple/portrait-0.jpg new file mode 100644 index 00000000..91546ba6 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_beeple/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_ben_enwonwu/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_ben_enwonwu/landscape-0.jpg new file mode 100644 index 00000000..9d183d4e Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_ben_enwonwu/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_ben_enwonwu/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_ben_enwonwu/portrait-0.jpg new file mode 100644 index 00000000..66f45838 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_ben_enwonwu/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_bob_eggleton/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_bob_eggleton/landscape-0.jpg new file mode 100644 index 00000000..ee7b32fb Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_bob_eggleton/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_bob_eggleton/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_bob_eggleton/portrait-0.jpg new file mode 100644 index 00000000..6df2a4af Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_bob_eggleton/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_caravaggio_michelangelo_merisi/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_caravaggio_michelangelo_merisi/landscape-0.jpg new file mode 100644 index 00000000..c71e98f5 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_caravaggio_michelangelo_merisi/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_caravaggio_michelangelo_merisi/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_caravaggio_michelangelo_merisi/portrait-0.jpg new file mode 100644 index 00000000..50ec70c6 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_caravaggio_michelangelo_merisi/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_caspar_david_friedrich/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_caspar_david_friedrich/landscape-0.jpg new file mode 100644 index 00000000..e141286e Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_caspar_david_friedrich/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_caspar_david_friedrich/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_caspar_david_friedrich/portrait-0.jpg new file mode 100644 index 00000000..7ae777c5 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_caspar_david_friedrich/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_chris_foss/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_chris_foss/landscape-0.jpg new file mode 100644 index 00000000..9e4faa61 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_chris_foss/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_chris_foss/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_chris_foss/portrait-0.jpg new file mode 100644 index 00000000..a6bc604e Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_chris_foss/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_claude_monet/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_claude_monet/landscape-0.jpg new file mode 100644 index 00000000..1a1ddc05 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_claude_monet/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_claude_monet/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_claude_monet/portrait-0.jpg new file mode 100644 index 00000000..1a18a042 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_claude_monet/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_dan_mumford/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_dan_mumford/landscape-0.jpg new file mode 100644 index 00000000..0ac12bc5 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_dan_mumford/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_dan_mumford/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_dan_mumford/portrait-0.jpg new file mode 100644 index 00000000..32f1ce24 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_dan_mumford/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_david_mann/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_david_mann/landscape-0.jpg new file mode 100644 index 00000000..eed7c8ad Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_david_mann/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_david_mann/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_david_mann/portrait-0.jpg new file mode 100644 index 00000000..f3810f81 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_david_mann/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_diego_vela_zquez/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_diego_vela_zquez/landscape-0.jpg new file mode 100644 index 00000000..3a957469 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_diego_vela_zquez/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_diego_vela_zquez/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_diego_vela_zquez/portrait-0.jpg new file mode 100644 index 00000000..43306a99 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_diego_vela_zquez/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_disney_animation_studios/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_disney_animation_studios/landscape-0.jpg new file mode 100644 index 00000000..ecaa33e8 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_disney_animation_studios/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_disney_animation_studios/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_disney_animation_studios/portrait-0.jpg new file mode 100644 index 00000000..08f20864 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_disney_animation_studios/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_e_douard_manet/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_e_douard_manet/landscape-0.jpg new file mode 100644 index 00000000..2e02199b Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_e_douard_manet/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_e_douard_manet/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_e_douard_manet/portrait-0.jpg new file mode 100644 index 00000000..e2161865 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_e_douard_manet/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_esao_andrews/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_esao_andrews/landscape-0.jpg new file mode 100644 index 00000000..b2c58b22 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_esao_andrews/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_esao_andrews/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_esao_andrews/portrait-0.jpg new file mode 100644 index 00000000..b3628d55 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_esao_andrews/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_frida_kahlo/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_frida_kahlo/landscape-0.jpg new file mode 100644 index 00000000..a6d66b4b Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_frida_kahlo/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_frida_kahlo/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_frida_kahlo/portrait-0.jpg new file mode 100644 index 00000000..dc8d2004 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_frida_kahlo/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_gediminas_pranckevicius/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_gediminas_pranckevicius/landscape-0.jpg new file mode 100644 index 00000000..cde1099c Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_gediminas_pranckevicius/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_gediminas_pranckevicius/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_gediminas_pranckevicius/portrait-0.jpg new file mode 100644 index 00000000..89f9fce2 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_gediminas_pranckevicius/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_georgia_o_keeffe/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_georgia_o_keeffe/landscape-0.jpg new file mode 100644 index 00000000..f374b239 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_georgia_o_keeffe/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_georgia_o_keeffe/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_georgia_o_keeffe/portrait-0.jpg new file mode 100644 index 00000000..26675244 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_georgia_o_keeffe/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_greg_rutkowski/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_greg_rutkowski/landscape-0.jpg new file mode 100644 index 00000000..65a6bc39 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_greg_rutkowski/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_greg_rutkowski/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_greg_rutkowski/portrait-0.jpg new file mode 100644 index 00000000..c5b7db7f Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_greg_rutkowski/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_gustave_dore_/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_gustave_dore_/landscape-0.jpg new file mode 100644 index 00000000..70f9acf0 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_gustave_dore_/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_gustave_dore_/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_gustave_dore_/portrait-0.jpg new file mode 100644 index 00000000..541fbad6 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_gustave_dore_/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_gustave_klimt/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_gustave_klimt/landscape-0.jpg new file mode 100644 index 00000000..00b13cd0 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_gustave_klimt/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_gustave_klimt/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_gustave_klimt/portrait-0.jpg new file mode 100644 index 00000000..8460065f Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_gustave_klimt/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_h_r_giger/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_h_r_giger/landscape-0.jpg new file mode 100644 index 00000000..c7255ed7 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_h_r_giger/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_h_r_giger/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_h_r_giger/portrait-0.jpg new file mode 100644 index 00000000..eca5d6e5 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_h_r_giger/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_hayao_miyazaki/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_hayao_miyazaki/landscape-0.jpg new file mode 100644 index 00000000..a975ce01 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_hayao_miyazaki/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_hayao_miyazaki/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_hayao_miyazaki/portrait-0.jpg new file mode 100644 index 00000000..ec758dd6 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_hayao_miyazaki/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_henri_matisse/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_henri_matisse/landscape-0.jpg new file mode 100644 index 00000000..8361f88d Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_henri_matisse/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_henri_matisse/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_henri_matisse/portrait-0.jpg new file mode 100644 index 00000000..31c0ae89 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_henri_matisse/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_hp_lovecraft/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_hp_lovecraft/landscape-0.jpg new file mode 100644 index 00000000..bf630c7e Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_hp_lovecraft/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_hp_lovecraft/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_hp_lovecraft/portrait-0.jpg new file mode 100644 index 00000000..820233bc Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_hp_lovecraft/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_ivan_shishkin/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_ivan_shishkin/landscape-0.jpg new file mode 100644 index 00000000..5847701c Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_ivan_shishkin/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_ivan_shishkin/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_ivan_shishkin/portrait-0.jpg new file mode 100644 index 00000000..cc7d850d Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_ivan_shishkin/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_jack_kirby/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_jack_kirby/landscape-0.jpg new file mode 100644 index 00000000..f2c079f2 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_jack_kirby/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_jack_kirby/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_jack_kirby/portrait-0.jpg new file mode 100644 index 00000000..cc6bed88 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_jack_kirby/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_jackson_pollock/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_jackson_pollock/landscape-0.jpg new file mode 100644 index 00000000..a83d9b17 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_jackson_pollock/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_jackson_pollock/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_jackson_pollock/portrait-0.jpg new file mode 100644 index 00000000..c1be354d Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_jackson_pollock/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_james_jean/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_james_jean/landscape-0.jpg new file mode 100644 index 00000000..8e6cb008 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_james_jean/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_james_jean/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_james_jean/portrait-0.jpg new file mode 100644 index 00000000..9fe5fd1a Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_james_jean/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_jim_burns/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_jim_burns/landscape-0.jpg new file mode 100644 index 00000000..4158915b Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_jim_burns/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_jim_burns/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_jim_burns/portrait-0.jpg new file mode 100644 index 00000000..fbaf00b5 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_jim_burns/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_johannes_vermeer/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_johannes_vermeer/landscape-0.jpg new file mode 100644 index 00000000..be39bf44 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_johannes_vermeer/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_johannes_vermeer/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_johannes_vermeer/portrait-0.jpg new file mode 100644 index 00000000..8aeef0a9 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_johannes_vermeer/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_john_william_waterhouse/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_john_william_waterhouse/landscape-0.jpg new file mode 100644 index 00000000..97fe5e61 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_john_william_waterhouse/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_john_william_waterhouse/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_john_william_waterhouse/portrait-0.jpg new file mode 100644 index 00000000..e735dec0 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_john_william_waterhouse/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_katsushika_hokusai/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_katsushika_hokusai/landscape-0.jpg new file mode 100644 index 00000000..23a9f4ec Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_katsushika_hokusai/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_katsushika_hokusai/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_katsushika_hokusai/portrait-0.jpg new file mode 100644 index 00000000..1a479148 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_katsushika_hokusai/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_kim_tschang_yeul/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_kim_tschang_yeul/landscape-0.jpg new file mode 100644 index 00000000..281eab8f Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_kim_tschang_yeul/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_kim_tschang_yeul/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_kim_tschang_yeul/portrait-0.jpg new file mode 100644 index 00000000..1e914a0d Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_kim_tschang_yeul/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_ko_young_hoon/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_ko_young_hoon/landscape-0.jpg new file mode 100644 index 00000000..34bcb6ac Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_ko_young_hoon/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_ko_young_hoon/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_ko_young_hoon/portrait-0.jpg new file mode 100644 index 00000000..ed22e9cf Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_ko_young_hoon/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_leonardo_da_vinci/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_leonardo_da_vinci/landscape-0.jpg new file mode 100644 index 00000000..d0408007 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_leonardo_da_vinci/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_leonardo_da_vinci/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_leonardo_da_vinci/portrait-0.jpg new file mode 100644 index 00000000..01c8881d Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_leonardo_da_vinci/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_lisa_frank/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_lisa_frank/landscape-0.jpg new file mode 100644 index 00000000..f21f0e2f Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_lisa_frank/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_lisa_frank/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_lisa_frank/portrait-0.jpg new file mode 100644 index 00000000..5ff81a89 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_lisa_frank/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_m_c_escher/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_m_c_escher/landscape-0.jpg new file mode 100644 index 00000000..90dda89d Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_m_c_escher/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_m_c_escher/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_m_c_escher/portrait-0.jpg new file mode 100644 index 00000000..cfe78a3f Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_m_c_escher/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_mahmoud_sai_d/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_mahmoud_sai_d/landscape-0.jpg new file mode 100644 index 00000000..4955bb28 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_mahmoud_sai_d/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_mahmoud_sai_d/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_mahmoud_sai_d/portrait-0.jpg new file mode 100644 index 00000000..f0ddbd04 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_mahmoud_sai_d/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_makoto_shinkai/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_makoto_shinkai/landscape-0.jpg new file mode 100644 index 00000000..85634b10 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_makoto_shinkai/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_makoto_shinkai/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_makoto_shinkai/portrait-0.jpg new file mode 100644 index 00000000..3551f282 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_makoto_shinkai/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_marc_simonetti/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_marc_simonetti/landscape-0.jpg new file mode 100644 index 00000000..57d3e308 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_marc_simonetti/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_marc_simonetti/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_marc_simonetti/portrait-0.jpg new file mode 100644 index 00000000..7722a813 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_marc_simonetti/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_mark_brooks/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_mark_brooks/landscape-0.jpg new file mode 100644 index 00000000..5cdb1681 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_mark_brooks/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_mark_brooks/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_mark_brooks/portrait-0.jpg new file mode 100644 index 00000000..76200b79 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_mark_brooks/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_michelangelo/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_michelangelo/landscape-0.jpg new file mode 100644 index 00000000..e64d6c87 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_michelangelo/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_michelangelo/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_michelangelo/portrait-0.jpg new file mode 100644 index 00000000..0b99fe85 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_michelangelo/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_pablo_picasso/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_pablo_picasso/landscape-0.jpg new file mode 100644 index 00000000..c00b8278 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_pablo_picasso/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_pablo_picasso/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_pablo_picasso/portrait-0.jpg new file mode 100644 index 00000000..5932b9d1 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_pablo_picasso/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_paul_klee/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_paul_klee/landscape-0.jpg new file mode 100644 index 00000000..b753e9e0 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_paul_klee/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_paul_klee/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_paul_klee/portrait-0.jpg new file mode 100644 index 00000000..a6d9803b Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_paul_klee/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_peter_mohrbacher/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_peter_mohrbacher/landscape-0.jpg new file mode 100644 index 00000000..d1400bf3 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_peter_mohrbacher/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_peter_mohrbacher/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_peter_mohrbacher/portrait-0.jpg new file mode 100644 index 00000000..85b6c887 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_peter_mohrbacher/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_pierre-auguste_renoir/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_pierre-auguste_renoir/landscape-0.jpg new file mode 100644 index 00000000..f7219bf4 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_pierre-auguste_renoir/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_pierre-auguste_renoir/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_pierre-auguste_renoir/portrait-0.jpg new file mode 100644 index 00000000..c4d6e715 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_pierre-auguste_renoir/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_pixar_animation_studios/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_pixar_animation_studios/landscape-0.jpg new file mode 100644 index 00000000..767aa502 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_pixar_animation_studios/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_pixar_animation_studios/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_pixar_animation_studios/portrait-0.jpg new file mode 100644 index 00000000..078893a1 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_pixar_animation_studios/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_rembrandt/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_rembrandt/landscape-0.jpg new file mode 100644 index 00000000..3bbdad0b Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_rembrandt/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_rembrandt/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_rembrandt/portrait-0.jpg new file mode 100644 index 00000000..c1207645 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_rembrandt/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_richard_dadd/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_richard_dadd/landscape-0.jpg new file mode 100644 index 00000000..f25919c0 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_richard_dadd/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_richard_dadd/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_richard_dadd/portrait-0.jpg new file mode 100644 index 00000000..6530cc13 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_richard_dadd/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_rossdraws/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_rossdraws/landscape-0.jpg new file mode 100644 index 00000000..4eb47e5c Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_rossdraws/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_rossdraws/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_rossdraws/portrait-0.jpg new file mode 100644 index 00000000..fa933154 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_rossdraws/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_salvador_dali_/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_salvador_dali_/landscape-0.jpg new file mode 100644 index 00000000..fa645ada Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_salvador_dali_/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_salvador_dali_/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_salvador_dali_/portrait-0.jpg new file mode 100644 index 00000000..64ea5160 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_salvador_dali_/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_sam_does_arts/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_sam_does_arts/landscape-0.jpg new file mode 100644 index 00000000..87a30e81 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_sam_does_arts/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_sam_does_arts/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_sam_does_arts/portrait-0.jpg new file mode 100644 index 00000000..2fccacd0 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_sam_does_arts/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_sandro_botticelli/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_sandro_botticelli/landscape-0.jpg new file mode 100644 index 00000000..84ac59ec Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_sandro_botticelli/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_sandro_botticelli/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_sandro_botticelli/portrait-0.jpg new file mode 100644 index 00000000..89ebfad7 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_sandro_botticelli/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_ted_nasmith/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_ted_nasmith/landscape-0.jpg new file mode 100644 index 00000000..73188f83 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_ted_nasmith/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_ted_nasmith/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_ted_nasmith/portrait-0.jpg new file mode 100644 index 00000000..6034d354 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_ted_nasmith/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_ten_hundred/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_ten_hundred/landscape-0.jpg new file mode 100644 index 00000000..558c2528 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_ten_hundred/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_ten_hundred/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_ten_hundred/portrait-0.jpg new file mode 100644 index 00000000..7227be3d Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_ten_hundred/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_thomas_kinkade/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_thomas_kinkade/landscape-0.jpg new file mode 100644 index 00000000..3f3c4ab2 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_thomas_kinkade/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_thomas_kinkade/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_thomas_kinkade/portrait-0.jpg new file mode 100644 index 00000000..49f5f59b Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_thomas_kinkade/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_tivadar_csontva_ry_kosztka/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_tivadar_csontva_ry_kosztka/landscape-0.jpg new file mode 100644 index 00000000..4839ba1a Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_tivadar_csontva_ry_kosztka/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_tivadar_csontva_ry_kosztka/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_tivadar_csontva_ry_kosztka/portrait-0.jpg new file mode 100644 index 00000000..5229d550 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_tivadar_csontva_ry_kosztka/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_victo_ngai/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_victo_ngai/landscape-0.jpg new file mode 100644 index 00000000..632091c6 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_victo_ngai/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_victo_ngai/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_victo_ngai/portrait-0.jpg new file mode 100644 index 00000000..4bbb3ed9 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_victo_ngai/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_vincent_di_fate/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_vincent_di_fate/landscape-0.jpg new file mode 100644 index 00000000..fe4becf9 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_vincent_di_fate/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_vincent_di_fate/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_vincent_di_fate/portrait-0.jpg new file mode 100644 index 00000000..8087d73b Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_vincent_di_fate/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_vincent_van_gogh/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_vincent_van_gogh/landscape-0.jpg new file mode 100644 index 00000000..15ced986 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_vincent_van_gogh/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_vincent_van_gogh/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_vincent_van_gogh/portrait-0.jpg new file mode 100644 index 00000000..f60ae946 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_vincent_van_gogh/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_wes_anderson/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_wes_anderson/landscape-0.jpg new file mode 100644 index 00000000..f3b05ed5 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_wes_anderson/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_wes_anderson/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_wes_anderson/portrait-0.jpg new file mode 100644 index 00000000..2f40313c Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_wes_anderson/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_wlop/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_wlop/landscape-0.jpg new file mode 100644 index 00000000..7378e735 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_wlop/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_wlop/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_wlop/portrait-0.jpg new file mode 100644 index 00000000..100280b1 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_wlop/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_yoshitaka_amano/landscape-0.jpg b/ui/media/modifier-thumbnails/artist/by_yoshitaka_amano/landscape-0.jpg new file mode 100644 index 00000000..8ad61929 Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_yoshitaka_amano/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/artist/by_yoshitaka_amano/portrait-0.jpg b/ui/media/modifier-thumbnails/artist/by_yoshitaka_amano/portrait-0.jpg new file mode 100644 index 00000000..3989acaa Binary files /dev/null and b/ui/media/modifier-thumbnails/artist/by_yoshitaka_amano/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/aerial_view/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/aerial_view/landscape-0.jpg new file mode 100644 index 00000000..7a62102f Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/aerial_view/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/aerial_view/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/aerial_view/portrait-0.jpg new file mode 100644 index 00000000..0ceaffb1 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/aerial_view/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/canon50/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/canon50/landscape-0.jpg new file mode 100644 index 00000000..1e3ade7b Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/canon50/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/canon50/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/canon50/portrait-0.jpg new file mode 100644 index 00000000..9c2de772 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/canon50/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/cinematic/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/cinematic/landscape-0.jpg new file mode 100644 index 00000000..1e582e1f Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/cinematic/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/cinematic/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/cinematic/portrait-0.jpg new file mode 100644 index 00000000..58513f76 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/cinematic/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/close-up/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/close-up/landscape-0.jpg new file mode 100644 index 00000000..9080e385 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/close-up/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/close-up/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/close-up/portrait-0.jpg new file mode 100644 index 00000000..f91e25f0 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/close-up/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/color_grading/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/color_grading/landscape-0.jpg new file mode 100644 index 00000000..ed3b7d13 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/color_grading/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/color_grading/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/color_grading/portrait-0.jpg new file mode 100644 index 00000000..91a0fec2 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/color_grading/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/dramatic/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/dramatic/landscape-0.jpg new file mode 100644 index 00000000..db9cd870 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/dramatic/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/dramatic/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/dramatic/portrait-0.jpg new file mode 100644 index 00000000..54c6c95b Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/dramatic/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/film_grain/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/film_grain/landscape-0.jpg new file mode 100644 index 00000000..b045299e Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/film_grain/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/film_grain/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/film_grain/portrait-0.jpg new file mode 100644 index 00000000..063c2923 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/film_grain/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/fisheye_lens/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/fisheye_lens/landscape-0.jpg new file mode 100644 index 00000000..c4a0e658 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/fisheye_lens/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/fisheye_lens/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/fisheye_lens/portrait-0.jpg new file mode 100644 index 00000000..74ce9fce Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/fisheye_lens/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/glamor_shot/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/glamor_shot/landscape-0.jpg new file mode 100644 index 00000000..fd7878b0 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/glamor_shot/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/glamor_shot/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/glamor_shot/portrait-0.jpg new file mode 100644 index 00000000..3a9e7151 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/glamor_shot/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/golden_hour/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/golden_hour/landscape-0.jpg new file mode 100644 index 00000000..d4814bba Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/golden_hour/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/golden_hour/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/golden_hour/portrait-0.jpg new file mode 100644 index 00000000..86dc055a Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/golden_hour/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/hd/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/hd/landscape-0.jpg new file mode 100644 index 00000000..dd98b0f7 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/hd/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/hd/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/hd/portrait-0.jpg new file mode 100644 index 00000000..bf7a9002 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/hd/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/landscape/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/landscape/landscape-0.jpg new file mode 100644 index 00000000..58faf8f1 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/landscape/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/landscape/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/landscape/portrait-0.jpg new file mode 100644 index 00000000..6acf3a07 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/landscape/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/lens_flare/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/lens_flare/landscape-0.jpg new file mode 100644 index 00000000..2bbe565e Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/lens_flare/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/lens_flare/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/lens_flare/portrait-0.jpg new file mode 100644 index 00000000..099e0da8 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/lens_flare/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/macro/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/macro/landscape-0.jpg new file mode 100644 index 00000000..4a1efe3f Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/macro/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/macro/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/macro/portrait-0.jpg new file mode 100644 index 00000000..74842b13 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/macro/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/photoshoot/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/photoshoot/landscape-0.jpg new file mode 100644 index 00000000..f271289d Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/photoshoot/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/photoshoot/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/photoshoot/portrait-0.jpg new file mode 100644 index 00000000..01010840 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/photoshoot/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/polaroid/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/polaroid/landscape-0.jpg new file mode 100644 index 00000000..970bd601 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/polaroid/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/polaroid/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/polaroid/portrait-0.jpg new file mode 100644 index 00000000..6aa809f5 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/polaroid/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/portrait/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/portrait/landscape-0.jpg new file mode 100644 index 00000000..26bfee5b Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/portrait/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/portrait/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/portrait/portrait-0.jpg new file mode 100644 index 00000000..81ebdf5d Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/portrait/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/studio_lighting/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/studio_lighting/landscape-0.jpg new file mode 100644 index 00000000..adaeca66 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/studio_lighting/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/studio_lighting/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/studio_lighting/portrait-0.jpg new file mode 100644 index 00000000..c5b34c45 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/studio_lighting/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/vintage/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/vintage/landscape-0.jpg new file mode 100644 index 00000000..8b63e895 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/vintage/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/vintage/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/vintage/portrait-0.jpg new file mode 100644 index 00000000..1b83031b Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/vintage/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/war_photography/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/war_photography/landscape-0.jpg new file mode 100644 index 00000000..24c47d9e Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/war_photography/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/war_photography/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/war_photography/portrait-0.jpg new file mode 100644 index 00000000..d925a5df Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/war_photography/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/white_balance/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/white_balance/landscape-0.jpg new file mode 100644 index 00000000..4dc38105 Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/white_balance/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/white_balance/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/white_balance/portrait-0.jpg new file mode 100644 index 00000000..27a6d9eb Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/white_balance/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/wildlife_photography/landscape-0.jpg b/ui/media/modifier-thumbnails/camera/wildlife_photography/landscape-0.jpg new file mode 100644 index 00000000..13e10b6c Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/wildlife_photography/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/camera/wildlife_photography/portrait-0.jpg b/ui/media/modifier-thumbnails/camera/wildlife_photography/portrait-0.jpg new file mode 100644 index 00000000..57870f3e Binary files /dev/null and b/ui/media/modifier-thumbnails/camera/wildlife_photography/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/etching/landscape-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/etching/landscape-0.jpg new file mode 100644 index 00000000..909c2c53 Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/etching/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/etching/portrait-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/etching/portrait-0.jpg new file mode 100644 index 00000000..4cecabb3 Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/etching/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/linocut/landscape-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/linocut/landscape-0.jpg new file mode 100644 index 00000000..edf51779 Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/linocut/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/linocut/portrait-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/linocut/portrait-0.jpg new file mode 100644 index 00000000..0f3bb2b6 Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/linocut/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/paper-mache/landscape-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/paper-mache/landscape-0.jpg new file mode 100644 index 00000000..d75c8ebe Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/paper-mache/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/paper-mache/portrait-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/paper-mache/portrait-0.jpg new file mode 100644 index 00000000..30c54d06 Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/paper-mache/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/paper_model/landscape-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/paper_model/landscape-0.jpg new file mode 100644 index 00000000..6325126c Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/paper_model/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/paper_model/portrait-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/paper_model/portrait-0.jpg new file mode 100644 index 00000000..4e5d11b7 Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/paper_model/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/papercutting/landscape-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/papercutting/landscape-0.jpg new file mode 100644 index 00000000..f69f4762 Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/papercutting/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/papercutting/portrait-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/papercutting/portrait-0.jpg new file mode 100644 index 00000000..44ae9422 Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/papercutting/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/pyrography/landscape-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/pyrography/landscape-0.jpg new file mode 100644 index 00000000..6a652527 Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/pyrography/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/pyrography/portrait-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/pyrography/portrait-0.jpg new file mode 100644 index 00000000..c65e3cca Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/pyrography/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/wood-carving/landscape-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/wood-carving/landscape-0.jpg new file mode 100644 index 00000000..d4707560 Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/wood-carving/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/carving_and_etching/wood-carving/portrait-0.jpg b/ui/media/modifier-thumbnails/carving_and_etching/wood-carving/portrait-0.jpg new file mode 100644 index 00000000..715ae3f1 Binary files /dev/null and b/ui/media/modifier-thumbnails/carving_and_etching/wood-carving/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/3d_render/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/3d_render/landscape-0.jpg new file mode 100644 index 00000000..73871503 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/3d_render/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/3d_render/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/3d_render/portrait-0.jpg new file mode 100644 index 00000000..c9137bda Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/3d_render/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/corona_render/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/corona_render/landscape-0.jpg new file mode 100644 index 00000000..e625a78e Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/corona_render/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/corona_render/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/corona_render/portrait-0.jpg new file mode 100644 index 00000000..e650d2e2 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/corona_render/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/creature_design/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/creature_design/landscape-0.jpg new file mode 100644 index 00000000..b0bb8093 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/creature_design/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/creature_design/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/creature_design/portrait-0.jpg new file mode 100644 index 00000000..ed08e5a1 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/creature_design/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/cycles_render/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/cycles_render/landscape-0.jpg new file mode 100644 index 00000000..1073277c Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/cycles_render/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/cycles_render/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/cycles_render/portrait-0.jpg new file mode 100644 index 00000000..9c62a0ef Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/cycles_render/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/detailed_render/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/detailed_render/landscape-0.jpg new file mode 100644 index 00000000..5880e0d8 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/detailed_render/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/detailed_render/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/detailed_render/portrait-0.jpg new file mode 100644 index 00000000..71b378f0 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/detailed_render/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/environment_design/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/environment_design/landscape-0.jpg new file mode 100644 index 00000000..3a48c2b4 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/environment_design/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/environment_design/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/environment_design/portrait-0.jpg new file mode 100644 index 00000000..96a1dfbc Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/environment_design/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/glass_caustics/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/glass_caustics/landscape-0.jpg new file mode 100644 index 00000000..44ddc2ba Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/glass_caustics/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/glass_caustics/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/glass_caustics/portrait-0.jpg new file mode 100644 index 00000000..62e8f6ed Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/glass_caustics/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/global_illumination/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/global_illumination/landscape-0.jpg new file mode 100644 index 00000000..e0deff28 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/global_illumination/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/global_illumination/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/global_illumination/portrait-0.jpg new file mode 100644 index 00000000..5dabf50f Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/global_illumination/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/intricate_environment/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/intricate_environment/landscape-0.jpg new file mode 100644 index 00000000..6ceaf8d3 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/intricate_environment/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/intricate_environment/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/intricate_environment/portrait-0.jpg new file mode 100644 index 00000000..c9df0f6f Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/intricate_environment/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/lsd_render/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/lsd_render/landscape-0.jpg new file mode 100644 index 00000000..11f3a0fa Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/lsd_render/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/lsd_render/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/lsd_render/portrait-0.jpg new file mode 100644 index 00000000..7f2dc13d Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/lsd_render/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/octane_render/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/octane_render/landscape-0.jpg new file mode 100644 index 00000000..9c73b479 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/octane_render/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/octane_render/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/octane_render/portrait-0.jpg new file mode 100644 index 00000000..883f483e Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/octane_render/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/pbr/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/pbr/landscape-0.jpg new file mode 100644 index 00000000..d8a11738 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/pbr/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/pbr/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/pbr/portrait-0.jpg new file mode 100644 index 00000000..6e335155 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/pbr/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/subsurface_scattering/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/subsurface_scattering/landscape-0.jpg new file mode 100644 index 00000000..af16505e Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/subsurface_scattering/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_rendering/subsurface_scattering/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_rendering/subsurface_scattering/portrait-0.jpg new file mode 100644 index 00000000..d047f4d8 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_rendering/subsurface_scattering/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/3d_model/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_software/3d_model/landscape-0.jpg new file mode 100644 index 00000000..0e107ee5 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/3d_model/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/3d_model/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_software/3d_model/portrait-0.jpg new file mode 100644 index 00000000..cd23e093 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/3d_model/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/3d_sculpt/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_software/3d_sculpt/landscape-0.jpg new file mode 100644 index 00000000..a3d437b3 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/3d_sculpt/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/3d_sculpt/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_software/3d_sculpt/portrait-0.jpg new file mode 100644 index 00000000..40bfcba4 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/3d_sculpt/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/3ds_max_model/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_software/3ds_max_model/landscape-0.jpg new file mode 100644 index 00000000..52156b47 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/3ds_max_model/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/3ds_max_model/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_software/3ds_max_model/portrait-0.jpg new file mode 100644 index 00000000..f85538cd Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/3ds_max_model/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/blender_model/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_software/blender_model/landscape-0.jpg new file mode 100644 index 00000000..bdcfd1f8 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/blender_model/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/blender_model/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_software/blender_model/portrait-0.jpg new file mode 100644 index 00000000..136baa81 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/blender_model/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/cinema4d_model/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_software/cinema4d_model/landscape-0.jpg new file mode 100644 index 00000000..7a3d0ee8 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/cinema4d_model/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/cinema4d_model/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_software/cinema4d_model/portrait-0.jpg new file mode 100644 index 00000000..d5a55841 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/cinema4d_model/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/maya_model/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_software/maya_model/landscape-0.jpg new file mode 100644 index 00000000..38be657a Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/maya_model/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/maya_model/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_software/maya_model/portrait-0.jpg new file mode 100644 index 00000000..9d3e4fda Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/maya_model/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/unreal_engine/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_software/unreal_engine/landscape-0.jpg new file mode 100644 index 00000000..d4532e3a Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/unreal_engine/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/unreal_engine/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_software/unreal_engine/portrait-0.jpg new file mode 100644 index 00000000..32d0b9fc Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/unreal_engine/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/zbrush_sculpt/landscape-0.jpg b/ui/media/modifier-thumbnails/cgi_software/zbrush_sculpt/landscape-0.jpg new file mode 100644 index 00000000..49270c61 Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/zbrush_sculpt/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/cgi_software/zbrush_sculpt/portrait-0.jpg b/ui/media/modifier-thumbnails/cgi_software/zbrush_sculpt/portrait-0.jpg new file mode 100644 index 00000000..6bd4bbfa Binary files /dev/null and b/ui/media/modifier-thumbnails/cgi_software/zbrush_sculpt/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/beautiful_lighting/landscape-0.jpg b/ui/media/modifier-thumbnails/color/beautiful_lighting/landscape-0.jpg new file mode 100644 index 00000000..d183a600 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/beautiful_lighting/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/beautiful_lighting/portrait-0.jpg b/ui/media/modifier-thumbnails/color/beautiful_lighting/portrait-0.jpg new file mode 100644 index 00000000..b8ecacfd Binary files /dev/null and b/ui/media/modifier-thumbnails/color/beautiful_lighting/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/cold_color_palette/landscape-0.jpg b/ui/media/modifier-thumbnails/color/cold_color_palette/landscape-0.jpg new file mode 100644 index 00000000..7039a9ce Binary files /dev/null and b/ui/media/modifier-thumbnails/color/cold_color_palette/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/cold_color_palette/portrait-0.jpg b/ui/media/modifier-thumbnails/color/cold_color_palette/portrait-0.jpg new file mode 100644 index 00000000..abf02c82 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/cold_color_palette/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/colorful/landscape-0.jpg b/ui/media/modifier-thumbnails/color/colorful/landscape-0.jpg new file mode 100644 index 00000000..fe708bf6 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/colorful/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/colorful/portrait-0.jpg b/ui/media/modifier-thumbnails/color/colorful/portrait-0.jpg new file mode 100644 index 00000000..c327c1f3 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/colorful/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/dynamic_lighting/landscape-0.jpg b/ui/media/modifier-thumbnails/color/dynamic_lighting/landscape-0.jpg new file mode 100644 index 00000000..632e8694 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/dynamic_lighting/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/dynamic_lighting/portrait-0.jpg b/ui/media/modifier-thumbnails/color/dynamic_lighting/portrait-0.jpg new file mode 100644 index 00000000..7f85330b Binary files /dev/null and b/ui/media/modifier-thumbnails/color/dynamic_lighting/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/electric_colors/landscape-0.jpg b/ui/media/modifier-thumbnails/color/electric_colors/landscape-0.jpg new file mode 100644 index 00000000..27bfa102 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/electric_colors/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/electric_colors/portrait-0.jpg b/ui/media/modifier-thumbnails/color/electric_colors/portrait-0.jpg new file mode 100644 index 00000000..14270895 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/electric_colors/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/infrared/landscape-0.jpg b/ui/media/modifier-thumbnails/color/infrared/landscape-0.jpg new file mode 100644 index 00000000..16a6e133 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/infrared/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/infrared/portrait-0.jpg b/ui/media/modifier-thumbnails/color/infrared/portrait-0.jpg new file mode 100644 index 00000000..b3b82b22 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/infrared/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/neon/landscape-0.jpg b/ui/media/modifier-thumbnails/color/neon/landscape-0.jpg new file mode 100644 index 00000000..3dee39a5 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/neon/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/neon/portrait-0.jpg b/ui/media/modifier-thumbnails/color/neon/portrait-0.jpg new file mode 100644 index 00000000..a00ae357 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/neon/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/pastel/landscape-0.jpg b/ui/media/modifier-thumbnails/color/pastel/landscape-0.jpg new file mode 100644 index 00000000..e1ec1d96 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/pastel/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/pastel/portrait-0.jpg b/ui/media/modifier-thumbnails/color/pastel/portrait-0.jpg new file mode 100644 index 00000000..8de9e72f Binary files /dev/null and b/ui/media/modifier-thumbnails/color/pastel/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/synthwave/landscape-0.jpg b/ui/media/modifier-thumbnails/color/synthwave/landscape-0.jpg new file mode 100644 index 00000000..2f9c0e61 Binary files /dev/null and b/ui/media/modifier-thumbnails/color/synthwave/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/synthwave/portrait-0.jpg b/ui/media/modifier-thumbnails/color/synthwave/portrait-0.jpg new file mode 100644 index 00000000..1c385eae Binary files /dev/null and b/ui/media/modifier-thumbnails/color/synthwave/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/warm_color_palette/landscape-0.jpg b/ui/media/modifier-thumbnails/color/warm_color_palette/landscape-0.jpg new file mode 100644 index 00000000..87c8501f Binary files /dev/null and b/ui/media/modifier-thumbnails/color/warm_color_palette/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/color/warm_color_palette/portrait-0.jpg b/ui/media/modifier-thumbnails/color/warm_color_palette/portrait-0.jpg new file mode 100644 index 00000000..4fb9758e Binary files /dev/null and b/ui/media/modifier-thumbnails/color/warm_color_palette/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/cel_shading/landscape-0.jpg b/ui/media/modifier-thumbnails/drawing_style/cel_shading/landscape-0.jpg new file mode 100644 index 00000000..e00cd163 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/cel_shading/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/cel_shading/portrait-0.jpg b/ui/media/modifier-thumbnails/drawing_style/cel_shading/portrait-0.jpg new file mode 100644 index 00000000..715f3e0e Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/cel_shading/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/children_s_drawing/landscape-0.jpg b/ui/media/modifier-thumbnails/drawing_style/children_s_drawing/landscape-0.jpg new file mode 100644 index 00000000..79d70a72 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/children_s_drawing/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/children_s_drawing/portrait-0.jpg b/ui/media/modifier-thumbnails/drawing_style/children_s_drawing/portrait-0.jpg new file mode 100644 index 00000000..bc29298f Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/children_s_drawing/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/crosshatch/landscape-0.jpg b/ui/media/modifier-thumbnails/drawing_style/crosshatch/landscape-0.jpg new file mode 100644 index 00000000..a6144a67 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/crosshatch/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/crosshatch/portrait-0.jpg b/ui/media/modifier-thumbnails/drawing_style/crosshatch/portrait-0.jpg new file mode 100644 index 00000000..f2bb7acf Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/crosshatch/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/detailed_and_intricate/landscape-0.jpg b/ui/media/modifier-thumbnails/drawing_style/detailed_and_intricate/landscape-0.jpg new file mode 100644 index 00000000..5048c432 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/detailed_and_intricate/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/detailed_and_intricate/portrait-0.jpg b/ui/media/modifier-thumbnails/drawing_style/detailed_and_intricate/portrait-0.jpg new file mode 100644 index 00000000..699f92d9 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/detailed_and_intricate/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/doodle/landscape-0.jpg b/ui/media/modifier-thumbnails/drawing_style/doodle/landscape-0.jpg new file mode 100644 index 00000000..92cec1c4 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/doodle/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/doodle/portrait-0.jpg b/ui/media/modifier-thumbnails/drawing_style/doodle/portrait-0.jpg new file mode 100644 index 00000000..7524efa5 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/doodle/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/dot_art/landscape-0.jpg b/ui/media/modifier-thumbnails/drawing_style/dot_art/landscape-0.jpg new file mode 100644 index 00000000..9fcb939f Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/dot_art/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/dot_art/portrait-0.jpg b/ui/media/modifier-thumbnails/drawing_style/dot_art/portrait-0.jpg new file mode 100644 index 00000000..815628a2 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/dot_art/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/line_art/landscape-0.jpg b/ui/media/modifier-thumbnails/drawing_style/line_art/landscape-0.jpg new file mode 100644 index 00000000..d3e13304 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/line_art/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/line_art/portrait-0.jpg b/ui/media/modifier-thumbnails/drawing_style/line_art/portrait-0.jpg new file mode 100644 index 00000000..469b3004 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/line_art/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/sketch/landscape-0.jpg b/ui/media/modifier-thumbnails/drawing_style/sketch/landscape-0.jpg new file mode 100644 index 00000000..4211b229 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/sketch/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/drawing_style/sketch/portrait-0.jpg b/ui/media/modifier-thumbnails/drawing_style/sketch/portrait-0.jpg new file mode 100644 index 00000000..4c222d07 Binary files /dev/null and b/ui/media/modifier-thumbnails/drawing_style/sketch/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/angry/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/angry/landscape-0.jpg new file mode 100644 index 00000000..22139255 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/angry/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/angry/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/angry/portrait-0.jpg new file mode 100644 index 00000000..a8065e42 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/angry/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/bitter/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/bitter/landscape-0.jpg new file mode 100644 index 00000000..63810553 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/bitter/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/bitter/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/bitter/portrait-0.jpg new file mode 100644 index 00000000..90712510 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/bitter/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/disgusted/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/disgusted/landscape-0.jpg new file mode 100644 index 00000000..e6fdf176 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/disgusted/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/disgusted/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/disgusted/portrait-0.jpg new file mode 100644 index 00000000..9bb8497b Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/disgusted/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/embarrassed/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/embarrassed/landscape-0.jpg new file mode 100644 index 00000000..bd3e1d65 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/embarrassed/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/embarrassed/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/embarrassed/portrait-0.jpg new file mode 100644 index 00000000..3ed2ae96 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/embarrassed/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/evil/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/evil/landscape-0.jpg new file mode 100644 index 00000000..7aac3ea3 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/evil/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/evil/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/evil/portrait-0.jpg new file mode 100644 index 00000000..c9adb919 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/evil/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/excited/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/excited/landscape-0.jpg new file mode 100644 index 00000000..cfbd3a20 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/excited/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/excited/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/excited/portrait-0.jpg new file mode 100644 index 00000000..82b8033a Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/excited/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/fear/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/fear/landscape-0.jpg new file mode 100644 index 00000000..d55b0d5d Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/fear/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/fear/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/fear/portrait-0.jpg new file mode 100644 index 00000000..f7fb810f Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/fear/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/funny/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/funny/landscape-0.jpg new file mode 100644 index 00000000..5b05507a Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/funny/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/funny/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/funny/portrait-0.jpg new file mode 100644 index 00000000..1590e8a5 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/funny/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/happy/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/happy/landscape-0.jpg new file mode 100644 index 00000000..30429d04 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/happy/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/happy/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/happy/portrait-0.jpg new file mode 100644 index 00000000..0a7a4bf5 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/happy/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/horrifying/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/horrifying/landscape-0.jpg new file mode 100644 index 00000000..31b5cc4c Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/horrifying/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/horrifying/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/horrifying/portrait-0.jpg new file mode 100644 index 00000000..aef8da40 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/horrifying/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/lonely/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/lonely/landscape-0.jpg new file mode 100644 index 00000000..cce5400b Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/lonely/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/lonely/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/lonely/portrait-0.jpg new file mode 100644 index 00000000..6f451950 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/lonely/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/melancholic/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/melancholic/landscape-0.jpg new file mode 100644 index 00000000..346a626e Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/melancholic/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/melancholic/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/melancholic/portrait-0.jpg new file mode 100644 index 00000000..a503597f Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/melancholic/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/sad/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/sad/landscape-0.jpg new file mode 100644 index 00000000..a086851d Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/sad/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/sad/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/sad/portrait-0.jpg new file mode 100644 index 00000000..e3f4fc6b Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/sad/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/serene/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/serene/landscape-0.jpg new file mode 100644 index 00000000..e508f95e Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/serene/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/serene/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/serene/portrait-0.jpg new file mode 100644 index 00000000..ca5a0a31 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/serene/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/surprised/landscape-0.jpg b/ui/media/modifier-thumbnails/emotions/surprised/landscape-0.jpg new file mode 100644 index 00000000..1e0aaaf1 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/surprised/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/emotions/surprised/portrait-0.jpg b/ui/media/modifier-thumbnails/emotions/surprised/portrait-0.jpg new file mode 100644 index 00000000..5d3bb467 Binary files /dev/null and b/ui/media/modifier-thumbnails/emotions/surprised/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/chalk/landscape-0.jpg b/ui/media/modifier-thumbnails/pen/chalk/landscape-0.jpg new file mode 100644 index 00000000..f7f8de12 Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/chalk/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/chalk/portrait-0.jpg b/ui/media/modifier-thumbnails/pen/chalk/portrait-0.jpg new file mode 100644 index 00000000..0cbe5f91 Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/chalk/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/colored_pencil/landscape-0.jpg b/ui/media/modifier-thumbnails/pen/colored_pencil/landscape-0.jpg new file mode 100644 index 00000000..a9f93581 Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/colored_pencil/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/colored_pencil/portrait-0.jpg b/ui/media/modifier-thumbnails/pen/colored_pencil/portrait-0.jpg new file mode 100644 index 00000000..9b07e5f3 Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/colored_pencil/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/graphite/landscape-0.jpg b/ui/media/modifier-thumbnails/pen/graphite/landscape-0.jpg new file mode 100644 index 00000000..b764c325 Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/graphite/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/graphite/portrait-0.jpg b/ui/media/modifier-thumbnails/pen/graphite/portrait-0.jpg new file mode 100644 index 00000000..8d9ce682 Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/graphite/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/ink/landscape-0.jpg b/ui/media/modifier-thumbnails/pen/ink/landscape-0.jpg new file mode 100644 index 00000000..04e9bb8d Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/ink/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/ink/portrait-0.jpg b/ui/media/modifier-thumbnails/pen/ink/portrait-0.jpg new file mode 100644 index 00000000..58912a5c Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/ink/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/oil_paint/landscape-0.jpg b/ui/media/modifier-thumbnails/pen/oil_paint/landscape-0.jpg new file mode 100644 index 00000000..e8487eb3 Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/oil_paint/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/oil_paint/portrait-0.jpg b/ui/media/modifier-thumbnails/pen/oil_paint/portrait-0.jpg new file mode 100644 index 00000000..39f49db7 Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/oil_paint/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/pastel_art/landscape-0.jpg b/ui/media/modifier-thumbnails/pen/pastel_art/landscape-0.jpg new file mode 100644 index 00000000..d47f061f Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/pastel_art/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/pen/pastel_art/portrait-0.jpg b/ui/media/modifier-thumbnails/pen/pastel_art/portrait-0.jpg new file mode 100644 index 00000000..b8389468 Binary files /dev/null and b/ui/media/modifier-thumbnails/pen/pastel_art/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/16-bit/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/16-bit/landscape-0.jpg new file mode 100644 index 00000000..cab6daba Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/16-bit/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/16-bit/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/16-bit/portrait-0.jpg new file mode 100644 index 00000000..ec0d327c Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/16-bit/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/2d/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/2d/landscape-0.jpg new file mode 100644 index 00000000..c171c474 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/2d/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/2d/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/2d/portrait-0.jpg new file mode 100644 index 00000000..5da42777 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/2d/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/8-bit/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/8-bit/landscape-0.jpg new file mode 100644 index 00000000..de645e6d Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/8-bit/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/8-bit/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/8-bit/portrait-0.jpg new file mode 100644 index 00000000..922cda91 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/8-bit/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/anaglyph/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/anaglyph/landscape-0.jpg new file mode 100644 index 00000000..acf16435 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/anaglyph/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/anaglyph/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/anaglyph/portrait-0.jpg new file mode 100644 index 00000000..48246fa5 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/anaglyph/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/anime/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/anime/landscape-0.jpg new file mode 100644 index 00000000..84b8deb4 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/anime/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/anime/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/anime/portrait-0.jpg new file mode 100644 index 00000000..fa34b2a2 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/anime/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/art_nouveau/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/art_nouveau/landscape-0.jpg new file mode 100644 index 00000000..aa8239f8 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/art_nouveau/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/art_nouveau/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/art_nouveau/portrait-0.jpg new file mode 100644 index 00000000..ff30bc9c Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/art_nouveau/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/baroque/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/baroque/landscape-0.jpg new file mode 100644 index 00000000..dfc78d2f Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/baroque/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/baroque/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/baroque/portrait-0.jpg new file mode 100644 index 00000000..32e90197 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/baroque/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/bauhaus/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/bauhaus/landscape-0.jpg new file mode 100644 index 00000000..b2b43378 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/bauhaus/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/bauhaus/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/bauhaus/portrait-0.jpg new file mode 100644 index 00000000..b7ee0025 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/bauhaus/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/cartoon/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/cartoon/landscape-0.jpg new file mode 100644 index 00000000..0e0690e1 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/cartoon/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/cartoon/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/cartoon/portrait-0.jpg new file mode 100644 index 00000000..95997d3c Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/cartoon/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/cgi/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/cgi/landscape-0.jpg new file mode 100644 index 00000000..e987dcef Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/cgi/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/cgi/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/cgi/portrait-0.jpg new file mode 100644 index 00000000..6184ba71 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/cgi/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/comic_book/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/comic_book/landscape-0.jpg new file mode 100644 index 00000000..8c0b91a3 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/comic_book/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/comic_book/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/comic_book/portrait-0.jpg new file mode 100644 index 00000000..4d435d52 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/comic_book/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/concept_art/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/concept_art/landscape-0.jpg new file mode 100644 index 00000000..26817477 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/concept_art/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/concept_art/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/concept_art/portrait-0.jpg new file mode 100644 index 00000000..0e7c0b07 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/concept_art/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/constructivist/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/constructivist/landscape-0.jpg new file mode 100644 index 00000000..e82b2d5a Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/constructivist/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/constructivist/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/constructivist/portrait-0.jpg new file mode 100644 index 00000000..d015f666 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/constructivist/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/cubist/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/cubist/landscape-0.jpg new file mode 100644 index 00000000..8b4f2266 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/cubist/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/cubist/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/cubist/portrait-0.jpg new file mode 100644 index 00000000..679b23b0 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/cubist/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/dadaist/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/dadaist/landscape-0.jpg new file mode 100644 index 00000000..31ec96ea Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/dadaist/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/dadaist/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/dadaist/portrait-0.jpg new file mode 100644 index 00000000..04f4443b Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/dadaist/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/digital_art/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/digital_art/landscape-0.jpg new file mode 100644 index 00000000..6977ef1a Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/digital_art/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/digital_art/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/digital_art/portrait-0.jpg new file mode 100644 index 00000000..9dde746a Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/digital_art/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/expressionist/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/expressionist/landscape-0.jpg new file mode 100644 index 00000000..c317ff44 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/expressionist/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/expressionist/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/expressionist/portrait-0.jpg new file mode 100644 index 00000000..e0d4f058 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/expressionist/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/fantasy/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/fantasy/landscape-0.jpg new file mode 100644 index 00000000..df3890e5 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/fantasy/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/fantasy/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/fantasy/portrait-0.jpg new file mode 100644 index 00000000..5e7ed735 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/fantasy/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/fauvist/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/fauvist/landscape-0.jpg new file mode 100644 index 00000000..57128ce1 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/fauvist/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/fauvist/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/fauvist/portrait-0.jpg new file mode 100644 index 00000000..1d75bdba Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/fauvist/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/figurative/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/figurative/landscape-0.jpg new file mode 100644 index 00000000..323ca7b2 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/figurative/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/figurative/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/figurative/portrait-0.jpg new file mode 100644 index 00000000..547ca265 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/figurative/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/geometric/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/geometric/landscape-0.jpg new file mode 100644 index 00000000..2cb79e10 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/geometric/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/geometric/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/geometric/portrait-0.jpg new file mode 100644 index 00000000..a07a8453 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/geometric/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/graphic_novel/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/graphic_novel/landscape-0.jpg new file mode 100644 index 00000000..9c4b4d13 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/graphic_novel/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/graphic_novel/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/graphic_novel/portrait-0.jpg new file mode 100644 index 00000000..ae186e55 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/graphic_novel/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/hard_edge_painting/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/hard_edge_painting/landscape-0.jpg new file mode 100644 index 00000000..6f5a1a6b Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/hard_edge_painting/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/hard_edge_painting/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/hard_edge_painting/portrait-0.jpg new file mode 100644 index 00000000..4651a8e8 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/hard_edge_painting/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/hydrodipped/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/hydrodipped/landscape-0.jpg new file mode 100644 index 00000000..01181f16 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/hydrodipped/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/hydrodipped/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/hydrodipped/portrait-0.jpg new file mode 100644 index 00000000..7b8e721f Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/hydrodipped/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/impressionistic/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/impressionistic/landscape-0.jpg new file mode 100644 index 00000000..64d765da Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/impressionistic/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/impressionistic/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/impressionistic/portrait-0.jpg new file mode 100644 index 00000000..60fe0cf0 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/impressionistic/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/lithography/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/lithography/landscape-0.jpg new file mode 100644 index 00000000..d7ef50cd Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/lithography/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/lithography/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/lithography/portrait-0.jpg new file mode 100644 index 00000000..0a9e81d8 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/lithography/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/manga/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/manga/landscape-0.jpg new file mode 100644 index 00000000..54faf7f1 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/manga/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/manga/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/manga/portrait-0.jpg new file mode 100644 index 00000000..fab81d2d Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/manga/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/minimalist/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/minimalist/landscape-0.jpg new file mode 100644 index 00000000..7f36b5b1 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/minimalist/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/minimalist/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/minimalist/portrait-0.jpg new file mode 100644 index 00000000..2812a6db Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/minimalist/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/modern_art/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/modern_art/landscape-0.jpg new file mode 100644 index 00000000..ec432308 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/modern_art/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/modern_art/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/modern_art/portrait-0.jpg new file mode 100644 index 00000000..1eb03650 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/modern_art/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/mosaic/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/mosaic/landscape-0.jpg new file mode 100644 index 00000000..32284748 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/mosaic/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/mosaic/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/mosaic/portrait-0.jpg new file mode 100644 index 00000000..43c07d87 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/mosaic/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/mural/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/mural/landscape-0.jpg new file mode 100644 index 00000000..2455f4d5 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/mural/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/mural/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/mural/portrait-0.jpg new file mode 100644 index 00000000..a31bd7d2 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/mural/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/naive/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/naive/landscape-0.jpg new file mode 100644 index 00000000..aec27ab0 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/naive/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/naive/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/naive/portrait-0.jpg new file mode 100644 index 00000000..37dab0d4 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/naive/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/neoclassical/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/neoclassical/landscape-0.jpg new file mode 100644 index 00000000..dc7d151f Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/neoclassical/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/neoclassical/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/neoclassical/portrait-0.jpg new file mode 100644 index 00000000..517d2970 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/neoclassical/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/photo/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/photo/landscape-0.jpg new file mode 100644 index 00000000..0e888b74 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/photo/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/photo/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/photo/portrait-0.jpg new file mode 100644 index 00000000..28b15e1f Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/photo/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/realistic/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/realistic/landscape-0.jpg new file mode 100644 index 00000000..001896d1 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/realistic/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/realistic/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/realistic/portrait-0.jpg new file mode 100644 index 00000000..e3b19a4b Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/realistic/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/rococo/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/rococo/landscape-0.jpg new file mode 100644 index 00000000..cff9271a Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/rococo/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/rococo/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/rococo/portrait-0.jpg new file mode 100644 index 00000000..7c0aa58d Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/rococo/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/romantic/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/romantic/landscape-0.jpg new file mode 100644 index 00000000..8a5e03db Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/romantic/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/romantic/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/romantic/portrait-0.jpg new file mode 100644 index 00000000..efb2ace0 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/romantic/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/street_art/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/street_art/landscape-0.jpg new file mode 100644 index 00000000..dd9340dc Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/street_art/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/street_art/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/street_art/portrait-0.jpg new file mode 100644 index 00000000..191209a8 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/street_art/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/stuckist/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/stuckist/landscape-0.jpg new file mode 100644 index 00000000..53d2ba03 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/stuckist/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/stuckist/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/stuckist/portrait-0.jpg new file mode 100644 index 00000000..a69865e8 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/stuckist/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/surrealist/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/surrealist/landscape-0.jpg new file mode 100644 index 00000000..fa18e3b1 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/surrealist/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/surrealist/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/surrealist/portrait-0.jpg new file mode 100644 index 00000000..c8f22302 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/surrealist/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/symbolist/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/symbolist/landscape-0.jpg new file mode 100644 index 00000000..8b5b7f76 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/symbolist/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/symbolist/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/symbolist/portrait-0.jpg new file mode 100644 index 00000000..59dfe64b Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/symbolist/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/visual_novel/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/visual_novel/landscape-0.jpg new file mode 100644 index 00000000..dd7534a1 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/visual_novel/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/visual_novel/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/visual_novel/portrait-0.jpg new file mode 100644 index 00000000..1cb5bce0 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/visual_novel/portrait-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/watercolor/landscape-0.jpg b/ui/media/modifier-thumbnails/visual_style/watercolor/landscape-0.jpg new file mode 100644 index 00000000..08e6faa0 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/watercolor/landscape-0.jpg differ diff --git a/ui/media/modifier-thumbnails/visual_style/watercolor/portrait-0.jpg b/ui/media/modifier-thumbnails/visual_style/watercolor/portrait-0.jpg new file mode 100644 index 00000000..8b21e4f2 Binary files /dev/null and b/ui/media/modifier-thumbnails/visual_style/watercolor/portrait-0.jpg differ diff --git a/ui/modifiers.json b/ui/modifiers.json index d1191cb5..325e724e 100644 --- a/ui/modifiers.json +++ b/ui/modifiers.json @@ -1,258 +1,2717 @@ [ - [ - "Drawing Style", - [ - "Cel Shading", - "Children's Drawing", - "Crosshatch", - "Detailed and Intricate", - "Doodle", - "Dot Art", - "Line Art", - "Sketch" + { + "category": "Drawing Style", + "modifiers": [ + { + "modifier": "Cel Shading", + "previews": [ + { + "name": "portrait", + "path": "drawing_style/cel_shading/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "drawing_style/cel_shading/landscape-0.jpg" + } + ] + }, + { + "modifier": "Children's Drawing", + "previews": [ + { + "name": "portrait", + "path": "drawing_style/children_s_drawing/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "drawing_style/children_s_drawing/landscape-0.jpg" + } + ] + }, + { + "modifier": "Crosshatch", + "previews": [ + { + "name": "portrait", + "path": "drawing_style/crosshatch/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "drawing_style/crosshatch/landscape-0.jpg" + } + ] + }, + { + "modifier": "Detailed and Intricate", + "previews": [ + { + "name": "portrait", + "path": "drawing_style/detailed_and_intricate/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "drawing_style/detailed_and_intricate/landscape-0.jpg" + } + ] + }, + { + "modifier": "Doodle", + "previews": [ + { + "name": "portrait", + "path": "drawing_style/doodle/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "drawing_style/doodle/landscape-0.jpg" + } + ] + }, + { + "modifier": "Dot Art", + "previews": [ + { + "name": "portrait", + "path": "drawing_style/dot_art/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "drawing_style/dot_art/landscape-0.jpg" + } + ] + }, + { + "modifier": "Line Art", + "previews": [ + { + "name": "portrait", + "path": "drawing_style/line_art/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "drawing_style/line_art/landscape-0.jpg" + } + ] + }, + { + "modifier": "Sketch", + "previews": [ + { + "name": "portrait", + "path": "drawing_style/sketch/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "drawing_style/sketch/landscape-0.jpg" + } + ] + } ] - ], - [ - "Visual Style", - [ - "2D", - "8-bit", - "16-bit", - "Anaglyph", - "Anime", - "Art Nouveau", - "Bauhaus", - "Baroque", - "CGI", - "Cartoon", - "Comic Book", - "Concept Art", - "Constructivist", - "Cubist", - "Digital Art", - "Dadaist", - "Expressionist", - "Fantasy", - "Fauvist", - "Figurative", - "Graphic Novel", - "Geometric", - "Hard Edge Painting", - "Hydrodipped", - "Impressionistic", - "Lithography", - "Manga", - "Minimalist", - "Modern Art", - "Mosaic", - "Mural", - "Naive", - "Neoclassical", - "Photo", - "Realistic", - "Rococo", - "Romantic", - "Street Art", - "Symbolist", - "Stuckist", - "Surrealist", - "Visual Novel", - "Watercolor" + }, + { + "category": "Visual Style", + "modifiers": [ + { + "modifier": "2D", + "previews": [ + { + "name": "portrait", + "path": "visual_style/2d/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/2d/landscape-0.jpg" + } + ] + }, + { + "modifier": "8-Bit", + "previews": [ + { + "name": "portrait", + "path": "visual_style/8-bit/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/8-bit/landscape-0.jpg" + } + ] + }, + { + "modifier": "16-Bit", + "previews": [ + { + "name": "portrait", + "path": "visual_style/16-bit/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/16-bit/landscape-0.jpg" + } + ] + }, + { + "modifier": "Anaglyph", + "previews": [ + { + "name": "portrait", + "path": "visual_style/anaglyph/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/anaglyph/landscape-0.jpg" + } + ] + }, + { + "modifier": "Anime", + "previews": [ + { + "name": "portrait", + "path": "visual_style/anime/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/anime/landscape-0.jpg" + } + ] + }, + { + "modifier": "Art Nouveau", + "previews": [ + { + "name": "portrait", + "path": "visual_style/art_nouveau/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/art_nouveau/landscape-0.jpg" + } + ] + }, + { + "modifier": "Bauhaus", + "previews": [ + { + "name": "portrait", + "path": "visual_style/bauhaus/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/bauhaus/landscape-0.jpg" + } + ] + }, + { + "modifier": "Baroque", + "previews": [ + { + "name": "portrait", + "path": "visual_style/baroque/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/baroque/landscape-0.jpg" + } + ] + }, + { + "modifier": "CGI", + "previews": [ + { + "name": "portrait", + "path": "visual_style/cgi/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/cgi/landscape-0.jpg" + } + ] + }, + { + "modifier": "Cartoon", + "previews": [ + { + "name": "portrait", + "path": "visual_style/cartoon/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/cartoon/landscape-0.jpg" + } + ] + }, + { + "modifier": "Comic Book", + "previews": [ + { + "name": "portrait", + "path": "visual_style/comic_book/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/comic_book/landscape-0.jpg" + } + ] + }, + { + "modifier": "Concept Art", + "previews": [ + { + "name": "portrait", + "path": "visual_style/concept_art/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/concept_art/landscape-0.jpg" + } + ] + }, + { + "modifier": "Constructivist", + "previews": [ + { + "name": "portrait", + "path": "visual_style/constructivist/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/constructivist/landscape-0.jpg" + } + ] + }, + { + "modifier": "Cubist", + "previews": [ + { + "name": "portrait", + "path": "visual_style/cubist/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/cubist/landscape-0.jpg" + } + ] + }, + { + "modifier": "Digital Art", + "previews": [ + { + "name": "portrait", + "path": "visual_style/digital_art/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/digital_art/landscape-0.jpg" + } + ] + }, + { + "modifier": "Dadaist", + "previews": [ + { + "name": "portrait", + "path": "visual_style/dadaist/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/dadaist/landscape-0.jpg" + } + ] + }, + { + "modifier": "Expressionist", + "previews": [ + { + "name": "portrait", + "path": "visual_style/expressionist/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/expressionist/landscape-0.jpg" + } + ] + }, + { + "modifier": "Fantasy", + "previews": [ + { + "name": "portrait", + "path": "visual_style/fantasy/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/fantasy/landscape-0.jpg" + } + ] + }, + { + "modifier": "Fauvist", + "previews": [ + { + "name": "portrait", + "path": "visual_style/fauvist/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/fauvist/landscape-0.jpg" + } + ] + }, + { + "modifier": "Figurative", + "previews": [ + { + "name": "portrait", + "path": "visual_style/figurative/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/figurative/landscape-0.jpg" + } + ] + }, + { + "modifier": "Graphic Novel", + "previews": [ + { + "name": "portrait", + "path": "visual_style/graphic_novel/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/graphic_novel/landscape-0.jpg" + } + ] + }, + { + "modifier": "Geometric", + "previews": [ + { + "name": "portrait", + "path": "visual_style/geometric/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/geometric/landscape-0.jpg" + } + ] + }, + { + "modifier": "Hard Edge Painting", + "previews": [ + { + "name": "portrait", + "path": "visual_style/hard_edge_painting/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/hard_edge_painting/landscape-0.jpg" + } + ] + }, + { + "modifier": "Hydrodipped", + "previews": [ + { + "name": "portrait", + "path": "visual_style/hydrodipped/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/hydrodipped/landscape-0.jpg" + } + ] + }, + { + "modifier": "Impressionistic", + "previews": [ + { + "name": "portrait", + "path": "visual_style/impressionistic/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/impressionistic/landscape-0.jpg" + } + ] + }, + { + "modifier": "Lithography", + "previews": [ + { + "name": "portrait", + "path": "visual_style/lithography/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/lithography/landscape-0.jpg" + } + ] + }, + { + "modifier": "Manga", + "previews": [ + { + "name": "portrait", + "path": "visual_style/manga/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/manga/landscape-0.jpg" + } + ] + }, + { + "modifier": "Minimalist", + "previews": [ + { + "name": "portrait", + "path": "visual_style/minimalist/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/minimalist/landscape-0.jpg" + } + ] + }, + { + "modifier": "Modern Art", + "previews": [ + { + "name": "portrait", + "path": "visual_style/modern_art/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/modern_art/landscape-0.jpg" + } + ] + }, + { + "modifier": "Mosaic", + "previews": [ + { + "name": "portrait", + "path": "visual_style/mosaic/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/mosaic/landscape-0.jpg" + } + ] + }, + { + "modifier": "Mural", + "previews": [ + { + "name": "portrait", + "path": "visual_style/mural/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/mural/landscape-0.jpg" + } + ] + }, + { + "modifier": "Naive", + "previews": [ + { + "name": "portrait", + "path": "visual_style/naive/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/naive/landscape-0.jpg" + } + ] + }, + { + "modifier": "Neoclassical", + "previews": [ + { + "name": "portrait", + "path": "visual_style/neoclassical/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/neoclassical/landscape-0.jpg" + } + ] + }, + { + "modifier": "Photo", + "previews": [ + { + "name": "portrait", + "path": "visual_style/photo/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/photo/landscape-0.jpg" + } + ] + }, + { + "modifier": "Realistic", + "previews": [ + { + "name": "portrait", + "path": "visual_style/realistic/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/realistic/landscape-0.jpg" + } + ] + }, + { + "modifier": "Rococo", + "previews": [ + { + "name": "portrait", + "path": "visual_style/rococo/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/rococo/landscape-0.jpg" + } + ] + }, + { + "modifier": "Romantic", + "previews": [ + { + "name": "portrait", + "path": "visual_style/romantic/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/romantic/landscape-0.jpg" + } + ] + }, + { + "modifier": "Street Art", + "previews": [ + { + "name": "portrait", + "path": "visual_style/street_art/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/street_art/landscape-0.jpg" + } + ] + }, + { + "modifier": "Symbolist", + "previews": [ + { + "name": "portrait", + "path": "visual_style/symbolist/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/symbolist/landscape-0.jpg" + } + ] + }, + { + "modifier": "Stuckist", + "previews": [ + { + "name": "portrait", + "path": "visual_style/stuckist/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/stuckist/landscape-0.jpg" + } + ] + }, + { + "modifier": "Surrealist", + "previews": [ + { + "name": "portrait", + "path": "visual_style/surrealist/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/surrealist/landscape-0.jpg" + } + ] + }, + { + "modifier": "Visual Novel", + "previews": [ + { + "name": "portrait", + "path": "visual_style/visual_novel/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/visual_novel/landscape-0.jpg" + } + ] + }, + { + "modifier": "Watercolor", + "previews": [ + { + "name": "portrait", + "path": "visual_style/watercolor/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "visual_style/watercolor/landscape-0.jpg" + } + ] + } ] - ], - [ - "Pen", - [ - "Chalk", - "Colored Pencil", - "Graphite", - "Ink", - "Oil Paint", - "Pastel Art" + }, + { + "category": "Pen", + "modifiers": [ + { + "modifier": "Chalk", + "previews": [ + { + "name": "portrait", + "path": "pen/chalk/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "pen/chalk/landscape-0.jpg" + } + ] + }, + { + "modifier": "Colored Pencil", + "previews": [ + { + "name": "portrait", + "path": "pen/colored_pencil/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "pen/colored_pencil/landscape-0.jpg" + } + ] + }, + { + "modifier": "Graphite", + "previews": [ + { + "name": "portrait", + "path": "pen/graphite/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "pen/graphite/landscape-0.jpg" + } + ] + }, + { + "modifier": "Ink", + "previews": [ + { + "name": "portrait", + "path": "pen/ink/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "pen/ink/landscape-0.jpg" + } + ] + }, + { + "modifier": "Oil Paint", + "previews": [ + { + "name": "portrait", + "path": "pen/oil_paint/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "pen/oil_paint/landscape-0.jpg" + } + ] + }, + { + "modifier": "Pastel Art", + "previews": [ + { + "name": "portrait", + "path": "pen/pastel_art/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "pen/pastel_art/landscape-0.jpg" + } + ] + } ] - ], - [ - "Carving and Etching", - [ - "Etching", - "Linocut", - "Paper Model", - "Paper-Mache", - "Papercutting", - "Pyrography", - "Wood-Carving" + }, + { + "category": "Carving and Etching", + "modifiers": [ + { + "modifier": "etching", + "previews": [ + { + "name": "portrait", + "path": "carving_and_etching/etching/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "carving_and_etching/etching/landscape-0.jpg" + } + ] + }, + { + "modifier": "Linocut", + "previews": [ + { + "name": "portrait", + "path": "carving_and_etching/linocut/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "carving_and_etching/linocut/landscape-0.jpg" + } + ] + }, + { + "modifier": "Paper Model", + "previews": [ + { + "name": "portrait", + "path": "carving_and_etching/paper_model/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "carving_and_etching/paper_model/landscape-0.jpg" + } + ] + }, + { + "modifier": "Paper-Mache", + "previews": [ + { + "name": "portrait", + "path": "carving_and_etching/paper-mache/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "carving_and_etching/paper-mache/landscape-0.jpg" + } + ] + }, + { + "modifier": "Papercutting", + "previews": [ + { + "name": "portrait", + "path": "carving_and_etching/papercutting/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "carving_and_etching/papercutting/landscape-0.jpg" + } + ] + }, + { + "modifier": "Pyrography", + "previews": [ + { + "name": "portrait", + "path": "carving_and_etching/pyrography/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "carving_and_etching/pyrography/landscape-0.jpg" + } + ] + }, + { + "modifier": "Wood-Carving", + "previews": [ + { + "name": "portrait", + "path": "carving_and_etching/wood-carving/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "carving_and_etching/wood-carving/landscape-0.jpg" + } + ] + } ] - ], - [ - "Camera", - [ - "Aerial View", - "Canon50", - "Cinematic", - "Close-up", - "Color Grading", - "Dramatic", - "Film Grain", - "Fisheye Lens", - "Glamor Shot", - "Golden Hour", - "HD", - "Landscape", - "Lens Flare", - "Macro", - "Polaroid", - "Photoshoot", - "Portrait", - "Studio Lighting", - "Vintage", - "War Photography", - "White Balance", - "Wildlife Photography" + }, + { + "category": "Camera", + "modifiers": [ + { + "modifier": "Aerial View", + "previews": [ + { + "name": "portrait", + "path": "camera/aerial_view/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/aerial_view/landscape-0.jpg" + } + ] + }, + { + "modifier": "Canon50", + "previews": [ + { + "name": "portrait", + "path": "camera/canon50/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/canon50/landscape-0.jpg" + } + ] + }, + { + "modifier": "Cinematic", + "previews": [ + { + "name": "portrait", + "path": "camera/cinematic/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/cinematic/landscape-0.jpg" + } + ] + }, + { + "modifier": "Close-up", + "previews": [ + { + "name": "portrait", + "path": "camera/close-up/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/close-up/landscape-0.jpg" + } + ] + }, + { + "modifier": "Color Grading", + "previews": [ + { + "name": "portrait", + "path": "camera/color_grading/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/color_grading/landscape-0.jpg" + } + ] + }, + { + "modifier": "Dramatic", + "previews": [ + { + "name": "portrait", + "path": "camera/dramatic/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/dramatic/landscape-0.jpg" + } + ] + }, + { + "modifier": "Film Grain", + "previews": [ + { + "name": "portrait", + "path": "camera/film_grain/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/film_grain/landscape-0.jpg" + } + ] + }, + { + "modifier": "Fisheye Lens", + "previews": [ + { + "name": "portrait", + "path": "camera/fisheye_lens/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/fisheye_lens/landscape-0.jpg" + } + ] + }, + { + "modifier": "Glamor Shot", + "previews": [ + { + "name": "portrait", + "path": "camera/glamor_shot/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/glamor_shot/landscape-0.jpg" + } + ] + }, + { + "modifier": "Golden Hour", + "previews": [ + { + "name": "portrait", + "path": "camera/golden_hour/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/golden_hour/landscape-0.jpg" + } + ] + }, + { + "modifier": "HD", + "previews": [ + { + "name": "portrait", + "path": "camera/hd/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/hd/landscape-0.jpg" + } + ] + }, + { + "modifier": "Landscape", + "previews": [ + { + "name": "portrait", + "path": "camera/landscape/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/landscape/landscape-0.jpg" + } + ] + }, + { + "modifier": "Lens Flare", + "previews": [ + { + "name": "portrait", + "path": "camera/lens_flare/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/lens_flare/landscape-0.jpg" + } + ] + }, + { + "modifier": "Macro", + "previews": [ + { + "name": "portrait", + "path": "camera/macro/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/macro/landscape-0.jpg" + } + ] + }, + { + "modifier": "Polaroid", + "previews": [ + { + "name": "portrait", + "path": "camera/polaroid/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/polaroid/landscape-0.jpg" + } + ] + }, + { + "modifier": "Photoshoot", + "previews": [ + { + "name": "portrait", + "path": "camera/photoshoot/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/photoshoot/landscape-0.jpg" + } + ] + }, + { + "modifier": "Portrait", + "previews": [ + { + "name": "portrait", + "path": "camera/portrait/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/portrait/landscape-0.jpg" + } + ] + }, + { + "modifier": "Studio Lighting", + "previews": [ + { + "name": "portrait", + "path": "camera/studio_lighting/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/studio_lighting/landscape-0.jpg" + } + ] + }, + { + "modifier": "Vintage", + "previews": [ + { + "name": "portrait", + "path": "camera/vintage/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/vintage/landscape-0.jpg" + } + ] + }, + { + "modifier": "War Photography", + "previews": [ + { + "name": "portrait", + "path": "camera/war_photography/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/war_photography/landscape-0.jpg" + } + ] + }, + { + "modifier": "White Balance", + "previews": [ + { + "name": "portrait", + "path": "camera/white_balance/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/white_balance/landscape-0.jpg" + } + ] + }, + { + "modifier": "Wildlife Photography", + "previews": [ + { + "name": "portrait", + "path": "camera/wildlife_photography/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "camera/wildlife_photography/landscape-0.jpg" + } + ] + } ] - ], - [ - "Color", - [ - "Beautiful Lighting", - "Cold Color Palette", - "Colorful", - "Dynamic Lighting", - "Electric Colors", - "Infrared", - "Pastel", - "Neon", - "Synthwave", - "Warm Color Palette" + }, + { + "category": "Color", + "modifiers": [ + { + "modifier": "Beautiful Lighting", + "previews": [ + { + "name": "portrait", + "path": "color/beautiful_lighting/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "color/beautiful_lighting/landscape-0.jpg" + } + ] + }, + { + "modifier": "Cold Color Palette", + "previews": [ + { + "name": "portrait", + "path": "color/cold_color_palette/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "color/cold_color_palette/landscape-0.jpg" + } + ] + }, + { + "modifier": "Colorful", + "previews": [ + { + "name": "portrait", + "path": "color/colorful/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "color/colorful/landscape-0.jpg" + } + ] + }, + { + "modifier": "Dynamic Lighting", + "previews": [ + { + "name": "portrait", + "path": "color/dynamic_lighting/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "color/dynamic_lighting/landscape-0.jpg" + } + ] + }, + { + "modifier": "Electric Colors", + "previews": [ + { + "name": "portrait", + "path": "color/electric_colors/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "color/electric_colors/landscape-0.jpg" + } + ] + }, + { + "modifier": "Infrared", + "previews": [ + { + "name": "portrait", + "path": "color/infrared/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "color/infrared/landscape-0.jpg" + } + ] + }, + { + "modifier": "Pastel", + "previews": [ + { + "name": "portrait", + "path": "color/pastel/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "color/pastel/landscape-0.jpg" + } + ] + }, + { + "modifier": "Neon", + "previews": [ + { + "name": "portrait", + "path": "color/neon/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "color/neon/landscape-0.jpg" + } + ] + }, + { + "modifier": "Synthwave", + "previews": [ + { + "name": "portrait", + "path": "color/synthwave/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "color/synthwave/landscape-0.jpg" + } + ] + }, + { + "modifier": "Warm Color Palette", + "previews": [ + { + "name": "portrait", + "path": "color/warm_color_palette/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "color/warm_color_palette/landscape-0.jpg" + } + ] + } ] - ], - [ - "Emotions", - [ - "Angry", - "Bitter", - "Disgusted", - "Embarrassed", - "Evil", - "Excited", - "Fear", - "Funny", - "Happy", - "Horrifying", - "Lonely", - "Sad", - "Serene", - "Surprised", - "Melancholic" + }, + { + "category": "Emotions", + "modifiers": [ + { + "modifier": "Angry", + "previews": [ + { + "name": "portrait", + "path": "emotions/angry/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/angry/landscape-0.jpg" + } + ] + }, + { + "modifier": "Bitter", + "previews": [ + { + "name": "portrait", + "path": "emotions/bitter/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/bitter/landscape-0.jpg" + } + ] + }, + { + "modifier": "Disgusted", + "previews": [ + { + "name": "portrait", + "path": "emotions/disgusted/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/disgusted/landscape-0.jpg" + } + ] + }, + { + "modifier": "Embarrassed", + "previews": [ + { + "name": "portrait", + "path": "emotions/embarrassed/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/embarrassed/landscape-0.jpg" + } + ] + }, + { + "modifier": "Evil", + "previews": [ + { + "name": "portrait", + "path": "emotions/evil/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/evil/landscape-0.jpg" + } + ] + }, + { + "modifier": "Excited", + "previews": [ + { + "name": "portrait", + "path": "emotions/excited/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/excited/landscape-0.jpg" + } + ] + }, + { + "modifier": "Fear", + "previews": [ + { + "name": "portrait", + "path": "emotions/fear/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/fear/landscape-0.jpg" + } + ] + }, + { + "modifier": "Funny", + "previews": [ + { + "name": "portrait", + "path": "emotions/funny/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/funny/landscape-0.jpg" + } + ] + }, + { + "modifier": "Happy", + "previews": [ + { + "name": "portrait", + "path": "emotions/happy/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/happy/landscape-0.jpg" + } + ] + }, + { + "modifier": "Horrifying", + "previews": [ + { + "name": "portrait", + "path": "emotions/horrifying/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/horrifying/landscape-0.jpg" + } + ] + }, + { + "modifier": "Lonely", + "previews": [ + { + "name": "portrait", + "path": "emotions/lonely/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/lonely/landscape-0.jpg" + } + ] + }, + { + "modifier": "Sad", + "previews": [ + { + "name": "portrait", + "path": "emotions/sad/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/sad/landscape-0.jpg" + } + ] + }, + { + "modifier": "Serene", + "previews": [ + { + "name": "portrait", + "path": "emotions/serene/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/serene/landscape-0.jpg" + } + ] + }, + { + "modifier": "Surprised", + "previews": [ + { + "name": "portrait", + "path": "emotions/surprised/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/surprised/landscape-0.jpg" + } + ] + }, + { + "modifier": "Melancholic", + "previews": [ + { + "name": "portrait", + "path": "emotions/melancholic/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "emotions/melancholic/landscape-0.jpg" + } + ] + } ] - ], - [ - "Style of an artist or community", - [ - "Artstation", - "trending on Artstation", - "by Agnes Lawrence Pelton", - "by Akihito Yoshida", - "by Alex Grey", - "by Alexander Jansson", - "by Alphonse Mucha", - "by Andy Warhol", - "by Artgerm", - "by Asaf Hanuka", - "by Aubrey Beardsley", - "by Banksy", - "by Beeple", - "by Ben Enwonwu", - "by Bob Eggleton", - "by Caravaggio Michelangelo Merisi", - "by Caspar David Friedrich", - "by Chris Foss", - "by Claude Monet", - "by Dan Mumford", - "by David Mann", - "by Diego Velázquez", - "by Disney Animation Studios", - "by Édouard Manet", - "by Esao Andrews", - "by Frida Kahlo", - "by Gediminas Pranckevicius", - "by Georgia O'Keeffe", - "by Greg Rutkowski", - "by Gustave Doré", - "by Gustave Klimt", - "by H.R. Giger", - "by Hayao Miyazaki", - "by Henri Matisse", - "by HP Lovecraft", - "by Ivan Shishkin", - "by Jack Kirby", - "by Jackson Pollock", - "by James Jean", - "by Jim Burns", - "by Johannes Vermeer", - "by John William Waterhouse", - "by Katsushika Hokusai", - "by Kim Tschang Yeul", - "by Ko Young Hoon", - "by Leonardo da Vinci", - "by Lisa Frank", - "by M.C. Escher", - "by Mahmoud Saïd", - "by Makoto Shinkai", - "by Marc Simonetti", - "by Mark Brooks", - "by Michelangelo", - "by Pablo Picasso", - "by Paul Klee", - "by Peter Mohrbacher", - "by Pierre-Auguste Renoir", - "by Pixar Animation Studios", - "by Rembrandt", - "by Richard Dadd", - "by Rossdraws", - "by Salvador Dalí", - "by Sam Does Arts", - "by Sandro Botticelli", - "by Ted Nasmith", - "by Ten Hundred", - "by Thomas Kinkade", - "by Tivadar Csontváry Kosztka", - "by Victo Ngai", - "by Vincent Di Fate", - "by Vincent van Gogh", - "by Wes Anderson", - "by wlop", - "by Yoshitaka Amano" + }, + { + "category": "Artist", + "modifiers": [ + { + "modifier": "Artstation", + "previews": [ + { + "name": "portrait", + "path": "artist/artstation/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/artstation/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Agnes Lawrence Pelton", + "previews": [ + { + "name": "portrait", + "path": "artist/by_agnes_lawrence_pelton/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_agnes_lawrence_pelton/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Akihito Yoshida", + "previews": [ + { + "name": "portrait", + "path": "artist/by_akihito_yoshida/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_akihito_yoshida/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Alex Grey", + "previews": [ + { + "name": "portrait", + "path": "artist/by_alex_grey/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_alex_grey/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Alexander Jansson", + "previews": [ + { + "name": "portrait", + "path": "artist/by_alexander_jansson/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_alexander_jansson/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Alphonse Mucha", + "previews": [ + { + "name": "portrait", + "path": "artist/by_alphonse_mucha/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_alphonse_mucha/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Andy Warhol", + "previews": [ + { + "name": "portrait", + "path": "artist/by_andy_warhol/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_andy_warhol/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Artgerm", + "previews": [ + { + "name": "portrait", + "path": "artist/by_artgerm/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_artgerm/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Asaf Hanuka", + "previews": [ + { + "name": "portrait", + "path": "artist/by_asaf_hanuka/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_asaf_hanuka/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Aubrey Beardsley", + "previews": [ + { + "name": "portrait", + "path": "artist/by_aubrey_beardsley/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_aubrey_beardsley/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Banksy", + "previews": [ + { + "name": "portrait", + "path": "artist/by_banksy/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_banksy/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Beeple", + "previews": [ + { + "name": "portrait", + "path": "artist/by_beeple/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_beeple/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Ben Enwonwu", + "previews": [ + { + "name": "portrait", + "path": "artist/by_ben_enwonwu/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_ben_enwonwu/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Bob Eggleton", + "previews": [ + { + "name": "portrait", + "path": "artist/by_bob_eggleton/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_bob_eggleton/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Caravaggio Michelangelo Merisi", + "previews": [ + { + "name": "portrait", + "path": "artist/by_caravaggio_michelangelo_merisi/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_caravaggio_michelangelo_merisi/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Caspar David Friedrich", + "previews": [ + { + "name": "portrait", + "path": "artist/by_caspar_david_friedrich/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_caspar_david_friedrich/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Chris Foss", + "previews": [ + { + "name": "portrait", + "path": "artist/by_chris_foss/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_chris_foss/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Claude Monet", + "previews": [ + { + "name": "portrait", + "path": "artist/by_claude_monet/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_claude_monet/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Dan Mumford", + "previews": [ + { + "name": "portrait", + "path": "artist/by_dan_mumford/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_dan_mumford/landscape-0.jpg" + } + ] + }, + { + "modifier": "by David Mann", + "previews": [ + { + "name": "portrait", + "path": "artist/by_david_mann/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_david_mann/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Diego Velázquez", + "previews": [ + { + "name": "portrait", + "path": "artist/by_diego_vela_zquez/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_diego_vela_zquez/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Disney Animation Studios", + "previews": [ + { + "name": "portrait", + "path": "artist/by_disney_animation_studios/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_disney_animation_studios/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Édouard Manet", + "previews": [ + { + "name": "portrait", + "path": "artist/by_e_douard_manet/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_e_douard_manet/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Esao Andrews", + "previews": [ + { + "name": "portrait", + "path": "artist/by_esao_andrews/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_esao_andrews/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Frida Kahlo", + "previews": [ + { + "name": "portrait", + "path": "artist/by_frida_kahlo/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_frida_kahlo/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Gediminas Pranckevicius", + "previews": [ + { + "name": "portrait", + "path": "artist/by_gediminas_pranckevicius/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_gediminas_pranckevicius/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Georgia O'Keeffe", + "previews": [ + { + "name": "portrait", + "path": "artist/by_georgia_o_keeffe/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_georgia_o_keeffe/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Greg Rutkowski", + "previews": [ + { + "name": "portrait", + "path": "artist/by_greg_rutkowski/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_greg_rutkowski/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Gustave Doré", + "previews": [ + { + "name": "portrait", + "path": "artist/by_gustave_dore_/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_gustave_dore_/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Gustave Klimt", + "previews": [ + { + "name": "portrait", + "path": "artist/by_gustave_klimt/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_gustave_klimt/landscape-0.jpg" + } + ] + }, + { + "modifier": "by H.R. Giger", + "previews": [ + { + "name": "portrait", + "path": "artist/by_h_r_giger/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_h_r_giger/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Hayao Miyazaki", + "previews": [ + { + "name": "portrait", + "path": "artist/by_hayao_miyazaki/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_hayao_miyazaki/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Henri Matisse", + "previews": [ + { + "name": "portrait", + "path": "artist/by_henri_matisse/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_henri_matisse/landscape-0.jpg" + } + ] + }, + { + "modifier": "by HP Lovecraft", + "previews": [ + { + "name": "portrait", + "path": "artist/by_hp_lovecraft/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_hp_lovecraft/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Ivan Shishkin", + "previews": [ + { + "name": "portrait", + "path": "artist/by_ivan_shishkin/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_ivan_shishkin/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Jack Kirby", + "previews": [ + { + "name": "portrait", + "path": "artist/by_jack_kirby/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_jack_kirby/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Jackson Pollock", + "previews": [ + { + "name": "portrait", + "path": "artist/by_jackson_pollock/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_jackson_pollock/landscape-0.jpg" + } + ] + }, + { + "modifier": "by James Jean", + "previews": [ + { + "name": "portrait", + "path": "artist/by_james_jean/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_james_jean/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Jim Burns", + "previews": [ + { + "name": "portrait", + "path": "artist/by_jim_burns/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_jim_burns/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Johannes Vermeer", + "previews": [ + { + "name": "portrait", + "path": "artist/by_johannes_vermeer/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_johannes_vermeer/landscape-0.jpg" + } + ] + }, + { + "modifier": "by John William Waterhouse", + "previews": [ + { + "name": "portrait", + "path": "artist/by_john_william_waterhouse/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_john_william_waterhouse/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Katsushika Hokusai", + "previews": [ + { + "name": "portrait", + "path": "artist/by_katsushika_hokusai/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_katsushika_hokusai/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Kim Tschang Yeul", + "previews": [ + { + "name": "portrait", + "path": "artist/by_kim_tschang_yeul/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_kim_tschang_yeul/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Ko Young Hoon", + "previews": [ + { + "name": "portrait", + "path": "artist/by_ko_young_hoon/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_ko_young_hoon/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Leonardo da Vinci", + "previews": [ + { + "name": "portrait", + "path": "artist/by_leonardo_da_vinci/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_leonardo_da_vinci/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Lisa Frank", + "previews": [ + { + "name": "portrait", + "path": "artist/by_lisa_frank/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_lisa_frank/landscape-0.jpg" + } + ] + }, + { + "modifier": "by M.C Escher", + "previews": [ + { + "name": "portrait", + "path": "artist/by_m_c_escher/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_m_c_escher/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Mahmoud Saïd", + "previews": [ + { + "name": "portrait", + "path": "artist/by_mahmoud_sai_d/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_mahmoud_sai_d/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Makoto Shinkai", + "previews": [ + { + "name": "portrait", + "path": "artist/by_makoto_shinkai/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_makoto_shinkai/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Marc Simonetti", + "previews": [ + { + "name": "portrait", + "path": "artist/by_marc_simonetti/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_marc_simonetti/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Mark Brooks", + "previews": [ + { + "name": "portrait", + "path": "artist/by_mark_brooks/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_mark_brooks/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Michelangelo", + "previews": [ + { + "name": "portrait", + "path": "artist/by_michelangelo/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_michelangelo/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Pablo Picasso", + "previews": [ + { + "name": "portrait", + "path": "artist/by_pablo_picasso/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_pablo_picasso/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Paul Klee", + "previews": [ + { + "name": "portrait", + "path": "artist/by_paul_klee/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_paul_klee/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Peter Mohrbacher", + "previews": [ + { + "name": "portrait", + "path": "artist/by_peter_mohrbacher/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_peter_mohrbacher/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Pierre-Auguste Renoir", + "previews": [ + { + "name": "portrait", + "path": "artist/by_pierre-auguste_renoir/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_pierre-auguste_renoir/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Pixar Animation Studios", + "previews": [ + { + "name": "portrait", + "path": "artist/by_pixar_animation_studios/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_pixar_animation_studios/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Rembrandt", + "previews": [ + { + "name": "portrait", + "path": "artist/by_rembrandt/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_rembrandt/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Richard Dadd", + "previews": [ + { + "name": "portrait", + "path": "artist/by_richard_dadd/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_richard_dadd/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Rossdraws", + "previews": [ + { + "name": "portrait", + "path": "artist/by_rossdraws/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_rossdraws/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Salvador Dalí", + "previews": [ + { + "name": "portrait", + "path": "artist/by_salvador_dali_/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_salvador_dali_/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Sam does Arts", + "previews": [ + { + "name": "portrait", + "path": "artist/by_sam_does_arts/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_sam_does_arts/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Sandro Botticelli", + "previews": [ + { + "name": "portrait", + "path": "artist/by_sandro_botticelli/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_sandro_botticelli/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Ted Nasmith", + "previews": [ + { + "name": "portrait", + "path": "artist/by_ted_nasmith/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_ted_nasmith/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Ten Hundred", + "previews": [ + { + "name": "portrait", + "path": "artist/by_ten_hundred/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_ten_hundred/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Thomas Kinkade", + "previews": [ + { + "name": "portrait", + "path": "artist/by_thomas_kinkade/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_thomas_kinkade/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Tivadar Csontváry Kosztka", + "previews": [ + { + "name": "portrait", + "path": "artist/by_tivadar_csontva_ry_kosztka/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_tivadar_csontva_ry_kosztka/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Victo Ngai", + "previews": [ + { + "name": "portrait", + "path": "artist/by_victo_ngai/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_victo_ngai/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Vincent di Fate", + "previews": [ + { + "name": "portrait", + "path": "artist/by_vincent_di_fate/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_vincent_di_fate/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Vincent van Gogh", + "previews": [ + { + "name": "portrait", + "path": "artist/by_vincent_van_gogh/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_vincent_van_gogh/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Wes Anderson", + "previews": [ + { + "name": "portrait", + "path": "artist/by_wes_anderson/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_wes_anderson/landscape-0.jpg" + } + ] + }, + { + "modifier": "by wlop", + "previews": [ + { + "name": "portrait", + "path": "artist/by_wlop/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_wlop/landscape-0.jpg" + } + ] + }, + { + "modifier": "by Yoshitaka Amano", + "previews": [ + { + "name": "portrait", + "path": "artist/by_yoshitaka_amano/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "artist/by_yoshitaka_amano/landscape-0.jpg" + } + ] + } ] - ], - [ - "CGI Software", - [ - "3D Model", - "3D Sculpt", - "3Ds Max Model", - "Blender Model", - "Cinema4d Model", - "Maya Model", - "Unreal Engine", - "Zbrush Sculpt" + }, + { + "category": "CGI Software", + "modifiers": [ + { + "modifier": "3D Model", + "previews": [ + { + "name": "portrait", + "path": "cgi_software/3d_model/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_software/3d_model/landscape-0.jpg" + } + ] + }, + { + "modifier": "3D Sculpt", + "previews": [ + { + "name": "portrait", + "path": "cgi_software/3d_sculpt/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_software/3d_sculpt/landscape-0.jpg" + } + ] + }, + { + "modifier": "3Ds Max Model", + "previews": [ + { + "name": "portrait", + "path": "cgi_software/3ds_max_model/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_software/3ds_max_model/landscape-0.jpg" + } + ] + }, + { + "modifier": "Blender Model", + "previews": [ + { + "name": "portrait", + "path": "cgi_software/blender_model/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_software/blender_model/landscape-0.jpg" + } + ] + }, + { + "modifier": "Cinema4d Model", + "previews": [ + { + "name": "portrait", + "path": "cgi_software/cinema4d_model/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_software/cinema4d_model/landscape-0.jpg" + } + ] + }, + { + "modifier": "Maya Model", + "previews": [ + { + "name": "portrait", + "path": "cgi_software/maya_model/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_software/maya_model/landscape-0.jpg" + } + ] + }, + { + "modifier": "Unreal Engine", + "previews": [ + { + "name": "portrait", + "path": "cgi_software/unreal_engine/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_software/unreal_engine/landscape-0.jpg" + } + ] + }, + { + "modifier": "Zbrush Sculpt", + "previews": [ + { + "name": "portrait", + "path": "cgi_software/zbrush_sculpt/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_software/zbrush_sculpt/landscape-0.jpg" + } + ] + } ] - ], - [ - "CGI Rendering", - [ - "3D Render", - "Corona Render", - "Creature Design", - "Cycles Render", - "Detailed Render", - "Environment Design", - "Intricate Environment", - "LSD Render", - "Octane Render", - "PBR", - "Glass Caustics", - "Global Illumination", - "Subsurface Scattering" + }, + { + "category": "CGI Rendering", + "modifiers": [ + { + "modifier": "3D Render", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/3d_render/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/3d_render/landscape-0.jpg" + } + ] + }, + { + "modifier": "Corona Render", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/corona_render/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/corona_render/landscape-0.jpg" + } + ] + }, + { + "modifier": "Creature Design", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/creature_design/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/creature_design/landscape-0.jpg" + } + ] + }, + { + "modifier": "Cycles Render", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/cycles_render/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/cycles_render/landscape-0.jpg" + } + ] + }, + { + "modifier": "Detailed Render", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/detailed_render/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/detailed_render/landscape-0.jpg" + } + ] + }, + { + "modifier": "Environment Design", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/environment_design/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/environment_design/landscape-0.jpg" + } + ] + }, + { + "modifier": "Intricate Environment", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/intricate_environment/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/intricate_environment/landscape-0.jpg" + } + ] + }, + { + "modifier": "LSD Render", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/lsd_render/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/lsd_render/landscape-0.jpg" + } + ] + }, + { + "modifier": "Octane Render", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/octane_render/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/octane_render/landscape-0.jpg" + } + ] + }, + { + "modifier": "PBR", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/pbr/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/pbr/landscape-0.jpg" + } + ] + }, + { + "modifier": "Glass Caustics", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/glass_caustics/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/glass_caustics/landscape-0.jpg" + } + ] + }, + { + "modifier": "Global Illumination", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/global_illumination/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/global_illumination/landscape-0.jpg" + } + ] + }, + { + "modifier": "Subsurface Scattering", + "previews": [ + { + "name": "portrait", + "path": "cgi_rendering/subsurface_scattering/portrait-0.jpg" + }, + { + "name": "landscape", + "path": "cgi_rendering/subsurface_scattering/landscape-0.jpg" + } + ] + } ] - ] + } ] diff --git a/ui/sd_internal/__init__.py b/ui/sd_internal/__init__.py index e3a8aa1e..e7630a1a 100644 --- a/ui/sd_internal/__init__.py +++ b/ui/sd_internal/__init__.py @@ -1,6 +1,7 @@ import json class Request: + session_id: str = "session" prompt: str = "" init_image: str = None # base64 mask: str = None # base64 @@ -11,6 +12,7 @@ class Request: height: int = 512 seed: int = 42 prompt_strength: float = 0.8 + sampler: str = None # "ddim", "plms", "heun", "euler", "euler_a", "dpm2", "dpm2_a", "lms" # allow_nsfw: bool = False precision: str = "autocast" # or "full" save_to_disk_path: str = None @@ -21,8 +23,12 @@ class Request: use_upscale: str = None # or "RealESRGAN_x4plus" or "RealESRGAN_x4plus_anime_6B" show_only_filtered_image: bool = False + stream_progress_updates: bool = False + stream_image_progress: bool = False + def json(self): return { + "session_id": self.session_id, "prompt": self.prompt, "num_outputs": self.num_outputs, "num_inference_steps": self.num_inference_steps, @@ -31,15 +37,18 @@ class Request: "height": self.height, "seed": self.seed, "prompt_strength": self.prompt_strength, + "sampler": self.sampler, "use_face_correction": self.use_face_correction, "use_upscale": self.use_upscale, } def to_string(self): return f''' + session_id: {self.session_id} prompt: {self.prompt} seed: {self.seed} num_inference_steps: {self.num_inference_steps} + sampler: {self.sampler} guidance_scale: {self.guidance_scale} w: {self.width} h: {self.height} @@ -50,7 +59,10 @@ class Request: use_full_precision: {self.use_full_precision} use_face_correction: {self.use_face_correction} use_upscale: {self.use_upscale} - show_only_filtered_image: {self.show_only_filtered_image}''' + show_only_filtered_image: {self.show_only_filtered_image} + + stream_progress_updates: {self.stream_progress_updates} + stream_image_progress: {self.stream_image_progress}''' class Image: data: str # base64 @@ -71,13 +83,11 @@ class Image: class Response: request: Request - session_id: str images: list def json(self): res = { "status": 'succeeded', - "session_id": self.session_id, "request": self.request.json(), "output": [], } diff --git a/ui/sd_internal/ddim_callback.patch b/ui/sd_internal/ddim_callback.patch index 685c2ce5..36335abe 100644 --- a/ui/sd_internal/ddim_callback.patch +++ b/ui/sd_internal/ddim_callback.patch @@ -1,8 +1,26 @@ diff --git a/optimizedSD/ddpm.py b/optimizedSD/ddpm.py -index dcf7901..1f99adc 100644 +index b967b55..35ef520 100644 --- a/optimizedSD/ddpm.py +++ b/optimizedSD/ddpm.py -@@ -528,7 +528,8 @@ class UNet(DDPM): +@@ -22,7 +22,7 @@ from ldm.util import exists, default, instantiate_from_config + from ldm.modules.diffusionmodules.util import make_beta_schedule + from ldm.modules.diffusionmodules.util import make_ddim_sampling_parameters, make_ddim_timesteps, noise_like + from ldm.modules.diffusionmodules.util import make_beta_schedule, extract_into_tensor, noise_like +-from samplers import CompVisDenoiser, get_ancestral_step, to_d, append_dims,linear_multistep_coeff ++from .samplers import CompVisDenoiser, get_ancestral_step, to_d, append_dims,linear_multistep_coeff + + def disabled_train(self): + """Overwrite model.train with this function to make sure train/eval mode +@@ -506,6 +506,8 @@ class UNet(DDPM): + + x_latent = noise if x0 is None else x0 + # sampling ++ if sampler in ('ddim', 'dpm2', 'heun', 'dpm2_a', 'lms') and not hasattr(self, 'ddim_timesteps'): ++ self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=False) + + if sampler == "plms": + self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=False) +@@ -528,39 +530,46 @@ class UNet(DDPM): elif sampler == "ddim": samples = self.ddim_sampling(x_latent, conditioning, S, unconditional_guidance_scale=unconditional_guidance_scale, unconditional_conditioning=unconditional_conditioning, @@ -10,9 +28,69 @@ index dcf7901..1f99adc 100644 + mask = mask,init_latent=x_T,use_original_steps=False, + callback=callback, img_callback=img_callback) - # elif sampler == "euler": - # cvd = CompVisDenoiser(self.alphas_cumprod) -@@ -687,7 +688,8 @@ class UNet(DDPM): + elif sampler == "euler": + self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=False) + samples = self.euler_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning, +- unconditional_guidance_scale=unconditional_guidance_scale) ++ unconditional_guidance_scale=unconditional_guidance_scale, ++ img_callback=img_callback) + elif sampler == "euler_a": + self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=False) + samples = self.euler_ancestral_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning, +- unconditional_guidance_scale=unconditional_guidance_scale) ++ unconditional_guidance_scale=unconditional_guidance_scale, ++ img_callback=img_callback) + + elif sampler == "dpm2": + samples = self.dpm_2_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning, +- unconditional_guidance_scale=unconditional_guidance_scale) ++ unconditional_guidance_scale=unconditional_guidance_scale, ++ img_callback=img_callback) + elif sampler == "heun": + samples = self.heun_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning, +- unconditional_guidance_scale=unconditional_guidance_scale) ++ unconditional_guidance_scale=unconditional_guidance_scale, ++ img_callback=img_callback) + + elif sampler == "dpm2_a": + samples = self.dpm_2_ancestral_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning, +- unconditional_guidance_scale=unconditional_guidance_scale) ++ unconditional_guidance_scale=unconditional_guidance_scale, ++ img_callback=img_callback) + + + elif sampler == "lms": + samples = self.lms_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning, +- unconditional_guidance_scale=unconditional_guidance_scale) ++ unconditional_guidance_scale=unconditional_guidance_scale, ++ img_callback=img_callback) ++ ++ yield from samples + + if(self.turbo): + self.model1.to("cpu") + self.model2.to("cpu") + +- return samples +- + @torch.no_grad() + def plms_sampling(self, cond,b, img, + ddim_use_original_steps=False, +@@ -599,10 +608,10 @@ class UNet(DDPM): + old_eps.append(e_t) + if len(old_eps) >= 4: + old_eps.pop(0) +- if callback: callback(i) +- if img_callback: img_callback(pred_x0, i) ++ if callback: yield from callback(i) ++ if img_callback: yield from img_callback(pred_x0, i) + +- return img ++ yield from img_callback(img, len(iterator)-1) + + @torch.no_grad() + def p_sample_plms(self, x, c, t, index, repeat_noise=False, use_original_steps=False, quantize_denoised=False, +@@ -706,7 +715,8 @@ class UNet(DDPM): @torch.no_grad() def ddim_sampling(self, x_latent, cond, t_start, unconditional_guidance_scale=1.0, unconditional_conditioning=None, @@ -22,13 +100,233 @@ index dcf7901..1f99adc 100644 timesteps = self.ddim_timesteps timesteps = timesteps[:t_start] -@@ -710,6 +712,9 @@ class UNet(DDPM): - x_dec = self.p_sample_ddim(x_dec, cond, ts, index=index, use_original_steps=use_original_steps, +@@ -730,10 +740,13 @@ class UNet(DDPM): unconditional_guidance_scale=unconditional_guidance_scale, unconditional_conditioning=unconditional_conditioning) -+ -+ if callback: callback(i) -+ if img_callback: img_callback(x_dec, i) ++ if callback: yield from callback(i) ++ if img_callback: yield from img_callback(x_dec, i) ++ if mask is not None: - return x0 * mask + (1. - mask) * x_dec +- return x0 * mask + (1. - mask) * x_dec ++ x_dec = x0 * mask + (1. - mask) * x_dec + +- return x_dec ++ yield from img_callback(x_dec, len(iterator)-1) + + + @torch.no_grad() +@@ -779,13 +792,16 @@ class UNet(DDPM): + + + @torch.no_grad() +- def euler_sampling(self, ac, x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None,callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1.): ++ def euler_sampling(self, ac, x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None,callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1., ++ img_callback=None): + """Implements Algorithm 2 (Euler steps) from Karras et al. (2022).""" + extra_args = {} if extra_args is None else extra_args + cvd = CompVisDenoiser(ac) + sigmas = cvd.get_sigmas(S) + x = x*sigmas[0] + ++ print(f"Running Euler Sampling with {len(sigmas) - 1} timesteps") ++ + s_in = x.new_ones([x.shape[0]]).half() + for i in trange(len(sigmas) - 1, disable=disable): + gamma = min(s_churn / (len(sigmas) - 1), 2 ** 0.5 - 1) if s_tmin <= sigmas[i] <= s_tmax else 0. +@@ -807,13 +823,18 @@ class UNet(DDPM): + d = to_d(x, sigma_hat, denoised) + if callback is not None: + callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigma_hat, 'denoised': denoised}) ++ ++ if img_callback: yield from img_callback(x, i) ++ + dt = sigmas[i + 1] - sigma_hat + # Euler method + x = x + d * dt +- return x ++ ++ yield from img_callback(x, len(sigmas)-1) + + @torch.no_grad() +- def euler_ancestral_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None, callback=None, disable=None): ++ def euler_ancestral_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None, callback=None, disable=None, ++ img_callback=None): + """Ancestral sampling with Euler method steps.""" + extra_args = {} if extra_args is None else extra_args + +@@ -822,6 +843,8 @@ class UNet(DDPM): + sigmas = cvd.get_sigmas(S) + x = x*sigmas[0] + ++ print(f"Running Euler Ancestral Sampling with {len(sigmas) - 1} timesteps") ++ + s_in = x.new_ones([x.shape[0]]).half() + for i in trange(len(sigmas) - 1, disable=disable): + +@@ -837,17 +860,22 @@ class UNet(DDPM): + sigma_down, sigma_up = get_ancestral_step(sigmas[i], sigmas[i + 1]) + if callback is not None: + callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigmas[i], 'denoised': denoised}) ++ ++ if img_callback: yield from img_callback(x, i) ++ + d = to_d(x, sigmas[i], denoised) + # Euler method + dt = sigma_down - sigmas[i] + x = x + d * dt + x = x + torch.randn_like(x) * sigma_up +- return x ++ ++ yield from img_callback(x, len(sigmas)-1) + + + + @torch.no_grad() +- def heun_sampling(self, ac, x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1.): ++ def heun_sampling(self, ac, x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1., ++ img_callback=None): + """Implements Algorithm 2 (Heun steps) from Karras et al. (2022).""" + extra_args = {} if extra_args is None else extra_args + +@@ -855,6 +883,8 @@ class UNet(DDPM): + sigmas = cvd.get_sigmas(S) + x = x*sigmas[0] + ++ print(f"Running Heun Sampling with {len(sigmas) - 1} timesteps") ++ + + s_in = x.new_ones([x.shape[0]]).half() + for i in trange(len(sigmas) - 1, disable=disable): +@@ -876,6 +906,9 @@ class UNet(DDPM): + d = to_d(x, sigma_hat, denoised) + if callback is not None: + callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigma_hat, 'denoised': denoised}) ++ ++ if img_callback: yield from img_callback(x, i) ++ + dt = sigmas[i + 1] - sigma_hat + if sigmas[i + 1] == 0: + # Euler method +@@ -895,11 +928,13 @@ class UNet(DDPM): + d_2 = to_d(x_2, sigmas[i + 1], denoised_2) + d_prime = (d + d_2) / 2 + x = x + d_prime * dt +- return x ++ ++ yield from img_callback(x, len(sigmas)-1) + + + @torch.no_grad() +- def dpm_2_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None, callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1.): ++ def dpm_2_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None, callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1., ++ img_callback=None): + """A sampler inspired by DPM-Solver-2 and Algorithm 2 from Karras et al. (2022).""" + extra_args = {} if extra_args is None else extra_args + +@@ -907,6 +942,8 @@ class UNet(DDPM): + sigmas = cvd.get_sigmas(S) + x = x*sigmas[0] + ++ print(f"Running DPM2 Sampling with {len(sigmas) - 1} timesteps") ++ + s_in = x.new_ones([x.shape[0]]).half() + for i in trange(len(sigmas) - 1, disable=disable): + gamma = min(s_churn / (len(sigmas) - 1), 2 ** 0.5 - 1) if s_tmin <= sigmas[i] <= s_tmax else 0. +@@ -924,7 +961,7 @@ class UNet(DDPM): + e_t_uncond, e_t = (x_in + eps * c_out).chunk(2) + denoised = e_t_uncond + unconditional_guidance_scale * (e_t - e_t_uncond) + +- ++ if img_callback: yield from img_callback(x, i) + + d = to_d(x, sigma_hat, denoised) + # Midpoint method, where the midpoint is chosen according to a rho=3 Karras schedule +@@ -945,11 +982,13 @@ class UNet(DDPM): + + d_2 = to_d(x_2, sigma_mid, denoised_2) + x = x + d_2 * dt_2 +- return x ++ ++ yield from img_callback(x, len(sigmas)-1) + + + @torch.no_grad() +- def dpm_2_ancestral_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None): ++ def dpm_2_ancestral_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None, ++ img_callback=None): + """Ancestral sampling with DPM-Solver inspired second-order steps.""" + extra_args = {} if extra_args is None else extra_args + +@@ -957,6 +996,8 @@ class UNet(DDPM): + sigmas = cvd.get_sigmas(S) + x = x*sigmas[0] + ++ print(f"Running DPM2 Ancestral Sampling with {len(sigmas) - 1} timesteps") ++ + s_in = x.new_ones([x.shape[0]]).half() + for i in trange(len(sigmas) - 1, disable=disable): + +@@ -973,6 +1014,9 @@ class UNet(DDPM): + sigma_down, sigma_up = get_ancestral_step(sigmas[i], sigmas[i + 1]) + if callback is not None: + callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigmas[i], 'denoised': denoised}) ++ ++ if img_callback: yield from img_callback(x, i) ++ + d = to_d(x, sigmas[i], denoised) + # Midpoint method, where the midpoint is chosen according to a rho=3 Karras schedule + sigma_mid = ((sigmas[i] ** (1 / 3) + sigma_down ** (1 / 3)) / 2) ** 3 +@@ -993,11 +1037,13 @@ class UNet(DDPM): + d_2 = to_d(x_2, sigma_mid, denoised_2) + x = x + d_2 * dt_2 + x = x + torch.randn_like(x) * sigma_up +- return x ++ ++ yield from img_callback(x, len(sigmas)-1) + + + @torch.no_grad() +- def lms_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None, order=4): ++ def lms_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None, order=4, ++ img_callback=None): + extra_args = {} if extra_args is None else extra_args + s_in = x.new_ones([x.shape[0]]) + +@@ -1005,6 +1051,8 @@ class UNet(DDPM): + sigmas = cvd.get_sigmas(S) + x = x*sigmas[0] + ++ print(f"Running LMS Sampling with {len(sigmas) - 1} timesteps") ++ + ds = [] + for i in trange(len(sigmas) - 1, disable=disable): + +@@ -1017,6 +1065,7 @@ class UNet(DDPM): + e_t_uncond, e_t = (x_in + eps * c_out).chunk(2) + denoised = e_t_uncond + unconditional_guidance_scale * (e_t - e_t_uncond) + ++ if img_callback: yield from img_callback(x, i) + + d = to_d(x, sigmas[i], denoised) + ds.append(d) +@@ -1027,4 +1076,5 @@ class UNet(DDPM): + cur_order = min(i + 1, order) + coeffs = [linear_multistep_coeff(cur_order, sigmas.cpu(), i, j) for j in range(cur_order)] + x = x + sum(coeff * d for coeff, d in zip(coeffs, reversed(ds))) +- return x ++ ++ yield from img_callback(x, len(sigmas)-1) +diff --git a/optimizedSD/openaimodelSplit.py b/optimizedSD/openaimodelSplit.py +index abc3098..7a32ffe 100644 +--- a/optimizedSD/openaimodelSplit.py ++++ b/optimizedSD/openaimodelSplit.py +@@ -13,7 +13,7 @@ from ldm.modules.diffusionmodules.util import ( + normalization, + timestep_embedding, + ) +-from splitAttention import SpatialTransformer ++from .splitAttention import SpatialTransformer + + + class AttentionPool2d(nn.Module): diff --git a/ui/sd_internal/env_yaml.patch b/ui/sd_internal/env_yaml.patch new file mode 100644 index 00000000..cc140ef1 --- /dev/null +++ b/ui/sd_internal/env_yaml.patch @@ -0,0 +1,13 @@ +diff --git a/environment.yaml b/environment.yaml +index 7f25da8..306750f 100644 +--- a/environment.yaml ++++ b/environment.yaml +@@ -23,6 +23,8 @@ dependencies: + - torch-fidelity==0.3.0 + - transformers==4.19.2 + - torchmetrics==0.6.0 ++ - pywavelets==1.3.0 ++ - pandas==1.4.4 + - kornia==0.6 + - -e git+https://github.com/CompVis/taming-transformers.git@master#egg=taming-transformers + - -e git+https://github.com/openai/CLIP.git@main#egg=clip diff --git a/ui/sd_internal/runtime.py b/ui/sd_internal/runtime.py index 0fe21ee6..3083e3ca 100644 --- a/ui/sd_internal/runtime.py +++ b/ui/sd_internal/runtime.py @@ -1,9 +1,10 @@ +import json import os, re import traceback import torch import numpy as np from omegaconf import OmegaConf -from PIL import Image +from PIL import Image, ImageOps from tqdm import tqdm, trange from itertools import islice from einops import rearrange @@ -32,10 +33,11 @@ filename_regex = re.compile('[^a-zA-Z0-9]') from . import Request, Response, Image as ResponseImage import base64 from io import BytesIO +#from colorama import Fore # local -session_id = str(uuid.uuid4())[-8:] stop_processing = False +temp_images = {} ckpt_file = None gfpgan_file = None @@ -184,23 +186,47 @@ def load_model_real_esrgan(real_esrgan_to_use): print('loaded ', real_esrgan_to_use, 'to', device, 'precision', precision) def mk_img(req: Request): - global modelFS, device + try: + yield from do_mk_img(req) + except Exception as e: + print(traceback.format_exc()) + + gc() + + if device != "cpu": + modelFS.to("cpu") + modelCS.to("cpu") + + model.model1.to("cpu") + model.model2.to("cpu") + + gc() + + yield json.dumps({ + "status": 'failed', + "detail": str(e) + }) + +def do_mk_img(req: Request): + global model, modelCS, modelFS, device global model_gfpgan, model_real_esrgan global stop_processing stop_processing = False res = Response() - res.session_id = session_id res.request = req res.images = [] + temp_images.clear() + model.turbo = req.turbo if req.use_cpu: if device != 'cpu': device = 'cpu' if model_is_half: + del model, modelCS, modelFS load_model_ckpt(ckpt_file, device) load_model_gfpgan(gfpgan_file) @@ -215,7 +241,8 @@ def mk_img(req: Request): (req.init_image is None and model_fs_is_half) or \ (req.init_image is not None and not model_fs_is_half and not force_full_precision): - load_model_ckpt(ckpt_file, device, model.turbo, unet_bs, ('full' if req.use_full_precision else 'autocast'), half_model_fs=(req.init_image is not None and not req.use_full_precision)) + del model, modelCS, modelFS + load_model_ckpt(ckpt_file, device, req.turbo, unet_bs, ('full' if req.use_full_precision else 'autocast'), half_model_fs=(req.init_image is not None and not req.use_full_precision)) if prev_device != device: load_model_gfpgan(gfpgan_file) @@ -248,6 +275,7 @@ def mk_img(req: Request): opt_use_upscale = req.use_upscale opt_show_only_filtered = req.show_only_filtered_image opt_format = 'png' + opt_sampler_name = req.sampler print(req.to_string(), '\n device', device) @@ -265,6 +293,8 @@ def mk_img(req: Request): else: precision_scope = nullcontext + mask = None + if req.init_image is None: handler = _txt2img @@ -284,18 +314,22 @@ def mk_img(req: Request): init_image = repeat(init_image, '1 ... -> b ...', b=batch_size) init_latent = modelFS.get_first_stage_encoding(modelFS.encode_first_stage(init_image)) # move to latent space - if device != "cpu": - mem = torch.cuda.memory_allocated() / 1e6 - modelFS.to("cpu") - while torch.cuda.memory_allocated() / 1e6 >= mem: - time.sleep(1) + if req.mask is not None: + mask = load_mask(req.mask, opt_W, opt_H, init_latent.shape[2], init_latent.shape[3], True).to(device) + mask = mask[0][0].unsqueeze(0).repeat(4, 1, 1).unsqueeze(0) + mask = repeat(mask, '1 ... -> b ...', b=batch_size) + + if device != "cpu" and precision == "autocast": + mask = mask.half() + + move_fs_to_cpu() assert 0. <= opt_strength <= 1., 'can only work with strength in [0.0, 1.0]' t_enc = int(opt_strength * opt_ddim_steps) print(f"target t_enc is {t_enc} steps") if opt_save_to_disk_path is not None: - session_out_path = os.path.join(opt_save_to_disk_path, session_id) + session_out_path = os.path.join(opt_save_to_disk_path, req.session_id) os.makedirs(session_out_path, exist_ok=True) else: session_out_path = None @@ -326,29 +360,60 @@ def mk_img(req: Request): else: c = modelCS.get_learned_conditioning(prompts) + modelFS.to(device) + partial_x_samples = None def img_callback(x_samples, i): nonlocal partial_x_samples partial_x_samples = x_samples + if req.stream_progress_updates: + n_steps = opt_ddim_steps if req.init_image is None else t_enc + progress = {"step": i, "total_steps": n_steps} + + if req.stream_image_progress and i % 5 == 0: + partial_images = [] + + for i in range(batch_size): + x_samples_ddim = modelFS.decode_first_stage(x_samples[i].unsqueeze(0)) + x_sample = torch.clamp((x_samples_ddim + 1.0) / 2.0, min=0.0, max=1.0) + x_sample = 255.0 * rearrange(x_sample[0].cpu().numpy(), "c h w -> h w c") + x_sample = x_sample.astype(np.uint8) + img = Image.fromarray(x_sample) + buf = BytesIO() + img.save(buf, format='JPEG') + buf.seek(0) + + del img, x_sample, x_samples_ddim + # don't delete x_samples, it is used in the code that called this callback + + temp_images[str(req.session_id) + '/' + str(i)] = buf + partial_images.append({'path': f'/image/tmp/{req.session_id}/{i}'}) + + progress['output'] = partial_images + + yield json.dumps(progress) + if stop_processing: raise UserInitiatedStop("User requested that we stop processing") # run the handler try: if handler == _txt2img: - x_samples = _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, None, opt_C, opt_f, opt_ddim_eta, c, uc, opt_seed, img_callback) + x_samples = _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, None, opt_C, opt_f, opt_ddim_eta, c, uc, opt_seed, img_callback, mask, opt_sampler_name) else: - x_samples = _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, opt_ddim_eta, opt_seed, img_callback) + x_samples = _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, opt_ddim_eta, opt_seed, img_callback, mask) + + yield from x_samples + + x_samples = partial_x_samples except UserInitiatedStop: if partial_x_samples is None: continue x_samples = partial_x_samples - modelFS.to(device) - print("saving images") for i in range(batch_size): @@ -358,6 +423,14 @@ def mk_img(req: Request): x_sample = x_sample.astype(np.uint8) img = Image.fromarray(x_sample) + has_filters = (opt_use_face_correction is not None and opt_use_face_correction.startswith('GFPGAN')) or \ + (opt_use_upscale is not None and opt_use_upscale.startswith('RealESRGAN')) + + return_orig_img = not has_filters or not opt_show_only_filtered + + if stop_processing: + return_orig_img = True + if opt_save_to_disk_path is not None: prompt_flattened = filename_regex.sub('_', prompts[0]) prompt_flattened = prompt_flattened[:50] @@ -368,12 +441,12 @@ def mk_img(req: Request): img_out_path = os.path.join(session_out_path, f"{file_path}.{opt_format}") meta_out_path = os.path.join(session_out_path, f"{file_path}.txt") - if not opt_show_only_filtered: + if return_orig_img: save_image(img, img_out_path) - save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps, opt_scale, opt_strength, opt_use_face_correction, opt_use_upscale) + save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps, opt_scale, opt_strength, opt_use_face_correction, opt_use_upscale, opt_sampler_name) - if not opt_show_only_filtered: + if return_orig_img: img_data = img_to_base64_str(img) res_image_orig = ResponseImage(data=img_data, seed=opt_seed) res.images.append(res_image_orig) @@ -381,8 +454,10 @@ def mk_img(req: Request): if opt_save_to_disk_path is not None: res_image_orig.path_abs = img_out_path - if (opt_use_face_correction is not None and opt_use_face_correction.startswith('GFPGAN')) or \ - (opt_use_upscale is not None and opt_use_upscale.startswith('RealESRGAN')): + del img + + if has_filters and not stop_processing: + print('Applying filters..') gc() filters_applied = [] @@ -410,18 +485,19 @@ def mk_img(req: Request): save_image(filtered_image, filtered_img_out_path) res_image_filtered.path_abs = filtered_img_out_path + del filtered_image + seeds += str(opt_seed) + "," opt_seed += 1 - if device != "cpu": - mem = torch.cuda.memory_allocated() / 1e6 - modelFS.to("cpu") - while torch.cuda.memory_allocated() / 1e6 >= mem: - time.sleep(1) - del x_samples + move_fs_to_cpu() + gc() + del x_samples, x_samples_ddim, x_sample print("memory_final = ", torch.cuda.memory_allocated() / 1e6) - return res + print('Task completed') + + yield json.dumps(res.json()) def save_image(img, img_out_path): try: @@ -429,8 +505,8 @@ def save_image(img, img_out_path): except: print('could not save the file', traceback.format_exc()) -def save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps, opt_scale, opt_prompt_strength, opt_correct_face, opt_upscale): - metadata = f"{prompts[0]}\nWidth: {opt_W}\nHeight: {opt_H}\nSeed: {opt_seed}\nSteps: {opt_ddim_steps}\nGuidance Scale: {opt_scale}\nPrompt Strength: {opt_prompt_strength}\nUse Face Correction: {opt_correct_face}\nUse Upscaling: {opt_upscale}" +def save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps, opt_scale, opt_prompt_strength, opt_correct_face, opt_upscale, sampler_name): + metadata = f"{prompts[0]}\nWidth: {opt_W}\nHeight: {opt_H}\nSeed: {opt_seed}\nSteps: {opt_ddim_steps}\nGuidance Scale: {opt_scale}\nPrompt Strength: {opt_prompt_strength}\nUse Face Correction: {opt_correct_face}\nUse Upscaling: {opt_upscale}\nSampler: {sampler_name}" try: with open(meta_out_path, 'w') as f: @@ -438,7 +514,7 @@ def save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps except: print('could not save the file', traceback.format_exc()) -def _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, start_code, opt_C, opt_f, opt_ddim_eta, c, uc, opt_seed, img_callback): +def _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, start_code, opt_C, opt_f, opt_ddim_eta, c, uc, opt_seed, img_callback, mask, sampler_name): shape = [opt_n_samples, opt_C, opt_H // opt_f, opt_W // opt_f] if device != "cpu": @@ -447,6 +523,9 @@ def _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, start_code, while torch.cuda.memory_allocated() / 1e6 >= mem: time.sleep(1) + if sampler_name == 'ddim': + model.make_schedule(ddim_num_steps=opt_ddim_steps, ddim_eta=opt_ddim_eta, verbose=False) + samples_ddim = model.sample( S=opt_ddim_steps, conditioning=c, @@ -458,12 +537,13 @@ def _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, start_code, eta=opt_ddim_eta, x_T=start_code, img_callback=img_callback, - sampler = 'plms', + mask=mask, + sampler = sampler_name, ) - return samples_ddim + yield from samples_ddim -def _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, opt_ddim_eta, opt_seed, img_callback): +def _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, opt_ddim_eta, opt_seed, img_callback, mask): # encode (scaled latent) z_enc = model.stochastic_encode( init_latent, @@ -472,6 +552,8 @@ def _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, o opt_ddim_eta, opt_ddim_steps, ) + x_T = None if mask is None else init_latent + # decode it samples_ddim = model.sample( t_enc, @@ -480,10 +562,19 @@ def _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, o unconditional_guidance_scale=opt_scale, unconditional_conditioning=uc, img_callback=img_callback, + mask=mask, + x_T=x_T, sampler = 'ddim' ) - return samples_ddim + yield from samples_ddim + +def move_fs_to_cpu(): + if device != "cpu": + mem = torch.cuda.memory_allocated() / 1e6 + modelFS.to("cpu") + while torch.cuda.memory_allocated() / 1e6 >= mem: + time.sleep(1) def gc(): if device == 'cpu': @@ -525,6 +616,31 @@ def load_img(img_str, w0, h0): image = torch.from_numpy(image) return 2.*image - 1. +def load_mask(mask_str, h0, w0, newH, newW, invert=False): + image = base64_str_to_img(mask_str).convert("RGB") + w, h = image.size + print(f"loaded input mask of size ({w}, {h})") + + if invert: + print("inverted") + image = ImageOps.invert(image) + # where_0, where_1 = np.where(image == 0), np.where(image == 255) + # image[where_0], image[where_1] = 255, 0 + + if h0 is not None and w0 is not None: + h, w = h0, w0 + + w, h = map(lambda x: x - x % 64, (w, h)) # resize to integer multiple of 64 + + print(f"New mask size ({w}, {h})") + image = image.resize((newW, newH), resample=Image.Resampling.LANCZOS) + image = np.array(image) + + image = image.astype(np.float32) / 255.0 + image = image[None].transpose(0, 3, 1, 2) + image = torch.from_numpy(image) + return image + # https://stackoverflow.com/a/61114178 def img_to_base64_str(img): buffered = BytesIO() diff --git a/ui/server.py b/ui/server.py index f55c1091..bdb252d8 100644 --- a/ui/server.py +++ b/ui/server.py @@ -15,7 +15,8 @@ CONFIG_DIR = os.path.join(SD_UI_DIR, '..', 'scripts') OUTPUT_DIRNAME = "Stable Diffusion UI" # in the user's home folder from fastapi import FastAPI, HTTPException -from starlette.responses import FileResponse +from fastapi.staticfiles import StaticFiles +from starlette.responses import FileResponse, StreamingResponse from pydantic import BaseModel import logging @@ -29,8 +30,14 @@ model_is_loading = False modifiers_cache = None outpath = os.path.join(os.path.expanduser("~"), OUTPUT_DIRNAME) +# don't show access log entries for URLs that start with the given prefix +ACCESS_LOG_SUPPRESS_PATH_PREFIXES = ['/ping', '/modifier-thumbnails'] + +app.mount('/media', StaticFiles(directory=os.path.join(SD_UI_DIR, 'media/')), name="media") + # defaults from https://huggingface.co/blog/stable_diffusion class ImageRequest(BaseModel): + session_id: str = "session" prompt: str = "" init_image: str = None # base64 mask: str = None # base64 @@ -41,6 +48,7 @@ class ImageRequest(BaseModel): height: int = 512 seed: int = 42 prompt_strength: float = 0.8 + sampler: str = None # "ddim", "plms", "heun", "euler", "euler_a", "dpm2", "dpm2_a", "lms" # allow_nsfw: bool = False save_to_disk_path: str = None turbo: bool = True @@ -50,6 +58,9 @@ class ImageRequest(BaseModel): use_upscale: str = None # or "RealESRGAN_x4plus" or "RealESRGAN_x4plus_anime_6B" show_only_filtered_image: bool = False + stream_progress_updates: bool = False + stream_image_progress: bool = False + class SetAppConfigRequest(BaseModel): update_branch: str = "main" @@ -87,6 +98,7 @@ def image(req : ImageRequest): from sd_internal import runtime r = Request() + r.session_id = req.session_id r.prompt = req.prompt r.init_image = req.init_image r.mask = req.mask @@ -97,6 +109,7 @@ def image(req : ImageRequest): r.height = req.height r.seed = req.seed r.prompt_strength = req.prompt_strength + r.sampler = req.sampler # r.allow_nsfw = req.allow_nsfw r.turbo = req.turbo r.use_cpu = req.use_cpu @@ -106,10 +119,24 @@ def image(req : ImageRequest): r.use_face_correction = req.use_face_correction r.show_only_filtered_image = req.show_only_filtered_image - try: - res: Response = runtime.mk_img(r) + r.stream_progress_updates = True # the underlying implementation only supports streaming + r.stream_image_progress = req.stream_image_progress - return res.json() + try: + if not req.stream_progress_updates: + r.stream_image_progress = False + + res = runtime.mk_img(r) + + if req.stream_progress_updates: + return StreamingResponse(res, media_type='application/json') + else: # compatibility mode: buffer the streaming responses, and return the last one + last_result = None + + for result in res: + last_result = result + + return json.loads(last_result) except Exception as e: print(traceback.format_exc()) return HTTPException(status_code=500, detail=str(e)) @@ -128,6 +155,13 @@ def stop(): print(traceback.format_exc()) return HTTPException(status_code=500, detail=str(e)) +@app.get('/image/tmp/{session_id}/{img_id}') +def get_image(session_id, img_id): + from sd_internal import runtime + buf = runtime.temp_images[session_id + '/' + img_id] + buf.seek(0) + return StreamingResponse(buf, media_type='image/jpeg') + @app.post('/app_config') async def setAppConfig(req : SetAppConfigRequest): try: @@ -173,28 +207,26 @@ def getAppConfig(): print(traceback.format_exc()) return HTTPException(status_code=500, detail=str(e)) -@app.get('/media/ding.mp3') -def read_ding(): - return FileResponse(os.path.join(SD_UI_DIR, 'media/ding.mp3')) - -@app.get('/media/kofi.png') -def read_modifiers(): - return FileResponse(os.path.join(SD_UI_DIR, 'media/kofi.png')) - @app.get('/modifiers.json') def read_modifiers(): - return FileResponse(os.path.join(SD_UI_DIR, 'modifiers.json')) + headers = {"Cache-Control": "no-cache, no-store, must-revalidate", "Pragma": "no-cache", "Expires": "0"} + return FileResponse(os.path.join(SD_UI_DIR, 'modifiers.json'), headers=headers) @app.get('/output_dir') def read_home_dir(): return {outpath} -# don't log /ping requests -class HealthCheckLogFilter(logging.Filter): +# don't log certain requests +class LogSuppressFilter(logging.Filter): def filter(self, record: logging.LogRecord) -> bool: - return record.getMessage().find('/ping') == -1 + path = record.getMessage() + for prefix in ACCESS_LOG_SUPPRESS_PATH_PREFIXES: + if path.find(prefix) != -1: + return False -logging.getLogger('uvicorn.access').addFilter(HealthCheckLogFilter()) + return True + +logging.getLogger('uvicorn.access').addFilter(LogSuppressFilter()) # start the browser ui -import webbrowser; webbrowser.open('http://localhost:9000') +import webbrowser; webbrowser.open('http://localhost:9000') \ No newline at end of file