mirror of
https://github.com/greflm13/StaticGalleryBuilder.git
synced 2026-02-05 02:59:27 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
559ff6a7b3
|
|||
|
3e3bb67884
|
|||
|
d0935a474f
|
|||
|
a57bc8e3b5
|
|||
| 08622bd092 | |||
| a8b2df43bd | |||
|
b249ae9d46
|
|||
| b4badfbd15 | |||
| cb0fe96654 | |||
| 6b04b75314 | |||
|
6076b5f6f2
|
|||
|
5036ff79f7
|
|||
|
50ca8ab5bf
|
|||
|
3f427dfa32
|
10
.hintrc
10
.hintrc
@@ -3,6 +3,14 @@
|
|||||||
"development"
|
"development"
|
||||||
],
|
],
|
||||||
"hints": {
|
"hints": {
|
||||||
"apple-touch-icons": "off"
|
"apple-touch-icons": "off",
|
||||||
|
"compat-api/css": [
|
||||||
|
"default",
|
||||||
|
{
|
||||||
|
"ignore": [
|
||||||
|
"-webkit-app-region"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,6 +90,8 @@
|
|||||||
"Scans",
|
"Scans",
|
||||||
"--exclude-folder",
|
"--exclude-folder",
|
||||||
"*/Galleries/*",
|
"*/Galleries/*",
|
||||||
|
"--exclude-folder",
|
||||||
|
"*/Wallpaper/*",
|
||||||
"--folderthumbnails"
|
"--folderthumbnails"
|
||||||
],
|
],
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
@@ -160,10 +162,12 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"prettier.htmlWhitespaceSensitivity": "css",
|
"prettier.htmlWhitespaceSensitivity": "css",
|
||||||
"pylint.args": [
|
"python-envs.pythonProjects": [
|
||||||
"--disable=C0111",
|
{
|
||||||
"--disable=C0301",
|
"path": "",
|
||||||
"--good-names-rgxs=^[_a-z][_a-z0-9]?$"
|
"envManager": "ms-python.python:pyenv",
|
||||||
|
"packageManager": "ms-python.python:pip"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"python.analysis.inlayHints.callArgumentNames": "off",
|
"python.analysis.inlayHints.callArgumentNames": "off",
|
||||||
"python.analysis.inlayHints.functionReturnTypes": false,
|
"python.analysis.inlayHints.functionReturnTypes": false,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from pathlib import Path
|
|||||||
|
|
||||||
from tqdm.auto import tqdm
|
from tqdm.auto import tqdm
|
||||||
from PIL import Image, ImageOps
|
from PIL import Image, ImageOps
|
||||||
|
from jsmin import jsmin
|
||||||
|
|
||||||
from modules.argumentparser import parse_arguments, Args
|
from modules.argumentparser import parse_arguments, Args
|
||||||
|
|
||||||
@@ -123,6 +124,10 @@ def copy_static_files(_args: Args) -> None:
|
|||||||
with open(os.path.join(static_dir, "theme.css"), "x", encoding="utf-8") as f:
|
with open(os.path.join(static_dir, "theme.css"), "x", encoding="utf-8") as f:
|
||||||
logger.info("writing theme file")
|
logger.info("writing theme file")
|
||||||
f.write(themehead + '\n.foldericon {\n content: url("data:image/svg+xml,' + svg + '");\n}\n' + themetail)
|
f.write(themehead + '\n.foldericon {\n content: url("data:image/svg+xml,' + svg + '");\n}\n' + themetail)
|
||||||
|
logger.info("minifying javascript")
|
||||||
|
with open(os.path.join(SCRIPTDIR, "templates", "functionality.js"), "r", encoding="utf-8") as js_file:
|
||||||
|
with open(os.path.join(static_dir, "functionality.min.js"), "w+", encoding="utf-8") as min_file:
|
||||||
|
min_file.write(jsmin(js_file.read()))
|
||||||
|
|
||||||
|
|
||||||
def generate_thumbnail(arguments: tuple[str, str, str]) -> None:
|
def generate_thumbnail(arguments: tuple[str, str, str]) -> None:
|
||||||
@@ -169,7 +174,7 @@ def main(args) -> None:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
Path(lock_file).touch()
|
Path(lock_file).touch()
|
||||||
logger.info("starting builder", extra={"version": VERSION})
|
logger.info("starting builder", extra={"version": VERSION, "arguments": args})
|
||||||
|
|
||||||
logger.info("getting logo from sorogon.eu")
|
logger.info("getting logo from sorogon.eu")
|
||||||
req = urllib.request.Request("https://files.sorogon.eu/logo.svg")
|
req = urllib.request.Request("https://files.sorogon.eu/logo.svg")
|
||||||
|
|||||||
@@ -66,6 +66,13 @@ body {
|
|||||||
padding: 0 2px;
|
padding: 0 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.centerload {
|
||||||
|
margin-top: 100px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
figure {
|
figure {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -208,7 +215,7 @@ input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tooltiptext.tagdropdown.show {
|
.tooltiptext.tagdropdown.show {
|
||||||
max-height: 286px;
|
max-height: 80vh;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
@@ -232,7 +239,7 @@ input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tagentryparent.show {
|
.tagentryparent.show {
|
||||||
max-height: 286px;
|
max-height: 80vh;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,7 @@
|
|||||||
transition: opacity 0.2s;
|
transition: opacity 0.2s;
|
||||||
-webkit-box-shadow: none;
|
-webkit-box-shadow: none;
|
||||||
box-shadow: none; }
|
box-shadow: none; }
|
||||||
.pswp__button:focus,
|
.pswp__button:focus, .pswp__button:hover {
|
||||||
.pswp__button:hover {
|
|
||||||
opacity: 1; }
|
opacity: 1; }
|
||||||
.pswp__button:active {
|
.pswp__button:active {
|
||||||
outline: none;
|
outline: none;
|
||||||
@@ -272,14 +271,13 @@ a.pswp__share--download:hover {
|
|||||||
color: #BBB; }
|
color: #BBB; }
|
||||||
|
|
||||||
.pswp__caption__center {
|
.pswp__caption__center {
|
||||||
text-align: center;
|
text-align: left;
|
||||||
max-width: 420px;
|
max-width: 420px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
color: #CCC;
|
color: #CCC; }
|
||||||
font-weight: bold; }
|
|
||||||
|
|
||||||
.pswp__caption--empty {
|
.pswp__caption--empty {
|
||||||
display: none; }
|
display: none; }
|
||||||
@@ -481,4 +479,4 @@ a.pswp__share--download:hover {
|
|||||||
display: none !important; }
|
display: none !important; }
|
||||||
|
|
||||||
.pswp--minimal--dark .pswp__top-bar {
|
.pswp--minimal--dark .pswp__top-bar {
|
||||||
background: none; }
|
background: none; }
|
||||||
@@ -1,131 +1 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<svg width="264" height="88" viewBox="0 0 264 88" xmlns="http://www.w3.org/2000/svg"><title>default-skin 2</title><g fill="none" fill-rule="evenodd"><g><path d="M67.002 59.5v3.768c-6.307.84-9.184 5.75-10.002 9.732 2.22-2.83 5.564-5.098 10.002-5.098V71.5L73 65.585 67.002 59.5z" id="Shape" fill="#fff"/><g fill="#fff"><path d="M13 29v-5h2v3h3v2h-5zM13 15h5v2h-3v3h-2v-5zM31 15v5h-2v-3h-3v-2h5zM31 29h-5v-2h3v-3h2v5z" id="Shape"/></g><g fill="#fff"><path d="M62 24v5h-2v-3h-3v-2h5zM62 20h-5v-2h3v-3h2v5zM70 20v-5h2v3h3v2h-5zM70 24h5v2h-3v3h-2v-5z"/></g><path d="M20.586 66l-5.656-5.656 1.414-1.414L22 64.586l5.656-5.656 1.414 1.414L23.414 66l5.656 5.656-1.414 1.414L22 67.414l-5.656 5.656-1.414-1.414L20.586 66z" fill="#fff"/><path d="M111.785 65.03L110 63.5l3-3.5h-10v-2h10l-3-3.5 1.785-1.468L117 59l-5.215 6.03z" fill="#fff"/><path d="M152.215 65.03L154 63.5l-3-3.5h10v-2h-10l3-3.5-1.785-1.468L147 59l5.215 6.03z" fill="#fff"/><g><path id="Rectangle-11" fill="#fff" d="M160.957 28.543l-3.25-3.25-1.413 1.414 3.25 3.25z"/><path d="M152.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z" id="Oval-1" stroke="#fff" stroke-width="1.5"/><path fill="#fff" d="M150 21h5v1h-5z"/></g><g><path d="M116.957 28.543l-1.414 1.414-3.25-3.25 1.414-1.414 3.25 3.25z" fill="#fff"/><path d="M108.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z" stroke="#fff" stroke-width="1.5"/><path fill="#fff" d="M106 21h5v1h-5z"/><path fill="#fff" d="M109.043 19.008l-.085 5-1-.017.085-5z"/></g></g></g></svg>
|
||||||
<svg
|
|
||||||
width="264"
|
|
||||||
height="88"
|
|
||||||
viewBox="0 0 264 88"
|
|
||||||
version="1.1"
|
|
||||||
id="svg12"
|
|
||||||
sodipodi:docname="default-skin.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
||||||
<defs
|
|
||||||
id="defs12" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview12"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="true"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="true"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
showborder="true"
|
|
||||||
borderlayer="true"
|
|
||||||
inkscape:zoom="3.0855569"
|
|
||||||
inkscape:cx="95.606729"
|
|
||||||
inkscape:cy="65.142212"
|
|
||||||
inkscape:window-width="1896"
|
|
||||||
inkscape:window-height="1016"
|
|
||||||
inkscape:window-x="1932"
|
|
||||||
inkscape:window-y="52"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="g11" />
|
|
||||||
<title
|
|
||||||
id="title1">default-skin 2</title>
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
fill-rule="evenodd"
|
|
||||||
id="g12">
|
|
||||||
<g
|
|
||||||
id="g11">
|
|
||||||
<g
|
|
||||||
fill="#fff"
|
|
||||||
id="g1">
|
|
||||||
<path
|
|
||||||
d="M13 29v-5h2v3h3v2h-5zM13 15h5v2h-3v3h-2v-5zM31 15v5h-2v-3h-3v-2h5zM31 29h-5v-2h3v-3h2v5z"
|
|
||||||
id="path1" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
fill="#fff"
|
|
||||||
id="g2">
|
|
||||||
<path
|
|
||||||
d="M62 24v5h-2v-3h-3v-2h5zM62 20h-5v-2h3v-3h2v5zM70 20v-5h2v3h3v2h-5zM70 24h5v2h-3v3h-2v-5z"
|
|
||||||
id="path2" />
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
d="M20.586 66l-5.656-5.656 1.414-1.414L22 64.586l5.656-5.656 1.414 1.414L23.414 66l5.656 5.656-1.414 1.414L22 67.414l-5.656 5.656-1.414-1.414L20.586 66z"
|
|
||||||
fill="#fff"
|
|
||||||
id="path3" />
|
|
||||||
<path
|
|
||||||
d="M111.785 65.03L110 63.5l3-3.5h-10v-2h10l-3-3.5 1.785-1.468L117 59l-5.215 6.03z"
|
|
||||||
fill="#fff"
|
|
||||||
id="path4" />
|
|
||||||
<path
|
|
||||||
d="M152.215 65.03L154 63.5l-3-3.5h10v-2h-10l3-3.5-1.785-1.468L147 59l5.215 6.03z"
|
|
||||||
fill="#fff"
|
|
||||||
id="path5" />
|
|
||||||
<g
|
|
||||||
id="g6">
|
|
||||||
<path
|
|
||||||
id="Rectangle-11"
|
|
||||||
fill="#fff"
|
|
||||||
d="M160.957 28.543l-3.25-3.25-1.413 1.414 3.25 3.25z" />
|
|
||||||
<path
|
|
||||||
d="M152.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z"
|
|
||||||
id="Oval-1"
|
|
||||||
stroke="#fff"
|
|
||||||
stroke-width="1.5" />
|
|
||||||
<path
|
|
||||||
fill="#fff"
|
|
||||||
d="M150 21h5v1h-5z"
|
|
||||||
id="path6" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g10">
|
|
||||||
<path
|
|
||||||
d="M116.957 28.543l-1.414 1.414-3.25-3.25 1.414-1.414 3.25 3.25z"
|
|
||||||
fill="#fff"
|
|
||||||
id="path7" />
|
|
||||||
<path
|
|
||||||
d="M108.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z"
|
|
||||||
stroke="#fff"
|
|
||||||
stroke-width="1.5"
|
|
||||||
id="path8" />
|
|
||||||
<path
|
|
||||||
fill="#fff"
|
|
||||||
d="M106 21h5v1h-5z"
|
|
||||||
id="path9" />
|
|
||||||
<path
|
|
||||||
fill="#fff"
|
|
||||||
d="M109.043 19.008l-.085 5-1-.017.085-5z"
|
|
||||||
id="path10" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g14">
|
|
||||||
<path
|
|
||||||
id="Shape"
|
|
||||||
style="fill:#ffffff"
|
|
||||||
d="M 63.708984 57.572266 L 63.708984 66.917969 L 62.773438 66.917969 L 59.173828 66.917969 L 65.089844 72.916016 L 71.173828 66.917969 L 67.40625 66.917969 L 66.640625 66.917969 L 66.640625 57.572266 L 63.708984 57.572266 z " />
|
|
||||||
<path
|
|
||||||
id="rect13"
|
|
||||||
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.649;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
d="m 56.24391,72.078606 v 3.51729 h 17.859837 v -3.51729 h -1.210961 v 2.324677 H 57.456705 v -2.324677 z" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<metadata
|
|
||||||
id="metadata12">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:title>default-skin 2</dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 1.5 KiB |
6
files/pswp/photoswipe-ui-default.min.js
vendored
6
files/pswp/photoswipe-ui-default.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -15,21 +15,14 @@
|
|||||||
touch-action: none;
|
touch-action: none;
|
||||||
z-index: 1500;
|
z-index: 1500;
|
||||||
-webkit-text-size-adjust: 100%;
|
-webkit-text-size-adjust: 100%;
|
||||||
text-size-adjust: 100%;
|
|
||||||
/* create separate layer, to avoid paint on window.onscroll in webkit/blink */
|
/* create separate layer, to avoid paint on window.onscroll in webkit/blink */
|
||||||
-webkit-backface-visibility: hidden;
|
-webkit-backface-visibility: hidden;
|
||||||
backface-visibility: hidden;
|
outline: none; }
|
||||||
outline: none;
|
.pswp * {
|
||||||
}
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box; }
|
||||||
.pswp * {
|
.pswp img {
|
||||||
-webkit-box-sizing: border-box;
|
max-width: none; }
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pswp img {
|
|
||||||
max-width: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* style is added when JS option showHideOpacity is set to true */
|
/* style is added when JS option showHideOpacity is set to true */
|
||||||
.pswp--animate_opacity {
|
.pswp--animate_opacity {
|
||||||
@@ -38,33 +31,28 @@
|
|||||||
will-change: opacity;
|
will-change: opacity;
|
||||||
/* for open/close transition */
|
/* for open/close transition */
|
||||||
-webkit-transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1);
|
-webkit-transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1);
|
||||||
transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1);
|
transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp--open {
|
.pswp--open {
|
||||||
display: block;
|
display: block; }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp--zoom-allowed .pswp__img {
|
.pswp--zoom-allowed .pswp__img {
|
||||||
/* autoprefixer: off */
|
/* autoprefixer: off */
|
||||||
cursor: -webkit-zoom-in;
|
cursor: -webkit-zoom-in;
|
||||||
cursor: -moz-zoom-in;
|
cursor: -moz-zoom-in;
|
||||||
cursor: zoom-in;
|
cursor: zoom-in; }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp--zoomed-in .pswp__img {
|
.pswp--zoomed-in .pswp__img {
|
||||||
/* autoprefixer: off */
|
/* autoprefixer: off */
|
||||||
cursor: -webkit-grab;
|
cursor: -webkit-grab;
|
||||||
cursor: -moz-grab;
|
cursor: -moz-grab;
|
||||||
cursor: grab;
|
cursor: grab; }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp--dragging .pswp__img {
|
.pswp--dragging .pswp__img {
|
||||||
/* autoprefixer: off */
|
/* autoprefixer: off */
|
||||||
cursor: -webkit-grabbing;
|
cursor: -webkit-grabbing;
|
||||||
cursor: -moz-grabbing;
|
cursor: -moz-grabbing;
|
||||||
cursor: grabbing;
|
cursor: grabbing; }
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Background is added as a separate element.
|
Background is added as a separate element.
|
||||||
@@ -78,10 +66,10 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
background: #000;
|
background: #000;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
-webkit-transform: translateZ(0);
|
||||||
|
transform: translateZ(0);
|
||||||
-webkit-backface-visibility: hidden;
|
-webkit-backface-visibility: hidden;
|
||||||
backface-visibility: hidden;
|
will-change: opacity; }
|
||||||
will-change: opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pswp__scroll-wrap {
|
.pswp__scroll-wrap {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -89,8 +77,7 @@
|
|||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden; }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp__container,
|
.pswp__container,
|
||||||
.pswp__zoom-wrap {
|
.pswp__zoom-wrap {
|
||||||
@@ -100,8 +87,7 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0; }
|
||||||
}
|
|
||||||
|
|
||||||
/* Prevent selection and tap highlights */
|
/* Prevent selection and tap highlights */
|
||||||
.pswp__container,
|
.pswp__container,
|
||||||
@@ -109,10 +95,9 @@
|
|||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none; }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp__zoom-wrap {
|
.pswp__zoom-wrap {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -122,27 +107,22 @@
|
|||||||
transform-origin: left top;
|
transform-origin: left top;
|
||||||
/* for open/close transition */
|
/* for open/close transition */
|
||||||
-webkit-transition: -webkit-transform 333ms cubic-bezier(0.4, 0, 0.22, 1);
|
-webkit-transition: -webkit-transform 333ms cubic-bezier(0.4, 0, 0.22, 1);
|
||||||
transition: transform 333ms cubic-bezier(0.4, 0, 0.22, 1);
|
transition: transform 333ms cubic-bezier(0.4, 0, 0.22, 1); }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp__bg {
|
.pswp__bg {
|
||||||
will-change: opacity;
|
will-change: opacity;
|
||||||
/* for open/close transition */
|
/* for open/close transition */
|
||||||
-webkit-transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1);
|
-webkit-transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1);
|
||||||
transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1);
|
transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp--animated-in .pswp__bg,
|
.pswp--animated-in .pswp__bg,
|
||||||
.pswp--animated-in .pswp__zoom-wrap {
|
.pswp--animated-in .pswp__zoom-wrap {
|
||||||
-webkit-transition: none;
|
-webkit-transition: none;
|
||||||
transition: none;
|
transition: none; }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp__container,
|
.pswp__container,
|
||||||
.pswp__zoom-wrap {
|
.pswp__zoom-wrap {
|
||||||
-webkit-backface-visibility: hidden;
|
-webkit-backface-visibility: hidden; }
|
||||||
backface-visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pswp__item {
|
.pswp__item {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -150,40 +130,34 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
overflow: hidden;
|
overflow: hidden; }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp__img {
|
.pswp__img {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0; }
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
stretched thumbnail or div placeholder element (see below)
|
stretched thumbnail or div placeholder element (see below)
|
||||||
style is added to avoid flickering in webkit/blink when layers overlap
|
style is added to avoid flickering in webkit/blink when layers overlap
|
||||||
*/
|
*/
|
||||||
.pswp__img--placeholder {
|
.pswp__img--placeholder {
|
||||||
-webkit-backface-visibility: hidden;
|
-webkit-backface-visibility: hidden; }
|
||||||
backface-visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
div element that matches size of large image
|
div element that matches size of large image
|
||||||
large image loads on top of it
|
large image loads on top of it
|
||||||
*/
|
*/
|
||||||
.pswp__img--placeholder--blank {
|
.pswp__img--placeholder--blank {
|
||||||
background: #222;
|
background: #222; }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp--ie .pswp__img {
|
.pswp--ie .pswp__img {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0; }
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Error message appears when image is not loaded
|
Error message appears when image is not loaded
|
||||||
@@ -198,10 +172,8 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
margin-top: -8px;
|
margin-top: -8px;
|
||||||
color: #CCC;
|
color: #CCC; }
|
||||||
}
|
|
||||||
|
|
||||||
.pswp__error-msg a {
|
.pswp__error-msg a {
|
||||||
color: #CCC;
|
color: #CCC;
|
||||||
text-decoration: underline;
|
text-decoration: underline; }
|
||||||
}
|
|
||||||
3788
files/pswp/photoswipe.js
Normal file
3788
files/pswp/photoswipe.js
Normal file
File diff suppressed because it is too large
Load Diff
9
files/pswp/photoswipe.min.js
vendored
9
files/pswp/photoswipe.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -3,6 +3,7 @@ import re
|
|||||||
import urllib.parse
|
import urllib.parse
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import json
|
import json
|
||||||
|
import html
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
@@ -11,6 +12,7 @@ from tqdm.auto import tqdm
|
|||||||
from PIL import Image, ExifTags, TiffImagePlugin, UnidentifiedImageError
|
from PIL import Image, ExifTags, TiffImagePlugin, UnidentifiedImageError
|
||||||
from jinja2 import Environment, FileSystemLoader
|
from jinja2 import Environment, FileSystemLoader
|
||||||
from defusedxml import ElementTree
|
from defusedxml import ElementTree
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
from modules.logger import logger
|
from modules.logger import logger
|
||||||
from modules import cclicense
|
from modules import cclicense
|
||||||
@@ -516,17 +518,18 @@ def process_subfolder(item: str, folder: str, baseurl: str, subfolders: list[dic
|
|||||||
|
|
||||||
def process_license(folder: str, item: str) -> None:
|
def process_license(folder: str, item: str) -> None:
|
||||||
"""
|
"""
|
||||||
Processes a LICENSE file.
|
Processes a LICENSE file, preserving formatting in HTML.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
folder (str): The folder containing the info file.
|
folder (str): The folder containing the LICENSE file.
|
||||||
item (str): The licenses file name.
|
item (str): The LICENSE file name.
|
||||||
"""
|
"""
|
||||||
with open(os.path.join(folder, item), encoding="utf-8") as f:
|
path = os.path.join(folder, item)
|
||||||
logger.info("processing LICENSE", extra={"path": os.path.join(folder, item)})
|
with open(path, encoding="utf-8") as f:
|
||||||
licens[urllib.parse.quote(folder)] = (
|
logger.info("processing LICENSE", extra={"path": path})
|
||||||
f.read().replace("\n", "</br>\n").replace(" ", " ").replace(" ", " ").replace("sp; ", "sp; ").replace("  ", " ")
|
raw_text = f.read()
|
||||||
)
|
escaped_text = html.escape(raw_text)
|
||||||
|
licens[urllib.parse.quote(folder)] = f"<pre>{escaped_text}</pre>"
|
||||||
|
|
||||||
|
|
||||||
def process_info_file(folder: str, item: str) -> None:
|
def process_info_file(folder: str, item: str) -> None:
|
||||||
@@ -556,6 +559,11 @@ def should_generate_html(images: list[dict[str, Any]], contains_files, _args: Ar
|
|||||||
return images or (_args.use_fancy_folders and not contains_files) or (_args.use_fancy_folders and _args.ignore_other_files)
|
return images or (_args.use_fancy_folders and not contains_files) or (_args.use_fancy_folders and _args.ignore_other_files)
|
||||||
|
|
||||||
|
|
||||||
|
def format_html(html: str) -> str:
|
||||||
|
soup = BeautifulSoup(html, "html5lib")
|
||||||
|
return soup.prettify()
|
||||||
|
|
||||||
|
|
||||||
def create_html_file(
|
def create_html_file(
|
||||||
folder: str, title: str, foldername: str, images: list[dict[str, Any]], subfolders: list[dict[str, str]], _args: Args, version: str, logo: str, subfoldertags: list[str]
|
folder: str, title: str, foldername: str, images: list[dict[str, Any]], subfolders: list[dict[str, str]], _args: Args, version: str, logo: str, subfoldertags: list[str]
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
@@ -591,7 +599,8 @@ def create_html_file(
|
|||||||
|
|
||||||
alltags = set()
|
alltags = set()
|
||||||
for img in images:
|
for img in images:
|
||||||
alltags.update(img["tags"])
|
if img["tags"]:
|
||||||
|
alltags.update(img["tags"])
|
||||||
|
|
||||||
alltags.update(set(subfoldertags))
|
alltags.update(set(subfoldertags))
|
||||||
|
|
||||||
@@ -624,7 +633,7 @@ def create_html_file(
|
|||||||
logo=logo,
|
logo=logo,
|
||||||
licensefile=folder_license,
|
licensefile=folder_license,
|
||||||
)
|
)
|
||||||
f.write(content)
|
f.write(format_html(content))
|
||||||
|
|
||||||
html = env.get_template("index.html.j2")
|
html = env.get_template("index.html.j2")
|
||||||
content = html.render(
|
content = html.render(
|
||||||
@@ -646,8 +655,8 @@ def create_html_file(
|
|||||||
)
|
)
|
||||||
|
|
||||||
with open(html_file, "w", encoding="utf-8") as f:
|
with open(html_file, "w", encoding="utf-8") as f:
|
||||||
logger.info("writing html file", extra={"path": html_file})
|
logger.info("writing formatted html file", extra={"path": html_file})
|
||||||
f.write(content)
|
f.write(format_html(content))
|
||||||
|
|
||||||
return sorted(alltags)
|
return sorted(alltags)
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ def setup_logger(level=logging.INFO):
|
|||||||
"""
|
"""
|
||||||
_logger = logging.getLogger(name="defaultlogger")
|
_logger = logging.getLogger(name="defaultlogger")
|
||||||
|
|
||||||
supported_keys = ["asctime", "created", "filename", "funcName", "levelname", "levelno", "lineno", "module", "msecs", "message", "name", "pathname", "process", "processName", "relativeCreated", "thread", "threadName", "taskName"]
|
supported_keys = ["asctime", "created", "filename", "funcName", "levelname", "levelno", "lineno", "module", "msecs", "message", "process", "processName", "relativeCreated", "thread", "threadName"]
|
||||||
|
|
||||||
custom_format = " ".join(log_format(supported_keys))
|
custom_format = " ".join(log_format(supported_keys))
|
||||||
formatter = jsonlogger.JsonFormatter(custom_format)
|
formatter = jsonlogger.JsonFormatter(custom_format)
|
||||||
@@ -121,7 +121,7 @@ def setup_consolelogger(level=logging.INFO):
|
|||||||
"""
|
"""
|
||||||
_logger = logging.getLogger(name="consolelogger")
|
_logger = logging.getLogger(name="consolelogger")
|
||||||
|
|
||||||
supported_keys = ["asctime", "created", "filename", "funcName", "levelname", "levelno", "lineno", "module", "msecs", "message", "name", "pathname", "process", "processName", "relativeCreated", "thread", "threadName", "taskName"]
|
supported_keys = ["asctime", "created", "filename", "funcName", "levelname", "levelno", "lineno", "module", "msecs", "message", "process", "processName", "relativeCreated", "thread", "threadName"]
|
||||||
|
|
||||||
custom_format = " ".join(log_format(supported_keys))
|
custom_format = " ".join(log_format(supported_keys))
|
||||||
formatter = jsonlogger.JsonFormatter(custom_format)
|
formatter = jsonlogger.JsonFormatter(custom_format)
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ def render_manifest_json(_args: Args, icon_list: list[Icon], colors: dict[str, s
|
|||||||
colors : dict[str, str]
|
colors : dict[str, str]
|
||||||
dictionary containing color scheme and theme color.
|
dictionary containing color scheme and theme color.
|
||||||
"""
|
"""
|
||||||
manifest = env.get_template("manifest.json.j2")
|
manifest = env.get_template("manifest.webmanifest.j2")
|
||||||
content = manifest.render(
|
content = manifest.render(
|
||||||
name=_args.web_root_url.replace("https://", "").replace("http://", "").replace("/", ""),
|
name=_args.web_root_url.replace("https://", "").replace("http://", "").replace("/", ""),
|
||||||
short_name=_args.site_title,
|
short_name=_args.site_title,
|
||||||
@@ -154,8 +154,8 @@ def render_manifest_json(_args: Args, icon_list: list[Icon], colors: dict[str, s
|
|||||||
background_color=colors["bcolor1"],
|
background_color=colors["bcolor1"],
|
||||||
theme_color=colors["theme_color"],
|
theme_color=colors["theme_color"],
|
||||||
)
|
)
|
||||||
with open(os.path.join(_args.root_directory, ".static", "manifest.json"), "w", encoding="utf-8") as f:
|
with open(os.path.join(_args.root_directory, ".static", "manifest.webmanifest"), "w", encoding="utf-8") as f:
|
||||||
logger.info("rendering manifest.json", extra={"path": os.path.join(_args.root_directory, ".static", "manifest.json")})
|
logger.info("rendering manifest.webmanifest", extra={"path": os.path.join(_args.root_directory, ".static", "manifest.webmanifest")})
|
||||||
f.write(content)
|
f.write(content)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
CairoSVG==2.7.1
|
beautifulsoup4~=4.13.4
|
||||||
defusedxml==0.7.1
|
CairoSVG~=2.7.1
|
||||||
Jinja2==3.1.5
|
defusedxml~=0.7.1
|
||||||
Pillow==11.1.0
|
html5lib~=1.1
|
||||||
pyinstaller==6.11.1
|
Jinja2~=3.1.6
|
||||||
python_json_logger==2.0.7
|
jsmin~=3.0.1
|
||||||
rich_argparse==1.7.0
|
Pillow~=11.3.0
|
||||||
selenium==4.28.1
|
pyinstaller~=6.11.1
|
||||||
tqdm==4.66.4
|
python_json_logger~=2.0.7
|
||||||
|
rich_argparse~=1.7.1
|
||||||
|
selenium~=4.34.2
|
||||||
|
tqdm~=4.66.4
|
||||||
|
|||||||
419
templates/functionality.js
Normal file
419
templates/functionality.js
Normal file
@@ -0,0 +1,419 @@
|
|||||||
|
class PhotoGallery {
|
||||||
|
constructor() {
|
||||||
|
this.pswpElement = document.querySelector(".pswp");
|
||||||
|
this.items = [];
|
||||||
|
this.shown = [];
|
||||||
|
this.subfolders = [];
|
||||||
|
this.controllers = {};
|
||||||
|
this.tagDropdownShown = false;
|
||||||
|
|
||||||
|
this.debounce = this.debounce.bind(this);
|
||||||
|
this.openSwipe = this.openSwipe.bind(this);
|
||||||
|
this.prefetch = this.prefetch.bind(this);
|
||||||
|
this.cancel = this.cancel.bind(this);
|
||||||
|
this.reset = this.reset.bind(this);
|
||||||
|
this.recursive = this.recursive.bind(this);
|
||||||
|
this.requestMetadata = this.requestMetadata.bind(this);
|
||||||
|
this.filter = this.filter.bind(this);
|
||||||
|
this.updateImageList = this.updateImageList.bind(this);
|
||||||
|
this.setFilter = this.setFilter.bind(this);
|
||||||
|
this.toggleTag = this.toggleTag.bind(this);
|
||||||
|
this.setupDropdownToggle = this.setupDropdownToggle.bind(this);
|
||||||
|
this.setupTagHandlers = this.setupTagHandlers.bind(this);
|
||||||
|
this.setupClickHandlers = this.setupClickHandlers.bind(this);
|
||||||
|
this.scrollFunction = this.scrollFunction.bind(this);
|
||||||
|
this.topFunction = this.topFunction.bind(this);
|
||||||
|
this.onLoad = this.onLoad.bind(this);
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
debounce(fn, delay) {
|
||||||
|
let timeoutId;
|
||||||
|
return (...args) => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
timeoutId = setTimeout(() => fn.apply(this, args), delay);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
openSwipe(imgIndex) {
|
||||||
|
const options = { index: imgIndex };
|
||||||
|
const gallery = new PhotoSwipe(
|
||||||
|
this.pswpElement,
|
||||||
|
PhotoSwipeUI_Default,
|
||||||
|
this.shown,
|
||||||
|
options
|
||||||
|
);
|
||||||
|
gallery.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
prefetch(imgIndex) {
|
||||||
|
if (this.controllers[imgIndex]) {
|
||||||
|
this.cancel(imgIndex);
|
||||||
|
}
|
||||||
|
const controller = new AbortController();
|
||||||
|
const signal = controller.signal;
|
||||||
|
this.controllers[imgIndex] = controller;
|
||||||
|
const urlToFetch = this.shown[imgIndex]?.src;
|
||||||
|
if (urlToFetch) {
|
||||||
|
fetch(urlToFetch, { method: "GET", signal }).catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel(imgIndex) {
|
||||||
|
if (this.controllers[imgIndex]) {
|
||||||
|
this.controllers[imgIndex].abort();
|
||||||
|
delete this.controllers[imgIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
const content = document.documentElement.innerHTML;
|
||||||
|
const title = document.title;
|
||||||
|
const folders = document.querySelector(".folders");
|
||||||
|
let path = window.location.origin + window.location.pathname;
|
||||||
|
if (path.startsWith("null")) {
|
||||||
|
path = window.location.protocol + "//" + path.substring(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (folders) folders.style.display = "";
|
||||||
|
document.getElementById("recursive").checked = false;
|
||||||
|
document
|
||||||
|
.querySelectorAll("#tagdropdown input.tagcheckbox:checked")
|
||||||
|
.forEach((checkbox) => (checkbox.checked = false));
|
||||||
|
window.history.replaceState({ html: content, pageTitle: title }, "", path);
|
||||||
|
this.requestMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
|
showLoader() {
|
||||||
|
const imagelist = document.getElementById("imagelist");
|
||||||
|
imagelist.innerHTML = '<span class="loader"></span>';
|
||||||
|
imagelist.classList.add("centerload");
|
||||||
|
imagelist.classList.remove("row");
|
||||||
|
}
|
||||||
|
|
||||||
|
async recursive() {
|
||||||
|
this.showLoader();
|
||||||
|
const loc = new URL(window.location.href);
|
||||||
|
const content = document.documentElement.innerHTML;
|
||||||
|
const title = document.title;
|
||||||
|
const isChecked = document.getElementById("recursive")?.checked;
|
||||||
|
const folders = document.querySelector(".folders");
|
||||||
|
|
||||||
|
if (!isChecked) {
|
||||||
|
if (folders) folders.style.display = "";
|
||||||
|
loc.searchParams.delete("recursive");
|
||||||
|
window.history.replaceState({ html: content, pageTitle: title }, "", loc);
|
||||||
|
this.requestMetadata();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (folders) folders.style.display = "none";
|
||||||
|
loc.searchParams.delete("recursive");
|
||||||
|
loc.searchParams.append("recursive", true);
|
||||||
|
window.history.replaceState({ html: content, pageTitle: title }, "", loc);
|
||||||
|
|
||||||
|
const visited = new Set();
|
||||||
|
const existingItems = new Set();
|
||||||
|
const newItems = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(".metadata.json");
|
||||||
|
if (!response.ok) throw new Error("Failed to fetch metadata");
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
this.items = [];
|
||||||
|
this.subfolders = data.subfolders || [];
|
||||||
|
|
||||||
|
for (const image of Object.values(data.images || {})) {
|
||||||
|
newItems.push(image);
|
||||||
|
existingItems.add(image.src);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchFoldersRecursively = async (folderList) => {
|
||||||
|
if (!Array.isArray(folderList)) return;
|
||||||
|
const nextLevel = [];
|
||||||
|
await Promise.all(
|
||||||
|
folderList.map(async (folder) => {
|
||||||
|
if (!folder || !folder.metadata || visited.has(folder.url)) return;
|
||||||
|
visited.add(folder.url);
|
||||||
|
try {
|
||||||
|
const response = await fetch(folder.metadata);
|
||||||
|
if (!response.ok) throw new Error();
|
||||||
|
const data = await response.json();
|
||||||
|
for (const image of Object.values(data.images || {})) {
|
||||||
|
if (!existingItems.has(image.src)) {
|
||||||
|
newItems.push(image);
|
||||||
|
existingItems.add(image.src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Array.isArray(data.subfolders))
|
||||||
|
nextLevel.push(...data.subfolders);
|
||||||
|
} catch {}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
if (nextLevel.length > 0) await fetchFoldersRecursively(nextLevel);
|
||||||
|
};
|
||||||
|
|
||||||
|
await fetchFoldersRecursively(this.subfolders);
|
||||||
|
this.items = [...newItems];
|
||||||
|
this.filter();
|
||||||
|
}
|
||||||
|
|
||||||
|
requestMetadata() {
|
||||||
|
this.showLoader();
|
||||||
|
const hash = window.location.hash;
|
||||||
|
const searchParams = new URLSearchParams(window.location.search);
|
||||||
|
fetch(".metadata.json")
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) throw new Error("Failed to fetch metadata");
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
this.items = Object.values(data.images || {});
|
||||||
|
this.subfolders = data.subfolders || [];
|
||||||
|
|
||||||
|
if (hash != "") {
|
||||||
|
const selected = hash.replace("#", "").split(",");
|
||||||
|
this.setFilter(selected);
|
||||||
|
}
|
||||||
|
if (searchParams.get("recursive") != null) {
|
||||||
|
const recChk = document.getElementById("recursive");
|
||||||
|
if (recChk) recChk.checked = true;
|
||||||
|
this.recursive();
|
||||||
|
} else {
|
||||||
|
this.filter();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
filter() {
|
||||||
|
const searchParams = new URLSearchParams(window.location.search);
|
||||||
|
this.shown = [];
|
||||||
|
let path = decodeURIComponent(
|
||||||
|
window.location.origin +
|
||||||
|
window.location.pathname.replace("index.html", "")
|
||||||
|
);
|
||||||
|
if (path.startsWith("null")) {
|
||||||
|
path = window.location.protocol + "//" + path.substring(4);
|
||||||
|
}
|
||||||
|
const selectedTags = [];
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelectorAll("#tagdropdown input.tagcheckbox:checked")
|
||||||
|
.forEach((checkbox) => {
|
||||||
|
let tag = checkbox.parentElement.id.trim().substring(1);
|
||||||
|
if (checkbox.parentElement.parentElement.children.length > 1)
|
||||||
|
tag += "|";
|
||||||
|
selectedTags.push(tag);
|
||||||
|
});
|
||||||
|
|
||||||
|
const urltags = selectedTags.join(",");
|
||||||
|
|
||||||
|
let isRecursiveChecked = false;
|
||||||
|
try {
|
||||||
|
isRecursiveChecked =
|
||||||
|
document.getElementById("recursive")?.checked || false;
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
for (const item of this.items) {
|
||||||
|
const tags = item.tags || [];
|
||||||
|
const include = selectedTags.every((selected) => {
|
||||||
|
const isParent = selected.endsWith("|");
|
||||||
|
return isParent
|
||||||
|
? tags.some((t) => t.startsWith(selected))
|
||||||
|
: tags.includes(selected);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (include || selectedTags.length === 0) {
|
||||||
|
if (!isRecursiveChecked) {
|
||||||
|
if (decodeURIComponent(item.src).replace(item.name, "") === path) {
|
||||||
|
this.shown.push(item);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.shown.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.updateImageList();
|
||||||
|
window.location.hash = urltags;
|
||||||
|
|
||||||
|
const pid = searchParams.get("pid") - 1;
|
||||||
|
if (pid != -1) {
|
||||||
|
this.openSwipe(pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateImageList() {
|
||||||
|
const imagelist = document.getElementById("imagelist");
|
||||||
|
if (!imagelist) return;
|
||||||
|
let str = "";
|
||||||
|
this.shown.forEach((item, index) => {
|
||||||
|
str += `<div class="column"><figure><img src="${item.msrc}" data-index="${index}" /><figcaption class="caption">${item.name}`;
|
||||||
|
if (item.tiff) str += ` <a href="${item.tiff}">TIFF</a>`;
|
||||||
|
if (item.raw) str += ` <a href="${item.raw}">RAW</a>`;
|
||||||
|
str += "</figcaption></figure></div>";
|
||||||
|
});
|
||||||
|
imagelist.classList.add("row");
|
||||||
|
imagelist.classList.remove("centerload");
|
||||||
|
imagelist.innerHTML = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
setFilter(selected) {
|
||||||
|
document
|
||||||
|
.querySelectorAll("#tagdropdown input.tagcheckbox")
|
||||||
|
.forEach((checkbox) => {
|
||||||
|
selected.forEach((tag) => {
|
||||||
|
if (
|
||||||
|
checkbox.parentElement.id
|
||||||
|
.trim()
|
||||||
|
.substring(1)
|
||||||
|
.replace(" ", "%20") === tag
|
||||||
|
) {
|
||||||
|
checkbox.checked = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleTag(tagid) {
|
||||||
|
const tag = document.getElementById(tagid);
|
||||||
|
const ol = tag?.closest(".tagentry")?.querySelector(".tagentryparent");
|
||||||
|
const svg = tag?.parentElement.querySelector(".tagtoggle svg");
|
||||||
|
if (!ol || !svg) return;
|
||||||
|
ol.classList.toggle("show");
|
||||||
|
svg.style.transform = ol.classList.contains("show")
|
||||||
|
? "rotate(180deg)"
|
||||||
|
: "rotate(0deg)";
|
||||||
|
}
|
||||||
|
|
||||||
|
setupDropdownToggle() {
|
||||||
|
const toggleLink = document.getElementById("tagtogglelink");
|
||||||
|
const dropdown = document.getElementById("tagdropdown");
|
||||||
|
if (!toggleLink) return;
|
||||||
|
|
||||||
|
toggleLink.addEventListener("click", (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
const svg = toggleLink.querySelector("svg");
|
||||||
|
dropdown.classList.toggle("show");
|
||||||
|
if (svg)
|
||||||
|
svg.style.transform = dropdown.classList.contains("show")
|
||||||
|
? "rotate(180deg)"
|
||||||
|
: "rotate(0deg)";
|
||||||
|
this.tagDropdownShown = dropdown.classList.contains("show");
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("click", (event) => {
|
||||||
|
if (
|
||||||
|
!dropdown.contains(event.target) &&
|
||||||
|
!toggleLink.contains(event.target)
|
||||||
|
) {
|
||||||
|
dropdown.classList.remove("show");
|
||||||
|
this.tagDropdownShown = false;
|
||||||
|
const svg = toggleLink.querySelector("svg");
|
||||||
|
if (svg) svg.style.transform = "rotate(0deg)";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setupTagHandlers() {
|
||||||
|
const tagContainer = document.getElementById("tagdropdown");
|
||||||
|
if (!tagContainer) return;
|
||||||
|
|
||||||
|
const debouncedFilter = this.debounce(this.filter, 150);
|
||||||
|
tagContainer.addEventListener("change", debouncedFilter);
|
||||||
|
|
||||||
|
tagContainer.addEventListener("click", (event) => {
|
||||||
|
const toggle = event.target.closest(".tagtoggle");
|
||||||
|
if (toggle) {
|
||||||
|
event.stopPropagation();
|
||||||
|
const tagid = toggle.dataset.toggleid;
|
||||||
|
this.toggleTag(tagid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setupClickHandlers() {
|
||||||
|
const resetEl = document
|
||||||
|
.getElementById("reset-filter")
|
||||||
|
?.querySelector("label");
|
||||||
|
if (resetEl) resetEl.addEventListener("click", this.reset);
|
||||||
|
|
||||||
|
const recurseEl = document.getElementById("recursive");
|
||||||
|
if (recurseEl)
|
||||||
|
recurseEl.addEventListener("change", this.debounce(this.recursive, 150));
|
||||||
|
|
||||||
|
const totop = document.getElementById("totop");
|
||||||
|
if (totop) totop.addEventListener("click", this.topFunction);
|
||||||
|
|
||||||
|
const imagelist = document.getElementById("imagelist");
|
||||||
|
if (imagelist) {
|
||||||
|
imagelist.addEventListener("click", (event) => {
|
||||||
|
const img = event.target.closest("img");
|
||||||
|
if (!img || !img.dataset.index) return;
|
||||||
|
const index = parseInt(img.dataset.index);
|
||||||
|
if (!isNaN(index)) this.openSwipe(index);
|
||||||
|
});
|
||||||
|
|
||||||
|
imagelist.addEventListener("mouseover", (event) => {
|
||||||
|
const img = event.target.closest("img");
|
||||||
|
if (!img || !img.dataset.index) return;
|
||||||
|
const index = parseInt(img.dataset.index);
|
||||||
|
if (!isNaN(index)) this.prefetch(index);
|
||||||
|
});
|
||||||
|
|
||||||
|
imagelist.addEventListener("mouseleave", (event) => {
|
||||||
|
const img = event.target.closest("img");
|
||||||
|
if (!img || !img.dataset.index) return;
|
||||||
|
const index = parseInt(img.dataset.index);
|
||||||
|
if (!isNaN(index)) this.cancel(index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollFunction() {
|
||||||
|
const totopbutton = document.getElementById("totop");
|
||||||
|
if (!totopbutton) return;
|
||||||
|
if (
|
||||||
|
document.body.scrollTop > 20 ||
|
||||||
|
document.documentElement.scrollTop > 20
|
||||||
|
) {
|
||||||
|
totopbutton.style.display = "block";
|
||||||
|
} else {
|
||||||
|
totopbutton.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
topFunction() {
|
||||||
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
document.querySelectorAll(".tagtoggle").forEach((toggle) => {
|
||||||
|
toggle.addEventListener("mouseup", (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
const tagid = toggle.getAttribute("data-tagid");
|
||||||
|
this.toggleTag(tagid);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.requestMetadata();
|
||||||
|
this.setupDropdownToggle();
|
||||||
|
this.setupTagHandlers();
|
||||||
|
this.setupClickHandlers();
|
||||||
|
|
||||||
|
window.addEventListener("scroll", this.scrollFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
if (window.addEventListener) {
|
||||||
|
window.addEventListener("load", this.onLoad, false);
|
||||||
|
} else if (window.attachEvent) {
|
||||||
|
window.attachEvent("onload", this.onLoad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{ title }}</title>
|
<title>{{ title }}</title>
|
||||||
{%- if webmanifest %}
|
{%- if webmanifest %}
|
||||||
<link rel="manifest" href="/.static/manifest.json">
|
<link rel="manifest" href="/.static/manifest.webmanifest">
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
<link rel="preload" href="{{ stylesheet }}" as="style">
|
<link rel="preload" href="{{ stylesheet }}" as="style">
|
||||||
{%- if theme %}
|
{%- if theme %}
|
||||||
@@ -43,10 +43,12 @@
|
|||||||
<link rel="preload" href="{{ root }}.static/pswp/default-skin/default-skin.css" as="style">
|
<link rel="preload" href="{{ root }}.static/pswp/default-skin/default-skin.css" as="style">
|
||||||
<link rel="modulepreload" href="{{ root }}.static/pswp/photoswipe.min.js">
|
<link rel="modulepreload" href="{{ root }}.static/pswp/photoswipe.min.js">
|
||||||
<link rel="modulepreload" href="{{ root }}.static/pswp/photoswipe-ui-default.min.js">
|
<link rel="modulepreload" href="{{ root }}.static/pswp/photoswipe-ui-default.min.js">
|
||||||
|
<link rel="modulepreload" href="{{ root }}.static/functionality.min.js">
|
||||||
<link rel="stylesheet" href="{{ root }}.static/pswp/photoswipe.css">
|
<link rel="stylesheet" href="{{ root }}.static/pswp/photoswipe.css">
|
||||||
<link rel="stylesheet" href="{{ root }}.static/pswp/default-skin/default-skin.css">
|
<link rel="stylesheet" href="{{ root }}.static/pswp/default-skin/default-skin.css">
|
||||||
<script src="{{ root }}.static/pswp/photoswipe.min.js"></script>
|
<script src="{{ root }}.static/pswp/photoswipe.min.js"></script>
|
||||||
<script src="{{ root }}.static/pswp/photoswipe-ui-default.min.js"></script>
|
<script src="{{ root }}.static/pswp/photoswipe-ui-default.min.js"></script>
|
||||||
|
<script src="{{ root }}.static/functionality.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -78,8 +80,9 @@
|
|||||||
</g>
|
</g>
|
||||||
</svg></a>
|
</svg></a>
|
||||||
<ol class="tooltiptext tagdropdown" id="tagdropdown">
|
<ol class="tooltiptext tagdropdown" id="tagdropdown">
|
||||||
|
<span class="tagentry" id="reset-filter"><label>reset filter</label></span>
|
||||||
<span class="tagentry">
|
<span class="tagentry">
|
||||||
<label onclick="recursive()">
|
<label>
|
||||||
<input type="checkbox" id="recursive" />recursive filter
|
<input type="checkbox" id="recursive" />recursive filter
|
||||||
</label>
|
</label>
|
||||||
</span>
|
</span>
|
||||||
@@ -130,14 +133,14 @@
|
|||||||
{%- endif %}
|
{%- endif %}
|
||||||
<span class="attribution">Made with <a href="https://github.com/greflm13/StaticGalleryBuilder" target="_blank" rel="noopener noreferrer">StaticGalleryBuilder {{ version }}</a> by <a
|
<span class="attribution">Made with <a href="https://github.com/greflm13/StaticGalleryBuilder" target="_blank" rel="noopener noreferrer">StaticGalleryBuilder {{ version }}</a> by <a
|
||||||
href="https://github.com/greflm13" target="_blank" rel="noopener noreferrer">{{ logo }}</a>.</span>
|
href="https://github.com/greflm13" target="_blank" rel="noopener noreferrer">{{ logo }}</a>.</span>
|
||||||
<button type="button" onclick="topFunction()" id="totop" title="Back to Top">Back to Top</button>
|
<button type="button" id="totop" title="Back to Top">Back to Top</button>
|
||||||
</div>
|
</div>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- else %}
|
{%- else %}
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<span class="attribution">Made with <a href="https://github.com/greflm13/StaticGalleryBuilder" target="_blank" rel="noopener noreferrer">StaticGalleryBuilder {{ version }}</a> by <a
|
<span class="attribution">Made with <a href="https://github.com/greflm13/StaticGalleryBuilder" target="_blank" rel="noopener noreferrer">StaticGalleryBuilder {{ version }}</a> by <a
|
||||||
href="https://github.com/greflm13" target="_blank" rel="noopener noreferrer">{{ logo }}</a>.</span>
|
href="https://github.com/greflm13" target="_blank" rel="noopener noreferrer">{{ logo }}</a>.</span>
|
||||||
<button type="button" onclick="topFunction()" id="totop" title="Back to Top">Back to Top</button>
|
<button type="button" id="totop" title="Back to Top">Back to Top</button>
|
||||||
</div>
|
</div>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
|
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
@@ -176,329 +179,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
const pswpElement = document.querySelectorAll('.pswp')[0];
|
|
||||||
const re = /pid=(\d+)/;
|
|
||||||
const filterre = /#(.*)/;
|
|
||||||
const recursere = /\?recursive/;
|
|
||||||
let items = [];
|
|
||||||
let shown = [];
|
|
||||||
let subfolders = [];
|
|
||||||
let controllers = {};
|
|
||||||
let tagdropdownshown = false;
|
|
||||||
|
|
||||||
function requestMetadata() {
|
|
||||||
fetch(".metadata.json").then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
||||||
}
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
items = Object.values(data.images);
|
|
||||||
subfolders = data.subfolders;
|
|
||||||
if (filterre.test(window.location.href)) {
|
|
||||||
const selected = window.location.href.match(filterre)[1].split(",");
|
|
||||||
setFilter(selected);
|
|
||||||
}
|
|
||||||
if (recursere.test(window.location.href)) {
|
|
||||||
document.getElementById("recursive").checked = true;
|
|
||||||
recursive();
|
|
||||||
}
|
|
||||||
filter();
|
|
||||||
|
|
||||||
if (re.test(window.location.href)) {
|
|
||||||
const pid = window.location.href.match(re)[1];
|
|
||||||
openSwipe(parseInt(pid));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => console.error('Failed to fetch data:', error));
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupTagHandlers() {
|
|
||||||
const tagContainer = document.getElementById("tagdropdown");
|
|
||||||
|
|
||||||
if (tagContainer == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tagContainer.addEventListener("change", debounce(filter, 150));
|
|
||||||
|
|
||||||
tagContainer.addEventListener("click", function (event) {
|
|
||||||
const toggle = event.target.closest(".tagtoggle");
|
|
||||||
if (toggle) {
|
|
||||||
event.stopPropagation();
|
|
||||||
const tagid = toggle.dataset.toggleid;
|
|
||||||
toggleTag(tagid);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleTag(tagid) {
|
|
||||||
const tag = document.getElementById(tagid);
|
|
||||||
const ol = tag?.closest(".tagentry")?.querySelector(".tagentryparent");
|
|
||||||
const svg = tag?.parentElement.querySelector(".tagtoggle svg");
|
|
||||||
|
|
||||||
if (!ol || !svg) return;
|
|
||||||
|
|
||||||
ol.classList.toggle("show");
|
|
||||||
svg.style.transform = ol.classList.contains("show") ? "rotate(180deg)" : "rotate(0deg)";
|
|
||||||
}
|
|
||||||
|
|
||||||
function debounce(fn, delay) {
|
|
||||||
let timeoutId;
|
|
||||||
return function (...args) {
|
|
||||||
clearTimeout(timeoutId);
|
|
||||||
timeoutId = setTimeout(() => fn.apply(this, args), delay);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function openSwipe(img) {
|
|
||||||
const options = {
|
|
||||||
index: img
|
|
||||||
};
|
|
||||||
const gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, shown, options);
|
|
||||||
gallery.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function recursive(sub = undefined) {
|
|
||||||
const curr = window.location.href.split("#");
|
|
||||||
const content = document.getRootNode().innerHTML;
|
|
||||||
const title = document.title;
|
|
||||||
const isChecked = document.getElementById("recursive").checked;
|
|
||||||
const folders = document.querySelector(".folders");
|
|
||||||
|
|
||||||
if (!isChecked) {
|
|
||||||
if (folders) folders.style.display = "";
|
|
||||||
window.history.replaceState({ html: content, pageTitle: title }, "", curr[0].split("?")[0] + "#" + curr[1]);
|
|
||||||
requestMetadata();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (folders) folders.style.display = "none";
|
|
||||||
window.history.replaceState({ html: content, pageTitle: title }, "", curr[0].split("?")[0] + "?recursive#" + curr[1]);
|
|
||||||
|
|
||||||
const visited = new Set();
|
|
||||||
const existingItems = new Set();
|
|
||||||
const newItems = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(".metadata.json");
|
|
||||||
if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
items = [];
|
|
||||||
subfolders = data.subfolders || [];
|
|
||||||
sub = subfolders;
|
|
||||||
|
|
||||||
for (const image of Object.values(data.images || {})) {
|
|
||||||
newItems.push(image);
|
|
||||||
existingItems.add(image.src);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to fetch base .metadata.json:", error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchFoldersRecursively(folderList) {
|
|
||||||
if (!Array.isArray(folderList)) return;
|
|
||||||
|
|
||||||
const nextLevel = [];
|
|
||||||
|
|
||||||
await Promise.all(folderList.map(async (folder) => {
|
|
||||||
if (!folder || !folder.metadata || visited.has(folder.url)) return;
|
|
||||||
visited.add(folder.url);
|
|
||||||
|
|
||||||
if (!folder.metadata) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(folder.metadata);
|
|
||||||
if (!response.ok) throw new Error(`Failed to fetch ${folder.metadata}`);
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
for (const image of Object.values(data.images || {})) {
|
|
||||||
if (!existingItems.has(image.src)) {
|
|
||||||
newItems.push(image);
|
|
||||||
existingItems.add(image.src);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(data.subfolders)) {
|
|
||||||
nextLevel.push(...data.subfolders);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to fetch folder metadata:", error);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (nextLevel.length > 0) {
|
|
||||||
await fetchFoldersRecursively(nextLevel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await fetchFoldersRecursively(sub);
|
|
||||||
|
|
||||||
items = [...newItems];
|
|
||||||
filter();
|
|
||||||
}
|
|
||||||
|
|
||||||
const totopbutton = document.getElementById("totop");
|
|
||||||
|
|
||||||
window.onscroll = function () { scrollFunction() };
|
|
||||||
|
|
||||||
function scrollFunction() {
|
|
||||||
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
|
|
||||||
totopbutton.style.display = "block";
|
|
||||||
} else {
|
|
||||||
totopbutton.style.display = "none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function topFunction() {
|
|
||||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateImageList() {
|
|
||||||
let str = ""
|
|
||||||
let imagelist = document.getElementById("imagelist");
|
|
||||||
shown.forEach((item, index) => {
|
|
||||||
str += '<div class="column"><figure><img src="' + item.msrc + '" onclick="openSwipe(' + index + ')" onmouseover="prefetch(' + index + ')" onmouseleave="cancel(' + index + ')" /><figcaption class="caption">' + item.name;
|
|
||||||
if (item.tiff != "" & item.tiff != undefined) {
|
|
||||||
str += ' <a href="' + item.tiff + '">TIFF</a>';
|
|
||||||
}
|
|
||||||
if (item.raw != "" & item.raw != undefined) {
|
|
||||||
str += ' <a href="' + item.raw + '">RAW</a>';
|
|
||||||
}
|
|
||||||
str += '</figcaption></figure></div>';
|
|
||||||
});
|
|
||||||
|
|
||||||
imagelist.innerHTML = str;
|
|
||||||
}
|
|
||||||
|
|
||||||
function prefetch(img) {
|
|
||||||
const controller = new AbortController()
|
|
||||||
const signal = controller.signal
|
|
||||||
controllers[img] = controller;
|
|
||||||
let urlToFetch = items[img].src;
|
|
||||||
|
|
||||||
fetch(urlToFetch, {
|
|
||||||
method: 'get',
|
|
||||||
signal: signal,
|
|
||||||
}).catch(function (err) { });
|
|
||||||
}
|
|
||||||
|
|
||||||
function cancel(img) {
|
|
||||||
controllers[img].abort();
|
|
||||||
delete controllers[img];
|
|
||||||
}
|
|
||||||
|
|
||||||
function filter() {
|
|
||||||
shown = [];
|
|
||||||
let isRecursiveChecked = false;
|
|
||||||
|
|
||||||
const curr = window.location.href.split("#")[0] + "#";
|
|
||||||
const path = decodeURIComponent(window.location.href.split("#")[0].replace("index.html", ""))
|
|
||||||
|
|
||||||
const selected_tags = [];
|
|
||||||
const tagcheckboxes = document.querySelectorAll("#tagdropdown input[class='tagcheckbox']:checked");
|
|
||||||
|
|
||||||
tagcheckboxes.forEach((checkbox) => {
|
|
||||||
let tag = checkbox.parentElement.id.trim().substring(1);
|
|
||||||
if (checkbox.parentElement.parentElement.children.length > 1) {
|
|
||||||
tag += "|"
|
|
||||||
}
|
|
||||||
selected_tags.push(tag);
|
|
||||||
});
|
|
||||||
|
|
||||||
const urltags = selected_tags.join(",");
|
|
||||||
|
|
||||||
try {
|
|
||||||
isRecursiveChecked = document.getElementById("recursive").checked;
|
|
||||||
} catch { }
|
|
||||||
|
|
||||||
for (const item of items) {
|
|
||||||
const tags = item.tags || [];
|
|
||||||
const include = selected_tags.every(selected => {
|
|
||||||
const isParent = selected.endsWith('|');
|
|
||||||
if (isParent) {
|
|
||||||
return tags.some(t => t.startsWith(selected));
|
|
||||||
} else {
|
|
||||||
return tags.includes(selected);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (include || selected_tags.length === 0) {
|
|
||||||
if (!isRecursiveChecked) {
|
|
||||||
if (decodeURIComponent(item.src.replace(item.name, "")) == path) {
|
|
||||||
shown.push(item);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
shown.push(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateImageList();
|
|
||||||
window.location.href = curr + urltags;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setFilter(selected) {
|
|
||||||
const tagcheckboxes = document.querySelectorAll("#tagdropdown input[class='tagcheckbox']");
|
|
||||||
selected.forEach((tag) => {
|
|
||||||
tagcheckboxes.forEach((checkbox) => {
|
|
||||||
if (checkbox.parentElement.id.trim().substring(1).replace(" ", "%20") == tag) {
|
|
||||||
checkbox.checked = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupDropdownToggle() {
|
|
||||||
const toggleLink = document.getElementById("tagtogglelink");
|
|
||||||
const dropdown = document.getElementById("tagdropdown");
|
|
||||||
|
|
||||||
if (toggleLink == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleLink.addEventListener("click", function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
const svg = this.querySelector("svg");
|
|
||||||
dropdown.classList.toggle("show");
|
|
||||||
if (svg) svg.style.transform = dropdown.classList.contains("show") ? "rotate(180deg)" : "rotate(0deg)";
|
|
||||||
tagdropdownshown = dropdown.classList.contains("show");
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener("click", function (event) {
|
|
||||||
if (!dropdown.contains(event.target) && !toggleLink.contains(event.target)) {
|
|
||||||
dropdown.classList.remove("show");
|
|
||||||
tagdropdownshown = false;
|
|
||||||
const svg = toggleLink.querySelector("svg");
|
|
||||||
if (svg) svg.style.transform = "rotate(0deg)";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLoad() {
|
|
||||||
document.querySelectorAll('.tagtoggle').forEach(toggle => {
|
|
||||||
toggle.addEventListener('mouseup', function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
const tagid = this.getAttribute('data-tagid');
|
|
||||||
toggleTag(tagid);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
requestMetadata();
|
|
||||||
setupDropdownToggle();
|
|
||||||
setupTagHandlers();
|
|
||||||
const recurseEl = document.getElementById("recursive")
|
|
||||||
if (recurseEl != null) { recurseEl.addEventListener("change", debounce(recursive, 150)); }
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener ?
|
|
||||||
window.addEventListener("load", onLoad, false) :
|
|
||||||
window.attachEvent && window.attachEvent("onload", onLoad);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
|
<script>
|
||||||
|
new PhotoGallery();
|
||||||
|
</script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -21,13 +21,16 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<ul class="navbar">
|
<ol class="navbar">
|
||||||
<li><a href="{{ root }}">Home</a></li>
|
<div class="navleft">
|
||||||
{%- if parent %}
|
<li><a href="{{ root }}">Home</a></li>
|
||||||
<li><a href="{{ parent }}">Parent Directory</a></li>
|
{%- if parent %}
|
||||||
{%- endif %}
|
<li><a href="{{ parent }}">Parent Directory</a></li>
|
||||||
<li class="title"><span class="header">{{ header }}</span></li>
|
{%- endif %}
|
||||||
</ul>
|
</div>
|
||||||
|
<div class="navcenter">
|
||||||
|
<li class="title"><span class="header">{{ header }}</span></li>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{%- if licensefile %}
|
{%- if licensefile %}
|
||||||
<div class="licensefile">
|
<div class="licensefile">
|
||||||
|
|||||||
@@ -118,3 +118,23 @@ body {
|
|||||||
color: var(--bcolor1);
|
color: var(--bcolor1);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
border-top: 3px solid var(--bcolor1);
|
||||||
|
border-right: 3px solid transparent;
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: rotation 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotation {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -116,4 +116,24 @@ body {
|
|||||||
background-color: var(--color2);
|
background-color: var(--color2);
|
||||||
color: var(--bcolor2);
|
color: var(--bcolor2);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
border-top: 3px solid var(--bcolor2);
|
||||||
|
border-right: 3px solid transparent;
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: rotation 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotation {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -96,6 +96,52 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: relative;
|
||||||
|
animation: rotate 1s linear infinite
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader::before {
|
||||||
|
content: "";
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: absolute;
|
||||||
|
inset: 0px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 5px solid var(--bcolor2);
|
||||||
|
animation: prixClipFix 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate {
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes prixClipFix {
|
||||||
|
0% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 0 0, 0 0, 0 0, 0 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
25% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 0, 100% 0, 100% 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 100% 100%, 100% 100%)
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 0 100%, 0 100%)
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 0 100%, 0 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor2);
|
color: var(--bcolor2);
|
||||||
background-color: var(--bcolor3);
|
background-color: var(--bcolor3);
|
||||||
|
|||||||
@@ -96,6 +96,52 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: relative;
|
||||||
|
animation: rotate 1s linear infinite
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader::before {
|
||||||
|
content: "";
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: absolute;
|
||||||
|
inset: 0px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 5px solid var(--bcolor2);
|
||||||
|
animation: prixClipFix 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate {
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes prixClipFix {
|
||||||
|
0% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 0 0, 0 0, 0 0, 0 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
25% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 0, 100% 0, 100% 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 100% 100%, 100% 100%)
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 0 100%, 0 100%)
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 0 100%, 0 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor2);
|
color: var(--bcolor2);
|
||||||
background-color: var(--bcolor3);
|
background-color: var(--bcolor3);
|
||||||
|
|||||||
@@ -1,14 +1,22 @@
|
|||||||
@import url("https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700;800;900&display=swap");
|
@import url("https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700;800;900&display=swap");
|
||||||
|
|
||||||
* {
|
* {
|
||||||
--color1: #FF7F50; /* Coral */
|
--color1: #FF7F50;
|
||||||
--color2: #D2691E; /* Chocolate */
|
/* Coral */
|
||||||
--color3: #8B4513; /* SaddleBrown */
|
--color2: #D2691E;
|
||||||
--color4: #FFA07A; /* LightSalmon */
|
/* Chocolate */
|
||||||
--bcolor1: #FFF8DC; /* Cornsilk */
|
--color3: #8B4513;
|
||||||
--bcolor2: #2F4F4F; /* DarkSlateGray */
|
/* SaddleBrown */
|
||||||
--bcolor3: #3E2723; /* Darker brown */
|
--color4: #FFA07A;
|
||||||
--bcolor4: #4E342E; /* Slightly lighter brown */
|
/* LightSalmon */
|
||||||
|
--bcolor1: #FFF8DC;
|
||||||
|
/* Cornsilk */
|
||||||
|
--bcolor2: #2F4F4F;
|
||||||
|
/* DarkSlateGray */
|
||||||
|
--bcolor3: #3E2723;
|
||||||
|
/* Darker brown */
|
||||||
|
--bcolor4: #4E342E;
|
||||||
|
/* Slightly lighter brown */
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
@@ -102,6 +110,54 @@
|
|||||||
font-family: "Playfair Display", serif;
|
font-family: "Playfair Display", serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader,
|
||||||
|
.loader:before,
|
||||||
|
.loader:after {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 2.5em;
|
||||||
|
height: 2.5em;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
animation: bblFadInOut 1.8s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
color: var(--bcolor2);
|
||||||
|
font-size: 7px;
|
||||||
|
position: relative;
|
||||||
|
text-indent: -9999em;
|
||||||
|
transform: translateZ(0);
|
||||||
|
animation-delay: -0.16s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:before,
|
||||||
|
.loader:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:before {
|
||||||
|
left: -3.5em;
|
||||||
|
animation-delay: -0.32s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:after {
|
||||||
|
left: 3.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bblFadInOut {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
80%,
|
||||||
|
100% {
|
||||||
|
box-shadow: 0 2.5em 0 -1.3em
|
||||||
|
}
|
||||||
|
|
||||||
|
40% {
|
||||||
|
box-shadow: 0 2.5em 0 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor1);
|
color: var(--bcolor1);
|
||||||
background-color: var(--bcolor3);
|
background-color: var(--bcolor3);
|
||||||
@@ -109,4 +165,4 @@ body {
|
|||||||
font-optical-sizing: auto;
|
font-optical-sizing: auto;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
@@ -95,6 +95,36 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: block;
|
||||||
|
margin: 15px auto;
|
||||||
|
position: relative;
|
||||||
|
color: var(--color1);
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: animloader 1s linear infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animloader {
|
||||||
|
0% {
|
||||||
|
box-shadow: -38px -12px, -14px 0, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
33% {
|
||||||
|
box-shadow: -38px 0px, -14px -12px, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
66% {
|
||||||
|
box-shadow: -38px 0px, -14px 0, 14px -12px, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
box-shadow: -38px 0, -14px 0, 14px 0, 38px -12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor1);
|
color: var(--bcolor1);
|
||||||
background-color: var(--bcolor3);
|
background-color: var(--bcolor3);
|
||||||
|
|||||||
@@ -103,6 +103,91 @@
|
|||||||
font-family: "Nunito", sans-serif;
|
font-family: "Nunito", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
transform: rotateZ(45deg);
|
||||||
|
perspective: 1000px;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
color: var(--color1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:before,
|
||||||
|
.loader:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: inherit;
|
||||||
|
height: inherit;
|
||||||
|
border-radius: 50%;
|
||||||
|
transform: rotateX(70deg);
|
||||||
|
animation: 1s spin linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:after {
|
||||||
|
color: var(--bcolor4);
|
||||||
|
transform: rotateY(70deg);
|
||||||
|
animation-delay: .4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate {
|
||||||
|
0% {
|
||||||
|
transform: translate(-50%, -50%) rotateZ(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translate(-50%, -50%) rotateZ(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotateccw {
|
||||||
|
0% {
|
||||||
|
transform: translate(-50%, -50%) rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translate(-50%, -50%) rotate(-360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
box-shadow: .2em 0px 0 0px currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
12% {
|
||||||
|
box-shadow: .2em .2em 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
25% {
|
||||||
|
box-shadow: 0 .2em 0 0px currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
37% {
|
||||||
|
box-shadow: -.2em .2em 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
box-shadow: -.2em 0 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
62% {
|
||||||
|
box-shadow: -.2em -.2em 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
box-shadow: 0px -.2em 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
87% {
|
||||||
|
box-shadow: .2em -.2em 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor2);
|
color: var(--bcolor2);
|
||||||
background-color: var(--bcolor3);
|
background-color: var(--bcolor3);
|
||||||
|
|||||||
@@ -95,6 +95,36 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: block;
|
||||||
|
margin: 15px auto;
|
||||||
|
position: relative;
|
||||||
|
color: var(--color1);
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: animloader 1s linear infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animloader {
|
||||||
|
0% {
|
||||||
|
box-shadow: -38px -12px, -14px 0, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
33% {
|
||||||
|
box-shadow: -38px 0px, -14px -12px, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
66% {
|
||||||
|
box-shadow: -38px 0px, -14px 0, 14px -12px, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
box-shadow: -38px 0, -14px 0, 14px 0, 38px -12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor1);
|
color: var(--bcolor1);
|
||||||
background-color: var(--bcolor3);
|
background-color: var(--bcolor3);
|
||||||
|
|||||||
@@ -74,6 +74,27 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
border-top: 3px solid var(--bcolor1);
|
||||||
|
border-right: 3px solid transparent;
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: rotation 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotation {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor1);
|
color: var(--bcolor1);
|
||||||
background-color: var(--color4);
|
background-color: var(--color4);
|
||||||
|
|||||||
@@ -74,6 +74,27 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
border-top: 3px solid var(--bcolor2);
|
||||||
|
border-right: 3px solid transparent;
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: rotation 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotation {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor2);
|
color: var(--bcolor2);
|
||||||
background-color: var(--bcolor1);
|
background-color: var(--bcolor1);
|
||||||
|
|||||||
@@ -93,6 +93,36 @@
|
|||||||
background-color: var(--color1);
|
background-color: var(--color1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: block;
|
||||||
|
margin: 15px auto;
|
||||||
|
position: relative;
|
||||||
|
color: var(--color1);
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: animloader 1s linear infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animloader {
|
||||||
|
0% {
|
||||||
|
box-shadow: -38px -12px, -14px 0, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
33% {
|
||||||
|
box-shadow: -38px 0px, -14px -12px, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
66% {
|
||||||
|
box-shadow: -38px 0px, -14px 0, 14px -12px, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
box-shadow: -38px 0, -14px 0, 14px 0, 38px -12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor1);
|
color: var(--bcolor1);
|
||||||
background-color: var(--bcolor3);
|
background-color: var(--bcolor3);
|
||||||
|
|||||||
@@ -94,6 +94,36 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: block;
|
||||||
|
margin: 15px auto;
|
||||||
|
position: relative;
|
||||||
|
color: var(--bcolor1);
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: animloader 1s linear infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animloader {
|
||||||
|
0% {
|
||||||
|
box-shadow: -38px -12px, -14px 0, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
33% {
|
||||||
|
box-shadow: -38px 0px, -14px -12px, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
66% {
|
||||||
|
box-shadow: -38px 0px, -14px 0, 14px -12px, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
box-shadow: -38px 0, -14px 0, 14px 0, 38px -12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor1);
|
color: var(--bcolor1);
|
||||||
background-color: var(--bcolor2);
|
background-color: var(--bcolor2);
|
||||||
|
|||||||
@@ -77,6 +77,91 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
transform: rotateZ(45deg);
|
||||||
|
perspective: 1000px;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
color: var(--color2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:before,
|
||||||
|
.loader:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: inherit;
|
||||||
|
height: inherit;
|
||||||
|
border-radius: 50%;
|
||||||
|
transform: rotateX(70deg);
|
||||||
|
animation: 1s spin linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:after {
|
||||||
|
color: var(--color4);
|
||||||
|
transform: rotateY(70deg);
|
||||||
|
animation-delay: .4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate {
|
||||||
|
0% {
|
||||||
|
transform: translate(-50%, -50%) rotateZ(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translate(-50%, -50%) rotateZ(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotateccw {
|
||||||
|
0% {
|
||||||
|
transform: translate(-50%, -50%) rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translate(-50%, -50%) rotate(-360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
box-shadow: .2em 0px 0 0px currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
12% {
|
||||||
|
box-shadow: .2em .2em 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
25% {
|
||||||
|
box-shadow: 0 .2em 0 0px currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
37% {
|
||||||
|
box-shadow: -.2em .2em 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
box-shadow: -.2em 0 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
62% {
|
||||||
|
box-shadow: -.2em -.2em 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
box-shadow: 0px -.2em 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
87% {
|
||||||
|
box-shadow: .2em -.2em 0 0 currentcolor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor1);
|
color: var(--bcolor1);
|
||||||
background-color: var(--bcolor4);
|
background-color: var(--bcolor4);
|
||||||
|
|||||||
@@ -98,6 +98,36 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: block;
|
||||||
|
margin: 15px auto;
|
||||||
|
position: relative;
|
||||||
|
color: var(--color4);
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: animloader 1s linear infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animloader {
|
||||||
|
0% {
|
||||||
|
box-shadow: -38px -12px, -14px 0, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
33% {
|
||||||
|
box-shadow: -38px 0px, -14px -12px, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
66% {
|
||||||
|
box-shadow: -38px 0px, -14px 0, 14px -12px, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
box-shadow: -38px 0, -14px 0, 14px 0, 38px -12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor3);
|
color: var(--bcolor3);
|
||||||
background-color: var(--bcolor1);
|
background-color: var(--bcolor1);
|
||||||
|
|||||||
@@ -1,14 +1,22 @@
|
|||||||
@import url("https://fonts.googleapis.com/css2?family=Lora:wght@300;400;500;600;700&display=swap");
|
@import url("https://fonts.googleapis.com/css2?family=Lora:wght@300;400;500;600;700&display=swap");
|
||||||
|
|
||||||
* {
|
* {
|
||||||
--color1: #FFB6C1; /* LightPink */
|
--color1: #FFB6C1;
|
||||||
--color2: #98FB98; /* PaleGreen */
|
/* LightPink */
|
||||||
--color3: #FFD700; /* Gold */
|
--color2: #98FB98;
|
||||||
--color4: #87CEFA; /* LightSkyBlue */
|
/* PaleGreen */
|
||||||
--bcolor1: #FFFFFF; /* White */
|
--color3: #FFD700;
|
||||||
--bcolor2: #2F4F4F; /* DarkSlateGray */
|
/* Gold */
|
||||||
--bcolor3: #FAF0E6; /* Linen */
|
--color4: #87CEFA;
|
||||||
--bcolor4: #E6E6FA; /* Lavender */
|
/* LightSkyBlue */
|
||||||
|
--bcolor1: #FFFFFF;
|
||||||
|
/* White */
|
||||||
|
--bcolor2: #2F4F4F;
|
||||||
|
/* DarkSlateGray */
|
||||||
|
--bcolor3: #FAF0E6;
|
||||||
|
/* Linen */
|
||||||
|
--bcolor4: #E6E6FA;
|
||||||
|
/* Lavender */
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
@@ -102,6 +110,54 @@
|
|||||||
font-family: "Lora", serif;
|
font-family: "Lora", serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader,
|
||||||
|
.loader:before,
|
||||||
|
.loader:after {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 2.5em;
|
||||||
|
height: 2.5em;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
animation: bblFadInOut 1.8s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
color: var(--bcolor2);
|
||||||
|
font-size: 7px;
|
||||||
|
position: relative;
|
||||||
|
text-indent: -9999em;
|
||||||
|
transform: translateZ(0);
|
||||||
|
animation-delay: -0.16s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:before,
|
||||||
|
.loader:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:before {
|
||||||
|
left: -3.5em;
|
||||||
|
animation-delay: -0.32s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:after {
|
||||||
|
left: 3.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bblFadInOut {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
80%,
|
||||||
|
100% {
|
||||||
|
box-shadow: 0 2.5em 0 -1.3em
|
||||||
|
}
|
||||||
|
|
||||||
|
40% {
|
||||||
|
box-shadow: 0 2.5em 0 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor2);
|
color: var(--bcolor2);
|
||||||
background-color: var(--bcolor3);
|
background-color: var(--bcolor3);
|
||||||
@@ -109,4 +165,4 @@ body {
|
|||||||
font-optical-sizing: auto;
|
font-optical-sizing: auto;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
@@ -102,6 +102,52 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: relative;
|
||||||
|
animation: rotate 1s linear infinite
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader::before {
|
||||||
|
content: "";
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: absolute;
|
||||||
|
inset: 0px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 5px solid var(--color2);
|
||||||
|
animation: prixClipFix 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate {
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes prixClipFix {
|
||||||
|
0% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 0 0, 0 0, 0 0, 0 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
25% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 0, 100% 0, 100% 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 100% 100%, 100% 100%)
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 0 100%, 0 100%)
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
clip-path: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 0 100%, 0 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor1);
|
color: var(--bcolor1);
|
||||||
background-color: var(--bcolor2);
|
background-color: var(--bcolor2);
|
||||||
@@ -109,4 +155,4 @@ body {
|
|||||||
font-optical-sizing: auto;
|
font-optical-sizing: auto;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
@@ -104,6 +104,54 @@
|
|||||||
font-family: "Roboto", sans-serif;
|
font-family: "Roboto", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader,
|
||||||
|
.loader:before,
|
||||||
|
.loader:after {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 2.5em;
|
||||||
|
height: 2.5em;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
animation: bblFadInOut 1.8s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
color: var(--bcolor2);
|
||||||
|
font-size: 7px;
|
||||||
|
position: relative;
|
||||||
|
text-indent: -9999em;
|
||||||
|
transform: translateZ(0);
|
||||||
|
animation-delay: -0.16s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:before,
|
||||||
|
.loader:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:before {
|
||||||
|
left: -3.5em;
|
||||||
|
animation-delay: -0.32s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:after {
|
||||||
|
left: 3.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bblFadInOut {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
80%,
|
||||||
|
100% {
|
||||||
|
box-shadow: 0 2.5em 0 -1.3em
|
||||||
|
}
|
||||||
|
|
||||||
|
40% {
|
||||||
|
box-shadow: 0 2.5em 0 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor2);
|
color: var(--bcolor2);
|
||||||
background-color: var(--bcolor3);
|
background-color: var(--bcolor3);
|
||||||
|
|||||||
@@ -96,6 +96,36 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: block;
|
||||||
|
margin: 15px auto;
|
||||||
|
position: relative;
|
||||||
|
color: var(--color1);
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: animloader 1s linear infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animloader {
|
||||||
|
0% {
|
||||||
|
box-shadow: -38px -12px, -14px 0, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
33% {
|
||||||
|
box-shadow: -38px 0px, -14px -12px, 14px 0, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
66% {
|
||||||
|
box-shadow: -38px 0px, -14px 0, 14px -12px, 38px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
box-shadow: -38px 0, -14px 0, 14px 0, 38px -12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor1);
|
color: var(--bcolor1);
|
||||||
background-color: var(--bcolor3);
|
background-color: var(--bcolor3);
|
||||||
|
|||||||
@@ -111,6 +111,54 @@
|
|||||||
font-family: "Montserrat", sans-serif;
|
font-family: "Montserrat", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader,
|
||||||
|
.loader:before,
|
||||||
|
.loader:after {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 2.5em;
|
||||||
|
height: 2.5em;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
animation: bblFadInOut 1.8s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
color: var(--bcolor2);
|
||||||
|
font-size: 7px;
|
||||||
|
position: relative;
|
||||||
|
text-indent: -9999em;
|
||||||
|
transform: translateZ(0);
|
||||||
|
animation-delay: -0.16s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:before,
|
||||||
|
.loader:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:before {
|
||||||
|
left: -3.5em;
|
||||||
|
animation-delay: -0.32s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:after {
|
||||||
|
left: 3.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bblFadInOut {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
80%,
|
||||||
|
100% {
|
||||||
|
box-shadow: 0 2.5em 0 -1.3em
|
||||||
|
}
|
||||||
|
|
||||||
|
40% {
|
||||||
|
box-shadow: 0 2.5em 0 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: var(--bcolor2);
|
color: var(--bcolor2);
|
||||||
background-color: var(--bcolor3);
|
background-color: var(--bcolor3);
|
||||||
|
|||||||
Reference in New Issue
Block a user