Add labels to icons and add 'Party Trick'

This commit is contained in:
Bad Manners 2025-01-02 11:23:24 -03:00
parent 9569420386
commit 477ef638cc
Signed by: badmanners
GPG key ID: 8C88292CCB075609
12 changed files with 581 additions and 191 deletions

519
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "gallery.badmanners.xyz",
"version": "1.14.0",
"version": "1.15.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "gallery.badmanners.xyz",
"version": "1.14.0",
"version": "1.15.0",
"hasInstallScript": true,
"dependencies": {
"@astrojs/alpinejs": "^0.4.0",
@ -703,6 +703,22 @@
"node": ">=12"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
"integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.21.5",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
@ -2198,14 +2214,14 @@
}
},
"node_modules/astro": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/astro/-/astro-5.0.1.tgz",
"integrity": "sha512-7XzFq3eFdSkeT/aCNealVv4klwmKoOYb6LZymbyZQrdUA9vEoUCKFcujVo4YbJJ8WXyEm515ZHPCxHTdDneEug==",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/astro/-/astro-5.1.2.tgz",
"integrity": "sha512-+U5lXPEJZ6cQx0botGbPhzN6XGWRgDtXgy/RUkpTmUj18LW6pbzYo0O0k3hFWOazlI039bZ+4P2e/oSNlKzm0Q==",
"license": "MIT",
"dependencies": {
"@astrojs/compiler": "^2.10.3",
"@astrojs/internal-helpers": "0.4.2",
"@astrojs/markdown-remark": "6.0.0",
"@astrojs/markdown-remark": "6.0.1",
"@astrojs/telemetry": "3.2.0",
"@oslojs/encoding": "^1.1.0",
"@rollup/pluginutils": "^5.1.3",
@ -2251,8 +2267,9 @@
"tsconfck": "^3.1.4",
"ultrahtml": "^1.5.3",
"unist-util-visit": "^5.0.0",
"unstorage": "^1.14.0",
"vfile": "^6.0.3",
"vite": "^6.0.1",
"vite": "^6.0.5",
"vitefu": "^1.0.4",
"which-pm": "^3.0.0",
"xxhash-wasm": "^1.1.0",
@ -2279,9 +2296,9 @@
"link": true
},
"node_modules/astro/node_modules/@astrojs/markdown-remark": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.0.0.tgz",
"integrity": "sha512-Tabo7xM44Pz2Yf9qpdaCCgxRmtaypi2YCinqTUNefDrWUa+OyKW62OuNeCaGwNh/ys+QAd9FUWN5/3HgPWjP4Q==",
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.0.1.tgz",
"integrity": "sha512-CTSYijj25NfxgZi15TU3CwPwgyD1/7yA3FcdcNmB9p94nydupiUbrIiq3IqeTp2m5kCVzxbPZeC7fTwEOaNyGw==",
"license": "MIT",
"dependencies": {
"@astrojs/prism": "3.2.0",
@ -2792,6 +2809,15 @@
"integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==",
"license": "ISC"
},
"node_modules/consola": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/consola/-/consola-3.3.3.tgz",
"integrity": "sha512-Qil5KwghMzlqd51UXM0b6fyaGHtOC22scxrwrz4A2882LyUMwQjnvaedN1HAeXzphspQ6CpHkzMAWxBTUruDLg==",
"license": "MIT",
"engines": {
"node": "^14.18.0 || >=16.10.0"
}
},
"node_modules/cookie": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
@ -2801,6 +2827,12 @@
"node": ">= 0.6"
}
},
"node_modules/cookie-es": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz",
"integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==",
"license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@ -2815,6 +2847,15 @@
"node": ">= 8"
}
},
"node_modules/crossws": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.1.tgz",
"integrity": "sha512-HsZgeVYaG+b5zA+9PbIPGq4+J/CJynJuearykPsXx4V/eMhyQ5EDVg3Ak2FBZtVXCiOLu/U7IiwDHTr9MA+IKw==",
"license": "MIT",
"dependencies": {
"uncrypto": "^0.1.3"
}
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@ -2866,6 +2907,12 @@
"node": ">=0.10.0"
}
},
"node_modules/defu": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
"integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
"license": "MIT"
},
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
@ -2875,6 +2922,12 @@
"node": ">=6"
}
},
"node_modules/destr": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/destr/-/destr-2.0.3.tgz",
"integrity": "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==",
"license": "MIT"
},
"node_modules/detect-libc": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
@ -3544,6 +3597,24 @@
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"license": "ISC"
},
"node_modules/h3": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/h3/-/h3-1.13.0.tgz",
"integrity": "sha512-vFEAu/yf8UMUcB4s43OaDaigcqpQd14yanmOsn+NcRX3/guSKncyE2rOYhq8RIchgJrPSs/QiIddnTTR1ddiAg==",
"license": "MIT",
"dependencies": {
"cookie-es": "^1.2.2",
"crossws": ">=0.2.0 <0.4.0",
"defu": "^6.1.4",
"destr": "^2.0.3",
"iron-webcrypto": "^1.2.1",
"ohash": "^1.1.4",
"radix3": "^1.1.2",
"ufo": "^1.5.4",
"uncrypto": "^0.1.3",
"unenv": "^1.10.0"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@ -3860,6 +3931,15 @@
"integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
"license": "MIT"
},
"node_modules/iron-webcrypto": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz",
"integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/brc-dd"
}
},
"node_modules/is-alphabetical": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
@ -5346,6 +5426,18 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/mime": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
"integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
@ -5442,6 +5534,12 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/node-fetch-native": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz",
"integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==",
"license": "MIT"
},
"node_modules/node-releases": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
@ -5484,6 +5582,23 @@
"node": ">= 6"
}
},
"node_modules/ofetch": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.4.1.tgz",
"integrity": "sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==",
"license": "MIT",
"dependencies": {
"destr": "^2.0.3",
"node-fetch-native": "^1.6.4",
"ufo": "^1.5.4"
}
},
"node_modules/ohash": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz",
"integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==",
"license": "MIT"
},
"node_modules/oniguruma-to-es": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-0.7.0.tgz",
@ -5704,6 +5819,12 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/pathe": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
"integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@ -6099,6 +6220,12 @@
],
"license": "MIT"
},
"node_modules/radix3": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz",
"integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==",
"license": "MIT"
},
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@ -7701,12 +7828,24 @@
"semver": "^7.3.8"
}
},
"node_modules/ufo": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz",
"integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==",
"license": "MIT"
},
"node_modules/ultrahtml": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.5.3.tgz",
"integrity": "sha512-GykOvZwgDWZlTQMtp5jrD4BVL+gNn2NVlVafjcFUJ7taY20tqYdwdoWBFy6GBJsNTZe1GkGPkSl5knQAjtgceg==",
"license": "MIT"
},
"node_modules/uncrypto": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz",
"integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==",
"license": "MIT"
},
"node_modules/undici-types": {
"version": "6.20.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
@ -7714,6 +7853,19 @@
"devOptional": true,
"license": "MIT"
},
"node_modules/unenv": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/unenv/-/unenv-1.10.0.tgz",
"integrity": "sha512-wY5bskBQFL9n3Eca5XnhH6KbUo/tfvkwm9OpcdCvLaeA7piBNbavbOKJySEwQ1V0RH6HvNlSAFRTpvTqgKRQXQ==",
"license": "MIT",
"dependencies": {
"consola": "^3.2.3",
"defu": "^6.1.4",
"mime": "^3.0.0",
"node-fetch-native": "^1.6.4",
"pathe": "^1.1.2"
}
},
"node_modules/unified": {
"version": "11.0.5",
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
@ -7869,6 +8021,146 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/unstorage": {
"version": "1.14.4",
"resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.14.4.tgz",
"integrity": "sha512-1SYeamwuYeQJtJ/USE1x4l17LkmQBzg7deBJ+U9qOBoHo15d1cDxG4jM31zKRgF7pG0kirZy4wVMX6WL6Zoscg==",
"license": "MIT",
"dependencies": {
"anymatch": "^3.1.3",
"chokidar": "^3.6.0",
"destr": "^2.0.3",
"h3": "^1.13.0",
"lru-cache": "^10.4.3",
"node-fetch-native": "^1.6.4",
"ofetch": "^1.4.1",
"ufo": "^1.5.4"
},
"peerDependencies": {
"@azure/app-configuration": "^1.8.0",
"@azure/cosmos": "^4.2.0",
"@azure/data-tables": "^13.3.0",
"@azure/identity": "^4.5.0",
"@azure/keyvault-secrets": "^4.9.0",
"@azure/storage-blob": "^12.26.0",
"@capacitor/preferences": "^6.0.3",
"@deno/kv": ">=0.8.4",
"@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0",
"@planetscale/database": "^1.19.0",
"@upstash/redis": "^1.34.3",
"@vercel/blob": ">=0.27.0",
"@vercel/kv": "^1.0.1",
"aws4fetch": "^1.0.20",
"db0": ">=0.2.1",
"idb-keyval": "^6.2.1",
"ioredis": "^5.4.2",
"uploadthing": "^7.4.1"
},
"peerDependenciesMeta": {
"@azure/app-configuration": {
"optional": true
},
"@azure/cosmos": {
"optional": true
},
"@azure/data-tables": {
"optional": true
},
"@azure/identity": {
"optional": true
},
"@azure/keyvault-secrets": {
"optional": true
},
"@azure/storage-blob": {
"optional": true
},
"@capacitor/preferences": {
"optional": true
},
"@deno/kv": {
"optional": true
},
"@netlify/blobs": {
"optional": true
},
"@planetscale/database": {
"optional": true
},
"@upstash/redis": {
"optional": true
},
"@vercel/blob": {
"optional": true
},
"@vercel/kv": {
"optional": true
},
"aws4fetch": {
"optional": true
},
"db0": {
"optional": true
},
"idb-keyval": {
"optional": true
},
"ioredis": {
"optional": true
},
"uploadthing": {
"optional": true
}
}
},
"node_modules/unstorage/node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"license": "MIT",
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
},
"engines": {
"node": ">= 8.10.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"node_modules/unstorage/node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/unstorage/node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"license": "MIT",
"dependencies": {
"picomatch": "^2.2.1"
},
"engines": {
"node": ">=8.10.0"
}
},
"node_modules/update-browserslist-db": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
@ -7948,12 +8240,12 @@
}
},
"node_modules/vite": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.0.2.tgz",
"integrity": "sha512-XdQ+VsY2tJpBsKGs0wf3U/+azx8BBpYRHFAyKm5VeEZNOJZRB63q7Sc8Iup3k0TrN3KO6QgyzFf+opSbfY1y0g==",
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.0.6.tgz",
"integrity": "sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ==",
"license": "MIT",
"dependencies": {
"esbuild": "^0.24.0",
"esbuild": "^0.24.2",
"postcss": "^8.4.49",
"rollup": "^4.23.0"
},
@ -8019,9 +8311,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/aix-ppc64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz",
"integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
"integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
"cpu": [
"ppc64"
],
@ -8035,9 +8327,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/android-arm": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz",
"integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
"integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
"cpu": [
"arm"
],
@ -8051,9 +8343,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/android-arm64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz",
"integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
"integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
"cpu": [
"arm64"
],
@ -8067,9 +8359,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/android-x64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz",
"integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
"integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
"cpu": [
"x64"
],
@ -8083,9 +8375,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/darwin-arm64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz",
"integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
"integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
"cpu": [
"arm64"
],
@ -8099,9 +8391,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/darwin-x64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz",
"integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
"integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
"cpu": [
"x64"
],
@ -8115,9 +8407,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/freebsd-arm64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz",
"integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
"integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
"cpu": [
"arm64"
],
@ -8131,9 +8423,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/freebsd-x64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz",
"integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
"integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
"cpu": [
"x64"
],
@ -8147,9 +8439,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/linux-arm": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz",
"integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
"integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
"cpu": [
"arm"
],
@ -8163,9 +8455,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/linux-arm64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz",
"integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
"integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
"cpu": [
"arm64"
],
@ -8179,9 +8471,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/linux-ia32": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz",
"integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
"integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
"cpu": [
"ia32"
],
@ -8195,9 +8487,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/linux-loong64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz",
"integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
"integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
"cpu": [
"loong64"
],
@ -8211,9 +8503,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/linux-mips64el": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz",
"integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
"integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
"cpu": [
"mips64el"
],
@ -8227,9 +8519,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/linux-ppc64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz",
"integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
"integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
"cpu": [
"ppc64"
],
@ -8243,9 +8535,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/linux-riscv64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz",
"integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
"integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
"cpu": [
"riscv64"
],
@ -8259,9 +8551,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/linux-s390x": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz",
"integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
"integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
"cpu": [
"s390x"
],
@ -8275,9 +8567,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/linux-x64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz",
"integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
"integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
"cpu": [
"x64"
],
@ -8291,9 +8583,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/netbsd-x64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz",
"integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
"integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
"cpu": [
"x64"
],
@ -8307,9 +8599,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/openbsd-arm64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz",
"integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
"integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
"cpu": [
"arm64"
],
@ -8323,9 +8615,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/openbsd-x64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz",
"integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
"integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
"cpu": [
"x64"
],
@ -8339,9 +8631,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/sunos-x64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz",
"integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
"integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
"cpu": [
"x64"
],
@ -8355,9 +8647,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/win32-arm64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz",
"integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
"integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
"cpu": [
"arm64"
],
@ -8371,9 +8663,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/win32-ia32": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz",
"integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
"integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
"cpu": [
"ia32"
],
@ -8387,9 +8679,9 @@
}
},
"node_modules/vite/node_modules/@esbuild/win32-x64": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz",
"integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
"integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
"cpu": [
"x64"
],
@ -8403,9 +8695,9 @@
}
},
"node_modules/vite/node_modules/esbuild": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz",
"integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==",
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
"integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
@ -8415,30 +8707,31 @@
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.24.0",
"@esbuild/android-arm": "0.24.0",
"@esbuild/android-arm64": "0.24.0",
"@esbuild/android-x64": "0.24.0",
"@esbuild/darwin-arm64": "0.24.0",
"@esbuild/darwin-x64": "0.24.0",
"@esbuild/freebsd-arm64": "0.24.0",
"@esbuild/freebsd-x64": "0.24.0",
"@esbuild/linux-arm": "0.24.0",
"@esbuild/linux-arm64": "0.24.0",
"@esbuild/linux-ia32": "0.24.0",
"@esbuild/linux-loong64": "0.24.0",
"@esbuild/linux-mips64el": "0.24.0",
"@esbuild/linux-ppc64": "0.24.0",
"@esbuild/linux-riscv64": "0.24.0",
"@esbuild/linux-s390x": "0.24.0",
"@esbuild/linux-x64": "0.24.0",
"@esbuild/netbsd-x64": "0.24.0",
"@esbuild/openbsd-arm64": "0.24.0",
"@esbuild/openbsd-x64": "0.24.0",
"@esbuild/sunos-x64": "0.24.0",
"@esbuild/win32-arm64": "0.24.0",
"@esbuild/win32-ia32": "0.24.0",
"@esbuild/win32-x64": "0.24.0"
"@esbuild/aix-ppc64": "0.24.2",
"@esbuild/android-arm": "0.24.2",
"@esbuild/android-arm64": "0.24.2",
"@esbuild/android-x64": "0.24.2",
"@esbuild/darwin-arm64": "0.24.2",
"@esbuild/darwin-x64": "0.24.2",
"@esbuild/freebsd-arm64": "0.24.2",
"@esbuild/freebsd-x64": "0.24.2",
"@esbuild/linux-arm": "0.24.2",
"@esbuild/linux-arm64": "0.24.2",
"@esbuild/linux-ia32": "0.24.2",
"@esbuild/linux-loong64": "0.24.2",
"@esbuild/linux-mips64el": "0.24.2",
"@esbuild/linux-ppc64": "0.24.2",
"@esbuild/linux-riscv64": "0.24.2",
"@esbuild/linux-s390x": "0.24.2",
"@esbuild/linux-x64": "0.24.2",
"@esbuild/netbsd-arm64": "0.24.2",
"@esbuild/netbsd-x64": "0.24.2",
"@esbuild/openbsd-arm64": "0.24.2",
"@esbuild/openbsd-x64": "0.24.2",
"@esbuild/sunos-x64": "0.24.2",
"@esbuild/win32-arm64": "0.24.2",
"@esbuild/win32-ia32": "0.24.2",
"@esbuild/win32-x64": "0.24.2"
}
},
"node_modules/vitefu": {

View file

@ -1,7 +1,7 @@
{
"name": "gallery.badmanners.xyz",
"type": "module",
"version": "1.14.0",
"version": "1.15.0",
"scripts": {
"postinstall": "astro sync",
"dev": "astro dev",

View file

@ -83,7 +83,7 @@ async function exportStory(id: string, options: { outputDir: string }) {
lines.on("close", reject);
});
console.log(`Astro listening on ${astroURL}`);
const response = await fetchRetry(new URL(`api/healthcheck`, astroURL), { retries: 5, retryDelay: 2000 });
const response = await fetchRetry(new URL(`/api/healthcheck`, astroURL), { retries: 5, retryDelay: 2000 });
if (!response.ok) {
throw new Error(response.statusText);
}
@ -103,7 +103,11 @@ async function exportStory(id: string, options: { outputDir: string }) {
let storyText = "";
try {
console.log("Getting data from Astro...");
const response = await fetch(new URL(`api/export-story/${id}`, astroURL));
const response = await fetchRetry(new URL(`/api/export-story/${id}`, astroURL), {
retries: 5,
retryDelay: 1000,
retryOn: [404],
});
if (!response.ok) {
throw new Error(`Failed to reach export-story API (status code ${response.status})`);
}
@ -129,7 +133,7 @@ async function exportStory(id: string, options: { outputDir: string }) {
.replace(/\?(&?[a-z][a-zA-Z0-9_-]+=[a-zA-Z0-9_-]*)*$/, "");
await copyFile(thumbnailPath, join(outputDir, `thumbnail${thumbnailPath.match(/\.[^.]+$/)![0]}`));
} else {
const thumbnail = await fetchRetry(data.thumbnail, { retries: 2, retryDelay: 10000 });
const thumbnail = await fetchRetry(data.thumbnail, { retries: 2, retryDelay: 2000 });
if (!thumbnail.ok) {
throw new Error("Failed to get thumbnail");
}

Binary file not shown.

After

(image error) Size: 17 KiB

View file

@ -23,66 +23,41 @@ const isVisible = eka || furaffinity || inkbunny || sofurry || weasyl;
<ul id="external-posts" class="flex flex-wrap justify-around">
{eka ? (
<li class="min-w-12 grow">
<a
class="u-syndication text-link w-full"
href={eka.link}
target="_blank"
aria-label={t(lang, "published_content/syndication_eka")}
>
<a class="u-syndication text-link flex w-full flex-col" href={eka.link} target="_blank">
<IconEkasPortal class="mx-auto" width="2rem" height="2rem" />
<span class="sr-only">{t(lang, "published_content/syndication_eka")}</span>
<span class="text-center text-xs">{t(lang, "published_content/syndication_eka")}</span>
</a>
</li>
) : null}
{furaffinity ? (
<li class="min-w-12 grow">
<a
class="u-syndication text-link w-full"
href={furaffinity.link}
target="_blank"
aria-label={t(lang, "published_content/syndication_furaffinity")}
>
<a class="u-syndication text-link flex w-full flex-col" href={furaffinity.link} target="_blank">
<IconFurAffinity class="mx-auto" width="2rem" height="2rem" />
<span class="sr-only">{t(lang, "published_content/syndication_furaffinity")}</span>
<span class="text-center text-xs">{t(lang, "published_content/syndication_furaffinity")}</span>
</a>
</li>
) : null}
{inkbunny ? (
<li class="min-w-12 grow">
<a
class="u-syndication text-link w-full"
href={inkbunny.link}
target="_blank"
aria-label={t(lang, "published_content/syndication_inkbunny")}
>
<a class="u-syndication text-link flex w-full flex-col" href={inkbunny.link} target="_blank">
<IconInkbunny class="mx-auto" width="2rem" height="2rem" />
<span class="sr-only">{t(lang, "published_content/syndication_inkbunny")}</span>
<span class="text-center text-xs">{t(lang, "published_content/syndication_inkbunny")}</span>
</a>
</li>
) : null}
{sofurry ? (
<li class="min-w-12 grow">
<a
class="u-syndication text-link w-full"
href={sofurry.link}
target="_blank"
aria-label={t(lang, "published_content/syndication_sofurry")}
>
<a class="u-syndication text-link flex w-full flex-col" href={sofurry.link} target="_blank">
<IconSoFurry class="mx-auto" width="2rem" height="2rem" />
<span class="sr-only">{t(lang, "published_content/syndication_sofurry")}</span>
<span class="text-center text-xs">{t(lang, "published_content/syndication_sofurry")}</span>
</a>
</li>
) : null}
{weasyl ? (
<li class="min-w-12 grow">
<a
class="u-syndication text-link w-full"
href={weasyl.link}
target="_blank"
aria-label={t(lang, "published_content/syndication_weasyl")}
>
<a class="u-syndication text-link flex w-full flex-col" href={weasyl.link} target="_blank">
<IconWeasyl class="mx-auto" width="2rem" height="2rem" />
<span class="sr-only">{t(lang, "published_content/syndication_weasyl")}</span>
<span class="text-center text-xs">{t(lang, "published_content/syndication_weasyl")}</span>
</a>
</li>
) : null}
@ -91,15 +66,3 @@ const isVisible = eka || furaffinity || inkbunny || sofurry || weasyl;
</section>
) : null
}
<script>
import tippy from "tippy.js";
import "tippy.js/dist/tippy.css";
const clipboardItems = document.querySelectorAll<HTMLElement>("ul#external-posts a[aria-label]");
tippy(clipboardItems, {
content: (el) => (el as HTMLElement).getAttribute("aria-label")!,
theme: "bm",
});
</script>

View file

@ -0,0 +1,130 @@
---
title: Party Trick
pubDate: 2025-01-02
isAgeRestricted: true
authors: bad-manners
wordCount: 1800
contentWarning: >
Contains: Oral vore (safe vore/endosoma), with willing male anthro jaguar predator, and willing anthro opossum prey. Also includes size difference, regurgitation, public vore, and alcohol.
thumbnail: /src/assets/thumbnails/stories/bm_ff_18_party_trick.png
description: |
Max receives an unusual request from a friend.
Happy new year! Here's a short story for the start of the year. I intend to make and share plenty of new stuff throughout 2025 as well, although progress may be slow due to me starting out a new job. We'll see!
posts:
eka: https://aryion.com/g4/view/1087736
furaffinity: https://www.furaffinity.net/view/59381567/
inkbunny: https://inkbunny.net/s/3515191
sofurry: https://www.sofurry.com/view/2216338
sofurrybeta: https://sofurrybeta.com/s/ZmM3vgW1
weasyl: https://www.weasyl.com/~badmanners/submissions/2454699/party-trick
bluesky: https://bsky.app/profile/badmanners.xyz/post/3lerb6lpxw22q
mastodon: https://meow.social/@BadManners/113759163137942723
tags:
- oral vore
- anthro predator
- anthro prey
- male predator
- ambiguous gender prey
- willing predator
- willing prey
- size difference
- public vore
- flash fiction
---
"...But then I told him, 'I thought you were against that sort of thing!'"
The circle of people laughed at Max's punchline, and the jaguar sipped from his beer can. After gulping, a small burp came from his lips, but the other guests in the party didn't seem to notice.
"Then he said, 'What the fuck do you mean'?" Max used an absurdly low register to mock the voice, while not noticing the cat approaching him from behind.
"Pssh... Maax..." The tabby cat whispered, nearly losing his balance from inebriation, but he was too quiet for the spotted feline to pay him any attention.
"And you should've seen the look on his wife's face... She went red as a peach!"
"Heey M-OOURP-Maxx..."
The burp _was_ loud enough to make the jaguar turn his neck. "Oh, hey Cam." He scanned the tabby, who certainly looked way more drunk than half-an-hour ago. Max took a step back to put some space between them, and that's when he noticed Cam's arms. "...Who is that you're carrying?"
"Ohh hic!, this?" He gently lifted the third-sized anthro, wearing a heavy hoodie that made it hard to tell their species apart. "Sooo I mighta told deese guys about dat trick you hic did in the last party we gone to, and dey wanna see it~..."
"Cam... But that was I-I was too drunk! I shouldn't have"
"Baaaah!" The tabby bleated. "But it was fine! Like you said, it's totally safe. C'mooooon~..."
Max gave a forced smile, glancing at the rest of his group all of them seemed confused. Then he looked at the small person that Cam was carrying they looked like an opossum, underneath the bulky clothes. 'Goddammit', he thought to himself, 'he _knows_ I have a soft spot for opossums...'
"...Fine, but you owe me." He blurted out before he even processed his own words.
Cam let out an excited squeal, raising the opossum to his taller friend. It was normally considered bad Manners to manhandle smaller anthros like this, but there wasn't any other way to go about it. After setting his beer aside, he managed to get a closer look, and they were definitely an opossum damn it! , but it was hard to tell their gender because of their bulky clothes. Not like it mattered, anyway.
"You probably want to ditch your clothes first." The jaguar told them.
They blushed and shrunk even more inside of their black hoodie. "N-No, it's fine..."
"You sure? I'm not paying to get them cleaned afterwards."
Gosh did they look cute with those beady eyes and bashful nodding. His maw was already watering.
Lifting them by the scuff of their hoodie, Max tried his best to ignore the insurmountable gazes set on him which only seemed to increase over time. He closed his eyes, letting the background house music drown out any whispers.
The jaguar opened his maw toward the ceiling, his hot breath likely tickling the opossum's legs. There was no reaction from the marsupial, who was limp in his grip. Maybe they were playing dead, or trying to contain their excitement like Max was.
He gently lowered them, until their feet were planted against his barbed tongue. Such a sweet, earthy flavor... Max already knew what those paws looked like cute pink digits sticking out from a fingerless glove of black fur , so he kept his eyes closed and let his imagination do the rest.
His jaws were wide enough to scoop the smaller opossum in one go, but Max was intent on savoring what little time they'd be between his menacing-looking teeth. He planted their butt on his tongue, legs pointing towards the back of his maw, enjoying the flavor and aroma satiating his predatorial side. The murmurs and gasps around Max seemed to intensify as did Cam's silly giggling , but he stood proud and erect as he continued to perform his 'trick'.
With the rat-like tail settling on his tongue, the jaguar wiggled his muscle, feeling the weight of the anthro who was a fraction of his size. More of that warmth seeped into his tastebuds as he, in turn, breathed all over their front. Perhaps some of the other guests might've thought that this was his trick using his maw as a chair , but his drunk friend's growing excitement indicated otherwise.
Planting his palm against their back, Max craned his neck further, far enough for the opossum to begin slipping forward. He opened one eye, just to make sure that his prey wasn't too close to the ceiling, and he saw the most adorable look of thrill on that blushing white face. Such a willing plaything... He had to resist the temptation and close his eye again, otherwise he might end up claiming them all in one gulp.
His throat was kept intentionally tight, wet flesh parting ever so slightly at the nudging of the marsupial's paws. But before they entered his gullet, Max took a deep breath it'd be his last one in a while. Now, the walls were looser, and one subdued shove planted those extremities inside, drawing a gasp from his prey.
Saliva dribbled out the corners of his mouth, pushed aside by the living snack slowly slipping down. As his neck started to bulge out, the jaguar couldn't help but purr at the feeling of those little claws tickling his esophagus. He knew that the opossum would look even cuter padding out his belly, which wouldn't be long from now. After all, Max was still holding his breath, to avoid choking on the bite-sized anthro.
They fit between his jaws without issue, until their hooded head finally lied on his tongue. He moved his paw away, feeling that large bulge in his spotted neck thanks to the marsupial's hips slipping down. Then, he lowered his head, keeping his maw almost shut as his palate pressed down on the marsupial's face, slowing them down just a tiny bit. Enough time for his paws to reach his shirt, undoing the buttons on the lower half.
Once his lungs started to burn, he gave one strong 'gulp!'. It was more than enough to force the opossum into his throat, sending down that immense and writhing swelling behind his tan fur. His jaws, snapping shut before the marsupial could let out a peep, relaxed as Max rubbed his chin. That pleasant weight quickly shifted down his chest, and the jaguar gasped for air once his prey stopped dislodging his lungs.
He opened his eyes as he faced down, just in time to see his spotted belly grow. His toned abs gave way to a slug-like mass arriving from his chest, held tight by the firm walls despite the occasional movements on its own.
"Fuck yeaaaaah! Woo!" Cam shouted out and cheered, inviting the uncomfortably quiet crowd around them to do the same.
Some awkwardly clapped and stared, Max noticed, although most of them were awestruck by his trick. He simply smiled proudly as he reached for his beer can, taking a swig to wash down some of the fur stuck to his throat. The drink was already warm, so it likely wouldn't bother his new occupant on the way down. Regardless, they'd have to get accustomed to the stuff already stewing in his gut.
"See, M-Max? Everyone liked dat!" The tabby blurted out, his eyes transfixed on the bulge that gurgled with every move. "Especially dat little one, I think..."
The jaguar flashed his teeth. "Would you like to confirm that?"
"I-I"
Before Cam could conceal his embarrassment, Max reached his arm around his friend's neck, putting him in a headlock and pressing his nose right against his midriff.
"So," the larger feline teased, "about that favor you owe me. You better start rubbing my belly, since I don't want to feel sore by the time I cough them out."
Still blushing, Cam's only response was to stick his tongue out. His paws moved to the vaguely anthro-shaped bulge, more than happy to oblige.
Max sighed, enjoying the feeling of his stomach walls being squeezed from both sides. Apparently, most of the guests had turned away, off to enjoy whatever else the party had to offer. Perhaps he should do the same.
"Sorry about that interruption," he said unabashed to the circle of people staring at him, still holding Cam against his groaning gut. "Now, where was I...?"
---
Tight... damp... squelchy... Though the thrumming heartbeat served as a biological clock, the opossum had lost track of time. How long had it been, hours? Minutes? The party outside seemed so distant in here.
They were about to doze off in the jaguar's acrid chamber... Until they suddenly started shifting up, with light finally reaching their eyes again. And the first thing they saw was a towel.
Max was careful to regurgitate them, so they wouldn't slip away or hit anything hard. From his jaws, he slowly deposited the drenched anthro on the towel he held, quickly staining the white cloth. His released prey noticed that they were in a restroom. He waited until all of that pink tail had slipped out from his maw before he decided to speak.
"Hey there, sorry about the mess. The party is winding down and your friend told me you were her ride home, so...time to let you out and all that. How was it?"
The opossum wrapped the towel tighter around their shoulders, intentionally looking away from the big feline. "...I-It was okay."
Max chuckled, expecting anything but that answer. "Ouch! Well, I'll leave you to dry yourself. Oh, but first," he reached into his shirt pocket and pulled out a card, "if you ever want to do it again even though it was 'just okay'. Just call me on that number right there."
The hoodie-wearing marsupial took his card between their fingers, inspecting the laminated paper as drool and gunk dribbled onto it. 'MAX SIMMONS Oncologist', it read. It was funny to receive a business card from a guy after just having been devoured by him. And they wouldn't have guessed that he was a doctor.
Before the opossum could speak, Max closed the door behind him, leaving them alone in the restroom. They never told him their name... Oh, well. They reached into their hoodie's pocket, placing the card there and fishing out a slimy phone. The screen unlocked to the gallery app displaying lots of pictures of the jaguar's tight pink insides.
What a party this had been...

View file

@ -27,6 +27,7 @@ tags:
- willing prey
- unwilling prey
- same size
- public vore
- flash fiction
---

View file

@ -35,6 +35,7 @@ tags:
- willing prey
- macro predator
- size difference
- public vore
- gay sex
- transformation
series: the-lost-of-the-marshes

View file

@ -59,9 +59,13 @@
description: Scenarios where at least one of the predators is a woman and/or female-presenting.
- name: non-binary predator
description: Scenarios where at least one of the predators has a non-binary gender expression, be they genderless/agender, intersex, androgynous, gender-fluid, non-binary and/or non-binary-presenting, et cetera, regardless of undergoing or having undergone gender transition or not.
- name: { en: ambiguous gender predator, tok: jan pi wawa mute li meli anu mije }
- name:
{
en: ambiguous gender predator,
tok: jan pi wawa mute li meli anu mije,
}
description:
en: Scenarios where the gender at least one of the predators is left ambiguous.
en: Scenarios where the gender of at least one of the predators is left ambiguous.
tok: jan pi moku musi pi wawa mute la toki tan meli anu mije anu tonsi li lon ala.
- name: male prey
description: Scenarios where at least one of the prey is a man and/or male-presenting.
@ -75,9 +79,10 @@
- female prey
- name: non-binary prey
description: Scenarios where at least one of the predators has a non-binary gender expression, be they genderless/agender, intersex, androgynous, gender-fluid, non-binary and/or non-binary-presenting, et cetera, regardless of undergoing or having undergone gender transition or not.
- name: { en: ambiguous gender prey, tok: jan pi wawa lili li meli anu mije }
- name:
{ en: ambiguous gender prey, tok: jan pi wawa lili li meli anu mije }
description:
en: Scenarios where the gender at least one of the predators is left ambiguous.
en: Scenarios where the gender of at least one of the prey is left ambiguous.
tok: jan pi moku musi pi wawa lili la toki tan meli anu mije anu tonsi li lon ala.
- id: relative-size
category: Relative size
@ -113,7 +118,8 @@
description: Scenarios where at least one of the prey participates in vore willingly.
- name: semi-willing prey
description: Scenarios where the willingness of at least one of the prey might be partial, oscillating between willing and unwilling, somewhere in-between, or ambiguous.
- name: { en: unwilling prey, tok: jan pi wawa lili li wile ala e moku musi }
- name:
{ en: unwilling prey, tok: jan pi wawa lili li wile ala e moku musi }
description:
en: Scenarios where at least one of the prey participates in vore unwillingly.
tok: jan pi moku musi pi wawa lili la jan li wile ala e moku musi.
@ -176,6 +182,8 @@
- role reversal
- name: multiple prey
description: Scenarios where one predator consumes multiple prey at once.
- name: public vore
description: Scenarios where vore is performed in public.
- name: messy stomach
description: Scenarios where a prey visits a messy stomach, usually with semi-digested food inside.
related:
@ -264,7 +272,7 @@
en: Short-format stories with no more than 2,500 words.
tok: lipu li jo e nanpa nimi lili.
- name: toki pona
description:
description:
en: Stories written in toki pona, the language of good.
tok: lipu li kepeken toki pona.
- name: behind the scenes
@ -291,4 +299,4 @@
- name: Muno
description: Content that features my character Muno, the snake.
- name: Yolk
description: Content that features <a href="https://www.furaffinity.net/user/vampire101" target="_blank" rel="nofollow">Vampire101's</a> fursona, Yolk the monkey.
description: Content that features <a href="https://www.furaffinity.net/user/vampire101" target="_blank" rel="nofollow">Vampire101's</a> fursona, Yolk the monkey.

View file

@ -68,7 +68,7 @@ const UI_STRINGS = {
},
// Shared strings for published content (stories + games)
"published_content/return_to_series": {
en: (seriesName: string) => `Return to ${seriesName}`,
en: "Return to series",
},
"published_content/go_to_description": {
en: "Go to description",

View file

@ -105,9 +105,7 @@ const thumbnail =
props.thumbnail &&
(await getImage({ src: props.thumbnail, width: props.thumbnailWidth, height: props.thumbnailHeight }));
const returnTo = series
? t(props.lang, "published_content/return_to_series", series.data.name)
: props.labelReturnTo.title;
const returnTo = series ? t(props.lang, "published_content/return_to_series") : props.labelReturnTo.title;
---
<BaseLayout pageTitle={props.title} lang={props.lang} isAgeRestricted={props.isAgeRestricted}>
@ -145,25 +143,23 @@ const returnTo = series
class="pointer-events-none absolute top-0 h-[80vh] py-2 pl-2 lg:inset-y-0 lg:h-full"
>
<div
class="pointer-events-auto sticky top-6 flex rounded-full bg-white px-1 py-1 shadow-md dark:bg-black print:hidden"
class="pointer-events-auto sticky top-6 flex flex-col rounded-xl bg-white px-1 py-1 shadow-md dark:bg-black print:hidden"
>
<a href={series ? series.data.link : props.labelReturnTo.link} class="text-link my-1 p-2" aria-label={returnTo}>
<a href={series ? series.data.link : props.labelReturnTo.link} class="text-link mx-1 flex items-center p-2">
<IconArrowBack width="1.25rem" height="1.25rem" />
<span class="ml-1 text-sm">{returnTo}</span>
</a>
<a
href="#meta"
class="text-link my-1 border-l border-stone-300 p-2 dark:border-stone-700"
aria-label={t(props.lang, "published_content/go_to_description")}
>
<a href="#meta" class="text-link mx-1 flex items-center border-t border-stone-300 p-2 dark:border-stone-700">
<IconCircleInfo width="1.25rem" height="1.25rem" />
<span class="ml-1 text-sm">{t(props.lang, "published_content/go_to_description")}</span>
</a>
<button
class="text-link my-1 border-l border-stone-300 p-2 dark:border-stone-700"
aria-label={t(props.lang, "published_content/toggle_dark_mode")}
class="text-link mx-1 flex items-center border-t border-stone-300 p-2 dark:border-stone-700"
@click="darkMode = !darkMode; localStorage.colorScheme = darkMode ? 'dark' : 'light'"
>
<IconSun width="1.25rem" height="1.25rem" class="hidden dark:block" />
<IconMoon width="1.25rem" height="1.25rem" class="block dark:hidden" />
<span class="ml-1 text-sm">{t(props.lang, "published_content/toggle_dark_mode")}</span>
</button>
</div>
</div>
@ -461,12 +457,6 @@ const returnTo = series
import tippy from "tippy.js";
import "tippy.js/dist/tippy.css";
tippy("#toolbox-buttons :is(a, button)[aria-label]", {
content: (el) => el.getAttribute("aria-label")!,
placement: "bottom",
theme: "bm",
});
const tooltipItems = document.querySelectorAll<HTMLElement>("[title][data-tooltip]");
tooltipItems.forEach((el) => el.setAttribute("data-tooltip", el.title));
tippy(tooltipItems, {

View file

@ -69,7 +69,7 @@ export const GET: APIRoute<Props, Params> = async ({ props: { story }, site }) =
: getWebsiteLinkForUser(user, exportWebsite, (user) => getUsernameForLang(user, lang));
const storyDescription = await [
story.data.description,
`*${t(lang, "story/warnings", story.data.wordCount, story.data.contentWarning)}*`,
`_${t(lang, "story/warnings", story.data.wordCount, story.data.contentWarning)}_`,
t(
lang,
"export_story/authors",