diff --git a/zefie_wtvp_minisrv/app.js b/zefie_wtvp_minisrv/app.js
index 3ac7644a..4c0da521 100644
--- a/zefie_wtvp_minisrv/app.js
+++ b/zefie_wtvp_minisrv/app.js
@@ -12,9 +12,11 @@ const {spawn} = require('child_process');
const http = require('follow-redirects').http
const https = require('follow-redirects').https
const httpx = require(classPath + "/HTTPX.js");
+const { URL } = require('url');
const net = require('net');
const crypto = require('crypto')
const CryptoJS = require('crypto-js');
+const sharp = require('sharp')
const process = require('process');
const WTVSec = require(classPath + "/WTVSec.js");
const WTVLzpf = require(classPath + "/WTVLzpf.js");
@@ -238,6 +240,8 @@ var runScriptInVM = function (script_data, user_contextObj = {}, privileged = fa
"wtvmime": wtvmime,
"http": http,
"https": https,
+ "URL": URL,
+ "sharp": sharp,
"wtvshared": wtvshared,
"zlib": zlib,
"clientShowAlert": clientShowAlert,
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook.js
index aab3991a..4a463e99 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook.js
@@ -2,7 +2,7 @@ var minisrv_service_file = true;
var files = session_data.pagestore.listScrapbook();
var dir = session_data.pagestore.scrapbookDir()
-var start = 12;
+var start = 0;
headers = `200 OK
Connection: Keep-Alive
@@ -158,14 +158,21 @@ Choose one of your saved images to view it full size.
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/add-to-scrapbook.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/add-to-scrapbook.js
new file mode 100644
index 00000000..f94497b4
--- /dev/null
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/add-to-scrapbook.js
@@ -0,0 +1,89 @@
+var minisrv_service_file = true;
+var request_is_async = true;
+
+
+function handleError(reason) {
+ var errpage = wtvshared.doErrorPage(400, reason);
+ sendToClient(socket, errpage[0], errpage[1]);
+}
+
+if (!request_headers.query.url) {
+ handleError('No URL provided');
+} else {
+ var url = request_headers.query.url;
+ function isValidImageType(contentType, url) {
+ // Check content-type header or file extension
+ if (contentType) {
+ return contentType === 'image/jpeg' || contentType == 'image/jpg' || contentType === 'image/gif';
+ }
+ return url.endsWith('.jpg') || url.endsWith('.jpeg') || url.endsWith('.gif');
+ }
+
+ try {
+ const parsedUrl = new URL(url);
+ const protocol = parsedUrl.protocol === 'https:' ? https : http;
+
+ protocol.get(url, (res) => {
+ if (res.statusCode !== 200) {
+ handleError('URL does not exist or returned status ' + res.statusCode);
+ res.resume();
+ return;
+ }
+
+ const contentType = res.headers['content-type'];
+ const contentLength = parseInt(res.headers['content-length'], 10);
+
+ if (!isValidImageType(contentType, url)) {
+ handleError('URL is not a JPEG or GIF image');
+ res.resume();
+ return;
+ }
+
+ if (contentLength && contentLength > 1024 * 1024) {
+ handleError('Image is larger than 1MB');
+ res.resume();
+ return;
+ }
+
+ let data = [];
+ let totalLength = 0;
+ res.on('data', (chunk) => {
+ totalLength += chunk.length;
+ if (totalLength > 1024 * 1024) {
+ handleError('Image is larger than 1MB');
+ res.destroy();
+ return;
+ }
+ data.push(chunk);
+ });
+
+ res.on('end', () => {
+ if (totalLength > 1024 * 1024) return;
+ data = Buffer.concat(data);
+ var id = session_data.pagestore.getFreeScrapbookID();
+ var result = session_data.pagestore.addToScrapbook(id, contentType, data);
+ if (result) {
+ var successScrapbook = new clientShowAlert({
+ 'image': minisrv_config.config.service_logo,
+ 'message': "The image has been added to your scrapbook. Would you like to view your scrapbook now?",
+ 'buttonlabel1': "No",
+ 'buttonaction1': "client:donothing",
+ 'buttonlabel2': "Yes",
+ 'buttonaction2': "wtv-author:/scrapbook",
+ }).getURL();
+ sendToClient(socket, {'Status': 302, 'Location': successScrapbook, 'wtv-visit': successScrapbook}, '');
+ } else {
+ handleError('Failed to add image to scrapbook');
+ }
+ });
+
+ res.on('error', (err) => {
+ handleError('Error downloading image');
+ });
+ }).on('error', (err) => {
+ handleError('Failed to fetch URL');
+ });
+ } catch (e) {
+ handleError(e.message);
+ }
+}
\ No newline at end of file
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/view-scrapbook-image.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/view-scrapbook-image.js
new file mode 100644
index 00000000..6e1ece60
--- /dev/null
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/view-scrapbook-image.js
@@ -0,0 +1,35 @@
+var minisrv_service_file = true;
+var request_is_async = true;
+
+function handleError(reason) {
+ var errpage = wtvshared.doErrorPage(400, reason);
+ sendToClient(socket, errpage[0], errpage[1]);
+}
+
+async function handleImage() {
+ if (!request_headers.query.id) {
+ handleError('No image ID specified');
+ } else {
+ data = session_data.pagestore.getScrapbookImage(request_headers.query.id);
+ if (!data) {
+ handleError('Image not found');
+ } else {
+ try {
+ if (request_headers.query.width) {
+ // Scale the image to the specified width without losing aspect ratio, without using wtvshared
+ const width = parseInt(request_headers.query.width, 10);
+ data = await sharp(data).resize({ width, withoutEnlargement: true }).toBuffer();
+ }
+ headers = `200 OK
+Content-Type: ${session_data.pagestore.getScrapbookImageType(request_headers.query.id)}
+Content-Length: ${data.length}`
+ sendToClient(socket, headers, data);
+ } catch (error) {
+ handleError('Error processing image');
+ console.error('Image processing error:', error);
+ }
+ }
+ }
+}
+
+handleImage();
\ No newline at end of file
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js b/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js
index ab37eacd..fca96eb5 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js
@@ -10,6 +10,7 @@ class WTVAuthor {
wtvclient = null;
pageFileExt = ".page";
pagestore_dir = null;
+ scrapbook_dir = null;
pageArr = [];
blockArr = [];
header = null;
@@ -59,16 +60,26 @@ class WTVAuthor {
if (this.pagestore_dir === null) {
// set pagestore directory local var so we don't call the function every time
var userstore_dir = this.wtvclient.getUserStoreDirectory();
- this.debug("pagestoreExists", "userstore_dir", userstore_dir)
-
// PageStore
var store_dir = "PageStore" + this.path.sep;
- this.pagestore_dir = userstore_dir + store_dir;
+ this.pagestore_dir = userstore_dir + store_dir;
}
return this.fs.existsSync(this.pagestore_dir);
}
return true;
}
+
+ scrapbookExists() {
+ if (!this.isguest) {
+ if (this.scrapbook_dir === null) {
+ var userstore_dir = this.wtvclient.getUserStoreDirectory();
+ var store_dir = "Scrapbook" + this.path.sep;
+ this.scrapbook_dir = userstore_dir + store_dir;
+ }
+ }
+ return this.fs.existsSync(this.scrapbook_dir);
+ }
+
createPagestore() {
if (this.pagestoreExists() === false) {
@@ -79,7 +90,93 @@ class WTVAuthor {
}
return false;
}
-
+
+ createScrapbook() {
+ if (this.scrapbookExists() === false) {
+ try {
+ if (!this.fs.existsSync(this.scrapbook_dir)) this.fs.mkdirSync(this.scrapbook_dir, { recursive: true });
+ return true;
+ } catch { }
+ }
+ return false
+ }
+
+ scrapbookDir() {
+ if (this.scrapbookExists() === false) {
+ this.createScrapbook();
+ }
+ return this.scrapbook_dir;
+ }
+
+ listScrapbook() {
+ if (this.scrapbookExists() === false) {
+ this.createScrapbook();
+ }
+ const files = this.fs.readdirSync(this.scrapbook_dir);
+ const filteredFiles = files.filter(file => !file.endsWith('.meta'));
+ return filteredFiles;
+ }
+
+ getFreeScrapbookID() {
+ if (this.scrapbookExists() === false) {
+ this.createScrapbook();
+ }
+ var id = 1;
+ var files = this.fs.readdirSync(this.scrapbook_dir);
+ if (files.length == 0) {
+ return id;
+ }
+ files = files.map(file => parseInt(file.substr(0, file.indexOf('.'))));
+ while (files.includes(id)) {
+ id++;
+ }
+ return id;
+ }
+
+ getScrapbookImage(id) {
+ if (this.scrapbookExists() === false) {
+ this.createScrapbook();
+ }
+ var file = this.scrapbook_dir + id;
+ if (this.fs.existsSync(file)) {
+ return this.fs.readFileSync(file);
+ }
+ return null;
+ }
+
+ getScrapbookImageType(id) {
+ if (this.scrapbookExists() === false) {
+ this.createScrapbook();
+ }
+ var file = this.scrapbook_dir + id + ".meta";
+ if (this.fs.existsSync(file)) {
+ var meta = this.fs.readFileSync(file, 'utf8');
+ try {
+ var metaData = JSON.parse(meta);
+ return metaData.contentType;
+ } catch (e) {
+ this.debug("getScrapbookImageType", "Error parsing metadata for image ID", id, e);
+ }
+ }
+ return null;
+ }
+
+ addToScrapbook(filename, contentType, data) {
+ try {
+ if (this.scrapbookExists() === false) {
+ this.createScrapbook();
+ }
+ var fileout = this.scrapbook_dir + filename;
+ var fileout_meta = this.scrapbook_dir + filename + ".meta";
+ this.fs.writeFileSync(fileout, data);
+ this.fs.writeFileSync(fileout_meta, JSON.stringify({
+ "contentType": contentType
+ }));
+ return true;
+ } catch {}
+ return false;
+ }
+
createPage(style) {
this.pagestoreExists()
var pagestorepath = this.pagestore_dir;
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVShared.js b/zefie_wtvp_minisrv/includes/classes/WTVShared.js
index f3943b18..61474cc7 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVShared.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVShared.js
@@ -703,7 +703,6 @@ class WTVShared {
return encoded.toUpperCase();
}
-
/**
* Decodes a urlencoded string into a binary buffer
* @param {string} encoded urlencoded string
diff --git a/zefie_wtvp_minisrv/package-lock.json b/zefie_wtvp_minisrv/package-lock.json
index d6d8444d..8767f855 100644
--- a/zefie_wtvp_minisrv/package-lock.json
+++ b/zefie_wtvp_minisrv/package-lock.json
@@ -6,7 +6,7 @@
"packages": {
"": {
"name": "zefie_wtvp_minisrv",
- "version": "0.9.60-pre",
+ "version": "0.9.61-pre",
"license": "GPL3",
"dependencies": {
"adm-zip": "^0.5.12",
@@ -25,6 +25,7 @@
"proxy-agent": "^6.4.0",
"rc4-crypto": "^1.5.0",
"sanitize-html": "^2.13.0",
+ "sharp": "^0.34.3",
"starttls": "^1.0.1",
"strftime": "^0.10.2",
"uuid": "^8.3.2"
@@ -37,6 +38,16 @@
"url": "https://www.patreon.com/zefie"
}
},
+ "node_modules/@emnapi/runtime": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz",
+ "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
@@ -138,6 +149,424 @@
"dev": true,
"license": "BSD-3-Clause"
},
+ "node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.3.tgz",
+ "integrity": "sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.2.0"
+ }
+ },
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.3.tgz",
+ "integrity": "sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.2.0"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.0.tgz",
+ "integrity": "sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.0.tgz",
+ "integrity": "sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.0.tgz",
+ "integrity": "sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.0.tgz",
+ "integrity": "sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.0.tgz",
+ "integrity": "sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.0.tgz",
+ "integrity": "sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.0.tgz",
+ "integrity": "sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.0.tgz",
+ "integrity": "sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.0.tgz",
+ "integrity": "sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.3.tgz",
+ "integrity": "sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.2.0"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.3.tgz",
+ "integrity": "sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.2.0"
+ }
+ },
+ "node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.3.tgz",
+ "integrity": "sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.2.0"
+ }
+ },
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.3.tgz",
+ "integrity": "sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.2.0"
+ }
+ },
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.3.tgz",
+ "integrity": "sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.2.0"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.3.tgz",
+ "integrity": "sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.0"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.3.tgz",
+ "integrity": "sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.0"
+ }
+ },
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.3.tgz",
+ "integrity": "sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.4.4"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-arm64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.3.tgz",
+ "integrity": "sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.3.tgz",
+ "integrity": "sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz",
+ "integrity": "sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -454,11 +883,23 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/color": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
+ "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1",
+ "color-string": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=12.5.0"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
@@ -471,9 +912,18 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true,
"license": "MIT"
},
+ "node_modules/color-string": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+ "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -639,6 +1089,15 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
+ "node_modules/detect-libc": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
+ "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@@ -1555,6 +2014,12 @@
"node": ">= 0.10"
}
},
+ "node_modules/is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+ "license": "MIT"
+ },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -2311,6 +2776,18 @@
"postcss": "^8.3.11"
}
},
+ "node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/send": {
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
@@ -2395,6 +2872,48 @@
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"license": "ISC"
},
+ "node_modules/sharp": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.3.tgz",
+ "integrity": "sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "color": "^4.2.3",
+ "detect-libc": "^2.0.4",
+ "semver": "^7.7.2"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.34.3",
+ "@img/sharp-darwin-x64": "0.34.3",
+ "@img/sharp-libvips-darwin-arm64": "1.2.0",
+ "@img/sharp-libvips-darwin-x64": "1.2.0",
+ "@img/sharp-libvips-linux-arm": "1.2.0",
+ "@img/sharp-libvips-linux-arm64": "1.2.0",
+ "@img/sharp-libvips-linux-ppc64": "1.2.0",
+ "@img/sharp-libvips-linux-s390x": "1.2.0",
+ "@img/sharp-libvips-linux-x64": "1.2.0",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.0",
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.0",
+ "@img/sharp-linux-arm": "0.34.3",
+ "@img/sharp-linux-arm64": "0.34.3",
+ "@img/sharp-linux-ppc64": "0.34.3",
+ "@img/sharp-linux-s390x": "0.34.3",
+ "@img/sharp-linux-x64": "0.34.3",
+ "@img/sharp-linuxmusl-arm64": "0.34.3",
+ "@img/sharp-linuxmusl-x64": "0.34.3",
+ "@img/sharp-wasm32": "0.34.3",
+ "@img/sharp-win32-arm64": "0.34.3",
+ "@img/sharp-win32-ia32": "0.34.3",
+ "@img/sharp-win32-x64": "0.34.3"
+ }
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -2488,6 +3007,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.3.1"
+ }
+ },
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
diff --git a/zefie_wtvp_minisrv/package.json b/zefie_wtvp_minisrv/package.json
index f0f90b65..9664ecdf 100644
--- a/zefie_wtvp_minisrv/package.json
+++ b/zefie_wtvp_minisrv/package.json
@@ -43,6 +43,7 @@
"proxy-agent": "^6.4.0",
"rc4-crypto": "^1.5.0",
"sanitize-html": "^2.13.0",
+ "sharp": "^0.34.3",
"starttls": "^1.0.1",
"strftime": "^0.10.2",
"uuid": "^8.3.2"