From 80c2b07ad0b4bcf9385d13ef3c5a6c4a04e87017 Mon Sep 17 00:00:00 2001 From: Ark74 Date: Tue, 31 Mar 2026 16:16:34 -0600 Subject: [PATCH] =?UTF-8?q?[dashboard]=20c=C3=B3digo=20migrado=20a=20iiab/?= =?UTF-8?q?iiab-android?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/dashboard/.gitignore | 14 - android/dashboard/package-lock.json | 1273 ----------------- android/dashboard/package.json | 23 - android/dashboard/public/css/dashboard.css | 121 -- android/dashboard/server.ts | 44 - android/dashboard/sockets/home.socket.ts | 126 -- android/dashboard/sockets/kiwix.socket.ts | 186 --- android/dashboard/sockets/maps.socket.ts | 164 --- android/dashboard/tsconfig.json | 11 - .../dashboard/views/components/app_home.ejs | 102 -- .../dashboard/views/components/app_kiwix.ejs | 277 ---- .../dashboard/views/components/app_maps.ejs | 174 --- .../dashboard/views/components/sidebar.ejs | 24 - android/dashboard/views/index.ejs | 42 - 14 files changed, 2581 deletions(-) delete mode 100644 android/dashboard/.gitignore delete mode 100644 android/dashboard/package-lock.json delete mode 100644 android/dashboard/package.json delete mode 100644 android/dashboard/public/css/dashboard.css delete mode 100644 android/dashboard/server.ts delete mode 100644 android/dashboard/sockets/home.socket.ts delete mode 100644 android/dashboard/sockets/kiwix.socket.ts delete mode 100644 android/dashboard/sockets/maps.socket.ts delete mode 100644 android/dashboard/tsconfig.json delete mode 100644 android/dashboard/views/components/app_home.ejs delete mode 100644 android/dashboard/views/components/app_kiwix.ejs delete mode 100644 android/dashboard/views/components/app_maps.ejs delete mode 100644 android/dashboard/views/components/sidebar.ejs delete mode 100644 android/dashboard/views/index.ejs diff --git a/android/dashboard/.gitignore b/android/dashboard/.gitignore deleted file mode 100644 index 1fd9ae4..0000000 --- a/android/dashboard/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# Dependencias -node_modules/ - -# Archivos de entorno y logs -.env -npm-debug.log* - -# Archivos compilados (si en el futuro decides compilar el TS) -dist/ -build/ - -# Archivos del sistema operativo (Mac/Linux) -.DS_Store -Thumbs.db diff --git a/android/dashboard/package-lock.json b/android/dashboard/package-lock.json deleted file mode 100644 index 166177d..0000000 --- a/android/dashboard/package-lock.json +++ /dev/null @@ -1,1273 +0,0 @@ -{ - "name": "dashboard-console", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "dashboard-console", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "ejs": "^5.0.1", - "express": "^5.2.1", - "socket.io": "^4.8.3" - }, - "devDependencies": { - "@types/express": "^5.0.6", - "@types/node": "^25.5.0", - "ts-node": "^10.9.2", - "typescript": "^6.0.2" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", - "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cors": { - "version": "2.8.19", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", - "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", - "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^5.0.0", - "@types/serve-static": "^2" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz", - "integrity": "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "dev": true - }, - "node_modules/@types/node": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", - "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", - "dependencies": { - "undici-types": "~7.18.0" - } - }, - "node_modules/@types/qs": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.0.tgz", - "integrity": "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==", - "dev": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true - }, - "node_modules/@types/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", - "dev": true, - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*" - } - }, - "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", - "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", - "dev": true, - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "engines": { - "node": "^4.5.0 || >= 5.9" - } - }, - "node_modules/body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", - "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "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/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/content-disposition": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", - "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "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.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/cors": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", - "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "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/diff": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", - "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "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/ejs": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-5.0.1.tgz", - "integrity": "sha512-COqBPFMxuPTPspXl2DkVYaDS3HtrD1GpzOGkNTJ1IYkifq/r9h8SVEFrjA3D9/VJGOEoMQcrlhpntcSUrM8k6A==", - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.12.18" - } - }, - "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/engine.io": { - "version": "6.6.6", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.6.tgz", - "integrity": "sha512-U2SN0w3OpjFRVlrc17E6TMDmH58Xl9rai1MblNjAdwWp07Kk+llmzX0hjDpQdrDGzwmvOtgM5yI+meYX6iZ2xA==", - "dependencies": { - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "@types/ws": "^8.5.12", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.7.2", - "cors": "~2.8.5", - "debug": "~4.4.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.18.3" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", - "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io/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/engine.io/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/engine.io/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/engine.io/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/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/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/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": "5.2.1", - "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", - "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.1", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "depd": "^2.0.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/finalhandler": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", - "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "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": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "engines": { - "node": ">= 0.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/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/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-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "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/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "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": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "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": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "engines": { - "node": ">= 0.6" - } - }, - "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/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==", - "dependencies": { - "wrappy": "1" - } - }, - "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": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "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/qs": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", - "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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": "3.0.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.7.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "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/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", - "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", - "dependencies": { - "debug": "^4.4.3", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.1", - "mime-types": "^3.0.2", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/serve-static": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", - "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "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/socket.io": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.3.tgz", - "integrity": "sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==", - "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.4.1", - "engine.io": "~6.6.0", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "node_modules/socket.io-adapter": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.6.tgz", - "integrity": "sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==", - "dependencies": { - "debug": "~4.4.1", - "ws": "~8.18.3" - } - }, - "node_modules/socket.io-parser": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", - "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.4.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io/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/socket.io/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/socket.io/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/socket.io/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/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "engines": { - "node": ">= 0.8" - } - }, - "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/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typescript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", - "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==" - }, - "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/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "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==" - }, - "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/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - } - } -} diff --git a/android/dashboard/package.json b/android/dashboard/package.json deleted file mode 100644 index be4ef7c..0000000 --- a/android/dashboard/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "dashboard-console", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "devDependencies": { - "@types/express": "^5.0.6", - "@types/node": "^25.5.0", - "ts-node": "^10.9.2", - "typescript": "^6.0.2" - }, - "dependencies": { - "ejs": "^5.0.1", - "express": "^5.2.1", - "socket.io": "^4.8.3" - } -} diff --git a/android/dashboard/public/css/dashboard.css b/android/dashboard/public/css/dashboard.css deleted file mode 100644 index 8fb1a77..0000000 --- a/android/dashboard/public/css/dashboard.css +++ /dev/null @@ -1,121 +0,0 @@ -/* ========================================= - BASE STYLES - ========================================= */ -body { - background-color: #121212; - color: #ffffff; - overflow-x: hidden; -} -.hidden-section { - display: none !important; -} - -/* ========================================= - RESPONSIVE NAVIGATION (SIDEBAR / BOTTOM NAV) - ========================================= */ -.nav-btn { cursor: pointer; border-radius: 8px; transition: background 0.2s; } -.nav-btn:hover, .nav-btn.active { background-color: rgba(255,255,255,0.1); } -.nav-icon { display: inline-block; margin-right: 10px; } - -/* Desktop (PC) */ -@media (min-width: 768px) { - .app-sidebar { - min-height: 100vh; - background-color: #1e1e1e; - border-right: 1px solid #333; - } -} - -/* Mobile (Phone) */ -@media (max-width: 767.98px) { - .app-sidebar { - position: fixed; - bottom: 0; - left: 0; - width: 100%; - z-index: 1050; - background-color: #121212 !important; - border-top: 1px solid #333; - padding: 10px 0 !important; - } - .sidebar-title { display: none; } - .app-sidebar .nav { - flex-direction: row !important; - justify-content: space-evenly; - } - .nav-btn { - display: flex; - flex-direction: column; - align-items: center; - padding: 5px; - font-size: 0.75rem; - } - .nav-icon { margin-right: 0; margin-bottom: 2px; } - - body { padding-bottom: 80px; } /* Prevents the menu from overlapping the content */ - .col-md-9 { padding: 15px !important; } /* Less lateral padding on mobile */ -} - -/* ========================================= - APP: HOME (DASHBOARD) - ========================================= */ -.disk-bar-container { background: #333; height: 25px; border-radius: 15px; overflow: hidden; display: flex; } -.disk-segment-used { background: #5dbca5; transition: width 1s ease-in-out; } -.disk-segment-free { background: rgba(255,255,255,0.1); flex-grow: 1; } -.stat-card { background: #1e1e1e; border: 1px solid #333; border-radius: 10px; padding: 20px; transition: border-color 0.2s; } -.stat-card:hover { border-color: #5dbca5; } -.icon-box { width: 50px; height: 50px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 24px; } - -/* ========================================= - APP: MAPS - ========================================= */ -.map-card { background-color: #1e1e1e; border: 1px solid #444; color: #ffffff; transition: 0.2s;} -.map-card:hover { border-color: #dc3545; } -.map-coords { color: #888; font-size: 0.85em; font-family: monospace; } - -/* ========================================= - APP: KIWIX - ========================================= */ -.collapse-btn-container { opacity: 0; transition: opacity 0.3s ease-in-out; text-align: center; margin-top: -10px; margin-bottom: 20px;} -#terminal-container:hover .collapse-btn-container, #maps-terminal-container:hover .collapse-btn-container { opacity: 1; } - -.filter-active { background-color: #198754 !important; color: white !important; border-color: #198754 !important;} -.filter-inactive { background-color: transparent !important; color: #198754 !important; border-color: #198754 !important;} - -/* ========================================= - FLOATING ADJUSTMENTS (Z-INDEX AND POSITION) - ========================================= */ -.floating-filter { - bottom: 0; -} - -/* On phones, move the button above the bottom menu */ -@media (max-width: 767.98px) { - .floating-filter { - bottom: 80px !important; - } - - /* ========================================= - MOBILE SPACING (CARD EXPERIENCE) - ========================================= */ - /* 1. Add margins to the main container to separate it from the phone edges */ - .app-panel { - padding-left: 15px !important; - padding-right: 15px !important; - } - - /* 2. Separate the terminal from the search box with a small top margin */ - #terminal, #kiwix-terminal { - margin-top: 15px !important; - } - - /* 3. The key: Force a bottom margin on EACH card when stacked (col-12) */ - .zim-card, .map-card { - margin-bottom: 15px !important; - } - - /* 4. Increase the general bottom padding to ensure the last card and floating button have space before the tab menu. */ - .app-panel.pb-5 { - padding-bottom: 120px !important; - } -} \ No newline at end of file diff --git a/android/dashboard/server.ts b/android/dashboard/server.ts deleted file mode 100644 index f57a1da..0000000 --- a/android/dashboard/server.ts +++ /dev/null @@ -1,44 +0,0 @@ -import express from 'express'; -import http from 'http'; -import { Server, Socket } from 'socket.io'; -import path from 'path'; - -// Import our modules (event controllers) -import { handleMapsEvents } from './sockets/maps.socket'; -import { handleKiwixEvents } from './sockets/kiwix.socket'; -import { handleHomeEvents } from './sockets/home.socket'; - -const app = express(); -const server = http.createServer(app); -const io = new Server(server); - -// EJS views and static files configuration -app.set('view engine', 'ejs'); -app.set('views', path.join(__dirname, 'views')); -app.use(express.static(path.join(__dirname, 'public'))); - -// Main route -app.get('/', (req, res) => { - res.render('index'); -}); - -// Main Socket Connection Handler -io.on('connection', (socket: Socket) => { - console.log(`A client has connected (ID: ${socket.id}).`); - - // Connect the wires to the modules - handleMapsEvents(socket); - handleKiwixEvents(socket); - handleHomeEvents(socket); - - socket.on('disconnect', () => { - console.log(`Client disconnected (ID: ${socket.id}).`); - }); -}); - -const PORT = 4000; -server.listen(PORT, () => { - console.log(`===========================================`); - console.log(`πŸš€ IIAB-oA Dashboard active on port ${PORT}`); - console.log(`===========================================`); -}); \ No newline at end of file diff --git a/android/dashboard/sockets/home.socket.ts b/android/dashboard/sockets/home.socket.ts deleted file mode 100644 index 407cff0..0000000 --- a/android/dashboard/sockets/home.socket.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { Socket } from 'socket.io'; -import os from 'os'; -import { exec } from 'child_process'; -import util from 'util'; - -const execPromise = util.promisify(exec); - -async function getSystemStats() { - let stats = { - hostname: os.hostname(), - ip: 'Unknown', - uptime: os.uptime(), - disk: { total: 0, used: 0, free: 0, percent: 0 }, - ram: { total: 0, used: 0, percent: 0 }, - swap: { total: 0, used: 0, percent: 0 } - }; - - // 1. GET IP (Plan A: Native | Plan B: raw ifconfig) - try { - const nets = os.networkInterfaces(); - for (const name of Object.keys(nets)) { - if (nets[name]) { - for (const net of nets[name]) { - if (net.family === 'IPv4' && !net.internal) { - stats.ip = net.address; break; - } - } - } - if (stats.ip !== 'Unknown') break; - } - } catch (e) {} - - // Architect's Plan B: Your ifconfig pipeline silencing the proot error - if (stats.ip === 'Unknown') { - try { - // The 2>/dev/null sends the "Warning: Permission denied" to the abyss - const { stdout } = await execPromise("ifconfig 2>/dev/null | grep inet | grep -v 127.0.0.1 | awk '{print $2}'"); - - const ips = stdout.trim().split('\n'); - if (ips.length > 0 && ips[0]) { - stats.ip = ips[0]; // We take the first valid IP it spits out - } - } catch (e) { - console.log('[Home] Plan B (ifconfig) failed or yielded no results.'); - } - } - - // 2. GET DISK (df -k /) - try { - const { stdout } = await execPromise('df -k /'); - const lines = stdout.trim().split('\n'); - if (lines.length > 1) { - const parts = lines[1].trim().split(/\s+/); - const total = parseInt(parts[1]) * 1024; - const used = parseInt(parts[2]) * 1024; - stats.disk = { - total, used, free: total - used, - percent: Math.round((used / total) * 100) - }; - } - } catch (e) {} - - // 3. GET RAM AND SWAP (free -b) - try { - const { stdout } = await execPromise('free -b'); - const lines = stdout.trim().split('\n'); - - // Parse RAM (Line 2) -> Mem: total used free ... - if (lines.length > 1) { - const ramParts = lines[1].trim().split(/\s+/); - const rTotal = parseInt(ramParts[1]); - const rUsed = parseInt(ramParts[2]); - stats.ram = { total: rTotal, used: rUsed, percent: Math.round((rUsed / rTotal) * 100) }; - } - - // Parse Swap (Line 3) -> Swap: total used free ... - if (lines.length > 2) { - const swapParts = lines[2].trim().split(/\s+/); - const sTotal = parseInt(swapParts[1]); - const sUsed = parseInt(swapParts[2]); - // Avoid division by zero if there is no Swap configured - stats.swap = { total: sTotal, used: sUsed, percent: sTotal > 0 ? Math.round((sUsed / sTotal) * 100) : 0 }; - } - } catch (e) { - console.log('[Home] Error reading memory (free -b). Using limited native data.'); - // Ultra-safe Node native fallback (Only gives RAM, no Swap) - stats.ram.total = os.totalmem(); - const free = os.freemem(); - stats.ram.used = stats.ram.total - free; - stats.ram.percent = Math.round((stats.ram.used / stats.ram.total) * 100); - } - - return stats; -} - -function formatBytes(bytes: number) { - if (bytes === 0 || isNaN(bytes)) return '0 B'; - const k = 1024; - const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; -} - -export const handleHomeEvents = (socket: Socket) => { - socket.on('request_home_stats', async () => { - const stats = await getSystemStats(); - - const uiData = { - hostname: stats.hostname, - ip: stats.ip, - uptime: Math.floor(stats.uptime / 60) + ' min', - diskTotal: formatBytes(stats.disk.total), - diskUsed: formatBytes(stats.disk.used), - diskFree: formatBytes(stats.disk.free), - diskPercent: stats.disk.percent, - ramUsed: formatBytes(stats.ram.used), - ramTotal: formatBytes(stats.ram.total), - ramPercent: stats.ram.percent, - swapUsed: formatBytes(stats.swap.used), - swapTotal: formatBytes(stats.swap.total), - swapPercent: stats.swap.percent - }; - - socket.emit('home_stats_ready', uiData); - }); -}; \ No newline at end of file diff --git a/android/dashboard/sockets/kiwix.socket.ts b/android/dashboard/sockets/kiwix.socket.ts deleted file mode 100644 index 90fa814..0000000 --- a/android/dashboard/sockets/kiwix.socket.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { Socket } from 'socket.io'; -import { spawn, ChildProcess } from 'child_process'; -import fs from 'fs'; -import path from 'path'; - -const ZIMS_DIR = '/library/zims/content/'; - -async function getKiwixCatalog() { - try { - console.log('[Kiwix] Querying server and cross-referencing with local disk...'); - const response = await fetch('https://download.kiwix.org/zim/wikipedia/'); - const html = await response.text(); - - let localFiles = new Set(); - if (fs.existsSync(ZIMS_DIR)) { - localFiles = new Set(fs.readdirSync(ZIMS_DIR)); - } - - const regex = /.*?<\/a>\s+([\d-]+ \d{2}:\d{2})\s+([0-9.]+[KMG]?)/g; - const results = []; - let match; - - while ((match = regex.exec(html)) !== null) { - const file = match[1]; - const fullDate = match[2]; - const size = match[3]; - - const cleanTitle = file.replace('.zim', '').split(/[-_]/).map((p, index) => { - if (index === 1) return p.toUpperCase(); - return p.charAt(0).toUpperCase() + p.slice(1); - }).join(' '); - - const isDownloaded = localFiles.has(file); - - results.push({ - id: file, - title: cleanTitle, - date: fullDate.split(' ')[0], - size: size, - isDownloaded: isDownloaded - }); - } - return results; - } catch (error) { - console.error('[Kiwix] Error querying the catalog:', error); - return []; - } -} - -export const handleKiwixEvents = (socket: Socket) => { - let downloadProcess: ChildProcess | null = null; - let indexProcess: ChildProcess | null = null; - let currentDownloads: string[] = []; - - socket.on('request_kiwix_catalog', async () => { - socket.emit('kiwix_status', { message: 'Synchronizing catalog with local disk...' }); - const catalog = await getKiwixCatalog(); - socket.emit('kiwix_catalog_ready', catalog); - }); - - socket.on('check_kiwix_tools', () => { - const hasAria2 = fs.existsSync('/usr/bin/aria2c'); - const hasIndexer = fs.existsSync('/usr/bin/iiab-make-kiwix-lib'); - socket.emit('kiwix_tools_status', { hasAria2, hasIndexer }); - }); - - socket.on('start_kiwix_download', (zims: string[]) => { - if (downloadProcess || indexProcess) { - socket.emit('kiwix_terminal_output', '\n[System] A process is already running.\n'); - return; - } - if (zims.length === 0) return; - - currentDownloads = zims; // Save what we are downloading - const baseUrl = 'https://download.kiwix.org/zim/wikipedia/'; - const urls = zims.map(zim => baseUrl + zim); - - socket.emit('kiwix_terminal_output', `\n[System] Starting download...\n`); - socket.emit('kiwix_process_status', { isRunning: true }); - - const args = ['-d', ZIMS_DIR, '-c', '-Z', '-x', '4', '-s', '4', '-j', '5', '--async-dns=false', ...urls]; - downloadProcess = spawn('/usr/bin/aria2c', args); - - downloadProcess.stdout?.on('data', (data) => socket.emit('kiwix_terminal_output', data.toString())); - downloadProcess.stderr?.on('data', (data) => socket.emit('kiwix_terminal_output', data.toString())); - - // Handle natural process exit - downloadProcess.on('exit', (code, signal) => { - downloadProcess = null; - - // If killed manually (Cancellation), ignore this block - if (signal === 'SIGKILL') return; - - if (code === 0) { - currentDownloads = []; - socket.emit('kiwix_terminal_output', `\n[System] 🟒 Downloads finished. Cleaning metadata...\n`); - - // Sweep left-over metadata - try { - const files = fs.readdirSync(ZIMS_DIR); - files.forEach(file => { - if (file.endsWith('.meta4') || file.endsWith('.aria2') || file.endsWith('.torrent')) { - fs.unlinkSync(path.join(ZIMS_DIR, file)); - } - }); - } catch (err) { - console.error('[System] Minor error cleaning metadata files:', err); - } - - socket.emit('kiwix_terminal_output', `[System] 🟒 Starting indexing...\n`); - if (fs.existsSync('/usr/bin/iiab-make-kiwix-lib')) { - indexProcess = spawn('/usr/bin/iiab-make-kiwix-lib'); - indexProcess.stdout?.on('data', (data) => socket.emit('kiwix_terminal_output', data.toString())); - - indexProcess.on('exit', (idxCode) => { - socket.emit('kiwix_terminal_output', `\n[System] 🏁 Indexing complete.\n`); - indexProcess = null; - socket.emit('kiwix_process_status', { isRunning: false }); - socket.emit('refresh_kiwix_catalog'); - }); - } else { - socket.emit('kiwix_process_status', { isRunning: false }); - socket.emit('refresh_kiwix_catalog'); - } - } else { - currentDownloads = []; - socket.emit('kiwix_process_status', { isRunning: false }); - } - }); - }); - - // CANCEL DOWNLOAD BUTTON - socket.on('cancel_kiwix_download', () => { - if (downloadProcess) { - socket.emit('kiwix_terminal_output', '\n[System] πŸ›‘ ABORTING: Killing Aria2c process...\n'); - - // 1. Kill the process (Ctrl+C equivalent) - downloadProcess.kill('SIGKILL'); - downloadProcess = null; - - // 2. Sweep the trash (Incomplete files) - socket.emit('kiwix_terminal_output', '[System] 🧹 Cleaning temporary and incomplete files...\n'); - currentDownloads.forEach(zim => { - const filePath = path.join(ZIMS_DIR, zim); - const ariaPath = filePath + '.aria2'; - - if (fs.existsSync(filePath)) fs.unlinkSync(filePath); // Delete the .zim - if (fs.existsSync(ariaPath)) fs.unlinkSync(ariaPath); // Delete the .aria2 map - }); - - currentDownloads = []; // Clear memory - - socket.emit('kiwix_terminal_output', '[System] βœ”οΈ Cancellation complete. System ready.\n'); - socket.emit('kiwix_process_status', { isRunning: false }); - socket.emit('refresh_kiwix_catalog'); - } - }); - - // Delete ZIMs from UI - socket.on('delete_zim', (zimId: string) => { - const filePath = path.join(ZIMS_DIR, zimId); - if (fs.existsSync(filePath)) { - socket.emit('kiwix_terminal_output', `\n[System] πŸ—‘οΈ Deleting file ${zimId}...\n`); - fs.unlinkSync(filePath); - - if (fs.existsSync('/usr/bin/iiab-make-kiwix-lib')) { - const idx = spawn('/usr/bin/iiab-make-kiwix-lib'); - idx.stdout?.on('data', (data) => socket.emit('kiwix_terminal_output', data.toString())); - idx.stderr?.on('data', (data) => socket.emit('kiwix_terminal_output', data.toString())); - - idx.on('exit', () => { - socket.emit('kiwix_terminal_output', `\n[System] 🏁 Index updated after deletion. Reloading interface...\n`); - socket.emit('refresh_kiwix_catalog'); - }); - } else { - socket.emit('kiwix_terminal_output', `\n[System] βœ… File deleted (no indexer). Reloading interface...\n`); - socket.emit('refresh_kiwix_catalog'); - } - } - }); - - socket.on('disconnect', () => { - if (downloadProcess) downloadProcess.kill('SIGKILL'); - if (indexProcess) indexProcess.kill('SIGKILL'); - }); -}; \ No newline at end of file diff --git a/android/dashboard/sockets/maps.socket.ts b/android/dashboard/sockets/maps.socket.ts deleted file mode 100644 index d59504d..0000000 --- a/android/dashboard/sockets/maps.socket.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { Socket } from 'socket.io'; -import { spawn, ChildProcess } from 'child_process'; -import fs from 'fs'; -import path from 'path'; - -// Critical paths in the backend -const SCRIPTS_DIR = '/opt/iiab/maps/tile-extract/'; -const EXTRACT_SCRIPT = path.join(SCRIPTS_DIR, 'tile-extract.py'); -const CATALOG_JSON = '/library/www/osm/maps/extracts.json'; - -// --- FUNCTION: Read existing regions from JSON --- -function getMapsCatalog() { - try { - if (!fs.existsSync(CATALOG_JSON)) return []; - - console.log('[Maps] Reading extracts.json catalog...'); - const fileContent = fs.readFileSync(CATALOG_JSON, 'utf8'); - const data = JSON.parse(fileContent); - - // Transform JSON format {"regions": {"name": [bbox...]}} - // to an array manageable by the web: [{name, bbox}] - const regions = []; - if (data && data.regions) { - for (const name in data.regions) { - // Format coordinates to 4 decimals so they look clean - const bbox = data.regions[name].map((coord: number) => coord.toFixed(4)); - regions.push({ - name: name, - bbox: bbox.join(', ') // "min_lon, min_lat, max_lon, max_lat" - }); - } - } - return regions; - } catch (error) { - console.error('[Maps] Error reading maps catalog:', error); - return []; - } -} - -// --- FUNCTION: The Security Regex Shield (Stricter) --- -// The region name MUST be lowercase letters, numbers, or underscore ONLY. -const regionNameRegex = /^[a-z0-9_]+$/; - -function validateSecureCommand(rawCommand: string): { type: string, region: string, bbox?: string, error?: string } { - const tokens = rawCommand.trim().split(/\s+/); - - // 1. Must start with sudo and point to the correct script - if (tokens[0] !== 'sudo' || tokens[1] !== EXTRACT_SCRIPT) { - return { type: '', region: '', error: 'The command does not start with sudo /opt/iiab/maps/tile-extract/tile-extract.py' }; - } - - const action = tokens[2]; // 'extract' or 'delete' - const regionName = tokens[3]; - - // 2. Validate the format of the region name - if (!regionName || !regionNameRegex.test(regionName)) { - return { type: '', region: '', error: 'SECURITY ERROR: The region name MUST contain ONLY lowercase letters, numbers, and underscores (_).' }; - } - - if (action === 'delete' && tokens.length === 4) { - // Variant 1: DELETE (sudo tile-extract.py delete desert1) - return { type: 'delete', region: regionName }; - } - - if (action === 'extract' && tokens.length === 5) { - // Variant 2: DOWNLOAD (sudo tile-extract.py extract desert1 bbox) - const bbox = tokens[4]; - if (!/^[-0-9.,]+$/.test(bbox)) { - return { type: '', region: '', error: 'ERROR: The coordinates (Bounding Box) have an invalid format.' }; - } - return { type: 'extract', region: regionName, bbox: bbox }; - } - - // 3. Anything else is an error - return { type: '', region: '', error: 'Invalid command format. Only sudo [script] extract {region} {bbox} OR sudo [script] delete {region} are allowed.' }; -} - -export const handleMapsEvents = (socket: Socket) => { - let scriptProcess: ChildProcess | null = null; - - // A. Send catalog to the web - socket.on('request_maps_catalog', () => { - const catalog = getMapsCatalog(); - socket.emit('maps_catalog_ready', catalog); - }); - - // B. Process raw order (copy-paste) with strict validation - socket.on('start_command', (config: { rawCommand: string }) => { - if (scriptProcess) { - socket.emit('terminal_output', '\n[System] A process is already running.\n'); - return; - } - - const validation = validateSecureCommand(config.rawCommand); - - if (validation.error) { - socket.emit('terminal_output', `\n[System] SECURITY ERROR: ${validation.error}\n`); - return; - } - - let args = [EXTRACT_SCRIPT, validation.type, validation.region]; - if (validation.type === 'extract' && validation.bbox) args.push(validation.bbox); - - socket.emit('terminal_output', `[System] Valid command. Starting action [${validation.type}] for region: ${validation.region}...\n`); - - scriptProcess = spawn('sudo', args, { env: { ...process.env, PYTHONUNBUFFERED: '1' } }); - - socket.emit('process_status', { isRunning: true }); - - scriptProcess.stdout?.on('data', (data) => socket.emit('terminal_output', data.toString())); - scriptProcess.stderr?.on('data', (data) => socket.emit('terminal_output', data.toString())); - - scriptProcess.on('exit', (code) => { - scriptProcess = null; - socket.emit('terminal_output', `\n[System] Process [${validation.type}] finished with code ${code}\n`); - socket.emit('process_status', { isRunning: false }); - // Reload catalog if successful - if (code === 0) { - const catalog = getMapsCatalog(); - socket.emit('maps_catalog_ready', catalog); - } - }); - }); - - // C. Process direct card deletion (Intelligent UI) - socket.on('delete_map_region', (regionName: string) => { - if (scriptProcess) return; - - // Double security check just in case - if (!regionNameRegex.test(regionName)) { - socket.emit('terminal_output', `\n[System] ERROR: Invalid region name for deletion: ${regionName}\n`); - return; - } - - socket.emit('terminal_output', `[System] Starting direct deletion for region: ${regionName}...\n`); - - scriptProcess = spawn('sudo', [EXTRACT_SCRIPT, 'delete', regionName], { env: { ...process.env, PYTHONUNBUFFERED: '1' } }); - socket.emit('process_status', { isRunning: true }); - - scriptProcess.stdout?.on('data', (data) => socket.emit('terminal_output', data.toString())); - scriptProcess.on('exit', (code) => { - scriptProcess = null; - if (code === 0) { - socket.emit('terminal_output', `\n[System] πŸ—‘οΈ Region ${regionName} successfully deleted from JSON.\n`); - // Send updated catalog - const catalog = getMapsCatalog(); - socket.emit('maps_catalog_ready', catalog); - } else { - socket.emit('terminal_output', `\n[System] Error deleting region ${regionName}. Code ${code}\n`); - } - socket.emit('process_status', { isRunning: false }); - }); - }); - - socket.on('send_input', (input: string) => { - if (scriptProcess && scriptProcess.stdin) { - scriptProcess.stdin.write(`${input}\n`); - } - }); - - socket.on('disconnect', () => { - if (scriptProcess) scriptProcess.kill(); - }); -}; \ No newline at end of file diff --git a/android/dashboard/tsconfig.json b/android/dashboard/tsconfig.json deleted file mode 100644 index 0f71468..0000000 --- a/android/dashboard/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "module": "commonjs", - "moduleResolution": "node16", - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "skipLibCheck": true - } -} diff --git a/android/dashboard/views/components/app_home.ejs b/android/dashboard/views/components/app_home.ejs deleted file mode 100644 index efc2a14..0000000 --- a/android/dashboard/views/components/app_home.ejs +++ /dev/null @@ -1,102 +0,0 @@ -
- -
-
-

My Digital Library

-
- Loading...  Β·  - IP: ...  Β·  - Uptime: ... -
-
-
- Online -
-
- -
- -
-
- πŸ’Ύ Main Storage - ... / ... -
-
-
-
-
-
- -
-
-
- ⚑ RAM Memory - ... -
-
-
-
-
-
- -
-
- πŸ’½ Swap (Virtual) - ... -
-
-
-
-
-
-
- -
- -

Installed Modules

-
-
-
-
πŸ“š
-
-
Kiwix Manager
-
Browse and download Wikipedia offline
-
-
-
-
-
-
πŸ—ΊοΈ
-
-
Map Extractor
-
Manage OpenStreetMap tiles
-
-
-
-
-
- - \ No newline at end of file diff --git a/android/dashboard/views/components/app_kiwix.ejs b/android/dashboard/views/components/app_kiwix.ejs deleted file mode 100644 index 729d366..0000000 --- a/android/dashboard/views/components/app_kiwix.ejs +++ /dev/null @@ -1,277 +0,0 @@ -
-

Kiwix Repository - Wikipedia

- -
- - Connecting to local server... -
- -
- -
- -
- - -
- - Selected: 0 / - - -
-
- -
-
Waiting for commands...
- -
- - -
-
- -
- -
- -
-
- - - - - - - - \ No newline at end of file diff --git a/android/dashboard/views/components/app_maps.ejs b/android/dashboard/views/components/app_maps.ejs deleted file mode 100644 index 3254ed7..0000000 --- a/android/dashboard/views/components/app_maps.ejs +++ /dev/null @@ -1,174 +0,0 @@ -
-

Map Extraction Dashboard

- -
- -
-
- -
-
- -
-
-
- -
-
Waiting for commands...
- -
- -
-
- -
-
- ⚠️ The system requires your confirmation to continue: -
- - -
-
-
- -
- -
-

πŸ—ΊοΈ Existing Regions on Maps Server

- -
- -
- - Loading server catalog... -
- -
-
-
- - \ No newline at end of file diff --git a/android/dashboard/views/components/sidebar.ejs b/android/dashboard/views/components/sidebar.ejs deleted file mode 100644 index 492506e..0000000 --- a/android/dashboard/views/components/sidebar.ejs +++ /dev/null @@ -1,24 +0,0 @@ -
\ No newline at end of file diff --git a/android/dashboard/views/index.ejs b/android/dashboard/views/index.ejs deleted file mode 100644 index 97b0ae6..0000000 --- a/android/dashboard/views/index.ejs +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - IIAB-oA | Dashboard - - - - - - - - - -
-
- <%- include('./components/sidebar') %> - -
- <%- include('./components/app_home') %> - <%- include('./components/app_maps') %> - <%- include('./components/app_kiwix') %> -
-
-
- - \ No newline at end of file