Lora Loader fixes: mute video audio, add option for autoplay previews, fix wrapping in notes, etc.

This commit is contained in:
rgthree
2026-08-18 12:01:56 -04:00
parent 6b76ee6f2c
commit 8f14800b3c
10 changed files with 235 additions and 14 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "rgthree-comfy"
description = "Making ComfyUI more comfortable."
version = "1.0.2607232129"
version = "1.0.2608181201"
license = { file = "LICENSE" }
dependencies = []
+2 -1
View File
@@ -57,7 +57,8 @@
}
},
"power_lora_loader": {
"show_info_badge": true
"show_info_badge": true,
"info_autoplay_video": true
}
},
"announcements": {
+6
View File
@@ -152,6 +152,12 @@ const CONFIGURABLE: { [key: string]: ConfigurationSchema[] } = {
label: "Show info badge/button",
description: "Show an info badge/button on each lora row to signal and open lora details.",
},
{
key: "nodes.power_lora_loader.info_autoplay_video",
type: ConfigType.BOOLEAN,
label: "Autoplay video previews in info dialog.",
description: "In the info dialog, autoplay video preview images.",
},
],
advanced: [
{
+52 -4
View File
@@ -14,9 +14,14 @@ import {
pencilColored,
diskColored,
dotdotdot,
play,
pause,
volumeHigh,
volumeMute,
} from "rgthree/common/media/svgs.js";
import {RgthreeModelInfo} from "typings/rgthree.js";
import {CHECKPOINT_INFO_SERVICE, LORA_INFO_SERVICE} from "rgthree/common/model_info_service.js";
import {SERVICE as CONFIG_SERVICE} from "./services/config_service.js";
import {rgthree} from "./rgthree.js";
import {MenuButton} from "rgthree/common/menu.js";
import {generateId, injectCss} from "rgthree/common/shared_utils.js";
@@ -257,10 +262,17 @@ abstract class RgthreeInfoDialog extends RgthreeDialog {
(img) => `
<li>
<figure>${
img.type === 'video'
? `<video src="${img.url}" autoplay loop></video>`
img.type === "video"
? `<video src="${img.url}"
${(CONFIG_SERVICE.getConfigValue("nodes.power_lora_loader.info_autoplay_video") && "autoplay") || ""}
loop
></video>`
: `<img src="${img.url}" />`
}
}
<menu>
<button class="rgthree-button-reset rgthree-info-btn-play-pause" data-action="video-play-pause">${play}${pause}</button>
<button class="rgthree-button-reset rgthree-info-btn-mute" data-action="video-toggle-mute">${volumeHigh}${volumeMute}</button>
</menu>
<figcaption><!--
-->${imgInfoField(
"",
@@ -302,6 +314,42 @@ abstract class RgthreeInfoDialog extends RgthreeDialog {
const div = $el("div", {html});
// Add functionality to the videos to play/pause and toggle mute.
for (const fig of queryAll("figure", div)) {
const video = query("video", fig);
if (!video) continue;
video.addEventListener("play", () => {
video.classList.add("-rgthree-is-playing");
});
video.addEventListener("pause", () => {
video.classList.remove("-rgthree-is-playing");
});
query('[data-action="video-play-pause"]', fig)!.addEventListener("click", () => {
const isPlaying = !!(
video.currentTime > 0 &&
!video.paused &&
!video.ended &&
video.readyState > 2
);
if (isPlaying) {
video.pause();
} else {
video.play();
}
});
video.volume = 0;
video.classList.add("-rgthree-is-muted");
query('[data-action="video-toggle-mute"]', fig)!.addEventListener("click", () => {
if (!video.volume) {
video.volume = 0.66;
video.classList.remove("-rgthree-is-muted");
} else {
video.volume = 0;
video.classList.add("-rgthree-is-muted");
}
});
}
if (rgthree.isDevMode()) {
setAttributes(query('[stub="menu"]', div)!, {
children: [
@@ -314,7 +362,7 @@ abstract class RgthreeInfoDialog extends RgthreeDialog {
callback: async (e: PointerEvent) => {
if (this.modelInfo?.file) {
window.open(
`rgthree/api/loras/info?file=${encodeURIComponent(this.modelInfo.file)}`,
`rgthree/api/loras/info?files=${encodeURIComponent(this.modelInfo.file)}`,
);
}
},
+41 -2
View File
@@ -183,7 +183,7 @@
}
tr[data-field-name="userNote"] td > span:first-child {
white-space: pre;
white-space: pre-wrap;
}
tr.rgthree-info-table-break-row td {
@@ -317,6 +317,43 @@
max-height: 45vh;
}
menu {display: none;}
video:not(#fakeid) {
~ menu {
display: block;
button {
position: absolute;
top: 8px;
width: 24px;
height: 24px;
}
svg {
position: absolute;
inset: 0;
filter: drop-shadow(1px 1px 3px black);
}
svg + svg {
display: none;
}
.rgthree-info-btn-play-pause {
left: 8px;
}
.rgthree-info-btn-mute {
right: 8px;
}
}
&.-rgthree-is-playing ~ menu {
.rgthree-info-btn-play-pause svg {display: none;}
.rgthree-info-btn-play-pause svg + svg {display: block;}
}
&.-rgthree-is-muted ~ menu {
.rgthree-info-btn-mute svg {display: none;}
.rgthree-info-btn-mute svg + svg {display: block;}
}
}
figcaption {
position: absolute;
left: 0;
@@ -326,8 +363,10 @@
font-size: 12px;
background: rgba(0,0,0,0.85);
opacity: 0;
max-height: 90%;
overflow: auto;
transform: translateY(50px);
transition: all 0.25s ease-in-out;
transition: transform 0.25s ease-in-out, opacity 0.25s ease-in-out;
> span {
display: inline-block;
+23
View File
@@ -33,6 +33,29 @@ export async function logoRgthreeAsync(): Promise<string> {
// Kick it off to cache upfront.
logoRgthreeAsync();
/* https://www.svgrepo.com/svg/514197/play */
export const play = `<svg fill="currentColor" viewBox="0 0 32 32">
<path d="M5.92 24.096q0 1.088 0.928 1.728 0.512 0.288 1.088 0.288 0.448 0 0.896-0.224l16.16-8.064q0.48-0.256 0.8-0.736t0.288-1.088-0.288-1.056-0.8-0.736l-16.16-8.064q-0.448-0.224-0.896-0.224-0.544 0-1.088 0.288-0.928 0.608-0.928 1.728v16.16z"></path>
</svg>`;
/* https://www.svgrepo.com/svg/514191/pause */
export const pause = `<svg fill="currentColor" viewBox="0 0 32 32">
<path d="M5.92 24.096q0 0.832 0.576 1.408t1.44 0.608h4.032q0.832 0 1.44-0.608t0.576-1.408v-16.16q0-0.832-0.576-1.44t-1.44-0.576h-4.032q-0.832 0-1.44 0.576t-0.576 1.44v16.16zM18.016 24.096q0 0.832 0.608 1.408t1.408 0.608h4.032q0.832 0 1.44-0.608t0.576-1.408v-16.16q0-0.832-0.576-1.44t-1.44-0.576h-4.032q-0.832 0-1.408 0.576t-0.608 1.44v16.16z"></path>
</svg>`;
/* https://www.svgrepo.com/svg/442732/volume-mute */
export const volumeMute = `<svg viewBox="0 0 24 24" fill="currentColor">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.2929 9.29289C16.6834 8.90237 17.3166 8.90237 17.7071 9.29289L19 10.5858L20.2929 9.29289C20.6834 8.90237 21.3166 8.90237 21.7071 9.29289C22.0976 9.68342 22.0976 10.3166 21.7071 10.7071L20.4142 12L21.7071 13.2929C22.0976 13.6834 22.0976 14.3166 21.7071 14.7071C21.3166 15.0976 20.6834 15.0976 20.2929 14.7071L19 13.4142L17.7071 14.7071C17.3166 15.0976 16.6834 15.0976 16.2929 14.7071C15.9024 14.3166 15.9024 13.6834 16.2929 13.2929L17.5858 12L16.2929 10.7071C15.9024 10.3166 15.9024 9.68342 16.2929 9.29289Z"></path>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.8397 4C9.38012 4 7.99337 4.63781 7.04346 5.74604C6.70415 6.1419 6.30972 6.44883 5.78377 6.55109L5.23652 6.6575C3.35695 7.02297 2 8.6692 2 10.584V13.416C2 15.3308 3.35696 16.977 5.23652 17.3425L5.78377 17.4489C6.30972 17.5512 6.70415 17.8581 7.04346 18.254C7.99337 19.3622 9.38012 20 10.8397 20H11C12.6569 20 14 18.6569 14 17V7C14 5.34315 12.6569 4 11 4H10.8397Z"></path>
</svg>`;
/* https://www.svgrepo.com/svg/442730/volume-high */
export const volumeHigh = `<svg viewBox="0 0 24 24" fill="currentColor">
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.2942 6.63396C19.7725 6.35782 20.3841 6.52169 20.6603 6.99998C21.5379 8.52018 22 10.2446 22 12C22 13.7553 21.5379 15.4798 20.6603 17C20.3841 17.4783 19.7725 17.6421 19.2942 17.366C18.8159 17.0899 18.6521 16.4783 18.9282 16C19.6304 14.7838 20 13.4043 20 12C20 10.5957 19.6304 9.21614 18.9282 7.99998C18.6521 7.52169 18.8159 6.9101 19.2942 6.63396Z"></path>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.399 8.30553C16.8773 8.02939 17.4889 8.19326 17.765 8.67155C18.3493 9.68353 18.6568 10.8315 18.6568 12C18.6568 13.1685 18.3493 14.3164 17.765 15.3284C17.4889 15.8067 16.8773 15.9706 16.399 15.6944C15.9207 15.4183 15.7568 14.8067 16.0329 14.3284C16.4417 13.6205 16.6568 12.8174 16.6568 12C16.6568 11.1825 16.4417 10.3795 16.0329 9.67155C15.7568 9.19326 15.9207 8.58167 16.399 8.30553Z"></path>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.8397 4C9.38012 4 7.99337 4.63781 7.04346 5.74604C6.70415 6.1419 6.30972 6.44883 5.78377 6.55109L5.23652 6.6575C3.35695 7.02297 2 8.6692 2 10.584V13.416C2 15.3308 3.35696 16.977 5.23652 17.3425L5.78377 17.4489C6.30972 17.5512 6.70415 17.8581 7.04346 18.254C7.99337 19.3622 9.38012 20 10.8397 20H11C12.6569 20 14 18.6569 14 17V7C14 5.34315 12.6569 4 11 4H10.8397Z"></path>
</svg>`;
export const github = `<svg viewBox="0 0 16 16" fill="currentColor" class="github-logo">
<path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path>
</svg>`;
+6
View File
@@ -128,6 +128,12 @@ const CONFIGURABLE = {
label: "Show info badge/button",
description: "Show an info badge/button on each lora row to signal and open lora details.",
},
{
key: "nodes.power_lora_loader.info_autoplay_video",
type: ConfigType.BOOLEAN,
label: "Autoplay video previews in info dialog.",
description: "In the info dialog, autoplay video preview images.",
},
],
advanced: [
{
+47 -4
View File
@@ -1,7 +1,8 @@
import { RgthreeDialog } from "../../rgthree/common/dialog.js";
import { createElement as $el, empty, appendChildren, getClosestOrSelf, query, queryAll, setAttributes, } from "../../rgthree/common/utils_dom.js";
import { logoCivitai, link, pencilColored, diskColored, dotdotdot, } from "../../rgthree/common/media/svgs.js";
import { logoCivitai, link, pencilColored, diskColored, dotdotdot, play, pause, volumeHigh, volumeMute, } from "../../rgthree/common/media/svgs.js";
import { CHECKPOINT_INFO_SERVICE, LORA_INFO_SERVICE } from "../../rgthree/common/model_info_service.js";
import { SERVICE as CONFIG_SERVICE } from "./services/config_service.js";
import { rgthree } from "./rgthree.js";
import { MenuButton } from "../../rgthree/common/menu.js";
import { generateId, injectCss } from "../../rgthree/common/shared_utils.js";
@@ -166,9 +167,16 @@ class RgthreeInfoDialog extends RgthreeDialog {
<ul class="rgthree-info-images">${(_y = (_x = info.images) === null || _x === void 0 ? void 0 : _x.map((img) => `
<li>
<figure>${img.type === 'video'
? `<video src="${img.url}" autoplay loop></video>`
<figure>${img.type === "video"
? `<video src="${img.url}"
${(CONFIG_SERVICE.getConfigValue("nodes.power_lora_loader.info_autoplay_video") && "autoplay") || ""}
loop
></video>`
: `<img src="${img.url}" />`}
<menu>
<button class="rgthree-button-reset rgthree-info-btn-play-pause" data-action="video-play-pause">${play}${pause}</button>
<button class="rgthree-button-reset rgthree-info-btn-mute" data-action="video-toggle-mute">${volumeHigh}${volumeMute}</button>
</menu>
<figcaption><!--
-->${imgInfoField("", img.civitaiUrl
? `<a href="${img.civitaiUrl}" target="_blank">civitai${link}</a>`
@@ -185,6 +193,41 @@ class RgthreeInfoDialog extends RgthreeDialog {
</li>`).join("")) !== null && _y !== void 0 ? _y : ""}</ul>
`;
const div = $el("div", { html });
for (const fig of queryAll("figure", div)) {
const video = query("video", fig);
if (!video)
continue;
video.addEventListener("play", () => {
video.classList.add("-rgthree-is-playing");
});
video.addEventListener("pause", () => {
video.classList.remove("-rgthree-is-playing");
});
query('[data-action="video-play-pause"]', fig).addEventListener("click", () => {
const isPlaying = !!(video.currentTime > 0 &&
!video.paused &&
!video.ended &&
video.readyState > 2);
if (isPlaying) {
video.pause();
}
else {
video.play();
}
});
video.volume = 0;
video.classList.add("-rgthree-is-muted");
query('[data-action="video-toggle-mute"]', fig).addEventListener("click", () => {
if (!video.volume) {
video.volume = 0.66;
video.classList.remove("-rgthree-is-muted");
}
else {
video.volume = 0;
video.classList.add("-rgthree-is-muted");
}
});
}
if (rgthree.isDevMode()) {
setAttributes(query('[stub="menu"]', div), {
children: [
@@ -197,7 +240,7 @@ class RgthreeInfoDialog extends RgthreeDialog {
callback: async (e) => {
var _a;
if ((_a = this.modelInfo) === null || _a === void 0 ? void 0 : _a.file) {
window.open(`rgthree/api/loras/info?file=${encodeURIComponent(this.modelInfo.file)}`);
window.open(`rgthree/api/loras/info?files=${encodeURIComponent(this.modelInfo.file)}`);
}
},
},
+42 -2
View File
@@ -149,7 +149,7 @@
margin: 2px;
}
.rgthree-info-dialog .rgthree-info-table tr[data-field-name=userNote] td > span:first-child {
white-space: pre;
white-space: pre-wrap;
}
.rgthree-info-dialog .rgthree-info-table tr.rgthree-info-table-break-row td {
border: 0;
@@ -268,6 +268,44 @@
.rgthree-info-dialog .rgthree-info-images > li figure video, .rgthree-info-dialog .rgthree-info-images > li figure img {
max-height: 45vh;
}
.rgthree-info-dialog .rgthree-info-images > li figure menu {
display: none;
}
.rgthree-info-dialog .rgthree-info-images > li figure video:not(#fakeid) ~ menu {
display: block;
}
.rgthree-info-dialog .rgthree-info-images > li figure video:not(#fakeid) ~ menu button {
position: absolute;
top: 8px;
width: 24px;
height: 24px;
}
.rgthree-info-dialog .rgthree-info-images > li figure video:not(#fakeid) ~ menu svg {
position: absolute;
inset: 0;
filter: drop-shadow(1px 1px 3px black);
}
.rgthree-info-dialog .rgthree-info-images > li figure video:not(#fakeid) ~ menu svg + svg {
display: none;
}
.rgthree-info-dialog .rgthree-info-images > li figure video:not(#fakeid) ~ menu .rgthree-info-btn-play-pause {
left: 8px;
}
.rgthree-info-dialog .rgthree-info-images > li figure video:not(#fakeid) ~ menu .rgthree-info-btn-mute {
right: 8px;
}
.rgthree-info-dialog .rgthree-info-images > li figure video:not(#fakeid).-rgthree-is-playing ~ menu .rgthree-info-btn-play-pause svg {
display: none;
}
.rgthree-info-dialog .rgthree-info-images > li figure video:not(#fakeid).-rgthree-is-playing ~ menu .rgthree-info-btn-play-pause svg + svg {
display: block;
}
.rgthree-info-dialog .rgthree-info-images > li figure video:not(#fakeid).-rgthree-is-muted ~ menu .rgthree-info-btn-mute svg {
display: none;
}
.rgthree-info-dialog .rgthree-info-images > li figure video:not(#fakeid).-rgthree-is-muted ~ menu .rgthree-info-btn-mute svg + svg {
display: block;
}
.rgthree-info-dialog .rgthree-info-images > li figure figcaption {
position: absolute;
left: 0;
@@ -277,8 +315,10 @@
font-size: 12px;
background: rgba(0, 0, 0, 0.85);
opacity: 0;
max-height: 90%;
overflow: auto;
transform: translateY(50px);
transition: all 0.25s ease-in-out;
transition: transform 0.25s ease-in-out, opacity 0.25s ease-in-out;
}
.rgthree-info-dialog .rgthree-info-images > li figure figcaption > span {
display: inline-block;
+15
View File
@@ -28,6 +28,21 @@ export async function logoRgthreeAsync() {
});
}
logoRgthreeAsync();
export const play = `<svg fill="currentColor" viewBox="0 0 32 32">
<path d="M5.92 24.096q0 1.088 0.928 1.728 0.512 0.288 1.088 0.288 0.448 0 0.896-0.224l16.16-8.064q0.48-0.256 0.8-0.736t0.288-1.088-0.288-1.056-0.8-0.736l-16.16-8.064q-0.448-0.224-0.896-0.224-0.544 0-1.088 0.288-0.928 0.608-0.928 1.728v16.16z"></path>
</svg>`;
export const pause = `<svg fill="currentColor" viewBox="0 0 32 32">
<path d="M5.92 24.096q0 0.832 0.576 1.408t1.44 0.608h4.032q0.832 0 1.44-0.608t0.576-1.408v-16.16q0-0.832-0.576-1.44t-1.44-0.576h-4.032q-0.832 0-1.44 0.576t-0.576 1.44v16.16zM18.016 24.096q0 0.832 0.608 1.408t1.408 0.608h4.032q0.832 0 1.44-0.608t0.576-1.408v-16.16q0-0.832-0.576-1.44t-1.44-0.576h-4.032q-0.832 0-1.408 0.576t-0.608 1.44v16.16z"></path>
</svg>`;
export const volumeMute = `<svg viewBox="0 0 24 24" fill="currentColor">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.2929 9.29289C16.6834 8.90237 17.3166 8.90237 17.7071 9.29289L19 10.5858L20.2929 9.29289C20.6834 8.90237 21.3166 8.90237 21.7071 9.29289C22.0976 9.68342 22.0976 10.3166 21.7071 10.7071L20.4142 12L21.7071 13.2929C22.0976 13.6834 22.0976 14.3166 21.7071 14.7071C21.3166 15.0976 20.6834 15.0976 20.2929 14.7071L19 13.4142L17.7071 14.7071C17.3166 15.0976 16.6834 15.0976 16.2929 14.7071C15.9024 14.3166 15.9024 13.6834 16.2929 13.2929L17.5858 12L16.2929 10.7071C15.9024 10.3166 15.9024 9.68342 16.2929 9.29289Z"></path>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.8397 4C9.38012 4 7.99337 4.63781 7.04346 5.74604C6.70415 6.1419 6.30972 6.44883 5.78377 6.55109L5.23652 6.6575C3.35695 7.02297 2 8.6692 2 10.584V13.416C2 15.3308 3.35696 16.977 5.23652 17.3425L5.78377 17.4489C6.30972 17.5512 6.70415 17.8581 7.04346 18.254C7.99337 19.3622 9.38012 20 10.8397 20H11C12.6569 20 14 18.6569 14 17V7C14 5.34315 12.6569 4 11 4H10.8397Z"></path>
</svg>`;
export const volumeHigh = `<svg viewBox="0 0 24 24" fill="currentColor">
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.2942 6.63396C19.7725 6.35782 20.3841 6.52169 20.6603 6.99998C21.5379 8.52018 22 10.2446 22 12C22 13.7553 21.5379 15.4798 20.6603 17C20.3841 17.4783 19.7725 17.6421 19.2942 17.366C18.8159 17.0899 18.6521 16.4783 18.9282 16C19.6304 14.7838 20 13.4043 20 12C20 10.5957 19.6304 9.21614 18.9282 7.99998C18.6521 7.52169 18.8159 6.9101 19.2942 6.63396Z"></path>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.399 8.30553C16.8773 8.02939 17.4889 8.19326 17.765 8.67155C18.3493 9.68353 18.6568 10.8315 18.6568 12C18.6568 13.1685 18.3493 14.3164 17.765 15.3284C17.4889 15.8067 16.8773 15.9706 16.399 15.6944C15.9207 15.4183 15.7568 14.8067 16.0329 14.3284C16.4417 13.6205 16.6568 12.8174 16.6568 12C16.6568 11.1825 16.4417 10.3795 16.0329 9.67155C15.7568 9.19326 15.9207 8.58167 16.399 8.30553Z"></path>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.8397 4C9.38012 4 7.99337 4.63781 7.04346 5.74604C6.70415 6.1419 6.30972 6.44883 5.78377 6.55109L5.23652 6.6575C3.35695 7.02297 2 8.6692 2 10.584V13.416C2 15.3308 3.35696 16.977 5.23652 17.3425L5.78377 17.4489C6.30972 17.5512 6.70415 17.8581 7.04346 18.254C7.99337 19.3622 9.38012 20 10.8397 20H11C12.6569 20 14 18.6569 14 17V7C14 5.34315 12.6569 4 11 4H10.8397Z"></path>
</svg>`;
export const github = `<svg viewBox="0 0 16 16" fill="currentColor" class="github-logo">
<path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path>
</svg>`;