// ==UserScript==
// @name Kemer 增強
// @name:zh-TW Kemer 增強
// @name:zh-CN Kemer 增强
// @name:ja Kemer 強化
// @name:en Kemer Enhancement
// @version 0.0.44
// @author HentaiSaru
// @description 側邊欄收縮美化界面 , 自動加載原圖 , 簡易隱藏廣告 , 瀏覽翻頁優化 , 自動開新分頁 , 影片區塊優化 , 底部添加下一頁與回到頂部按鈕
// @description:zh-TW 側邊欄收縮美化界面 , 自動加載原圖 , 簡易隱藏廣告 , 瀏覽翻頁優化 , 自動開新分頁 , 影片區塊優化 , 底部添加下一頁與回到頂部按鈕
// @description:zh-CN 侧边栏收缩美化界面 , 自动加载原图 , 简易隐藏广告 , 浏览翻页优化 , 自动开新分页 , 影片区块优化 , 底部添加下一页与回到顶部按钮
// @description:ja サイドバーを縮小してインターフェースを美しくし、オリジナル画像を自動的に読み込み、広告を簡単に非表示にし、ページの閲覧とページめくりを最適化し、新しいページを自動的に開き、ビデオセクションを最適化し、下部に「次のページ」と「トップに戻る」ボタンを追加し。
// @description:en Collapse the sidebar to beautify the interface, automatically load original images, easily hide ads, optimize page browsing and flipping, automatically open new pages, optimize the video section, add next page and back to top buttons at the bottom.
// @match *://kemono.su/*
// @match *://coomer.su/*
// @match *://*.kemono.su/*
// @match *://*.coomer.su/*
// @icon https://cdn-icons-png.flaticon.com/512/2566/2566449.png
// @license MIT
// @namespace https://greasyfork.org/users/989635
// @run-at document-start
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_openInTab
// @grant GM_addElement
// @grant GM_xmlhttpRequest
// @grant GM_getResourceText
// @grant GM_registerMenuCommand
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js
// @resource font-awesome https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/svg-with-js.min.css
// ==/UserScript==
(function () {
var Language, ImgRules, GetSet, Set, buffer, parser = new DOMParser();
/* 功能選擇 (0 = false | 1 = true) */
const Config = {
Beautify: 1, // 側邊攔收縮美化
RemoveNotice: 1, // 刪除上方公告
Ad_Block: 1, // 清除阻擋廣告
CardSize: 1, // 帖子預覽卡放大
PostCardFade: 1, // 帖子文字卡淡化 [1 = 隱藏文字 , 2 = 淡化文字]
NewTabOpens: 1, // 自動新分頁
QuickPostToggle: 1, // 快速切換帖子
OriginalImage: 1, // 自動原圖 [1 = 快速自動 , 2 = 慢速自動 , 3 = 觀察觸
LinkAnalysis: 1, // 文本連結字串解析
LinkOriented: 1, // 下載連結轉換
VideoBeautify: 1, // 影片美化 [1 = 複製節點 , 2 = 移動節點]
CommentFormat: 1, // 修改評論區排版
ExtraButton: 1, // 額外的下方按鈕
};
async function Main() {
const M = {
DmsPage: /^(https?:\/\/)?(www\.)?.+\/dms\/?(\?.*)?$/,
PostsPage: /^(https?:\/\/)?(www\.)?.+\/posts\/?(\?.*)?$/,
Browse: /^(https?:\/\/)?(www\.)?.+\/.+\/user\/.+\/post\/.+$/,
UserPage: /^(https?:\/\/)?(www\.)?.+\/.+\/user\/[^\/]+(\?.*)?$/,
M1: function(url) {return this.Browse.test(url)},
M3: function(url) {return this.UserPage.test(url) || this.PostsPage.test(url) || this.DmsPage.test(url)}
}, R = {
U: (select, func) => {select > 0 ? func(select) : null},
Beautify: s => R.U(s, Beautify),
RemoveNotice: s => R.U(s, RemoveNotice),
Ad_Block: s => R.U(s, Ad_Block),
CardSize: s => R.U(s, CardSize),
PostCardFade: s => R.U(s, PostCardFade),
NewTabOpens: s => R.U(s, NewTabOpens),
QuickPostToggle: s => R.U(s, QuickPostToggle),
OriginalImage: s => R.U(s, OriginalImage),
LinkAnalysis: s => R.U(s, LinkAnalysis),
LinkOriented: s => R.U(s, LinkOriented),
VideoBeautify: s => R.U(s, VideoBeautify),
CommentFormat: s => R.U(s, CommentFormat),
ExtraButton: s => R.U(s, ExtraButton),
}, Url = document.URL, a = Object.entries(Config),
[g, p, w] = [a.slice(0, 3), a.slice(3, 7), a.slice(7, 13)];
g.forEach(([func, set]) => R[func](set));
if (M.M3(Url)) {p.forEach(([func, set]) => R[func](set))}
else if (M.M1(Url)) {
w.forEach(([func, set]) => R[func](set));
Load_Dependencies("Menu");
Language = language(GM_getValue("language", null));
GM_registerMenuCommand(Language.RM_01, function () {Menu()});
}
}Main();
async function Beautify() {
addstyle(`
.global-sidebar {
opacity: 0;
height: 100%;
width: 10rem;
display: flex;
position: fixed;
padding: 0.5em 0;
transition: 0.8s;
background: #282a2e;
flex-direction: column;
transform: translateX(-9rem);
}
.global-sidebar:hover {
opacity: 1;
transform: translateX(0rem);
}
.content-wrapper.shifted {
transition: 0.7s;
margin-left: 0rem;
}
.global-sidebar:hover + .content-wrapper.shifted {
margin-left: 10rem;
}
`, "Effects");
}
async function RemoveNotice() {
const announce = $$("body > div.content-wrapper.shifted > a");
if (announce) {announce.remove()}
}
async function Ad_Block() {
addstyle(`.ad-container, .root--ujvuu {display: none}`, "Ad-blocking-style");
addscript(`
const Ad_observer = new MutationObserver(() => {
try {
document.querySelectorAll(".ad-container").forEach(ad => {ad.remove()});
document.querySelector(".root--ujvuu button").click();
} catch {}
let XMLRequest = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url) {
if (url.endsWith(".m3u8") || url === "https://s.magsrv.com/v1/api.php") {
return;
}
XMLRequest.apply(this, arguments);
};
});
try {
Ad_observer.observe(document.body, {childList: true, subtree: true});
} catch {}
`, "Ad-blocking-script");
}
async function CardSize() {
addstyle(`
* { --card-size: 12vw; }
`, "Effects");
}
async function PostCardFade(Mode) {
switch (Mode) {
case 2:
addstyle(`
.post-card__header, .post-card__footer {
opacity: 0.4;
transition: opacity 0.3s;
}
a:hover .post-card__header,
a:hover .post-card__footer {
opacity: 1;
}
`, "Effects");break;
default:
addstyle(`
.post-card__header {
opacity: 0;
z-index: 1;
padding: 5px;
pointer-events: none;
transform: translateY(-6vh);
}
.post-card__footer {
opacity: 0;
z-index: 1;
padding: 5px;
pointer-events: none;
transform: translateY(6vh);
}
a:hover .post-card__header,
a:hover .post-card__footer {
opacity: 1;
pointer-events: auto;
transform: translateY(0vh);
transition: transform 0.4s, opacity 0.6s;
}
`, "Effects");
}
}
async function NewTabOpens() {
WaitElem("article a", true, 8, article => {
article.forEach(link => {
addlistener(link, "click", event => {
event.preventDefault();
GM_openInTab(link.href, { active: false, insert: true });
}, { capture: true })
})
});
}
async function QuickPostToggle() {
Load_Dependencies("Preview");
let Old_data, New_data, item;
async function Request(link) {
Old_data = $$("section");
item = $$("div.card-list__items");
GM_addElement(item, "img", {class: "gif-overlay"});
GM_xmlhttpRequest({
method: "GET",
url: link,
nocache: false,
onload: response => {
New_data = parser.parseFromString(response.responseText, "text/html").querySelector("section");
ReactDOM.render(React.createElement(ReactRendering, { content: New_data.innerHTML }), Old_data);
history.pushState(null, null, link);
QuickPostToggle();
NewTabOpens();
}
});
}
WaitElem("menu a", true, 8, meun => {
meun.forEach(ma => {
addlistener(ma, "click", (event) => {
event.preventDefault();
Request(ma.href);
}, { capture: true, once: true })
})
});
}
async function OriginalImage(Mode) {
Load_Dependencies("Postview");
let href, a, img;
WaitElem("div.post__thumbnail", true, 5, thumbnail => {
function ImgRendering({ ID, href }) {
return React.createElement("a", {
id: ID,
className: "image-link"
}, React.createElement("img", {
key: "img",
src: href.href.split("?f=")[0],
className: "img-style",
onError: function () {
Reload(ID, 15);
}
})
)
};
function Replace(index) {
if (index == thumbnail.length) {return}
const object = thumbnail[index];
object.classList.remove("post__thumbnail");
a = $$("a", false, object);
img = $$("img", false, a);
Object.assign(img, {
className: "img-style",
src: a.href.split("?f=")[0],
});
img.removeAttribute("data-src");
a.id = `IMG-${index}`
a.removeAttribute("href");
a.removeAttribute("download");
img.onload = function() {Replace(++index)};
};
const observer = new IntersectionObserver(observed => {
observed.forEach(entry => {
if (entry.isIntersecting) {
const object = entry.target;
observer.unobserve(object);
ReactDOM.render(React.createElement(ImgRendering, { ID: object.alt, href: $$("a", false, object) }), object);
object.classList.remove("post__thumbnail");
}
});
}, { threshold: 0.8 });
switch (Mode) {
case 2:
Replace(0);
break;
case 3:
thumbnail.forEach((object, index) => {
object.alt = `IMG-${index}`;
observer.observe(object);
});break;
default:
thumbnail.forEach((object, index) => {
object.classList.remove("post__thumbnail");
href = $$("a", false, object);
ReactDOM.render(React.createElement(ImgRendering, { ID: `IMG-${index}`, href: href }), object);
});
$$("a.image-link", true).forEach(link => {
const handleClick = () => {
img = $$("img", false, link);
if (!img.complete) {
img.src = img.src;
} else {
link.removeEventListener("click", handleClick);
}
}
link.addEventListener("click", handleClick);
});
}
});
}
async function Reload(ID, retry) {
if (retry > 0) {
setTimeout(() => {
let object = $$(`#${ID}`), old = $$("img", false, object), img = document.createElement("img");
Object.assign(img, {
src: old.src,
alt: "Reload",
className: "img-style"
});
img.onerror = function () { Reload(ID, retry) };
old.remove();
object.appendChild(buffer.appendChild(img));
retry--;
}, 1500);
}
}
async function LinkOriented() {
WaitElem("a.post__attachment-link", true, 5, post => {
post.forEach(link => {
link.setAttribute("download", "");
link.href = decodeURIComponent(link.href);
link.textContent = link.textContent.replace("Download", "").trim();
});
});
}
async function VideoBeautify(Mode) {
addstyle(`
.video-title {
margin-top: 0.5rem;
}
.post-video {
height: 50%;
width: 60%;
}
`, "Effects");
WaitElem("ul[style*='text-align: center;list-style-type: none;'] li", true, 5, parents => {
WaitElem("a.post__attachment-link", true, 5, post => {
function ReactBeautify({ stream }) {
return React.createElement("summary", {
className: "video-title"
} , React.createElement("video", {
key: "video",
controls: true,
preload: "auto",
"data-setup": JSON.stringify({}),
className: "post-video",
},
React.createElement("source", {
key: "source",
src: stream.src,
type: stream.type
})
));
}
parents.forEach(li => {
let title = $$("summary", false, li),
stream = $$("source", false, li);
if (title && stream) {
post.forEach(link => {
if (link.textContent.includes(title.textContent)) {
switch (Mode) {
case 2:
link.parentNode.remove();
title = link;
default:
title = link.cloneNode(true);
return;
}
}
});
ReactDOM.render(React.createElement(ReactBeautify, { stream: stream }), li);
li.insertBefore(title, $$("summary", false, li));
}
});
});
});
}
async function LinkAnalysis() {
const URL_Format = /(?:https?:\/\/[^\s]+|.*\.com\/[^\s]+)/g, Protocol_format = /^(?!https?:\/\/).*/g;
async function Analysis(father, text) {
father.innerHTML = text.replace(URL_Format, url => {
const link = Protocol_format.test(url) ? `https://${url}` : url;
return `<a href="${link}" target="_blank">${url}</a>`;
});
}
WaitElem("div.post__content", false, 8, content => {
let data = $$("pre", false, content);
if (data) {
Analysis(data, data.textContent);
} else {
$$("p", true, content).forEach(p => {
const a = $$("a", false, p);
if (a) {
Analysis(a, a.href);
} else {
Analysis(p, p.textContent);
}
});
}
});
}
async function CommentFormat() {
addstyle(`
.post__comments {
display: flex;
flex-wrap: wrap;
}
.post__comments>*:last-child {
margin-bottom: 0.5rem;
}
.comment {
margin: 0.5rem;
max-width: 25rem;
border-radius: 10px;
flex-basis: calc(35%);
word-break: break-all;
border: 0.125em solid var(--colour1-secondary);
}
`, "Effects");
}
async function Initialization() {
OriginalImage();
LinkAnalysis();
LinkOriented();
VideoBeautify();
CommentFormat();
ExtraButton();
if ($$(".post__content img", true).length > 2) {
$$(".post__content").remove();
}
$$("h1.post__title").scrollIntoView();
}
async function ExtraButton() {
Load_Dependencies("Awesome");
WaitElem("h2.site-section__subheading", false, 8, comments => {
const prev = $$("a.post__nav-link.prev");
const next = $$("a.post__nav-link.next");
const span = document.createElement("span");
const svg = document.createElement("svg");
const color = location.hostname.startsWith("coomer") ? "#99ddff !important" : "#e8a17d !important";
span.id = "next_box";
span.style = "float: right";
span.appendChild(next.cloneNode(true));
svg.innerHTML = `
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" style="margin-left: 10px;cursor: pointer;">
<style>svg{fill: ${color}}</style>
<path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM135.1 217.4l107.1-99.9c3.8-3.5 8.7-5.5 13.8-5.5s10.1 2 13.8 5.5l107.1 99.9c4.5 4.2 7.1 10.1 7.1 16.3c0 12.3-10 22.3-22.3 22.3H304v96c0 17.7-14.3 32-32 32H240c-17.7 0-32-14.3-32-32V256H150.3C138 256 128 246 128 233.7c0-6.2 2.6-12.1 7.1-16.3z"></path>
</svg>
`
buffer.appendChild(svg);
buffer.appendChild(span);
addlistener(svg, "click", () => {
$$("header").scrollIntoView();
}, { capture: true, passive: true })
setTimeout(() => {
comments.appendChild(buffer);
addlistener($$("#next_box a"), "click", event => {
event.preventDefault();
AjexReplace(next.href, $$("main"));
}, { capture: true, once: true });
}, 1300);
});
}
async function AjexReplace(url, old_main) {
let New_data, New_main;
GM_xmlhttpRequest({
method: "GET",
url: url,
nocache: false,
onload: response => {
New_data = parser.parseFromString(response.responseText, "text/html");
New_main = $$("main", false, New_data);
ReactDOM.render(React.createElement(ReactRendering, { content: New_main.innerHTML }), old_main);
history.pushState(null, null, url);
setTimeout(Initialization(), 500);
}
});
}
const styleRules = {
img_h: value => ImgRules[0].style.height = value,
img_w: value => ImgRules[0].style.width = value,
img_mw: value => ImgRules[0].style.maxWidth = value,
img_gap: value => ImgRules[0].style.margin = `${value} auto`,
MT: value => ImgRules[2].style.top = value,
ML: value => ImgRules[2].style.left = value
}
async function Menu() {
if (!$$(".modal-background")) {
ImgRules = $$("#Custom-style").sheet.cssRules;
Set = GetSet.ImgSet();
let parent, child, img_input, img_select, analyze;
const img_data = [Set.img_h, Set.img_w, Set.img_mw, Set.img_gap];
const menu = `
<div class="modal-background">
<div class="modal-interface">
<table class="modal-box">
<tr>
<td class="menu">
<h2 class="menu-text">${Language.MT_01}</h2>
<ul>
<li>
<a class="toggle-menu" href="#image-settings-show">
<button class="menu-options" id="image-settings">${Language.MO_01}</button>
</a>
<li>
<li>
<a class="toggle-menu" href="#">
<button class="menu-options" disabled>null</button>
</a>
<li>
</ul>
</td>
<td>
<table>
<tr>
<td class="content" id="set-content">
<div id="image-settings-show" class="form-hidden">
<div>
<h2 class="narrative">${Language.MIS_01}:</h2>
<p><input type="number" id="img_h" class="Image-input-settings" oninput="value = check(value)"></p>
</div>
<div>
<h2 class="narrative">${Language.MIS_02}:</h2>
<p><input type="number" id="img_w" class="Image-input-settings" oninput="value = check(value)"></p>
</div>
<div>
<h2 class="narrative">${Language.MIS_03}:</h2>
<p><input type="number" id="img_mw" class="Image-input-settings" oninput="value = check(value)"></p>
</div>
<div>
<h2 class="narrative">${Language.MIS_04}:</h2>
<p><input type="number" id="img_gap" class="Image-input-settings" oninput="value = check(value)"></p>
</div>
</div>
</td>
</tr>
<tr>
<td class="button-area">
<select id="language">
<option value="" disabled selected>${Language.ML_01}</option>
<option value="en">${Language.ML_02}</option>
<option value="zh-TW">${Language.ML_03}</option>
<option value="zh-CN">${Language.ML_04}</option>
<option value="ja">${Language.ML_05}</option>
</select>
<button id="readsettings" class="button-options" disabled>${Language.MB_01}</button>
<span class="button-space"></span>
<button id="closure" class="button-options">${Language.MB_02}</button>
<span class="button-space"></span>
<button id="application" class="button-options">${Language.MB_03}</button>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</div>
`
const UnitOptions = `
<select class="Image-input-settings" style="margin-left: 1rem;">
<option value="px" selected>px</option>
<option value="%">%</option>
<option value="rem">rem</option>
<option value="vh">vh</option>
<option value="vw">vw</option>
<option value="auto">auto</option>
</select>
`
$(document.body).append(menu);
$(".modal-interface").draggable({ cursor: "grabbing" });
$(".modal-interface").tabs();
$on("#image-settings", "click", () => {
const img_set = $("#image-settings-show");
if (img_set.css("opacity") === "0") {
img_set.find("p").each(function() {
$(this).append(UnitOptions);
});
img_set.css({
"height": "auto",
"width": "auto",
"opacity": 1
});
$("#readsettings").prop("disabled", false);
PictureSettings();
}
})
$("#language").val(GM_getValue("language", null) || "")
$on("#language", "input change", function (event) {
event.stopPropagation();
const value = $(this).val();
Language = language(value);
GM_setValue("language", value);
$("#language").off("input change");
$(".modal-background").remove();
Menu();
});
async function PictureSettings() {
$on(".Image-input-settings", "input change", function (event) {
event.stopPropagation();
const target = $(this), value = target.val(), id = target.attr("id");
parent = target.closest("div");
if (isNaN(value)) {
child = parent.find("input");
if (value === "auto") {
child.prop("disabled", true);
styleRules[child.attr("id")](value);
} else {
child.prop("disabled", false);
styleRules[child.attr("id")](`${child.val()}${value}`);
}
} else {
child = parent.find("select");
styleRules[id](`${value}${child.val()}`);
}
});
}
$on("#readsettings", "click", () => {
const img_set = $("#image-settings-show").find("p");
img_data.forEach((read, index) => {
img_input = img_set.eq(index).find("input");
img_select = img_set.eq(index).find("select");
if (read === "auto") {
img_input.prop("disabled", true);
img_select.val(read);
} else {
analyze = read.match(/^(\d+)(\D+)$/);
img_input.val(analyze[1]);
img_select.val(analyze[2]);
}
})
});
let save = {};
$on("#application", "click", () => {
const img_set = $("#image-settings-show").find("p");
img_data.forEach((read, index) => {
img_input = img_set.eq(index).find("input");
img_select = img_set.eq(index).find("select");
if (img_select.val() === "auto") {
save[img_input.attr("id")] = "auto";
} else if (img_input.val() === "") {
save[img_input.attr("id")] = read;
} else {
save[img_input.attr("id")] = `${img_input.val()}${img_select.val()}`;
}
})
GM_setValue("ImgSet", [save]);
save = {};
const menu_location = $(".modal-interface");
const top = menu_location.css("top");
const left = menu_location.css("left");
save["MT"] = top;
save["ML"] = left;
GM_setValue("MenuSet", [save]);
styleRules["MT"](top);
styleRules["ML"](left);
$(".modal-background").remove();
});
$on("#closure", "click", () => {
$(".modal-background").remove();
});
}
}
function Load_Dependencies(type) {
switch (type) {
case "Preview":
addstyle(`
.gif-overlay {
top: 45%;
left: 50%;
width: 60%;
height: 60%;
opacity: 0.5;
z-index: 9999;
position: absolute;
border-radius: 50%;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
transform: translate(-50%, -50%);
background-image: url("https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/images/loading.gif");
}
.card-list__items {
gap: 0.5em;
display: flex;
grid-gap: 0.5em;
position: relative;
flex-flow: var(--local-flex-flow);
justify-content: var(--local-justify);
align-items: var(--local-align);
}
`, "Effects");break;
case "Postview":
buffer = document.createDocumentFragment();
GetSet = {
MenuSet: () => {
const data = GM_getValue("MenuSet", null) || [{
"MT": "2vh",
"ML": "50vw",
}]; return data[0];
},
ImgSet: () => {
const data = GM_getValue("ImgSet", null) || [{
"img_h": "auto",
"img_w": "auto",
"img_mw": "100%",
"img_gap": "0px",
}]; return data[0];
},
}
Set = GetSet.ImgSet();
addstyle(`
.img-style {
display: block;
width: ${Set.img_w};
height: ${Set.img_h};
margin: ${Set.img_gap} auto;
max-width: ${Set.img_mw};
}
`, "Custom-style");break;
case "Awesome":
addstyle(GM_getResourceText("font-awesome"), "font-awesome");break;
case "Menu":
Set = GetSet.MenuSet();
addscript(`
function check(value) {
if (value.toString().length > 4 || value > 1000) {
value = 1000;
} else if (value < 0) {
value = 0;
}
return value || 0;
}
`);
addstyle(`
.modal-background {
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
z-index: 9999;
overflow: auto;
position: fixed;
pointer-events: none;
}
.modal-interface {
top: ${Set.MT};
left: ${Set.ML};
margin: 0;
display: flex;
overflow: auto;
position: fixed;
border-radius: 5px;
pointer-events: auto;
background-color: #2C2E3E;
border: 3px solid #EE2B47;
}
.modal-box {
padding: 0.5rem;
height: 50vh;
width: 32vw;
}
.menu {
width: 5.5vw;
overflow: auto;
text-align: center;
vertical-align: top;
border-radius: 2px;
border: 2px solid #F6F6F6;
}
.menu-text {
color: #EE2B47;
cursor: default;
padding: 0.2rem;
margin: 0.3rem;
margin-bottom: 1.5rem;
white-space: nowrap;
border-radius: 10px;
border: 4px solid #f05d73;
background-color: #1f202c;
}
.menu-options {
cursor: pointer;
font-size: 1.4rem;
color: #F6F6F6;
font-weight: bold;
border-radius: 5px;
margin-bottom: 1.2rem;
border: 5px inset #EE2B47;
background-color: #6e7292;
transition: color 0.8s, background-color 0.8s;
}
.menu-options:hover {
color: #EE2B47;
background-color: #F6F6F6;
}
.menu-options:disabled {
color: #6e7292;
cursor: default;
background-color: #c5c5c5;
border: 5px inset #faa5b2;
}
.content {
height: 48vh;
width: 28vw;
overflow: auto;
padding: 0px 1rem;
border-radius: 2px;
vertical-align: top;
border-top: 2px solid #F6F6F6;
border-right: 2px solid #F6F6F6;
}
.narrative { color: #EE2B47; }
.Image-input-settings {
width: 8rem;
color: #F6F6F6;
text-align: center;
font-size: 1.5rem;
border-radius: 15px;
border: 3px inset #EE2B47;
background-color: #202127;
}
.Image-input-settings:disabled {
border: 3px inset #faa5b2;
background-color: #5a5a5a;
}
.button-area {
display: flex;
padding: 0.3rem;
border-left: none;
border-radius: 2px;
border: 2px solid #F6F6F6;
justify-content: space-between;
}
.button-area select {
color: #F6F6F6;
margin-right: 1.5rem;
border: 3px inset #EE2B47;
background-color: #6e7292;
}
.button-options {
color: #F6F6F6;
cursor: pointer;
font-size: 0.8rem;
font-weight: bold;
border-radius: 10px;
white-space: nowrap;
background-color: #6e7292;
border: 3px inset #EE2B47;
transition: color 0.5s, background-color 0.5s;
}
.button-options:hover {
color: #EE2B47;
background-color: #F6F6F6;
}
.button-space { margin: 0 0.6rem; }
.form-hidden {
opacity: 0;
height: 0;
width: 0;
overflow: hidden;
transition: opacity 0.8s, height 0.8s, width 0.8s;
}
.toggle-menu {
height: 0;
width: 0;
padding: 0;
margin: 0;
}
table, td {
margin: 0px;
padding: 0px;
overflow: auto;
border-spacing: 0px;
}
p { display: flex; flex-wrap: nowrap; }
option { color: #F6F6F6; }
ul {
list-style: none;
padding: 0px;
margin: 0px;
}
`, "Custom-style");break;
}
}
function ReactRendering({ content }) {
return React.createElement("div", { dangerouslySetInnerHTML: { __html: content } });
}
async function addscript(Rule, ID="Add-script") {
let new_script = $$(`#${ID}`);
if (!new_script) {
new_script = document.createElement("script");
new_script.id = ID;
document.head.appendChild(new_script);
}
new_script.appendChild(document.createTextNode(Rule));
}
async function addstyle(Rule, ID="Add-Style") {
let new_style = $$(`#${ID}`);
if (!new_style) {
new_style = document.createElement("style");
new_style.id = ID;
document.head.appendChild(new_style);
}
new_style.appendChild(document.createTextNode(Rule));
}
async function $on(element, type, listener) {
$(element).on(type, listener);
}
async function addlistener(element, type, listener, add={}) {
element.addEventListener(type, listener, add);
}
function $$(Selector, All=false, Source=document) {
if (All) {return Source.querySelectorAll(Selector)}
else {
const slice = Selector.slice(1);
const analyze = (slice.includes(" ") || slice.includes(".") || slice.includes("#")) ? " " : Selector[0];
switch (analyze) {
case "#": return Source.getElementById(slice);
case " ": return Source.querySelector(Selector);
case ".": return Source.getElementsByClassName(slice)[0];
default: return Source.getElementsByTagName(Selector)[0];
}
}
}
async function WaitElem(selector, all, timeout, callback) {
let timer, element, result;
const observer = new MutationObserver(() => {
element = all ? document.querySelectorAll(selector, true) : document.querySelector(selector);
result = all ? element.length > 0 : element;
if (result) {
observer.disconnect();
clearTimeout(timer);
callback(element);
}
});
observer.observe(document.body, { childList: true, subtree: true });
timer = setTimeout(() => {
observer.disconnect();
}, 1000 * timeout);
}
function language(language) {
let display = {
"zh-TW": [{
"RM_01":"📝 設置選單",
"MT_01":"設置菜單", "MO_01":"圖像設置",
"MB_01":"讀取設定", "MB_02":"關閉離開", "MB_03":"保存應用",
"ML_01":"語言", "ML_02":"英文", "ML_03":"繁體", "ML_04":"簡體", "ML_05":"日文",
"MIS_01":"圖片高度", "MIS_02":"圖片寬度", "MIS_03":"圖片最大寬度", "MIS_04":"圖片間隔高度"
}],
"zh-CN": [{
"RM_01":"📝 设置菜单",
"MT_01":"设置菜单", "MO_01":"图像设置",
"MB_01":"读取设置", "MB_02":"关闭退出", "MB_03":"保存应用",
"ML_01":"语言", "ML_02":"英文", "ML_03":"繁体", "ML_04":"简体", "ML_05":"日文",
"MIS_01":"图片高度", "MIS_02":"图片宽度", "MIS_03":"图片最大宽度", "MIS_04":"图片间隔高度"
}],
"ja": [{
"RM_01":"📝 設定メニュー",
"MT_01":"設定メニュー", "MO_01":"画像設定",
"MB_01":"設定の読み込み", "MB_02":"閉じて終了する", "MB_03":"保存して適用する",
"ML_01":"言語", "ML_02":"英語", "ML_03":"繁体字", "ML_04":"簡体字", "ML_05":"日本語",
"MIS_01":"画像の高さ", "MIS_02":"画像の幅", "MIS_03":"画像の最大幅", "MIS_04":"画像の間隔の高さ"
}],
"en-US": [{
"RM_01":"📝 Settings Menu",
"MT_01":"Settings Menu", "MO_01":"Image Settings",
"MB_01":"Load Settings", "MB_02":"Close and Exit", "MB_03":"Save and Apply",
"ML_01":"Language", "ML_02":"English", "ML_03":"Traditional Chinese", "ML_04":"Simplified Chinese", "ML_05":"Japanese",
"MIS_01":"Image Height", "MIS_02":"Image Width", "MIS_03":"Maximum Image Width", "MIS_04":"Image Spacing Height"
}],
};
return display.hasOwnProperty(language) ? display[language][0] : display["en-US"][0];
}
})();