- {{ with .Site.Params.Author.image }}
- {{ $authorImage := "" }}
- {{ if or (strings.HasPrefix . "http:") (strings.HasPrefix . "https:") }}
- {{ $authorImage = resources.GetRemote . }}
- {{ else }}
- {{ $authorImage = resources.Get . }}
- {{ end }}
- {{ if $authorImage }}
- {{ if not $disableImageOptimization }}
- {{ $authorImage = $authorImage.Fill "192x192" }}
- {{ end }}
-
- {{ else }}
- {{ $authorImage := resources.GetRemote . }}
- {{ if not $disableImageOptimization }}
- {{ $authorImage = $authorImage.Fill "192x192" }}
- {{ end }}
-
- {{ end }}
+{{ with .Site.Params.Author.image }}
+ {{ $authorImage := "" }}
+ {{ if or (strings.HasPrefix . "http:") (strings.HasPrefix . "https:") }}
+ {{ $authorImage = resources.GetRemote . }}
+ {{ else }}
+ {{ $authorImage = resources.Get . }}
{{ end }}
-
- {{ with .Site.Params.Author.name | markdownify }}
-
- {{ i18n "author.byline_title" | markdownify }}
-
-
- {{ . }}
-
+ {{ if $authorImage }}
+ {{ if not $disableImageOptimization }}
+ {{ $authorImage = $authorImage.Fill "192x192" }}
{{ end }}
- {{ with .Site.Params.Author.bio | markdownify }}
-
{{ . }}
+
+ {{ else }}
+ {{ $authorImage := resources.GetRemote . }}
+ {{ if not $disableImageOptimization }}
+ {{ $authorImage = $authorImage.Fill "192x192" }}
{{ end }}
-
{{ partialCached "author-links.html" . }}
+
+ {{ end }}
+{{ end }}
+
+ {{ with .Site.Params.Author.name | markdownify }}
+
+ {{ i18n "author.byline_title" | markdownify }}
+
+ {{ . }}
+
+ {{ end }}
+ {{ with .Site.Params.Author.bio | markdownify }}
+
{{ . }}
+ {{ end }}
+
{{ partialCached "author-links.html" . }}
diff --git a/layouts/shortcodes/panzoom-figure.html b/layouts/shortcodes/panzoom-figure.html
index 6a4facc..b7682c7 100644
--- a/layouts/shortcodes/panzoom-figure.html
+++ b/layouts/shortcodes/panzoom-figure.html
@@ -10,6 +10,10 @@
{{- $target := .Get "target" | default "_blank" }}
{{- $gallery_class := .Get "gallery_class" }}
+ {{- if not $gallery_class }}
+
+ {{- end }}
+
- {{ with $caption }}
{{ . | markdownify }} {{ end }}
+ {{ with $caption }}
{{ . | markdownify }} {{ end }}
+ {{- if not $gallery_class }}
+
+ {{- end }}
{{- end -}}
diff --git a/layouts/shortcodes/panzoom-gallery.html b/layouts/shortcodes/panzoom-gallery.html
index 4c5ead5..f4018a5 100644
--- a/layouts/shortcodes/panzoom-gallery.html
+++ b/layouts/shortcodes/panzoom-gallery.html
@@ -2,8 +2,9 @@
{{- $caption := .Get "caption" }}
-
+
{{ .Inner }}
-{{ with $caption }}
{{ . | markdownify }} {{ end }}
\ No newline at end of file
+{{ with $caption }}
{{ . | markdownify }} {{ end }}
+
\ No newline at end of file
diff --git a/public/404.html b/public/404.html
new file mode 100644
index 0000000..6b94bb8
--- /dev/null
+++ b/public/404.html
@@ -0,0 +1,6 @@
+
404 Page not found · N.E.E.T. Works
+
Error 404
It seems that the page you've requested does not exist.
\ No newline at end of file
diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png
new file mode 100644
index 0000000..23a026c
Binary files /dev/null and b/public/android-chrome-192x192.png differ
diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png
new file mode 100644
index 0000000..51749bb
Binary files /dev/null and b/public/android-chrome-512x512.png differ
diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png
new file mode 100644
index 0000000..fbbf9b2
Binary files /dev/null and b/public/apple-touch-icon.png differ
diff --git a/public/authors/index.html b/public/authors/index.html
new file mode 100644
index 0000000..627e7bd
--- /dev/null
+++ b/public/authors/index.html
@@ -0,0 +1,6 @@
+
Authors · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/authors/index.xml b/public/authors/index.xml
new file mode 100644
index 0000000..4eee5eb
--- /dev/null
+++ b/public/authors/index.xml
@@ -0,0 +1 @@
+
Authors on N.E.E.T. Works https://blog.neet.works/authors/Recent content in Authors on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.*
\ No newline at end of file
diff --git a/public/categories/diy/index.html b/public/categories/diy/index.html
new file mode 100644
index 0000000..ad83911
--- /dev/null
+++ b/public/categories/diy/index.html
@@ -0,0 +1,15 @@
+
Diy · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/categories/diy/index.xml b/public/categories/diy/index.xml
new file mode 100644
index 0000000..72fc726
--- /dev/null
+++ b/public/categories/diy/index.xml
@@ -0,0 +1 @@
+
Diy on N.E.E.T. Works https://blog.neet.works/categories/diy/Recent content in Diy on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/categories/diy/page/1/index.html b/public/categories/diy/page/1/index.html
new file mode 100644
index 0000000..8ff66a5
--- /dev/null
+++ b/public/categories/diy/page/1/index.html
@@ -0,0 +1,2 @@
+
https://blog.neet.works/categories/diy/
+
\ No newline at end of file
diff --git a/public/categories/homelab/index.html b/public/categories/homelab/index.html
new file mode 100644
index 0000000..9ddc18d
--- /dev/null
+++ b/public/categories/homelab/index.html
@@ -0,0 +1,15 @@
+
Homelab · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/categories/homelab/index.xml b/public/categories/homelab/index.xml
new file mode 100644
index 0000000..5880b74
--- /dev/null
+++ b/public/categories/homelab/index.xml
@@ -0,0 +1 @@
+
Homelab on N.E.E.T. Works https://blog.neet.works/categories/homelab/Recent content in Homelab on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/categories/homelab/page/1/index.html b/public/categories/homelab/page/1/index.html
new file mode 100644
index 0000000..5056a0d
--- /dev/null
+++ b/public/categories/homelab/page/1/index.html
@@ -0,0 +1,2 @@
+
https://blog.neet.works/categories/homelab/
+
\ No newline at end of file
diff --git a/public/categories/index.html b/public/categories/index.html
new file mode 100644
index 0000000..0c75de8
--- /dev/null
+++ b/public/categories/index.html
@@ -0,0 +1,14 @@
+
Categories · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/categories/index.xml b/public/categories/index.xml
new file mode 100644
index 0000000..049f3cb
--- /dev/null
+++ b/public/categories/index.xml
@@ -0,0 +1 @@
+
Categories on N.E.E.T. Works https://blog.neet.works/categories/Recent content in Categories on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Diy https://blog.neet.works/categories/diy/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/categories/diy/ Homelab https://blog.neet.works/categories/homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/categories/homelab/ Servers https://blog.neet.works/categories/servers/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/categories/servers/ Watercooling https://blog.neet.works/categories/watercooling/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/categories/watercooling/
\ No newline at end of file
diff --git a/public/categories/servers/index.html b/public/categories/servers/index.html
new file mode 100644
index 0000000..f7292ac
--- /dev/null
+++ b/public/categories/servers/index.html
@@ -0,0 +1,15 @@
+
Servers · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/categories/servers/index.xml b/public/categories/servers/index.xml
new file mode 100644
index 0000000..e8b091b
--- /dev/null
+++ b/public/categories/servers/index.xml
@@ -0,0 +1 @@
+
Servers on N.E.E.T. Works https://blog.neet.works/categories/servers/Recent content in Servers on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/categories/servers/page/1/index.html b/public/categories/servers/page/1/index.html
new file mode 100644
index 0000000..8c60512
--- /dev/null
+++ b/public/categories/servers/page/1/index.html
@@ -0,0 +1,2 @@
+
https://blog.neet.works/categories/servers/
+
\ No newline at end of file
diff --git a/public/categories/watercooling/index.html b/public/categories/watercooling/index.html
new file mode 100644
index 0000000..5c8faf7
--- /dev/null
+++ b/public/categories/watercooling/index.html
@@ -0,0 +1,15 @@
+
Watercooling · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/categories/watercooling/index.xml b/public/categories/watercooling/index.xml
new file mode 100644
index 0000000..7d9ac23
--- /dev/null
+++ b/public/categories/watercooling/index.xml
@@ -0,0 +1 @@
+
Watercooling on N.E.E.T. Works https://blog.neet.works/categories/watercooling/Recent content in Watercooling on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/categories/watercooling/page/1/index.html b/public/categories/watercooling/page/1/index.html
new file mode 100644
index 0000000..7c0b4e3
--- /dev/null
+++ b/public/categories/watercooling/page/1/index.html
@@ -0,0 +1,2 @@
+
https://blog.neet.works/categories/watercooling/
+
\ No newline at end of file
diff --git a/public/css/main.bundle.min.40e00100ae5ec4637cecd46ba4ae5f8db39bb83da61b5efe4900676fc0f4c10ac17e7da11e467fb8f1f39dfa5a5070c05bba06b4c05c629c2d389f4263d4c633.css b/public/css/main.bundle.min.40e00100ae5ec4637cecd46ba4ae5f8db39bb83da61b5efe4900676fc0f4c10ac17e7da11e467fb8f1f39dfa5a5070c05bba06b4c05c629c2d389f4263d4c633.css
new file mode 100644
index 0000000..35ae104
--- /dev/null
+++ b/public/css/main.bundle.min.40e00100ae5ec4637cecd46ba4ae5f8db39bb83da61b5efe4900676fc0f4c10ac17e7da11e467fb8f1f39dfa5a5070c05bba06b4c05c629c2d389f4263d4c633.css
@@ -0,0 +1 @@
+:root{--color-neutral:255, 255, 255;--color-neutral-50:255,255,255;--color-neutral-100:255,255,255;--color-neutral-200:255,255,255;--color-neutral-300:223,203,232;--color-neutral-400:190,149,209;--color-neutral-500:157,96,186;--color-neutral-600:138,73,168;--color-neutral-700:114,61,140;--color-neutral-800:91,48,111;--color-neutral-900:68,36,83;--color-primary-50:255,255,255;--color-primary-100:242,238,249;--color-primary-200:199,181,229;--color-primary-300:157,125,209;--color-primary-400:114,68,189;--color-primary-500:80,47,134;--color-primary-600:62,36,104;--color-primary-700:44,26,74;--color-primary-800:26,15,43;--color-primary-900:8,5,13;--color-secondary-50:255,255,255;--color-secondary-100:255,255,255;--color-secondary-200:255,255,255;--color-secondary-300:255,255,255;--color-secondary-400:255,255,255;--color-secondary-500:255,215,233;--color-secondary-600:255,174,211;--color-secondary-700:255,133,188;--color-secondary-800:255,93,166;--color-secondary-900:255,52,143}/*!Blowfish | MIT License | https://github.com/nunocoracao/blowfish*/#zen-mode-button{cursor:pointer}.zen-mode{position:relative}body.zen-mode-enable{ #bmc-wbtn, .author { display:none !important; }}*,::before,::after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*!tailwindcss v3.4.14 | MIT License | https://tailwindcss.com*/*,::before,::after{box-sizing:border-box;border-width:0;border-style:solid;border-color:initial}::before,::after{--tw-content:''}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,apple color emoji,segoe ui emoji,segoe ui symbol,noto color emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,liberation mono,courier new,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}[type=text],input:where(:not([type])),[type=email],[type=url],[type=password],[type=number],[type=date],[type=datetime-local],[type=month],[type=search],[type=tel],[type=time],[type=week],[multiple],textarea,select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-width:1px;border-radius:0;padding-top:.5rem;padding-right:.75rem;padding-bottom:.5rem;padding-left:.75rem;font-size:1rem;line-height:1.5rem;--tw-shadow:0 0 #0000}[type=text]:focus,input:where(:not([type])):focus,[type=email]:focus,[type=url]:focus,[type=password]:focus,[type=number]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=month]:focus,[type=search]:focus,[type=tel]:focus,[type=time]:focus,[type=week]:focus,[multiple]:focus,textarea:focus,select:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-color:#2563eb}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field{padding-top:0;padding-bottom:0}select{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple],[size]:where(select:not([size="1"])){background-image:initial;background-position:initial;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;flex-shrink:0;height:1rem;width:1rem;color:#2563eb;background-color:#fff;border-color:#6b7280;border-width:1px;--tw-shadow:0 0 #0000}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}[type=checkbox]:checked,[type=radio]:checked{border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}[type=checkbox]:checked{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e")}@media(forced-colors:active){[type=checkbox]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=radio]:checked{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e")}@media(forced-colors:active){[type=radio]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:checked:hover,[type=checkbox]:checked:focus,[type=radio]:checked:hover,[type=radio]:checked:focus{border-color:transparent;background-color:currentColor}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}@media(forced-colors:active){[type=checkbox]:indeterminate{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:indeterminate:hover,[type=checkbox]:indeterminate:focus{border-color:transparent;background-color:currentColor}[type=file]{background:unset;border-color:inherit;border-width:0;border-radius:0;padding:0;font-size:unset;line-height:inherit}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}@supports(-moz-appearance:none){*{scrollbar-color:initial;scrollbar-width:initial}}.container{width:100%}@media(min-width:640px){.container{max-width:640px}}@media(min-width:853px){.container{max-width:853px}}@media(min-width:1024px){.container{max-width:1024px}}@media(min-width:1280px){.container{max-width:1280px}}@media(min-width:1536px){.container{max-width:1536px}}.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);text-decoration:none;font-weight:500;text-decoration-color:rgba(var(--color-primary-300),1)}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)):hover{color:rgba(var(--color-primary-600),1);text-decoration:none;border-radius:.09rem}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=As]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=as]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=Is]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=is]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{font-weight:400;color:var(--tw-prose-counters)}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.25em}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-style:italic;color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"\201C""\201D""\2018""\2019";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *))::before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *))::after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:900;color:inherit}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:800;color:inherit}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-top:2em;margin-bottom:2em}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:600;font-family:inherit;color:var(--tw-prose-kbd);box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows)/10%),0 3px rgb(var(--tw-prose-kbd-shadows)/10%);font-size:.9rem;border-radius:.25rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em;background-color:rgba(var(--color-neutral-200),1);padding:.1rem .4rem}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-weight:600;font-size:.875em;background-color:rgba(var(--color-neutral-50),1);padding-top:3px;padding-bottom:3px;padding-left:5px;padding-right:5px;border-radius:.25rem}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *))::before{content:"`";display:none}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *))::after{content:"`";display:none}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code)}.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);overflow-x:auto;font-weight:400;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *))::before{content:none}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *))::after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){width:100%;table-layout:auto;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;vertical-align:bottom;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose{--tw-prose-body:rgba(var(--color-neutral-700), 1);--tw-prose-headings:rgba(var(--color-neutral-800), 1);--tw-prose-lead:rgba(var(--color-neutral-500), 1);--tw-prose-links:rgba(var(--color-primary-600), 1);--tw-prose-bold:rgba(var(--color-neutral-900), 1);--tw-prose-counters:rgba(var(--color-neutral-800), 1);--tw-prose-bullets:rgba(var(--color-neutral-500), 1);--tw-prose-hr:rgba(var(--color-neutral-200), 1);--tw-prose-quotes:rgba(var(--color-neutral-700), 1);--tw-prose-quote-borders:rgba(var(--color-primary-200), 1);--tw-prose-captions:rgba(var(--color-neutral-500), 1);--tw-prose-kbd:#111827;--tw-prose-kbd-shadows:17 24 39;--tw-prose-code:rgba(var(--color-secondary-700), 1);--tw-prose-pre-code:rgba(var(--color-neutral-700), 1);--tw-prose-pre-bg:rgba(var(--color-neutral-50), 1);--tw-prose-th-borders:rgba(var(--color-neutral-500), 1);--tw-prose-td-borders:rgba(var(--color-neutral-300), 1);--tw-prose-invert-body:rgba(var(--color-neutral-300), 1);--tw-prose-invert-headings:rgba(var(--color-neutral-50), 1);--tw-prose-invert-lead:rgba(var(--color-neutral-500), 1);--tw-prose-invert-links:rgba(var(--color-primary-400), 1);--tw-prose-invert-bold:rgba(var(--color-neutral), 1);--tw-prose-invert-counters:rgba(var(--color-neutral-400), 1);--tw-prose-invert-bullets:rgba(var(--color-neutral-600), 1);--tw-prose-invert-hr:rgba(var(--color-neutral-500), 1);--tw-prose-invert-quotes:rgba(var(--color-neutral-200), 1);--tw-prose-invert-quote-borders:rgba(var(--color-primary-900), 1);--tw-prose-invert-captions:rgba(var(--color-neutral-400), 1);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:255 255 255;--tw-prose-invert-code:rgba(var(--color-secondary-400), 1);--tw-prose-invert-pre-code:rgba(var(--color-neutral-200), 1);--tw-prose-invert-pre-bg:rgba(var(--color-neutral-700), 1);--tw-prose-invert-th-borders:rgba(var(--color-neutral-500), 1);--tw-prose-invert-td-borders:rgba(var(--color-neutral-700), 1);font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose :where(mark):not(:where([class~=not-prose],[class~=not-prose] *)){color:rgba(var(--color-neutral-800),1);background-color:rgba(var(--color-primary-600),1);padding:.1rem .2rem;border-radius:.25rem}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *))::before{display:none}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *))::after{display:none}.prose :where(a.active):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-color:rgba(var(--color-primary-600),1)}.prose :where(p.active):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-color:rgba(var(--color-primary-600),1)}.prose-invert{--tw-prose-body:var(--tw-prose-invert-body);--tw-prose-headings:var(--tw-prose-invert-headings);--tw-prose-lead:var(--tw-prose-invert-lead);--tw-prose-links:var(--tw-prose-invert-links);--tw-prose-bold:var(--tw-prose-invert-bold);--tw-prose-counters:var(--tw-prose-invert-counters);--tw-prose-bullets:var(--tw-prose-invert-bullets);--tw-prose-hr:var(--tw-prose-invert-hr);--tw-prose-quotes:var(--tw-prose-invert-quotes);--tw-prose-quote-borders:var(--tw-prose-invert-quote-borders);--tw-prose-captions:var(--tw-prose-invert-captions);--tw-prose-kbd:var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows:var(--tw-prose-invert-kbd-shadows);--tw-prose-code:var(--tw-prose-invert-code);--tw-prose-pre-code:var(--tw-prose-invert-pre-code);--tw-prose-pre-bg:var(--tw-prose-invert-pre-bg);--tw-prose-th-borders:var(--tw-prose-invert-th-borders);--tw-prose-td-borders:var(--tw-prose-invert-td-borders)}.prose-invert :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-color:rgba(var(--color-neutral-600),1)}.prose-invert :where(a):not(:where([class~=not-prose],[class~=not-prose] *)):hover{color:rgba(var(--color-primary-400),1)}.prose-invert :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:rgba(var(--color-neutral-200),1);background-color:rgba(var(--color-neutral-700),1)}.prose-invert :where(mark):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:rgba(var(--color-primary-400),1)}.prose-invert :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:rgba(var(--color-neutral-700),1)}.prose-invert :where(a.active):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-color:rgba(var(--color-primary-400),1)}.prose-invert :where(p.active):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-color:rgba(var(--color-primary-400),1)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.\!visible{visibility:visible!important}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.\!absolute{position:absolute!important}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{left:0;right:0}.bottom-0{bottom:0}.left-0{left:0}.right-0{right:0}.top-0{top:0}.top-20{top:5rem}.top-\[110vh\]{top:110vh}.top-\[calc\(100vh-5\.5rem\)\]{top:calc(100vh - 5.5rem)}.z-10{z-index:10}.z-30{z-index:30}.z-\[1040\]{z-index:1040}.z-\[1070\]{z-index:1070}.z-\[1080\]{z-index:1080}.z-\[1\]{z-index:1}.z-\[2\]{z-index:2}.z-\[999\]{z-index:999}.order-first{order:-9999}.float-left{float:left}.\!-m-px{margin:-1px!important}.m-0{margin:0}.m-1{margin:.25rem}.m-2{margin:.5rem}.m-auto{margin:auto}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-\[15\%\]{margin-left:15%;margin-right:15%}.mx-\[3px\]{margin-left:3px;margin-right:3px}.mx-auto{margin-left:auto;margin-right:auto}.my-0{margin-top:0;margin-bottom:0}.my-3{margin-top:.75rem;margin-bottom:.75rem}.\!mb-0{margin-bottom:0!important}.\!mb-9{margin-bottom:2.25rem!important}.\!mt-0{margin-top:0!important}.-mb-1{margin-bottom:-.25rem}.-ml-12{margin-left:-3rem}.-mr-2{margin-right:-.5rem}.-mr-48{margin-right:-12rem}.-mr-\[100\%\]{margin-right:-100%}.mb-0{margin-bottom:0}.mb-1{margin-bottom:.25rem}.mb-10{margin-bottom:2.5rem}.mb-12{margin-bottom:3rem}.mb-16{margin-bottom:4rem}.mb-2{margin-bottom:.5rem}.mb-20{margin-bottom:5rem}.mb-3{margin-bottom:.75rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-\[2px\]{margin-bottom:2px}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-6{margin-left:1.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-3{margin-right:.75rem}.mr-5{margin-right:1.25rem}.mr-auto{margin-right:auto}.mt-0{margin-top:0}.mt-1{margin-top:.25rem}.mt-10{margin-top:2.5rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-20{margin-top:5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.mt-\[-2px\]{margin-top:-2px}.mt-\[0\.1rem\]{margin-top:.1rem}.box-border{box-sizing:border-box}.box-content{box-sizing:content-box}.\!block{display:block!important}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.\!h-px{height:1px!important}.h-0{height:0}.h-1\/2{height:50%}.h-12{height:3rem}.h-24{height:6rem}.h-3{height:.75rem}.h-36{height:9rem}.h-48{height:12rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-\[1000px\]{height:1000px}.h-\[150px\]{height:150px}.h-\[3px\]{height:3px}.h-\[800px\]{height:800px}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.max-h-3{max-height:.75rem}.max-h-\[5rem\]{max-height:5rem}.min-h-0{min-height:0}.min-h-\[130px\]{min-height:130px}.min-h-\[148px\]{min-height:148px}.min-h-full{min-height:100%}.\!w-px{width:1px!important}.w-0{width:0}.w-12{width:3rem}.w-2{width:.5rem}.w-24{width:6rem}.w-3{width:.75rem}.w-36{width:9rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-\[15\%\]{width:15%}.w-\[30px\]{width:30px}.w-auto{width:auto}.w-full{width:100%}.w-screen{width:100vw}.min-w-0{min-width:0}.min-w-\[1\.8rem\]{min-width:1.8rem}.min-w-\[220px\]{min-width:220px}.min-w-\[30px\]{min-width:30px}.min-w-full{min-width:100%}.max-w-3xl{max-width:48rem}.max-w-7xl{max-width:80rem}.max-w-\[1600px\]{max-width:1600px}.max-w-\[200px\]{max-width:200px}.max-w-\[267px\]{max-width:267px}.max-w-\[5rem\]{max-width:5rem}.max-w-\[64rem\]{max-width:64rem}.max-w-\[calc\(100\%-1rem\)\]{max-width:calc(100% - 1rem)}.max-w-fit{max-width:-moz-fit-content;max-width:fit-content}.max-w-full{max-width:100%}.max-w-prose{max-width:65ch}.max-w-xl{max-width:36rem}.flex-1{flex:1}.flex-auto{flex:auto}.flex-initial{flex:initial}.flex-none{flex:none}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.grow-0{flex-grow:0}.basis-auto{flex-basis:auto}.-translate-x-full{--tw-translate-x:-100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.-translate-y-8{--tw-translate-y:-2rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.translate-x-full{--tw-translate-x:100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.scale-0{--tw-scale-x:0;--tw-scale-y:0;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.scale-100{--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.scale-\[1\.02\]{--tw-scale-x:1.02;--tw-scale-y:1.02;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.transform-none{transform:none}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1)infinite}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.touch-pan-y{--tw-pan-y:pan-y;touch-action:var(--tw-pan-x)var(--tw-pan-y)var(--tw-pinch-zoom)}.resize{resize:both}.list-none{list-style-type:none}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-4{gap:1rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.75rem * var(--tw-space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1.25rem * var(--tw-space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-10>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2.5rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.place-self-center{place-self:center}.self-center{align-self:center}.overflow-auto{overflow:auto}.\!overflow-hidden{overflow:hidden!important}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-y-scroll{overflow-y:scroll}.overscroll-contain{overscroll-behavior:contain}.scroll-smooth{scroll-behavior:smooth}.whitespace-normal{white-space:normal}.\!whitespace-nowrap{white-space:nowrap!important}.break-normal{overflow-wrap:normal;word-break:normal}.break-words{overflow-wrap:break-word}.\!rounded-md{border-radius:.375rem!important}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-\[50\%\]{border-radius:50%}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-e-\[0\.25rem\]{border-start-end-radius:.25rem;border-end-end-radius:.25rem}.rounded-s-\[0\.25rem\]{border-start-start-radius:.25rem;border-end-start-radius:.25rem}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.\!border-0{border-width:0!important}.border{border-width:1px}.border-0{border-width:0}.border-2{border-width:2px}.border-y-\[10px\]{border-top-width:10px;border-bottom-width:10px}.border-b-2{border-bottom-width:2px}.border-e-0{border-inline-end-width:0}.border-l-2{border-left-width:2px}.border-s-0{border-inline-start-width:0}.border-s-\[0\.125rem\]{border-inline-start-width:.125rem}.border-t{border-top-width:1px}.border-solid{border-style:solid}.border-dotted{border-style:dotted}.border-neutral-100{--tw-border-opacity:1;border-color:rgba(var(--color-neutral-100),var(--tw-border-opacity))}.border-neutral-200{--tw-border-opacity:1;border-color:rgba(var(--color-neutral-200),var(--tw-border-opacity))}.border-neutral-300{--tw-border-opacity:1;border-color:rgba(var(--color-neutral-300),var(--tw-border-opacity))}.border-primary-400{--tw-border-opacity:1;border-color:rgba(var(--color-primary-400),var(--tw-border-opacity))}.border-primary-500{--tw-border-opacity:1;border-color:rgba(var(--color-primary-500),var(--tw-border-opacity))}.border-secondary-500{--tw-border-opacity:1;border-color:rgba(var(--color-secondary-500),var(--tw-border-opacity))}.border-transparent{border-color:transparent}.border-t-transparent{border-top-color:transparent}.bg-\[\#6d6d6d\]{--tw-bg-opacity:1;background-color:rgb(109 109 109/var(--tw-bg-opacity))}.bg-neutral{--tw-bg-opacity:1;background-color:rgba(var(--color-neutral),var(--tw-bg-opacity))}.bg-neutral-100{--tw-bg-opacity:1;background-color:rgba(var(--color-neutral-100),var(--tw-bg-opacity))}.bg-neutral-100\/50{background-color:rgba(var(--color-neutral-100),.5)}.bg-neutral-300{--tw-bg-opacity:1;background-color:rgba(var(--color-neutral-300),var(--tw-bg-opacity))}.bg-neutral-500\/50{background-color:rgba(var(--color-neutral-500),.5)}.bg-neutral\/50{background-color:rgba(var(--color-neutral),.5)}.bg-primary-100{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100),var(--tw-bg-opacity))}.bg-primary-200{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-200),var(--tw-bg-opacity))}.bg-primary-500{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500),var(--tw-bg-opacity))}.bg-primary-600{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-600),var(--tw-bg-opacity))}.bg-transparent{background-color:transparent}.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.bg-none{background-image:none}.from-neutral{--tw-gradient-from:rgba(var(--color-neutral), 1) var(--tw-gradient-from-position);--tw-gradient-to:rgba(var(--color-neutral), 0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.from-primary-500{--tw-gradient-from:rgba(var(--color-primary-500), 1) var(--tw-gradient-from-position);--tw-gradient-to:rgba(var(--color-primary-500), 0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.from-60\%{--tw-gradient-from-position:60%}.to-neutral{--tw-gradient-to:rgba(var(--color-neutral), 1) var(--tw-gradient-to-position)}.to-neutral-100{--tw-gradient-to:rgba(var(--color-neutral-100), 1) var(--tw-gradient-to-position)}.to-secondary-600{--tw-gradient-to:rgba(var(--color-secondary-600), 1) var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.bg-clip-padding{background-clip:padding-box}.object-cover{-o-object-fit:cover;object-fit:cover}.object-scale-down{-o-object-fit:scale-down;object-fit:scale-down}.object-left{-o-object-position:left;object-position:left}.\!p-0{padding:0!important}.p-0{padding:0}.p-1\.5{padding:.375rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-0{padding-left:0;padding-right:0}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-\[0\.4rem\]{padding-left:.4rem;padding-right:.4rem}.px-\[30px\]{padding-left:30px;padding-right:30px}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.py-\[0\.4rem\]{padding-top:.4rem;padding-bottom:.4rem}.py-\[1px\]{padding-top:1px;padding-bottom:1px}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-32{padding-bottom:8rem}.pb-4{padding-bottom:1rem}.pl-2{padding-left:.5rem}.pl-\[24px\]{padding-left:24px}.pr-\[24px\]{padding-right:24px}.pt-16{padding-top:4rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-8{padding-top:2rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.-indent-\[999px\]{text-indent:-999px}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.align-bottom{vertical-align:bottom}.align-text-bottom{vertical-align:text-bottom}.text-2xl{font-size:1.5rem;line-height:2rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[0\.6rem\]{font-size:.6rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-light{font-weight:300}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.normal-case{text-transform:none}.italic{font-style:italic}.not-italic{font-style:normal}.leading-3{line-height:.75rem}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-\[1\.6\]{line-height:1.6}.tracking-normal{letter-spacing:0}.\!text-neutral{--tw-text-opacity:1 !important;color:rgba(var(--color-neutral),var(--tw-text-opacity))!important}.text-neutral-200{--tw-text-opacity:1;color:rgba(var(--color-neutral-200),var(--tw-text-opacity))}.text-neutral-300{--tw-text-opacity:1;color:rgba(var(--color-neutral-300),var(--tw-text-opacity))}.text-neutral-400{--tw-text-opacity:1;color:rgba(var(--color-neutral-400),var(--tw-text-opacity))}.text-neutral-50{--tw-text-opacity:1;color:rgba(var(--color-neutral-50),var(--tw-text-opacity))}.text-neutral-500{--tw-text-opacity:1;color:rgba(var(--color-neutral-500),var(--tw-text-opacity))}.text-neutral-700{--tw-text-opacity:1;color:rgba(var(--color-neutral-700),var(--tw-text-opacity))}.text-neutral-800{--tw-text-opacity:1;color:rgba(var(--color-neutral-800),var(--tw-text-opacity))}.text-neutral-900{--tw-text-opacity:1;color:rgba(var(--color-neutral-900),var(--tw-text-opacity))}.text-primary-100{--tw-text-opacity:1;color:rgba(var(--color-primary-100),var(--tw-text-opacity))}.text-primary-300{--tw-text-opacity:1;color:rgba(var(--color-primary-300),var(--tw-text-opacity))}.text-primary-400{--tw-text-opacity:1;color:rgba(var(--color-primary-400),var(--tw-text-opacity))}.text-primary-500{--tw-text-opacity:1;color:rgba(var(--color-primary-500),var(--tw-text-opacity))}.text-primary-600{--tw-text-opacity:1;color:rgba(var(--color-primary-600),var(--tw-text-opacity))}.text-primary-700{--tw-text-opacity:1;color:rgba(var(--color-primary-700),var(--tw-text-opacity))}.text-primary-800{--tw-text-opacity:1;color:rgba(var(--color-primary-800),var(--tw-text-opacity))}.text-transparent{color:transparent}.\!no-underline{text-decoration-line:none!important}.no-underline{text-decoration-line:none}.decoration-neutral-300{text-decoration-color:rgba(var(--color-neutral-300),1)}.decoration-primary-500{text-decoration-color:rgba(var(--color-primary-500),1)}.underline-offset-auto{text-underline-offset:auto}.\!opacity-0{opacity:0!important}.\!opacity-100{opacity:1!important}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-30{opacity:.3}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-65{opacity:.65}.mix-blend-normal{mix-blend-mode:normal}.mix-blend-multiply{mix-blend-mode:multiply}.shadow{--tw-shadow:0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px rgb(0 0 0 / 0.25);--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.filter{filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur)var(--tw-backdrop-brightness)var(--tw-backdrop-contrast)var(--tw-backdrop-grayscale)var(--tw-backdrop-hue-rotate)var(--tw-backdrop-invert)var(--tw-backdrop-opacity)var(--tw-backdrop-saturate)var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur)var(--tw-backdrop-brightness)var(--tw-backdrop-contrast)var(--tw-backdrop-grayscale)var(--tw-backdrop-hue-rotate)var(--tw-backdrop-invert)var(--tw-backdrop-opacity)var(--tw-backdrop-saturate)var(--tw-backdrop-sepia)}.backdrop-blur-2xl{--tw-backdrop-blur:blur(40px);-webkit-backdrop-filter:var(--tw-backdrop-blur)var(--tw-backdrop-brightness)var(--tw-backdrop-contrast)var(--tw-backdrop-grayscale)var(--tw-backdrop-hue-rotate)var(--tw-backdrop-invert)var(--tw-backdrop-opacity)var(--tw-backdrop-saturate)var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur)var(--tw-backdrop-brightness)var(--tw-backdrop-contrast)var(--tw-backdrop-grayscale)var(--tw-backdrop-hue-rotate)var(--tw-backdrop-invert)var(--tw-backdrop-opacity)var(--tw-backdrop-saturate)var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur)var(--tw-backdrop-brightness)var(--tw-backdrop-contrast)var(--tw-backdrop-grayscale)var(--tw-backdrop-hue-rotate)var(--tw-backdrop-invert)var(--tw-backdrop-opacity)var(--tw-backdrop-saturate)var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur)var(--tw-backdrop-brightness)var(--tw-backdrop-contrast)var(--tw-backdrop-grayscale)var(--tw-backdrop-hue-rotate)var(--tw-backdrop-invert)var(--tw-backdrop-opacity)var(--tw-backdrop-saturate)var(--tw-backdrop-sepia)}.transition-\[height\]{transition-property:height;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:150ms}.transition-\[transform\2c _opacity\]{transition-property:transform,opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:150ms}.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:150ms}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:150ms}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:150ms}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:150ms}.duration-150{transition-duration:150ms}.duration-200{transition-duration:200ms}.duration-300{transition-duration:300ms}.duration-\[350ms\]{transition-duration:350ms}.duration-\[600ms\]{transition-duration:600ms}.ease-\[cubic-bezier\(0\2c 0\2c 0\.15\2c 1\)\2c _cubic-bezier\(0\2c 0\2c 0\.15\2c 1\)\]{transition-timing-function:cubic-bezier(0,0,.15,1),cubic-bezier(0,0,.15,1)}.ease-\[cubic-bezier\(0\.25\2c 0\.1\2c 0\.25\2c 1\.0\)\]{transition-timing-function:cubic-bezier(.25,.1,.25,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-linear{transition-timing-function:linear}.scrollbar-thin::-webkit-scrollbar-track{background-color:var(--scrollbar-track);border-radius:var(--scrollbar-track-radius)}.scrollbar-thin::-webkit-scrollbar-track:hover{background-color:var(--scrollbar-track-hover,var(--scrollbar-track))}.scrollbar-thin::-webkit-scrollbar-track:active{background-color:var(--scrollbar-track-active,var(--scrollbar-track-hover,var(--scrollbar-track)))}.scrollbar-thin::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb);border-radius:var(--scrollbar-thumb-radius)}.scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover,var(--scrollbar-thumb))}.scrollbar-thin::-webkit-scrollbar-thumb:active{background-color:var(--scrollbar-thumb-active,var(--scrollbar-thumb-hover,var(--scrollbar-thumb)))}.scrollbar-thin::-webkit-scrollbar-corner{background-color:var(--scrollbar-corner);border-radius:var(--scrollbar-corner-radius)}.scrollbar-thin::-webkit-scrollbar-corner:hover{background-color:var(--scrollbar-corner-hover,var(--scrollbar-corner))}.scrollbar-thin::-webkit-scrollbar-corner:active{background-color:var(--scrollbar-corner-active,var(--scrollbar-corner-hover,var(--scrollbar-corner)))}@supports(-moz-appearance:none){.scrollbar-thin{scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb,initial)var(--scrollbar-track,initial)}}.scrollbar-thin::-webkit-scrollbar{display:block;width:8px;height:8px}.scrollbar-track-neutral-200{--scrollbar-track:rgba(var(--color-neutral-200), 1) !important}.scrollbar-thumb-neutral-400{--scrollbar-thumb:rgba(var(--color-neutral-400), 1) !important}.\!\[clip\:rect\(0\2c 0\2c 0\2c 0\)\]{clip:rect(0,0,0,0)!important}body a,body button{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:150ms}.icon svg{height:1em;width:1em}.logo svg{height:5rem;width:5rem}#search-query::-webkit-search-cancel-button,#search-query::-webkit-search-decoration,#search-query::-webkit-search-results-button,#search-query::-webkit-search-results-decoration{display:none}.prose blockquote:where([dir=rtl],[dir=rtl] *){border-left-width:0;border-right-width:4px;padding-right:1rem}.prose ul>li:where([dir=rtl],[dir=rtl] *),.prose ol>li:where([dir=rtl],[dir=rtl] *){margin-right:1.75rem;padding-left:0;padding-right:.5rem}.prose ol>li:where([dir=rtl],[dir=rtl] *):before,.prose ul>li:where([dir=rtl],[dir=rtl] *):before{left:auto;right:.25rem}.prose thead td:first-child:where([dir=rtl],[dir=rtl] *),.prose thead th:first-child:where([dir=rtl],[dir=rtl] *){padding-right:0}.prose thead td:last-child:where([dir=rtl],[dir=rtl] *),.prose thead th:last-child:where([dir=rtl],[dir=rtl] *){padding-left:0}.prose div.min-w-0.max-w-prose>*:first-child{margin-top:.75rem}.toc ul,.toc li{list-style-type:none;padding-left:0;padding-right:0;line-height:1.375}.toc ul ul:where([dir=ltr],[dir=ltr] *){padding-left:1rem}.toc ul ul:where([dir=rtl],[dir=rtl] *){padding-right:1rem}.toc a{font-weight:400;--tw-text-opacity:1;color:rgba(var(--color-neutral-700),var(--tw-text-opacity))}.toc a:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-400),var(--tw-text-opacity))}.toc ul>li:where([dir=rtl],[dir=rtl] *){margin-right:0}.highlight-wrapper{display:block}.highlight{position:relative;z-index:0}.highlight:hover>.copy-button{visibility:visible}.copy-button{visibility:hidden;position:absolute;top:0;right:0;z-index:10;width:5rem;cursor:pointer;white-space:nowrap;border-bottom-left-radius:.375rem;border-top-right-radius:.375rem;--tw-bg-opacity:1;background-color:rgba(var(--color-neutral-200),var(--tw-bg-opacity));padding-top:.25rem;padding-bottom:.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,liberation mono,courier new,monospace;font-size:.875rem;line-height:1.25rem;--tw-text-opacity:1;color:rgba(var(--color-neutral-700),var(--tw-text-opacity));opacity:.9}.copy-button:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-neutral-600),var(--tw-bg-opacity));--tw-text-opacity:1;color:rgba(var(--color-neutral-200),var(--tw-text-opacity))}.copy-button:hover,.copy-button:focus,.copy-button:active,.copy-button:active:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100),var(--tw-bg-opacity))}.copy-button:hover:is(.dark *),.copy-button:focus:is(.dark *),.copy-button:active:is(.dark *),.copy-button:active:hover:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-primary-600),var(--tw-bg-opacity))}.copy-textarea{position:absolute;z-index:-10;opacity:.05}.katex-display{overflow:auto hidden}table{display:block;overflow:auto}code{word-wrap:break-word;overflow-wrap:break-word}a{word-break:break-word;word-wrap:break-word;overflow-wrap:break-word}.prose .chroma{position:static;border-radius:.375rem;--tw-bg-opacity:1;background-color:rgba(var(--color-neutral-50),var(--tw-bg-opacity));--tw-text-opacity:1;color:rgba(var(--color-neutral-700),var(--tw-text-opacity))}.prose .chroma:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-neutral-700),var(--tw-bg-opacity));--tw-text-opacity:1;color:rgba(var(--color-neutral-200),var(--tw-text-opacity))}.chroma .lntd,.chroma .lntd pre{margin:0;border-style:none;padding:0;vertical-align:top}.chroma .lntable{display:block;width:auto;overflow:hidden;padding-left:1rem;padding-right:1rem;padding-top:.75rem;padding-bottom:.75rem;font-size:1rem;line-height:1.5rem;border-spacing:0}.chroma .hl{margin-left:-1rem;margin-right:-1rem;display:block;width:auto;--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100),var(--tw-bg-opacity));padding-left:1rem;padding-right:1rem}.chroma .hl:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-primary-900),var(--tw-bg-opacity))}.chroma .lntd .hl{margin:0;padding:0}.chroma .lnt,.chroma .ln{margin-right:.4em;padding-left:.4em;padding-right:.4em;padding-top:0;padding-bottom:0;--tw-text-opacity:1;color:rgba(var(--color-neutral-600),var(--tw-text-opacity))}.chroma .lnt:is(.dark *),.chroma .ln:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-300),var(--tw-text-opacity))}.chroma .k,.chroma .kd,.chroma .kn,.chroma .kp,.chroma .kr,.chroma .nc,.chroma .fm,.chroma .nn,.chroma .vc,.chroma .o{--tw-text-opacity:1;color:rgba(var(--color-primary-600),var(--tw-text-opacity))}.chroma .k:is(.dark *),.chroma .kd:is(.dark *),.chroma .kn:is(.dark *),.chroma .kp:is(.dark *),.chroma .kr:is(.dark *),.chroma .nc:is(.dark *),.chroma .fm:is(.dark *),.chroma .nn:is(.dark *),.chroma .vc:is(.dark *),.chroma .o:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-primary-300),var(--tw-text-opacity))}.chroma .kc{font-weight:600;--tw-text-opacity:1;color:rgba(var(--color-secondary-400),var(--tw-text-opacity))}.chroma .kc:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-secondary-500),var(--tw-text-opacity))}.chroma .kt,.chroma .nv,.chroma .vi,.chroma .vm,.chroma .m,.chroma .mb,.chroma .mf,.chroma .mh,.chroma .mi,.chroma .il,.chroma .mo{--tw-text-opacity:1;color:rgba(var(--color-secondary-400),var(--tw-text-opacity))}.chroma .kt:is(.dark *),.chroma .nv:is(.dark *),.chroma .vi:is(.dark *),.chroma .vm:is(.dark *),.chroma .m:is(.dark *),.chroma .mb:is(.dark *),.chroma .mf:is(.dark *),.chroma .mh:is(.dark *),.chroma .mi:is(.dark *),.chroma .il:is(.dark *),.chroma .mo:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-secondary-600),var(--tw-text-opacity))}.chroma .n,.chroma .nd,.chroma .ni,.chroma .nl{--tw-text-opacity:1;color:rgba(var(--color-secondary-900),var(--tw-text-opacity))}.chroma .n:is(.dark *),.chroma .nd:is(.dark *),.chroma .ni:is(.dark *),.chroma .nl:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-secondary-200),var(--tw-text-opacity))}.chroma .na,.chroma .nb,.chroma .bp,.chroma .nx,.chroma .py,.chroma .nt{--tw-text-opacity:1;color:rgba(var(--color-secondary-800),var(--tw-text-opacity))}.chroma .na:is(.dark *),.chroma .nb:is(.dark *),.chroma .bp:is(.dark *),.chroma .nx:is(.dark *),.chroma .py:is(.dark *),.chroma .nt:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-secondary-300),var(--tw-text-opacity))}.chroma .no,.chroma .ne,.chroma .vg{font-weight:600;--tw-text-opacity:1;color:rgba(var(--color-secondary-400),var(--tw-text-opacity))}.chroma .no:is(.dark *),.chroma .ne:is(.dark *),.chroma .vg:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-secondary-500),var(--tw-text-opacity))}.chroma .nf{--tw-text-opacity:1;color:rgba(var(--color-secondary-600),var(--tw-text-opacity))}.chroma .nf:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-secondary-500),var(--tw-text-opacity))}.chroma .l,.chroma .ld,.chroma .s,.chroma .sa,.chroma .sb,.chroma .sc,.chroma .dl,.chroma .sd,.chroma .s2,.chroma .sh,.chroma .si,.chroma .sx,.chroma .s1,.chroma .gi,.chroma .go,.chroma .gp{--tw-text-opacity:1;color:rgba(var(--color-primary-800),var(--tw-text-opacity))}.chroma .l:is(.dark *),.chroma .ld:is(.dark *),.chroma .s:is(.dark *),.chroma .sa:is(.dark *),.chroma .sb:is(.dark *),.chroma .sc:is(.dark *),.chroma .dl:is(.dark *),.chroma .sd:is(.dark *),.chroma .s2:is(.dark *),.chroma .sh:is(.dark *),.chroma .si:is(.dark *),.chroma .sx:is(.dark *),.chroma .s1:is(.dark *),.chroma .gi:is(.dark *),.chroma .go:is(.dark *),.chroma .gp:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-primary-400),var(--tw-text-opacity))}.chroma .se{font-weight:600;--tw-text-opacity:1;color:rgba(var(--color-secondary-400),var(--tw-text-opacity))}.chroma .se:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-secondary-500),var(--tw-text-opacity))}.chroma .sr,.chroma .ss{font-weight:600;--tw-text-opacity:1;color:rgba(var(--color-primary-800),var(--tw-text-opacity))}.chroma .sr:is(.dark *),.chroma .ss:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-primary-400),var(--tw-text-opacity))}.chroma .ow{font-weight:600;--tw-text-opacity:1;color:rgba(var(--color-primary-400),var(--tw-text-opacity))}.chroma .ow:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-primary-600),var(--tw-text-opacity))}.chroma .c,.chroma .cm,.chroma .c1,.chroma .cs,.chroma .cp,.chroma .cpf{font-style:italic;--tw-text-opacity:1;color:rgba(var(--color-neutral-500),var(--tw-text-opacity))}.chroma .c:is(.dark *),.chroma .cm:is(.dark *),.chroma .c1:is(.dark *),.chroma .cs:is(.dark *),.chroma .cp:is(.dark *),.chroma .cpf:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-400),var(--tw-text-opacity))}.chroma .ch{font-weight:600;font-style:italic;--tw-text-opacity:1;color:rgba(var(--color-neutral-500),var(--tw-text-opacity))}.chroma .ch:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-400),var(--tw-text-opacity))}.chroma .ge{font-style:italic}.chroma .gh{font-weight:600;--tw-text-opacity:1;color:rgba(var(--color-neutral-500),var(--tw-text-opacity))}.chroma .gs{font-weight:600}.chroma .gu,.chroma .gt{--tw-text-opacity:1;color:rgba(var(--color-neutral-500),var(--tw-text-opacity))}.chroma .gl{text-decoration-line:underline}pre{text-align:left}.thumbnail{min-width:300px;height:180px;background-repeat:no-repeat;background-size:cover;background-position:50%}.thumbnail_card{height:200px;background-repeat:no-repeat;background-size:cover;background-position:50%}.thumbnail_card_related{height:150px;background-repeat:no-repeat;background-size:cover;background-position:50%}.thumbnail_card_term{height:150px;background-repeat:no-repeat;background-size:cover;background-position:50%}.single_hero_basic{background-repeat:no-repeat;background-size:cover;background-position:50%}.single_hero_round{max-height:50vh;-o-object-fit:cover;object-fit:cover}.single_hero_background{background-repeat:no-repeat;background-size:cover;background-position:50%;width:calc(100% + 40px);z-index:-10;margin-left:-20px}.hero_gradient{width:100%;height:100%}.thumbnailshadow{box-shadow:5px 5px 20px 1px rgba(0,0,0,.3)}.anchor{display:block;position:relative;top:-150px;height:0;visibility:hidden}@media(min-width:640px){.thumbnail{min-width:100%;height:180px}.article{flex-wrap:wrap}}@media(min-width:853px){.thumbnail{min-width:300px;min-height:180px;height:auto}.article{flex-wrap:nowrap}}.medium-zoom-image--opened{z-index:100}.nested-menu:hover+.menuhide{visibility:visible;opacity:1;transition:visibility .3s,opacity .3s ease-in-out}.menuhide:hover{visibility:visible;opacity:1;transition:visibility .3s,opacity .3s ease-in-out}.menuhide{visibility:hidden;opacity:0;transition:visibility .3s,opacity .3s ease-in-out;z-index:1000}.active{text-decoration-line:underline;text-decoration-thickness:3px;text-underline-offset:4px}.grid-w10{width:calc(10% - 5px);margin:0!important}.grid-w15{width:calc(15% - 5px);margin:0!important}.grid-w20{width:calc(20% - 5px);margin:0!important}.grid-w25{width:calc(25% - 5px);margin:0!important}.grid-w30{width:calc(30% - 5px);margin:0!important}.grid-w33{width:calc(33% - 5px);margin:0!important}.grid-w35{width:calc(35% - 5px);margin:0!important}.grid-w40{width:calc(40% - 5px);margin:0!important}.grid-w45{width:calc(45% - 5px);margin:0!important}.grid-w50{width:calc(50% - 5px);margin:0!important}.grid-w55{width:calc(55% - 5px);margin:0!important}.grid-w60{width:calc(60% - 5px);margin:0!important}.grid-w65{width:calc(65% - 5px);margin:0!important}.grid-w66{width:calc(66% - 5px);margin:0!important}.grid-w70{width:calc(70% - 5px);margin:0!important}.grid-w75{width:calc(75% - 5px);margin:0!important}.grid-w80{width:calc(80% - 5px);margin:0!important}.grid-w85{width:calc(85% - 5px);margin:0!important}.grid-w90{width:calc(90% - 5px);margin:0!important}.grid-w95{width:calc(95% - 5px);margin:0!important}.grid-w100{width:calc(100% - 5px);margin:0!important}@media(min-width:640px){.sm\:grid-w10{width:calc(10% - 5px);margin:0!important}.sm\:grid-w15{width:calc(15% - 5px);margin:0!important}.sm\:grid-w20{width:calc(20% - 5px);margin:0!important}.sm\:grid-w25{width:calc(25% - 5px);margin:0!important}.sm\:grid-w30{width:calc(30% - 5px);margin:0!important}.sm\:grid-w33{width:calc(33% - 5px);margin:0!important}.sm\:grid-w35{width:calc(35% - 5px);margin:0!important}.sm\:grid-w40{width:calc(40% - 5px);margin:0!important}.sm\:grid-w45{width:calc(45% - 5px);margin:0!important}.sm\:grid-w50{width:calc(50% - 5px);margin:0!important}.sm\:grid-w55{width:calc(55% - 5px);margin:0!important}.sm\:grid-w60{width:calc(60% - 5px);margin:0!important}.sm\:grid-w65{width:calc(65% - 5px);margin:0!important}.sm\:grid-w66{width:calc(66% - 5px);margin:0!important}.sm\:grid-w70{width:calc(70% - 5px);margin:0!important}.sm\:grid-w75{width:calc(75% - 5px);margin:0!important}.sm\:grid-w80{width:calc(80% - 5px);margin:0!important}.sm\:grid-w85{width:calc(85% - 5px);margin:0!important}.sm\:grid-w90{width:calc(90% - 5px);margin:0!important}.sm\:grid-w95{width:calc(95% - 5px);margin:0!important}.sm\:grid-w100{width:calc(100% - 5px);margin:0!important}}@media(min-width:853px){.md\:grid-w10{width:calc(10% - 5px);margin:0!important}.md\:grid-w15{width:calc(15% - 5px);margin:0!important}.md\:grid-w20{width:calc(20% - 5px);margin:0!important}.md\:grid-w25{width:calc(25% - 5px);margin:0!important}.md\:grid-w30{width:calc(30% - 5px);margin:0!important}.md\:grid-w33{width:calc(33% - 5px);margin:0!important}.md\:grid-w35{width:calc(35% - 5px);margin:0!important}.md\:grid-w40{width:calc(40% - 5px);margin:0!important}.md\:grid-w45{width:calc(45% - 5px);margin:0!important}.md\:grid-w50{width:calc(50% - 5px);margin:0!important}.md\:grid-w55{width:calc(55% - 5px);margin:0!important}.md\:grid-w60{width:calc(60% - 5px);margin:0!important}.md\:grid-w65{width:calc(65% - 5px);margin:0!important}.md\:grid-w66{width:calc(66% - 5px);margin:0!important}.md\:grid-w70{width:calc(70% - 5px);margin:0!important}.md\:grid-w75{width:calc(75% - 5px);margin:0!important}.md\:grid-w80{width:calc(80% - 5px);margin:0!important}.md\:grid-w85{width:calc(85% - 5px);margin:0!important}.md\:grid-w90{width:calc(90% - 5px);margin:0!important}.md\:grid-w95{width:calc(95% - 5px);margin:0!important}.md\:grid-w100{width:calc(100% - 5px);margin:0!important}}@media(min-width:1024px){.lg\:grid-w10{width:calc(10% - 5px);margin:0!important}.lg\:grid-w15{width:calc(15% - 5px);margin:0!important}.lg\:grid-w20{width:calc(20% - 5px);margin:0!important}.lg\:grid-w25{width:calc(25% - 5px);margin:0!important}.lg\:grid-w30{width:calc(30% - 5px);margin:0!important}.lg\:grid-w33{width:calc(33% - 5px);margin:0!important}.lg\:grid-w35{width:calc(35% - 5px);margin:0!important}.lg\:grid-w40{width:calc(40% - 5px);margin:0!important}.lg\:grid-w45{width:calc(45% - 5px);margin:0!important}.lg\:grid-w50{width:calc(50% - 5px);margin:0!important}.lg\:grid-w55{width:calc(55% - 5px);margin:0!important}.lg\:grid-w60{width:calc(60% - 5px);margin:0!important}.lg\:grid-w65{width:calc(65% - 5px);margin:0!important}.lg\:grid-w66{width:calc(66% - 5px);margin:0!important}.lg\:grid-w70{width:calc(70% - 5px);margin:0!important}.lg\:grid-w75{width:calc(75% - 5px);margin:0!important}.lg\:grid-w80{width:calc(80% - 5px);margin:0!important}.lg\:grid-w85{width:calc(85% - 5px);margin:0!important}.lg\:grid-w90{width:calc(90% - 5px);margin:0!important}.lg\:grid-w95{width:calc(95% - 5px);margin:0!important}.lg\:grid-w100{width:calc(100% - 5px);margin:0!important}}@media(min-width:1280px){.xl\:grid-w10{width:calc(10% - 5px);margin:0!important}.xl\:grid-w15{width:calc(15% - 5px);margin:0!important}.xl\:grid-w20{width:calc(20% - 5px);margin:0!important}.xl\:grid-w25{width:calc(25% - 5px);margin:0!important}.xl\:grid-w30{width:calc(30% - 5px);margin:0!important}.xl\:grid-w33{width:calc(33% - 5px);margin:0!important}.xl\:grid-w35{width:calc(35% - 5px);margin:0!important}.xl\:grid-w40{width:calc(40% - 5px);margin:0!important}.xl\:grid-w45{width:calc(45% - 5px);margin:0!important}.xl\:grid-w50{width:calc(50% - 5px);margin:0!important}.xl\:grid-w55{width:calc(55% - 5px);margin:0!important}.xl\:grid-w60{width:calc(60% - 5px);margin:0!important}.xl\:grid-w65{width:calc(65% - 5px);margin:0!important}.xl\:grid-w66{width:calc(66% - 5px);margin:0!important}.xl\:grid-w70{width:calc(70% - 5px);margin:0!important}.xl\:grid-w75{width:calc(75% - 5px);margin:0!important}.xl\:grid-w80{width:calc(80% - 5px);margin:0!important}.xl\:grid-w85{width:calc(85% - 5px);margin:0!important}.xl\:grid-w90{width:calc(90% - 5px);margin:0!important}.xl\:grid-w95{width:calc(95% - 5px);margin:0!important}.xl\:grid-w100{width:calc(100% - 5px);margin:0!important}}@media(min-width:1536px){.2xl\:grid-w10{width:calc(10% - 5px);margin:0!important}.2xl\:grid-w15{width:calc(15% - 5px);margin:0!important}.2xl\:grid-w20{width:calc(20% - 5px);margin:0!important}.2xl\:grid-w25{width:calc(25% - 5px);margin:0!important}.2xl\:grid-w30{width:calc(30% - 5px);margin:0!important}.2xl\:grid-w33{width:calc(33% - 5px);margin:0!important}.2xl\:grid-w35{width:calc(35% - 5px);margin:0!important}.2xl\:grid-w40{width:calc(40% - 5px);margin:0!important}.2xl\:grid-w45{width:calc(45% - 5px);margin:0!important}.2xl\:grid-w50{width:calc(50% - 5px);margin:0!important}.2xl\:grid-w55{width:calc(55% - 5px);margin:0!important}.2xl\:grid-w60{width:calc(60% - 5px);margin:0!important}.2xl\:grid-w65{width:calc(65% - 5px);margin:0!important}.2xl\:grid-w66{width:calc(66% - 5px);margin:0!important}.2xl\:grid-w70{width:calc(70% - 5px);margin:0!important}.2xl\:grid-w75{width:calc(75% - 5px);margin:0!important}.2xl\:grid-w80{width:calc(80% - 5px);margin:0!important}.2xl\:grid-w85{width:calc(85% - 5px);margin:0!important}.2xl\:grid-w90{width:calc(90% - 5px);margin:0!important}.2xl\:grid-w95{width:calc(95% - 5px);margin:0!important}.2xl\:grid-w100{width:calc(100% - 5px);margin:0!important}}.ratio-16-9{padding-top:56.25%}.ratio-21-9{padding-top:42.85%}.ratio-32-9{padding-top:28.125%}@media(min-width:640px){.sm\:ratio-16-9{padding-top:56.25%}.sm\:ratio-21-9{padding-top:42.85%}.sm\:ratio-32-9{padding-top:28.125%}}@media(min-width:853px){.md\:ratio-16-9{padding-top:56.25%}.md\:ratio-21-9{padding-top:42.85%}.md\:ratio-32-9{padding-top:28.125%}}@media(min-width:1024px){.lg\:ratio-16-9{padding-top:56.25%}.lg\:ratio-21-9{padding-top:42.85%}.lg\:ratio-32-9{padding-top:28.125%}}@media(min-width:1280px){.xl\:ratio-16-9{padding-top:56.25%}.xl\:ratio-21-9{padding-top:42.85%}.xl\:ratio-32-9{padding-top:28.125%}}@media(min-width:1536px){.2xl\:ratio-16-9{padding-top:56.25%}.2xl\:ratio-21-9{padding-top:42.85%}.2xl\:ratio-32-9{padding-top:28.125%}}.dark\:prose-invert:is(.dark *){--tw-prose-body:var(--tw-prose-invert-body);--tw-prose-headings:var(--tw-prose-invert-headings);--tw-prose-lead:var(--tw-prose-invert-lead);--tw-prose-links:var(--tw-prose-invert-links);--tw-prose-bold:var(--tw-prose-invert-bold);--tw-prose-counters:var(--tw-prose-invert-counters);--tw-prose-bullets:var(--tw-prose-invert-bullets);--tw-prose-hr:var(--tw-prose-invert-hr);--tw-prose-quotes:var(--tw-prose-invert-quotes);--tw-prose-quote-borders:var(--tw-prose-invert-quote-borders);--tw-prose-captions:var(--tw-prose-invert-captions);--tw-prose-kbd:var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows:var(--tw-prose-invert-kbd-shadows);--tw-prose-code:var(--tw-prose-invert-code);--tw-prose-pre-code:var(--tw-prose-invert-pre-code);--tw-prose-pre-bg:var(--tw-prose-invert-pre-bg);--tw-prose-th-borders:var(--tw-prose-invert-th-borders);--tw-prose-td-borders:var(--tw-prose-invert-td-borders)}.dark\:prose-invert:is(.dark *) :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-color:rgba(var(--color-neutral-600),1)}.dark\:prose-invert:is(.dark *) :where(a):not(:where([class~=not-prose],[class~=not-prose] *)):hover{color:rgba(var(--color-primary-400),1)}.dark\:prose-invert:is(.dark *) :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:rgba(var(--color-neutral-200),1);background-color:rgba(var(--color-neutral-700),1)}.dark\:prose-invert:is(.dark *) :where(mark):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:rgba(var(--color-primary-400),1)}.dark\:prose-invert:is(.dark *) :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:rgba(var(--color-neutral-700),1)}.dark\:prose-invert:is(.dark *) :where(a.active):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-color:rgba(var(--color-primary-400),1)}.dark\:prose-invert:is(.dark *) :where(p.active):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-color:rgba(var(--color-primary-400),1)}.after\:clear-both::after{content:var(--tw-content);clear:both}.after\:block::after{content:var(--tw-content);display:block}.after\:content-\[\'\'\]::after{--tw-content:'';content:var(--tw-content)}.first\:mt-8:first-child{margin-top:2rem}.empty\:hidden:empty{display:none}.group:hover .group-hover\:text-primary-300{--tw-text-opacity:1;color:rgba(var(--color-primary-300),var(--tw-text-opacity))}.group:hover .group-hover\:text-primary-600{--tw-text-opacity:1;color:rgba(var(--color-primary-600),var(--tw-text-opacity))}.group:hover .group-hover\:underline{text-decoration-line:underline}.group:hover .group-hover\:decoration-primary-500{text-decoration-color:rgba(var(--color-primary-500),1)}.group:hover .group-hover\:opacity-100{opacity:1}.data-\[twe-carousel-fade\]\:z-0[data-twe-carousel-fade]{z-index:0}.data-\[twe-carousel-fade\]\:z-\[1\][data-twe-carousel-fade]{z-index:1}.data-\[popper-reference-hidden\]\:hidden[data-popper-reference-hidden]{display:none}.data-\[twe-carousel-fade\]\:opacity-0[data-twe-carousel-fade]{opacity:0}.data-\[twe-carousel-fade\]\:opacity-100[data-twe-carousel-fade]{opacity:1}.data-\[twe-carousel-fade\]\:duration-\[600ms\][data-twe-carousel-fade]{transition-duration:600ms}.group[data-twe-input-focused] .group-data-\[twe-input-focused\]\:border-x-0{border-left-width:0;border-right-width:0}.group[data-twe-input-state-active] .group-data-\[twe-input-state-active\]\:border-x-0{border-left-width:0;border-right-width:0}.group[data-twe-input-focused] .group-data-\[twe-input-focused\]\:border-e-0{border-inline-end-width:0}.group[data-twe-input-focused] .group-data-\[twe-input-focused\]\:border-s-0{border-inline-start-width:0}.group[data-twe-input-focused] .group-data-\[twe-input-focused\]\:border-t{border-top-width:1px}.group[data-twe-input-state-active] .group-data-\[twe-input-state-active\]\:border-e-0{border-inline-end-width:0}.group[data-twe-input-state-active] .group-data-\[twe-input-state-active\]\:border-s-0{border-inline-start-width:0}.group[data-twe-input-state-active] .group-data-\[twe-input-state-active\]\:border-t{border-top-width:1px}.group[data-twe-input-focused] .group-data-\[twe-input-focused\]\:border-solid{border-style:solid}.group[data-twe-input-state-active] .group-data-\[twe-input-state-active\]\:border-solid{border-style:solid}.group[data-twe-input-focused] .group-data-\[twe-input-focused\]\:border-t-transparent{border-top-color:transparent}.group[data-twe-input-state-active] .group-data-\[twe-input-state-active\]\:border-t-transparent{border-top-color:transparent}.hover\:border-transparent:hover{border-color:transparent}.hover\:\!bg-primary-500:hover{--tw-bg-opacity:1 !important;background-color:rgba(var(--color-primary-500),var(--tw-bg-opacity))!important}.hover\:bg-primary-100:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100),var(--tw-bg-opacity))}.hover\:bg-primary-500:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500),var(--tw-bg-opacity))}.hover\:bg-primary-600:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-600),var(--tw-bg-opacity))}.hover\:text-neutral:hover{--tw-text-opacity:1;color:rgba(var(--color-neutral),var(--tw-text-opacity))}.hover\:text-primary-400:hover{--tw-text-opacity:1;color:rgba(var(--color-primary-400),var(--tw-text-opacity))}.hover\:text-primary-500:hover{--tw-text-opacity:1;color:rgba(var(--color-primary-500),var(--tw-text-opacity))}.hover\:text-primary-600:hover{--tw-text-opacity:1;color:rgba(var(--color-primary-600),var(--tw-text-opacity))}.hover\:text-primary-700:hover{--tw-text-opacity:1;color:rgba(var(--color-primary-700),var(--tw-text-opacity))}.hover\:underline:hover{text-decoration-line:underline}.hover\:no-underline:hover{text-decoration-line:none}.hover\:decoration-primary-400:hover{text-decoration-color:rgba(var(--color-primary-400),1)}.hover\:decoration-2:hover{text-decoration-thickness:2px}.hover\:underline-offset-2:hover{text-underline-offset:2px}.hover\:opacity-90:hover{opacity:.9}.hover\:outline-none:hover{outline:2px solid transparent;outline-offset:2px}.focus\:translate-y-0:focus{--tw-translate-y:0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.focus\:bg-primary-100:focus{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100),var(--tw-bg-opacity))}.focus\:no-underline:focus{text-decoration-line:none}.focus\:opacity-90:focus{opacity:.9}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:outline-dotted:focus{outline-style:dotted}.focus\:outline-2:focus{outline-width:2px}.focus\:outline-transparent:focus{outline-color:transparent}@media(prefers-reduced-motion:reduce){.motion-reduce\:transition-none{transition-property:none}}.dark\:flex:is(.dark *){display:flex}.dark\:hidden:is(.dark *){display:none}.dark\:border-neutral-400:is(.dark *){--tw-border-opacity:1;border-color:rgba(var(--color-neutral-400),var(--tw-border-opacity))}.dark\:border-neutral-600:is(.dark *){--tw-border-opacity:1;border-color:rgba(var(--color-neutral-600),var(--tw-border-opacity))}.dark\:border-neutral-700:is(.dark *){--tw-border-opacity:1;border-color:rgba(var(--color-neutral-700),var(--tw-border-opacity))}.dark\:border-primary-300:is(.dark *){--tw-border-opacity:1;border-color:rgba(var(--color-primary-300),var(--tw-border-opacity))}.dark\:border-primary-600:is(.dark *){--tw-border-opacity:1;border-color:rgba(var(--color-primary-600),var(--tw-border-opacity))}.dark\:bg-neutral-400:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-neutral-400),var(--tw-bg-opacity))}.dark\:bg-neutral-600:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-neutral-600),var(--tw-bg-opacity))}.dark\:bg-neutral-700:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-neutral-700),var(--tw-bg-opacity))}.dark\:bg-neutral-800:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-neutral-800),var(--tw-bg-opacity))}.dark\:bg-neutral-800\/50:is(.dark *){background-color:rgba(var(--color-neutral-800),.5)}.dark\:bg-neutral-900\/50:is(.dark *){background-color:rgba(var(--color-neutral-900),.5)}.dark\:bg-primary-300:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-primary-300),var(--tw-bg-opacity))}.dark\:bg-primary-400:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-primary-400),var(--tw-bg-opacity))}.dark\:bg-primary-800:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-primary-800),var(--tw-bg-opacity))}.dark\:bg-primary-900:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-primary-900),var(--tw-bg-opacity))}.dark\:from-neutral-800:is(.dark *){--tw-gradient-from:rgba(var(--color-neutral-800), 1) var(--tw-gradient-from-position);--tw-gradient-to:rgba(var(--color-neutral-800), 0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:from-primary-600:is(.dark *){--tw-gradient-from:rgba(var(--color-primary-600), 1) var(--tw-gradient-from-position);--tw-gradient-to:rgba(var(--color-primary-600), 0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:to-neutral-800:is(.dark *){--tw-gradient-to:rgba(var(--color-neutral-800), 1) var(--tw-gradient-to-position)}.dark\:to-secondary-800:is(.dark *){--tw-gradient-to:rgba(var(--color-secondary-800), 1) var(--tw-gradient-to-position)}.dark\:text-neutral:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral),var(--tw-text-opacity))}.dark\:text-neutral-100:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-100),var(--tw-text-opacity))}.dark\:text-neutral-200:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-200),var(--tw-text-opacity))}.dark\:text-neutral-300:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-300),var(--tw-text-opacity))}.dark\:text-neutral-400:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-400),var(--tw-text-opacity))}.dark\:text-neutral-500:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-500),var(--tw-text-opacity))}.dark\:text-neutral-700:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-700),var(--tw-text-opacity))}.dark\:text-neutral-800:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-800),var(--tw-text-opacity))}.dark\:text-primary-200:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-primary-200),var(--tw-text-opacity))}.dark\:text-primary-400:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-primary-400),var(--tw-text-opacity))}.dark\:opacity-60:is(.dark *){opacity:.6}.dark\:scrollbar-track-neutral-800:is(.dark *){--scrollbar-track:rgba(var(--color-neutral-800), 1) !important}.dark\:scrollbar-thumb-neutral-600:is(.dark *){--scrollbar-thumb:rgba(var(--color-neutral-600), 1) !important}.group:hover .dark\:group-hover\:text-neutral-700:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-700),var(--tw-text-opacity))}.group:hover .dark\:group-hover\:text-primary-400:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-primary-400),var(--tw-text-opacity))}.dark\:hover\:\!bg-primary-700:hover:is(.dark *){--tw-bg-opacity:1 !important;background-color:rgba(var(--color-primary-700),var(--tw-bg-opacity))!important}.dark\:hover\:bg-primary-400:hover:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-primary-400),var(--tw-bg-opacity))}.dark\:hover\:bg-primary-900:hover:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-primary-900),var(--tw-bg-opacity))}.dark\:hover\:text-neutral-800:hover:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-neutral-800),var(--tw-text-opacity))}.dark\:hover\:text-primary-400:hover:is(.dark *){--tw-text-opacity:1;color:rgba(var(--color-primary-400),var(--tw-text-opacity))}.dark\:focus\:bg-primary-900:focus:is(.dark *){--tw-bg-opacity:1;background-color:rgba(var(--color-primary-900),var(--tw-bg-opacity))}@media(min-width:640px){.sm\:mb-0{margin-bottom:0}.sm\:mt-16{margin-top:4rem}.sm\:w-1\/2{width:50%}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:overflow-hidden{overflow:hidden}.sm\:p-6{padding:1.5rem}.sm\:px-14{padding-left:3.5rem;padding-right:3.5rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-24{padding-top:6rem;padding-bottom:6rem}.sm\:text-lg{font-size:1.125rem;line-height:1.75rem}}@media(min-width:853px){.md\:-mr-16{margin-right:-4rem}.md\:ml-12{margin-left:3rem}.md\:mr-7{margin-right:1.75rem}.md\:mt-0{margin-top:0}.md\:flex{display:flex}.md\:hidden{display:none}.md\:h-56{height:14rem}.md\:h-\[200px\]{height:200px}.md\:w-1\/3{width:33.333333%}.md\:w-auto{width:auto}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:justify-start{justify-content:flex-start}.md\:p-\[10vh\]{padding:10vh}.md\:px-24{padding-left:6rem;padding-right:6rem}}@media(min-width:1024px){.lg\:absolute{position:absolute}.lg\:relative{position:relative}.lg\:sticky{position:sticky}.lg\:left-0{left:0}.lg\:top-10{top:2.5rem}.lg\:top-\[140px\]{top:140px}.lg\:order-last{order:9999}.lg\:m-0{margin:0}.lg\:mx-0{margin-left:0;margin-right:0}.lg\:mx-auto{margin-left:auto;margin-right:auto}.lg\:ml-auto{margin-left:auto}.lg\:mt-0{margin-top:0}.lg\:block{display:block}.lg\:grid{display:grid}.lg\:hidden{display:none}.lg\:h-72{height:18rem}.lg\:h-full{height:100%}.lg\:w-1\/4{width:25%}.lg\:w-auto{width:auto}.lg\:max-w-7xl{max-width:80rem}.lg\:max-w-none{max-width:none}.lg\:max-w-xs{max-width:20rem}.lg\:grid-flow-col-dense{grid-auto-flow:column dense}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:gap-24{gap:6rem}.lg\:p-\[12vh\]{padding:12vh}.lg\:px-0{padding-left:0;padding-right:0}.lg\:px-32{padding-left:8rem;padding-right:8rem}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:py-16{padding-top:4rem;padding-bottom:4rem}.lg\:py-32{padding-top:8rem;padding-bottom:8rem}}@media(min-width:1280px){.xl\:w-1\/4{width:25%}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media(min-width:1536px){.\32xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}}.ltr\:-left-6:where([dir=ltr],[dir=ltr] *){left:-1.5rem}.ltr\:right-0:where([dir=ltr],[dir=ltr] *){right:0}.ltr\:-ml-5:where([dir=ltr],[dir=ltr] *){margin-left:-1.25rem}.ltr\:ml-2:where([dir=ltr],[dir=ltr] *){margin-left:.5rem}.ltr\:mr-14:where([dir=ltr],[dir=ltr] *){margin-right:3.5rem}.ltr\:mr-4:where([dir=ltr],[dir=ltr] *){margin-right:1rem}.ltr\:block:where([dir=ltr],[dir=ltr] *){display:block}.ltr\:inline:where([dir=ltr],[dir=ltr] *){display:inline}.ltr\:hidden:where([dir=ltr],[dir=ltr] *){display:none}.ltr\:border-l:where([dir=ltr],[dir=ltr] *){border-left-width:1px}.ltr\:pl-5:where([dir=ltr],[dir=ltr] *){padding-left:1.25rem}.ltr\:pr-2:where([dir=ltr],[dir=ltr] *){padding-right:.5rem}.ltr\:pr-3:where([dir=ltr],[dir=ltr] *){padding-right:.75rem}.ltr\:text-right:where([dir=ltr],[dir=ltr] *){text-align:right}@media(min-width:640px){.ltr\:sm\:mr-7:where([dir=ltr],[dir=ltr] *){margin-right:1.75rem}.ltr\:sm\:last\:mr-0:last-child:where([dir=ltr],[dir=ltr] *){margin-right:0}}@media(min-width:1024px){.ltr\:lg\:pl-8:where([dir=ltr],[dir=ltr] *){padding-left:2rem}}.rtl\:-right-6:where([dir=rtl],[dir=rtl] *){right:-1.5rem}.rtl\:left-0:where([dir=rtl],[dir=rtl] *){left:0}.rtl\:-mr-5:where([dir=rtl],[dir=rtl] *){margin-right:-1.25rem}.rtl\:ml-14:where([dir=rtl],[dir=rtl] *){margin-left:3.5rem}.rtl\:ml-4:where([dir=rtl],[dir=rtl] *){margin-left:1rem}.rtl\:mr-2:where([dir=rtl],[dir=rtl] *){margin-right:.5rem}.rtl\:block:where([dir=rtl],[dir=rtl] *){display:block}.rtl\:inline:where([dir=rtl],[dir=rtl] *){display:inline}.rtl\:hidden:where([dir=rtl],[dir=rtl] *){display:none}.rtl\:border-r:where([dir=rtl],[dir=rtl] *){border-right-width:1px}.rtl\:pl-2:where([dir=rtl],[dir=rtl] *){padding-left:.5rem}.rtl\:pl-3:where([dir=rtl],[dir=rtl] *){padding-left:.75rem}.rtl\:pr-5:where([dir=rtl],[dir=rtl] *){padding-right:1.25rem}.rtl\:text-left:where([dir=rtl],[dir=rtl] *){text-align:left}@media(min-width:640px){.rtl\:sm\:ml-7:where([dir=rtl],[dir=rtl] *){margin-left:1.75rem}.rtl\:sm\:last\:ml-0:last-child:where([dir=rtl],[dir=rtl] *){margin-left:0}}@media(min-width:1024px){.rtl\:lg\:pr-8:where([dir=rtl],[dir=rtl] *){padding-right:2rem}}@media print{.print\:hidden{display:none}}.max-w-prose{max-width:240ch}.panzoom-popup{position:fixed;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,.8);display:flex;justify-content:center;align-items:center;z-index:9999;cursor:zoom-out;overflow:hidden}.panzoom-popup img{max-width:100%;max-height:100%;cursor:grab;vertical-align:middle;margin-left:auto;margin-right:auto}.panzoom-popup .panzoom-overlay{position:relative;width:100%;height:100%}.panzoom-container{cursor:zoom-in;display:inline-block;max-width:fit-content;max-height:fit-content;margin:0 auto;overflow:hidden}.panzoom-container img{display:block;max-width:100%;height:auto}.gallery{width:auto;max-width:100%;margin-bottom:8px}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);text-decoration:underline;font-weight:500;text-decoration-color:rgba(var(--color-secondary-700),1);text-decoration-thickness:1px;text-decoration-style:wavy}.prose nav a{color:var(--tw-prose-links);text-decoration:none;font-weight:500;text-decoration-color:rgba(var(--color-primary-300),1)}.dark\:prose-invert:is(.dark *) :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-color:rgba(var(--color-secondary-700),1)}.prose{--tw-prose-body:rgba(var(--color-neutral-700), 1);--tw-prose-headings:rgba(var(--color-neutral-800), 1);--tw-prose-lead:rgba(var(--color-neutral-500), 1);--tw-prose-links:rgba(var(--color-secondary-600), 1);--tw-prose-bold:rgba(var(--color-neutral-900), 1);--tw-prose-counters:rgba(var(--color-neutral-800), 1);--tw-prose-bullets:rgba(var(--color-neutral-500), 1);--tw-prose-hr:rgba(var(--color-neutral-200), 1);--tw-prose-quotes:rgba(var(--color-neutral-700), 1);--tw-prose-quote-borders:rgba(var(--color-primary-200), 1);--tw-prose-captions:rgba(var(--color-neutral-500), 1);--tw-prose-kbd:#111827;--tw-prose-kbd-shadows:17 24 39;--tw-prose-code:rgba(var(--color-secondary-700), 1);--tw-prose-pre-code:rgba(var(--color-neutral-700), 1);--tw-prose-pre-bg:rgba(var(--color-neutral-50), 1);--tw-prose-th-borders:rgba(var(--color-neutral-500), 1);--tw-prose-td-borders:rgba(var(--color-neutral-300), 1);--tw-prose-invert-body:rgba(var(--color-neutral-300), 1);--tw-prose-invert-headings:rgba(var(--color-secondary-600), 1);--tw-prose-invert-lead:rgba(var(--color-neutral-500), 1);--tw-prose-invert-links:rgba(var(--color-secondary-600), 1);--tw-prose-invert-bold:rgba(var(--color-neutral), 1);--tw-prose-invert-counters:rgba(var(--color-neutral-400), 1);--tw-prose-invert-bullets:rgba(var(--color-neutral-600), 1);--tw-prose-invert-hr:rgba(var(--color-neutral-500), 1);--tw-prose-invert-quotes:rgba(var(--color-neutral-200), 1);--tw-prose-invert-quote-borders:rgba(var(--color-primary-900), 1);--tw-prose-invert-captions:rgba(var(--color-neutral-400), 1);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:255 255 255;--tw-prose-invert-code:rgba(var(--color-secondary-400), 1);--tw-prose-invert-pre-code:rgba(var(--color-neutral-200), 1);--tw-prose-invert-pre-bg:rgba(var(--color-neutral-700), 1);--tw-prose-invert-th-borders:rgba(var(--color-neutral-500), 1);--tw-prose-invert-td-borders:rgba(var(--color-neutral-700), 1);font-size:1rem;line-height:1.75}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.article-content{background-color:rgba(var(--color-primary-900),.5);border-width:2px;border-style:dashed;border-radius:2px;border-color:rgba(var(--color-secondary-600),1);padding-right:8px;padding-left:8px;padding-bottom:8px;border-top-color:transparent}#single_header{flex-grow:1;background-color:rgba(var(--color-primary-900),.5);border-width:2px;border-style:dashed;border-radius:2px;border-color:rgba(var(--color-secondary-600),1);padding-right:8px;padding-left:8px;padding-top:8px;border-bottom-color:transparent}.prose .chroma:is(.dark *){background-color:rgba(var(--color-primary-900),.8);--tw-text-opacity:1;color:rgba(var(--color-neutral-200),var(--tw-text-opacity))}.dark\:prose-invert:is(.dark *) :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:.5em;margin-bottom:.2em;line-height:1.3333333}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:.5em;margin-bottom:.2em;line-height:1.6}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:.5em;margin-bottom:.2em;line-height:1.5}.cool-title{color:rgba(var(--color-primary-700),1);background-color:rgba(var(--color-secondary-600),1);padding:4px}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:.5em;margin-bottom:.5em}.min-w-content{min-width:fit-content}.vari-flex{display:flex;flex-wrap:nowrap}@media(max-width:512px){.vari-flex{flex-wrap:wrap}}.card-styled{background-color:rgba(var(--color-primary-900),.5);border-width:2px;border-style:dashed;border-radius:2px;border-color:rgba(var(--color-secondary-600),1);padding-top:8px;padding-right:8px;padding-left:8px}.caption{background-color:rgba(var(--color-primary-900),.5);border-width:1px;border-style:hidden;border-radius:8px;border-color:rgba(var(--color-secondary-600),1);padding:4px;padding-left:8px;padding-right:8px;max-width:fit-content;font-style:italic;margin:auto;text-align:center}
\ No newline at end of file
diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png
new file mode 100644
index 0000000..4ca348e
Binary files /dev/null and b/public/favicon-16x16.png differ
diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png
new file mode 100644
index 0000000..86c30a5
Binary files /dev/null and b/public/favicon-32x32.png differ
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..9455fe3
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/img/background.webp b/public/img/background.webp
new file mode 100644
index 0000000..0628716
Binary files /dev/null and b/public/img/background.webp differ
diff --git a/public/img/blowfish_logo_hu13719681768044762498.webp b/public/img/blowfish_logo_hu13719681768044762498.webp
new file mode 100644
index 0000000..cef6cbf
Binary files /dev/null and b/public/img/blowfish_logo_hu13719681768044762498.webp differ
diff --git a/public/img/blowfish_logo_hu536110971430689468.webp b/public/img/blowfish_logo_hu536110971430689468.webp
new file mode 100644
index 0000000..b6763b2
Binary files /dev/null and b/public/img/blowfish_logo_hu536110971430689468.webp differ
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..ab53b88
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,18 @@
+
N.E.E.T. Works
+
beep-boop maggot!
\ No newline at end of file
diff --git a/public/index.json b/public/index.json
new file mode 100644
index 0000000..34020ad
--- /dev/null
+++ b/public/index.json
@@ -0,0 +1 @@
+[{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/tags/alphacool/","section":"Tags","summary":"","title":"Alphacool","type":"tags"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/tags/aqua-computer/","section":"Tags","summary":"","title":"Aqua Computer","type":"tags"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/tags/arduino/","section":"Tags","summary":"","title":"Arduino","type":"tags"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/categories/diy/","section":"Categories","summary":"","title":"Diy","type":"categories"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/categories/homelab/","section":"Categories","summary":"","title":"Homelab","type":"categories"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/tags/intel/","section":"Tags","summary":"","title":"Intel","type":"tags"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/","section":"N.E.E.T. Works","summary":"","title":"N.E.E.T. Works","type":"page"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/tags/nvidia/","section":"Tags","summary":"","title":"Nvidia","type":"tags"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/categories/servers/","section":"Categories","summary":"","title":"Servers","type":"categories"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/tags/supermicro/","section":"Tags","summary":"","title":"Supermicro","type":"tags"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"January 16 2025","externalUrl":null,"permalink":"/categories/watercooling/","section":"Categories","summary":"","title":"Watercooling","type":"categories"},{"content":" Overview # I\u0026rsquo;ve been watercooling my desktop since 2020, and case modding custom cooling solutions since my first modern dGPU in 2012. I enjoy it for the aesthetic, as well as the ability to run my hardware to the redline, despite the lower gains that modern hardware has\u0026hellip; It\u0026rsquo;s still fun to try and see how high you can get on benchmark scoreboards. It was a big initial investment, but with most parts being reusable, the ongoing cost for component upgrades are minimal. Early in 2024, I bought some GPUs to use for dedicated ML tasks in my server rack, and immediately had watercooling on the mind. There weren\u0026rsquo;t particularly strong reasons to do so, but it would lower the power usage a bit, give me some more VRAM overclocking headroom, and give me a bit more core clock stability, as well as the ability to use a cheap two-slot NVLINK connector without suffocating a GPU.\nMy initial setup with 3x 2080 Tis, using m.2 NVMe to PCIe risers in an ASUS prebuilt. Two are connected by NVLINK, which I found to provide a slight performance benefit on the order of ~1-5% in multi-GPU SISR training, which is not worth the typical price for NVLINK bridges from this era. I was lucky to get this ugly, quadro-oriented bridge for just $40. I\u0026rsquo;ve never had a leak on my desktop, but with wider temperature swings in my garage, and collectively, a whole lot more expensive hardware that might get damaged than compared to my desktop setup, I was hesitant. The benefits seemed minimal, and I considered it a fun what-if scenario until I upgraded my main server and discovered that the forced-air passive chassis cooling was insufficient for my new CPUs. At that point, I had to make a decision: Get better heatsinks, which would be single-purpose and cost in excess of $100 each, or whole rack watercooling. I chose whole rack watercooling.\nWith enough reason for me to go ahead with the project, and the only thing holding me back being a fear of leaks, I had to figure out how to actively monitor for, and preferably prevent such an eventuality. I happened upon a product called LEAKSHIELD, from Aqua Computer, that advertised itself as doing exactly that.\nHow does it work? You pull a vacuum inside the fluid loop and monitor the loss rate. Water can\u0026rsquo;t get out if air is trying to get in, and if air gets in, the vacuum is reduced. It\u0026rsquo;s so simple, I don\u0026rsquo;t know why it took this long for such a product to enter the PC watercooling space. I could have just bought a LEAKSHIELD and called it a day, but Aqua Computer\u0026rsquo;s software doesn\u0026rsquo;t support Linux, and the specs for the vacuum pump seemed a bit weak for a loop of my scale. But, its functionality was something I was confident I could emulate with more robust off-the-shelf parts. Thus, sufficiently armed with esoteric plumbing knowledge, I took the plunge and started loading up on parts.\nThe Hardware # Most of the build uses pretty standard off-the-shelf parts for PC watercooling, but there are a few bits and pieces that most builders won\u0026rsquo;t have seen before, and a custom control system that offers a more relevant experience for a server rack. The control system is based on an Arduino Uno that feeds vital statistics over serial, and features pressure control and monitoring similar to the LEAKSHIELD, with fan control based on a PID algorithm keeping the water temperature at a fixed setpoint above ambient.\nOff-the-shelf # General Details # The centerpiece of the build, which the control unit and pump mount to, is the \u0026ldquo;MOther of all RAdiators\u0026rdquo;, version 3, from Watercool. This is the 360mm version with support for up to 18x 120mm fans, or 8x 180mm fans. It\u0026rsquo;s constructed more in the spirit of a vehicle radiator than a traditional PC radiator, with a less restrictive fin stack and large, round tubes rather than thin rectangular ones. It provides several mounting points for accessories which I was able to utilize to secure it to my server rack in a satisfactorily sturdy fashion. An in-depth teardown on the construction method and material quality of the MO-RA can be found on igor\u0026rsquo;sLAB. For fans, I have a collection of old DC-control Corsair Air Series SP120s. They\u0026rsquo;ve all been retired from regular use, because of noise-related aging issues. In fact, one of them failed to turn at all once I had everything wired up, and another had its bearing disintegrate about 8 weeks after putting the thing into service. That being said, they did survive (and continue to survive, in the remaining 16 cases) 24/7 use for anywhere from 4-10 years, at bottom of the barrel pricing, so that\u0026rsquo;s not too bad. I\u0026rsquo;m not exactly pushing the limits of this radiator here, so a few fans breaking down over time isn\u0026rsquo;t the end of the world.\nA MO-RA V3 360 PRO PC Watercooling Radiator from Watercool I got a secondhand Corsair XD5 pump/res combo from eBay for about sixty bucks, which is pretty good for a genuine D5-based pump/res combo. It has PWM support which I did wire up, but the flow ended up being rather anemic even at 100%, so I just run it full speed all the time. The flow rate is measured through an Aqua Computer flow sensor, which is simply a hall-effect tachometer translated to l/h through software. I did not attempt to verify the accuracy of the sensor in my setup. The absolute accuracy is less relevant than simply getting an overall idea of whether or not the measurement is consistent with flow behavior, which it is.\nSimple, cheap aluminum bars and angles mount to the studs on the radiator and into the stud holes on the server rack, and the pump and control box mount onto brackets along with the fans. CPUs # My thermally problematic server upgrade was to dual Xeon Gold 6154s, which are Skylake-SP architecture. This specific SKU is pretty beefy, with 18 cores at sustained all-core speeds of 3.7GHz SSE / 3.3GHz AVX2 / 2.7GHz AVX512, and a TDP of 200 watts. The rated tjmax was 105C, and with the chassis cooling, they readily met that and started throttling under all-core loads, with idle as high as 60-70*C. I previously had Xeon E5-2697 v2s, which had TDPs of 130w. They got toasty, but never throttled. I\u0026rsquo;m not sure if the chassis had any easy fan upgrades available that might have made a difference, and I certainly could have moved to 4u-compatible tower coolers rather than forced air, but since I wanted to watercool the GPUs anyway, adding the CPUs as well would be minimal cost/effort, with more future compatibility for the waterblocks compared to a specialized LGA3647 tower cooler.\nAlphacool Eisblock XPX Pro coldplate Image credit \u0026amp; copyright - igor\u0026rsquo;sLAB The CPU waterblocks are Alphacool Eisblock XPX Pro Aurora Light models, which are significantly cheaper than the XPX Aurora Pro not-light version. They appear to be entirely identical, functionally\u0026hellip; I\u0026rsquo;m not sure if there any actual performance benefits offered by the not-light version. It\u0026rsquo;s a relatively obscure block family without many thorough reviews, which makes sense, given this block is designed for full coverage on Xeons/Threadrippers. The coldplate appears to be skived, which is uncommon in this price bracket for a discrete block, and the fins are incredibly short and dense. In smaller desktop loops, I\u0026rsquo;ve seen this block criticized for having overly restrictive flow, but when you have four blocks + quick disconnects, \u0026ldquo;good\u0026rdquo; flow is relative. At the power limit of 200w, the maximum core temperature delta relative to the water temperature is 25*C, with a ~1-2*C average delta between the two serially-connected sockets at a flow rate of ~130L/h, and that\u0026rsquo;s more than sufficient.\nInterior view of the Supermicro CSE-846 chassis showcasing the installed waterblocks and other components. GPUs # The GPU blocks are Phanteks 2080 Ti Founder\u0026rsquo;s Edition blocks. Nothing special, they\u0026rsquo;re just the cheapest matching ones I could find in 2024 that looked like they\u0026rsquo;d fit these almost-reference-but-not-quite OEM cards. They\u0026rsquo;re generic OEM models that would have gone in prebuilts. The most interesting thing about these cards, is that they\u0026rsquo;ve been modded to have 22GB of VRAM. There\u0026rsquo;s a dedicated supplier still offering them, and it\u0026rsquo;s by far the best $/GB value for VRAM in modern NVIDIA GPUs.1 Whether or not this is a better value overall than, say, a 3090 (Ti) depends on your usecase. Performance improvements in ML tasks between the 2080 Ti and 3090 (Ti) range from as little as ~20% to as much as ~100% depending on how memory bandwidth constrained your workload is. With secondhand 3090 (Ti)s still going for minimum $700 on the used market in the US, I found the alternative 2080 Ti option to be more alluring for my usecase, which is primarily single image super-resolution. More VRAM is desirable to increase the size of tiles for inference, and to increase the batch size during training. Training speed scales almost linearly, and inference speed scales linearly, per GPU. So, for my usecase, where I\u0026rsquo;m not really limited by the performance of a single GPU, the 2080 Ti mod route offers better overall value both for VRAM and combined core performance compared to 3090 (Ti)s. The idea of having a modded GPU in itself was also appealing and definitely part of why I made that decision. Pulling up a hardware monitor and seeing a 2080 Ti with 22GB of VRAM feels a little bit naughty, and I like that.\nThe blocks installed in an ASUS prebuilt gaming tower. I did initially buy three of them, as pictured at the beginning of this post, but one of them failed just after the 30 day warranty period listed on their website. Despite that, they were kind enough to offer a full refund if I covered return shipping, and were very communicative and responded in \u0026lt;24 hours every time I sent them any kind of message/inquiry.\nThe biggest benefit that watercooling theoretically brings to modern video cards is a prolonged lifespan. Not due to lower core temperatures,2 in an absolute sense, but due to the reduced stress from thermal cycles. Mismatches in the rate of thermal expansion between the die and the substrate will eventually cause their bond to break, and this happens faster the larger your die is, and the more extreme the temperature differences are. Today\u0026rsquo;s GPU dies are huge, and it\u0026rsquo;s hard to say how many failures are attributable to this factor alone, but it is certain to be more of a risk than it has been in the past. I\u0026rsquo;d rather buy a used mining GPU than a used gaming GPU any day, because it has likely been kept at roughly the same temperature for most of its life, as opposed to experiencing wide periodic swings.\nThe GPU blocks required a moderate amount of light massaging to properly fit on these OEM model cards. The power plugs are in a different position and a singular capacitor on these models is slightly taller than on the actual Founder\u0026rsquo;s Edition reference card, but they\u0026rsquo;re otherwise close enough to identical. That\u0026rsquo;s not to say that there are no benefits from lowering the operating temperature. As an absolute value, within manufacturer limits, it affects boost clocks, and leakage current. A cooler chip will use less power to run at the same clock speed compared to a hotter chip due to reduced leakage current, making them measurably more energy efficient per clock cycle the colder they run. In my case, with the fan on max, while not thermal throttling, these GPUs would bounce off the power limit of 280w while attempting to hit a core clock of 1800MHz. Under water, at a reported core temperature of ~30*C, the reported board power draw is only ~220w at 1800MHz3 core clock for the same workload. The type of fan typically found in these coolers is rated anywhere from 15-30w on its own, so a reduction of at least 30w can likely be attributed to a lower leakage current.\nDIY Time # In no particular order, here is a list of the major components involved in the control system.\nGeneric metal box, formerly from a PBX system. Arduino Uno clone, unknown brand 60mm Corsair fan RS232 TTL shifter Aesthetic retro power switch 12v DC vacuum pump U.S. Solid 12V NC Solenoid 12v relay modules HX711 ADC MD-PS002 Absolute Pressure Sensors L298-like PWM motor driver Apple White iMac PSU Adafruit Arduino Uno Proto Shield DS18B20 temperature probes Fit check for all the major components. I didn\u0026rsquo;t take excruciatingly detailed pictures of every single step of the assembly/prototyping process. For the most part, I was just plugging pre-made components together. The most interesting production notes include the pressure sensor and the power supply.\nPutting New Life into an iMac PSU # The power supply I used is from a first-gen Intel White iMac, which is visually very similar to the G5. It was one of the earliest things that I installed Linux on, and I used it as a seedbox for a bit, but eventually took it apart and saved some of the more interesting stuff.\nAll the credit goes to the user ersterhernd, from this thread on the tonymacx86.com forum for figuring out the pinout of this PSU, which is almost entirely identical to the one that was in my unit, apart from the power rating on mine being 200w. There are two banks of pins, half of which are always on, half of which are toggleable. Each bank has 12v, 5v, and 3.3v. I didn\u0026rsquo;t end up using 3.3v for anything other than the power switch. I have no idea what the energy efficiency of this unit is, obviously it doesn\u0026rsquo;t have an 80+ certification\u0026hellip; But I\u0026rsquo;m assuming that Apple would make it at least halfway decent. Hopefully more efficient than a random 12v power brick with additional converters, I\u0026rsquo;d hope.\nMy schematic for the control unit. It was the first time I\u0026rsquo;ve ever used KiCad, and the first time I\u0026rsquo;ve ever made a schematic like this at all. I hope it\u0026rsquo;s relatively legible. As you can see in the schematic above, the always-on 3.3v pin is connected to SYS_POWERUP through a relay board. The relay input is pulled low by a single pole switch, which turns the relay on, which connects ground to SYS_POWERUP, engaging the other rail of the power supply. This is kind of a convoluted solution to not having a double-pole switch\u0026hellip; But I didn\u0026rsquo;t have a double-pole switch, so that\u0026rsquo;s what I did.\nMeasuring vacuum # The leak-resisting aspect all hinges on monitoring the pressure of the loop\u0026hellip; Or potentially running a vacuum pump constantly, but that\u0026rsquo;s stupid. For some reason, I had a really hard time finding a vacuum pressur sensor. There are plenty of physical, analogue vacuum gauges available, but as far as an electronic sensor\u0026hellip; I just couldn\u0026rsquo;t find any located in the US, at a reasonable price. There were a few hobbyist grade differential sensors, but I wanted to be able to measure down to an almost complete vacuum, and they didn\u0026rsquo;t have the range. Maybe I had the wrong search terms, but I just wasn\u0026rsquo;t finding anything. Eventually I found an unpackaged sensor with obscure, not entirely legible datasheets that claimed to have an acceptable pressure range for my application. The MD-PS002 is what I settled on, available on Amazon in the US in a 2-pack for $8. It\u0026rsquo;s a tiny little thing, and it took two attempts to successfully create a sensor package that didn\u0026rsquo;t leak.\nSensor package details, installed and all gooped up. I drilled a hole in a G1/4\u0026quot; plug, just slightly bigger than the metal ring on the sensor, coated that ring with J-B Weld, and inserted it, letting it cure before grinding away the exterior of the top of the plug and building up more J-B weld to add some strain relief for the wires as well as edge-to-edge sealing. The current vacuum loss rate, after running the system for a few months, allowing the loop to very thoroughly de-gas, is now less than 50mbar per day at -500 to -600mbar. I was slightly worried about the lifetime of the pump, given it\u0026rsquo;s a cheap thing from Amazon, but given it only has to run for about a second every 2-3 days, I imagine that won\u0026rsquo;t be an issue.\nHere\u0026rsquo;s a quick video showing the system not leaking!\nThis pressure sensor is a wheatstone bridge, which works the same way as load cells for digital scales. The resistance changes are very, very low, thus the signal must be amplified before being fed into an ADC. You could use an op-amp, and feed that signal into an analog input on the Arduino, but I felt more comfortable using the HX711, a two-channel ADC with integrated amplifier designed to be used with wheatstone bridge load cells. Here\u0026rsquo;s a code snippet showing how I converted the raw analog measurement to mbar.\nfloat pressure_raw_to_mbar(int32_t pressure_raw) { return (pressure_raw - 390000) * (1700.0 / (5600000 - 390000)) - 700; } I calibrated it manually, comparing it to an analogue gauge. It\u0026rsquo;s calibrated to a zero point at atmospheric pressure in my locale, and from -700mbar to +1000mbar. I figured out that, when setting the HX711 to a gain of 64 with the Adafruit HX711 library, a change of 100mbar is a change in the ADC measurement by 30k, highly consistent across the entire pressure range that I tested. I can\u0026rsquo;t be 100% sure how accurate the analogue gauge is, but 100% accuracy doesn\u0026rsquo;t really matter for this application. All I really need to know is the fact that an adequate vacuum is present, and a general idea of the leak rate, which is a requirement that this setup meets.\nOther stuff # I got a beefy PWM motor driver with L298 logic, claiming a continuous current of 7 amps per channel, which nicely fit my requirements. 120mm PC fans are typically 0.2-0.3 amps, and mine in particular are 0.25. For 18 fans, it should be approximately 4.5 amps at 100% speed. It\u0026rsquo;s a bit oversized, and I\u0026rsquo;m only using one channel, but it leaves me the option in the future to use larger, generic radiator fans that have more demanding power requirements. I\u0026rsquo;m already down two from eighteen, eventually enough of them are going to fail that I\u0026rsquo;ll have to find another solution.\nRequired additions to the solenoid, pump motor, and the complete assembly without cover. In my initial tests, I found that operating the pump and solenoid would cause the Arduino to reset, seemingly at random, or cause other undefined behavior. Since they were not electrically isolated on a second power supply, that makes sense. They were backfeeding energy and causing a notable amount of general interference during operation, to the point that the LEDs on the inactive relay modules would dimly illuminate when the motor was in operation, and very visibly illuminate whenever the motor or the solenoid deactivated. I had to add flyback diodes, and, for peace of mind, I added ceramic filtering capacitors to the pump as well. Those additions completely eliminated the issue. Below is a video demonstrating the bad behavior.\nI did a similar plug-drilling setup for the water temperature sensor with a generic Dallas temperature probe. The air probe was taped to the exterior of the box, in the path of the incoming air. All that remained was to solder up a sort of bus bar for the radiator fan connectors, get the temperature probes and pull-up resistors wired into the proto board, and hook everything up to the Arduino, then write the software to tie it all together.\nThe Software # rawhide_k/server-watercooling-controller C\u0026#43;\u0026#43; 0 0 The Arduino operates independently, without a server. The fan speed and loop pressure are managed autonomously. The serial connection is only used to report vital stats, for later integration into more connected monitoring systems. Ultimately, there are only two actions it can take: Change the fan speed, and turn on the vacuum pump. Neither of these require any external knowledge. It doesn\u0026rsquo;t need any information about the connected hardware to function correctly. All it\u0026rsquo;s concerned with is keeping the water temperature at a certain delta above ambient temperature, and keeping the loop pressure within a certain range. Ultimately, very simple.\nOnce per second, the temperature sensors are sampled, the PID loop for the fans runs with the new temperature data points, and the fan speed, temperature data, vacuum pressure, and pump/flow measurements are sent over serial with the help of the ArduinoJSON library. I settled on a target water delta of 4*C relative to ambient, with a chosen min/max temperature range where the fans turn off or pin themselves to 100% completely. The 4*C delta is rather arbitrary. It\u0026rsquo;s approximately the delta that exists when the systems are on, but idle, and the fans are at their minimum speed. That delta can be maintained during 100% CPU load, and during medium-heavy GPU loads, but not both combined. It still stays well under a 10*C delta in that case, though, so I can\u0026rsquo;t complain.\nThere are also hard stops to turn the fans off if the water temperature hits 5*C, and pin them to max if it hits 40*C. I\u0026rsquo;m not sure how realistic either of those figures are, but it\u0026rsquo;s better to be safe than frozen up and/or exploded.\nint fan_PID(float* air_temp, float* water_temp, uint32_t* cur_loop_timestamp) { static const float kp = 120.0; static const float ki = 0.16; static const float kd = 4.0; static float integral = 0; static float derivative = 0; static float last_error = 0; static float error; static float delta; static float last_time = *cur_loop_timestamp; static const float min_water_temp = 5.0; static const float max_water_temp = 40.0; static const uint8_t min_fan_speed = 90; static const uint8_t max_fan_speed = 255; static const uint8_t temp_target_offset = 4; static const uint8_t fan_offset = 10; static int16_t fan_speed; if (*water_temp \u0026gt;= max_water_temp) { return max_fan_speed; } else if (*water_temp \u0026lt;= min_water_temp) { return 0; } else { error = *water_temp - min(*air_temp + temp_target_offset, max_water_temp); delta = *cur_loop_timestamp - last_time; //mitigate unlimited integral windup if (fan_speed == max_fan_speed) { integral += error * delta; } if (*air_temp + temp_target_offset \u0026gt; *water_temp - 1) { integral = 0; } derivative = (error - last_error) / delta; fan_speed = round(constrain(min_fan_speed + fan_offset + (kp * error + ki * integral + kd * derivative), min_fan_speed, max_fan_speed)); last_error = error; return fan_speed; } } Occasionally, the temperature probes as well as the HX711 return spurious readings that cause poor behavior, such as crashing the Arduino. In particular, the temperature probes will sometimes return -127, which caused my PID algorithm to crash the Arduino for reasons I could not divine.\nFor the temperature probes, I simply ignore the one problematic result that I\u0026rsquo;ve observed.\nnew_water_temp = sensors.getTempC(water_therm); new_air_temp = sensors.getTempC(air_therm); if (new_water_temp != -127) { water_temp = new_water_temp; } if (new_air_temp != -127) { air_temp = new_air_temp; } sensors.requestTemperatures(); In case of any other freezing/crashing issues, I also enabled the watchdog timer for 2 seconds. So, if, for some reason, it does freeze/crash, it should self reset after 2 seconds. It seems to be working, although I guess time will tell in the long-term. I haven\u0026rsquo;t experienced any operation issues since I added it over a month ago. The other concern is undefined behavior when the timer overflows. The Uno only has a 32-bit timer, so it will overflow around 50 days of uptime. This function pre-emptively resets it.\n//we will use this function to periodically self-reset to avoid timer overflows void(* resetFunc) (void) = 0; ... //reset the system when approaching timer overflow if (cur_loop_timestamp \u0026gt;= 4000000000) { resetFunc(); } In addition to the temperature probe problem, the HX711 occasionally returns wildly wrong results that need to be filtered out. To compensate for that, if the pressure dips below the threshold, I wait one second, and if the pressure is still below the threshold, I then begin pumping. This check happens approximately ten times per second, as the default behavior of the HX711 board that I have is to run in 10hz mode. I\u0026rsquo;m not sure if the issue springs from some kind of interference with the tachometer interrupts messing up the signaling timing, or if I\u0026rsquo;m misunderstanding the correct way to sample the HX711 over time.\nif (cur_loop_timestamp - last_pressure_check \u0026gt;= 100) { loop_pressure = pressure_raw_to_mbar(hx711.readChannelRaw(CHAN_A_GAIN_64)); if (sucking == false) { if (loop_pressure \u0026gt; low_pressure_threshold) { if (checking_low_pressure == false) { checking_low_pressure = true; low_pressure_confirmation_timestamp = cur_loop_timestamp; } if (cur_loop_timestamp - low_pressure_confirmation_timestamp \u0026gt;= 1000) { digitalWrite(pump_relay, HIGH); digitalWrite(solenoid_relay, HIGH); sucking = true; checking_low_pressure = false; } } else if (cur_loop_timestamp - low_pressure_confirmation_timestamp \u0026gt;= 1000) { checking_low_pressure = false; } } else { if (loop_pressure \u0026lt; high_pressure_threshold) { digitalWrite(pump_relay, LOW); digitalWrite(solenoid_relay, LOW); sucking = false; } } last_pressure_check = cur_loop_timestamp; } Currently, my server-side software is incomplete. It\u0026rsquo;s just a brute-force JSON-over-serial reader written in Python, that I glance at from time to time. I plan write a Zabbix bridge, and have that manage the monitoring, alerts, and reactions to catostraphic events, once I have Zabbix properly setup for my systems\u0026hellip; But that hasn\u0026rsquo;t happened just yet. I don\u0026rsquo;t expect it to be a particularly interesting event, but if anything comes up I might write a post about it.\nOther Thoughts? # The Arduino\u0026rsquo;s software hadn\u0026rsquo;t been 100% finalized when I took the below pictures. The control box does have a lid now, and all the cable management is a lot cleaner\u0026hellip; Promise!\nEverything installed and working! When I was testing it, I had an incident where the Arduino crashed, which means the fans stopped\u0026hellip; That\u0026rsquo;s a big drawback with the motor controller that I have, it fails off instead of on. But, I haven\u0026rsquo;t experienced any more issues after adding those software fixes. At that time, I was running a full GPU workload\u0026hellip; The water temperature exceeded 70*C. It happened at night, and I have no idea how long it ran like that\u0026hellip; Hours. Pretty scary stuff, but it all came out alright.\nThis project had a lot of firsts for me. It was the first time I\u0026rsquo;ve done any kind of embedded-adjacent development beyond \u0026ldquo;ooooo look at the blinky light, oooooooo it turns off when you press the button, wwaaaow\u0026rdquo;, and the first time I\u0026rsquo;d designed something with so many individual parts. I\u0026rsquo;ve never worked with air pumps, solenoids, or pressure sensing before, nor had to debug issues like the lack of flyback diodes.\nThe biggest mistake I made was using that stupid battery box. It\u0026rsquo;s steel, and I don\u0026rsquo;t have the tools or experience to work with steel in the way that I intended to. I thought it would look cool, and it does, but if I did it again, I\u0026rsquo;d use a generic aluminum or plastic project box instead, because it took two entire days plus waiting for new drill bits that can actually cut through it.\nIf I were to ever take it apart again, I\u0026rsquo;d add a passthrough for the SPI header, and/or an external reset button. I should have gotten a physical display of some type that could show the sensors and debug info on the device itself without being connected to another device to readout the data.\nI\u0026rsquo;d like to get a second pump, for redundancy\u0026rsquo;s sake and to increase the flow rate. But it\u0026rsquo;s going to be such a pain to install that I feel like I\u0026rsquo;m never going to bother to do it, unless the current pump fails, or I add more components to be cooled and the flow is adversely affected. I was slightly concerned about the evaporation rate of the liquid via the vacuum tank, and that I\u0026rsquo;d need to add some kind of fluid level detection system, but there\u0026rsquo;s been no noticeable loss thus far. Now that I know the pump turns on so infrequently, I can\u0026rsquo;t imagine that it\u0026rsquo;s going to need to be topped up anytime soon.\nIn terms of value\u0026hellip; This was unbelievably bad. Buying tower coolers would have allowed the CPUs to run without throttling, and buying another GPU would have overpowered any benefits gained by NVLINK. I haven\u0026rsquo;t tallied up exactly how much I spent on it, but it was at least $1000, including buying new tools and excess materials that I haven\u0026rsquo;t fully used, and excluding the original cost of re-using some parts I already had. I\u0026rsquo;ve added risk, maintenance overhead, and pain whenever I swap out hardware in the future. Custom watercooling4 is an ongoing abusive relationship between your fingertips and your ego, or your fascination for slightly more optimized numbers on a screen\u0026hellip; But I\u0026rsquo;d do it again in a heartbeat, because it was fun.\nIn modern, post-Turing cards, that is. Please stop buying mesozoic-era Kepler/Maxwell Quadros and Teslas just because they have VRAM. There\u0026rsquo;s a reason they\u0026rsquo;re going for like, $20, and if you paid more for anything from that era, I\u0026rsquo;m sorry. Electrical costs are a thing, and your life is worth more than waiting for any meaningful, current-year work to happen on those decrepit e-waste cards. I feel even worse for you if you got tricked into buying one of those \u0026ldquo;24GB\u0026rdquo; or \u0026ldquo;16GB\u0026rdquo; cards that are actually 2x12GB and 2x8GB. You can make an argument for Volta, but only if you\u0026rsquo;re doing some deranged pure FP64 stuff. Consumer Turing and newer are faster at everything else! And if you\u0026rsquo;re buying them for HW-accel encode\u0026hellip; The quality is awful compared to any Intel ARC card. Buy one of those instead.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nI don\u0026rsquo;t understand why people don\u0026rsquo;t trust the manufacturer specifications when it comes to silicon temperature limits, beyond unfounded conspiracy nonsense around planned destruction/obselence. In terms of Intel server SKUs, you find that the throttling temp is higher than on consumer SKUs, despite the higher reliability demanded by the enterprise market\u0026hellip; I\u0026rsquo;m assuming that this is due to reduced hotspot variance thanks to generally lower voltage spread from lower boosting clock speeds. On enterprise SKUs which are focused on single threaded performance, the throttling temp is typically lower than those without the ability to boost as high. If you have evidence to the contrary, let me know.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nNVIDIA overclocking on Linux is awful. There\u0026rsquo;s no way to edit the voltage-frequency curve through the Linux drivers. You can only set the offset. So you can\u0026rsquo;t really make use of dynamic boosting if you want to undervolt. I have the max clock speed clamped at 1800MHz with a core offset to emulate undervolting as you would do on Windows, but it\u0026rsquo;s hard to say if I\u0026rsquo;m getting the peak performance that I could be getting at whatever the core voltage is under these circumstances - because NVIDIA\u0026rsquo;s Linux drivers ALSO don\u0026rsquo;t report that. VRAM temperature? Nope. VRM? Nope. Hotspot? Nope. You better hope your card works with NVML, too, because otherwise you\u0026rsquo;re going to have to mess around with X to use nvidia-settings.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nStop calling them open loops. Open loop systems exchange fluid with the environment. Unless you\u0026rsquo;re getting your water out of the sink and flushing it right down the drain, your system is not open loop. It\u0026rsquo;s closed. I don\u0026rsquo;t understand why people call custom loops \u0026ldquo;open\u0026rdquo; and AIOs \u0026ldquo;closed\u0026rdquo; when their modes of operation are identical. It\u0026rsquo;s just plain wrong.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"January 16 2025","externalUrl":null,"permalink":"/posts/watercooling-homelab/","section":"Posts","summary":"","title":"Watercooling My Homelab","type":"posts"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]
\ No newline at end of file
diff --git a/public/index.xml b/public/index.xml
new file mode 100644
index 0000000..75e4695
--- /dev/null
+++ b/public/index.xml
@@ -0,0 +1 @@
+
N.E.E.T. Works https://blog.neet.works/Recent content on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/js/appearance.min.516a16745bea5a9bd011138d254cc0fd3973cd55ce6e15f3dec763e7c7c2c7448f8fe7b54cca811cb821b0c7e12cd161caace1dd794ac3d34d40937cbcc9ee12.js b/public/js/appearance.min.516a16745bea5a9bd011138d254cc0fd3973cd55ce6e15f3dec763e7c7c2c7448f8fe7b54cca811cb821b0c7e12cd161caace1dd794ac3d34d40937cbcc9ee12.js
new file mode 100644
index 0000000..dfe7d81
--- /dev/null
+++ b/public/js/appearance.min.516a16745bea5a9bd011138d254cc0fd3973cd55ce6e15f3dec763e7c7c2c7448f8fe7b54cca811cb821b0c7e12cd161caace1dd794ac3d34d40937cbcc9ee12.js
@@ -0,0 +1 @@
+const sitePreference=document.documentElement.getAttribute("data-default-appearance"),userPreference=localStorage.getItem("appearance");(sitePreference==="dark"&&userPreference===null||userPreference==="dark")&&document.documentElement.classList.add("dark"),document.documentElement.getAttribute("data-auto-appearance")==="true"&&(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches&&userPreference!=="light"&&document.documentElement.classList.add("dark"),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{e.matches?document.documentElement.classList.add("dark"):document.documentElement.classList.remove("dark")})),window.addEventListener("DOMContentLoaded",e=>{const t=document.getElementById("appearance-switcher"),n=document.getElementById("appearance-switcher-mobile");updateMeta(),this.updateLogo?.(getTargetAppearance()),t&&(t.addEventListener("click",()=>{document.documentElement.classList.toggle("dark");var e=getTargetAppearance();localStorage.setItem("appearance",e),updateMeta(),this.updateLogo?.(e)}),t.addEventListener("contextmenu",e=>{e.preventDefault(),localStorage.removeItem("appearance")})),n&&(n.addEventListener("click",()=>{document.documentElement.classList.toggle("dark");var e=getTargetAppearance();localStorage.setItem("appearance",e),updateMeta(),this.updateLogo?.(e)}),n.addEventListener("contextmenu",e=>{e.preventDefault(),localStorage.removeItem("appearance")}))});var updateMeta=()=>{var e=document.querySelector("body"),t=getComputedStyle(e);document.querySelector('meta[name="theme-color"]').setAttribute("content",t.backgroundColor)},getTargetAppearance=()=>document.documentElement.classList.contains("dark")?"dark":"light";window.addEventListener("DOMContentLoaded",e=>{const t=document.getElementById("top-scroller"),n=document.getElementById("site-footer");t&&n&&t.getBoundingClientRect().top>n.getBoundingClientRect().top&&(t.hidden=!0)})
\ No newline at end of file
diff --git a/public/js/main.bundle.min.a2d78d78672e549fbfc972ece871725b5478ba0b65708dda20cb97ab80a865eae6d247e1b05a4aec6ebbf78647ec3233bad8b2609ed98eee53cd58aa17128bc7.js b/public/js/main.bundle.min.a2d78d78672e549fbfc972ece871725b5478ba0b65708dda20cb97ab80a865eae6d247e1b05a4aec6ebbf78647ec3233bad8b2609ed98eee53cd58aa17128bc7.js
new file mode 100644
index 0000000..be670a0
--- /dev/null
+++ b/public/js/main.bundle.min.a2d78d78672e549fbfc972ece871725b5478ba0b65708dda20cb97ab80a865eae6d247e1b05a4aec6ebbf78647ec3233bad8b2609ed98eee53cd58aa17128bc7.js
@@ -0,0 +1,15 @@
+e=this,t=function(){"use strict";function R(e,t){var n,s=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),s.push.apply(s,n)),s}function h(e){for(var t,n=1;n
e.length)&&(t=e.length);for(var n=0,s=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:{},s=n.getFn,i=void 0===s?e.getFn:s,o=n.fieldNormWeight,r=void 0===o?e.fieldNormWeight:o;t(this,a),this.norm=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,e=new Map,t=Math.pow(10,s);return{get:function(s){if(o=s.match(re).length,e.has(o))return e.get(o);var o,a=1/Math.pow(o,.5*n),i=parseFloat(Math.round(a*t)/t);return e.set(o,i),i},clear:function(){e.clear()}}}(r,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return n(a,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=e,this._keysMap={},e.forEach(function(e,n){t._keysMap[e.id]=n})}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,o(this.docs[0])?this.docs.forEach(function(t,n){e._addString(t,n)}):this.docs.forEach(function(t,n){e._addObject(t,n)}),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();o(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},i=o.getFn,r=void 0===i?e.getFn:i,a=o.fieldNormWeight,c=void 0===a?e.fieldNormWeight:a,s=new E({getFn:r,fieldNormWeight:c});return s.setKeys(t.map(H)),s.setSources(n),s.create(),s}function f(t){var s,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},d=n.errors,f=void 0===d?0:d,l=n.currentLocation,u=void 0===l?0:l,a=n.expectedLocation,h=void 0===a?0:a,r=n.distance,c=void 0===r?e.distance:r,i=n.ignoreLocation,m=void 0===i?e.ignoreLocation:i,o=f/t.length;return m?o:(s=Math.abs(h-u),c?o+s/c:s?1:o)}l=32;function U(t,n,s){var o,a,p,v,b,_,E,M,P,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},B=r.location,V=void 0===B?e.location:B,R=r.distance,C=void 0===R?e.distance:R,N=r.threshold,U=void 0===N?e.threshold:N,F=r.findAllMatches,$=void 0===F?e.findAllMatches:F,D=r.minMatchCharLength,z=void 0===D?e.minMatchCharLength:D,I=r.includeMatches,H=void 0===I?e.includeMatches:I,L=r.ignoreLocation,j=void 0===L?e.ignoreLocation:L;if(n.length>l)throw new Error("Pattern length exceeds max of ".concat(l,"."));for(var y,d=n.length,g=t.length,i=Math.max(0,Math.min(V,g)),m=U,h=i,x=z>1||H,S=x?Array(g):[];(y=t.indexOf(n,h))>-1;)if(P=f(n,{currentLocation:y,expectedLocation:i,distance:C,ignoreLocation:j}),m=Math.min(P,m),h=y+d,x)for(b=0;b=T;o-=1)if(v=o-1,E=s[t.charAt(v)],x&&(S[v]=+!!E),u[o]=(u[o+1]<<1|1)&E,c&&(u[o]|=(w[o+1]|w[o])<<1|1|w[o+1]),u[o]&W&&(A=f(n,{errors:c,currentLocation:v,expectedLocation:i,distance:C,ignoreLocation:j}))<=m){if(m=A,(h=v)<=i)break;T=Math.max(1,2*i-h)}if(f(n,{errors:c+1,currentLocation:i,expectedLocation:i,distance:C,ignoreLocation:j})>m)break;w=u}return _={isMatch:h>=0,score:Math.max(.001,A)},x&&(M=function(){for(var i,s=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:e.minMatchCharLength,o=[],t=-1,r=-1,n=0,c=s.length;n=a&&o.push([t,r]),t=-1);return s[n-1]&&n-t>=a&&o.push([t,n-1]),o}(S,z),M.length?H&&(_.indices=M):_.isMatch=!1),_}function J(e){for(var s,n={},t=0,o=e.length;t1&&void 0!==arguments[1]?arguments[1]:{},h=o.location,C=void 0===h?e.location:h,g=o.threshold,O=void 0===g?e.threshold:g,d=o.distance,A=void 0===d?e.distance:d,m=o.includeMatches,E=void 0===m?e.includeMatches:m,p=o.findAllMatches,x=void 0===p?e.findAllMatches:p,v=o.minMatchCharLength,_=void 0===v?e.minMatchCharLength:v,u=o.isCaseSensitive,j=void 0===u?e.isCaseSensitive:u,b=o.ignoreLocation,w=void 0===b?e.ignoreLocation:b;if(t(this,s),this.options={location:C,threshold:O,distance:A,includeMatches:E,findAllMatches:x,minMatchCharLength:_,isCaseSensitive:j,ignoreLocation:w},this.pattern=j?n:n.toLowerCase(),this.chunks=[],this.pattern.length)if(a=function(e,t){y.chunks.push({pattern:e,alphabet:J(e),startIndex:t})},i=this.pattern.length,i>l){for(var r=0,f=i%l,k=i-f;r1&&void 0!==arguments[1]?arguments[1]:{},h=s.location,g=void 0===h?e.location:h,l=s.threshold,p=void 0===l?e.threshold:l,u=s.distance,j=void 0===u?e.distance:u,a=s.includeMatches,w=void 0===a?e.includeMatches:a,d=s.findAllMatches,v=void 0===d?e.findAllMatches:d,m=s.minMatchCharLength,b=void 0===m?e.minMatchCharLength:m,r=s.isCaseSensitive,y=void 0===r?e.isCaseSensitive:r,c=s.ignoreLocation,O=void 0===c?e.ignoreLocation:c;return t(this,o),(f=i.call(this,n))._bitapSearch=new _(n,{location:g,threshold:p,distance:j,includeMatches:w,findAllMatches:v,minMatchCharLength:b,isCaseSensitive:y,ignoreLocation:O}),f}return n(o,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),o}(a),W=function(e){c(s,e);var o=r(s);function s(e){return t(this,s),o.call(this,e)}return n(s,[{key:"search",value:function(e){for(var t,o,n=0,s=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,s.push([t,n-1]);return o=!!s.length,{isMatch:o,score:o?0:1,indices:s}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),s}(a),j=[Q,W,ne,q,G,Y,X,S],I=j.length,ee=/ +(?=(?:[^"]*"[^"]*")*[^"]*$)/,te=new Set([S.type,W.type]),K=function(){function s(n){var o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=o.isCaseSensitive,r=void 0===a?e.isCaseSensitive:a,c=o.includeMatches,y=void 0===c?e.includeMatches:c,d=o.minMatchCharLength,v=void 0===d?e.minMatchCharLength:d,h=o.ignoreLocation,f=void 0===h?e.ignoreLocation:h,m=o.findAllMatches,p=void 0===m?e.findAllMatches:m,i=o.location,g=void 0===i?e.location:i,u=o.threshold,b=void 0===u?e.threshold:u,l=o.distance,_=void 0===l?e.distance:l;t(this,s),this.query=null,this.options={isCaseSensitive:r,includeMatches:y,minMatchCharLength:v,findAllMatches:p,ignoreLocation:f,location:g,threshold:b,distance:_},this.pattern=r?n:n.toLowerCase(),this.query=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map(function(e){for(var a,r,c,l,d=e.trim().split(ee).filter(function(e){return e&&!!e.trim()}),s=[],o=0,h=d.length;o2&&void 0!==arguments[2]?arguments[2]:{}).auto,s=void 0===n||n;return w(e)||(e=T(e)),function e(n){var r,c,d,u,a=Object.keys(n),l=function(e){return!!e[D]}(n);if(!l&&a.length>1&&!w(n))return e(T(n));if(function(e){return!i(e)&&B(e)&&!w(e)}(n)){if(r=l?n[D]:a[0],c=l?n[ce]:n[r],!o(c))throw new Error(function(e){return"Invalid value for key ".concat(e)}(r));return d={keyId:b(r),pattern:c},s&&(d.searcher=v(c,t)),d}return u={children:[],operator:a[0]},a.forEach(function(t){var s=n[t];i(s)&&s.forEach(function(t){u.children.push(e(t))})}),u}(e)}function he(e,t){var n=e.matches;t.matches=[],s(n)&&n.forEach(function(e){if(s(e.indices)&&e.indices.length){var n={indices:e.indices,value:e.value};e.key&&(n.key=e.key.src),e.idx>-1&&(n.refIndex=e.idx),t.matches.push(n)}})}function me(e,t){t.score=e.score}return u=function(){function a(n){var s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;t(this,a),this.options=h(h({},e),s),this.options.useExtendedSearch,this._keyStore=new fe(this.options.keys),this.setCollection(n,o)}return n(a,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof E))throw new Error("Incorrect 'index' type");this._myIndex=t||L(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){s(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var t,o=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},n=[],e=0,s=this._docs.length;e1&&void 0!==arguments[1]?arguments[1]:{}).limit,i=void 0===a?-1:a,n=this.options,r=n.includeMatches,c=n.includeScore,l=n.shouldSort,d=n.sortFn,u=n.ignoreFieldNorm,s=o(t)?o(this._docs[0])?this._searchStringList(t):this._searchObjectList(t):this._searchLogical(t);return function(t,n){var s=n.ignoreFieldNorm,o=void 0===s?e.ignoreFieldNorm:s;t.forEach(function(e){var t=1;e.matches.forEach(function(e){var n=e.key,a=e.norm,s=e.score,i=n?n.weight:null;t*=Math.pow(0===s&&i?Number.EPSILON:s,(i||1)*(o?1:a))}),e.score=t})}(s,{ignoreFieldNorm:u}),l&&s.sort(d),V(i)&&i>-1&&(s=s.slice(0,i)),function(t,n){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=o.includeMatches,r=void 0===i?e.includeMatches:i,a=o.includeScore,c=void 0===a?e.includeScore:a,s=[];return r&&s.push(he),c&&s.push(me),t.map(function(e){var t=e.idx,o={item:n[t],refIndex:t};return s.length&&s.forEach(function(t){t(e,o)}),o})}(s,this._docs,{includeMatches:r,includeScore:c})}},{key:"_searchStringList",value:function(e){var n=v(e,this.options),o=this._myIndex.records,t=[];return o.forEach(function(e){var o=e.v,a=e.i,r=e.n;if(s(o)){var i=n.searchIn(o),c=i.isMatch,l=i.score,d=i.indices;c&&t.push({item:o,idx:a,matches:[{score:l,value:o,norm:r,indices:d}]})}}),t}},{key:"_searchLogical",value:function(e){var n=this,i=ue(e,this.options),a=function e(t,s,o){if(!t.children){var c,l=t.keyId,u=t.searcher,i=n._findMatches({key:n._keyStore.get(l),value:n._myIndex.getValueForItemAtKeyId(s,l),searcher:u});return i&&i.length?[{idx:o,item:s,matches:i}]:[]}for(var a=[],r=0,h=t.children.length;r1&&void 0!==arguments[1]?arguments[1]:{},o=s.getFn,a=void 0===o?e.getFn:o,i=s.fieldNormWeight,r=void 0===i?e.fieldNormWeight:i,c=t.keys,l=t.records,n=new E({getFn:a,fieldNormWeight:r});return n.setKeys(c),n.setIndexRecords(l),n},u.config=e,function(){p.push.apply(p,arguments)}(K),u},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t();var e,t,fuse,scriptBundle,copyText,copiedText,menuButton,menuCloseButton,menuWrapper,menuOpen,openMenu,closeMenu,showButton=document.getElementById("search-button"),showButtonMobile=document.getElementById("search-button-mobile"),hideButton=document.getElementById("close-search-button"),wrapper=document.getElementById("search-wrapper"),modal=document.getElementById("search-modal"),input=document.getElementById("search-query"),output=document.getElementById("search-results"),first=output.firstChild,last=output.lastChild,searchVisible=!1,indexed=!1,hasResults=!1;showButton?showButton.addEventListener("click",displaySearch):null,showButtonMobile?showButtonMobile.addEventListener("click",displaySearch):null,hideButton.addEventListener("click",hideSearch),wrapper.addEventListener("click",hideSearch),modal.addEventListener("click",function(e){return e.stopPropagation(),e.stopImmediatePropagation(),!1}),document.addEventListener("keydown",function(e){e.key=="/"&&(searchVisible||(e.preventDefault(),displaySearch())),e.key=="Escape"&&hideSearch(),e.key=="ArrowDown"&&searchVisible&&hasResults&&(e.preventDefault(),document.activeElement==input?first.focus():document.activeElement==last?last.focus():document.activeElement.parentElement.nextSibling.firstElementChild.focus()),e.key=="ArrowUp"&&searchVisible&&hasResults&&(e.preventDefault(),document.activeElement==input?input.focus():document.activeElement==first?input.focus():document.activeElement.parentElement.previousSibling.firstElementChild.focus()),e.key=="Enter"&&searchVisible&&hasResults&&(e.preventDefault(),document.activeElement==input?first.focus():document.activeElement.click())}),input.onkeyup=function(){executeQuery(this.value)};function displaySearch(){indexed||buildIndex(),searchVisible||(document.body.style.overflow="hidden",wrapper.style.visibility="visible",input.focus(),searchVisible=!0)}function hideSearch(){searchVisible&&(document.body.style.overflow="visible",wrapper.style.visibility="hidden",input.value="",output.innerHTML="",document.activeElement.blur(),searchVisible=!1)}function fetchJSON(e,t){var n=new XMLHttpRequest;n.onreadystatechange=function(){if(n.readyState===4&&n.status===200){var e=JSON.parse(n.responseText);t&&t(e)}},n.open("GET",e),n.send()}function buildIndex(){var e=wrapper.getAttribute("data-url"),e=e.replace(/\/?$/,"/");fetchJSON(e+"index.json",function(e){var t={shouldSort:!0,ignoreLocation:!0,threshold:0,includeMatches:!0,keys:[{name:"title",weight:.8},{name:"section",weight:.2},{name:"summary",weight:.6},{name:"content",weight:.4}]};fuse=new Fuse(e,t),indexed=!0})}function executeQuery(e){let n=fuse.search(e),t="";n.length>0?(n.forEach(function(e){console.log(e.item.summary);var o,i,a=e.item.summary,s=document.createElement("div");s.innerHTML=a,e.item.summary=s.textContent||s.innerText||"",o=e.item.externalUrl?e.item.title+''+e.item.externalUrl+" ":e.item.title,i=e.item.externalUrl?'target="_blank" rel="noopener" href="'+e.item.externalUrl+'"':'href="'+e.item.permalink+'"',t=t+`
+
+
+
+ ${o}
+
+
${e.item.section}· ${e.item.date?e.item.date:""}
+
${e.item.summary}
+
+ →
+ ←
+
+ `}),hasResults=!0):(t="",hasResults=!1),output.innerHTML=t,n.length>0&&(first=output.firstChild.firstElementChild,last=output.lastChild.firstElementChild)}scriptBundle=document.getElementById("script-bundle"),copyText=scriptBundle&&scriptBundle.getAttribute("data-copy")?scriptBundle.getAttribute("data-copy"):"Copy",copiedText=scriptBundle&&scriptBundle.getAttribute("data-copied")?scriptBundle.getAttribute("data-copied"):"Copied";function createCopyButton(e){const t=document.createElement("button");t.className="copy-button",t.type="button",t.ariaLabel=copyText,t.innerText=copyText,t.addEventListener("click",()=>copyCodeToClipboard(t,e)),addCopyButtonToDom(t,e)}async function copyCodeToClipboard(e,t){const n=t.querySelector(":last-child").innerText;try{result=await navigator.permissions.query({name:"clipboard-write"}),result.state=="granted"||result.state=="prompt"?await navigator.clipboard.writeText(n):copyCodeBlockExecCommand(n,t)}catch{copyCodeBlockExecCommand(n,t)}finally{codeWasCopied(e)}}function copyCodeBlockExecCommand(e,t){const n=document.createElement("textArea");n.contentEditable="true",n.readOnly="false",n.className="copy-textarea",n.value=e,t.insertBefore(n,t.firstChild);const s=document.createRange();s.selectNodeContents(n);const o=window.getSelection();o.removeAllRanges(),o.addRange(s),n.setSelectionRange(0,999999),document.execCommand("copy"),t.removeChild(n)}function codeWasCopied(e){e.blur(),e.innerText=copiedText,setTimeout(function(){e.innerText=copyText},2e3)}function addCopyButtonToDom(e,t){t.insertBefore(e,t.firstChild);const n=document.createElement("div");n.className="highlight-wrapper",t.parentNode.insertBefore(n,t),n.appendChild(t)}window.addEventListener("DOMContentLoaded",e=>{document.querySelectorAll(".highlight").forEach(e=>createCopyButton(e))}),menuButton=document.getElementById("menu-button"),menuCloseButton=document.getElementById("menu-close-button"),menuWrapper=document.getElementById("menu-wrapper"),menuOpen=!1,openMenu=function(){menuOpen||(menuOpen=!0,document.body.style.overflowY="hidden",menuButton.style.visibility="hidden",menuWrapper.style.visibility="visible",menuWrapper.style.opacity="1",window.onbeforeunload=function(){closeMenu()})},closeMenu=function(e){menuOpen&&(menuOpen=!1,document.body.style.overflowY="auto",menuButton.style.visibility="visible",menuWrapper.style.visibility="hidden",menuWrapper.style.opacity="0",window.onbeforeunload=function(){},e.stopPropagation())},menuButton.addEventListener("click",openMenu),menuCloseButton.addEventListener("click",closeMenu)
\ No newline at end of file
diff --git a/public/js/page.min.0860cf4e04fa2d72cc33ddba263083464d48f67de06114529043cb4623319efed4f484fd7f1730df5abea0e2da6f3538855634081d02f2d6e920b956f063e823.js b/public/js/page.min.0860cf4e04fa2d72cc33ddba263083464d48f67de06114529043cb4623319efed4f484fd7f1730df5abea0e2da6f3538855634081d02f2d6e920b956f063e823.js
new file mode 100644
index 0000000..02d5337
--- /dev/null
+++ b/public/js/page.min.0860cf4e04fa2d72cc33ddba263083464d48f67de06114529043cb4623319efed4f484fd7f1730df5abea0e2da6f3538855634081d02f2d6e920b956f063e823.js
@@ -0,0 +1 @@
+var viewed,liked,liked_page=!1,id=oid&&oid.replaceAll("/","-"),id_likes=oid_likes&&oid_likes.replaceAll("/","-");typeof auth!="undefined"&&(viewed=localStorage.getItem(id),viewed||auth.signInAnonymously().then(()=>{var e=db.collection("views").doc(id);localStorage.setItem(id,!0),e.get().then(e=>{e.exists?db.collection("views").doc(id).update({views:firebase.firestore.FieldValue.increment(1)}):db.collection("views").doc(id).set({views:1})}).catch(e=>{console.log("Error getting document:",e)})}).catch(e=>{var t=e.code,n=e.message;console.error(t,n)}),liked=localStorage.getItem(id_likes),liked&&(liked_page=!0,document.querySelectorAll("span[id='button_likes_heart']")[0].style.display="",document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display="none",document.querySelectorAll("span[id='button_likes_text']")[0].innerText=""));function like_article(e){auth.signInAnonymously().then(()=>{var t=db.collection("likes").doc(e);t.get().then(t=>{liked_page=!0,localStorage.setItem(e,!0),document.querySelectorAll("span[id='button_likes_heart']")[0].style.display="",document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display="none",document.querySelectorAll("span[id='button_likes_text']")[0].innerText="",t.exists?db.collection("likes").doc(e).update({likes:firebase.firestore.FieldValue.increment(1)}):db.collection("likes").doc(e).set({likes:1})}).catch(e=>{console.log("Error getting document:",e)})}).catch(e=>{var t=e.code,n=e.message;console.error(t,n)})}function remove_like_article(e){auth.signInAnonymously().then(()=>{var t=db.collection("likes").doc(e);t.get().then(t=>{liked_page=!1,localStorage.removeItem(e),document.querySelectorAll("span[id='button_likes_heart']")[0].style.display="none",document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display="",document.querySelectorAll("span[id='button_likes_text']")[0].innerText="\xa0Like",t.exists?db.collection("likes").doc(e).update({likes:firebase.firestore.FieldValue.increment(-1)}):db.collection("likes").doc(e).set({likes:0})}).catch(e=>{console.log("Error getting document:",e)})}).catch(e=>{var t=e.code,n=e.message;console.error(t,n)})}function process_article(){liked_page?remove_like_article(id_likes):like_article(id_likes)}
\ No newline at end of file
diff --git a/public/js/panzoom-util.0b774e030782a9868719da996178ac3b16e1b62d1e91bc2d30acff9d859a5621b373e1ae37cef8bbb467283f80648346c36d54b799a38d6da96aeac3bf4ff8e1.js b/public/js/panzoom-util.0b774e030782a9868719da996178ac3b16e1b62d1e91bc2d30acff9d859a5621b373e1ae37cef8bbb467283f80648346c36d54b799a38d6da96aeac3bf4ff8e1.js
new file mode 100644
index 0000000..89bd396
--- /dev/null
+++ b/public/js/panzoom-util.0b774e030782a9868719da996178ac3b16e1b62d1e91bc2d30acff9d859a5621b373e1ae37cef8bbb467283f80648346c36d54b799a38d6da96aeac3bf4ff8e1.js
@@ -0,0 +1,131 @@
+// AI GENNED AS FUCK NGL
+
+// Define the handler variables outside of any event listener
+let activeContainer = null;
+let panzoomInstance = null;
+let isProcessingClick = false;
+let isInitialized = false; // Add a flag to prevent multiple initializations
+
+// Handle keyboard events
+function handleKeyPress(e) {
+ if (e.key === "Escape" && activeContainer) {
+ closePopup();
+ }
+}
+
+// Function to close the popup and cleanup
+function closePopup() {
+ if (activeContainer) {
+ // Remove the keyboard event listener
+ document.removeEventListener("keydown", handleKeyPress);
+
+ // Clean up Panzoom instance
+ if (panzoomInstance && typeof panzoomInstance.destroy === 'function') {
+ panzoomInstance.destroy();
+ }
+
+ activeContainer.remove();
+ activeContainer = null;
+ panzoomInstance = null;
+ isProcessingClick = false;
+ }
+}
+
+// Initialize the panzoom functionality
+function initializePanzoom() {
+ if (isInitialized) return; // Prevent multiple initializations
+
+ // Create a single delegated click handler at the document level
+ document.body.addEventListener('click', function(event) {
+ // First, check if we clicked a zoomable image
+ const clickedImage = event.target.closest('.zoomable');
+ if (!clickedImage) return; // Exit if we didn't click a zoomable image
+
+ event.preventDefault();
+ event.stopPropagation(); // Stop event from bubbling
+
+ // If there's already a container or we're processing a click, don't create another
+ if (activeContainer || isProcessingClick) {
+ console.log('Already processing or container exists'); // Debug log
+ return;
+ }
+
+ isProcessingClick = true;
+
+ // Create the popup container
+ activeContainer = document.createElement("div");
+ activeContainer.className = "panzoom-popup";
+
+ // Use the clicked image's source and alt
+ const imgSrc = clickedImage.dataset.src || clickedImage.src;
+ const imgAlt = clickedImage.alt || '';
+
+ activeContainer.innerHTML = `
+
+
+
+ `;
+
+ document.body.appendChild(activeContainer);
+
+ // Initialize Panzoom on the image
+ const popupImage = activeContainer.querySelector("img");
+
+ // Wait for the image to load before initializing Panzoom
+ popupImage.onload = () => {
+ // Get the image and viewport dimensions
+ const imageWidth = popupImage.naturalWidth;
+ const imageHeight = popupImage.naturalHeight;
+ const viewportWidth = window.innerWidth;
+ const viewportHeight = window.innerHeight;
+
+ // Calculate the scaling factor to fit the image within the viewport
+ const scaleX = viewportWidth / imageWidth;
+ const scaleY = viewportHeight / imageHeight;
+
+ // Use the smaller scaling factor to ensure the image fits within the viewport
+ const scale = Math.min(scaleX, scaleY);
+
+ // Calculate the initial x and y coordinates to center the image after scaling
+ const startX = (viewportWidth - imageWidth * scale) / 2;
+ const startY = (viewportHeight - imageHeight * scale) / 2;
+
+ // But only modifying y is necessary because centering works VIA CESSPOOL HORIZONTALLY BUT NOT VERTICALLY
+ panzoomInstance = Panzoom(popupImage, {
+ startY: startY,
+ startScale: 1,
+ maxScale: 5
+ });
+
+ // Enable wheel zoom
+ activeContainer.addEventListener("wheel", panzoomInstance.zoomWithWheel);
+ isProcessingClick = false;
+ };
+
+ // Handle errors
+ popupImage.onerror = () => {
+ console.error('Failed to load image:', imgSrc);
+ closePopup();
+ isProcessingClick = false;
+ };
+
+ // Close popup when clicking outside the image
+ activeContainer.addEventListener("click", function (e) {
+ if (e.target === activeContainer || e.target.classList.contains("panzoom-overlay")) {
+ closePopup();
+ }
+ });
+
+ // Add keyboard support for closing
+ document.addEventListener("keydown", handleKeyPress);
+ });
+
+ isInitialized = true; // Mark as initialized
+}
+
+// Initialize only once when the DOM is loaded
+if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', initializePanzoom);
+} else {
+ initializePanzoom();
+}
\ No newline at end of file
diff --git a/public/js/panzoom.min.b48202c3408ba8ef63ef9a6cc583e9d7ddb6574828cf79a4aaefe3c3964d0098ad77da46fdd5dddb66314ca975f6b9562093fa227ef51db7eba6d640facf448c.js b/public/js/panzoom.min.b48202c3408ba8ef63ef9a6cc583e9d7ddb6574828cf79a4aaefe3c3964d0098ad77da46fdd5dddb66314ca975f6b9562093fa227ef51db7eba6d640facf448c.js
new file mode 100644
index 0000000..6c167e5
--- /dev/null
+++ b/public/js/panzoom.min.b48202c3408ba8ef63ef9a6cc583e9d7ddb6574828cf79a4aaefe3c3964d0098ad77da46fdd5dddb66314ca975f6b9562093fa227ef51db7eba6d640facf448c.js
@@ -0,0 +1,6 @@
+/**
+* Panzoom for panning and zooming elements using CSS transforms
+* Copyright Timmy Willison and other contributors
+* https://github.com/timmywil/panzoom/blob/main/MIT-License.txt
+*/
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Panzoom=e()}(this,function(){"use strict";var Y=function(){return(Y=Object.assign||function(t){for(var e,n=1,o=arguments.length;n{var n=t.data();n?e.innerText=numberWithCommas(n.views):e.innerText=0,toggleLoaders(e)})},update_likes=function(e,t){likesCollection.doc(t).onSnapshot(t=>{var n=t.data();n?e.innerText=numberWithCommas(n.likes):e.innerText=0,toggleLoaders(e)})},auth.signInAnonymously().then(()=>{var e,t,n,s,o=document.querySelectorAll("span[id^='views_']");for(n in o)e=o[n],t=e.id?e.id.replaceAll("/","-"):e.id,t&&update_views(e,t);s=document.querySelectorAll("span[id^='likes_']");for(n in s)e=s[n],t=e.id?e.id.replaceAll("/","-"):e.id,t&&update_likes(e,t)}).catch(e=>{var t=e.code,n=e.message;console.error(t,n)})}
\ No newline at end of file
diff --git a/public/js/shortcodes/gallery.min.5fddb0ac85fed097f7b3630b6616e67caf1eea7ca23a42a6f7fc645f561306e7dabaef0a4eda37c74fb627ae3c97e11cb39b8895a4c839816632940e4a482508.js b/public/js/shortcodes/gallery.min.5fddb0ac85fed097f7b3630b6616e67caf1eea7ca23a42a6f7fc645f561306e7dabaef0a4eda37c74fb627ae3c97e11cb39b8895a4c839816632940e4a482508.js
new file mode 100644
index 0000000..a6476e6
--- /dev/null
+++ b/public/js/shortcodes/gallery.min.5fddb0ac85fed097f7b3630b6616e67caf1eea7ca23a42a6f7fc645f561306e7dabaef0a4eda37c74fb627ae3c97e11cb39b8895a4c839816632940e4a482508.js
@@ -0,0 +1 @@
+function _getDefaultPackeryOptions(){return{percentPosition:!0,gutter:5,resize:!0,itemSelector:".panzoom-container"}}(function(){$(window).on("load",function(){let e=[],t=document.querySelectorAll(".gallery");t.forEach(t=>{let n=new Packery(t,_getDefaultPackeryOptions());e.push(n)}),console.groupEnd()})})()
\ No newline at end of file
diff --git a/public/lib/jquery/jquery.slim.min.b0dca576e87d7eaa5850ae4e61759c065786cdb6489d68fcc82240539eebd5da522bdb4fda085ffd245808c8fe2acb2516408eb774ef26b5f6015fc6737c0ea8.js b/public/lib/jquery/jquery.slim.min.b0dca576e87d7eaa5850ae4e61759c065786cdb6489d68fcc82240539eebd5da522bdb4fda085ffd245808c8fe2acb2516408eb774ef26b5f6015fc6737c0ea8.js
new file mode 100644
index 0000000..35906b9
--- /dev/null
+++ b/public/lib/jquery/jquery.slim.min.b0dca576e87d7eaa5850ae4e61759c065786cdb6489d68fcc82240539eebd5da522bdb4fda085ffd245808c8fe2acb2516408eb774ef26b5f6015fc6737c0ea8.js
@@ -0,0 +1,2 @@
+/*! jQuery v3.7.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/animatedSelector,-effects/Tween | (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(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},m=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||m).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/animatedSelector,-effects/Tween",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),b=new RegExp(ge+"|>"),A=new RegExp(g),D=new RegExp("^"+t+"$"),N={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+d),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},L=/^(?:input|select|textarea|button)$/i,j=/^h\d$/i,O=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,P=/[+~]/,H=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),q=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))},R=function(){V()},M=K(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{E.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){E={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&(V(e),e=e||C,T)){if(11!==d&&(u=O.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return E.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return E.call(n,a),n}else{if(u[2])return E.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return E.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||p&&p.test(t))){if(c=t,f=e,1===d&&(b.test(t)||m.test(t))){(f=P.test(t)&&X(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=k)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+G(l[o]);c=l.join(",")}try{return E.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function B(e){return e[k]=!0,e}function F(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function $(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(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&&M(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function U(a){return B(function(o){return o=+o,B(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 X(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=C&&9===n.nodeType&&n.documentElement&&(r=(C=n).documentElement,T=!ce.isXMLDoc(C),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=C&&(t=C.defaultView)&&t.top!==t&&t.addEventListener("unload",R),le.getById=F(function(e){return r.appendChild(e).id=ce.expando,!C.getElementsByName||!C.getElementsByName(ce.expando).length}),le.disconnectedMatch=F(function(e){return i.call(e,"*")}),le.scope=F(function(){return C.querySelectorAll(":scope")}),le.cssHas=F(function(){try{return C.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(x.filter.ID=function(e){var t=e.replace(H,q);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&T){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(H,q);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&T){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[]}}),x.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},x.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&T)return t.getElementsByClassName(e)},p=[],F(function(e){var t;r.appendChild(e).innerHTML=" ",e.querySelectorAll("[selected]").length||p.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+k+"-]").length||p.push("~="),e.querySelectorAll("a#"+k+"+*").length||p.push(".#.+[+~]"),e.querySelectorAll(":checked").length||p.push(":checked"),(t=C.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&p.push(":enabled",":disabled"),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||p.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||p.push(":has"),p=p.length&&new RegExp(p.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===C||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),C}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),T&&!h[t+" "]&&(!p||!p.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(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(H,q),e[3]=(e[3]||e[4]||e[5]||"").replace(H,q),"~="===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]||I.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]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return N.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&A.test(n)&&(t=Y(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(H,q).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(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=I.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 T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||E,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:k.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 ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:m,!0)),C.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=m.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,E=ce(m);var S=/^(?:parents|prev(?:Until|All))/,A={children:!0,contents:!0,next:!0,prev:!0};function D(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;re=m.createDocumentFragment().appendChild(m.createElement("div")),(be=m.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),re.appendChild(be),le.checkClone=re.cloneNode(!0).cloneNode(!0).lastChild.checked,re.innerHTML="",le.noCloneChecked=!!re.cloneNode(!0).lastChild.defaultValue,re.innerHTML=" ",le.option=!!re.lastChild;var Te={thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function Ee(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function ke(e,t){for(var n=0,r=e.length;n",""]);var Se=/<|?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),d=[],p=0,h=e.length;p\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Me(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Ie(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function We(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n",2===yt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=m.implementation.createHTMLDocument("")).createElement("base")).href=m.location.href,t.head.appendChild(r)):t=m),o=!n&&[],(i=C.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.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),v(t)&&(t=t.call(e,n,ce.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)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.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"===ce.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"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||K})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return R(this,function(e,t,n){var r;if(y(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)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Qe(le.pixelPosition,function(e,t){if(t)return t=Ve(e,n),$e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return R(this,function(e,t,n){var r;return y(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?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.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.on("mouseenter",e).on("mouseleave",t||e)}}),ce.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){ce.fn[n]=function(e,t){return 0 {
+ if( e.key === 'Enter' || e.key === ' ' ){
+ e.preventDefault();
+ this.activate();
+ }
+ });
+ }
+
+ // On hover (or tap), warm up the TCP connections we're (likely) about to use.
+ this.addEventListener('pointerover', LiteYTEmbed.warmConnections, {once: true});
+ this.addEventListener('focusin', LiteYTEmbed.warmConnections, {once: true});
+
+ // Once the user clicks, add the real iframe and drop our play button
+ // TODO: In the future we could be like amp-youtube and silently swap in the iframe during idle time
+ // We'd want to only do this for in-viewport or near-viewport ones: https://github.com/ampproject/amphtml/pull/5003
+ this.addEventListener('click', this.activate);
+
+ // Chrome & Edge desktop have no problem with the basic YouTube Embed with ?autoplay=1
+ // However Safari desktop and most/all mobile browsers do not successfully track the user gesture of clicking through the creation/loading of the iframe,
+ // so they don't autoplay automatically. Instead we must load an additional 2 sequential JS files (1KB + 165KB) (un-br) for the YT Player API
+ // TODO: Try loading the the YT API in parallel with our iframe and then attaching/playing it. #82
+ this.needsYTApi = this.hasAttribute("js-api") || navigator.vendor.includes('Apple') || navigator.userAgent.includes('Mobi');
+ }
+
+ /**
+ * Add a to the head
+ */
+ static addPrefetch(kind, url, as) {
+ const linkEl = document.createElement('link');
+ linkEl.rel = kind;
+ linkEl.href = url;
+ if (as) {
+ linkEl.as = as;
+ }
+ document.head.append(linkEl);
+ }
+
+ /**
+ * Begin pre-connecting to warm up the iframe load
+ * Since the embed's network requests load within its iframe,
+ * preload/prefetch'ing them outside the iframe will only cause double-downloads.
+ * So, the best we can do is warm up a few connections to origins that are in the critical path.
+ *
+ * Maybe ` ` would work, but it's unsupported: http://crbug.com/593267
+ * But TBH, I don't think it'll happen soon with Site Isolation and split caches adding serious complexity.
+ */
+ static warmConnections() {
+ if (LiteYTEmbed.preconnected) return;
+
+ // The iframe document and most of its subresources come right off youtube.com
+ LiteYTEmbed.addPrefetch('preconnect', 'https://www.youtube-nocookie.com');
+ // The botguard script is fetched off from google.com
+ LiteYTEmbed.addPrefetch('preconnect', 'https://www.google.com');
+
+ // Not certain if these ad related domains are in the critical path. Could verify with domain-specific throttling.
+ LiteYTEmbed.addPrefetch('preconnect', 'https://googleads.g.doubleclick.net');
+ LiteYTEmbed.addPrefetch('preconnect', 'https://static.doubleclick.net');
+
+ LiteYTEmbed.preconnected = true;
+ }
+
+ fetchYTPlayerApi() {
+ if (window.YT || (window.YT && window.YT.Player)) return;
+
+ this.ytApiPromise = new Promise((res, rej) => {
+ var el = document.createElement('script');
+ el.src = 'https://www.youtube.com/iframe_api';
+ el.async = true;
+ el.onload = _ => {
+ YT.ready(res);
+ };
+ el.onerror = rej;
+ this.append(el);
+ });
+ }
+
+ /** Return the YT Player API instance. (Public L-YT-E API) */
+ async getYTPlayer() {
+ if(!this.playerPromise) {
+ await this.activate();
+ }
+
+ return this.playerPromise;
+ }
+
+ async addYTPlayerIframe() {
+ this.fetchYTPlayerApi();
+ await this.ytApiPromise;
+
+ const videoPlaceholderEl = document.createElement('div')
+ this.append(videoPlaceholderEl);
+
+ const paramsObj = Object.fromEntries(this.getParams().entries());
+
+ this.playerPromise = new Promise(resolve => {
+ let player = new YT.Player(videoPlaceholderEl, {
+ width: '100%',
+ videoId: this.videoId,
+ playerVars: paramsObj,
+ events: {
+ 'onReady': event => {
+ event.target.playVideo();
+ resolve(player);
+ }
+ }
+ });
+ });
+ }
+
+ // Add the iframe within for indexability discoverability. See https://github.com/paulirish/lite-youtube-embed/issues/105
+ addNoscriptIframe() {
+ const iframeEl = this.createBasicIframe();
+ const noscriptEl = document.createElement('noscript');
+ // Appending into noscript isn't equivalant for mysterious reasons: https://html.spec.whatwg.org/multipage/scripting.html#the-noscript-element
+ noscriptEl.innerHTML = iframeEl.outerHTML;
+ this.append(noscriptEl);
+ }
+
+ getParams() {
+ const params = new URLSearchParams(this.getAttribute('params') || []);
+ params.append('autoplay', '1');
+ params.append('playsinline', '1');
+ return params;
+ }
+
+ async activate(){
+ if (this.classList.contains('lyt-activated')) return;
+ this.classList.add('lyt-activated');
+
+ if (this.needsYTApi) {
+ return this.addYTPlayerIframe(this.getParams());
+ }
+
+ const iframeEl = this.createBasicIframe();
+ this.append(iframeEl);
+
+ // Set focus for a11y
+ iframeEl.focus();
+ }
+
+ createBasicIframe(){
+ const iframeEl = document.createElement('iframe');
+ iframeEl.width = 560;
+ iframeEl.height = 315;
+ // No encoding necessary as [title] is safe. https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#:~:text=Safe%20HTML%20Attributes%20include
+ iframeEl.title = this.playLabel;
+ iframeEl.allow = 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture';
+ iframeEl.allowFullscreen = true;
+ // AFAIK, the encoding here isn't necessary for XSS, but we'll do it only because this is a URL
+ // https://stackoverflow.com/q/64959723/89484
+ iframeEl.src = `https://www.youtube-nocookie.com/embed/${encodeURIComponent(this.videoId)}?${this.getParams().toString()}`;
+ return iframeEl;
+ }
+
+ /**
+ * In the spirit of the `lowsrc` attribute and progressive JPEGs, we'll upgrade the reliable
+ * poster image to a higher resolution one, if it's available.
+ * Interestingly this sddefault webp is often smaller in filesize, but we will still attempt it second
+ * because getting _an_ image in front of the user if our first priority.
+ *
+ * See https://github.com/paulirish/lite-youtube-embed/blob/master/youtube-thumbnail-urls.md for more details
+ */
+ upgradePosterImage() {
+ // Defer to reduce network contention.
+ setTimeout(() => {
+ const webpUrl = `https://i.ytimg.com/vi_webp/${this.videoId}/sddefault.webp`;
+ const img = new Image();
+ img.fetchPriority = 'low'; // low priority to reduce network contention
+ img.referrerpolicy = 'origin'; // Not 100% sure it's needed, but https://github.com/ampproject/amphtml/pull/3940
+ img.src = webpUrl;
+ img.onload = e => {
+ // A pretty ugly hack since onerror won't fire on YouTube image 404. This is (probably) due to
+ // Youtube's style of returning data even with a 404 status. That data is a 120x90 placeholder image.
+ // β¦ per "annoying yt 404 behavior" in the .md
+ const noAvailablePoster = e.target.naturalHeight == 90 && e.target.naturalWidth == 120;
+ if (noAvailablePoster) return;
+
+ this.style.backgroundImage = `url("${webpUrl}")`;
+ }
+ }, 100);
+ }
+}
+// Register custom element
+customElements.define('lite-youtube', LiteYTEmbed);
diff --git a/public/lib/lite-youtube-embed/lite-yt-embed.css b/public/lib/lite-youtube-embed/lite-yt-embed.css
new file mode 100644
index 0000000..c96a472
--- /dev/null
+++ b/public/lib/lite-youtube-embed/lite-yt-embed.css
@@ -0,0 +1,95 @@
+lite-youtube {
+ background-color: #000;
+ position: relative;
+ display: block;
+ contain: content;
+ background-position: center center;
+ background-size: cover;
+ cursor: pointer;
+ max-width: 720px;
+}
+
+/* gradient */
+lite-youtube::before {
+ content: attr(data-title);
+ display: block;
+ position: absolute;
+ top: 0;
+ /* Pixel-perfect port of YT's gradient PNG, using https://github.com/bluesmoon/pngtocss plus optimizations */
+ background-image: linear-gradient(180deg, rgb(0 0 0 / 67%) 0%, rgb(0 0 0 / 54%) 14%, rgb(0 0 0 / 15%) 54%, rgb(0 0 0 / 5%) 72%, rgb(0 0 0 / 0%) 94%);
+ height: 99px;
+ width: 100%;
+ font-family: "YouTube Noto",Roboto,Arial,Helvetica,sans-serif;
+ color: hsl(0deg 0% 93.33%);
+ text-shadow: 0 0 2px rgba(0,0,0,.5);
+ font-size: 18px;
+ padding: 25px 20px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ box-sizing: border-box;
+}
+
+lite-youtube:hover::before {
+ color: white;
+}
+
+/* responsive iframe with a 16:9 aspect ratio
+ thanks https://css-tricks.com/responsive-iframes/
+*/
+lite-youtube::after {
+ content: "";
+ display: block;
+ padding-bottom: calc(100% / (16 / 9));
+}
+lite-youtube > iframe {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ border: 0;
+}
+
+/* play button */
+lite-youtube > .lty-playbtn {
+ display: block;
+ /* Make the button element cover the whole area for a large hover/click target⦠*/
+ width: 100%;
+ height: 100%;
+ /* β¦but visually it's still the same size */
+ background: no-repeat center/68px 48px;
+ /* YT's actual play button svg */
+ background-image: url('data:image/svg+xml;utf8, ');
+ position: absolute;
+ cursor: pointer;
+ z-index: 1;
+ filter: grayscale(100%);
+ transition: filter .1s cubic-bezier(0, 0, 0.2, 1);
+ border: 0;
+}
+
+lite-youtube:hover > .lty-playbtn,
+lite-youtube .lty-playbtn:focus {
+ filter: none;
+}
+
+/* Post-click styles */
+lite-youtube.lyt-activated {
+ cursor: unset;
+}
+lite-youtube.lyt-activated::before,
+lite-youtube.lyt-activated > .lty-playbtn {
+ opacity: 0;
+ pointer-events: none;
+}
+
+.lyt-visually-hidden {
+ clip: rect(0 0 0 0);
+ clip-path: inset(50%);
+ height: 1px;
+ overflow: hidden;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+ }
diff --git a/public/lib/packery/packery.pkgd.min.js b/public/lib/packery/packery.pkgd.min.js
new file mode 100644
index 0000000..3dc3ef4
--- /dev/null
+++ b/public/lib/packery/packery.pkgd.min.js
@@ -0,0 +1,13 @@
+/*!
+ * Packery PACKAGED v2.1.2
+ * Gapless, draggable grid layouts
+ *
+ * Licensed GPLv3 for open source use
+ * or Packery Commercial License for commercial use
+ *
+ * http://packery.metafizzy.co
+ * Copyright 2013-2018 Metafizzy
+ */
+
+!function(t,e){"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function(t,e){"use strict";function i(i,s,a){function h(t,e,n){var o,s="$()."+i+'("'+e+'")';return t.each(function(t,h){var u=a.data(h,i);if(!u)return void r(i+" not initialized. Cannot call methods, i.e. "+s);var c=u[e];if(!c||"_"==e.charAt(0))return void r(s+" is not a valid method");var d=c.apply(u,n);o=void 0===o?d:o}),void 0!==o?o:t}function u(t,e){t.each(function(t,n){var o=a.data(n,i);o?(o.option(e),o._init()):(o=new s(n,e),a.data(n,i,o))})}a=a||e||t.jQuery,a&&(s.prototype.option||(s.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=o.call(arguments,1);return h(this,t,e)}return u(this,t),this},n(a))}function n(t){!t||t&&t.bridget||(t.bridget=i)}var o=Array.prototype.slice,s=t.console,r="undefined"==typeof s?function(){}:function(t){s.error(t)};return n(e||t.jQuery),i}),function(t,e){"function"==typeof define&&define.amd?define("get-size/get-size",e):"object"==typeof module&&module.exports?module.exports=e():t.getSize=e()}(window,function(){"use strict";function t(t){var e=parseFloat(t),i=-1==t.indexOf("%")&&!isNaN(e);return i&&e}function e(){}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0;u>e;e++){var i=h[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See https://bit.ly/getsizebug1"),e}function o(){if(!c){c=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);r=200==Math.round(t(o.width)),s.isBoxSizeOuter=r,i.removeChild(e)}}function s(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var s=n(e);if("none"==s.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var c=a.isBorderBox="border-box"==s.boxSizing,d=0;u>d;d++){var l=h[d],f=s[l],p=parseFloat(f);a[l]=isNaN(p)?0:p}var g=a.paddingLeft+a.paddingRight,m=a.paddingTop+a.paddingBottom,y=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,x=a.borderTopWidth+a.borderBottomWidth,b=c&&r,E=t(s.width);E!==!1&&(a.width=E+(b?0:g+_));var w=t(s.height);return w!==!1&&(a.height=w+(b?0:m+x)),a.innerWidth=a.width-(g+_),a.innerHeight=a.height-(m+x),a.outerWidth=a.width+y,a.outerHeight=a.height+v,a}}var r,a="undefined"==typeof console?e:function(t){console.error(t)},h=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=h.length,c=!1;return s}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){i=i.slice(0),e=e||[];for(var n=this._onceEvents&&this._onceEvents[t],o=0;o=t.x+e&&this.y+this.height>=t.y+i},e.overlaps=function(t){var e=this.x+this.width,i=this.y+this.height,n=t.x+t.width,o=t.y+t.height;return this.xt.x&&this.yt.y},e.getMaximalFreeRects=function(e){if(!this.overlaps(e))return!1;var i,n=[],o=this.x+this.width,s=this.y+this.height,r=e.x+e.width,a=e.y+e.height;return this.yr&&(i=new t({x:r,y:this.y,width:o-r,height:this.height}),n.push(i)),s>a&&(i=new t({x:this.x,y:a,width:this.width,height:s-a}),n.push(i)),this.x=t.width&&this.height>=t.height},t}),function(t,e){if("function"==typeof define&&define.amd)define("packery/js/packer",["./rect"],e);else if("object"==typeof module&&module.exports)module.exports=e(require("./rect"));else{var i=t.Packery=t.Packery||{};i.Packer=e(i.Rect)}}(window,function(t){"use strict";function e(t,e,i){this.width=t||0,this.height=e||0,this.sortDirection=i||"downwardLeftToRight",this.reset()}var i=e.prototype;i.reset=function(){this.spaces=[];var e=new t({x:0,y:0,width:this.width,height:this.height});this.spaces.push(e),this.sorter=n[this.sortDirection]||n.downwardLeftToRight},i.pack=function(t){for(var e=0;e=t.x+t.width&&i.height>=t.height-.01;if(n){t.y=i.y,this.placed(t);break}}},i.rowPack=function(t){for(var e=0;e=t.y+t.height&&i.width>=t.width-.01;if(n){t.x=i.x,this.placed(t);break}}},i.placeInSpace=function(t,e){t.x=e.x,t.y=e.y,this.placed(t)},i.placed=function(t){for(var e=[],i=0;ii&&1>n;return o?void this.goTo(t,e):void a.apply(this,arguments)},s.enablePlacing=function(){this.removeTransitionStyles(),this.isTransitioning&&n&&(this.element.style[n]="none"),this.isTransitioning=!1,this.getSize(),this.layout._setRectSize(this.element,this.rect),this.isPlacing=!0},s.disablePlacing=function(){this.isPlacing=!1},s.removeElem=function(){var t=this.element.parentNode;t&&t.removeChild(this.element),this.layout.packer.addSpace(this.rect),this.emitEvent("remove",[this])},s.showDropPlaceholder=function(){var t=this.dropPlaceholder;t||(t=this.dropPlaceholder=document.createElement("div"),t.className="packery-drop-placeholder",t.style.position="absolute"),t.style.width=this.size.width+"px",t.style.height=this.size.height+"px",this.positionDropPlaceholder(),this.layout.element.appendChild(t)},s.positionDropPlaceholder=function(){this.dropPlaceholder.style[n]="translate("+this.rect.x+"px, "+this.rect.y+"px)"},s.hideDropPlaceholder=function(){var t=this.dropPlaceholder.parentNode;t&&t.removeChild(this.dropPlaceholder)},o}),function(t,e){"function"==typeof define&&define.amd?define(["get-size/get-size","outlayer/outlayer","packery/js/rect","packery/js/packer","packery/js/item"],e):"object"==typeof module&&module.exports?module.exports=e(require("get-size"),require("outlayer"),require("./rect"),require("./packer"),require("./item")):t.Packery=e(t.getSize,t.Outlayer,t.Packery.Rect,t.Packery.Packer,t.Packery.Item)}(window,function(t,e,i,n,o){"use strict";function s(t,e){return t.position.y-e.position.y||t.position.x-e.position.x}function r(t,e){return t.position.x-e.position.x||t.position.y-e.position.y}function a(t,e){var i=e.x-t.x,n=e.y-t.y;return Math.sqrt(i*i+n*n)}i.prototype.canFit=function(t){return this.width>=t.width-1&&this.height>=t.height-1};var h=e.create("packery");h.Item=o;var u=h.prototype;u._create=function(){e.prototype._create.call(this),this.packer=new n,this.shiftPacker=new n,this.isEnabled=!0,this.dragItemCount=0;var t=this;this.handleDraggabilly={dragStart:function(){t.itemDragStart(this.element)},dragMove:function(){t.itemDragMove(this.element,this.position.x,this.position.y)},dragEnd:function(){t.itemDragEnd(this.element)}},this.handleUIDraggable={start:function(e,i){i&&t.itemDragStart(e.currentTarget)},drag:function(e,i){i&&t.itemDragMove(e.currentTarget,i.position.left,i.position.top)},stop:function(e,i){i&&t.itemDragEnd(e.currentTarget)}}},u._resetLayout=function(){this.getSize(),this._getMeasurements();var t,e,i;this._getOption("horizontal")?(t=1/0,e=this.size.innerHeight+this.gutter,i="rightwardTopToBottom"):(t=this.size.innerWidth+this.gutter,e=1/0,i="downwardLeftToRight"),this.packer.width=this.shiftPacker.width=t,this.packer.height=this.shiftPacker.height=e,this.packer.sortDirection=this.shiftPacker.sortDirection=i,this.packer.reset(),this.maxY=0,this.maxX=0},u._getMeasurements=function(){this._getMeasurement("columnWidth","width"),this._getMeasurement("rowHeight","height"),this._getMeasurement("gutter","width")},u._getItemLayoutPosition=function(t){if(this._setRectSize(t.element,t.rect),this.isShifting||this.dragItemCount>0){var e=this._getPackMethod();this.packer[e](t.rect)}else this.packer.pack(t.rect);return this._setMaxXY(t.rect),t.rect},u.shiftLayout=function(){this.isShifting=!0,this.layout(),delete this.isShifting},u._getPackMethod=function(){return this._getOption("horizontal")?"rowPack":"columnPack"},u._setMaxXY=function(t){this.maxX=Math.max(t.x+t.width,this.maxX),this.maxY=Math.max(t.y+t.height,this.maxY)},u._setRectSize=function(e,i){var n=t(e),o=n.outerWidth,s=n.outerHeight;(o||s)&&(o=this._applyGridGutter(o,this.columnWidth),s=this._applyGridGutter(s,this.rowHeight)),i.width=Math.min(o,this.packer.width),i.height=Math.min(s,this.packer.height)},u._applyGridGutter=function(t,e){if(!e)return t+this.gutter;e+=this.gutter;var i=t%e,n=i&&1>i?"round":"ceil";return t=Math[n](t/e)*e},u._getContainerSize=function(){return this._getOption("horizontal")?{width:this.maxX-this.gutter}:{height:this.maxY-this.gutter}},u._manageStamp=function(t){var e,n=this.getItem(t);if(n&&n.isPlacing)e=n.rect;else{var o=this._getElementOffset(t);e=new i({x:this._getOption("originLeft")?o.left:o.right,y:this._getOption("originTop")?o.top:o.bottom})}this._setRectSize(t,e),this.packer.placed(e),this._setMaxXY(e)},u.sortItemsByPosition=function(){var t=this._getOption("horizontal")?r:s;this.items.sort(t)},u.fit=function(t,e,i){var n=this.getItem(t);n&&(this.stamp(n.element),n.enablePlacing(),this.updateShiftTargets(n),e=void 0===e?n.rect.x:e,i=void 0===i?n.rect.y:i,this.shift(n,e,i),this._bindFitEvents(n),n.moveTo(n.rect.x,n.rect.y),this.shiftLayout(),this.unstamp(n.element),this.sortItemsByPosition(),n.disablePlacing())},u._bindFitEvents=function(t){function e(){n++,2==n&&i.dispatchEvent("fitComplete",null,[t])}var i=this,n=0;t.once("layout",e),this.once("layoutComplete",e)},u.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&(this.options.shiftPercentResize?this.resizeShiftPercentLayout():this.layout())},u.needsResizeLayout=function(){var e=t(this.element),i=this._getOption("horizontal")?"innerHeight":"innerWidth";return e[i]!=this.size[i]},u.resizeShiftPercentLayout=function(){var e=this._getItemsForLayout(this.items),i=this._getOption("horizontal"),n=i?"y":"x",o=i?"height":"width",s=i?"rowHeight":"columnWidth",r=i?"innerHeight":"innerWidth",a=this[s];if(a=a&&a+this.gutter){this._getMeasurements();var h=this[s]+this.gutter;e.forEach(function(t){var e=Math.round(t.rect[n]/a);t.rect[n]=e*h})}else{var u=t(this.element)[r]+this.gutter,c=this.packer[o];e.forEach(function(t){t.rect[n]=t.rect[n]/c*u})}this.shiftLayout()},u.itemDragStart=function(t){if(this.isEnabled){this.stamp(t);var e=this.getItem(t);e&&(e.enablePlacing(),e.showDropPlaceholder(),this.dragItemCount++,this.updateShiftTargets(e))}},u.updateShiftTargets=function(t){this.shiftPacker.reset(),this._getBoundingRect();var e=this._getOption("originLeft"),n=this._getOption("originTop");this.stamps.forEach(function(t){var o=this.getItem(t);if(!o||!o.isPlacing){var s=this._getElementOffset(t),r=new i({x:e?s.left:s.right,y:n?s.top:s.bottom});this._setRectSize(t,r),this.shiftPacker.placed(r)}},this);var o=this._getOption("horizontal"),s=o?"rowHeight":"columnWidth",r=o?"height":"width";this.shiftTargetKeys=[],this.shiftTargets=[];var a,h=this[s];if(h=h&&h+this.gutter){var u=Math.ceil(t.rect[r]/h),c=Math.floor((this.shiftPacker[r]+this.gutter)/h);a=(c-u)*h;for(var d=0;c>d;d++){var l=o?0:d*h,f=o?d*h:0;this._addShiftTarget(l,f,a)}}else a=this.shiftPacker[r]+this.gutter-t.rect[r],this._addShiftTarget(0,0,a);var p=this._getItemsForLayout(this.items),g=this._getPackMethod();p.forEach(function(t){var e=t.rect;this._setRectSize(t.element,e),this.shiftPacker[g](e),this._addShiftTarget(e.x,e.y,a);var i=o?e.x+e.width:e.x,n=o?e.y:e.y+e.height;if(this._addShiftTarget(i,n,a),h)for(var s=Math.round(e[r]/h),u=1;s>u;u++){var c=o?i:e.x+h*u,d=o?e.y+h*u:n;this._addShiftTarget(c,d,a)}},this)},u._addShiftTarget=function(t,e,i){var n=this._getOption("horizontal")?e:t;if(!(0!==n&&n>i)){var o=t+","+e,s=-1!=this.shiftTargetKeys.indexOf(o);s||(this.shiftTargetKeys.push(o),this.shiftTargets.push({x:t,y:e}))}},u.shift=function(t,e,i){var n,o=1/0,s={x:e,y:i};this.shiftTargets.forEach(function(t){
+var e=a(t,s);o>e&&(n=t,o=e)}),t.rect.x=n.x,t.rect.y=n.y};var c=120;u.itemDragMove=function(t,e,i){function n(){s.shift(o,e,i),o.positionDropPlaceholder(),s.layout()}var o=this.isEnabled&&this.getItem(t);if(o){e-=this.size.paddingLeft,i-=this.size.paddingTop;var s=this,r=new Date,a=this._itemDragTime&&r-this._itemDragTimehttps://blog.neet.works/
+
\ No newline at end of file
diff --git a/public/posts/index.html b/public/posts/index.html
new file mode 100644
index 0000000..ab802e9
--- /dev/null
+++ b/public/posts/index.html
@@ -0,0 +1,15 @@
+Posts · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/posts/index.xml b/public/posts/index.xml
new file mode 100644
index 0000000..aed49a9
--- /dev/null
+++ b/public/posts/index.xml
@@ -0,0 +1 @@
+Posts on N.E.E.T. Works https://blog.neet.works/posts/Recent content in Posts on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/posts/page/1/index.html b/public/posts/page/1/index.html
new file mode 100644
index 0000000..31c75d5
--- /dev/null
+++ b/public/posts/page/1/index.html
@@ -0,0 +1,2 @@
+https://blog.neet.works/posts/
+
\ No newline at end of file
diff --git a/public/posts/watercooling-homelab/featured.webp b/public/posts/watercooling-homelab/featured.webp
new file mode 100644
index 0000000..13a7602
Binary files /dev/null and b/public/posts/watercooling-homelab/featured.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/featured_hu11504899310106128621.webp b/public/posts/watercooling-homelab/featured_hu11504899310106128621.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/featured_hu11504899310106128621.webp
rename to public/posts/watercooling-homelab/featured_hu11504899310106128621.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/featured_hu13568191302889737537.webp b/public/posts/watercooling-homelab/featured_hu13568191302889737537.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/featured_hu13568191302889737537.webp
rename to public/posts/watercooling-homelab/featured_hu13568191302889737537.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A.webp b/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A.webp
new file mode 100644
index 0000000..7e3f636
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu1954630252676748703.webp b/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu1954630252676748703.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu1954630252676748703.webp
rename to public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu1954630252676748703.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu6560107379008232574.webp b/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu6560107379008232574.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu6560107379008232574.webp
rename to public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu6560107379008232574.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu7088133987632116537.webp b/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu7088133987632116537.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu7088133987632116537.webp
rename to public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu7088133987632116537.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B.webp b/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B.webp
new file mode 100644
index 0000000..ea421c2
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu12155478021797826213.webp b/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu12155478021797826213.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu12155478021797826213.webp
rename to public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu12155478021797826213.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu2333850158973680984.webp b/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu2333850158973680984.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu2333850158973680984.webp
rename to public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu2333850158973680984.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu5952309977048855875.webp b/public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu5952309977048855875.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu5952309977048855875.webp
rename to public/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu5952309977048855875.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/Coldplate.webp b/public/posts/watercooling-homelab/images/compressed/Coldplate.webp
new file mode 100644
index 0000000..d1a9c7d
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/Coldplate.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Coldplate_hu13174017899928575525.webp b/public/posts/watercooling-homelab/images/compressed/Coldplate_hu13174017899928575525.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Coldplate_hu13174017899928575525.webp
rename to public/posts/watercooling-homelab/images/compressed/Coldplate_hu13174017899928575525.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Coldplate_hu16258961307282205929.webp b/public/posts/watercooling-homelab/images/compressed/Coldplate_hu16258961307282205929.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Coldplate_hu16258961307282205929.webp
rename to public/posts/watercooling-homelab/images/compressed/Coldplate_hu16258961307282205929.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Coldplate_hu3290250784134948227.webp b/public/posts/watercooling-homelab/images/compressed/Coldplate_hu3290250784134948227.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Coldplate_hu3290250784134948227.webp
rename to public/posts/watercooling-homelab/images/compressed/Coldplate_hu3290250784134948227.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/Different_Plugs.webp b/public/posts/watercooling-homelab/images/compressed/Different_Plugs.webp
new file mode 100644
index 0000000..1ba45cf
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/Different_Plugs.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu17890886748642996535.webp b/public/posts/watercooling-homelab/images/compressed/Different_Plugs_hu17890886748642996535.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu17890886748642996535.webp
rename to public/posts/watercooling-homelab/images/compressed/Different_Plugs_hu17890886748642996535.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu2378229743182206831.webp b/public/posts/watercooling-homelab/images/compressed/Different_Plugs_hu2378229743182206831.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu2378229743182206831.webp
rename to public/posts/watercooling-homelab/images/compressed/Different_Plugs_hu2378229743182206831.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu3502703824848779819.webp b/public/posts/watercooling-homelab/images/compressed/Different_Plugs_hu3502703824848779819.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu3502703824848779819.webp
rename to public/posts/watercooling-homelab/images/compressed/Different_Plugs_hu3502703824848779819.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom.webp b/public/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom.webp
new file mode 100644
index 0000000..15972ff
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu1233157730881247055.webp b/public/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu1233157730881247055.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu1233157730881247055.webp
rename to public/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu1233157730881247055.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu1716452709661764841.webp b/public/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu1716452709661764841.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu1716452709661764841.webp
rename to public/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu1716452709661764841.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu478575305574189147.webp b/public/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu478575305574189147.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu478575305574189147.webp
rename to public/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu478575305574189147.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/GPUs_Installed.webp b/public/posts/watercooling-homelab/images/compressed/GPUs_Installed.webp
new file mode 100644
index 0000000..b545a26
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/GPUs_Installed.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu1860541658624349795.webp b/public/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu1860541658624349795.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu1860541658624349795.webp
rename to public/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu1860541658624349795.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu1923429014339473058.webp b/public/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu1923429014339473058.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu1923429014339473058.webp
rename to public/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu1923429014339473058.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu4193758725753816349.webp b/public/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu4193758725753816349.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu4193758725753816349.webp
rename to public/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu4193758725753816349.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/MO-RA!.webp b/public/posts/watercooling-homelab/images/compressed/MO-RA!.webp
new file mode 100644
index 0000000..9357b11
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/MO-RA!.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu15264814207577810858.webp b/public/posts/watercooling-homelab/images/compressed/MO-RA!_hu15264814207577810858.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu15264814207577810858.webp
rename to public/posts/watercooling-homelab/images/compressed/MO-RA!_hu15264814207577810858.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu6856946684884405237.webp b/public/posts/watercooling-homelab/images/compressed/MO-RA!_hu6856946684884405237.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu6856946684884405237.webp
rename to public/posts/watercooling-homelab/images/compressed/MO-RA!_hu6856946684884405237.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu7453820902150892044.webp b/public/posts/watercooling-homelab/images/compressed/MO-RA!_hu7453820902150892044.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu7453820902150892044.webp
rename to public/posts/watercooling-homelab/images/compressed/MO-RA!_hu7453820902150892044.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/Mounting_Detail.webp b/public/posts/watercooling-homelab/images/compressed/Mounting_Detail.webp
new file mode 100644
index 0000000..8099cdb
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/Mounting_Detail.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu11231283172588266533.webp b/public/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu11231283172588266533.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu11231283172588266533.webp
rename to public/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu11231283172588266533.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu1490212990626714303.webp b/public/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu1490212990626714303.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu1490212990626714303.webp
rename to public/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu1490212990626714303.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu3280937936208174423.webp b/public/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu3280937936208174423.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu3280937936208174423.webp
rename to public/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu3280937936208174423.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/Tall_Capacitor.webp b/public/posts/watercooling-homelab/images/compressed/Tall_Capacitor.webp
new file mode 100644
index 0000000..06b27f6
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/Tall_Capacitor.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu1042940534242500862.webp b/public/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu1042940534242500862.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu1042940534242500862.webp
rename to public/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu1042940534242500862.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu11882410216080315790.webp b/public/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu11882410216080315790.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu11882410216080315790.webp
rename to public/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu11882410216080315790.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu3985119007043451200.webp b/public/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu3985119007043451200.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu3985119007043451200.webp
rename to public/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu3985119007043451200.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/Test_Fit.webp b/public/posts/watercooling-homelab/images/compressed/Test_Fit.webp
new file mode 100644
index 0000000..51fdbef
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/Test_Fit.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu2884804705215397458.webp b/public/posts/watercooling-homelab/images/compressed/Test_Fit_hu2884804705215397458.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu2884804705215397458.webp
rename to public/posts/watercooling-homelab/images/compressed/Test_Fit_hu2884804705215397458.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu4196319411009163019.webp b/public/posts/watercooling-homelab/images/compressed/Test_Fit_hu4196319411009163019.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu4196319411009163019.webp
rename to public/posts/watercooling-homelab/images/compressed/Test_Fit_hu4196319411009163019.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu6466058294895506811.webp b/public/posts/watercooling-homelab/images/compressed/Test_Fit_hu6466058294895506811.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu6466058294895506811.webp
rename to public/posts/watercooling-homelab/images/compressed/Test_Fit_hu6466058294895506811.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/Triple_Card_Jank.webp b/public/posts/watercooling-homelab/images/compressed/Triple_Card_Jank.webp
new file mode 100644
index 0000000..c168c74
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/Triple_Card_Jank.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu10619128996450324123.webp b/public/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu10619128996450324123.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu10619128996450324123.webp
rename to public/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu10619128996450324123.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu17456463471095554312.webp b/public/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu17456463471095554312.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu17456463471095554312.webp
rename to public/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu17456463471095554312.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu3171065713872445154.webp b/public/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu3171065713872445154.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu3171065713872445154.webp
rename to public/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu3171065713872445154.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/complete_a.webp b/public/posts/watercooling-homelab/images/compressed/complete_a.webp
new file mode 100644
index 0000000..39a4915
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/complete_a.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_a_hu11784685921316552556.webp b/public/posts/watercooling-homelab/images/compressed/complete_a_hu11784685921316552556.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_a_hu11784685921316552556.webp
rename to public/posts/watercooling-homelab/images/compressed/complete_a_hu11784685921316552556.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_a_hu2347091142476872481.webp b/public/posts/watercooling-homelab/images/compressed/complete_a_hu2347091142476872481.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_a_hu2347091142476872481.webp
rename to public/posts/watercooling-homelab/images/compressed/complete_a_hu2347091142476872481.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_a_hu2371455810172732269.webp b/public/posts/watercooling-homelab/images/compressed/complete_a_hu2371455810172732269.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_a_hu2371455810172732269.webp
rename to public/posts/watercooling-homelab/images/compressed/complete_a_hu2371455810172732269.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/complete_assembly.webp b/public/posts/watercooling-homelab/images/compressed/complete_assembly.webp
new file mode 100644
index 0000000..2656402
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/complete_assembly.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu13996029485759007548.webp b/public/posts/watercooling-homelab/images/compressed/complete_assembly_hu13996029485759007548.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu13996029485759007548.webp
rename to public/posts/watercooling-homelab/images/compressed/complete_assembly_hu13996029485759007548.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu17913719379729244320.webp b/public/posts/watercooling-homelab/images/compressed/complete_assembly_hu17913719379729244320.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu17913719379729244320.webp
rename to public/posts/watercooling-homelab/images/compressed/complete_assembly_hu17913719379729244320.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu402138244258743400.webp b/public/posts/watercooling-homelab/images/compressed/complete_assembly_hu402138244258743400.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu402138244258743400.webp
rename to public/posts/watercooling-homelab/images/compressed/complete_assembly_hu402138244258743400.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/complete_b.webp b/public/posts/watercooling-homelab/images/compressed/complete_b.webp
new file mode 100644
index 0000000..7624992
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/complete_b.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_b_hu10235357959924345043.webp b/public/posts/watercooling-homelab/images/compressed/complete_b_hu10235357959924345043.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_b_hu10235357959924345043.webp
rename to public/posts/watercooling-homelab/images/compressed/complete_b_hu10235357959924345043.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_b_hu10444887637626475779.webp b/public/posts/watercooling-homelab/images/compressed/complete_b_hu10444887637626475779.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_b_hu10444887637626475779.webp
rename to public/posts/watercooling-homelab/images/compressed/complete_b_hu10444887637626475779.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_b_hu12966552216401371125.webp b/public/posts/watercooling-homelab/images/compressed/complete_b_hu12966552216401371125.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_b_hu12966552216401371125.webp
rename to public/posts/watercooling-homelab/images/compressed/complete_b_hu12966552216401371125.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/goopy_installed.webp b/public/posts/watercooling-homelab/images/compressed/goopy_installed.webp
new file mode 100644
index 0000000..892ab04
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/goopy_installed.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu13878470882578617902.webp b/public/posts/watercooling-homelab/images/compressed/goopy_installed_hu13878470882578617902.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu13878470882578617902.webp
rename to public/posts/watercooling-homelab/images/compressed/goopy_installed_hu13878470882578617902.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu7775517930751145146.webp b/public/posts/watercooling-homelab/images/compressed/goopy_installed_hu7775517930751145146.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu7775517930751145146.webp
rename to public/posts/watercooling-homelab/images/compressed/goopy_installed_hu7775517930751145146.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu8582164235252167480.webp b/public/posts/watercooling-homelab/images/compressed/goopy_installed_hu8582164235252167480.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu8582164235252167480.webp
rename to public/posts/watercooling-homelab/images/compressed/goopy_installed_hu8582164235252167480.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/plug_detail_bottom.webp b/public/posts/watercooling-homelab/images/compressed/plug_detail_bottom.webp
new file mode 100644
index 0000000..6a5b125
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/plug_detail_bottom.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu12744847709972265499.webp b/public/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu12744847709972265499.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu12744847709972265499.webp
rename to public/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu12744847709972265499.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu3645814594706023691.webp b/public/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu3645814594706023691.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu3645814594706023691.webp
rename to public/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu3645814594706023691.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu3698649971536149681.webp b/public/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu3698649971536149681.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu3698649971536149681.webp
rename to public/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu3698649971536149681.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/plug_detail_top.webp b/public/posts/watercooling-homelab/images/compressed/plug_detail_top.webp
new file mode 100644
index 0000000..ba5e400
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/plug_detail_top.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu13627305942680874943.webp b/public/posts/watercooling-homelab/images/compressed/plug_detail_top_hu13627305942680874943.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu13627305942680874943.webp
rename to public/posts/watercooling-homelab/images/compressed/plug_detail_top_hu13627305942680874943.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu16358936284331608818.webp b/public/posts/watercooling-homelab/images/compressed/plug_detail_top_hu16358936284331608818.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu16358936284331608818.webp
rename to public/posts/watercooling-homelab/images/compressed/plug_detail_top_hu16358936284331608818.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu7787027711586187933.webp b/public/posts/watercooling-homelab/images/compressed/plug_detail_top_hu7787027711586187933.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu7787027711586187933.webp
rename to public/posts/watercooling-homelab/images/compressed/plug_detail_top_hu7787027711586187933.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/pump_greeble.webp b/public/posts/watercooling-homelab/images/compressed/pump_greeble.webp
new file mode 100644
index 0000000..7fb245d
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/pump_greeble.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu1040829716072557719.webp b/public/posts/watercooling-homelab/images/compressed/pump_greeble_hu1040829716072557719.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu1040829716072557719.webp
rename to public/posts/watercooling-homelab/images/compressed/pump_greeble_hu1040829716072557719.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu1471177938307566585.webp b/public/posts/watercooling-homelab/images/compressed/pump_greeble_hu1471177938307566585.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu1471177938307566585.webp
rename to public/posts/watercooling-homelab/images/compressed/pump_greeble_hu1471177938307566585.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu4319233910559987333.webp b/public/posts/watercooling-homelab/images/compressed/pump_greeble_hu4319233910559987333.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu4319233910559987333.webp
rename to public/posts/watercooling-homelab/images/compressed/pump_greeble_hu4319233910559987333.webp
diff --git a/public/posts/watercooling-homelab/images/compressed/solenoid_diode.webp b/public/posts/watercooling-homelab/images/compressed/solenoid_diode.webp
new file mode 100644
index 0000000..1893a28
Binary files /dev/null and b/public/posts/watercooling-homelab/images/compressed/solenoid_diode.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu13681423255705621406.webp b/public/posts/watercooling-homelab/images/compressed/solenoid_diode_hu13681423255705621406.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu13681423255705621406.webp
rename to public/posts/watercooling-homelab/images/compressed/solenoid_diode_hu13681423255705621406.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu14196543121366269339.webp b/public/posts/watercooling-homelab/images/compressed/solenoid_diode_hu14196543121366269339.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu14196543121366269339.webp
rename to public/posts/watercooling-homelab/images/compressed/solenoid_diode_hu14196543121366269339.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu3904316093352162951.webp b/public/posts/watercooling-homelab/images/compressed/solenoid_diode_hu3904316093352162951.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu3904316093352162951.webp
rename to public/posts/watercooling-homelab/images/compressed/solenoid_diode_hu3904316093352162951.webp
diff --git a/public/posts/watercooling-homelab/images/original/Block_Mod_Detail_A.jpg b/public/posts/watercooling-homelab/images/original/Block_Mod_Detail_A.jpg
new file mode 100644
index 0000000..5266b0f
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/Block_Mod_Detail_A.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/Block_Mod_Detail_B.jpg b/public/posts/watercooling-homelab/images/original/Block_Mod_Detail_B.jpg
new file mode 100644
index 0000000..5abe309
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/Block_Mod_Detail_B.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/Coldplate.jpg b/public/posts/watercooling-homelab/images/original/Coldplate.jpg
new file mode 100644
index 0000000..255d51b
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/Coldplate.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/Different_Plugs.jpg b/public/posts/watercooling-homelab/images/original/Different_Plugs.jpg
new file mode 100644
index 0000000..cad6902
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/Different_Plugs.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/Dual_Blocks_Zoom.jpg b/public/posts/watercooling-homelab/images/original/Dual_Blocks_Zoom.jpg
new file mode 100644
index 0000000..61978ee
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/Dual_Blocks_Zoom.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/GPUs_Installed.jpg b/public/posts/watercooling-homelab/images/original/GPUs_Installed.jpg
new file mode 100644
index 0000000..5928d30
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/GPUs_Installed.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/MO-RA!.jpg b/public/posts/watercooling-homelab/images/original/MO-RA!.jpg
new file mode 100644
index 0000000..511a10c
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/MO-RA!.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/Mounting_Detail.jpg b/public/posts/watercooling-homelab/images/original/Mounting_Detail.jpg
new file mode 100644
index 0000000..4840763
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/Mounting_Detail.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/Tall_Capacitor.jpg b/public/posts/watercooling-homelab/images/original/Tall_Capacitor.jpg
new file mode 100644
index 0000000..f5ef26a
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/Tall_Capacitor.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/Test_Fit.jpg b/public/posts/watercooling-homelab/images/original/Test_Fit.jpg
new file mode 100644
index 0000000..ba6a65f
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/Test_Fit.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/Triple_Card_Jank.jpg b/public/posts/watercooling-homelab/images/original/Triple_Card_Jank.jpg
new file mode 100644
index 0000000..d42f624
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/Triple_Card_Jank.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/complete_a.jpg b/public/posts/watercooling-homelab/images/original/complete_a.jpg
new file mode 100644
index 0000000..b9c6604
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/complete_a.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/complete_assembly.jpg b/public/posts/watercooling-homelab/images/original/complete_assembly.jpg
new file mode 100644
index 0000000..26e673e
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/complete_assembly.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/complete_b.jpg b/public/posts/watercooling-homelab/images/original/complete_b.jpg
new file mode 100644
index 0000000..8bb3fb8
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/complete_b.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/featured.jpg b/public/posts/watercooling-homelab/images/original/featured.jpg
new file mode 100644
index 0000000..73db392
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/featured.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/goopy_installed.jpg b/public/posts/watercooling-homelab/images/original/goopy_installed.jpg
new file mode 100644
index 0000000..cf2d831
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/goopy_installed.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/plug_detail_bottom.jpg b/public/posts/watercooling-homelab/images/original/plug_detail_bottom.jpg
new file mode 100644
index 0000000..d0b3595
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/plug_detail_bottom.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/plug_detail_top.jpg b/public/posts/watercooling-homelab/images/original/plug_detail_top.jpg
new file mode 100644
index 0000000..0f5dd00
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/plug_detail_top.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/pump_greeble.jpg b/public/posts/watercooling-homelab/images/original/pump_greeble.jpg
new file mode 100644
index 0000000..a3b6e85
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/pump_greeble.jpg differ
diff --git a/public/posts/watercooling-homelab/images/original/solenoid_diode.jpg b/public/posts/watercooling-homelab/images/original/solenoid_diode.jpg
new file mode 100644
index 0000000..875545b
Binary files /dev/null and b/public/posts/watercooling-homelab/images/original/solenoid_diode.jpg differ
diff --git a/public/posts/watercooling-homelab/index.html b/public/posts/watercooling-homelab/index.html
new file mode 100644
index 0000000..1f37f9c
--- /dev/null
+++ b/public/posts/watercooling-homelab/index.html
@@ -0,0 +1,177 @@
+Watercooling My Homelab · N.E.E.T. Works
+Table of Contents Table of Contents Overview
# I’ve been watercooling my desktop since 2020, and case modding custom cooling solutions since my first modern dGPU in 2012. I enjoy it for the aesthetic, as well as the ability to run my hardware to the redline, despite the lower gains that modern hardware has… It’s still fun to try and see how high you can get on benchmark scoreboards. It was a big initial investment, but with most parts being reusable, the ongoing cost for component upgrades are minimal. Early in 2024, I bought some GPUs to use for dedicated ML tasks in my server rack, and immediately had watercooling on the mind. There weren’t particularly strong reasons to do so, but it would lower the power usage a bit, give me some more VRAM overclocking headroom, and give me a bit more core clock stability, as well as the ability to use a cheap two-slot NVLINK connector without suffocating a GPU.
My initial setup with 3x 2080 Tis, using m.2 NVMe to PCIe risers in an ASUS prebuilt. Two are connected by NVLINK, which I found to provide a slight performance benefit on the order of ~1-5% in multi-GPU SISR training, which is not worth the typical price for NVLINK bridges from this era. I was lucky to get this ugly, quadro-oriented bridge for just $40. I’ve never had a leak on my desktop, but with wider temperature swings in my garage, and collectively, a whole lot more expensive hardware that might get damaged than compared to my desktop setup, I was hesitant. The benefits seemed minimal, and I considered it a fun what-if scenario until I upgraded my main server and discovered that the forced-air passive chassis cooling was insufficient for my new CPUs. At that point, I had to make a decision: Get better heatsinks, which would be single-purpose and cost in excess of $100 each, or whole rack watercooling. I chose whole rack watercooling.
With enough reason for me to go ahead with the project, and the only thing holding me back being a fear of leaks, I had to figure out how to actively monitor for, and preferably prevent such an eventuality. I happened upon a product called LEAKSHIELD , from Aqua Computer, that advertised itself as doing exactly that.
How does it work? You pull a vacuum inside the fluid loop and monitor the loss rate. Water can’t get out if air is trying to get in, and if air gets in, the vacuum is reduced. It’s so simple, I don’t know why it took this long for such a product to enter the PC watercooling space. I could have just bought a LEAKSHIELD and called it a day, but Aqua Computer’s software doesn’t support Linux, and the specs for the vacuum pump seemed a bit weak for a loop of my scale. But, its functionality was something I was confident I could emulate with more robust off-the-shelf parts. Thus, sufficiently armed with esoteric plumbing knowledge, I took the plunge and started loading up on parts.
The Hardware
# Most of the build uses pretty standard off-the-shelf parts for PC watercooling, but there are a few bits and pieces that most builders won’t have seen before, and a custom control system that offers a more relevant experience for a server rack. The control system is based on an Arduino Uno that feeds vital statistics over serial, and features pressure control and monitoring similar to the LEAKSHIELD, with fan control based on a PID algorithm keeping the water temperature at a fixed setpoint above ambient.
Off-the-shelf
# General Details
# The centerpiece of the build, which the control unit and pump mount to, is the “MOther of all RAdiators”, version 3, from Watercool. This is the 360mm version with support for up to 18x 120mm fans, or 8x 180mm fans. It’s constructed more in the spirit of a vehicle radiator than a traditional PC radiator, with a less restrictive fin stack and large, round tubes rather than thin rectangular ones. It provides several mounting points for accessories which I was able to utilize to secure it to my server rack in a satisfactorily sturdy fashion. An in-depth teardown on the construction method and material quality of the MO-RA can be found on igor’sLAB . For fans, I have a collection of old DC-control Corsair Air Series SP120s. They’ve all been retired from regular use, because of noise-related aging issues. In fact, one of them failed to turn at all once I had everything wired up, and another had its bearing disintegrate about 8 weeks after putting the thing into service. That being said, they did survive (and continue to survive, in the remaining 16 cases) 24/7 use for anywhere from 4-10 years, at bottom of the barrel pricing, so that’s not too bad. I’m not exactly pushing the limits of this radiator here, so a few fans breaking down over time isn’t the end of the world.
A MO-RA V3 360 PRO PC Watercooling Radiator from Watercool I got a secondhand Corsair XD5 pump/res combo from eBay for about sixty bucks, which is pretty good for a genuine D5-based pump/res combo. It has PWM support which I did wire up, but the flow ended up being rather anemic even at 100%, so I just run it full speed all the time. The flow rate is measured through an Aqua Computer flow sensor , which is simply a hall-effect tachometer translated to l/h through software. I did not attempt to verify the accuracy of the sensor in my setup. The absolute accuracy is less relevant than simply getting an overall idea of whether or not the measurement is consistent with flow behavior, which it is.
Simple, cheap aluminum bars and angles mount to the studs on the radiator and into the stud holes on the server rack, and the pump and control box mount onto brackets along with the fans. CPUs
# My thermally problematic server upgrade was to dual Xeon Gold 6154s, which are Skylake-SP architecture. This specific SKU is pretty beefy, with 18 cores at sustained all-core speeds of 3.7GHz SSE / 3.3GHz AVX2 / 2.7GHz AVX512, and a TDP of 200 watts. The rated tjmax was 105C, and with the chassis cooling, they readily met that and started throttling under all-core loads, with idle as high as 60-70*C. I previously had Xeon E5-2697 v2s, which had TDPs of 130w. They got toasty, but never throttled. I’m not sure if the chassis had any easy fan upgrades available that might have made a difference, and I certainly could have moved to 4u-compatible tower coolers rather than forced air, but since I wanted to watercool the GPUs anyway, adding the CPUs as well would be minimal cost/effort, with more future compatibility for the waterblocks compared to a specialized LGA3647 tower cooler.
Alphacool Eisblock XPX Pro coldplate Image credit & copyright - igor’sLAB The CPU waterblocks are Alphacool Eisblock XPX Pro Aurora Light models, which are significantly cheaper than the XPX Aurora Pro not-light version. They appear to be entirely identical, functionally… I’m not sure if there any actual performance benefits offered by the not-light version. It’s a relatively obscure block family without many thorough reviews, which makes sense, given this block is designed for full coverage on Xeons/Threadrippers. The coldplate appears to be skived , which is uncommon in this price bracket for a discrete block, and the fins are incredibly short and dense. In smaller desktop loops, I’ve seen this block criticized for having overly restrictive flow, but when you have four blocks + quick disconnects, “good” flow is relative. At the power limit of 200w, the maximum core temperature delta relative to the water temperature is 25*C, with a ~1-2*C average delta between the two serially-connected sockets at a flow rate of ~130L/h, and that’s more than sufficient.
Interior view of the Supermicro CSE-846 chassis showcasing the installed waterblocks and other components. GPUs
# The GPU blocks are Phanteks 2080 Ti Founder’s Edition blocks. Nothing special, they’re just the cheapest matching ones I could find in 2024 that looked like they’d fit these almost-reference-but-not-quite OEM cards. They’re generic OEM models that would have gone in prebuilts. The most interesting thing about these cards, is that they’ve been modded to have 22GB of VRAM. There’s a dedicated supplier still offering them, and it’s by far the best $/GB value for VRAM in modern NVIDIA GPUs. Whether or not this is a better value overall than, say, a 3090 (Ti) depends on your usecase. Performance improvements in ML tasks between the 2080 Ti and 3090 (Ti) range from as little as ~20% to as much as ~100% depending on how memory bandwidth constrained your workload is. With secondhand 3090 (Ti)s still going for minimum $700 on the used market in the US, I found the alternative 2080 Ti option to be more alluring for my usecase, which is primarily single image super-resolution. More VRAM is desirable to increase the size of tiles for inference, and to increase the batch size during training. Training speed scales almost linearly, and inference speed scales linearly, per GPU. So, for my usecase, where I’m not really limited by the performance of a single GPU, the 2080 Ti mod route offers better overall value both for VRAM and combined core performance compared to 3090 (Ti)s. The idea of having a modded GPU in itself was also appealing and definitely part of why I made that decision. Pulling up a hardware monitor and seeing a 2080 Ti with 22GB of VRAM feels a little bit naughty, and I like that.
The blocks installed in an ASUS prebuilt gaming tower. I did initially buy three of them, as pictured at the beginning of this post, but one of them failed just after the 30 day warranty period listed on their website. Despite that, they were kind enough to offer a full refund if I covered return shipping, and were very communicative and responded in <24 hours every time I sent them any kind of message/inquiry.
The biggest benefit that watercooling theoretically brings to modern video cards is a prolonged lifespan. Not due to lower core temperatures, in an absolute sense, but due to the reduced stress from thermal cycles. Mismatches in the rate of thermal expansion between the die and the substrate will eventually cause their bond to break, and this happens faster the larger your die is, and the more extreme the temperature differences are. Today’s GPU dies are huge, and it’s hard to say how many failures are attributable to this factor alone, but it is certain to be more of a risk than it has been in the past. I’d rather buy a used mining GPU than a used gaming GPU any day, because it has likely been kept at roughly the same temperature for most of its life, as opposed to experiencing wide periodic swings.
The GPU blocks required a moderate amount of light massaging to properly fit on these OEM model cards. The power plugs are in a different position and a singular capacitor on these models is slightly taller than on the actual Founder’s Edition reference card, but they’re otherwise close enough to identical. That’s not to say that there are no benefits from lowering the operating temperature. As an absolute value, within manufacturer limits, it affects boost clocks, and leakage current . A cooler chip will use less power to run at the same clock speed compared to a hotter chip due to reduced leakage current, making them measurably more energy efficient per clock cycle the colder they run. In my case, with the fan on max, while not thermal throttling, these GPUs would bounce off the power limit of 280w while attempting to hit a core clock of 1800MHz. Under water, at a reported core temperature of ~30*C, the reported board power draw is only ~220w at 1800MHz core clock for the same workload. The type of fan typically found in these coolers is rated anywhere from 15-30w on its own, so a reduction of at least 30w can likely be attributed to a lower leakage current.
DIY Time
# In no particular order, here is a list of the major components involved in the control system.
Generic metal box, formerly from a PBX system. Arduino Uno clone, unknown brand 60mm Corsair fan RS232 TTL shifter Aesthetic retro power switch 12v DC vacuum pump U.S. Solid 12V NC Solenoid 12v relay modules HX711 ADC MD-PS002 Absolute Pressure Sensors L298-like PWM motor driver Apple White iMac PSU Adafruit Arduino Uno Proto Shield DS18B20 temperature probes Fit check for all the major components. I didn’t take excruciatingly detailed pictures of every single step of the assembly/prototyping process. For the most part, I was just plugging pre-made components together. The most interesting production notes include the pressure sensor and the power supply.
Putting New Life into an iMac PSU
# The power supply I used is from a first-gen Intel White iMac, which is visually very similar to the G5. It was one of the earliest things that I installed Linux on, and I used it as a seedbox for a bit, but eventually took it apart and saved some of the more interesting stuff.
All the credit goes to the user ersterhernd , from this thread on the tonymacx86.com forum for figuring out the pinout of this PSU, which is almost entirely identical to the one that was in my unit, apart from the power rating on mine being 200w. There are two banks of pins, half of which are always on, half of which are toggleable. Each bank has 12v, 5v, and 3.3v. I didn’t end up using 3.3v for anything other than the power switch. I have no idea what the energy efficiency of this unit is, obviously it doesn’t have an 80+ certification… But I’m assuming that Apple would make it at least halfway decent. Hopefully more efficient than a random 12v power brick with additional converters, I’d hope.
My schematic for the control unit. It was the first time I’ve ever used KiCad, and the first time I’ve ever made a schematic like this at all. I hope it’s relatively legible. As you can see in the schematic above, the always-on 3.3v pin is connected to SYS_POWERUP through a relay board. The relay input is pulled low by a single pole switch, which turns the relay on, which connects ground to SYS_POWERUP, engaging the other rail of the power supply. This is kind of a convoluted solution to not having a double-pole switch… But I didn’t have a double-pole switch, so that’s what I did.
Measuring vacuum
# The leak-resisting aspect all hinges on monitoring the pressure of the loop… Or potentially running a vacuum pump constantly, but that’s stupid. For some reason, I had a really hard time finding a vacuum pressur sensor. There are plenty of physical, analogue vacuum gauges available, but as far as an electronic sensor… I just couldn’t find any located in the US, at a reasonable price. There were a few hobbyist grade differential sensors, but I wanted to be able to measure down to an almost complete vacuum, and they didn’t have the range. Maybe I had the wrong search terms, but I just wasn’t finding anything. Eventually I found an unpackaged sensor with obscure, not entirely legible datasheets that claimed to have an acceptable pressure range for my application. The MD-PS002 is what I settled on, available on Amazon in the US in a 2-pack for $8. It’s a tiny little thing, and it took two attempts to successfully create a sensor package that didn’t leak.
Sensor package details, installed and all gooped up. I drilled a hole in a G1/4" plug, just slightly bigger than the metal ring on the sensor, coated that ring with J-B Weld, and inserted it, letting it cure before grinding away the exterior of the top of the plug and building up more J-B weld to add some strain relief for the wires as well as edge-to-edge sealing. The current vacuum loss rate, after running the system for a few months, allowing the loop to very thoroughly de-gas, is now less than 50mbar per day at -500 to -600mbar. I was slightly worried about the lifetime of the pump, given it’s a cheap thing from Amazon, but given it only has to run for about a second every 2-3 days, I imagine that won’t be an issue.
Here’s a quick video showing the system not leaking!
This pressure sensor is a wheatstone bridge, which works the same way as load cells for digital scales. The resistance changes are very, very low, thus the signal must be amplified before being fed into an ADC. You could use an op-amp, and feed that signal into an analog input on the Arduino, but I felt more comfortable using the HX711, a two-channel ADC with integrated amplifier designed to be used with wheatstone bridge load cells. Here’s a code snippet showing how I converted the raw analog measurement to mbar.
float pressure_raw_to_mbar ( int32_t pressure_raw ) {
+ return ( pressure_raw - 390000 ) * ( 1700.0 / ( 5600000 - 390000 )) - 700 ;
+ }
+
I calibrated it manually, comparing it to an analogue gauge. It’s calibrated to a zero point at atmospheric pressure in my locale, and from -700mbar to +1000mbar. I figured out that, when setting the HX711 to a gain of 64 with the Adafruit HX711 library, a change of 100mbar is a change in the ADC measurement by 30k, highly consistent across the entire pressure range that I tested. I can’t be 100% sure how accurate the analogue gauge is, but 100% accuracy doesn’t really matter for this application. All I really need to know is the fact that an adequate vacuum is present, and a general idea of the leak rate, which is a requirement that this setup meets.
Other stuff
# I got a beefy PWM motor driver with L298 logic, claiming a continuous current of 7 amps per channel, which nicely fit my requirements. 120mm PC fans are typically 0.2-0.3 amps, and mine in particular are 0.25. For 18 fans, it should be approximately 4.5 amps at 100% speed. It’s a bit oversized, and I’m only using one channel, but it leaves me the option in the future to use larger, generic radiator fans that have more demanding power requirements. I’m already down two from eighteen, eventually enough of them are going to fail that I’ll have to find another solution.
Required additions to the solenoid, pump motor, and the complete assembly without cover. In my initial tests, I found that operating the pump and solenoid would cause the Arduino to reset, seemingly at random, or cause other undefined behavior. Since they were not electrically isolated on a second power supply, that makes sense. They were backfeeding energy and causing a notable amount of general interference during operation, to the point that the LEDs on the inactive relay modules would dimly illuminate when the motor was in operation, and very visibly illuminate whenever the motor or the solenoid deactivated. I had to add flyback diodes, and, for peace of mind, I added ceramic filtering capacitors to the pump as well. Those additions completely eliminated the issue. Below is a video demonstrating the bad behavior.
I did a similar plug-drilling setup for the water temperature sensor with a generic Dallas temperature probe. The air probe was taped to the exterior of the box, in the path of the incoming air. All that remained was to solder up a sort of bus bar for the radiator fan connectors, get the temperature probes and pull-up resistors wired into the proto board, and hook everything up to the Arduino, then write the software to tie it all together.
The Software
# rawhide_k/server-watercooling-controller
The Arduino operates independently, without a server. The fan speed and loop pressure are managed autonomously. The serial connection is only used to report vital stats, for later integration into more connected monitoring systems. Ultimately, there are only two actions it can take: Change the fan speed, and turn on the vacuum pump. Neither of these require any external knowledge. It doesn’t need any information about the connected hardware to function correctly. All it’s concerned with is keeping the water temperature at a certain delta above ambient temperature, and keeping the loop pressure within a certain range. Ultimately, very simple.
Once per second, the temperature sensors are sampled, the PID loop for the fans runs with the new temperature data points, and the fan speed, temperature data, vacuum pressure, and pump/flow measurements are sent over serial with the help of the ArduinoJSON library. I settled on a target water delta of 4*C relative to ambient, with a chosen min/max temperature range where the fans turn off or pin themselves to 100% completely. The 4*C delta is rather arbitrary. It’s approximately the delta that exists when the systems are on, but idle, and the fans are at their minimum speed. That delta can be maintained during 100% CPU load, and during medium-heavy GPU loads, but not both combined. It still stays well under a 10*C delta in that case, though, so I can’t complain.
There are also hard stops to turn the fans off if the water temperature hits 5*C, and pin them to max if it hits 40*C. I’m not sure how realistic either of those figures are, but it’s better to be safe than frozen up and/or exploded.
int fan_PID ( float * air_temp , float * water_temp , uint32_t * cur_loop_timestamp ) {
+ static const float kp = 120.0 ;
+ static const float ki = 0.16 ;
+ static const float kd = 4.0 ;
+
+ static float integral = 0 ;
+ static float derivative = 0 ;
+ static float last_error = 0 ;
+ static float error ;
+ static float delta ;
+ static float last_time = * cur_loop_timestamp ;
+ static const float min_water_temp = 5.0 ;
+ static const float max_water_temp = 40.0 ;
+ static const uint8_t min_fan_speed = 90 ;
+ static const uint8_t max_fan_speed = 255 ;
+
+ static const uint8_t temp_target_offset = 4 ;
+ static const uint8_t fan_offset = 10 ;
+
+ static int16_t fan_speed ;
+
+ if ( * water_temp >= max_water_temp ) {
+ return max_fan_speed ;
+ }
+
+ else if ( * water_temp <= min_water_temp ) {
+ return 0 ;
+ }
+
+ else {
+ error = * water_temp - min ( * air_temp + temp_target_offset , max_water_temp );
+ delta = * cur_loop_timestamp - last_time ;
+
+ //mitigate unlimited integral windup
+ if ( fan_speed == max_fan_speed ) {
+ integral += error * delta ;
+ }
+
+ if ( * air_temp + temp_target_offset > * water_temp - 1 ) {
+ integral = 0 ;
+ }
+
+ derivative = ( error - last_error ) / delta ;
+ fan_speed = round ( constrain ( min_fan_speed + fan_offset + ( kp * error + ki * integral + kd * derivative ), min_fan_speed , max_fan_speed ));
+ last_error = error ;
+ return fan_speed ;
+ }
+ }
+
Occasionally, the temperature probes as well as the HX711 return spurious readings that cause poor behavior, such as crashing the Arduino. In particular, the temperature probes will sometimes return -127, which caused my PID algorithm to crash the Arduino for reasons I could not divine.
For the temperature probes, I simply ignore the one problematic result that I’ve observed.
new_water_temp = sensors . getTempC ( water_therm );
+new_air_temp = sensors . getTempC ( air_therm );
+
+ if ( new_water_temp != - 127 ) {
+ water_temp = new_water_temp ;
+ }
+
+ if ( new_air_temp != - 127 ) {
+ air_temp = new_air_temp ;
+ }
+
+ sensors . requestTemperatures ();
+
In case of any other freezing/crashing issues, I also enabled the watchdog timer for 2 seconds. So, if, for some reason, it does freeze/crash, it should self reset after 2 seconds. It seems to be working, although I guess time will tell in the long-term. I haven’t experienced any operation issues since I added it over a month ago. The other concern is undefined behavior when the timer overflows. The Uno only has a 32-bit timer, so it will overflow around 50 days of uptime. This function pre-emptively resets it.
//we will use this function to periodically self-reset to avoid timer overflows
+ void ( * resetFunc ) ( void ) = 0 ;
+
+ ...
+
+ //reset the system when approaching timer overflow
+ if ( cur_loop_timestamp >= 4000000000 ) {
+ resetFunc ();
+ }
+
In addition to the temperature probe problem, the HX711 occasionally returns wildly wrong results that need to be filtered out. To compensate for that, if the pressure dips below the threshold, I wait one second, and if the pressure is still below the threshold, I then begin pumping. This check happens approximately ten times per second, as the default behavior of the HX711 board that I have is to run in 10hz mode. I’m not sure if the issue springs from some kind of interference with the tachometer interrupts messing up the signaling timing, or if I’m misunderstanding the correct way to sample the HX711 over time.
if ( cur_loop_timestamp - last_pressure_check >= 100 ) {
+ loop_pressure = pressure_raw_to_mbar ( hx711 . readChannelRaw ( CHAN_A_GAIN_64 ));
+
+ if ( sucking == false ) {
+ if ( loop_pressure > low_pressure_threshold ) {
+ if ( checking_low_pressure == false ) {
+ checking_low_pressure = true ;
+ low_pressure_confirmation_timestamp = cur_loop_timestamp ;
+ }
+ if ( cur_loop_timestamp - low_pressure_confirmation_timestamp >= 1000 ) {
+ digitalWrite ( pump_relay , HIGH );
+ digitalWrite ( solenoid_relay , HIGH );
+ sucking = true ;
+ checking_low_pressure = false ;
+ }
+ }
+
+ else if ( cur_loop_timestamp - low_pressure_confirmation_timestamp >= 1000 ) {
+ checking_low_pressure = false ;
+ }
+ }
+
+ else {
+ if ( loop_pressure < high_pressure_threshold ) {
+ digitalWrite ( pump_relay , LOW );
+ digitalWrite ( solenoid_relay , LOW );
+ sucking = false ;
+ }
+ }
+ last_pressure_check = cur_loop_timestamp ;
+ }
+
Currently, my server-side software is incomplete. It’s just a brute-force JSON-over-serial reader written in Python, that I glance at from time to time. I plan write a Zabbix bridge, and have that manage the monitoring, alerts, and reactions to catostraphic events, once I have Zabbix properly setup for my systems… But that hasn’t happened just yet. I don’t expect it to be a particularly interesting event, but if anything comes up I might write a post about it.
Other Thoughts?
# The Arduino’s software hadn’t been 100% finalized when I took the below pictures. The control box does have a lid now, and all the cable management is a lot cleaner… Promise!
Everything installed and working! When I was testing it, I had an incident where the Arduino crashed, which means the fans stopped… That’s a big drawback with the motor controller that I have, it fails off instead of on. But, I haven’t experienced any more issues after adding those software fixes. At that time, I was running a full GPU workload… The water temperature exceeded 70*C. It happened at night, and I have no idea how long it ran like that… Hours. Pretty scary stuff, but it all came out alright.
This project had a lot of firsts for me. It was the first time I’ve done any kind of embedded-adjacent development beyond “ooooo look at the blinky light, oooooooo it turns off when you press the button, wwaaaow”, and the first time I’d designed something with so many individual parts. I’ve never worked with air pumps, solenoids, or pressure sensing before, nor had to debug issues like the lack of flyback diodes.
The biggest mistake I made was using that stupid battery box. It’s steel, and I don’t have the tools or experience to work with steel in the way that I intended to. I thought it would look cool, and it does, but if I did it again, I’d use a generic aluminum or plastic project box instead, because it took two entire days plus waiting for new drill bits that can actually cut through it.
If I were to ever take it apart again, I’d add a passthrough for the SPI header, and/or an external reset button. I should have gotten a physical display of some type that could show the sensors and debug info on the device itself without being connected to another device to readout the data.
I’d like to get a second pump, for redundancy’s sake and to increase the flow rate. But it’s going to be such a pain to install that I feel like I’m never going to bother to do it, unless the current pump fails, or I add more components to be cooled and the flow is adversely affected. I was slightly concerned about the evaporation rate of the liquid via the vacuum tank, and that I’d need to add some kind of fluid level detection system, but there’s been no noticeable loss thus far. Now that I know the pump turns on so infrequently, I can’t imagine that it’s going to need to be topped up anytime soon.
In terms of value… This was unbelievably bad. Buying tower coolers would have allowed the CPUs to run without throttling, and buying another GPU would have overpowered any benefits gained by NVLINK. I haven’t tallied up exactly how much I spent on it, but it was at least $1000, including buying new tools and excess materials that I haven’t fully used, and excluding the original cost of re-using some parts I already had. I’ve added risk, maintenance overhead, and pain whenever I swap out hardware in the future. Custom watercooling is an ongoing abusive relationship between your fingertips and your ego, or your fascination for slightly more optimized numbers on a screen… But I’d do it again in a heartbeat, because it was fun.
Reply by Email
\ No newline at end of file
diff --git a/public/posts/watercooling-homelab/schematic_minify.svg b/public/posts/watercooling-homelab/schematic_minify.svg
new file mode 100644
index 0000000..22ed0ef
--- /dev/null
+++ b/public/posts/watercooling-homelab/schematic_minify.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/posts/watercooling-my-homelab/featured.webp b/public/posts/watercooling-my-homelab/featured.webp
new file mode 100644
index 0000000..13a7602
Binary files /dev/null and b/public/posts/watercooling-my-homelab/featured.webp differ
diff --git a/public/posts/watercooling-my-homelab/featured_hu11504899310106128621.webp b/public/posts/watercooling-my-homelab/featured_hu11504899310106128621.webp
new file mode 100644
index 0000000..c367236
Binary files /dev/null and b/public/posts/watercooling-my-homelab/featured_hu11504899310106128621.webp differ
diff --git a/public/posts/watercooling-my-homelab/featured_hu13568191302889737537.webp b/public/posts/watercooling-my-homelab/featured_hu13568191302889737537.webp
new file mode 100644
index 0000000..87b93fe
Binary files /dev/null and b/public/posts/watercooling-my-homelab/featured_hu13568191302889737537.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A.webp b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A.webp
new file mode 100644
index 0000000..7e3f636
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu9356083241289898304.webp b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu1954630252676748703.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu9356083241289898304.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu1954630252676748703.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu6984269313153752643.webp b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu6560107379008232574.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu6984269313153752643.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu6560107379008232574.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu6397503244716169044.webp b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu7088133987632116537.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu6397503244716169044.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu7088133987632116537.webp
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B.webp b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B.webp
new file mode 100644
index 0000000..ea421c2
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu12155478021797826213.webp b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu12155478021797826213.webp
new file mode 100644
index 0000000..5646d45
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu12155478021797826213.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu2333850158973680984.webp b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu2333850158973680984.webp
new file mode 100644
index 0000000..c37bb25
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu2333850158973680984.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu5952309977048855875.webp b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu5952309977048855875.webp
new file mode 100644
index 0000000..4ca7a9d
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu5952309977048855875.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Coldplate.webp b/public/posts/watercooling-my-homelab/images/compressed/Coldplate.webp
new file mode 100644
index 0000000..d1a9c7d
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Coldplate.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Coldplate_hu13174017899928575525.webp b/public/posts/watercooling-my-homelab/images/compressed/Coldplate_hu13174017899928575525.webp
new file mode 100644
index 0000000..b54c589
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Coldplate_hu13174017899928575525.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Coldplate_hu16258961307282205929.webp b/public/posts/watercooling-my-homelab/images/compressed/Coldplate_hu16258961307282205929.webp
new file mode 100644
index 0000000..f9ca293
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Coldplate_hu16258961307282205929.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Coldplate_hu3290250784134948227.webp b/public/posts/watercooling-my-homelab/images/compressed/Coldplate_hu3290250784134948227.webp
new file mode 100644
index 0000000..38e9921
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Coldplate_hu3290250784134948227.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Different_Plugs.webp b/public/posts/watercooling-my-homelab/images/compressed/Different_Plugs.webp
new file mode 100644
index 0000000..1ba45cf
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Different_Plugs.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu13876830105851013017.webp b/public/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu17890886748642996535.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu13876830105851013017.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu17890886748642996535.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu11688300824440909668.webp b/public/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu2378229743182206831.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu11688300824440909668.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu2378229743182206831.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu12922261886977581896.webp b/public/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu3502703824848779819.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu12922261886977581896.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu3502703824848779819.webp
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom.webp b/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom.webp
new file mode 100644
index 0000000..15972ff
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu1233157730881247055.webp b/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu1233157730881247055.webp
new file mode 100644
index 0000000..7985b6b
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu1233157730881247055.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu1716452709661764841.webp b/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu1716452709661764841.webp
new file mode 100644
index 0000000..26a05c9
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu1716452709661764841.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu478575305574189147.webp b/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu478575305574189147.webp
new file mode 100644
index 0000000..1e9fc92
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_hu478575305574189147.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/GPUs_Installed.webp b/public/posts/watercooling-my-homelab/images/compressed/GPUs_Installed.webp
new file mode 100644
index 0000000..b545a26
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/GPUs_Installed.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu4439790823947660511.webp b/public/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu1860541658624349795.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu4439790823947660511.webp
rename to public/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu1860541658624349795.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu405899069562073892.webp b/public/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu1923429014339473058.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu405899069562073892.webp
rename to public/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu1923429014339473058.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu3799253580645485008.webp b/public/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu4193758725753816349.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu3799253580645485008.webp
rename to public/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_hu4193758725753816349.webp
diff --git a/public/posts/watercooling-my-homelab/images/compressed/MO-RA!.webp b/public/posts/watercooling-my-homelab/images/compressed/MO-RA!.webp
new file mode 100644
index 0000000..9357b11
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/MO-RA!.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu9356083241289898304.webp b/public/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu15264814207577810858.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu9356083241289898304.webp
rename to public/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu15264814207577810858.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu6984269313153752643.webp b/public/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu6856946684884405237.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu6984269313153752643.webp
rename to public/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu6856946684884405237.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu6397503244716169044.webp b/public/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu7453820902150892044.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu6397503244716169044.webp
rename to public/posts/watercooling-my-homelab/images/compressed/MO-RA!_hu7453820902150892044.webp
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail.webp b/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail.webp
new file mode 100644
index 0000000..8099cdb
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu11231283172588266533.webp b/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu11231283172588266533.webp
new file mode 100644
index 0000000..4055cc0
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu11231283172588266533.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu1490212990626714303.webp b/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu1490212990626714303.webp
new file mode 100644
index 0000000..8931075
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu1490212990626714303.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu3280937936208174423.webp b/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu3280937936208174423.webp
new file mode 100644
index 0000000..734f8aa
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu3280937936208174423.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor.webp b/public/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor.webp
new file mode 100644
index 0000000..06b27f6
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu4934561748590927396.webp b/public/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu1042940534242500862.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu4934561748590927396.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu1042940534242500862.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu14827369144277650222.webp b/public/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu11882410216080315790.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu14827369144277650222.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu11882410216080315790.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu9574847335040547215.webp b/public/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu3985119007043451200.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu9574847335040547215.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_hu3985119007043451200.webp
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Test_Fit.webp b/public/posts/watercooling-my-homelab/images/compressed/Test_Fit.webp
new file mode 100644
index 0000000..51fdbef
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Test_Fit.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu2884804705215397458.webp b/public/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu2884804705215397458.webp
new file mode 100644
index 0000000..878d0f2
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu2884804705215397458.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu4196319411009163019.webp b/public/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu4196319411009163019.webp
new file mode 100644
index 0000000..95ea791
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu4196319411009163019.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu6466058294895506811.webp b/public/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu6466058294895506811.webp
new file mode 100644
index 0000000..8314386
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Test_Fit_hu6466058294895506811.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank.webp b/public/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank.webp
new file mode 100644
index 0000000..c168c74
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu6397503244716169044.webp b/public/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu10619128996450324123.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu6397503244716169044.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu10619128996450324123.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu6984269313153752643.webp b/public/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu17456463471095554312.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu6984269313153752643.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu17456463471095554312.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu9356083241289898304.webp b/public/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu3171065713872445154.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu9356083241289898304.webp
rename to public/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu3171065713872445154.webp
diff --git a/public/posts/watercooling-my-homelab/images/compressed/complete_a.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_a.webp
new file mode 100644
index 0000000..39a4915
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/complete_a.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/complete_a_hu11784685921316552556.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_a_hu11784685921316552556.webp
new file mode 100644
index 0000000..a58dd35
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/complete_a_hu11784685921316552556.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/complete_a_hu2347091142476872481.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_a_hu2347091142476872481.webp
new file mode 100644
index 0000000..95d622f
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/complete_a_hu2347091142476872481.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/complete_a_hu2371455810172732269.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_a_hu2371455810172732269.webp
new file mode 100644
index 0000000..d5be382
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/complete_a_hu2371455810172732269.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/complete_assembly.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_assembly.webp
new file mode 100644
index 0000000..2656402
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/complete_assembly.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu6984269313153752643.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu13996029485759007548.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu6984269313153752643.webp
rename to public/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu13996029485759007548.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu6397503244716169044.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu17913719379729244320.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu6397503244716169044.webp
rename to public/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu17913719379729244320.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu9356083241289898304.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu402138244258743400.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu9356083241289898304.webp
rename to public/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu402138244258743400.webp
diff --git a/public/posts/watercooling-my-homelab/images/compressed/complete_b.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_b.webp
new file mode 100644
index 0000000..7624992
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/complete_b.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/complete_b_hu10235357959924345043.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_b_hu10235357959924345043.webp
new file mode 100644
index 0000000..1aee7a1
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/complete_b_hu10235357959924345043.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/complete_b_hu10444887637626475779.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_b_hu10444887637626475779.webp
new file mode 100644
index 0000000..71f69df
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/complete_b_hu10444887637626475779.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/complete_b_hu12966552216401371125.webp b/public/posts/watercooling-my-homelab/images/compressed/complete_b_hu12966552216401371125.webp
new file mode 100644
index 0000000..7cdfe35
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/complete_b_hu12966552216401371125.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/goopy_installed.webp b/public/posts/watercooling-my-homelab/images/compressed/goopy_installed.webp
new file mode 100644
index 0000000..892ab04
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/goopy_installed.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu14022192958183349575.webp b/public/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu13878470882578617902.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu14022192958183349575.webp
rename to public/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu13878470882578617902.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu6572088406921936810.webp b/public/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu7775517930751145146.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu6572088406921936810.webp
rename to public/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu7775517930751145146.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu3978349436068542195.webp b/public/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu8582164235252167480.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu3978349436068542195.webp
rename to public/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu8582164235252167480.webp
diff --git a/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom.webp b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom.webp
new file mode 100644
index 0000000..6a5b125
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu12744847709972265499.webp b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu12744847709972265499.webp
new file mode 100644
index 0000000..b00ac4e
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu12744847709972265499.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu3645814594706023691.webp b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu3645814594706023691.webp
new file mode 100644
index 0000000..2299aaf
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu3645814594706023691.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu3698649971536149681.webp b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu3698649971536149681.webp
new file mode 100644
index 0000000..8c313f0
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_hu3698649971536149681.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/plug_detail_top.webp b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_top.webp
new file mode 100644
index 0000000..ba5e400
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_top.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu6397503244716169044.webp b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu13627305942680874943.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu6397503244716169044.webp
rename to public/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu13627305942680874943.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu9356083241289898304.webp b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu16358936284331608818.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu9356083241289898304.webp
rename to public/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu16358936284331608818.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu6984269313153752643.webp b/public/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu7787027711586187933.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu6984269313153752643.webp
rename to public/posts/watercooling-my-homelab/images/compressed/plug_detail_top_hu7787027711586187933.webp
diff --git a/public/posts/watercooling-my-homelab/images/compressed/pump_greeble.webp b/public/posts/watercooling-my-homelab/images/compressed/pump_greeble.webp
new file mode 100644
index 0000000..7fb245d
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/pump_greeble.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu1040829716072557719.webp b/public/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu1040829716072557719.webp
new file mode 100644
index 0000000..46ec6fe
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu1040829716072557719.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu1471177938307566585.webp b/public/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu1471177938307566585.webp
new file mode 100644
index 0000000..1bf2e3f
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu1471177938307566585.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu4319233910559987333.webp b/public/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu4319233910559987333.webp
new file mode 100644
index 0000000..4bc261a
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/pump_greeble_hu4319233910559987333.webp differ
diff --git a/public/posts/watercooling-my-homelab/images/compressed/solenoid_diode.webp b/public/posts/watercooling-my-homelab/images/compressed/solenoid_diode.webp
new file mode 100644
index 0000000..1893a28
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/compressed/solenoid_diode.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu6984269313153752643.webp b/public/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu13681423255705621406.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu6984269313153752643.webp
rename to public/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu13681423255705621406.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu6397503244716169044.webp b/public/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu14196543121366269339.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu6397503244716169044.webp
rename to public/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu14196543121366269339.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu9356083241289898304.webp b/public/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu3904316093352162951.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu9356083241289898304.webp
rename to public/posts/watercooling-my-homelab/images/compressed/solenoid_diode_hu3904316093352162951.webp
diff --git a/public/posts/watercooling-my-homelab/images/original/Block_Mod_Detail_A.jpg b/public/posts/watercooling-my-homelab/images/original/Block_Mod_Detail_A.jpg
new file mode 100644
index 0000000..5266b0f
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/Block_Mod_Detail_A.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/Block_Mod_Detail_B.jpg b/public/posts/watercooling-my-homelab/images/original/Block_Mod_Detail_B.jpg
new file mode 100644
index 0000000..5abe309
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/Block_Mod_Detail_B.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/Coldplate.jpg b/public/posts/watercooling-my-homelab/images/original/Coldplate.jpg
new file mode 100644
index 0000000..255d51b
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/Coldplate.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/Different_Plugs.jpg b/public/posts/watercooling-my-homelab/images/original/Different_Plugs.jpg
new file mode 100644
index 0000000..cad6902
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/Different_Plugs.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/Dual_Blocks_Zoom.jpg b/public/posts/watercooling-my-homelab/images/original/Dual_Blocks_Zoom.jpg
new file mode 100644
index 0000000..61978ee
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/Dual_Blocks_Zoom.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/GPUs_Installed.jpg b/public/posts/watercooling-my-homelab/images/original/GPUs_Installed.jpg
new file mode 100644
index 0000000..5928d30
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/GPUs_Installed.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/MO-RA!.jpg b/public/posts/watercooling-my-homelab/images/original/MO-RA!.jpg
new file mode 100644
index 0000000..511a10c
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/MO-RA!.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/Mounting_Detail.jpg b/public/posts/watercooling-my-homelab/images/original/Mounting_Detail.jpg
new file mode 100644
index 0000000..4840763
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/Mounting_Detail.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/Tall_Capacitor.jpg b/public/posts/watercooling-my-homelab/images/original/Tall_Capacitor.jpg
new file mode 100644
index 0000000..f5ef26a
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/Tall_Capacitor.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/Test_Fit.jpg b/public/posts/watercooling-my-homelab/images/original/Test_Fit.jpg
new file mode 100644
index 0000000..ba6a65f
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/Test_Fit.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/Triple_Card_Jank.jpg b/public/posts/watercooling-my-homelab/images/original/Triple_Card_Jank.jpg
new file mode 100644
index 0000000..d42f624
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/Triple_Card_Jank.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/complete_a.jpg b/public/posts/watercooling-my-homelab/images/original/complete_a.jpg
new file mode 100644
index 0000000..b9c6604
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/complete_a.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/complete_assembly.jpg b/public/posts/watercooling-my-homelab/images/original/complete_assembly.jpg
new file mode 100644
index 0000000..26e673e
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/complete_assembly.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/complete_b.jpg b/public/posts/watercooling-my-homelab/images/original/complete_b.jpg
new file mode 100644
index 0000000..8bb3fb8
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/complete_b.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/featured.jpg b/public/posts/watercooling-my-homelab/images/original/featured.jpg
new file mode 100644
index 0000000..73db392
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/featured.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/goopy_installed.jpg b/public/posts/watercooling-my-homelab/images/original/goopy_installed.jpg
new file mode 100644
index 0000000..cf2d831
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/goopy_installed.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/plug_detail_bottom.jpg b/public/posts/watercooling-my-homelab/images/original/plug_detail_bottom.jpg
new file mode 100644
index 0000000..d0b3595
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/plug_detail_bottom.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/plug_detail_top.jpg b/public/posts/watercooling-my-homelab/images/original/plug_detail_top.jpg
new file mode 100644
index 0000000..0f5dd00
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/plug_detail_top.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/pump_greeble.jpg b/public/posts/watercooling-my-homelab/images/original/pump_greeble.jpg
new file mode 100644
index 0000000..a3b6e85
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/pump_greeble.jpg differ
diff --git a/public/posts/watercooling-my-homelab/images/original/solenoid_diode.jpg b/public/posts/watercooling-my-homelab/images/original/solenoid_diode.jpg
new file mode 100644
index 0000000..875545b
Binary files /dev/null and b/public/posts/watercooling-my-homelab/images/original/solenoid_diode.jpg differ
diff --git a/public/posts/watercooling-my-homelab/index.html b/public/posts/watercooling-my-homelab/index.html
new file mode 100644
index 0000000..3f12581
--- /dev/null
+++ b/public/posts/watercooling-my-homelab/index.html
@@ -0,0 +1,1842 @@
+
+
+
+
+
+
+
+
+
+ Watercooling My Homelab · N.E.E.T. Works
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Table of Contents
+
+
+
+
+
+ Table of Contents
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Overview
+
+
+
+ #
+
+
+
+
I’ve been watercooling my desktop since 2020, and case modding custom cooling solutions since my first modern dGPU in 2012. I enjoy it for the aesthetic, as well as the ability to run my hardware to the redline, despite the lower gains that modern hardware has… It’s still fun to try and see how high you can get on benchmark scoreboards. It was a big initial investment, but with most parts being reusable, the ongoing cost for component upgrades are minimal. Early in 2024, I bought some GPUs to use for dedicated ML tasks in my server rack, and immediately had watercooling on the mind. There weren’t particularly strong reasons to do so, but it would lower the power usage a bit, give me some more VRAM overclocking headroom, and give me a bit more core clock stability, as well as the ability to use a cheap two-slot NVLINK connector without suffocating a GPU.
+
+
+
+
+
+
+
+
+
+
+
+
My initial setup with 3x 2080 Tis, using m.2 NVMe to PCIe risers in an ASUS prebuilt. Two are connected by NVLINK, which I found to provide a slight performance benefit on the order of ~1-5% in multi-GPU SISR training, which is not worth the typical price for NVLINK bridges from this era. I was lucky to get this ugly, quadro-oriented bridge for just $40.
+
+
I’ve never had a leak on my desktop, but with wider temperature swings in my garage, and collectively, a whole lot more expensive hardware that might get damaged than compared to my desktop setup, I was hesitant. The benefits seemed minimal, and I considered it a fun what-if scenario until I upgraded my main server and discovered that the forced-air passive chassis cooling was insufficient for my new CPUs. At that point, I had to make a decision: Get better heatsinks, which would be single-purpose and cost in excess of $100 each, or whole rack watercooling. I chose whole rack watercooling.
+
With enough reason for me to go ahead with the project, and the only thing holding me back being a fear of leaks, I had to figure out how to actively monitor for, and preferably prevent such an eventuality. I happened upon a product called LEAKSHIELD , from Aqua Computer, that advertised itself as doing exactly that.
+
+
+
How does it work? You pull a vacuum inside the fluid loop and monitor the loss rate. Water can’t get out if air is trying to get in, and if air gets in, the vacuum is reduced. It’s so simple, I don’t know why it took this long for such a product to enter the PC watercooling space. I could have just bought a LEAKSHIELD and called it a day, but Aqua Computer’s software doesn’t support Linux, and the specs for the vacuum pump seemed a bit weak for a loop of my scale. But, its functionality was something I was confident I could emulate with more robust off-the-shelf parts. Thus, sufficiently armed with esoteric plumbing knowledge, I took the plunge and started loading up on parts.
+
+
+
The Hardware
+
+
+
+ #
+
+
+
+
Most of the build uses pretty standard off-the-shelf parts for PC watercooling, but there are a few bits and pieces that most builders won’t have seen before, and a custom control system that offers a more relevant experience for a server rack. The control system is based on an Arduino Uno that feeds vital statistics over serial, and features pressure control and monitoring similar to the LEAKSHIELD, with fan control based on a PID algorithm keeping the water temperature at a fixed setpoint above ambient.
+
+
+
Off-the-shelf
+
+
+
+ #
+
+
+
+
+
+
General Details
+
+
+
+ #
+
+
+
+
The centerpiece of the build, which the control unit and pump mount to, is the “MOther of all RAdiators”, version 3, from Watercool. This is the 360mm version with support for up to 18x 120mm fans, or 8x 180mm fans. It’s constructed more in the spirit of a vehicle radiator than a traditional PC radiator, with a less restrictive fin stack and large, round tubes rather than thin rectangular ones. It provides several mounting points for accessories which I was able to utilize to secure it to my server rack in a satisfactorily sturdy fashion. An in-depth teardown on the construction method and material quality of the MO-RA can be found on igor’sLAB . For fans, I have a collection of old DC-control Corsair Air Series SP120s. They’ve all been retired from regular use, because of noise-related aging issues. In fact, one of them failed to turn at all once I had everything wired up, and another had its bearing disintegrate about 8 weeks after putting the thing into service. That being said, they did survive (and continue to survive, in the remaining 16 cases) 24/7 use for anywhere from 4-10 years, at bottom of the barrel pricing, so that’s not too bad. I’m not exactly pushing the limits of this radiator here, so a few fans breaking down over time isn’t the end of the world.
+
+
+
+
+
+
+
+
+
+
+
+
A MO-RA V3 360 PRO PC Watercooling Radiator from Watercool
+
+
I got a secondhand Corsair XD5 pump/res combo from eBay for about sixty bucks, which is pretty good for a genuine D5-based pump/res combo. It has PWM support which I did wire up, but the flow ended up being rather anemic even at 100%, so I just run it full speed all the time. The flow rate is measured through an Aqua Computer flow sensor , which is simply a hall-effect tachometer translated to l/h through software. I did not attempt to verify the accuracy of the sensor in my setup. The absolute accuracy is less relevant than simply getting an overall idea of whether or not the measurement is consistent with flow behavior, which it is.
+
+
+
+
+
+
+
+
+
+
+
+
Simple, cheap aluminum bars and angles mount to the studs on the radiator and into the stud holes on the server rack, and the pump and control box mount onto brackets along with the fans.
+
+
+
+
CPUs
+
+
+
+ #
+
+
+
+
My thermally problematic server upgrade was to dual Xeon Gold 6154s, which are Skylake-SP architecture. This specific SKU is pretty beefy, with 18 cores at sustained all-core speeds of 3.7GHz SSE / 3.3GHz AVX2 / 2.7GHz AVX512, and a TDP of 200 watts. The rated tjmax was 105C, and with the chassis cooling, they readily met that and started throttling under all-core loads, with idle as high as 60-70*C. I previously had Xeon E5-2697 v2s, which had TDPs of 130w. They got toasty, but never throttled. I’m not sure if the chassis had any easy fan upgrades available that might have made a difference, and I certainly could have moved to 4u-compatible tower coolers rather than forced air, but since I wanted to watercool the GPUs anyway, adding the CPUs as well would be minimal cost/effort, with more future compatibility for the waterblocks compared to a specialized LGA3647 tower cooler.
+
+
+
+
+
+
+
+
+
+
+
+
Alphacool Eisblock XPX Pro coldplate Image credit & copyright - igor’sLAB
+
+
The CPU waterblocks are Alphacool Eisblock XPX Pro Aurora Light models, which are significantly cheaper than the XPX Aurora Pro not-light version. They appear to be entirely identical, functionally… I’m not sure if there any actual performance benefits offered by the not-light version. It’s a relatively obscure block family without many thorough reviews, which makes sense, given this block is designed for full coverage on Xeons/Threadrippers. The coldplate appears to be skived , which is uncommon in this price bracket for a discrete block, and the fins are incredibly short and dense. In smaller desktop loops, I’ve seen this block criticized for having overly restrictive flow, but when you have four blocks + quick disconnects, “good” flow is relative. At the power limit of 200w, the maximum core temperature delta relative to the water temperature is 25*C, with a ~1-2*C average delta between the two serially-connected sockets at a flow rate of ~130L/h, and that’s more than sufficient.
+
+
+
+
+
+
+
+
+
+
+
+
Interior view of the Supermicro CSE-846 chassis showcasing the installed waterblocks and other components.
+
+
+
+
GPUs
+
+
+
+ #
+
+
+
+
The GPU blocks are Phanteks 2080 Ti Founder’s Edition blocks. Nothing special, they’re just the cheapest matching ones I could find in 2024 that looked like they’d fit these almost-reference-but-not-quite OEM cards. They’re generic OEM models that would have gone in prebuilts. The most interesting thing about these cards, is that they’ve been modded to have 22GB of VRAM. There’s a dedicated supplier still offering them, and it’s by far the best $/GB value for VRAM in modern NVIDIA GPUs. Whether or not this is a better value overall than, say, a 3090 (Ti) depends on your usecase. Performance improvements in ML tasks between the 2080 Ti and 3090 (Ti) range from as little as ~20% to as much as ~100% depending on how memory bandwidth constrained your workload is. With secondhand 3090 (Ti)s still going for minimum $700 on the used market in the US, I found the alternative 2080 Ti option to be more alluring for my usecase, which is primarily single image super-resolution. More VRAM is desirable to increase the size of tiles for inference, and to increase the batch size during training. Training speed scales almost linearly, and inference speed scales linearly, per GPU. So, for my usecase, where I’m not really limited by the performance of a single GPU, the 2080 Ti mod route offers better overall value both for VRAM and combined core performance compared to 3090 (Ti)s. The idea of having a modded GPU in itself was also appealing and definitely part of why I made that decision. Pulling up a hardware monitor and seeing a 2080 Ti with 22GB of VRAM feels a little bit naughty, and I like that.
+
+
+
+
+
+
+
+
+
+
+
+
The blocks installed in an ASUS prebuilt gaming tower.
+
+
I did initially buy three of them, as pictured at the beginning of this post, but one of them failed just after the 30 day warranty period listed on their website. Despite that, they were kind enough to offer a full refund if I covered return shipping, and were very communicative and responded in <24 hours every time I sent them any kind of message/inquiry.
+
The biggest benefit that watercooling theoretically brings to modern video cards is a prolonged lifespan. Not due to lower core temperatures, in an absolute sense, but due to the reduced stress from thermal cycles. Mismatches in the rate of thermal expansion between the die and the substrate will eventually cause their bond to break, and this happens faster the larger your die is, and the more extreme the temperature differences are. Today’s GPU dies are huge, and it’s hard to say how many failures are attributable to this factor alone, but it is certain to be more of a risk than it has been in the past. I’d rather buy a used mining GPU than a used gaming GPU any day, because it has likely been kept at roughly the same temperature for most of its life, as opposed to experiencing wide periodic swings.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The GPU blocks required a moderate amount of light massaging to properly fit on these OEM model cards. The power plugs are in a different position and a singular capacitor on these models is slightly taller than on the actual Founder’s Edition reference card, but they’re otherwise close enough to identical.
+
+
That’s not to say that there are no benefits from lowering the operating temperature. As an absolute value, within manufacturer limits, it affects boost clocks, and leakage current . A cooler chip will use less power to run at the same clock speed compared to a hotter chip due to reduced leakage current, making them measurably more energy efficient per clock cycle the colder they run. In my case, with the fan on max, while not thermal throttling, these GPUs would bounce off the power limit of 280w while attempting to hit a core clock of 1800MHz. Under water, at a reported core temperature of ~30*C, the reported board power draw is only ~220w at 1800MHz core clock for the same workload. The type of fan typically found in these coolers is rated anywhere from 15-30w on its own, so a reduction of at least 30w can likely be attributed to a lower leakage current.
+
+
+
DIY Time
+
+
+
+ #
+
+
+
+
In no particular order, here is a list of the major components involved in the control system.
+
+Generic metal box, formerly from a PBX system.
+Arduino Uno clone, unknown brand
+60mm Corsair fan
+RS232 TTL shifter
+Aesthetic retro power switch
+12v DC vacuum pump
+U.S. Solid 12V NC Solenoid
+12v relay modules
+HX711 ADC
+MD-PS002 Absolute Pressure Sensors
+L298-like PWM motor driver
+Apple White iMac PSU
+Adafruit Arduino Uno Proto Shield
+DS18B20 temperature probes
+
+
+
+
+
+
+
+
+
+
+
+
+
Fit check for all the major components.
+
+
I didn’t take excruciatingly detailed pictures of every single step of the assembly/prototyping process. For the most part, I was just plugging pre-made components together. The most interesting production notes include the pressure sensor and the power supply.
+
+
+
Putting New Life into an iMac PSU
+
+
+
+ #
+
+
+
+
The power supply I used is from a first-gen Intel White iMac, which is visually very similar to the G5. It was one of the earliest things that I installed Linux on, and I used it as a seedbox for a bit, but eventually took it apart and saved some of the more interesting stuff.
+
All the credit goes to the user ersterhernd , from this thread on the tonymacx86.com forum for figuring out the pinout of this PSU, which is almost entirely identical to the one that was in my unit, apart from the power rating on mine being 200w. There are two banks of pins, half of which are always on, half of which are toggleable. Each bank has 12v, 5v, and 3.3v. I didn’t end up using 3.3v for anything other than the power switch. I have no idea what the energy efficiency of this unit is, obviously it doesn’t have an 80+ certification… But I’m assuming that Apple would make it at least halfway decent. Hopefully more efficient than a random 12v power brick with additional converters, I’d hope.
+
+
+
+
+
+
+
+
+
+
My schematic for the control unit. It was the first time I’ve ever used KiCad, and the first time I’ve ever made a schematic like this at all. I hope it’s relatively legible.
+
+
As you can see in the schematic above, the always-on 3.3v pin is connected to SYS_POWERUP through a relay board. The relay input is pulled low by a single pole switch, which turns the relay on, which connects ground to SYS_POWERUP, engaging the other rail of the power supply. This is kind of a convoluted solution to not having a double-pole switch… But I didn’t have a double-pole switch, so that’s what I did.
+
+
+
Measuring vacuum
+
+
+
+ #
+
+
+
+
The leak-resisting aspect all hinges on monitoring the pressure of the loop… Or potentially running a vacuum pump constantly, but that’s stupid. For some reason, I had a really hard time finding a vacuum pressur sensor. There are plenty of physical, analogue vacuum gauges available, but as far as an electronic sensor… I just couldn’t find any located in the US, at a reasonable price. There were a few hobbyist grade differential sensors, but I wanted to be able to measure down to an almost complete vacuum, and they didn’t have the range. Maybe I had the wrong search terms, but I just wasn’t finding anything. Eventually I found an unpackaged sensor with obscure, not entirely legible datasheets that claimed to have an acceptable pressure range for my application. The MD-PS002 is what I settled on, available on Amazon in the US in a 2-pack for $8. It’s a tiny little thing, and it took two attempts to successfully create a sensor package that didn’t leak.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Sensor package details, installed and all gooped up.
+
+
I drilled a hole in a G1/4" plug, just slightly bigger than the metal ring on the sensor, coated that ring with J-B Weld, and inserted it, letting it cure before grinding away the exterior of the top of the plug and building up more J-B weld to add some strain relief for the wires as well as edge-to-edge sealing. The current vacuum loss rate, after running the system for a few months, allowing the loop to very thoroughly de-gas, is now less than 50mbar per day at -500 to -600mbar. I was slightly worried about the lifetime of the pump, given it’s a cheap thing from Amazon, but given it only has to run for about a second every 2-3 days, I imagine that won’t be an issue.
+
Here’s a quick video showing the system not leaking!
+
+
+
This pressure sensor is a wheatstone bridge, which works the same way as load cells for digital scales. The resistance changes are very, very low, thus the signal must be amplified before being fed into an ADC. You could use an op-amp, and feed that signal into an analog input on the Arduino, but I felt more comfortable using the HX711, a two-channel ADC with integrated amplifier designed to be used with wheatstone bridge load cells. Here’s a code snippet showing how I converted the raw analog measurement to mbar.
+
float pressure_raw_to_mbar ( int32_t pressure_raw ) {
+ return ( pressure_raw - 390000 ) * ( 1700.0 / ( 5600000 - 390000 )) - 700 ;
+ }
+
I calibrated it manually, comparing it to an analogue gauge. It’s calibrated to a zero point at atmospheric pressure in my locale, and from -700mbar to +1000mbar. I figured out that, when setting the HX711 to a gain of 64 with the Adafruit HX711 library, a change of 100mbar is a change in the ADC measurement by 30k, highly consistent across the entire pressure range that I tested. I can’t be 100% sure how accurate the analogue gauge is, but 100% accuracy doesn’t really matter for this application. All I really need to know is the fact that an adequate vacuum is present, and a general idea of the leak rate, which is a requirement that this setup meets.
+
+
+
Other stuff
+
+
+
+ #
+
+
+
+
I got a beefy PWM motor driver with L298 logic, claiming a continuous current of 7 amps per channel, which nicely fit my requirements. 120mm PC fans are typically 0.2-0.3 amps, and mine in particular are 0.25. For 18 fans, it should be approximately 4.5 amps at 100% speed. It’s a bit oversized, and I’m only using one channel, but it leaves me the option in the future to use larger, generic radiator fans that have more demanding power requirements. I’m already down two from eighteen, eventually enough of them are going to fail that I’ll have to find another solution.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Required additions to the solenoid, pump motor, and the complete assembly without cover.
+
+
In my initial tests, I found that operating the pump and solenoid would cause the Arduino to reset, seemingly at random, or cause other undefined behavior. Since they were not electrically isolated on a second power supply, that makes sense. They were backfeeding energy and causing a notable amount of general interference during operation, to the point that the LEDs on the inactive relay modules would dimly illuminate when the motor was in operation, and very visibly illuminate whenever the motor or the solenoid deactivated. I had to add flyback diodes, and, for peace of mind, I added ceramic filtering capacitors to the pump as well. Those additions completely eliminated the issue. Below is a video demonstrating the bad behavior.
+
+
+
I did a similar plug-drilling setup for the water temperature sensor with a generic Dallas temperature probe. The air probe was taped to the exterior of the box, in the path of the incoming air. All that remained was to solder up a sort of bus bar for the radiator fan connectors, get the temperature probes and pull-up resistors wired into the proto board, and hook everything up to the Arduino, then write the software to tie it all together.
+
+
+
The Software
+
+
+
+ #
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rawhide_k/server-watercooling-controller
+
+
+
+
+
+
+
+
+
+
+
+ C++
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
The Arduino operates independently, without a server. The fan speed and loop pressure are managed autonomously. The serial connection is only used to report vital stats, for later integration into more connected monitoring systems. Ultimately, there are only two actions it can take: Change the fan speed, and turn on the vacuum pump. Neither of these require any external knowledge. It doesn’t need any information about the connected hardware to function correctly. All it’s concerned with is keeping the water temperature at a certain delta above ambient temperature, and keeping the loop pressure within a certain range. Ultimately, very simple.
+
Once per second, the temperature sensors are sampled, the PID loop for the fans runs with the new temperature data points, and the fan speed, temperature data, vacuum pressure, and pump/flow measurements are sent over serial with the help of the ArduinoJSON library. I settled on a target water delta of 4*C relative to ambient, with a chosen min/max temperature range where the fans turn off or pin themselves to 100% completely. The 4*C delta is rather arbitrary. It’s approximately the delta that exists when the systems are on, but idle, and the fans are at their minimum speed. That delta can be maintained during 100% CPU load, and during medium-heavy GPU loads, but not both combined. It still stays well under a 10*C delta in that case, though, so I can’t complain.
+
There are also hard stops to turn the fans off if the water temperature hits 5*C, and pin them to max if it hits 40*C. I’m not sure how realistic either of those figures are, but it’s better to be safe than frozen up and/or exploded.
+
int fan_PID ( float * air_temp , float * water_temp , uint32_t * cur_loop_timestamp ) {
+ static const float kp = 120.0 ;
+ static const float ki = 0.16 ;
+ static const float kd = 4.0 ;
+
+ static float integral = 0 ;
+ static float derivative = 0 ;
+ static float last_error = 0 ;
+ static float error ;
+ static float delta ;
+ static float last_time = * cur_loop_timestamp ;
+ static const float min_water_temp = 5.0 ;
+ static const float max_water_temp = 40.0 ;
+ static const uint8_t min_fan_speed = 90 ;
+ static const uint8_t max_fan_speed = 255 ;
+
+ static const uint8_t temp_target_offset = 4 ;
+ static const uint8_t fan_offset = 10 ;
+
+ static int16_t fan_speed ;
+
+ if ( * water_temp >= max_water_temp ) {
+ return max_fan_speed ;
+ }
+
+ else if ( * water_temp <= min_water_temp ) {
+ return 0 ;
+ }
+
+ else {
+ error = * water_temp - min ( * air_temp + temp_target_offset , max_water_temp );
+ delta = * cur_loop_timestamp - last_time ;
+
+ //mitigate unlimited integral windup
+ if ( fan_speed == max_fan_speed ) {
+ integral += error * delta ;
+ }
+
+ if ( * air_temp + temp_target_offset > * water_temp - 1 ) {
+ integral = 0 ;
+ }
+
+ derivative = ( error - last_error ) / delta ;
+ fan_speed = round ( constrain ( min_fan_speed + fan_offset + ( kp * error + ki * integral + kd * derivative ), min_fan_speed , max_fan_speed ));
+ last_error = error ;
+ return fan_speed ;
+ }
+ }
+
Occasionally, the temperature probes as well as the HX711 return spurious readings that cause poor behavior, such as crashing the Arduino. In particular, the temperature probes will sometimes return -127, which caused my PID algorithm to crash the Arduino for reasons I could not divine.
+
For the temperature probes, I simply ignore the one problematic result that I’ve observed.
+
new_water_temp = sensors . getTempC ( water_therm );
+new_air_temp = sensors . getTempC ( air_therm );
+
+ if ( new_water_temp != - 127 ) {
+ water_temp = new_water_temp ;
+ }
+
+ if ( new_air_temp != - 127 ) {
+ air_temp = new_air_temp ;
+ }
+
+ sensors . requestTemperatures ();
+
In case of any other freezing/crashing issues, I also enabled the watchdog timer for 2 seconds. So, if, for some reason, it does freeze/crash, it should self reset after 2 seconds. It seems to be working, although I guess time will tell in the long-term. I haven’t experienced any operation issues since I added it over a month ago. The other concern is undefined behavior when the timer overflows. The Uno only has a 32-bit timer, so it will overflow around 50 days of uptime. This function pre-emptively resets it.
+
//we will use this function to periodically self-reset to avoid timer overflows
+ void ( * resetFunc ) ( void ) = 0 ;
+
+ ...
+
+ //reset the system when approaching timer overflow
+ if ( cur_loop_timestamp >= 4000000000 ) {
+ resetFunc ();
+ }
+
In addition to the temperature probe problem, the HX711 occasionally returns wildly wrong results that need to be filtered out. To compensate for that, if the pressure dips below the threshold, I wait one second, and if the pressure is still below the threshold, I then begin pumping. This check happens approximately ten times per second, as the default behavior of the HX711 board that I have is to run in 10hz mode. I’m not sure if the issue springs from some kind of interference with the tachometer interrupts messing up the signaling timing, or if I’m misunderstanding the correct way to sample the HX711 over time.
+
if ( cur_loop_timestamp - last_pressure_check >= 100 ) {
+ loop_pressure = pressure_raw_to_mbar ( hx711 . readChannelRaw ( CHAN_A_GAIN_64 ));
+
+ if ( sucking == false ) {
+ if ( loop_pressure > low_pressure_threshold ) {
+ if ( checking_low_pressure == false ) {
+ checking_low_pressure = true ;
+ low_pressure_confirmation_timestamp = cur_loop_timestamp ;
+ }
+ if ( cur_loop_timestamp - low_pressure_confirmation_timestamp >= 1000 ) {
+ digitalWrite ( pump_relay , HIGH );
+ digitalWrite ( solenoid_relay , HIGH );
+ sucking = true ;
+ checking_low_pressure = false ;
+ }
+ }
+
+ else if ( cur_loop_timestamp - low_pressure_confirmation_timestamp >= 1000 ) {
+ checking_low_pressure = false ;
+ }
+ }
+
+ else {
+ if ( loop_pressure < high_pressure_threshold ) {
+ digitalWrite ( pump_relay , LOW );
+ digitalWrite ( solenoid_relay , LOW );
+ sucking = false ;
+ }
+ }
+ last_pressure_check = cur_loop_timestamp ;
+ }
+
Currently, my server-side software is incomplete. It’s just a brute-force JSON-over-serial reader written in Python, that I glance at from time to time. I plan write a Zabbix bridge, and have that manage the monitoring, alerts, and reactions to catostraphic events, once I have Zabbix properly setup for my systems… But that hasn’t happened just yet. I don’t expect it to be a particularly interesting event, but if anything comes up I might write a post about it.
+
+
+
Other Thoughts?
+
+
+
+ #
+
+
+
+
The Arduino’s software hadn’t been 100% finalized when I took the below pictures. The control box does have a lid now, and all the cable management is a lot cleaner… Promise!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Everything installed and working!
+
+
When I was testing it, I had an incident where the Arduino crashed, which means the fans stopped… That’s a big drawback with the motor controller that I have, it fails off instead of on. But, I haven’t experienced any more issues after adding those software fixes. At that time, I was running a full GPU workload… The water temperature exceeded 70*C. It happened at night, and I have no idea how long it ran like that… Hours. Pretty scary stuff, but it all came out alright.
+
This project had a lot of firsts for me. It was the first time I’ve done any kind of embedded-adjacent development beyond “ooooo look at the blinky light, oooooooo it turns off when you press the button, wwaaaow”, and the first time I’d designed something with so many individual parts. I’ve never worked with air pumps, solenoids, or pressure sensing before, nor had to debug issues like the lack of flyback diodes.
+
The biggest mistake I made was using that stupid battery box. It’s steel, and I don’t have the tools or experience to work with steel in the way that I intended to. I thought it would look cool, and it does, but if I did it again, I’d use a generic aluminum or plastic project box instead, because it took two entire days plus waiting for new drill bits that can actually cut through it.
+
If I were to ever take it apart again, I’d add a passthrough for the SPI header, and/or an external reset button. I should have gotten a physical display of some type that could show the sensors and debug info on the device itself without being connected to another device to readout the data.
+
I’d like to get a second pump, for redundancy’s sake and to increase the flow rate. But it’s going to be such a pain to install that I feel like I’m never going to bother to do it, unless the current pump fails, or I add more components to be cooled and the flow is adversely affected. I was slightly concerned about the evaporation rate of the liquid via the vacuum tank, and that I’d need to add some kind of fluid level detection system, but there’s been no noticeable loss thus far. Now that I know the pump turns on so infrequently, I can’t imagine that it’s going to need to be topped up anytime soon.
+
In terms of value… This was unbelievably bad. Buying tower coolers would have allowed the CPUs to run without throttling, and buying another GPU would have overpowered any benefits gained by NVLINK. I haven’t tallied up exactly how much I spent on it, but it was at least $1000, including buying new tools and excess materials that I haven’t fully used, and excluding the original cost of re-using some parts I already had. I’ve added risk, maintenance overhead, and pain whenever I swap out hardware in the future. Custom watercooling is an ongoing abusive relationship between your fingertips and your ego, or your fascination for slightly more optimized numbers on a screen… But I’d do it again in a heartbeat, because it was fun.
+
+
+
+
+
+
+
+ Reply by Email
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/posts/watercooling-my-homelab/schematic_minify.svg b/public/posts/watercooling-my-homelab/schematic_minify.svg
new file mode 100644
index 0000000..22ed0ef
--- /dev/null
+++ b/public/posts/watercooling-my-homelab/schematic_minify.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..5c0725b
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,3 @@
+User-agent: *
+Allow: /
+Sitemap: https://blog.neet.works/sitemap.xml
diff --git a/public/series/index.html b/public/series/index.html
new file mode 100644
index 0000000..10016bc
--- /dev/null
+++ b/public/series/index.html
@@ -0,0 +1,6 @@
+Series · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/series/index.xml b/public/series/index.xml
new file mode 100644
index 0000000..7056ba3
--- /dev/null
+++ b/public/series/index.xml
@@ -0,0 +1 @@
+Series on N.E.E.T. Works https://blog.neet.works/series/Recent content in Series on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.*
\ No newline at end of file
diff --git a/public/site.webmanifest b/public/site.webmanifest
new file mode 100644
index 0000000..45dc8a2
--- /dev/null
+++ b/public/site.webmanifest
@@ -0,0 +1 @@
+{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
\ No newline at end of file
diff --git a/public/sitemap.xml b/public/sitemap.xml
new file mode 100644
index 0000000..e0abbf8
--- /dev/null
+++ b/public/sitemap.xml
@@ -0,0 +1 @@
+https://blog.neet.works/ 2025-01-16T05:56:41+00:00 daily 0.5 https://blog.neet.works/posts/ 2025-01-16T05:56:41+00:00 daily 0.5 https://blog.neet.works/posts/watercooling-homelab/ 2025-01-16T05:56:41+00:00 daily 0.5
\ No newline at end of file
diff --git a/public/tags/alphacool/index.html b/public/tags/alphacool/index.html
new file mode 100644
index 0000000..0e9f725
--- /dev/null
+++ b/public/tags/alphacool/index.html
@@ -0,0 +1,15 @@
+Alphacool · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/tags/alphacool/index.xml b/public/tags/alphacool/index.xml
new file mode 100644
index 0000000..63598d4
--- /dev/null
+++ b/public/tags/alphacool/index.xml
@@ -0,0 +1 @@
+Alphacool on N.E.E.T. Works https://blog.neet.works/tags/alphacool/Recent content in Alphacool on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/tags/alphacool/page/1/index.html b/public/tags/alphacool/page/1/index.html
new file mode 100644
index 0000000..704246b
--- /dev/null
+++ b/public/tags/alphacool/page/1/index.html
@@ -0,0 +1,2 @@
+https://blog.neet.works/tags/alphacool/
+
\ No newline at end of file
diff --git a/public/tags/aqua-computer/index.html b/public/tags/aqua-computer/index.html
new file mode 100644
index 0000000..5172ec3
--- /dev/null
+++ b/public/tags/aqua-computer/index.html
@@ -0,0 +1,15 @@
+Aqua Computer · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/tags/aqua-computer/index.xml b/public/tags/aqua-computer/index.xml
new file mode 100644
index 0000000..b087031
--- /dev/null
+++ b/public/tags/aqua-computer/index.xml
@@ -0,0 +1 @@
+Aqua Computer on N.E.E.T. Works https://blog.neet.works/tags/aqua-computer/Recent content in Aqua Computer on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/tags/aqua-computer/page/1/index.html b/public/tags/aqua-computer/page/1/index.html
new file mode 100644
index 0000000..04833f1
--- /dev/null
+++ b/public/tags/aqua-computer/page/1/index.html
@@ -0,0 +1,2 @@
+https://blog.neet.works/tags/aqua-computer/
+
\ No newline at end of file
diff --git a/public/tags/arduino/index.html b/public/tags/arduino/index.html
new file mode 100644
index 0000000..5767b07
--- /dev/null
+++ b/public/tags/arduino/index.html
@@ -0,0 +1,15 @@
+Arduino · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/tags/arduino/index.xml b/public/tags/arduino/index.xml
new file mode 100644
index 0000000..cad7a78
--- /dev/null
+++ b/public/tags/arduino/index.xml
@@ -0,0 +1 @@
+Arduino on N.E.E.T. Works https://blog.neet.works/tags/arduino/Recent content in Arduino on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/tags/arduino/page/1/index.html b/public/tags/arduino/page/1/index.html
new file mode 100644
index 0000000..dd7c830
--- /dev/null
+++ b/public/tags/arduino/page/1/index.html
@@ -0,0 +1,2 @@
+https://blog.neet.works/tags/arduino/
+
\ No newline at end of file
diff --git a/public/tags/index.html b/public/tags/index.html
new file mode 100644
index 0000000..e54ba11
--- /dev/null
+++ b/public/tags/index.html
@@ -0,0 +1,18 @@
+Tags · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/tags/index.xml b/public/tags/index.xml
new file mode 100644
index 0000000..164fb24
--- /dev/null
+++ b/public/tags/index.xml
@@ -0,0 +1 @@
+Tags on N.E.E.T. Works https://blog.neet.works/tags/Recent content in Tags on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Alphacool https://blog.neet.works/tags/alphacool/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/tags/alphacool/ Aqua Computer https://blog.neet.works/tags/aqua-computer/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/tags/aqua-computer/ Arduino https://blog.neet.works/tags/arduino/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/tags/arduino/ Intel https://blog.neet.works/tags/intel/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/tags/intel/ Nvidia https://blog.neet.works/tags/nvidia/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/tags/nvidia/ Supermicro https://blog.neet.works/tags/supermicro/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/tags/supermicro/
\ No newline at end of file
diff --git a/public/tags/intel/index.html b/public/tags/intel/index.html
new file mode 100644
index 0000000..1aa889e
--- /dev/null
+++ b/public/tags/intel/index.html
@@ -0,0 +1,15 @@
+Intel · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/tags/intel/index.xml b/public/tags/intel/index.xml
new file mode 100644
index 0000000..3f51e77
--- /dev/null
+++ b/public/tags/intel/index.xml
@@ -0,0 +1 @@
+Intel on N.E.E.T. Works https://blog.neet.works/tags/intel/Recent content in Intel on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/tags/intel/page/1/index.html b/public/tags/intel/page/1/index.html
new file mode 100644
index 0000000..b640b6c
--- /dev/null
+++ b/public/tags/intel/page/1/index.html
@@ -0,0 +1,2 @@
+https://blog.neet.works/tags/intel/
+
\ No newline at end of file
diff --git a/public/tags/nvidia/index.html b/public/tags/nvidia/index.html
new file mode 100644
index 0000000..f4aec3f
--- /dev/null
+++ b/public/tags/nvidia/index.html
@@ -0,0 +1,15 @@
+Nvidia · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/tags/nvidia/index.xml b/public/tags/nvidia/index.xml
new file mode 100644
index 0000000..cc3234a
--- /dev/null
+++ b/public/tags/nvidia/index.xml
@@ -0,0 +1 @@
+Nvidia on N.E.E.T. Works https://blog.neet.works/tags/nvidia/Recent content in Nvidia on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/tags/nvidia/page/1/index.html b/public/tags/nvidia/page/1/index.html
new file mode 100644
index 0000000..08ac136
--- /dev/null
+++ b/public/tags/nvidia/page/1/index.html
@@ -0,0 +1,2 @@
+https://blog.neet.works/tags/nvidia/
+
\ No newline at end of file
diff --git a/public/tags/supermicro/index.html b/public/tags/supermicro/index.html
new file mode 100644
index 0000000..7f05b22
--- /dev/null
+++ b/public/tags/supermicro/index.html
@@ -0,0 +1,15 @@
+Supermicro · N.E.E.T. Works
+
\ No newline at end of file
diff --git a/public/tags/supermicro/index.xml b/public/tags/supermicro/index.xml
new file mode 100644
index 0000000..1edf9d6
--- /dev/null
+++ b/public/tags/supermicro/index.xml
@@ -0,0 +1 @@
+Supermicro on N.E.E.T. Works https://blog.neet.works/tags/supermicro/Recent content in Supermicro on N.E.E.T. Works Hugo -- gohugo.io en rawhide@neet.works (rawhide kobayashi) rawhide@neet.works (rawhide kobayashi) *Β© 2025 rawhide kobayashi | **Original content** licensed under **[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)** unless otherwise noted.* Thu, 16 Jan 2025 05:56:41 +0000 Watercooling My Homelab https://blog.neet.works/posts/watercooling-homelab/Thu, 16 Jan 2025 05:56:41 +0000 rawhide@neet.works (rawhide kobayashi) https://blog.neet.works/posts/watercooling-homelab/
\ No newline at end of file
diff --git a/public/tags/supermicro/page/1/index.html b/public/tags/supermicro/page/1/index.html
new file mode 100644
index 0000000..953d35e
--- /dev/null
+++ b/public/tags/supermicro/page/1/index.html
@@ -0,0 +1,2 @@
+https://blog.neet.works/tags/supermicro/
+
\ No newline at end of file
diff --git a/resources/_gen/images/img/blowfish_logo_hu10418442261355118245.png b/resources/_gen/images/img/blowfish_logo_hu10418442261355118245.png
deleted file mode 100644
index fa2a03e..0000000
Binary files a/resources/_gen/images/img/blowfish_logo_hu10418442261355118245.png and /dev/null differ
diff --git a/resources/_gen/images/img/blowfish_logo_hu10440971084165979012.png b/resources/_gen/images/img/blowfish_logo_hu10440971084165979012.png
deleted file mode 100644
index d809d64..0000000
Binary files a/resources/_gen/images/img/blowfish_logo_hu10440971084165979012.png and /dev/null differ
diff --git a/resources/_gen/images/img/blowfish_logo_hu13719681768044762498.webp b/resources/_gen/images/img/blowfish_logo_hu13719681768044762498.webp
new file mode 100644
index 0000000..cef6cbf
Binary files /dev/null and b/resources/_gen/images/img/blowfish_logo_hu13719681768044762498.webp differ
diff --git a/resources/_gen/images/img/blowfish_logo_hu536110971430689468.webp b/resources/_gen/images/img/blowfish_logo_hu536110971430689468.webp
new file mode 100644
index 0000000..b6763b2
Binary files /dev/null and b/resources/_gen/images/img/blowfish_logo_hu536110971430689468.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/featured_hu11504899310106128621.webp b/resources/_gen/images/posts/watercooling-homelab/featured_hu11504899310106128621.webp
new file mode 100644
index 0000000..c367236
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/featured_hu11504899310106128621.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/featured_hu13568191302889737537.webp b/resources/_gen/images/posts/watercooling-homelab/featured_hu13568191302889737537.webp
new file mode 100644
index 0000000..87b93fe
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/featured_hu13568191302889737537.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_5615170330311787003.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_5615170330311787003.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_5615170330311787003.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_5615170330311787003.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu1954630252676748703.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu1954630252676748703.webp
new file mode 100644
index 0000000..afd41bb
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu1954630252676748703.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu6560107379008232574.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu6560107379008232574.webp
new file mode 100644
index 0000000..721b185
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu6560107379008232574.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu7088133987632116537.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu7088133987632116537.webp
new file mode 100644
index 0000000..45b6320
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_A_hu7088133987632116537.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_10409934285657632450.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_10409934285657632450.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_10409934285657632450.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_10409934285657632450.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu12155478021797826213.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu12155478021797826213.webp
new file mode 100644
index 0000000..5646d45
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu12155478021797826213.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu2333850158973680984.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu2333850158973680984.webp
new file mode 100644
index 0000000..c37bb25
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu2333850158973680984.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu5952309977048855875.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu5952309977048855875.webp
new file mode 100644
index 0000000..4ca7a9d
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Block_Mod_Detail_B_hu5952309977048855875.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Coldplate_16964685507568574413.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Coldplate_16964685507568574413.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Coldplate_16964685507568574413.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Coldplate_16964685507568574413.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Coldplate_hu13174017899928575525.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Coldplate_hu13174017899928575525.webp
new file mode 100644
index 0000000..b54c589
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Coldplate_hu13174017899928575525.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Coldplate_hu16258961307282205929.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Coldplate_hu16258961307282205929.webp
new file mode 100644
index 0000000..f9ca293
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Coldplate_hu16258961307282205929.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Coldplate_hu3290250784134948227.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Coldplate_hu3290250784134948227.webp
new file mode 100644
index 0000000..38e9921
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Coldplate_hu3290250784134948227.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_17570414387999729626.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Different_Plugs_17570414387999729626.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_17570414387999729626.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Different_Plugs_17570414387999729626.json
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu6984269313153752643.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Different_Plugs_hu17890886748642996535.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu6984269313153752643.webp
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Different_Plugs_hu17890886748642996535.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu9356083241289898304.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Different_Plugs_hu2378229743182206831.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu9356083241289898304.webp
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Different_Plugs_hu2378229743182206831.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu6397503244716169044.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Different_Plugs_hu3502703824848779819.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_hu6397503244716169044.webp
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Different_Plugs_hu3502703824848779819.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_4734246681061187453.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_4734246681061187453.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Dual_Blocks_Zoom_4734246681061187453.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_4734246681061187453.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu1233157730881247055.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu1233157730881247055.webp
new file mode 100644
index 0000000..7985b6b
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu1233157730881247055.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu1716452709661764841.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu1716452709661764841.webp
new file mode 100644
index 0000000..26a05c9
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu1716452709661764841.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu478575305574189147.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu478575305574189147.webp
new file mode 100644
index 0000000..1e9fc92
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Dual_Blocks_Zoom_hu478575305574189147.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_17114047156511750685.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/GPUs_Installed_17114047156511750685.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_17114047156511750685.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/GPUs_Installed_17114047156511750685.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu1860541658624349795.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu1860541658624349795.webp
new file mode 100644
index 0000000..74c07bd
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu1860541658624349795.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu1923429014339473058.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu1923429014339473058.webp
new file mode 100644
index 0000000..8e6df53
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu1923429014339473058.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu4193758725753816349.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu4193758725753816349.webp
new file mode 100644
index 0000000..f9ad750
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/GPUs_Installed_hu4193758725753816349.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_17010757286397298119.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/MO-RA!_17010757286397298119.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_17010757286397298119.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/MO-RA!_17010757286397298119.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/MO-RA!_hu15264814207577810858.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/MO-RA!_hu15264814207577810858.webp
new file mode 100644
index 0000000..85185fa
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/MO-RA!_hu15264814207577810858.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/MO-RA!_hu6856946684884405237.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/MO-RA!_hu6856946684884405237.webp
new file mode 100644
index 0000000..b7d29cd
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/MO-RA!_hu6856946684884405237.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/MO-RA!_hu7453820902150892044.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/MO-RA!_hu7453820902150892044.webp
new file mode 100644
index 0000000..aa9a516
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/MO-RA!_hu7453820902150892044.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_15220004529048276947.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Mounting_Detail_15220004529048276947.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_15220004529048276947.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Mounting_Detail_15220004529048276947.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu11231283172588266533.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu11231283172588266533.webp
new file mode 100644
index 0000000..4055cc0
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu11231283172588266533.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu1490212990626714303.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu1490212990626714303.webp
new file mode 100644
index 0000000..8931075
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu1490212990626714303.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu3280937936208174423.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu3280937936208174423.webp
new file mode 100644
index 0000000..734f8aa
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Mounting_Detail_hu3280937936208174423.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_3127877694928138578.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Tall_Capacitor_3127877694928138578.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_3127877694928138578.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Tall_Capacitor_3127877694928138578.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu1042940534242500862.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu1042940534242500862.webp
new file mode 100644
index 0000000..1ca577f
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu1042940534242500862.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu11882410216080315790.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu11882410216080315790.webp
new file mode 100644
index 0000000..b62a5af
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu11882410216080315790.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu3985119007043451200.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu3985119007043451200.webp
new file mode 100644
index 0000000..a7b7c81
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Tall_Capacitor_hu3985119007043451200.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Test_Fit_11787269413487762109.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Test_Fit_11787269413487762109.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Test_Fit_11787269413487762109.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Test_Fit_11787269413487762109.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Test_Fit_hu2884804705215397458.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Test_Fit_hu2884804705215397458.webp
new file mode 100644
index 0000000..878d0f2
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Test_Fit_hu2884804705215397458.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Test_Fit_hu4196319411009163019.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Test_Fit_hu4196319411009163019.webp
new file mode 100644
index 0000000..95ea791
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Test_Fit_hu4196319411009163019.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Test_Fit_hu6466058294895506811.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Test_Fit_hu6466058294895506811.webp
new file mode 100644
index 0000000..8314386
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Test_Fit_hu6466058294895506811.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_2097884559484938538.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_2097884559484938538.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_2097884559484938538.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_2097884559484938538.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu10619128996450324123.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu10619128996450324123.webp
new file mode 100644
index 0000000..726476c
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu10619128996450324123.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu17456463471095554312.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu17456463471095554312.webp
new file mode 100644
index 0000000..c4d2169
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu17456463471095554312.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu3171065713872445154.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu3171065713872445154.webp
new file mode 100644
index 0000000..3c9c7c4
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/Triple_Card_Jank_hu3171065713872445154.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_a_13225163134512815412.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_a_13225163134512815412.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_a_13225163134512815412.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_a_13225163134512815412.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_a_hu11784685921316552556.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_a_hu11784685921316552556.webp
new file mode 100644
index 0000000..a58dd35
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_a_hu11784685921316552556.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_a_hu2347091142476872481.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_a_hu2347091142476872481.webp
new file mode 100644
index 0000000..95d622f
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_a_hu2347091142476872481.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_a_hu2371455810172732269.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_a_hu2371455810172732269.webp
new file mode 100644
index 0000000..d5be382
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_a_hu2371455810172732269.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_4843000676286649320.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_assembly_4843000676286649320.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_4843000676286649320.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_assembly_4843000676286649320.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_assembly_hu13996029485759007548.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_assembly_hu13996029485759007548.webp
new file mode 100644
index 0000000..6b20dd5
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_assembly_hu13996029485759007548.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_assembly_hu17913719379729244320.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_assembly_hu17913719379729244320.webp
new file mode 100644
index 0000000..f3e462f
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_assembly_hu17913719379729244320.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_assembly_hu402138244258743400.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_assembly_hu402138244258743400.webp
new file mode 100644
index 0000000..40b3695
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_assembly_hu402138244258743400.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_b_10040444187820463369.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_b_10040444187820463369.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_b_10040444187820463369.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_b_10040444187820463369.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_b_hu10235357959924345043.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_b_hu10235357959924345043.webp
new file mode 100644
index 0000000..1aee7a1
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_b_hu10235357959924345043.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_b_hu10444887637626475779.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_b_hu10444887637626475779.webp
new file mode 100644
index 0000000..71f69df
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_b_hu10444887637626475779.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_b_hu12966552216401371125.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_b_hu12966552216401371125.webp
new file mode 100644
index 0000000..7cdfe35
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/complete_b_hu12966552216401371125.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_9352709651048579546.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/goopy_installed_9352709651048579546.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_9352709651048579546.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/goopy_installed_9352709651048579546.json
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu6984269313153752643.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/goopy_installed_hu13878470882578617902.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu6984269313153752643.webp
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/goopy_installed_hu13878470882578617902.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu9356083241289898304.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/goopy_installed_hu7775517930751145146.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu9356083241289898304.webp
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/goopy_installed_hu7775517930751145146.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu6397503244716169044.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/goopy_installed_hu8582164235252167480.webp
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_hu6397503244716169044.webp
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/goopy_installed_hu8582164235252167480.webp
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_15238469055321922669.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_bottom_15238469055321922669.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_bottom_15238469055321922669.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_bottom_15238469055321922669.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu12744847709972265499.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu12744847709972265499.webp
new file mode 100644
index 0000000..b00ac4e
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu12744847709972265499.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu3645814594706023691.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu3645814594706023691.webp
new file mode 100644
index 0000000..2299aaf
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu3645814594706023691.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu3698649971536149681.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu3698649971536149681.webp
new file mode 100644
index 0000000..8c313f0
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_bottom_hu3698649971536149681.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_13770873283219702036.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_top_13770873283219702036.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_13770873283219702036.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_top_13770873283219702036.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_top_hu13627305942680874943.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_top_hu13627305942680874943.webp
new file mode 100644
index 0000000..50e5885
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_top_hu13627305942680874943.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_top_hu16358936284331608818.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_top_hu16358936284331608818.webp
new file mode 100644
index 0000000..570750a
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_top_hu16358936284331608818.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_top_hu7787027711586187933.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_top_hu7787027711586187933.webp
new file mode 100644
index 0000000..53347aa
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/plug_detail_top_hu7787027711586187933.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/pump_greeble_16479979128071154219.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/pump_greeble_16479979128071154219.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/pump_greeble_16479979128071154219.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/pump_greeble_16479979128071154219.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/pump_greeble_hu1040829716072557719.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/pump_greeble_hu1040829716072557719.webp
new file mode 100644
index 0000000..46ec6fe
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/pump_greeble_hu1040829716072557719.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/pump_greeble_hu1471177938307566585.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/pump_greeble_hu1471177938307566585.webp
new file mode 100644
index 0000000..1bf2e3f
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/pump_greeble_hu1471177938307566585.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/pump_greeble_hu4319233910559987333.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/pump_greeble_hu4319233910559987333.webp
new file mode 100644
index 0000000..4bc261a
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/pump_greeble_hu4319233910559987333.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_13216679186790688094.json b/resources/_gen/images/posts/watercooling-homelab/images/compressed/solenoid_diode_13216679186790688094.json
similarity index 100%
rename from resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_13216679186790688094.json
rename to resources/_gen/images/posts/watercooling-homelab/images/compressed/solenoid_diode_13216679186790688094.json
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/solenoid_diode_hu13681423255705621406.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/solenoid_diode_hu13681423255705621406.webp
new file mode 100644
index 0000000..0272fff
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/solenoid_diode_hu13681423255705621406.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/solenoid_diode_hu14196543121366269339.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/solenoid_diode_hu14196543121366269339.webp
new file mode 100644
index 0000000..25952f0
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/solenoid_diode_hu14196543121366269339.webp differ
diff --git a/resources/_gen/images/posts/watercooling-homelab/images/compressed/solenoid_diode_hu3904316093352162951.webp b/resources/_gen/images/posts/watercooling-homelab/images/compressed/solenoid_diode_hu3904316093352162951.webp
new file mode 100644
index 0000000..579ef82
Binary files /dev/null and b/resources/_gen/images/posts/watercooling-homelab/images/compressed/solenoid_diode_hu3904316093352162951.webp differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_5809633292235993597.json b/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_5809633292235993597.json
deleted file mode 100644
index 2729792..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_5809633292235993597.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"6"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_hu18074075123923392350.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_hu18074075123923392350.jpg
deleted file mode 100644
index c1c2afc..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_hu18074075123923392350.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_hu5880308029515304488.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_hu5880308029515304488.jpg
deleted file mode 100644
index 7cc94e5..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_hu5880308029515304488.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_hu9492169065146778961.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_hu9492169065146778961.jpg
deleted file mode 100644
index e66a5f7..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_A_hu9492169065146778961.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_742980028206750564.json b/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_742980028206750564.json
deleted file mode 100644
index 2729792..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_742980028206750564.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"6"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_hu15851469336025682114.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_hu15851469336025682114.jpg
deleted file mode 100644
index 538a37a..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_hu15851469336025682114.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_hu16906162129047067519.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_hu16906162129047067519.jpg
deleted file mode 100644
index 1f88c8a..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_hu16906162129047067519.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_hu3417076273150677422.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_hu3417076273150677422.jpg
deleted file mode 100644
index eb75461..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Block_Mod_Detail_B_hu3417076273150677422.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_6372841327883208705.json b/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_6372841327883208705.json
deleted file mode 100644
index 1e4deb2..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_6372841327883208705.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu12054192195339521772.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu12054192195339521772.jpg
deleted file mode 100644
index 4744b55..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu12054192195339521772.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu12874532714916603845.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu12874532714916603845.jpg
deleted file mode 100644
index df11956..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu12874532714916603845.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu6292484912944328365.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu6292484912944328365.jpg
deleted file mode 100644
index 071d063..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu6292484912944328365.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu6565527765781053987.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu6565527765781053987.jpg
deleted file mode 100644
index bbd49a7..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Coldplate_hu6565527765781053987.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_7540516435025752608.json b/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_7540516435025752608.json
deleted file mode 100644
index e66ceb5..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_7540516435025752608.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint32":"0"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_hu15716426620243268089.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_hu15716426620243268089.jpg
deleted file mode 100644
index 1107b9a..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_hu15716426620243268089.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_hu4183386033562968630.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_hu4183386033562968630.jpg
deleted file mode 100644
index 7310dcb..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_hu4183386033562968630.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_hu4793767829912076558.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_hu4793767829912076558.jpg
deleted file mode 100644
index 37c8e03..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Different_Plugs_hu4793767829912076558.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_11370189265629524719.json b/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_11370189265629524719.json
deleted file mode 100644
index 28c932a..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_11370189265629524719.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"1"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu13908381936289152279.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu13908381936289152279.jpg
deleted file mode 100644
index d59293c..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu13908381936289152279.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu17468285238877770317.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu17468285238877770317.jpg
deleted file mode 100644
index 421b4c9..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu17468285238877770317.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu3940820771614763935.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu3940820771614763935.jpg
deleted file mode 100644
index a81de59..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu3940820771614763935.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu7868988101157053081.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu7868988101157053081.jpg
deleted file mode 100644
index 4cc4730..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Dual_Blocks_Zoom_hu7868988101157053081.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_11853282398334015033.json b/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_11853282398334015033.json
deleted file mode 100644
index e66ceb5..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_11853282398334015033.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint32":"0"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_hu13607471453277651931.jpg b/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_hu13607471453277651931.jpg
deleted file mode 100644
index 2db1e0e..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_hu13607471453277651931.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_hu1604295178153193725.jpg b/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_hu1604295178153193725.jpg
deleted file mode 100644
index 1ba78c7..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_hu1604295178153193725.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_hu836063494480596912.jpg b/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_hu836063494480596912.jpg
deleted file mode 100644
index 7845e4d..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/GPUs_Installed_hu836063494480596912.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_9879562890875865097.json b/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_9879562890875865097.json
deleted file mode 100644
index 28c932a..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_9879562890875865097.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"1"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu10688976488496395446.jpg b/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu10688976488496395446.jpg
deleted file mode 100644
index 3063d26..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu10688976488496395446.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu15853611718912596499.jpg b/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu15853611718912596499.jpg
deleted file mode 100644
index 758dbc3..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu15853611718912596499.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu17108253306787555372.jpg b/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu17108253306787555372.jpg
deleted file mode 100644
index b71e0e4..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu17108253306787555372.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu4295159796658311073.jpg b/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu4295159796658311073.jpg
deleted file mode 100644
index af9bee8..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu4295159796658311073.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu6189865404437848914.jpg b/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu6189865404437848914.jpg
deleted file mode 100644
index ea383e6..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/MO-RA!_hu6189865404437848914.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_14492637136343791037.json b/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_14492637136343791037.json
deleted file mode 100644
index 2729792..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_14492637136343791037.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"6"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu11749109309790143379.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu11749109309790143379.jpg
deleted file mode 100644
index 499bd53..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu11749109309790143379.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu12209600976794790922.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu12209600976794790922.jpg
deleted file mode 100644
index c7fedab..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu12209600976794790922.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu13299117016165240038.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu13299117016165240038.jpg
deleted file mode 100644
index 36f952a..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu13299117016165240038.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu13708798783634309757.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu13708798783634309757.jpg
deleted file mode 100644
index e435edc..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu13708798783634309757.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu1566311589005578420.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu1566311589005578420.jpg
deleted file mode 100644
index ff1a90d..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu1566311589005578420.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu205452476573419691.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu205452476573419691.jpg
deleted file mode 100644
index 5e11231..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu205452476573419691.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu375607582299287875.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu375607582299287875.jpg
deleted file mode 100644
index 280f287..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Mounting_Detail_hu375607582299287875.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_10226290263723708448.json b/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_10226290263723708448.json
deleted file mode 100644
index e66ceb5..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_10226290263723708448.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint32":"0"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_hu18395364824067327093.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_hu18395364824067327093.jpg
deleted file mode 100644
index a8c33f7..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_hu18395364824067327093.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_hu2913180726925457453.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_hu2913180726925457453.jpg
deleted file mode 100644
index c031749..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_hu2913180726925457453.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_hu8114996651518970227.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_hu8114996651518970227.jpg
deleted file mode 100644
index 955ef30..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Tall_Capacitor_hu8114996651518970227.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_4096638643860886223.json b/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_4096638643860886223.json
deleted file mode 100644
index 28c932a..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_4096638643860886223.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"1"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_hu16454569078391126386.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_hu16454569078391126386.jpg
deleted file mode 100644
index ef7e982..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_hu16454569078391126386.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_hu6835306718449597831.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_hu6835306718449597831.jpg
deleted file mode 100644
index 2bbcf5b..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_hu6835306718449597831.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_hu7489691193183959244.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_hu7489691193183959244.jpg
deleted file mode 100644
index 94799b7..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Test_Fit_hu7489691193183959244.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_7677591895010082253.json b/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_7677591895010082253.json
deleted file mode 100644
index 2729792..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_7677591895010082253.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"6"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu11490867819589852614.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu11490867819589852614.jpg
deleted file mode 100644
index ebc3e08..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu11490867819589852614.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu16354810552685272732.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu16354810552685272732.jpg
deleted file mode 100644
index abc0b7f..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu16354810552685272732.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu2156760759405692730.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu2156760759405692730.jpg
deleted file mode 100644
index eace152..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu2156760759405692730.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu3596181966891003706.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu3596181966891003706.jpg
deleted file mode 100644
index 5219e9c..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu3596181966891003706.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu7317882862347184772.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu7317882862347184772.jpg
deleted file mode 100644
index cc4a03e..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu7317882862347184772.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu8461465864634564711.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu8461465864634564711.jpg
deleted file mode 100644
index fbe7f41..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu8461465864634564711.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu9871679831063181670.jpg b/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu9871679831063181670.jpg
deleted file mode 100644
index 9951de0..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/Triple_Card_Jank_hu9871679831063181670.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_a_14631887664134973272.json b/resources/_gen/images/posts/watercooling-my-homelab/complete_a_14631887664134973272.json
deleted file mode 100644
index 28c932a..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/complete_a_14631887664134973272.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"1"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_a_hu5033996381909984907.jpg b/resources/_gen/images/posts/watercooling-my-homelab/complete_a_hu5033996381909984907.jpg
deleted file mode 100644
index 909ec6c..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/complete_a_hu5033996381909984907.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_a_hu5356274077694873467.jpg b/resources/_gen/images/posts/watercooling-my-homelab/complete_a_hu5356274077694873467.jpg
deleted file mode 100644
index 217cf1f..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/complete_a_hu5356274077694873467.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_a_hu8276072409686337379.jpg b/resources/_gen/images/posts/watercooling-my-homelab/complete_a_hu8276072409686337379.jpg
deleted file mode 100644
index d6b92e3..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/complete_a_hu8276072409686337379.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_16031240908979960718.json b/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_16031240908979960718.json
deleted file mode 100644
index 2729792..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_16031240908979960718.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"6"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_hu12002901743809675925.jpg b/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_hu12002901743809675925.jpg
deleted file mode 100644
index 820ef3f..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_hu12002901743809675925.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_hu13478367401076202878.jpg b/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_hu13478367401076202878.jpg
deleted file mode 100644
index 2de19ff..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_hu13478367401076202878.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_hu2210815369484441822.jpg b/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_hu2210815369484441822.jpg
deleted file mode 100644
index 6e915cb..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/complete_assembly_hu2210815369484441822.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_b_5675827800781415085.json b/resources/_gen/images/posts/watercooling-my-homelab/complete_b_5675827800781415085.json
deleted file mode 100644
index 28c932a..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/complete_b_5675827800781415085.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"1"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_b_hu10767286083060877288.jpg b/resources/_gen/images/posts/watercooling-my-homelab/complete_b_hu10767286083060877288.jpg
deleted file mode 100644
index 4824f1d..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/complete_b_hu10767286083060877288.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_b_hu16478031875694564998.jpg b/resources/_gen/images/posts/watercooling-my-homelab/complete_b_hu16478031875694564998.jpg
deleted file mode 100644
index 88b5325..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/complete_b_hu16478031875694564998.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/complete_b_hu4616298409251397535.jpg b/resources/_gen/images/posts/watercooling-my-homelab/complete_b_hu4616298409251397535.jpg
deleted file mode 100644
index 7054736..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/complete_b_hu4616298409251397535.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/featured_hu15953821710082054155.jpg b/resources/_gen/images/posts/watercooling-my-homelab/featured_hu15953821710082054155.jpg
deleted file mode 100644
index f8fa35e..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/featured_hu15953821710082054155.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/featured_hu2105059034206722096.jpg b/resources/_gen/images/posts/watercooling-my-homelab/featured_hu2105059034206722096.jpg
deleted file mode 100644
index f950bdd..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/featured_hu2105059034206722096.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/featured_hu3104278607946126058.jpg b/resources/_gen/images/posts/watercooling-my-homelab/featured_hu3104278607946126058.jpg
deleted file mode 100644
index ab01043..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/featured_hu3104278607946126058.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/featured_hu5070883403929875594.jpg b/resources/_gen/images/posts/watercooling-my-homelab/featured_hu5070883403929875594.jpg
deleted file mode 100644
index 634d869..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/featured_hu5070883403929875594.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_6038501444377338538.json b/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_6038501444377338538.json
deleted file mode 100644
index e66ceb5..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_6038501444377338538.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint32":"0"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_hu14664884337149828911.jpg b/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_hu14664884337149828911.jpg
deleted file mode 100644
index a203aee..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_hu14664884337149828911.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_hu1582829447164391648.jpg b/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_hu1582829447164391648.jpg
deleted file mode 100644
index 901e9ef..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_hu1582829447164391648.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_hu161130888202897702.jpg b/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_hu161130888202897702.jpg
deleted file mode 100644
index 249f3c4..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/goopy_installed_hu161130888202897702.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_11669286768562804815.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_11669286768562804815.json
deleted file mode 100644
index 2729792..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_11669286768562804815.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"6"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu10135666633532349971.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu10135666633532349971.webp
deleted file mode 100644
index 3ee900d..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu10135666633532349971.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu1185606546140242812.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu1185606546140242812.webp
deleted file mode 100644
index f907656..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu1185606546140242812.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu15580473747579807272.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu15580473747579807272.webp
deleted file mode 100644
index 79b5335..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_A_hu15580473747579807272.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_4897032272284050434.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_4897032272284050434.json
deleted file mode 100644
index 2729792..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_4897032272284050434.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"6"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu3514938234529834191.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu3514938234529834191.webp
deleted file mode 100644
index cef26c7..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu3514938234529834191.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu4433789582976635675.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu4433789582976635675.webp
deleted file mode 100644
index 0c6d2ce..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu4433789582976635675.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu5645202655129247224.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu5645202655129247224.webp
deleted file mode 100644
index fe8508d..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Block_Mod_Detail_B_hu5645202655129247224.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_13643531967006020762.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_13643531967006020762.json
deleted file mode 100644
index e66ceb5..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_13643531967006020762.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint32":"0"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_14299772929806227012.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Different_Plugs_14299772929806227012.json
deleted file mode 100644
index e69de29..0000000
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_9096598664261438593.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_9096598664261438593.json
deleted file mode 100644
index e66ceb5..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/GPUs_Installed_9096598664261438593.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint32":"0"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_14299772929806227012.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/MO-RA!_14299772929806227012.json
deleted file mode 100644
index e69de29..0000000
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_10886334582480208524.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_10886334582480208524.json
deleted file mode 100644
index 2729792..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_10886334582480208524.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"6"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu15453937681749687717.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu15453937681749687717.webp
deleted file mode 100644
index 050ee2e..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu15453937681749687717.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu8777874604872247927.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu8777874604872247927.webp
deleted file mode 100644
index 500d36f..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu8777874604872247927.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu8845039929165688843.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu8845039929165688843.webp
deleted file mode 100644
index bc56c37..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Mounting_Detail_hu8845039929165688843.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_11309497749415272664.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_11309497749415272664.json
deleted file mode 100644
index e66ceb5..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Tall_Capacitor_11309497749415272664.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint32":"0"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_14299772929806227012.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_14299772929806227012.json
deleted file mode 100644
index e69de29..0000000
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_1776322075238722498.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_1776322075238722498.json
deleted file mode 100644
index 2729792..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_1776322075238722498.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"6"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu11891929429703735008.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu11891929429703735008.webp
deleted file mode 100644
index 89747a0..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu11891929429703735008.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu2342240762270192595.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu2342240762270192595.webp
deleted file mode 100644
index 3ca2bfa..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu2342240762270192595.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu248475302641151746.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu248475302641151746.webp
deleted file mode 100644
index df4d0f4..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/Triple_Card_Jank_hu248475302641151746.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_11763338158399219326.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_11763338158399219326.json
deleted file mode 100644
index 2729792..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_11763338158399219326.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"6"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_14299772929806227012.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_14299772929806227012.json
deleted file mode 100644
index e69de29..0000000
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu11828826125605575816.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu11828826125605575816.webp
deleted file mode 100644
index a09a5af..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu11828826125605575816.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu8749971626102845841.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu8749971626102845841.webp
deleted file mode 100644
index a7c20bf..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu8749971626102845841.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu9393345692205703172.webp b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu9393345692205703172.webp
deleted file mode 100644
index 5cec061..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/complete_assembly_hu9393345692205703172.webp and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_14299772929806227012.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_14299772929806227012.json
deleted file mode 100644
index e69de29..0000000
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_2179205901997953532.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_2179205901997953532.json
deleted file mode 100644
index e66ceb5..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/goopy_installed_2179205901997953532.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint32":"0"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_14299772929806227012.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/plug_detail_top_14299772929806227012.json
deleted file mode 100644
index e69de29..0000000
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_14299772929806227012.json b/resources/_gen/images/posts/watercooling-my-homelab/images/compressed/solenoid_diode_14299772929806227012.json
deleted file mode 100644
index e69de29..0000000
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_15416830398744373725.json b/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_15416830398744373725.json
deleted file mode 100644
index 28c932a..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_15416830398744373725.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"1"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_hu380018390424752032.jpg b/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_hu380018390424752032.jpg
deleted file mode 100644
index 381e93e..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_hu380018390424752032.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_hu4721531240136297022.jpg b/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_hu4721531240136297022.jpg
deleted file mode 100644
index 88cfea0..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_hu4721531240136297022.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_hu4884052793440922853.jpg b/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_hu4884052793440922853.jpg
deleted file mode 100644
index 5d37305..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_bottom_hu4884052793440922853.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_15415937442436383448.json b/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_15415937442436383448.json
deleted file mode 100644
index 28c932a..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_15415937442436383448.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"1"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_hu12684192767717054926.jpg b/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_hu12684192767717054926.jpg
deleted file mode 100644
index 8d50afd..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_hu12684192767717054926.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_hu16135941679676632890.jpg b/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_hu16135941679676632890.jpg
deleted file mode 100644
index 48aeb32..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_hu16135941679676632890.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_hu8631510140704525390.jpg b/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_hu8631510140704525390.jpg
deleted file mode 100644
index e74767a..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/plug_detail_top_hu8631510140704525390.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_10827391041612229493.json b/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_10827391041612229493.json
deleted file mode 100644
index 28c932a..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_10827391041612229493.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"1"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_hu14466657194488615062.jpg b/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_hu14466657194488615062.jpg
deleted file mode 100644
index 6ecf673..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_hu14466657194488615062.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_hu17274917339745661912.jpg b/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_hu17274917339745661912.jpg
deleted file mode 100644
index bf92a4e..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_hu17274917339745661912.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_hu6761832281731258071.jpg b/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_hu6761832281731258071.jpg
deleted file mode 100644
index bfc1ac2..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/pump_greeble_hu6761832281731258071.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_18252822193403583436.json b/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_18252822193403583436.json
deleted file mode 100644
index 28c932a..0000000
--- a/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_18252822193403583436.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Exif":{"Lat":0,"Long":0,"Date":"0001-01-01T00:00:00Z","Tags":{"Orientation|uint16":"1"}}}
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_hu12170367355616971676.jpg b/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_hu12170367355616971676.jpg
deleted file mode 100644
index 6f99cb0..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_hu12170367355616971676.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_hu15435741691645780974.jpg b/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_hu15435741691645780974.jpg
deleted file mode 100644
index 58dc3fb..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_hu15435741691645780974.jpg and /dev/null differ
diff --git a/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_hu3463397237986938589.jpg b/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_hu3463397237986938589.jpg
deleted file mode 100644
index 06baf59..0000000
Binary files a/resources/_gen/images/posts/watercooling-my-homelab/solenoid_diode_hu3463397237986938589.jpg and /dev/null differ
diff --git a/static/android-chrome-192x192.png b/static/android-chrome-192x192.png
new file mode 100644
index 0000000..23a026c
Binary files /dev/null and b/static/android-chrome-192x192.png differ
diff --git a/static/android-chrome-512x512.png b/static/android-chrome-512x512.png
new file mode 100644
index 0000000..51749bb
Binary files /dev/null and b/static/android-chrome-512x512.png differ
diff --git a/static/apple-touch-icon.png b/static/apple-touch-icon.png
new file mode 100644
index 0000000..fbbf9b2
Binary files /dev/null and b/static/apple-touch-icon.png differ
diff --git a/static/favicon-16x16.png b/static/favicon-16x16.png
new file mode 100644
index 0000000..4ca348e
Binary files /dev/null and b/static/favicon-16x16.png differ
diff --git a/static/favicon-32x32.png b/static/favicon-32x32.png
new file mode 100644
index 0000000..86c30a5
Binary files /dev/null and b/static/favicon-32x32.png differ
diff --git a/static/favicon.ico b/static/favicon.ico
new file mode 100644
index 0000000..9455fe3
Binary files /dev/null and b/static/favicon.ico differ
diff --git a/static/site.webmanifest b/static/site.webmanifest
new file mode 100644
index 0000000..45dc8a2
--- /dev/null
+++ b/static/site.webmanifest
@@ -0,0 +1 @@
+{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
\ No newline at end of file