From 493f1c2e1f6c5c3ea9ae94cac237f64fa5abb5d8 Mon Sep 17 00:00:00 2001 From: metacryst Date: Thu, 13 Nov 2025 15:30:11 -0600 Subject: [PATCH] init --- .gitignore | 1 + app.js | 68 ++ db/db.json | 3 + package-lock.json | 1615 +++++++++++++++++++++++++++++++++++++ package.json | 19 + server/db/db.js | 76 ++ server/db/getDownloads.js | 67 ++ server/index.html | 29 + server/index.js | 115 +++ server/ws.js | 31 + ui/_/code/quill.js | 872 ++++++++++++++++++++ ui/_/code/shared.css | 24 + ui/_/icons/logo.png | Bin 0 -> 119955 bytes ui/components/Home.js | 73 ++ ui/index.html | 13 + ui/index.js | 2 + 16 files changed, 3008 insertions(+) create mode 100644 .gitignore create mode 100644 app.js create mode 100644 db/db.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 server/db/db.js create mode 100644 server/db/getDownloads.js create mode 100644 server/index.html create mode 100644 server/index.js create mode 100644 server/ws.js create mode 100644 ui/_/code/quill.js create mode 100644 ui/_/code/shared.css create mode 100644 ui/_/icons/logo.png create mode 100644 ui/components/Home.js create mode 100644 ui/index.html create mode 100644 ui/index.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/app.js b/app.js new file mode 100644 index 0000000..36fb4dc --- /dev/null +++ b/app.js @@ -0,0 +1,68 @@ +import { app, BrowserWindow, globalShortcut } from 'electron'; +import paths from 'path' +import "./server/index.js" + +import { fileURLToPath } from 'url'; +const __filename = fileURLToPath(import.meta.url); +const __dirname = paths.dirname(__filename); + +function createWindow() { + const win = new BrowserWindow({ + width: 800, + height: 600, + frame: false, + titleBarStyle: "hidden", + webPreferences: { + contextIsolation: true, + nodeIntegration: false, + webviewTag: true, + } + }); + + win.loadFile('server/index.html'); + + win.webContents.on('did-fail-load', (e, code, desc) => { + console.log('Webview failed:', desc); +}); +} + +let devToolsOpened = false; + +function toggleDevTools(win) { + if (devToolsOpened) { + win.closeDevTools(); + } else { + win.openDevTools(); + } + devToolsOpened = !devToolsOpened; +} + +app.on("ready", async () => { + // await Forms.init(); + createWindow(); + + // Register global shortcuts + app.on("browser-window-focus", () => { + const reloadShortcut = process.platform === "darwin" ? "Command+R" : "Control+R"; + globalShortcut.register(reloadShortcut, () => { + BrowserWindow.getFocusedWindow().reload(); + }); + globalShortcut.register("\\", () => { + toggleDevTools(BrowserWindow.getFocusedWindow()); + }); + }); + + app.on("browser-window-blur", () => { + globalShortcut.unregisterAll(); + }); +}); + +app.on("activate", () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow(); + } +}); + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') app.quit(); +}); \ No newline at end of file diff --git a/db/db.json b/db/db.json new file mode 100644 index 0000000..544b7b4 --- /dev/null +++ b/db/db.json @@ -0,0 +1,3 @@ +{ + +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..cf7bf10 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1615 @@ +{ + "name": "downloads-lister", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "downloads-lister", + "version": "1.0.0", + "dependencies": { + "chalk": "^5.6.2", + "cors": "^2.8.5", + "express": "^4.18.2", + "moment": "^2.30.1", + "ws": "^8.18.3" + }, + "devDependencies": { + "electron": "^30.0.0" + } + }, + "node_modules/@electron/get": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.19.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", + "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", + "dev": true, + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "optional": true + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "optional": true + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron": { + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-30.5.1.tgz", + "integrity": "sha512-AhL7+mZ8Lg14iaNfoYTkXQ2qee8mmsQyllKdqxlpv/zrKgfxz6jNVtcRRbQtLxtF8yzcImWdfTQROpYiPumdbw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^20.9.0", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "optional": true + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/global-agent/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "optional": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "optional": true + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "optional": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..aa907ee --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "downloads-lister", + "version": "1.0.0", + "type": "module", + "main": "app.js", + "scripts": { + "start": "electron ." + }, + "devDependencies": { + "electron": "^30.0.0" + }, + "dependencies": { + "chalk": "^5.6.2", + "cors": "^2.8.5", + "express": "^4.18.2", + "moment": "^2.30.1", + "ws": "^8.18.3" + } +} diff --git a/server/db/db.js b/server/db/db.js new file mode 100644 index 0000000..bc9cc22 --- /dev/null +++ b/server/db/db.js @@ -0,0 +1,76 @@ +import chalk from 'chalk' +import path from 'path'; +import fs from 'fs/promises'; +import { pathToFileURL } from 'url'; + +export default class Database { + #nodes; + #edges; + #labels = {} + + constructor() { + this.getData() + } + + async getData() { + const dbData = await fs.readFile(path.join(process.cwd(), 'db/db.json'), 'utf8'); + let dbJson; + try { + dbJson = JSON.parse(dbData); + } catch { + dbJson = [] + } + this.#nodes = dbJson["nodes"]; + this.#edges = dbJson["edges"]; + + console.log(chalk.yellow("DB established.")) + Object.preventExtensions(this); + } + + // superKey = "nodes" || "edges" + async writeData(superKey, key, value) { + const dbData = await fs.readFile(path.join(process.cwd(), 'db/db.json'), 'utf8'); + let dbJson; + try { + dbJson = JSON.parse(dbData); + } catch { + dbJson = [] + } + + dbJson[superKey][key] = value; + + await fs.writeFile(path.join(process.cwd(), 'db/db.json'), JSON.stringify(dbJson, null, 2), 'utf8') + } + + async getLabelModels() { + const labelHandlers = {}; + const labelDir = path.join(process.cwd(), 'src/model/labels'); + const files = await fs.readdir(labelDir); + + for (const file of files) { + if (!file.endsWith('.js')) continue; + + const label = path.basename(file, '.js'); + const modulePath = path.join(labelDir, file); + const module = await import(pathToFileURL(modulePath).href); + labelHandlers[label] = module.default; + + if (!this.#labels[label]) { + this.#labels[label] = []; + } + } + return labelHandlers + } + + generateUserID() { + let id = this.#labels["User"].length + 1; + while (this.get.user(`user-${id}`)) { + id++; + } + return `user-${id}`; // O(1) most of the time + } + + async getAll() { + return { nodes: this.#nodes } + } +} \ No newline at end of file diff --git a/server/db/getDownloads.js b/server/db/getDownloads.js new file mode 100644 index 0000000..ab957c6 --- /dev/null +++ b/server/db/getDownloads.js @@ -0,0 +1,67 @@ +// getDownloadsFiles.js +import fs from 'fs/promises'; +import path from 'path'; +import os from 'os'; + +const DOWNLOADS = path.join(os.homedir(), 'Downloads'); + +/** + * Recursively get all files in Downloads with name, path, and inode. + * @returns {Promise>} + */ +async function getAllDownloadsFiles() { + const files = []; + + async function scan(dir) { + let entries; + try { + entries = await fs.readdir(dir, { withFileTypes: true }); + } catch (err) { + console.warn(`Cannot read directory: ${dir}`, err.message); + return; + } + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + + try { + // Get stats (inode = ino on Unix, null on Windows) + // const stats = await fs.stat(fullPath); + // const inode = stats.ino ?? null; + + if (entry.isDirectory()) { + // Recurse into subdirectories + await scan(fullPath); + } else if (entry.isFile()) { + const parsed = path.parse(entry.name); // splits name/ext + const realExtension = path.extname(fullPath); // from full path (more reliable) + + // Use realExtension if available, fallback to parsed.ext + const extension = realExtension || parsed.ext; + + // Build clean name + extension + const nameWithExt = parsed.name + extension; + + files.push({ + name: entry.name, // original (may hide ext) + // nameWithExt: nameWithExt, // ALWAYS has correct ext + // displayName: nameWithExt, // use this in UI + // extension: extension.slice(1).toLowerCase() || null, // "jpg", null if none + // path: fullPath, + // inode: stats.ino ?? null, + // size: stats.size, + // mtime: stats.mtime.toISOString() + }); + } + // Skip symlinks, sockets, etc. (or handle if needed) + } catch (err) { + console.warn(`Cannot access: ${fullPath}`, err.message); + } + } + } + + await scan(DOWNLOADS); + return files; +} + +export default getAllDownloadsFiles; \ No newline at end of file diff --git a/server/index.html b/server/index.html new file mode 100644 index 0000000..affadf0 --- /dev/null +++ b/server/index.html @@ -0,0 +1,29 @@ + + + + + Downloads + + + + +
+ + + diff --git a/server/index.js b/server/index.js new file mode 100644 index 0000000..62659f9 --- /dev/null +++ b/server/index.js @@ -0,0 +1,115 @@ +import path from 'path'; +import fs from 'fs/promises' +import { fileURLToPath } from 'url'; +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +import express from 'express'; +import cors from 'cors' +import http from 'http' +import chalk from 'chalk' +import moment from 'moment' + +import { initWebSocket } from './ws.js' +import Database from "./db/db.js" +import getAllDownloadsFiles from "./db/getDownloads.js" + +class Server { + db; + UIPath = path.join(__dirname, '../ui') + + registerRoutes(router) { + router.get('/', this.index) + router.get('/*', this.get) + return router + } + + index = async (req, res) => { + let filePath = path.join(this.UIPath, "index.html"); + let html = await fs.readFile(filePath, 'utf-8'); + + let downloads = await getAllDownloadsFiles() + const jsonString = JSON.stringify(downloads, null, 2); // pretty-print optional + const scriptTag = ``; + + const headEndRegex = /<\/head\s*>/i; + + const match = html.match(headEndRegex); + const insertPos = match.index; + let result = html.slice(0, insertPos) + scriptTag + '\n' + html.slice(insertPos); + res.type('html').send(result); + } + + get = async (req, res) => { + let url = req.url + + let filePath = path.join(this.UIPath, url); + + res.sendFile(filePath, (err) => { + if (err) { + console.error(`Error serving ${filePath}:`, err); + res.status(err.status || 500).send('File not found or error serving file.'); + } + }); + } + + logRequest(req, res, next) { + const formattedDate = moment().format('M.D'); + const formattedTime = moment().format('h:mma'); + if(req.url.includes("/api/")) { + console.log(chalk.blue(` ${req.method} ${req.url} | ${formattedDate} ${formattedTime}`)); + } else { + if(req.url === "/") + console.log(chalk.gray(` ${req.method} ${req.url} | ${formattedDate} ${formattedTime}`)); + } + next(); + } + + logResponse(req, res, next) { + const originalSend = res.send; + res.send = function (body) { + if(res.statusCode >= 400) { + console.log(chalk.blue( `<-${chalk.red(res.statusCode)}- ${req.method} ${req.url} | ${chalk.red(body)}`)); + } else { + console.log(chalk.blue(`<-${res.statusCode}- ${req.method} ${req.url}`)); + } + originalSend.call(this, body); + }; + next(); + } + + constructor() { + this.db = new Database() + const app = express(); + app.use(cors({ origin: '*' })); + app.use(express.json()); + + app.use(this.logRequest); + app.use(this.logResponse); + + let router = express.Router(); + this.registerRoutes(router) + app.use('/', router); + + const server = http.createServer(app); + initWebSocket(server); + const PORT = 3020; + server.listen(PORT, () => { + console.log("\n") + console.log(chalk.yellow("**************Downloads****************")) + console.log(chalk.yellowBright(`Server is running on port ${PORT}: http://localhost`)); + console.log(chalk.yellow("***************************************")) + console.log("\n") + }); + + process.on('SIGINT', async () => { + console.log(chalk.red('Closing server...')); + console.log(chalk.green('Database connection closed.')); + process.exit(0); + }); + + Object.preventExtensions(this); + } +} + +const server = new Server() \ No newline at end of file diff --git a/server/ws.js b/server/ws.js new file mode 100644 index 0000000..2cf8142 --- /dev/null +++ b/server/ws.js @@ -0,0 +1,31 @@ +import { WebSocket, WebSocketServer } from 'ws'; + +let wss; + +export function initWebSocket(server) { + wss = new WebSocketServer({ server }); + + wss.on('connection', (ws, req) => { + console.log('✅ New WebSocket client connected'); + + ws.on('close', () => { + console.log('Client disconnected'); + }); + }); + + console.log('WebSocket server initialized'); +} + +// Broadcast a message to all connected clients +export function broadcast(reqType, data) { + if (!wss) return; + + const payload = typeof data === 'string' ? data : JSON.stringify(data); + const message = `${reqType}|${payload}`; + + wss.clients.forEach(client => { + if (client.readyState === WebSocket.OPEN) { + client.send(message); + } + }); +} diff --git a/ui/_/code/quill.js b/ui/_/code/quill.js new file mode 100644 index 0000000..d407b0e --- /dev/null +++ b/ui/_/code/quill.js @@ -0,0 +1,872 @@ +/* + Sam Russell + Captured Sun + 11.9.25 - changed p(innerText) to p(innerHTML), adjusted onNavigate to work for multiple elements and with correct "this" scope + 11.7.25 - changed registerShadow() to register(), changed onClick() to be like onHover() + 11.6.25 - adding default value for "button()" "children" parameter + 10.29.25 - adding "gap()" and "label()" functions +*/ + +/* $ NAVIGATION */ +let oldPushState = history.pushState; +history.pushState = function pushState() { + let ret = oldPushState.apply(this, arguments); + window.dispatchEvent(new Event('pushstate')); + window.dispatchEvent(new Event('navigate')); + return ret; +}; + +window.addEventListener('popstate', () => { + window.dispatchEvent(new Event('navigate')); +}); + +window.navigateTo = function(url) { + window.dispatchEvent(new Event('navigate')); + window.history.pushState({}, '', url); +} + +/* $ SELECTOR */ + +HTMLElement.prototype.$ = function(selector) { + return window.$(selector, this) +} +DocumentFragment.prototype.$ = function(selector) { + return window.$(selector, this) +} +window.$ = function(selector, el = document) { + return el.querySelector(selector) +} + +window.$$ = function(selector, el = document) { + return Array.from(el.querySelectorAll(selector)) +} + +/* CONSOLE */ + +console.red = function(message) { + this.log(`%c${message}`, "color: rgb(254, 79, 42);"); +}; + +console.green = function(message) { + this.log(`%c${message}`, "color: rgb(79, 254, 42);"); + +} + +/* GET CSS VARIABLES FOR DARK OR LIGHT MODE */ +window.darkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; +document.documentElement.classList.add(darkMode ? 'dark' : 'light'); + +window.getColor = function(name) { + const rootStyles = getComputedStyle(document.documentElement); + const color = rootStyles.getPropertyValue(`--${name}`).trim(); + if(!color) { + throw new Error("Color not found") + } + return color +} + +/* MOBILE */ + +window.isMobile = function isMobile() { + return /Android|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i.test(navigator.userAgent); +} + +window.css = function css(cssString) { + let container = document.querySelector("style#pageStyle"); + if(!container) { + container = document.createElement('style'); + container.id = "pageStyle"; + document.head.appendChild(container); + } + + let primarySelector = cssString.substring(0, cssString.indexOf("{")).trim(); + primarySelector = primarySelector.replace(/\*/g, "all"); + primarySelector = primarySelector.replace(/#/g, "id-"); + primarySelector = primarySelector.replace(/,/g, ""); + let stylesheet = container.querySelector(`:scope > style[id='${primarySelector}']`) + if(!stylesheet) { + stylesheet = document.createElement('style'); + stylesheet.id = primarySelector; + stylesheet.appendChild(document.createTextNode(cssString)); + container.appendChild(stylesheet); + } else { + stylesheet.innerText = cssString + } +} + +window.html = function html(elementString) { + let parser = new DOMParser(); + let doc = parser.parseFromString(elementString, 'text/html'); + return doc.body.firstChild; +} + +window.util = {} +window.util.observeClassChange = (el, callback) => { + if (!el || !(el instanceof Element)) { + throw new Error("observeClassChange requires a valid DOM element."); + } + + const observer = new MutationObserver((mutations) => { + for (const mutation of mutations) { + if (mutation.type === "attributes" && mutation.attributeName === "class") { + callback(el.classList); + } + } + }); + + observer.observe(el, { + attributes: true, + attributeFilter: ["class"] + }); + + return observer; // Optional: return it so you can disconnect later +} + +/* PAGE SETUP */ + +Object.defineProperty(Array.prototype, 'last', { + get() { + return this[this.length - 1]; + }, + enumerable: false, +}); + +/* QUILL */ + +window.quill = { + rendering: [], + + render: (el) => { + if(el instanceof Shadow) { + let parent = quill.rendering[quill.rendering.length-1] + if(!parent) { + parent = document.body + } + parent.appendChild(el) + } else { + if(!el.render) {el.render = () => {}} + let parent = quill.rendering[quill.rendering.length-1] + if(!parent) throw new Error("Quill: no parent for element") + parent.appendChild(el) + } + + quill.rendering.push(el) + el.render() + quill.rendering.pop(el) + }, + + rerender: (el) => { + Array.from(el.attributes).forEach(attr => el.removeAttribute(attr.name)); + el.innerHTML = "" + el.removeAllListeners() + + quill.rendering.push(el) + el.render() + quill.rendering.pop() + }, + + loadPage: () => { + let URL = window.location.pathname + if(!window.routes[URL]) { + throw new Error("No URL for this route: ", URL) + } + + let pageClass = window[routes[URL]] + document.title = pageClass.title ?? document.title + document.body.innerHTML = "" + let page = new pageClass() + quill.render(page) + }, + + isStack: (el) => { + return el.classList.contains("HStack") || el.classList.contains("ZStack") || el.classList.contains("VStack") + }, +} + +window.Shadow = class extends HTMLElement { + constructor() { + super() + } +} +window.register = (el, tagname) => { + if (typeof el.prototype.render !== 'function') { + throw new Error("Element must have a render: " + el.prototype.constructor.name) + } + if(!tagname) { + tagname = el.prototype.constructor.name.toLowerCase() + "-" + } + customElements.define(tagname, el) + if(el.css) { + css(el.css) + } + + window[el.prototype.constructor.name] = function (...params) { + let instance = new el(...params) + quill.render(instance) + return instance + } +} + +HTMLElement.prototype.rerender = function() { + quill.rerender(this) +} + +/* Styling */ + +window.vh = "vh" +window.vw = "vw" +window.px = "px" +window.em = "em" +window.rem = "rem" +window.inches = "in" + +HTMLElement.prototype.addStyle = function(func) { + return func(this) +} + +window.css = function css(cssString) { + let container = document.querySelector("style#pageStyle"); + if(!container) { + container = document.createElement('style'); + container.id = "pageStyle"; + document.head.appendChild(container); + } + + let primarySelector = cssString.substring(0, cssString.indexOf("{")).trim(); + primarySelector = primarySelector.replace(/\*/g, "all"); + primarySelector = primarySelector.replace(/#/g, "id-"); + primarySelector = primarySelector.replace(/,/g, ""); + let stylesheet = container.querySelector(`:scope > style[id='${primarySelector}']`) + if(!stylesheet) { + stylesheet = document.createElement('style'); + stylesheet.id = primarySelector; + stylesheet.appendChild(document.createTextNode(cssString)); + container.appendChild(stylesheet); + } else { + stylesheet.innerText = cssString + } +} + +function extendHTMLElementWithStyleSetters() { + let allStyleProps = Object.keys(document.createElement("div").style) + allStyleProps.forEach(prop => { + if(prop === "translate") return + HTMLElement.prototype[prop] = function(value) { + this.style[prop] = value; + return this; + }; + }); +} +extendHTMLElementWithStyleSetters(); + +HTMLElement.prototype.padding = function(one, two, three = "px") { + + const setPadding = (side, val) => { + const directionName = `padding${side.charAt(0).toUpperCase()}${side.slice(1)}`; + this.style[directionName] = (typeof val === 'number') ? `${val}${three}` : val; + }; + + if(one === "horizontal" || one === "vertical") { // is one a direction + if (one === "horizontal") { + setPadding("left", two); + setPadding("right", two); + } else if (one === "vertical") { + setPadding("top", two); + setPadding("bottom", two); + } + } else { // is two a value + if(typeof one !== 'number' || isNaN(one)) { + this.style.padding = one + } else { + this.style.padding = one + two + } + } + + return this; +}; + + HTMLElement.prototype.paddingTop = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.paddingTop = value + unit + return this + } + + HTMLElement.prototype.paddingLeft = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.paddingLeft = value + unit + return this + } + + HTMLElement.prototype.paddingBottom = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.paddingBottom = value + unit + return this + } + + HTMLElement.prototype.paddingRight = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.paddingRight = value + unit + return this + } + + HTMLElement.prototype.paddingVertical = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.paddingTop = value + unit + this.style.paddingBottom = value + unit + return this + } + + HTMLElement.prototype.paddingHorizontal = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.paddingRight = value + unit + this.style.paddingLeft = value + unit + return this + } + +HTMLElement.prototype.margin = function(direction, value, unit = "px") { + if (!value) { + this.style.margin = direction; + return this; + } + + const setMargin = (side, val) => { + const directionName = `margin${side.charAt(0).toUpperCase()}${side.slice(1)}`; + this.style[directionName] = (typeof val === 'number') ? `${val}${unit}` : val; + }; + + if (direction === "horizontal") { + setMargin("left", value); + setMargin("right", value); + } else if (direction === "vertical") { + setMargin("top", value); + setMargin("bottom", value); + } else { + setMargin(direction, value); + } + + return this; +}; + + HTMLElement.prototype.marginTop = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.marginTop = value + unit + return this + } + + HTMLElement.prototype.marginLeft = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.marginLeft = value + unit + return this + } + + HTMLElement.prototype.marginBottom = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.marginBottom = value + unit + return this + } + + HTMLElement.prototype.marginRight = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.marginRight = value + unit + return this + } + +HTMLElement.prototype.width = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.width = value + unit + return this +} + +HTMLElement.prototype.minWidth = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.minWidth = value + unit + return this +} + +HTMLElement.prototype.height = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.height = value + unit + return this +} + +HTMLElement.prototype.minHeight = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.minHeight = value + unit + return this +} + +HTMLElement.prototype.fontSize = function(value, unit = "px") { + if ((typeof value !== 'number' && value !== "auto") || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + + switch(value) { + case "6xl": + value = "3.75"; unit = "rem" + break; + + case "5xl": + value = "3"; unit = "rem" + break; + + case "4xl": + value = "2.25"; unit = "rem" + break; + + case "3xl": + value = "1.875"; unit = "rem" + break; + + case "2xl": + value = "1.5"; unit = "rem" + break; + + case "xl": + value = "1.25"; unit = "rem" + break; + + case "l": + value = "1.125"; unit = "rem" + break; + + case "s": + value = "0.875"; unit = "rem" + break; + + case "xs": + value = "0.75"; unit = "rem" + break; + + default: + break; + } + this.style.fontSize = value + unit + return this +} + +function checkPositionType(el) { + let computed = window.getComputedStyle(el).position + if(!(computed === "absolute" || computed === "fixed")) { + el.style.position = "absolute" + } +} + +HTMLElement.prototype.x = function(value, unit = "px") { + if (typeof value !== 'number' || isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + checkPositionType(this) + this.style.left = value + unit + return this +} + +HTMLElement.prototype.y = function(value, unit = "px") { + if (typeof value !== 'number' || isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + checkPositionType(this) + this.style.top = value + unit + return this +} + +HTMLElement.prototype.xRight = function(value, unit = "px") { + if (typeof value !== 'number' || isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + checkPositionType(this) + this.style.right = value + unit + return this +} + +HTMLElement.prototype.yBottom = function(value, unit = "px") { + if (typeof value !== 'number' || isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + checkPositionType(this) + this.style.bottom = value + unit + return this +} + +HTMLElement.prototype.borderRadius = function(value, unit = "px") { + if (typeof value !== 'number' || isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.borderRadius = value + unit + return this +} + +HTMLElement.prototype.positionType = function (value) { + if(!(value === "absolute" || value === "relative" || value === "static" || value === "fixed" || value === "sticky")) { + console.error("HTMLElement.overlflow: must have valid overflow value!") + return; + } + this.style.position = value + return this +} + +HTMLElement.prototype.gap = function(value, unit = "px") { + if (typeof value !== 'number' || Number.isNaN(value)) + throw new Error(`Invalid value: ${value}. Expected a number.`); + this.style.gap = value + unit + return this +} + +HTMLElement.prototype.backgroundImage = function (...values) { + const formatted = values + .map(v => { + if(v.includes("/") && !v.includes("gradient")) { + v = "url(" + v + ")" + } + return String(v).trim(); + }) + .join(", "); + + this.style.backgroundImage = formatted; + return this; +}; + +/* Elements */ + +quill.setChildren = function(el, innerContent) { + if(typeof innerContent === "string") { + el.innerText = innerContent + } else if(typeof innerContent === "function") { + el.render = innerContent + } else { + throw new Error("Children of unknown type") + } +} + +window.a = function a( href, inner=href ) { + if(!href) throw new Error("quill a: missing href argument. Function: a( href, inner=href )") + let link = document.createElement("a") + link.setAttribute('href', href); + quill.setChildren(link, inner) + quill.render(link) + return link +} + +window.img = function img(src, width="", height="") { + let image = document.createElement("img") + + if(!src || !(typeof src==="string")) { + throw new Error("img: missing first argument: src | String") + } else { + image.src = src + } + if(width && typeof width === "string") { + image.style.width = width + } else if(width) { + image.style.width = width + "px" + } + if(height && typeof height === "string") { + image.style.height = height + } else if(height) { + image.style.height = height + "px" + } + quill.render(image) + return image +} + +HTMLImageElement.prototype.backgroundColor = function(value) { + if (this.src.endsWith('.svg') || this.src.startsWith('data:image/svg+xml')) { + fetch(this.src).then(response => response.text()) + .then(svgText => { + const modifiedSvg = svgText.replace(/\bfill="[^"]*"/g, `fill="${value}"`); + const blob = new Blob([modifiedSvg], { type: 'image/svg+xml' }); + this.src = URL.createObjectURL(blob); + }).catch(error => { + console.error('Error updating SVG fill:', error); + }); + } else { + this.style.backgroundColor = value; + } + + return this; // Always returns the element itself + }; + +window.p = function p(innerHTML) { + let el = document.createElement("p") + if(typeof innerText === "function") { + el.render = innerHTML + } else { + el.innerHTML = innerHTML + } + el.style.margin = "0"; + quill.render(el) + return el +} + +window.h1 = function h1(innerText) { + let el = document.createElement("h1") + el.innerText = innerText + quill.render(el) + return el +} + +window.h2 = function h2(innerText) { + let el = document.createElement("h2") + el.innerText = innerText + quill.render(el) + return el +} + +window.h3 = function h3(innerText) { + let el = document.createElement("h3") + el.innerText = innerText + quill.render(el) + return el +} + +window.div = function (innerText) { + let el = document.createElement("div") + el.innerText = innerText ?? "" + quill.render(el) + return el +} + +window.span = function (innerText) { + let el = document.createElement("span") + el.innerText = innerText + quill.render(el) + return el +} + +window.button = function (children = "") { + let el = document.createElement("button") + quill.setChildren(el, children) + quill.render(el) + return el +} + +window.form = function(cb) { + let el = document.createElement("form") + el.render = cb + quill.render(el) + return el +} + +window.input = function(placeholder, width, height) { + let el = document.createElement("input") + el.placeholder = placeholder + el.style.width = width + el.style.height = height + quill.render(el) + return el +} + +window.label = function(text) { + let el = document.createElement("label") + el.innerText = text + quill.render(el) + return el +} + +window.textarea = function(placeholder) { + let el = document.createElement("textarea") + el.placeholder = placeholder + quill.render(el) + return el +} + + +/* STACKS */ + +window.VStack = function (cb = () => {}) { + let styles = ` + display: flex; + flex-direction: column; + ` + let nowRendering = quill.rendering[quill.rendering.length-1] + if (nowRendering.innerHTML.trim() === "" && !quill.isStack(nowRendering)) { + nowRendering.style.cssText += styles + nowRendering.classList.add("VStack") + cb() + return nowRendering + } + + let div = document.createElement("div") + div.classList.add("VStack") + div.style.cssText += styles + div.render = cb + quill.render(div) + return div +} + +window.HStack = function (cb = () => {}) { + let styles = ` + display: flex; + flex-direction: row; + `; + let nowRendering = quill.rendering[quill.rendering.length - 1]; + if (nowRendering.innerHTML.trim() === "" && !quill.isStack(nowRendering)) { + nowRendering.style.cssText += styles; + nowRendering.classList.add("HStack") + cb(); + return nowRendering; + } + + let div = document.createElement("div"); + div.classList.add("HStack"); + div.style.cssText += styles; + div.render = cb; + quill.render(div); + return div; +}; + +window.ZStack = function (cb = () => {}) { + let nowRendering = quill.rendering[quill.rendering.length - 1]; + if (nowRendering.innerHTML.trim() === "" && !quill.isStack(nowRendering)) { + nowRendering.classList.add("ZStack") + cb(); + return nowRendering; + } + + let div = document.createElement("div"); + div.classList.add("ZStack"); + div.render = cb; + quill.render(div); + return div; +}; + +/* EVENTS */ + +HTMLElement.prototype.onAppear = function(func) { + func(this); + return this; +}; + +HTMLElement.prototype.onClick = function(func) { + const onMouseDown = () => func.call(this, true); + const onMouseUp = () => func.call(this, false); + this._storeListener("mousedown", onMouseDown); + this._storeListener("mouseup", onMouseUp); + return this; +}; + +HTMLElement.prototype.onMouseDown = function(func) { + this._storeListener("mousedown", func); + return this; +}; + +HTMLElement.prototype.onMouseUp = function(func) { + this._storeListener("mouseup", func); + return this; +}; + +HTMLElement.prototype.onRightClick = function(func) { + this._storeListener("contextmenu", func); + return this; +}; + +HTMLElement.prototype.onHover = function(cb) { + const onEnter = () => cb.call(this, true); + const onLeave = () => cb.call(this, false); + this._storeListener("mouseover", onEnter); + this._storeListener("mouseleave", onLeave); + return this; +}; + +HTMLElement.prototype.onFocus = function(cb) { + if (!this.matches('input, textarea, select, button')) { + throw new Error("Can't put focus event on non-form element!"); + } + const onFocus = () => cb.call(this, true); + const onBlur = () => cb.call(this, false); + this._storeListener("focus", onFocus); + this._storeListener("blur", onBlur); + return this; +}; + +HTMLElement.prototype.onKeyDown = function(cb) { + this._storeListener("keydown", cb); + return this; +}; + +HTMLElement.prototype.onInput = function(cb) { + if(!this.matches('input, textarea, [contenteditable=""], [contenteditable="true"]')) + throw new Error("Can't put input event on non-input element!") + this._storeListener("input", cb); + return this; +}; + +/* WHY THIS LISTENER IS THE WAY IT IS: +- If we dispatch the "navigate" event on the window (as one would expect for a "navigate" event), a listener placed on the element will not pick it up. +- However, if we add the event as a window event, it won't have the "this" scope that a callback normally would. +- Then, if we try to add that scope using bind(), it makes the function.toString() unreadable, which means we will get false positives for duplicate listeners. +- Therefore, we just have to attach the navigate event to the element, and manually trigger that when the window listener fires. +*/ +HTMLElement.prototype.onNavigate = function(cb) { + this._storeListener("navigate", cb); + window.addEventListener("navigate", () => this.dispatchEvent(new CustomEvent("navigate"))) + return this; +}; + +HTMLElement.prototype.onEvent = function(name, cb) { + window._storeListener(window, name, cb); + return this; +}; + +HTMLElement.prototype._storeListener = function(type, handler, options) { + window._storeListener(this, type, handler, options) +} + +window.__listeners = [] + +function _storeListener(target, type, handler, options) { + if (!target.__listeners) target.__listeners = []; + + const optionsString = JSON.stringify(options); + + const index = target.__listeners.findIndex(listener => + listener.type === type && + listener.handler.toString() === handler.toString() && + JSON.stringify(listener.options) === optionsString + ); + + if (index === -1) { // Listener is new + target.addEventListener(type, handler, options); + target.__listeners.push({ type, handler, options }); + } else { // Listener is a duplicate, can be replaced + const old = target.__listeners[index]; + target.removeEventListener(old.type, old.handler, old.options); + + // Replace with the new one + target.addEventListener(type, handler, options); + target.__listeners[index] = { type, handler, options }; + } +} + +HTMLElement.prototype.removeAllListeners = function() { + if (!this.__listeners) return; + for (const { type, handler, options } of this.__listeners) { + this.removeEventListener(type, handler, options); + } + this.__listeners = []; + return this; +}; + +/* ATTRIBUTES */ + +HTMLElement.prototype.attr = function(attributes) { + if ( + typeof attributes !== "object" || + attributes === null || + Array.isArray(attributes) + ) { + throw new TypeError("attr() expects an object with key-value pairs"); + } + + for (const [key, value] of Object.entries(attributes)) { + this.setAttribute(key, value); + } + return this; +}; diff --git a/ui/_/code/shared.css b/ui/_/code/shared.css new file mode 100644 index 0000000..dd4fb48 --- /dev/null +++ b/ui/_/code/shared.css @@ -0,0 +1,24 @@ +:root { + --main: #BD410D; + --accent: var(--tan); + --accent2: var(--brown); + + --tan: #FEB279; + --purple: #251D44; + --green: #0B5538; + --red: #BC1C02; + --brown: #c6a476; + --darkbrown: #60320c; + --darkred: #7f0b09; + --orange: #FE9201; + --periwinkle: #655BAF; + +} + +@media (prefers-color-scheme: dark) { +:root { + --main: #BD410D; + --accent: var(--tan); + --accent2: var(--green); +} +} \ No newline at end of file diff --git a/ui/_/icons/logo.png b/ui/_/icons/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4f828a68aa772ba7d4700c03d9a32ecd33faeb7b GIT binary patch literal 119955 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 (>}(LeA% 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
  • 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 literal 0 HcmV?d00001 diff --git a/ui/components/Home.js b/ui/components/Home.js new file mode 100644 index 0000000..0c7ad3d --- /dev/null +++ b/ui/components/Home.js @@ -0,0 +1,73 @@ +class Home extends Shadow { + + + + render() { + ZStack(() => { + input("", "20vw") + .backgroundColor("var(--darkred)") + .color("var(--accent)") + .border("none") + .borderTop("1px solid var(--accent)") + .borderBottom("1px solid var(--accent)") + .outline("0.5px solid black") + .borderRadius(7, px) + .transition("padding .2s") + .padding(0.5, em) + .position("absolute") + .x(50, vw).y(7, em) + .transform("translate(-50%, -50%)") + .onInput(() => { + console.log('typing') + }) + .onFocus(function (focusing) { + if(focusing) { + this.style.padding = "1em" + this.style.borderColor = "var(--darkred)" + } else { + this.style.padding = "0.5em" + this.style.borderColor = "var(--accent)" + } + }) + + VStack(() => { + + let json = this.getJSONData() + for(let i=0; i<100; i++) { + p(json[i].name) + .marginLeft(0, em) + } + }) + .paddingLeft(5, em) + .paddingTop(10, em) + }) + .backgroundColor("var(--main)") + .display("block") + .width(100, vw).height("auto") + .color("var(--accent)") + .fontFamily("Arial") + .onAppear(() => { + document.body.style.backgroundColor = "var(--main)" + }) + } + + getJSONData() { + const script = document.getElementById('jsonData'); + if (!script) { + console.warn('initial-data script not found'); + return null; + } + + try { + // script.textContent is the raw JSON string + const data = JSON.parse(script.textContent); + console.log(data) + return data; + } catch (err) { + console.error('Failed to parse initial-data JSON:', err); + return null; + } + } +} + +register(Home) \ No newline at end of file diff --git a/ui/index.html b/ui/index.html new file mode 100644 index 0000000..705db67 --- /dev/null +++ b/ui/index.html @@ -0,0 +1,13 @@ + + + + Downloads + + + + + + + + + \ No newline at end of file diff --git a/ui/index.js b/ui/index.js new file mode 100644 index 0000000..b14af88 --- /dev/null +++ b/ui/index.js @@ -0,0 +1,2 @@ +import "./components/Home.js" +Home() \ No newline at end of file