feat: bypass administrador en memoria para desarrollo
This commit is contained in:
@@ -7,3 +7,11 @@ GEMINI_API_KEY="MY_GEMINI_API_KEY"
|
|||||||
# AI Studio automatically injects this at runtime with the Cloud Run service URL.
|
# AI Studio automatically injects this at runtime with the Cloud Run service URL.
|
||||||
# Used for self-referential links, OAuth callbacks, and API endpoints.
|
# Used for self-referential links, OAuth callbacks, and API endpoints.
|
||||||
APP_URL="MY_APP_URL"
|
APP_URL="MY_APP_URL"
|
||||||
|
|
||||||
|
# MongoDB Configuration
|
||||||
|
MONGODB_URI="mongodb://127.0.0.1:27017"
|
||||||
|
DB_NAME="hospital"
|
||||||
|
|
||||||
|
# Default Admin Credentials (Optional, defaults will be used if not set)
|
||||||
|
ADMIN_DNI="12345678"
|
||||||
|
ADMIN_PASSWORD="admin123"
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
"@radix-ui/react-toggle-group": "^1.1.11",
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||||
"@radix-ui/react-tooltip": "^1.2.8",
|
"@radix-ui/react-tooltip": "^1.2.8",
|
||||||
"bcryptjs": "^3.0.3",
|
"bcryptjs": "^3.0.3",
|
||||||
"better-sqlite3": "^12.9.0",
|
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cmdk": "^1.1.1",
|
"cmdk": "^1.1.1",
|
||||||
@@ -44,7 +43,7 @@
|
|||||||
"input-otp": "^1.4.2",
|
"input-otp": "^1.4.2",
|
||||||
"jspdf": "^4.2.1",
|
"jspdf": "^4.2.1",
|
||||||
"lucide-react": "^0.562.0",
|
"lucide-react": "^0.562.0",
|
||||||
"mariadb": "^3.5.2",
|
"mongodb": "^7.5.0",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
@@ -54,8 +53,6 @@
|
|||||||
"react-resizable-panels": "^4.2.2",
|
"react-resizable-panels": "^4.2.2",
|
||||||
"recharts": "^2.15.4",
|
"recharts": "^2.15.4",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
"sqlite": "^4.2.1",
|
|
||||||
"sqlite3": "^5.1.6",
|
|
||||||
"tailwind-merge": "^3.4.0",
|
"tailwind-merge": "^3.4.0",
|
||||||
"vaul": "^1.1.2",
|
"vaul": "^1.1.2",
|
||||||
"zod": "^4.3.5",
|
"zod": "^4.3.5",
|
||||||
@@ -372,8 +369,6 @@
|
|||||||
|
|
||||||
"@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="],
|
"@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="],
|
||||||
|
|
||||||
"@gar/promisify": ["@gar/promisify@1.1.3", "", {}, "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw=="],
|
|
||||||
|
|
||||||
"@hookform/resolvers": ["@hookform/resolvers@5.2.2", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.55.0" } }, "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA=="],
|
"@hookform/resolvers": ["@hookform/resolvers@5.2.2", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.55.0" } }, "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA=="],
|
||||||
|
|
||||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||||
@@ -394,16 +389,14 @@
|
|||||||
|
|
||||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
||||||
|
|
||||||
|
"@mongodb-js/saslprep": ["@mongodb-js/saslprep@1.4.13", "", { "dependencies": { "sparse-bitfield": "^3.0.3" } }, "sha512-E3Sv4eCYAlKYUTx8S3ioQcDUscOif+8zZ5OnW1IzJ+Tt+EO+ke8mn+Y3FX6N1H79picwbdOavVOb1jPi2EOyrg=="],
|
||||||
|
|
||||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||||
|
|
||||||
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
|
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
|
||||||
|
|
||||||
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
||||||
|
|
||||||
"@npmcli/fs": ["@npmcli/fs@1.1.1", "", { "dependencies": { "@gar/promisify": "^1.0.1", "semver": "^7.3.5" } }, "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ=="],
|
|
||||||
|
|
||||||
"@npmcli/move-file": ["@npmcli/move-file@1.1.2", "", { "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" } }, "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg=="],
|
|
||||||
|
|
||||||
"@pdf-lib/standard-fonts": ["@pdf-lib/standard-fonts@1.0.0", "", { "dependencies": { "pako": "^1.0.6" } }, "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA=="],
|
"@pdf-lib/standard-fonts": ["@pdf-lib/standard-fonts@1.0.0", "", { "dependencies": { "pako": "^1.0.6" } }, "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA=="],
|
||||||
|
|
||||||
"@pdf-lib/upng": ["@pdf-lib/upng@1.0.1", "", { "dependencies": { "pako": "^1.0.10" } }, "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ=="],
|
"@pdf-lib/upng": ["@pdf-lib/upng@1.0.1", "", { "dependencies": { "pako": "^1.0.10" } }, "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ=="],
|
||||||
@@ -570,8 +563,6 @@
|
|||||||
|
|
||||||
"@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="],
|
"@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="],
|
||||||
|
|
||||||
"@tootallnate/once": ["@tootallnate/once@1.1.2", "", {}, "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw=="],
|
|
||||||
|
|
||||||
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
|
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
|
||||||
|
|
||||||
"@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="],
|
"@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="],
|
||||||
@@ -600,8 +591,6 @@
|
|||||||
|
|
||||||
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||||
|
|
||||||
"@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="],
|
|
||||||
|
|
||||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@24.10.4", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg=="],
|
"@types/node": ["@types/node@24.10.4", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg=="],
|
||||||
@@ -616,6 +605,10 @@
|
|||||||
|
|
||||||
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
|
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
|
||||||
|
|
||||||
|
"@types/webidl-conversions": ["@types/webidl-conversions@7.0.3", "", {}, "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA=="],
|
||||||
|
|
||||||
|
"@types/whatwg-url": ["@types/whatwg-url@13.0.0", "", { "dependencies": { "@types/webidl-conversions": "*" } }, "sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q=="],
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.52.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.52.0", "@typescript-eslint/type-utils": "8.52.0", "@typescript-eslint/utils": "8.52.0", "@typescript-eslint/visitor-keys": "8.52.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.52.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q=="],
|
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.52.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.52.0", "@typescript-eslint/type-utils": "8.52.0", "@typescript-eslint/utils": "8.52.0", "@typescript-eslint/visitor-keys": "8.52.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.52.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q=="],
|
||||||
|
|
||||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.52.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.52.0", "@typescript-eslint/types": "8.52.0", "@typescript-eslint/typescript-estree": "8.52.0", "@typescript-eslint/visitor-keys": "8.52.0", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg=="],
|
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.52.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.52.0", "@typescript-eslint/types": "8.52.0", "@typescript-eslint/typescript-estree": "8.52.0", "@typescript-eslint/visitor-keys": "8.52.0", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg=="],
|
||||||
@@ -638,34 +631,20 @@
|
|||||||
|
|
||||||
"@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.2", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.53", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ=="],
|
"@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.2", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.53", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ=="],
|
||||||
|
|
||||||
"abbrev": ["abbrev@1.1.1", "", {}, "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="],
|
|
||||||
|
|
||||||
"accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="],
|
"accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="],
|
||||||
|
|
||||||
"acorn": ["acorn@8.15.0", "", { "bin": "bin/acorn" }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
"acorn": ["acorn@8.15.0", "", { "bin": "bin/acorn" }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||||
|
|
||||||
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
||||||
|
|
||||||
"agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
|
|
||||||
|
|
||||||
"agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="],
|
|
||||||
|
|
||||||
"aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="],
|
|
||||||
|
|
||||||
"ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="],
|
"ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="],
|
||||||
|
|
||||||
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
||||||
|
|
||||||
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||||
|
|
||||||
"any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="],
|
"any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="],
|
||||||
|
|
||||||
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
|
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
|
||||||
|
|
||||||
"aproba": ["aproba@2.1.0", "", {}, "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew=="],
|
|
||||||
|
|
||||||
"are-we-there-yet": ["are-we-there-yet@3.0.1", "", { "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" } }, "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg=="],
|
|
||||||
|
|
||||||
"arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
|
"arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
|
||||||
|
|
||||||
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||||
@@ -686,20 +665,12 @@
|
|||||||
|
|
||||||
"base64-arraybuffer": ["base64-arraybuffer@1.0.2", "", {}, "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="],
|
"base64-arraybuffer": ["base64-arraybuffer@1.0.2", "", {}, "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="],
|
||||||
|
|
||||||
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
|
||||||
|
|
||||||
"baseline-browser-mapping": ["baseline-browser-mapping@2.9.11", "", { "bin": "dist/cli.js" }, "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ=="],
|
"baseline-browser-mapping": ["baseline-browser-mapping@2.9.11", "", { "bin": "dist/cli.js" }, "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ=="],
|
||||||
|
|
||||||
"bcryptjs": ["bcryptjs@3.0.3", "", { "bin": { "bcrypt": "bin/bcrypt" } }, "sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g=="],
|
"bcryptjs": ["bcryptjs@3.0.3", "", { "bin": { "bcrypt": "bin/bcrypt" } }, "sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g=="],
|
||||||
|
|
||||||
"better-sqlite3": ["better-sqlite3@12.9.0", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ=="],
|
|
||||||
|
|
||||||
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
|
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
|
||||||
|
|
||||||
"bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="],
|
|
||||||
|
|
||||||
"bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
|
|
||||||
|
|
||||||
"body-parser": ["body-parser@1.20.4", "", { "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.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", "qs": "~6.14.0", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" } }, "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA=="],
|
"body-parser": ["body-parser@1.20.4", "", { "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.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", "qs": "~6.14.0", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" } }, "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA=="],
|
||||||
|
|
||||||
"brace-expansion": ["brace-expansion@1.1.14", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g=="],
|
"brace-expansion": ["brace-expansion@1.1.14", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g=="],
|
||||||
@@ -708,12 +679,10 @@
|
|||||||
|
|
||||||
"browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": "cli.js" }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
|
"browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": "cli.js" }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
|
||||||
|
|
||||||
"buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
"bson": ["bson@7.3.1", "", {}, "sha512-h/C0qe6857pQhcSJHLfsR1uYGj98Ge3wKAD3Ed9KqH3wcVh+BM4Jq4xISD7vs9OPuT07n+q3QQVjslJ286j6ag=="],
|
||||||
|
|
||||||
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
|
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
|
||||||
|
|
||||||
"cacache": ["cacache@15.3.0", "", { "dependencies": { "@npmcli/fs": "^1.0.0", "@npmcli/move-file": "^1.0.1", "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "glob": "^7.1.4", "infer-owner": "^1.0.4", "lru-cache": "^6.0.0", "minipass": "^3.1.1", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.2", "mkdirp": "^1.0.3", "p-map": "^4.0.0", "promise-inflight": "^1.0.1", "rimraf": "^3.0.2", "ssri": "^8.0.1", "tar": "^6.0.2", "unique-filename": "^1.1.1" } }, "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ=="],
|
|
||||||
|
|
||||||
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
||||||
|
|
||||||
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
|
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
|
||||||
@@ -730,12 +699,8 @@
|
|||||||
|
|
||||||
"chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
|
"chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
|
||||||
|
|
||||||
"chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="],
|
|
||||||
|
|
||||||
"class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="],
|
"class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="],
|
||||||
|
|
||||||
"clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="],
|
|
||||||
|
|
||||||
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
||||||
|
|
||||||
"cmdk": ["cmdk@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-id": "^1.1.0", "@radix-ui/react-primitive": "^2.0.2" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg=="],
|
"cmdk": ["cmdk@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-id": "^1.1.0", "@radix-ui/react-primitive": "^2.0.2" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg=="],
|
||||||
@@ -744,14 +709,10 @@
|
|||||||
|
|
||||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||||
|
|
||||||
"color-support": ["color-support@1.1.3", "", { "bin": "bin.js" }, "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="],
|
|
||||||
|
|
||||||
"commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="],
|
"commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="],
|
||||||
|
|
||||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||||
|
|
||||||
"console-control-strings": ["console-control-strings@1.1.0", "", {}, "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="],
|
|
||||||
|
|
||||||
"content-disposition": ["content-disposition@0.5.4", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="],
|
"content-disposition": ["content-disposition@0.5.4", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="],
|
||||||
|
|
||||||
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
|
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
|
||||||
@@ -806,22 +767,12 @@
|
|||||||
|
|
||||||
"decimal.js-light": ["decimal.js-light@2.5.1", "", {}, "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="],
|
"decimal.js-light": ["decimal.js-light@2.5.1", "", {}, "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="],
|
||||||
|
|
||||||
"decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="],
|
|
||||||
|
|
||||||
"deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
|
|
||||||
|
|
||||||
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
||||||
|
|
||||||
"delegates": ["delegates@1.0.0", "", {}, "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="],
|
|
||||||
|
|
||||||
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
|
|
||||||
|
|
||||||
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
||||||
|
|
||||||
"destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="],
|
"destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="],
|
||||||
|
|
||||||
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
|
||||||
|
|
||||||
"detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
|
"detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
|
||||||
|
|
||||||
"didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="],
|
"didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="],
|
||||||
@@ -844,18 +795,8 @@
|
|||||||
|
|
||||||
"embla-carousel-reactive-utils": ["embla-carousel-reactive-utils@8.6.0", "", { "peerDependencies": { "embla-carousel": "8.6.0" } }, "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A=="],
|
"embla-carousel-reactive-utils": ["embla-carousel-reactive-utils@8.6.0", "", { "peerDependencies": { "embla-carousel": "8.6.0" } }, "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A=="],
|
||||||
|
|
||||||
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
|
||||||
|
|
||||||
"encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
|
"encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
|
||||||
|
|
||||||
"encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="],
|
|
||||||
|
|
||||||
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
|
|
||||||
|
|
||||||
"env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="],
|
|
||||||
|
|
||||||
"err-code": ["err-code@2.0.3", "", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="],
|
|
||||||
|
|
||||||
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
||||||
|
|
||||||
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
||||||
@@ -894,8 +835,6 @@
|
|||||||
|
|
||||||
"eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="],
|
"eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="],
|
||||||
|
|
||||||
"expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="],
|
|
||||||
|
|
||||||
"express": ["express@4.22.1", "", { "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.14.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" } }, "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g=="],
|
"express": ["express@4.22.1", "", { "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.14.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" } }, "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g=="],
|
||||||
|
|
||||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||||
@@ -918,8 +857,6 @@
|
|||||||
|
|
||||||
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
||||||
|
|
||||||
"file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="],
|
|
||||||
|
|
||||||
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
||||||
|
|
||||||
"finalhandler": ["finalhandler@1.3.2", "", { "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.2", "unpipe": "~1.0.0" } }, "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg=="],
|
"finalhandler": ["finalhandler@1.3.2", "", { "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.2", "unpipe": "~1.0.0" } }, "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg=="],
|
||||||
@@ -936,18 +873,10 @@
|
|||||||
|
|
||||||
"fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="],
|
"fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="],
|
||||||
|
|
||||||
"fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
|
|
||||||
|
|
||||||
"fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="],
|
|
||||||
|
|
||||||
"fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
|
|
||||||
|
|
||||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||||
|
|
||||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||||
|
|
||||||
"gauge": ["gauge@4.0.4", "", { "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.3", "console-control-strings": "^1.1.0", "has-unicode": "^2.0.1", "signal-exit": "^3.0.7", "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "wide-align": "^1.1.5" } }, "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg=="],
|
|
||||||
|
|
||||||
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
|
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
|
||||||
|
|
||||||
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "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" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "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" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
||||||
@@ -956,24 +885,16 @@
|
|||||||
|
|
||||||
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
||||||
|
|
||||||
"github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="],
|
|
||||||
|
|
||||||
"glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
|
|
||||||
|
|
||||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||||
|
|
||||||
"globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="],
|
"globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="],
|
||||||
|
|
||||||
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
||||||
|
|
||||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
|
||||||
|
|
||||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||||
|
|
||||||
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
|
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
|
||||||
|
|
||||||
"has-unicode": ["has-unicode@2.0.1", "", {}, "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="],
|
|
||||||
|
|
||||||
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
||||||
|
|
||||||
"hermes-estree": ["hermes-estree@0.25.1", "", {}, "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw=="],
|
"hermes-estree": ["hermes-estree@0.25.1", "", {}, "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw=="],
|
||||||
@@ -982,19 +903,9 @@
|
|||||||
|
|
||||||
"html2canvas": ["html2canvas@1.4.1", "", { "dependencies": { "css-line-break": "^2.1.0", "text-segmentation": "^1.0.3" } }, "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA=="],
|
"html2canvas": ["html2canvas@1.4.1", "", { "dependencies": { "css-line-break": "^2.1.0", "text-segmentation": "^1.0.3" } }, "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA=="],
|
||||||
|
|
||||||
"http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="],
|
|
||||||
|
|
||||||
"http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
|
"http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
|
||||||
|
|
||||||
"http-proxy-agent": ["http-proxy-agent@4.0.1", "", { "dependencies": { "@tootallnate/once": "1", "agent-base": "6", "debug": "4" } }, "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg=="],
|
"iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="],
|
||||||
|
|
||||||
"https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
|
|
||||||
|
|
||||||
"humanize-ms": ["humanize-ms@1.2.1", "", { "dependencies": { "ms": "^2.0.0" } }, "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ=="],
|
|
||||||
|
|
||||||
"iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
|
|
||||||
|
|
||||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
|
||||||
|
|
||||||
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
||||||
|
|
||||||
@@ -1002,24 +913,14 @@
|
|||||||
|
|
||||||
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
||||||
|
|
||||||
"indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="],
|
|
||||||
|
|
||||||
"infer-owner": ["infer-owner@1.0.4", "", {}, "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="],
|
|
||||||
|
|
||||||
"inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="],
|
|
||||||
|
|
||||||
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||||
|
|
||||||
"ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
|
|
||||||
|
|
||||||
"input-otp": ["input-otp@1.4.2", "", { "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA=="],
|
"input-otp": ["input-otp@1.4.2", "", { "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA=="],
|
||||||
|
|
||||||
"internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
|
"internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
|
||||||
|
|
||||||
"iobuffer": ["iobuffer@5.4.0", "", {}, "sha512-DRebOWuqDvxunfkNJAlc3IzWIPD5xVxwUNbHr7xKB8E6aLJxIPfNX3CoMJghcFjpv6RWQsrcJbghtEwSPoJqMA=="],
|
"iobuffer": ["iobuffer@5.4.0", "", {}, "sha512-DRebOWuqDvxunfkNJAlc3IzWIPD5xVxwUNbHr7xKB8E6aLJxIPfNX3CoMJghcFjpv6RWQsrcJbghtEwSPoJqMA=="],
|
||||||
|
|
||||||
"ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="],
|
|
||||||
|
|
||||||
"ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
|
"ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
|
||||||
|
|
||||||
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
|
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
|
||||||
@@ -1028,12 +929,8 @@
|
|||||||
|
|
||||||
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
||||||
|
|
||||||
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
|
|
||||||
|
|
||||||
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
||||||
|
|
||||||
"is-lambda": ["is-lambda@1.0.1", "", {}, "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="],
|
|
||||||
|
|
||||||
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
|
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
|
||||||
|
|
||||||
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
||||||
@@ -1076,20 +973,18 @@
|
|||||||
|
|
||||||
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": "cli.js" }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
|
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": "cli.js" }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
|
||||||
|
|
||||||
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
||||||
|
|
||||||
"lucide-react": ["lucide-react@0.562.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw=="],
|
"lucide-react": ["lucide-react@0.562.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw=="],
|
||||||
|
|
||||||
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||||
|
|
||||||
"make-fetch-happen": ["make-fetch-happen@9.1.0", "", { "dependencies": { "agentkeepalive": "^4.1.3", "cacache": "^15.2.0", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^4.0.1", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", "lru-cache": "^6.0.0", "minipass": "^3.1.3", "minipass-collect": "^1.0.2", "minipass-fetch": "^1.3.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.2", "promise-retry": "^2.0.1", "socks-proxy-agent": "^6.0.0", "ssri": "^8.0.0" } }, "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg=="],
|
|
||||||
|
|
||||||
"mariadb": ["mariadb@3.5.2", "", { "dependencies": { "@types/geojson": "^7946.0.16", "@types/node": ">=18", "denque": "^2.1.0", "iconv-lite": "^0.7.2", "lru-cache": "^10.4.3" } }, "sha512-9rztrI4nouxAY/82a+RlzzZ5ie2vxu2eYclkBvTy1ATXH1B9cnvZ0O71Pzsy/mlfDb5P3HhOg0JzQKkDRhctyA=="],
|
|
||||||
|
|
||||||
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||||
|
|
||||||
"media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="],
|
"media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="],
|
||||||
|
|
||||||
|
"memory-pager": ["memory-pager@1.5.0", "", {}, "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg=="],
|
||||||
|
|
||||||
"merge-descriptors": ["merge-descriptors@1.0.3", "", {}, "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="],
|
"merge-descriptors": ["merge-descriptors@1.0.3", "", {}, "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="],
|
||||||
|
|
||||||
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
||||||
@@ -1104,29 +999,11 @@
|
|||||||
|
|
||||||
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
||||||
|
|
||||||
"mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="],
|
|
||||||
|
|
||||||
"minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
"minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
||||||
|
|
||||||
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
"mongodb": ["mongodb@7.5.0", "", { "dependencies": { "@mongodb-js/saslprep": "^1.4.11", "bson": "^7.2.0", "mongodb-connection-string-url": "^7.0.1" }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.806.0", "@mongodb-js/zstd": "^7.0.0", "gcp-metadata": "^7.0.1", "kerberos": "^7.0.0", "mongodb-client-encryption": "^7.2.0", "snappy": "^7.3.2", "socks": "^2.8.6" }, "optionalPeers": ["@aws-sdk/credential-providers", "@mongodb-js/zstd", "gcp-metadata", "kerberos", "mongodb-client-encryption", "snappy", "socks"] }, "sha512-5FnrEDLnvp6ycUOGLNLLU33BfCx2qmp2mJjGPDwKLruYsVzXVSK5fsGpoDXvsXJwBfBsD7ebMRdawbDxC2814g=="],
|
||||||
|
|
||||||
"minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
|
"mongodb-connection-string-url": ["mongodb-connection-string-url@7.0.2", "", { "dependencies": { "@types/whatwg-url": "^13.0.0", "whatwg-url": "^14.1.0" } }, "sha512-ZoS07RoFqpKYQwAk59qmrx8+jJHNHU30UjlU96QktiGn1ltvDr+vCznLX5DiUBLEpMAHatHNWV1nM/74ul66kA=="],
|
||||||
|
|
||||||
"minipass-collect": ["minipass-collect@1.0.2", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA=="],
|
|
||||||
|
|
||||||
"minipass-fetch": ["minipass-fetch@1.4.1", "", { "dependencies": { "minipass": "^3.1.0", "minipass-sized": "^1.0.3", "minizlib": "^2.0.0" }, "optionalDependencies": { "encoding": "^0.1.12" } }, "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw=="],
|
|
||||||
|
|
||||||
"minipass-flush": ["minipass-flush@1.0.7", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA=="],
|
|
||||||
|
|
||||||
"minipass-pipeline": ["minipass-pipeline@1.2.4", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="],
|
|
||||||
|
|
||||||
"minipass-sized": ["minipass-sized@1.0.3", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g=="],
|
|
||||||
|
|
||||||
"minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
|
|
||||||
|
|
||||||
"mkdirp": ["mkdirp@1.0.4", "", { "bin": "bin/cmd.js" }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
|
|
||||||
|
|
||||||
"mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="],
|
|
||||||
|
|
||||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||||
|
|
||||||
@@ -1134,28 +1011,16 @@
|
|||||||
|
|
||||||
"nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
"nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||||
|
|
||||||
"napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="],
|
|
||||||
|
|
||||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||||
|
|
||||||
"negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
|
"negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
|
||||||
|
|
||||||
"next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="],
|
"next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="],
|
||||||
|
|
||||||
"node-abi": ["node-abi@3.89.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA=="],
|
|
||||||
|
|
||||||
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
|
||||||
|
|
||||||
"node-gyp": ["node-gyp@8.4.1", "", { "dependencies": { "env-paths": "^2.2.0", "glob": "^7.1.4", "graceful-fs": "^4.2.6", "make-fetch-happen": "^9.1.0", "nopt": "^5.0.0", "npmlog": "^6.0.0", "rimraf": "^3.0.2", "semver": "^7.3.5", "tar": "^6.1.2", "which": "^2.0.2" }, "bin": "bin/node-gyp.js" }, "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w=="],
|
|
||||||
|
|
||||||
"node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
|
"node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
|
||||||
|
|
||||||
"nopt": ["nopt@5.0.0", "", { "dependencies": { "abbrev": "1" }, "bin": "bin/nopt.js" }, "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ=="],
|
|
||||||
|
|
||||||
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
|
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
|
||||||
|
|
||||||
"npmlog": ["npmlog@6.0.2", "", { "dependencies": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", "gauge": "^4.0.3", "set-blocking": "^2.0.0" } }, "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg=="],
|
|
||||||
|
|
||||||
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
||||||
|
|
||||||
"object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="],
|
"object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="],
|
||||||
@@ -1164,16 +1029,12 @@
|
|||||||
|
|
||||||
"on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
|
"on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
|
||||||
|
|
||||||
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
|
|
||||||
|
|
||||||
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
|
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
|
||||||
|
|
||||||
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
||||||
|
|
||||||
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
||||||
|
|
||||||
"p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" } }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="],
|
|
||||||
|
|
||||||
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
|
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
|
||||||
|
|
||||||
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
|
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
|
||||||
@@ -1182,8 +1043,6 @@
|
|||||||
|
|
||||||
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
|
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
|
||||||
|
|
||||||
"path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="],
|
|
||||||
|
|
||||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||||
|
|
||||||
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
|
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
|
||||||
@@ -1216,20 +1075,12 @@
|
|||||||
|
|
||||||
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
|
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
|
||||||
|
|
||||||
"prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": "bin.js" }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="],
|
|
||||||
|
|
||||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||||
|
|
||||||
"promise-inflight": ["promise-inflight@1.0.1", "", {}, "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g=="],
|
|
||||||
|
|
||||||
"promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="],
|
|
||||||
|
|
||||||
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
|
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
|
||||||
|
|
||||||
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
|
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
|
||||||
|
|
||||||
"pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="],
|
|
||||||
|
|
||||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||||
|
|
||||||
"qs": ["qs@6.14.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q=="],
|
"qs": ["qs@6.14.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q=="],
|
||||||
@@ -1242,8 +1093,6 @@
|
|||||||
|
|
||||||
"raw-body": ["raw-body@2.5.3", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "unpipe": "~1.0.0" } }, "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA=="],
|
"raw-body": ["raw-body@2.5.3", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "unpipe": "~1.0.0" } }, "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA=="],
|
||||||
|
|
||||||
"rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": "cli.js" }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
|
|
||||||
|
|
||||||
"react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="],
|
"react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="],
|
||||||
|
|
||||||
"react-day-picker": ["react-day-picker@9.13.0", "", { "dependencies": { "@date-fns/tz": "^1.4.1", "date-fns": "^4.1.0", "date-fns-jalali": "^4.1.0-0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-euzj5Hlq+lOHqI53NiuNhCP8HWgsPf/bBAVijR50hNaY1XwjKjShAnIe8jm8RD2W9IJUvihDIZ+KrmqfFzNhFQ=="],
|
"react-day-picker": ["react-day-picker@9.13.0", "", { "dependencies": { "@date-fns/tz": "^1.4.1", "date-fns": "^4.1.0", "date-fns-jalali": "^4.1.0-0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-euzj5Hlq+lOHqI53NiuNhCP8HWgsPf/bBAVijR50hNaY1XwjKjShAnIe8jm8RD2W9IJUvihDIZ+KrmqfFzNhFQ=="],
|
||||||
@@ -1270,8 +1119,6 @@
|
|||||||
|
|
||||||
"read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
|
"read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
|
||||||
|
|
||||||
"readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
|
||||||
|
|
||||||
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
|
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
|
||||||
|
|
||||||
"recharts": ["recharts@2.15.4", "", { "dependencies": { "clsx": "^2.0.0", "eventemitter3": "^4.0.1", "lodash": "^4.17.21", "react-is": "^18.3.1", "react-smooth": "^4.0.4", "recharts-scale": "^0.4.4", "tiny-invariant": "^1.3.1", "victory-vendor": "^36.6.8" }, "peerDependencies": { "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw=="],
|
"recharts": ["recharts@2.15.4", "", { "dependencies": { "clsx": "^2.0.0", "eventemitter3": "^4.0.1", "lodash": "^4.17.21", "react-is": "^18.3.1", "react-smooth": "^4.0.4", "recharts-scale": "^0.4.4", "tiny-invariant": "^1.3.1", "victory-vendor": "^36.6.8" }, "peerDependencies": { "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw=="],
|
||||||
@@ -1294,14 +1141,10 @@
|
|||||||
|
|
||||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||||
|
|
||||||
"retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="],
|
|
||||||
|
|
||||||
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
|
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
|
||||||
|
|
||||||
"rgbcolor": ["rgbcolor@1.0.1", "", {}, "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw=="],
|
"rgbcolor": ["rgbcolor@1.0.1", "", {}, "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw=="],
|
||||||
|
|
||||||
"rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": "bin.js" }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="],
|
|
||||||
|
|
||||||
"rollup": ["rollup@4.60.2", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.2", "@rollup/rollup-android-arm64": "4.60.2", "@rollup/rollup-darwin-arm64": "4.60.2", "@rollup/rollup-darwin-x64": "4.60.2", "@rollup/rollup-freebsd-arm64": "4.60.2", "@rollup/rollup-freebsd-x64": "4.60.2", "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", "@rollup/rollup-linux-arm-musleabihf": "4.60.2", "@rollup/rollup-linux-arm64-gnu": "4.60.2", "@rollup/rollup-linux-arm64-musl": "4.60.2", "@rollup/rollup-linux-loong64-gnu": "4.60.2", "@rollup/rollup-linux-loong64-musl": "4.60.2", "@rollup/rollup-linux-ppc64-gnu": "4.60.2", "@rollup/rollup-linux-ppc64-musl": "4.60.2", "@rollup/rollup-linux-riscv64-gnu": "4.60.2", "@rollup/rollup-linux-riscv64-musl": "4.60.2", "@rollup/rollup-linux-s390x-gnu": "4.60.2", "@rollup/rollup-linux-x64-gnu": "4.60.2", "@rollup/rollup-linux-x64-musl": "4.60.2", "@rollup/rollup-openbsd-x64": "4.60.2", "@rollup/rollup-openharmony-arm64": "4.60.2", "@rollup/rollup-win32-arm64-msvc": "4.60.2", "@rollup/rollup-win32-ia32-msvc": "4.60.2", "@rollup/rollup-win32-x64-gnu": "4.60.2", "@rollup/rollup-win32-x64-msvc": "4.60.2", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ=="],
|
"rollup": ["rollup@4.60.2", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.2", "@rollup/rollup-android-arm64": "4.60.2", "@rollup/rollup-darwin-arm64": "4.60.2", "@rollup/rollup-darwin-x64": "4.60.2", "@rollup/rollup-freebsd-arm64": "4.60.2", "@rollup/rollup-freebsd-x64": "4.60.2", "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", "@rollup/rollup-linux-arm-musleabihf": "4.60.2", "@rollup/rollup-linux-arm64-gnu": "4.60.2", "@rollup/rollup-linux-arm64-musl": "4.60.2", "@rollup/rollup-linux-loong64-gnu": "4.60.2", "@rollup/rollup-linux-loong64-musl": "4.60.2", "@rollup/rollup-linux-ppc64-gnu": "4.60.2", "@rollup/rollup-linux-ppc64-musl": "4.60.2", "@rollup/rollup-linux-riscv64-gnu": "4.60.2", "@rollup/rollup-linux-riscv64-musl": "4.60.2", "@rollup/rollup-linux-s390x-gnu": "4.60.2", "@rollup/rollup-linux-x64-gnu": "4.60.2", "@rollup/rollup-linux-x64-musl": "4.60.2", "@rollup/rollup-openbsd-x64": "4.60.2", "@rollup/rollup-openharmony-arm64": "4.60.2", "@rollup/rollup-win32-arm64-msvc": "4.60.2", "@rollup/rollup-win32-ia32-msvc": "4.60.2", "@rollup/rollup-win32-x64-gnu": "4.60.2", "@rollup/rollup-win32-x64-msvc": "4.60.2", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ=="],
|
||||||
|
|
||||||
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
||||||
@@ -1318,8 +1161,6 @@
|
|||||||
|
|
||||||
"serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="],
|
"serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="],
|
||||||
|
|
||||||
"set-blocking": ["set-blocking@2.0.0", "", {}, "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="],
|
|
||||||
|
|
||||||
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
|
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
|
||||||
|
|
||||||
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
||||||
@@ -1334,38 +1175,16 @@
|
|||||||
|
|
||||||
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "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" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
|
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "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" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
|
||||||
|
|
||||||
"signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
|
|
||||||
|
|
||||||
"simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="],
|
|
||||||
|
|
||||||
"simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="],
|
|
||||||
|
|
||||||
"smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="],
|
|
||||||
|
|
||||||
"socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="],
|
|
||||||
|
|
||||||
"socks-proxy-agent": ["socks-proxy-agent@6.2.1", "", { "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", "socks": "^2.6.2" } }, "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ=="],
|
|
||||||
|
|
||||||
"sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="],
|
"sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="],
|
||||||
|
|
||||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||||
|
|
||||||
"sqlite": ["sqlite@4.2.1", "", {}, "sha512-Tll0Ndvnwkuv5Hn6WIbh26rZiYQORuH1t5m/or9LUpSmDmmyFG89G9fKrSeugMPxwmEIXoVxqTun4LbizTs4uw=="],
|
"sparse-bitfield": ["sparse-bitfield@3.0.3", "", { "dependencies": { "memory-pager": "^1.0.2" } }, "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ=="],
|
||||||
|
|
||||||
"sqlite3": ["sqlite3@5.1.7", "", { "dependencies": { "bindings": "^1.5.0", "node-addon-api": "^7.0.0", "prebuild-install": "^7.1.1", "tar": "^6.1.11" }, "optionalDependencies": { "node-gyp": "8.x" }, "peerDependencies": { "node-gyp": "8.x" } }, "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog=="],
|
|
||||||
|
|
||||||
"ssri": ["ssri@8.0.1", "", { "dependencies": { "minipass": "^3.1.1" } }, "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ=="],
|
|
||||||
|
|
||||||
"stackblur-canvas": ["stackblur-canvas@2.7.0", "", {}, "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ=="],
|
"stackblur-canvas": ["stackblur-canvas@2.7.0", "", {}, "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ=="],
|
||||||
|
|
||||||
"statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
|
"statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
|
||||||
|
|
||||||
"string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
|
||||||
|
|
||||||
"string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
|
|
||||||
|
|
||||||
"strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
|
||||||
|
|
||||||
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
||||||
|
|
||||||
"sucrase": ["sucrase@3.35.1", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw=="],
|
"sucrase": ["sucrase@3.35.1", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw=="],
|
||||||
@@ -1382,12 +1201,6 @@
|
|||||||
|
|
||||||
"tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="],
|
"tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="],
|
||||||
|
|
||||||
"tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
|
|
||||||
|
|
||||||
"tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="],
|
|
||||||
|
|
||||||
"tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
|
|
||||||
|
|
||||||
"text-segmentation": ["text-segmentation@1.0.3", "", { "dependencies": { "utrie": "^1.0.2" } }, "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw=="],
|
"text-segmentation": ["text-segmentation@1.0.3", "", { "dependencies": { "utrie": "^1.0.2" } }, "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw=="],
|
||||||
|
|
||||||
"thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
|
"thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
|
||||||
@@ -1402,6 +1215,8 @@
|
|||||||
|
|
||||||
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
|
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
|
||||||
|
|
||||||
|
"tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="],
|
||||||
|
|
||||||
"ts-api-utils": ["ts-api-utils@2.4.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA=="],
|
"ts-api-utils": ["ts-api-utils@2.4.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA=="],
|
||||||
|
|
||||||
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
|
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
|
||||||
@@ -1410,8 +1225,6 @@
|
|||||||
|
|
||||||
"tsx": ["tsx@4.23.9", "", { "dependencies": { "esbuild": "~0.28.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-6q8uTORRGauQVjqMQnKUucLFoeXZAfw6zKvG35GLbdKWbLdeOtZ3H4mhyA5mxuUd2o2cRTskhj59nLLQseUvUw=="],
|
"tsx": ["tsx@4.23.9", "", { "dependencies": { "esbuild": "~0.28.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-6q8uTORRGauQVjqMQnKUucLFoeXZAfw6zKvG35GLbdKWbLdeOtZ3H4mhyA5mxuUd2o2cRTskhj59nLLQseUvUw=="],
|
||||||
|
|
||||||
"tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
|
|
||||||
|
|
||||||
"tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="],
|
"tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="],
|
||||||
|
|
||||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||||
@@ -1432,10 +1245,6 @@
|
|||||||
|
|
||||||
"unicode-property-aliases-ecmascript": ["unicode-property-aliases-ecmascript@2.2.0", "", {}, "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ=="],
|
"unicode-property-aliases-ecmascript": ["unicode-property-aliases-ecmascript@2.2.0", "", {}, "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ=="],
|
||||||
|
|
||||||
"unique-filename": ["unique-filename@1.1.1", "", { "dependencies": { "unique-slug": "^2.0.0" } }, "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ=="],
|
|
||||||
|
|
||||||
"unique-slug": ["unique-slug@2.0.2", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w=="],
|
|
||||||
|
|
||||||
"unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
|
"unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
|
||||||
|
|
||||||
"update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
|
"update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
|
||||||
@@ -1462,15 +1271,15 @@
|
|||||||
|
|
||||||
"vite": ["vite@7.3.2", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": "bin/vite.js" }, "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg=="],
|
"vite": ["vite@7.3.2", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": "bin/vite.js" }, "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg=="],
|
||||||
|
|
||||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
"webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
|
||||||
|
|
||||||
"wide-align": ["wide-align@1.1.5", "", { "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } }, "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg=="],
|
"whatwg-url": ["whatwg-url@14.2.0", "", { "dependencies": { "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" } }, "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw=="],
|
||||||
|
|
||||||
|
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||||
|
|
||||||
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
||||||
|
|
||||||
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
|
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
||||||
|
|
||||||
"yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
|
|
||||||
|
|
||||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||||
|
|
||||||
@@ -1478,14 +1287,10 @@
|
|||||||
|
|
||||||
"zod-validation-error": ["zod-validation-error@4.0.2", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ=="],
|
"zod-validation-error": ["zod-validation-error@4.0.2", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ=="],
|
||||||
|
|
||||||
"@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
|
||||||
|
|
||||||
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||||
|
|
||||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||||
|
|
||||||
"@npmcli/fs/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
|
||||||
|
|
||||||
"@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
"@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||||
|
|
||||||
"@radix-ui/react-aspect-ratio/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
|
"@radix-ui/react-aspect-ratio/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
|
||||||
@@ -1528,16 +1333,8 @@
|
|||||||
|
|
||||||
"body-parser/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
"body-parser/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||||
|
|
||||||
"body-parser/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="],
|
|
||||||
|
|
||||||
"cacache/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
|
|
||||||
|
|
||||||
"cacache/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
||||||
|
|
||||||
"chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
"chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||||
|
|
||||||
"encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
|
||||||
|
|
||||||
"express/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
"express/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||||
|
|
||||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||||
@@ -1546,36 +1343,10 @@
|
|||||||
|
|
||||||
"finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
"finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||||
|
|
||||||
"fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
||||||
|
|
||||||
"make-fetch-happen/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
|
|
||||||
|
|
||||||
"make-fetch-happen/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
||||||
|
|
||||||
"micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
|
"micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
|
||||||
|
|
||||||
"minipass-collect/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
||||||
|
|
||||||
"minipass-fetch/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
||||||
|
|
||||||
"minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
||||||
|
|
||||||
"minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
||||||
|
|
||||||
"minipass-sized/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
||||||
|
|
||||||
"minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
||||||
|
|
||||||
"node-abi/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
|
||||||
|
|
||||||
"node-gyp/semver": ["semver@7.7.4", "", { "bin": "bin/semver.js" }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
|
||||||
|
|
||||||
"prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
"prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
||||||
|
|
||||||
"raw-body/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="],
|
|
||||||
|
|
||||||
"rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
|
|
||||||
|
|
||||||
"react-remove-scroll/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"react-remove-scroll/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
"react-remove-scroll-bar/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"react-remove-scroll-bar/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
@@ -1586,18 +1357,12 @@
|
|||||||
|
|
||||||
"send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
"send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||||
|
|
||||||
"ssri/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
||||||
|
|
||||||
"tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
|
|
||||||
|
|
||||||
"use-callback-ref/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"use-callback-ref/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
"use-sidecar/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"use-sidecar/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
"vite/esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": "bin/esbuild" }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="],
|
"vite/esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": "bin/esbuild" }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="],
|
||||||
|
|
||||||
"@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="],
|
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="],
|
||||||
|
|
||||||
"body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
"body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
||||||
|
|||||||
+1
-4
@@ -39,7 +39,6 @@
|
|||||||
"@radix-ui/react-toggle-group": "^1.1.11",
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||||
"@radix-ui/react-tooltip": "^1.2.8",
|
"@radix-ui/react-tooltip": "^1.2.8",
|
||||||
"bcryptjs": "^3.0.3",
|
"bcryptjs": "^3.0.3",
|
||||||
"better-sqlite3": "^12.9.0",
|
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cmdk": "^1.1.1",
|
"cmdk": "^1.1.1",
|
||||||
@@ -50,7 +49,7 @@
|
|||||||
"input-otp": "^1.4.2",
|
"input-otp": "^1.4.2",
|
||||||
"jspdf": "^4.2.1",
|
"jspdf": "^4.2.1",
|
||||||
"lucide-react": "^0.562.0",
|
"lucide-react": "^0.562.0",
|
||||||
"mariadb": "^3.5.2",
|
"mongodb": "^7.5.0",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
@@ -60,8 +59,6 @@
|
|||||||
"react-resizable-panels": "^4.2.2",
|
"react-resizable-panels": "^4.2.2",
|
||||||
"recharts": "^2.15.4",
|
"recharts": "^2.15.4",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
"sqlite": "^4.2.1",
|
|
||||||
"sqlite3": "^5.1.6",
|
|
||||||
"tailwind-merge": "^3.4.0",
|
"tailwind-merge": "^3.4.0",
|
||||||
"vaul": "^1.1.2",
|
"vaul": "^1.1.2",
|
||||||
"zod": "^4.3.5"
|
"zod": "^4.3.5"
|
||||||
|
|||||||
@@ -1,9 +1,21 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { createServer as createViteServer } from 'vite';
|
import { createServer as createViteServer } from 'vite';
|
||||||
import apiApp from './server/index.js';
|
import apiApp, { initDb } from './server/api-mongodb.js';
|
||||||
|
|
||||||
async function startServer() {
|
async function startServer() {
|
||||||
|
// Initialize MongoDB
|
||||||
|
try {
|
||||||
|
await initDb();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to initialize MongoDB:', err);
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
process.exit(1);
|
||||||
|
} else {
|
||||||
|
console.warn('Continuing in development mode without database connection.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const PORT = 3000;
|
const PORT = 3000;
|
||||||
const HOST = '0.0.0.0';
|
const HOST = '0.0.0.0';
|
||||||
@@ -14,7 +26,10 @@ async function startServer() {
|
|||||||
// Vite middleware for development or static serving for production
|
// Vite middleware for development or static serving for production
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
const vite = await createViteServer({
|
const vite = await createViteServer({
|
||||||
server: { middlewareMode: true },
|
server: {
|
||||||
|
middlewareMode: true,
|
||||||
|
hmr: false,
|
||||||
|
},
|
||||||
appType: 'spa',
|
appType: 'spa',
|
||||||
});
|
});
|
||||||
app.use(vite.middlewares);
|
app.use(vite.middlewares);
|
||||||
|
|||||||
@@ -1,665 +0,0 @@
|
|||||||
import express from 'express';
|
|
||||||
import cors from 'cors';
|
|
||||||
import { initDb,
|
|
||||||
getUsuarioByDni, getUsuarioById, getAllUsuarios, createUsuario, updateUsuario, deleteUsuario, verifyPassword, hashPassword,
|
|
||||||
getAllPacientes, getPacienteById, createPaciente, updatePaciente, deletePaciente,
|
|
||||||
getAllAreas, createArea, updateArea, deleteArea,
|
|
||||||
getAllCamas, getCamaById, createCama, updateCama, deleteCama,
|
|
||||||
getAllInternaciones, getInternacionById, createInternacion, updateInternacion, deleteInternacion,
|
|
||||||
getAllEvoluciones, createEvolucion, updateEvolucion, deleteEvolucion,
|
|
||||||
getAllLaboratorios, createLaboratorio, updateLaboratorio, deleteLaboratorio,
|
|
||||||
getAllAcidosBase, createAcidoBase, deleteAcidoBase,
|
|
||||||
getAllCultivos, createCultivo, updateCultivo, deleteCultivo,
|
|
||||||
getAllEstudiosComplementarios, createEstudioComplementario, deleteEstudioComplementario,
|
|
||||||
getAllInterconsultas, createInterconsulta, updateInterconsulta, deleteInterconsulta,
|
|
||||||
getAllAtb, createAtb, deleteAtb,
|
|
||||||
getAllIndicaciones, createIndicacion, updateIndicacion, deleteIndicacion,
|
|
||||||
getAllMovimientosIndicaciones, createMovimientoIndicacion,
|
|
||||||
getValue, setValue
|
|
||||||
} from './db-mariadb.js';
|
|
||||||
|
|
||||||
const app = express();
|
|
||||||
app.use(cors({
|
|
||||||
origin: true,
|
|
||||||
credentials: true
|
|
||||||
}));
|
|
||||||
app.use(express.json({ limit: '50mb' }));
|
|
||||||
|
|
||||||
// UUID generator
|
|
||||||
function generateUUID() {
|
|
||||||
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
|
||||||
return crypto.randomUUID();
|
|
||||||
}
|
|
||||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
||||||
const r = (Math.random() * 16) | 0;
|
|
||||||
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
||||||
return v.toString(16);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== STATE ENDPOINT (initial load) ==========
|
|
||||||
app.get('/api/state', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const state = {
|
|
||||||
pacientes: await getAllPacientes(),
|
|
||||||
areas: await getAllAreas(),
|
|
||||||
camas: await getAllCamas(),
|
|
||||||
internaciones: await getAllInternaciones(),
|
|
||||||
evoluciones: (await getAllEvoluciones()).map(e => ({
|
|
||||||
...e,
|
|
||||||
signosVitales: typeof e.signosVitales === 'string' ? JSON.parse(e.signosVitales) : e.signosVitales,
|
|
||||||
examenFisico: typeof e.examenFisico === 'string' ? JSON.parse(e.examenFisico) : e.examenFisico
|
|
||||||
})),
|
|
||||||
laboratorios: (await getAllLaboratorios()).map(l => ({ ...l, resultados: typeof l.resultados === 'string' ? JSON.parse(l.resultados) : l.resultados })),
|
|
||||||
acidosBase: await getAllAcidosBase(),
|
|
||||||
cultivos: await getAllCultivos(),
|
|
||||||
estudiosComplementarios: await getAllEstudiosComplementarios(),
|
|
||||||
interconsultas: (await getAllInterconsultas()).map(ic => ({ ...ic, realizada: !!ic.realizada })),
|
|
||||||
atb: await getAllAtb(),
|
|
||||||
indicaciones: await getAllIndicaciones(),
|
|
||||||
movimientosIndicaciones: await getAllMovimientosIndicaciones(),
|
|
||||||
vistaActual: 'dashboard',
|
|
||||||
currentInternacionId: null
|
|
||||||
};
|
|
||||||
res.json(state);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ error: 'failed to read state' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== USUARIOS ==========
|
|
||||||
app.get('/api/usuarios', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const usuarios = await getAllUsuarios();
|
|
||||||
const usuariosSinPassword = usuarios.map(({ passwordHash, ...u }) => u);
|
|
||||||
res.json(usuariosSinPassword);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener usuarios' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/usuarios', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { apellido, nombre, dni, fechaNacimiento, email, rol, matriculaProfesional, password, areaId } = req.body;
|
|
||||||
|
|
||||||
if (!apellido || !nombre || !dni || !fechaNacimiento || !email || !rol || !password) {
|
|
||||||
return res.status(400).json({ error: 'Todos los campos obligatorios deben estar presentes' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const existente = await getUsuarioByDni(dni);
|
|
||||||
if (existente) {
|
|
||||||
return res.status(400).json({ error: 'Ya existe un usuario con ese DNI' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const passwordHash = hashPassword(password);
|
|
||||||
const usuario = {
|
|
||||||
id: generateUUID(),
|
|
||||||
apellido, nombre, dni, fechaNacimiento, email, rol,
|
|
||||||
matriculaProfesional: matriculaProfesional || null,
|
|
||||||
passwordHash,
|
|
||||||
areaId: areaId || null,
|
|
||||||
fechaCreacion: new Date().toISOString().split('T')[0]
|
|
||||||
};
|
|
||||||
|
|
||||||
await createUsuario(usuario);
|
|
||||||
res.json({ ...usuario, passwordHash: undefined });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear usuario' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/usuarios/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { id } = req.params;
|
|
||||||
const { apellido, nombre, fechaNacimiento, email, rol, matriculaProfesional, areaId, password } = req.body;
|
|
||||||
|
|
||||||
const usuario = await getUsuarioById(id);
|
|
||||||
if (!usuario) {
|
|
||||||
return res.status(404).json({ error: 'Usuario no encontrado' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const datos = {};
|
|
||||||
if (apellido !== undefined) datos.apellido = apellido;
|
|
||||||
if (nombre !== undefined) datos.nombre = nombre;
|
|
||||||
if (fechaNacimiento !== undefined) datos.fechaNacimiento = fechaNacimiento;
|
|
||||||
if (email !== undefined) datos.email = email;
|
|
||||||
if (rol !== undefined) datos.rol = rol;
|
|
||||||
if (matriculaProfesional !== undefined) datos.matriculaProfesional = matriculaProfesional;
|
|
||||||
if (areaId !== undefined) datos.areaId = areaId;
|
|
||||||
if (password) datos.passwordHash = hashPassword(password);
|
|
||||||
|
|
||||||
await updateUsuario(id, datos);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al actualizar usuario' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/usuarios/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteUsuario(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar usuario' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== PACIENTES ==========
|
|
||||||
app.get('/api/pacientes', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllPacientes());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener pacientes' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/pacientes', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const paciente = { ...req.body, id: generateUUID() };
|
|
||||||
await createPaciente(paciente);
|
|
||||||
res.json(paciente);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear paciente' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/pacientes/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await updatePaciente(req.params.id, req.body);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al actualizar paciente' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/pacientes/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deletePaciente(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar paciente' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== AREAS ==========
|
|
||||||
app.get('/api/areas', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllAreas());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener areas' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/areas', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const area = { ...req.body, id: generateUUID() };
|
|
||||||
await createArea(area);
|
|
||||||
res.json(area);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear area' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/areas/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await updateArea(req.params.id, req.body);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al actualizar area' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/areas/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteArea(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar area' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== CAMAS ==========
|
|
||||||
app.get('/api/camas', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllCamas());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener camas' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/camas/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await updateCama(req.params.id, req.body);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al actualizar cama' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/camas', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const cama = req.body;
|
|
||||||
if (!cama.id) {
|
|
||||||
cama.id = generateUUID();
|
|
||||||
}
|
|
||||||
await createCama(cama);
|
|
||||||
res.json(cama);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear cama' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/camas/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteCama(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar cama' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== INTERNACIONES ==========
|
|
||||||
app.get('/api/internaciones', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllInternaciones());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener internaciones' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/internaciones', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const internacion = { ...req.body, id: generateUUID(), activa: true };
|
|
||||||
await createInternacion(internacion);
|
|
||||||
res.json(internacion);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear internacion' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/internaciones/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await updateInternacion(req.params.id, req.body);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al actualizar internacion' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/internaciones/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteInternacion(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar internacion' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== EVOLUCIONES ==========
|
|
||||||
app.get('/api/evoluciones', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllEvoluciones());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener evoluciones' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/evoluciones', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const evolucion = { ...req.body, id: generateUUID() };
|
|
||||||
await createEvolucion(evolucion);
|
|
||||||
res.json(evolucion);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear evolucion' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/evoluciones/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await updateEvolucion(req.params.id, req.body);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al actualizar evolucion' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/evoluciones/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteEvolucion(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar evolucion' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== LABORATORIOS ==========
|
|
||||||
app.get('/api/laboratorios', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllLaboratorios());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener laboratorios' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/laboratorios', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const laboratorio = { ...req.body, id: generateUUID() };
|
|
||||||
await createLaboratorio(laboratorio);
|
|
||||||
res.json(laboratorio);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear laboratorio' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/laboratorios/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await updateLaboratorio(req.params.id, req.body);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al actualizar laboratorio' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/laboratorios/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteLaboratorio(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar laboratorio' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== ACIDOS BASE ==========
|
|
||||||
app.get('/api/acid-os-base', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllAcidosBase());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener acidos base' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/acid-os-base', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const acido = { ...req.body, id: generateUUID() };
|
|
||||||
await createAcidoBase(acido);
|
|
||||||
res.json(acido);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear acido base' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/acid-os-base/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteAcidoBase(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar acido base' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== CULTIVOS ==========
|
|
||||||
app.get('/api/cultivos', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllCultivos());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener cultivos' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/cultivos', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const cultivo = { ...req.body, id: generateUUID() };
|
|
||||||
await createCultivo(cultivo);
|
|
||||||
res.json(cultivo);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear cultivo' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/cultivos/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await updateCultivo(req.params.id, req.body);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al actualizar cultivo' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/cultivos/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteCultivo(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar cultivo' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== ESTUDIOS COMPLEMENTARIOS ==========
|
|
||||||
app.get('/api/estudios-complementarios', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllEstudiosComplementarios());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener estudios' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/estudios-complementarios', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const estudio = { ...req.body, id: generateUUID() };
|
|
||||||
await createEstudioComplementario(estudio);
|
|
||||||
res.json(estudio);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear estudio' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/estudios-complementarios/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteEstudioComplementario(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar estudio' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== INTERCONSULTAS ==========
|
|
||||||
app.get('/api/interconsultas', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllInterconsultas());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener interconsultas' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/interconsultas', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const interconsulta = { ...req.body, id: generateUUID() };
|
|
||||||
await createInterconsulta(interconsulta);
|
|
||||||
res.json(interconsulta);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear interconsulta' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/interconsultas/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await updateInterconsulta(req.params.id, req.body);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al actualizar interconsulta' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/interconsultas/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteInterconsulta(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar interconsulta' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== ATB ==========
|
|
||||||
app.get('/api/atb', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllAtb());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener ATB' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/atb', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const atb = { ...req.body, id: generateUUID() };
|
|
||||||
await createAtb(atb);
|
|
||||||
res.json(atb);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear ATB' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/atb/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteAtb(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar ATB' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== INDICACIONES ==========
|
|
||||||
app.get('/api/indicaciones', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllIndicaciones());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener indicaciones' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/indicaciones', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const indicacion = { ...req.body, id: generateUUID() };
|
|
||||||
await createIndicacion(indicacion);
|
|
||||||
res.json(indicacion);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al crear indicacion' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/indicaciones/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await updateIndicacion(req.params.id, req.body);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al actualizar indicacion' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/indicaciones/:id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deleteIndicacion(req.params.id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al eliminar indicacion' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== MOVIMIENTOS INDICACIONES ==========
|
|
||||||
app.get('/api/movimientos-indicaciones', async (req, res) => {
|
|
||||||
try {
|
|
||||||
res.json(await getAllMovimientosIndicaciones());
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al obtener movimientos' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/movimientos-indicaciones', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const movimiento = { ...req.body, id: generateUUID() };
|
|
||||||
console.log('Creating movimiento:', movimiento);
|
|
||||||
await createMovimientoIndicacion(movimiento);
|
|
||||||
res.json(movimiento);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error creating movimiento:', err);
|
|
||||||
res.status(500).json({ error: err.message || 'Error al crear movimiento' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== AUTH ==========
|
|
||||||
app.post('/api/auth/login', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { dni, password } = req.body;
|
|
||||||
if (!dni || !password) {
|
|
||||||
return res.status(400).json({ error: 'DNI y contraseña requeridos' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const usuario = await getUsuarioByDni(dni);
|
|
||||||
if (!usuario) {
|
|
||||||
return res.status(401).json({ error: 'Usuario no encontrado' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const validPassword = verifyPassword(dni, password);
|
|
||||||
if (!validPassword) {
|
|
||||||
return res.status(401).json({ error: 'Contraseña incorrecta' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const { passwordHash, ...userWithoutPassword } = usuario;
|
|
||||||
res.json(userWithoutPassword);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error en autenticación' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/auth/change-password', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { dni, oldPassword, newPassword } = req.body;
|
|
||||||
if (!dni || !oldPassword || !newPassword) {
|
|
||||||
return res.status(400).json({ error: 'Todos los campos son requeridos' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const validPassword = verifyPassword(dni, oldPassword);
|
|
||||||
if (!validPassword) {
|
|
||||||
return res.status(401).json({ error: 'Contraseña actual incorrecta' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const newHash = hashPassword(newPassword);
|
|
||||||
const usuario = await getUsuarioByDni(dni);
|
|
||||||
if (usuario) {
|
|
||||||
await updateUsuario(usuario.id, { passwordHash: newHash });
|
|
||||||
}
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al cambiar contraseña' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/auth/update-email', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { dni, newEmail } = req.body;
|
|
||||||
if (!dni || !newEmail) {
|
|
||||||
return res.status(400).json({ error: 'DNI y email son requeridos' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const usuario = await getUsuarioByDni(dni);
|
|
||||||
if (usuario) {
|
|
||||||
await updateUsuario(usuario.id, { email: newEmail });
|
|
||||||
}
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({ error: 'Error al actualizar email' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Initialize DB and start server
|
|
||||||
const PORT = process.env.PORT || 4000;
|
|
||||||
const HOST = process.env.HOST || '0.0.0.0';
|
|
||||||
|
|
||||||
initDb().then(() => {
|
|
||||||
app.listen(Number(PORT), HOST, () => {
|
|
||||||
console.log(`MariaDB Server running on http://${HOST}:${PORT}`);
|
|
||||||
});
|
|
||||||
}).catch(err => {
|
|
||||||
console.error('Failed to initialize database:', err);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
+18
-10
@@ -594,12 +594,26 @@ app.post('/api/auth/login', async (req, res) => {
|
|||||||
return res.status(400).json({ error: 'DNI y contraseña requeridos' });
|
return res.status(400).json({ error: 'DNI y contraseña requeridos' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bypass TOTAL "en memoria" directamente en el controlador de la API para entornos sin DB
|
||||||
|
const adminDni = process.env.ADMIN_DNI || '12345678';
|
||||||
|
const adminPassword = process.env.ADMIN_PASSWORD || 'admin123';
|
||||||
|
|
||||||
|
if ((String(dni) === adminDni || dni === 'admin') && password === adminPassword) {
|
||||||
|
return res.json({
|
||||||
|
id: 'admin-hardcoded-api',
|
||||||
|
apellido: 'Administrador',
|
||||||
|
nombre: 'Sistema (Memoria)',
|
||||||
|
dni: String(dni),
|
||||||
|
rol: 'admin'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const usuario = await getUsuarioByDni(dni);
|
const usuario = await getUsuarioByDni(dni);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
return res.status(401).json({ error: 'Usuario no encontrado' });
|
return res.status(401).json({ error: 'Usuario no encontrado' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const validPassword = verifyPassword(dni, password);
|
const validPassword = await verifyPassword(dni, password);
|
||||||
if (!validPassword) {
|
if (!validPassword) {
|
||||||
return res.status(401).json({ error: 'Contraseña incorrecta' });
|
return res.status(401).json({ error: 'Contraseña incorrecta' });
|
||||||
}
|
}
|
||||||
@@ -618,7 +632,7 @@ app.post('/api/auth/change-password', async (req, res) => {
|
|||||||
return res.status(400).json({ error: 'Todos los campos son requeridos' });
|
return res.status(400).json({ error: 'Todos los campos son requeridos' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const validPassword = verifyPassword(dni, oldPassword);
|
const validPassword = await verifyPassword(dni, oldPassword);
|
||||||
if (!validPassword) {
|
if (!validPassword) {
|
||||||
return res.status(401).json({ error: 'Contraseña actual incorrecta' });
|
return res.status(401).json({ error: 'Contraseña actual incorrecta' });
|
||||||
}
|
}
|
||||||
@@ -655,11 +669,5 @@ app.put('/api/auth/update-email', async (req, res) => {
|
|||||||
const PORT = process.env.PORT || 4000;
|
const PORT = process.env.PORT || 4000;
|
||||||
const HOST = process.env.HOST || '0.0.0.0';
|
const HOST = process.env.HOST || '0.0.0.0';
|
||||||
|
|
||||||
initDb().then(() => {
|
export { initDb };
|
||||||
app.listen(Number(PORT), HOST, () => {
|
export default app;
|
||||||
console.log(`MongoDB Server running on http://${HOST}:${PORT}`);
|
|
||||||
});
|
|
||||||
}).catch(err => {
|
|
||||||
console.error('Failed to initialize database:', err);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -1,682 +0,0 @@
|
|||||||
import * as mariadb from 'mariadb';
|
|
||||||
import bcrypt from 'bcryptjs';
|
|
||||||
const { compareSync, hashSync } = bcrypt;
|
|
||||||
|
|
||||||
// UUID generator
|
|
||||||
export function generateUUID() {
|
|
||||||
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
|
||||||
return crypto.randomUUID();
|
|
||||||
}
|
|
||||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
||||||
const r = (Math.random() * 16) | 0;
|
|
||||||
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
||||||
return v.toString(16);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// MariaDB connection pool
|
|
||||||
const pool = mariadb.createPool({
|
|
||||||
host: process.env.DB_HOST || '10.9.8.135',
|
|
||||||
port: parseInt(process.env.DB_PORT || '3306'),
|
|
||||||
user: process.env.DB_USER || 'snlavaise',
|
|
||||||
password: process.env.DB_PASSWORD || '1123581321Rtaylor%_+',
|
|
||||||
database: process.env.DB_NAME || 'santojanni',
|
|
||||||
connectionLimit: 10,
|
|
||||||
connectTimeout: 10000,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Helper to execute queries
|
|
||||||
async function query(sql, params = []) {
|
|
||||||
let conn;
|
|
||||||
try {
|
|
||||||
conn = await pool.getConnection();
|
|
||||||
const result = await conn.query(sql, params);
|
|
||||||
return result;
|
|
||||||
} finally {
|
|
||||||
if (conn) conn.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper to get a single row
|
|
||||||
async function queryOne(sql, params = []) {
|
|
||||||
const rows = await query(sql, params);
|
|
||||||
return rows[0] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize database tables
|
|
||||||
export async function initDb() {
|
|
||||||
const tables = [
|
|
||||||
`CREATE TABLE IF NOT EXISTS usuarios (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
apellido VARCHAR(255) NOT NULL,
|
|
||||||
nombre VARCHAR(255) NOT NULL,
|
|
||||||
dni VARCHAR(20) NOT NULL UNIQUE,
|
|
||||||
fechaNacimiento VARCHAR(10),
|
|
||||||
email VARCHAR(255),
|
|
||||||
rol VARCHAR(50),
|
|
||||||
matriculaProfesional VARCHAR(100),
|
|
||||||
passwordHash VARCHAR(255),
|
|
||||||
areaId VARCHAR(36),
|
|
||||||
fechaCreacion VARCHAR(10)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS pacientes (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
apellido VARCHAR(255) NOT NULL,
|
|
||||||
nombre VARCHAR(255) NOT NULL,
|
|
||||||
dni VARCHAR(20) NOT NULL UNIQUE,
|
|
||||||
fechaNacimiento VARCHAR(10),
|
|
||||||
sexo VARCHAR(10),
|
|
||||||
telefono VARCHAR(50),
|
|
||||||
email VARCHAR(255),
|
|
||||||
direccion TEXT,
|
|
||||||
obraSocial VARCHAR(100),
|
|
||||||
nacionalidad VARCHAR(100),
|
|
||||||
medicacionHabitual TEXT,
|
|
||||||
antecedentes TEXT,
|
|
||||||
alergias TEXT,
|
|
||||||
grupoSanguineo VARCHAR(10),
|
|
||||||
historiaClinica TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS areas (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
nombre VARCHAR(255) NOT NULL UNIQUE
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS camas (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
numero VARCHAR(20) NOT NULL,
|
|
||||||
areaId VARCHAR(36),
|
|
||||||
tipo VARCHAR(50) DEFAULT 'Estándar',
|
|
||||||
estado VARCHAR(20) DEFAULT 'Disponible',
|
|
||||||
pacienteId VARCHAR(36),
|
|
||||||
internacionId VARCHAR(36)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS internaciones (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
camaId VARCHAR(36),
|
|
||||||
areaId VARCHAR(36),
|
|
||||||
fechaIngresoHospital VARCHAR(10),
|
|
||||||
fechaIngresoClinica VARCHAR(10),
|
|
||||||
fechaEgreso VARCHAR(10),
|
|
||||||
diagnosticoIngreso TEXT,
|
|
||||||
motivoConsulta TEXT,
|
|
||||||
enfermedadActual TEXT,
|
|
||||||
antecedentesEnfermedadActual TEXT,
|
|
||||||
diagnosticoEgreso TEXT,
|
|
||||||
medicoIngresante VARCHAR(255),
|
|
||||||
motivoEgreso VARCHAR(50),
|
|
||||||
activa TINYINT DEFAULT 1,
|
|
||||||
apache TEXT,
|
|
||||||
derivacion TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS evoluciones (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
internacionId VARCHAR(36) NOT NULL,
|
|
||||||
fecha VARCHAR(10) NOT NULL,
|
|
||||||
hora VARCHAR(5),
|
|
||||||
medico VARCHAR(255),
|
|
||||||
signosVitales TEXT,
|
|
||||||
examenFisico TEXT,
|
|
||||||
novedades TEXT,
|
|
||||||
comentarios TEXT,
|
|
||||||
pendientes TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS laboratorios (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36),
|
|
||||||
fecha VARCHAR(10) NOT NULL,
|
|
||||||
hora VARCHAR(5),
|
|
||||||
tipo VARCHAR(50),
|
|
||||||
resultados TEXT,
|
|
||||||
observaciones TEXT,
|
|
||||||
medicoSolicitante VARCHAR(255)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS acidosbase (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36),
|
|
||||||
fecha VARCHAR(10) NOT NULL,
|
|
||||||
hora VARCHAR(5),
|
|
||||||
ph DECIMAL(4,2),
|
|
||||||
pco2 DECIMAL(6,2),
|
|
||||||
po2 DECIMAL(6,2),
|
|
||||||
hco3 DECIMAL(6,2),
|
|
||||||
be DECIMAL(6,2),
|
|
||||||
sato2 DECIMAL(6,2),
|
|
||||||
lactato DECIMAL(6,2),
|
|
||||||
interpretacion TEXT,
|
|
||||||
fio2 DECIMAL(6,2)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS cultivos (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36),
|
|
||||||
fechaToma VARCHAR(10),
|
|
||||||
protocolo VARCHAR(50),
|
|
||||||
fechaResultado VARCHAR(10),
|
|
||||||
tipoMuestra VARCHAR(100),
|
|
||||||
germen TEXT,
|
|
||||||
sensible TEXT,
|
|
||||||
resistente TEXT,
|
|
||||||
estado VARCHAR(50) DEFAULT 'NAF/Pendiente',
|
|
||||||
observaciones TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS estudiosComplementarios (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36),
|
|
||||||
fecha VARCHAR(10),
|
|
||||||
tipo VARCHAR(100),
|
|
||||||
resultado TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS interconsultas (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36) NOT NULL,
|
|
||||||
fecha VARCHAR(10),
|
|
||||||
servicioInterconsultado VARCHAR(255),
|
|
||||||
motivo TEXT,
|
|
||||||
respuestaInterconsulta TEXT,
|
|
||||||
respuestaFecha VARCHAR(10)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS atb (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36) NOT NULL,
|
|
||||||
antibiotico VARCHAR(255),
|
|
||||||
fechaInicio VARCHAR(10),
|
|
||||||
fechaFinalizacion VARCHAR(10)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS indicaciones (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
internacionId VARCHAR(36) NOT NULL,
|
|
||||||
tipo VARCHAR(50) NOT NULL,
|
|
||||||
droga VARCHAR(255),
|
|
||||||
dosis VARCHAR(100),
|
|
||||||
frecuenciaHoras INT,
|
|
||||||
via VARCHAR(50),
|
|
||||||
descripcion TEXT,
|
|
||||||
tipoPlan VARCHAR(50),
|
|
||||||
tipoPlan2 VARCHAR(50),
|
|
||||||
cantidadMl INT,
|
|
||||||
cantidadMl2 INT,
|
|
||||||
tiempoHoras INT,
|
|
||||||
estado VARCHAR(20) DEFAULT 'Activa',
|
|
||||||
medicoCrea VARCHAR(255),
|
|
||||||
fechaCrea VARCHAR(10),
|
|
||||||
tipoInsulina VARCHAR(50),
|
|
||||||
unidadesDesayuno INT,
|
|
||||||
unidadesAlmuerzo INT,
|
|
||||||
unidadesNoche INT,
|
|
||||||
indicacionNoFco TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS movimientos_indicaciones (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
indicacionId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36) NOT NULL,
|
|
||||||
tipo VARCHAR(50) NOT NULL,
|
|
||||||
fecha VARCHAR(10) NOT NULL,
|
|
||||||
profesional VARCHAR(255) NOT NULL,
|
|
||||||
indicacionPrevia TEXT,
|
|
||||||
indicacionNueva TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS kv (
|
|
||||||
kv_key VARCHAR(255) PRIMARY KEY,
|
|
||||||
value TEXT
|
|
||||||
)`
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const sql of tables) {
|
|
||||||
await query(sql);
|
|
||||||
}
|
|
||||||
console.log('Database tables initialized');
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== USUARIOS ==========
|
|
||||||
export async function getUsuarioByDni(dni) {
|
|
||||||
return await queryOne('SELECT * FROM usuarios WHERE dni = ?', [dni]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getUsuarioById(id) {
|
|
||||||
return await queryOne('SELECT * FROM usuarios WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getAllUsuarios() {
|
|
||||||
return await query('SELECT * FROM usuarios ORDER BY apellido, nombre');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createUsuario(usuario) {
|
|
||||||
await query(
|
|
||||||
`INSERT INTO usuarios (id, apellido, nombre, dni, fechaNacimiento, email, rol, matriculaProfesional, passwordHash, areaId, fechaCreacion)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
||||||
[usuario.id, usuario.apellido, usuario.nombre, usuario.dni, usuario.fechaNacimiento, usuario.email, usuario.rol, usuario.matriculaProfesional || null, usuario.passwordHash, usuario.areaId || null, usuario.fechaCreacion]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateUsuario(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
|
|
||||||
if (datos.apellido !== undefined) { fields.push('apellido = ?'); values.push(datos.apellido); }
|
|
||||||
if (datos.nombre !== undefined) { fields.push('nombre = ?'); values.push(datos.nombre); }
|
|
||||||
if (datos.fechaNacimiento !== undefined) { fields.push('fechaNacimiento = ?'); values.push(datos.fechaNacimiento); }
|
|
||||||
if (datos.email !== undefined) { fields.push('email = ?'); values.push(datos.email); }
|
|
||||||
if (datos.rol !== undefined) { fields.push('rol = ?'); values.push(datos.rol); }
|
|
||||||
if (datos.matriculaProfesional !== undefined) { fields.push('matriculaProfesional = ?'); values.push(datos.matriculaProfesional); }
|
|
||||||
if (datos.passwordHash !== undefined) { fields.push('passwordHash = ?'); values.push(datos.passwordHash); }
|
|
||||||
if (datos.areaId !== undefined) { fields.push('areaId = ?'); values.push(datos.areaId); }
|
|
||||||
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
await query(`UPDATE usuarios SET ${fields.join(', ')} WHERE id = ?`, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteUsuario(id) {
|
|
||||||
await query('DELETE FROM usuarios WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function verifyPassword(dni, password) {
|
|
||||||
const row = await queryOne('SELECT passwordHash FROM usuarios WHERE dni = ?', [dni]);
|
|
||||||
if (!row) return false;
|
|
||||||
return compareSync(password, row.passwordHash);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function hashPassword(password) {
|
|
||||||
return hashSync(password, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== PACIENTES ==========
|
|
||||||
export async function getAllPacientes() {
|
|
||||||
return await query('SELECT * FROM pacientes');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getPacienteById(id) {
|
|
||||||
return await queryOne('SELECT * FROM pacientes WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createPaciente(paciente) {
|
|
||||||
await query(
|
|
||||||
`INSERT INTO pacientes (id, apellido, nombre, dni, fechaNacimiento, sexo, telefono, email, direccion, obraSocial, nacionalidad, medicacionHabitual, antecedentes, alergias, grupoSanguineo, historiaClinica)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
||||||
[paciente.id, paciente.apellido, paciente.nombre, paciente.dni, paciente.fechaNacimiento || null, paciente.sexo || null, paciente.telefono || null, paciente.email || null, paciente.direccion || null, paciente.obraSocial || null, paciente.nacionalidad || null, paciente.medicacionHabitual || null, paciente.antecedentes || null, paciente.alergias || null, paciente.grupoSanguineo || null, paciente.historiaClinica || null]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updatePaciente(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
|
|
||||||
if (datos.apellido !== undefined) { fields.push('apellido = ?'); values.push(datos.apellido); }
|
|
||||||
if (datos.nombre !== undefined) { fields.push('nombre = ?'); values.push(datos.nombre); }
|
|
||||||
if (datos.dni !== undefined) { fields.push('dni = ?'); values.push(datos.dni); }
|
|
||||||
if (datos.fechaNacimiento !== undefined) { fields.push('fechaNacimiento = ?'); values.push(datos.fechaNacimiento); }
|
|
||||||
if (datos.sexo !== undefined) { fields.push('sexo = ?'); values.push(datos.sexo); }
|
|
||||||
if (datos.telefono !== undefined) { fields.push('telefono = ?'); values.push(datos.telefono); }
|
|
||||||
if (datos.email !== undefined) { fields.push('email = ?'); values.push(datos.email); }
|
|
||||||
if (datos.direccion !== undefined) { fields.push('direccion = ?'); values.push(datos.direccion); }
|
|
||||||
if (datos.obraSocial !== undefined) { fields.push('obraSocial = ?'); values.push(datos.obraSocial); }
|
|
||||||
if (datos.nacionalidad !== undefined) { fields.push('nacionalidad = ?'); values.push(datos.nacionalidad); }
|
|
||||||
if (datos.medicacionHabitual !== undefined) { fields.push('medicacionHabitual = ?'); values.push(datos.medicacionHabitual); }
|
|
||||||
if (datos.antecedentes !== undefined) { fields.push('antecedentes = ?'); values.push(datos.antecedentes); }
|
|
||||||
if (datos.alergias !== undefined) { fields.push('alergias = ?'); values.push(datos.alergias); }
|
|
||||||
if (datos.grupoSanguineo !== undefined) { fields.push('grupoSanguineo = ?'); values.push(datos.grupoSanguineo); }
|
|
||||||
if (datos.historiaClinica !== undefined) { fields.push('historiaClinica = ?'); values.push(datos.historiaClinica); }
|
|
||||||
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
await query(`UPDATE pacientes SET ${fields.join(', ')} WHERE id = ?`, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deletePaciente(id) {
|
|
||||||
await query('DELETE FROM pacientes WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== AREAS ==========
|
|
||||||
export async function getAllAreas() {
|
|
||||||
return await query('SELECT * FROM areas');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createArea(area) {
|
|
||||||
await query('INSERT INTO areas (id, nombre) VALUES (?, ?)', [area.id, area.nombre]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateArea(id, datos) {
|
|
||||||
if (datos.nombre !== undefined) {
|
|
||||||
await query('UPDATE areas SET nombre = ? WHERE id = ?', [datos.nombre, id]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteArea(id) {
|
|
||||||
await query('DELETE FROM areas WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== CAMAS ==========
|
|
||||||
export async function getAllCamas() {
|
|
||||||
return await query('SELECT * FROM camas');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getCamaById(id) {
|
|
||||||
return await queryOne('SELECT * FROM camas WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createCama(cama) {
|
|
||||||
const id = cama.id || generateUUID();
|
|
||||||
await query(
|
|
||||||
'INSERT INTO camas (id, numero, areaId, tipo, estado) VALUES (?, ?, ?, ?, ?)',
|
|
||||||
[id, cama.numero, cama.areaId, cama.tipo, cama.estado]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateCama(id, updates) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
|
|
||||||
if (updates.numero !== undefined) { fields.push('numero = ?'); values.push(updates.numero); }
|
|
||||||
if (updates.areaId !== undefined) { fields.push('areaId = ?'); values.push(updates.areaId); }
|
|
||||||
if (updates.tipo !== undefined) { fields.push('tipo = ?'); values.push(updates.tipo); }
|
|
||||||
if (updates.estado !== undefined) { fields.push('estado = ?'); values.push(updates.estado); }
|
|
||||||
if (updates.pacienteId !== undefined) { fields.push('pacienteId = ?'); values.push(updates.pacienteId); }
|
|
||||||
if (updates.internacionId !== undefined) { fields.push('internacionId = ?'); values.push(updates.internacionId); }
|
|
||||||
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
await query(`UPDATE camas SET ${fields.join(', ')} WHERE id = ?`, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteCama(id) {
|
|
||||||
await query('DELETE FROM camas WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== INTERNACIONES ==========
|
|
||||||
export async function getAllInternaciones() {
|
|
||||||
const rows = await query('SELECT * FROM internaciones');
|
|
||||||
return rows.map(r => ({ ...r, activa: !!r.activa }));
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getInternacionById(id) {
|
|
||||||
const row = await queryOne('SELECT * FROM internaciones WHERE id = ?', [id]);
|
|
||||||
if (row) row.activa = !!row.activa;
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createInternacion(internacion) {
|
|
||||||
await query(
|
|
||||||
`INSERT INTO internaciones (id, pacienteId, camaId, areaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
||||||
[internacion.id, internacion.pacienteId, internacion.camaId, internacion.areaId || null, internacion.fechaIngresoHospital || null, internacion.fechaIngresoClinica || null, internacion.fechaEgreso || null, internacion.diagnosticoIngreso || null, internacion.motivoConsulta || null, internacion.enfermedadActual || null, internacion.antecedentesEnfermedadActual || null, internacion.diagnosticoEgreso || null, internacion.medicoIngresante || null, internacion.motivoEgreso || null, internacion.activa ? 1 : 0, internacion.apache || null, internacion.derivacion || null]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateInternacion(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
|
|
||||||
if (datos.pacienteId !== undefined) { fields.push('pacienteId = ?'); values.push(datos.pacienteId); }
|
|
||||||
if (datos.camaId !== undefined) { fields.push('camaId = ?'); values.push(datos.camaId); }
|
|
||||||
if (datos.areaId !== undefined) { fields.push('areaId = ?'); values.push(datos.areaId); }
|
|
||||||
if (datos.fechaIngresoHospital !== undefined) { fields.push('fechaIngresoHospital = ?'); values.push(datos.fechaIngresoHospital); }
|
|
||||||
if (datos.fechaIngresoClinica !== undefined) { fields.push('fechaIngresoClinica = ?'); values.push(datos.fechaIngresoClinica); }
|
|
||||||
if (datos.fechaEgreso !== undefined) { fields.push('fechaEgreso = ?'); values.push(datos.fechaEgreso); }
|
|
||||||
if (datos.diagnosticoIngreso !== undefined) { fields.push('diagnosticoIngreso = ?'); values.push(datos.diagnosticoIngreso); }
|
|
||||||
if (datos.motivoConsulta !== undefined) { fields.push('motivoConsulta = ?'); values.push(datos.motivoConsulta); }
|
|
||||||
if (datos.enfermedadActual !== undefined) { fields.push('enfermedadActual = ?'); values.push(datos.enfermedadActual); }
|
|
||||||
if (datos.antecedentesEnfermedadActual !== undefined) { fields.push('antecedentesEnfermedadActual = ?'); values.push(datos.antecedentesEnfermedadActual); }
|
|
||||||
if (datos.diagnosticoEgreso !== undefined) { fields.push('diagnosticoEgreso = ?'); values.push(datos.diagnosticoEgreso); }
|
|
||||||
if (datos.medicoIngresante !== undefined) { fields.push('medicoIngresante = ?'); values.push(datos.medicoIngresante); }
|
|
||||||
if (datos.motivoEgreso !== undefined) { fields.push('motivoEgreso = ?'); values.push(datos.motivoEgreso); }
|
|
||||||
if (datos.activa !== undefined) { fields.push('activa = ?'); values.push(datos.activa ? 1 : 0); }
|
|
||||||
if (datos.apache !== undefined) { fields.push('apache = ?'); values.push(datos.apache); }
|
|
||||||
if (datos.derivacion !== undefined) { fields.push('derivacion = ?'); values.push(datos.derivacion); }
|
|
||||||
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
await query(`UPDATE internaciones SET ${fields.join(', ')} WHERE id = ?`, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteInternacion(id) {
|
|
||||||
await query('DELETE FROM internaciones WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== EVOLUCIONES ==========
|
|
||||||
export async function getAllEvoluciones() {
|
|
||||||
return await query('SELECT * FROM evoluciones');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createEvolucion(evolucion) {
|
|
||||||
await query(
|
|
||||||
'INSERT INTO evoluciones (id, internacionId, fecha, hora, medico, signosVitales, examenFisico, novedades, comentarios, pendientes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
|
||||||
[evolucion.id, evolucion.internacionId, evolucion.fecha, evolucion.hora || '', evolucion.medico || '', JSON.stringify(evolucion.signosVitales || {}), JSON.stringify(evolucion.examenFisico || {}), evolucion.novedades || '', evolucion.comentarios || '', evolucion.pendientes || '']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateEvolucion(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
|
|
||||||
if (datos.internacionId !== undefined) { fields.push('internacionId = ?'); values.push(datos.internacionId); }
|
|
||||||
if (datos.fecha !== undefined) { fields.push('fecha = ?'); values.push(datos.fecha); }
|
|
||||||
if (datos.hora !== undefined) { fields.push('hora = ?'); values.push(datos.hora); }
|
|
||||||
if (datos.medico !== undefined) { fields.push('medico = ?'); values.push(datos.medico); }
|
|
||||||
if (datos.signosVitales !== undefined) { fields.push('signosVitales = ?'); values.push(JSON.stringify(datos.signosVitales)); }
|
|
||||||
if (datos.examenFisico !== undefined) { fields.push('examenFisico = ?'); values.push(JSON.stringify(datos.examenFisico)); }
|
|
||||||
if (datos.novedades !== undefined) { fields.push('novedades = ?'); values.push(datos.novedades); }
|
|
||||||
if (datos.comentarios !== undefined) { fields.push('comentarios = ?'); values.push(datos.comentarios); }
|
|
||||||
if (datos.pendientes !== undefined) { fields.push('pendientes = ?'); values.push(datos.pendientes); }
|
|
||||||
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
await query(`UPDATE evoluciones SET ${fields.join(', ')} WHERE id = ?`, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteEvolucion(id) {
|
|
||||||
await query('DELETE FROM evoluciones WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== LABORATORIOS ==========
|
|
||||||
export async function getAllLaboratorios() {
|
|
||||||
return await query('SELECT * FROM laboratorios');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createLaboratorio(laboratorio) {
|
|
||||||
await query(
|
|
||||||
'INSERT INTO laboratorios (id, pacienteId, internacionId, fecha, hora, tipo, resultados, observaciones, medicoSolicitante) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
|
||||||
[laboratorio.id, laboratorio.pacienteId, laboratorio.internacionId || null, laboratorio.fecha, laboratorio.hora || null, laboratorio.tipo, JSON.stringify(laboratorio.resultados), laboratorio.observaciones || null, laboratorio.medicoSolicitante || null]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateLaboratorio(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
|
|
||||||
if (datos.pacienteId !== undefined) { fields.push('pacienteId = ?'); values.push(datos.pacienteId); }
|
|
||||||
if (datos.internacionId !== undefined) { fields.push('internacionId = ?'); values.push(datos.internacionId); }
|
|
||||||
if (datos.fecha !== undefined) { fields.push('fecha = ?'); values.push(datos.fecha); }
|
|
||||||
if (datos.hora !== undefined) { fields.push('hora = ?'); values.push(datos.hora); }
|
|
||||||
if (datos.tipo !== undefined) { fields.push('tipo = ?'); values.push(datos.tipo); }
|
|
||||||
if (datos.resultados !== undefined) { fields.push('resultados = ?'); values.push(JSON.stringify(datos.resultados)); }
|
|
||||||
if (datos.observaciones !== undefined) { fields.push('observaciones = ?'); values.push(datos.observaciones); }
|
|
||||||
if (datos.medicoSolicitante !== undefined) { fields.push('medicoSolicitante = ?'); values.push(datos.medicoSolicitante); }
|
|
||||||
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
await query(`UPDATE laboratorios SET ${fields.join(', ')} WHERE id = ?`, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteLaboratorio(id) {
|
|
||||||
await query('DELETE FROM laboratorios WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== ACIDOS BASE ==========
|
|
||||||
export async function getAllAcidosBase() {
|
|
||||||
return await query('SELECT * FROM acidosbase');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createAcidoBase(acido) {
|
|
||||||
await query(
|
|
||||||
'INSERT INTO acidosbase (id, pacienteId, internacionId, fecha, hora, ph, pco2, po2, hco3, be, sato2, lactato, interpretacion, fio2) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
|
||||||
[acido.id, acido.pacienteId, acido.internacionId || null, acido.fecha, acido.hora || null, acido.ph || null, acido.pco2 || null, acido.po2 || null, acido.hco3 || null, acido.be || null, acido.sato2 || null, acido.lactato || null, acido.interpretacion || null, acido.fio2 || null]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteAcidoBase(id) {
|
|
||||||
await query('DELETE FROM acidosbase WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== CULTIVOS ==========
|
|
||||||
export async function getAllCultivos() {
|
|
||||||
return await query('SELECT * FROM cultivos');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createCultivo(cultivo) {
|
|
||||||
await query(
|
|
||||||
'INSERT INTO cultivos (id, pacienteId, internacionId, fechaToma, protocolo, fechaResultado, tipoMuestra, germen, sensible, resistente, estado, observaciones) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
|
||||||
[cultivo.id, cultivo.pacienteId, cultivo.internacionId, cultivo.fechaToma || null, cultivo.protocolo || null, cultivo.fechaResultado || null, cultivo.tipoMuestra || null, cultivo.germen || null, cultivo.sensible || null, cultivo.resistente || null, cultivo.estado || 'NAF/Pendiente', cultivo.observaciones || null]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateCultivo(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
|
|
||||||
if (datos.estado !== undefined) { fields.push('estado = ?'); values.push(datos.estado); }
|
|
||||||
if (datos.germen !== undefined) { fields.push('germen = ?'); values.push(datos.germen); }
|
|
||||||
if (datos.sensible !== undefined) { fields.push('sensible = ?'); values.push(datos.sensible); }
|
|
||||||
if (datos.resistente !== undefined) { fields.push('resistente = ?'); values.push(datos.resistente); }
|
|
||||||
if (datos.fechaResultado !== undefined) { fields.push('fechaResultado = ?'); values.push(datos.fechaResultado); }
|
|
||||||
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
await query(`UPDATE cultivos SET ${fields.join(', ')} WHERE id = ?`, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteCultivo(id) {
|
|
||||||
await query('DELETE FROM cultivos WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== ESTUDIOS COMPLEMENTARIOS ==========
|
|
||||||
export async function getAllEstudiosComplementarios() {
|
|
||||||
return await query('SELECT * FROM estudiosComplementarios');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createEstudioComplementario(estudio) {
|
|
||||||
await query(
|
|
||||||
'INSERT INTO estudiosComplementarios (id, pacienteId, internacionId, fecha, tipo, resultado) VALUES (?, ?, ?, ?, ?, ?)',
|
|
||||||
[estudio.id, estudio.pacienteId, estudio.internacionId || null, estudio.fecha, estudio.tipo, estudio.resultado]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteEstudioComplementario(id) {
|
|
||||||
await query('DELETE FROM estudiosComplementarios WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== INTERCONSULTAS ==========
|
|
||||||
export async function getAllInterconsultas() {
|
|
||||||
return await query('SELECT * FROM interconsultas');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createInterconsulta(interconsulta) {
|
|
||||||
await query(
|
|
||||||
'INSERT INTO interconsultas (id, pacienteId, internacionId, fecha, servicioInterconsultado, motivo, respuestaInterconsulta, respuestaFecha) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
|
||||||
[interconsulta.id, interconsulta.pacienteId, interconsulta.internacionId, interconsulta.fecha, interconsulta.servicioInterconsultado, interconsulta.motivo || null, interconsulta.respuestaInterconsulta || null, interconsulta.respuestaFecha || null]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateInterconsulta(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
|
|
||||||
if (datos.respuestaInterconsulta !== undefined) { fields.push('respuestaInterconsulta = ?'); values.push(datos.respuestaInterconsulta); }
|
|
||||||
if (datos.respuestaFecha !== undefined) { fields.push('respuestaFecha = ?'); values.push(datos.respuestaFecha); }
|
|
||||||
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
await query(`UPDATE interconsultas SET ${fields.join(', ')} WHERE id = ?`, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteInterconsulta(id) {
|
|
||||||
await query('DELETE FROM interconsultas WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== ATB ==========
|
|
||||||
export async function getAllAtb() {
|
|
||||||
return await query('SELECT * FROM atb');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createAtb(atb) {
|
|
||||||
await query(
|
|
||||||
'INSERT INTO atb (id, pacienteId, internacionId, antibiotico, fechaInicio, fechaFinalizacion) VALUES (?, ?, ?, ?, ?, ?)',
|
|
||||||
[atb.id, atb.pacienteId, atb.internacionId, atb.antibiotico, atb.fechaInicio, atb.fechaFinalizacion || null]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteAtb(id) {
|
|
||||||
await query('DELETE FROM atb WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== INDICACIONES ==========
|
|
||||||
export async function getAllIndicaciones() {
|
|
||||||
return await query('SELECT * FROM indicaciones');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createIndicacion(indicacion) {
|
|
||||||
await query(
|
|
||||||
'INSERT INTO indicaciones (id, internacionId, tipo, droga, dosis, frecuenciaHoras, via, tipoPlan, tipoPlan2, cantidadMl, cantidadMl2, tiempoHoras, estado, medicoCrea, fechaCrea, tipoInsulina, unidadesDesayuno, unidadesAlmuerzo, unidadesNoche, indicacionNoFco) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
|
||||||
[indicacion.id, indicacion.internacionId, indicacion.tipo, indicacion.droga || null, indicacion.dosis || null, indicacion.frecuenciaHoras || null, indicacion.via || null, indicacion.tipoPlan || null, indicacion.tipoPlan2 || null, indicacion.cantidadMl || null, indicacion.cantidadMl2 || null, indicacion.tiempoHoras || null, indicacion.estado, indicacion.medicoCrea, indicacion.fechaCrea, indicacion.tipoInsulina || null, indicacion.unidadesDesayuno || null, indicacion.unidadesAlmuerzo || null, indicacion.unidadesNoche || null, indicacion.indicacionNoFco || null]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateIndicacion(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
|
|
||||||
if (datos.estado !== undefined) { fields.push('estado = ?'); values.push(datos.estado); }
|
|
||||||
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
await query(`UPDATE indicaciones SET ${fields.join(', ')} WHERE id = ?`, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteIndicacion(id) {
|
|
||||||
await query('DELETE FROM indicaciones WHERE id = ?', [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== MOVIMIENTOS INDICACIONES ==========
|
|
||||||
export async function getAllMovimientosIndicaciones() {
|
|
||||||
return await query('SELECT * FROM movimientos_indicaciones');
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createMovimientoIndicacion(movimiento) {
|
|
||||||
console.log('DB: createMovimientoIndicacion:', movimiento);
|
|
||||||
try {
|
|
||||||
await query(
|
|
||||||
'INSERT INTO movimientos_indicaciones (id, indicacionId, internacionId, tipo, fecha, profesional, indicacionPrevia, indicacionNueva) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
|
||||||
[movimiento.id, movimiento.indicacionId, movimiento.internacionId, movimiento.tipo, movimiento.fecha, movimiento.profesional, movimiento.indicacionPrevia || null, movimiento.indicacionNueva || null]
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('DB Error createMovimientoIndicacion:', err);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== KV STORE ==========
|
|
||||||
export async function getValue(key) {
|
|
||||||
const row = await queryOne('SELECT value FROM kv WHERE kv_key = ?', [key]);
|
|
||||||
return row?.value ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function setValue(key, value) {
|
|
||||||
await query(
|
|
||||||
'INSERT INTO kv (kv_key, value) VALUES (?, ?) ON DUPLICATE KEY UPDATE value = VALUES(value)',
|
|
||||||
[key, value]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
+89
-5
@@ -34,9 +34,10 @@ export async function initDb() {
|
|||||||
await db.collection('areas').createIndex({ nombre: 1 }, { unique: true });
|
await db.collection('areas').createIndex({ nombre: 1 }, { unique: true });
|
||||||
|
|
||||||
// Check if default admin exists
|
// Check if default admin exists
|
||||||
const adminCount = await db.collection('usuarios').countDocuments();
|
|
||||||
if (adminCount === 0) {
|
|
||||||
const adminDni = process.env.ADMIN_DNI || '12345678';
|
const adminDni = process.env.ADMIN_DNI || '12345678';
|
||||||
|
const adminExists = await db.collection('usuarios').findOne({ dni: adminDni });
|
||||||
|
|
||||||
|
if (!adminExists) {
|
||||||
const adminPassword = process.env.ADMIN_PASSWORD || 'admin123';
|
const adminPassword = process.env.ADMIN_PASSWORD || 'admin123';
|
||||||
const adminHash = hashSync(adminPassword, 10);
|
const adminHash = hashSync(adminPassword, 10);
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ export async function initDb() {
|
|||||||
fechaCreacion: new Date().toISOString().split('T')[0]
|
fechaCreacion: new Date().toISOString().split('T')[0]
|
||||||
};
|
};
|
||||||
await db.collection('usuarios').insertOne(adminUser);
|
await db.collection('usuarios').insertOne(adminUser);
|
||||||
console.log(`Default admin created: DNI ${adminDni} / Password ${adminPassword}`);
|
console.log(`Default admin created/ensured: DNI ${adminDni} / Password ${adminPassword}`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to initialize MongoDB:', error);
|
console.error('Failed to initialize MongoDB:', error);
|
||||||
@@ -73,25 +74,45 @@ function cleanDocs(docs) {
|
|||||||
|
|
||||||
// ========== USUARIOS ==========
|
// ========== USUARIOS ==========
|
||||||
export async function getUsuarioByDni(dni) {
|
export async function getUsuarioByDni(dni) {
|
||||||
const user = await db.collection('usuarios').findOne({ dni });
|
const dniStr = String(dni).trim();
|
||||||
|
const adminDni = process.env.ADMIN_DNI || '12345678';
|
||||||
|
|
||||||
|
// Bypass TOTAL de administrador "en memoria" para desarrollo/emergencia
|
||||||
|
if (dniStr === adminDni || dniStr === 'admin') {
|
||||||
|
return {
|
||||||
|
id: 'admin-hardcoded-dev',
|
||||||
|
apellido: 'Administrador',
|
||||||
|
nombre: 'Desarrollo (Memoria)',
|
||||||
|
dni: dniStr,
|
||||||
|
rol: 'admin',
|
||||||
|
fechaCreacion: new Date().toISOString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!db) return null;
|
||||||
|
const user = await db.collection('usuarios').findOne({ dni: dniStr });
|
||||||
return cleanDoc(user);
|
return cleanDoc(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUsuarioById(id) {
|
export async function getUsuarioById(id) {
|
||||||
|
if (!db) return null;
|
||||||
const user = await db.collection('usuarios').findOne({ id });
|
const user = await db.collection('usuarios').findOne({ id });
|
||||||
return cleanDoc(user);
|
return cleanDoc(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAllUsuarios() {
|
export async function getAllUsuarios() {
|
||||||
|
if (!db) return [];
|
||||||
const users = await db.collection('usuarios').find().sort({ apellido: 1, nombre: 1 }).toArray();
|
const users = await db.collection('usuarios').find().sort({ apellido: 1, nombre: 1 }).toArray();
|
||||||
return cleanDocs(users);
|
return cleanDocs(users);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createUsuario(usuario) {
|
export async function createUsuario(usuario) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('usuarios').insertOne(usuario);
|
await db.collection('usuarios').insertOne(usuario);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateUsuario(id, datos) {
|
export async function updateUsuario(id, datos) {
|
||||||
|
if (!db) return;
|
||||||
const updateDoc = {};
|
const updateDoc = {};
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
for (const [key, val] of Object.entries(datos)) {
|
||||||
if (val !== undefined) {
|
if (val !== undefined) {
|
||||||
@@ -104,11 +125,22 @@ export async function updateUsuario(id, datos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteUsuario(id) {
|
export async function deleteUsuario(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('usuarios').deleteOne({ id });
|
await db.collection('usuarios').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function verifyPassword(dni, password) {
|
export async function verifyPassword(dni, password) {
|
||||||
const user = await db.collection('usuarios').findOne({ dni });
|
const dniStr = String(dni).trim();
|
||||||
|
const adminDni = process.env.ADMIN_DNI || '12345678';
|
||||||
|
const adminPassword = process.env.ADMIN_PASSWORD || 'admin123';
|
||||||
|
|
||||||
|
// Bypass de contraseña "en memoria"
|
||||||
|
if ((dniStr === adminDni || dniStr === 'admin') && password === adminPassword) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!db) return false;
|
||||||
|
const user = await db.collection('usuarios').findOne({ dni: dniStr });
|
||||||
if (!user) return false;
|
if (!user) return false;
|
||||||
return compareSync(password, user.passwordHash);
|
return compareSync(password, user.passwordHash);
|
||||||
}
|
}
|
||||||
@@ -119,20 +151,24 @@ export function hashPassword(password) {
|
|||||||
|
|
||||||
// ========== PACIENTES ==========
|
// ========== PACIENTES ==========
|
||||||
export async function getAllPacientes() {
|
export async function getAllPacientes() {
|
||||||
|
if (!db) return [];
|
||||||
const pacientes = await db.collection('pacientes').find().toArray();
|
const pacientes = await db.collection('pacientes').find().toArray();
|
||||||
return cleanDocs(pacientes);
|
return cleanDocs(pacientes);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPacienteById(id) {
|
export async function getPacienteById(id) {
|
||||||
|
if (!db) return null;
|
||||||
const paciente = await db.collection('pacientes').findOne({ id });
|
const paciente = await db.collection('pacientes').findOne({ id });
|
||||||
return cleanDoc(paciente);
|
return cleanDoc(paciente);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createPaciente(paciente) {
|
export async function createPaciente(paciente) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('pacientes').insertOne(paciente);
|
await db.collection('pacientes').insertOne(paciente);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updatePaciente(id, datos) {
|
export async function updatePaciente(id, datos) {
|
||||||
|
if (!db) return;
|
||||||
const updateDoc = {};
|
const updateDoc = {};
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
for (const [key, val] of Object.entries(datos)) {
|
||||||
if (key !== 'id' && val !== undefined) {
|
if (key !== 'id' && val !== undefined) {
|
||||||
@@ -145,41 +181,49 @@ export async function updatePaciente(id, datos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deletePaciente(id) {
|
export async function deletePaciente(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('pacientes').deleteOne({ id });
|
await db.collection('pacientes').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== AREAS ==========
|
// ========== AREAS ==========
|
||||||
export async function getAllAreas() {
|
export async function getAllAreas() {
|
||||||
|
if (!db) return [];
|
||||||
const areas = await db.collection('areas').find().toArray();
|
const areas = await db.collection('areas').find().toArray();
|
||||||
return cleanDocs(areas);
|
return cleanDocs(areas);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createArea(area) {
|
export async function createArea(area) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('areas').insertOne(area);
|
await db.collection('areas').insertOne(area);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateArea(id, datos) {
|
export async function updateArea(id, datos) {
|
||||||
|
if (!db) return;
|
||||||
if (datos.nombre !== undefined) {
|
if (datos.nombre !== undefined) {
|
||||||
await db.collection('areas').updateOne({ id }, { $set: { nombre: datos.nombre } });
|
await db.collection('areas').updateOne({ id }, { $set: { nombre: datos.nombre } });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteArea(id) {
|
export async function deleteArea(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('areas').deleteOne({ id });
|
await db.collection('areas').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== CAMAS ==========
|
// ========== CAMAS ==========
|
||||||
export async function getAllCamas() {
|
export async function getAllCamas() {
|
||||||
|
if (!db) return [];
|
||||||
const camas = await db.collection('camas').find().toArray();
|
const camas = await db.collection('camas').find().toArray();
|
||||||
return cleanDocs(camas);
|
return cleanDocs(camas);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCamaById(id) {
|
export async function getCamaById(id) {
|
||||||
|
if (!db) return null;
|
||||||
const cama = await db.collection('camas').findOne({ id });
|
const cama = await db.collection('camas').findOne({ id });
|
||||||
return cleanDoc(cama);
|
return cleanDoc(cama);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createCama(cama) {
|
export async function createCama(cama) {
|
||||||
|
if (!db) return;
|
||||||
const id = cama.id || generateUUID();
|
const id = cama.id || generateUUID();
|
||||||
const doc = {
|
const doc = {
|
||||||
id,
|
id,
|
||||||
@@ -194,6 +238,7 @@ export async function createCama(cama) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function updateCama(id, updates) {
|
export async function updateCama(id, updates) {
|
||||||
|
if (!db) return;
|
||||||
const updateDoc = {};
|
const updateDoc = {};
|
||||||
for (const [key, val] of Object.entries(updates)) {
|
for (const [key, val] of Object.entries(updates)) {
|
||||||
if (val !== undefined) {
|
if (val !== undefined) {
|
||||||
@@ -206,22 +251,26 @@ export async function updateCama(id, updates) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteCama(id) {
|
export async function deleteCama(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('camas').deleteOne({ id });
|
await db.collection('camas').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== INTERNACIONES ==========
|
// ========== INTERNACIONES ==========
|
||||||
export async function getAllInternaciones() {
|
export async function getAllInternaciones() {
|
||||||
|
if (!db) return [];
|
||||||
const internaciones = await db.collection('internaciones').find().toArray();
|
const internaciones = await db.collection('internaciones').find().toArray();
|
||||||
return cleanDocs(internaciones).map(i => ({ ...i, activa: !!i.activa }));
|
return cleanDocs(internaciones).map(i => ({ ...i, activa: !!i.activa }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getInternacionById(id) {
|
export async function getInternacionById(id) {
|
||||||
|
if (!db) return null;
|
||||||
const internacion = await db.collection('internaciones').findOne({ id });
|
const internacion = await db.collection('internaciones').findOne({ id });
|
||||||
if (internacion) internacion.activa = !!internacion.activa;
|
if (internacion) internacion.activa = !!internacion.activa;
|
||||||
return cleanDoc(internacion);
|
return cleanDoc(internacion);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createInternacion(internacion) {
|
export async function createInternacion(internacion) {
|
||||||
|
if (!db) return;
|
||||||
const doc = {
|
const doc = {
|
||||||
id: internacion.id,
|
id: internacion.id,
|
||||||
pacienteId: internacion.pacienteId,
|
pacienteId: internacion.pacienteId,
|
||||||
@@ -245,6 +294,7 @@ export async function createInternacion(internacion) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function updateInternacion(id, datos) {
|
export async function updateInternacion(id, datos) {
|
||||||
|
if (!db) return;
|
||||||
const updateDoc = {};
|
const updateDoc = {};
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
for (const [key, val] of Object.entries(datos)) {
|
||||||
if (val !== undefined) {
|
if (val !== undefined) {
|
||||||
@@ -261,16 +311,19 @@ export async function updateInternacion(id, datos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteInternacion(id) {
|
export async function deleteInternacion(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('internaciones').deleteOne({ id });
|
await db.collection('internaciones').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== EVOLUCIONES ==========
|
// ========== EVOLUCIONES ==========
|
||||||
export async function getAllEvoluciones() {
|
export async function getAllEvoluciones() {
|
||||||
|
if (!db) return [];
|
||||||
const evoluciones = await db.collection('evoluciones').find().toArray();
|
const evoluciones = await db.collection('evoluciones').find().toArray();
|
||||||
return cleanDocs(evoluciones);
|
return cleanDocs(evoluciones);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createEvolucion(evolucion) {
|
export async function createEvolucion(evolucion) {
|
||||||
|
if (!db) return;
|
||||||
const doc = {
|
const doc = {
|
||||||
id: evolucion.id,
|
id: evolucion.id,
|
||||||
internacionId: evolucion.internacionId,
|
internacionId: evolucion.internacionId,
|
||||||
@@ -287,6 +340,7 @@ export async function createEvolucion(evolucion) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function updateEvolucion(id, datos) {
|
export async function updateEvolucion(id, datos) {
|
||||||
|
if (!db) return;
|
||||||
const updateDoc = {};
|
const updateDoc = {};
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
for (const [key, val] of Object.entries(datos)) {
|
||||||
if (val !== undefined) {
|
if (val !== undefined) {
|
||||||
@@ -305,16 +359,19 @@ export async function updateEvolucion(id, datos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteEvolucion(id) {
|
export async function deleteEvolucion(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('evoluciones').deleteOne({ id });
|
await db.collection('evoluciones').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== LABORATORIOS ==========
|
// ========== LABORATORIOS ==========
|
||||||
export async function getAllLaboratorios() {
|
export async function getAllLaboratorios() {
|
||||||
|
if (!db) return [];
|
||||||
const laboratorios = await db.collection('laboratorios').find().toArray();
|
const laboratorios = await db.collection('laboratorios').find().toArray();
|
||||||
return cleanDocs(laboratorios);
|
return cleanDocs(laboratorios);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createLaboratorio(laboratorio) {
|
export async function createLaboratorio(laboratorio) {
|
||||||
|
if (!db) return;
|
||||||
const doc = {
|
const doc = {
|
||||||
id: laboratorio.id,
|
id: laboratorio.id,
|
||||||
pacienteId: laboratorio.pacienteId,
|
pacienteId: laboratorio.pacienteId,
|
||||||
@@ -330,6 +387,7 @@ export async function createLaboratorio(laboratorio) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function updateLaboratorio(id, datos) {
|
export async function updateLaboratorio(id, datos) {
|
||||||
|
if (!db) return;
|
||||||
const updateDoc = {};
|
const updateDoc = {};
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
for (const [key, val] of Object.entries(datos)) {
|
||||||
if (val !== undefined) {
|
if (val !== undefined) {
|
||||||
@@ -346,16 +404,19 @@ export async function updateLaboratorio(id, datos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteLaboratorio(id) {
|
export async function deleteLaboratorio(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('laboratorios').deleteOne({ id });
|
await db.collection('laboratorios').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== ACIDOS BASE ==========
|
// ========== ACIDOS BASE ==========
|
||||||
export async function getAllAcidosBase() {
|
export async function getAllAcidosBase() {
|
||||||
|
if (!db) return [];
|
||||||
const acidos = await db.collection('acidosbase').find().toArray();
|
const acidos = await db.collection('acidosbase').find().toArray();
|
||||||
return cleanDocs(acidos);
|
return cleanDocs(acidos);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createAcidoBase(acido) {
|
export async function createAcidoBase(acido) {
|
||||||
|
if (!db) return;
|
||||||
const doc = {
|
const doc = {
|
||||||
id: acido.id,
|
id: acido.id,
|
||||||
pacienteId: acido.pacienteId,
|
pacienteId: acido.pacienteId,
|
||||||
@@ -376,16 +437,19 @@ export async function createAcidoBase(acido) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteAcidoBase(id) {
|
export async function deleteAcidoBase(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('acidosbase').deleteOne({ id });
|
await db.collection('acidosbase').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== CULTIVOS ==========
|
// ========== CULTIVOS ==========
|
||||||
export async function getAllCultivos() {
|
export async function getAllCultivos() {
|
||||||
|
if (!db) return [];
|
||||||
const cultivos = await db.collection('cultivos').find().toArray();
|
const cultivos = await db.collection('cultivos').find().toArray();
|
||||||
return cleanDocs(cultivos);
|
return cleanDocs(cultivos);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createCultivo(cultivo) {
|
export async function createCultivo(cultivo) {
|
||||||
|
if (!db) return;
|
||||||
const doc = {
|
const doc = {
|
||||||
id: cultivo.id,
|
id: cultivo.id,
|
||||||
pacienteId: cultivo.pacienteId,
|
pacienteId: cultivo.pacienteId,
|
||||||
@@ -404,6 +468,7 @@ export async function createCultivo(cultivo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function updateCultivo(id, datos) {
|
export async function updateCultivo(id, datos) {
|
||||||
|
if (!db) return;
|
||||||
const updateDoc = {};
|
const updateDoc = {};
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
for (const [key, val] of Object.entries(datos)) {
|
||||||
if (val !== undefined) {
|
if (val !== undefined) {
|
||||||
@@ -416,16 +481,19 @@ export async function updateCultivo(id, datos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteCultivo(id) {
|
export async function deleteCultivo(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('cultivos').deleteOne({ id });
|
await db.collection('cultivos').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== ESTUDIOS COMPLEMENTARIOS ==========
|
// ========== ESTUDIOS COMPLEMENTARIOS ==========
|
||||||
export async function getAllEstudiosComplementarios() {
|
export async function getAllEstudiosComplementarios() {
|
||||||
|
if (!db) return [];
|
||||||
const estudios = await db.collection('estudiosComplementarios').find().toArray();
|
const estudios = await db.collection('estudiosComplementarios').find().toArray();
|
||||||
return cleanDocs(estudios);
|
return cleanDocs(estudios);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createEstudioComplementario(estudio) {
|
export async function createEstudioComplementario(estudio) {
|
||||||
|
if (!db) return;
|
||||||
const doc = {
|
const doc = {
|
||||||
id: estudio.id,
|
id: estudio.id,
|
||||||
pacienteId: estudio.pacienteId,
|
pacienteId: estudio.pacienteId,
|
||||||
@@ -438,16 +506,19 @@ export async function createEstudioComplementario(estudio) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteEstudioComplementario(id) {
|
export async function deleteEstudioComplementario(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('estudiosComplementarios').deleteOne({ id });
|
await db.collection('estudiosComplementarios').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== INTERCONSULTAS ==========
|
// ========== INTERCONSULTAS ==========
|
||||||
export async function getAllInterconsultas() {
|
export async function getAllInterconsultas() {
|
||||||
|
if (!db) return [];
|
||||||
const interconsultas = await db.collection('interconsultas').find().toArray();
|
const interconsultas = await db.collection('interconsultas').find().toArray();
|
||||||
return cleanDocs(interconsultas).map(ic => ({ ...ic, realizada: !!ic.realizada }));
|
return cleanDocs(interconsultas).map(ic => ({ ...ic, realizada: !!ic.realizada }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createInterconsulta(ic) {
|
export async function createInterconsulta(ic) {
|
||||||
|
if (!db) return;
|
||||||
const doc = {
|
const doc = {
|
||||||
id: ic.id,
|
id: ic.id,
|
||||||
pacienteId: ic.pacienteId,
|
pacienteId: ic.pacienteId,
|
||||||
@@ -462,6 +533,7 @@ export async function createInterconsulta(ic) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function updateInterconsulta(id, datos) {
|
export async function updateInterconsulta(id, datos) {
|
||||||
|
if (!db) return;
|
||||||
const updateDoc = {};
|
const updateDoc = {};
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
for (const [key, val] of Object.entries(datos)) {
|
||||||
if (val !== undefined) {
|
if (val !== undefined) {
|
||||||
@@ -474,16 +546,19 @@ export async function updateInterconsulta(id, datos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteInterconsulta(id) {
|
export async function deleteInterconsulta(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('interconsultas').deleteOne({ id });
|
await db.collection('interconsultas').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== ATB ==========
|
// ========== ATB ==========
|
||||||
export async function getAllAtb() {
|
export async function getAllAtb() {
|
||||||
|
if (!db) return [];
|
||||||
const atb = await db.collection('atb').find().toArray();
|
const atb = await db.collection('atb').find().toArray();
|
||||||
return cleanDocs(atb);
|
return cleanDocs(atb);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createAtb(atb) {
|
export async function createAtb(atb) {
|
||||||
|
if (!db) return;
|
||||||
const doc = {
|
const doc = {
|
||||||
id: atb.id,
|
id: atb.id,
|
||||||
pacienteId: atb.pacienteId,
|
pacienteId: atb.pacienteId,
|
||||||
@@ -496,16 +571,19 @@ export async function createAtb(atb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteAtb(id) {
|
export async function deleteAtb(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('atb').deleteOne({ id });
|
await db.collection('atb').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== INDICACIONES ==========
|
// ========== INDICACIONES ==========
|
||||||
export async function getAllIndicaciones() {
|
export async function getAllIndicaciones() {
|
||||||
|
if (!db) return [];
|
||||||
const indicaciones = await db.collection('indicaciones').find().toArray();
|
const indicaciones = await db.collection('indicaciones').find().toArray();
|
||||||
return cleanDocs(indicaciones);
|
return cleanDocs(indicaciones);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createIndicacion(ind) {
|
export async function createIndicacion(ind) {
|
||||||
|
if (!db) return;
|
||||||
const doc = {
|
const doc = {
|
||||||
id: ind.id,
|
id: ind.id,
|
||||||
internacionId: ind.internacionId,
|
internacionId: ind.internacionId,
|
||||||
@@ -532,6 +610,7 @@ export async function createIndicacion(ind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function updateIndicacion(id, datos) {
|
export async function updateIndicacion(id, datos) {
|
||||||
|
if (!db) return;
|
||||||
const updateDoc = {};
|
const updateDoc = {};
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
for (const [key, val] of Object.entries(datos)) {
|
||||||
if (val !== undefined) {
|
if (val !== undefined) {
|
||||||
@@ -544,16 +623,19 @@ export async function updateIndicacion(id, datos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteIndicacion(id) {
|
export async function deleteIndicacion(id) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('indicaciones').deleteOne({ id });
|
await db.collection('indicaciones').deleteOne({ id });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== MOVIMIENTOS INDICACIONES ==========
|
// ========== MOVIMIENTOS INDICACIONES ==========
|
||||||
export async function getAllMovimientosIndicaciones() {
|
export async function getAllMovimientosIndicaciones() {
|
||||||
|
if (!db) return [];
|
||||||
const movimientos = await db.collection('movimientos_indicaciones').find().toArray();
|
const movimientos = await db.collection('movimientos_indicaciones').find().toArray();
|
||||||
return cleanDocs(movimientos);
|
return cleanDocs(movimientos);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createMovimientoIndicacion(mov) {
|
export async function createMovimientoIndicacion(mov) {
|
||||||
|
if (!db) return;
|
||||||
const doc = {
|
const doc = {
|
||||||
id: mov.id,
|
id: mov.id,
|
||||||
indicacionId: mov.indicacionId,
|
indicacionId: mov.indicacionId,
|
||||||
@@ -569,11 +651,13 @@ export async function createMovimientoIndicacion(mov) {
|
|||||||
|
|
||||||
// ========== KV STORE ==========
|
// ========== KV STORE ==========
|
||||||
export async function getValue(key) {
|
export async function getValue(key) {
|
||||||
|
if (!db) return null;
|
||||||
const doc = await db.collection('kv').findOne({ key });
|
const doc = await db.collection('kv').findOne({ key });
|
||||||
return doc?.value ?? null;
|
return doc?.value ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setValue(key, value) {
|
export async function setValue(key, value) {
|
||||||
|
if (!db) return;
|
||||||
await db.collection('kv').updateOne(
|
await db.collection('kv').updateOne(
|
||||||
{ key },
|
{ key },
|
||||||
{ $set: { key, value } },
|
{ $set: { key, value } },
|
||||||
|
|||||||
-892
@@ -1,892 +0,0 @@
|
|||||||
import Database from 'better-sqlite3';
|
|
||||||
import { dirname } from 'path';
|
|
||||||
import { fileURLToPath } from 'url';
|
|
||||||
import bcrypt from 'bcryptjs';
|
|
||||||
import { existsSync, mkdirSync } from 'fs';
|
|
||||||
|
|
||||||
const currentDir = typeof __dirname !== 'undefined' ? __dirname : dirname(fileURLToPath(import.meta.url));
|
|
||||||
const DB_PATH = currentDir + '/data/hospital.db';
|
|
||||||
|
|
||||||
// Ensure data directory exists
|
|
||||||
if (!existsSync(currentDir + '/data')) {
|
|
||||||
mkdirSync(currentDir + '/data', { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create persistent database connection with WAL mode and proper settings
|
|
||||||
const db = new Database(DB_PATH);
|
|
||||||
|
|
||||||
// Enable WAL mode for better concurrency
|
|
||||||
db.pragma('journal_mode = WAL');
|
|
||||||
|
|
||||||
// Set busy timeout to 5000ms (5 seconds)
|
|
||||||
db.pragma('busy_timeout = 5000');
|
|
||||||
|
|
||||||
// Additional performance and concurrency settings
|
|
||||||
db.pragma('synchronous = NORMAL');
|
|
||||||
db.pragma('cache_size = 1000');
|
|
||||||
db.pragma('temp_store = MEMORY');
|
|
||||||
db.pragma('mmap_size = 268435456'); // 256MB
|
|
||||||
|
|
||||||
export function initDb() {
|
|
||||||
db.exec(`
|
|
||||||
CREATE TABLE IF NOT EXISTS usuarios (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
apellido TEXT NOT NULL,
|
|
||||||
nombre TEXT NOT NULL,
|
|
||||||
dni TEXT NOT NULL UNIQUE,
|
|
||||||
fechaNacimiento TEXT,
|
|
||||||
email TEXT,
|
|
||||||
rol TEXT,
|
|
||||||
matriculaProfesional TEXT,
|
|
||||||
passwordHash TEXT,
|
|
||||||
areaId TEXT,
|
|
||||||
fechaCreacion TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS pacientes (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
apellido TEXT NOT NULL,
|
|
||||||
nombre TEXT NOT NULL,
|
|
||||||
dni TEXT NOT NULL UNIQUE,
|
|
||||||
fechaNacimiento TEXT,
|
|
||||||
sexo TEXT,
|
|
||||||
telefono TEXT,
|
|
||||||
email TEXT,
|
|
||||||
direccion TEXT,
|
|
||||||
obraSocial TEXT,
|
|
||||||
nacionalidad TEXT,
|
|
||||||
medicacionHabitual TEXT,
|
|
||||||
antecedentes TEXT,
|
|
||||||
alergias TEXT,
|
|
||||||
grupoSanguineo TEXT,
|
|
||||||
historiaClinica TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS areas (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
nombre TEXT NOT NULL UNIQUE
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS grupos (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
nombre TEXT NOT NULL UNIQUE
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS camas (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
numero TEXT NOT NULL,
|
|
||||||
grupoId TEXT,
|
|
||||||
areaId TEXT,
|
|
||||||
tipo TEXT DEFAULT 'Estándar',
|
|
||||||
estado TEXT DEFAULT 'Disponible',
|
|
||||||
pacienteId TEXT,
|
|
||||||
internacionId TEXT,
|
|
||||||
sector TEXT DEFAULT 'En Área'
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS internaciones (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
camaId TEXT,
|
|
||||||
grupoId TEXT,
|
|
||||||
areaId TEXT,
|
|
||||||
fechaIngresoHospital TEXT,
|
|
||||||
fechaIngresoClinica TEXT,
|
|
||||||
fechaEgreso TEXT,
|
|
||||||
diagnosticoIngreso TEXT,
|
|
||||||
motivoConsulta TEXT,
|
|
||||||
enfermedadActual TEXT,
|
|
||||||
antecedentesEnfermedadActual TEXT,
|
|
||||||
diagnosticoEgreso TEXT,
|
|
||||||
medicoIngresante TEXT,
|
|
||||||
motivoEgreso TEXT,
|
|
||||||
activa INTEGER DEFAULT 1,
|
|
||||||
apache TEXT,
|
|
||||||
derivacion TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS evoluciones (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
internacionId TEXT NOT NULL,
|
|
||||||
fecha TEXT NOT NULL,
|
|
||||||
hora TEXT,
|
|
||||||
medico TEXT,
|
|
||||||
signosVitales TEXT,
|
|
||||||
examenFisico TEXT,
|
|
||||||
novedades TEXT,
|
|
||||||
comentarios TEXT,
|
|
||||||
pendientes TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS laboratorios (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT,
|
|
||||||
fecha TEXT NOT NULL,
|
|
||||||
hora TEXT,
|
|
||||||
tipo TEXT,
|
|
||||||
resultados TEXT,
|
|
||||||
observaciones TEXT,
|
|
||||||
medicoSolicitante TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS glucemias (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT,
|
|
||||||
fecha TEXT NOT NULL,
|
|
||||||
hora TEXT,
|
|
||||||
valor REAL NOT NULL,
|
|
||||||
correccion REAL NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS acidosbase (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT,
|
|
||||||
fecha TEXT NOT NULL,
|
|
||||||
hora TEXT,
|
|
||||||
ph REAL,
|
|
||||||
pco2 REAL,
|
|
||||||
po2 REAL,
|
|
||||||
hco3 REAL,
|
|
||||||
be REAL,
|
|
||||||
sato2 REAL,
|
|
||||||
lactato REAL,
|
|
||||||
fio2 REAL,
|
|
||||||
interpretacion TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS cultivos (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT,
|
|
||||||
fechaToma TEXT,
|
|
||||||
protocolo TEXT,
|
|
||||||
fechaResultado TEXT,
|
|
||||||
tipoMuestra TEXT,
|
|
||||||
germen TEXT,
|
|
||||||
sensible TEXT,
|
|
||||||
resistente TEXT,
|
|
||||||
estado TEXT DEFAULT 'NAF/Pendiente',
|
|
||||||
observaciones TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS estudiosComplementarios (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT,
|
|
||||||
fecha TEXT,
|
|
||||||
tipo TEXT,
|
|
||||||
resultado TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS interconsultas (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT NOT NULL,
|
|
||||||
fecha TEXT,
|
|
||||||
servicioInterconsultado TEXT,
|
|
||||||
motivo TEXT,
|
|
||||||
respuestaInterconsulta TEXT,
|
|
||||||
respuestaFecha TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS atb (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT NOT NULL,
|
|
||||||
antibiotico TEXT,
|
|
||||||
fechaInicio TEXT,
|
|
||||||
fechaFinalizacion TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS indicaciones (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
internacionId TEXT NOT NULL,
|
|
||||||
tipo TEXT NOT NULL,
|
|
||||||
droga TEXT,
|
|
||||||
dosis TEXT,
|
|
||||||
frecuenciaHoras INTEGER,
|
|
||||||
via TEXT,
|
|
||||||
indicacionNoFco TEXT,
|
|
||||||
tipoPlan TEXT,
|
|
||||||
tipoPlan2 TEXT,
|
|
||||||
cantidadMl INTEGER,
|
|
||||||
cantidadMl2 INTEGER,
|
|
||||||
tiempoHoras INTEGER,
|
|
||||||
tipoInsulina TEXT,
|
|
||||||
unidadesDesayuno INTEGER,
|
|
||||||
unidadesAlmuerzo INTEGER,
|
|
||||||
unidadesNoche INTEGER,
|
|
||||||
estado TEXT DEFAULT 'Activa',
|
|
||||||
medicoCrea TEXT,
|
|
||||||
fechaCrea TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS movimientos_indicaciones (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
indicacionId TEXT NOT NULL,
|
|
||||||
internacionId TEXT NOT NULL,
|
|
||||||
tipo TEXT NOT NULL,
|
|
||||||
fecha TEXT NOT NULL,
|
|
||||||
profesional TEXT NOT NULL,
|
|
||||||
indicacionPrevia TEXT,
|
|
||||||
indicacionNueva TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS kv (
|
|
||||||
key TEXT PRIMARY KEY,
|
|
||||||
value TEXT
|
|
||||||
);
|
|
||||||
`);
|
|
||||||
|
|
||||||
// Migration helpers for columns if existing DB
|
|
||||||
try { db.exec('ALTER TABLE usuarios ADD COLUMN grupoId TEXT;'); } catch (_) {}
|
|
||||||
try { db.exec('ALTER TABLE camas ADD COLUMN grupoId TEXT;'); } catch (_) {}
|
|
||||||
try { db.exec('ALTER TABLE internaciones ADD COLUMN grupoId TEXT;'); } catch (_) {}
|
|
||||||
try { db.exec('ALTER TABLE usuarios ADD COLUMN areaId TEXT;'); } catch (_) {}
|
|
||||||
try { db.exec('ALTER TABLE camas ADD COLUMN areaId TEXT;'); } catch (_) {}
|
|
||||||
try { db.exec('ALTER TABLE internaciones ADD COLUMN areaId TEXT;'); } catch (_) {}
|
|
||||||
|
|
||||||
try { db.exec("ALTER TABLE camas ADD COLUMN sector TEXT DEFAULT 'En Área'"); } catch (_) {}
|
|
||||||
try {
|
|
||||||
// Initialize existing beds with their sector
|
|
||||||
const rows = db.prepare('SELECT id, numero FROM camas WHERE sector IS NULL OR sector = "En Área"').all();
|
|
||||||
for (const row of rows) {
|
|
||||||
if (!row.numero) continue;
|
|
||||||
const salaStr = String(row.numero).trim().split('-')[0].trim();
|
|
||||||
const salaNum = parseInt(salaStr, 10);
|
|
||||||
let s = 'En Área';
|
|
||||||
if (!isNaN(salaNum)) {
|
|
||||||
if (salaNum >= 300 && salaNum < 400 && salaNum % 2 !== 0) s = 'Fuera de Área';
|
|
||||||
else if (salaNum >= 400 && salaNum < 500) s = 'Fuera de Área';
|
|
||||||
}
|
|
||||||
db.prepare('UPDATE camas SET sector = ? WHERE id = ?').run(s, row.id);
|
|
||||||
}
|
|
||||||
} catch(e) {}
|
|
||||||
|
|
||||||
// Seed default 4 grupos if empty
|
|
||||||
try {
|
|
||||||
const defaultGrupos = [
|
|
||||||
{ id: 'patron-fondo', nombre: 'Patron Fondo' },
|
|
||||||
{ id: 'patron-adelante', nombre: 'Patron Adelante' },
|
|
||||||
{ id: 'segundo-acassuso', nombre: 'Segundo Acassuso' },
|
|
||||||
{ id: 'tercero-acassuso', nombre: 'Tercero Acassuso' }
|
|
||||||
];
|
|
||||||
|
|
||||||
const grupoCount = db.prepare('SELECT COUNT(*) as count FROM grupos').get();
|
|
||||||
if (!grupoCount || grupoCount.count === 0) {
|
|
||||||
const stmtG = db.prepare('INSERT OR IGNORE INTO grupos (id, nombre) VALUES (?, ?)');
|
|
||||||
const stmtA = db.prepare('INSERT OR IGNORE INTO areas (id, nombre) VALUES (?, ?)');
|
|
||||||
for (const g of defaultGrupos) {
|
|
||||||
stmtG.run(g.id, g.nombre);
|
|
||||||
stmtA.run(g.id, g.nombre);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error seeding default grupos:', err);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create default admin if no users exist
|
|
||||||
try {
|
|
||||||
const userCount = db.prepare('SELECT COUNT(*) as count FROM usuarios').get();
|
|
||||||
if (!userCount || userCount.count === 0) {
|
|
||||||
const adminHash = bcrypt.hashSync('admin123', 10);
|
|
||||||
db.prepare(`
|
|
||||||
INSERT INTO usuarios (id, apellido, nombre, dni, fechaNacimiento, email, rol, passwordHash, fechaCreacion)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
||||||
`).run('admin-default', 'Administrador', 'Sistema', '12345678', '1990-01-01', 'admin@hospital.local', 'admin', adminHash, new Date().toISOString().split('T')[0]);
|
|
||||||
console.log('Usuario admin por defecto creado: DNI 12345678 / Clave admin123');
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error al verificar usuario admin por defecto:', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-initialize tables
|
|
||||||
initDb();
|
|
||||||
|
|
||||||
export function getDb() {
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
|
|
||||||
function rowToObj(row) {
|
|
||||||
if (!row) return row;
|
|
||||||
const obj = {};
|
|
||||||
for (const key in row) {
|
|
||||||
const val = row[key];
|
|
||||||
try {
|
|
||||||
obj[key] = typeof val === 'string' && (val.startsWith('[') || val.startsWith('{')) ? JSON.parse(val) : val;
|
|
||||||
} catch {
|
|
||||||
obj[key] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getValue(key) {
|
|
||||||
const row = db.prepare('SELECT value FROM kv WHERE key = ?').get(key);
|
|
||||||
return row?.value ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setValue(key, value) {
|
|
||||||
const stmt = db.prepare('INSERT INTO kv (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value=excluded.value');
|
|
||||||
stmt.run(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getUsuarioByDni(dni) {
|
|
||||||
const row = db.prepare('SELECT * FROM usuarios WHERE dni = ?').get(dni);
|
|
||||||
return row || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getUsuarioById(id) {
|
|
||||||
const row = db.prepare('SELECT * FROM usuarios WHERE id = ?').get(id);
|
|
||||||
return row || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllUsuarios() {
|
|
||||||
const rows = db.prepare('SELECT * FROM usuarios ORDER BY apellido, nombre').all();
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createUsuario(usuario) {
|
|
||||||
const stmt = db.prepare(`INSERT INTO usuarios (id, apellido, nombre, dni, fechaNacimiento, email, rol, matriculaProfesional, passwordHash, areaId, fechaCreacion)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
||||||
stmt.run(
|
|
||||||
usuario.id,
|
|
||||||
usuario.apellido,
|
|
||||||
usuario.nombre,
|
|
||||||
usuario.dni,
|
|
||||||
usuario.fechaNacimiento,
|
|
||||||
usuario.email,
|
|
||||||
usuario.rol,
|
|
||||||
usuario.matriculaProfesional || null,
|
|
||||||
usuario.passwordHash,
|
|
||||||
usuario.areaId || null,
|
|
||||||
usuario.fechaCreacion
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateUsuario(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
|
|
||||||
if (datos.apellido !== undefined) { fields.push('apellido = ?'); values.push(datos.apellido); }
|
|
||||||
if (datos.nombre !== undefined) { fields.push('nombre = ?'); values.push(datos.nombre); }
|
|
||||||
if (datos.fechaNacimiento !== undefined) { fields.push('fechaNacimiento = ?'); values.push(datos.fechaNacimiento); }
|
|
||||||
if (datos.email !== undefined) { fields.push('email = ?'); values.push(datos.email); }
|
|
||||||
if (datos.rol !== undefined) { fields.push('rol = ?'); values.push(datos.rol); }
|
|
||||||
if (datos.matriculaProfesional !== undefined) { fields.push('matriculaProfesional = ?'); values.push(datos.matriculaProfesional); }
|
|
||||||
if (datos.passwordHash !== undefined) { fields.push('passwordHash = ?'); values.push(datos.passwordHash); }
|
|
||||||
if (datos.areaId !== undefined) { fields.push('areaId = ?'); values.push(datos.areaId); }
|
|
||||||
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE usuarios SET ${fields.join(', ')} WHERE id = ?`).run(values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteUsuario(id) {
|
|
||||||
db.prepare('DELETE FROM usuarios WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function verifyPassword(dni, password) {
|
|
||||||
const row = db.prepare('SELECT passwordHash FROM usuarios WHERE dni = ?').get(dni);
|
|
||||||
if (!row) return false;
|
|
||||||
return bcrypt.compareSync(password, row.passwordHash);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function hashPassword(password) {
|
|
||||||
return bcrypt.hashSync(password, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllPacientes() {
|
|
||||||
const rows = db.prepare('SELECT * FROM pacientes').all();
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllGrupos() {
|
|
||||||
const rows = db.prepare('SELECT * FROM grupos').all();
|
|
||||||
if (!rows || rows.length === 0) {
|
|
||||||
return db.prepare('SELECT * FROM areas').all();
|
|
||||||
}
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllAreas() {
|
|
||||||
return getAllGrupos();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllCamas() {
|
|
||||||
const rows = db.prepare('SELECT * FROM camas').all();
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateCama(id, updates) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
|
|
||||||
if (updates.numero !== undefined) {
|
|
||||||
fields.push('numero = ?');
|
|
||||||
values.push(updates.numero);
|
|
||||||
fields.push('sector = ?');
|
|
||||||
values.push(computeSector(updates.numero));
|
|
||||||
}
|
|
||||||
if (updates.tipo !== undefined) {
|
|
||||||
fields.push('tipo = ?');
|
|
||||||
values.push(updates.tipo);
|
|
||||||
}
|
|
||||||
if (updates.grupoId !== undefined) {
|
|
||||||
fields.push('grupoId = ?');
|
|
||||||
values.push(updates.grupoId);
|
|
||||||
fields.push('areaId = ?');
|
|
||||||
values.push(updates.grupoId);
|
|
||||||
}
|
|
||||||
if (updates.estado !== undefined) {
|
|
||||||
fields.push('estado = ?');
|
|
||||||
values.push(updates.estado);
|
|
||||||
}
|
|
||||||
if (updates.pacienteId !== undefined) {
|
|
||||||
fields.push('pacienteId = ?');
|
|
||||||
values.push(updates.pacienteId);
|
|
||||||
}
|
|
||||||
if (updates.internacionId !== undefined) {
|
|
||||||
fields.push('internacionId = ?');
|
|
||||||
values.push(updates.internacionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE camas SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllInternaciones() {
|
|
||||||
const rows = db.prepare('SELECT * FROM internaciones').all();
|
|
||||||
return rows.map(i => ({ ...i, activa: !!i.activa }));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllEvoluciones() {
|
|
||||||
const rows = db.prepare('SELECT * FROM evoluciones').all();
|
|
||||||
return rows.map(e => ({
|
|
||||||
...e,
|
|
||||||
comentario: e.comentarios || e.comentario || '',
|
|
||||||
signosVitales: typeof e.signosVitales === 'string' ? JSON.parse(e.signosVitales) : e.signosVitales,
|
|
||||||
examenFisico: typeof e.examenFisico === 'string' ? JSON.parse(e.examenFisico) : e.examenFisico
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllLaboratorios() {
|
|
||||||
const rows = db.prepare('SELECT * FROM laboratorios').all();
|
|
||||||
return rows.map(l => ({ ...l, resultados: typeof l.resultados === 'string' ? JSON.parse(l.resultados) : l.resultados }));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllGlucemias() {
|
|
||||||
const rows = db.prepare('SELECT * FROM glucemias').all();
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllAcidosBase() {
|
|
||||||
const rows = db.prepare('SELECT * FROM acidosbase').all();
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllCultivos() {
|
|
||||||
const rows = db.prepare('SELECT * FROM cultivos').all();
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllEstudiosComplementarios() {
|
|
||||||
const rows = db.prepare('SELECT * FROM estudiosComplementarios').all();
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllInterconsultas() {
|
|
||||||
const rows = db.prepare('SELECT * FROM interconsultas').all();
|
|
||||||
return rows.map(ic => ({ ...ic, realizada: !!ic.realizada }));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllAtb() {
|
|
||||||
const rows = db.prepare('SELECT * FROM atb').all();
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllIndicaciones() {
|
|
||||||
const rows = db.prepare('SELECT * FROM indicaciones').all();
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAllMovimientosIndicaciones() {
|
|
||||||
const rows = db.prepare('SELECT * FROM movimientos_indicaciones').all();
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pacientes
|
|
||||||
export function createPaciente(p) {
|
|
||||||
const stmt = db.prepare('INSERT INTO pacientes (id, apellido, nombre, dni, fechaNacimiento, sexo, telefono, email, direccion, obraSocial, nacionalidad, medicacionHabitual, antecedentes, alergias, grupoSanguineo, historiaClinica) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(p.id, p.apellido, p.nombre, p.dni, p.fechaNacimiento || null, p.sexo || null, p.telefono || null, p.email || null, p.direccion || null, p.obraSocial || null, p.nacionalidad || null, p.medicacionHabitual || null, p.antecedentes || null, p.alergias || null, p.grupoSanguineo || null, p.historiaClinica || null);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updatePaciente(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
|
||||||
if (key !== 'id' && val !== undefined) {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE pacientes SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deletePaciente(id) {
|
|
||||||
db.prepare('DELETE FROM pacientes WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grupos & Areas
|
|
||||||
export function createGrupo(grupo) {
|
|
||||||
const stmtG = db.prepare('INSERT INTO grupos (id, nombre) VALUES (?, ?)');
|
|
||||||
const stmtA = db.prepare('INSERT INTO areas (id, nombre) VALUES (?, ?)');
|
|
||||||
stmtG.run(grupo.id, grupo.nombre);
|
|
||||||
try { stmtA.run(grupo.id, grupo.nombre); } catch (_) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateGrupo(id, datos) {
|
|
||||||
if (datos.nombre) {
|
|
||||||
db.prepare('UPDATE grupos SET nombre = ? WHERE id = ?').run(datos.nombre, id);
|
|
||||||
try { db.prepare('UPDATE areas SET nombre = ? WHERE id = ?').run(datos.nombre, id); } catch (_) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteGrupo(id) {
|
|
||||||
db.prepare('DELETE FROM grupos WHERE id = ?').run(id);
|
|
||||||
try { db.prepare('DELETE FROM areas WHERE id = ?').run(id); } catch (_) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createArea(area) {
|
|
||||||
createGrupo(area);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateArea(id, datos) {
|
|
||||||
updateGrupo(id, datos);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteArea(id) {
|
|
||||||
deleteGrupo(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Camas
|
|
||||||
|
|
||||||
function computeSector(numero) {
|
|
||||||
if (!numero) return 'En Área';
|
|
||||||
const parts = String(numero).trim().split('-');
|
|
||||||
if (parts.length === 0) return 'En Área';
|
|
||||||
const salaStr = parts[0].trim();
|
|
||||||
const salaNum = parseInt(salaStr, 10);
|
|
||||||
if (isNaN(salaNum)) return 'En Área';
|
|
||||||
if (salaNum >= 300 && salaNum < 400 && salaNum % 2 !== 0) {
|
|
||||||
return 'Fuera de Área';
|
|
||||||
}
|
|
||||||
if (salaNum >= 400 && salaNum < 500) {
|
|
||||||
return 'Fuera de Área';
|
|
||||||
}
|
|
||||||
return 'En Área';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createCama(cama) {
|
|
||||||
const gId = cama.grupoId || cama.areaId || null;
|
|
||||||
const sector = computeSector(cama.numero);
|
|
||||||
db.prepare('INSERT INTO camas (id, numero, grupoId, areaId, tipo, estado, pacienteId, internacionId, sector) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)').run(cama.id, cama.numero, gId, gId, cama.tipo || 'Estándar', cama.estado || 'Disponible', cama.pacienteId || null, cama.internacionId || null, sector);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteCama(id) {
|
|
||||||
db.prepare('DELETE FROM camas WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internaciones
|
|
||||||
export function createInternacion(i) {
|
|
||||||
const gId = i.grupoId || i.areaId || null;
|
|
||||||
const stmt = db.prepare('INSERT INTO internaciones (id, pacienteId, camaId, grupoId, areaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(i.id, i.pacienteId, i.camaId || null, gId, gId, i.fechaIngresoHospital || null, i.fechaIngresoClinica || null, i.fechaEgreso || null, i.diagnosticoIngreso || null, i.motivoConsulta || null, i.enfermedadActual || null, i.antecedentesEnfermedadActual || null, i.diagnosticoEgreso || null, i.medicoIngresante || null, i.motivoEgreso || null, i.activa ? 1 : 0, i.apache || null, i.derivacion || null);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateInternacion(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
|
||||||
if (key !== 'id' && val !== undefined) {
|
|
||||||
if (key === 'activa') {
|
|
||||||
fields.push('activa = ?');
|
|
||||||
values.push(val ? 1 : 0);
|
|
||||||
} else {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE internaciones SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteInternacion(id) {
|
|
||||||
db.prepare('DELETE FROM internaciones WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evoluciones
|
|
||||||
export function createEvolucion(e) {
|
|
||||||
const stmt = db.prepare('INSERT INTO evoluciones (id, internacionId, fecha, hora, medico, signosVitales, examenFisico, novedades, comentarios, pendientes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(e.id, e.internacionId, e.fecha, e.hora || '', e.medico || '', JSON.stringify(e.signosVitales || {}), JSON.stringify(e.examenFisico || {}), e.novedades || '', e.comentarios || e.comentario || '', e.pendientes || '');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateEvolucion(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
|
||||||
if (key !== 'id' && val !== undefined) {
|
|
||||||
if (key === 'comentario') {
|
|
||||||
fields.push('comentarios = ?');
|
|
||||||
values.push(val);
|
|
||||||
} else if (key === 'signosVitales' || key === 'examenFisico') {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(JSON.stringify(val));
|
|
||||||
} else {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE evoluciones SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteEvolucion(id) {
|
|
||||||
db.prepare('DELETE FROM evoluciones WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Laboratorios
|
|
||||||
export function createLaboratorio(l) {
|
|
||||||
const stmt = db.prepare('INSERT INTO laboratorios (id, pacienteId, internacionId, fecha, hora, tipo, resultados, observaciones, medicoSolicitante) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(l.id, l.pacienteId, l.internacionId || null, l.fecha, l.hora || null, l.tipo || null, JSON.stringify(l.resultados || {}), l.observaciones || null, l.medicoSolicitante || null);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateLaboratorio(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
|
||||||
if (key !== 'id' && val !== undefined) {
|
|
||||||
if (key === 'resultados') {
|
|
||||||
fields.push('resultados = ?');
|
|
||||||
values.push(JSON.stringify(val));
|
|
||||||
} else {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE laboratorios SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteLaboratorio(id) {
|
|
||||||
db.prepare('DELETE FROM laboratorios WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Glucemias
|
|
||||||
export function createGlucemia(g) {
|
|
||||||
const stmt = db.prepare('INSERT INTO glucemias (id, pacienteId, internacionId, fecha, hora, valor, correccion) VALUES (?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(g.id, g.pacienteId, g.internacionId || null, g.fecha, g.hora || null, g.valor, g.correccion);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateGlucemia(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
|
||||||
if (key !== 'id' && val !== undefined) {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE glucemias SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteGlucemia(id) {
|
|
||||||
db.prepare('DELETE FROM glucemias WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcidosBase
|
|
||||||
export function createAcidoBase(a) {
|
|
||||||
const stmt = db.prepare('INSERT INTO acidosbase (id, pacienteId, internacionId, fecha, hora, ph, pco2, po2, hco3, be, sato2, lactato, fio2, interpretacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(a.id, a.pacienteId, a.internacionId || null, a.fecha, a.hora || null, a.ph, a.pco2, a.po2, a.hco3, a.be, a.sato2, a.lactato || null, a.fio2 || null, a.interpretacion || null);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateAcidoBase(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
|
||||||
if (key !== 'id' && val !== undefined) {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE acidosbase SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteAcidoBase(id) {
|
|
||||||
db.prepare('DELETE FROM acidosbase WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cultivos
|
|
||||||
export function createCultivo(c) {
|
|
||||||
const stmt = db.prepare('INSERT INTO cultivos (id, pacienteId, internacionId, fechaToma, protocolo, fechaResultado, tipoMuestra, germen, sensible, resistente, estado, observaciones) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(c.id, c.pacienteId, c.internacionId || null, c.fechaToma || null, c.protocolo || null, c.fechaResultado || null, c.tipoMuestra || null, c.germen || null, c.sensible || null, c.resistente || null, c.estado || 'NAF/Pendiente', c.observaciones || null);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateCultivo(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
|
||||||
if (key !== 'id' && val !== undefined) {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE cultivos SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteCultivo(id) {
|
|
||||||
db.prepare('DELETE FROM cultivos WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Estudios Complementarios
|
|
||||||
export function createEstudioComplementario(e) {
|
|
||||||
const stmt = db.prepare('INSERT INTO estudiosComplementarios (id, pacienteId, internacionId, fecha, tipo, resultado) VALUES (?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(e.id, e.pacienteId, e.internacionId || null, e.fecha || null, e.tipo || null, e.resultado || null);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateEstudioComplementario(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
|
||||||
if (key !== 'id' && val !== undefined) {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE estudiosComplementarios SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteEstudioComplementario(id) {
|
|
||||||
db.prepare('DELETE FROM estudiosComplementarios WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interconsultas
|
|
||||||
export function createInterconsulta(ic) {
|
|
||||||
const stmt = db.prepare('INSERT INTO interconsultas (id, pacienteId, internacionId, fecha, servicioInterconsultado, motivo, respuestaInterconsulta, respuestaFecha) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(ic.id, ic.pacienteId, ic.internacionId, ic.fecha || null, ic.servicioInterconsultado, ic.motivo || null, ic.respuestaInterconsulta || null, ic.respuestaFecha || null);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateInterconsulta(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
|
||||||
if (key !== 'id' && val !== undefined) {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE interconsultas SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteInterconsulta(id) {
|
|
||||||
db.prepare('DELETE FROM interconsultas WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ATB
|
|
||||||
export function createAtb(a) {
|
|
||||||
const stmt = db.prepare('INSERT INTO atb (id, pacienteId, internacionId, antibiotico, fechaInicio, fechaFinalizacion) VALUES (?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(a.id, a.pacienteId, a.internacionId, a.antibiotico || null, a.fechaInicio || null, a.fechaFinalizacion || null);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateAtb(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
|
||||||
if (key !== 'id' && val !== undefined) {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE atb SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteAtb(id) {
|
|
||||||
db.prepare('DELETE FROM atb WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Indicaciones
|
|
||||||
export function createIndicacion(ind) {
|
|
||||||
const stmt = db.prepare('INSERT INTO indicaciones (id, internacionId, tipo, droga, dosis, frecuenciaHoras, via, indicacionNoFco, tipoPlan, tipoPlan2, cantidadMl, cantidadMl2, tiempoHoras, tipoInsulina, unidadesDesayuno, unidadesAlmuerzo, unidadesNoche, estado, medicoCrea, fechaCrea) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(ind.id, ind.internacionId, ind.tipo, ind.droga || null, ind.dosis || null, ind.frecuenciaHoras || null, ind.via || null, ind.indicacionNoFco || null, ind.tipoPlan || null, ind.tipoPlan2 || null, ind.cantidadMl || null, ind.cantidadMl2 || null, ind.tiempoHoras || null, ind.tipoInsulina || null, ind.unidadesDesayuno || null, ind.unidadesAlmuerzo || null, ind.unidadesNoche || null, ind.estado || 'Activa', ind.medicoCrea || null, ind.fechaCrea || null);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateIndicacion(id, datos) {
|
|
||||||
const fields = [];
|
|
||||||
const values = [];
|
|
||||||
for (const [key, val] of Object.entries(datos)) {
|
|
||||||
if (key !== 'id' && val !== undefined) {
|
|
||||||
fields.push(`${key} = ?`);
|
|
||||||
values.push(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fields.length > 0) {
|
|
||||||
values.push(id);
|
|
||||||
db.prepare(`UPDATE indicaciones SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteIndicacion(id) {
|
|
||||||
db.prepare('DELETE FROM indicaciones WHERE id = ?').run(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Movimientos Indicaciones
|
|
||||||
export function createMovimientoIndicacion(m) {
|
|
||||||
const stmt = db.prepare('INSERT INTO movimientos_indicaciones (id, indicacionId, internacionId, tipo, fecha, profesional, indicacionPrevia, indicacionNueva) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
stmt.run(
|
|
||||||
m.id,
|
|
||||||
m.indicacionId || '',
|
|
||||||
m.internacionId || '',
|
|
||||||
m.tipo || '',
|
|
||||||
m.fecha || new Date().toISOString(),
|
|
||||||
m.profesional || '',
|
|
||||||
m.indicacionPrevia || null,
|
|
||||||
m.indicacionNueva || null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
-703
@@ -1,703 +0,0 @@
|
|||||||
import express from 'express';
|
|
||||||
import cors from 'cors';
|
|
||||||
import {
|
|
||||||
getDb, getValue, setValue, getUsuarioByDni, getUsuarioById, getAllUsuarios, createUsuario, updateUsuario, deleteUsuario, verifyPassword, hashPassword,
|
|
||||||
getAllPacientes, createPaciente, updatePaciente, deletePaciente,
|
|
||||||
getAllGrupos, createGrupo, updateGrupo, deleteGrupo,
|
|
||||||
getAllCamas, createCama, updateCama, deleteCama,
|
|
||||||
getAllInternaciones, createInternacion, updateInternacion, deleteInternacion,
|
|
||||||
getAllEvoluciones, createEvolucion, updateEvolucion, deleteEvolucion,
|
|
||||||
getAllLaboratorios, createLaboratorio, updateLaboratorio, deleteLaboratorio,
|
|
||||||
getAllGlucemias, createGlucemia, updateGlucemia, deleteGlucemia,
|
|
||||||
getAllAcidosBase, createAcidoBase, updateAcidoBase, deleteAcidoBase,
|
|
||||||
getAllCultivos, createCultivo, updateCultivo, deleteCultivo,
|
|
||||||
getAllEstudiosComplementarios, createEstudioComplementario, updateEstudioComplementario, deleteEstudioComplementario,
|
|
||||||
getAllInterconsultas, createInterconsulta, updateInterconsulta, deleteInterconsulta,
|
|
||||||
getAllAtb, createAtb, updateAtb, deleteAtb,
|
|
||||||
getAllIndicaciones, createIndicacion, updateIndicacion, deleteIndicacion,
|
|
||||||
getAllMovimientosIndicaciones, createMovimientoIndicacion
|
|
||||||
} from './db.js';
|
|
||||||
|
|
||||||
const app = express();
|
|
||||||
app.use(cors());
|
|
||||||
app.use(express.json({ limit: '5mb' }));
|
|
||||||
|
|
||||||
const PORT = process.env.PORT || 4001;
|
|
||||||
const STORAGE_KEY = 'hospital-data-v1';
|
|
||||||
|
|
||||||
app.get('/api/state', (req, res) => {
|
|
||||||
try {
|
|
||||||
const gruposList = getAllGrupos();
|
|
||||||
const state = {
|
|
||||||
pacientes: getAllPacientes(),
|
|
||||||
grupos: gruposList,
|
|
||||||
areas: gruposList,
|
|
||||||
camas: getAllCamas(),
|
|
||||||
internaciones: getAllInternaciones(),
|
|
||||||
evoluciones: getAllEvoluciones(),
|
|
||||||
laboratorios: getAllLaboratorios(),
|
|
||||||
glucemias: getAllGlucemias(),
|
|
||||||
acidosBase: getAllAcidosBase(),
|
|
||||||
cultivos: getAllCultivos(),
|
|
||||||
estudiosComplementarios: getAllEstudiosComplementarios(),
|
|
||||||
interconsultas: getAllInterconsultas(),
|
|
||||||
atb: getAllAtb(),
|
|
||||||
indicaciones: getAllIndicaciones(),
|
|
||||||
movimientosIndicaciones: getAllMovimientosIndicaciones(),
|
|
||||||
vistaActual: 'dashboard',
|
|
||||||
currentInternacionId: null
|
|
||||||
};
|
|
||||||
res.json(state);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ error: 'failed to read state' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/state', (req, res) => {
|
|
||||||
try {
|
|
||||||
const state = req.body;
|
|
||||||
const db = getDb();
|
|
||||||
|
|
||||||
// Use transaction for atomicity and better performance
|
|
||||||
const result = db.transaction(() => {
|
|
||||||
db.prepare('DELETE FROM evoluciones').run();
|
|
||||||
db.prepare('DELETE FROM acidosbase').run();
|
|
||||||
db.prepare('DELETE FROM cultivos').run();
|
|
||||||
db.prepare('DELETE FROM laboratorios').run();
|
|
||||||
db.prepare('DELETE FROM glucemias').run();
|
|
||||||
db.prepare('DELETE FROM internaciones').run();
|
|
||||||
db.prepare('DELETE FROM camas').run();
|
|
||||||
db.prepare('DELETE FROM grupos').run();
|
|
||||||
db.prepare('DELETE FROM areas').run();
|
|
||||||
db.prepare('DELETE FROM pacientes').run();
|
|
||||||
db.prepare('DELETE FROM estudiosComplementarios').run();
|
|
||||||
db.prepare('DELETE FROM interconsultas').run();
|
|
||||||
db.prepare('DELETE FROM atb').run();
|
|
||||||
db.prepare('DELETE FROM indicaciones').run();
|
|
||||||
db.prepare('DELETE FROM movimientos_indicaciones').run();
|
|
||||||
|
|
||||||
if (state.pacientes?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO pacientes (id, apellido, nombre, dni, fechaNacimiento, sexo, telefono, email, direccion, obraSocial, nacionalidad, medicacionHabitual, antecedentes, alergias, grupoSanguineo, historiaClinica) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const p of state.pacientes) {
|
|
||||||
stmt.run(p.id, p.apellido, p.nombre, p.dni, p.fechaNacimiento || null, p.sexo || null, p.telefono || null, p.email || null, p.direccion || null, p.obraSocial || null, p.nacionalidad || null, p.medicacionHabitual || null, p.antecedentes || null, p.alergias || null, p.grupoSanguineo || null, p.historiaClinica || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const gruposData = state.grupos?.length ? state.grupos : state.areas;
|
|
||||||
if (gruposData?.length) {
|
|
||||||
const stmtG = db.prepare('INSERT OR IGNORE INTO grupos (id, nombre) VALUES (?, ?)');
|
|
||||||
const stmtA = db.prepare('INSERT OR IGNORE INTO areas (id, nombre) VALUES (?, ?)');
|
|
||||||
for (const g of gruposData) {
|
|
||||||
stmtG.run(g.id, g.nombre);
|
|
||||||
stmtA.run(g.id, g.nombre);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.camas?.length) {
|
|
||||||
const stmt = db.prepare('INSERT OR IGNORE INTO camas (id, numero, grupoId, areaId, tipo, estado, sector) VALUES (?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const c of state.camas) {
|
|
||||||
const gId = c.grupoId || c.areaId || null;
|
|
||||||
const sector = computeSector(c.numero);
|
|
||||||
stmt.run(c.id, c.numero, gId, gId, c.tipo, c.estado, sector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.internaciones?.length) {
|
|
||||||
const stmt = db.prepare('INSERT OR IGNORE INTO internaciones (id, pacienteId, camaId, grupoId, areaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const i of state.internaciones) {
|
|
||||||
const gId = i.grupoId || i.areaId || null;
|
|
||||||
stmt.run(i.id, i.pacienteId, i.camaId, gId, gId, i.fechaIngresoHospital || null, i.fechaIngresoClinica || null, i.fechaEgreso || null, i.diagnosticoIngreso || null, i.motivoConsulta || null, i.enfermedadActual || null, i.antecedentesEnfermedadActual || null, i.diagnosticoEgreso || null, i.medicoIngresante || null, i.motivoEgreso || null, i.activa ? 1 : 0, i.apache || null, i.derivacion || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.evoluciones?.length) {
|
|
||||||
const stmt = db.prepare('INSERT OR IGNORE INTO evoluciones (id, internacionId, fecha, hora, medico, signosVitales, examenFisico, novedades, comentarios, pendientes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const e of state.evoluciones) {
|
|
||||||
stmt.run(e.id, e.internacionId, e.fecha, e.hora || '', e.medico || '', JSON.stringify(e.signosVitales || {}), JSON.stringify(e.examenFisico || {}), e.novedades || '', e.comentarios || '', e.pendientes || '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.laboratorios?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO laboratorios (id, pacienteId, fecha, hora, tipo, resultados, observaciones) VALUES (?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const l of state.laboratorios) {
|
|
||||||
stmt.run(l.id, l.pacienteId, l.fecha, l.hora || null, l.tipo, JSON.stringify(l.resultados), l.observaciones || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.glucemias?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO glucemias (id, pacienteId, internacionId, fecha, hora, valor, correccion) VALUES (?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const g of state.glucemias) {
|
|
||||||
stmt.run(g.id, g.pacienteId, g.internacionId || null, g.fecha, g.hora || null, g.valor, g.correccion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.acidosBase?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO acidosbase (id, pacienteId, fecha, hora, ph, pco2, po2, hco3, be, sato2, lactato, interpretacion, fio2) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const a of state.acidosBase) {
|
|
||||||
stmt.run(a.id, a.pacienteId, a.fecha, a.hora, a.ph, a.pco2, a.po2, a.hco3, a.be, a.sato2, a.lactato || null, a.interpretacion || null, a.fio2 || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.cultivos?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO cultivos (id, pacienteId, internacionId, fechaToma, protocolo, tipoMuestra, observaciones, estado, fechaResultado, germen, sensible, resistente) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const c of state.cultivos) {
|
|
||||||
stmt.run(c.id, c.pacienteId, c.internacionId, c.fechaToma, c.protocolo, c.tipoMuestra, c.observaciones, c.estado, c.fechaResultado, c.germen, c.sensible, c.resistente);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.estudiosComplementarios?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO estudiosComplementarios (id, pacienteId, internacionId, fecha, tipo, resultado) VALUES (?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const e of state.estudiosComplementarios) {
|
|
||||||
stmt.run(e.id, e.pacienteId, e.internacionId || null, e.fecha, e.tipo, e.resultado);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.interconsultas?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO interconsultas (id, pacienteId, internacionId, fecha, servicioInterconsultado, motivo, respuestaInterconsulta, respuestaFecha) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const ic of state.interconsultas) {
|
|
||||||
stmt.run(ic.id, ic.pacienteId, ic.internacionId, ic.fecha, ic.servicioInterconsultado, ic.motivo || null, ic.respuestaInterconsulta || null, ic.respuestaFecha || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.atb?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO atb (id, pacienteId, internacionId, antibiotico, fechaInicio, fechaFinalizacion) VALUES (?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const atb of state.atb) {
|
|
||||||
stmt.run(atb.id, atb.pacienteId, atb.internacionId, atb.antibiotico, atb.fechaInicio, atb.fechaFinalizacion || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.indicaciones?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO indicaciones (id, internacionId, tipo, droga, dosis, frecuenciaHoras, via, tipoPlan, tipoPlan2, cantidadMl, cantidadMl2, tiempoHoras, estado, medicoCrea, fechaCrea, tipoInsulina, unidadesDesayuno, unidadesAlmuerzo, unidadesNoche, indicacionNoFco) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const ind of state.indicaciones) {
|
|
||||||
stmt.run(ind.id, ind.internacionId, ind.tipo, ind.droga || null, ind.dosis || null, ind.frecuenciaHoras || null, ind.via || null, ind.tipoPlan || null, ind.tipoPlan2 || null, ind.cantidadMl || null, ind.cantidadMl2 || null, ind.tiempoHoras || null, ind.estado, ind.medicoCrea, ind.fechaCrea, ind.tipoInsulina || null, ind.unidadesDesayuno || null, ind.unidadesAlmuerzo || null, ind.unidadesNoche || null, ind.indicacionNoFco || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.movimientosIndicaciones?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO movimientos_indicaciones (id, indicacionId, internacionId, tipo, fecha, profesional, indicacionPrevia, indicacionNueva) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const mov of state.movimientosIndicaciones) {
|
|
||||||
stmt.run(mov.id, mov.indicacionId, mov.internacionId, mov.tipo, mov.fecha, mov.profesional, mov.indicacionPrevia || null, mov.indicacionNueva || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ error: 'failed to save state' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Partial state update (only changed parts)
|
|
||||||
app.put('/api/state/partial', (req, res) => {
|
|
||||||
try {
|
|
||||||
const updates = req.body;
|
|
||||||
if (!updates || typeof updates !== 'object') {
|
|
||||||
return res.status(400).json({ error: 'Invalid update data' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const db = getDb();
|
|
||||||
|
|
||||||
// Use transaction for atomicity
|
|
||||||
const result = db.transaction(() => {
|
|
||||||
// Only update tables that were actually changed
|
|
||||||
if (updates.pacientes) {
|
|
||||||
db.prepare('DELETE FROM pacientes').run();
|
|
||||||
if (updates.pacientes.length > 0) {
|
|
||||||
const stmt = db.prepare('INSERT INTO pacientes (id, apellido, nombre, dni, fechaNacimiento, sexo, telefono, email, direccion, obraSocial, nacionalidad, medicacionHabitual, antecedentes, alergias, grupoSanguineo, historiaClinica) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const p of updates.pacientes) {
|
|
||||||
stmt.run(p.id, p.apellido, p.nombre, p.dni, p.fechaNacimiento || null, p.sexo || null, p.telefono || null, p.email || null, p.direccion || null, p.obraSocial || null, p.nacionalidad || null, p.medicacionHabitual || null, p.antecedentes || null, p.alergias || null, p.grupoSanguineo || null, p.historiaClinica || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updates.areas) {
|
|
||||||
db.prepare('DELETE FROM areas').run();
|
|
||||||
if (updates.areas.length > 0) {
|
|
||||||
const stmt = db.prepare('INSERT INTO areas (id, nombre) VALUES (?, ?)');
|
|
||||||
for (const a of updates.areas) {
|
|
||||||
stmt.run(a.id, a.nombre);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updates.camas) {
|
|
||||||
db.prepare('DELETE FROM camas').run();
|
|
||||||
if (updates.camas.length > 0) {
|
|
||||||
const stmt = db.prepare('INSERT INTO camas (id, numero, grupoId, areaId, tipo, estado, sector) VALUES (?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const c of updates.camas) {
|
|
||||||
const sector = computeSector(c.numero);
|
|
||||||
stmt.run(c.id, c.numero, c.grupoId || c.areaId || null, c.grupoId || c.areaId || null, c.tipo, c.estado, sector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updates.internaciones) {
|
|
||||||
db.prepare('DELETE FROM internaciones').run();
|
|
||||||
if (updates.internaciones.length > 0) {
|
|
||||||
const stmt = db.prepare('INSERT OR IGNORE INTO internaciones (id, pacienteId, camaId, areaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const i of updates.internaciones) {
|
|
||||||
stmt.run(i.id, i.pacienteId, i.camaId, i.areaId || null, i.fechaIngresoHospital || null, i.fechaIngresoClinica || null, i.fechaEgreso || null, i.diagnosticoIngreso || null, i.motivoConsulta || null, i.enfermedadActual || null, i.antecedentesEnfermedadActual || null, i.diagnosticoEgreso || null, i.medicoIngresante || null, i.motivoEgreso || null, i.activa ? 1 : 0, i.apache || null, i.derivacion || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updates.evoluciones) {
|
|
||||||
db.prepare('DELETE FROM evoluciones').run();
|
|
||||||
if (updates.evoluciones.length > 0) {
|
|
||||||
const stmt = db.prepare('INSERT OR IGNORE INTO evoluciones (id, internacionId, fecha, hora, medico, signosVitales, examenFisico, novedades, comentarios, pendientes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const e of updates.evoluciones) {
|
|
||||||
stmt.run(e.id, e.internacionId, e.fecha, e.hora || '', e.medico || '', JSON.stringify(e.signosVitales || {}), JSON.stringify(e.examenFisico || {}), e.novedades || '', e.comentarios || '', e.pendientes || '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ error: err.message });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default app;
|
|
||||||
|
|
||||||
// === AUTENTICACIÓN ===
|
|
||||||
|
|
||||||
function generateUUID() {
|
|
||||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
||||||
const r = (Math.random() * 16) | 0;
|
|
||||||
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
||||||
return v.toString(16);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
app.post('/api/auth/login', (req, res) => {
|
|
||||||
try {
|
|
||||||
const { dni, password } = req.body;
|
|
||||||
if (!dni || !password) {
|
|
||||||
return res.status(400).json({ error: 'DNI y contraseña requeridos' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const usuario = getUsuarioByDni(dni);
|
|
||||||
if (!usuario) {
|
|
||||||
return res.status(401).json({ error: 'Usuario no encontrado' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const validPassword = verifyPassword(dni, password);
|
|
||||||
if (!validPassword) {
|
|
||||||
return res.status(401).json({ error: 'Contraseña incorrecta' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const { passwordHash, ...userWithoutPassword } = usuario;
|
|
||||||
res.json(userWithoutPassword);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ error: 'Error en autenticación' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/auth/change-password', (req, res) => {
|
|
||||||
try {
|
|
||||||
const { dni, oldPassword, newPassword } = req.body;
|
|
||||||
if (!dni || !oldPassword || !newPassword) {
|
|
||||||
return res.status(400).json({ error: 'Todos los campos son requeridos' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const validPassword = verifyPassword(dni, oldPassword);
|
|
||||||
if (!validPassword) {
|
|
||||||
return res.status(401).json({ error: 'Contraseña actual incorrecta' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const newHash = hashPassword(newPassword);
|
|
||||||
updateUsuarioByDni(dni, { passwordHash: newHash });
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ error: 'Error al cambiar contraseña' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/auth/update-email', (req, res) => {
|
|
||||||
try {
|
|
||||||
const { dni, newEmail } = req.body;
|
|
||||||
if (!dni || !newEmail) {
|
|
||||||
return res.status(400).json({ error: 'DNI y email son requeridos' });
|
|
||||||
}
|
|
||||||
|
|
||||||
updateUsuarioByDni(dni, { email: newEmail });
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ error: 'Error al actualizar email' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// === GESTIÓN DE USUARIOS (ADMIN) ===
|
|
||||||
|
|
||||||
app.get('/api/grupos', (req, res) => {
|
|
||||||
try {
|
|
||||||
const areas = getAllGrupos();
|
|
||||||
res.json(areas);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ error: 'Error al obtener áreas' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/api/usuarios', (req, res) => {
|
|
||||||
try {
|
|
||||||
const usuarios = getAllUsuarios();
|
|
||||||
const usuariosSinPassword = usuarios.map(({ passwordHash, ...u }) => u);
|
|
||||||
res.json(usuariosSinPassword);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ error: 'Error al obtener usuarios' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/api/usuarios', (req, res) => {
|
|
||||||
try {
|
|
||||||
const { apellido, nombre, dni, fechaNacimiento, email, rol, matriculaProfesional, password, areaId } = req.body;
|
|
||||||
|
|
||||||
if (!apellido?.trim() || !nombre?.trim() || !dni?.trim() || !rol) {
|
|
||||||
return res.status(400).json({ error: 'Apellido, nombre, DNI y rol son obligatorios' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const existente = getUsuarioByDni(dni.trim());
|
|
||||||
if (existente) {
|
|
||||||
return res.status(400).json({ error: 'Ya existe un usuario con ese DNI' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const passwordFinal = (password && password.trim()) ? password.trim() : (dni.trim() || '123456');
|
|
||||||
const passwordHash = hashPassword(passwordFinal);
|
|
||||||
const usuario = {
|
|
||||||
id: generateUUID(),
|
|
||||||
apellido: apellido.trim(),
|
|
||||||
nombre: nombre.trim(),
|
|
||||||
dni: dni.trim(),
|
|
||||||
fechaNacimiento: fechaNacimiento?.trim() || null,
|
|
||||||
email: email?.trim() || null,
|
|
||||||
rol,
|
|
||||||
matriculaProfesional: matriculaProfesional?.trim() || null,
|
|
||||||
passwordHash,
|
|
||||||
areaId: areaId || null,
|
|
||||||
fechaCreacion: new Date().toISOString().split('T')[0]
|
|
||||||
};
|
|
||||||
|
|
||||||
createUsuario(usuario);
|
|
||||||
res.json({ ...usuario, passwordHash: undefined });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error al crear usuario:', err);
|
|
||||||
res.status(500).json({ error: 'Error al crear usuario' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/usuarios/:id', (req, res) => {
|
|
||||||
try {
|
|
||||||
const { id } = req.params;
|
|
||||||
const { apellido, nombre, dni, fechaNacimiento, email, rol, matriculaProfesional, areaId, password } = req.body;
|
|
||||||
|
|
||||||
const usuario = getUsuarioById(id);
|
|
||||||
if (!usuario) {
|
|
||||||
return res.status(404).json({ error: 'Usuario no encontrado' });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dni && dni.trim() !== usuario.dni) {
|
|
||||||
const existente = getUsuarioByDni(dni.trim());
|
|
||||||
if (existente && existente.id !== id) {
|
|
||||||
return res.status(400).json({ error: 'Ya existe otro usuario con ese DNI' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const datos = {};
|
|
||||||
if (apellido !== undefined) datos.apellido = apellido.trim();
|
|
||||||
if (nombre !== undefined) datos.nombre = nombre.trim();
|
|
||||||
if (dni !== undefined) datos.dni = dni.trim();
|
|
||||||
if (fechaNacimiento !== undefined) datos.fechaNacimiento = fechaNacimiento?.trim() || null;
|
|
||||||
if (email !== undefined) datos.email = email?.trim() || null;
|
|
||||||
if (rol !== undefined) datos.rol = rol;
|
|
||||||
if (matriculaProfesional !== undefined) datos.matriculaProfesional = matriculaProfesional?.trim() || null;
|
|
||||||
if (areaId !== undefined) datos.areaId = areaId || null;
|
|
||||||
if (password && password.trim()) {
|
|
||||||
datos.passwordHash = hashPassword(password.trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
updateUsuario(id, datos);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error al actualizar usuario:', err);
|
|
||||||
res.status(500).json({ error: 'Error al actualizar usuario' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.delete('/api/usuarios/:id', (req, res) => {
|
|
||||||
try {
|
|
||||||
const { id } = req.params;
|
|
||||||
deleteUsuario(id);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ error: 'Error al eliminar usuario' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/camas/:id', (req, res) => {
|
|
||||||
try {
|
|
||||||
const { id } = req.params;
|
|
||||||
updateCama(id, req.body);
|
|
||||||
res.json({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error updating cama:', err.message);
|
|
||||||
res.status(500).json({ error: err.message });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== PACIENTES ==========
|
|
||||||
app.get('/api/pacientes', (req, res) => {
|
|
||||||
try { res.json(getAllPacientes()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/pacientes', (req, res) => {
|
|
||||||
try {
|
|
||||||
const paciente = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createPaciente(paciente);
|
|
||||||
res.json(paciente);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/pacientes/:id', (req, res) => {
|
|
||||||
try { updatePaciente(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/pacientes/:id', (req, res) => {
|
|
||||||
try { deletePaciente(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== AREAS ==========
|
|
||||||
app.post('/api/grupos', (req, res) => {
|
|
||||||
try {
|
|
||||||
const area = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createGrupo(area);
|
|
||||||
res.json(area);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/grupos/:id', (req, res) => {
|
|
||||||
try { updateGrupo(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/grupos/:id', (req, res) => {
|
|
||||||
try { deleteGrupo(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== CAMAS ==========
|
|
||||||
app.get('/api/camas', (req, res) => {
|
|
||||||
try { res.json(getAllCamas()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/camas', (req, res) => {
|
|
||||||
try {
|
|
||||||
const cama = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createCama(cama);
|
|
||||||
res.json(cama);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/camas/:id', (req, res) => {
|
|
||||||
try { deleteCama(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== INTERNACIONES ==========
|
|
||||||
app.get('/api/internaciones', (req, res) => {
|
|
||||||
try { res.json(getAllInternaciones()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/internaciones', (req, res) => {
|
|
||||||
try {
|
|
||||||
const internacion = { ...req.body, id: req.body.id || generateUUID(), activa: true };
|
|
||||||
createInternacion(internacion);
|
|
||||||
res.json(internacion);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/internaciones/:id', (req, res) => {
|
|
||||||
try { updateInternacion(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/internaciones/:id', (req, res) => {
|
|
||||||
try { deleteInternacion(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== EVOLUCIONES ==========
|
|
||||||
app.get('/api/evoluciones', (req, res) => {
|
|
||||||
try { res.json(getAllEvoluciones()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/evoluciones', (req, res) => {
|
|
||||||
try {
|
|
||||||
const evolucion = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createEvolucion(evolucion);
|
|
||||||
res.json(evolucion);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/evoluciones/:id', (req, res) => {
|
|
||||||
try { updateEvolucion(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/evoluciones/:id', (req, res) => {
|
|
||||||
try { deleteEvolucion(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== LABORATORIOS ==========
|
|
||||||
app.get('/api/laboratorios', (req, res) => {
|
|
||||||
try { res.json(getAllLaboratorios()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/laboratorios', (req, res) => {
|
|
||||||
try {
|
|
||||||
const laboratorio = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createLaboratorio(laboratorio);
|
|
||||||
res.json(laboratorio);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/laboratorios/:id', (req, res) => {
|
|
||||||
try { updateLaboratorio(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/laboratorios/:id', (req, res) => {
|
|
||||||
try { deleteLaboratorio(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== GLUCEMIAS ==========
|
|
||||||
app.get('/api/glucemias', (req, res) => {
|
|
||||||
try { res.json(getAllGlucemias()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/glucemias', (req, res) => {
|
|
||||||
try {
|
|
||||||
const glucemia = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createGlucemia(glucemia);
|
|
||||||
res.json(glucemia);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/glucemias/:id', (req, res) => {
|
|
||||||
try { updateGlucemia(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/glucemias/:id', (req, res) => {
|
|
||||||
try { deleteGlucemia(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== ACIDOS BASE ==========
|
|
||||||
app.get('/api/acid-os-base', (req, res) => {
|
|
||||||
try { res.json(getAllAcidosBase()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/acid-os-base', (req, res) => {
|
|
||||||
try {
|
|
||||||
const acido = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createAcidoBase(acido);
|
|
||||||
res.json(acido);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/acid-os-base/:id', (req, res) => {
|
|
||||||
try { updateAcidoBase(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/acid-os-base/:id', (req, res) => {
|
|
||||||
try { deleteAcidoBase(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== CULTIVOS ==========
|
|
||||||
app.get('/api/cultivos', (req, res) => {
|
|
||||||
try { res.json(getAllCultivos()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/cultivos', (req, res) => {
|
|
||||||
try {
|
|
||||||
const cultivo = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createCultivo(cultivo);
|
|
||||||
res.json(cultivo);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/cultivos/:id', (req, res) => {
|
|
||||||
try { updateCultivo(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/cultivos/:id', (req, res) => {
|
|
||||||
try { deleteCultivo(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== ESTUDIOS COMPLEMENTARIOS ==========
|
|
||||||
app.get('/api/estudios-complementarios', (req, res) => {
|
|
||||||
try { res.json(getAllEstudiosComplementarios()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/estudios-complementarios', (req, res) => {
|
|
||||||
try {
|
|
||||||
const estudio = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createEstudioComplementario(estudio);
|
|
||||||
res.json(estudio);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/estudios-complementarios/:id', (req, res) => {
|
|
||||||
try { updateEstudioComplementario(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/estudios-complementarios/:id', (req, res) => {
|
|
||||||
try { deleteEstudioComplementario(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== INTERCONSULTAS ==========
|
|
||||||
app.get('/api/interconsultas', (req, res) => {
|
|
||||||
try { res.json(getAllInterconsultas()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/interconsultas', (req, res) => {
|
|
||||||
try {
|
|
||||||
const interconsulta = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createInterconsulta(interconsulta);
|
|
||||||
res.json(interconsulta);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/interconsultas/:id', (req, res) => {
|
|
||||||
try { updateInterconsulta(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/interconsultas/:id', (req, res) => {
|
|
||||||
try { deleteInterconsulta(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== ATB ==========
|
|
||||||
app.get('/api/atb', (req, res) => {
|
|
||||||
try { res.json(getAllAtb()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/atb', (req, res) => {
|
|
||||||
try {
|
|
||||||
const atb = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createAtb(atb);
|
|
||||||
res.json(atb);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/atb/:id', (req, res) => {
|
|
||||||
try { updateAtb(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/atb/:id', (req, res) => {
|
|
||||||
try { deleteAtb(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== INDICACIONES ==========
|
|
||||||
app.get('/api/indicaciones', (req, res) => {
|
|
||||||
try { res.json(getAllIndicaciones()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/indicaciones', (req, res) => {
|
|
||||||
try {
|
|
||||||
const indicacion = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createIndicacion(indicacion);
|
|
||||||
res.json(indicacion);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.put('/api/indicaciones/:id', (req, res) => {
|
|
||||||
try { updateIndicacion(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.delete('/api/indicaciones/:id', (req, res) => {
|
|
||||||
try { deleteIndicacion(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ========== MOVIMIENTOS INDICACIONES ==========
|
|
||||||
app.get('/api/movimientos-indicaciones', (req, res) => {
|
|
||||||
try { res.json(getAllMovimientosIndicaciones()); } catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
app.post('/api/movimientos-indicaciones', (req, res) => {
|
|
||||||
try {
|
|
||||||
const movimiento = { ...req.body, id: req.body.id || generateUUID() };
|
|
||||||
createMovimientoIndicacion(movimiento);
|
|
||||||
res.json(movimiento);
|
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// Helper para actualizar por DNI
|
|
||||||
function updateUsuarioByDni(dni, datos) {
|
|
||||||
const usuario = getUsuarioByDni(dni);
|
|
||||||
if (usuario) {
|
|
||||||
updateUsuario(usuario.id, datos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,288 +0,0 @@
|
|||||||
import Database from 'better-sqlite3';
|
|
||||||
import { fileURLToPath } from 'url';
|
|
||||||
import { dirname, join } from 'path';
|
|
||||||
import * as mariadb from 'mariadb';
|
|
||||||
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
||||||
const SQLITE_PATH = join(__dirname, 'data', 'hospital.db');
|
|
||||||
|
|
||||||
// MariaDB connection config
|
|
||||||
const mariaPool = mariadb.createPool({
|
|
||||||
host: process.env.DB_HOST || '10.9.8.135',
|
|
||||||
port: parseInt(process.env.DB_PORT || '3306'),
|
|
||||||
user: process.env.DB_USER || 'snlavaise',
|
|
||||||
password: process.env.DB_PASSWORD || '1123581321Rtaylor%_+',
|
|
||||||
database: process.env.DB_NAME || 'santojanni',
|
|
||||||
connectionLimit: 5,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Table definitions for MariaDB
|
|
||||||
const CREATE_TABLES = [
|
|
||||||
`CREATE TABLE IF NOT EXISTS usuarios (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
apellido VARCHAR(255) NOT NULL,
|
|
||||||
nombre VARCHAR(255) NOT NULL,
|
|
||||||
dni VARCHAR(20) NOT NULL UNIQUE,
|
|
||||||
fechaNacimiento VARCHAR(10),
|
|
||||||
email VARCHAR(255),
|
|
||||||
rol VARCHAR(50),
|
|
||||||
matriculaProfesional VARCHAR(100),
|
|
||||||
passwordHash VARCHAR(255),
|
|
||||||
areaId VARCHAR(36),
|
|
||||||
fechaCreacion VARCHAR(10)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS pacientes (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
apellido VARCHAR(255) NOT NULL,
|
|
||||||
nombre VARCHAR(255) NOT NULL,
|
|
||||||
dni VARCHAR(20) NOT NULL UNIQUE,
|
|
||||||
fechaNacimiento VARCHAR(10),
|
|
||||||
sexo VARCHAR(10),
|
|
||||||
telefono VARCHAR(50),
|
|
||||||
email VARCHAR(255),
|
|
||||||
direccion TEXT,
|
|
||||||
obraSocial VARCHAR(100),
|
|
||||||
nacionalidad VARCHAR(100),
|
|
||||||
medicacionHabitual TEXT,
|
|
||||||
antecedentes TEXT,
|
|
||||||
alergias TEXT,
|
|
||||||
grupoSanguineo VARCHAR(10),
|
|
||||||
historiaClinica TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS areas (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
nombre VARCHAR(255) NOT NULL UNIQUE
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS camas (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
numero VARCHAR(20) NOT NULL,
|
|
||||||
areaId VARCHAR(36),
|
|
||||||
tipo VARCHAR(50) DEFAULT 'Estándar',
|
|
||||||
estado VARCHAR(20) DEFAULT 'Disponible',
|
|
||||||
pacienteId VARCHAR(36),
|
|
||||||
internacionId VARCHAR(36)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS internaciones (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
camaId VARCHAR(36),
|
|
||||||
areaId VARCHAR(36),
|
|
||||||
fechaIngresoHospital VARCHAR(10),
|
|
||||||
fechaIngresoClinica VARCHAR(10),
|
|
||||||
fechaEgreso VARCHAR(10),
|
|
||||||
diagnosticoIngreso TEXT,
|
|
||||||
motivoConsulta TEXT,
|
|
||||||
enfermedadActual TEXT,
|
|
||||||
antecedentesEnfermedadActual TEXT,
|
|
||||||
diagnosticoEgreso TEXT,
|
|
||||||
medicoIngresante VARCHAR(255),
|
|
||||||
motivoEgreso VARCHAR(50),
|
|
||||||
activa TINYINT DEFAULT 1,
|
|
||||||
apache TEXT,
|
|
||||||
derivacion TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS evoluciones (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
internacionId VARCHAR(36) NOT NULL,
|
|
||||||
fecha VARCHAR(10) NOT NULL,
|
|
||||||
hora VARCHAR(5),
|
|
||||||
medico VARCHAR(255),
|
|
||||||
signosVitales TEXT,
|
|
||||||
examenFisico TEXT,
|
|
||||||
novedades TEXT,
|
|
||||||
comentarios TEXT,
|
|
||||||
pendientes TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS laboratorios (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36),
|
|
||||||
fecha VARCHAR(10) NOT NULL,
|
|
||||||
hora VARCHAR(5),
|
|
||||||
tipo VARCHAR(50),
|
|
||||||
resultados TEXT,
|
|
||||||
observaciones TEXT,
|
|
||||||
medicoSolicitante VARCHAR(255)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS acidosbase (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36),
|
|
||||||
fecha VARCHAR(10) NOT NULL,
|
|
||||||
hora VARCHAR(5),
|
|
||||||
ph DECIMAL(4,2),
|
|
||||||
pco2 DECIMAL(6,2),
|
|
||||||
po2 DECIMAL(6,2),
|
|
||||||
hco3 DECIMAL(6,2),
|
|
||||||
be DECIMAL(6,2),
|
|
||||||
sato2 DECIMAL(6,2),
|
|
||||||
lactato DECIMAL(6,2),
|
|
||||||
interpretacion TEXT,
|
|
||||||
fio2 DECIMAL(6,2)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS cultivos (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36),
|
|
||||||
fechaToma VARCHAR(10),
|
|
||||||
protocolo VARCHAR(50),
|
|
||||||
fechaResultado VARCHAR(10),
|
|
||||||
tipoMuestra VARCHAR(100),
|
|
||||||
germen TEXT,
|
|
||||||
sensible TEXT,
|
|
||||||
resistente TEXT,
|
|
||||||
estado VARCHAR(50) DEFAULT 'NAF/Pendiente',
|
|
||||||
observaciones TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS estudiosComplementarios (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36),
|
|
||||||
fecha VARCHAR(10),
|
|
||||||
tipo VARCHAR(100),
|
|
||||||
resultado TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS interconsultas (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36) NOT NULL,
|
|
||||||
fecha VARCHAR(10),
|
|
||||||
servicioInterconsultado VARCHAR(255),
|
|
||||||
motivo TEXT,
|
|
||||||
respuestaInterconsulta TEXT,
|
|
||||||
respuestaFecha VARCHAR(10)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS atb (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
pacienteId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36) NOT NULL,
|
|
||||||
antibiotico VARCHAR(255),
|
|
||||||
fechaInicio VARCHAR(10),
|
|
||||||
fechaFinalizacion VARCHAR(10)
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS indicaciones (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
internacionId VARCHAR(36) NOT NULL,
|
|
||||||
tipo VARCHAR(50) NOT NULL,
|
|
||||||
droga VARCHAR(255),
|
|
||||||
dosis VARCHAR(100),
|
|
||||||
frecuenciaHoras INT,
|
|
||||||
via VARCHAR(50),
|
|
||||||
descripcion TEXT,
|
|
||||||
tipoPlan VARCHAR(50),
|
|
||||||
tipoPlan2 VARCHAR(50),
|
|
||||||
cantidadMl INT,
|
|
||||||
cantidadMl2 INT,
|
|
||||||
tiempoHoras INT,
|
|
||||||
estado VARCHAR(20) DEFAULT 'Activa',
|
|
||||||
medicoCrea VARCHAR(255),
|
|
||||||
fechaCrea VARCHAR(10),
|
|
||||||
tipoInsulina VARCHAR(50),
|
|
||||||
unidadesDesayuno INT,
|
|
||||||
unidadesAlmuerzo INT,
|
|
||||||
unidadesNoche INT,
|
|
||||||
indicacionNoFco TEXT
|
|
||||||
)`,
|
|
||||||
`CREATE TABLE IF NOT EXISTS movimientos_indicaciones (
|
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
|
||||||
indicacionId VARCHAR(36) NOT NULL,
|
|
||||||
internacionId VARCHAR(36) NOT NULL,
|
|
||||||
tipo VARCHAR(50) NOT NULL,
|
|
||||||
fecha VARCHAR(10) NOT NULL,
|
|
||||||
profesional VARCHAR(255) NOT NULL,
|
|
||||||
indicacionPrevia TEXT,
|
|
||||||
indicacionNueva TEXT
|
|
||||||
)`,
|
|
||||||
'CREATE TABLE IF NOT EXISTS kv (\n `key` VARCHAR(255) PRIMARY KEY,\n value TEXT\n )'
|
|
||||||
];
|
|
||||||
|
|
||||||
async function migrate() {
|
|
||||||
console.log('Starting migration from SQLite to MariaDB...');
|
|
||||||
|
|
||||||
// Open SQLite database
|
|
||||||
const sqliteDb = new Database(SQLITE_PATH);
|
|
||||||
console.log('Connected to SQLite database');
|
|
||||||
|
|
||||||
const mariaConn = await mariaPool.getConnection();
|
|
||||||
console.log('Connected to MariaDB');
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Drop tables in MariaDB first (reverse order due to foreign keys)
|
|
||||||
const tablesToDrop = [
|
|
||||||
'kv', 'movimientos_indicaciones', 'indicaciones', 'atb', 'interconsultas',
|
|
||||||
'estudiosComplementarios', 'cultivos', 'acidosbase', 'laboratorios',
|
|
||||||
'evoluciones', 'internaciones', 'camas', 'areas', 'pacientes', 'usuarios'
|
|
||||||
];
|
|
||||||
console.log('Dropping existing tables...');
|
|
||||||
for (const table of tablesToDrop) {
|
|
||||||
try {
|
|
||||||
await mariaConn.query(`DROP TABLE IF EXISTS ${table}`);
|
|
||||||
} catch (e) {
|
|
||||||
// Ignore errors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create tables in MariaDB
|
|
||||||
console.log('Creating tables in MariaDB...');
|
|
||||||
for (const sql of CREATE_TABLES) {
|
|
||||||
await mariaConn.query(sql);
|
|
||||||
}
|
|
||||||
console.log('Tables created successfully');
|
|
||||||
|
|
||||||
// Migrate each table
|
|
||||||
const tables = [
|
|
||||||
'usuarios', 'pacientes', 'areas', 'camas', 'internaciones',
|
|
||||||
'evoluciones', 'laboratorios', 'acidosbase', 'cultivos',
|
|
||||||
'estudiosComplementarios', 'interconsultas', 'atb',
|
|
||||||
'indicaciones', 'movimientos_indicaciones', 'kv'
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const table of tables) {
|
|
||||||
console.log(`Migrating ${table}...`);
|
|
||||||
|
|
||||||
// Get all data from SQLite
|
|
||||||
const rows = sqliteDb.prepare(`SELECT * FROM ${table}`).all();
|
|
||||||
console.log(` Found ${rows.length} rows in ${table}`);
|
|
||||||
|
|
||||||
if (rows.length === 0) continue;
|
|
||||||
|
|
||||||
// Get column names from first row
|
|
||||||
const columns = Object.keys(rows[0]);
|
|
||||||
const placeholders = columns.map(() => '?').join(', ');
|
|
||||||
const columnNames = columns.map(c => `\`${c}\``).join(', ');
|
|
||||||
|
|
||||||
// Insert into MariaDB
|
|
||||||
for (const row of rows) {
|
|
||||||
const values = columns.map(col => {
|
|
||||||
const val = row[col];
|
|
||||||
// Handle JSON strings or special cases
|
|
||||||
if (typeof val === 'object' && val !== null) {
|
|
||||||
return JSON.stringify(val);
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await mariaConn.query(
|
|
||||||
`INSERT IGNORE INTO ${table} (${columnNames}) VALUES (${placeholders})`,
|
|
||||||
values
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(` Error inserting row in ${table}:`, err.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(` Migrated ${rows.length} rows to ${table}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Migration completed successfully!');
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Migration failed:', err);
|
|
||||||
} finally {
|
|
||||||
sqliteDb.close();
|
|
||||||
mariaConn.release();
|
|
||||||
mariaPool.end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
migrate();
|
|
||||||
@@ -10,7 +10,6 @@
|
|||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"express": "^4.21.2",
|
"express": "^4.21.2",
|
||||||
"http-proxy-middleware": "^3.0.5",
|
"http-proxy-middleware": "^3.0.5",
|
||||||
"mariadb": "^3.4.0",
|
|
||||||
"mongodb": "^6.8.0"
|
"mongodb": "^6.8.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,511 +0,0 @@
|
|||||||
import express from 'express';
|
|
||||||
import cors from 'cors';
|
|
||||||
import http from 'http';
|
|
||||||
import Database from 'better-sqlite3';
|
|
||||||
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
||||||
import { dirname, join } from 'path';
|
|
||||||
import { fileURLToPath } from 'url';
|
|
||||||
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
||||||
const DB_PATH = join(__dirname, 'data', 'hospital.db');
|
|
||||||
const DIST_PATH = join(__dirname, '..', 'dist');
|
|
||||||
|
|
||||||
if (!existsSync(join(__dirname, 'data'))) {
|
|
||||||
mkdirSync(join(__dirname, 'data'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const db = new Database(DB_PATH);
|
|
||||||
|
|
||||||
// Configure WAL mode and performance settings
|
|
||||||
db.pragma('journal_mode = WAL');
|
|
||||||
db.pragma('busy_timeout = 5000');
|
|
||||||
db.pragma('synchronous = NORMAL');
|
|
||||||
db.pragma('cache_size = 1000');
|
|
||||||
db.pragma('temp_store = MEMORY');
|
|
||||||
db.pragma('mmap_size = 268435456');
|
|
||||||
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE internaciones ADD COLUMN areaId TEXT;");
|
|
||||||
} catch (e) {
|
|
||||||
// Ignore errors - column might already exist or other issues
|
|
||||||
}
|
|
||||||
|
|
||||||
db.exec(`
|
|
||||||
CREATE TABLE IF NOT EXISTS usuarios (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
apellido TEXT NOT NULL,
|
|
||||||
nombre TEXT NOT NULL,
|
|
||||||
dni TEXT NOT NULL UNIQUE,
|
|
||||||
fechaNacimiento TEXT,
|
|
||||||
email TEXT,
|
|
||||||
rol TEXT,
|
|
||||||
matriculaProfesional TEXT,
|
|
||||||
passwordHash TEXT,
|
|
||||||
areaId TEXT,
|
|
||||||
fechaCreacion TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS pacientes (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
apellido TEXT NOT NULL,
|
|
||||||
nombre TEXT NOT NULL,
|
|
||||||
dni TEXT NOT NULL UNIQUE,
|
|
||||||
fechaNacimiento TEXT,
|
|
||||||
sexo TEXT,
|
|
||||||
telefono TEXT,
|
|
||||||
email TEXT,
|
|
||||||
direccion TEXT,
|
|
||||||
obraSocial TEXT,
|
|
||||||
nacionalidad TEXT,
|
|
||||||
medicacionHabitual TEXT,
|
|
||||||
antecedentes TEXT,
|
|
||||||
alergias TEXT,
|
|
||||||
grupoSanguineo TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS areas (
|
|
||||||
nombre TEXT NOT NULL UNIQUE
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS camas (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
numero TEXT NOT NULL,
|
|
||||||
areaId TEXT,
|
|
||||||
tipo TEXT DEFAULT 'Estándar',
|
|
||||||
estado TEXT DEFAULT 'Disponible',
|
|
||||||
pacienteId TEXT,
|
|
||||||
internacionId TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS internaciones (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
camaId TEXT,
|
|
||||||
areaId TEXT,
|
|
||||||
fechaIngresoHospital TEXT,
|
|
||||||
fechaIngresoClinica TEXT,
|
|
||||||
fechaEgreso TEXT,
|
|
||||||
diagnosticoIngreso TEXT,
|
|
||||||
motivoConsulta TEXT,
|
|
||||||
enfermedadActual TEXT,
|
|
||||||
antecedentesEnfermedadActual TEXT,
|
|
||||||
diagnosticoEgreso TEXT,
|
|
||||||
medicoIngresante TEXT,
|
|
||||||
motivoEgreso TEXT,
|
|
||||||
activa INTEGER DEFAULT 1,
|
|
||||||
apache TEXT,
|
|
||||||
derivacion TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS evoluciones (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
internacionId TEXT NOT NULL,
|
|
||||||
fecha TEXT NOT NULL,
|
|
||||||
hora TEXT,
|
|
||||||
medico TEXT,
|
|
||||||
signosVitales TEXT,
|
|
||||||
examenFisico TEXT,
|
|
||||||
novedades TEXT,
|
|
||||||
comentarios TEXT,
|
|
||||||
pendientes TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS laboratorios (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT,
|
|
||||||
fecha TEXT NOT NULL,
|
|
||||||
hora TEXT,
|
|
||||||
tipo TEXT,
|
|
||||||
resultados TEXT,
|
|
||||||
observaciones TEXT,
|
|
||||||
medicoSolicitante TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS acidosbase (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT,
|
|
||||||
fecha TEXT NOT NULL,
|
|
||||||
hora TEXT,
|
|
||||||
ph REAL,
|
|
||||||
pco2 REAL,
|
|
||||||
po2 REAL,
|
|
||||||
hco3 REAL,
|
|
||||||
be REAL,
|
|
||||||
sato2 REAL,
|
|
||||||
lactato REAL,
|
|
||||||
interpretacion TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS cultivos (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT,
|
|
||||||
fechaToma TEXT,
|
|
||||||
protocolo TEXT,
|
|
||||||
fechaResultado TEXT,
|
|
||||||
tipoMuestra TEXT,
|
|
||||||
germen TEXT,
|
|
||||||
sensible TEXT,
|
|
||||||
resistente TEXT,
|
|
||||||
estado TEXT DEFAULT 'NAF/Pendiente',
|
|
||||||
observaciones TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS estudiosComplementarios (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT,
|
|
||||||
fecha TEXT,
|
|
||||||
tipo TEXT,
|
|
||||||
resultado TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS kv (
|
|
||||||
key TEXT PRIMARY KEY,
|
|
||||||
value TEXT
|
|
||||||
);
|
|
||||||
`);
|
|
||||||
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE pacientes ADD COLUMN historiaClinica TEXT");
|
|
||||||
} catch (e) {
|
|
||||||
// La columna ya existe
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE acidosbase ADD COLUMN fio2 REAL");
|
|
||||||
} catch (e) {
|
|
||||||
// La columna ya existe
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE laboratorios ADD COLUMN internacionId TEXT");
|
|
||||||
} catch (e) {
|
|
||||||
// La columna ya existe
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE laboratorios ADD COLUMN hora TEXT");
|
|
||||||
} catch (e) {
|
|
||||||
// La columna ya existe
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const existingTable = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='interconsultas'").get();
|
|
||||||
if (!existingTable) {
|
|
||||||
db.exec(`
|
|
||||||
CREATE TABLE interconsultas (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT NOT NULL,
|
|
||||||
fecha TEXT,
|
|
||||||
servicioInterconsultado TEXT,
|
|
||||||
motivo TEXT,
|
|
||||||
respuestaInterconsulta TEXT,
|
|
||||||
respuestaFecha TEXT
|
|
||||||
)
|
|
||||||
`);
|
|
||||||
console.log('Tabla interconsultas creada');
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE interconsultas ADD COLUMN respuestaFecha TEXT");
|
|
||||||
} catch (e) {
|
|
||||||
// Column already exists
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE interconsultas ADD COLUMN motivo TEXT");
|
|
||||||
} catch (e) {
|
|
||||||
// Column already exists
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Error tabla interconsultas:', e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const existingATB = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='atb'").get();
|
|
||||||
if (!existingATB) {
|
|
||||||
db.exec(`
|
|
||||||
CREATE TABLE atb (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
pacienteId TEXT NOT NULL,
|
|
||||||
internacionId TEXT NOT NULL,
|
|
||||||
antibiotico TEXT,
|
|
||||||
fechaInicio TEXT,
|
|
||||||
fechaFinalizacion TEXT
|
|
||||||
)
|
|
||||||
`);
|
|
||||||
console.log('Tabla atb creada');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Error tabla atb:', e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const existingIndicaciones = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='indicaciones'").get();
|
|
||||||
if (!existingIndicaciones) {
|
|
||||||
db.exec(`
|
|
||||||
CREATE TABLE indicaciones (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
internacionId TEXT NOT NULL,
|
|
||||||
tipo TEXT NOT NULL,
|
|
||||||
droga TEXT,
|
|
||||||
dosis TEXT,
|
|
||||||
frecuenciaHoras INTEGER,
|
|
||||||
via TEXT,
|
|
||||||
descripcion TEXT,
|
|
||||||
tipoPlan TEXT,
|
|
||||||
tipoPlan2 TEXT,
|
|
||||||
cantidadMl INTEGER,
|
|
||||||
cantidadMl2 INTEGER,
|
|
||||||
tiempoHoras INTEGER,
|
|
||||||
estado TEXT DEFAULT 'Activa',
|
|
||||||
medicoCrea TEXT,
|
|
||||||
fechaCrea TEXT,
|
|
||||||
indicacionNoFco TEXT
|
|
||||||
)
|
|
||||||
`);
|
|
||||||
console.log('Tabla indicaciones creada');
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE indicaciones ADD COLUMN tipoPlan2 TEXT");
|
|
||||||
} catch (e) {
|
|
||||||
// column may already exist
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE indicaciones ADD COLUMN cantidadMl2 INTEGER");
|
|
||||||
} catch (e) {
|
|
||||||
// column may already exist
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE indicaciones ADD COLUMN tipoInsulina TEXT");
|
|
||||||
} catch (e) {
|
|
||||||
// column may already exist
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE indicaciones ADD COLUMN unidadesDesayuno INTEGER");
|
|
||||||
} catch (e) {
|
|
||||||
// column may already exist
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE indicaciones ADD COLUMN unidadesAlmuerzo INTEGER");
|
|
||||||
} catch (e) {
|
|
||||||
// column may already exist
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
db.exec("ALTER TABLE indicaciones ADD COLUMN unidadesNoche INTEGER");
|
|
||||||
} catch (e) {
|
|
||||||
// column may already exist
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Error tabla indicaciones:', e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const exists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='movimientos_indicaciones'").get();
|
|
||||||
if (!exists) {
|
|
||||||
db.exec(`
|
|
||||||
CREATE TABLE movimientos_indicaciones (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
indicacionId TEXT NOT NULL,
|
|
||||||
internacionId TEXT NOT NULL,
|
|
||||||
tipo TEXT NOT NULL,
|
|
||||||
fecha TEXT NOT NULL,
|
|
||||||
profesional TEXT NOT NULL,
|
|
||||||
indicacionPrevia TEXT,
|
|
||||||
indicacionNueva TEXT
|
|
||||||
)
|
|
||||||
`);
|
|
||||||
console.log('Tabla movimientos_indicaciones creada');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Tabla movimientos_indicaciones:', e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
const app = express();
|
|
||||||
app.use(cors());
|
|
||||||
app.use(express.json({ limit: '50mb' }));
|
|
||||||
|
|
||||||
function rowToObj(row) {
|
|
||||||
if (!row) return row;
|
|
||||||
const obj = {};
|
|
||||||
for (const key in row) {
|
|
||||||
const val = row[key];
|
|
||||||
try {
|
|
||||||
obj[key] = typeof val === 'string' && (val.startsWith('[') || val.startsWith('{')) ? JSON.parse(val) : val;
|
|
||||||
} catch {
|
|
||||||
obj[key] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
function queryAll(sql, params = []) {
|
|
||||||
const stmt = db.prepare(sql);
|
|
||||||
const rows = params.length ? stmt.all(...params) : stmt.all();
|
|
||||||
return rows.map(rowToObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
function queryOne(sql, params = []) {
|
|
||||||
const stmt = db.prepare(sql);
|
|
||||||
const row = params.length ? stmt.get(...params) : stmt.get();
|
|
||||||
return rowToObj(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
function run(sql, params = []) {
|
|
||||||
const stmt = db.prepare(sql);
|
|
||||||
return params.length ? stmt.run(...params) : stmt.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
app.get('/api/state', (req, res) => {
|
|
||||||
const state = {
|
|
||||||
pacientes: queryAll('SELECT * FROM pacientes'),
|
|
||||||
areas: queryAll('SELECT * FROM areas'),
|
|
||||||
camas: queryAll('SELECT * FROM camas'),
|
|
||||||
internaciones: queryAll('SELECT * FROM internaciones').map(i => ({ ...i, activa: !!i.activa })),
|
|
||||||
evoluciones: queryAll('SELECT * FROM evoluciones').map(e => ({
|
|
||||||
...e,
|
|
||||||
signosVitales: typeof e.signosVitales === 'string' ? JSON.parse(e.signosVitales) : e.signosVitales,
|
|
||||||
examenFisico: typeof e.examenFisico === 'string' ? JSON.parse(e.examenFisico) : e.examenFisico
|
|
||||||
})),
|
|
||||||
laboratorios: queryAll('SELECT * FROM laboratorios').map(l => ({ ...l, resultados: typeof l.resultados === 'string' ? JSON.parse(l.resultados) : l.resultados })),
|
|
||||||
acidosBase: queryAll('SELECT * FROM acidosbase'),
|
|
||||||
cultivos: queryAll('SELECT * FROM cultivos'),
|
|
||||||
estudiosComplementarios: queryAll('SELECT * FROM estudiosComplementarios'),
|
|
||||||
interconsultas: queryAll('SELECT * FROM interconsultas').map(ic => ({ ...ic, realizada: !!ic.realizada })),
|
|
||||||
atb: queryAll('SELECT * FROM atb'),
|
|
||||||
indicaciones: queryAll('SELECT * FROM indicaciones'),
|
|
||||||
movimientosIndicaciones: queryAll('SELECT * FROM movimientos_indicaciones'),
|
|
||||||
vistaActual: 'dashboard',
|
|
||||||
currentInternacionId: null
|
|
||||||
};
|
|
||||||
res.json(state);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.put('/api/state', (req, res) => {
|
|
||||||
const state = req.body;
|
|
||||||
|
|
||||||
run('DELETE FROM evoluciones');
|
|
||||||
run('DELETE FROM acidosbase');
|
|
||||||
run('DELETE FROM cultivos');
|
|
||||||
run('DELETE FROM laboratorios');
|
|
||||||
run('DELETE FROM internaciones');
|
|
||||||
run('DELETE FROM camas');
|
|
||||||
run('DELETE FROM areas');
|
|
||||||
run('DELETE FROM pacientes');
|
|
||||||
run('DELETE FROM estudiosComplementarios');
|
|
||||||
|
|
||||||
if (state.pacientes?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO pacientes (id, apellido, nombre, dni, fechaNacimiento, sexo, telefono, email, direccion, obraSocial, nacionalidad, medicacionHabitual, antecedentes, alergias, grupoSanguineo, historiaClinica) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const p of state.pacientes) {
|
|
||||||
stmt.run(p.id, p.apellido, p.nombre, p.dni, p.fechaNacimiento || null, p.sexo || null, p.telefono || null, p.email || null, p.direccion || null, p.obraSocial || null, p.nacionalidad || null, p.medicacionHabitual || null, p.antecedentes || null, p.alergias || null, p.grupoSanguineo || null, p.historiaClinica || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.areas?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO areas (id, nombre) VALUES (?, ?)');
|
|
||||||
for (const a of state.areas) {
|
|
||||||
stmt.run(a.id, a.nombre);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.camas?.length) {
|
|
||||||
const stmt = db.prepare('INSERT OR IGNORE INTO camas (id, numero, areaId, tipo, estado) VALUES (?, ?, ?, ?, ?)');
|
|
||||||
for (const c of state.camas) {
|
|
||||||
stmt.run(c.id, c.numero, c.areaId, c.tipo, c.estado);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.internaciones?.length) {
|
|
||||||
const stmt = db.prepare('INSERT OR IGNORE INTO internaciones (id, pacienteId, camaId, areaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const i of state.internaciones) {
|
|
||||||
stmt.run(i.id, i.pacienteId, i.camaId, i.areaId || null, i.fechaIngresoHospital || null, i.fechaIngresoClinica || null, i.fechaEgreso || null, i.diagnosticoIngreso || null, i.motivoConsulta || null, i.enfermedadActual || null, i.antecedentesEnfermedadActual || null, i.diagnosticoEgreso || null, i.medicoIngresante || null, i.motivoEgreso || null, i.activa ? 1 : 0, i.apache || null, i.derivacion || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.evoluciones?.length) {
|
|
||||||
const stmt = db.prepare('INSERT OR IGNORE INTO evoluciones (id, internacionId, fecha, hora, medico, signosVitales, examenFisico, novedades, comentarios, pendientes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const e of state.evoluciones) {
|
|
||||||
stmt.run(e.id, e.internacionId, e.fecha, e.hora || '', e.medico || '', JSON.stringify(e.signosVitales || {}), JSON.stringify(e.examenFisico || {}), e.novedades || '', e.comentario || '', e.pendientes || '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.laboratorios?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO laboratorios (id, pacienteId, fecha, hora, tipo, resultados, observaciones) VALUES (?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const l of state.laboratorios) {
|
|
||||||
stmt.run(l.id, l.pacienteId, l.fecha, l.hora || null, l.tipo, JSON.stringify(l.resultados), l.observaciones || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.acidosBase?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO acidosbase (id, pacienteId, fecha, hora, ph, pco2, po2, hco3, be, sato2, lactato, interpretacion, fio2) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const a of state.acidosBase) {
|
|
||||||
stmt.run(a.id, a.pacienteId, a.fecha, a.hora, a.ph, a.pco2, a.po2, a.hco3, a.be, a.sato2, a.lactato || null, a.interpretacion || null, a.fio2 || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.cultivos?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO cultivos (id, pacienteId, internacionId, fechaToma, protocolo, tipoMuestra, observaciones, estado, fechaResultado, germen, sensible, resistente) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const c of state.cultivos) {
|
|
||||||
stmt.run(c.id, c.pacienteId, c.internacionId, c.fechaToma, c.protocolo, c.tipoMuestra, c.observaciones, c.estado, c.fechaResultado, c.germen, c.sensible, c.resistente);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.estudiosComplementarios?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO estudiosComplementarios (id, pacienteId, internacionId, fecha, tipo, resultado) VALUES (?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const e of state.estudiosComplementarios) {
|
|
||||||
stmt.run(e.id, e.pacienteId, e.internacionId || null, e.fecha, e.tipo, e.resultado);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
run('DELETE FROM interconsultas');
|
|
||||||
if (state.interconsultas?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO interconsultas (id, pacienteId, internacionId, fecha, servicioInterconsultado, motivo, respuestaInterconsulta, respuestaFecha) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const ic of state.interconsultas) {
|
|
||||||
stmt.run(ic.id, ic.pacienteId, ic.internacionId, ic.fecha, ic.servicioInterconsultado, ic.motivo || null, ic.respuestaInterconsulta || null, ic.respuestaFecha || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
run('DELETE FROM atb');
|
|
||||||
if (state.atb?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO atb (id, pacienteId, internacionId, antibiotico, fechaInicio, fechaFinalizacion) VALUES (?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const atb of state.atb) {
|
|
||||||
stmt.run(atb.id, atb.pacienteId, atb.internacionId, atb.antibiotico, atb.fechaInicio, atb.fechaFinalizacion || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
run('DELETE FROM indicaciones');
|
|
||||||
if (state.indicaciones?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO indicaciones (id, internacionId, tipo, droga, dosis, frecuenciaHoras, via, tipoPlan, tipoPlan2, cantidadMl, cantidadMl2, tiempoHoras, estado, medicoCrea, fechaCrea, tipoInsulina, unidadesDesayuno, unidadesAlmuerzo, unidadesNoche, indicacionNoFco) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const ind of state.indicaciones) {
|
|
||||||
stmt.run(ind.id, ind.internacionId, ind.tipo, ind.droga || null, ind.dosis || null, ind.frecuenciaHoras || null, ind.via || null, ind.tipoPlan || null, ind.tipoPlan2 || null, ind.cantidadMl || null, ind.cantidadMl2 || null, ind.tiempoHoras || null, ind.estado, ind.medicoCrea, ind.fechaCrea, ind.tipoInsulina || null, ind.unidadesDesayuno || null, ind.unidadesAlmuerzo || null, ind.unidadesNoche || null, ind.indicacionNoFco || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
run('DELETE FROM movimientos_indicaciones');
|
|
||||||
if (state.movimientosIndicaciones?.length) {
|
|
||||||
const stmt = db.prepare('INSERT INTO movimientos_indicaciones (id, indicacionId, internacionId, tipo, fecha, profesional, indicacionPrevia, indicacionNueva) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
|
|
||||||
for (const mov of state.movimientosIndicaciones) {
|
|
||||||
stmt.run(mov.id, mov.indicacionId, mov.internacionId, mov.tipo, mov.fecha, mov.profesional, mov.indicacionPrevia || null, mov.indicacionNueva || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json({ ok: true });
|
|
||||||
});
|
|
||||||
|
|
||||||
if (existsSync(DIST_PATH)) {
|
|
||||||
app.use(express.static(DIST_PATH));
|
|
||||||
}
|
|
||||||
|
|
||||||
app.get('*', (req, res) => {
|
|
||||||
res.sendFile(join(DIST_PATH, 'index.html'));
|
|
||||||
});
|
|
||||||
|
|
||||||
const PORT = process.env.PORT || 4000;
|
|
||||||
const HOST = process.env.HOST || '0.0.0.0';
|
|
||||||
app.listen(Number(PORT), HOST, () => {
|
|
||||||
console.log(`Server running on http://${HOST}:${PORT}`);
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
> my-app@0.0.0 dev
|
||||||
|
> tsx server.ts
|
||||||
|
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
Failed to initialize MongoDB: MongoServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
|
||||||
|
at Topology.selectServer (/app/applet/node_modules/mongodb/src/sdam/topology.ts:638:30)
|
||||||
|
at async Topology._connect (/app/applet/node_modules/mongodb/src/sdam/topology.ts:466:22)
|
||||||
|
at async Topology.connect (/app/applet/node_modules/mongodb/src/sdam/topology.ts:402:7)
|
||||||
|
at async topologyConnect (/app/applet/node_modules/mongodb/src/mongo_client.ts:684:9)
|
||||||
|
at async MongoClient._connect (/app/applet/node_modules/mongodb/src/mongo_client.ts:696:7)
|
||||||
|
at async MongoClient.connect (/app/applet/node_modules/mongodb/src/mongo_client.ts:608:7)
|
||||||
|
at async initDb (file:///app/applet/server/db-mongodb.js:27:5)
|
||||||
|
at async startServer (/app/applet/server.ts:9:5) {
|
||||||
|
errorLabelSet: Set(0) {},
|
||||||
|
reason: TopologyDescription {
|
||||||
|
type: 'Unknown',
|
||||||
|
servers: Map(1) { '127.0.0.1:27017' => [ServerDescription] },
|
||||||
|
stale: false,
|
||||||
|
compatible: true,
|
||||||
|
heartbeatFrequencyMS: 10000,
|
||||||
|
localThresholdMS: 15,
|
||||||
|
setName: null,
|
||||||
|
maxElectionId: null,
|
||||||
|
maxSetVersion: null,
|
||||||
|
commonWireVersion: 0,
|
||||||
|
logicalSessionTimeoutMinutes: null
|
||||||
|
},
|
||||||
|
code: undefined,
|
||||||
|
[cause]: MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017
|
||||||
|
at Socket.<anonymous> (/app/applet/node_modules/mongodb/src/cmap/connect.ts:430:16)
|
||||||
|
at Object.onceWrapper (node:events:634:26)
|
||||||
|
at Socket.emit (node:events:519:28)
|
||||||
|
at emitErrorNT (node:internal/streams/destroy:170:8)
|
||||||
|
at emitErrorCloseNT (node:internal/streams/destroy:129:3)
|
||||||
|
at process.processTicksAndRejections (node:internal/process/task_queues:89:21) {
|
||||||
|
errorLabelSet: Set(3) { 'SystemOverloadedError', 'RetryableError', 'ResetPool' },
|
||||||
|
beforeHandshake: false,
|
||||||
|
[cause]: Error: connect ECONNREFUSED 127.0.0.1:27017
|
||||||
|
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1638:16) {
|
||||||
|
errno: -111,
|
||||||
|
code: 'ECONNREFUSED',
|
||||||
|
syscall: 'connect',
|
||||||
|
address: '127.0.0.1',
|
||||||
|
port: 27017
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Failed to initialize MongoDB: MongoServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
|
||||||
|
at Topology.selectServer (/app/applet/node_modules/mongodb/src/sdam/topology.ts:638:30)
|
||||||
|
at async Topology._connect (/app/applet/node_modules/mongodb/src/sdam/topology.ts:466:22)
|
||||||
|
at async Topology.connect (/app/applet/node_modules/mongodb/src/sdam/topology.ts:402:7)
|
||||||
|
at async topologyConnect (/app/applet/node_modules/mongodb/src/mongo_client.ts:684:9)
|
||||||
|
at async MongoClient._connect (/app/applet/node_modules/mongodb/src/mongo_client.ts:696:7)
|
||||||
|
at async MongoClient.connect (/app/applet/node_modules/mongodb/src/mongo_client.ts:608:7)
|
||||||
|
at async initDb (file:///app/applet/server/db-mongodb.js:27:5)
|
||||||
|
at async startServer (/app/applet/server.ts:9:5) {
|
||||||
|
errorLabelSet: Set(0) {},
|
||||||
|
reason: TopologyDescription {
|
||||||
|
type: 'Unknown',
|
||||||
|
servers: Map(1) { '127.0.0.1:27017' => [ServerDescription] },
|
||||||
|
stale: false,
|
||||||
|
compatible: true,
|
||||||
|
heartbeatFrequencyMS: 10000,
|
||||||
|
localThresholdMS: 15,
|
||||||
|
setName: null,
|
||||||
|
maxElectionId: null,
|
||||||
|
maxSetVersion: null,
|
||||||
|
commonWireVersion: 0,
|
||||||
|
logicalSessionTimeoutMinutes: null
|
||||||
|
},
|
||||||
|
code: undefined,
|
||||||
|
[cause]: MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017
|
||||||
|
at Socket.<anonymous> (/app/applet/node_modules/mongodb/src/cmap/connect.ts:430:16)
|
||||||
|
at Object.onceWrapper (node:events:634:26)
|
||||||
|
at Socket.emit (node:events:519:28)
|
||||||
|
at emitErrorNT (node:internal/streams/destroy:170:8)
|
||||||
|
at emitErrorCloseNT (node:internal/streams/destroy:129:3)
|
||||||
|
at process.processTicksAndRejections (node:internal/process/task_queues:89:21) {
|
||||||
|
errorLabelSet: Set(3) { 'SystemOverloadedError', 'RetryableError', 'ResetPool' },
|
||||||
|
beforeHandshake: false,
|
||||||
|
[cause]: Error: connect ECONNREFUSED 127.0.0.1:27017
|
||||||
|
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1638:16) {
|
||||||
|
errno: -111,
|
||||||
|
code: 'ECONNREFUSED',
|
||||||
|
syscall: 'connect',
|
||||||
|
address: '127.0.0.1',
|
||||||
|
port: 27017
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Continuing in development mode without database connection.
|
||||||
|
WebSocket server error: Port 24678 is already in use
|
||||||
|
node:events:497
|
||||||
|
throw er; // Unhandled 'error' event
|
||||||
|
^
|
||||||
|
|
||||||
|
Error: listen EADDRINUSE: address already in use 0.0.0.0:3000
|
||||||
|
at Server.setupListenHandle [as _listen2] (node:net:1941:16)
|
||||||
|
at listenInCluster (node:net:1998:12)
|
||||||
|
at node:net:2207:7
|
||||||
|
at process.processTicksAndRejections (node:internal/process/task_queues:89:21)
|
||||||
|
Emitted 'error' event on Server instance at:
|
||||||
|
at emitErrorNT (node:net:1977:8)
|
||||||
|
at process.processTicksAndRejections (node:internal/process/task_queues:89:21) {
|
||||||
|
code: 'EADDRINUSE',
|
||||||
|
errno: -98,
|
||||||
|
syscall: 'listen',
|
||||||
|
address: '0.0.0.0',
|
||||||
|
port: 3000
|
||||||
|
}
|
||||||
|
|
||||||
|
Node.js v22.23.1
|
||||||
Reference in New Issue
Block a user