diff --git a/.swcrc b/.swcrc
deleted file mode 100644
index a26032a..0000000
--- a/.swcrc
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "exclude": "node_modules/",
- "jsc": {
- "parser": {
- "syntax": "typescript",
- "topLevelAwait": true
- },
- "target": "esnext",
- "baseUrl": ".",
- "experimental": {
- "plugins": [
- [
- "@swc/plugin-transform-imports",
- {
- "^(.*?)(\\.ts)$": {
- "skipDefaultConversion": true,
- "transform": "{{matches.[1]}}.js"
- }
- }
- ]
- ]
- }
- },
- "module": {
- "type": "nodenext"
- }
-}
diff --git a/README.md b/README.md
index 0e35d92..3e57795 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ Automatization around Siril () and ASIAIR for deep sky astro
**Poto-Siril is a CLI tool to automate the pre-processing of astrophotography images on top of Siril.**
-Poto-Siril's primary goal is to **overcome the repetitive** work when pre-processing multiple layers before compositing a (L)RGB image (e.g. narrowband filters with monochrome camera or color camera with dual-band filters). It works with images captured by a ZWO ASIAIR device out of the box or with any `fit` files that follows the same [naming convention and directory structure](#poto-siril-project-architecture).
+Poto-Siril's primary goal is to **overcome the repetitive and tedious** work when pre-processing multiple layers before compositing a (L)RGB image (e.g. narrowband filters with monochrome camera or color camera with dual-band filters). It works with images captured by a ZWO ASIAIR device out of the box or with any `fit` files that follows the same [naming convention and directory structure](#poto-siril-project-architecture).
### Workflow š
@@ -18,6 +18,9 @@ Poto-Siril's primary goal is to **overcome the repetitive** work when pre-proces
Import one or several night sessions (lights and flats from `autorun` or `plan` mode with ASIAIR) and automatically pick the darks and bias from the bank folder (matching bulb, gain, binning, ...).
A summary resumes the light sequence(s) and the calibration files associated.
![dispatch](./img/poto-siril_dispatch.png)
+- **Complex Light - Flat matching**
+ The project consists of multiple night sessions where the flats changed over the time? e.g., a significant date gap between shooting sessions and the lights aren't coming with the same collimation and/or dust in the optical train.
+ Poto-Siril will auto-detect that and help you to associate the right flats to the right lights.
- **Multi-layers project structure**
The imported files āļø are organized by filters and light sets (bulb, gain & binning, if there's multiple combinations). Each light set will map to a light sequence in Siril that you preprocess separately.
š You can easily work on a LRGB or LRGBHaOIIISII project.
diff --git a/eslint.config.mjs b/eslint.config.mjs
index 97313ef..a369e28 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -41,7 +41,7 @@ export default [
rules: {
indent: [
- "error",
+ "warn",
2,
{
offsetTernaryExpressions: true,
diff --git a/package-lock.json b/package-lock.json
index 5156d9b..7c21034 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -26,7 +26,6 @@
"eslint": "^9.17.0",
"globals": "^15.14.0",
"jest": "^29.7.0",
- "swc": "^1.0.11",
"ts-jest": "^29.2.4",
"ts-node": "^10.9.2",
"tsx": "^3.8.0",
@@ -1798,26 +1797,6 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "node_modules/@mole-inc/bin-wrapper": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/@mole-inc/bin-wrapper/-/bin-wrapper-8.0.1.tgz",
- "integrity": "sha512-sTGoeZnjI8N4KS+sW2AN95gDBErhAguvkw/tWdCjeM8bvxpz5lqrnd0vOJABA1A+Ic3zED7PYoLP/RANLgVotA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "bin-check": "^4.1.0",
- "bin-version-check": "^5.0.0",
- "content-disposition": "^0.5.4",
- "ext-name": "^5.0.0",
- "file-type": "^17.1.6",
- "filenamify": "^5.0.2",
- "got": "^11.8.5",
- "os-filter-obj": "^2.0.0"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- }
- },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -1869,19 +1848,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@sindresorhus/is": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
- "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/is?sponsor=1"
- }
- },
"node_modules/@sindresorhus/merge-streams": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
@@ -1914,331 +1880,6 @@
"@sinonjs/commons": "^3.0.0"
}
},
- "node_modules/@swc/cli": {
- "version": "0.1.65",
- "resolved": "https://registry.npmjs.org/@swc/cli/-/cli-0.1.65.tgz",
- "integrity": "sha512-4NcgsvJVHhA7trDnMmkGLLvWMHu2kSy+qHx6QwRhhJhdiYdNUrhdp+ERxen73sYtaeEOYeLJcWrQ60nzKi6rpg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@mole-inc/bin-wrapper": "^8.0.1",
- "commander": "^7.1.0",
- "fast-glob": "^3.2.5",
- "minimatch": "^9.0.3",
- "semver": "^7.3.8",
- "slash": "3.0.0",
- "source-map": "^0.7.3"
- },
- "bin": {
- "spack": "bin/spack.js",
- "swc": "bin/swc.js",
- "swcx": "bin/swcx.js"
- },
- "engines": {
- "node": ">= 12.13"
- },
- "peerDependencies": {
- "@swc/core": "^1.2.66",
- "chokidar": "^3.5.1"
- },
- "peerDependenciesMeta": {
- "chokidar": {
- "optional": true
- }
- }
- },
- "node_modules/@swc/cli/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/@swc/cli/node_modules/commander": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
- "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@swc/cli/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@swc/cli/node_modules/source-map": {
- "version": "0.7.4",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
- "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@swc/core": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.1.tgz",
- "integrity": "sha512-rQ4dS6GAdmtzKiCRt3LFVxl37FaY1cgL9kSUTnhQ2xc3fmHOd7jdJK/V4pSZMG1ruGTd0bsi34O2R0Olg9Zo/w==",
- "dev": true,
- "hasInstallScript": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@swc/counter": "^0.1.3",
- "@swc/types": "^0.1.17"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/swc"
- },
- "optionalDependencies": {
- "@swc/core-darwin-arm64": "1.10.1",
- "@swc/core-darwin-x64": "1.10.1",
- "@swc/core-linux-arm-gnueabihf": "1.10.1",
- "@swc/core-linux-arm64-gnu": "1.10.1",
- "@swc/core-linux-arm64-musl": "1.10.1",
- "@swc/core-linux-x64-gnu": "1.10.1",
- "@swc/core-linux-x64-musl": "1.10.1",
- "@swc/core-win32-arm64-msvc": "1.10.1",
- "@swc/core-win32-ia32-msvc": "1.10.1",
- "@swc/core-win32-x64-msvc": "1.10.1"
- },
- "peerDependencies": {
- "@swc/helpers": "*"
- },
- "peerDependenciesMeta": {
- "@swc/helpers": {
- "optional": true
- }
- }
- },
- "node_modules/@swc/core-darwin-arm64": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.1.tgz",
- "integrity": "sha512-NyELPp8EsVZtxH/mEqvzSyWpfPJ1lugpTQcSlMduZLj1EASLO4sC8wt8hmL1aizRlsbjCX+r0PyL+l0xQ64/6Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-darwin-x64": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.1.tgz",
- "integrity": "sha512-L4BNt1fdQ5ZZhAk5qoDfUnXRabDOXKnXBxMDJ+PWLSxOGBbWE6aJTnu4zbGjJvtot0KM46m2LPAPY8ttknqaZA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-arm-gnueabihf": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.1.tgz",
- "integrity": "sha512-Y1u9OqCHgvVp2tYQAJ7hcU9qO5brDMIrA5R31rwWQIAKDkJKtv3IlTHF0hrbWk1wPR0ZdngkQSJZple7G+Grvw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-arm64-gnu": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.1.tgz",
- "integrity": "sha512-tNQHO/UKdtnqjc7o04iRXng1wTUXPgVd8Y6LI4qIbHVoVPwksZydISjMcilKNLKIwOoUQAkxyJ16SlOAeADzhQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-arm64-musl": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.1.tgz",
- "integrity": "sha512-x0L2Pd9weQ6n8dI1z1Isq00VHFvpBClwQJvrt3NHzmR+1wCT/gcYl1tp9P5xHh3ldM8Cn4UjWCw+7PaUgg8FcQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-x64-gnu": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.1.tgz",
- "integrity": "sha512-yyYEwQcObV3AUsC79rSzN9z6kiWxKAVJ6Ntwq2N9YoZqSPYph+4/Am5fM1xEQYf/kb99csj0FgOelomJSobxQA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-linux-x64-musl": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.1.tgz",
- "integrity": "sha512-tcaS43Ydd7Fk7sW5ROpaf2Kq1zR+sI5K0RM+0qYLYYurvsJruj3GhBCaiN3gkzd8m/8wkqNqtVklWaQYSDsyqA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-win32-arm64-msvc": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.1.tgz",
- "integrity": "sha512-D3Qo1voA7AkbOzQ2UGuKNHfYGKL6eejN8VWOoQYtGHHQi1p5KK/Q7V1ku55oxXBsj79Ny5FRMqiRJpVGad7bjQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-win32-ia32-msvc": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.1.tgz",
- "integrity": "sha512-WalYdFoU3454Og+sDKHM1MrjvxUGwA2oralknXkXL8S0I/8RkWZOB++p3pLaGbTvOO++T+6znFbQdR8KRaa7DA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/core-win32-x64-msvc": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.1.tgz",
- "integrity": "sha512-JWobfQDbTnoqaIwPKQ3DVSywihVXlQMbDuwik/dDWlj33A8oEHcjPOGs4OqcA3RHv24i+lfCQpM3Mn4FAMfacA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "Apache-2.0 AND MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@swc/counter": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
- "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "node_modules/@swc/types": {
- "version": "0.1.17",
- "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz",
- "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@swc/counter": "^0.1.3"
- }
- },
- "node_modules/@szmarczak/http-timer": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
- "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "defer-to-connect": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@tokenizer/token": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
- "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@tsconfig/node10": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
@@ -2312,19 +1953,6 @@
"@babel/types": "^7.20.7"
}
},
- "node_modules/@types/cacheable-request": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
- "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/http-cache-semantics": "*",
- "@types/keyv": "^3.1.4",
- "@types/node": "*",
- "@types/responselike": "^1.0.0"
- }
- },
"node_modules/@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
@@ -2342,13 +1970,6 @@
"@types/node": "*"
}
},
- "node_modules/@types/http-cache-semantics": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
- "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@types/inquirer": {
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.7.tgz",
@@ -2405,16 +2026,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@types/keyv": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
- "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
"node_modules/@types/node": {
"version": "22.10.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz",
@@ -2425,16 +2036,6 @@
"undici-types": "~6.20.0"
}
},
- "node_modules/@types/responselike": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz",
- "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
"node_modules/@types/stack-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
@@ -2801,27 +2402,6 @@
"node": ">= 8"
}
},
- "node_modules/arch": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
- "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
"node_modules/arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
@@ -2942,346 +2522,72 @@
"semver": "bin/semver.js"
}
},
- "node_modules/babel-plugin-jest-hoist": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
- "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.3.3",
- "@babel/types": "^7.3.3",
- "@types/babel__core": "^7.1.14",
- "@types/babel__traverse": "^7.0.6"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/babel-preset-current-node-syntax": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz",
- "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-bigint": "^7.8.3",
- "@babel/plugin-syntax-class-properties": "^7.12.13",
- "@babel/plugin-syntax-class-static-block": "^7.14.5",
- "@babel/plugin-syntax-import-attributes": "^7.24.7",
- "@babel/plugin-syntax-import-meta": "^7.10.4",
- "@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
- "@babel/plugin-syntax-top-level-await": "^7.14.5"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/babel-preset-jest": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
- "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "babel-plugin-jest-hoist": "^29.6.3",
- "babel-preset-current-node-syntax": "^1.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/bin-check": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz",
- "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "execa": "^0.7.0",
- "executable": "^4.1.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/bin-check/node_modules/cross-spawn": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
- "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lru-cache": "^4.0.1",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- }
- },
- "node_modules/bin-check/node_modules/execa": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
- "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^5.0.1",
- "get-stream": "^3.0.0",
- "is-stream": "^1.1.0",
- "npm-run-path": "^2.0.0",
- "p-finally": "^1.0.0",
- "signal-exit": "^3.0.0",
- "strip-eof": "^1.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/bin-check/node_modules/get-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
- "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/bin-check/node_modules/is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/bin-check/node_modules/lru-cache": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
- "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "pseudomap": "^1.0.2",
- "yallist": "^2.1.2"
- }
- },
- "node_modules/bin-check/node_modules/npm-run-path": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
- "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^2.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/bin-check/node_modules/path-key": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/bin-check/node_modules/shebang-command": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
- "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "shebang-regex": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/bin-check/node_modules/shebang-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
- "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/bin-check/node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/bin-check/node_modules/which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "which": "bin/which"
- }
- },
- "node_modules/bin-check/node_modules/yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/bin-version": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-6.0.0.tgz",
- "integrity": "sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "execa": "^5.0.0",
- "find-versions": "^5.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/bin-version-check": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-5.1.0.tgz",
- "integrity": "sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "bin-version": "^6.0.0",
- "semver": "^7.5.3",
- "semver-truncate": "^3.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/bin-version/node_modules/execa": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
- "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^6.0.0",
- "human-signals": "^2.1.0",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.1",
- "onetime": "^5.1.2",
- "signal-exit": "^3.0.3",
- "strip-final-newline": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
- }
- },
- "node_modules/bin-version/node_modules/get-stream": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
- "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/bin-version/node_modules/human-signals": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
- "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
+ "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
"dev": true,
- "license": "Apache-2.0",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.1.14",
+ "@types/babel__traverse": "^7.0.6"
+ },
"engines": {
- "node": ">=10.17.0"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/bin-version/node_modules/is-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz",
+ "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==",
"dev": true,
"license": "MIT",
- "engines": {
- "node": ">=8"
+ "dependencies": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-import-attributes": "^7.24.7",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
}
},
- "node_modules/bin-version/node_modules/npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "node_modules/babel-preset-jest": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
+ "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "path-key": "^3.0.0"
+ "babel-plugin-jest-hoist": "^29.6.3",
+ "babel-preset-current-node-syntax": "^1.0.0"
},
"engines": {
- "node": ">=8"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
}
},
- "node_modules/bin-version/node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/bin-version/node_modules/strip-final-newline": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
- "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
+ "license": "MIT"
},
"node_modules/brace-expansion": {
"version": "1.1.11",
@@ -3370,51 +2676,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/cacheable-lookup": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
- "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10.6.0"
- }
- },
- "node_modules/cacheable-request": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
- "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "clone-response": "^1.0.2",
- "get-stream": "^5.1.0",
- "http-cache-semantics": "^4.0.0",
- "keyv": "^4.0.0",
- "lowercase-keys": "^2.0.0",
- "normalize-url": "^6.0.1",
- "responselike": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cacheable-request/node_modules/get-stream": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
- "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "pump": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -3516,19 +2777,6 @@
"node": ">=12"
}
},
- "node_modules/clone-response": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
- "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mimic-response": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@@ -3583,19 +2831,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/content-disposition": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
- "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "5.2.1"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -3697,35 +2932,6 @@
}
}
},
- "node_modules/decompress-response": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
- "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mimic-response": "^3.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/decompress-response/node_modules/mimic-response": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
- "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/dedent": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
@@ -3758,16 +2964,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/defer-to-connect": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
- "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@@ -3841,16 +3037,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "once": "^1.4.0"
- }
- },
"node_modules/enquirer": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz",
@@ -4200,19 +3386,6 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
- "node_modules/executable": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz",
- "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "pify": "^2.2.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/exit": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
@@ -4239,33 +3412,6 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/ext-list": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
- "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mime-db": "^1.28.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/ext-name": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
- "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ext-list": "^2.0.0",
- "sort-keys-length": "^1.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -4365,24 +3511,6 @@
"node": ">=16.0.0"
}
},
- "node_modules/file-type": {
- "version": "17.1.6",
- "resolved": "https://registry.npmjs.org/file-type/-/file-type-17.1.6.tgz",
- "integrity": "sha512-hlDw5Ev+9e883s0pwUsuuYNu4tD7GgpUnOvykjv1Gya0ZIjuKumthDRua90VUn6/nlRKAjcxLUnHNTIUWwWIiw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "readable-web-to-node-stream": "^3.0.2",
- "strtok3": "^7.0.0-alpha.9",
- "token-types": "^5.0.0-alpha.2"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/file-type?sponsor=1"
- }
- },
"node_modules/filelist": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
@@ -4416,37 +3544,6 @@
"node": ">=10"
}
},
- "node_modules/filename-reserved-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz",
- "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/filenamify": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-5.1.1.tgz",
- "integrity": "sha512-M45CbrJLGACfrPOkrTp3j2EcO9OBkKUYME0eiqOCa7i2poaklU0jhlIaMlr8ijLorT0uLAzrn3qXOp5684CkfA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "filename-reserved-regex": "^3.0.0",
- "strip-outer": "^2.0.0",
- "trim-repeated": "^2.0.0"
- },
- "engines": {
- "node": ">=12.20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -4477,22 +3574,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/find-versions": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz",
- "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver-regex": "^4.0.5"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/flat-cache": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
@@ -4653,32 +3734,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/got": {
- "version": "11.8.6",
- "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
- "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sindresorhus/is": "^4.0.0",
- "@szmarczak/http-timer": "^4.0.5",
- "@types/cacheable-request": "^6.0.1",
- "@types/responselike": "^1.0.0",
- "cacheable-lookup": "^5.0.3",
- "cacheable-request": "^7.0.2",
- "decompress-response": "^6.0.0",
- "http2-wrapper": "^1.0.0-beta.5.2",
- "lowercase-keys": "^2.0.0",
- "p-cancelable": "^2.0.0",
- "responselike": "^2.0.0"
- },
- "engines": {
- "node": ">=10.19.0"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/got?sponsor=1"
- }
- },
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -4723,27 +3778,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/http-cache-semantics": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
- "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
- "dev": true,
- "license": "BSD-2-Clause"
- },
- "node_modules/http2-wrapper": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
- "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "quick-lru": "^5.1.1",
- "resolve-alpn": "^1.0.0"
- },
- "engines": {
- "node": ">=10.19.0"
- }
- },
"node_modules/human-signals": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz",
@@ -4753,27 +3787,6 @@
"node": ">=18.18.0"
}
},
- "node_modules/ieee754": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "BSD-3-Clause"
- },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -6397,16 +5410,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/lowercase-keys": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
- "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -6481,16 +5484,6 @@
"node": ">=8.6"
}
},
- "node_modules/mime-db": {
- "version": "1.53.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz",
- "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
@@ -6501,16 +5494,6 @@
"node": ">=6"
}
},
- "node_modules/mimic-response": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
- "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -6562,19 +5545,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/normalize-url": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
- "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/npm-run-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz",
@@ -6647,39 +5617,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/os-filter-obj": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz",
- "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "arch": "^2.1.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/p-cancelable": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
- "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/p-finally": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -6802,20 +5739,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/peek-readable": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.3.1.tgz",
- "integrity": "sha512-GVlENSDW6KHaXcd9zkZltB7tCLosKB/4Hg0fqBJkAoBgYG2Tn1xtMgXtSUuMU9AK/gCm/tTdT8mgAeF4YNeeqw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Borewit"
- }
- },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -6836,16 +5759,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/pirates": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
@@ -6979,24 +5892,6 @@
"node": ">= 6"
}
},
- "node_modules/pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/pump": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
- "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -7045,19 +5940,6 @@
],
"license": "MIT"
},
- "node_modules/quick-lru": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
- "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
@@ -7065,38 +5947,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/readable-web-to-node-stream": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz",
- "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "readable-stream": "^3.6.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Borewit"
- }
- },
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -7128,13 +5978,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/resolve-alpn": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
- "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/resolve-cwd": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
@@ -7188,19 +6031,6 @@
"node": ">=10"
}
},
- "node_modules/responselike": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
- "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lowercase-keys": "^2.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -7246,27 +6076,6 @@
"tslib": "^2.1.0"
}
},
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
"node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@@ -7280,35 +6089,6 @@
"node": ">=10"
}
},
- "node_modules/semver-regex": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz",
- "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/semver-truncate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-3.0.0.tgz",
- "integrity": "sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^7.3.5"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -7359,42 +6139,6 @@
"node": ">=8"
}
},
- "node_modules/sort-keys": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
- "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-plain-obj": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/sort-keys-length": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
- "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "sort-keys": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/sort-keys/node_modules/is-plain-obj": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
- "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -7446,16 +6190,6 @@
"node": ">=8"
}
},
- "node_modules/string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "~5.2.0"
- }
- },
"node_modules/string-length": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
@@ -7507,16 +6241,6 @@
"node": ">=8"
}
},
- "node_modules/strip-eof": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
- "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/strip-final-newline": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz",
@@ -7542,37 +6266,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/strip-outer": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-2.0.0.tgz",
- "integrity": "sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/strtok3": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.1.1.tgz",
- "integrity": "sha512-mKX8HA/cdBqMKUr0MMZAFssCkIGoZeSCMXgnt79yKxNFguMLVFgRe6wB+fsL0NmoHDbeyZXczy7vEPSoo3rkzg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@tokenizer/token": "^0.3.0",
- "peek-readable": "^5.1.3"
- },
- "engines": {
- "node": ">=16"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Borewit"
- }
- },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -7599,17 +6292,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/swc": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/swc/-/swc-1.0.11.tgz",
- "integrity": "sha512-YbG4eija7g/ajQ0lu4P2WPgKt5zCm743VgKn+buBrXXo1IETftO2r/8VdBPhv8wpTyg3CO+VU1z2wHuL4iohmw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@swc/cli": "^0.1.26",
- "@swc/core": "^1.2.12"
- }
- },
"node_modules/test-exclude": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
@@ -7645,50 +6327,6 @@
"node": ">=8.0"
}
},
- "node_modules/token-types": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz",
- "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@tokenizer/token": "^0.3.0",
- "ieee754": "^1.2.1"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Borewit"
- }
- },
- "node_modules/trim-repeated": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-2.0.0.tgz",
- "integrity": "sha512-QUHBFTJGdOwmp0tbOG505xAgOp/YliZP/6UgafFXYZ26WT1bvQmSMJUvkeVSASuJJHbqsFbynTvkd5W8RBTipg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "escape-string-regexp": "^5.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/trim-repeated/node_modules/escape-string-regexp": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
- "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/ts-api-utils": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
@@ -7964,13 +6602,6 @@
"punycode": "^2.1.0"
}
},
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
diff --git a/package.json b/package.json
index a3c0364..08420a0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "poto-siril",
- "version": "0.1.0",
+ "version": "0.2.0",
"description": "Automatization around Siril () and ASIAIR for deep sky astrophotography.",
"main": "poto.sh",
"type": "module",
@@ -32,7 +32,6 @@
"eslint": "^9.17.0",
"globals": "^15.14.0",
"jest": "^29.7.0",
- "swc": "^1.0.11",
"ts-jest": "^29.2.4",
"ts-node": "^10.9.2",
"typescript": "^5.5.3",
diff --git a/src/commands/dispatch-dump.ts b/src/commands/dispatch-dump.ts
index 7572114..32e545c 100644
--- a/src/commands/dispatch-dump.ts
+++ b/src/commands/dispatch-dump.ts
@@ -7,15 +7,20 @@
import fs from "fs";
import Enquirer from "enquirer";
-import { logger } from "../utils/logger";
+import { formatMessage, logger } from "../utils/logger";
import {
copyFileToProject,
getFitsFromDirectory,
matchSetFile,
getImageSpecFromSetName,
} from "../utils/utils";
-import { FileImageSpec, LayerSet, PotoProject } from "../utils/types";
-import { POTO_JSON } from "../utils/const";
+import {
+ FileImageSpec,
+ LayerSet,
+ LightsFlatsMatch,
+ PotoProject,
+} from "../utils/types";
+import { POTO_JSON, POTO_VERSION } from "../utils/const";
export type DispatchOptions = {
projectDirectory: string;
@@ -24,6 +29,8 @@ export type DispatchOptions = {
bankDirectory: string;
};
+const enquirer = new Enquirer();
+
const dispatch = async ({
projectDirectory,
asiAirDirectory,
@@ -32,132 +39,466 @@ const dispatch = async ({
}: DispatchOptions) => {
await ensureProjectDirectoryExists(projectDirectory);
+ logger.step("Reading input directories");
+
const inputFiles = getAllFitsInInputDirectories(
asiAirDirectory,
shootingMode,
projectDirectory,
);
- const lights = inputFiles.filter(file => file.type === "Light");
+ const allLights = inputFiles.filter(file => file.type === "Light");
+
+ logger.step("Matching lights and flats (early stage)");
+
+ const allFlatsMatchingLights = getFlatsMatchingLightsNaive(
+ inputFiles,
+ allLights,
+ );
+
+ logger.step("Matching lights and flats (final stage)");
+
+ const lightsFlatsMatches = await matchLightsToFlats(
+ allFlatsMatchingLights,
+ allLights,
+ );
+
+ let layerSets: LayerSet[] = initLayerSetsWithLightsnFlats(
+ lightsFlatsMatches,
+ allLights,
+ allFlatsMatchingLights,
+ );
+
+ logger.step("Tagging darks and biases");
+
+ const bankFiles = getAllFitsInBankDirectories(
+ bankDirectory,
+ projectDirectory,
+ );
+
+ layerSets = AssignDarksBiasesToLayerSets(layerSets, bankFiles);
+
+ logger.step("Preview before dispatching");
+
+ const go = await previewBeforeDispatching(layerSets);
+
+ if (!go) {
+ logger.warning("Aborted.");
+ return;
+ }
+ logger.step("Dispatching");
+
+ const potoProject: PotoProject = {
+ generatedAt: new Date(),
+ potoVersion: POTO_VERSION,
+ layerSets,
+ };
+
+ await dispatchProject(potoProject, projectDirectory);
+
+ logger.success("Dispatch complete.");
+
+ // TODO. custom sort if LRGBSHO filter names to ease reading.
+};
+
+export default dispatch;
+
+/**
+ * Ensure that the project directory exists.
+ * If it does not exist, ask the user if they want to create it.
+ *
+ * @param projectDirectory - The directory of the current project.
+ */
+const ensureProjectDirectoryExists = async (projectDirectory: string) => {
+ if (!fs.existsSync(projectDirectory)) {
+ const response = (await enquirer.prompt({
+ type: "confirm",
+ name: "createProjectDirectory",
+ message: `Directory ${projectDirectory} does not exist. Do you want to create it?`,
+ })) as { createProjectDirectory: boolean };
+
+ if (response.createProjectDirectory) {
+ fs.mkdirSync(projectDirectory, { recursive: true });
+ }
+ }
+};
+
+/**
+ * Retrieve all FITS files from the input directories.
+ *
+ * @param asiAirDirectory - The directory where ASIAIR files are stored.
+ * @param shootingMode - The shooting mode, either "autorun" or "plan".
+ * @param projectDirectory - The directory of the current project.
+ * @returns An array of FileImageSpec objects representing the FITS files.
+ */
+const getAllFitsInInputDirectories = (
+ asiAirDirectory: string,
+ shootingMode: string,
+ projectDirectory: string,
+): FileImageSpec[] => {
+ // TODO. Allow multiple directories in input.
+ // TODO. Decouple from ASIAIR. Just warn if files both found in Autorun and Plan, and ask the user to probably review the input files first.
+ const files = getFitsFromDirectory({
+ directory: `${asiAirDirectory}/${
+ shootingMode === "autorun" ? "Autorun" : "Plan"
+ }`,
+ projectDirectory,
+ });
+ logger.info(`Found ${files.length} files in input dir(s) to dispatch.`);
+ return files;
+};
+
+/**
+ * Naive matching of flats with lights.
+ * Sufficient enough to skip the flats that do not have a matching light at all.
+ *
+ * @param inputFiles - The input files to process. Searching for the flats in this list.
+ * @param lights - The lights to match with the flats.
+ */
+const getFlatsMatchingLightsNaive = (
+ inputFiles: FileImageSpec[],
+ lights: FileImageSpec[],
+): FileImageSpec[] => {
+ const notMatchedFlats: string[] = [];
const matchingFlats = inputFiles
.filter(x => x.type === "Flat")
.filter(flat => {
if (lights.find(light => matchSetFile(light, flat))) {
return flat;
} else {
- logger.infoNR(
- `Skippingg ${flat.setName} seq ${flat.sequenceId} from the ASIAIR, No light matching.`,
+ notMatchedFlats.push(
+ `No matching light for ${flat.setName} (seq ${flat.sequenceId}). Skipping.`,
);
}
});
+ const sequences = [...new Set(matchingFlats.map(file => file.sequenceId))];
+ for (const skip of [...new Set(notMatchedFlats)]) {
+ logger.warning(skip);
+ }
logger.info(
- `Found ${matchingFlats.length} matching flats.`,
- matchingFlats.map(x => x.fileName),
+ `Found ${matchingFlats.length} matching flats (${sequences.length} sequences).`,
);
- const importedLightsFlatsFiles: FileImageSpec[] = [];
- const importedDarksBiasesFiles: FileImageSpec[] = [];
+ return matchingFlats;
+};
- // Dispatch the ASIAIR Lights files to the project directory.
- const lightFiles = inputFiles.filter(file => file.type === "Light");
- lightFiles.forEach(file => {
- copyFileToProject(file);
- importedLightsFlatsFiles.push(file);
- });
+/**
+ * Process the light and flat matching.
+ * If multiple sequences are found for a flat, ask the user to select the flat sequence to use for each light sequence.
+ * NOTE. We expect that all flats have a matching light at this point, thanks to the `getFlatsMatchingLightsNaive` function.
+ *
+ * @param matchingFlats - The flats that have a matching light.
+ * @param lights - The lights to match with the flats.
+ */
+const matchLightsToFlats = async (
+ matchingFlats: FileImageSpec[],
+ lights: FileImageSpec[],
+): Promise => {
+ const flatSets = [...new Set(matchingFlats.map(file => file.setName))];
+
+ const LightFlatMatches: LightsFlatsMatch[] = [];
+
+ for (const flatSet of flatSets) {
+ const flatSetNameSequenceIds = [
+ ...new Set(
+ matchingFlats
+ .filter(flat => flat.setName === flatSet)
+ .map(flat => `${flat.setName}__${flat.sequenceId}`),
+ ),
+ ];
+ if (flatSetNameSequenceIds.length === 0) {
+ throw new Error(`āāāāļø No sequences found for flat ${flatSet}.`);
+ }
- // Dispatch associated flats.
- inputFiles
- .filter(x => x.type === "Flat")
- .forEach(file => {
- if (lightFiles.find(f => matchSetFile(f, file))) {
- copyFileToProject(file);
- importedLightsFlatsFiles.push(file);
- } else {
- logger.info(
- `Skipping ${file.fileName} from the ASIAIR, No light matching.`,
- );
+ if (flatSetNameSequenceIds.length === 1) {
+ // Auto match the flat to the light. Nothing to ask from the user.
+ const flatSetNameSequenceId = flatSetNameSequenceIds[0];
+ const matchingLights = lights.filter(light =>
+ matchSetFile(light, getImageSpecFromSetName(flatSet)),
+ );
+ const matchingLightSetNameSequenceIds = [
+ ...new Set(
+ matchingLights.map(light => `${light.setName}__${light.sequenceId}`),
+ ),
+ ];
+
+ for (const lightSetSequence of matchingLightSetNameSequenceIds) {
+ LightFlatMatches.push({
+ lightSetName: lightSetSequence.split("__")[0],
+ lightSequenceId: lightSetSequence.split("__")[1],
+
+ flatSetName: flatSetNameSequenceId.split("__")[0],
+ flatSequenceId: flatSetNameSequenceId.split("__")[1],
+
+ isManualMatch: false,
+ });
}
- });
+ continue;
+ }
- // Search for the darks and biases we need to copy.
- const bankFiles = getFitsFromDirectory({
- directory: bankDirectory,
- projectDirectory,
- });
- logger.info(`Found ${bankFiles.length} files in the bank.`);
- bankFiles.forEach(file => {
- // Check if the file is needed from the bank.
- if (importedLightsFlatsFiles.find(f => matchSetFile(f, file))) {
- copyFileToProject(file);
- importedDarksBiasesFiles.push(file);
- } else {
- logger.debug(`Skipping ${file.fileName} from the bank, not needed.`);
+ logger.info(`š¤ Several sequences found for flat set ${flatSet}:`);
+ logger.info(
+ `${flatSetNameSequenceIds.map(x => `- ${x.split("__")[1]}`).join("\n")}`,
+ );
+ logger.debug(
+ "We assume that multiple sequences of the same flat set indicate multiple night sessions where the flats had to be re-shot in between (e.g., a significant date gap between shooting sessions and the lights were not collected with the same collimation and/or same dust in the optical train).",
+ );
+ logger.info(
+ "We will ask you to tag each concerned light sequence to the right flat sequence.",
+ );
+
+ // TODO. Provide a smart way to match the sequences.
+ // E.G Flats always before / after lights.
+ // Propose the choice manual / auto (light before flats) / auto (flats before lights).
+ // show the summary for auto, and ask if needs to be reviewed in manual mode.
+
+ const lightsConcerned = [
+ ...new Set(
+ lights
+ .filter(light =>
+ matchSetFile(light, getImageSpecFromSetName(flatSet)),
+ )
+ .map(light => ({
+ setName: light.setName,
+ sequenceId: light.sequenceId,
+ }))
+ .sort((a, b) => {
+ return a.sequenceId.localeCompare(b.sequenceId);
+ })
+ .map(light => `${light.setName}__${light.sequenceId}`),
+ ),
+ ];
+
+ for (const lightConcerned of lightsConcerned) {
+ const lightConcernedSetName = lightConcerned.split("__")[0];
+ const lightConcernedSequenceId = lightConcerned.split("__")[1];
+
+ const response = (await enquirer.prompt({
+ type: "select",
+ name: "selectedFlatSequence",
+ message: formatMessage(
+ `${lightConcernedSetName} ${lightConcernedSequenceId} will use`,
+ ),
+ choices: flatSetNameSequenceIds.map(x => ({
+ name: x,
+ message: formatMessage(x.replace("__", " ")),
+ })),
+ })) as { selectedFlatSequence: string };
+
+ LightFlatMatches.push({
+ lightSetName: lightConcernedSetName,
+ lightSequenceId: lightConcernedSequenceId,
+
+ flatSetName: response.selectedFlatSequence.split("__")[0],
+ flatSequenceId: response.selectedFlatSequence.split("__")[1],
+
+ isManualMatch: true,
+ });
}
- });
+ }
- // TODO. Extract below to a new isolated stats function.
+ logger.space();
+ logger.info("š Light - Flat matching summary:");
+ for (const pair of LightFlatMatches) {
+ logger.debug(
+ `- ${pair.lightSetName} ${pair.lightSequenceId} š¹ ${pair.flatSetName} ${pair.flatSequenceId}`,
+ );
+ }
+
+ return LightFlatMatches;
+};
+
+/**
+ * Initialize the layer sets with lights and flats matches.
+ *
+ * @param lightsFlatsMatches - The lights and flats matches.
+ * @param allLights - All the lights.
+ * @param allFlatsMatchingLights - All the flats matching lights.
+ */
+const initLayerSetsWithLightsnFlats = (
+ lightsFlatsMatches: LightsFlatsMatch[],
+ allLights: FileImageSpec[],
+ allFlatsMatchingLights: FileImageSpec[],
+): LayerSet[] => {
+ const layerSets: LayerSet[] = [];
+
+ for (const lightsFlatsMatch of lightsFlatsMatches) {
+ const lights = lightsFlatsMatch.isManualMatch
+ ? allLights.filter(
+ light =>
+ light.sequenceId === lightsFlatsMatch.lightSequenceId &&
+ light.setName === lightsFlatsMatch.lightSetName,
+ )
+ : allLights.filter(
+ light => light.setName === lightsFlatsMatch.lightSetName,
+ );
+ if (!lights) {
+ throw new Error(
+ `āāāāļø Light ${lightsFlatsMatch.lightSetName} ${lightsFlatsMatch.lightSequenceId} not found.`,
+ );
+ }
- // Check that there's flat, darks and biases for each sets.
- const files = [...importedLightsFlatsFiles, ...importedDarksBiasesFiles];
- const flatFiles = files.filter(file => file.type === "Flat");
- const darkFiles = files.filter(file => file.type === "Dark");
- const biasFiles = files.filter(file => file.type === "Bias");
+ const flats = allFlatsMatchingLights.filter(
+ flat => flat.sequenceId === lightsFlatsMatch.flatSequenceId,
+ );
+ if (!flats) {
+ throw new Error(
+ `āāāāļø Flat ${lightsFlatsMatch.lightSetName} ${lightsFlatsMatch.flatSequenceId} not found.`,
+ );
+ }
- const layerSets = [
- ...new Set(
- files.filter(file => file.type === "Light").map(file => file.setName),
- ),
- ].map(layerSetName => {
- const setSpecs = getImageSpecFromSetName(layerSetName);
+ const layerSetId = lightsFlatsMatch.isManualMatch
+ ? `${lights[0].setName}__${lights[0].sequenceId}`
+ : lights[0].setName;
+
+ const lightSequenceIds = new Set(
+ [...lights].map(light => light.sequenceId),
+ );
+ const lightSequences: LayerSet["lightSequences"] = [];
+ for (const lightSequenceId of lightSequenceIds) {
+ const lightsOfSequence = lights.filter(
+ light => light.sequenceId === lightSequenceId,
+ );
+
+ const count = lightsOfSequence.length;
+ const integrationMs = lightsOfSequence.reduce(
+ (total, light) => total + light.bulbMs,
+ 0,
+ );
+ lightSequences.push({
+ sequenceId: lightSequenceId,
+ count,
+ integrationMinutes: integrationMs / 1000 / 60,
+ });
+ }
+
+ const lightTotalIntegrationMs = lights.reduce(
+ (total, light) => total + light.bulbMs,
+ 0,
+ );
const layerSet = {
- filter: setSpecs.filter,
- lightSet: layerSetName,
- // TODO. Refactor to use the filter function here too. Or store the decision previously made (during the bank selection) to reuse it here.
- // The core issue is that we kinda recompute the same thing twice when importing files + when generating the poto project file.
- lights: lightFiles.filter(file => file.setName === layerSetName),
- darks: darkFiles.filter(
- file =>
- file.bin === setSpecs.bin &&
- file.gain === setSpecs.gain &&
- file.bulb === setSpecs.bulb,
- ),
- flats: flatFiles.filter(
- file => file.bin === setSpecs.bin && file.filter === setSpecs.filter,
- ),
+ layerSetId,
+ filter: lights[0].filter,
+
+ lightSequences,
+ lightTotalCount: lights.length,
+ lightTotalIntegrationMinutes: lightTotalIntegrationMs / 1000 / 60,
+ lights,
+
+ flatSet: flats[0].setName,
+ flatSequenceId: flats[0].sequenceId,
+ flatsCount: flats.length,
+ flats,
} as LayerSet;
- const biases = biasFiles.filter(
- file =>
- file.bin === (layerSet.flats[0]?.bin ?? undefined) &&
- file.gain === (layerSet.flats[0]?.gain ?? undefined),
+ layerSets.push(layerSet);
+ }
+ return layerSets;
+};
+
+/**
+ * Retrieve all FITS files from the input directories.
+ *
+ * @param bankDirectory - The directory where ASIAIR files are stored.
+ * @param projectDirectory - The directory of the current project.
+ * @returns An array of FileImageSpec objects representing the FITS files.
+ */
+const getAllFitsInBankDirectories = (
+ bankDirectory: string,
+ projectDirectory: string,
+): FileImageSpec[] => {
+ // TODO. Allow multiple directories in input.
+ const files = getFitsFromDirectory({
+ directory: bankDirectory,
+ projectDirectory,
+ });
+ logger.info(`Found ${files.length} files in the bank.`);
+ return files;
+};
+
+/**
+ * Assign darks and biases to the layer sets.
+ * We darks are assigned to lights, and biases are assigned to flats.
+ *
+ * @param layerSets - The layer sets with lights and flats filled in.
+ * @param bankFiles - The bank files available.
+ */
+const AssignDarksBiasesToLayerSets = (
+ layerSets: LayerSet[],
+ bankFiles: FileImageSpec[],
+): LayerSet[] => {
+ for (const layerSet of layerSets) {
+ const darks = bankFiles.filter(
+ dark => dark.type === "Dark" && matchSetFile(layerSet.lights[0], dark),
);
- return {
- filter: layerSet.filter,
+ if (darks.length === 0) {
+ logger.error(`No darks found for ${layerSet.lights[0].setName}.`);
+ } else {
+ layerSet.darkSet = darks[0].setName;
+ layerSet.darksCount = darks.length;
+ layerSet.darks = darks;
+ }
- lightSet: layerSet.lightSet,
- flatSet: layerSet.flats[0]?.setName ?? undefined,
- darkSet: layerSet.darks[0]?.setName ?? undefined,
- biasSet: biases[0]?.setName ?? undefined,
+ const biases = bankFiles.filter(
+ bias => bias.type === "Bias" && matchSetFile(layerSet.flats[0], bias),
+ );
- lightsCount: layerSet.lights.length,
- flatsCount: layerSet.flats.length,
- darksCount: layerSet.darks.length,
- biasesCount: biases.length,
+ if (biases.length === 0) {
+ logger.error(`No biases found for ${layerSet.flats[0].setName}.`);
+ } else {
+ layerSet.biasSet = biases[0].setName;
+ layerSet.biasesCount = biases.length;
+ layerSet.biases = biases;
+ }
- lights: layerSet.lights,
- darks: layerSet.darks,
- flats: layerSet.flats,
- biases,
- } as LayerSet;
- });
+ // Warn if there are multiple sequences for the same layer set
+ const darkSequences = new Set(darks.map(dark => dark.sequenceId));
+ if (darkSequences.size > 1) {
+ logger.warning(
+ `Multiple dark sequences found for ${layerSet.lights[0].setName}: ${[
+ ...darkSequences,
+ ].join(", ")}`,
+ );
+ logger.warning(
+ "Gathering them all for the master dark. Make sure that's what you want.",
+ );
+ }
+ const biasSequences = new Set(biases.map(bias => bias.sequenceId));
+ if (biasSequences.size > 1) {
+ logger.warning(
+ `Multiple bias sequences found for ${layerSet.flats[0].setName}: ${[
+ ...biasSequences,
+ ].join(", ")}`,
+ );
+ logger.warning(
+ "Gathering them all for the master flat. Make sure that's what you want.",
+ );
+ }
+ }
+
+ return layerSets;
+};
+
+/**
+ * Preview the project composition before dispatching.
+ *
+ * @param layerSets - The layer sets to preview.
+ */
+const previewBeforeDispatching = async (layerSets: LayerSet[]) => {
logger.info(
- `š Project size: ${layerSets.reduce(
- (total, layerSet) => total + layerSet.flatsCount,
+ `š Cumulated light integration: ${layerSets.reduce(
+ (total, layerSet) => total + layerSet.lightTotalIntegrationMinutes,
+ 0,
+ )} minutes.`,
+ );
+ logger.info(
+ `š¦ Project size: ${layerSets.reduce(
+ (total, layerSet) => total + layerSet.lightTotalCount,
0,
)} lights, ${layerSets.reduce(
(total, layerSet) => total + layerSet.darksCount,
@@ -171,67 +512,62 @@ const dispatch = async ({
)} biases.`,
);
+ logger.space();
+
+ logger.info("š Layer sets:");
for (const layerSet of layerSets) {
- const log = ` š Set ${layerSet.lightSet} has ${layerSet.lights.length} lights, ${layerSet.darks.length} darks, ${layerSet.flats.length} flats, ${layerSet.biases.length} biases.`;
+ const log = `- ${layerSet.layerSetId} has ${layerSet.lights.length} lights, ${layerSet.darks.length} darks, ${layerSet.flats.length} flats, ${layerSet.biases.length} biases.`;
if (
layerSet.lights.length > 0 &&
layerSet.flats.length > 0 &&
layerSet.darks.length > 0 &&
layerSet.biases.length > 0
) {
- logger.info(log);
+ logger.debug(log);
} else {
logger.warning(log);
}
}
- const potoProject: PotoProject = {
- generatedAt: new Date(),
- potoVersion: "0.1.0",
- layerSets,
- };
+ logger.space();
- const potoJsonPath = `${projectDirectory}/${POTO_JSON}`;
-
- fs.writeFileSync(potoJsonPath, JSON.stringify(potoProject, null, 2));
+ const response = (await enquirer.prompt({
+ type: "confirm",
+ name: "go",
+ message: "Do you want to proceed with the dispatch?",
+ })) as { go: boolean };
- logger.success(`Dispatch done ā
. ${POTO_JSON} generated š.`);
+ return response.go;
};
-export default dispatch;
-
/**
- * Ensure that the project directory exists.
- * If it does not exist, ask the user if they want to create it.
+ * Dispatch the project json and the files to the poto project directory.
+ *
+ * @param potoProject - The POTO project to dispatch.
+ * @param projectDirectory - The project directory.
*/
-const ensureProjectDirectoryExists = async (projectDirectory: string) => {
- if (!fs.existsSync(projectDirectory)) {
- const enquirer = new Enquirer();
- const response = (await enquirer.prompt({
- type: "confirm",
- name: "createProjectDirectory",
- message: `Directory ${projectDirectory} does not exist. Do you want to create it?`,
- })) as { createProjectDirectory: boolean };
+const dispatchProject = (
+ potoProject: PotoProject,
+ projectDirectory: string,
+): void => {
+ const potoJsonPath = `${projectDirectory}/${POTO_JSON}`;
- if (response.createProjectDirectory) {
- fs.mkdirSync(projectDirectory, { recursive: true });
+ fs.writeFileSync(potoJsonPath, JSON.stringify(potoProject, null, 2));
+
+ for (const layerSet of potoProject.layerSets) {
+ for (const file of [
+ ...layerSet.lights,
+ ...layerSet.darks,
+ ...layerSet.flats,
+ ...layerSet.biases,
+ ]) {
+ copyFileToProject(file);
}
}
};
-// TODO. Decouple from ASIAIR. Just warn if files both found in Autorun and Plan, and ask the user to probably review the input files first.
-// TODO. Allow multiple directories in input.
-const getAllFitsInInputDirectories = (
- asiAirDirectory: string,
- shootingMode: string,
- projectDirectory: string,
-) => {
- const files = getFitsFromDirectory({
- directory: `${asiAirDirectory}/${
- shootingMode === "autorun" ? "Autorun" : "Plan"
- }`,
- projectDirectory,
- });
- logger.info(`Found ${files.length} files to dispatch.`);
- return files;
-};
+// TODO. Enrich dataset 1 for a layerset with a missing dark.
+// TODO. Create a dataset 1 Light D (exact same as Light A, but another sequence, to be matched with another flat sequence).
+// TODO. Enrich dataset 1 for a layerset with a missing flat.
+// TODO. Enrich dataset 1 for a layerset with multiple dark sequences
+// or in separated dataset TBD.
diff --git a/src/commands/generate-scripts.ts b/src/commands/generate-scripts.ts
index 32b65d4..8849d6c 100644
--- a/src/commands/generate-scripts.ts
+++ b/src/commands/generate-scripts.ts
@@ -50,14 +50,14 @@ const generateScriptForLightSet = (
const anyDirectory = path.join(projectDirectory, "any");
const processDirectory = path.join(
filterDirectory,
- `${set.lightSet}_process`,
+ `${set.layerSetId}_process`,
);
if (!fs.existsSync(processDirectory)) {
fs.mkdirSync(processDirectory, { recursive: false });
}
const mastersDirectory = path.join(
filterDirectory,
- `${set.lightSet}_masters`,
+ `${set.layerSetId}_masters`,
);
if (!fs.existsSync(mastersDirectory)) {
fs.mkdirSync(mastersDirectory, { recursive: false });
@@ -73,7 +73,7 @@ const generateScriptForLightSet = (
// TODO. Move checkers to dispatch-dump.
const lightsdirs = [...new Set(set.lights.map(x => x.projectDirectory))];
if (lightsdirs.length === 0) {
- throw new Error("No lights found for filter " + set.lightSet);
+ throw new Error("No lights found for filter " + set.layerSetId);
}
if (lightsdirs.length > 1) {
logger.errorThrow("Multiple sets of light for ", lightsdirs);
@@ -82,28 +82,28 @@ const generateScriptForLightSet = (
const flatsDirs = [...new Set(set.flats.map(x => x.projectDirectory))];
if (flatsDirs.length === 0) {
- throw new Error("No flats found for filter " + set.lightSet);
+ throw new Error("No flats found for filter " + set.layerSetId);
}
if (flatsDirs.length > 1) {
- throw new Error("Multiple sets of flat for " + set.lightSet);
+ throw new Error("Multiple sets of flat for " + set.layerSetId);
}
const flatsDir = flatsDirs[0];
const darksDirs = [...new Set(set.darks.map(x => x.projectDirectory))];
if (darksDirs.length === 0) {
- throw new Error("No darks found for filter " + set.lightSet);
+ throw new Error("No darks found for filter " + set.layerSetId);
}
if (darksDirs.length > 1) {
- throw new Error("Multiple sets of darks for " + set.lightSet);
+ throw new Error("Multiple sets of darks for " + set.layerSetId);
}
const darksDir = darksDirs[0];
const biasesDirs = [...new Set(set.biases.map(x => x.projectDirectory))];
if (biasesDirs.length === 0) {
- throw new Error("No biases found for filter " + set.lightSet);
+ throw new Error("No biases found for filter " + set.layerSetId);
}
if (biasesDirs.length > 1) {
- throw new Error("Multiple sets of biases for " + set.lightSet);
+ throw new Error("Multiple sets of biases for " + set.layerSetId);
}
const biasesDir = biasesDirs[0];
diff --git a/src/poto-siril.ts b/src/poto-siril.ts
index 8a24239..4ed6077 100644
--- a/src/poto-siril.ts
+++ b/src/poto-siril.ts
@@ -6,13 +6,14 @@ import {
} from "./commands/asiair-dump-cleaning";
import { generateScripts } from "./commands/generate-scripts";
import { runScripts } from "./commands/run-scripts";
+import { POTO_VERSION } from "./utils/const";
const program = new Command();
program
.name("poto-siril")
.description("CLI to some ASIAIR import and SIRIL processing")
- .version("0.1.0");
+ .version(POTO_VERSION);
// const parseMode = (value: string, previous: string) => {
// if (value != "autorun" && value != "plan") {
diff --git a/src/tests/e2e/__snapshots__/e2e-testing.spec.ts.snap b/src/tests/e2e/__snapshots__/e2e-testing.spec.ts.snap
index e95a243..93e6a24 100644
--- a/src/tests/e2e/__snapshots__/e2e-testing.spec.ts.snap
+++ b/src/tests/e2e/__snapshots__/e2e-testing.spec.ts.snap
@@ -3,229 +3,26 @@
exports[`E2E should be neat 2`] = `
"{
"generatedAt": "2024-10-15T00:00:00.000Z",
- "potoVersion": "0.1.0",
+ "potoVersion": "0.2.0",
"layerSets": [
{
- "filter": "S",
- "lightSet": "Light_120.0s_Bin1_S_gain0",
- "flatSet": "Flat_1.0ms_Bin1_S_gain100",
- "darkSet": "Dark_120.0s_Bin1_L_gain0",
- "biasSet": "Bias_1.0ms_Bin1_gain100",
- "lightsCount": 1,
- "flatsCount": 6,
- "darksCount": 1,
- "biasesCount": 3,
- "lights": [
- {
- "setName": "Light_120.0s_Bin1_S_gain0",
- "type": "Light",
- "bulb": "120.0s",
- "bin": "Bin1",
- "filter": "S",
- "gain": 0,
- "sequenceId": "20240626-010850",
- "sequencePosition": 1,
- "datetime": "2024-06-26T01:08:50.000Z",
- "temperature": "-10.1C",
- "fileName": "Light_FOV_120.0s_Bin1_S_gain0_20240626-010850_-10.1C_0001.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/asiair-dump/Autorun/Light/FOV",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_120.0s_Bin1_S_gain0_20240626-010850_-10.1C_0001.fit",
- "projectDirectory": "tmp/project/S/Light_120.0s_Bin1_S_gain0"
- }
- ],
- "darks": [
- {
- "setName": "Dark_120.0s_Bin1_L_gain0",
- "type": "Dark",
- "bulb": "120.0s",
- "bin": "Bin1",
- "filter": "L",
- "gain": 0,
- "sequenceId": "20240308-155722",
- "sequencePosition": 1,
- "datetime": "2024-03-08T15:57:22.000Z",
- "temperature": "-10.0C",
- "fileName": "Dark_120.0s_Bin1_L_gain0_20240308-155722_-10.0C_0001.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/bank/Darks",
- "sourceFilePath": "tmp/bank/Darks/Dark_120.0s_Bin1_L_gain0_20240308-155722_-10.0C_0001.fit",
- "projectDirectory": "tmp/project/any/Dark_120.0s_Bin1_gain0"
- }
- ],
- "flats": [
- {
- "setName": "Flat_1.0ms_Bin1_S_gain100",
- "type": "Flat",
- "bulb": "1.0ms",
- "bin": "Bin1",
- "filter": "S",
- "gain": 100,
- "sequenceId": "20240624-094304",
- "sequencePosition": 1,
- "datetime": "2024-06-24T09:43:04.000Z",
- "temperature": "-10.5C",
- "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit",
- "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
- },
- {
- "setName": "Flat_1.0ms_Bin1_S_gain100",
- "type": "Flat",
- "bulb": "1.0ms",
- "bin": "Bin1",
- "filter": "S",
- "gain": 100,
- "sequenceId": "20240624-094304",
- "sequencePosition": 2,
- "datetime": "2024-06-24T09:43:05.000Z",
- "temperature": "-10.0C",
- "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit",
- "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
- },
- {
- "setName": "Flat_1.0ms_Bin1_S_gain100",
- "type": "Flat",
- "bulb": "1.0ms",
- "bin": "Bin1",
- "filter": "S",
- "gain": 100,
- "sequenceId": "20240624-094304",
- "sequencePosition": 3,
- "datetime": "2024-06-24T09:43:06.000Z",
- "temperature": "-10.5C",
- "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit",
- "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
- },
- {
- "setName": "Flat_1.0ms_Bin1_S_gain100",
- "type": "Flat",
- "bulb": "1.0ms",
- "bin": "Bin1",
- "filter": "S",
- "gain": 100,
- "sequenceId": "20240626-094304",
- "sequencePosition": 1,
- "datetime": "2024-06-26T09:43:04.000Z",
- "temperature": "-10.5C",
- "fileName": "Flat_1.0ms_Bin1_S_gain100_20240626-094304_-10.5C_0001.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240626-094304_-10.5C_0001.fit",
- "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
- },
- {
- "setName": "Flat_1.0ms_Bin1_S_gain100",
- "type": "Flat",
- "bulb": "1.0ms",
- "bin": "Bin1",
- "filter": "S",
- "gain": 100,
- "sequenceId": "20240626-094304",
- "sequencePosition": 2,
- "datetime": "2024-06-26T09:43:05.000Z",
- "temperature": "-10.0C",
- "fileName": "Flat_1.0ms_Bin1_S_gain100_20240626-094305_-10.0C_0002.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240626-094305_-10.0C_0002.fit",
- "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
- },
+ "layerSetId": "Light_60.0s_Bin1_H_gain0",
+ "filter": "H",
+ "lightSequences": [
{
- "setName": "Flat_1.0ms_Bin1_S_gain100",
- "type": "Flat",
- "bulb": "1.0ms",
- "bin": "Bin1",
- "filter": "S",
- "gain": 100,
- "sequenceId": "20240626-094304",
- "sequencePosition": 3,
- "datetime": "2024-06-26T09:43:06.000Z",
- "temperature": "-10.5C",
- "fileName": "Flat_1.0ms_Bin1_S_gain100_20240626-094306_-10.5C_0003.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240626-094306_-10.5C_0003.fit",
- "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
+ "sequenceId": "20240625-010850",
+ "count": 3,
+ "integrationMinutes": 3
}
],
- "biases": [
- {
- "setName": "Bias_1.0ms_Bin1_gain100",
- "type": "Bias",
- "bulb": "1.0ms",
- "bin": "Bin1",
- "filter": null,
- "gain": 100,
- "sequenceId": "20230910-101133",
- "sequencePosition": 1,
- "datetime": "2023-09-10T10:11:33.000Z",
- "temperature": "-9.8C",
- "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/bank/Bias",
- "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit",
- "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100"
- },
- {
- "setName": "Bias_1.0ms_Bin1_gain100",
- "type": "Bias",
- "bulb": "1.0ms",
- "bin": "Bin1",
- "filter": null,
- "gain": 100,
- "sequenceId": "20230910-101133",
- "sequencePosition": 2,
- "datetime": "2023-09-10T10:11:33.000Z",
- "temperature": "-9.8C",
- "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/bank/Bias",
- "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit",
- "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100"
- },
- {
- "setName": "Bias_1.0ms_Bin1_gain100",
- "type": "Bias",
- "bulb": "1.0ms",
- "bin": "Bin1",
- "filter": null,
- "gain": 100,
- "sequenceId": "20230910-101133",
- "sequencePosition": 3,
- "datetime": "2023-09-10T10:11:33.000Z",
- "temperature": "-9.8C",
- "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/bank/Bias",
- "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit",
- "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100"
- }
- ]
- },
- {
- "filter": "H",
- "lightSet": "Light_60.0s_Bin1_H_gain0",
- "flatSet": "Flat_1.0ms_Bin1_H_gain100",
- "darkSet": "Dark_60.0s_Bin1_gain0",
- "biasSet": "Bias_1.0ms_Bin1_gain100",
- "lightsCount": 3,
- "flatsCount": 3,
- "darksCount": 1,
- "biasesCount": 3,
+ "lightTotalCount": 3,
+ "lightTotalIntegrationMinutes": 3,
"lights": [
{
"setName": "Light_60.0s_Bin1_H_gain0",
"type": "Light",
"bulb": "60.0s",
+ "bulbMs": 60000,
"bin": "Bin1",
"filter": "H",
"gain": 0,
@@ -243,6 +40,7 @@ exports[`E2E should be neat 2`] = `
"setName": "Light_60.0s_Bin1_H_gain0",
"type": "Light",
"bulb": "60.0s",
+ "bulbMs": 60000,
"bin": "Bin1",
"filter": "H",
"gain": 0,
@@ -260,6 +58,7 @@ exports[`E2E should be neat 2`] = `
"setName": "Light_60.0s_Bin1_H_gain0",
"type": "Light",
"bulb": "60.0s",
+ "bulbMs": 60000,
"bin": "Bin1",
"filter": "H",
"gain": 0,
@@ -274,30 +73,15 @@ exports[`E2E should be neat 2`] = `
"projectDirectory": "tmp/project/H/Light_60.0s_Bin1_H_gain0"
}
],
- "darks": [
- {
- "setName": "Dark_60.0s_Bin1_gain0",
- "type": "Dark",
- "bulb": "60.0s",
- "bin": "Bin1",
- "filter": null,
- "gain": 0,
- "sequenceId": "20240308-155722",
- "sequencePosition": 1,
- "datetime": "2024-03-08T15:57:22.000Z",
- "temperature": "-10.0C",
- "fileName": "Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit",
- "extension": "fit",
- "sourceDirectory": "tmp/bank/Darks",
- "sourceFilePath": "tmp/bank/Darks/Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit",
- "projectDirectory": "tmp/project/any/Dark_60.0s_Bin1_gain0"
- }
- ],
+ "flatSet": "Flat_1.0ms_Bin1_H_gain100",
+ "flatSequenceId": "20240511-094306",
+ "flatsCount": 3,
"flats": [
{
"setName": "Flat_1.0ms_Bin1_H_gain100",
"type": "Flat",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": "H",
"gain": 100,
@@ -315,80 +99,109 @@ exports[`E2E should be neat 2`] = `
"setName": "Flat_1.0ms_Bin1_H_gain100",
"type": "Flat",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": "H",
"gain": 100,
"sequenceId": "20240511-094306",
"sequencePosition": 2,
- "datetime": "2024-05-11T09:43:06.000Z",
+ "datetime": "2024-05-11T09:43:07.000Z",
"temperature": "-10.5C",
- "fileName": "Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0002.fit",
+ "fileName": "Flat_1.0ms_Bin1_H_gain100_20240511-094307_-10.5C_0002.fit",
"extension": "fit",
"sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0002.fit",
+ "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094307_-10.5C_0002.fit",
"projectDirectory": "tmp/project/H/Flat_1.0ms_Bin1_H_gain100"
},
{
"setName": "Flat_1.0ms_Bin1_H_gain100",
"type": "Flat",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": "H",
"gain": 100,
"sequenceId": "20240511-094306",
"sequencePosition": 3,
- "datetime": "2024-05-11T09:43:06.000Z",
+ "datetime": "2024-05-11T09:43:08.000Z",
"temperature": "-10.5C",
- "fileName": "Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0003.fit",
+ "fileName": "Flat_1.0ms_Bin1_H_gain100_20240511-094308_-10.5C_0003.fit",
"extension": "fit",
"sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0003.fit",
+ "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094308_-10.5C_0003.fit",
"projectDirectory": "tmp/project/H/Flat_1.0ms_Bin1_H_gain100"
}
],
+ "darkSet": "Dark_60.0s_Bin1_gain0",
+ "darksCount": 1,
+ "darks": [
+ {
+ "setName": "Dark_60.0s_Bin1_gain0",
+ "type": "Dark",
+ "bulb": "60.0s",
+ "bulbMs": 60000,
+ "bin": "Bin1",
+ "filter": null,
+ "gain": 0,
+ "sequenceId": "20240308-155722",
+ "sequencePosition": 1,
+ "datetime": "2024-03-08T15:57:22.000Z",
+ "temperature": "-10.0C",
+ "fileName": "Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit",
+ "extension": "fit",
+ "sourceDirectory": "tmp/bank/Darks",
+ "sourceFilePath": "tmp/bank/Darks/Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit",
+ "projectDirectory": "tmp/project/any/Dark_60.0s_Bin1_gain0"
+ }
+ ],
+ "biasSet": "Bias_1.0ms_Bin1_gain100",
+ "biasesCount": 3,
"biases": [
{
"setName": "Bias_1.0ms_Bin1_gain100",
"type": "Bias",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": null,
"gain": 100,
- "sequenceId": "20230910-101133",
+ "sequenceId": "20230910-101131",
"sequencePosition": 1,
- "datetime": "2023-09-10T10:11:33.000Z",
+ "datetime": "2023-09-10T10:11:31.000Z",
"temperature": "-9.8C",
- "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit",
+ "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit",
"extension": "fit",
"sourceDirectory": "tmp/bank/Bias",
- "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit",
+ "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit",
"projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100"
},
{
"setName": "Bias_1.0ms_Bin1_gain100",
"type": "Bias",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": null,
"gain": 100,
- "sequenceId": "20230910-101133",
+ "sequenceId": "20230910-101131",
"sequencePosition": 2,
- "datetime": "2023-09-10T10:11:33.000Z",
+ "datetime": "2023-09-10T10:11:32.000Z",
"temperature": "-9.8C",
- "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit",
+ "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit",
"extension": "fit",
"sourceDirectory": "tmp/bank/Bias",
- "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit",
+ "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit",
"projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100"
},
{
"setName": "Bias_1.0ms_Bin1_gain100",
"type": "Bias",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": null,
"gain": 100,
- "sequenceId": "20230910-101133",
+ "sequenceId": "20230910-101131",
"sequencePosition": 3,
"datetime": "2023-09-10T10:11:33.000Z",
"temperature": "-9.8C",
@@ -401,73 +214,140 @@ exports[`E2E should be neat 2`] = `
]
},
{
+ "layerSetId": "Light_60.0s_Bin1_S_gain100__20240624-010840",
"filter": "S",
- "lightSet": "Light_60.0s_Bin1_S_gain100",
- "flatSet": "Flat_1.0ms_Bin1_S_gain100",
- "darkSet": "Dark_60.0s_Bin1_L_gain100",
- "biasSet": "Bias_1.0ms_Bin1_gain100",
- "lightsCount": 3,
- "flatsCount": 6,
- "darksCount": 3,
- "biasesCount": 3,
+ "lightSequences": [
+ {
+ "sequenceId": "20240624-010840",
+ "count": 3,
+ "integrationMinutes": 3
+ }
+ ],
+ "lightTotalCount": 3,
+ "lightTotalIntegrationMinutes": 3,
"lights": [
{
"setName": "Light_60.0s_Bin1_S_gain100",
"type": "Light",
"bulb": "60.0s",
+ "bulbMs": 60000,
"bin": "Bin1",
"filter": "S",
"gain": 100,
- "sequenceId": "20240624-010850",
+ "sequenceId": "20240624-010840",
"sequencePosition": 1,
- "datetime": "2024-06-24T01:08:50.000Z",
+ "datetime": "2024-06-24T01:08:40.000Z",
"temperature": "-10.1C",
- "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010850_-10.1C_0001.fit",
+ "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010840_-10.1C_0001.fit",
"extension": "fit",
"sourceDirectory": "tmp/asiair-dump/Autorun/Light/FOV",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010850_-10.1C_0001.fit",
+ "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010840_-10.1C_0001.fit",
"projectDirectory": "tmp/project/S/Light_60.0s_Bin1_S_gain100"
},
{
"setName": "Light_60.0s_Bin1_S_gain100",
"type": "Light",
"bulb": "60.0s",
+ "bulbMs": 60000,
"bin": "Bin1",
"filter": "S",
"gain": 100,
- "sequenceId": "20240624-010850",
+ "sequenceId": "20240624-010840",
"sequencePosition": 2,
- "datetime": "2024-06-24T01:08:51.000Z",
+ "datetime": "2024-06-24T01:08:41.000Z",
"temperature": "-10.1C",
- "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010851_-10.1C_0002.fit",
+ "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010841_-10.1C_0002.fit",
"extension": "fit",
"sourceDirectory": "tmp/asiair-dump/Autorun/Light/FOV",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010851_-10.1C_0002.fit",
+ "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010841_-10.1C_0002.fit",
"projectDirectory": "tmp/project/S/Light_60.0s_Bin1_S_gain100"
},
{
"setName": "Light_60.0s_Bin1_S_gain100",
"type": "Light",
"bulb": "60.0s",
+ "bulbMs": 60000,
"bin": "Bin1",
"filter": "S",
"gain": 100,
- "sequenceId": "20240624-010850",
+ "sequenceId": "20240624-010840",
"sequencePosition": 3,
- "datetime": "2024-06-24T01:08:52.000Z",
+ "datetime": "2024-06-24T01:08:42.000Z",
"temperature": "-10.1C",
- "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010852_-10.1C_0003.fit",
+ "fileName": "Light_FOV_60.0s_Bin1_S_gain100_20240624-010842_-10.1C_0003.fit",
"extension": "fit",
"sourceDirectory": "tmp/asiair-dump/Autorun/Light/FOV",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010852_-10.1C_0003.fit",
+ "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010842_-10.1C_0003.fit",
"projectDirectory": "tmp/project/S/Light_60.0s_Bin1_S_gain100"
}
],
+ "flatSet": "Flat_1.0ms_Bin1_S_gain100",
+ "flatSequenceId": "20240624-094304",
+ "flatsCount": 3,
+ "flats": [
+ {
+ "setName": "Flat_1.0ms_Bin1_S_gain100",
+ "type": "Flat",
+ "bulb": "1.0ms",
+ "bulbMs": 1,
+ "bin": "Bin1",
+ "filter": "S",
+ "gain": 100,
+ "sequenceId": "20240624-094304",
+ "sequencePosition": 1,
+ "datetime": "2024-06-24T09:43:04.000Z",
+ "temperature": "-10.5C",
+ "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit",
+ "extension": "fit",
+ "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
+ "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit",
+ "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
+ },
+ {
+ "setName": "Flat_1.0ms_Bin1_S_gain100",
+ "type": "Flat",
+ "bulb": "1.0ms",
+ "bulbMs": 1,
+ "bin": "Bin1",
+ "filter": "S",
+ "gain": 100,
+ "sequenceId": "20240624-094304",
+ "sequencePosition": 2,
+ "datetime": "2024-06-24T09:43:05.000Z",
+ "temperature": "-10.0C",
+ "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit",
+ "extension": "fit",
+ "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
+ "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit",
+ "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
+ },
+ {
+ "setName": "Flat_1.0ms_Bin1_S_gain100",
+ "type": "Flat",
+ "bulb": "1.0ms",
+ "bulbMs": 1,
+ "bin": "Bin1",
+ "filter": "S",
+ "gain": 100,
+ "sequenceId": "20240624-094304",
+ "sequencePosition": 3,
+ "datetime": "2024-06-24T09:43:06.000Z",
+ "temperature": "-10.5C",
+ "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit",
+ "extension": "fit",
+ "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
+ "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit",
+ "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
+ }
+ ],
+ "darkSet": "Dark_60.0s_Bin1_L_gain100",
+ "darksCount": 3,
"darks": [
{
"setName": "Dark_60.0s_Bin1_L_gain100",
"type": "Dark",
"bulb": "60.0s",
+ "bulbMs": 60000,
"bin": "Bin1",
"filter": "L",
"gain": 100,
@@ -485,6 +365,7 @@ exports[`E2E should be neat 2`] = `
"setName": "Dark_60.0s_Bin1_L_gain100",
"type": "Dark",
"bulb": "60.0s",
+ "bulbMs": 60000,
"bin": "Bin1",
"filter": "L",
"gain": 100,
@@ -502,6 +383,7 @@ exports[`E2E should be neat 2`] = `
"setName": "Dark_60.0s_Bin1_L_gain100",
"type": "Dark",
"bulb": "60.0s",
+ "bulbMs": 60000,
"bin": "Bin1",
"filter": "L",
"gain": 100,
@@ -516,62 +398,106 @@ exports[`E2E should be neat 2`] = `
"projectDirectory": "tmp/project/any/Dark_60.0s_Bin1_gain100"
}
],
- "flats": [
+ "biasSet": "Bias_1.0ms_Bin1_gain100",
+ "biasesCount": 3,
+ "biases": [
{
- "setName": "Flat_1.0ms_Bin1_S_gain100",
- "type": "Flat",
+ "setName": "Bias_1.0ms_Bin1_gain100",
+ "type": "Bias",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
- "filter": "S",
+ "filter": null,
"gain": 100,
- "sequenceId": "20240624-094304",
+ "sequenceId": "20230910-101131",
"sequencePosition": 1,
- "datetime": "2024-06-24T09:43:04.000Z",
- "temperature": "-10.5C",
- "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit",
+ "datetime": "2023-09-10T10:11:31.000Z",
+ "temperature": "-9.8C",
+ "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit",
"extension": "fit",
- "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit",
- "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
+ "sourceDirectory": "tmp/bank/Bias",
+ "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit",
+ "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100"
},
{
- "setName": "Flat_1.0ms_Bin1_S_gain100",
- "type": "Flat",
+ "setName": "Bias_1.0ms_Bin1_gain100",
+ "type": "Bias",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
- "filter": "S",
+ "filter": null,
"gain": 100,
- "sequenceId": "20240624-094304",
+ "sequenceId": "20230910-101131",
"sequencePosition": 2,
- "datetime": "2024-06-24T09:43:05.000Z",
- "temperature": "-10.0C",
- "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit",
+ "datetime": "2023-09-10T10:11:32.000Z",
+ "temperature": "-9.8C",
+ "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit",
"extension": "fit",
- "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094305_-10.0C_0002.fit",
- "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
+ "sourceDirectory": "tmp/bank/Bias",
+ "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit",
+ "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100"
},
{
- "setName": "Flat_1.0ms_Bin1_S_gain100",
- "type": "Flat",
+ "setName": "Bias_1.0ms_Bin1_gain100",
+ "type": "Bias",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
- "filter": "S",
+ "filter": null,
"gain": 100,
- "sequenceId": "20240624-094304",
+ "sequenceId": "20230910-101131",
"sequencePosition": 3,
- "datetime": "2024-06-24T09:43:06.000Z",
- "temperature": "-10.5C",
- "fileName": "Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit",
+ "datetime": "2023-09-10T10:11:33.000Z",
+ "temperature": "-9.8C",
+ "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit",
"extension": "fit",
- "sourceDirectory": "tmp/asiair-dump/Autorun/Flat",
- "sourceFilePath": "tmp/asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094306_-10.5C_0003.fit",
- "projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
- },
+ "sourceDirectory": "tmp/bank/Bias",
+ "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit",
+ "projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100"
+ }
+ ]
+ },
+ {
+ "layerSetId": "Light_120.0s_Bin1_S_gain0__20240626-010853",
+ "filter": "S",
+ "lightSequences": [
+ {
+ "sequenceId": "20240626-010853",
+ "count": 1,
+ "integrationMinutes": 2
+ }
+ ],
+ "lightTotalCount": 1,
+ "lightTotalIntegrationMinutes": 2,
+ "lights": [
+ {
+ "setName": "Light_120.0s_Bin1_S_gain0",
+ "type": "Light",
+ "bulb": "120.0s",
+ "bulbMs": 120000,
+ "bin": "Bin1",
+ "filter": "S",
+ "gain": 0,
+ "sequenceId": "20240626-010853",
+ "sequencePosition": 1,
+ "datetime": "2024-06-26T01:08:53.000Z",
+ "temperature": "-10.1C",
+ "fileName": "Light_FOV_120.0s_Bin1_S_gain0_20240626-010853_-10.1C_0001.fit",
+ "extension": "fit",
+ "sourceDirectory": "tmp/asiair-dump/Autorun/Light/FOV",
+ "sourceFilePath": "tmp/asiair-dump/Autorun/Light/FOV/Light_FOV_120.0s_Bin1_S_gain0_20240626-010853_-10.1C_0001.fit",
+ "projectDirectory": "tmp/project/S/Light_120.0s_Bin1_S_gain0"
+ }
+ ],
+ "flatSet": "Flat_1.0ms_Bin1_S_gain100",
+ "flatSequenceId": "20240626-094304",
+ "flatsCount": 3,
+ "flats": [
{
"setName": "Flat_1.0ms_Bin1_S_gain100",
"type": "Flat",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": "S",
"gain": 100,
@@ -589,6 +515,7 @@ exports[`E2E should be neat 2`] = `
"setName": "Flat_1.0ms_Bin1_S_gain100",
"type": "Flat",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": "S",
"gain": 100,
@@ -606,6 +533,7 @@ exports[`E2E should be neat 2`] = `
"setName": "Flat_1.0ms_Bin1_S_gain100",
"type": "Flat",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": "S",
"gain": 100,
@@ -620,49 +548,76 @@ exports[`E2E should be neat 2`] = `
"projectDirectory": "tmp/project/S/Flat_1.0ms_Bin1_S_gain100"
}
],
+ "darkSet": "Dark_120.0s_Bin1_L_gain0",
+ "darksCount": 1,
+ "darks": [
+ {
+ "setName": "Dark_120.0s_Bin1_L_gain0",
+ "type": "Dark",
+ "bulb": "120.0s",
+ "bulbMs": 120000,
+ "bin": "Bin1",
+ "filter": "L",
+ "gain": 0,
+ "sequenceId": "20240308-155723",
+ "sequencePosition": 1,
+ "datetime": "2024-03-08T15:57:23.000Z",
+ "temperature": "-10.0C",
+ "fileName": "Dark_120.0s_Bin1_L_gain0_20240308-155723_-10.0C_0001.fit",
+ "extension": "fit",
+ "sourceDirectory": "tmp/bank/Darks",
+ "sourceFilePath": "tmp/bank/Darks/Dark_120.0s_Bin1_L_gain0_20240308-155723_-10.0C_0001.fit",
+ "projectDirectory": "tmp/project/any/Dark_120.0s_Bin1_gain0"
+ }
+ ],
+ "biasSet": "Bias_1.0ms_Bin1_gain100",
+ "biasesCount": 3,
"biases": [
{
"setName": "Bias_1.0ms_Bin1_gain100",
"type": "Bias",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": null,
"gain": 100,
- "sequenceId": "20230910-101133",
+ "sequenceId": "20230910-101131",
"sequencePosition": 1,
- "datetime": "2023-09-10T10:11:33.000Z",
+ "datetime": "2023-09-10T10:11:31.000Z",
"temperature": "-9.8C",
- "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit",
+ "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit",
"extension": "fit",
"sourceDirectory": "tmp/bank/Bias",
- "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit",
+ "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit",
"projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100"
},
{
"setName": "Bias_1.0ms_Bin1_gain100",
"type": "Bias",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": null,
"gain": 100,
- "sequenceId": "20230910-101133",
+ "sequenceId": "20230910-101131",
"sequencePosition": 2,
- "datetime": "2023-09-10T10:11:33.000Z",
+ "datetime": "2023-09-10T10:11:32.000Z",
"temperature": "-9.8C",
- "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit",
+ "fileName": "Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit",
"extension": "fit",
"sourceDirectory": "tmp/bank/Bias",
- "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit",
+ "sourceFilePath": "tmp/bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit",
"projectDirectory": "tmp/project/any/Bias_1.0ms_Bin1_gain100"
},
{
"setName": "Bias_1.0ms_Bin1_gain100",
"type": "Bias",
"bulb": "1.0ms",
+ "bulbMs": 1,
"bin": "Bin1",
"filter": null,
"gain": 100,
- "sequenceId": "20230910-101133",
+ "sequenceId": "20230910-101131",
"sequencePosition": 3,
"datetime": "2023-09-10T10:11:33.000Z",
"temperature": "-9.8C",
@@ -763,8 +718,8 @@ exports[`E2E should be neat 5`] = `
# flats: tmp/project/S/Flat_1.0ms_Bin1_S_gain100/
# darks: tmp/project/any/Dark_120.0s_Bin1_gain0/
# lights: tmp/project/S/Light_120.0s_Bin1_S_gain0/
-# process: tmp/project/S/Light_120.0s_Bin1_S_gain0_process/
-# masters: tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/
+# process: tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process/
+# masters: tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/
#
############################################
@@ -772,38 +727,38 @@ requires 1.2.0
# Convert Bias Frames to .fit files
cd tmp/project/any/Bias_1.0ms_Bin1_gain100
-convert bias -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_process
-cd tmp/project/S/Light_120.0s_Bin1_S_gain0_process
+convert bias -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process
+cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process
# Stack Bias Frames to bias_stacked.fit
-stack bias rej 3 3 -nonorm -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/bias_stacked
+stack bias rej 3 3 -nonorm -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/bias_stacked
# Convert Flat Frames to .fit files
cd tmp/project/S/Flat_1.0ms_Bin1_S_gain100
-convert flat -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_process
-cd tmp/project/S/Light_120.0s_Bin1_S_gain0_process
+convert flat -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process
+cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process
# Calibrate Flat Frames
-calibrate flat -bias=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/bias_stacked
+calibrate flat -bias=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/bias_stacked
# Stack Flat Frames to pp_flat_stacked.fit
-stack pp_flat rej 3 3 -norm=mul -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/pp_flat_stacked
+stack pp_flat rej 3 3 -norm=mul -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/pp_flat_stacked
# Convert Dark Frames to .fit files
cd tmp/project/any/Dark_120.0s_Bin1_gain0
-convert dark -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_process
-cd tmp/project/S/Light_120.0s_Bin1_S_gain0_process
+convert dark -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process
+cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process
# Stack Dark Frames to dark_stacked.fit
-stack dark rej 3 3 -nonorm -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/dark_stacked
+stack dark rej 3 3 -nonorm -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/dark_stacked
# Convert Light Frames to .fit files
cd tmp/project/S/Light_120.0s_Bin1_S_gain0
-convert light -out=tmp/project/S/Light_120.0s_Bin1_S_gain0_process
-cd tmp/project/S/Light_120.0s_Bin1_S_gain0_process
+convert light -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process
+cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process
# Calibrate Light Frames
-calibrate light -dark=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/dark_stacked -flat=tmp/project/S/Light_120.0s_Bin1_S_gain0_masters/pp_flat_stacked -cc=dark
+calibrate light -dark=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/dark_stacked -flat=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/pp_flat_stacked -cc=dark
# Align Lights
register pp_light
@@ -830,8 +785,8 @@ exports[`E2E should be neat 6`] = `
# flats: tmp/project/S/Flat_1.0ms_Bin1_S_gain100/
# darks: tmp/project/any/Dark_60.0s_Bin1_gain100/
# lights: tmp/project/S/Light_60.0s_Bin1_S_gain100/
-# process: tmp/project/S/Light_60.0s_Bin1_S_gain100_process/
-# masters: tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/
+# process: tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process/
+# masters: tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/
#
############################################
@@ -839,38 +794,38 @@ requires 1.2.0
# Convert Bias Frames to .fit files
cd tmp/project/any/Bias_1.0ms_Bin1_gain100
-convert bias -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_process
-cd tmp/project/S/Light_60.0s_Bin1_S_gain100_process
+convert bias -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process
+cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process
# Stack Bias Frames to bias_stacked.fit
-stack bias rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/bias_stacked
+stack bias rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/bias_stacked
# Convert Flat Frames to .fit files
cd tmp/project/S/Flat_1.0ms_Bin1_S_gain100
-convert flat -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_process
-cd tmp/project/S/Light_60.0s_Bin1_S_gain100_process
+convert flat -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process
+cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process
# Calibrate Flat Frames
-calibrate flat -bias=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/bias_stacked
+calibrate flat -bias=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/bias_stacked
# Stack Flat Frames to pp_flat_stacked.fit
-stack pp_flat rej 3 3 -norm=mul -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/pp_flat_stacked
+stack pp_flat rej 3 3 -norm=mul -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/pp_flat_stacked
# Convert Dark Frames to .fit files
cd tmp/project/any/Dark_60.0s_Bin1_gain100
-convert dark -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_process
-cd tmp/project/S/Light_60.0s_Bin1_S_gain100_process
+convert dark -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process
+cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process
# Stack Dark Frames to dark_stacked.fit
-stack dark rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/dark_stacked
+stack dark rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/dark_stacked
# Convert Light Frames to .fit files
cd tmp/project/S/Light_60.0s_Bin1_S_gain100
-convert light -out=tmp/project/S/Light_60.0s_Bin1_S_gain100_process
-cd tmp/project/S/Light_60.0s_Bin1_S_gain100_process
+convert light -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process
+cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process
# Calibrate Light Frames
-calibrate light -dark=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/dark_stacked -flat=tmp/project/S/Light_60.0s_Bin1_S_gain100_masters/pp_flat_stacked -cc=dark
+calibrate light -dark=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/dark_stacked -flat=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/pp_flat_stacked -cc=dark
# Align Lights
register pp_light
diff --git a/src/tests/e2e/e2e-testing.spec.ts b/src/tests/e2e/e2e-testing.spec.ts
index 9d0afc2..2f2996f 100644
--- a/src/tests/e2e/e2e-testing.spec.ts
+++ b/src/tests/e2e/e2e-testing.spec.ts
@@ -1,12 +1,16 @@
import { jest } from "@jest/globals"; // Import Jest globals
import path from "path";
import fs from "fs";
+import Enquirer from "enquirer";
+
import dispatch from "../../commands/dispatch-dump";
import { POTO_JSON } from "../../utils/const";
import { cleanThumbnails } from "../../commands/asiair-dump-cleaning";
import { generateScripts } from "../../commands/generate-scripts";
import { spawnMockedDatasetToFs_dataset_1 } from "../fixtures";
+jest.mock("enquirer");
+
describe("E2E", () => {
let asiAirDirectory: string = "";
let bankDirectory: string = "";
@@ -19,38 +23,56 @@ describe("E2E", () => {
spawnMockedDatasetToFs_dataset_1());
});
- test("should be neat", async () => {
- let files = fs.readdirSync(asiAirDirectory, {
- recursive: true,
- withFileTypes: false,
- encoding: "utf8",
- });
- expect(files.filter(f => f.endsWith("_thn.jpg"))).toHaveLength(3);
-
- cleanThumbnails(asiAirDirectory);
-
- files = fs.readdirSync(asiAirDirectory, {
- recursive: true,
- withFileTypes: false,
- encoding: "utf8",
- });
- expect(files.filter(f => f.endsWith("_thn.jpg"))).toHaveLength(0);
-
- fs.mkdirSync(projectDirectory, { recursive: true });
- await dispatch({
- projectDirectory,
- asiAirDirectory,
- shootingMode: "autorun",
- bankDirectory,
- });
-
- files = fs.readdirSync(projectDirectory, {
- recursive: true,
- withFileTypes: false,
- encoding: "utf8",
- });
-
- expect(files).toMatchInlineSnapshot(`
+ test(
+ "should be neat",
+ async () => {
+ const promptMock = jest.fn();
+ (Enquirer.prototype.prompt as jest.Mock) = promptMock;
+
+ promptMock
+ .mockResolvedValueOnce({
+ createProjectDirectory: true,
+ } as never)
+ .mockResolvedValueOnce({
+ selectedFlatSequence: "Flat_1.0ms_Bin1_S_gain100__20240624-094304",
+ } as never)
+ .mockResolvedValueOnce({
+ selectedFlatSequence: "Flat_1.0ms_Bin1_S_gain100__20240626-094304",
+ } as never)
+ .mockResolvedValueOnce({
+ go: true,
+ } as never);
+
+ let files = fs.readdirSync(asiAirDirectory, {
+ recursive: true,
+ withFileTypes: false,
+ encoding: "utf8",
+ });
+ expect(files.filter(f => f.endsWith("_thn.jpg"))).toHaveLength(3);
+
+ cleanThumbnails(asiAirDirectory);
+
+ files = fs.readdirSync(asiAirDirectory, {
+ recursive: true,
+ withFileTypes: false,
+ encoding: "utf8",
+ });
+ expect(files.filter(f => f.endsWith("_thn.jpg"))).toHaveLength(0);
+
+ await dispatch({
+ projectDirectory,
+ asiAirDirectory,
+ shootingMode: "autorun",
+ bankDirectory,
+ });
+
+ files = fs.readdirSync(projectDirectory, {
+ recursive: true,
+ withFileTypes: false,
+ encoding: "utf8",
+ });
+
+ expect(files).toMatchInlineSnapshot(`
[
"H",
"S",
@@ -66,8 +88,8 @@ describe("E2E", () => {
"any/Dark_60.0s_Bin1_gain0",
"any/Dark_60.0s_Bin1_gain100",
"H/Flat_1.0ms_Bin1_H_gain100/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0001.fit",
- "H/Flat_1.0ms_Bin1_H_gain100/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0002.fit",
- "H/Flat_1.0ms_Bin1_H_gain100/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0003.fit",
+ "H/Flat_1.0ms_Bin1_H_gain100/Flat_1.0ms_Bin1_H_gain100_20240511-094307_-10.5C_0002.fit",
+ "H/Flat_1.0ms_Bin1_H_gain100/Flat_1.0ms_Bin1_H_gain100_20240511-094308_-10.5C_0003.fit",
"H/Light_60.0s_Bin1_H_gain0/Light_FOV_60.0s_Bin1_H_gain0_20240625-010850_-10.1C_0001.fit",
"H/Light_60.0s_Bin1_H_gain0/Light_FOV_60.0s_Bin1_H_gain0_20240625-010851_-10.1C_0002.fit",
"H/Light_60.0s_Bin1_H_gain0/Light_FOV_60.0s_Bin1_H_gain0_20240625-010852_-10.1C_0003.fit",
@@ -77,14 +99,14 @@ describe("E2E", () => {
"S/Flat_1.0ms_Bin1_S_gain100/Flat_1.0ms_Bin1_S_gain100_20240626-094304_-10.5C_0001.fit",
"S/Flat_1.0ms_Bin1_S_gain100/Flat_1.0ms_Bin1_S_gain100_20240626-094305_-10.0C_0002.fit",
"S/Flat_1.0ms_Bin1_S_gain100/Flat_1.0ms_Bin1_S_gain100_20240626-094306_-10.5C_0003.fit",
- "S/Light_120.0s_Bin1_S_gain0/Light_FOV_120.0s_Bin1_S_gain0_20240626-010850_-10.1C_0001.fit",
- "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010850_-10.1C_0001.fit",
- "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010851_-10.1C_0002.fit",
- "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010852_-10.1C_0003.fit",
- "any/Bias_1.0ms_Bin1_gain100/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit",
- "any/Bias_1.0ms_Bin1_gain100/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit",
+ "S/Light_120.0s_Bin1_S_gain0/Light_FOV_120.0s_Bin1_S_gain0_20240626-010853_-10.1C_0001.fit",
+ "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010840_-10.1C_0001.fit",
+ "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010841_-10.1C_0002.fit",
+ "S/Light_60.0s_Bin1_S_gain100/Light_FOV_60.0s_Bin1_S_gain100_20240624-010842_-10.1C_0003.fit",
+ "any/Bias_1.0ms_Bin1_gain100/Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit",
+ "any/Bias_1.0ms_Bin1_gain100/Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit",
"any/Bias_1.0ms_Bin1_gain100/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit",
- "any/Dark_120.0s_Bin1_gain0/Dark_120.0s_Bin1_L_gain0_20240308-155722_-10.0C_0001.fit",
+ "any/Dark_120.0s_Bin1_gain0/Dark_120.0s_Bin1_L_gain0_20240308-155723_-10.0C_0001.fit",
"any/Dark_60.0s_Bin1_gain0/Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit",
"any/Dark_60.0s_Bin1_gain100/Dark_60.0s_Bin1_L_gain100_20240308-155722_-10.0C_0001.fit",
"any/Dark_60.0s_Bin1_gain100/Dark_60.0s_Bin1_L_gain100_20240308-155723_-10.0C_0002.fit",
@@ -92,46 +114,48 @@ describe("E2E", () => {
]
`);
- const potoJson = fs.readFileSync(path.join(projectDirectory, POTO_JSON), {
- encoding: "utf8",
- });
+ const potoJson = fs.readFileSync(path.join(projectDirectory, POTO_JSON), {
+ encoding: "utf8",
+ });
- expect(potoJson).toMatchSnapshot();
+ expect(potoJson).toMatchSnapshot();
- await generateScripts(
- projectDirectory,
- "src/process/mono_processing_process/1_preprocessing.ssf",
- );
+ await generateScripts(
+ projectDirectory,
+ "src/process/mono_processing_process/1_preprocessing.ssf",
+ );
- files = fs.readdirSync(projectDirectory, {
- recursive: true,
- withFileTypes: false,
- encoding: "utf8",
- });
+ files = fs.readdirSync(projectDirectory, {
+ recursive: true,
+ withFileTypes: false,
+ encoding: "utf8",
+ });
- const scripts = files.filter(f => f.endsWith(".ssf"));
- expect(scripts).toHaveLength(3);
- expect(scripts).toMatchInlineSnapshot(`
+ const scripts = files.filter(f => f.endsWith(".ssf"));
+ expect(scripts).toHaveLength(3);
+ expect(scripts).toMatchInlineSnapshot(`
[
"H/Light_60.0s_Bin1_H_gain0_process/poto_1_preprocessing.ssf",
- "S/Light_120.0s_Bin1_S_gain0_process/poto_1_preprocessing.ssf",
- "S/Light_60.0s_Bin1_S_gain100_process/poto_1_preprocessing.ssf",
+ "S/Light_120.0s_Bin1_S_gain0__20240626-010853_process/poto_1_preprocessing.ssf",
+ "S/Light_60.0s_Bin1_S_gain100__20240624-010840_process/poto_1_preprocessing.ssf",
]
`);
- const script1 = fs.readFileSync(path.join(projectDirectory, scripts[0]), {
- encoding: "utf8",
- });
- expect(script1).toMatchSnapshot();
-
- const script2 = fs.readFileSync(path.join(projectDirectory, scripts[1]), {
- encoding: "utf8",
- });
- expect(script2).toMatchSnapshot();
-
- const script3 = fs.readFileSync(path.join(projectDirectory, scripts[2]), {
- encoding: "utf8",
- });
- expect(script3).toMatchSnapshot();
- });
+ const script1 = fs.readFileSync(path.join(projectDirectory, scripts[0]), {
+ encoding: "utf8",
+ });
+ expect(script1).toMatchSnapshot();
+
+ const script2 = fs.readFileSync(path.join(projectDirectory, scripts[1]), {
+ encoding: "utf8",
+ });
+ expect(script2).toMatchSnapshot();
+
+ const script3 = fs.readFileSync(path.join(projectDirectory, scripts[2]), {
+ encoding: "utf8",
+ });
+ expect(script3).toMatchSnapshot();
+ },
+ 30 * 1000,
+ );
});
diff --git a/src/tests/fixtures.ts b/src/tests/fixtures.ts
index bb57f98..e73b582 100644
--- a/src/tests/fixtures.ts
+++ b/src/tests/fixtures.ts
@@ -1,9 +1,11 @@
import path from "path";
import fs from "fs";
+import { logger } from "../utils/logger";
const tmpDir = "tmp";
export const spawnMockedDatasetToFs_dataset_1 = () => {
+ logger.dev("Creating ./tmp directory with dataset_1.");
return spawnMockedDatasetToFs(dataset_1);
};
@@ -32,8 +34,6 @@ const spawnMockedDatasetToFs = (
const bankDirectory = path.join(tmpDir, "bank");
const projectDirectory = path.join(tmpDir, "project");
- console.log("Creating ./tmp directory");
-
return {
directory: tmpDir,
asiAirDirectory,
@@ -50,9 +50,9 @@ const spawnMockedDatasetToFs = (
*/
const dataset_1 = [
// Lights set A (60.0s_Bin1_S_gain100).
- "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010850_-10.1C_0001.fit",
- "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010851_-10.1C_0002.fit",
- "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010852_-10.1C_0003.fit",
+ "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010840_-10.1C_0001.fit",
+ "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010841_-10.1C_0002.fit",
+ "asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_S_gain100_20240624-010842_-10.1C_0003.fit",
// Lights set B (60.0s_Bin1_H_gain0).
"asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_H_gain0_20240625-010850_-10.1C_0001.fit",
@@ -60,7 +60,7 @@ const dataset_1 = [
"asiair-dump/Autorun/Light/FOV/Light_FOV_60.0s_Bin1_H_gain0_20240625-010852_-10.1C_0003.fit",
// Lights set C (120.0s_Bin1_S_gain0).
- "asiair-dump/Autorun/Light/FOV/Light_FOV_120.0s_Bin1_S_gain0_20240626-010850_-10.1C_0001.fit",
+ "asiair-dump/Autorun/Light/FOV/Light_FOV_120.0s_Bin1_S_gain0_20240626-010853_-10.1C_0001.fit",
// Flats matching set A. Flats matching set C.
"asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240624-094304_-10.5C_0001.fit", // Sequence that aims to match the lights set A (collimation of that day).
@@ -72,15 +72,15 @@ const dataset_1 = [
// Flats matching set B.
"asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0001.fit", // Gain 100, but can still matching with lights gain 0!
- "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0002.fit",
- "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0003.fit",
+ "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094307_-10.5C_0002.fit",
+ "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094308_-10.5C_0003.fit",
// Flats not matching any sets.
"asiair-dump/Autorun/Flat/Flat_1.0ms_Bin2_S_gain100_20240511-094304_-10.5C_0001.fit", // Another bin.
"asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_O_gain100_20240511-094305_-10.0C_0002.fit", // Another Filter.
- "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240511-094304_-10.5C_0001.fot", // Not a fit.
+ "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_S_gain100_20240511-094306_-10.5C_0001.fot", // Not a fit file based on extension.
- // Darks matching set A.
+ // Darks matching set A. Not same filter as lights set A, but filter is irrelevant for darks.
"bank/Darks/Dark_60.0s_Bin1_L_gain100_20240308-155722_-10.0C_0001.fit",
"bank/Darks/Dark_60.0s_Bin1_L_gain100_20240308-155723_-10.0C_0002.fit",
"bank/Darks/Dark_60.0s_Bin1_L_gain100_20240308-155724_-10.0C_0003.fit",
@@ -89,25 +89,25 @@ const dataset_1 = [
"bank/Darks/Dark_60.0s_Bin1_gain0_20240308-155722_-10.0C_0001.fit",
// Darks matching set C.
- "bank/Darks/Dark_120.0s_Bin1_L_gain0_20240308-155722_-10.0C_0001.fit",
+ "bank/Darks/Dark_120.0s_Bin1_L_gain0_20240308-155723_-10.0C_0001.fit",
// Darks not matching any sets.
- "bank/Darks/Dark_300.0s_Bin1_L_gain100_20240308-155722_-10.0C_0001.fit", // Another bulb.
- "bank/Darks/Dark_60.0s_Bin2_L_gain100_20240308-155722_-10.0C_0001.fit", // Another bin.
- "bank/Darks/Dark_60.0s_Bin1_L_gain50_20240308-155722_-10.0C_0001.fit", // Another gain.
+ "bank/Darks/Dark_300.0s_Bin1_L_gain100_20240308-155724_-10.0C_0001.fit", // Another bulb.
+ "bank/Darks/Dark_60.0s_Bin2_L_gain100_20240308-155725_-10.0C_0001.fit", // Another bin.
+ "bank/Darks/Dark_60.0s_Bin1_L_gain50_20240308-155726_-10.0C_0001.fit", // Another gain.
// Biases matching set A. Biases matching set C.
// Biases matching set B. Matching with Flat of gain 100, despite lights being gain 0.
- "bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0001.fit",
- "bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0002.fit",
+ "bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101131_-9.8C_0001.fit",
+ "bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit",
"bank/Bias/Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit",
// Biases not matching any sets.
- "bank/Bias/Bias_1.0ms_Bin1_gain0_20230910-101133_-9.8C_0001.fit", // Won't match set B, because flat gain is 100.
- "bank/Bias/Bias_1.0ms_Bin2_gain100_20230910-101133_-9.8C_0002.fit", // Another bin.
+ "bank/Bias/Bias_1.0ms_Bin1_gain0_20230910-101141_-9.8C_0001.fit", // Won't match set B, because flat gain is 100.
+ "bank/Bias/Bias_1.0ms_Bin2_gain100_20230910-101142_-9.8C_0002.fit", // Another bin.
- // thumbnails.
+ // Thumbnails from ASIAIR.
"asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0001_thn.jpg",
- "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0002_thn.jpg",
- "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094306_-10.5C_0003_thn.jpg",
+ "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094307_-10.5C_0002_thn.jpg",
+ "asiair-dump/Autorun/Flat/Flat_1.0ms_Bin1_H_gain100_20240511-094308_-10.5C_0003_thn.jpg",
];
diff --git a/src/utils/const.ts b/src/utils/const.ts
index 5b804a1..f25a19e 100644
--- a/src/utils/const.ts
+++ b/src/utils/const.ts
@@ -1,4 +1,4 @@
-export const POTO_VERSION = "0.1.0";
+export const POTO_VERSION = "0.2.0";
export const POTO_JSON = "poto.json";
diff --git a/src/utils/logger.ts b/src/utils/logger.ts
index fcd272a..637bbbc 100644
--- a/src/utils/logger.ts
+++ b/src/utils/logger.ts
@@ -1,68 +1,73 @@
import chalk from "chalk";
-import ansiEscapes from "ansi-escapes";
-const debug = chalk.gray;
+const debug = chalk.gray.italic;
const info = chalk.blue;
const success = chalk.bold.green;
const warning = chalk.bold.yellow;
const error = chalk.bold.red;
-const logCounts: { [key: string]: number } = {};
-const lastMessages: { [key: string]: string } = {};
-
-const logNR = (
+const log = (
type: (message: string) => string,
message: string,
...optionalParams: unknown[]
) => {
- if (logCounts[message]) {
- logCounts[message]++;
- process.stdout.write(
- ansiEscapes.cursorUp(1) +
- ansiEscapes.eraseLine +
- type(`${message} x${logCounts[message]}`) +
- "\n",
- );
- } else {
- logCounts[message] = 1;
- lastMessages[message] = type(message);
- console.log(type(message), ...optionalParams);
+ console.log(type(message), ...optionalParams);
+};
+
+export const formatMessage = (message: string) => {
+ if (!message) {
+ return message;
}
+
+ return message
+ .replace(/(Light|Flat|Dark|Bias)_/g, chalk.hex("#001f3f")("$1_")) // Color image type.
+ .replace(/(\d+\.\d(ms|s))/g, chalk.hex("#003f5c")("$1")) // Color bulb.
+ .replace(/(Bin\d)/g, chalk.hex("#2f4b7c")("$1")) // Color binning.
+ .replace(/(_[A-Za-z]_)/g, chalk.hex("#665191")("$1")) // Color filter.
+ .replace(/(gain\d+)/g, chalk.hex("#a05195")("$1")) // Color gain.
+ .replace(
+ /(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})(\d{2})/g,
+ (_, y, m, d, h, min, s) =>
+ `${chalk.hex("#d45087")(y)}${chalk.hex("#f95d6a")(m)}${chalk.hex(
+ "#ff7c43",
+ )(d)}-${chalk.hex("#ffa600")(h)}${chalk.hex("#ffb000")(min)}${chalk.hex(
+ "#ffc000",
+ )(s)}`,
+ ) // Adjusted colors for date and time.
+ .replace(/_thn.jpg/g, chalk.bgHex("#ff0000")("_thn.jpg")); // Color thumbnail.
};
export const logger = {
debug: (message: string, ...optionalParams: unknown[]) => {
- console.log(debug(message), ...optionalParams);
+ log(debug, formatMessage(message), ...optionalParams);
},
info: (message: string, ...optionalParams: unknown[]) => {
- console.log(info(message), ...optionalParams);
+ log(info, formatMessage(message), ...optionalParams);
},
success: (message: string, ...optionalParams: unknown[]) => {
- console.log(success(message), ...optionalParams);
+ log(success, formatMessage(message), ...optionalParams);
},
warning: (message: string, ...optionalParams: unknown[]) => {
- console.log(warning(message), ...optionalParams);
+ log(warning, formatMessage(message), ...optionalParams);
},
error: (message: string, ...optionalParams: unknown[]) => {
- console.log(error(message), ...optionalParams);
+ log(error, formatMessage(message), ...optionalParams);
},
errorThrow: (message: string, ...optionalParams: unknown[]) => {
- console.log(error(message), ...optionalParams);
+ log(error, formatMessage(message), ...optionalParams);
throw new Error(message);
},
- debugNR: (message: string, ...optionalParams: unknown[]) => {
- logNR(debug, message, ...optionalParams);
- },
- infoNR: (message: string, ...optionalParams: unknown[]) => {
- logNR(info, message, ...optionalParams);
+ dev: (message: string, ...optionalParams: unknown[]) => {
+ log(debug, `DEV: ${message}`, ...optionalParams);
},
- successNR: (message: string, ...optionalParams: unknown[]) => {
- logNR(success, message, ...optionalParams);
- },
- warningNR: (message: string, ...optionalParams: unknown[]) => {
- logNR(warning, message, ...optionalParams);
+ step: (message: string, ...optionalParams: unknown[]) => {
+ log(
+ info,
+ `\n${"=".repeat(80)}\nš ${message}\n${"=".repeat(80)}\n`,
+ ...optionalParams,
+ );
},
- errorNR: (message: string, ...optionalParams: unknown[]) => {
- logNR(error, message, ...optionalParams);
+ space: () => {
+ console.log();
},
};
diff --git a/src/utils/tests/__snapshots__/utils.spec.ts.snap b/src/utils/tests/__snapshots__/utils.spec.ts.snap
new file mode 100644
index 0000000..cef66ae
--- /dev/null
+++ b/src/utils/tests/__snapshots__/utils.spec.ts.snap
@@ -0,0 +1,64 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`utils getFileImageSpecFromFilename should match snapshot (ASIAIR plan target format) 1`] = `
+{
+ "bin": "Bin1",
+ "bulb": "120.0s",
+ "bulbMs": 120000,
+ "datetime": 2024-07-07T00:23:48.000Z,
+ "extension": "fit",
+ "fileName": "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit",
+ "filter": "H",
+ "gain": 100,
+ "projectDirectory": "project/bar/H/Light_120.0s_Bin1_H_gain100",
+ "sequenceId": "20240707-002348",
+ "sequencePosition": 1,
+ "setName": "Light_120.0s_Bin1_H_gain100",
+ "sourceDirectory": "input/bar",
+ "sourceFilePath": "input/bar/Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit",
+ "temperature": "-10.0C",
+ "type": "Light",
+}
+`;
+
+exports[`utils getFileImageSpecFromFilename should match snapshot (filter named with spaces) 1`] = `
+{
+ "bin": "Bin1",
+ "bulb": "120.0s",
+ "bulbMs": 120000,
+ "datetime": 2024-07-07T00:23:48.000Z,
+ "extension": "fit",
+ "fileName": "Light_LDN 1093_120.0s_Bin1_filter h_gain100_20240707-002348_-10.0C_0001.fit",
+ "filter": "filterh",
+ "gain": 100,
+ "projectDirectory": "project/bar/filterh/Light_120.0s_Bin1_filterh_gain100",
+ "sequenceId": "20240707-002348",
+ "sequencePosition": 1,
+ "setName": "Light_120.0s_Bin1_filterh_gain100",
+ "sourceDirectory": "input/bar",
+ "sourceFilePath": "input/bar/Light_LDN 1093_120.0s_Bin1_filter h_gain100_20240707-002348_-10.0C_0001.fit",
+ "temperature": "-10.0C",
+ "type": "Light",
+}
+`;
+
+exports[`utils getFileImageSpecFromFilename should match snapshot (no filter) 1`] = `
+{
+ "bin": "Bin1",
+ "bulb": "120.0s",
+ "bulbMs": 120000,
+ "datetime": 2024-07-07T00:23:48.000Z,
+ "extension": "fit",
+ "fileName": "Light_LDN 1093_120.0s_Bin1_gain100_20240707-002348_-10.0C_0001.fit",
+ "filter": null,
+ "gain": 100,
+ "projectDirectory": "project/bar/Light_120.0s_Bin1_gain100",
+ "sequenceId": "20240707-002348",
+ "sequencePosition": 1,
+ "setName": "Light_120.0s_Bin1_gain100",
+ "sourceDirectory": "input/bar",
+ "sourceFilePath": "input/bar/Light_LDN 1093_120.0s_Bin1_gain100_20240707-002348_-10.0C_0001.fit",
+ "temperature": "-10.0C",
+ "type": "Light",
+}
+`;
diff --git a/src/utils/tests/logger.spec.ts b/src/utils/tests/logger.spec.ts
new file mode 100644
index 0000000..2dd9425
--- /dev/null
+++ b/src/utils/tests/logger.spec.ts
@@ -0,0 +1,119 @@
+import { jest } from "@jest/globals"; // Import Jest globals
+
+import { logger, formatMessage } from "../logger";
+import chalk from "chalk";
+
+describe("logger", () => {
+ const consoleLogSpy = jest.spyOn(console, "log");
+
+ afterEach(() => {
+ consoleLogSpy.mockClear();
+ });
+
+ afterAll(() => {
+ consoleLogSpy.mockRestore();
+ });
+
+ it("should log debug messages", () => {
+ logger.debug("Debug message");
+ expect(consoleLogSpy).toHaveBeenCalledWith(
+ chalk.gray.italic("Debug message"),
+ );
+ });
+
+ it("should log info messages", () => {
+ logger.info("Info message");
+ expect(consoleLogSpy).toHaveBeenCalledWith(chalk.blue("Info message"));
+ });
+
+ it("should log success messages", () => {
+ logger.success("Success message");
+ expect(consoleLogSpy).toHaveBeenCalledWith(
+ chalk.bold.green("Success message"),
+ );
+ });
+
+ it("should log warning messages", () => {
+ logger.warning("Warning message");
+ expect(consoleLogSpy).toHaveBeenCalledWith(
+ chalk.bold.yellow("Warning message"),
+ );
+ });
+
+ it("should log error messages", () => {
+ logger.error("Error message");
+ expect(consoleLogSpy).toHaveBeenCalledWith(chalk.bold.red("Error message"));
+ });
+
+ it("should throw an error with errorThrow", () => {
+ expect(() => logger.errorThrow("Error message")).toThrow("Error message");
+ expect(consoleLogSpy).toHaveBeenCalledWith(chalk.bold.red("Error message"));
+ });
+
+ it("should log dev messages", () => {
+ logger.dev("Dev message");
+ expect(consoleLogSpy).toHaveBeenCalledWith(
+ chalk.gray.italic("DEV: Dev message"),
+ );
+ });
+
+ it("should log step messages", () => {
+ logger.step("Step message");
+ expect(consoleLogSpy).toHaveBeenCalledWith(
+ chalk.blue(`\n${"=".repeat(80)}\nš Step message\n${"=".repeat(80)}\n`),
+ );
+ });
+
+ it("should log a space", () => {
+ logger.space();
+ expect(consoleLogSpy).toHaveBeenCalledWith();
+ });
+
+ it("should format and log messages with optional parameters", () => {
+ logger.info("Info message with params", { param1: "value1" });
+ expect(consoleLogSpy).toHaveBeenCalledWith(
+ chalk.blue("Info message with params"),
+ { param1: "value1" },
+ );
+ });
+
+ it("should handle empty messages", () => {
+ logger.info("");
+ expect(consoleLogSpy).toHaveBeenCalledWith(chalk.blue(""));
+ });
+
+ it("should handle undefined messages", () => {
+ logger.info(undefined);
+ expect(consoleLogSpy).toHaveBeenCalledWith(chalk.blue(undefined));
+ });
+});
+
+describe("formatMessage", () => {
+ it("should format messages correctly", () => {
+ const message = "Light_1234 gain10 Bin2 20220101-120000_thn.jpg";
+ const formattedMessage = formatMessage(message);
+ expect(formattedMessage).toContain(chalk.hex("#001f3f")("Light_"));
+ expect(formattedMessage).toContain(chalk.hex("#a05195")("gain10"));
+ expect(formattedMessage).toContain(chalk.hex("#2f4b7c")("Bin2"));
+ expect(formattedMessage).toContain(
+ `${chalk.hex("#d45087")("2022")}${chalk.hex("#f95d6a")("01")}${chalk.hex(
+ "#ff7c43",
+ )("01")}-${chalk.hex("#ffa600")("12")}${chalk.hex("#ffb000")(
+ "00",
+ )}${chalk.hex("#ffc000")("00")}`,
+ );
+ expect(formattedMessage).toContain(chalk.bgHex("#ff0000")("_thn.jpg"));
+ });
+
+ it("should handle empty messages", () => {
+ const message = "";
+ const formattedMessage = formatMessage(message);
+ expect(formattedMessage).toBe("");
+ });
+
+ it("should handle undefined messages", () => {
+ const message = undefined;
+ const formattedMessage = formatMessage(message);
+ expect(formattedMessage).toBe(undefined);
+ });
+});
diff --git a/src/utils/tests/utils.spec.ts b/src/utils/tests/utils.spec.ts
new file mode 100644
index 0000000..05f9a27
--- /dev/null
+++ b/src/utils/tests/utils.spec.ts
@@ -0,0 +1,208 @@
+import { jest } from "@jest/globals"; // Import Jest globals
+
+import fs from "fs";
+import {
+ getFileImageSpecFromFilename,
+ getFitsFromDirectory,
+ copyFileToProject,
+ matchSetFile,
+ getImageSpecFromSetName,
+} from "../utils";
+import { FileImageSpec, ImageSpec } from "../types";
+
+describe("utils", () => {
+ describe("getFileImageSpecFromFilename", () => {
+ it("should match snapshot (ASIAIR plan target format)", () => {
+ const file = new fs.Dirent();
+ file.name =
+ "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit";
+ file.path = "input/bar";
+ const projectDirectory = "project/bar";
+ const previousFile = null;
+
+ expect(
+ getFileImageSpecFromFilename(file, projectDirectory, previousFile),
+ ).toMatchSnapshot();
+ });
+
+ it("should match snapshot (filter named with spaces)", () => {
+ const file = new fs.Dirent();
+ file.name =
+ "Light_LDN 1093_120.0s_Bin1_filter h_gain100_20240707-002348_-10.0C_0001.fit";
+ file.path = "input/bar";
+ const projectDirectory = "project/bar";
+ const previousFile = null;
+
+ const specs = getFileImageSpecFromFilename(
+ file,
+ projectDirectory,
+ previousFile,
+ );
+ expect(specs).toMatchSnapshot();
+ expect(specs.filter).toBe("filterh");
+ });
+
+ it("should match snapshot (no filter)", () => {
+ const file = new fs.Dirent();
+ file.name =
+ "Light_LDN 1093_120.0s_Bin1_gain100_20240707-002348_-10.0C_0001.fit";
+ file.path = "input/bar";
+ const projectDirectory = "project/bar";
+ const previousFile = null;
+
+ const specs = getFileImageSpecFromFilename(
+ file,
+ projectDirectory,
+ previousFile,
+ );
+ expect(specs).toMatchSnapshot();
+ expect(specs.filter).toBeNull();
+ });
+ });
+
+ it.each([
+ { bulb: "120.0s", expected: 120000 },
+ { bulb: "810.0ms", expected: 810 },
+ ])("should parse bulb in ms (%s)", data => {
+ const file = new fs.Dirent();
+ file.name = `Light_LDN 1093_${data.bulb}_Bin1_gain100_20240707-002348_-10.0C_0001.fit`;
+ file.path = "input/bar";
+ const projectDirectory = "project/bar";
+ const previousFile = null;
+
+ const specs = getFileImageSpecFromFilename(
+ file,
+ projectDirectory,
+ previousFile,
+ );
+ expect(specs.bulbMs).toBe(data.expected);
+ });
+
+ describe("getFitsFromDirectory", () => {
+ it("should retrieve FITS files from a directory", () => {
+ jest.spyOn(fs, "readdirSync").mockReturnValue([
+ Object.assign(new fs.Dirent(), {
+ name: "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit",
+ isFile: () => true,
+ path: "input/dir",
+ }),
+ Object.assign(new fs.Dirent(), {
+ name: "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002349_-10.0C_0002.fit",
+ isFile: () => true,
+ path: "input/dir",
+ }),
+ Object.assign(new fs.Dirent(), {
+ name: "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001_thn.jpg",
+ isFile: () => true,
+ path: "input/dir",
+ }),
+ ]);
+
+ const result = getFitsFromDirectory({
+ directory: "input/dir",
+ projectDirectory: "project/dir",
+ });
+
+ expect(result).toHaveLength(2);
+ expect(result[0].fileName).toBe(
+ "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002348_-10.0C_0001.fit",
+ );
+ expect(result[1].fileName).toBe(
+ "Light_LDN 1093_120.0s_Bin1_H_gain100_20240707-002349_-10.0C_0002.fit",
+ );
+ });
+ });
+
+ describe("copyFileToProject", () => {
+ it("should copy a file to the project directory", () => {
+ const file = {
+ projectDirectory: "project/dir",
+ fileName: "file1.fit",
+ sourceFilePath: "input/dir/file1.fit",
+ } as FileImageSpec;
+
+ jest.spyOn(fs, "existsSync").mockReturnValue(false);
+ jest.spyOn(fs, "mkdirSync");
+ jest.spyOn(fs, "copyFileSync").mockImplementation(() => {});
+
+ copyFileToProject(file);
+
+ expect(fs.existsSync).toHaveBeenCalledWith("project/dir");
+ expect(fs.mkdirSync).toHaveBeenCalledWith("project/dir", {
+ recursive: true,
+ });
+ expect(fs.copyFileSync).toHaveBeenCalledWith(
+ "input/dir/file1.fit",
+ "project/dir/file1.fit",
+ );
+ });
+ });
+
+ describe("matchSetFile", () => {
+ it("should match Light with Dark", () => {
+ const A = {
+ type: "Light",
+ bulb: "120.0s",
+ bin: "Bin1",
+ gain: 100,
+ } as ImageSpec;
+ const B = {
+ type: "Dark",
+ bulb: "120.0s",
+ bin: "Bin1",
+ gain: 100,
+ } as ImageSpec;
+ expect(matchSetFile(A, B)).toBe(true);
+ });
+
+ it("should match Light with Flat", () => {
+ const A = { type: "Light", bin: "Bin1", filter: "H" } as ImageSpec;
+ const B = { type: "Flat", bin: "Bin1", filter: "H" } as ImageSpec;
+ expect(matchSetFile(A, B)).toBe(true);
+ });
+
+ it("should match Flat with Bias", () => {
+ const A = { type: "Flat", bin: "Bin1", gain: 100 } as ImageSpec;
+ const B = {
+ type: "Bias",
+ bin: "Bin1",
+ gain: 100,
+ } as ImageSpec;
+ expect(matchSetFile(A, B)).toBe(true);
+ });
+
+ it("should not match Light with Bias", () => {
+ const A = { type: "Light" } as ImageSpec;
+ const B = { type: "Bias" } as ImageSpec;
+ expect(matchSetFile(A, B)).toBe(false);
+ });
+ });
+
+ describe("getImageSpecFromSetName", () => {
+ it("should return the correct ImageSpec with filter", () => {
+ const setName = "Flat_520.0ms_Bin1_H_gain0";
+ const result = getImageSpecFromSetName(setName);
+ expect(result).toEqual({
+ setName,
+ type: "Flat",
+ bulb: "520.0ms",
+ bin: "Bin1",
+ filter: "H",
+ gain: 0,
+ });
+ });
+
+ it("should return the correct ImageSpec without filter", () => {
+ const setName = "Flat_520.0ms_Bin1_gain0";
+ const result = getImageSpecFromSetName(setName);
+ expect(result).toEqual({
+ setName,
+ type: "Flat",
+ bulb: "520.0ms",
+ bin: "Bin1",
+ filter: null,
+ gain: 0,
+ });
+ });
+ });
+});
diff --git a/src/utils/types.ts b/src/utils/types.ts
index c9fdd9a..2197b33 100644
--- a/src/utils/types.ts
+++ b/src/utils/types.ts
@@ -14,6 +14,7 @@ export type ImageSpec = {
* Bulb duration: 60.0s, 810.0ms, etc...
*/
bulb: string;
+ bulbMs: number; // TODO. Compute this.
/**
* Binning: Bin1, Bin2, Bin 3 & Bin 4.
*/
@@ -82,12 +83,31 @@ export type FileImageSpec = ImageSpec & {
* Each set has unique filter + exposure + gain + bin combination.
*/
export type LayerSet = {
- filter: string;
+ /**
+ * `Flat_520.0ms_Bin1_O_gain0` format.
+ * `Flat_520.0ms_Bin1_O_gain0__sequence-01` format for advanced light-flats matching.
+ */
+ layerSetId: string;
+
+ /**
+ * Filter: L, R, G, B, H... As Specified in the ASIAIR zwo wheel.
+ * Optional.
+ */
+ filter: string | null;
- lightSet: string;
- lightsCount: number;
+ /**
+ * Sequences of lights used.
+ */
+ lightSequences: {
+ sequenceId: string;
+ count: number;
+ integrationMinutes: number;
+ }[];
+ lightTotalCount: number; // TODO. fix duplicate of sum of lightSequences.count
+ lightTotalIntegrationMinutes: number; // TODO. fix duplicate of sum of lightSequences.integrationMinutes
flatSet: string;
+ flatSequenceId: string;
flatsCount: number;
darkSet: string;
@@ -106,4 +126,18 @@ export type PotoProject = {
generatedAt: Date;
potoVersion: string;
layerSets: LayerSet[];
+ // TODO. Move total light integrations & various stats here.
+};
+
+export type LightsFlatsMatch = {
+ lightSetName: string;
+ lightSequenceId: string;
+
+ flatSetName: string;
+ flatSequenceId: string;
+
+ /**
+ * True if the light was manually matched because several flats sequences were available.
+ */
+ isManualMatch: boolean;
};
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index 0359d4f..5ac8f37 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -28,11 +28,16 @@ export const getFitsFromDirectory = ({
if (file.isDirectory()) {
return;
}
- if (
- !(file.isFile() || file.isSymbolicLink()) ||
- !file.name.endsWith(".fit")
- ) {
- logger.debugNR("Skipping ", file.name);
+ if (file.name.endsWith("_thn.jpg")) {
+ logger.debug(`Skipping thumbnail file (${file.name})`);
+ return;
+ }
+ if (!(file.isFile() || file.isSymbolicLink())) {
+ logger.debug(`Skipping not-file or symlink (${file.name})`);
+ return;
+ }
+ if (!file.name.endsWith(".fit")) {
+ logger.debug(`Skipping unknown file (${file.name})`);
return;
}
@@ -67,7 +72,7 @@ export const getFileImageSpecFromFilename = (
// Note: Filter is not always specified in the filename.
const regex =
- /^(?[A-Za-z]+)(?:_[^_]+)?_(?[^_]+)_(?Bin\d)_((?[A-Za-z0-9])_)?gain(?\d+)_(?\d{8}-\d{6})_(?-?\d+\.\d+C)_(?\d{4})\.(?fit)$/;
+ /^(?[A-Za-z]+)(?:_[^_]+)?_(?[^_]+)_(?Bin\d)_((?[A-Za-z0-9 ]+)_)?gain(?\d+)_(?\d{8}-\d{6})_(?-?\d+\.\d+C)_(?\d{4})\.(?fit)$/;
const match = fileFS.name.match(regex);
// TODO. Check if well sorted!
@@ -91,8 +96,9 @@ export const getFileImageSpecFromFilename = (
type: match.groups.type,
bulb: match.groups.bulb,
+ bulbMs: parseBulbString(match.groups.bulb),
bin: match.groups.bin,
- filter: match.groups.filter ?? null,
+ filter: match.groups.filter?.replaceAll(" ", "").trim() ?? null,
gain: parseInt(match.groups.gain, 10),
sequenceId,
@@ -141,7 +147,7 @@ const parseDate = (datetimeString: string): Date => {
const [_, year, month, day, hour, minute, second] = matchResult;
const parsedDate = new Date(
parseInt(year, 10),
- parseInt(month, 10) - 1, // Month is zero-based in JavaScript Date
+ parseInt(month, 10) - 1, // Month is zero-based in JavaScript Date.
parseInt(day, 10),
parseInt(hour, 10),
parseInt(minute, 10),
@@ -166,6 +172,23 @@ const unParseDate = (datetime: Date): string => {
)}`;
};
+/**
+ *
+ * @param bulbString `120.0s` or `810.0ms`.
+ * @returns 120000 or 810 (in ms).
+ */
+const parseBulbString = (bulbString: string): number => {
+ const bulbRegex = /(\d+\.\d+)(ms|s)/;
+ const matchResult = bulbString.match(bulbRegex);
+
+ if (matchResult) {
+ const [_, bulb, unit] = matchResult;
+ return unit === "s" ? parseFloat(bulb) * 1000 : parseFloat(bulb);
+ } else {
+ throw new Error(`Invalid bulb string: ${bulbString}`);
+ }
+};
+
export const copyFileToProject = (file: FileImageSpec) => {
if (!fs.existsSync(file.projectDirectory)) {
fs.mkdirSync(file.projectDirectory, { recursive: true });
@@ -174,7 +197,7 @@ export const copyFileToProject = (file: FileImageSpec) => {
const targetFile = path.join(file.projectDirectory, file.fileName);
fs.copyFileSync(file.sourceFilePath, targetFile);
- logger.debug(`Copied ${file.fileName} to ${targetFile}`);
+ logger.debug(`- ${file.fileName} dispatched.`);
};
/**
@@ -185,7 +208,7 @@ export const copyFileToProject = (file: FileImageSpec) => {
* - Light with Flat (allowing for different gain).
* - Flat with Bias.
*/
-export const matchSetFile = (A: FileImageSpec, B: FileImageSpec): boolean => {
+export const matchSetFile = (A: ImageSpec, B: ImageSpec): boolean => {
if (A.type === "Light" && B.type === "Dark") {
return (
// TODO. Filter based on the temperature.
diff --git a/tsconfig.json b/tsconfig.json
index 244a211..285a49f 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -16,16 +16,3 @@
"exclude": ["node_modules"],
"include": ["src/**/*.ts", "bin/*.ts"]
}
-
-// {
-// "compilerOptions": {
-// "target": "ES2023",
-// "module": "ESNext",
-// "esModuleInterop": true,
-// "moduleResolution": "node",
-// "outDir": "./dist",
-// "strict": true,
-// "types": ["node", "jest"]
-// },
-// "include": ["src/**/*"]
-// }