AkaringoP said in forum #423829:
Danbooru Post Timeline
Neat but makes it require two subtractions to actually see when something was posted to Danbooru
Posted under General
AkaringoP said in forum #423829:
Danbooru Post Timeline
Neat but makes it require two subtractions to actually see when something was posted to Danbooru
Turns all notes in a post into fancy embedded notes, just open up a post with an already existing notes or translate them yourself first, then go to the top right of the screen to open the note stamper setting and turn them into those fancy hard translated-like notes. The scripts already had a guide explaining how it works inside it so I'll just be explaining its limitation here
Don't mind the notes and image button down there it's part of another experimental script I had 
Now go spread the gospel of embedded notes
this script is 100% vibe coded I cannot guarantee you that I will and can fix any bugs you came across, and any features I said I'll add depends if I feel like making changes to it
Updated by Andrecnuuy
Danbooru Post Timeline
Tracks the journey from source platform to Danbooru by showing when the artwork was originally published, when the media asset was uploaded, and when the post was created.
https://github.com/AkaringoP/JavaScripts/raw/refs/heads/main/PostTimeline/PostTimeline.user.js
had this idea the other day. dumb script that nests general tags if the name of one tag contains another tag. it just reorders the tags btw doesn't duplicate them if they contain multiple words
// ==UserScript==
// @name Danbooru Nest Gentags
// @version 1
// @grant none
// @run-at document-end
// @match https://danbooru.donmai.us/*
// ==/UserScript==
(function() {
'use strict';
const FAKE_TAGS = [
'alternate', 'bangs', 'clothes', 'cutout', 'ears', 'eyes', 'eyewear',
'feet', 'fingers', 'focus', 'footwear', 'hair', 'headwear', 'legwear',
'legs', 'lips', 'mouth', 'nails', 'neckwear', 'nose', 'pupils', 'print',
'sleeves', 'skin', 'teeth', 'toes', 'thighs', 'thumbs'
];
const SORT_FAKE_TAGS = true;
const PRIORITIZE_VERBS = false;
const SKIP_VERBS = true;
const PLURALS = {
'teeth': 'tooth',
'feet': 'foot',
'men': 'man',
'women': 'woman',
'children': 'child',
'mice': 'mouse',
'lice': 'louse',
'die': 'dice',
'people': 'person',
'cacti': 'cactus',
'hippopotami': 'hippopotamus',
'streaks': 'streaked_hair',
'smartphone': 'smart_phone',
'cellphone': 'cell_phone',
'fingernails': 'finger_nail',
'toenails': 'toe_nail',
'toes': 'toe',
'sleeves': 'sleeve',
'focus': 'focus',
'pantyshot': 'panty_shot',
};
function addFakeTags() {
const tagList = document.querySelector('ul.general-tag-list');
const listedTags = tagList.querySelectorAll('li');
function addFakeTag(tag) {
const exists = tagList.querySelector(`[data-tag-name=${tag}]`);
if(exists) {
return;
}
const li = document.createElement('li');
li.innerText = '? ' + tag;
li.dataset.tagName = tag;
li.dataset.isFakeTag = '1';
li.className = 'fake-gentag';
li.title = "Created by Nest Gentags userscript";
li.style.color = 'var(--muted-text-color)';
let before;
if(SORT_FAKE_TAGS) {
for(let listedTag of listedTags) {
if(listedTag.dataset.tagName > tag) {
before = listedTag;
break;
}
}
}
tagList.insertBefore(li, before);
}
FAKE_TAGS.map(addFakeTag);
}
function removeEmptyFakeTags(groups) {
for(let tag of document.querySelectorAll('.fake-gentag')) {
if(!groups.tagGroups[tag.dataset.tagName]) {
tag.remove();
}
}
}
function getGeneralTags() {
return [...document.querySelectorAll("ul.general-tag-list > li")];
}
function normalizeWord(word) {
const irregular = PLURALS[word];
if(irregular) {
return irregular;
}
function unsuffix(word, suffix, newSuffix="") {
if(!word.endsWith(suffix)) {
return null;
} else {
const nosuffix = word.substring(0, word.length - suffix.length);
return nosuffix + newSuffix;
}
}
if(word.length > 3 && word.endsWith('s')) {
if('sxz'.indexOf(word[word.length - 2]) === -1) {
return (
unsuffix(word, 'ves', 'f') ||
unsuffix(word, 'oes', 'o') ||
unsuffix(word, 'ies', 'y') ||
unsuffix(word, 'xes', 'x') ||
unsuffix(word, 'hes', 'h') ||
unsuffix(word, 'sses', 's') ||
unsuffix(word, 'zzes', 'z') ||
unsuffix(word, 'ses', 's') ||
unsuffix(word, 's') ||
word
);
}
}
return word;
}
function isVerb(tag) {
return tag.split('_')[0].endsWith('ing');
}
function createTag(li) {
const tag = li.dataset.tagName;
const normalized = tag.split('_').map(normalizeWord).join('_');
return {
tag, li, normalized, isVerb: isVerb(normalized), words: new Set(normalized.split('_'))
};
}
function groupTags(tags) {
function createGroup(groupMap, name, depth, member) {
let group = groupMap[name];
if(!group) {
group = { tags: [], depth, name };
tagGroups[name] = group;
}
group.tags.push(member);
return group;
}
const tagMap = {};
for(let tag of tags) {
tagMap[tag.tag] = tag;
}
const tagNames = tags.map(t => t.tag);
tagNames.sort((a, b) => {
const atag = tagMap[a];
const btag = tagMap[b];
const words = atag.words.size - btag.words.size;
if(words === 0) {
return atag.normalized.length - btag.normalized.length;
} else {
return words;
}
});
const len = tagNames.length;
if(PRIORITIZE_VERBS) {
let verbs = 0;
for(let i = 0; i < len; i++) {
const tagName = tagNames[i];
const tag = tagMap[tag];
if(tag.words.size !== 1) {
continue;
}
if(tag.isVerb) {
tagNames.splice(i, 1);
tagNames.splice(verbs, 0, tagName);
}
}
}
const tagGroups = {};
const grouped = {};
const ungrouped = [];
for(let i = 0; i < len; i++) {
const itagName = tagNames[i];
if(itagName in grouped) {
continue;
}
const itag = tagMap[itagName];
if(SKIP_VERBS && itag.isVerb) {
ungrouped.push(itagName);
continue;
}
for(let j = i + 1; j < tags.length; j++) {
const jtagName = tagNames[j];
if(!itag.words.isSubsetOf(tagMap[jtagName].words)) {
continue;
}
if(jtagName in grouped) {
continue;
}
grouped[jtagName] = createGroup(
tagGroups, itagName, 1, jtagName
);
}
ungrouped.push(itagName);
}
const subTagGroups = {};
const subgrouped = [];
for(let groupName in tagGroups) {
const group = tagGroups[groupName];
const len = group.tags.length;
for(let i = 0; i < len; i++) {
const itag = group.tags[i];
if(itag in subgrouped) {
continue;
}
for(let j = i + 1; j < len; j++) {
const jtag = group.tags[j];
if(!tagMap[itag].words.isSubsetOf(tagMap[jtag].words)) {
continue;
}
if(jtag in subgrouped) {
continue;
}
subgrouped[jtag] = createGroup(subTagGroups, itag, 2, jtag);
delete grouped[jtag];
}
}
}
return {
tags, tagGroups, tagMap,
grouped, ungrouped, subgrouped, subTagGroups
};
}
function padGrouped(groups) {
const len = groups.tags.length;
for(let i = len - 1; i >= 0; i--) {
const tag = groups.tags[i];
const group = groups.grouped[tag.tag];
if(!group) {
continue;
}
const groupTag = groups.tagMap[group.name];
groupTag.li.after(tag.li);
makeNested(tag, group.depth);
}
for(let i = len - 1; i >= 0; i--) {
const tag = groups.tags[i];
const subgroup = groups.subgrouped[tag.tag];
if(!subgroup) {
continue;
}
const groupTag = groups.tagMap[subgroup.name];
groupTag.li.after(tag.li);
makeNested(tag, subgroup.depth);
}
}
function createNestedIcon(depth) {
const span = document.createElement('span');
span.className = "nested-tag-icon text-muted select-none mr-1";
span.innerText = '↳';
span.style.marginLeft = `${0.75 * (depth - 1)}rem`;
return span;
}
function makeNested(tag, depth) {
tag.li.querySelector('.mr-2')?.after(createNestedIcon(depth));
}
if(window.nestedGenTags) {
return;
}
window.nestedGenTags = true;
addFakeTags();
const groups = groupTags(getGeneralTags().map(createTag));
padGrouped(groups);
removeEmptyFakeTags(groups);
})();after using it a bit i thought it was too random because i couldn't find anything in alphabetical order anymore so i changed it. version 2 creates a copy of the tag and nests it so the same tag appears both in normal alphabetical order and nested everywhere
// ==UserScript==
// @name Danbooru Nest Gentags
// @version 2.1
// @grant none
// @run-at document-end
// @match https://danbooru.donmai.us/*
// ==/UserScript==
(function() {
'use strict';
const FAKE_TAGS = [
'alternate', 'ankles', 'arms', 'ass', 'bangs', 'back', 'backless',
'background', 'chest', 'clothes', 'collarbone', 'crotch', 'crotchless',
'cupless', 'cutout', 'ears', 'elbows', 'eyes', 'eyewear', 'feet',
'fingers', 'focus', 'footwear', 'foreground', 'fourth_wall', 'hair',
'hands', 'head', 'headwear', 'hips', 'holding', 'knees', 'legwear',
'legs', 'lips', 'mouth', 'nails', 'neck', 'neckwear', 'nose', 'pupils',
'print', 'shoulders', 'sleeves', 'skin', 'soles', 'stomach',
'teeth', 'toes', 'thighs', 'thumbs', 'throat', 'waist',
];
const SORT_FAKE_TAGS = true;
const PLURALS_AND_NORMS = {
'teeth': 'tooth',
'feet': 'foot',
'men': 'man',
'women': 'woman',
'children': 'child',
'mice': 'mouse',
'lice': 'louse',
'die': 'dice',
'people': 'person',
'cacti': 'cactus',
'hippopotami': 'hippopotamus',
'streaks': 'streaked_hair',
'smartphone': 'smart_phone',
'cellphone': 'cell_phone',
'fingernails': 'finger_nail',
'toenails': 'toe_nail',
'toes': 'toe',
'sleeves': 'sleeve',
'focus': 'focus',
'pantyshot': 'panty_shot',
'naked': 'nude',
'sideboob': 'side_breasts',
'underboob': 'under_breasts',
'backboob': 'back_breasts',
'dark-skinned_male': 'dark_skin_male',
'dark-skinned_female': 'dark_skin_female',
'censoring': 'censor',
'censored': 'censor',
};
function addFakeTags() {
const tagList = document.querySelector('ul.general-tag-list');
const listedTags = tagList.querySelectorAll('li');
function addFakeTag(tag) {
const exists = tagList.querySelector(`[data-tag-name=${tag}]`);
if(exists) {
return;
}
const li = document.createElement('li');
li.innerText = tag;
const q = document.createElement('span');
q.className = 'mr-2';
q.innerText= '?';
li.insertBefore(q, li.childNodes[0]);
li.dataset.tagName = tag;
li.dataset.isFakeTag = '1';
li.className = 'fake-gentag';
li.title = "Created by Nest Gentags userscript";
li.style.color = 'var(--muted-text-color)';
let before;
if(SORT_FAKE_TAGS) {
for(let listedTag of listedTags) {
if(listedTag.dataset.tagName > tag) {
before = listedTag;
break;
}
}
}
tagList.insertBefore(li, before);
}
FAKE_TAGS.map(addFakeTag);
}
function removeEmptyFakeTags(groups) {
for(let tag of groups.tags) {
if(tag.isFake && tag.subtags.length === 0) {
tag.li.remove();
}
}
}
function getGeneralTags() {
return [...document.querySelectorAll("ul.general-tag-list > li")];
}
function normalizeWord(word) {
const irregular = PLURALS_AND_NORMS[word];
if(irregular) {
return irregular;
}
function unsuffix(word, suffix, newSuffix="") {
if(!word.endsWith(suffix)) {
return null;
} else {
const nosuffix = word.substring(0, word.length - suffix.length);
return nosuffix + newSuffix;
}
}
if(word.length > 3 && word.endsWith('s')) {
if('sxz'.indexOf(word[word.length - 2]) === -1) {
return (
unsuffix(word, 'ves', 'f') ||
unsuffix(word, 'oes', 'o') ||
unsuffix(word, 'ies', 'y') ||
unsuffix(word, 'xes', 'x') ||
unsuffix(word, 'hes', 'h') ||
unsuffix(word, 'sses', 's') ||
unsuffix(word, 'zzes', 'z') ||
unsuffix(word, 'ses', 's') ||
unsuffix(word, 's') ||
word
);
}
}
return word;
}
function isVerb(tag) {
return tag.split('_')[0].endsWith('ing');
}
function createTag(li) {
const tag = li.dataset.tagName;
const normalized = tag.split('_').map(normalizeWord);
const firstNormal = normalized[0];
return {
tag, li, normalized: normalized.join('_'),
isVerb: isVerb(firstNormal), firstNormal,
isFake: li.dataset.isFakeTag,
parents: [], subtags: [], words: new Set(normalized),
};
}
function groupTags(tags) {
for(let tag of tags) {
tag.subtags = tags.filter(
t => t !== tag && tag.words.isSubsetOf(t.words)
);
for(let sub of tag.subtags) {
sub.parents.push(tag);
}
}
return { tags };
}
function padGrouped(groups) {
for(let tag of groups.tags) {
if(tag.parents.filter(p => p.firstNormal == tag.firstNormal).length > 0) {
tag.li.remove();
continue;
}
let before = tag.li;
for(let subtag of tag.subtags) {
const clone = subtag.li.cloneNode(true);
before.after(clone);
before = clone;
clone.querySelector('.mr-2')?.after(createNestedIcon(1));
}
}
}
function createNestedIcon(depth) {
const span = document.createElement('span');
span.className = "nested-tag-icon text-muted select-none mr-1";
span.innerText = '↳';
span.style.marginLeft = `${0.75 * (depth - 1)}rem`;
return span;
}
if(window.nestedGenTags) {
return;
}
window.nestedGenTags = true;
addFakeTags();
const groups = groupTags(getGeneralTags().map(createTag));
padGrouped(groups);
removeEmptyFakeTags(groups);
})();Updated by trapster77
Andrecnuuy said in forum #423879:
Quick Fancy Embedded notes
Turns all notes in a post into fancy embedded notes, just open up a post with an already existing notes or translate them yourself first, then go to the top right of the screen to open the note stamper setting and turn them into those fancy hard translated-like notes.
Install (old)this script is 100% vibe coded I cannot guarantee you that I will and can fix any bugs you came across, and any features I said I'll add depends if I feel like making changes to it
Added some more new option to the script, rotation, font option, outline options blah blah even I forgot what got added really. This should've been shared a week ago but I forgot. Anyway here's the difference from old and new option if you like the simpler one just use the old one there's no difference in functionality just more option to choose from
Install here I left out the old version up there if anyone feel like this one is a bit bloated
And also call it a 2 in one deal here's another new script to download said notes
Downloads a post image along with its note, as shrimple as it said it download an image of a post with its embedded notes. Only works for embedded notes, normal notes will just looks like shite. The way it works is just that it fetched the original image then just overlay the embedded notes element on top so there should be no loss in quality. And also the button to download em is right beside the fav post button, there's option to download with note, and raw download aka just the normal download post button but just repositioned.
But for absurdres or near absurdres image please do load it in original res first
Updated by Andrecnuuy
shows a link to search the source of your post in your assets to help posting large variant sets
// ==UserScript==
// @name Danbooru Search Source in Assets
// @version 1
// @grant none
// @run-at document-end
// @match https://danbooru.donmai.us/*
// ==/UserScript==
window.searchSourceInAssets ||= (() => {
const d = document.body.dataset;
const userId = d.currentUserId;
const source = document.getElementById('post-info-source');
const href = source?.querySelector('a')?.href;
if(!href || userId !== d.postUploaderId) { return; }
const li = document.createElement('li');
const a = li.appendChild(document.createElement('a'));
a.innerText = "Search Source in Assets";
a.href = ((userId, source) => {
return `https://danbooru.donmai.us/users/${userId}/uploads?commit=Search&search%5Bany_source_matches%5D=${source}&user_id=${userId}`;
}).apply(null, [userId, href].map(encodeURIComponent));
source.after(li);
})() || 1;Helps you to quickly made a new artist entry for said sites artists. But if said artist was already registered here it'll copy said artist's tag to your clipboard, it also supports multiple artist at once. How does it work?
1. Go to a video you wanna up (yes this is mainly for video upping) for an example this video
2. Press "alt o" or just click the button on the bottom right of the screen
3. If the artist is already registered it'll just copy the name, if not it'll open a new tab to create a new artist entry. Refer to image below
4. You choose one of the name on top it'll automatically filled in all the required field with romanization if needed
5. Just submit, if there's another artist to be made like one I had here just go back to the create new artist tab and choose that one, click x to clear the list if they're still there after you're done.
Caveat: If an artist actually already exist on the database but they don't have their bilibili/youtube/nicovideo linked on their page already, the script won't recognize it and ask you to make a new artist tag anyway. Could I fix it? yea ig but nah shurely I won't came across one of those too often esp in bilibili 
this script is 100% vibe coded I cannot guarantee you that I will and can fix any bugs you came across
And also I got others teeny tiny script here that aren't really prioritized to be shared here cuz they're less of a productivity script but moreso a fun little or just a miniscule change script if you're interested
Updated by Andrecnuuy
this userscript lets you press tab to go from the tag edit box to the submit button because a recent danbooru change broke my workflow
// ==UserScript==
// @name Danbooru Patch Tab to Submit Button
// @version 1
// @grant none
// @run-at document-end
// @match https://danbooru.donmai.us/*
// ==/UserScript==
window.tab2SubmitButton ||= (() => {
document.getElementById('post_tag_string').addEventListener('keydown', function(e) {
if (e.key !== 'Tab') { return; }
if([...document.querySelectorAll('.ui-autocomplete')].some(a => a.style.display !== 'none')) { return; }
e.preventDefault();
this.closest('form')
.querySelector(e.shiftKey ? '#open-edit-dialog' : 'input[type=submit]')
?.focus();
}, true);
})() || 1;Just as the name suggest it helps you organize your asset by assigning their artist tag (if available) to each asset. This comes with a search bar along with unlimited pages support (thanks Mango 2 with unlimited paginator works, for helping me (gemini) figuring out how to load more pages)
The script features many button with features that I will not elaborate for now I'll just let you know how to use the script and tell you as we go. First you go to your unposted my upload page, yes unposted, I did not make this for the all category one for efficiency. You'd first see many button to choose from, first thing you should do if you're fresh installing this script is to click that scan library button. And we move on to the explanation-
Explanation and a bit of rant
So basically the way the artist tag scan works is that it detect the artist tag on each asset's upload page source information and from that it register that artist tag to said asset, is there a better way to do this? Maybe idk I can't seem to find out how to find the artist tag for pixiv links and other similar link without their name on the link so I had to get somewhat creative and came out with this solution, was it efficient? no but I can't came up with anything else. And this is where the quick twitter button came to play, if your asset mostly consist of twitter sourced asset you can just use this to just quickly use the twitter handle as the artist name without having to check what their name was on danbooru, and by quickly I mean it a whole 200 page in a second all registered with their twitter name. If you want more precise names just click on the scan library button. And also another thing, registered artist data is permanently stored in the script memory but unregistered one isn't, and this is why I made the quick twitter button a toggle, if you had it on it would ignore any new changes to unregistered twitter artist and just use their twitter name but if you turn it off it would do a rescan of every twitter artist you had and move em to registered artist if you or someone had already made an artist entry for them since last scan. But have no fear the script can detect similar artist name so if you have let's say 100 asset from an unregistered artist and you've now made an entry for them, the script would check the artist handle and remember that for their next 100 asset and instantly register them without having to check one by one. And also one more thing, regarding pixiv links, pixiv links with no artist tag related to them will be treated as unknown, I mean hwell they did not have any names connected to them so what do you want me to mark them as. Oh and also if you've made an artist entry for them later you can make it rescan it by clicking the scan library button. can you tell that I wrote this at 3 in the morning?
So to summarize it, the button basically just makes thing load faster, just keep it on after the scan library thing is finished. Shrimple as that, if you want to read more into how it works read the whole 📜, if not it's fine it won't change your experience with this script.
Anyway install here
Install
And also one more thing, if you're using hide uploads userscript by @ Nameless Contributor you might noticed that the extra loaded assets doesn't seem to be hidden by the script and so "I" modified his script to be able to work along with this script so here it is. NC if you read this and want it gone I will remove it if you say so
Install
Updated by Andrecnuuy
Andrecnuuy said in forum #433262:
Asset Organizer
Just as the name suggest it helps you organize your asset by assigning their artist tag (if available) to each asset. This comes with a search bar along with unlimited pages support (thanks Mango 2 with unlimited paginator works, for helping me (gemini) figuring out how to load more pages)
Now it also have the character and copyright of an asset (if it's available) to each asset.
The way it detects them is by using the asset's translated tag so if it detects one it will assign it to that asset, if there's none then there's none, only artist data for that asset (if there's one). Be sure to clear cache first before doing a library scan if you've used the old version above before (if). And also because the script now fetch more data it will take longer to scan all of your asset, in my experience about 20 minutes for 1.5k asset. But if your asset is mostly twitter it should be faster I believe
Updated by Andrecnuuy
AkaringoP said in forum #405141:
Danbooru Mobile Note Assist
As the old saying goes: 'Someone who suggests it, implements it.'
Although it doesn't create all notes at once as suggested before, it enables you to work on notes in mobile environments that support UserScripts.
On a PC, just use what you used instead of this.
Usage
1. Activate: On the post page, tap "Note Assist" in the sidebar options or the floating button (📝) to enable the script.
2. Spawn: Tap anywhere on the image to create the Note Box.
3. Adjust: Drag the box or its corners to fit the text bubble.
- NW / SE: Resize the box.
- SW / NE: Move the box.
Tip. Touch areas extend outward so your finger doesn't block the view.
4. Edit: Type the translation directly into the text field and toggle tags (e.g., Translated) if needed.
5. Save: Tap the Check (✔) button. The note and tags will be saved automatically, and the page will reload.
Note: Long-press the floating button to move it up or down.
Hey there. First of all thanks for making this script. Unfortunately tho it isn't working on my end. Every time I tap anywhere on the image, all it says is "Cancelled" and no note boxes were made.
Andrecnuuy said in forum #433262:
Asset Organizer
Just as the name suggest it helps you organize your asset by assigning their artist tag (if available) to each asset. This comes with a search bar along with unlimited pages support (thanks Mango 2 with unlimited paginator works, for helping me (gemini) figuring out how to load more pages)
Andrecnuuy said in forum #433397:
Now it also have the character and copyright of an asset (if it's available) to each asset.
19/4/2026 update:
Okay new update, now it has the ability to detect duplicates among other small things. For more details read read the guide I've written inside the script. Basically just forgot the old version and use this instead
22/4/2026 update:
- Fixed the thing where it's having a hard time differentiating 1up and lower res category. Though the solution was kinda annoying to work with, just read into the guide
- Now can detect AI and R18 tagged artworks, again only if it's tagged from the source
- Other small ui changes..
24/4/2026 update
- Fixing me forgetting to add "AIイラスト" and many other AI-generated tag othername for ai tag detection
26/4/2026 update
- Adding small little feature to clear cache for assets individually so if the script break on them you can just do a scan again
27/4/2026 update
- Added some small little quality of life update and sliming out the loc, as in making it slimmer
And also updated modified hide upload to support this script
[Install Hide Upload]
Updated by Andrecnuuy
Fhtagn said in forum #434294:
Hey there. First of all thanks for making this script. Unfortunately tho it isn't working on my end. Every time I tap anywhere on the image, all it says is "Cancelled" and no note boxes were made.
Hi. I just pushed v2.5 fixing the tap-to-create regression from v2.3. Please re-install and try again.
Thanks for the report!
AkaringoP said in forum #434363:
Hi. I just pushed v2.5 fixing the tap-to-create regression from v2.3. Please re-install and try again.
Thanks for the report!👍
It works now. Thank you so much!
Although, will resizing/moving existing notes be possible in the future?
Fhtagn said in forum #434384:
It works now. Thank you so much!
Although, will resizing/moving existing notes be possible in the future?
I'll check it later.
BrokenEagle98 said in forum #136251:
The following will make maintaining bookmarks on Danbooru easier, as it removes the trailing search parameters thereby leaving a clean URL to bookmark. Use the Bookmarklet if it's only needed occasionally, or the Userscript if it's to be used all the time. (ref forum #136183)
love this script, but the query selector breaks the comments page due to the way that page is laid out (each comment group is a .post-preview and the script selects the links of the comment ui and post tags). changing the selector as such seems to fix it from my quick testing:
$(".post-preview:has(>.post-preview-container) a.post-preview-link").each((i,entry)=>{
entry.href = entry.pathname;
});edit: i realized there was another issue with the post voting widget being broken, so i've updated the selector to fix that too.
Updated by wingdings
