// ==UserScript==
// @id gelbooru-slide
// @name Gelbooru Image Viewer
// @version 1.9.1
// @namespace intermission
// @author intermission
// @license WTFPL; http://www.wtfpl.net/about/
// @description Adds a fullscreen image view option when you click on images
// @include http://gelbooru.com/*
// @include https://gelbooru.com/*
// @include http://gelbooru.com/
// @include https://gelbooru.com/
// @include http://rule34.xxx/*
// @include https://rule34.xxx/*
// @include http://rule34.xxx/
// @include https://rule34.xxx/
// @include http://e621.net/*
// @include https://e621.net/*
// @include http://e621.net/
// @include https://e621.net/
// @include http://*.booru.org/*
// @include https://*.booru.org/*
// @include http://*.booru.org/
// @include https://*.booru.org/
// @run-at document-start
// @grant GM_registerMenuCommand
// @grant GM_xmlhttpRequest
// ==/UserScript==
(function(d, w, stor){
"use strict";
var domain = location.hostname.match(/[^\.]+\.[^\.]+$/)[0], ns = "gelbooru-slide", toggle = stor[ns] === "true", notification, Pos, Menu, Btn, slideshow, $, Main, Prog, Hover;
if (!stor[ns]) stor[ns] = "false";
GM_registerMenuCommand("Current image mode: " + (toggle ? "Always original size" : "Sample only"), () => {
if (domain !== "booru.org") stor[ns] = toggle ? "false" : "true";
return location.reload();
});
if (stor[ns + "-firstrun"] != "1.8.8") {
(function(l){
var a, r = /^gelbooru-slide./;
for (a in l)
if (r.test(a)) l.removeItem(a);
}(stor));
stor[ns + "-firstrun"] = "1.8.8";
}
$ = function(a, b) {
return [...(b || d).querySelectorAll(a)];
};
$.extend = function(obj, props) {
var key, val;
for (key in props) {
if (!props.hasOwnProperty(key)) continue;
val = props[key];
obj[key] = val;
}
};
$.extend($, {
cache: function(id, b) {
var val = toggle ? "original" : "sample", ret, obj, temp;
if (!b) {
try { ret = JSON.parse(stor[ns + id])[val]; } catch(e) {}
ret = ret || "loading";
} else {
try { temp = JSON.parse(stor[ns + id]); } catch(e) {}
obj = temp || {};
obj[val] = b;
stor[ns + id] = JSON.stringify(obj);
ret = b;
}
return ret;
},
base: a => a.split("/").pop().split(".")[0].split("_").pop(),
current: src => $("a[data-id] > img[src*='" + $.base(src || Main.el.dataset.src) + "']")[0].parentNode,
find: function(el, method) {
var a;
el = el.parentNode;
do {
try {
el = el[(method ? "next" : "previous") + "ElementSibling"];
a = el.querySelector("a[data-full]");
} catch(err) {
return false;
}
if (a) break;
a = false;
} while(!a);
return a;
},
preload: function() {
var curr = $.current();
Main.req($.find(curr, true));
return Main.req($.find(curr, false));
},
keyDown: function(e) {
var move;
if (slideshow) return;
switch(e.keyCode) {
case 32: case 39:
move = true;
break;
case 37:
move = false;
break;
case 38:
if (e.event) Menu.fn(e.event);
else w.location = $.current().href;
return;
case 40:
e.preventDefault();
return Main.el.click();
}
if (typeof move != "undefined") {
e = $.find($.current(), move);
if (e) {
if (Prog.el) {
Prog.el.classList.remove("progdone");
Prog.el.style.width = 0;
}
Main.slide(e.firstElementChild.src);
Pos.fn(move);
$.preload();
} else if (!notification) {
notification = $.c("div");
notification.classList.add("nomoreimages");
notification.setAttribute("style", "pointer-events: none; background: linear-gradient(to " + (move ? "right" : "left") + ", transparent, rgba(255,0,0,.5));" + (move ? "right" : "left") + ": 0;");
d.body.insertBefore(notification, d.body.lastElementChild);
}
} return;
},
c: c => d.createElement(c)
});
Pos = {
fn: function(a) {
var no, thumbs, el = Pos.el;
if (typeof a === "boolean") {
no = el.firstElementChild;
no.innerHTML = Number(no.innerHTML) + (a ? 1 : -1);
if (Menu.el)
for (let a of $("a", Menu.el)) a.href = $.current().href;
} else {
if (Main.el && !el) {
thumbs = $("span.thumb a[data-full]");
Pos.el = el = $.c("div");
el.insertAdjacentHTML("beforeend", "<span>" + (thumbs.indexOf($.current()) + 1) + "</span> / " + thumbs.length);
el.setAttribute("style", "position: fixed; bottom: 20px; left: 0; display: block; pointer-events: none;");
Main.el.insertAdjacentElement("afterend", el);
} else if (el) Pos.el = el.remove();
} return;
}
};
Menu = {
fn: function(e) {
var _l = e.clientX + 1, _t = e.clientY + 1,
left = (_l > w.innerWidth - 139 ? (_l - 139) : _l) + "px",
top = (_t > w.innerHeight - 48 ? (_t - 48) : _t) + "px",
href, el = Menu.el;
if (el) {
el.removeAttribute("class");
el.style.left = left;
el.style.top = top;
setTimeout(() => el.classList.add("menuel"), 10);
} else {
href = $.current().href;
Menu.el = el = $.c("div");
el.id = "menuel";
el.insertAdjacentHTML("beforeend", '<a href="'+href+'" style="margin-bottom: 2px">Open in This Tab</a><a href="'+href+'" target="_blank">Open in New Tab</a>');
el.style.left = left;
el.style.top = top;
d.body.appendChild(el);
el.classList.add("menuel");
}
return;
}
};
Btn = {
fn: function() {
var sel, el = Btn.el;
sel = "this.previousElementSibling.firstElementChild";
if (el) {
Btn.clear();
Btn.el = Btn.el.remove();
} else {
Btn.el = el = $.c("div");
el.setAttribute("style", 'opacity: .7;');
el.className = "slideshow";
el.insertAdjacentHTML('beforeend', '<span title="Slideshow">' + Btn.svg_play + "</span>" + `<div style="display: none;padding: 10px 0">Options<hr><label>Loop: <input type="checkbox" checked></label> <label onclick="${sel}.checked=true;${sel}.disabled=!${sel}.disabled">Shuffle: <input type="checkbox"></label><br>Interval: <input type="number" value="5" style="width: 100px"></div>`);
Btn.svg_state = true;
el.firstElementChild.onclick = Btn.cb;
d.body.appendChild(el);
}
},
clear: () => clearTimeout(Number(Btn.el.dataset.timer) || 0),
cb: function() {
var el = Btn.el, sel = "span.thumb a[data-full]",
options = $("div input", el).map(a =>
a.type == "number" ? (+a.value >= 1 ? +a.value : 1) * 1E3 : a.checked
), _fnS = () => {
Main.el.removeEventListener("load", _fnS);
el.dataset.timer = setTimeout(_fnT, options[2]);
}, _fnT = () => {
var _el;
if (thumbs.length === 0) thumbs = $(sel);
if (options[1]) {
thumbs.splice(thumbs.indexOf($.current()), 1);
_el = thumbs[Math.random() * thumbs.length & -1];
} else _el = $.find($.current(), true);
if (!_el && options[0]) _el = $(sel)[0];
if (!_el) return Btn.cb();
Main.el.addEventListener("load", _fnS, { passive: true });
Main.slide(_el.firstElementChild.src);
}, thumbs = [];
slideshow = !!Btn.svg_state;
Pos.fn();
el.firstElementChild.innerHTML = (Btn.svg_state = !Btn.svg_state) ? Btn.svg_play : Btn.svg_pause;
if (slideshow) {
el.dataset.timer = setTimeout(_fnT, options[2]);
el.style.opacity = ".4";
Hover.el.setAttribute("style", "display: none !important");
} else {
Btn.clear();
el.style.opacity = ".7";
el.removeAttribute("data-timer");
Hover.el.removeAttribute("style");
Hover.center($.current().firstElementChild.src);
}
return;
},
svg_play: '<svg width="50" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg"><rect rx="5" height="48" width="48" y="1" x="1" fill="#fff" /><polygon fill="#000" points="16 12 16 38 36 25" /></svg>',
svg_pause: '<span><svg width="50" height="50" xmlns="http://www.w3.org/2000/svg"><rect fill="#fff" x="1" y="1" width="48" height="48" rx="5" /><rect fill="#000" x="12" y="12" width="10" height="26" /><rect fill="#000" x="28" y="12" width="10" height="26" /></svg>'
};
Prog = {
check: e => ~Main.el.dataset.src.indexOf($.base(e.finalUrl || e)),
load: function(id, e) {
var blob, type, el = Prog.el, img = Main.el;
delete Prog.reqs[id];
if (!el) throw Error("There was an event order issue with GM_xmlhttpRequest");
if (e.status != 200 && e.status != 304) return Prog.error(id, e);
else if (img && Prog.check(e)) {
type = e.responseHeaders.match(/Content-Type: ([a-z\/\+]+)/)[1];
blob = new Blob([e.response], {type: type});
el.classList.add("progdone");
img.src = $("a[data-id='" + id + "']")[0].dataset.blob = w.URL.createObjectURL(blob);
}
},
progress: function(url, id, e) {
var el = Prog.el;
if (!el) {
Prog.el = el = $.c("span");
el.setAttribute("style", "width:0");
el.classList.add("progress");
d.body.appendChild(el);
}
if (e && e.lengthComputable && Main.el && Prog.check(url) && el) {
el.classList.remove("progfail");
el.style.width = (id in Prog.reqs ? e.loaded / e.total * 100 : 0) + "%";
} else return el;
},
error: function(id, e) {
var el = Prog.el;
if (Main.el && Prog.check(e) && el) {
el.classList.add("progfail");
try { Prog.reqs[id].abort(); }
catch(err) {}
delete Prog.reqs[id];
}
if (slideshow)
Main.el.dispatchEvent(new Event("load"));
stor.removeItem(ns + id);
$("a[data-id='" + id + "']")[0].dataset.full = "loading";
},
fn: function(url, id) {
var details, err = Prog.error.bind(Prog, id);
if (Prog.el) Prog.el.style.width = 0;
details = {
method: "GET",
url: url,
responseType: "arraybuffer",
onload: Prog.load.bind(Prog, id),
onprogress: Prog.progress.bind(Prog, url, id),
onerror: err,
onabort: err,
ontimeout: err
};
Prog.reqs[id] = GM_xmlhttpRequest(details);
},
reqs: {}
};
Hover = {
fn: function() {
var el = Hover.el;
if (el) Hover.el = el.remove();
else {
Hover.el = el = $.c("div");
el.insertAdjacentHTML("beforeend", `<div class="layover"></div><div class="tentcon"><div class="wrapthatshit"><div class="listimage"></div></div></div>`);
el.className = "viewpre";
d.body.appendChild(el);
Hover.construct();
}
},
construct: function() {
var target = $(".listimage", Hover.el)[0], thumbs = $("a[data-full]"), i;
target.style.width = thumbs.length * 180 + "px";
for (i = 0; i < thumbs.length; i++) {
let span = $.c("span"), img = $.c("img");
img.src = thumbs[i].firstElementChild.src;
img.dataset.nth = i;
span.appendChild(img);
target.appendChild(span);
img.addEventListener("click", Hover.click, { passive: true });
}
},
click: function(e) {
e = e.currentTarget.src;
Main.slide(e);
Hover.center(e);
},
center: function (src) {
var base = $.base(src),
img = $("img[src*='" + base + "']", Hover.el),
pos = +img[0].dataset.nth,
scroll = $(".wrapthatshit", Hover.el)[0],
half = scroll.offsetWidth / 2,
dist = pos * 180 + 90,
res = dist - half;
scroll.scrollLeft = res > 0 ? res : 0;
}
};
Main = {
init: function() {
var style = $.c("style"), observer;
if (location.pathname == "/" || (domain != "e621.net" && location.search === ""))
return d.addEventListener("DOMContentLoaded", Main.front, { passive: true, once: true });
function click(e) {
if (e.button === 0) {
e.preventDefault();
e.stopPropagation();
Main.fn(e.currentTarget);
}
}
function process(node) {
var a, id, alt;
try {
if (node && node.nodeType === 1 && node.matches("span.thumb") && (a = node.firstElementChild) && !a.dataset.full) {
alt = $("img[alt]", node)[0];
if (!alt) return;
alt = alt.alt;
if (Main.r[4].test(alt) || $("img[src*='webm-preview.png']", node).length) return;
try {
id = (node.id || a.id || a.children[0].id).match(Main.r[5])[0];
} catch(err) { return console.error(err); }
if (!id) throw Error("Incompatible booru - missing IDs from thumbnails");
if (domain == "gelbooru.com")
a.setAttribute("href", "/index.php?page=post&s=view&id=" + id);
if (alt && ~alt.indexOf("animated_gif")) {
a.firstElementChild.style.border = "2px solid lime";
a.dataset.gif = "gif";
}
a.dataset.id = id;
a.dataset.full = $.cache(id);
node.removeAttribute("onclick");
a.addEventListener("click", click);
}
} catch(err) { console.error(err); } return;
}
switch(domain) {
case "booru.org":
Main.r[0] = Main.r[1] = /<img alt="img" src="([^"]+)/i;
Main.css += "\nspan.thumb {\n float: left\n}";
break;
case "e621.net":
Main.css += "\n.thumb > a[data-id] {\n display: inline-block;\n margin-bottom: -3px\n}";
}
style.appendChild(d.createTextNode(Main.css));
observer = new MutationObserver(mutations => mutations.forEach(mutation => [...mutation.addedNodes].forEach(process)));
observer.observe(d, {
childList: true,
subtree: true
});
d.addEventListener("DOMContentLoaded", _ => d.head.appendChild(style), { passive: true, once: true });
d.addEventListener("animationend", e => {
switch(e.animationName) {
case "Outlined":
e.target.classList.remove("outlined");
break;
case "nomoreimages":
notification = e.target.remove();
break;
case "menuelement":
Menu.el = e.target.remove();
break;
case "warn":
e.target.remove();
break;
case "progfail": case "progdone":
Prog.el = e.target.remove();
}
}, { passive: true });
w.addEventListener("keypress", e => {
if (e.key === "Enter" || e.keyCode === 13) {
if (slideshow) {
Btn.el.firstElementChild.click();
} else if (e.target.matches("span.thumb>a[data-full]")) {
e.preventDefault();
Main.fn(e.target);
}
}
});
w.addEventListener("wheel", e => Main.el && $.keyDown({ keyCode: e.deltaY > 0 ? 39 : e.deltaY < 0 ? 37 : 0 }), { passive: true });
},
fn: function(node) {
d.dispatchEvent(new CustomEvent(ns, {bubbles:true}));
return Main[!!Main.el ? "off" : "on"](node);
},
off: function(a) {
var center;
console.log
slideshow = !(a = $.current());
Main.el = Main.el.remove();
d.body.classList.remove("sliding");
a.classList.add("outlined");
d.removeEventListener("keydown", $.keyDown);
center = a.offsetTop + a.offsetHeight / 2 - w.innerHeight / 2;
w.scrollTo(0, center < 0 ? 0 : center);
Pos.fn(); Btn.fn(); Hover.fn();
Main.gif = Main.gif.remove();
Prog.el = Prog.el.remove();
},
on: function(a) {
var el;
d.body.classList.add("sliding");
for (let a of $("span>a.outlined")) a.classList.remove("outlined");
Main.el = el = $.c("img");
el.id = "slide";
el.alt = "Loading...";
el.onclick = Main.fn;
el.onmouseup = e => e.button === 1 && $.keyDown({keyCode:38, event:e});
d.body.appendChild(el);
Main.gif = el = $.c("span");
el.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -3 36 22"><path d="M26 16c0 1.6-1.3 3-3 3H-7c-1.7 0-3-1.4-3-3V0c0-1.7 1.3-3 3-3h30c1.7 0 3 1.3 3 3v16z" opacity=".6"/><path fill="#FFF" d="M22-1H-6c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h28c1.1 0 2-.9 2-2V1c0-1.1-.9-2-2-2zM6.3 13.2H4.9l-.2-1.1c-.4.5-.8.9-1.3 1.1-.5.2-1 .3-1.4.3-.8 0-1.5-.1-2.1-.4s-1.1-.6-1.5-1.1-.7-1-1-1.6C-2.9 9.7-3 9-3 8.3c0-.7.1-1.4.3-2.1.2-.6.5-1.2 1-1.7s.9-.8 1.5-1.1C.5 3.2 1.2 3 1.9 3c.5 0 1 .1 1.5.2.5.2.9.4 1.3.7.4.3.7.7 1 1.1.2.5.4 1 .4 1.5H4c-.1-.5-.3-.9-.7-1.2-.4-.3-.8-.4-1.4-.4-.5 0-.9.1-1.2.3-.4.1-.7.4-.9.7-.2.3-.3.7-.4 1.1s-.1.8-.1 1.3c0 .4 0 .8.1 1.2s.3.8.5 1.1c.2.3.5.6.8.8s.8.3 1.3.3c.7 0 1.3-.2 1.7-.6.4-.4.6-.9.7-1.6H2.1V7.8h4.2v5.4zm4 0H8.1v-10h2.2v10zm8.9-8.1h-4.8v2.3h4.2v1.7h-4.2v4.1h-2.2v-10h7v1.9z"/></svg>';
el.classList.add("gif");
Hover.fn();
d.body.appendChild(el);
try { Main.slide(a.firstElementChild.src); } catch (err) { console.error(err); }
d.addEventListener("keydown", $.keyDown, { passive: true });
Pos.fn(); Btn.fn(); $.preload();
},
slide: function(src) {
var data, curr;
if (!slideshow) {
Main.el.src = src;
Hover.center(src);
}
Main.el.dataset.src = src;
curr = $.current(src);
data = curr.dataset.full;
Main.gif.removeAttribute("style");
/* dirty hack ahead because GIF doesn't want to play as a blob
* and doesn't give proper progress info for
* GM_xmlhttpRequest for whatever reason */
if (data == "loading") Main.req(curr);
// hack start
else if (data.match(Main.r[3])[1].toLowerCase() == "gif") {
Main.el.removeAttribute("src");
Main.el.src = data;
Main.gif.setAttribute("style", "display: inline-block");
}
// hack end
else if (curr.dataset.blob) {
Main.el.src = curr.dataset.blob;
if (Prog.el) Prog.el = Prog.el.remove();
let el = Prog.progress();
el.style.width = "100%";
el.classList.add("progdone");
} else Prog.fn(data, curr.dataset.id);
},
r: [/file_url[=>]"?([^" <]+)"?/i, /sample_url[=>]"?([^" <]+)"?/i, /com\/images\//i, /\.(gif|png|jpe?g)/i, /\b(webm|video|mp4|flash)\b/i, /\d+/],
req: function(node) {
var process, id, api;
if (!node || node.dataset.alreadyLoading || node.dataset.full != "loading") return;
switch(domain) {
case "e621.net":
id = node.parentNode.id.substr(1);
api = "/post/show.xml?id=";
break;
case "booru.org":
id = node.dataset.id;
api = "/index.php?page=post&s=view&id=";
break;
default:
id = node.dataset.id;
api = "/index.php?page=dapi&s=post&q=index&id=";
}
node.dataset.alreadyLoading = "true";
process = function(img) {
img = img.match((!node.dataset.gif && !toggle) ? Main.r[1] : Main.r[0])[1].replace(Main.r[2], "com//images/");
if (!img) throw Error("API error");
node.dataset.full = $.cache(id, img);
if (Main.el && Main.el.dataset.src.indexOf($.base(img)) > -1) {
try { Main.slide(img); } catch (err) { console.error(err); }
}
$("img", node)[0].style.outline = "";
return node.removeAttribute("data-already-loading");
};
return fetch(api + id)
.then(x => x.text())
.then(process)
.catch(err => {
Main.warn();
$("img", node)[0].style.outline = "6px solid red";
console.error("Failed HTTP request\nDo you have an internet connection?\n", err);
return node.removeAttribute("data-already-loading");
});
},
warn: function() {
var warn = $.c("span");
warn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"><style>path.a{fill:red;stroke-width:8px;stroke:black;}</style><path d="M500 673c-17 0-34 4-48 11-24 12-44 33-55 58-5 14-9 28-9 44 0 62 50 113 112 113 63 0 113-50 113-113C613 723 562 673 500 673zM500 843c-32 0-58-26-58-58 0-32 26-58 58-58 32 0 59 26 59 58C558 817 532 843 500 843z" class="a"/><path d="M285 643c4 3 8 5 12 5l132-138c-57 14-109 47-149 94C272 617 273 634 285 643z" class="a"/><path d="M606 522L565 565c43 13 83 39 112 75 5 7 13 10 21 10 6 0 12-2 17-6 11-9 13-27 3-38C689 568 650 539 606 522z" class="a"/><path d="M500 384c16 0 32 1 48 3l46-48c-30-7-61-10-93-10-137 0-265 61-351 167-10 11-8 29 4 38 5 4 11 7 17 7 8 0 15-4 21-10C267 438 379 384 500 384z" class="a"/><path d="M729 393l-38 40c45 24 86 58 119 98 10 12 27 14 39 4 12-9 13-27 4-38C817 454 776 420 729 393z" class="a"/><path d="M685 244l41-43c-70-28-147-42-226-42-188 0-364 84-484 230-9 12-7 29 4 39 5 4 11 6 17 6 8 0 16-3 21-10 109-133 270-210 442-210C564 214 626 224 685 244z" class="a"/><path d="M984 389c-38-48-83-88-133-121l-38 40c49 32 93 71 130 117 9 11 27 13 38 4C991 418 994 401 984 389z" class="a"/><path d="M907 110c-11-10-28-10-38 1L181 828c-10 11-10 28 1 38 5 5 12 8 19 8 7 0 14-3 20-8L908 148C918 138 918 120 907 110z" class="a"/></svg>';
warn.classList.add("warn");
if ($(".sliding>.warn").length === 0) d.body.appendChild(warn);
if (slideshow)
Main.el.dispatchEvent(new Event("load"));
},
front: function() {
var target, method;
switch(domain) {
case "e621.net":
target = "#mascot_artist";
method = "afterend";
break;
case "booru.org": case "rule34.xxx":
target = "#static-index > div:last-child > p:first-child";
method = "beforeend";
break;
default:
target = "form:last-of-type + div";
method = "beforeend";
}
$("#tags")[0].focus();
$(target)[0].insertAdjacentHTML(method, `<br><br>Gelbooru Enhancement:<br><pre style="font-size: 11px;text-align: left;display: inline-block;margin-top: 5px;">- Gelbooru Image Viewer 1.9.1</pre>`);
},
css: `
@keyframes Outlined {
0% { outline: 6px solid orange }
60% { outline: 6px solid orange }
100% { outline: 6px solid transparent }
}
@keyframes nomoreimages {
0% { opacity: 0 }
20% { opacity: 1 }
100% { opacity: 0 }
}
@keyframes menuelement {
0% { opacity: 1 }
80% { opacity: 1 }
100% { opacity: 0 }
}
@keyframes progfail {
0% { opacity: 1 }
60% { opacity: 1 }
100% { opacity: 0 }
}
@keyframes warn {
0% { opacity: 0; bottom: 5vh }
25% { opacity: 1; bottom: 10vh }
90% { opacity: 1 }
100% { opacity: 0 }
}
body.sliding > *:not(#slide) {
display: none
}
.warn {
display: inline-block ! important;
position: absolute;
width: 10vw;
left: 45vw;
bottom: 10vh;
animation-duration: 2s;
animation-name: warn
}
#slide {
width: 100vw;
height: 100vh;
object-fit: contain
}
.outlined {
outline: 6px solid transparent;
animation-duration: 4s;
animation-name: Outlined
}
.nomoreimages {
display: block ! important;
width: 33vw;
height: 100vh;
top: 0;
position: fixed;
animation-duration: 1s;
animation-name: nomoreimages
}
span.thumb {
max-width: 180px;
max-height: 180px;
}
#menuel {
opacity: 1;
position: fixed;
display: block ! important;
padding: 2px;
background: black;
width: 139px;
height: 44px;
animation-duration: 1s
}
.menuel {
animation-name: menuelement
}
#menuel:hover {
animation-name: keepalive
}
#menuel a {
background: #fff;
display: block
}
.slideshow {
display: block ! important;
position: fixed;
bottom: 20px;
right: 20px
}
.progress {
display: block ! important;
background-color: rgb(128,200,255);
height: 1vh;
position: absolute;
top: 0;
left: 0;
box-shadow: 0 .5vh 10px rgba(0,0,0,.7), inset 0 0 .1vh black;
transition: ease-in-out .08s width;
min-height: 3px;
max-width: 100vw;
pointer-events: none
}
.progfail {
background-color: red ! important;
width: 100% ! important;
animation-name: progfail;
animation-duration: .6s
}
.progdone {
width: 100% ! important;
animation-name: progfail;
animation-duration: .6s
}
.slideshow:hover:not([data-timer]) > div {
background: white;
color: black;
position: fixed;
display: block ! important;
bottom: 70px;
right: 20px
}
.sliding > .gif {
position: absolute;
top: 3vh;
right: 2vw;
width: 3.5vw;
opacity: .7;
min-width: 50px;
transition: ease .15s margin-top;
margin-top: 0;
will-change: margin-top
}
body.sliding {
padding: 0
}
.viewpre {
display: block ! important
}
.viewpre > div {
display: inherit;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 200px
}
.viewpre > .layover {
}
.viewpre > .tentcon {
transform: translateY(-100%);
transition: ease .15s transform;
background: linear-gradient(to bottom, black, transparent);
will-change: transform
}
.viewpre:hover > .tentcon {
transform: unset
}
.viewpre .wrapthatshit, .viewpre .wrapthatshit > .listimage {
transform: rotateX(180deg);
}
.viewpre:hover ~ .gif {
margin-top: 200px
}
.wrapthatshit {
height: 100%;
width: 100%;
overflow-x: auto
}
.listimage {
height: 180px
}
.listimage span {
height: 180px;
width: 180px;
display: inline-block;
text-align: center
}
.listimage span img {
cursor: pointer
}`
};
Main.init();
}(document, window, localStorage));